jdcolor.cpp (14097B)
1 /* 2 * jdcolor.c 3 * 4 * Copyright (C) 1991-1995, 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 my_cconvert_ptr cconvert = (my_cconvert_ptr) cinfo->cconvert; 72 int i; 73 INT32 x; 74 SHIFT_TEMPS 75 76 cconvert->Cr_r_tab = (int *) 77 ( *cinfo->mem->alloc_small )( (j_common_ptr) cinfo, JPOOL_IMAGE, 78 ( MAXJSAMPLE + 1 ) * SIZEOF( int ) ); 79 cconvert->Cb_b_tab = (int *) 80 ( *cinfo->mem->alloc_small )( (j_common_ptr) cinfo, JPOOL_IMAGE, 81 ( MAXJSAMPLE + 1 ) * SIZEOF( int ) ); 82 cconvert->Cr_g_tab = (INT32 *) 83 ( *cinfo->mem->alloc_small )( (j_common_ptr) cinfo, JPOOL_IMAGE, 84 ( MAXJSAMPLE + 1 ) * SIZEOF( INT32 ) ); 85 cconvert->Cb_g_tab = (INT32 *) 86 ( *cinfo->mem->alloc_small )( (j_common_ptr) cinfo, JPOOL_IMAGE, 87 ( MAXJSAMPLE + 1 ) * SIZEOF( INT32 ) ); 88 89 for ( i = 0, x = -CENTERJSAMPLE; i <= MAXJSAMPLE; i++, x++ ) { 90 /* i is the actual input pixel value, in the range 0..MAXJSAMPLE */ 91 /* The Cb or Cr value we are thinking of is x = i - CENTERJSAMPLE */ 92 /* Cr=>R value is nearest int to 1.40200 * x */ 93 cconvert->Cr_r_tab[i] = (int) 94 RIGHT_SHIFT( FIX( 1.40200 ) * x + ONE_HALF, SCALEBITS ); 95 /* Cb=>B value is nearest int to 1.77200 * x */ 96 cconvert->Cb_b_tab[i] = (int) 97 RIGHT_SHIFT( FIX( 1.77200 ) * x + ONE_HALF, SCALEBITS ); 98 /* Cr=>G value is scaled-up -0.71414 * x */ 99 cconvert->Cr_g_tab[i] = ( -FIX( 0.71414 ) ) * x; 100 /* Cb=>G value is scaled-up -0.34414 * x */ 101 /* We also add in ONE_HALF so that need not do it in inner loop */ 102 cconvert->Cb_g_tab[i] = ( -FIX( 0.34414 ) ) * x + ONE_HALF; 103 } 104 } 105 106 107 /* 108 * Convert some rows of samples to the output colorspace. 109 * 110 * Note that we change from noninterleaved, one-plane-per-component format 111 * to interleaved-pixel format. The output buffer is therefore three times 112 * as wide as the input buffer. 113 * A starting row offset is provided only for the input buffer. The caller 114 * can easily adjust the passed output_buf value to accommodate any row 115 * offset required on that side. 116 */ 117 118 METHODDEF void 119 ycc_rgb_convert( j_decompress_ptr cinfo, 120 JSAMPIMAGE input_buf, JDIMENSION input_row, 121 JSAMPARRAY output_buf, int num_rows ) { 122 my_cconvert_ptr cconvert = (my_cconvert_ptr) cinfo->cconvert; 123 register int y, cb, cr; 124 register JSAMPROW outptr; 125 register JSAMPROW inptr0, inptr1, inptr2; 126 register JDIMENSION col; 127 JDIMENSION num_cols = cinfo->output_width; 128 /* copy these pointers into registers if possible */ 129 register JSAMPLE * range_limit = cinfo->sample_range_limit; 130 register int * Crrtab = cconvert->Cr_r_tab; 131 register int * Cbbtab = cconvert->Cb_b_tab; 132 register INT32 * Crgtab = cconvert->Cr_g_tab; 133 register INT32 * Cbgtab = cconvert->Cb_g_tab; 134 SHIFT_TEMPS 135 136 while ( --num_rows >= 0 ) { 137 inptr0 = input_buf[0][input_row]; 138 inptr1 = input_buf[1][input_row]; 139 inptr2 = input_buf[2][input_row]; 140 input_row++; 141 outptr = *output_buf++; 142 for ( col = 0; col < num_cols; col++ ) { 143 y = GETJSAMPLE( inptr0[col] ); 144 cb = GETJSAMPLE( inptr1[col] ); 145 cr = GETJSAMPLE( inptr2[col] ); 146 /* Range-limiting is essential due to noise introduced by DCT losses. */ 147 outptr[RGB_RED] = range_limit[y + Crrtab[cr]]; 148 outptr[RGB_GREEN] = range_limit[y + 149 ( (int) RIGHT_SHIFT( Cbgtab[cb] + Crgtab[cr], 150 SCALEBITS ) )]; 151 outptr[RGB_BLUE] = range_limit[y + Cbbtab[cb]]; 152 outptr += RGB_PIXELSIZE; 153 } 154 } 155 } 156 157 158 /**************** Cases other than YCbCr -> RGB **************/ 159 160 161 /* 162 * Color conversion for no colorspace change: just copy the data, 163 * converting from separate-planes to interleaved representation. 164 */ 165 166 METHODDEF void 167 null_convert( j_decompress_ptr cinfo, 168 JSAMPIMAGE input_buf, JDIMENSION input_row, 169 JSAMPARRAY output_buf, int num_rows ) { 170 register JSAMPROW inptr, outptr; 171 register JDIMENSION count; 172 register int num_components = cinfo->num_components; 173 JDIMENSION num_cols = cinfo->output_width; 174 int ci; 175 176 while ( --num_rows >= 0 ) { 177 for ( ci = 0; ci < num_components; ci++ ) { 178 inptr = input_buf[ci][input_row]; 179 outptr = output_buf[0] + ci; 180 for ( count = num_cols; count > 0; count-- ) { 181 *outptr = *inptr++;/* needn't bother with GETJSAMPLE() here */ 182 outptr += num_components; 183 } 184 } 185 input_row++; 186 output_buf++; 187 } 188 } 189 190 191 /* 192 * Color conversion for grayscale: just copy the data. 193 * This also works for YCbCr -> grayscale conversion, in which 194 * we just copy the Y (luminance) component and ignore chrominance. 195 */ 196 197 METHODDEF void 198 grayscale_convert( j_decompress_ptr cinfo, 199 JSAMPIMAGE input_buf, JDIMENSION input_row, 200 JSAMPARRAY output_buf, int num_rows ) { 201 jcopy_sample_rows( input_buf[0], (int) input_row, output_buf, 0, 202 num_rows, cinfo->output_width ); 203 } 204 205 206 /* 207 * Adobe-style YCCK->CMYK conversion. 208 * We convert YCbCr to R=1-C, G=1-M, and B=1-Y using the same 209 * conversion as above, while passing K (black) unchanged. 210 * We assume build_ycc_rgb_table has been called. 211 */ 212 213 METHODDEF void 214 ycck_cmyk_convert( j_decompress_ptr cinfo, 215 JSAMPIMAGE input_buf, JDIMENSION input_row, 216 JSAMPARRAY output_buf, int num_rows ) { 217 my_cconvert_ptr cconvert = (my_cconvert_ptr) cinfo->cconvert; 218 register int y, cb, cr; 219 register JSAMPROW outptr; 220 register JSAMPROW inptr0, inptr1, inptr2, inptr3; 221 register JDIMENSION col; 222 JDIMENSION num_cols = cinfo->output_width; 223 /* copy these pointers into registers if possible */ 224 register JSAMPLE * range_limit = cinfo->sample_range_limit; 225 register int * Crrtab = cconvert->Cr_r_tab; 226 register int * Cbbtab = cconvert->Cb_b_tab; 227 register INT32 * Crgtab = cconvert->Cr_g_tab; 228 register INT32 * Cbgtab = cconvert->Cb_g_tab; 229 SHIFT_TEMPS 230 231 while ( --num_rows >= 0 ) { 232 inptr0 = input_buf[0][input_row]; 233 inptr1 = input_buf[1][input_row]; 234 inptr2 = input_buf[2][input_row]; 235 inptr3 = input_buf[3][input_row]; 236 input_row++; 237 outptr = *output_buf++; 238 for ( col = 0; col < num_cols; col++ ) { 239 y = GETJSAMPLE( inptr0[col] ); 240 cb = GETJSAMPLE( inptr1[col] ); 241 cr = GETJSAMPLE( inptr2[col] ); 242 /* Range-limiting is essential due to noise introduced by DCT losses. */ 243 outptr[0] = range_limit[MAXJSAMPLE - ( y + Crrtab[cr] )];/* red */ 244 outptr[1] = range_limit[MAXJSAMPLE - ( y + /* green */ 245 ( (int) RIGHT_SHIFT( Cbgtab[cb] + Crgtab[cr], 246 SCALEBITS ) ) )]; 247 outptr[2] = range_limit[MAXJSAMPLE - ( y + Cbbtab[cb] )];/* blue */ 248 /* K passes through unchanged */ 249 outptr[3] = inptr3[col];/* don't need GETJSAMPLE here */ 250 outptr += 4; 251 } 252 } 253 } 254 255 256 /* 257 * Empty method for start_pass. 258 */ 259 260 METHODDEF void 261 start_pass_dcolor( j_decompress_ptr cinfo ) { 262 /* no work needed */ 263 } 264 265 266 /* 267 * Module initialization routine for output colorspace conversion. 268 */ 269 270 GLOBAL void 271 jinit_color_deconverter( j_decompress_ptr cinfo ) { 272 my_cconvert_ptr cconvert; 273 int ci; 274 275 cconvert = (my_cconvert_ptr) 276 ( *cinfo->mem->alloc_small )( (j_common_ptr) cinfo, JPOOL_IMAGE, 277 SIZEOF( my_color_deconverter ) ); 278 cinfo->cconvert = (struct jpeg_color_deconverter *) cconvert; 279 cconvert->pub.start_pass = start_pass_dcolor; 280 281 /* Make sure num_components agrees with jpeg_color_space */ 282 switch ( cinfo->jpeg_color_space ) { 283 case JCS_GRAYSCALE: 284 if ( cinfo->num_components != 1 ) { 285 ERREXIT( cinfo, JERR_BAD_J_COLORSPACE ); 286 } 287 break; 288 289 case JCS_RGB: 290 case JCS_YCbCr: 291 if ( cinfo->num_components != 3 ) { 292 ERREXIT( cinfo, JERR_BAD_J_COLORSPACE ); 293 } 294 break; 295 296 case JCS_CMYK: 297 case JCS_YCCK: 298 if ( cinfo->num_components != 4 ) { 299 ERREXIT( cinfo, JERR_BAD_J_COLORSPACE ); 300 } 301 break; 302 303 default: /* JCS_UNKNOWN can be anything */ 304 if ( cinfo->num_components < 1 ) { 305 ERREXIT( cinfo, JERR_BAD_J_COLORSPACE ); 306 } 307 break; 308 } 309 310 /* Set out_color_components and conversion method based on requested space. 311 * Also clear the component_needed flags for any unused components, 312 * so that earlier pipeline stages can avoid useless computation. 313 */ 314 315 switch ( cinfo->out_color_space ) { 316 case JCS_GRAYSCALE: 317 cinfo->out_color_components = 1; 318 if ( ( cinfo->jpeg_color_space == JCS_GRAYSCALE ) || 319 ( cinfo->jpeg_color_space == JCS_YCbCr ) ) { 320 cconvert->pub.color_convert = grayscale_convert; 321 /* For color->grayscale conversion, only the Y (0) component is needed */ 322 for ( ci = 1; ci < cinfo->num_components; ci++ ) { 323 cinfo->comp_info[ci].component_needed = FALSE; 324 } 325 } else { 326 ERREXIT( cinfo, JERR_CONVERSION_NOTIMPL ); 327 } 328 break; 329 330 case JCS_RGB: 331 cinfo->out_color_components = RGB_PIXELSIZE; 332 if ( cinfo->jpeg_color_space == JCS_YCbCr ) { 333 cconvert->pub.color_convert = ycc_rgb_convert; 334 build_ycc_rgb_table( cinfo ); 335 } else if ( cinfo->jpeg_color_space == JCS_RGB && RGB_PIXELSIZE == 3 ) { 336 cconvert->pub.color_convert = null_convert; 337 } else { 338 ERREXIT( cinfo, JERR_CONVERSION_NOTIMPL ); 339 } 340 break; 341 342 case JCS_CMYK: 343 cinfo->out_color_components = 4; 344 if ( cinfo->jpeg_color_space == JCS_YCCK ) { 345 cconvert->pub.color_convert = ycck_cmyk_convert; 346 build_ycc_rgb_table( cinfo ); 347 } else if ( cinfo->jpeg_color_space == JCS_CMYK ) { 348 cconvert->pub.color_convert = null_convert; 349 } else { 350 ERREXIT( cinfo, JERR_CONVERSION_NOTIMPL ); 351 } 352 break; 353 354 default: 355 /* Permit null conversion to same output space */ 356 if ( cinfo->out_color_space == cinfo->jpeg_color_space ) { 357 cinfo->out_color_components = cinfo->num_components; 358 cconvert->pub.color_convert = null_convert; 359 } else {/* unsupported non-null conversion */ 360 ERREXIT( cinfo, JERR_CONVERSION_NOTIMPL ); 361 } 362 break; 363 } 364 365 if ( cinfo->quantize_colors ) { 366 cinfo->output_components = 1; 367 } /* single colormapped output component */ 368 else { 369 cinfo->output_components = cinfo->out_color_components; 370 } 371 }