3 { This file contains output colorspace conversion routines. }
5 { Original: jdcolor.c ; Copyright (C) 1991-1997, Thomas G. Lane. }
19 { Module initialization routine for output colorspace conversion. }
22 procedure jinit_color_deconverter (cinfo
: j_decompress_ptr
);
28 int_Color_Table
= array[0..MAXJSAMPLE
+1-1] of int
;
29 int_table_ptr
= ^int_Color_Table
;
30 INT32_Color_Table
= array[0..MAXJSAMPLE
+1-1] of INT32
;
31 INT32_table_ptr
= ^INT32_Color_Table
;
33 my_cconvert_ptr
= ^my_color_deconverter
;
34 my_color_deconverter
= record
35 pub
: jpeg_color_deconverter
; { public fields }
37 { Private state for YCC^.RGB conversion }
38 Cr_r_tab
: int_table_ptr
; { => table for Cr to R conversion }
39 Cb_b_tab
: int_table_ptr
; { => table for Cb to B conversion }
40 Cr_g_tab
: INT32_table_ptr
; { => table for Cr to G conversion }
41 Cb_g_tab
: INT32_table_ptr
; { => table for Cb to G conversion }
47 {*************** YCbCr ^. RGB conversion: most common case *************}
49 { YCbCr is defined per CCIR 601-1, except that Cb and Cr are
50 normalized to the range 0..MAXJSAMPLE rather than -0.5 .. 0.5.
51 The conversion equations to be implemented are therefore
53 G = Y - 0.34414 * Cb - 0.71414 * Cr
55 where Cb and Cr represent the incoming values less CENTERJSAMPLE.
56 (These numbers are derived from TIFF 6.0 section 21, dated 3-June-92.)
58 To avoid floating-point arithmetic, we represent the fractional constants
59 as integers scaled up by 2^16 (about 4 digits precision); we have to divide
60 the products by 2^16, with appropriate rounding, to get the correct answer.
61 Notice that Y, being an integral input, does not contribute any fraction
62 so it need not participate in the rounding.
64 For even more speed, we avoid doing any multiplications in the inner loop
65 by precalculating the constants times Cb and Cr for all possible values.
66 For 8-bit JSAMPLEs this is very reasonable (only 256 entries per table);
67 for 12-bit samples it is still acceptable. It's not very reasonable for
68 16-bit samples, but if you want lossless storage you shouldn't be changing
70 The Cr=>R and Cb=>B values can be rounded to integers in advance; the
71 values for the G calculation are left scaled up, since we must add them
72 together before rounding. }
75 SCALEBITS
= 16; { speediest right-shift on some machines }
76 ONE_HALF
= (INT32(1) shl (SCALEBITS
-1));
79 { Initialize tables for YCC->RGB colorspace conversion. }
82 procedure build_ycc_rgb_table (cinfo
: j_decompress_ptr
);
84 FIX_1_40200
= INT32(Round( 1.40200 * (1 shl SCALEBITS
)));
85 FIX_1_77200
= INT32(Round( 1.77200 * (1 shl SCALEBITS
)));
86 FIX_0_71414
= INT32(Round( 0.71414 * (1 shl SCALEBITS
)));
87 FIX_0_34414
= INT32(Round( 0.34414 * (1 shl SCALEBITS
)));
90 cconvert
: my_cconvert_ptr
;
96 cconvert
:= my_cconvert_ptr (cinfo
^.cconvert
);
99 cconvert
^.Cr_r_tab
:= int_table_ptr(
100 cinfo
^.mem
^.alloc_small ( j_common_ptr(cinfo
), JPOOL_IMAGE
,
101 (MAXJSAMPLE
+1) * SIZEOF(int
)) );
102 cconvert
^.Cb_b_tab
:= int_table_ptr (
103 cinfo
^.mem
^.alloc_small ( j_common_ptr(cinfo
), JPOOL_IMAGE
,
104 (MAXJSAMPLE
+1) * SIZEOF(int
)) );
105 cconvert
^.Cr_g_tab
:= INT32_table_ptr (
106 cinfo
^.mem
^.alloc_small ( j_common_ptr(cinfo
), JPOOL_IMAGE
,
107 (MAXJSAMPLE
+1) * SIZEOF(INT32
)) );
108 cconvert
^.Cb_g_tab
:= INT32_table_ptr (
109 cinfo
^.mem
^.alloc_small ( j_common_ptr(cinfo
), JPOOL_IMAGE
,
110 (MAXJSAMPLE
+1) * SIZEOF(INT32
)) );
114 for i
:= 0 to MAXJSAMPLE
do
116 { i is the actual input pixel value, in the range 0..MAXJSAMPLE }
117 { The Cb or Cr value we are thinking of is x := i - CENTERJSAMPLE }
118 { Cr=>R value is nearest int to 1.40200 * x }
120 shift_temp
:= FIX_1_40200
* x
+ ONE_HALF
;
121 if shift_temp
< 0 then { SHIFT arithmetic RIGHT }
122 cconvert
^.Cr_r_tab
^[i
] := int((shift_temp
shr SCALEBITS
)
123 or ( (not INT32(0)) shl (32-SCALEBITS
)))
125 cconvert
^.Cr_r_tab
^[i
] := int(shift_temp
shr SCALEBITS
);
127 { Cb=>B value is nearest int to 1.77200 * x }
128 shift_temp
:= FIX_1_77200
* x
+ ONE_HALF
;
129 if shift_temp
< 0 then { SHIFT arithmetic RIGHT }
130 cconvert
^.Cb_b_tab
^[i
] := int((shift_temp
shr SCALEBITS
)
131 or ( (not INT32(0)) shl (32-SCALEBITS
)))
133 cconvert
^.Cb_b_tab
^[i
] := int(shift_temp
shr SCALEBITS
);
135 { Cr=>G value is scaled-up -0.71414 * x }
136 cconvert
^.Cr_g_tab
^[i
] := (- FIX_0_71414
) * x
;
137 { Cb=>G value is scaled-up -0.34414 * x }
138 { We also add in ONE_HALF so that need not do it in inner loop }
139 cconvert
^.Cb_g_tab
^[i
] := (- FIX_0_34414
) * x
+ ONE_HALF
;
145 { Convert some rows of samples to the output colorspace.
147 Note that we change from noninterleaved, one-plane-per-component format
148 to interleaved-pixel format. The output buffer is therefore three times
149 as wide as the input buffer.
150 A starting row offset is provided only for the input buffer. The caller
151 can easily adjust the passed output_buf value to accommodate any row
152 offset required on that side. }
155 procedure ycc_rgb_convert (cinfo
: j_decompress_ptr
;
156 input_buf
: JSAMPIMAGE
;
157 input_row
: JDIMENSION
;
158 output_buf
: JSAMPARRAY
;
161 cconvert
: my_cconvert_ptr
;
162 {register} y
, cb
, cr
: int
;
163 {register} outptr
: JSAMPROW
;
164 {register} inptr0
, inptr1
, inptr2
: JSAMPROW
;
165 {register} col
: JDIMENSION
;
166 num_cols
: JDIMENSION
;
167 { copy these pointers into registers if possible }
168 {register} range_limit
: range_limit_table_ptr
;
169 {register} Crrtab
: int_table_ptr
;
170 {register} Cbbtab
: int_table_ptr
;
171 {register} Crgtab
: INT32_table_ptr
;
172 {register} Cbgtab
: INT32_table_ptr
;
176 cconvert
:= my_cconvert_ptr (cinfo
^.cconvert
);
177 num_cols
:= cinfo
^.output_width
;
178 range_limit
:= cinfo
^.sample_range_limit
;
179 Crrtab
:= cconvert
^.Cr_r_tab
;
180 Cbbtab
:= cconvert
^.Cb_b_tab
;
181 Crgtab
:= cconvert
^.Cr_g_tab
;
182 Cbgtab
:= cconvert
^.Cb_g_tab
;
184 while (num_rows
> 0) do
187 inptr0
:= input_buf
^[0]^[input_row
];
188 inptr1
:= input_buf
^[1]^[input_row
];
189 inptr2
:= input_buf
^[2]^[input_row
];
191 outptr
:= output_buf
^[0];
192 Inc(JSAMPROW_PTR(output_buf
));
193 for col
:= 0 to pred(num_cols
) do
195 y
:= GETJSAMPLE(inptr0
^[col
]);
196 cb
:= GETJSAMPLE(inptr1
^[col
]);
197 cr
:= GETJSAMPLE(inptr2
^[col
]);
198 { Range-limiting is essential due to noise introduced by DCT losses. }
199 outptr
^[RGB_RED
] := range_limit
^[y
+ Crrtab
^[cr
]];
200 shift_temp
:= Cbgtab
^[cb
] + Crgtab
^[cr
];
201 if shift_temp
< 0 then { SHIFT arithmetic RIGHT }
202 outptr
^[RGB_GREEN
] := range_limit
^[y
+ int((shift_temp
shr SCALEBITS
)
203 or ( (not INT32(0)) shl (32-SCALEBITS
)))]
205 outptr
^[RGB_GREEN
] := range_limit
^[y
+ int(shift_temp
shr SCALEBITS
)];
207 outptr
^[RGB_BLUE
] := range_limit
^[y
+ Cbbtab
^[cb
]];
208 Inc(JSAMPLE_PTR(outptr
), RGB_PIXELSIZE
);
214 {*************** Cases other than YCbCr -> RGB *************}
217 { Color conversion for no colorspace change: just copy the data,
218 converting from separate-planes to interleaved representation. }
221 procedure null_convert (cinfo
: j_decompress_ptr
;
222 input_buf
: JSAMPIMAGE
;
223 input_row
: JDIMENSION
;
224 output_buf
: JSAMPARRAY
;
228 outptr
: JSAMPLE_PTR
;
229 {register} count
: JDIMENSION
;
230 {register} num_components
: int
;
231 num_cols
: JDIMENSION
;
234 num_components
:= cinfo
^.num_components
;
235 num_cols
:= cinfo
^.output_width
;
237 while (num_rows
> 0) do
240 for ci
:= 0 to pred(num_components
) do
242 inptr
:= JSAMPLE_PTR(input_buf
^[ci
]^[input_row
]);
243 outptr
:= JSAMPLE_PTR(@(output_buf
^[0]^[ci
]));
245 for count
:= pred(num_cols
) downto 0 do
247 outptr
^ := inptr
^; { needn't bother with GETJSAMPLE() here }
249 Inc(outptr
, num_components
);
253 Inc(JSAMPROW_PTR(output_buf
));
258 { Color conversion for grayscale: just copy the data.
259 This also works for YCbCr -> grayscale conversion, in which
260 we just copy the Y (luminance) component and ignore chrominance. }
263 procedure grayscale_convert (cinfo
: j_decompress_ptr
;
264 input_buf
: JSAMPIMAGE
;
265 input_row
: JDIMENSION
;
266 output_buf
: JSAMPARRAY
;
269 jcopy_sample_rows(input_buf
^[0], int(input_row
), output_buf
, 0,
270 num_rows
, cinfo
^.output_width
);
273 { Convert grayscale to RGB: just duplicate the graylevel three times.
274 This is provided to support applications that don't want to cope
275 with grayscale as a separate case. }
278 procedure gray_rgb_convert (cinfo
: j_decompress_ptr
;
279 input_buf
: JSAMPIMAGE
;
280 input_row
: JDIMENSION
;
281 output_buf
: JSAMPARRAY
;
284 {register} inptr
, outptr
: JSAMPLE_PTR
;
285 {register} col
: JDIMENSION
;
286 num_cols
: JDIMENSION
;
288 num_cols
:= cinfo
^.output_width
;
289 while (num_rows
> 0) do
291 inptr
:= JSAMPLE_PTR(input_buf
^[0]^[input_row
]);
293 outptr
:= JSAMPLE_PTR(@output_buf
^[0]);
294 Inc(JSAMPROW_PTR(output_buf
));
295 for col
:= 0 to pred(num_cols
) do
297 { We can dispense with GETJSAMPLE() here }
298 JSAMPROW(outptr
)^[RGB_RED
] := inptr
^;
299 JSAMPROW(outptr
)^[RGB_GREEN
] := inptr
^;
300 JSAMPROW(outptr
)^[RGB_BLUE
] := inptr
^;
302 Inc(outptr
, RGB_PIXELSIZE
);
309 { Adobe-style YCCK -> CMYK conversion.
310 We convert YCbCr to R=1-C, G=1-M, and B=1-Y using the same
311 conversion as above, while passing K (black) unchanged.
312 We assume build_ycc_rgb_table has been called. }
315 procedure ycck_cmyk_convert (cinfo
: j_decompress_ptr
;
316 input_buf
: JSAMPIMAGE
;
317 input_row
: JDIMENSION
;
318 output_buf
: JSAMPARRAY
;
321 cconvert
: my_cconvert_ptr
;
322 {register} y
, cb
, cr
: int
;
323 {register} outptr
: JSAMPROW
;
324 {register} inptr0
, inptr1
, inptr2
, inptr3
: JSAMPROW
;
325 {register} col
: JDIMENSION
;
326 num_cols
: JDIMENSION
;
327 { copy these pointers into registers if possible }
328 {register} range_limit
: range_limit_table_ptr
;
329 {register} Crrtab
: int_table_ptr
;
330 {register} Cbbtab
: int_table_ptr
;
331 {register} Crgtab
: INT32_table_ptr
;
332 {register} Cbgtab
: INT32_table_ptr
;
336 cconvert
:= my_cconvert_ptr (cinfo
^.cconvert
);
337 num_cols
:= cinfo
^.output_width
;
338 { copy these pointers into registers if possible }
339 range_limit
:= cinfo
^.sample_range_limit
;
340 Crrtab
:= cconvert
^.Cr_r_tab
;
341 Cbbtab
:= cconvert
^.Cb_b_tab
;
342 Crgtab
:= cconvert
^.Cr_g_tab
;
343 Cbgtab
:= cconvert
^.Cb_g_tab
;
345 while (num_rows
> 0) do
348 inptr0
:= input_buf
^[0]^[input_row
];
349 inptr1
:= input_buf
^[1]^[input_row
];
350 inptr2
:= input_buf
^[2]^[input_row
];
351 inptr3
:= input_buf
^[3]^[input_row
];
353 outptr
:= output_buf
^[0];
354 Inc(JSAMPROW_PTR(output_buf
));
355 for col
:= 0 to pred(num_cols
) do
357 y
:= GETJSAMPLE(inptr0
^[col
]);
358 cb
:= GETJSAMPLE(inptr1
^[col
]);
359 cr
:= GETJSAMPLE(inptr2
^[col
]);
360 { Range-limiting is essential due to noise introduced by DCT losses. }
361 outptr
^[0] := range_limit
^[MAXJSAMPLE
- (y
+ Crrtab
^[cr
])]; { red }
362 shift_temp
:= Cbgtab
^[cb
] + Crgtab
^[cr
];
363 if shift_temp
< 0 then
364 outptr
^[1] := range_limit
^[MAXJSAMPLE
- (y
+ int(
365 (shift_temp
shr SCALEBITS
) or ((not INT32(0)) shl (32-SCALEBITS
))
368 outptr
^[1] := range_limit
^[MAXJSAMPLE
- { green }
369 (y
+ int(shift_temp
shr SCALEBITS
) )];
370 outptr
^[2] := range_limit
^[MAXJSAMPLE
- (y
+ Cbbtab
^[cb
])]; { blue }
371 { K passes through unchanged }
372 outptr
^[3] := inptr3
^[col
]; { don't need GETJSAMPLE here }
373 Inc(JSAMPLE_PTR(outptr
), 4);
379 { Empty method for start_pass. }
382 procedure start_pass_dcolor (cinfo
: j_decompress_ptr
);
388 { Module initialization routine for output colorspace conversion. }
391 procedure jinit_color_deconverter (cinfo
: j_decompress_ptr
);
393 cconvert
: my_cconvert_ptr
;
396 cconvert
:= my_cconvert_ptr (
397 cinfo
^.mem
^.alloc_small (j_common_ptr(cinfo
), JPOOL_IMAGE
,
398 SIZEOF(my_color_deconverter
)) );
399 cinfo
^.cconvert
:= jpeg_color_deconverter_ptr (cconvert
);
400 cconvert
^.pub
.start_pass
:= start_pass_dcolor
;
402 { Make sure num_components agrees with jpeg_color_space }
403 case (cinfo
^.jpeg_color_space
) of
405 if (cinfo
^.num_components
<> 1) then
406 ERREXIT(j_common_ptr(cinfo
), JERR_BAD_J_COLORSPACE
);
410 if (cinfo
^.num_components
<> 3) then
411 ERREXIT(j_common_ptr(cinfo
), JERR_BAD_J_COLORSPACE
);
415 if (cinfo
^.num_components
<> 4) then
416 ERREXIT(j_common_ptr(cinfo
), JERR_BAD_J_COLORSPACE
);
418 else { JCS_UNKNOWN can be anything }
419 if (cinfo
^.num_components
< 1) then
420 ERREXIT(j_common_ptr(cinfo
), JERR_BAD_J_COLORSPACE
);
423 { Set out_color_components and conversion method based on requested space.
424 Also clear the component_needed flags for any unused components,
425 so that earlier pipeline stages can avoid useless computation. }
427 case (cinfo
^.out_color_space
) of
430 cinfo
^.out_color_components
:= 1;
431 if (cinfo
^.jpeg_color_space
= JCS_GRAYSCALE
)
432 or (cinfo
^.jpeg_color_space
= JCS_YCbCr
) then
434 cconvert
^.pub
.color_convert
:= grayscale_convert
;
435 { For color -> grayscale conversion, only the
436 Y (0) component is needed }
437 for ci
:= 1 to pred(cinfo
^.num_components
) do
438 cinfo
^.comp_info
^[ci
].component_needed
:= FALSE;
441 ERREXIT(j_common_ptr(cinfo
), JERR_CONVERSION_NOTIMPL
);
446 cinfo
^.out_color_components
:= RGB_PIXELSIZE
;
447 if (cinfo
^.jpeg_color_space
= JCS_YCbCr
) then
449 cconvert
^.pub
.color_convert
:= ycc_rgb_convert
;
450 build_ycc_rgb_table(cinfo
);
453 if (cinfo
^.jpeg_color_space
= JCS_GRAYSCALE
) then
455 cconvert
^.pub
.color_convert
:= gray_rgb_convert
;
458 if (cinfo
^.jpeg_color_space
= JCS_RGB
) and (RGB_PIXELSIZE
= 3) then
460 cconvert
^.pub
.color_convert
:= null_convert
;
463 ERREXIT(j_common_ptr(cinfo
), JERR_CONVERSION_NOTIMPL
);
468 cinfo
^.out_color_components
:= 4;
469 if (cinfo
^.jpeg_color_space
= JCS_YCCK
) then
471 cconvert
^.pub
.color_convert
:= ycck_cmyk_convert
;
472 build_ycc_rgb_table(cinfo
);
475 if (cinfo
^.jpeg_color_space
= JCS_CMYK
) then
477 cconvert
^.pub
.color_convert
:= null_convert
;
480 ERREXIT(j_common_ptr(cinfo
), JERR_CONVERSION_NOTIMPL
);
484 begin { Permit null conversion to same output space }
485 if (cinfo
^.out_color_space
= cinfo
^.jpeg_color_space
) then
487 cinfo
^.out_color_components
:= cinfo
^.num_components
;
488 cconvert
^.pub
.color_convert
:= null_convert
;
490 else { unsupported non-null conversion }
491 ERREXIT(j_common_ptr(cinfo
), JERR_CONVERSION_NOTIMPL
);
495 if (cinfo
^.quantize_colors
) then
496 cinfo
^.output_components
:= 1 { single colormapped output component }
498 cinfo
^.output_components
:= cinfo
^.out_color_components
;