1 /*
   2  * jdcolor.c
   3  *
   4  * Copyright (C) 1991-1997, Thomas G. Lane.
   5  * This file is part of the Independent JPEG Group's software.
   6  * For conditions of distribution and use, see the accompanying README file.
   7  *
   8  * This file contains output colorspace conversion routines.
   9  */
  10 
  11 #define JPEG_INTERNALS
  12 #include "jinclude.h"
  13 #include "jpeglib.h"
  14 
  15 
  16 /* Private subobject */
  17 
  18 typedef struct {
  19   struct jpeg_color_deconverter pub; /* public fields */
  20 
  21   /* Private state for YCC->RGB conversion */
  22   int * Cr_r_tab;               /* => table for Cr to R conversion */
  23   int * Cb_b_tab;               /* => table for Cb to B conversion */
  24   INT32 * Cr_g_tab;             /* => table for Cr to G conversion */
  25   INT32 * Cb_g_tab;             /* => table for Cb to G conversion */
  26 } my_color_deconverter;
  27 
  28 typedef my_color_deconverter * my_cconvert_ptr;
  29 
  30 
  31 /**************** YCbCr -> RGB conversion: most common case **************/
  32 
  33 /*
  34  * YCbCr is defined per CCIR 601-1, except that Cb and Cr are
  35  * normalized to the range 0..MAXJSAMPLE rather than -0.5 .. 0.5.
  36  * The conversion equations to be implemented are therefore
  37  *      R = Y                + 1.40200 * Cr
  38  *      G = Y - 0.34414 * Cb - 0.71414 * Cr
  39  *      B = Y + 1.77200 * Cb
  40  * where Cb and Cr represent the incoming values less CENTERJSAMPLE.
  41  * (These numbers are derived from TIFF 6.0 section 21, dated 3-June-92.)
  42  *
  43  * To avoid floating-point arithmetic, we represent the fractional constants
  44  * as integers scaled up by 2^16 (about 4 digits precision); we have to divide
  45  * the products by 2^16, with appropriate rounding, to get the correct answer.
  46  * Notice that Y, being an integral input, does not contribute any fraction
  47  * so it need not participate in the rounding.
  48  *
  49  * For even more speed, we avoid doing any multiplications in the inner loop
  50  * by precalculating the constants times Cb and Cr for all possible values.
  51  * For 8-bit JSAMPLEs this is very reasonable (only 256 entries per table);
  52  * for 12-bit samples it is still acceptable.  It's not very reasonable for
  53  * 16-bit samples, but if you want lossless storage you shouldn't be changing
  54  * colorspace anyway.
  55  * The Cr=>R and Cb=>B values can be rounded to integers in advance; the
  56  * values for the G calculation are left scaled up, since we must add them
  57  * together before rounding.
  58  */
  59 
  60 #define SCALEBITS       16      /* speediest right-shift on some machines */
  61 #define ONE_HALF        ((INT32) 1 << (SCALEBITS-1))
  62 #define FIX(x)          ((INT32) ((x) * (1L<<SCALEBITS) + 0.5))
  63 
  64 
  65 /*
  66  * Initialize tables for YCC->RGB colorspace conversion.
  67  */
  68 
  69 LOCAL(void)
  70 build_ycc_rgb_table (j_decompress_ptr cinfo)
  71 {
  72   my_cconvert_ptr cconvert = (my_cconvert_ptr) cinfo->cconvert;
  73   int i;
  74   INT32 x;
  75   SHIFT_TEMPS
  76 
  77   cconvert->Cr_r_tab = (int *)
  78     (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
  79                                 (MAXJSAMPLE+1) * SIZEOF(int));
  80   cconvert->Cb_b_tab = (int *)
  81     (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
  82                                 (MAXJSAMPLE+1) * SIZEOF(int));
  83   cconvert->Cr_g_tab = (INT32 *)
  84     (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
  85                                 (MAXJSAMPLE+1) * SIZEOF(INT32));
  86   cconvert->Cb_g_tab = (INT32 *)
  87     (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
  88                                 (MAXJSAMPLE+1) * SIZEOF(INT32));
  89 
  90   for (i = 0, x = -CENTERJSAMPLE; i <= MAXJSAMPLE; i++, x++) {
  91     /* i is the actual input pixel value, in the range 0..MAXJSAMPLE */
  92     /* The Cb or Cr value we are thinking of is x = i - CENTERJSAMPLE */
  93     /* Cr=>R value is nearest int to 1.40200 * x */
  94     cconvert->Cr_r_tab[i] = (int)
  95                     RIGHT_SHIFT(FIX(1.40200) * x + ONE_HALF, SCALEBITS);
  96     /* Cb=>B value is nearest int to 1.77200 * x */
  97     cconvert->Cb_b_tab[i] = (int)
  98                     RIGHT_SHIFT(FIX(1.77200) * x + ONE_HALF, SCALEBITS);
  99     /* Cr=>G value is scaled-up -0.71414 * x */
 100     cconvert->Cr_g_tab[i] = (- FIX(0.71414)) * x;
 101     /* Cb=>G value is scaled-up -0.34414 * x */
 102     /* We also add in ONE_HALF so that need not do it in inner loop */
 103     cconvert->Cb_g_tab[i] = (- FIX(0.34414)) * x + ONE_HALF;
 104   }
 105 }
 106 
 107 
 108 /*
 109  * Convert some rows of samples to the output colorspace.
 110  *
 111  * Note that we change from noninterleaved, one-plane-per-component format
 112  * to interleaved-pixel format.  The output buffer is therefore three times
 113  * as wide as the input buffer.
 114  * A starting row offset is provided only for the input buffer.  The caller
 115  * can easily adjust the passed output_buf value to accommodate any row
 116  * offset required on that side.
 117  */
 118 
 119 METHODDEF(void)
 120 ycc_rgb_convert (j_decompress_ptr cinfo,
 121                  JSAMPIMAGE input_buf, JDIMENSION input_row,
 122                  JSAMPARRAY output_buf, int num_rows)
 123 {
 124   my_cconvert_ptr cconvert = (my_cconvert_ptr) cinfo->cconvert;
 125   register int y, cb, cr;
 126   register JSAMPROW outptr;
 127   register JSAMPROW inptr0, inptr1, inptr2;
 128   register JDIMENSION col;
 129   JDIMENSION num_cols = cinfo->output_width;
 130   /* copy these pointers into registers if possible */
 131   register JSAMPLE * range_limit = cinfo->sample_range_limit;
 132   register int * Crrtab = cconvert->Cr_r_tab;
 133   register int * Cbbtab = cconvert->Cb_b_tab;
 134   register INT32 * Crgtab = cconvert->Cr_g_tab;
 135   register INT32 * Cbgtab = cconvert->Cb_g_tab;
 136   SHIFT_TEMPS
 137 
 138   while (--num_rows >= 0) {
 139     inptr0 = input_buf[0][input_row];
 140     inptr1 = input_buf[1][input_row];
 141     inptr2 = input_buf[2][input_row];
 142     input_row++;
 143     outptr = *output_buf++;
 144     for (col = 0; col < num_cols; col++) {
 145       y  = GETJSAMPLE(inptr0[col]);
 146       cb = GETJSAMPLE(inptr1[col]);
 147       cr = GETJSAMPLE(inptr2[col]);
 148       /* Range-limiting is essential due to noise introduced by DCT losses. */
 149       outptr[RGB_RED] =   range_limit[y + Crrtab[cr]];
 150       outptr[RGB_GREEN] = range_limit[y +
 151                               ((int) RIGHT_SHIFT(Cbgtab[cb] + Crgtab[cr],
 152                                                  SCALEBITS))];
 153       outptr[RGB_BLUE] =  range_limit[y + Cbbtab[cb]];
 154       outptr += RGB_PIXELSIZE;
 155     }
 156   }
 157 }
 158 
 159 
 160 /**************** Cases other than YCbCr -> RGB **************/
 161 
 162 
 163 /*
 164  * Color conversion for no colorspace change: just copy the data,
 165  * converting from separate-planes to interleaved representation.
 166  */
 167 
 168 METHODDEF(void)
 169 null_convert (j_decompress_ptr cinfo,
 170               JSAMPIMAGE input_buf, JDIMENSION input_row,
 171               JSAMPARRAY output_buf, int num_rows)
 172 {
 173   register JSAMPROW inptr, outptr;
 174   register JDIMENSION count;
 175   register int num_components = cinfo->num_components;
 176   JDIMENSION num_cols = cinfo->output_width;
 177   int ci;
 178 
 179   while (--num_rows >= 0) {
 180     for (ci = 0; ci < num_components; ci++) {
 181       inptr = input_buf[ci][input_row];
 182       outptr = output_buf[0] + ci;
 183       for (count = num_cols; count > 0; count--) {
 184         *outptr = *inptr++;     /* needn't bother with GETJSAMPLE() here */
 185         outptr += num_components;
 186       }
 187     }
 188     input_row++;
 189     output_buf++;
 190   }
 191 }
 192 
 193 
 194 /*
 195  * Color conversion for grayscale: just copy the data.
 196  * This also works for YCbCr -> grayscale conversion, in which
 197  * we just copy the Y (luminance) component and ignore chrominance.
 198  */
 199 
 200 METHODDEF(void)
 201 grayscale_convert (j_decompress_ptr cinfo,
 202                    JSAMPIMAGE input_buf, JDIMENSION input_row,
 203                    JSAMPARRAY output_buf, int num_rows)
 204 {
 205   jcopy_sample_rows(input_buf[0], (int) input_row, output_buf, 0,
 206                     num_rows, cinfo->output_width);
 207 }
 208 
 209 
 210 /*
 211  * Convert grayscale to RGB: just duplicate the graylevel three times.
 212  * This is provided to support applications that don't want to cope
 213  * with grayscale as a separate case.
 214  */
 215 
 216 METHODDEF(void)
 217 gray_rgb_convert (j_decompress_ptr cinfo,
 218                   JSAMPIMAGE input_buf, JDIMENSION input_row,
 219                   JSAMPARRAY output_buf, int num_rows)
 220 {
 221   register JSAMPROW inptr, outptr;
 222   register JDIMENSION col;
 223   JDIMENSION num_cols = cinfo->output_width;
 224 
 225   while (--num_rows >= 0) {
 226     inptr = input_buf[0][input_row++];
 227     outptr = *output_buf++;
 228     for (col = 0; col < num_cols; col++) {
 229       /* We can dispense with GETJSAMPLE() here */
 230       outptr[RGB_RED] = outptr[RGB_GREEN] = outptr[RGB_BLUE] = inptr[col];
 231       outptr += RGB_PIXELSIZE;
 232     }
 233   }
 234 }
 235 
 236 /*
 237  * YCCK->CMYK->CMY->RGB conversion.
 238  *
 239  * NB: this color conversion is introduced in jfx libjpeg snapshot as
 240  *     a part of the fix for RT-17000. In case of library upgrade, please
 241  *     check whether this convertor needs to be moved into upgraded version
 242  *     of the library.
 243  */
 244 METHODDEF(void)
 245 ycck_rgb_convert (j_decompress_ptr cinfo,
 246                    JSAMPIMAGE input_buf, JDIMENSION input_row,
 247                    JSAMPARRAY output_buf, int num_rows)
 248 {
 249   my_cconvert_ptr cconvert = (my_cconvert_ptr) cinfo->cconvert;
 250   register int y, cb, cr, k;
 251   register int C, M, Y;
 252   register int r, g, b;
 253   register JSAMPROW outptr;
 254   register JSAMPROW inptr0, inptr1, inptr2, inptr3;
 255   register JDIMENSION col;
 256   JDIMENSION num_cols = cinfo->output_width;
 257   /* copy these pointers into registers if possible */
 258   register JSAMPLE * range_limit = cinfo->sample_range_limit;
 259   register int * Crrtab = cconvert->Cr_r_tab;
 260   register int * Cbbtab = cconvert->Cb_b_tab;
 261   register INT32 * Crgtab = cconvert->Cr_g_tab;
 262   register INT32 * Cbgtab = cconvert->Cb_g_tab;
 263   SHIFT_TEMPS
 264 
 265   while (--num_rows >= 0) {
 266     inptr0 = input_buf[0][input_row];
 267     inptr1 = input_buf[1][input_row];
 268     inptr2 = input_buf[2][input_row];
 269     inptr3 = input_buf[3][input_row];
 270     input_row++;
 271     outptr = *output_buf++;
 272     for (col = 0; col < num_cols; col++) {
 273       y  = GETJSAMPLE(inptr0[col]);
 274       cb = GETJSAMPLE(inptr1[col]);
 275       cr = GETJSAMPLE(inptr2[col]);
 276       k  = GETJSAMPLE(inptr3[col]);
 277 
 278       C = MAXJSAMPLE - (y + Crrtab[cr]);
 279       M = MAXJSAMPLE - (y + ((int) RIGHT_SHIFT(Cbgtab[cb] + Crgtab[cr], SCALEBITS)));
 280       Y = MAXJSAMPLE - (y + Cbbtab[cb]);
 281 
 282       r = C * k / MAXJSAMPLE;
 283       g = M * k / MAXJSAMPLE;
 284       b = Y * k / MAXJSAMPLE;
 285 
 286       /* Range-limiting is essential due to noise introduced by DCT losses. */
 287       outptr[RGB_RED] = range_limit[r];
 288       outptr[RGB_GREEN] = range_limit[g];
 289       outptr[RGB_BLUE] = range_limit[b];
 290 
 291       outptr += RGB_PIXELSIZE;
 292     }
 293   }
 294 }
 295 
 296 /*
 297  * CMYK->CMY->RGB conversion.
 298  *
 299  * NB: this color conversion is introduced in jfx libjpeg snapshot as
 300  *     a part of the fix for RT-17000. In case of library upgrade, please
 301  *     check whether this convertor needs to be moved into upgraded version
 302  *     of the library.
 303  */
 304 METHODDEF(void)
 305 cmyk_rgb_convert (j_decompress_ptr cinfo,
 306                    JSAMPIMAGE input_buf, JDIMENSION input_row,
 307                    JSAMPARRAY output_buf, int num_rows)
 308 {
 309   my_cconvert_ptr cconvert = (my_cconvert_ptr) cinfo->cconvert;
 310   register int c, m, y, k;
 311   register int r, g, b;
 312   register JSAMPROW outptr;
 313   register JSAMPROW inptr0, inptr1, inptr2, inptr3;
 314   register JDIMENSION col;
 315   JDIMENSION num_cols = cinfo->output_width;
 316   /* copy these pointers into registers if possible */
 317   register JSAMPLE * range_limit = cinfo->sample_range_limit;
 318   SHIFT_TEMPS
 319 
 320   while (--num_rows >= 0) {
 321     inptr0 = input_buf[0][input_row];
 322     inptr1 = input_buf[1][input_row];
 323     inptr2 = input_buf[2][input_row];
 324     inptr3 = input_buf[3][input_row];
 325     input_row++;
 326     outptr = *output_buf++;
 327     for (col = 0; col < num_cols; col++) {
 328       c = GETJSAMPLE(inptr0[col]);
 329       m = GETJSAMPLE(inptr1[col]);
 330       y = GETJSAMPLE(inptr2[col]);
 331       k = GETJSAMPLE(inptr3[col]);
 332 
 333       r = c * k / MAXJSAMPLE;
 334       g = m * k / MAXJSAMPLE;
 335       b = y * k / MAXJSAMPLE;
 336 
 337       /* Range-limiting is essential due to noise introduced by DCT losses. */
 338       outptr[RGB_RED] = range_limit[r];
 339       outptr[RGB_GREEN] = range_limit[g];
 340       outptr[RGB_BLUE] = range_limit[b];
 341 
 342       outptr += RGB_PIXELSIZE;
 343     }
 344   }
 345 }
 346 
 347 /*
 348  * Adobe-style YCCK->CMYK conversion.
 349  * We convert YCbCr to R=1-C, G=1-M, and B=1-Y using the same
 350  * conversion as above, while passing K (black) unchanged.
 351  * We assume build_ycc_rgb_table has been called.
 352  */
 353 
 354 METHODDEF(void)
 355 ycck_cmyk_convert (j_decompress_ptr cinfo,
 356                    JSAMPIMAGE input_buf, JDIMENSION input_row,
 357                    JSAMPARRAY output_buf, int num_rows)
 358 {
 359   my_cconvert_ptr cconvert = (my_cconvert_ptr) cinfo->cconvert;
 360   register int y, cb, cr;
 361   register JSAMPROW outptr;
 362   register JSAMPROW inptr0, inptr1, inptr2, inptr3;
 363   register JDIMENSION col;
 364   JDIMENSION num_cols = cinfo->output_width;
 365   /* copy these pointers into registers if possible */
 366   register JSAMPLE * range_limit = cinfo->sample_range_limit;
 367   register int * Crrtab = cconvert->Cr_r_tab;
 368   register int * Cbbtab = cconvert->Cb_b_tab;
 369   register INT32 * Crgtab = cconvert->Cr_g_tab;
 370   register INT32 * Cbgtab = cconvert->Cb_g_tab;
 371   SHIFT_TEMPS
 372 
 373   while (--num_rows >= 0) {
 374     inptr0 = input_buf[0][input_row];
 375     inptr1 = input_buf[1][input_row];
 376     inptr2 = input_buf[2][input_row];
 377     inptr3 = input_buf[3][input_row];
 378     input_row++;
 379     outptr = *output_buf++;
 380     for (col = 0; col < num_cols; col++) {
 381       y  = GETJSAMPLE(inptr0[col]);
 382       cb = GETJSAMPLE(inptr1[col]);
 383       cr = GETJSAMPLE(inptr2[col]);
 384       /* Range-limiting is essential due to noise introduced by DCT losses. */
 385       outptr[0] = range_limit[MAXJSAMPLE - (y + Crrtab[cr])];   /* red */
 386       outptr[1] = range_limit[MAXJSAMPLE - (y +                 /* green */
 387                               ((int) RIGHT_SHIFT(Cbgtab[cb] + Crgtab[cr],
 388                                                  SCALEBITS)))];
 389       outptr[2] = range_limit[MAXJSAMPLE - (y + Cbbtab[cb])];   /* blue */
 390       /* K passes through unchanged */
 391       outptr[3] = inptr3[col];  /* don't need GETJSAMPLE here */
 392       outptr += 4;
 393     }
 394   }
 395 }
 396 
 397 
 398 /*
 399  * Empty method for start_pass.
 400  */
 401 
 402 METHODDEF(void)
 403 start_pass_dcolor (j_decompress_ptr cinfo)
 404 {
 405   /* no work needed */
 406 }
 407 
 408 
 409 /*
 410  * Module initialization routine for output colorspace conversion.
 411  */
 412 
 413 GLOBAL(void)
 414 jinit_color_deconverter (j_decompress_ptr cinfo)
 415 {
 416   my_cconvert_ptr cconvert;
 417   int ci;
 418 
 419   cconvert = (my_cconvert_ptr)
 420     (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
 421                                 SIZEOF(my_color_deconverter));
 422   cinfo->cconvert = (struct jpeg_color_deconverter *) cconvert;
 423   cconvert->pub.start_pass = start_pass_dcolor;
 424 
 425   /* Make sure num_components agrees with jpeg_color_space */
 426   switch (cinfo->jpeg_color_space) {
 427   case JCS_GRAYSCALE:
 428     if (cinfo->num_components != 1)
 429       ERREXIT(cinfo, JERR_BAD_J_COLORSPACE);
 430     break;
 431 
 432   case JCS_RGB:
 433   case JCS_YCbCr:
 434     if (cinfo->num_components != 3)
 435       ERREXIT(cinfo, JERR_BAD_J_COLORSPACE);
 436     break;
 437 
 438   case JCS_CMYK:
 439   case JCS_YCCK:
 440     if (cinfo->num_components != 4)
 441       ERREXIT(cinfo, JERR_BAD_J_COLORSPACE);
 442     break;
 443 
 444   default:                      /* JCS_UNKNOWN can be anything */
 445     if (cinfo->num_components < 1)
 446       ERREXIT(cinfo, JERR_BAD_J_COLORSPACE);
 447     break;
 448   }
 449 
 450   /* Set out_color_components and conversion method based on requested space.
 451    * Also clear the component_needed flags for any unused components,
 452    * so that earlier pipeline stages can avoid useless computation.
 453    */
 454 
 455   switch (cinfo->out_color_space) {
 456   case JCS_GRAYSCALE:
 457     cinfo->out_color_components = 1;
 458     if (cinfo->jpeg_color_space == JCS_GRAYSCALE ||
 459         cinfo->jpeg_color_space == JCS_YCbCr) {
 460       cconvert->pub.color_convert = grayscale_convert;
 461       /* For color->grayscale conversion, only the Y (0) component is needed */
 462       for (ci = 1; ci < cinfo->num_components; ci++)
 463         cinfo->comp_info[ci].component_needed = FALSE;
 464     } else
 465       ERREXIT(cinfo, JERR_CONVERSION_NOTIMPL);
 466     break;
 467 
 468   case JCS_RGB:
 469     cinfo->out_color_components = RGB_PIXELSIZE;
 470     if (cinfo->jpeg_color_space == JCS_YCbCr) {
 471       cconvert->pub.color_convert = ycc_rgb_convert;
 472       build_ycc_rgb_table(cinfo);
 473     } else if (cinfo->jpeg_color_space == JCS_GRAYSCALE) {
 474       cconvert->pub.color_convert = gray_rgb_convert;
 475     } else if (cinfo->jpeg_color_space == JCS_RGB && RGB_PIXELSIZE == 3) {
 476       cconvert->pub.color_convert = null_convert;
 477     } else if (cinfo->jpeg_color_space == JCS_YCCK) {
 478       cconvert->pub.color_convert = ycck_rgb_convert;
 479       build_ycc_rgb_table(cinfo);
 480     } else if (cinfo->jpeg_color_space == JCS_CMYK) {
 481       cconvert->pub.color_convert = cmyk_rgb_convert;
 482     } else {
 483       ERREXIT(cinfo, JERR_CONVERSION_NOTIMPL);
 484     }
 485     break;
 486 
 487   case JCS_CMYK:
 488     cinfo->out_color_components = 4;
 489     if (cinfo->jpeg_color_space == JCS_YCCK) {
 490       cconvert->pub.color_convert = ycck_cmyk_convert;
 491       build_ycc_rgb_table(cinfo);
 492     } else if (cinfo->jpeg_color_space == JCS_CMYK) {
 493       cconvert->pub.color_convert = null_convert;
 494     } else
 495       ERREXIT(cinfo, JERR_CONVERSION_NOTIMPL);
 496     break;
 497 
 498   default:
 499     /* Permit null conversion to same output space */
 500     if (cinfo->out_color_space == cinfo->jpeg_color_space) {
 501       cinfo->out_color_components = cinfo->num_components;
 502       cconvert->pub.color_convert = null_convert;
 503     } else                      /* unsupported non-null conversion */
 504       ERREXIT(cinfo, JERR_CONVERSION_NOTIMPL);
 505     break;
 506   }
 507 
 508   if (cinfo->quantize_colors)
 509     cinfo->output_components = 1; /* single colormapped output component */
 510   else
 511     cinfo->output_components = cinfo->out_color_components;
 512 }