Port RGB-to-Grayscale color transform from jpeg-8d

git-svn-id: svn+ssh://svn.code.sf.net/p/libjpeg-turbo/code/trunk@885 632fc199-4ca6-4c93-a231-07263d6284db
This commit is contained in:
DRC
2013-01-01 10:52:29 +00:00
3 changed files with 91 additions and 2 deletions

View File

@@ -40,6 +40,9 @@ corner should be moved by the same amount. In other words, this feature causes
jpegtran to strictly honor the specified width/height rather than the specified jpegtran to strictly honor the specified width/height rather than the specified
bottom right corner (feature ported from jpeg-8d.) bottom right corner (feature ported from jpeg-8d.)
[10] JPEG files using the RGB colorspace can now be decompressed into grayscale
images (feature ported from jpeg-8d.)
1.2.1 1.2.1
===== =====

View File

@@ -3,6 +3,7 @@
* *
* This file was part of the Independent JPEG Group's software: * This file was part of the Independent JPEG Group's software:
* Copyright (C) 1991-1997, Thomas G. Lane. * Copyright (C) 1991-1997, Thomas G. Lane.
* Modified 2011 by Guido Vollbeding.
* Modifications: * Modifications:
* Copyright 2009 Pierre Ossman <ossman@cendio.se> for Cendio AB * Copyright 2009 Pierre Ossman <ossman@cendio.se> for Cendio AB
* Copyright (C) 2009, 2011-2012, D. R. Commander. * Copyright (C) 2009, 2011-2012, D. R. Commander.
@@ -28,20 +29,28 @@ typedef struct {
int * Cb_b_tab; /* => table for Cb to B conversion */ int * Cb_b_tab; /* => table for Cb to B conversion */
INT32 * Cr_g_tab; /* => table for Cr to G conversion */ INT32 * Cr_g_tab; /* => table for Cr to G conversion */
INT32 * Cb_g_tab; /* => table for Cb 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; } my_color_deconverter;
typedef my_color_deconverter * my_cconvert_ptr; typedef my_color_deconverter * my_cconvert_ptr;
/**************** YCbCr -> RGB conversion: most common case **************/ /**************** YCbCr -> RGB conversion: most common case **************/
/**************** RGB -> Y conversion: less common case **************/
/* /*
* YCbCr is defined per CCIR 601-1, except that Cb and Cr are * 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. * normalized to the range 0..MAXJSAMPLE rather than -0.5 .. 0.5.
* The conversion equations to be implemented are therefore * The conversion equations to be implemented are therefore
*
* R = Y + 1.40200 * Cr * R = Y + 1.40200 * Cr
* G = Y - 0.34414 * Cb - 0.71414 * Cr * G = Y - 0.34414 * Cb - 0.71414 * Cr
* B = Y + 1.77200 * Cb * B = Y + 1.77200 * Cb
*
* Y = 0.29900 * R + 0.58700 * G + 0.11400 * B
*
* where Cb and Cr represent the incoming values less CENTERJSAMPLE. * where Cb and Cr represent the incoming values less CENTERJSAMPLE.
* (These numbers are derived from TIFF 6.0 section 21, dated 3-June-92.) * (These numbers are derived from TIFF 6.0 section 21, dated 3-June-92.)
* *
@@ -66,6 +75,18 @@ typedef my_color_deconverter * my_cconvert_ptr;
#define ONE_HALF ((INT32) 1 << (SCALEBITS-1)) #define ONE_HALF ((INT32) 1 << (SCALEBITS-1))
#define FIX(x) ((INT32) ((x) * (1L<<SCALEBITS) + 0.5)) #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))
/* Include inline routines for colorspace extensions */ /* Include inline routines for colorspace extensions */
@@ -272,6 +293,66 @@ ycc_rgb_convert (j_decompress_ptr cinfo,
/**************** Cases other than YCbCr -> RGB **************/ /**************** Cases other than YCbCr -> 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.29900) * i;
rgb_y_tab[i+G_Y_OFF] = FIX(0.58700) * i;
rgb_y_tab[i+B_Y_OFF] = FIX(0.11400) * 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 int r, g, b;
register INT32 * ctab = cconvert->rgb_y_tab;
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);
}
}
}
/* /*
* Color conversion for no colorspace change: just copy the data, * Color conversion for no colorspace change: just copy the data,
* converting from separate-planes to interleaved representation. * converting from separate-planes to interleaved representation.
@@ -410,6 +491,7 @@ rgb_rgb_convert (j_decompress_ptr cinfo,
} }
} }
/* /*
* Adobe-style YCCK->CMYK conversion. * Adobe-style YCCK->CMYK conversion.
* We convert YCbCr to R=1-C, G=1-M, and B=1-Y using the same * We convert YCbCr to R=1-C, G=1-M, and B=1-Y using the same
@@ -527,6 +609,9 @@ jinit_color_deconverter (j_decompress_ptr cinfo)
/* For color->grayscale conversion, only the Y (0) component is needed */ /* For color->grayscale conversion, only the Y (0) component is needed */
for (ci = 1; ci < cinfo->num_components; ci++) for (ci = 1; ci < cinfo->num_components; ci++)
cinfo->comp_info[ci].component_needed = FALSE; cinfo->comp_info[ci].component_needed = FALSE;
} else if (cinfo->jpeg_color_space == JCS_RGB) {
cconvert->pub.color_convert = rgb_gray_convert;
build_rgb_y_table(cinfo);
} else } else
ERREXIT(cinfo, JERR_CONVERSION_NOTIMPL); ERREXIT(cinfo, JERR_CONVERSION_NOTIMPL);
break; break;

View File

@@ -1,7 +1,7 @@
USING THE IJG JPEG LIBRARY USING THE IJG JPEG LIBRARY
This file was part of the Independent JPEG Group's software: This file was part of the Independent JPEG Group's software:
Copyright (C) 1994-2009, Thomas G. Lane, Guido Vollbeding. Copyright (C) 1994-2011, Thomas G. Lane, Guido Vollbeding.
Modifications: Modifications:
Copyright (C) 2010, D. R. Commander. Copyright (C) 2010, D. R. Commander.
For conditions of distribution and use, see the accompanying README file. For conditions of distribution and use, see the accompanying README file.
@@ -1279,8 +1279,9 @@ jpeg_read_header's guess by setting jpeg_color_space. jpeg_read_header also
selects a default output color space based on (its guess of) jpeg_color_space; selects a default output color space based on (its guess of) jpeg_color_space;
set out_color_space to override this. Again, you must select a supported set out_color_space to override this. Again, you must select a supported
transformation. jdcolor.c currently supports transformation. jdcolor.c currently supports
YCbCr => GRAYSCALE
YCbCr => RGB YCbCr => RGB
YCbCr => GRAYSCALE
RGB => GRAYSCALE
GRAYSCALE => RGB GRAYSCALE => RGB
YCCK => CMYK YCCK => CMYK
as well as the null transforms. (Since GRAYSCALE=>RGB is provided, an as well as the null transforms. (Since GRAYSCALE=>RGB is provided, an