Upstream version 7.36.149.0
[platform/framework/web/crosswalk.git] / src / third_party / libjpeg_turbo / jdcolor.c
1 /*
2  * jdcolor.c
3  *
4  * This file was part of the Independent JPEG Group's software:
5  * Copyright (C) 1991-1997, Thomas G. Lane.
6  * Modified 2011 by Guido Vollbeding.
7  * libjpeg-turbo Modifications:
8  * Copyright 2009 Pierre Ossman <ossman@cendio.se> for Cendio AB
9  * Copyright (C) 2009, 2011-2012, D. R. Commander.
10  * For conditions of distribution and use, see the accompanying README file.
11  *
12  * This file contains output colorspace conversion routines.
13  */
14
15 #define JPEG_INTERNALS
16 #include "jinclude.h"
17 #include "jpeglib.h"
18 #include "jsimd.h"
19 #include "config.h"
20
21
22 /* Private subobject */
23
24 typedef struct {
25   struct jpeg_color_deconverter pub; /* public fields */
26
27   /* Private state for YCC->RGB conversion */
28   int * Cr_r_tab;               /* => table for Cr to R conversion */
29   int * Cb_b_tab;               /* => table for Cb to B conversion */
30   INT32 * Cr_g_tab;             /* => table for Cr to G conversion */
31   INT32 * Cb_g_tab;             /* => table for Cb to G conversion */
32
33   /* Private state for RGB->Y conversion */
34   INT32 * rgb_y_tab;            /* => table for RGB to Y conversion */
35 } my_color_deconverter;
36
37 typedef my_color_deconverter * my_cconvert_ptr;
38
39
40 /**************** YCbCr -> RGB conversion: most common case **************/
41 /****************   RGB -> Y   conversion: less common case **************/
42
43 /*
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  *
48  *      R = Y                + 1.40200 * Cr
49  *      G = Y - 0.34414 * Cb - 0.71414 * Cr
50  *      B = Y + 1.77200 * Cb
51  *
52  *      Y = 0.29900 * R + 0.58700 * G + 0.11400 * B
53  *
54  * where Cb and Cr represent the incoming values less CENTERJSAMPLE.
55  * (These numbers are derived from TIFF 6.0 section 21, dated 3-June-92.)
56  *
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.
60  * Notice that Y, being an integral input, does not contribute any fraction
61  * so it need not participate in the rounding.
62  *
63  * For even more speed, we avoid doing any multiplications in the inner loop
64  * by precalculating the constants times Cb and Cr for all possible values.
65  * For 8-bit JSAMPLEs this is very reasonable (only 256 entries per table);
66  * for 12-bit samples it is still acceptable.  It's not very reasonable for
67  * 16-bit samples, but if you want lossless storage you shouldn't be changing
68  * colorspace anyway.
69  * The Cr=>R and Cb=>B values can be rounded to integers in advance; the
70  * values for the G calculation are left scaled up, since we must add them
71  * together before rounding.
72  */
73
74 #define SCALEBITS       16      /* speediest right-shift on some machines */
75 #define ONE_HALF        ((INT32) 1 << (SCALEBITS-1))
76 #define FIX(x)          ((INT32) ((x) * (1L<<SCALEBITS) + 0.5))
77
78 /* We allocate one big table for RGB->Y conversion and divide it up into
79  * three parts, instead of doing three alloc_small requests.  This lets us
80  * use a single table base address, which can be held in a register in the
81  * inner loops on many machines (more than can hold all three addresses,
82  * anyway).
83  */
84
85 #define R_Y_OFF         0                       /* offset to R => Y section */
86 #define G_Y_OFF         (1*(MAXJSAMPLE+1))      /* offset to G => Y section */
87 #define B_Y_OFF         (2*(MAXJSAMPLE+1))      /* etc. */
88 #define TABLE_SIZE      (3*(MAXJSAMPLE+1))
89
90
91 /* Include inline routines for colorspace extensions */
92
93 #include "jdcolext.c"
94 #undef RGB_RED
95 #undef RGB_GREEN
96 #undef RGB_BLUE
97 #undef RGB_PIXELSIZE
98
99 #define RGB_RED EXT_RGB_RED
100 #define RGB_GREEN EXT_RGB_GREEN
101 #define RGB_BLUE EXT_RGB_BLUE
102 #define RGB_PIXELSIZE EXT_RGB_PIXELSIZE
103 #define ycc_rgb_convert_internal ycc_extrgb_convert_internal
104 #define gray_rgb_convert_internal gray_extrgb_convert_internal
105 #define rgb_rgb_convert_internal rgb_extrgb_convert_internal
106 #include "jdcolext.c"
107 #undef RGB_RED
108 #undef RGB_GREEN
109 #undef RGB_BLUE
110 #undef RGB_PIXELSIZE
111 #undef ycc_rgb_convert_internal
112 #undef gray_rgb_convert_internal
113 #undef rgb_rgb_convert_internal
114
115 #define RGB_RED EXT_RGBX_RED
116 #define RGB_GREEN EXT_RGBX_GREEN
117 #define RGB_BLUE EXT_RGBX_BLUE
118 #define RGB_ALPHA 3
119 #define RGB_PIXELSIZE EXT_RGBX_PIXELSIZE
120 #define ycc_rgb_convert_internal ycc_extrgbx_convert_internal
121 #define gray_rgb_convert_internal gray_extrgbx_convert_internal
122 #define rgb_rgb_convert_internal rgb_extrgbx_convert_internal
123 #include "jdcolext.c"
124 #undef RGB_RED
125 #undef RGB_GREEN
126 #undef RGB_BLUE
127 #undef RGB_ALPHA
128 #undef RGB_PIXELSIZE
129 #undef ycc_rgb_convert_internal
130 #undef gray_rgb_convert_internal
131 #undef rgb_rgb_convert_internal
132
133 #define RGB_RED EXT_BGR_RED
134 #define RGB_GREEN EXT_BGR_GREEN
135 #define RGB_BLUE EXT_BGR_BLUE
136 #define RGB_PIXELSIZE EXT_BGR_PIXELSIZE
137 #define ycc_rgb_convert_internal ycc_extbgr_convert_internal
138 #define gray_rgb_convert_internal gray_extbgr_convert_internal
139 #define rgb_rgb_convert_internal rgb_extbgr_convert_internal
140 #include "jdcolext.c"
141 #undef RGB_RED
142 #undef RGB_GREEN
143 #undef RGB_BLUE
144 #undef RGB_PIXELSIZE
145 #undef ycc_rgb_convert_internal
146 #undef gray_rgb_convert_internal
147 #undef rgb_rgb_convert_internal
148
149 #define RGB_RED EXT_BGRX_RED
150 #define RGB_GREEN EXT_BGRX_GREEN
151 #define RGB_BLUE EXT_BGRX_BLUE
152 #define RGB_ALPHA 3
153 #define RGB_PIXELSIZE EXT_BGRX_PIXELSIZE
154 #define ycc_rgb_convert_internal ycc_extbgrx_convert_internal
155 #define gray_rgb_convert_internal gray_extbgrx_convert_internal
156 #define rgb_rgb_convert_internal rgb_extbgrx_convert_internal
157 #include "jdcolext.c"
158 #undef RGB_RED
159 #undef RGB_GREEN
160 #undef RGB_BLUE
161 #undef RGB_ALPHA
162 #undef RGB_PIXELSIZE
163 #undef ycc_rgb_convert_internal
164 #undef gray_rgb_convert_internal
165 #undef rgb_rgb_convert_internal
166
167 #define RGB_RED EXT_XBGR_RED
168 #define RGB_GREEN EXT_XBGR_GREEN
169 #define RGB_BLUE EXT_XBGR_BLUE
170 #define RGB_ALPHA 0
171 #define RGB_PIXELSIZE EXT_XBGR_PIXELSIZE
172 #define ycc_rgb_convert_internal ycc_extxbgr_convert_internal
173 #define gray_rgb_convert_internal gray_extxbgr_convert_internal
174 #define rgb_rgb_convert_internal rgb_extxbgr_convert_internal
175 #include "jdcolext.c"
176 #undef RGB_RED
177 #undef RGB_GREEN
178 #undef RGB_BLUE
179 #undef RGB_ALPHA
180 #undef RGB_PIXELSIZE
181 #undef ycc_rgb_convert_internal
182 #undef gray_rgb_convert_internal
183 #undef rgb_rgb_convert_internal
184
185 #define RGB_RED EXT_XRGB_RED
186 #define RGB_GREEN EXT_XRGB_GREEN
187 #define RGB_BLUE EXT_XRGB_BLUE
188 #define RGB_ALPHA 0
189 #define RGB_PIXELSIZE EXT_XRGB_PIXELSIZE
190 #define ycc_rgb_convert_internal ycc_extxrgb_convert_internal
191 #define gray_rgb_convert_internal gray_extxrgb_convert_internal
192 #define rgb_rgb_convert_internal rgb_extxrgb_convert_internal
193 #include "jdcolext.c"
194 #undef RGB_RED
195 #undef RGB_GREEN
196 #undef RGB_BLUE
197 #undef RGB_ALPHA
198 #undef RGB_PIXELSIZE
199 #undef ycc_rgb_convert_internal
200 #undef gray_rgb_convert_internal
201 #undef rgb_rgb_convert_internal
202
203
204 /*
205  * Initialize tables for YCC->RGB colorspace conversion.
206  */
207
208 LOCAL(void)
209 build_ycc_rgb_table (j_decompress_ptr cinfo)
210 {
211   my_cconvert_ptr cconvert = (my_cconvert_ptr) cinfo->cconvert;
212   int i;
213   INT32 x;
214   SHIFT_TEMPS
215
216   cconvert->Cr_r_tab = (int *)
217     (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
218                                 (MAXJSAMPLE+1) * SIZEOF(int));
219   cconvert->Cb_b_tab = (int *)
220     (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
221                                 (MAXJSAMPLE+1) * SIZEOF(int));
222   cconvert->Cr_g_tab = (INT32 *)
223     (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
224                                 (MAXJSAMPLE+1) * SIZEOF(INT32));
225   cconvert->Cb_g_tab = (INT32 *)
226     (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
227                                 (MAXJSAMPLE+1) * SIZEOF(INT32));
228
229   for (i = 0, x = -CENTERJSAMPLE; i <= MAXJSAMPLE; i++, x++) {
230     /* i is the actual input pixel value, in the range 0..MAXJSAMPLE */
231     /* The Cb or Cr value we are thinking of is x = i - CENTERJSAMPLE */
232     /* Cr=>R value is nearest int to 1.40200 * x */
233     cconvert->Cr_r_tab[i] = (int)
234                     RIGHT_SHIFT(FIX(1.40200) * x + ONE_HALF, SCALEBITS);
235     /* Cb=>B value is nearest int to 1.77200 * x */
236     cconvert->Cb_b_tab[i] = (int)
237                     RIGHT_SHIFT(FIX(1.77200) * x + ONE_HALF, SCALEBITS);
238     /* Cr=>G value is scaled-up -0.71414 * x */
239     cconvert->Cr_g_tab[i] = (- FIX(0.71414)) * x;
240     /* Cb=>G value is scaled-up -0.34414 * x */
241     /* We also add in ONE_HALF so that need not do it in inner loop */
242     cconvert->Cb_g_tab[i] = (- FIX(0.34414)) * x + ONE_HALF;
243   }
244 }
245
246
247 /*
248  * Convert some rows of samples to the output colorspace.
249  */
250
251 METHODDEF(void)
252 ycc_rgb_convert (j_decompress_ptr cinfo,
253                  JSAMPIMAGE input_buf, JDIMENSION input_row,
254                  JSAMPARRAY output_buf, int num_rows)
255 {
256   switch (cinfo->out_color_space) {
257     case JCS_EXT_RGB:
258       ycc_extrgb_convert_internal(cinfo, input_buf, input_row, output_buf,
259                                   num_rows);
260       break;
261     case JCS_EXT_RGBX:
262     case JCS_EXT_RGBA:
263       ycc_extrgbx_convert_internal(cinfo, input_buf, input_row, output_buf,
264                                    num_rows);
265       break;
266     case JCS_EXT_BGR:
267       ycc_extbgr_convert_internal(cinfo, input_buf, input_row, output_buf,
268                                   num_rows);
269       break;
270     case JCS_EXT_BGRX:
271     case JCS_EXT_BGRA:
272       ycc_extbgrx_convert_internal(cinfo, input_buf, input_row, output_buf,
273                                    num_rows);
274       break;
275     case JCS_EXT_XBGR:
276     case JCS_EXT_ABGR:
277       ycc_extxbgr_convert_internal(cinfo, input_buf, input_row, output_buf,
278                                    num_rows);
279       break;
280     case JCS_EXT_XRGB:
281     case JCS_EXT_ARGB:
282       ycc_extxrgb_convert_internal(cinfo, input_buf, input_row, output_buf,
283                                    num_rows);
284       break;
285     default:
286       ycc_rgb_convert_internal(cinfo, input_buf, input_row, output_buf,
287                                num_rows);
288       break;
289   }
290 }
291
292
293 /**************** Cases other than YCbCr -> RGB **************/
294
295
296 /*
297  * Initialize for RGB->grayscale colorspace conversion.
298  */
299
300 LOCAL(void)
301 build_rgb_y_table (j_decompress_ptr cinfo)
302 {
303   my_cconvert_ptr cconvert = (my_cconvert_ptr) cinfo->cconvert;
304   INT32 * rgb_y_tab;
305   INT32 i;
306
307   /* Allocate and fill in the conversion tables. */
308   cconvert->rgb_y_tab = rgb_y_tab = (INT32 *)
309     (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
310                                 (TABLE_SIZE * SIZEOF(INT32)));
311
312   for (i = 0; i <= MAXJSAMPLE; i++) {
313     rgb_y_tab[i+R_Y_OFF] = FIX(0.29900) * i;
314     rgb_y_tab[i+G_Y_OFF] = FIX(0.58700) * i;
315     rgb_y_tab[i+B_Y_OFF] = FIX(0.11400) * i + ONE_HALF;
316   }
317 }
318
319
320 /*
321  * Convert RGB to grayscale.
322  */
323
324 METHODDEF(void)
325 rgb_gray_convert (j_decompress_ptr cinfo,
326                   JSAMPIMAGE input_buf, JDIMENSION input_row,
327                   JSAMPARRAY output_buf, int num_rows)
328 {
329   my_cconvert_ptr cconvert = (my_cconvert_ptr) cinfo->cconvert;
330   register int r, g, b;
331   register INT32 * ctab = cconvert->rgb_y_tab;
332   register JSAMPROW outptr;
333   register JSAMPROW inptr0, inptr1, inptr2;
334   register JDIMENSION col;
335   JDIMENSION num_cols = cinfo->output_width;
336
337   while (--num_rows >= 0) {
338     inptr0 = input_buf[0][input_row];
339     inptr1 = input_buf[1][input_row];
340     inptr2 = input_buf[2][input_row];
341     input_row++;
342     outptr = *output_buf++;
343     for (col = 0; col < num_cols; col++) {
344       r = GETJSAMPLE(inptr0[col]);
345       g = GETJSAMPLE(inptr1[col]);
346       b = GETJSAMPLE(inptr2[col]);
347       /* Y */
348       outptr[col] = (JSAMPLE)
349                 ((ctab[r+R_Y_OFF] + ctab[g+G_Y_OFF] + ctab[b+B_Y_OFF])
350                  >> SCALEBITS);
351     }
352   }
353 }
354
355
356 /*
357  * Color conversion for no colorspace change: just copy the data,
358  * converting from separate-planes to interleaved representation.
359  */
360
361 METHODDEF(void)
362 null_convert (j_decompress_ptr cinfo,
363               JSAMPIMAGE input_buf, JDIMENSION input_row,
364               JSAMPARRAY output_buf, int num_rows)
365 {
366   register JSAMPROW inptr, outptr;
367   register JDIMENSION count;
368   register int num_components = cinfo->num_components;
369   JDIMENSION num_cols = cinfo->output_width;
370   int ci;
371
372   while (--num_rows >= 0) {
373     for (ci = 0; ci < num_components; ci++) {
374       inptr = input_buf[ci][input_row];
375       outptr = output_buf[0] + ci;
376       for (count = num_cols; count > 0; count--) {
377         *outptr = *inptr++;     /* needn't bother with GETJSAMPLE() here */
378         outptr += num_components;
379       }
380     }
381     input_row++;
382     output_buf++;
383   }
384 }
385
386
387 /*
388  * Color conversion for grayscale: just copy the data.
389  * This also works for YCbCr -> grayscale conversion, in which
390  * we just copy the Y (luminance) component and ignore chrominance.
391  */
392
393 METHODDEF(void)
394 grayscale_convert (j_decompress_ptr cinfo,
395                    JSAMPIMAGE input_buf, JDIMENSION input_row,
396                    JSAMPARRAY output_buf, int num_rows)
397 {
398   jcopy_sample_rows(input_buf[0], (int) input_row, output_buf, 0,
399                     num_rows, cinfo->output_width);
400 }
401
402
403 /*
404  * Convert grayscale to RGB
405  */
406
407 METHODDEF(void)
408 gray_rgb_convert (j_decompress_ptr cinfo,
409                   JSAMPIMAGE input_buf, JDIMENSION input_row,
410                   JSAMPARRAY output_buf, int num_rows)
411 {
412   switch (cinfo->out_color_space) {
413     case JCS_EXT_RGB:
414       gray_extrgb_convert_internal(cinfo, input_buf, input_row, output_buf,
415                                    num_rows);
416       break;
417     case JCS_EXT_RGBX:
418     case JCS_EXT_RGBA:
419       gray_extrgbx_convert_internal(cinfo, input_buf, input_row, output_buf,
420                                     num_rows);
421       break;
422     case JCS_EXT_BGR:
423       gray_extbgr_convert_internal(cinfo, input_buf, input_row, output_buf,
424                                    num_rows);
425       break;
426     case JCS_EXT_BGRX:
427     case JCS_EXT_BGRA:
428       gray_extbgrx_convert_internal(cinfo, input_buf, input_row, output_buf,
429                                     num_rows);
430       break;
431     case JCS_EXT_XBGR:
432     case JCS_EXT_ABGR:
433       gray_extxbgr_convert_internal(cinfo, input_buf, input_row, output_buf,
434                                     num_rows);
435       break;
436     case JCS_EXT_XRGB:
437     case JCS_EXT_ARGB:
438       gray_extxrgb_convert_internal(cinfo, input_buf, input_row, output_buf,
439                                     num_rows);
440       break;
441     default:
442       gray_rgb_convert_internal(cinfo, input_buf, input_row, output_buf,
443                                 num_rows);
444       break;
445   }
446 }
447
448
449 /*
450  * Convert plain RGB to extended RGB
451  */
452
453 METHODDEF(void)
454 rgb_rgb_convert (j_decompress_ptr cinfo,
455                   JSAMPIMAGE input_buf, JDIMENSION input_row,
456                   JSAMPARRAY output_buf, int num_rows)
457 {
458   switch (cinfo->out_color_space) {
459     case JCS_EXT_RGB:
460       rgb_extrgb_convert_internal(cinfo, input_buf, input_row, output_buf,
461                                   num_rows);
462       break;
463     case JCS_EXT_RGBX:
464     case JCS_EXT_RGBA:
465       rgb_extrgbx_convert_internal(cinfo, input_buf, input_row, output_buf,
466                                    num_rows);
467       break;
468     case JCS_EXT_BGR:
469       rgb_extbgr_convert_internal(cinfo, input_buf, input_row, output_buf,
470                                   num_rows);
471       break;
472     case JCS_EXT_BGRX:
473     case JCS_EXT_BGRA:
474       rgb_extbgrx_convert_internal(cinfo, input_buf, input_row, output_buf,
475                                    num_rows);
476       break;
477     case JCS_EXT_XBGR:
478     case JCS_EXT_ABGR:
479       rgb_extxbgr_convert_internal(cinfo, input_buf, input_row, output_buf,
480                                    num_rows);
481       break;
482     case JCS_EXT_XRGB:
483     case JCS_EXT_ARGB:
484       rgb_extxrgb_convert_internal(cinfo, input_buf, input_row, output_buf,
485                                    num_rows);
486       break;
487     default:
488       rgb_rgb_convert_internal(cinfo, input_buf, input_row, output_buf,
489                                num_rows);
490       break;
491   }
492 }
493
494
495 /*
496  * Adobe-style YCCK->CMYK conversion.
497  * We convert YCbCr to R=1-C, G=1-M, and B=1-Y using the same
498  * conversion as above, while passing K (black) unchanged.
499  * We assume build_ycc_rgb_table has been called.
500  */
501
502 METHODDEF(void)
503 ycck_cmyk_convert (j_decompress_ptr cinfo,
504                    JSAMPIMAGE input_buf, JDIMENSION input_row,
505                    JSAMPARRAY output_buf, int num_rows)
506 {
507   my_cconvert_ptr cconvert = (my_cconvert_ptr) cinfo->cconvert;
508   register int y, cb, cr;
509   register JSAMPROW outptr;
510   register JSAMPROW inptr0, inptr1, inptr2, inptr3;
511   register JDIMENSION col;
512   JDIMENSION num_cols = cinfo->output_width;
513   /* copy these pointers into registers if possible */
514   register JSAMPLE * range_limit = cinfo->sample_range_limit;
515   register int * Crrtab = cconvert->Cr_r_tab;
516   register int * Cbbtab = cconvert->Cb_b_tab;
517   register INT32 * Crgtab = cconvert->Cr_g_tab;
518   register INT32 * Cbgtab = cconvert->Cb_g_tab;
519   SHIFT_TEMPS
520
521   while (--num_rows >= 0) {
522     inptr0 = input_buf[0][input_row];
523     inptr1 = input_buf[1][input_row];
524     inptr2 = input_buf[2][input_row];
525     inptr3 = input_buf[3][input_row];
526     input_row++;
527     outptr = *output_buf++;
528     for (col = 0; col < num_cols; col++) {
529       y  = GETJSAMPLE(inptr0[col]);
530       cb = GETJSAMPLE(inptr1[col]);
531       cr = GETJSAMPLE(inptr2[col]);
532       /* Range-limiting is essential due to noise introduced by DCT losses. */
533       outptr[0] = range_limit[MAXJSAMPLE - (y + Crrtab[cr])];   /* red */
534       outptr[1] = range_limit[MAXJSAMPLE - (y +                 /* green */
535                               ((int) RIGHT_SHIFT(Cbgtab[cb] + Crgtab[cr],
536                                                  SCALEBITS)))];
537       outptr[2] = range_limit[MAXJSAMPLE - (y + Cbbtab[cb])];   /* blue */
538       /* K passes through unchanged */
539       outptr[3] = inptr3[col];  /* don't need GETJSAMPLE here */
540       outptr += 4;
541     }
542   }
543 }
544
545
546 /*
547  * Empty method for start_pass.
548  */
549
550 METHODDEF(void)
551 start_pass_dcolor (j_decompress_ptr cinfo)
552 {
553   /* no work needed */
554 }
555
556
557 /*
558  * Module initialization routine for output colorspace conversion.
559  */
560
561 GLOBAL(void)
562 jinit_color_deconverter (j_decompress_ptr cinfo)
563 {
564   my_cconvert_ptr cconvert;
565   int ci;
566
567   cconvert = (my_cconvert_ptr)
568     (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
569                                 SIZEOF(my_color_deconverter));
570   cinfo->cconvert = (struct jpeg_color_deconverter *) cconvert;
571   cconvert->pub.start_pass = start_pass_dcolor;
572
573   /* Make sure num_components agrees with jpeg_color_space */
574   switch (cinfo->jpeg_color_space) {
575   case JCS_GRAYSCALE:
576     if (cinfo->num_components != 1)
577       ERREXIT(cinfo, JERR_BAD_J_COLORSPACE);
578     break;
579
580   case JCS_RGB:
581   case JCS_YCbCr:
582     if (cinfo->num_components != 3)
583       ERREXIT(cinfo, JERR_BAD_J_COLORSPACE);
584     break;
585
586   case JCS_CMYK:
587   case JCS_YCCK:
588     if (cinfo->num_components != 4)
589       ERREXIT(cinfo, JERR_BAD_J_COLORSPACE);
590     break;
591
592   default:                      /* JCS_UNKNOWN can be anything */
593     if (cinfo->num_components < 1)
594       ERREXIT(cinfo, JERR_BAD_J_COLORSPACE);
595     break;
596   }
597
598   /* Set out_color_components and conversion method based on requested space.
599    * Also clear the component_needed flags for any unused components,
600    * so that earlier pipeline stages can avoid useless computation.
601    */
602
603   switch (cinfo->out_color_space) {
604   case JCS_GRAYSCALE:
605     cinfo->out_color_components = 1;
606     if (cinfo->jpeg_color_space == JCS_GRAYSCALE ||
607         cinfo->jpeg_color_space == JCS_YCbCr) {
608       cconvert->pub.color_convert = grayscale_convert;
609       /* For color->grayscale conversion, only the Y (0) component is needed */
610       for (ci = 1; ci < cinfo->num_components; ci++)
611         cinfo->comp_info[ci].component_needed = FALSE;
612     } else if (cinfo->jpeg_color_space == JCS_RGB) {
613       cconvert->pub.color_convert = rgb_gray_convert;
614       build_rgb_y_table(cinfo);
615     } else
616       ERREXIT(cinfo, JERR_CONVERSION_NOTIMPL);
617     break;
618
619   case JCS_RGB:
620   case JCS_EXT_RGB:
621   case JCS_EXT_RGBX:
622   case JCS_EXT_BGR:
623   case JCS_EXT_BGRX:
624   case JCS_EXT_XBGR:
625   case JCS_EXT_XRGB:
626   case JCS_EXT_RGBA:
627   case JCS_EXT_BGRA:
628   case JCS_EXT_ABGR:
629   case JCS_EXT_ARGB:
630     cinfo->out_color_components = rgb_pixelsize[cinfo->out_color_space];
631     if (cinfo->jpeg_color_space == JCS_YCbCr) {
632       if (jsimd_can_ycc_rgb())
633         cconvert->pub.color_convert = jsimd_ycc_rgb_convert;
634       else {
635         cconvert->pub.color_convert = ycc_rgb_convert;
636         build_ycc_rgb_table(cinfo);
637       }
638     } else if (cinfo->jpeg_color_space == JCS_GRAYSCALE) {
639       cconvert->pub.color_convert = gray_rgb_convert;
640     } else if (cinfo->jpeg_color_space == JCS_RGB) {
641       if (rgb_red[cinfo->out_color_space] == 0 &&
642           rgb_green[cinfo->out_color_space] == 1 &&
643           rgb_blue[cinfo->out_color_space] == 2 &&
644           rgb_pixelsize[cinfo->out_color_space] == 3)
645         cconvert->pub.color_convert = null_convert;
646       else
647         cconvert->pub.color_convert = rgb_rgb_convert;
648     } else
649       ERREXIT(cinfo, JERR_CONVERSION_NOTIMPL);
650     break;
651
652   case JCS_CMYK:
653     cinfo->out_color_components = 4;
654     if (cinfo->jpeg_color_space == JCS_YCCK) {
655       cconvert->pub.color_convert = ycck_cmyk_convert;
656       build_ycc_rgb_table(cinfo);
657     } else if (cinfo->jpeg_color_space == JCS_CMYK) {
658       cconvert->pub.color_convert = null_convert;
659     } else
660       ERREXIT(cinfo, JERR_CONVERSION_NOTIMPL);
661     break;
662
663   default:
664     /* Permit null conversion to same output space */
665     if (cinfo->out_color_space == cinfo->jpeg_color_space) {
666       cinfo->out_color_components = cinfo->num_components;
667       cconvert->pub.color_convert = null_convert;
668     } else                      /* unsupported non-null conversion */
669       ERREXIT(cinfo, JERR_CONVERSION_NOTIMPL);
670     break;
671   }
672
673   if (cinfo->quantize_colors)
674     cinfo->output_components = 1; /* single colormapped output component */
675   else
676     cinfo->output_components = cinfo->out_color_components;
677 }