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, 2014-2015, D. R. Commander.
     10  * Copyright (C) 2013, Linaro Limited.
     11  * For conditions of distribution and use, see the accompanying README.ijg
     12  * file.
     13  *
     14  * This file contains output colorspace conversion routines.
     15  */
     16 
     17 #define JPEG_INTERNALS
     18 #include "jinclude.h"
     19 #include "jpeglib.h"
     20 #include "jsimd.h"
     21 #include "jconfigint.h"
     22 
     23 
     24 /* Private subobject */
     25 
     26 typedef struct {
     27   struct jpeg_color_deconverter pub; /* public fields */
     28 
     29   /* Private state for YCC->RGB conversion */
     30   int *Cr_r_tab;                /* => table for Cr to R conversion */
     31   int *Cb_b_tab;                /* => table for Cb to B conversion */
     32   JLONG *Cr_g_tab;              /* => table for Cr to G conversion */
     33   JLONG *Cb_g_tab;              /* => table for Cb to G conversion */
     34 
     35   /* Private state for RGB->Y conversion */
     36   JLONG *rgb_y_tab;             /* => table for RGB to Y conversion */
     37 } my_color_deconverter;
     38 
     39 typedef my_color_deconverter *my_cconvert_ptr;
     40 
     41 
     42 /**************** YCbCr -> RGB conversion: most common case **************/
     43 /****************   RGB -> Y   conversion: less common case **************/
     44 
     45 /*
     46  * YCbCr is defined per CCIR 601-1, except that Cb and Cr are
     47  * normalized to the range 0..MAXJSAMPLE rather than -0.5 .. 0.5.
     48  * The conversion equations to be implemented are therefore
     49  *
     50  *      R = Y                + 1.40200 * Cr
     51  *      G = Y - 0.34414 * Cb - 0.71414 * Cr
     52  *      B = Y + 1.77200 * Cb
     53  *
     54  *      Y = 0.29900 * R + 0.58700 * G + 0.11400 * B
     55  *
     56  * where Cb and Cr represent the incoming values less CENTERJSAMPLE.
     57  * (These numbers are derived from TIFF 6.0 section 21, dated 3-June-92.)
     58  *
     59  * To avoid floating-point arithmetic, we represent the fractional constants
     60  * as integers scaled up by 2^16 (about 4 digits precision); we have to divide
     61  * the products by 2^16, with appropriate rounding, to get the correct answer.
     62  * Notice that Y, being an integral input, does not contribute any fraction
     63  * so it need not participate in the rounding.
     64  *
     65  * For even more speed, we avoid doing any multiplications in the inner loop
     66  * by precalculating the constants times Cb and Cr for all possible values.
     67  * For 8-bit JSAMPLEs this is very reasonable (only 256 entries per table);
     68  * for 12-bit samples it is still acceptable.  It's not very reasonable for
     69  * 16-bit samples, but if you want lossless storage you shouldn't be changing
     70  * colorspace anyway.
     71  * The Cr=>R and Cb=>B values can be rounded to integers in advance; the
     72  * values for the G calculation are left scaled up, since we must add them
     73  * together before rounding.
     74  */
     75 
     76 #define SCALEBITS       16      /* speediest right-shift on some machines */
     77 #define ONE_HALF        ((JLONG)1 << (SCALEBITS - 1))
     78 #define FIX(x)          ((JLONG)((x) * (1L << SCALEBITS) + 0.5))
     79 
     80 /* We allocate one big table for RGB->Y conversion and divide it up into
     81  * three parts, instead of doing three alloc_small requests.  This lets us
     82  * use a single table base address, which can be held in a register in the
     83  * inner loops on many machines (more than can hold all three addresses,
     84  * anyway).
     85  */
     86 
     87 #define R_Y_OFF         0                       /* offset to R => Y section */
     88 #define G_Y_OFF         (1 * (MAXJSAMPLE + 1))  /* offset to G => Y section */
     89 #define B_Y_OFF         (2 * (MAXJSAMPLE + 1))  /* etc. */
     90 #define TABLE_SIZE      (3 * (MAXJSAMPLE + 1))
     91 
     92 
     93 /* Include inline routines for colorspace extensions */
     94 
     95 #include "jdcolext.c"
     96 #undef RGB_RED
     97 #undef RGB_GREEN
     98 #undef RGB_BLUE
     99 #undef RGB_PIXELSIZE
    100 
    101 #define RGB_RED  EXT_RGB_RED
    102 #define RGB_GREEN  EXT_RGB_GREEN
    103 #define RGB_BLUE  EXT_RGB_BLUE
    104 #define RGB_PIXELSIZE  EXT_RGB_PIXELSIZE
    105 #define ycc_rgb_convert_internal  ycc_extrgb_convert_internal
    106 #define gray_rgb_convert_internal  gray_extrgb_convert_internal
    107 #define rgb_rgb_convert_internal  rgb_extrgb_convert_internal
    108 #include "jdcolext.c"
    109 #undef RGB_RED
    110 #undef RGB_GREEN
    111 #undef RGB_BLUE
    112 #undef RGB_PIXELSIZE
    113 #undef ycc_rgb_convert_internal
    114 #undef gray_rgb_convert_internal
    115 #undef rgb_rgb_convert_internal
    116 
    117 #define RGB_RED  EXT_RGBX_RED
    118 #define RGB_GREEN  EXT_RGBX_GREEN
    119 #define RGB_BLUE  EXT_RGBX_BLUE
    120 #define RGB_ALPHA  3
    121 #define RGB_PIXELSIZE  EXT_RGBX_PIXELSIZE
    122 #define ycc_rgb_convert_internal  ycc_extrgbx_convert_internal
    123 #define gray_rgb_convert_internal  gray_extrgbx_convert_internal
    124 #define rgb_rgb_convert_internal  rgb_extrgbx_convert_internal
    125 #include "jdcolext.c"
    126 #undef RGB_RED
    127 #undef RGB_GREEN
    128 #undef RGB_BLUE
    129 #undef RGB_ALPHA
    130 #undef RGB_PIXELSIZE
    131 #undef ycc_rgb_convert_internal
    132 #undef gray_rgb_convert_internal
    133 #undef rgb_rgb_convert_internal
    134 
    135 #define RGB_RED  EXT_BGR_RED
    136 #define RGB_GREEN  EXT_BGR_GREEN
    137 #define RGB_BLUE  EXT_BGR_BLUE
    138 #define RGB_PIXELSIZE  EXT_BGR_PIXELSIZE
    139 #define ycc_rgb_convert_internal  ycc_extbgr_convert_internal
    140 #define gray_rgb_convert_internal  gray_extbgr_convert_internal
    141 #define rgb_rgb_convert_internal  rgb_extbgr_convert_internal
    142 #include "jdcolext.c"
    143 #undef RGB_RED
    144 #undef RGB_GREEN
    145 #undef RGB_BLUE
    146 #undef RGB_PIXELSIZE
    147 #undef ycc_rgb_convert_internal
    148 #undef gray_rgb_convert_internal
    149 #undef rgb_rgb_convert_internal
    150 
    151 #define RGB_RED  EXT_BGRX_RED
    152 #define RGB_GREEN  EXT_BGRX_GREEN
    153 #define RGB_BLUE  EXT_BGRX_BLUE
    154 #define RGB_ALPHA  3
    155 #define RGB_PIXELSIZE  EXT_BGRX_PIXELSIZE
    156 #define ycc_rgb_convert_internal  ycc_extbgrx_convert_internal
    157 #define gray_rgb_convert_internal  gray_extbgrx_convert_internal
    158 #define rgb_rgb_convert_internal  rgb_extbgrx_convert_internal
    159 #include "jdcolext.c"
    160 #undef RGB_RED
    161 #undef RGB_GREEN
    162 #undef RGB_BLUE
    163 #undef RGB_ALPHA
    164 #undef RGB_PIXELSIZE
    165 #undef ycc_rgb_convert_internal
    166 #undef gray_rgb_convert_internal
    167 #undef rgb_rgb_convert_internal
    168 
    169 #define RGB_RED  EXT_XBGR_RED
    170 #define RGB_GREEN  EXT_XBGR_GREEN
    171 #define RGB_BLUE  EXT_XBGR_BLUE
    172 #define RGB_ALPHA  0
    173 #define RGB_PIXELSIZE  EXT_XBGR_PIXELSIZE
    174 #define ycc_rgb_convert_internal  ycc_extxbgr_convert_internal
    175 #define gray_rgb_convert_internal  gray_extxbgr_convert_internal
    176 #define rgb_rgb_convert_internal  rgb_extxbgr_convert_internal
    177 #include "jdcolext.c"
    178 #undef RGB_RED
    179 #undef RGB_GREEN
    180 #undef RGB_BLUE
    181 #undef RGB_ALPHA
    182 #undef RGB_PIXELSIZE
    183 #undef ycc_rgb_convert_internal
    184 #undef gray_rgb_convert_internal
    185 #undef rgb_rgb_convert_internal
    186 
    187 #define RGB_RED  EXT_XRGB_RED
    188 #define RGB_GREEN  EXT_XRGB_GREEN
    189 #define RGB_BLUE  EXT_XRGB_BLUE
    190 #define RGB_ALPHA  0
    191 #define RGB_PIXELSIZE  EXT_XRGB_PIXELSIZE
    192 #define ycc_rgb_convert_internal  ycc_extxrgb_convert_internal
    193 #define gray_rgb_convert_internal  gray_extxrgb_convert_internal
    194 #define rgb_rgb_convert_internal  rgb_extxrgb_convert_internal
    195 #include "jdcolext.c"
    196 #undef RGB_RED
    197 #undef RGB_GREEN
    198 #undef RGB_BLUE
    199 #undef RGB_ALPHA
    200 #undef RGB_PIXELSIZE
    201 #undef ycc_rgb_convert_internal
    202 #undef gray_rgb_convert_internal
    203 #undef rgb_rgb_convert_internal
    204 
    205 
    206 /*
    207  * Initialize tables for YCC->RGB colorspace conversion.
    208  */
    209 
    210 LOCAL(void)
    211 build_ycc_rgb_table(j_decompress_ptr cinfo)
    212 {
    213   my_cconvert_ptr cconvert = (my_cconvert_ptr)cinfo->cconvert;
    214   int i;
    215   JLONG x;
    216   SHIFT_TEMPS
    217 
    218   cconvert->Cr_r_tab = (int *)
    219     (*cinfo->mem->alloc_small) ((j_common_ptr)cinfo, JPOOL_IMAGE,
    220                                 (MAXJSAMPLE + 1) * sizeof(int));
    221   cconvert->Cb_b_tab = (int *)
    222     (*cinfo->mem->alloc_small) ((j_common_ptr)cinfo, JPOOL_IMAGE,
    223                                 (MAXJSAMPLE + 1) * sizeof(int));
    224   cconvert->Cr_g_tab = (JLONG *)
    225     (*cinfo->mem->alloc_small) ((j_common_ptr)cinfo, JPOOL_IMAGE,
    226                                 (MAXJSAMPLE + 1) * sizeof(JLONG));
    227   cconvert->Cb_g_tab = (JLONG *)
    228     (*cinfo->mem->alloc_small) ((j_common_ptr)cinfo, JPOOL_IMAGE,
    229                                 (MAXJSAMPLE + 1) * sizeof(JLONG));
    230 
    231   for (i = 0, x = -CENTERJSAMPLE; i <= MAXJSAMPLE; i++, x++) {
    232     /* i is the actual input pixel value, in the range 0..MAXJSAMPLE */
    233     /* The Cb or Cr value we are thinking of is x = i - CENTERJSAMPLE */
    234     /* Cr=>R value is nearest int to 1.40200 * x */
    235     cconvert->Cr_r_tab[i] = (int)
    236                     RIGHT_SHIFT(FIX(1.40200) * x + ONE_HALF, SCALEBITS);
    237     /* Cb=>B value is nearest int to 1.77200 * x */
    238     cconvert->Cb_b_tab[i] = (int)
    239                     RIGHT_SHIFT(FIX(1.77200) * x + ONE_HALF, SCALEBITS);
    240     /* Cr=>G value is scaled-up -0.71414 * x */
    241     cconvert->Cr_g_tab[i] = (-FIX(0.71414)) * x;
    242     /* Cb=>G value is scaled-up -0.34414 * x */
    243     /* We also add in ONE_HALF so that need not do it in inner loop */
    244     cconvert->Cb_g_tab[i] = (-FIX(0.34414)) * x + ONE_HALF;
    245   }
    246 }
    247 
    248 
    249 /*
    250  * Convert some rows of samples to the output colorspace.
    251  */
    252 
    253 METHODDEF(void)
    254 ycc_rgb_convert(j_decompress_ptr cinfo, JSAMPIMAGE input_buf,
    255                 JDIMENSION input_row, JSAMPARRAY output_buf, int num_rows)
    256 {
    257   switch (cinfo->out_color_space) {
    258   case JCS_EXT_RGB:
    259     ycc_extrgb_convert_internal(cinfo, input_buf, input_row, output_buf,
    260                                 num_rows);
    261     break;
    262   case JCS_EXT_RGBX:
    263   case JCS_EXT_RGBA:
    264     ycc_extrgbx_convert_internal(cinfo, input_buf, input_row, output_buf,
    265                                  num_rows);
    266     break;
    267   case JCS_EXT_BGR:
    268     ycc_extbgr_convert_internal(cinfo, input_buf, input_row, output_buf,
    269                                 num_rows);
    270     break;
    271   case JCS_EXT_BGRX:
    272   case JCS_EXT_BGRA:
    273     ycc_extbgrx_convert_internal(cinfo, input_buf, input_row, output_buf,
    274                                  num_rows);
    275     break;
    276   case JCS_EXT_XBGR:
    277   case JCS_EXT_ABGR:
    278     ycc_extxbgr_convert_internal(cinfo, input_buf, input_row, output_buf,
    279                                  num_rows);
    280     break;
    281   case JCS_EXT_XRGB:
    282   case JCS_EXT_ARGB:
    283     ycc_extxrgb_convert_internal(cinfo, input_buf, input_row, output_buf,
    284                                  num_rows);
    285     break;
    286   default:
    287     ycc_rgb_convert_internal(cinfo, input_buf, input_row, output_buf,
    288                              num_rows);
    289     break;
    290   }
    291 }
    292 
    293 
    294 /**************** Cases other than YCbCr -> RGB **************/
    295 
    296 
    297 /*
    298  * Initialize for RGB->grayscale colorspace conversion.
    299  */
    300 
    301 LOCAL(void)
    302 build_rgb_y_table(j_decompress_ptr cinfo)
    303 {
    304   my_cconvert_ptr cconvert = (my_cconvert_ptr)cinfo->cconvert;
    305   JLONG *rgb_y_tab;
    306   JLONG i;
    307 
    308   /* Allocate and fill in the conversion tables. */
    309   cconvert->rgb_y_tab = rgb_y_tab = (JLONG *)
    310     (*cinfo->mem->alloc_small) ((j_common_ptr)cinfo, JPOOL_IMAGE,
    311                                 (TABLE_SIZE * sizeof(JLONG)));
    312 
    313   for (i = 0; i <= MAXJSAMPLE; i++) {
    314     rgb_y_tab[i + R_Y_OFF] = FIX(0.29900) * i;
    315     rgb_y_tab[i + G_Y_OFF] = FIX(0.58700) * i;
    316     rgb_y_tab[i + B_Y_OFF] = FIX(0.11400) * i + ONE_HALF;
    317   }
    318 }
    319 
    320 
    321 /*
    322  * Convert RGB to grayscale.
    323  */
    324 
    325 METHODDEF(void)
    326 rgb_gray_convert(j_decompress_ptr cinfo, JSAMPIMAGE input_buf,
    327                  JDIMENSION input_row, 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 JLONG *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)((ctab[r + R_Y_OFF] + ctab[g + G_Y_OFF] +
    349                                ctab[b + B_Y_OFF]) >> SCALEBITS);
    350     }
    351   }
    352 }
    353 
    354 
    355 /*
    356  * Color conversion for no colorspace change: just copy the data,
    357  * converting from separate-planes to interleaved representation.
    358  */
    359 
    360 METHODDEF(void)
    361 null_convert(j_decompress_ptr cinfo, JSAMPIMAGE input_buf,
    362              JDIMENSION input_row, JSAMPARRAY output_buf, int num_rows)
    363 {
    364   register JSAMPROW inptr, inptr0, inptr1, inptr2, inptr3, outptr;
    365   register JDIMENSION col;
    366   register int num_components = cinfo->num_components;
    367   JDIMENSION num_cols = cinfo->output_width;
    368   int ci;
    369 
    370   if (num_components == 3) {
    371     while (--num_rows >= 0) {
    372       inptr0 = input_buf[0][input_row];
    373       inptr1 = input_buf[1][input_row];
    374       inptr2 = input_buf[2][input_row];
    375       input_row++;
    376       outptr = *output_buf++;
    377       for (col = 0; col < num_cols; col++) {
    378         *outptr++ = inptr0[col];
    379         *outptr++ = inptr1[col];
    380         *outptr++ = inptr2[col];
    381       }
    382     }
    383   } else if (num_components == 4) {
    384     while (--num_rows >= 0) {
    385       inptr0 = input_buf[0][input_row];
    386       inptr1 = input_buf[1][input_row];
    387       inptr2 = input_buf[2][input_row];
    388       inptr3 = input_buf[3][input_row];
    389       input_row++;
    390       outptr = *output_buf++;
    391       for (col = 0; col < num_cols; col++) {
    392         *outptr++ = inptr0[col];
    393         *outptr++ = inptr1[col];
    394         *outptr++ = inptr2[col];
    395         *outptr++ = inptr3[col];
    396       }
    397     }
    398   } else {
    399     while (--num_rows >= 0) {
    400       for (ci = 0; ci < num_components; ci++) {
    401         inptr = input_buf[ci][input_row];
    402         outptr = *output_buf;
    403         for (col = 0; col < num_cols; col++) {
    404           outptr[ci] = inptr[col];
    405           outptr += num_components;
    406         }
    407       }
    408       output_buf++;
    409       input_row++;
    410     }
    411   }
    412 }
    413 
    414 
    415 /*
    416  * Color conversion for grayscale: just copy the data.
    417  * This also works for YCbCr -> grayscale conversion, in which
    418  * we just copy the Y (luminance) component and ignore chrominance.
    419  */
    420 
    421 METHODDEF(void)
    422 grayscale_convert(j_decompress_ptr cinfo, JSAMPIMAGE input_buf,
    423                   JDIMENSION input_row, JSAMPARRAY output_buf, int num_rows)
    424 {
    425   jcopy_sample_rows(input_buf[0], (int)input_row, output_buf, 0, num_rows,
    426                     cinfo->output_width);
    427 }
    428 
    429 
    430 /*
    431  * Convert grayscale to RGB
    432  */
    433 
    434 METHODDEF(void)
    435 gray_rgb_convert(j_decompress_ptr cinfo, JSAMPIMAGE input_buf,
    436                  JDIMENSION input_row, JSAMPARRAY output_buf, int num_rows)
    437 {
    438   switch (cinfo->out_color_space) {
    439   case JCS_EXT_RGB:
    440     gray_extrgb_convert_internal(cinfo, input_buf, input_row, output_buf,
    441                                  num_rows);
    442     break;
    443   case JCS_EXT_RGBX:
    444   case JCS_EXT_RGBA:
    445     gray_extrgbx_convert_internal(cinfo, input_buf, input_row, output_buf,
    446                                   num_rows);
    447     break;
    448   case JCS_EXT_BGR:
    449     gray_extbgr_convert_internal(cinfo, input_buf, input_row, output_buf,
    450                                  num_rows);
    451     break;
    452   case JCS_EXT_BGRX:
    453   case JCS_EXT_BGRA:
    454     gray_extbgrx_convert_internal(cinfo, input_buf, input_row, output_buf,
    455                                   num_rows);
    456     break;
    457   case JCS_EXT_XBGR:
    458   case JCS_EXT_ABGR:
    459     gray_extxbgr_convert_internal(cinfo, input_buf, input_row, output_buf,
    460                                   num_rows);
    461     break;
    462   case JCS_EXT_XRGB:
    463   case JCS_EXT_ARGB:
    464     gray_extxrgb_convert_internal(cinfo, input_buf, input_row, output_buf,
    465                                   num_rows);
    466     break;
    467   default:
    468     gray_rgb_convert_internal(cinfo, input_buf, input_row, output_buf,
    469                               num_rows);
    470     break;
    471   }
    472 }
    473 
    474 
    475 /*
    476  * Convert plain RGB to extended RGB
    477  */
    478 
    479 METHODDEF(void)
    480 rgb_rgb_convert(j_decompress_ptr cinfo, JSAMPIMAGE input_buf,
    481                 JDIMENSION input_row, JSAMPARRAY output_buf, int num_rows)
    482 {
    483   switch (cinfo->out_color_space) {
    484   case JCS_EXT_RGB:
    485     rgb_extrgb_convert_internal(cinfo, input_buf, input_row, output_buf,
    486                                 num_rows);
    487     break;
    488   case JCS_EXT_RGBX:
    489   case JCS_EXT_RGBA:
    490     rgb_extrgbx_convert_internal(cinfo, input_buf, input_row, output_buf,
    491                                  num_rows);
    492     break;
    493   case JCS_EXT_BGR:
    494     rgb_extbgr_convert_internal(cinfo, input_buf, input_row, output_buf,
    495                                 num_rows);
    496     break;
    497   case JCS_EXT_BGRX:
    498   case JCS_EXT_BGRA:
    499     rgb_extbgrx_convert_internal(cinfo, input_buf, input_row, output_buf,
    500                                  num_rows);
    501     break;
    502   case JCS_EXT_XBGR:
    503   case JCS_EXT_ABGR:
    504     rgb_extxbgr_convert_internal(cinfo, input_buf, input_row, output_buf,
    505                                  num_rows);
    506     break;
    507   case JCS_EXT_XRGB:
    508   case JCS_EXT_ARGB:
    509     rgb_extxrgb_convert_internal(cinfo, input_buf, input_row, output_buf,
    510                                  num_rows);
    511     break;
    512   default:
    513     rgb_rgb_convert_internal(cinfo, input_buf, input_row, output_buf,
    514                              num_rows);
    515     break;
    516   }
    517 }
    518 
    519 
    520 /*
    521  * Adobe-style YCCK->CMYK conversion.
    522  * We convert YCbCr to R=1-C, G=1-M, and B=1-Y using the same
    523  * conversion as above, while passing K (black) unchanged.
    524  * We assume build_ycc_rgb_table has been called.
    525  */
    526 
    527 METHODDEF(void)
    528 ycck_cmyk_convert(j_decompress_ptr cinfo, JSAMPIMAGE input_buf,
    529                   JDIMENSION input_row, JSAMPARRAY output_buf, int num_rows)
    530 {
    531   my_cconvert_ptr cconvert = (my_cconvert_ptr)cinfo->cconvert;
    532   register int y, cb, cr;
    533   register JSAMPROW outptr;
    534   register JSAMPROW inptr0, inptr1, inptr2, inptr3;
    535   register JDIMENSION col;
    536   JDIMENSION num_cols = cinfo->output_width;
    537   /* copy these pointers into registers if possible */
    538   register JSAMPLE *range_limit = cinfo->sample_range_limit;
    539   register int *Crrtab = cconvert->Cr_r_tab;
    540   register int *Cbbtab = cconvert->Cb_b_tab;
    541   register JLONG *Crgtab = cconvert->Cr_g_tab;
    542   register JLONG *Cbgtab = cconvert->Cb_g_tab;
    543   SHIFT_TEMPS
    544 
    545   while (--num_rows >= 0) {
    546     inptr0 = input_buf[0][input_row];
    547     inptr1 = input_buf[1][input_row];
    548     inptr2 = input_buf[2][input_row];
    549     inptr3 = input_buf[3][input_row];
    550     input_row++;
    551     outptr = *output_buf++;
    552     for (col = 0; col < num_cols; col++) {
    553       y  = GETJSAMPLE(inptr0[col]);
    554       cb = GETJSAMPLE(inptr1[col]);
    555       cr = GETJSAMPLE(inptr2[col]);
    556       /* Range-limiting is essential due to noise introduced by DCT losses. */
    557       outptr[0] = range_limit[MAXJSAMPLE - (y + Crrtab[cr])];   /* red */
    558       outptr[1] = range_limit[MAXJSAMPLE - (y +                 /* green */
    559                               ((int)RIGHT_SHIFT(Cbgtab[cb] + Crgtab[cr],
    560                                                  SCALEBITS)))];
    561       outptr[2] = range_limit[MAXJSAMPLE - (y + Cbbtab[cb])];   /* blue */
    562       /* K passes through unchanged */
    563       outptr[3] = inptr3[col];  /* don't need GETJSAMPLE here */
    564       outptr += 4;
    565     }
    566   }
    567 }
    568 
    569 
    570 /*
    571  * RGB565 conversion
    572  */
    573 
    574 #define PACK_SHORT_565_LE(r, g, b)  ((((r) << 8) & 0xF800) | \
    575                                      (((g) << 3) & 0x7E0) | ((b) >> 3))
    576 #define PACK_SHORT_565_BE(r, g, b)  (((r) & 0xF8) | ((g) >> 5) | \
    577                                      (((g) << 11) & 0xE000) | \
    578                                      (((b) << 5) & 0x1F00))
    579 
    580 #define PACK_TWO_PIXELS_LE(l, r)    ((r << 16) | l)
    581 #define PACK_TWO_PIXELS_BE(l, r)    ((l << 16) | r)
    582 
    583 #define PACK_NEED_ALIGNMENT(ptr)    (((size_t)(ptr)) & 3)
    584 
    585 #define WRITE_TWO_ALIGNED_PIXELS(addr, pixels)  ((*(int *)(addr)) = pixels)
    586 
    587 #define DITHER_565_R(r, dither)  ((r) + ((dither) & 0xFF))
    588 #define DITHER_565_G(g, dither)  ((g) + (((dither) & 0xFF) >> 1))
    589 #define DITHER_565_B(b, dither)  ((b) + ((dither) & 0xFF))
    590 
    591 
    592 /* Declarations for ordered dithering
    593  *
    594  * We use a 4x4 ordered dither array packed into 32 bits.  This array is
    595  * sufficient for dithering RGB888 to RGB565.
    596  */
    597 
    598 #define DITHER_MASK       0x3
    599 #define DITHER_ROTATE(x)  ((((x) & 0xFF) << 24) | (((x) >> 8) & 0x00FFFFFF))
    600 static const JLONG dither_matrix[4] = {
    601   0x0008020A,
    602   0x0C040E06,
    603   0x030B0109,
    604   0x0F070D05
    605 };
    606 
    607 
    608 static INLINE boolean is_big_endian(void)
    609 {
    610   int test_value = 1;
    611   if (*(char *)&test_value != 1)
    612     return TRUE;
    613   return FALSE;
    614 }
    615 
    616 
    617 /* Include inline routines for RGB565 conversion */
    618 
    619 #define PACK_SHORT_565  PACK_SHORT_565_LE
    620 #define PACK_TWO_PIXELS  PACK_TWO_PIXELS_LE
    621 #define ycc_rgb565_convert_internal  ycc_rgb565_convert_le
    622 #define ycc_rgb565D_convert_internal  ycc_rgb565D_convert_le
    623 #define rgb_rgb565_convert_internal  rgb_rgb565_convert_le
    624 #define rgb_rgb565D_convert_internal  rgb_rgb565D_convert_le
    625 #define gray_rgb565_convert_internal  gray_rgb565_convert_le
    626 #define gray_rgb565D_convert_internal  gray_rgb565D_convert_le
    627 #include "jdcol565.c"
    628 #undef PACK_SHORT_565
    629 #undef PACK_TWO_PIXELS
    630 #undef ycc_rgb565_convert_internal
    631 #undef ycc_rgb565D_convert_internal
    632 #undef rgb_rgb565_convert_internal
    633 #undef rgb_rgb565D_convert_internal
    634 #undef gray_rgb565_convert_internal
    635 #undef gray_rgb565D_convert_internal
    636 
    637 #define PACK_SHORT_565  PACK_SHORT_565_BE
    638 #define PACK_TWO_PIXELS  PACK_TWO_PIXELS_BE
    639 #define ycc_rgb565_convert_internal  ycc_rgb565_convert_be
    640 #define ycc_rgb565D_convert_internal  ycc_rgb565D_convert_be
    641 #define rgb_rgb565_convert_internal  rgb_rgb565_convert_be
    642 #define rgb_rgb565D_convert_internal  rgb_rgb565D_convert_be
    643 #define gray_rgb565_convert_internal  gray_rgb565_convert_be
    644 #define gray_rgb565D_convert_internal  gray_rgb565D_convert_be
    645 #include "jdcol565.c"
    646 #undef PACK_SHORT_565
    647 #undef PACK_TWO_PIXELS
    648 #undef ycc_rgb565_convert_internal
    649 #undef ycc_rgb565D_convert_internal
    650 #undef rgb_rgb565_convert_internal
    651 #undef rgb_rgb565D_convert_internal
    652 #undef gray_rgb565_convert_internal
    653 #undef gray_rgb565D_convert_internal
    654 
    655 
    656 METHODDEF(void)
    657 ycc_rgb565_convert(j_decompress_ptr cinfo, JSAMPIMAGE input_buf,
    658                    JDIMENSION input_row, JSAMPARRAY output_buf, int num_rows)
    659 {
    660   if (is_big_endian())
    661     ycc_rgb565_convert_be(cinfo, input_buf, input_row, output_buf, num_rows);
    662   else
    663     ycc_rgb565_convert_le(cinfo, input_buf, input_row, output_buf, num_rows);
    664 }
    665 
    666 
    667 METHODDEF(void)
    668 ycc_rgb565D_convert(j_decompress_ptr cinfo, JSAMPIMAGE input_buf,
    669                     JDIMENSION input_row, JSAMPARRAY output_buf, int num_rows)
    670 {
    671   if (is_big_endian())
    672     ycc_rgb565D_convert_be(cinfo, input_buf, input_row, output_buf, num_rows);
    673   else
    674     ycc_rgb565D_convert_le(cinfo, input_buf, input_row, output_buf, num_rows);
    675 }
    676 
    677 
    678 METHODDEF(void)
    679 rgb_rgb565_convert(j_decompress_ptr cinfo, JSAMPIMAGE input_buf,
    680                    JDIMENSION input_row, JSAMPARRAY output_buf, int num_rows)
    681 {
    682   if (is_big_endian())
    683     rgb_rgb565_convert_be(cinfo, input_buf, input_row, output_buf, num_rows);
    684   else
    685     rgb_rgb565_convert_le(cinfo, input_buf, input_row, output_buf, num_rows);
    686 }
    687 
    688 
    689 METHODDEF(void)
    690 rgb_rgb565D_convert(j_decompress_ptr cinfo, JSAMPIMAGE input_buf,
    691                     JDIMENSION input_row, JSAMPARRAY output_buf, int num_rows)
    692 {
    693   if (is_big_endian())
    694     rgb_rgb565D_convert_be(cinfo, input_buf, input_row, output_buf, num_rows);
    695   else
    696     rgb_rgb565D_convert_le(cinfo, input_buf, input_row, output_buf, num_rows);
    697 }
    698 
    699 
    700 METHODDEF(void)
    701 gray_rgb565_convert(j_decompress_ptr cinfo, JSAMPIMAGE input_buf,
    702                     JDIMENSION input_row, JSAMPARRAY output_buf, int num_rows)
    703 {
    704   if (is_big_endian())
    705     gray_rgb565_convert_be(cinfo, input_buf, input_row, output_buf, num_rows);
    706   else
    707     gray_rgb565_convert_le(cinfo, input_buf, input_row, output_buf, num_rows);
    708 }
    709 
    710 
    711 METHODDEF(void)
    712 gray_rgb565D_convert(j_decompress_ptr cinfo, JSAMPIMAGE input_buf,
    713                      JDIMENSION input_row, JSAMPARRAY output_buf, int num_rows)
    714 {
    715   if (is_big_endian())
    716     gray_rgb565D_convert_be(cinfo, input_buf, input_row, output_buf, num_rows);
    717   else
    718     gray_rgb565D_convert_le(cinfo, input_buf, input_row, output_buf, num_rows);
    719 }
    720 
    721 
    722 /*
    723  * Empty method for start_pass.
    724  */
    725 
    726 METHODDEF(void)
    727 start_pass_dcolor(j_decompress_ptr cinfo)
    728 {
    729   /* no work needed */
    730 }
    731 
    732 
    733 /*
    734  * Module initialization routine for output colorspace conversion.
    735  */
    736 
    737 GLOBAL(void)
    738 jinit_color_deconverter(j_decompress_ptr cinfo)
    739 {
    740   my_cconvert_ptr cconvert;
    741   int ci;
    742 
    743   cconvert = (my_cconvert_ptr)
    744     (*cinfo->mem->alloc_small) ((j_common_ptr)cinfo, JPOOL_IMAGE,
    745                                 sizeof(my_color_deconverter));
    746   cinfo->cconvert = (struct jpeg_color_deconverter *)cconvert;
    747   cconvert->pub.start_pass = start_pass_dcolor;
    748 
    749   /* Make sure num_components agrees with jpeg_color_space */
    750   switch (cinfo->jpeg_color_space) {
    751   case JCS_GRAYSCALE:
    752     if (cinfo->num_components != 1)
    753       ERREXIT(cinfo, JERR_BAD_J_COLORSPACE);
    754     break;
    755 
    756   case JCS_RGB:
    757   case JCS_YCbCr:
    758     if (cinfo->num_components != 3)
    759       ERREXIT(cinfo, JERR_BAD_J_COLORSPACE);
    760     break;
    761 
    762   case JCS_CMYK:
    763   case JCS_YCCK:
    764     if (cinfo->num_components != 4)
    765       ERREXIT(cinfo, JERR_BAD_J_COLORSPACE);
    766     break;
    767 
    768   default:                      /* JCS_UNKNOWN can be anything */
    769     if (cinfo->num_components < 1)
    770       ERREXIT(cinfo, JERR_BAD_J_COLORSPACE);
    771     break;
    772   }
    773 
    774   /* Set out_color_components and conversion method based on requested space.
    775    * Also clear the component_needed flags for any unused components,
    776    * so that earlier pipeline stages can avoid useless computation.
    777    */
    778 
    779   switch (cinfo->out_color_space) {
    780   case JCS_GRAYSCALE:
    781     cinfo->out_color_components = 1;
    782     if (cinfo->jpeg_color_space == JCS_GRAYSCALE ||
    783         cinfo->jpeg_color_space == JCS_YCbCr) {
    784       cconvert->pub.color_convert = grayscale_convert;
    785       /* For color->grayscale conversion, only the Y (0) component is needed */
    786       for (ci = 1; ci < cinfo->num_components; ci++)
    787         cinfo->comp_info[ci].component_needed = FALSE;
    788     } else if (cinfo->jpeg_color_space == JCS_RGB) {
    789       cconvert->pub.color_convert = rgb_gray_convert;
    790       build_rgb_y_table(cinfo);
    791     } else
    792       ERREXIT(cinfo, JERR_CONVERSION_NOTIMPL);
    793     break;
    794 
    795   case JCS_RGB:
    796   case JCS_EXT_RGB:
    797   case JCS_EXT_RGBX:
    798   case JCS_EXT_BGR:
    799   case JCS_EXT_BGRX:
    800   case JCS_EXT_XBGR:
    801   case JCS_EXT_XRGB:
    802   case JCS_EXT_RGBA:
    803   case JCS_EXT_BGRA:
    804   case JCS_EXT_ABGR:
    805   case JCS_EXT_ARGB:
    806     cinfo->out_color_components = rgb_pixelsize[cinfo->out_color_space];
    807     if (cinfo->jpeg_color_space == JCS_YCbCr) {
    808       if (jsimd_can_ycc_rgb())
    809         cconvert->pub.color_convert = jsimd_ycc_rgb_convert;
    810       else {
    811         cconvert->pub.color_convert = ycc_rgb_convert;
    812         build_ycc_rgb_table(cinfo);
    813       }
    814     } else if (cinfo->jpeg_color_space == JCS_GRAYSCALE) {
    815       cconvert->pub.color_convert = gray_rgb_convert;
    816     } else if (cinfo->jpeg_color_space == JCS_RGB) {
    817       if (rgb_red[cinfo->out_color_space] == 0 &&
    818           rgb_green[cinfo->out_color_space] == 1 &&
    819           rgb_blue[cinfo->out_color_space] == 2 &&
    820           rgb_pixelsize[cinfo->out_color_space] == 3)
    821         cconvert->pub.color_convert = null_convert;
    822       else
    823         cconvert->pub.color_convert = rgb_rgb_convert;
    824     } else
    825       ERREXIT(cinfo, JERR_CONVERSION_NOTIMPL);
    826     break;
    827 
    828   case JCS_RGB565:
    829     cinfo->out_color_components = 3;
    830     if (cinfo->dither_mode == JDITHER_NONE) {
    831       if (cinfo->jpeg_color_space == JCS_YCbCr) {
    832         if (jsimd_can_ycc_rgb565())
    833           cconvert->pub.color_convert = jsimd_ycc_rgb565_convert;
    834         else {
    835           cconvert->pub.color_convert = ycc_rgb565_convert;
    836           build_ycc_rgb_table(cinfo);
    837         }
    838       } else if (cinfo->jpeg_color_space == JCS_GRAYSCALE) {
    839         cconvert->pub.color_convert = gray_rgb565_convert;
    840       } else if (cinfo->jpeg_color_space == JCS_RGB) {
    841         cconvert->pub.color_convert = rgb_rgb565_convert;
    842       } else
    843         ERREXIT(cinfo, JERR_CONVERSION_NOTIMPL);
    844     } else {
    845       /* only ordered dithering is supported */
    846       if (cinfo->jpeg_color_space == JCS_YCbCr) {
    847         cconvert->pub.color_convert = ycc_rgb565D_convert;
    848         build_ycc_rgb_table(cinfo);
    849       } else if (cinfo->jpeg_color_space == JCS_GRAYSCALE) {
    850         cconvert->pub.color_convert = gray_rgb565D_convert;
    851       } else if (cinfo->jpeg_color_space == JCS_RGB) {
    852         cconvert->pub.color_convert = rgb_rgb565D_convert;
    853       } else
    854         ERREXIT(cinfo, JERR_CONVERSION_NOTIMPL);
    855     }
    856     break;
    857 
    858   case JCS_CMYK:
    859     cinfo->out_color_components = 4;
    860     if (cinfo->jpeg_color_space == JCS_YCCK) {
    861       cconvert->pub.color_convert = ycck_cmyk_convert;
    862       build_ycc_rgb_table(cinfo);
    863     } else if (cinfo->jpeg_color_space == JCS_CMYK) {
    864       cconvert->pub.color_convert = null_convert;
    865     } else
    866       ERREXIT(cinfo, JERR_CONVERSION_NOTIMPL);
    867     break;
    868 
    869   default:
    870     /* Permit null conversion to same output space */
    871     if (cinfo->out_color_space == cinfo->jpeg_color_space) {
    872       cinfo->out_color_components = cinfo->num_components;
    873       cconvert->pub.color_convert = null_convert;
    874     } else                      /* unsupported non-null conversion */
    875       ERREXIT(cinfo, JERR_CONVERSION_NOTIMPL);
    876     break;
    877   }
    878 
    879   if (cinfo->quantize_colors)
    880     cinfo->output_components = 1; /* single colormapped output component */
    881   else
    882     cinfo->output_components = cinfo->out_color_components;
    883 }
    884