YCbCr->RGB conversion routines now in the tif_color.c module. New function

TIFFYCbCrtoRGB() available in TIFF API.
This commit is contained in:
Andrey Kiselev 2003-12-04 10:31:54 +00:00
parent a5407eb75f
commit 1e2bc737c6
3 changed files with 52 additions and 64 deletions

View File

@ -1,4 +1,4 @@
/* $Header: /cvs/maptools/cvsroot/libtiff/libtiff/tif_color.c,v 1.2 2003-12-03 19:54:03 dron Exp $ */ /* $Header: /cvs/maptools/cvsroot/libtiff/libtiff/tif_color.c,v 1.3 2003-12-04 10:31:54 dron Exp $ */
/* /*
* Copyright (c) 1988-1997 Sam Leffler * Copyright (c) 1988-1997 Sam Leffler
@ -40,8 +40,7 @@
#include <math.h> #include <math.h>
/* /*
* Convert color value from the CIE L*a*b* 1976 space to CIE XYZ. Different * Convert color value from the CIE L*a*b* 1976 space to CIE XYZ.
* reference white tristimuli can be specified.
*/ */
void void
TIFFCIELabToXYZ(TIFFCIELabToRGB *cielab, uint32 l, int32 a, int32 b, TIFFCIELabToXYZ(TIFFCIELabToRGB *cielab, uint32 l, int32 a, int32 b,
@ -203,17 +202,30 @@ TIFFCIELabToRGBInit(TIFFCIELabToRGB* cielab, TIFFDisplay *display,
/* /*
* Free TIFFYCbCrToRGB structure. * Free TIFFYCbCrToRGB structure.
*/ */
int void
TIFFCIELabToRGBEnd(TIFFCIELabToRGB* cielab) TIFFCIELabToRGBEnd(TIFFCIELabToRGB* cielab)
{ {
static char module[] = "TIFFCIELabToRGBEnd";
_TIFFfree(cielab->Yr2r); _TIFFfree(cielab->Yr2r);
_TIFFfree(cielab->Yg2g); _TIFFfree(cielab->Yg2g);
_TIFFfree(cielab->Yb2b); _TIFFfree(cielab->Yb2b);
_TIFFfree(cielab->display); _TIFFfree(cielab->display);
} }
/*
* Convert color value from the YCbCr space to CIE XYZ.
* The colorspace conversion algorithm comes from the IJG v5a code;
* see below for more information on how it works.
*/
void
TIFFYCbCrtoRGB(TIFFYCbCrToRGB *ycbcr, uint32 Y, int32 Cb, int32 Cr,
uint32 *r, uint32 *g, uint32 *b)
{
*r = ycbcr->clamptab[Y + ycbcr->Cr_r_tab[Cr]];
*g = ycbcr->clamptab[Y
+ (int)((ycbcr->Cb_g_tab[Cb] + ycbcr->Cr_g_tab[Cr]) >> 16)];
*b = ycbcr->clamptab[Y + ycbcr->Cb_b_tab[Cb]];
}
#define SHIFT 16 #define SHIFT 16
#define FIX(x) ((int32)((x) * (1L<<SHIFT) + 0.5)) #define FIX(x) ((int32)((x) * (1L<<SHIFT) + 0.5))
#define ONE_HALF ((int32)(1<<(SHIFT-1))) #define ONE_HALF ((int32)(1<<(SHIFT-1)))

View File

@ -1,4 +1,4 @@
/* $Header: /cvs/maptools/cvsroot/libtiff/libtiff/tif_getimage.c,v 1.31 2003-12-03 19:54:03 dron Exp $ */ /* $Header: /cvs/maptools/cvsroot/libtiff/libtiff/tif_getimage.c,v 1.32 2003-12-04 10:31:54 dron Exp $ */
/* /*
* Copyright (c) 1991-1997 Sam Leffler * Copyright (c) 1991-1997 Sam Leffler
@ -1571,25 +1571,14 @@ DECLAREContigPutFunc(putcontig8bitCIELab)
} }
/* /*
* YCbCr -> RGB conversion and packing routines. The colorspace * YCbCr -> RGB conversion and packing routines.
* conversion algorithm comes from the IJG v5a code; see below
* for more information on how it works.
*/ */
#define YCbCrtoRGB(dst, yc) { \ #define YCbCrtoRGB(dst, Y) { \
int Y = (yc); \ uint32 r, g, b; \
dst = PACK( \ TIFFYCbCrtoRGB(img->ycbcr, (Y), Cb, Cr, &r, &g, &b); \
clamptab[Y+Crrtab[Cr]], \ dst = PACK(r, g, b); \
clamptab[Y + (int)((Cbgtab[Cb]+Crgtab[Cr])>>16)], \
clamptab[Y+Cbbtab[Cb]]); \
} }
#define YCbCrSetup \
TIFFYCbCrToRGB* ycbcr = img->ycbcr; \
int* Crrtab = ycbcr->Cr_r_tab; \
int* Cbbtab = ycbcr->Cb_b_tab; \
int32* Crgtab = ycbcr->Cr_g_tab; \
int32* Cbgtab = ycbcr->Cb_g_tab; \
TIFFRGBValue* clamptab = ycbcr->clamptab
/* /*
* 8-bit packed YCbCr samples => RGB * 8-bit packed YCbCr samples => RGB
@ -1611,13 +1600,11 @@ static void putcontig8bitYCbCrGenericTile(
int v_group ) int v_group )
{ {
YCbCrSetup;
uint32* cp1 = cp+w+toskew; uint32* cp1 = cp+w+toskew;
uint32* cp2 = cp1+w+toskew; uint32* cp2 = cp1+w+toskew;
uint32* cp3 = cp2+w+toskew; uint32* cp3 = cp2+w+toskew;
int32 incr = 3*w+4*toskew; int32 incr = 3*w+4*toskew;
int Cb, Cr; int32 Cb, Cr;
int group_size = v_group * h_group + 2; int group_size = v_group * h_group + 2;
(void) y; (void) y;
@ -1674,7 +1661,6 @@ static void putcontig8bitYCbCrGenericTile(
*/ */
DECLAREContigPutFunc(putcontig8bitYCbCr44tile) DECLAREContigPutFunc(putcontig8bitYCbCr44tile)
{ {
YCbCrSetup;
uint32* cp1 = cp+w+toskew; uint32* cp1 = cp+w+toskew;
uint32* cp2 = cp1+w+toskew; uint32* cp2 = cp1+w+toskew;
uint32* cp3 = cp2+w+toskew; uint32* cp3 = cp2+w+toskew;
@ -1687,8 +1673,8 @@ DECLAREContigPutFunc(putcontig8bitYCbCr44tile)
for (; h >= 4; h -= 4) { for (; h >= 4; h -= 4) {
x = w>>2; x = w>>2;
do { do {
int Cb = pp[16]; int32 Cb = pp[16];
int Cr = pp[17]; int32 Cr = pp[17];
YCbCrtoRGB(cp [0], pp[ 0]); YCbCrtoRGB(cp [0], pp[ 0]);
YCbCrtoRGB(cp [1], pp[ 1]); YCbCrtoRGB(cp [1], pp[ 1]);
@ -1716,8 +1702,8 @@ DECLAREContigPutFunc(putcontig8bitYCbCr44tile)
} else { } else {
while (h > 0) { while (h > 0) {
for (x = w; x > 0;) { for (x = w; x > 0;) {
int Cb = pp[16]; int32 Cb = pp[16];
int Cr = pp[17]; int32 Cr = pp[17];
switch (x) { switch (x) {
default: default:
switch (h) { switch (h) {
@ -1772,7 +1758,6 @@ DECLAREContigPutFunc(putcontig8bitYCbCr44tile)
*/ */
DECLAREContigPutFunc(putcontig8bitYCbCr42tile) DECLAREContigPutFunc(putcontig8bitYCbCr42tile)
{ {
YCbCrSetup;
uint32* cp1 = cp+w+toskew; uint32* cp1 = cp+w+toskew;
int32 incr = 2*toskew+w; int32 incr = 2*toskew+w;
@ -1782,8 +1767,8 @@ DECLAREContigPutFunc(putcontig8bitYCbCr42tile)
for (; h >= 2; h -= 2) { for (; h >= 2; h -= 2) {
x = w>>2; x = w>>2;
do { do {
int Cb = pp[8]; int32 Cb = pp[8];
int Cr = pp[9]; int32 Cr = pp[9];
YCbCrtoRGB(cp [0], pp[0]); YCbCrtoRGB(cp [0], pp[0]);
YCbCrtoRGB(cp [1], pp[1]); YCbCrtoRGB(cp [1], pp[1]);
@ -1803,8 +1788,8 @@ DECLAREContigPutFunc(putcontig8bitYCbCr42tile)
} else { } else {
while (h > 0) { while (h > 0) {
for (x = w; x > 0;) { for (x = w; x > 0;) {
int Cb = pp[8]; int32 Cb = pp[8];
int Cr = pp[9]; int32 Cr = pp[9];
switch (x) { switch (x) {
default: default:
switch (h) { switch (h) {
@ -1851,15 +1836,13 @@ DECLAREContigPutFunc(putcontig8bitYCbCr42tile)
*/ */
DECLAREContigPutFunc(putcontig8bitYCbCr41tile) DECLAREContigPutFunc(putcontig8bitYCbCr41tile)
{ {
YCbCrSetup;
(void) y; (void) y;
/* XXX adjust fromskew */ /* XXX adjust fromskew */
do { do {
x = w>>2; x = w>>2;
do { do {
int Cb = pp[4]; int32 Cb = pp[4];
int Cr = pp[5]; int32 Cr = pp[5];
YCbCrtoRGB(cp [0], pp[0]); YCbCrtoRGB(cp [0], pp[0]);
YCbCrtoRGB(cp [1], pp[1]); YCbCrtoRGB(cp [1], pp[1]);
@ -1872,8 +1855,8 @@ DECLAREContigPutFunc(putcontig8bitYCbCr41tile)
if( (w&3) != 0 ) if( (w&3) != 0 )
{ {
int Cb = pp[4]; int32 Cb = pp[4];
int Cr = pp[5]; int32 Cr = pp[5];
switch( (w&3) ) { switch( (w&3) ) {
case 3: YCbCrtoRGB(cp [2], pp[2]); case 3: YCbCrtoRGB(cp [2], pp[2]);
@ -1897,7 +1880,6 @@ DECLAREContigPutFunc(putcontig8bitYCbCr41tile)
*/ */
DECLAREContigPutFunc(putcontig8bitYCbCr22tile) DECLAREContigPutFunc(putcontig8bitYCbCr22tile)
{ {
YCbCrSetup;
uint32* cp1 = cp+w+toskew; uint32* cp1 = cp+w+toskew;
int32 incr = 2*toskew+w; int32 incr = 2*toskew+w;
@ -1907,8 +1889,8 @@ DECLAREContigPutFunc(putcontig8bitYCbCr22tile)
for (; h >= 2; h -= 2) { for (; h >= 2; h -= 2) {
x = w>>1; x = w>>1;
do { do {
int Cb = pp[4]; int32 Cb = pp[4];
int Cr = pp[5]; int32 Cr = pp[5];
YCbCrtoRGB(cp [0], pp[0]); YCbCrtoRGB(cp [0], pp[0]);
YCbCrtoRGB(cp [1], pp[1]); YCbCrtoRGB(cp [1], pp[1]);
@ -1924,8 +1906,8 @@ DECLAREContigPutFunc(putcontig8bitYCbCr22tile)
} else { } else {
while (h > 0) { while (h > 0) {
for (x = w; x > 0;) { for (x = w; x > 0;) {
int Cb = pp[4]; int32 Cb = pp[4];
int Cr = pp[5]; int32 Cr = pp[5];
switch (x) { switch (x) {
default: default:
switch (h) { switch (h) {
@ -1962,15 +1944,13 @@ DECLAREContigPutFunc(putcontig8bitYCbCr22tile)
*/ */
DECLAREContigPutFunc(putcontig8bitYCbCr21tile) DECLAREContigPutFunc(putcontig8bitYCbCr21tile)
{ {
YCbCrSetup;
(void) y; (void) y;
fromskew = (fromskew * 4) / 2; fromskew = (fromskew * 4) / 2;
do { do {
x = w>>1; x = w>>1;
do { do {
int Cb = pp[2]; int32 Cb = pp[2];
int Cr = pp[3]; int32 Cr = pp[3];
YCbCrtoRGB(cp[0], pp[0]); YCbCrtoRGB(cp[0], pp[0]);
YCbCrtoRGB(cp[1], pp[1]); YCbCrtoRGB(cp[1], pp[1]);
@ -1981,8 +1961,8 @@ DECLAREContigPutFunc(putcontig8bitYCbCr21tile)
if( (w&1) != 0 ) if( (w&1) != 0 )
{ {
int Cb = pp[2]; int32 Cb = pp[2];
int Cr = pp[3]; int32 Cr = pp[3];
YCbCrtoRGB(cp [0], pp[0]); YCbCrtoRGB(cp [0], pp[0]);
@ -2000,15 +1980,13 @@ DECLAREContigPutFunc(putcontig8bitYCbCr21tile)
*/ */
DECLAREContigPutFunc(putcontig8bitYCbCr11tile) DECLAREContigPutFunc(putcontig8bitYCbCr11tile)
{ {
YCbCrSetup;
(void) y; (void) y;
fromskew *= 3; fromskew *= 3;
do { do {
x = w; /* was x = w>>1; patched 2000/09/25 warmerda@home.com */ x = w; /* was x = w>>1; patched 2000/09/25 warmerda@home.com */
do { do {
int Cb = pp[1]; int32 Cb = pp[1];
int Cr = pp[2]; int32 Cr = pp[2];
YCbCrtoRGB(*cp++, pp[0]); YCbCrtoRGB(*cp++, pp[0]);
@ -2018,7 +1996,6 @@ DECLAREContigPutFunc(putcontig8bitYCbCr11tile)
pp += fromskew; pp += fromskew;
} while (--h); } while (--h);
} }
#undef YCbCrSetup
#undef YCbCrtoRGB #undef YCbCrtoRGB
static tileContigRoutine static tileContigRoutine

View File

@ -1,4 +1,4 @@
/* $Header: /cvs/maptools/cvsroot/libtiff/libtiff/tiffio.h,v 1.22 2003-12-03 19:54:03 dron Exp $ */ /* $Header: /cvs/maptools/cvsroot/libtiff/libtiff/tiffio.h,v 1.23 2003-12-04 10:31:54 dron Exp $ */
/* /*
* Copyright (c) 1988-1997 Sam Leffler * Copyright (c) 1988-1997 Sam Leffler
@ -153,8 +153,6 @@ typedef struct { /* YCbCr->RGB support */
int* Cb_b_tab; int* Cb_b_tab;
int32* Cr_g_tab; int32* Cr_g_tab;
int32* Cb_g_tab; int32* Cb_g_tab;
float coeffs[3]; /* XXX: no longer required. Will
be removed in the future. */
} TIFFYCbCrToRGB; } TIFFYCbCrToRGB;
typedef struct { /* CIE Lab 1976->RGB support */ typedef struct { /* CIE Lab 1976->RGB support */
@ -169,14 +167,15 @@ typedef struct { /* CIE Lab 1976->RGB support */
extern int TIFFCIELabToRGBInit(TIFFCIELabToRGB*, TIFFDisplay *display, extern int TIFFCIELabToRGBInit(TIFFCIELabToRGB*, TIFFDisplay *display,
float X0, float Y0, float Z0); float X0, float Y0, float Z0);
extern int TIFFCIELabToRGBEnd(TIFFCIELabToRGB*); extern void TIFFCIELabToRGBEnd(TIFFCIELabToRGB*);
extern void TIFFCIELabToXYZ(TIFFCIELabToRGB *, uint32, int32, int32, extern void TIFFCIELabToXYZ(TIFFCIELabToRGB *, uint32, int32, int32,
float *, float *, float *); float *, float *, float *);
extern void TIFFXYZToRGB(TIFFCIELabToRGB *, float, float, float, extern void TIFFXYZToRGB(TIFFCIELabToRGB *, float, float, float,
uint32 *, uint32 *, uint32 *); uint32 *, uint32 *, uint32 *);
extern int extern int TIFFYCbCrToRGBInit(TIFFYCbCrToRGB*, float, float, float);
TIFFYCbCrToRGBInit(TIFFYCbCrToRGB*, float, float, float); extern void TIFFYCbCrtoRGB(TIFFYCbCrToRGB *, uint32, int32, int32,
uint32 *, uint32 *, uint32 *);
/* /*
* RGBA-style image support. * RGBA-style image support.