tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

jccolor.c (23875B)


      1 /*
      2 * jccolor.c
      3 *
      4 * This file was part of the Independent JPEG Group's software:
      5 * Copyright (C) 1991-1996, Thomas G. Lane.
      6 * libjpeg-turbo Modifications:
      7 * Copyright 2009 Pierre Ossman <ossman@cendio.se> for Cendio AB
      8 * Copyright (C) 2009-2012, 2015, 2022, D. R. Commander.
      9 * Copyright (C) 2014, MIPS Technologies, Inc., California.
     10 * For conditions of distribution and use, see the accompanying README.ijg
     11 * file.
     12 *
     13 * This file contains input colorspace conversion routines.
     14 */
     15 
     16 #define JPEG_INTERNALS
     17 #include "jinclude.h"
     18 #include "jpeglib.h"
     19 #include "jsimd.h"
     20 #include "jsamplecomp.h"
     21 
     22 
     23 #if BITS_IN_JSAMPLE != 16 || defined(C_LOSSLESS_SUPPORTED)
     24 
     25 /* Private subobject */
     26 
     27 typedef struct {
     28  struct jpeg_color_converter pub; /* public fields */
     29 
     30 #if BITS_IN_JSAMPLE != 16
     31  /* Private state for RGB->YCC conversion */
     32  JLONG *rgb_ycc_tab;           /* => table for RGB to YCbCr conversion */
     33 #endif
     34 } my_color_converter;
     35 
     36 typedef my_color_converter *my_cconvert_ptr;
     37 
     38 
     39 /**************** RGB -> YCbCr conversion: most common case **************/
     40 
     41 /*
     42 * YCbCr is defined per CCIR 601-1, except that Cb and Cr are
     43 * normalized to the range 0.._MAXJSAMPLE rather than -0.5 .. 0.5.
     44 * The conversion equations to be implemented are therefore
     45 *      Y  =  0.29900 * R + 0.58700 * G + 0.11400 * B
     46 *      Cb = -0.16874 * R - 0.33126 * G + 0.50000 * B  + _CENTERJSAMPLE
     47 *      Cr =  0.50000 * R - 0.41869 * G - 0.08131 * B  + _CENTERJSAMPLE
     48 * (These numbers are derived from TIFF 6.0 section 21, dated 3-June-92.)
     49 * Note: older versions of the IJG code used a zero offset of _MAXJSAMPLE/2,
     50 * rather than _CENTERJSAMPLE, for Cb and Cr.  This gave equal positive and
     51 * negative swings for Cb/Cr, but meant that grayscale values (Cb=Cr=0)
     52 * were not represented exactly.  Now we sacrifice exact representation of
     53 * maximum red and maximum blue in order to get exact grayscales.
     54 *
     55 * To avoid floating-point arithmetic, we represent the fractional constants
     56 * as integers scaled up by 2^16 (about 4 digits precision); we have to divide
     57 * the products by 2^16, with appropriate rounding, to get the correct answer.
     58 *
     59 * For even more speed, we avoid doing any multiplications in the inner loop
     60 * by precalculating the constants times R,G,B for all possible values.
     61 * For 8-bit samples this is very reasonable (only 256 entries per table);
     62 * for 12-bit samples it is still acceptable.  It's not very reasonable for
     63 * 16-bit samples, but if you want lossless storage you shouldn't be changing
     64 * colorspace anyway.
     65 * The _CENTERJSAMPLE offsets and the rounding fudge-factor of 0.5 are included
     66 * in the tables to save adding them separately in the inner loop.
     67 */
     68 
     69 #define SCALEBITS       16      /* speediest right-shift on some machines */
     70 #define CBCR_OFFSET     ((JLONG)_CENTERJSAMPLE << SCALEBITS)
     71 #define ONE_HALF        ((JLONG)1 << (SCALEBITS - 1))
     72 #define FIX(x)          ((JLONG)((x) * (1L << SCALEBITS) + 0.5))
     73 
     74 /* We allocate one big table and divide it up into eight parts, instead of
     75 * doing eight alloc_small requests.  This lets us use a single table base
     76 * address, which can be held in a register in the inner loops on many
     77 * machines (more than can hold all eight addresses, anyway).
     78 */
     79 
     80 #define R_Y_OFF         0                       /* offset to R => Y section */
     81 #define G_Y_OFF         (1 * (_MAXJSAMPLE + 1)) /* offset to G => Y section */
     82 #define B_Y_OFF         (2 * (_MAXJSAMPLE + 1)) /* etc. */
     83 #define R_CB_OFF        (3 * (_MAXJSAMPLE + 1))
     84 #define G_CB_OFF        (4 * (_MAXJSAMPLE + 1))
     85 #define B_CB_OFF        (5 * (_MAXJSAMPLE + 1))
     86 #define R_CR_OFF        B_CB_OFF                /* B=>Cb, R=>Cr are the same */
     87 #define G_CR_OFF        (6 * (_MAXJSAMPLE + 1))
     88 #define B_CR_OFF        (7 * (_MAXJSAMPLE + 1))
     89 #define TABLE_SIZE      (8 * (_MAXJSAMPLE + 1))
     90 
     91 /* 12-bit samples use a 16-bit data type, so it is possible to pass
     92 * out-of-range sample values (< 0 or > 4095) to jpeg_write_scanlines().
     93 * Thus, we mask the incoming 12-bit samples to guard against overrunning
     94 * or underrunning the conversion tables.
     95 */
     96 
     97 #if BITS_IN_JSAMPLE == 12
     98 #define RANGE_LIMIT(value)  ((value) & 0xFFF)
     99 #else
    100 #define RANGE_LIMIT(value)  (value)
    101 #endif
    102 
    103 
    104 /* Include inline routines for colorspace extensions */
    105 
    106 #include "jccolext.c"
    107 #undef RGB_RED
    108 #undef RGB_GREEN
    109 #undef RGB_BLUE
    110 #undef RGB_PIXELSIZE
    111 
    112 #define RGB_RED  EXT_RGB_RED
    113 #define RGB_GREEN  EXT_RGB_GREEN
    114 #define RGB_BLUE  EXT_RGB_BLUE
    115 #define RGB_PIXELSIZE  EXT_RGB_PIXELSIZE
    116 #define rgb_ycc_convert_internal  extrgb_ycc_convert_internal
    117 #define rgb_gray_convert_internal  extrgb_gray_convert_internal
    118 #define rgb_rgb_convert_internal  extrgb_rgb_convert_internal
    119 #include "jccolext.c"
    120 #undef RGB_RED
    121 #undef RGB_GREEN
    122 #undef RGB_BLUE
    123 #undef RGB_PIXELSIZE
    124 #undef rgb_ycc_convert_internal
    125 #undef rgb_gray_convert_internal
    126 #undef rgb_rgb_convert_internal
    127 
    128 #define RGB_RED  EXT_RGBX_RED
    129 #define RGB_GREEN  EXT_RGBX_GREEN
    130 #define RGB_BLUE  EXT_RGBX_BLUE
    131 #define RGB_PIXELSIZE  EXT_RGBX_PIXELSIZE
    132 #define rgb_ycc_convert_internal  extrgbx_ycc_convert_internal
    133 #define rgb_gray_convert_internal  extrgbx_gray_convert_internal
    134 #define rgb_rgb_convert_internal  extrgbx_rgb_convert_internal
    135 #include "jccolext.c"
    136 #undef RGB_RED
    137 #undef RGB_GREEN
    138 #undef RGB_BLUE
    139 #undef RGB_PIXELSIZE
    140 #undef rgb_ycc_convert_internal
    141 #undef rgb_gray_convert_internal
    142 #undef rgb_rgb_convert_internal
    143 
    144 #define RGB_RED  EXT_BGR_RED
    145 #define RGB_GREEN  EXT_BGR_GREEN
    146 #define RGB_BLUE  EXT_BGR_BLUE
    147 #define RGB_PIXELSIZE  EXT_BGR_PIXELSIZE
    148 #define rgb_ycc_convert_internal  extbgr_ycc_convert_internal
    149 #define rgb_gray_convert_internal  extbgr_gray_convert_internal
    150 #define rgb_rgb_convert_internal  extbgr_rgb_convert_internal
    151 #include "jccolext.c"
    152 #undef RGB_RED
    153 #undef RGB_GREEN
    154 #undef RGB_BLUE
    155 #undef RGB_PIXELSIZE
    156 #undef rgb_ycc_convert_internal
    157 #undef rgb_gray_convert_internal
    158 #undef rgb_rgb_convert_internal
    159 
    160 #define RGB_RED  EXT_BGRX_RED
    161 #define RGB_GREEN  EXT_BGRX_GREEN
    162 #define RGB_BLUE  EXT_BGRX_BLUE
    163 #define RGB_PIXELSIZE  EXT_BGRX_PIXELSIZE
    164 #define rgb_ycc_convert_internal  extbgrx_ycc_convert_internal
    165 #define rgb_gray_convert_internal  extbgrx_gray_convert_internal
    166 #define rgb_rgb_convert_internal  extbgrx_rgb_convert_internal
    167 #include "jccolext.c"
    168 #undef RGB_RED
    169 #undef RGB_GREEN
    170 #undef RGB_BLUE
    171 #undef RGB_PIXELSIZE
    172 #undef rgb_ycc_convert_internal
    173 #undef rgb_gray_convert_internal
    174 #undef rgb_rgb_convert_internal
    175 
    176 #define RGB_RED  EXT_XBGR_RED
    177 #define RGB_GREEN  EXT_XBGR_GREEN
    178 #define RGB_BLUE  EXT_XBGR_BLUE
    179 #define RGB_PIXELSIZE  EXT_XBGR_PIXELSIZE
    180 #define rgb_ycc_convert_internal  extxbgr_ycc_convert_internal
    181 #define rgb_gray_convert_internal  extxbgr_gray_convert_internal
    182 #define rgb_rgb_convert_internal  extxbgr_rgb_convert_internal
    183 #include "jccolext.c"
    184 #undef RGB_RED
    185 #undef RGB_GREEN
    186 #undef RGB_BLUE
    187 #undef RGB_PIXELSIZE
    188 #undef rgb_ycc_convert_internal
    189 #undef rgb_gray_convert_internal
    190 #undef rgb_rgb_convert_internal
    191 
    192 #define RGB_RED  EXT_XRGB_RED
    193 #define RGB_GREEN  EXT_XRGB_GREEN
    194 #define RGB_BLUE  EXT_XRGB_BLUE
    195 #define RGB_PIXELSIZE  EXT_XRGB_PIXELSIZE
    196 #define rgb_ycc_convert_internal  extxrgb_ycc_convert_internal
    197 #define rgb_gray_convert_internal  extxrgb_gray_convert_internal
    198 #define rgb_rgb_convert_internal  extxrgb_rgb_convert_internal
    199 #include "jccolext.c"
    200 #undef RGB_RED
    201 #undef RGB_GREEN
    202 #undef RGB_BLUE
    203 #undef RGB_PIXELSIZE
    204 #undef rgb_ycc_convert_internal
    205 #undef rgb_gray_convert_internal
    206 #undef rgb_rgb_convert_internal
    207 
    208 
    209 /*
    210 * Initialize for RGB->YCC colorspace conversion.
    211 */
    212 
    213 METHODDEF(void)
    214 rgb_ycc_start(j_compress_ptr cinfo)
    215 {
    216 #if BITS_IN_JSAMPLE != 16
    217  my_cconvert_ptr cconvert = (my_cconvert_ptr)cinfo->cconvert;
    218  JLONG *rgb_ycc_tab;
    219  JLONG i;
    220 
    221  /* Allocate and fill in the conversion tables. */
    222  cconvert->rgb_ycc_tab = rgb_ycc_tab = (JLONG *)
    223    (*cinfo->mem->alloc_small) ((j_common_ptr)cinfo, JPOOL_IMAGE,
    224                                (TABLE_SIZE * sizeof(JLONG)));
    225 
    226  for (i = 0; i <= _MAXJSAMPLE; i++) {
    227    rgb_ycc_tab[i + R_Y_OFF] = FIX(0.29900) * i;
    228    rgb_ycc_tab[i + G_Y_OFF] = FIX(0.58700) * i;
    229    rgb_ycc_tab[i + B_Y_OFF] = FIX(0.11400) * i   + ONE_HALF;
    230    rgb_ycc_tab[i + R_CB_OFF] = (-FIX(0.16874)) * i;
    231    rgb_ycc_tab[i + G_CB_OFF] = (-FIX(0.33126)) * i;
    232    /* We use a rounding fudge-factor of 0.5-epsilon for Cb and Cr.
    233     * This ensures that the maximum output will round to _MAXJSAMPLE
    234     * not _MAXJSAMPLE+1, and thus that we don't have to range-limit.
    235     */
    236    rgb_ycc_tab[i + B_CB_OFF] = FIX(0.50000) * i  + CBCR_OFFSET + ONE_HALF - 1;
    237 /*  B=>Cb and R=>Cr tables are the same
    238    rgb_ycc_tab[i + R_CR_OFF] = FIX(0.50000) * i  + CBCR_OFFSET + ONE_HALF - 1;
    239 */
    240    rgb_ycc_tab[i + G_CR_OFF] = (-FIX(0.41869)) * i;
    241    rgb_ycc_tab[i + B_CR_OFF] = (-FIX(0.08131)) * i;
    242  }
    243 #else
    244  ERREXIT(cinfo, JERR_CONVERSION_NOTIMPL);
    245 #endif
    246 }
    247 
    248 
    249 /*
    250 * Convert some rows of samples to the JPEG colorspace.
    251 */
    252 
    253 METHODDEF(void)
    254 rgb_ycc_convert(j_compress_ptr cinfo, _JSAMPARRAY input_buf,
    255                _JSAMPIMAGE output_buf, JDIMENSION output_row, int num_rows)
    256 {
    257  switch (cinfo->in_color_space) {
    258  case JCS_EXT_RGB:
    259    extrgb_ycc_convert_internal(cinfo, input_buf, output_buf, output_row,
    260                                num_rows);
    261    break;
    262  case JCS_EXT_RGBX:
    263  case JCS_EXT_RGBA:
    264    extrgbx_ycc_convert_internal(cinfo, input_buf, output_buf, output_row,
    265                                 num_rows);
    266    break;
    267  case JCS_EXT_BGR:
    268    extbgr_ycc_convert_internal(cinfo, input_buf, output_buf, output_row,
    269                                num_rows);
    270    break;
    271  case JCS_EXT_BGRX:
    272  case JCS_EXT_BGRA:
    273    extbgrx_ycc_convert_internal(cinfo, input_buf, output_buf, output_row,
    274                                 num_rows);
    275    break;
    276  case JCS_EXT_XBGR:
    277  case JCS_EXT_ABGR:
    278    extxbgr_ycc_convert_internal(cinfo, input_buf, output_buf, output_row,
    279                                 num_rows);
    280    break;
    281  case JCS_EXT_XRGB:
    282  case JCS_EXT_ARGB:
    283    extxrgb_ycc_convert_internal(cinfo, input_buf, output_buf, output_row,
    284                                 num_rows);
    285    break;
    286  default:
    287    rgb_ycc_convert_internal(cinfo, input_buf, output_buf, output_row,
    288                             num_rows);
    289    break;
    290  }
    291 }
    292 
    293 
    294 /**************** Cases other than RGB -> YCbCr **************/
    295 
    296 
    297 /*
    298 * Convert some rows of samples to the JPEG colorspace.
    299 */
    300 
    301 METHODDEF(void)
    302 rgb_gray_convert(j_compress_ptr cinfo, _JSAMPARRAY input_buf,
    303                 _JSAMPIMAGE output_buf, JDIMENSION output_row, int num_rows)
    304 {
    305  switch (cinfo->in_color_space) {
    306  case JCS_EXT_RGB:
    307    extrgb_gray_convert_internal(cinfo, input_buf, output_buf, output_row,
    308                                 num_rows);
    309    break;
    310  case JCS_EXT_RGBX:
    311  case JCS_EXT_RGBA:
    312    extrgbx_gray_convert_internal(cinfo, input_buf, output_buf, output_row,
    313                                  num_rows);
    314    break;
    315  case JCS_EXT_BGR:
    316    extbgr_gray_convert_internal(cinfo, input_buf, output_buf, output_row,
    317                                 num_rows);
    318    break;
    319  case JCS_EXT_BGRX:
    320  case JCS_EXT_BGRA:
    321    extbgrx_gray_convert_internal(cinfo, input_buf, output_buf, output_row,
    322                                  num_rows);
    323    break;
    324  case JCS_EXT_XBGR:
    325  case JCS_EXT_ABGR:
    326    extxbgr_gray_convert_internal(cinfo, input_buf, output_buf, output_row,
    327                                  num_rows);
    328    break;
    329  case JCS_EXT_XRGB:
    330  case JCS_EXT_ARGB:
    331    extxrgb_gray_convert_internal(cinfo, input_buf, output_buf, output_row,
    332                                  num_rows);
    333    break;
    334  default:
    335    rgb_gray_convert_internal(cinfo, input_buf, output_buf, output_row,
    336                              num_rows);
    337    break;
    338  }
    339 }
    340 
    341 
    342 /*
    343 * Extended RGB to plain RGB conversion
    344 */
    345 
    346 METHODDEF(void)
    347 rgb_rgb_convert(j_compress_ptr cinfo, _JSAMPARRAY input_buf,
    348                _JSAMPIMAGE output_buf, JDIMENSION output_row, int num_rows)
    349 {
    350  switch (cinfo->in_color_space) {
    351  case JCS_EXT_RGB:
    352    extrgb_rgb_convert_internal(cinfo, input_buf, output_buf, output_row,
    353                                num_rows);
    354    break;
    355  case JCS_EXT_RGBX:
    356  case JCS_EXT_RGBA:
    357    extrgbx_rgb_convert_internal(cinfo, input_buf, output_buf, output_row,
    358                                 num_rows);
    359    break;
    360  case JCS_EXT_BGR:
    361    extbgr_rgb_convert_internal(cinfo, input_buf, output_buf, output_row,
    362                                num_rows);
    363    break;
    364  case JCS_EXT_BGRX:
    365  case JCS_EXT_BGRA:
    366    extbgrx_rgb_convert_internal(cinfo, input_buf, output_buf, output_row,
    367                                 num_rows);
    368    break;
    369  case JCS_EXT_XBGR:
    370  case JCS_EXT_ABGR:
    371    extxbgr_rgb_convert_internal(cinfo, input_buf, output_buf, output_row,
    372                                 num_rows);
    373    break;
    374  case JCS_EXT_XRGB:
    375  case JCS_EXT_ARGB:
    376    extxrgb_rgb_convert_internal(cinfo, input_buf, output_buf, output_row,
    377                                 num_rows);
    378    break;
    379  default:
    380    rgb_rgb_convert_internal(cinfo, input_buf, output_buf, output_row,
    381                             num_rows);
    382    break;
    383  }
    384 }
    385 
    386 
    387 /*
    388 * Convert some rows of samples to the JPEG colorspace.
    389 * This version handles Adobe-style CMYK->YCCK conversion,
    390 * where we convert R=1-C, G=1-M, and B=1-Y to YCbCr using the same
    391 * conversion as above, while passing K (black) unchanged.
    392 * We assume rgb_ycc_start has been called.
    393 */
    394 
    395 METHODDEF(void)
    396 cmyk_ycck_convert(j_compress_ptr cinfo, _JSAMPARRAY input_buf,
    397                  _JSAMPIMAGE output_buf, JDIMENSION output_row, int num_rows)
    398 {
    399 #if BITS_IN_JSAMPLE != 16
    400  my_cconvert_ptr cconvert = (my_cconvert_ptr)cinfo->cconvert;
    401  register int r, g, b;
    402  register JLONG *ctab = cconvert->rgb_ycc_tab;
    403  register _JSAMPROW inptr;
    404  register _JSAMPROW outptr0, outptr1, outptr2, outptr3;
    405  register JDIMENSION col;
    406  JDIMENSION num_cols = cinfo->image_width;
    407 
    408  while (--num_rows >= 0) {
    409    inptr = *input_buf++;
    410    outptr0 = output_buf[0][output_row];
    411    outptr1 = output_buf[1][output_row];
    412    outptr2 = output_buf[2][output_row];
    413    outptr3 = output_buf[3][output_row];
    414    output_row++;
    415    for (col = 0; col < num_cols; col++) {
    416      r = _MAXJSAMPLE - RANGE_LIMIT(inptr[0]);
    417      g = _MAXJSAMPLE - RANGE_LIMIT(inptr[1]);
    418      b = _MAXJSAMPLE - RANGE_LIMIT(inptr[2]);
    419      /* K passes through as-is */
    420      outptr3[col] = inptr[3];
    421      inptr += 4;
    422      /* If the inputs are 0.._MAXJSAMPLE, the outputs of these equations
    423       * must be too; we do not need an explicit range-limiting operation.
    424       * Hence the value being shifted is never negative, and we don't
    425       * need the general RIGHT_SHIFT macro.
    426       */
    427      /* Y */
    428      outptr0[col] = (_JSAMPLE)((ctab[r + R_Y_OFF] + ctab[g + G_Y_OFF] +
    429                                 ctab[b + B_Y_OFF]) >> SCALEBITS);
    430      /* Cb */
    431      outptr1[col] = (_JSAMPLE)((ctab[r + R_CB_OFF] + ctab[g + G_CB_OFF] +
    432                                 ctab[b + B_CB_OFF]) >> SCALEBITS);
    433      /* Cr */
    434      outptr2[col] = (_JSAMPLE)((ctab[r + R_CR_OFF] + ctab[g + G_CR_OFF] +
    435                                 ctab[b + B_CR_OFF]) >> SCALEBITS);
    436    }
    437  }
    438 #else
    439  ERREXIT(cinfo, JERR_CONVERSION_NOTIMPL);
    440 #endif
    441 }
    442 
    443 
    444 /*
    445 * Convert some rows of samples to the JPEG colorspace.
    446 * This version handles grayscale output with no conversion.
    447 * The source can be either plain grayscale or YCbCr (since Y == gray).
    448 */
    449 
    450 METHODDEF(void)
    451 grayscale_convert(j_compress_ptr cinfo, _JSAMPARRAY input_buf,
    452                  _JSAMPIMAGE output_buf, JDIMENSION output_row, int num_rows)
    453 {
    454  register _JSAMPROW inptr;
    455  register _JSAMPROW outptr;
    456  register JDIMENSION col;
    457  JDIMENSION num_cols = cinfo->image_width;
    458  int instride = cinfo->input_components;
    459 
    460  while (--num_rows >= 0) {
    461    inptr = *input_buf++;
    462    outptr = output_buf[0][output_row];
    463    output_row++;
    464    for (col = 0; col < num_cols; col++) {
    465      outptr[col] = inptr[0];
    466      inptr += instride;
    467    }
    468  }
    469 }
    470 
    471 
    472 /*
    473 * Convert some rows of samples to the JPEG colorspace.
    474 * This version handles multi-component colorspaces without conversion.
    475 * We assume input_components == num_components.
    476 */
    477 
    478 METHODDEF(void)
    479 null_convert(j_compress_ptr cinfo, _JSAMPARRAY input_buf,
    480             _JSAMPIMAGE output_buf, JDIMENSION output_row, int num_rows)
    481 {
    482  register _JSAMPROW inptr;
    483  register _JSAMPROW outptr, outptr0, outptr1, outptr2, outptr3;
    484  register JDIMENSION col;
    485  register int ci;
    486  int nc = cinfo->num_components;
    487  JDIMENSION num_cols = cinfo->image_width;
    488 
    489  if (nc == 3) {
    490    while (--num_rows >= 0) {
    491      inptr = *input_buf++;
    492      outptr0 = output_buf[0][output_row];
    493      outptr1 = output_buf[1][output_row];
    494      outptr2 = output_buf[2][output_row];
    495      output_row++;
    496      for (col = 0; col < num_cols; col++) {
    497        outptr0[col] = *inptr++;
    498        outptr1[col] = *inptr++;
    499        outptr2[col] = *inptr++;
    500      }
    501    }
    502  } else if (nc == 4) {
    503    while (--num_rows >= 0) {
    504      inptr = *input_buf++;
    505      outptr0 = output_buf[0][output_row];
    506      outptr1 = output_buf[1][output_row];
    507      outptr2 = output_buf[2][output_row];
    508      outptr3 = output_buf[3][output_row];
    509      output_row++;
    510      for (col = 0; col < num_cols; col++) {
    511        outptr0[col] = *inptr++;
    512        outptr1[col] = *inptr++;
    513        outptr2[col] = *inptr++;
    514        outptr3[col] = *inptr++;
    515      }
    516    }
    517  } else {
    518    while (--num_rows >= 0) {
    519      /* It seems fastest to make a separate pass for each component. */
    520      for (ci = 0; ci < nc; ci++) {
    521        inptr = *input_buf;
    522        outptr = output_buf[ci][output_row];
    523        for (col = 0; col < num_cols; col++) {
    524          outptr[col] = inptr[ci];
    525          inptr += nc;
    526        }
    527      }
    528      input_buf++;
    529      output_row++;
    530    }
    531  }
    532 }
    533 
    534 
    535 /*
    536 * Empty method for start_pass.
    537 */
    538 
    539 METHODDEF(void)
    540 null_method(j_compress_ptr cinfo)
    541 {
    542  /* no work needed */
    543 }
    544 
    545 
    546 /*
    547 * Module initialization routine for input colorspace conversion.
    548 */
    549 
    550 GLOBAL(void)
    551 _jinit_color_converter(j_compress_ptr cinfo)
    552 {
    553  my_cconvert_ptr cconvert;
    554 
    555  if (cinfo->data_precision != BITS_IN_JSAMPLE)
    556    ERREXIT1(cinfo, JERR_BAD_PRECISION, cinfo->data_precision);
    557 
    558  cconvert = (my_cconvert_ptr)
    559    (*cinfo->mem->alloc_small) ((j_common_ptr)cinfo, JPOOL_IMAGE,
    560                                sizeof(my_color_converter));
    561  cinfo->cconvert = (struct jpeg_color_converter *)cconvert;
    562  /* set start_pass to null method until we find out differently */
    563  cconvert->pub.start_pass = null_method;
    564 
    565  /* Make sure input_components agrees with in_color_space */
    566  switch (cinfo->in_color_space) {
    567  case JCS_GRAYSCALE:
    568    if (cinfo->input_components != 1)
    569      ERREXIT(cinfo, JERR_BAD_IN_COLORSPACE);
    570    break;
    571 
    572  case JCS_RGB:
    573  case JCS_EXT_RGB:
    574  case JCS_EXT_RGBX:
    575  case JCS_EXT_BGR:
    576  case JCS_EXT_BGRX:
    577  case JCS_EXT_XBGR:
    578  case JCS_EXT_XRGB:
    579  case JCS_EXT_RGBA:
    580  case JCS_EXT_BGRA:
    581  case JCS_EXT_ABGR:
    582  case JCS_EXT_ARGB:
    583    if (cinfo->input_components != rgb_pixelsize[cinfo->in_color_space])
    584      ERREXIT(cinfo, JERR_BAD_IN_COLORSPACE);
    585    break;
    586 
    587  case JCS_YCbCr:
    588    if (cinfo->input_components != 3)
    589      ERREXIT(cinfo, JERR_BAD_IN_COLORSPACE);
    590    break;
    591 
    592  case JCS_CMYK:
    593  case JCS_YCCK:
    594    if (cinfo->input_components != 4)
    595      ERREXIT(cinfo, JERR_BAD_IN_COLORSPACE);
    596    break;
    597 
    598  default:                      /* JCS_UNKNOWN can be anything */
    599    if (cinfo->input_components < 1)
    600      ERREXIT(cinfo, JERR_BAD_IN_COLORSPACE);
    601    break;
    602  }
    603 
    604  /* Check num_components, set conversion method based on requested space.
    605   * NOTE: We do not allow any lossy color conversion algorithms in lossless
    606   * mode.
    607   */
    608  switch (cinfo->jpeg_color_space) {
    609  case JCS_GRAYSCALE:
    610    if (cinfo->master->lossless &&
    611        cinfo->in_color_space != cinfo->jpeg_color_space)
    612      ERREXIT(cinfo, JERR_CONVERSION_NOTIMPL);
    613    if (cinfo->num_components != 1)
    614      ERREXIT(cinfo, JERR_BAD_J_COLORSPACE);
    615    if (cinfo->in_color_space == JCS_GRAYSCALE)
    616      cconvert->pub._color_convert = grayscale_convert;
    617    else if (IsExtRGB(cinfo->in_color_space)) {
    618 #ifdef WITH_SIMD
    619      if (jsimd_can_rgb_gray())
    620        cconvert->pub._color_convert = jsimd_rgb_gray_convert;
    621      else
    622 #endif
    623      {
    624        cconvert->pub.start_pass = rgb_ycc_start;
    625        cconvert->pub._color_convert = rgb_gray_convert;
    626      }
    627    } else if (cinfo->in_color_space == JCS_YCbCr)
    628      cconvert->pub._color_convert = grayscale_convert;
    629    else
    630      ERREXIT(cinfo, JERR_CONVERSION_NOTIMPL);
    631    break;
    632 
    633  case JCS_RGB:
    634    if (cinfo->master->lossless && !IsExtRGB(cinfo->in_color_space))
    635      ERREXIT(cinfo, JERR_CONVERSION_NOTIMPL);
    636    if (cinfo->num_components != 3)
    637      ERREXIT(cinfo, JERR_BAD_J_COLORSPACE);
    638    if (rgb_red[cinfo->in_color_space] == 0 &&
    639        rgb_green[cinfo->in_color_space] == 1 &&
    640        rgb_blue[cinfo->in_color_space] == 2 &&
    641        rgb_pixelsize[cinfo->in_color_space] == 3) {
    642 #if defined(WITH_SIMD) && defined(__mips__)
    643      if (jsimd_c_can_null_convert())
    644        cconvert->pub._color_convert = jsimd_c_null_convert;
    645      else
    646 #endif
    647        cconvert->pub._color_convert = null_convert;
    648    } else if (IsExtRGB(cinfo->in_color_space))
    649      cconvert->pub._color_convert = rgb_rgb_convert;
    650    else
    651      ERREXIT(cinfo, JERR_CONVERSION_NOTIMPL);
    652    break;
    653 
    654  case JCS_YCbCr:
    655    if (cinfo->master->lossless &&
    656        cinfo->in_color_space != cinfo->jpeg_color_space)
    657      ERREXIT(cinfo, JERR_CONVERSION_NOTIMPL);
    658    if (cinfo->num_components != 3)
    659      ERREXIT(cinfo, JERR_BAD_J_COLORSPACE);
    660    if (IsExtRGB(cinfo->in_color_space)) {
    661 #ifdef WITH_SIMD
    662      if (jsimd_can_rgb_ycc())
    663        cconvert->pub._color_convert = jsimd_rgb_ycc_convert;
    664      else
    665 #endif
    666      {
    667        cconvert->pub.start_pass = rgb_ycc_start;
    668        cconvert->pub._color_convert = rgb_ycc_convert;
    669      }
    670    } else if (cinfo->in_color_space == JCS_YCbCr) {
    671 #if defined(WITH_SIMD) && defined(__mips__)
    672      if (jsimd_c_can_null_convert())
    673        cconvert->pub._color_convert = jsimd_c_null_convert;
    674      else
    675 #endif
    676        cconvert->pub._color_convert = null_convert;
    677    } else
    678      ERREXIT(cinfo, JERR_CONVERSION_NOTIMPL);
    679    break;
    680 
    681  case JCS_CMYK:
    682    if (cinfo->master->lossless &&
    683        cinfo->in_color_space != cinfo->jpeg_color_space)
    684      ERREXIT(cinfo, JERR_CONVERSION_NOTIMPL);
    685    if (cinfo->num_components != 4)
    686      ERREXIT(cinfo, JERR_BAD_J_COLORSPACE);
    687    if (cinfo->in_color_space == JCS_CMYK) {
    688 #if defined(WITH_SIMD) && defined(__mips__)
    689      if (jsimd_c_can_null_convert())
    690        cconvert->pub._color_convert = jsimd_c_null_convert;
    691      else
    692 #endif
    693        cconvert->pub._color_convert = null_convert;
    694    } else
    695      ERREXIT(cinfo, JERR_CONVERSION_NOTIMPL);
    696    break;
    697 
    698  case JCS_YCCK:
    699    if (cinfo->master->lossless &&
    700        cinfo->in_color_space != cinfo->jpeg_color_space)
    701      ERREXIT(cinfo, JERR_CONVERSION_NOTIMPL);
    702    if (cinfo->num_components != 4)
    703      ERREXIT(cinfo, JERR_BAD_J_COLORSPACE);
    704    if (cinfo->in_color_space == JCS_CMYK) {
    705      cconvert->pub.start_pass = rgb_ycc_start;
    706      cconvert->pub._color_convert = cmyk_ycck_convert;
    707    } else if (cinfo->in_color_space == JCS_YCCK) {
    708 #if defined(WITH_SIMD) && defined(__mips__)
    709      if (jsimd_c_can_null_convert())
    710        cconvert->pub._color_convert = jsimd_c_null_convert;
    711      else
    712 #endif
    713        cconvert->pub._color_convert = null_convert;
    714    } else
    715      ERREXIT(cinfo, JERR_CONVERSION_NOTIMPL);
    716    break;
    717 
    718  default:                      /* allow null conversion of JCS_UNKNOWN */
    719    if (cinfo->jpeg_color_space != cinfo->in_color_space ||
    720        cinfo->num_components != cinfo->input_components)
    721      ERREXIT(cinfo, JERR_CONVERSION_NOTIMPL);
    722 #if defined(WITH_SIMD) && defined(__mips__)
    723    if (jsimd_c_can_null_convert())
    724      cconvert->pub._color_convert = jsimd_c_null_convert;
    725    else
    726 #endif
    727      cconvert->pub._color_convert = null_convert;
    728    break;
    729  }
    730 }
    731 
    732 #endif /* BITS_IN_JSAMPLE != 16 || defined(C_LOSSLESS_SUPPORTED) */