< 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 >