8 * Copyright (C) 1991-1997, Thomas G. Lane.
9 * This file is part of the Independent JPEG Group's software.
10 * For conditions of distribution and use, see the accompanying README file.
12 * This file contains output colorspace conversion routines.
15 #define JPEG_INTERNALS
20 /* Private subobject */
23 struct jpeg_color_deconverter pub
; /* public fields */
25 /* Private state for YCC->RGB conversion */
26 int * Cr_r_tab
; /* => table for Cr to R conversion */
27 int * Cb_b_tab
; /* => table for Cb to B conversion */
28 INT32
* Cr_g_tab
; /* => table for Cr to G conversion */
29 INT32
* Cb_g_tab
; /* => table for Cb to G conversion */
30 } my_color_deconverter
;
32 typedef my_color_deconverter
* my_cconvert_ptr
;
35 /**************** YCbCr -> RGB conversion: most common case **************/
38 * YCbCr is defined per CCIR 601-1, except that Cb and Cr are
39 * normalized to the range 0..MAXJSAMPLE rather than -0.5 .. 0.5.
40 * The conversion equations to be implemented are therefore
41 * R = Y + 1.40200 * Cr
42 * G = Y - 0.34414 * Cb - 0.71414 * Cr
43 * B = Y + 1.77200 * Cb
44 * where Cb and Cr represent the incoming values less CENTERJSAMPLE.
45 * (These numbers are derived from TIFF 6.0 section 21, dated 3-June-92.)
47 * To avoid floating-point arithmetic, we represent the fractional constants
48 * as integers scaled up by 2^16 (about 4 digits precision); we have to divide
49 * the products by 2^16, with appropriate rounding, to get the correct answer.
50 * Notice that Y, being an integral input, does not contribute any fraction
51 * so it need not participate in the rounding.
53 * For even more speed, we avoid doing any multiplications in the inner loop
54 * by precalculating the constants times Cb and Cr for all possible values.
55 * For 8-bit JSAMPLEs this is very reasonable (only 256 entries per table);
56 * for 12-bit samples it is still acceptable. It's not very reasonable for
57 * 16-bit samples, but if you want lossless storage you shouldn't be changing
59 * The Cr=>R and Cb=>B values can be rounded to integers in advance; the
60 * values for the G calculation are left scaled up, since we must add them
61 * together before rounding.
64 #define SCALEBITS 16 /* speediest right-shift on some machines */
65 #define ONE_HALF ((INT32) 1 << (SCALEBITS-1))
66 #define FIX(x) ((INT32) ((x) * (1L<<SCALEBITS) + 0.5))
70 * Initialize tables for YCC->RGB colorspace conversion.
74 build_ycc_rgb_table (j_decompress_ptr cinfo
)
76 my_cconvert_ptr cconvert
= (my_cconvert_ptr
) cinfo
->cconvert
;
81 cconvert
->Cr_r_tab
= (int *)
82 (*cinfo
->mem
->alloc_small
) ((j_common_ptr
) cinfo
, JPOOL_IMAGE
,
83 (MAXJSAMPLE
+1) * SIZEOF(int));
84 cconvert
->Cb_b_tab
= (int *)
85 (*cinfo
->mem
->alloc_small
) ((j_common_ptr
) cinfo
, JPOOL_IMAGE
,
86 (MAXJSAMPLE
+1) * SIZEOF(int));
87 cconvert
->Cr_g_tab
= (INT32
*)
88 (*cinfo
->mem
->alloc_small
) ((j_common_ptr
) cinfo
, JPOOL_IMAGE
,
89 (MAXJSAMPLE
+1) * SIZEOF(INT32
));
90 cconvert
->Cb_g_tab
= (INT32
*)
91 (*cinfo
->mem
->alloc_small
) ((j_common_ptr
) cinfo
, JPOOL_IMAGE
,
92 (MAXJSAMPLE
+1) * SIZEOF(INT32
));
94 for (i
= 0, x
= -CENTERJSAMPLE
; i
<= MAXJSAMPLE
; i
++, x
++) {
95 /* i is the actual input pixel value, in the range 0..MAXJSAMPLE */
96 /* The Cb or Cr value we are thinking of is x = i - CENTERJSAMPLE */
97 /* Cr=>R value is nearest int to 1.40200 * x */
98 cconvert
->Cr_r_tab
[i
] = (int)
99 RIGHT_SHIFT(FIX(1.40200) * x
+ ONE_HALF
, SCALEBITS
);
100 /* Cb=>B value is nearest int to 1.77200 * x */
101 cconvert
->Cb_b_tab
[i
] = (int)
102 RIGHT_SHIFT(FIX(1.77200) * x
+ ONE_HALF
, SCALEBITS
);
103 /* Cr=>G value is scaled-up -0.71414 * x */
104 cconvert
->Cr_g_tab
[i
] = (- FIX(0.71414)) * x
;
105 /* Cb=>G value is scaled-up -0.34414 * x */
106 /* We also add in ONE_HALF so that need not do it in inner loop */
107 cconvert
->Cb_g_tab
[i
] = (- FIX(0.34414)) * x
+ ONE_HALF
;
113 * Convert some rows of samples to the output colorspace.
115 * Note that we change from noninterleaved, one-plane-per-component format
116 * to interleaved-pixel format. The output buffer is therefore three times
117 * as wide as the input buffer.
118 * A starting row offset is provided only for the input buffer. The caller
119 * can easily adjust the passed output_buf value to accommodate any row
120 * offset required on that side.
124 ycc_rgb_convert (j_decompress_ptr cinfo
,
125 JSAMPIMAGE input_buf
, JDIMENSION input_row
,
126 JSAMPARRAY output_buf
, int num_rows
)
128 my_cconvert_ptr cconvert
= (my_cconvert_ptr
) cinfo
->cconvert
;
129 register int y
, cb
, cr
;
130 register JSAMPROW outptr
;
131 register JSAMPROW inptr0
, inptr1
, inptr2
;
132 register JDIMENSION col
;
133 JDIMENSION num_cols
= cinfo
->output_width
;
134 /* copy these pointers into registers if possible */
135 register JSAMPLE
* range_limit
= cinfo
->sample_range_limit
;
136 register int * Crrtab
= cconvert
->Cr_r_tab
;
137 register int * Cbbtab
= cconvert
->Cb_b_tab
;
138 register INT32
* Crgtab
= cconvert
->Cr_g_tab
;
139 register INT32
* Cbgtab
= cconvert
->Cb_g_tab
;
142 while (--num_rows
>= 0) {
143 inptr0
= input_buf
[0][input_row
];
144 inptr1
= input_buf
[1][input_row
];
145 inptr2
= input_buf
[2][input_row
];
147 outptr
= *output_buf
++;
148 for (col
= 0; col
< num_cols
; col
++) {
149 y
= GETJSAMPLE(inptr0
[col
]);
150 cb
= GETJSAMPLE(inptr1
[col
]);
151 cr
= GETJSAMPLE(inptr2
[col
]);
152 /* Range-limiting is essential due to noise introduced by DCT losses. */
153 outptr
[RGB_RED
] = range_limit
[y
+ Crrtab
[cr
]];
154 outptr
[RGB_GREEN
] = range_limit
[y
+
155 ((int) RIGHT_SHIFT(Cbgtab
[cb
] + Crgtab
[cr
],
157 outptr
[RGB_BLUE
] = range_limit
[y
+ Cbbtab
[cb
]];
158 outptr
+= RGB_PIXELSIZE
;
164 /**************** Cases other than YCbCr -> RGB **************/
168 * Color conversion for no colorspace change: just copy the data,
169 * converting from separate-planes to interleaved representation.
173 null_convert (j_decompress_ptr cinfo
,
174 JSAMPIMAGE input_buf
, JDIMENSION input_row
,
175 JSAMPARRAY output_buf
, int num_rows
)
177 register JSAMPROW inptr
, outptr
;
178 register JDIMENSION count
;
179 register int num_components
= cinfo
->num_components
;
180 JDIMENSION num_cols
= cinfo
->output_width
;
183 while (--num_rows
>= 0) {
184 for (ci
= 0; ci
< num_components
; ci
++) {
185 inptr
= input_buf
[ci
][input_row
];
186 outptr
= output_buf
[0] + ci
;
187 for (count
= num_cols
; count
> 0; count
--) {
188 *outptr
= *inptr
++; /* needn't bother with GETJSAMPLE() here */
189 outptr
+= num_components
;
199 * Color conversion for grayscale: just copy the data.
200 * This also works for YCbCr -> grayscale conversion, in which
201 * we just copy the Y (luminance) component and ignore chrominance.
205 grayscale_convert (j_decompress_ptr cinfo
,
206 JSAMPIMAGE input_buf
, JDIMENSION input_row
,
207 JSAMPARRAY output_buf
, int num_rows
)
209 jcopy_sample_rows(input_buf
[0], (int) input_row
, output_buf
, 0,
210 num_rows
, cinfo
->output_width
);
215 * Convert grayscale to RGB: just duplicate the graylevel three times.
216 * This is provided to support applications that don't want to cope
217 * with grayscale as a separate case.
221 gray_rgb_convert (j_decompress_ptr cinfo
,
222 JSAMPIMAGE input_buf
, JDIMENSION input_row
,
223 JSAMPARRAY output_buf
, int num_rows
)
225 register JSAMPROW inptr
, outptr
;
226 register JDIMENSION col
;
227 JDIMENSION num_cols
= cinfo
->output_width
;
229 while (--num_rows
>= 0) {
230 inptr
= input_buf
[0][input_row
++];
231 outptr
= *output_buf
++;
232 for (col
= 0; col
< num_cols
; col
++) {
233 /* We can dispense with GETJSAMPLE() here */
234 outptr
[RGB_RED
] = outptr
[RGB_GREEN
] = outptr
[RGB_BLUE
] = inptr
[col
];
235 outptr
+= RGB_PIXELSIZE
;
242 * Adobe-style YCCK->CMYK conversion.
243 * We convert YCbCr to R=1-C, G=1-M, and B=1-Y using the same
244 * conversion as above, while passing K (black) unchanged.
245 * We assume build_ycc_rgb_table has been called.
249 ycck_cmyk_convert (j_decompress_ptr cinfo
,
250 JSAMPIMAGE input_buf
, JDIMENSION input_row
,
251 JSAMPARRAY output_buf
, int num_rows
)
253 my_cconvert_ptr cconvert
= (my_cconvert_ptr
) cinfo
->cconvert
;
254 register int y
, cb
, cr
;
255 register JSAMPROW outptr
;
256 register JSAMPROW inptr0
, inptr1
, inptr2
, inptr3
;
257 register JDIMENSION col
;
258 JDIMENSION num_cols
= cinfo
->output_width
;
259 /* copy these pointers into registers if possible */
260 register JSAMPLE
* range_limit
= cinfo
->sample_range_limit
;
261 register int * Crrtab
= cconvert
->Cr_r_tab
;
262 register int * Cbbtab
= cconvert
->Cb_b_tab
;
263 register INT32
* Crgtab
= cconvert
->Cr_g_tab
;
264 register INT32
* Cbgtab
= cconvert
->Cb_g_tab
;
267 while (--num_rows
>= 0) {
268 inptr0
= input_buf
[0][input_row
];
269 inptr1
= input_buf
[1][input_row
];
270 inptr2
= input_buf
[2][input_row
];
271 inptr3
= input_buf
[3][input_row
];
273 outptr
= *output_buf
++;
274 for (col
= 0; col
< num_cols
; col
++) {
275 y
= GETJSAMPLE(inptr0
[col
]);
276 cb
= GETJSAMPLE(inptr1
[col
]);
277 cr
= GETJSAMPLE(inptr2
[col
]);
278 /* Range-limiting is essential due to noise introduced by DCT losses. */
279 outptr
[0] = range_limit
[MAXJSAMPLE
- (y
+ Crrtab
[cr
])]; /* red */
280 outptr
[1] = range_limit
[MAXJSAMPLE
- (y
+ /* green */
281 ((int) RIGHT_SHIFT(Cbgtab
[cb
] + Crgtab
[cr
],
283 outptr
[2] = range_limit
[MAXJSAMPLE
- (y
+ Cbbtab
[cb
])]; /* blue */
284 /* K passes through unchanged */
285 outptr
[3] = inptr3
[col
]; /* don't need GETJSAMPLE here */
293 * Empty method for start_pass.
297 start_pass_dcolor (j_decompress_ptr cinfo
)
304 * Module initialization routine for output colorspace conversion.
308 jinit_color_deconverter (j_decompress_ptr cinfo
)
310 my_cconvert_ptr cconvert
;
313 cconvert
= (my_cconvert_ptr
)
314 (*cinfo
->mem
->alloc_small
) ((j_common_ptr
) cinfo
, JPOOL_IMAGE
,
315 SIZEOF(my_color_deconverter
));
316 cinfo
->cconvert
= (struct jpeg_color_deconverter
*) cconvert
;
317 cconvert
->pub
.start_pass
= start_pass_dcolor
;
319 /* Make sure num_components agrees with jpeg_color_space */
320 switch (cinfo
->jpeg_color_space
) {
322 if (cinfo
->num_components
!= 1)
323 ERREXIT(cinfo
, JERR_BAD_J_COLORSPACE
);
328 if (cinfo
->num_components
!= 3)
329 ERREXIT(cinfo
, JERR_BAD_J_COLORSPACE
);
334 if (cinfo
->num_components
!= 4)
335 ERREXIT(cinfo
, JERR_BAD_J_COLORSPACE
);
338 default: /* JCS_UNKNOWN can be anything */
339 if (cinfo
->num_components
< 1)
340 ERREXIT(cinfo
, JERR_BAD_J_COLORSPACE
);
344 /* Set out_color_components and conversion method based on requested space.
345 * Also clear the component_needed flags for any unused components,
346 * so that earlier pipeline stages can avoid useless computation.
349 switch (cinfo
->out_color_space
) {
351 cinfo
->out_color_components
= 1;
352 if (cinfo
->jpeg_color_space
== JCS_GRAYSCALE
||
353 cinfo
->jpeg_color_space
== JCS_YCbCr
) {
354 cconvert
->pub
.color_convert
= grayscale_convert
;
355 /* For color->grayscale conversion, only the Y (0) component is needed */
356 for (ci
= 1; ci
< cinfo
->num_components
; ci
++)
357 cinfo
->comp_info
[ci
].component_needed
= FALSE
;
359 ERREXIT(cinfo
, JERR_CONVERSION_NOTIMPL
);
363 cinfo
->out_color_components
= RGB_PIXELSIZE
;
364 if (cinfo
->jpeg_color_space
== JCS_YCbCr
) {
365 cconvert
->pub
.color_convert
= ycc_rgb_convert
;
366 build_ycc_rgb_table(cinfo
);
367 } else if (cinfo
->jpeg_color_space
== JCS_GRAYSCALE
) {
368 cconvert
->pub
.color_convert
= gray_rgb_convert
;
369 } else if (cinfo
->jpeg_color_space
== JCS_RGB
&& RGB_PIXELSIZE
== 3) {
370 cconvert
->pub
.color_convert
= null_convert
;
372 ERREXIT(cinfo
, JERR_CONVERSION_NOTIMPL
);
376 cinfo
->out_color_components
= 4;
377 if (cinfo
->jpeg_color_space
== JCS_YCCK
) {
378 cconvert
->pub
.color_convert
= ycck_cmyk_convert
;
379 build_ycc_rgb_table(cinfo
);
380 } else if (cinfo
->jpeg_color_space
== JCS_CMYK
) {
381 cconvert
->pub
.color_convert
= null_convert
;
383 ERREXIT(cinfo
, JERR_CONVERSION_NOTIMPL
);
387 /* Permit null conversion to same output space */
388 if (cinfo
->out_color_space
== cinfo
->jpeg_color_space
) {
389 cinfo
->out_color_components
= cinfo
->num_components
;
390 cconvert
->pub
.color_convert
= null_convert
;
391 } else /* unsupported non-null conversion */
392 ERREXIT(cinfo
, JERR_CONVERSION_NOTIMPL
);
396 if (cinfo
->quantize_colors
)
397 cinfo
->output_components
= 1; /* single colormapped output component */
399 cinfo
->output_components
= cinfo
->out_color_components
;