< prev index next >

modules/javafx.graphics/src/main/native-iio/libjpeg7/jdcolor.c

Print this page

        

*** 1,9 **** --- 1,10 ---- /* * jdcolor.c * * Copyright (C) 1991-1997, Thomas G. Lane. + * Modified 2011-2017 by Guido Vollbeding. * This file is part of the Independent JPEG Group's software. * For conditions of distribution and use, see the accompanying README file. * * This file contains output colorspace conversion routines. */
*** 11,75 **** #define JPEG_INTERNALS #include "jinclude.h" #include "jpeglib.h" /* Private subobject */ typedef struct { struct jpeg_color_deconverter pub; /* public fields */ ! /* Private state for YCC->RGB conversion */ int * Cr_r_tab; /* => table for Cr to R conversion */ int * Cb_b_tab; /* => table for Cb to B conversion */ INT32 * Cr_g_tab; /* => table for Cr to G conversion */ INT32 * Cb_g_tab; /* => table for Cb to G conversion */ } my_color_deconverter; typedef my_color_deconverter * my_cconvert_ptr; ! /**************** YCbCr -> RGB conversion: most common case **************/ /* ! * YCbCr is defined per CCIR 601-1, except that Cb and Cr are ! * normalized to the range 0..MAXJSAMPLE rather than -0.5 .. 0.5. ! * The conversion equations to be implemented are therefore ! * R = Y + 1.40200 * Cr ! * G = Y - 0.34414 * Cb - 0.71414 * Cr ! * B = Y + 1.77200 * Cb * where Cb and Cr represent the incoming values less CENTERJSAMPLE. ! * (These numbers are derived from TIFF 6.0 section 21, dated 3-June-92.) * * To avoid floating-point arithmetic, we represent the fractional constants * as integers scaled up by 2^16 (about 4 digits precision); we have to divide * the products by 2^16, with appropriate rounding, to get the correct answer. * Notice that Y, being an integral input, does not contribute any fraction * so it need not participate in the rounding. * * For even more speed, we avoid doing any multiplications in the inner loop * by precalculating the constants times Cb and Cr for all possible values. * For 8-bit JSAMPLEs this is very reasonable (only 256 entries per table); ! * for 12-bit samples it is still acceptable. It's not very reasonable for ! * 16-bit samples, but if you want lossless storage you shouldn't be changing ! * colorspace anyway. * The Cr=>R and Cb=>B values can be rounded to integers in advance; the * values for the G calculation are left scaled up, since we must add them * together before rounding. */ #define SCALEBITS 16 /* speediest right-shift on some machines */ #define ONE_HALF ((INT32) 1 << (SCALEBITS-1)) #define FIX(x) ((INT32) ((x) * (1L<<SCALEBITS) + 0.5)) /* ! * Initialize tables for YCC->RGB colorspace conversion. */ LOCAL(void) build_ycc_rgb_table (j_decompress_ptr cinfo) { my_cconvert_ptr cconvert = (my_cconvert_ptr) cinfo->cconvert; int i; INT32 x; SHIFT_TEMPS --- 12,165 ---- #define JPEG_INTERNALS #include "jinclude.h" #include "jpeglib.h" + #if RANGE_BITS < 2 + /* Deliberate syntax err */ + Sorry, this code requires 2 or more range extension bits. + #endif + + /* Private subobject */ typedef struct { struct jpeg_color_deconverter pub; /* public fields */ ! /* Private state for YCbCr->RGB and BG_YCC->RGB conversion */ int * Cr_r_tab; /* => table for Cr to R conversion */ int * Cb_b_tab; /* => table for Cb to B conversion */ INT32 * Cr_g_tab; /* => table for Cr to G conversion */ INT32 * Cb_g_tab; /* => table for Cb to G conversion */ + + /* Private state for RGB->Y conversion */ + INT32 * rgb_y_tab; /* => table for RGB to Y conversion */ } my_color_deconverter; typedef my_color_deconverter * my_cconvert_ptr; ! /*************** YCbCr -> RGB conversion: most common case **************/ ! /*************** BG_YCC -> RGB conversion: less common case **************/ ! /*************** RGB -> Y conversion: less common case **************/ /* ! * YCbCr is defined per Recommendation ITU-R BT.601-7 (03/2011), ! * previously known as Recommendation CCIR 601-1, except that Cb and Cr ! * are normalized to the range 0..MAXJSAMPLE rather than -0.5 .. 0.5. ! * sRGB (standard RGB color space) is defined per IEC 61966-2-1:1999. ! * sYCC (standard luma-chroma-chroma color space with extended gamut) ! * is defined per IEC 61966-2-1:1999 Amendment A1:2003 Annex F. ! * bg-sRGB and bg-sYCC (big gamut standard color spaces) ! * are defined per IEC 61966-2-1:1999 Amendment A1:2003 Annex G. ! * Note that the derived conversion coefficients given in some of these ! * documents are imprecise. The general conversion equations are ! * ! * R = Y + K * (1 - Kr) * Cr ! * G = Y - K * (Kb * (1 - Kb) * Cb + Kr * (1 - Kr) * Cr) / (1 - Kr - Kb) ! * B = Y + K * (1 - Kb) * Cb ! * ! * Y = Kr * R + (1 - Kr - Kb) * G + Kb * B ! * ! * With Kr = 0.299 and Kb = 0.114 (derived according to SMPTE RP 177-1993 ! * from the 1953 FCC NTSC primaries and CIE Illuminant C), K = 2 for sYCC, ! * the conversion equations to be implemented are therefore ! * ! * R = Y + 1.402 * Cr ! * G = Y - 0.344136286 * Cb - 0.714136286 * Cr ! * B = Y + 1.772 * Cb ! * ! * Y = 0.299 * R + 0.587 * G + 0.114 * B ! * * where Cb and Cr represent the incoming values less CENTERJSAMPLE. ! * For bg-sYCC, with K = 4, the equations are ! * ! * R = Y + 2.804 * Cr ! * G = Y - 0.688272572 * Cb - 1.428272572 * Cr ! * B = Y + 3.544 * Cb * * To avoid floating-point arithmetic, we represent the fractional constants * as integers scaled up by 2^16 (about 4 digits precision); we have to divide * the products by 2^16, with appropriate rounding, to get the correct answer. * Notice that Y, being an integral input, does not contribute any fraction * so it need not participate in the rounding. * * For even more speed, we avoid doing any multiplications in the inner loop * by precalculating the constants times Cb and Cr for all possible values. * For 8-bit JSAMPLEs this is very reasonable (only 256 entries per table); ! * for 9-bit to 12-bit samples it is still acceptable. It's not very ! * reasonable for 16-bit samples, but if you want lossless storage you ! * shouldn't be changing colorspace anyway. * The Cr=>R and Cb=>B values can be rounded to integers in advance; the * values for the G calculation are left scaled up, since we must add them * together before rounding. */ #define SCALEBITS 16 /* speediest right-shift on some machines */ #define ONE_HALF ((INT32) 1 << (SCALEBITS-1)) #define FIX(x) ((INT32) ((x) * (1L<<SCALEBITS) + 0.5)) + /* We allocate one big table for RGB->Y conversion and divide it up into + * three parts, instead of doing three alloc_small requests. This lets us + * use a single table base address, which can be held in a register in the + * inner loops on many machines (more than can hold all three addresses, + * anyway). + */ + + #define R_Y_OFF 0 /* offset to R => Y section */ + #define G_Y_OFF (1*(MAXJSAMPLE+1)) /* offset to G => Y section */ + #define B_Y_OFF (2*(MAXJSAMPLE+1)) /* etc. */ + #define TABLE_SIZE (3*(MAXJSAMPLE+1)) + /* ! * Initialize tables for YCbCr->RGB and BG_YCC->RGB colorspace conversion. */ LOCAL(void) build_ycc_rgb_table (j_decompress_ptr cinfo) + /* Normal case, sYCC */ + { + my_cconvert_ptr cconvert = (my_cconvert_ptr) cinfo->cconvert; + int i; + INT32 x; + SHIFT_TEMPS + + cconvert->Cr_r_tab = (int *) + (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE, + (MAXJSAMPLE+1) * SIZEOF(int)); + cconvert->Cb_b_tab = (int *) + (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE, + (MAXJSAMPLE+1) * SIZEOF(int)); + cconvert->Cr_g_tab = (INT32 *) + (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE, + (MAXJSAMPLE+1) * SIZEOF(INT32)); + cconvert->Cb_g_tab = (INT32 *) + (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE, + (MAXJSAMPLE+1) * SIZEOF(INT32)); + + for (i = 0, x = -CENTERJSAMPLE; i <= MAXJSAMPLE; i++, x++) { + /* i is the actual input pixel value, in the range 0..MAXJSAMPLE */ + /* The Cb or Cr value we are thinking of is x = i - CENTERJSAMPLE */ + /* Cr=>R value is nearest int to 1.402 * x */ + cconvert->Cr_r_tab[i] = (int) + RIGHT_SHIFT(FIX(1.402) * x + ONE_HALF, SCALEBITS); + /* Cb=>B value is nearest int to 1.772 * x */ + cconvert->Cb_b_tab[i] = (int) + RIGHT_SHIFT(FIX(1.772) * x + ONE_HALF, SCALEBITS); + /* Cr=>G value is scaled-up -0.714136286 * x */ + cconvert->Cr_g_tab[i] = (- FIX(0.714136286)) * x; + /* Cb=>G value is scaled-up -0.344136286 * x */ + /* We also add in ONE_HALF so that need not do it in inner loop */ + cconvert->Cb_g_tab[i] = (- FIX(0.344136286)) * x + ONE_HALF; + } + } + + + LOCAL(void) + build_bg_ycc_rgb_table (j_decompress_ptr cinfo) + /* Wide gamut case, bg-sYCC */ { my_cconvert_ptr cconvert = (my_cconvert_ptr) cinfo->cconvert; int i; INT32 x; SHIFT_TEMPS
*** 88,108 **** (MAXJSAMPLE+1) * SIZEOF(INT32)); for (i = 0, x = -CENTERJSAMPLE; i <= MAXJSAMPLE; i++, x++) { /* i is the actual input pixel value, in the range 0..MAXJSAMPLE */ /* The Cb or Cr value we are thinking of is x = i - CENTERJSAMPLE */ ! /* Cr=>R value is nearest int to 1.40200 * x */ cconvert->Cr_r_tab[i] = (int) ! RIGHT_SHIFT(FIX(1.40200) * x + ONE_HALF, SCALEBITS); ! /* Cb=>B value is nearest int to 1.77200 * x */ cconvert->Cb_b_tab[i] = (int) ! RIGHT_SHIFT(FIX(1.77200) * x + ONE_HALF, SCALEBITS); ! /* Cr=>G value is scaled-up -0.71414 * x */ ! cconvert->Cr_g_tab[i] = (- FIX(0.71414)) * x; ! /* Cb=>G value is scaled-up -0.34414 * x */ /* We also add in ONE_HALF so that need not do it in inner loop */ ! cconvert->Cb_g_tab[i] = (- FIX(0.34414)) * x + ONE_HALF; } } /* --- 178,198 ---- (MAXJSAMPLE+1) * SIZEOF(INT32)); for (i = 0, x = -CENTERJSAMPLE; i <= MAXJSAMPLE; i++, x++) { /* i is the actual input pixel value, in the range 0..MAXJSAMPLE */ /* The Cb or Cr value we are thinking of is x = i - CENTERJSAMPLE */ ! /* Cr=>R value is nearest int to 2.804 * x */ cconvert->Cr_r_tab[i] = (int) ! RIGHT_SHIFT(FIX(2.804) * x + ONE_HALF, SCALEBITS); ! /* Cb=>B value is nearest int to 3.544 * x */ cconvert->Cb_b_tab[i] = (int) ! RIGHT_SHIFT(FIX(3.544) * x + ONE_HALF, SCALEBITS); ! /* Cr=>G value is scaled-up -1.428272572 * x */ ! cconvert->Cr_g_tab[i] = (- FIX(1.428272572)) * x; ! /* Cb=>G value is scaled-up -0.688272572 * x */ /* We also add in ONE_HALF so that need not do it in inner loop */ ! cconvert->Cb_g_tab[i] = (- FIX(0.688272572)) * x + ONE_HALF; } } /*
*** 143,153 **** outptr = *output_buf++; for (col = 0; col < num_cols; col++) { y = GETJSAMPLE(inptr0[col]); cb = GETJSAMPLE(inptr1[col]); cr = GETJSAMPLE(inptr2[col]); ! /* Range-limiting is essential due to noise introduced by DCT losses. */ outptr[RGB_RED] = range_limit[y + Crrtab[cr]]; outptr[RGB_GREEN] = range_limit[y + ((int) RIGHT_SHIFT(Cbgtab[cb] + Crgtab[cr], SCALEBITS))]; outptr[RGB_BLUE] = range_limit[y + Cbbtab[cb]]; --- 233,245 ---- outptr = *output_buf++; for (col = 0; col < num_cols; col++) { y = GETJSAMPLE(inptr0[col]); cb = GETJSAMPLE(inptr1[col]); cr = GETJSAMPLE(inptr2[col]); ! /* Range-limiting is essential due to noise introduced by DCT losses, ! * for extended gamut (sYCC) and wide gamut (bg-sYCC) encodings. ! */ outptr[RGB_RED] = range_limit[y + Crrtab[cr]]; outptr[RGB_GREEN] = range_limit[y + ((int) RIGHT_SHIFT(Cbgtab[cb] + Crgtab[cr], SCALEBITS))]; outptr[RGB_BLUE] = range_limit[y + Cbbtab[cb]];
*** 155,351 **** } } } ! /**************** Cases other than YCbCr -> RGB **************/ /* ! * Color conversion for no colorspace change: just copy the data, ! * converting from separate-planes to interleaved representation. */ ! METHODDEF(void) ! null_convert (j_decompress_ptr cinfo, ! JSAMPIMAGE input_buf, JDIMENSION input_row, ! JSAMPARRAY output_buf, int num_rows) { ! register JSAMPROW inptr, outptr; ! register JDIMENSION count; ! register int num_components = cinfo->num_components; ! JDIMENSION num_cols = cinfo->output_width; ! int ci; ! while (--num_rows >= 0) { ! for (ci = 0; ci < num_components; ci++) { ! inptr = input_buf[ci][input_row]; ! outptr = output_buf[0] + ci; ! for (count = num_cols; count > 0; count--) { ! *outptr = *inptr++; /* needn't bother with GETJSAMPLE() here */ ! outptr += num_components; ! } ! } ! input_row++; ! output_buf++; } } /* ! * Color conversion for grayscale: just copy the data. ! * This also works for YCbCr -> grayscale conversion, in which ! * we just copy the Y (luminance) component and ignore chrominance. */ METHODDEF(void) ! grayscale_convert (j_decompress_ptr cinfo, JSAMPIMAGE input_buf, JDIMENSION input_row, JSAMPARRAY output_buf, int num_rows) { ! jcopy_sample_rows(input_buf[0], (int) input_row, output_buf, 0, ! num_rows, cinfo->output_width); } /* ! * Convert grayscale to RGB: just duplicate the graylevel three times. ! * This is provided to support applications that don't want to cope ! * with grayscale as a separate case. */ METHODDEF(void) ! gray_rgb_convert (j_decompress_ptr cinfo, JSAMPIMAGE input_buf, JDIMENSION input_row, JSAMPARRAY output_buf, int num_rows) { ! register JSAMPROW inptr, outptr; register JDIMENSION col; JDIMENSION num_cols = cinfo->output_width; while (--num_rows >= 0) { ! inptr = input_buf[0][input_row++]; outptr = *output_buf++; for (col = 0; col < num_cols; col++) { ! /* We can dispense with GETJSAMPLE() here */ ! outptr[RGB_RED] = outptr[RGB_GREEN] = outptr[RGB_BLUE] = inptr[col]; outptr += RGB_PIXELSIZE; } } } /* ! * YCCK->CMYK->CMY->RGB conversion. ! * ! * NB: this color conversion is introduced in jfx libjpeg snapshot as ! * a part of the fix for RT-17000. In case of library upgrade, please ! * check whether this convertor needs to be moved into upgraded version ! * of the library. */ METHODDEF(void) ! ycck_rgb_convert (j_decompress_ptr cinfo, JSAMPIMAGE input_buf, JDIMENSION input_row, JSAMPARRAY output_buf, int num_rows) { my_cconvert_ptr cconvert = (my_cconvert_ptr) cinfo->cconvert; ! register int y, cb, cr, k; ! register int C, M, Y; register int r, g, b; register JSAMPROW outptr; ! register JSAMPROW inptr0, inptr1, inptr2, inptr3; register JDIMENSION col; JDIMENSION num_cols = cinfo->output_width; - /* copy these pointers into registers if possible */ - register JSAMPLE * range_limit = cinfo->sample_range_limit; - register int * Crrtab = cconvert->Cr_r_tab; - register int * Cbbtab = cconvert->Cb_b_tab; - register INT32 * Crgtab = cconvert->Cr_g_tab; - register INT32 * Cbgtab = cconvert->Cb_g_tab; - SHIFT_TEMPS while (--num_rows >= 0) { inptr0 = input_buf[0][input_row]; inptr1 = input_buf[1][input_row]; inptr2 = input_buf[2][input_row]; - inptr3 = input_buf[3][input_row]; input_row++; outptr = *output_buf++; for (col = 0; col < num_cols; col++) { ! y = GETJSAMPLE(inptr0[col]); ! cb = GETJSAMPLE(inptr1[col]); ! cr = GETJSAMPLE(inptr2[col]); ! k = GETJSAMPLE(inptr3[col]); ! ! C = MAXJSAMPLE - (y + Crrtab[cr]); ! M = MAXJSAMPLE - (y + ((int) RIGHT_SHIFT(Cbgtab[cb] + Crgtab[cr], SCALEBITS))); ! Y = MAXJSAMPLE - (y + Cbbtab[cb]); ! ! r = C * k / MAXJSAMPLE; ! g = M * k / MAXJSAMPLE; ! b = Y * k / MAXJSAMPLE; ! ! /* Range-limiting is essential due to noise introduced by DCT losses. */ ! outptr[RGB_RED] = range_limit[r]; ! outptr[RGB_GREEN] = range_limit[g]; ! outptr[RGB_BLUE] = range_limit[b]; ! ! outptr += RGB_PIXELSIZE; } } } /* ! * CMYK->CMY->RGB conversion. ! * ! * NB: this color conversion is introduced in jfx libjpeg snapshot as ! * a part of the fix for RT-17000. In case of library upgrade, please ! * check whether this convertor needs to be moved into upgraded version ! * of the library. */ METHODDEF(void) ! cmyk_rgb_convert (j_decompress_ptr cinfo, JSAMPIMAGE input_buf, JDIMENSION input_row, JSAMPARRAY output_buf, int num_rows) { - my_cconvert_ptr cconvert = (my_cconvert_ptr) cinfo->cconvert; - register int c, m, y, k; - register int r, g, b; register JSAMPROW outptr; ! register JSAMPROW inptr0, inptr1, inptr2, inptr3; register JDIMENSION col; JDIMENSION num_cols = cinfo->output_width; - /* copy these pointers into registers if possible */ - register JSAMPLE * range_limit = cinfo->sample_range_limit; - SHIFT_TEMPS while (--num_rows >= 0) { inptr0 = input_buf[0][input_row]; inptr1 = input_buf[1][input_row]; inptr2 = input_buf[2][input_row]; - inptr3 = input_buf[3][input_row]; input_row++; outptr = *output_buf++; for (col = 0; col < num_cols; col++) { ! c = GETJSAMPLE(inptr0[col]); ! m = GETJSAMPLE(inptr1[col]); ! y = GETJSAMPLE(inptr2[col]); ! k = GETJSAMPLE(inptr3[col]); ! ! r = c * k / MAXJSAMPLE; ! g = m * k / MAXJSAMPLE; ! b = y * k / MAXJSAMPLE; ! ! /* Range-limiting is essential due to noise introduced by DCT losses. */ ! outptr[RGB_RED] = range_limit[r]; ! outptr[RGB_GREEN] = range_limit[g]; ! outptr[RGB_BLUE] = range_limit[b]; outptr += RGB_PIXELSIZE; } } } /* * Adobe-style YCCK->CMYK conversion. * We convert YCbCr to R=1-C, G=1-M, and B=1-Y using the same * conversion as above, while passing K (black) unchanged. * We assume build_ycc_rgb_table has been called. --- 247,510 ---- } } } ! /**************** Cases other than YCC -> RGB ****************/ /* ! * Initialize for RGB->grayscale colorspace conversion. */ ! LOCAL(void) ! build_rgb_y_table (j_decompress_ptr cinfo) { ! my_cconvert_ptr cconvert = (my_cconvert_ptr) cinfo->cconvert; ! INT32 * rgb_y_tab; ! INT32 i; ! /* Allocate and fill in the conversion tables. */ ! cconvert->rgb_y_tab = rgb_y_tab = (INT32 *) ! (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE, ! (TABLE_SIZE * SIZEOF(INT32))); ! ! for (i = 0; i <= MAXJSAMPLE; i++) { ! rgb_y_tab[i+R_Y_OFF] = FIX(0.299) * i; ! rgb_y_tab[i+G_Y_OFF] = FIX(0.587) * i; ! rgb_y_tab[i+B_Y_OFF] = FIX(0.114) * i + ONE_HALF; } } /* ! * Convert RGB to grayscale. */ METHODDEF(void) ! rgb_gray_convert (j_decompress_ptr cinfo, JSAMPIMAGE input_buf, JDIMENSION input_row, JSAMPARRAY output_buf, int num_rows) { ! my_cconvert_ptr cconvert = (my_cconvert_ptr) cinfo->cconvert; ! register INT32 * ctab = cconvert->rgb_y_tab; ! register int r, g, b; ! register JSAMPROW outptr; ! register JSAMPROW inptr0, inptr1, inptr2; ! register JDIMENSION col; ! JDIMENSION num_cols = cinfo->output_width; ! ! while (--num_rows >= 0) { ! inptr0 = input_buf[0][input_row]; ! inptr1 = input_buf[1][input_row]; ! inptr2 = input_buf[2][input_row]; ! input_row++; ! outptr = *output_buf++; ! for (col = 0; col < num_cols; col++) { ! r = GETJSAMPLE(inptr0[col]); ! g = GETJSAMPLE(inptr1[col]); ! b = GETJSAMPLE(inptr2[col]); ! /* Y */ ! outptr[col] = (JSAMPLE) ! ((ctab[r+R_Y_OFF] + ctab[g+G_Y_OFF] + ctab[b+B_Y_OFF]) ! >> SCALEBITS); ! } ! } } /* ! * [R-G,G,B-G] to [R,G,B] conversion with modulo calculation ! * (inverse color transform). ! * This can be seen as an adaption of the general YCbCr->RGB ! * conversion equation with Kr = Kb = 0, while replacing the ! * normalization by modulo calculation. */ METHODDEF(void) ! rgb1_rgb_convert (j_decompress_ptr cinfo, JSAMPIMAGE input_buf, JDIMENSION input_row, JSAMPARRAY output_buf, int num_rows) { ! register int r, g, b; ! register JSAMPROW outptr; ! register JSAMPROW inptr0, inptr1, inptr2; register JDIMENSION col; JDIMENSION num_cols = cinfo->output_width; while (--num_rows >= 0) { ! inptr0 = input_buf[0][input_row]; ! inptr1 = input_buf[1][input_row]; ! inptr2 = input_buf[2][input_row]; ! input_row++; outptr = *output_buf++; for (col = 0; col < num_cols; col++) { ! r = GETJSAMPLE(inptr0[col]); ! g = GETJSAMPLE(inptr1[col]); ! b = GETJSAMPLE(inptr2[col]); ! /* Assume that MAXJSAMPLE+1 is a power of 2, so that the MOD ! * (modulo) operator is equivalent to the bitmask operator AND. ! */ ! outptr[RGB_RED] = (JSAMPLE) ((r + g - CENTERJSAMPLE) & MAXJSAMPLE); ! outptr[RGB_GREEN] = (JSAMPLE) g; ! outptr[RGB_BLUE] = (JSAMPLE) ((b + g - CENTERJSAMPLE) & MAXJSAMPLE); outptr += RGB_PIXELSIZE; } } } + /* ! * [R-G,G,B-G] to grayscale conversion with modulo calculation ! * (inverse color transform). */ + METHODDEF(void) ! rgb1_gray_convert (j_decompress_ptr cinfo, JSAMPIMAGE input_buf, JDIMENSION input_row, JSAMPARRAY output_buf, int num_rows) { my_cconvert_ptr cconvert = (my_cconvert_ptr) cinfo->cconvert; ! register INT32 * ctab = cconvert->rgb_y_tab; register int r, g, b; register JSAMPROW outptr; ! register JSAMPROW inptr0, inptr1, inptr2; register JDIMENSION col; JDIMENSION num_cols = cinfo->output_width; while (--num_rows >= 0) { inptr0 = input_buf[0][input_row]; inptr1 = input_buf[1][input_row]; inptr2 = input_buf[2][input_row]; input_row++; outptr = *output_buf++; for (col = 0; col < num_cols; col++) { ! r = GETJSAMPLE(inptr0[col]); ! g = GETJSAMPLE(inptr1[col]); ! b = GETJSAMPLE(inptr2[col]); ! /* Assume that MAXJSAMPLE+1 is a power of 2, so that the MOD ! * (modulo) operator is equivalent to the bitmask operator AND. ! */ ! r = (r + g - CENTERJSAMPLE) & MAXJSAMPLE; ! b = (b + g - CENTERJSAMPLE) & MAXJSAMPLE; ! /* Y */ ! outptr[col] = (JSAMPLE) ! ((ctab[r+R_Y_OFF] + ctab[g+G_Y_OFF] + ctab[b+B_Y_OFF]) ! >> SCALEBITS); } } } + /* ! * No colorspace change, but conversion from separate-planes ! * to interleaved representation. */ + METHODDEF(void) ! rgb_convert (j_decompress_ptr cinfo, JSAMPIMAGE input_buf, JDIMENSION input_row, JSAMPARRAY output_buf, int num_rows) { register JSAMPROW outptr; ! register JSAMPROW inptr0, inptr1, inptr2; register JDIMENSION col; JDIMENSION num_cols = cinfo->output_width; while (--num_rows >= 0) { inptr0 = input_buf[0][input_row]; inptr1 = input_buf[1][input_row]; inptr2 = input_buf[2][input_row]; input_row++; outptr = *output_buf++; for (col = 0; col < num_cols; col++) { ! /* We can dispense with GETJSAMPLE() here */ ! outptr[RGB_RED] = inptr0[col]; ! outptr[RGB_GREEN] = inptr1[col]; ! outptr[RGB_BLUE] = inptr2[col]; ! outptr += RGB_PIXELSIZE; ! } ! } ! } ! ! ! /* ! * Color conversion for no colorspace change: just copy the data, ! * converting from separate-planes to interleaved representation. ! */ ! ! METHODDEF(void) ! null_convert (j_decompress_ptr cinfo, ! JSAMPIMAGE input_buf, JDIMENSION input_row, ! JSAMPARRAY output_buf, int num_rows) ! { ! int ci; ! register int nc = cinfo->num_components; ! register JSAMPROW outptr; ! register JSAMPROW inptr; ! register JDIMENSION col; ! JDIMENSION num_cols = cinfo->output_width; ! ! while (--num_rows >= 0) { ! for (ci = 0; ci < nc; ci++) { ! inptr = input_buf[ci][input_row]; ! outptr = output_buf[0] + ci; ! for (col = 0; col < num_cols; col++) { ! *outptr = *inptr++; /* needn't bother with GETJSAMPLE() here */ ! outptr += nc; ! } ! } ! input_row++; ! output_buf++; ! } ! } ! ! ! /* ! * Color conversion for grayscale: just copy the data. ! * This also works for YCC -> grayscale conversion, in which ! * we just copy the Y (luminance) component and ignore chrominance. ! */ ! ! METHODDEF(void) ! grayscale_convert (j_decompress_ptr cinfo, ! JSAMPIMAGE input_buf, JDIMENSION input_row, ! JSAMPARRAY output_buf, int num_rows) ! { ! jcopy_sample_rows(input_buf[0], (int) input_row, output_buf, 0, ! num_rows, cinfo->output_width); ! } ! ! ! /* ! * Convert grayscale to RGB: just duplicate the graylevel three times. ! * This is provided to support applications that don't want to cope ! * with grayscale as a separate case. ! */ + METHODDEF(void) + gray_rgb_convert (j_decompress_ptr cinfo, + JSAMPIMAGE input_buf, JDIMENSION input_row, + JSAMPARRAY output_buf, int num_rows) + { + register JSAMPROW outptr; + register JSAMPROW inptr; + register JDIMENSION col; + JDIMENSION num_cols = cinfo->output_width; + + while (--num_rows >= 0) { + inptr = input_buf[0][input_row++]; + outptr = *output_buf++; + for (col = 0; col < num_cols; col++) { + /* We can dispense with GETJSAMPLE() here */ + outptr[RGB_RED] = outptr[RGB_GREEN] = outptr[RGB_BLUE] = inptr[col]; outptr += RGB_PIXELSIZE; } } } + /* * Adobe-style YCCK->CMYK conversion. * We convert YCbCr to R=1-C, G=1-M, and B=1-Y using the same * conversion as above, while passing K (black) unchanged. * We assume build_ycc_rgb_table has been called.
*** 379,389 **** outptr = *output_buf++; for (col = 0; col < num_cols; col++) { y = GETJSAMPLE(inptr0[col]); cb = GETJSAMPLE(inptr1[col]); cr = GETJSAMPLE(inptr2[col]); ! /* Range-limiting is essential due to noise introduced by DCT losses. */ outptr[0] = range_limit[MAXJSAMPLE - (y + Crrtab[cr])]; /* red */ outptr[1] = range_limit[MAXJSAMPLE - (y + /* green */ ((int) RIGHT_SHIFT(Cbgtab[cb] + Crgtab[cr], SCALEBITS)))]; outptr[2] = range_limit[MAXJSAMPLE - (y + Cbbtab[cb])]; /* blue */ --- 538,550 ---- outptr = *output_buf++; for (col = 0; col < num_cols; col++) { y = GETJSAMPLE(inptr0[col]); cb = GETJSAMPLE(inptr1[col]); cr = GETJSAMPLE(inptr2[col]); ! /* Range-limiting is essential due to noise introduced by DCT losses, ! * and for extended gamut encodings (sYCC). ! */ outptr[0] = range_limit[MAXJSAMPLE - (y + Crrtab[cr])]; /* red */ outptr[1] = range_limit[MAXJSAMPLE - (y + /* green */ ((int) RIGHT_SHIFT(Cbgtab[cb] + Crgtab[cr], SCALEBITS)))]; outptr[2] = range_limit[MAXJSAMPLE - (y + Cbbtab[cb])]; /* blue */
*** 417,427 **** int ci; cconvert = (my_cconvert_ptr) (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE, SIZEOF(my_color_deconverter)); ! cinfo->cconvert = (struct jpeg_color_deconverter *) cconvert; cconvert->pub.start_pass = start_pass_dcolor; /* Make sure num_components agrees with jpeg_color_space */ switch (cinfo->jpeg_color_space) { case JCS_GRAYSCALE: --- 578,588 ---- int ci; cconvert = (my_cconvert_ptr) (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE, SIZEOF(my_color_deconverter)); ! cinfo->cconvert = &cconvert->pub; cconvert->pub.start_pass = start_pass_dcolor; /* Make sure num_components agrees with jpeg_color_space */ switch (cinfo->jpeg_color_space) { case JCS_GRAYSCALE:
*** 429,438 **** --- 590,601 ---- ERREXIT(cinfo, JERR_BAD_J_COLORSPACE); break; case JCS_RGB: case JCS_YCbCr: + case JCS_BG_RGB: + case JCS_BG_YCC: if (cinfo->num_components != 3) ERREXIT(cinfo, JERR_BAD_J_COLORSPACE); break; case JCS_CMYK:
*** 445,500 **** if (cinfo->num_components < 1) ERREXIT(cinfo, JERR_BAD_J_COLORSPACE); break; } /* Set out_color_components and conversion method based on requested space. * Also clear the component_needed flags for any unused components, * so that earlier pipeline stages can avoid useless computation. */ switch (cinfo->out_color_space) { case JCS_GRAYSCALE: cinfo->out_color_components = 1; ! if (cinfo->jpeg_color_space == JCS_GRAYSCALE || ! cinfo->jpeg_color_space == JCS_YCbCr) { cconvert->pub.color_convert = grayscale_convert; /* For color->grayscale conversion, only the Y (0) component is needed */ for (ci = 1; ci < cinfo->num_components; ci++) cinfo->comp_info[ci].component_needed = FALSE; ! } else ERREXIT(cinfo, JERR_CONVERSION_NOTIMPL); break; case JCS_RGB: cinfo->out_color_components = RGB_PIXELSIZE; ! if (cinfo->jpeg_color_space == JCS_YCbCr) { ! cconvert->pub.color_convert = ycc_rgb_convert; ! build_ycc_rgb_table(cinfo); ! } else if (cinfo->jpeg_color_space == JCS_GRAYSCALE) { cconvert->pub.color_convert = gray_rgb_convert; ! } else if (cinfo->jpeg_color_space == JCS_RGB && RGB_PIXELSIZE == 3) { ! cconvert->pub.color_convert = null_convert; ! } else if (cinfo->jpeg_color_space == JCS_YCCK) { ! cconvert->pub.color_convert = ycck_rgb_convert; build_ycc_rgb_table(cinfo); ! } else if (cinfo->jpeg_color_space == JCS_CMYK) { ! cconvert->pub.color_convert = cmyk_rgb_convert; ! } else { ERREXIT(cinfo, JERR_CONVERSION_NOTIMPL); } break; case JCS_CMYK: cinfo->out_color_components = 4; ! if (cinfo->jpeg_color_space == JCS_YCCK) { cconvert->pub.color_convert = ycck_cmyk_convert; build_ycc_rgb_table(cinfo); ! } else if (cinfo->jpeg_color_space == JCS_CMYK) { cconvert->pub.color_convert = null_convert; ! } else ERREXIT(cinfo, JERR_CONVERSION_NOTIMPL); break; default: /* Permit null conversion to same output space */ if (cinfo->out_color_space == cinfo->jpeg_color_space) { --- 608,719 ---- if (cinfo->num_components < 1) ERREXIT(cinfo, JERR_BAD_J_COLORSPACE); break; } + /* Support color transform only for RGB colorspaces */ + if (cinfo->color_transform && + cinfo->jpeg_color_space != JCS_RGB && + cinfo->jpeg_color_space != JCS_BG_RGB) + ERREXIT(cinfo, JERR_CONVERSION_NOTIMPL); + /* Set out_color_components and conversion method based on requested space. * Also clear the component_needed flags for any unused components, * so that earlier pipeline stages can avoid useless computation. */ switch (cinfo->out_color_space) { case JCS_GRAYSCALE: cinfo->out_color_components = 1; ! switch (cinfo->jpeg_color_space) { ! case JCS_GRAYSCALE: ! case JCS_YCbCr: ! case JCS_BG_YCC: cconvert->pub.color_convert = grayscale_convert; /* For color->grayscale conversion, only the Y (0) component is needed */ for (ci = 1; ci < cinfo->num_components; ci++) cinfo->comp_info[ci].component_needed = FALSE; ! break; ! case JCS_RGB: ! switch (cinfo->color_transform) { ! case JCT_NONE: ! cconvert->pub.color_convert = rgb_gray_convert; ! break; ! case JCT_SUBTRACT_GREEN: ! cconvert->pub.color_convert = rgb1_gray_convert; ! break; ! default: ! ERREXIT(cinfo, JERR_CONVERSION_NOTIMPL); ! } ! build_rgb_y_table(cinfo); ! break; ! default: ERREXIT(cinfo, JERR_CONVERSION_NOTIMPL); + } break; case JCS_RGB: cinfo->out_color_components = RGB_PIXELSIZE; ! switch (cinfo->jpeg_color_space) { ! case JCS_GRAYSCALE: cconvert->pub.color_convert = gray_rgb_convert; ! break; ! case JCS_YCbCr: ! cconvert->pub.color_convert = ycc_rgb_convert; build_ycc_rgb_table(cinfo); ! break; ! case JCS_BG_YCC: ! cconvert->pub.color_convert = ycc_rgb_convert; ! build_bg_ycc_rgb_table(cinfo); ! break; ! case JCS_RGB: ! switch (cinfo->color_transform) { ! case JCT_NONE: ! cconvert->pub.color_convert = rgb_convert; ! break; ! case JCT_SUBTRACT_GREEN: ! cconvert->pub.color_convert = rgb1_rgb_convert; ! break; ! default: ! ERREXIT(cinfo, JERR_CONVERSION_NOTIMPL); ! } ! break; ! default: ERREXIT(cinfo, JERR_CONVERSION_NOTIMPL); } break; + case JCS_BG_RGB: + cinfo->out_color_components = RGB_PIXELSIZE; + if (cinfo->jpeg_color_space == JCS_BG_RGB) { + switch (cinfo->color_transform) { + case JCT_NONE: + cconvert->pub.color_convert = rgb_convert; + break; + case JCT_SUBTRACT_GREEN: + cconvert->pub.color_convert = rgb1_rgb_convert; + break; + default: + ERREXIT(cinfo, JERR_CONVERSION_NOTIMPL); + } + } else + ERREXIT(cinfo, JERR_CONVERSION_NOTIMPL); + break; + case JCS_CMYK: cinfo->out_color_components = 4; ! switch (cinfo->jpeg_color_space) { ! case JCS_YCCK: cconvert->pub.color_convert = ycck_cmyk_convert; build_ycc_rgb_table(cinfo); ! break; ! case JCS_CMYK: cconvert->pub.color_convert = null_convert; ! break; ! default: ERREXIT(cinfo, JERR_CONVERSION_NOTIMPL); + } break; default: /* Permit null conversion to same output space */ if (cinfo->out_color_space == cinfo->jpeg_color_space) {
< prev index next >