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. 
   8  * This file contains output colorspace conversion routines. 
  11 #define JPEG_INTERNALS 
  16 /* Private subobject */ 
  19   struct jpeg_color_deconverter pub
; /* public fields */ 
  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
; 
  28 typedef my_color_deconverter 
* my_cconvert_ptr
; 
  31 /**************** YCbCr -> RGB conversion: most common case **************/ 
  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.) 
  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. 
  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 
  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. 
  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)) 
  66  * Initialize tables for YCC->RGB colorspace conversion. 
  70 build_ycc_rgb_table (j_decompress_ptr cinfo
) 
  72   my_cconvert_ptr cconvert 
= (my_cconvert_ptr
) cinfo
->cconvert
; 
  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
)); 
  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
; 
 109  * Convert some rows of samples to the output colorspace. 
 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. 
 120 ycc_rgb_convert (j_decompress_ptr cinfo
, 
 121                  JSAMPIMAGE input_buf
, JDIMENSION input_row
, 
 122                  JSAMPARRAY output_buf
, int num_rows
) 
 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
; 
 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
]; 
 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
], 
 153       outptr
[RGB_BLUE
] =  range_limit
[y 
+ Cbbtab
[cb
]]; 
 154       outptr 
+= RGB_PIXELSIZE
; 
 160 /**************** Cases other than YCbCr -> RGB **************/ 
 164  * Color conversion for no colorspace change: just copy the data, 
 165  * converting from separate-planes to interleaved representation. 
 169 null_convert (j_decompress_ptr cinfo
, 
 170               JSAMPIMAGE input_buf
, JDIMENSION input_row
, 
 171               JSAMPARRAY output_buf
, int num_rows
) 
 173   register JSAMPROW inptr
, outptr
; 
 174   register JDIMENSION count
; 
 175   register int num_components 
= cinfo
->num_components
; 
 176   JDIMENSION num_cols 
= cinfo
->output_width
; 
 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
; 
 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. 
 201 grayscale_convert (j_decompress_ptr cinfo
, 
 202                    JSAMPIMAGE input_buf
, JDIMENSION input_row
, 
 203                    JSAMPARRAY output_buf
, int num_rows
) 
 205   jcopy_sample_rows(input_buf
[0], (int) input_row
, output_buf
, 0, 
 206                     num_rows
, cinfo
->output_width
); 
 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. 
 217 gray_rgb_convert (j_decompress_ptr cinfo
, 
 218                   JSAMPIMAGE input_buf
, JDIMENSION input_row
, 
 219                   JSAMPARRAY output_buf
, int num_rows
) 
 221   register JSAMPROW inptr
, outptr
; 
 222   register JDIMENSION col
; 
 223   JDIMENSION num_cols 
= cinfo
->output_width
; 
 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
; 
 238  * Adobe-style YCCK->CMYK conversion. 
 239  * We convert YCbCr to R=1-C, G=1-M, and B=1-Y using the same 
 240  * conversion as above, while passing K (black) unchanged. 
 241  * We assume build_ycc_rgb_table has been called. 
 245 ycck_cmyk_convert (j_decompress_ptr cinfo
, 
 246                    JSAMPIMAGE input_buf
, JDIMENSION input_row
, 
 247                    JSAMPARRAY output_buf
, int num_rows
) 
 249   my_cconvert_ptr cconvert 
= (my_cconvert_ptr
) cinfo
->cconvert
; 
 250   register int y
, cb
, cr
; 
 251   register JSAMPROW outptr
; 
 252   register JSAMPROW inptr0
, inptr1
, inptr2
, inptr3
; 
 253   register JDIMENSION col
; 
 254   JDIMENSION num_cols 
= cinfo
->output_width
; 
 255   /* copy these pointers into registers if possible */ 
 256   register JSAMPLE 
* range_limit 
= cinfo
->sample_range_limit
; 
 257   register int * Crrtab 
= cconvert
->Cr_r_tab
; 
 258   register int * Cbbtab 
= cconvert
->Cb_b_tab
; 
 259   register INT32 
* Crgtab 
= cconvert
->Cr_g_tab
; 
 260   register INT32 
