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