1 /*
   2  * jdcolor.c
   3  *
   4  * Copyright (C) 1991-1997, Thomas G. Lane.
   5  * Modified 2011-2017 by Guido Vollbeding.
   6  * This file is part of the Independent JPEG Group's software.
   7  * For conditions of distribution and use, see the accompanying README file.
   8  *
   9  * This file contains output colorspace conversion routines.
  10  */
  11 
  12 #define JPEG_INTERNALS
  13 #include "jinclude.h"
  14 #include "jpeglib.h"
  15 
  16 
  17 #if RANGE_BITS < 2
  18   /* Deliberate syntax err */
  19   Sorry, this code requires 2 or more range extension bits.
  20 #endif
  21 
  22 
  23 /* Private subobject */
  24 
  25 typedef struct {
  26   struct jpeg_color_deconverter pub; /* public fields */
  27 
  28   /* Private state for YCbCr->RGB and BG_YCC->RGB conversion */
  29   int * Cr_r_tab;               /* => table for Cr to R conversion */
  30   int * Cb_b_tab;               /* => table for Cb to B conversion */
  31   INT32 * Cr_g_tab;             /* => table for Cr to G conversion */
  32   INT32 * Cb_g_tab;             /* => table for Cb to G conversion */
  33 
  34   /* Private state for RGB->Y conversion */
  35   INT32 * rgb_y_tab;            /* => table for RGB to Y conversion */
  36 } my_color_deconverter;
  37 
  38 typedef my_color_deconverter * my_cconvert_ptr;
  39 
  40 
  41 /***************  YCbCr -> RGB conversion: most common case **************/
  42 /*************** BG_YCC -> RGB conversion: less common case **************/
  43 /***************    RGB -> Y   conversion: less common case **************/
  44 
  45 /*
  46  * YCbCr is defined per Recommendation ITU-R BT.601-7 (03/2011),
  47  * previously known as Recommendation CCIR 601-1, except that Cb and Cr
  48  * are normalized to the range 0..MAXJSAMPLE rather than -0.5 .. 0.5.
  49  * sRGB (standard RGB color space) is defined per IEC 61966-2-1:1999.
  50  * sYCC (standard luma-chroma-chroma color space with extended gamut)
  51  * is defined per IEC 61966-2-1:1999 Amendment A1:2003 Annex F.
  52  * bg-sRGB and bg-sYCC (big gamut standard color spaces)
  53  * are defined per IEC 61966-2-1:1999 Amendment A1:2003 Annex G.
  54  * Note that the derived conversion coefficients given in some of these
  55  * documents are imprecise.  The general conversion equations are
  56  *
  57  *      R = Y + K * (1 - Kr) * Cr
  58  *      G = Y - K * (Kb * (1 - Kb) * Cb + Kr * (1 - Kr) * Cr) / (1 - Kr - Kb)
  59  *      B = Y + K * (1 - Kb) * Cb
  60  *
  61  *      Y = Kr * R + (1 - Kr - Kb) * G + Kb * B
  62  *
  63  * With Kr = 0.299 and Kb = 0.114 (derived according to SMPTE RP 177-1993
  64  * from the 1953 FCC NTSC primaries and CIE Illuminant C), K = 2 for sYCC,
  65  * the conversion equations to be implemented are therefore
  66  *
  67  *      R = Y + 1.402 * Cr
  68  *      G = Y - 0.344136286 * Cb - 0.714136286 * Cr
  69  *      B = Y + 1.772 * Cb
  70  *
  71  *      Y = 0.299 * R + 0.587 * G + 0.114 * B
  72  *
  73  * where Cb and Cr represent the incoming values less CENTERJSAMPLE.
  74  * For bg-sYCC, with K = 4, the equations are
  75  *
  76  *      R = Y + 2.804 * Cr
  77  *      G = Y - 0.688272572 * Cb - 1.428272572 * Cr
  78  *      B = Y + 3.544 * Cb
  79  *
  80  * To avoid floating-point arithmetic, we represent the fractional constants
  81  * as integers scaled up by 2^16 (about 4 digits precision); we have to divide
  82  * the products by 2^16, with appropriate rounding, to get the correct answer.
  83  * Notice that Y, being an integral input, does not contribute any fraction
  84  * so it need not participate in the rounding.
  85  *
  86  * For even more speed, we avoid doing any multiplications in the inner loop
  87  * by precalculating the constants times Cb and Cr for all possible values.
  88  * For 8-bit JSAMPLEs this is very reasonable (only 256 entries per table);
  89  * for 9-bit to 12-bit samples it is still acceptable.  It's not very
  90  * reasonable for 16-bit samples, but if you want lossless storage you
  91  * shouldn't be changing colorspace anyway.
  92  * The Cr=>R and Cb=>B values can be rounded to integers in advance; the
  93  * values for the G calculation are left scaled up, since we must add them
  94  * together before rounding.
  95  */
  96 
  97 #define SCALEBITS       16      /* speediest right-shift on some machines */
  98 #define ONE_HALF        ((INT32) 1 << (SCALEBITS-1))
  99 #define FIX(x)          ((INT32) ((x) * (1L<<SCALEBITS) + 0.5))
 100 
 101 /* We allocate one big table for RGB->Y conversion and divide it up into
 102  * three parts, instead of doing three alloc_small requests.  This lets us
 103  * use a single table base address, which can be held in a register in the
 104  * inner loops on many machines (more than can hold all three addresses,
 105  * anyway).
 106  */
 107 
 108 #define R_Y_OFF         0                       /* offset to R => Y section */
 109 #define G_Y_OFF         (1*(MAXJSAMPLE+1))      /* offset to G => Y section */
 110 #define B_Y_OFF         (2*(MAXJSAMPLE+1))      /* etc. */
 111 #define TABLE_SIZE      (3*(MAXJSAMPLE+1))
 112 
 113 
 114 /*
 115  * Initialize tables for YCbCr->RGB and BG_YCC->RGB colorspace conversion.
 116  */
 117 
 118 LOCAL(void)
 119 build_ycc_rgb_table (j_decompress_ptr cinfo)
 120 /* Normal case, sYCC */
 121 {
 122   my_cconvert_ptr cconvert = (my_cconvert_ptr) cinfo->cconvert;
 123   int i;
 124   INT32 x;
 125   SHIFT_TEMPS
 126 
 127   cconvert->Cr_r_tab = (int *)
 128     (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
 129                                 (MAXJSAMPLE+1) * SIZEOF(int));
 130   cconvert->Cb_b_tab = (int *)
 131     (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
 132                                 (MAXJSAMPLE+1) * SIZEOF(int));
 133   cconvert->Cr_g_tab = (INT32 *)
 134     (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
 135                                 (MAXJSAMPLE+1) * SIZEOF(INT32));
 136   cconvert->Cb_g_tab = (INT32 *)
 137     (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
 138                                 (MAXJSAMPLE+1) * SIZEOF(INT32));
 139 
 140   for (i = 0, x = -CENTERJSAMPLE; i <= MAXJSAMPLE; i++, x++) {
 141     /* i is the actual input pixel value, in the range 0..MAXJSAMPLE */
 142     /* The Cb or Cr value we are thinking of is x = i - CENTERJSAMPLE */
 143     /* Cr=>R value is nearest int to 1.402 * x */
 144     cconvert->Cr_r_tab[i] = (int)
 145                     RIGHT_SHIFT(FIX(1.402) * x + ONE_HALF, SCALEBITS);
 146     /* Cb=>B value is nearest int to 1.772 * x */
 147     cconvert->Cb_b_tab[i] = (int)
 148                     RIGHT_SHIFT(FIX(1.772) * x + ONE_HALF, SCALEBITS);
 149     /* Cr=>G value is scaled-up -0.714136286 * x */
 150     cconvert->Cr_g_tab[i] = (- FIX(0.714136286)) * x;
 151     /* Cb=>G value is scaled-up -0.344136286 * x */
 152     /* We also add in ONE_HALF so that need not do it in inner loop */
 153     cconvert->Cb_g_tab[i] = (- FIX(0.344136286)) * x + ONE_HALF;
 154   }
 155 }
 156 
 157 
 158 LOCAL(void)
 159 build_bg_ycc_rgb_table (j_decompress_ptr cinfo)
 160 /* Wide gamut case, bg-sYCC */
 161 {
 162   my_cconvert_ptr cconvert = (my_cconvert_ptr) cinfo->cconvert;
 163   int i;
 164   INT32 x;
 165   SHIFT_TEMPS
 166 
 167   cconvert->Cr_r_tab = (int *)
 168     (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
 169                                 (MAXJSAMPLE+1) * SIZEOF(int));
 170   cconvert->Cb_b_tab = (int *)
 171     (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
 172                                 (MAXJSAMPLE+1) * SIZEOF(int));
 173   cconvert->Cr_g_tab = (INT32 *)
 174     (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
 175                                 (MAXJSAMPLE+1) * SIZEOF(INT32));
 176   cconvert->Cb_g_tab = (INT32 *)
 177     (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
 178                                 (MAXJSAMPLE+1) * SIZEOF(INT32));
 179 
 180   for (i = 0, x = -CENTERJSAMPLE; i <= MAXJSAMPLE; i++, x++) {
 181     /* i is the actual input pixel value, in the range 0..MAXJSAMPLE */
 182     /* The Cb or Cr value we are thinking of is x = i - CENTERJSAMPLE */
 183     /* Cr=>R value is nearest int to 2.804 * x */
 184     cconvert->Cr_r_tab[i] = (int)
 185                     RIGHT_SHIFT(FIX(2.804) * x + ONE_HALF, SCALEBITS);
 186     /* Cb=>B value is nearest int to 3.544 * x */
 187     cconvert->Cb_b_tab[i] = (int)
 188                     RIGHT_SHIFT(FIX(3.544) * x + ONE_HALF, SCALEBITS);
 189     /* Cr=>G value is scaled-up -1.428272572 * x */
 190     cconvert->Cr_g_tab[i] = (- FIX(1.428272572)) * x;
 191     /* Cb=>G value is scaled-up -0.688272572 * x */
 192     /* We also add in ONE_HALF so that need not do it in inner loop */
 193     cconvert->Cb_g_tab[i] = (- FIX(0.688272572)) * x + ONE_HALF;
 194   }
 195 }
 196 
 197 
 198 /*
 199  * Convert some rows of samples to the output colorspace.
 200  *
 201  * Note that we change from noninterleaved, one-plane-per-component format
 202  * to interleaved-pixel format.  The output buffer is therefore three times
 203  * as wide as the input buffer.
 204  * A starting row offset is provided only for the input buffer.  The caller
 205  * can easily adjust the passed output_buf value to accommodate any row
 206  * offset required on that side.
 207  */
 208 
 209 METHODDEF(void)
 210 ycc_rgb_convert (j_decompress_ptr cinfo,
 211                  JSAMPIMAGE input_buf, JDIMENSION input_row,
 212                  JSAMPARRAY output_buf, int num_rows)
 213 {
 214   my_cconvert_ptr cconvert = (my_cconvert_ptr) cinfo->cconvert;
 215   register int y, cb, cr;
 216   register JSAMPROW outptr;
 217   register JSAMPROW inptr0, inptr1, inptr2;
 218   register JDIMENSION col;
 219   JDIMENSION num_cols = cinfo->output_width;
 220   /* copy these pointers into registers if possible */
 221   register JSAMPLE * range_limit = cinfo->sample_range_limit;
 222   register int * Crrtab = cconvert->Cr_r_tab;
 223   register int * Cbbtab = cconvert->Cb_b_tab;
 224   register INT32 * Crgtab = cconvert->Cr_g_tab;
 225   register INT32 * Cbgtab = cconvert->Cb_g_tab;
 226   SHIFT_TEMPS
 227 
 228   while (--num_rows >= 0) {
 229     inptr0 = input_buf[0][input_row];
 230     inptr1 = input_buf[1][input_row];
 231     inptr2 = input_buf[2][input_row];
 232     input_row++;
 233     outptr = *output_buf++;
 234     for (col = 0; col < num_cols; col++) {
 235       y  = GETJSAMPLE(inptr0[col]);
 236       cb = GETJSAMPLE(inptr1[col]);
 237       cr = GETJSAMPLE(inptr2[col]);
 238       /* Range-limiting is essential due to noise introduced by DCT losses,
 239        * for extended gamut (sYCC) and wide gamut (bg-sYCC) encodings.
 240        */
 241       outptr[RGB_RED]   = range_limit[y + Crrtab[cr]];
 242       outptr[RGB_GREEN] = range_limit[y +
 243                               ((int) RIGHT_SHIFT(Cbgtab[cb] + Crgtab[cr],
 244                                                  SCALEBITS))];
 245       outptr[RGB_BLUE]  = range_limit[y + Cbbtab[cb]];
 246       outptr += RGB_PIXELSIZE;
 247     }
 248   }
 249 }
 250 
 251 
 252 /**************** Cases other than YCC -> RGB ****************/
 253 
 254 
 255 /*
 256  * Initialize for RGB->grayscale colorspace conversion.
 257  */
 258 
 259 LOCAL(void)
 260 build_rgb_y_table (j_decompress_ptr cinfo)
 261 {
 262   my_cconvert_ptr cconvert = (my_cconvert_ptr) cinfo->cconvert;
 263   INT32 * rgb_y_tab;
 264   INT32 i;
 265 
 266   /* Allocate and fill in the conversion tables. */
 267   cconvert->rgb_y_tab = rgb_y_tab = (INT32 *)
 268     (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
 269                                 (TABLE_SIZE * SIZEOF(INT32)));
 270 
 271   for (i = 0; i <= MAXJSAMPLE; i++) {
 272     rgb_y_tab[i+R_Y_OFF] = FIX(0.299) * i;
 273     rgb_y_tab[i+G_Y_OFF] = FIX(0.587) * i;
 274     rgb_y_tab[i+B_Y_OFF] = FIX(0.114) * i + ONE_HALF;
 275   }
 276 }
 277 
 278 
 279 /*
 280  * Convert RGB to grayscale.
 281  */
 282 
 283 METHODDEF(void)
 284 rgb_gray_convert (j_decompress_ptr cinfo,
 285                   JSAMPIMAGE input_buf, JDIMENSION input_row,
 286                   JSAMPARRAY output_buf, int num_rows)
 287 {
 288   my_cconvert_ptr cconvert = (my_cconvert_ptr) cinfo->cconvert;
 289   register INT32 * ctab = cconvert->rgb_y_tab;
 290   register int r, g, b;
 291   register JSAMPROW outptr;
 292   register JSAMPROW inptr0, inptr1, inptr2;
 293   register JDIMENSION col;
 294   JDIMENSION num_cols = cinfo->output_width;
 295 
 296   while (--num_rows >= 0) {
 297     inptr0 = input_buf[0][input_row];
 298     inptr1 = input_buf[1][input_row];
 299     inptr2 = input_buf[2][input_row];
 300     input_row++;
 301     outptr = *output_buf++;
 302     for (col = 0; col < num_cols; col++) {
 303       r = GETJSAMPLE(inptr0[col]);
 304       g = GETJSAMPLE(inptr1[col]);
 305       b = GETJSAMPLE(inptr2[col]);
 306       /* Y */
 307       outptr[col] = (JSAMPLE)
 308                 ((ctab[r+R_Y_OFF] + ctab[g+G_Y_OFF] + ctab[b+B_Y_OFF])
 309                  >> SCALEBITS);
 310     }
 311   }
 312 }
 313 
 314 
 315 /*
 316  * [R-G,G,B-G] to [R,G,B] conversion with modulo calculation
 317  * (inverse color transform).
 318  * This can be seen as an adaption of the general YCbCr->RGB
 319  * conversion equation with Kr = Kb = 0, while replacing the
 320  * normalization by modulo calculation.
 321  */
 322 
 323 METHODDEF(void)
 324 rgb1_rgb_convert (j_decompress_ptr cinfo,
 325                   JSAMPIMAGE input_buf, JDIMENSION input_row,
 326                   JSAMPARRAY output_buf, int num_rows)
 327 {
 328   register int r, g, b;
 329   register JSAMPROW outptr;
 330   register JSAMPROW inptr0, inptr1, inptr2;
 331   register JDIMENSION col;
 332   JDIMENSION num_cols = cinfo->output_width;
 333 
 334   while (--num_rows >= 0) {
 335     inptr0 = input_buf[0][input_row];
 336     inptr1 = input_buf[1][input_row];
 337     inptr2 = input_buf[2][input_row];
 338     input_row++;
 339     outptr = *output_buf++;
 340     for (col = 0; col < num_cols; col++) {
 341       r = GETJSAMPLE(inptr0[col]);
 342       g = GETJSAMPLE(inptr1[col]);
 343       b = GETJSAMPLE(inptr2[col]);
 344       /* Assume that MAXJSAMPLE+1 is a power of 2, so that the MOD
 345        * (modulo) operator is equivalent to the bitmask operator AND.
 346        */
 347       outptr[RGB_RED]   = (JSAMPLE) ((r + g - CENTERJSAMPLE) & MAXJSAMPLE);
 348       outptr[RGB_GREEN] = (JSAMPLE) g;
 349       outptr[RGB_BLUE]  = (JSAMPLE) ((b + g - CENTERJSAMPLE) & MAXJSAMPLE);
 350       outptr += RGB_PIXELSIZE;
 351     }
 352   }
 353 }
 354 
 355 
 356 /*
 357  * [R-G,G,B-G] to grayscale conversion with modulo calculation
 358  * (inverse color transform).
 359  */
 360 
 361 METHODDEF(void)
 362 rgb1_gray_convert (j_decompress_ptr cinfo,
 363                    JSAMPIMAGE input_buf, JDIMENSION input_row,
 364                    JSAMPARRAY output_buf, int num_rows)
 365 {
 366   my_cconvert_ptr cconvert = (my_cconvert_ptr) cinfo->cconvert;
 367   register INT32 * ctab = cconvert->rgb_y_tab;
 368   register int r, g, b;
 369   register JSAMPROW outptr;
 370   register JSAMPROW inptr0, inptr1, inptr2;
 371   register JDIMENSION col;
 372   JDIMENSION num_cols = cinfo->output_width;
 373 
 374   while (--num_rows >= 0) {
 375     inptr0 = input_buf[0][input_row];
 376     inptr1 = input_buf[1][input_row];
 377     inptr2 = input_buf[2][input_row];
 378     input_row++;
 379     outptr = *output_buf++;
 380     for (col = 0; col < num_cols; col++) {
 381       r = GETJSAMPLE(inptr0[col]);
 382       g = GETJSAMPLE(inptr1[col]);
 383       b = GETJSAMPLE(inptr2[col]);
 384       /* Assume that MAXJSAMPLE+1 is a power of 2, so that the MOD
 385        * (modulo) operator is equivalent to the bitmask operator AND.
 386        */
 387       r = (r + g - CENTERJSAMPLE) & MAXJSAMPLE;
 388       b = (b + g - CENTERJSAMPLE) & MAXJSAMPLE;
 389       /* Y */
 390       outptr[col] = (JSAMPLE)
 391                 ((ctab[r+R_Y_OFF] + ctab[g+G_Y_OFF] + ctab[b+B_Y_OFF])
 392                  >> SCALEBITS);
 393     }
 394   }
 395 }
 396 
 397 
 398 /*
 399  * No colorspace change, but conversion from separate-planes
 400  * to interleaved representation.
 401  */
 402 
 403 METHODDEF(void)
 404 rgb_convert (j_decompress_ptr cinfo,
 405              JSAMPIMAGE input_buf, JDIMENSION input_row,
 406              JSAMPARRAY output_buf, int num_rows)
 407 {
 408   register JSAMPROW outptr;
 409   register JSAMPROW inptr0, inptr1, inptr2;
 410   register JDIMENSION col;
 411   JDIMENSION num_cols = cinfo->output_width;
 412 
 413   while (--num_rows >= 0) {
 414     inptr0 = input_buf[0][input_row];
 415     inptr1 = input_buf[1][input_row];
 416     inptr2 = input_buf[2][input_row];
 417     input_row++;
 418     outptr = *output_buf++;
 419     for (col = 0; col < num_cols; col++) {
 420       /* We can dispense with GETJSAMPLE() here */
 421       outptr[RGB_RED]   = inptr0[col];
 422       outptr[RGB_GREEN] = inptr1[col];
 423       outptr[RGB_BLUE]  = inptr2[col];
 424       outptr += RGB_PIXELSIZE;
 425     }
 426   }
 427 }
 428 
 429 
 430 /*
 431  * Color conversion for no colorspace change: just copy the data,
 432  * converting from separate-planes to interleaved representation.
 433  */
 434 
 435 METHODDEF(void)
 436 null_convert (j_decompress_ptr cinfo,
 437               JSAMPIMAGE input_buf, JDIMENSION input_row,
 438               JSAMPARRAY output_buf, int num_rows)
 439 {
 440   int ci;
 441   register int nc = cinfo->num_components;
 442   register JSAMPROW outptr;
 443   register JSAMPROW inptr;
 444   register JDIMENSION col;
 445   JDIMENSION num_cols = cinfo->output_width;
 446 
 447   while (--num_rows >= 0) {
 448     for (ci = 0; ci < nc; ci++) {
 449       inptr = input_buf[ci][input_row];
 450       outptr = output_buf[0] + ci;
 451       for (col = 0; col < num_cols; col++) {
 452         *outptr = *inptr++;     /* needn't bother with GETJSAMPLE() here */
 453         outptr += nc;
 454       }
 455     }
 456     input_row++;
 457     output_buf++;
 458   }
 459 }
 460 
 461 
 462 /*
 463  * Color conversion for grayscale: just copy the data.
 464  * This also works for YCC -> grayscale conversion, in which
 465  * we just copy the Y (luminance) component and ignore chrominance.
 466  */
 467 
 468 METHODDEF(void)
 469 grayscale_convert (j_decompress_ptr cinfo,
 470                    JSAMPIMAGE input_buf, JDIMENSION input_row,
 471                    JSAMPARRAY output_buf, int num_rows)
 472 {
 473   jcopy_sample_rows(input_buf[0], (int) input_row, output_buf, 0,
 474                     num_rows, cinfo->output_width);
 475 }
 476 
 477 
 478 /*
 479  * Convert grayscale to RGB: just duplicate the graylevel three times.
 480  * This is provided to support applications that don't want to cope
 481  * with grayscale as a separate case.
 482  */
 483 
 484 METHODDEF(void)
 485 gray_rgb_convert (j_decompress_ptr cinfo,
 486                   JSAMPIMAGE input_buf, JDIMENSION input_row,
 487                   JSAMPARRAY output_buf, int num_rows)
 488 {
 489   register JSAMPROW outptr;
 490   register JSAMPROW inptr;
 491   register JDIMENSION col;
 492   JDIMENSION num_cols = cinfo->output_width;
 493 
 494   while (--num_rows >= 0) {
 495     inptr = input_buf[0][input_row++];
 496     outptr = *output_buf++;
 497     for (col = 0; col < num_cols; col++) {
 498       /* We can dispense with GETJSAMPLE() here */
 499       outptr[RGB_RED] = outptr[RGB_GREEN] = outptr[RGB_BLUE] = inptr[col];
 500       outptr += RGB_PIXELSIZE;
 501     }
 502   }
 503 }
 504 
 505 
 506 /*
 507  * Adobe-style YCCK->CMYK conversion.
 508  * We convert YCbCr to R=1-C, G=1-M, and B=1-Y using the same
 509  * conversion as above, while passing K (black) unchanged.
 510  * We assume build_ycc_rgb_table has been called.
 511  */
 512 
 513 METHODDEF(void)
 514 ycck_cmyk_convert (j_decompress_ptr cinfo,
 515                    JSAMPIMAGE input_buf, JDIMENSION input_row,
 516                    JSAMPARRAY output_buf, int num_rows)
 517 {
 518   my_cconvert_ptr cconvert = (my_cconvert_ptr) cinfo->cconvert;
 519   register int y, cb, cr;
 520   register JSAMPROW outptr;
 521   register JSAMPROW inptr0, inptr1, inptr2, inptr3;
 522   register JDIMENSION col;
 523   JDIMENSION num_cols = cinfo->output_width;
 524   /* copy these pointers into registers if possible */
 525   register JSAMPLE * range_limit = cinfo->sample_range_limit;
 526   register int * Crrtab = cconvert->Cr_r_tab;
 527   register int * Cbbtab = cconvert->Cb_b_tab;
 528   register INT32 * Crgtab = cconvert->Cr_g_tab;
 529   register INT32 * Cbgtab = cconvert->Cb_g_tab;
 530   SHIFT_TEMPS
 531 
 532   while (--num_rows >= 0) {
 533     inptr0 = input_buf[0][input_row];
 534     inptr1 = input_buf[1][input_row];
 535     inptr2 = input_buf[2][input_row];
 536     inptr3 = input_buf[3][input_row];
 537     input_row++;
 538     outptr = *output_buf++;
 539     for (col = 0; col < num_cols; col++) {
 540       y  = GETJSAMPLE(inptr0[col]);
 541       cb = GETJSAMPLE(inptr1[col]);
 542       cr = GETJSAMPLE(inptr2[col]);
 543       /* Range-limiting is essential due to noise introduced by DCT losses,
 544        * and for extended gamut encodings (sYCC).
 545        */
 546       outptr[0] = range_limit[MAXJSAMPLE - (y + Crrtab[cr])];   /* red */
 547       outptr[1] = range_limit[MAXJSAMPLE - (y +                 /* green */
 548                               ((int) RIGHT_SHIFT(Cbgtab[cb] + Crgtab[cr],
 549                                                  SCALEBITS)))];
 550       outptr[2] = range_limit[MAXJSAMPLE - (y + Cbbtab[cb])];   /* blue */
 551       /* K passes through unchanged */
 552       outptr[3] = inptr3[col];  /* don't need GETJSAMPLE here */
 553       outptr += 4;
 554     }
 555   }
 556 }
 557 
 558 
 559 /*
 560  * Empty method for start_pass.
 561  */
 562 
 563 METHODDEF(void)
 564 start_pass_dcolor (j_decompress_ptr cinfo)
 565 {
 566   /* no work needed */
 567 }
 568 
 569 
 570 /*
 571  * Module initialization routine for output colorspace conversion.
 572  */
 573 
 574 GLOBAL(void)
 575 jinit_color_deconverter (j_decompress_ptr cinfo)
 576 {
 577   my_cconvert_ptr cconvert;
 578   int ci;
 579 
 580   cconvert = (my_cconvert_ptr)
 581     (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
 582                                 SIZEOF(my_color_deconverter));
 583   cinfo->cconvert = &cconvert->pub;
 584   cconvert->pub.start_pass = start_pass_dcolor;
 585 
 586   /* Make sure num_components agrees with jpeg_color_space */
 587   switch (cinfo->jpeg_color_space) {
 588   case JCS_GRAYSCALE:
 589     if (cinfo->num_components != 1)
 590       ERREXIT(cinfo, JERR_BAD_J_COLORSPACE);
 591     break;
 592 
 593   case JCS_RGB:
 594   case JCS_YCbCr:
 595   case JCS_BG_RGB:
 596   case JCS_BG_YCC:
 597     if (cinfo->num_components != 3)
 598       ERREXIT(cinfo, JERR_BAD_J_COLORSPACE);
 599     break;
 600 
 601   case JCS_CMYK:
 602   case JCS_YCCK:
 603     if (cinfo->num_components != 4)
 604       ERREXIT(cinfo, JERR_BAD_J_COLORSPACE);
 605     break;
 606 
 607   default:                      /* JCS_UNKNOWN can be anything */
 608     if (cinfo->num_components < 1)
 609       ERREXIT(cinfo, JERR_BAD_J_COLORSPACE);
 610     break;
 611   }
 612 
 613   /* Support color transform only for RGB colorspaces */
 614   if (cinfo->color_transform &&
 615       cinfo->jpeg_color_space != JCS_RGB &&
 616       cinfo->jpeg_color_space != JCS_BG_RGB)
 617     ERREXIT(cinfo, JERR_CONVERSION_NOTIMPL);
 618 
 619   /* Set out_color_components and conversion method based on requested space.
 620    * Also clear the component_needed flags for any unused components,
 621    * so that earlier pipeline stages can avoid useless computation.
 622    */
 623 
 624   switch (cinfo->out_color_space) {
 625   case JCS_GRAYSCALE:
 626     cinfo->out_color_components = 1;
 627     switch (cinfo->jpeg_color_space) {
 628     case JCS_GRAYSCALE:
 629     case JCS_YCbCr:
 630     case JCS_BG_YCC:
 631       cconvert->pub.color_convert = grayscale_convert;
 632       /* For color->grayscale conversion, only the Y (0) component is needed */
 633       for (ci = 1; ci < cinfo->num_components; ci++)
 634         cinfo->comp_info[ci].component_needed = FALSE;
 635       break;
 636     case JCS_RGB:
 637       switch (cinfo->color_transform) {
 638       case JCT_NONE:
 639         cconvert->pub.color_convert = rgb_gray_convert;
 640         break;
 641       case JCT_SUBTRACT_GREEN:
 642         cconvert->pub.color_convert = rgb1_gray_convert;
 643         break;
 644       default:
 645         ERREXIT(cinfo, JERR_CONVERSION_NOTIMPL);
 646       }
 647       build_rgb_y_table(cinfo);
 648       break;
 649     default:
 650       ERREXIT(cinfo, JERR_CONVERSION_NOTIMPL);
 651     }
 652     break;
 653 
 654   case JCS_RGB:
 655     cinfo->out_color_components = RGB_PIXELSIZE;
 656     switch (cinfo->jpeg_color_space) {
 657     case JCS_GRAYSCALE:
 658       cconvert->pub.color_convert = gray_rgb_convert;
 659       break;
 660     case JCS_YCbCr:
 661       cconvert->pub.color_convert = ycc_rgb_convert;
 662       build_ycc_rgb_table(cinfo);
 663       break;
 664     case JCS_BG_YCC:
 665       cconvert->pub.color_convert = ycc_rgb_convert;
 666       build_bg_ycc_rgb_table(cinfo);
 667       break;
 668     case JCS_RGB:
 669       switch (cinfo->color_transform) {
 670       case JCT_NONE:
 671         cconvert->pub.color_convert = rgb_convert;
 672         break;
 673       case JCT_SUBTRACT_GREEN:
 674         cconvert->pub.color_convert = rgb1_rgb_convert;
 675         break;
 676       default:
 677         ERREXIT(cinfo, JERR_CONVERSION_NOTIMPL);
 678       }
 679       break;
 680     default:
 681       ERREXIT(cinfo, JERR_CONVERSION_NOTIMPL);
 682     }
 683     break;
 684 
 685   case JCS_BG_RGB:
 686     cinfo->out_color_components = RGB_PIXELSIZE;
 687     if (cinfo->jpeg_color_space == JCS_BG_RGB) {
 688       switch (cinfo->color_transform) {
 689       case JCT_NONE:
 690         cconvert->pub.color_convert = rgb_convert;
 691         break;
 692       case JCT_SUBTRACT_GREEN:
 693         cconvert->pub.color_convert = rgb1_rgb_convert;
 694         break;
 695       default:
 696         ERREXIT(cinfo, JERR_CONVERSION_NOTIMPL);
 697       }
 698     } else
 699       ERREXIT(cinfo, JERR_CONVERSION_NOTIMPL);
 700     break;
 701 
 702   case JCS_CMYK:
 703     cinfo->out_color_components = 4;
 704     switch (cinfo->jpeg_color_space) {
 705     case JCS_YCCK:
 706       cconvert->pub.color_convert = ycck_cmyk_convert;
 707       build_ycc_rgb_table(cinfo);
 708       break;
 709     case JCS_CMYK:
 710       cconvert->pub.color_convert = null_convert;
 711       break;
 712     default:
 713       ERREXIT(cinfo, JERR_CONVERSION_NOTIMPL);
 714     }
 715     break;
 716 
 717   default:
 718     /* Permit null conversion to same output space */
 719     if (cinfo->out_color_space == cinfo->jpeg_color_space) {
 720       cinfo->out_color_components = cinfo->num_components;
 721       cconvert->pub.color_convert = null_convert;
 722     } else                      /* unsupported non-null conversion */
 723       ERREXIT(cinfo, JERR_CONVERSION_NOTIMPL);
 724     break;
 725   }
 726 
 727   if (cinfo->quantize_colors)
 728     cinfo->output_components = 1; /* single colormapped output component */
 729   else
 730     cinfo->output_components = cinfo->out_color_components;
 731 }