* Cbgtab 
= cconvert
->Cb_g_tab
; 
 263   while (--num_rows 
>= 0) { 
 264     inptr0 
= input_buf
[0][input_row
]; 
 265     inptr1 
= input_buf
[1][input_row
]; 
 266     inptr2 
= input_buf
[2][input_row
]; 
 267     inptr3 
= input_buf
[3][input_row
]; 
 269     outptr 
= *output_buf
++; 
 270     for (col 
= 0; col 
< num_cols
; col
++) { 
 271       y  
= GETJSAMPLE(inptr0
[col
]); 
 272       cb 
= GETJSAMPLE(inptr1
[col
]); 
 273       cr 
= GETJSAMPLE(inptr2
[col
]); 
 274       /* Range-limiting is essential due to noise introduced by DCT losses. */ 
 275       outptr
[0] = range_limit
[MAXJSAMPLE 
- (y 
+ Crrtab
[cr
])];   /* red */ 
 276       outptr
[1] = range_limit
[MAXJSAMPLE 
- (y 
+                 /* green */ 
 277                               ((int) RIGHT_SHIFT(Cbgtab
[cb
] + Crgtab
[cr
], 
 279       outptr
[2] = range_limit
[MAXJSAMPLE 
- (y 
+ Cbbtab
[cb
])];   /* blue */ 
 280       /* K passes through unchanged */ 
 281       outptr
[3] = inptr3
[col
];  /* don't need GETJSAMPLE here */ 
 289  * Empty method for start_pass. 
 293 start_pass_dcolor (j_decompress_ptr cinfo
) 
 300  * Module initialization routine for output colorspace conversion. 
 304 jinit_color_deconverter (j_decompress_ptr cinfo
) 
 306   my_cconvert_ptr cconvert
; 
 309   cconvert 
= (my_cconvert_ptr
) 
 310     (*cinfo
->mem
->alloc_small
) ((j_common_ptr
) cinfo
, JPOOL_IMAGE
, 
 311                                 SIZEOF(my_color_deconverter
)); 
 312   cinfo
->cconvert 
= (struct jpeg_color_deconverter 
*) cconvert
; 
 313   cconvert
->pub
.start_pass 
= start_pass_dcolor
; 
 315   /* Make sure num_components agrees with jpeg_color_space */ 
 316   switch (cinfo
->jpeg_color_space
) { 
 318     if (cinfo
->num_components 
!= 1) 
 319       ERREXIT(cinfo
, JERR_BAD_J_COLORSPACE
); 
 324     if (cinfo
->num_components 
!= 3) 
 325       ERREXIT(cinfo
, JERR_BAD_J_COLORSPACE
); 
 330     if (cinfo
->num_components 
!= 4) 
 331       ERREXIT(cinfo
, JERR_BAD_J_COLORSPACE
); 
 334   default:                      /* JCS_UNKNOWN can be anything */ 
 335     if (cinfo
->num_components 
< 1) 
 336       ERREXIT(cinfo
, JERR_BAD_J_COLORSPACE
); 
 340   /* Set out_color_components and conversion method based on requested space. 
 341    * Also clear the component_needed flags for any unused components, 
 342    * so that earlier pipeline stages can avoid useless computation. 
 345   switch (cinfo
->out_color_space
) { 
 347     cinfo
->out_color_components 
= 1; 
 348     if (cinfo
->jpeg_color_space 
== JCS_GRAYSCALE 
|| 
 349         cinfo
->jpeg_color_space 
== JCS_YCbCr
) { 
 350       cconvert
->pub
.color_convert 
= grayscale_convert
; 
 351       /* For color->grayscale conversion, only the Y (0) component is needed */ 
 352       for (ci 
= 1; ci 
< cinfo
->num_components
; ci
++) 
 353         cinfo
->comp_info
[ci
].component_needed 
= FALSE
; 
 355       ERREXIT(cinfo
, JERR_CONVERSION_NOTIMPL
); 
 359     cinfo
->out_color_components 
= RGB_PIXELSIZE
; 
 360     if (cinfo
->jpeg_color_space 
== JCS_YCbCr
) { 
 361       cconvert
->pub
.color_convert 
= ycc_rgb_convert
; 
 362       build_ycc_rgb_table(cinfo
); 
 363     } else if (cinfo
->jpeg_color_space 
== JCS_GRAYSCALE
) { 
 364       cconvert
->pub
.color_convert 
= gray_rgb_convert
; 
 365     } else if (cinfo
->jpeg_color_space 
== JCS_RGB 
&& RGB_PIXELSIZE 
== 3) { 
 366       cconvert
->pub
.color_convert 
= null_convert
; 
 368       ERREXIT(cinfo
, JERR_CONVERSION_NOTIMPL
); 
 372     cinfo
->out_color_components 
= 4; 
 373     if (cinfo
->jpeg_color_space 
== JCS_YCCK
) { 
 374       cconvert
->pub
.color_convert 
= ycck_cmyk_convert
; 
 375       build_ycc_rgb_table(cinfo
); 
 376     } else if (cinfo
->jpeg_color_space 
== JCS_CMYK
) { 
 377       cconvert
->pub
.color_convert 
= null_convert
; 
 379       ERREXIT(cinfo
, JERR_CONVERSION_NOTIMPL
); 
 383     /* Permit null conversion to same output space */ 
 384     if (cinfo
->out_color_space 
== cinfo
->jpeg_color_space
) { 
 385       cinfo
->out_color_components 
= cinfo
->num_components
; 
 386       cconvert
->pub
.color_convert 
= null_convert
; 
 387     } else                      /* unsupported non-null conversion */ 
 388       ERREXIT(cinfo
, JERR_CONVERSION_NOTIMPL
); 
 392   if (cinfo
->quantize_colors
) 
 393     cinfo
->output_components 
= 1; /* single colormapped output component */ 
 395     cinfo
->output_components 
= cinfo
->out_color_components
;