blob: e1dd3ff5bda17356bb3f8f0f0552db3fe833c4f5 [file] [log] [blame]
Thomas G. Lane2cbeb8a1991-10-07 00:00:00 +00001/*
2 * jdcolor.c
3 *
Thomas G. Lane5ead57a1998-03-27 00:00:00 +00004 * Copyright (C) 1991-1997, Thomas G. Lane.
Pierre Ossman59a39382009-03-09 13:15:56 +00005 * Copyright 2009 Pierre Ossman <ossman@cendio.se> for Cendio AB
Thomas G. Lane2cbeb8a1991-10-07 00:00:00 +00006 * This file is part of the Independent JPEG Group's software.
7 * For conditions of distribution and use, see the accompanying README file.
8 *
9 * This file contains output colorspace conversion routines.
Thomas G. Lane2cbeb8a1991-10-07 00:00:00 +000010 */
11
Thomas G. Lane36a4ccc1994-09-24 00:00:00 +000012#define JPEG_INTERNALS
Thomas G. Lane2cbeb8a1991-10-07 00:00:00 +000013#include "jinclude.h"
Thomas G. Lane36a4ccc1994-09-24 00:00:00 +000014#include "jpeglib.h"
Pierre Ossman59a39382009-03-09 13:15:56 +000015#include "jsimd.h"
Thomas G. Lane36a4ccc1994-09-24 00:00:00 +000016
17
18/* Private subobject */
19
20typedef struct {
21 struct jpeg_color_deconverter pub; /* public fields */
22
23 /* Private state for YCC->RGB conversion */
24 int * Cr_r_tab; /* => table for Cr to R conversion */
25 int * Cb_b_tab; /* => table for Cb to B conversion */
26 INT32 * Cr_g_tab; /* => table for Cr to G conversion */
27 INT32 * Cb_g_tab; /* => table for Cb to G conversion */
28} my_color_deconverter;
29
30typedef my_color_deconverter * my_cconvert_ptr;
Thomas G. Lane2cbeb8a1991-10-07 00:00:00 +000031
32
Thomas G. Lane4a6b7301992-03-17 00:00:00 +000033/**************** YCbCr -> RGB conversion: most common case **************/
34
35/*
36 * YCbCr is defined per CCIR 601-1, except that Cb and Cr are
37 * normalized to the range 0..MAXJSAMPLE rather than -0.5 .. 0.5.
38 * The conversion equations to be implemented are therefore
39 * R = Y + 1.40200 * Cr
40 * G = Y - 0.34414 * Cb - 0.71414 * Cr
41 * B = Y + 1.77200 * Cb
Thomas G. Lane9ba2f5e1994-12-07 00:00:00 +000042 * where Cb and Cr represent the incoming values less CENTERJSAMPLE.
Thomas G. Lane88aeed41992-12-10 00:00:00 +000043 * (These numbers are derived from TIFF 6.0 section 21, dated 3-June-92.)
Thomas G. Lane4a6b7301992-03-17 00:00:00 +000044 *
45 * To avoid floating-point arithmetic, we represent the fractional constants
Thomas G. Lane88aeed41992-12-10 00:00:00 +000046 * as integers scaled up by 2^16 (about 4 digits precision); we have to divide
47 * the products by 2^16, with appropriate rounding, to get the correct answer.
Thomas G. Lane4a6b7301992-03-17 00:00:00 +000048 * Notice that Y, being an integral input, does not contribute any fraction
49 * so it need not participate in the rounding.
50 *
51 * For even more speed, we avoid doing any multiplications in the inner loop
52 * by precalculating the constants times Cb and Cr for all possible values.
Thomas G. Lane88aeed41992-12-10 00:00:00 +000053 * For 8-bit JSAMPLEs this is very reasonable (only 256 entries per table);
54 * for 12-bit samples it is still acceptable. It's not very reasonable for
55 * 16-bit samples, but if you want lossless storage you shouldn't be changing
Thomas G. Lane4a6b7301992-03-17 00:00:00 +000056 * colorspace anyway.
57 * The Cr=>R and Cb=>B values can be rounded to integers in advance; the
58 * values for the G calculation are left scaled up, since we must add them
59 * together before rounding.
60 */
61
Thomas G. Lane36a4ccc1994-09-24 00:00:00 +000062#define SCALEBITS 16 /* speediest right-shift on some machines */
Thomas G. Lane4a6b7301992-03-17 00:00:00 +000063#define ONE_HALF ((INT32) 1 << (SCALEBITS-1))
64#define FIX(x) ((INT32) ((x) * (1L<<SCALEBITS) + 0.5))
65
Thomas G. Lane4a6b7301992-03-17 00:00:00 +000066
Thomas G. Lane2cbeb8a1991-10-07 00:00:00 +000067/*
Thomas G. Lanebc79e061995-08-02 00:00:00 +000068 * Initialize tables for YCC->RGB colorspace conversion.
Thomas G. Lane2cbeb8a1991-10-07 00:00:00 +000069 */
70
Thomas G. Lane489583f1996-02-07 00:00:00 +000071LOCAL(void)
Thomas G. Lanebc79e061995-08-02 00:00:00 +000072build_ycc_rgb_table (j_decompress_ptr cinfo)
Thomas G. Lane2cbeb8a1991-10-07 00:00:00 +000073{
Thomas G. Lane36a4ccc1994-09-24 00:00:00 +000074 my_cconvert_ptr cconvert = (my_cconvert_ptr) cinfo->cconvert;
Thomas G. Lanebc79e061995-08-02 00:00:00 +000075 int i;
76 INT32 x;
Thomas G. Lane4a6b7301992-03-17 00:00:00 +000077 SHIFT_TEMPS
78
Thomas G. Lane36a4ccc1994-09-24 00:00:00 +000079 cconvert->Cr_r_tab = (int *)
80 (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
81 (MAXJSAMPLE+1) * SIZEOF(int));
82 cconvert->Cb_b_tab = (int *)
83 (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
84 (MAXJSAMPLE+1) * SIZEOF(int));
85 cconvert->Cr_g_tab = (INT32 *)
86 (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
87 (MAXJSAMPLE+1) * SIZEOF(INT32));
88 cconvert->Cb_g_tab = (INT32 *)
89 (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
90 (MAXJSAMPLE+1) * SIZEOF(INT32));
Thomas G. Lane4a6b7301992-03-17 00:00:00 +000091
Thomas G. Lane9ba2f5e1994-12-07 00:00:00 +000092 for (i = 0, x = -CENTERJSAMPLE; i <= MAXJSAMPLE; i++, x++) {
Thomas G. Lane4a6b7301992-03-17 00:00:00 +000093 /* i is the actual input pixel value, in the range 0..MAXJSAMPLE */
Thomas G. Lane9ba2f5e1994-12-07 00:00:00 +000094 /* The Cb or Cr value we are thinking of is x = i - CENTERJSAMPLE */
Thomas G. Lane4a6b7301992-03-17 00:00:00 +000095 /* Cr=>R value is nearest int to 1.40200 * x */
Thomas G. Lane36a4ccc1994-09-24 00:00:00 +000096 cconvert->Cr_r_tab[i] = (int)
Thomas G. Lane9ba2f5e1994-12-07 00:00:00 +000097 RIGHT_SHIFT(FIX(1.40200) * x + ONE_HALF, SCALEBITS);
Thomas G. Lane4a6b7301992-03-17 00:00:00 +000098 /* Cb=>B value is nearest int to 1.77200 * x */
Thomas G. Lane36a4ccc1994-09-24 00:00:00 +000099 cconvert->Cb_b_tab[i] = (int)
Thomas G. Lane9ba2f5e1994-12-07 00:00:00 +0000100 RIGHT_SHIFT(FIX(1.77200) * x + ONE_HALF, SCALEBITS);
Thomas G. Lane4a6b7301992-03-17 00:00:00 +0000101 /* Cr=>G value is scaled-up -0.71414 * x */
Thomas G. Lane9ba2f5e1994-12-07 00:00:00 +0000102 cconvert->Cr_g_tab[i] = (- FIX(0.71414)) * x;
Thomas G. Lane4a6b7301992-03-17 00:00:00 +0000103 /* Cb=>G value is scaled-up -0.34414 * x */
104 /* We also add in ONE_HALF so that need not do it in inner loop */
Thomas G. Lane9ba2f5e1994-12-07 00:00:00 +0000105 cconvert->Cb_g_tab[i] = (- FIX(0.34414)) * x + ONE_HALF;
Thomas G. Lane4a6b7301992-03-17 00:00:00 +0000106 }
Thomas G. Lane2cbeb8a1991-10-07 00:00:00 +0000107}
108
109
110/*
111 * Convert some rows of samples to the output colorspace.
Thomas G. Lane36a4ccc1994-09-24 00:00:00 +0000112 *
113 * Note that we change from noninterleaved, one-plane-per-component format
114 * to interleaved-pixel format. The output buffer is therefore three times
115 * as wide as the input buffer.
116 * A starting row offset is provided only for the input buffer. The caller
117 * can easily adjust the passed output_buf value to accommodate any row
118 * offset required on that side.
Thomas G. Lane2cbeb8a1991-10-07 00:00:00 +0000119 */
120
Thomas G. Lane489583f1996-02-07 00:00:00 +0000121METHODDEF(void)
Thomas G. Lane36a4ccc1994-09-24 00:00:00 +0000122ycc_rgb_convert (j_decompress_ptr cinfo,
123 JSAMPIMAGE input_buf, JDIMENSION input_row,
124 JSAMPARRAY output_buf, int num_rows)
Thomas G. Lane2cbeb8a1991-10-07 00:00:00 +0000125{
Thomas G. Lane36a4ccc1994-09-24 00:00:00 +0000126 my_cconvert_ptr cconvert = (my_cconvert_ptr) cinfo->cconvert;
Thomas G. Lane4a6b7301992-03-17 00:00:00 +0000127 register int y, cb, cr;
Thomas G. Lane36a4ccc1994-09-24 00:00:00 +0000128 register JSAMPROW outptr;
Thomas G. Lane2cbeb8a1991-10-07 00:00:00 +0000129 register JSAMPROW inptr0, inptr1, inptr2;
Thomas G. Lane36a4ccc1994-09-24 00:00:00 +0000130 register JDIMENSION col;
131 JDIMENSION num_cols = cinfo->output_width;
Thomas G. Lane88aeed41992-12-10 00:00:00 +0000132 /* copy these pointers into registers if possible */
133 register JSAMPLE * range_limit = cinfo->sample_range_limit;
Thomas G. Lane36a4ccc1994-09-24 00:00:00 +0000134 register int * Crrtab = cconvert->Cr_r_tab;
135 register int * Cbbtab = cconvert->Cb_b_tab;
136 register INT32 * Crgtab = cconvert->Cr_g_tab;
137 register INT32 * Cbgtab = cconvert->Cb_g_tab;
Thomas G. Lane4a6b7301992-03-17 00:00:00 +0000138 SHIFT_TEMPS
Thomas G. Lane36a4ccc1994-09-24 00:00:00 +0000139
140 while (--num_rows >= 0) {
141 inptr0 = input_buf[0][input_row];
142 inptr1 = input_buf[1][input_row];
143 inptr2 = input_buf[2][input_row];
144 input_row++;
145 outptr = *output_buf++;
Thomas G. Lane88aeed41992-12-10 00:00:00 +0000146 for (col = 0; col < num_cols; col++) {
147 y = GETJSAMPLE(inptr0[col]);
148 cb = GETJSAMPLE(inptr1[col]);
149 cr = GETJSAMPLE(inptr2[col]);
Thomas G. Lane9ba2f5e1994-12-07 00:00:00 +0000150 /* Range-limiting is essential due to noise introduced by DCT losses. */
DRCf25c0712009-04-03 12:00:51 +0000151 outptr[rgb_red[cinfo->out_color_space]] = range_limit[y + Crrtab[cr]];
152 outptr[rgb_green[cinfo->out_color_space]] = range_limit[y +
Thomas G. Lane36a4ccc1994-09-24 00:00:00 +0000153 ((int) RIGHT_SHIFT(Cbgtab[cb] + Crgtab[cr],
154 SCALEBITS))];
DRCf25c0712009-04-03 12:00:51 +0000155 outptr[rgb_blue[cinfo->out_color_space]] = range_limit[y + Cbbtab[cb]];
156 outptr += rgb_pixelsize[cinfo->out_color_space];
Thomas G. Lane2cbeb8a1991-10-07 00:00:00 +0000157 }
158 }
159}
160
161
Thomas G. Lane4a6b7301992-03-17 00:00:00 +0000162/**************** Cases other than YCbCr -> RGB **************/
163
164
165/*
Thomas G. Lane36a4ccc1994-09-24 00:00:00 +0000166 * Color conversion for no colorspace change: just copy the data,
167 * converting from separate-planes to interleaved representation.
Thomas G. Lane4a6b7301992-03-17 00:00:00 +0000168 */
169
Thomas G. Lane489583f1996-02-07 00:00:00 +0000170METHODDEF(void)
Thomas G. Lane36a4ccc1994-09-24 00:00:00 +0000171null_convert (j_decompress_ptr cinfo,
172 JSAMPIMAGE input_buf, JDIMENSION input_row,
173 JSAMPARRAY output_buf, int num_rows)
Thomas G. Lane4a6b7301992-03-17 00:00:00 +0000174{
Thomas G. Lane36a4ccc1994-09-24 00:00:00 +0000175 register JSAMPROW inptr, outptr;
176 register JDIMENSION count;
Thomas G. Lanebc79e061995-08-02 00:00:00 +0000177 register int num_components = cinfo->num_components;
Thomas G. Lane36a4ccc1994-09-24 00:00:00 +0000178 JDIMENSION num_cols = cinfo->output_width;
179 int ci;
Thomas G. Lane4a6b7301992-03-17 00:00:00 +0000180
Thomas G. Lane36a4ccc1994-09-24 00:00:00 +0000181 while (--num_rows >= 0) {
182 for (ci = 0; ci < num_components; ci++) {
183 inptr = input_buf[ci][input_row];
184 outptr = output_buf[0] + ci;
185 for (count = num_cols; count > 0; count--) {
186 *outptr = *inptr++; /* needn't bother with GETJSAMPLE() here */
187 outptr += num_components;
188 }
189 }
190 input_row++;
191 output_buf++;
Thomas G. Lane2cbeb8a1991-10-07 00:00:00 +0000192 }
193}
194
195
196/*
197 * Color conversion for grayscale: just copy the data.
Thomas G. Lane36a4ccc1994-09-24 00:00:00 +0000198 * This also works for YCbCr -> grayscale conversion, in which
Thomas G. Lane2cbeb8a1991-10-07 00:00:00 +0000199 * we just copy the Y (luminance) component and ignore chrominance.
200 */
201
Thomas G. Lane489583f1996-02-07 00:00:00 +0000202METHODDEF(void)
Thomas G. Lane36a4ccc1994-09-24 00:00:00 +0000203grayscale_convert (j_decompress_ptr cinfo,
204 JSAMPIMAGE input_buf, JDIMENSION input_row,
205 JSAMPARRAY output_buf, int num_rows)
Thomas G. Lane2cbeb8a1991-10-07 00:00:00 +0000206{
Thomas G. Lane36a4ccc1994-09-24 00:00:00 +0000207 jcopy_sample_rows(input_buf[0], (int) input_row, output_buf, 0,
208 num_rows, cinfo->output_width);
Thomas G. Lane2cbeb8a1991-10-07 00:00:00 +0000209}
210
211
212/*
Thomas G. Lane5ead57a1998-03-27 00:00:00 +0000213 * Convert grayscale to RGB: just duplicate the graylevel three times.
214 * This is provided to support applications that don't want to cope
215 * with grayscale as a separate case.
216 */
217
218METHODDEF(void)
219gray_rgb_convert (j_decompress_ptr cinfo,
220 JSAMPIMAGE input_buf, JDIMENSION input_row,
221 JSAMPARRAY output_buf, int num_rows)
222{
223 register JSAMPROW inptr, outptr;
224 register JDIMENSION col;
225 JDIMENSION num_cols = cinfo->output_width;
226
227 while (--num_rows >= 0) {
228 inptr = input_buf[0][input_row++];
229 outptr = *output_buf++;
230 for (col = 0; col < num_cols; col++) {
231 /* We can dispense with GETJSAMPLE() here */
DRCf25c0712009-04-03 12:00:51 +0000232 outptr[rgb_red[cinfo->out_color_space]] =
233 outptr[rgb_green[cinfo->out_color_space]] =
234 outptr[rgb_blue[cinfo->out_color_space]] = inptr[col];
235 outptr += rgb_pixelsize[cinfo->out_color_space];
Thomas G. Lane5ead57a1998-03-27 00:00:00 +0000236 }
237 }
238}
239
240
241/*
Thomas G. Lane36a4ccc1994-09-24 00:00:00 +0000242 * 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.
Thomas G. Lanebc79e061995-08-02 00:00:00 +0000245 * We assume build_ycc_rgb_table has been called.
Thomas G. Lane2cbeb8a1991-10-07 00:00:00 +0000246 */
247
Thomas G. Lane489583f1996-02-07 00:00:00 +0000248METHODDEF(void)
Thomas G. Lane36a4ccc1994-09-24 00:00:00 +0000249ycck_cmyk_convert (j_decompress_ptr cinfo,
250 JSAMPIMAGE input_buf, JDIMENSION input_row,
251 JSAMPARRAY output_buf, int num_rows)
252{
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;
265 SHIFT_TEMPS
266
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];
272 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]);
Thomas G. Lane9ba2f5e1994-12-07 00:00:00 +0000278 /* Range-limiting is essential due to noise introduced by DCT losses. */
Thomas G. Lane36a4ccc1994-09-24 00:00:00 +0000279 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],
282 SCALEBITS)))];
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 */
286 outptr += 4;
287 }
288 }
289}
290
291
292/*
293 * Empty method for start_pass.
294 */
295
Thomas G. Lane489583f1996-02-07 00:00:00 +0000296METHODDEF(void)
Thomas G. Lanebc79e061995-08-02 00:00:00 +0000297start_pass_dcolor (j_decompress_ptr cinfo)
Thomas G. Lane2cbeb8a1991-10-07 00:00:00 +0000298{
299 /* no work needed */
300}
301
302
303/*
Thomas G. Lane36a4ccc1994-09-24 00:00:00 +0000304 * Module initialization routine for output colorspace conversion.
Thomas G. Lane2cbeb8a1991-10-07 00:00:00 +0000305 */
306
Thomas G. Lane489583f1996-02-07 00:00:00 +0000307GLOBAL(void)
Thomas G. Lane36a4ccc1994-09-24 00:00:00 +0000308jinit_color_deconverter (j_decompress_ptr cinfo)
Thomas G. Lane2cbeb8a1991-10-07 00:00:00 +0000309{
Thomas G. Lane36a4ccc1994-09-24 00:00:00 +0000310 my_cconvert_ptr cconvert;
Thomas G. Lanecc7150e1993-02-18 00:00:00 +0000311 int ci;
312
Thomas G. Lane36a4ccc1994-09-24 00:00:00 +0000313 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;
Thomas G. Lanebc79e061995-08-02 00:00:00 +0000317 cconvert->pub.start_pass = start_pass_dcolor;
Thomas G. Lane36a4ccc1994-09-24 00:00:00 +0000318
Thomas G. Lane2cbeb8a1991-10-07 00:00:00 +0000319 /* Make sure num_components agrees with jpeg_color_space */
320 switch (cinfo->jpeg_color_space) {
Thomas G. Lane36a4ccc1994-09-24 00:00:00 +0000321 case JCS_GRAYSCALE:
Thomas G. Lane2cbeb8a1991-10-07 00:00:00 +0000322 if (cinfo->num_components != 1)
Thomas G. Lane36a4ccc1994-09-24 00:00:00 +0000323 ERREXIT(cinfo, JERR_BAD_J_COLORSPACE);
Thomas G. Lane2cbeb8a1991-10-07 00:00:00 +0000324 break;
325
Thomas G. Lane36a4ccc1994-09-24 00:00:00 +0000326 case JCS_RGB:
327 case JCS_YCbCr:
Thomas G. Lane2cbeb8a1991-10-07 00:00:00 +0000328 if (cinfo->num_components != 3)
Thomas G. Lane36a4ccc1994-09-24 00:00:00 +0000329 ERREXIT(cinfo, JERR_BAD_J_COLORSPACE);
Thomas G. Lane2cbeb8a1991-10-07 00:00:00 +0000330 break;
331
Thomas G. Lane36a4ccc1994-09-24 00:00:00 +0000332 case JCS_CMYK:
333 case JCS_YCCK:
Thomas G. Lane2cbeb8a1991-10-07 00:00:00 +0000334 if (cinfo->num_components != 4)
Thomas G. Lane36a4ccc1994-09-24 00:00:00 +0000335 ERREXIT(cinfo, JERR_BAD_J_COLORSPACE);
Thomas G. Lane2cbeb8a1991-10-07 00:00:00 +0000336 break;
337
Thomas G. Lane36a4ccc1994-09-24 00:00:00 +0000338 default: /* JCS_UNKNOWN can be anything */
339 if (cinfo->num_components < 1)
340 ERREXIT(cinfo, JERR_BAD_J_COLORSPACE);
Thomas G. Lane2cbeb8a1991-10-07 00:00:00 +0000341 break;
342 }
343
Thomas G. Lane36a4ccc1994-09-24 00:00:00 +0000344 /* 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.
347 */
Thomas G. Lanecc7150e1993-02-18 00:00:00 +0000348
Thomas G. Lane2cbeb8a1991-10-07 00:00:00 +0000349 switch (cinfo->out_color_space) {
Thomas G. Lane36a4ccc1994-09-24 00:00:00 +0000350 case JCS_GRAYSCALE:
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;
Thomas G. Lanecc7150e1993-02-18 00:00:00 +0000355 /* For color->grayscale conversion, only the Y (0) component is needed */
356 for (ci = 1; ci < cinfo->num_components; ci++)
Thomas G. Lane36a4ccc1994-09-24 00:00:00 +0000357 cinfo->comp_info[ci].component_needed = FALSE;
Thomas G. Lane4a6b7301992-03-17 00:00:00 +0000358 } else
Thomas G. Lane36a4ccc1994-09-24 00:00:00 +0000359 ERREXIT(cinfo, JERR_CONVERSION_NOTIMPL);
Thomas G. Lane2cbeb8a1991-10-07 00:00:00 +0000360 break;
361
Thomas G. Lane36a4ccc1994-09-24 00:00:00 +0000362 case JCS_RGB:
DRCf25c0712009-04-03 12:00:51 +0000363 case JCS_EXT_RGB:
364 case JCS_EXT_RGBX:
365 case JCS_EXT_BGR:
366 case JCS_EXT_BGRX:
367 case JCS_EXT_XBGR:
368 case JCS_EXT_XRGB:
369 cinfo->out_color_components = rgb_pixelsize[cinfo->out_color_space];
Thomas G. Lane36a4ccc1994-09-24 00:00:00 +0000370 if (cinfo->jpeg_color_space == JCS_YCbCr) {
Pierre Ossman59a39382009-03-09 13:15:56 +0000371 if (jsimd_can_ycc_rgb())
372 cconvert->pub.color_convert = jsimd_ycc_rgb_convert;
373 else {
374 cconvert->pub.color_convert = ycc_rgb_convert;
375 build_ycc_rgb_table(cinfo);
376 }
Thomas G. Lane5ead57a1998-03-27 00:00:00 +0000377 } else if (cinfo->jpeg_color_space == JCS_GRAYSCALE) {
378 cconvert->pub.color_convert = gray_rgb_convert;
DRCf25c0712009-04-03 12:00:51 +0000379 } else if (cinfo->jpeg_color_space == cinfo->out_color_space &&
380 rgb_pixelsize[cinfo->out_color_space] == 3) {
Thomas G. Lane36a4ccc1994-09-24 00:00:00 +0000381 cconvert->pub.color_convert = null_convert;
Thomas G. Lane4a6b7301992-03-17 00:00:00 +0000382 } else
Thomas G. Lane36a4ccc1994-09-24 00:00:00 +0000383 ERREXIT(cinfo, JERR_CONVERSION_NOTIMPL);
384 break;
385
386 case JCS_CMYK:
387 cinfo->out_color_components = 4;
388 if (cinfo->jpeg_color_space == JCS_YCCK) {
Thomas G. Lane36a4ccc1994-09-24 00:00:00 +0000389 cconvert->pub.color_convert = ycck_cmyk_convert;
Thomas G. Lanebc79e061995-08-02 00:00:00 +0000390 build_ycc_rgb_table(cinfo);
Thomas G. Lane36a4ccc1994-09-24 00:00:00 +0000391 } else if (cinfo->jpeg_color_space == JCS_CMYK) {
392 cconvert->pub.color_convert = null_convert;
393 } else
394 ERREXIT(cinfo, JERR_CONVERSION_NOTIMPL);
Thomas G. Lane2cbeb8a1991-10-07 00:00:00 +0000395 break;
396
397 default:
Thomas G. Lane36a4ccc1994-09-24 00:00:00 +0000398 /* Permit null conversion to same output space */
Thomas G. Lane4a6b7301992-03-17 00:00:00 +0000399 if (cinfo->out_color_space == cinfo->jpeg_color_space) {
Thomas G. Lane36a4ccc1994-09-24 00:00:00 +0000400 cinfo->out_color_components = cinfo->num_components;
401 cconvert->pub.color_convert = null_convert;
Thomas G. Lane4a6b7301992-03-17 00:00:00 +0000402 } else /* unsupported non-null conversion */
Thomas G. Lane36a4ccc1994-09-24 00:00:00 +0000403 ERREXIT(cinfo, JERR_CONVERSION_NOTIMPL);
Thomas G. Lane2cbeb8a1991-10-07 00:00:00 +0000404 break;
405 }
406
407 if (cinfo->quantize_colors)
Thomas G. Lane36a4ccc1994-09-24 00:00:00 +0000408 cinfo->output_components = 1; /* single colormapped output component */
Thomas G. Lane2cbeb8a1991-10-07 00:00:00 +0000409 else
Thomas G. Lane36a4ccc1994-09-24 00:00:00 +0000410 cinfo->output_components = cinfo->out_color_components;
Thomas G. Lane2cbeb8a1991-10-07 00:00:00 +0000411}