Home | History | Annotate | Download | only in libjpeg_turbo
      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 (at) 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 }
    678