4 * Copyright (C) 1991-1997, Thomas G. Lane.
5 * Copyright 2009 Pierre Ossman <ossman@cendio.se> for Cendio AB
6 * Copyright (C) 2009, D. R. Commander.
7 * This file is part of the Independent JPEG Group's software.
8 * For conditions of distribution and use, see the accompanying README file.
10 * This file contains output colorspace conversion routines.
13 #define JPEG_INTERNALS
19 /* Private subobject */
22 struct jpeg_color_deconverter pub
; /* public fields */
24 /* Private state for YCC->RGB conversion */
25 int * Cr_r_tab
; /* => table for Cr to R conversion */
26 int * Cb_b_tab
; /* => table for Cb to B conversion */
27 INT32
* Cr_g_tab
; /* => table for Cr to G conversion */
28 INT32
* Cb_g_tab
; /* => table for Cb to G conversion */
29 } my_color_deconverter
;
31 typedef my_color_deconverter
* my_cconvert_ptr
;
34 /**************** YCbCr -> RGB conversion: most common case **************/
37 * YCbCr is defined per CCIR 601-1, except that Cb and Cr are
38 * normalized to the range 0..MAXJSAMPLE rather than -0.5 .. 0.5.
39 * The conversion equations to be implemented are therefore
40 * R = Y + 1.40200 * Cr
41 * G = Y - 0.34414 * Cb - 0.71414 * Cr
42 * B = Y + 1.77200 * Cb
43 * where Cb and Cr represent the incoming values less CENTERJSAMPLE.
44 * (These numbers are derived from TIFF 6.0 section 21, dated 3-June-92.)
46 * To avoid floating-point arithmetic, we represent the fractional constants
47 * as integers scaled up by 2^16 (about 4 digits precision); we have to divide
48 * the products by 2^16, with appropriate rounding, to get the correct answer.
49 * Notice that Y, being an integral input, does not contribute any fraction
50 * so it need not participate in the rounding.
52 * For even more speed, we avoid doing any multiplications in the inner loop
53 * by precalculating the constants times Cb and Cr for all possible values.
54 * For 8-bit JSAMPLEs this is very reasonable (only 256 entries per table);
55 * for 12-bit samples it is still acceptable. It's not very reasonable for
56 * 16-bit samples, but if you want lossless storage you shouldn't be changing
58 * The Cr=>R and Cb=>B values can be rounded to integers in advance; the
59 * values for the G calculation are left scaled up, since we must add them
60 * together before rounding.
63 #define SCALEBITS 16 /* speediest right-shift on some machines */
64 #define ONE_HALF ((INT32) 1 << (SCALEBITS-1))
65 #define FIX(x) ((INT32) ((x) * (1L<<SCALEBITS) + 0.5))
69 * Initialize tables for YCC->RGB colorspace conversion.
73 build_ycc_rgb_table (j_decompress_ptr cinfo
)
75 my_cconvert_ptr cconvert
= (my_cconvert_ptr
) cinfo
->cconvert
;
80 cconvert
->Cr_r_tab
= (int *)
81 (*cinfo
->mem
->alloc_small
) ((j_common_ptr
) cinfo
, JPOOL_IMAGE
,
82 (MAXJSAMPLE
+1) * SIZEOF(int));
83 cconvert
->Cb_b_tab
= (int *)
84 (*cinfo
->mem
->alloc_small
) ((j_common_ptr
) cinfo
, JPOOL_IMAGE
,
85 (MAXJSAMPLE
+1) * SIZEOF(int));
86 cconvert
->Cr_g_tab
= (INT32
*)
87 (*cinfo
->mem
->alloc_small
) ((j_common_ptr
) cinfo
, JPOOL_IMAGE
,
88 (MAXJSAMPLE
+1) * SIZEOF(INT32
));
89 cconvert
->Cb_g_tab
= (INT32
*)
90 (*cinfo
->mem
->alloc_small
) ((j_common_ptr
) cinfo
, JPOOL_IMAGE
,
91 (MAXJSAMPLE
+1) * SIZEOF(INT32
));
93 for (i
= 0, x
= -CENTERJSAMPLE
; i
<= MAXJSAMPLE
; i
++, x
++) {
94 /* i is the actual input pixel value, in the range 0..MAXJSAMPLE */
95 /* The Cb or Cr value we are thinking of is x = i - CENTERJSAMPLE */
96 /* Cr=>R value is nearest int to 1.40200 * x */
97 cconvert
->Cr_r_tab
[i
] = (int)
98 RIGHT_SHIFT(FIX(1.40200) * x
+ ONE_HALF
, SCALEBITS
);
99 /* Cb=>B value is nearest int to 1.77200 * x */
100 cconvert
->Cb_b_tab
[i
] = (int)
101 RIGHT_SHIFT(FIX(1.77200) * x
+ ONE_HALF
, SCALEBITS
);
102 /* Cr=>G value is scaled-up -0.71414 * x */
103 cconvert
->Cr_g_tab
[i
] = (- FIX(0.71414)) * x
;
104 /* Cb=>G value is scaled-up -0.34414 * x */
105 /* We also add in ONE_HALF so that need not do it in inner loop */
106 cconvert
->Cb_g_tab
[i
] = (- FIX(0.34414)) * x
+ ONE_HALF
;
112 * Convert some rows of samples to the output colorspace.
114 * Note that we change from noninterleaved, one-plane-per-component format
115 * to interleaved-pixel format. The output buffer is therefore three times
116 * as wide as the input buffer.
117 * A starting row offset is provided only for the input buffer. The caller
118 * can easily adjust the passed output_buf value to accommodate any row
119 * offset required on that side.
123 ycc_rgb_convert (j_decompress_ptr cinfo
,
124 JSAMPIMAGE input_buf
, JDIMENSION input_row
,
125 JSAMPARRAY output_buf
, int num_rows
)
127 my_cconvert_ptr cconvert
= (my_cconvert_ptr
) cinfo
->cconvert
;
128 register int y
, cb
, cr
;
129 register JSAMPROW outptr
;
130 register JSAMPROW inptr0
, inptr1
, inptr2
;
131 register JDIMENSION col
;
132 JDIMENSION num_cols
= cinfo
->output_width
;
133 /* copy these pointers into registers if possible */
134 register JSAMPLE
* range_limit
= cinfo
->sample_range_limit
;
135 register int * Crrtab
= cconvert
->Cr_r_tab
;
136 register int * Cbbtab
= cconvert
->Cb_b_tab
;
137 register INT32
* Crgtab
= cconvert
->Cr_g_tab
;
138 register INT32
* Cbgtab
= cconvert
->Cb_g_tab
;
141 while (--num_rows
>= 0) {
142 inptr0
= input_buf
[0][input_row
];
143 inptr1
= input_buf
[1][input_row
];
144 inptr2
= input_buf
[2][input_row
];
146 outptr
= *output_buf
++;
147 for (col
= 0; col
< num_cols
; col
++) {
148 y
= GETJSAMPLE(inptr0
[col
]);
149 cb
= GETJSAMPLE(inptr1
[col
]);
150 cr
= GETJSAMPLE(inptr2
[col
]);
151 /* Range-limiting is essential due to noise introduced by DCT losses. */
152 outptr
[rgb_red
[cinfo
->out_color_space
]] = range_limit
[y
+ Crrtab
[cr
]];
153 outptr
[rgb_green
[cinfo
->out_color_space
]] = range_limit
[y
+
154 ((int) RIGHT_SHIFT(Cbgtab
[cb
] + Crgtab
[cr
],
156 outptr
[rgb_blue
[cinfo
->out_color_space
]] = range_limit
[y
+ Cbbtab
[cb
]];
157 outptr
+= rgb_pixelsize
[cinfo
->out_color_space
];
163 /**************** Cases other than YCbCr -> RGB **************/
167 * Color conversion for no colorspace change: just copy the data,
168 * converting from separate-planes to interleaved representation.
172 null_convert (j_decompress_ptr cinfo
,
173 JSAMPIMAGE input_buf
, JDIMENSION input_row
,
174 JSAMPARRAY output_buf
, int num_rows
)
176 register JSAMPROW inptr
, outptr
;
177 register JDIMENSION count
;
178 register int num_components
= cinfo
->num_components
;
179 JDIMENSION num_cols
= cinfo
->output_width
;
182 while (--num_rows
>= 0) {
183 for (ci
= 0; ci
< num_components
; ci
++) {
184 inptr
= input_buf
[ci
][input_row
];
185 outptr
= output_buf
[0] + ci
;
186 for (count
= num_cols
; count
> 0; count
--) {
187 *outptr
= *inptr
++; /* needn't bother with GETJSAMPLE() here */
188 outptr
+= num_components
;
198 * Color conversion for grayscale: just copy the data.
199 * This also works for YCbCr -> grayscale conversion, in which
200 * we just copy the Y (luminance) component and ignore chrominance.
204 grayscale_convert (j_decompress_ptr cinfo
,
205 JSAMPIMAGE input_buf
, JDIMENSION input_row
,
206 JSAMPARRAY output_buf
, int num_rows
)
208 jcopy_sample_rows(input_buf
[0], (int) input_row
, output_buf
, 0,
209 num_rows
, cinfo
->output_width
);
214 * Convert grayscale to RGB: just duplicate the graylevel three times.
215 * This is provided to support applications that don't want to cope
216 * with grayscale as a separate case.
220 gray_rgb_convert (j_decompress_ptr cinfo
,
221 JSAMPIMAGE input_buf
, JDIMENSION input_row
,
222 JSAMPARRAY output_buf
, int num_rows
)
224 register JSAMPROW inptr
, outptr
;
226 JDIMENSION num_cols
= cinfo
->output_width
;
227 int rindex
= rgb_red
[cinfo
->out_color_space
];
228 int gindex
= rgb_green
[cinfo
->out_color_space
];
229 int bindex
= rgb_blue
[cinfo
->out_color_space
];
230 int rgbstride
= rgb_pixelsize
[cinfo
->out_color_space
];
232 while (--num_rows
>= 0) {
233 inptr
= input_buf
[0][input_row
++];
234 maxinptr
= &inptr
[num_cols
];
235 outptr
= *output_buf
++;
236 for (; inptr
< maxinptr
; inptr
++, outptr
+= rgbstride
) {
237 /* We can dispense with GETJSAMPLE() here */
238 outptr
[rindex
] = outptr
[gindex
] = outptr
[bindex
] = *inptr
;
245 * Adobe-style YCCK->CMYK conversion.
246 * We convert YCbCr to R=1-C, G=1-M, and B=1-Y using the same
247 * conversion as above, while passing K (black) unchanged.
248 * We assume build_ycc_rgb_table has been called.
252 ycck_cmyk_convert (j_decompress_ptr cinfo
,
253 JSAMPIMAGE input_buf
, JDIMENSION input_row
,
254 JSAMPARRAY output_buf
, int num_rows
)
256 my_cconvert_ptr cconvert
= (my_cconvert_ptr
) cinfo
->cconvert
;
257 register int y
, cb
, cr
;
258 register JSAMPROW outptr
;
259 register JSAMPROW inptr0
, inptr1
, inptr2
, inptr3
;
260 register JDIMENSION col
;
261 JDIMENSION num_cols
= cinfo
->output_width
;
262 /* copy these pointers into registers if possible */
263 register JSAMPLE
* range_limit
= cinfo
->sample_range_limit
;
264 register int * Crrtab
= cconvert
->Cr_r_tab
;
265 register int * Cbbtab
= cconvert
->Cb_b_tab
;
266 register INT32
* Crgtab
= cconvert
->Cr_g_tab
;
267 register INT32
* Cbgtab
= cconvert
->Cb_g_tab
;
270 while (--num_rows
>= 0) {
271 inptr0
= input_buf
[0][input_row
];
272 inptr1
= input_buf
[1][input_row
];
273 inptr2
= input_buf
[2][input_row
];
274 inptr3
= input_buf
[3][input_row
];
276 outptr
= *output_buf
++;
277 for (col
= 0; col
< num_cols
; col
++) {
278 y
= GETJSAMPLE(inptr0
[col
]);
279 cb
= GETJSAMPLE(inptr1
[col
]);
280 cr
= GETJSAMPLE(inptr2
[col
]);
281 /* Range-limiting is essential due to noise introduced by DCT losses. */
282 outptr
[0] = range_limit
[MAXJSAMPLE
- (y
+ Crrtab
[cr
])]; /* red */
283 outptr
[1] = range_limit
[MAXJSAMPLE
- (y
+ /* green */
284 ((int) RIGHT_SHIFT(Cbgtab
[cb
] + Crgtab
[cr
],
286 outptr
[2] = range_limit
[MAXJSAMPLE
- (y
+ Cbbtab
[cb
])]; /* blue */
287 /* K passes through unchanged */
288 outptr
[3] = inptr3
[col
]; /* don't need GETJSAMPLE here */
296 * Empty method for start_pass.
300 start_pass_dcolor (j_decompress_ptr cinfo
)
307 * Module initialization routine for output colorspace conversion.
311 jinit_color_deconverter (j_decompress_ptr cinfo
)
313 my_cconvert_ptr cconvert
;
316 cconvert
= (my_cconvert_ptr
)
317 (*cinfo
->mem
->alloc_small
) ((j_common_ptr
) cinfo
, JPOOL_IMAGE
,
318 SIZEOF(my_color_deconverter
));
319 cinfo
->cconvert
= (struct jpeg_color_deconverter
*) cconvert
;
320 cconvert
->pub
.start_pass
= start_pass_dcolor
;
322 /* Make sure num_components agrees with jpeg_color_space */
323 switch (cinfo
->jpeg_color_space
) {
325 if (cinfo
->num_components
!= 1)
326 ERREXIT(cinfo
, JERR_BAD_J_COLORSPACE
);
331 if (cinfo
->num_components
!= 3)
332 ERREXIT(cinfo
, JERR_BAD_J_COLORSPACE
);
337 if (cinfo
->num_components
!= 4)
338 ERREXIT(cinfo
, JERR_BAD_J_COLORSPACE
);
341 default: /* JCS_UNKNOWN can be anything */
342 if (cinfo
->num_components
< 1)
343 ERREXIT(cinfo
, JERR_BAD_J_COLORSPACE
);
347 /* Set out_color_components and conversion method based on requested space.
348 * Also clear the component_needed flags for any unused components,
349 * so that earlier pipeline stages can avoid useless computation.
352 switch (cinfo
->out_color_space
) {
354 cinfo
->out_color_components
= 1;
355 if (cinfo
->jpeg_color_space
== JCS_GRAYSCALE
||
356 cinfo
->jpeg_color_space
== JCS_YCbCr
) {
357 cconvert
->pub
.color_convert
= grayscale_convert
;
358 /* For color->grayscale conversion, only the Y (0) component is needed */
359 for (ci
= 1; ci
< cinfo
->num_components
; ci
++)
360 cinfo
->comp_info
[ci
].component_needed
= FALSE
;
362 ERREXIT(cinfo
, JERR_CONVERSION_NOTIMPL
);
372 cinfo
->out_color_components
= rgb_pixelsize
[cinfo
->out_color_space
];
373 if (cinfo
->jpeg_color_space
== JCS_YCbCr
) {
374 if (jsimd_can_ycc_rgb())
375 cconvert
->pub
.color_convert
= jsimd_ycc_rgb_convert
;
377 cconvert
->pub
.color_convert
= ycc_rgb_convert
;
378 build_ycc_rgb_table(cinfo
);
380 } else if (cinfo
->jpeg_color_space
== JCS_GRAYSCALE
) {
381 cconvert
->pub
.color_convert
= gray_rgb_convert
;
382 } else if (cinfo
->jpeg_color_space
== cinfo
->out_color_space
&&
383 rgb_pixelsize
[cinfo
->out_color_space
] == 3) {
384 cconvert
->pub
.color_convert
= null_convert
;
386 ERREXIT(cinfo
, JERR_CONVERSION_NOTIMPL
);
390 cinfo
->out_color_components
= 4;
391 if (cinfo
->jpeg_color_space
== JCS_YCCK
) {
392 cconvert
->pub
.color_convert
= ycck_cmyk_convert
;
393 build_ycc_rgb_table(cinfo
);
394 } else if (cinfo
->jpeg_color_space
== JCS_CMYK
) {
395 cconvert
->pub
.color_convert
= null_convert
;
397 ERREXIT(cinfo
, JERR_CONVERSION_NOTIMPL
);
401 /* Permit null conversion to same output space */
402 if (cinfo
->out_color_space
== cinfo
->jpeg_color_space
) {
403 cinfo
->out_color_components
= cinfo
->num_components
;
404 cconvert
->pub
.color_convert
= null_convert
;
405 } else /* unsupported non-null conversion */
406 ERREXIT(cinfo
, JERR_CONVERSION_NOTIMPL
);
410 if (cinfo
->quantize_colors
)
411 cinfo
->output_components
= 1; /* single colormapped output component */
413 cinfo
->output_components
= cinfo
->out_color_components
;