578706c1b88e9bba27ef54352281e7c487c818bb
3 { This file contains input colorspace conversion routines. }
5 { Original : jccolor.c ; Copyright (C) 1991-1996, Thomas G. Lane. }
18 { Module initialization routine for input colorspace conversion. }
21 procedure jinit_color_converter (cinfo
: j_compress_ptr
);
27 jTInt32
= 0..Pred(MaxInt
div SizeOf(INT32
));
28 INT32_FIELD
= array[jTInt32
] of INT32
;
29 INT32_FIELD_PTR
= ^INT32_FIELD
;
32 my_cconvert_ptr
= ^my_color_converter
;
33 my_color_converter
= record
34 pub
: jpeg_color_converter
; { public fields }
36 { Private state for RGB -> YCC conversion }
37 rgb_ycc_tab
: INT32_FIELD_PTR
; { => table for RGB to YCbCr conversion }
38 end; {my_color_converter;}
41 {*************** RGB -> YCbCr conversion: most common case *************}
44 YCbCr is defined per CCIR 601-1, except that Cb and Cr are
45 normalized to the range 0..MAXJSAMPLE rather than -0.5 .. 0.5.
46 The conversion equations to be implemented are therefore
47 Y = 0.29900 * R + 0.58700 * G + 0.11400 * B
48 Cb = -0.16874 * R - 0.33126 * G + 0.50000 * B + CENTERJSAMPLE
49 Cr = 0.50000 * R - 0.41869 * G - 0.08131 * B + CENTERJSAMPLE
50 (These numbers are derived from TIFF 6.0 section 21, dated 3-June-92.)
51 Note: older versions of the IJG code used a zero offset of MAXJSAMPLE/2,
52 rather than CENTERJSAMPLE, for Cb and Cr. This gave equal positive and
53 negative swings for Cb/Cr, but meant that grayscale values (Cb=Cr=0)
54 were not represented exactly. Now we sacrifice exact representation of
55 maximum red and maximum blue in order to get exact grayscales.
57 To avoid floating-point arithmetic, we represent the fractional constants
58 as integers scaled up by 2^16 (about 4 digits precision); we have to divide
59 the products by 2^16, with appropriate rounding, to get the correct answer.
61 For even more speed, we avoid doing any multiplications in the inner loop
62 by precalculating the constants times R,G,B for all possible values.
63 For 8-bit JSAMPLEs this is very reasonable (only 256 entries per table);
64 for 12-bit samples it is still acceptable. It's not very reasonable for
65 16-bit samples, but if you want lossless storage you shouldn't be changing
67 The CENTERJSAMPLE offsets and the rounding fudge-factor of 0.5 are included
68 in the tables to save adding them separately in the inner loop. }
70 SCALEBITS
= 16; { speediest right-shift on some machines }
71 CBCR_OFFSET
= INT32(CENTERJSAMPLE
shl SCALEBITS
);
72 ONE_HALF
= INT32(1) shl (SCALEBITS
-1);
75 { We allocate one big table and divide it up into eight parts, instead of
76 doing eight alloc_small requests. This lets us use a single table base
77 address, which can be held in a register in the inner loops on many
78 machines (more than can hold all eight addresses, anyway). }
80 R_Y_OFF
= 0; { offset to R => Y section }
81 G_Y_OFF
= 1*(MAXJSAMPLE
+1); { offset to G => Y section }
82 B_Y_OFF
= 2*(MAXJSAMPLE
+1); { etc. }
83 R_CB_OFF
= 3*(MAXJSAMPLE
+1);
84 G_CB_OFF
= 4*(MAXJSAMPLE
+1);
85 B_CB_OFF
= 5*(MAXJSAMPLE
+1);
86 R_CR_OFF
= B_CB_OFF
; { B=>Cb, R=>Cr are the same }
87 G_CR_OFF
= 6*(MAXJSAMPLE
+1);
88 B_CR_OFF
= 7*(MAXJSAMPLE
+1);
89 TABLE_SIZE
= 8*(MAXJSAMPLE
+1);
92 { Initialize for RGB->YCC colorspace conversion. }
95 procedure rgb_ycc_start (cinfo
: j_compress_ptr
);
97 FIX_0_29900
= INT32(Round (0.29900 * (1 shl SCALEBITS
)) );
98 FIX_0_58700
= INT32(Round (0.58700 * (1 shl SCALEBITS
)) );
99 FIX_0_11400
= INT32(Round (0.11400 * (1 shl SCALEBITS
)) );
100 FIX_0_16874
= INT32(Round (0.16874 * (1 shl SCALEBITS
)) );
101 FIX_0_33126
= INT32(Round (0.33126 * (1 shl SCALEBITS
)) );
102 FIX_0_50000
= INT32(Round (0.50000 * (1 shl SCALEBITS
)) );
103 FIX_0_41869
= INT32(Round (0.41869 * (1 shl SCALEBITS
)) );
104 FIX_0_08131
= INT32(Round (0.08131 * (1 shl SCALEBITS
)) );
106 cconvert
: my_cconvert_ptr
;
107 rgb_ycc_tab
: INT32_FIELD_PTR
;
110 cconvert
:= my_cconvert_ptr (cinfo
^.cconvert
);
112 { Allocate and fill in the conversion tables. }
113 rgb_ycc_tab
:= INT32_FIELD_PTR(
114 cinfo
^.mem
^.alloc_small (j_common_ptr(cinfo
), JPOOL_IMAGE
,
115 (TABLE_SIZE
* SIZEOF(INT32
))) );
116 cconvert
^.rgb_ycc_tab
:= rgb_ycc_tab
;
118 for i
:= 0 to MAXJSAMPLE
do
120 rgb_ycc_tab
^[i
+R_Y_OFF
] := FIX_0_29900
* i
;
121 rgb_ycc_tab
^[i
+G_Y_OFF
] := FIX_0_58700
* i
;
122 rgb_ycc_tab
^[i
+B_Y_OFF
] := FIX_0_11400
* i
+ ONE_HALF
;
123 rgb_ycc_tab
^[i
+R_CB_OFF
] := (-FIX_0_16874
) * i
;
124 rgb_ycc_tab
^[i
+G_CB_OFF
] := (-FIX_0_33126
) * i
;
125 { We use a rounding fudge-factor of 0.5-epsilon for Cb and Cr.
126 This ensures that the maximum output will round to MAXJSAMPLE
127 not MAXJSAMPLE+1, and thus that we don't have to range-limit. }
129 rgb_ycc_tab
^[i
+B_CB_OFF
] := FIX_0_50000
* i
+ CBCR_OFFSET
+ ONE_HALF
-1;
130 { B=>Cb and R=>Cr tables are the same
131 rgb_ycc_tab^[i+R_CR_OFF] := FIX_0_50000 * i + CBCR_OFFSET + ONE_HALF-1;
133 rgb_ycc_tab
^[i
+G_CR_OFF
] := (-FIX_0_41869
) * i
;
134 rgb_ycc_tab
^[i
+B_CR_OFF
] := (-FIX_0_08131
) * i
;
139 { Convert some rows of samples to the JPEG colorspace.
141 Note that we change from the application's interleaved-pixel format
142 to our internal noninterleaved, one-plane-per-component format.
143 The input buffer is therefore three times as wide as the output buffer.
145 A starting row offset is provided only for the output buffer. The caller
146 can easily adjust the passed input_buf value to accommodate any row
147 offset required on that side. }
150 procedure rgb_ycc_convert (cinfo
: j_compress_ptr
;
151 input_buf
: JSAMPARRAY
;
152 output_buf
: JSAMPIMAGE
;
153 output_row
: JDIMENSION
;
156 cconvert
: my_cconvert_ptr
;
157 {register} r
, g
, b
: int
;
158 {register} ctab
: INT32_FIELD_PTR
;
159 {register} inptr
: JSAMPROW
;
160 {register} outptr0
, outptr1
, outptr2
: JSAMPROW
;
161 {register} col
: JDIMENSION
;
162 num_cols
: JDIMENSION
;
164 cconvert
:= my_cconvert_ptr (cinfo
^.cconvert
);
165 ctab
:= cconvert
^.rgb_ycc_tab
;
166 num_cols
:= cinfo
^.image_width
;
168 while (num_rows
> 0) do
171 inptr
:= input_buf
^[0];
172 Inc(JSAMPROW_PTR(input_buf
));
173 outptr0
:= output_buf
^[0]^[output_row
];
174 outptr1
:= output_buf
^[1]^[output_row
];
175 outptr2
:= output_buf
^[2]^[output_row
];
177 for col
:= 0 to pred(num_cols
) do
179 r
:= GETJSAMPLE(inptr
^[RGB_RED
]);
180 g
:= GETJSAMPLE(inptr
^[RGB_GREEN
]);
181 b
:= GETJSAMPLE(inptr
^[RGB_BLUE
]);
182 Inc(JSAMPLE_PTR(inptr
), RGB_PIXELSIZE
);
183 { If the inputs are 0..MAXJSAMPLE, the outputs of these equations
184 must be too; we do not need an explicit range-limiting operation.
185 Hence the value being shifted is never negative, and we don't
186 need the general RIGHT_SHIFT macro. }
189 outptr0
^[col
] := JSAMPLE(
190 ((ctab
^[r
+R_Y_OFF
] + ctab
^[g
+G_Y_OFF
] + ctab
^[b
+B_Y_OFF
])
193 outptr1
^[col
] := JSAMPLE(
194 ((ctab
^[r
+R_CB_OFF
] + ctab
^[g
+G_CB_OFF
] + ctab
^[b
+B_CB_OFF
])
197 outptr2
^[col
] := JSAMPLE(
198 ((ctab
^[r
+R_CR_OFF
] + ctab
^[g
+G_CR_OFF
] + ctab
^[b
+B_CR_OFF
])
205 {*************** Cases other than RGB -> YCbCr *************}
208 { Convert some rows of samples to the JPEG colorspace.
209 This version handles RGB -> grayscale conversion, which is the same
210 as the RGB -> Y portion of RGB -> YCbCr.
211 We assume rgb_ycc_start has been called (we only use the Y tables). }
214 procedure rgb_gray_convert (cinfo
: j_compress_ptr
;
215 input_buf
: JSAMPARRAY
;
216 output_buf
: JSAMPIMAGE
;
217 output_row
: JDIMENSION
;
220 cconvert
: my_cconvert_ptr
;
221 {register} r
, g
, b
: int
;
222 {register} ctab
:INT32_FIELD_PTR
;
223 {register} inptr
: JSAMPROW
;
224 {register} outptr
: JSAMPROW
;
225 {register} col
: JDIMENSION
;
226 num_cols
: JDIMENSION
;
228 cconvert
:= my_cconvert_ptr (cinfo
^.cconvert
);
229 ctab
:= cconvert
^.rgb_ycc_tab
;
230 num_cols
:= cinfo
^.image_width
;
232 while (num_rows
> 0) do
235 inptr
:= input_buf
^[0];
236 Inc(JSAMPROW_PTR(input_buf
));
237 outptr
:= output_buf
^[0]^[output_row
];
239 for col
:= 0 to pred(num_cols
) do
241 r
:= GETJSAMPLE(inptr
^[RGB_RED
]);
242 g
:= GETJSAMPLE(inptr
^[RGB_GREEN
]);
243 b
:= GETJSAMPLE(inptr
^[RGB_BLUE
]);
244 Inc(JSAMPLE_PTR(inptr
), RGB_PIXELSIZE
);
246 // kylix 3 compiler crashes on this
247 {$IF (not Defined(LINUX)) or Defined(FPC)}
248 outptr
^[col
] := JSAMPLE (
249 ((ctab
^[r
+R_Y_OFF
] + ctab
^[g
+G_Y_OFF
] + ctab
^[b
+B_Y_OFF
])
258 { Convert some rows of samples to the JPEG colorspace.
259 This version handles Adobe-style CMYK -> YCCK conversion,
260 where we convert R=1-C, G=1-M, and B=1-Y to YCbCr using the same
261 conversion as above, while passing K (black) unchanged.
262 We assume rgb_ycc_start has been called. }
265 procedure cmyk_ycck_convert (cinfo
: j_compress_ptr
;
266 input_buf
: JSAMPARRAY
;
267 output_buf
: JSAMPIMAGE
;
268 output_row
: JDIMENSION
;
271 cconvert
: my_cconvert_ptr
;
272 {register} r
, g
, b
: int
;
273 {register} ctab
: INT32_FIELD_PTR
;
274 {register} inptr
: JSAMPROW
;
275 {register} outptr0
, outptr1
, outptr2
, outptr3
: JSAMPROW
;
276 {register} col
: JDIMENSION
;
277 num_cols
: JDIMENSION
;
279 cconvert
:= my_cconvert_ptr (cinfo
^.cconvert
);
280 ctab
:= cconvert
^.rgb_ycc_tab
;
281 num_cols
:= cinfo
^.image_width
;
283 while (num_rows
> 0) do
286 inptr
:= input_buf
^[0];
287 Inc(JSAMPROW_PTR(input_buf
));
288 outptr0
:= output_buf
^[0]^[output_row
];
289 outptr1
:= output_buf
^[1]^[output_row
];
290 outptr2
:= output_buf
^[2]^[output_row
];
291 outptr3
:= output_buf
^[3]^[output_row
];
293 for col
:= 0 to pred(num_cols
) do
295 r
:= MAXJSAMPLE
- GETJSAMPLE(inptr
^[0]);
296 g
:= MAXJSAMPLE
- GETJSAMPLE(inptr
^[1]);
297 b
:= MAXJSAMPLE
- GETJSAMPLE(inptr
^[2]);
298 { K passes through as-is }
299 outptr3
^[col
] := inptr
^[3]; { don't need GETJSAMPLE here }
300 Inc(JSAMPLE_PTR(inptr
), 4);
301 { If the inputs are 0..MAXJSAMPLE, the outputs of these equations
302 must be too; we do not need an explicit range-limiting operation.
303 Hence the value being shifted is never negative, and we don't
304 need the general RIGHT_SHIFT macro. }
307 outptr0
^[col
] := JSAMPLE (
308 ((ctab
^[r
+R_Y_OFF
] + ctab
^[g
+G_Y_OFF
] + ctab
^[b
+B_Y_OFF
])
311 outptr1
^[col
] := JSAMPLE(
312 ((ctab
^[r
+R_CB_OFF
] + ctab
^[g
+G_CB_OFF
] + ctab
^[b
+B_CB_OFF
])
315 outptr2
^[col
] := JSAMPLE (
316 ((ctab
^[r
+R_CR_OFF
] + ctab
^[g
+G_CR_OFF
] + ctab
^[b
+B_CR_OFF
])
323 { Convert some rows of samples to the JPEG colorspace.
324 This version handles grayscale output with no conversion.
325 The source can be either plain grayscale or YCbCr (since Y = gray). }
328 procedure grayscale_convert (cinfo
: j_compress_ptr
;
329 input_buf
: JSAMPARRAY
;
330 output_buf
: JSAMPIMAGE
;
331 output_row
: JDIMENSION
;
334 {register} inptr
: JSAMPROW
;
335 {register} outptr
: JSAMPROW
;
336 {register} col
: JDIMENSION
;
337 num_cols
:JDIMENSION
;
340 num_cols
:= cinfo
^.image_width
;
341 instride
:= cinfo
^.input_components
;
343 while (num_rows
> 0) do
346 inptr
:= input_buf
^[0];
347 Inc(JSAMPROW_PTR(input_buf
));
348 outptr
:= output_buf
^[0]^[output_row
];
350 for col
:= 0 to pred(num_cols
) do
352 outptr
^[col
] := inptr
^[0]; { don't need GETJSAMPLE() here }
353 Inc(JSAMPLE_PTR(inptr
), instride
);
359 { Convert some rows of samples to the JPEG colorspace.
360 This version handles multi-component colorspaces without conversion.
361 We assume input_components = num_components. }
364 procedure null_convert (cinfo
: j_compress_ptr
;
365 input_buf
: JSAMPARRAY
;
366 output_buf
: JSAMPIMAGE
;
367 output_row
: JDIMENSION
;
370 {register} inptr
: JSAMPROW
;
371 {register} outptr
: JSAMPROW
;
372 {register} col
: JDIMENSION
;
375 num_cols
: JDIMENSION
;
377 nc
:= cinfo
^.num_components
;
378 num_cols
:= cinfo
^.image_width
;
380 while (num_rows
> 0) do
383 { It seems fastest to make a separate pass for each component. }
384 for ci
:= 0 to pred(nc
) do
386 inptr
:= input_buf
^[0];
387 outptr
:= output_buf
^[ci
]^[output_row
];
388 for col
:= 0 to pred(num_cols
) do
390 outptr
^[col
] := inptr
^[ci
]; { don't need GETJSAMPLE() here }
391 Inc(JSAMPLE_PTR(inptr
), nc
);
394 Inc(JSAMPROW_PTR(input_buf
));
400 { Empty method for start_pass. }
403 procedure null_method (cinfo
: j_compress_ptr
);
409 { Module initialization routine for input colorspace conversion. }
412 procedure jinit_color_converter (cinfo
: j_compress_ptr
);
414 cconvert
: my_cconvert_ptr
;
416 cconvert
:= my_cconvert_ptr(
417 cinfo
^.mem
^.alloc_small (j_common_ptr(cinfo
), JPOOL_IMAGE
,
418 SIZEOF(my_color_converter
)) );
419 cinfo
^.cconvert
:= jpeg_color_converter_ptr(cconvert
);
420 { set start_pass to null method until we find out differently }
421 cconvert
^.pub
.start_pass
:= null_method
;
423 { Make sure input_components agrees with in_color_space }
424 case (cinfo
^.in_color_space
) of
426 if (cinfo
^.input_components
<> 1) then
427 ERREXIT(j_common_ptr(cinfo
), JERR_BAD_IN_COLORSPACE
);
429 {$ifdef RGB_PIXELSIZE <> 3}
431 if (cinfo
^.input_components
<> RGB_PIXELSIZE
) then
432 ERREXIT(j_common_ptr(cinfo
), JERR_BAD_IN_COLORSPACE
);
433 {$else} { share code with YCbCr }
437 if (cinfo
^.input_components
<> 3) then
438 ERREXIT(j_common_ptr(cinfo
), JERR_BAD_IN_COLORSPACE
);
442 if (cinfo
^.input_components
<> 4) then
443 ERREXIT(j_common_ptr(cinfo
), JERR_BAD_IN_COLORSPACE
);
445 else { JCS_UNKNOWN can be anything }
446 if (cinfo
^.input_components
< 1) then
447 ERREXIT(j_common_ptr(cinfo
), JERR_BAD_IN_COLORSPACE
);
450 { Check num_components, set conversion method based on requested space }
451 case (cinfo
^.jpeg_color_space
) of
454 if (cinfo
^.num_components
<> 1) then
455 ERREXIT(j_common_ptr(cinfo
), JERR_BAD_J_COLORSPACE
);
456 if (cinfo
^.in_color_space
= JCS_GRAYSCALE
) then
457 cconvert
^.pub
.color_convert
:= grayscale_convert
459 if (cinfo
^.in_color_space
= JCS_RGB
) then
461 cconvert
^.pub
.start_pass
:= rgb_ycc_start
;
462 cconvert
^.pub
.color_convert
:= rgb_gray_convert
;
465 if (cinfo
^.in_color_space
= JCS_YCbCr
) then
466 cconvert
^.pub
.color_convert
:= grayscale_convert
468 ERREXIT(j_common_ptr(cinfo
), JERR_CONVERSION_NOTIMPL
);
473 if (cinfo
^.num_components
<> 3) then
474 ERREXIT(j_common_ptr(cinfo
), JERR_BAD_J_COLORSPACE
);
475 if (cinfo
^.in_color_space
= JCS_RGB
) and (RGB_PIXELSIZE
= 3) then
476 cconvert
^.pub
.color_convert
:= null_convert
478 ERREXIT(j_common_ptr(cinfo
), JERR_CONVERSION_NOTIMPL
);
483 if (cinfo
^.num_components
<> 3) then
484 ERREXIT(j_common_ptr(cinfo
), JERR_BAD_J_COLORSPACE
);
485 if (cinfo
^.in_color_space
= JCS_RGB
) then
487 cconvert
^.pub
.start_pass
:= rgb_ycc_start
;
488 cconvert
^.pub
.color_convert
:= rgb_ycc_convert
;
491 if (cinfo
^.in_color_space
= JCS_YCbCr
) then
492 cconvert
^.pub
.color_convert
:= null_convert
494 ERREXIT(j_common_ptr(cinfo
), JERR_CONVERSION_NOTIMPL
);
499 if (cinfo
^.num_components
<> 4) then
500 ERREXIT(j_common_ptr(cinfo
), JERR_BAD_J_COLORSPACE
);
501 if (cinfo
^.in_color_space
= JCS_CMYK
) then
502 cconvert
^.pub
.color_convert
:= null_convert
504 ERREXIT(j_common_ptr(cinfo
), JERR_CONVERSION_NOTIMPL
);
509 if (cinfo
^.num_components
<> 4) then
510 ERREXIT(j_common_ptr(cinfo
), JERR_BAD_J_COLORSPACE
);
511 if (cinfo
^.in_color_space
= JCS_CMYK
) then
513 cconvert
^.pub
.start_pass
:= rgb_ycc_start
;
514 cconvert
^.pub
.color_convert
:= cmyk_ycck_convert
;
517 if (cinfo
^.in_color_space
= JCS_YCCK
) then
518 cconvert
^.pub
.color_convert
:= null_convert
520 ERREXIT(j_common_ptr(cinfo
), JERR_CONVERSION_NOTIMPL
);
523 else { allow null conversion of JCS_UNKNOWN }
525 if (cinfo
^.jpeg_color_space
<> cinfo
^.in_color_space
) or
526 (cinfo
^.num_components
<> cinfo
^.input_components
) then
527 ERREXIT(j_common_ptr(cinfo
), JERR_CONVERSION_NOTIMPL
);
528 cconvert
^.pub
.color_convert
:= null_convert
;