From 1e2bc737c632fcad286d123ae4b39553ad6f0baa Mon Sep 17 00:00:00 2001 From: Andrey Kiselev Date: Thu, 4 Dec 2003 10:31:54 +0000 Subject: [PATCH] YCbCr->RGB conversion routines now in the tif_color.c module. New function TIFFYCbCrtoRGB() available in TIFF API. --- libtiff/tif_color.c | 24 +++++++++---- libtiff/tif_getimage.c | 81 +++++++++++++++--------------------------- libtiff/tiffio.h | 11 +++--- 3 files changed, 52 insertions(+), 64 deletions(-) diff --git a/libtiff/tif_color.c b/libtiff/tif_color.c index 2c3c2831..403c7512 100644 --- a/libtiff/tif_color.c +++ b/libtiff/tif_color.c @@ -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 @@ -40,8 +40,7 @@ #include /* - * Convert color value from the CIE L*a*b* 1976 space to CIE XYZ. Different - * reference white tristimuli can be specified. + * Convert color value from the CIE L*a*b* 1976 space to CIE XYZ. */ void TIFFCIELabToXYZ(TIFFCIELabToRGB *cielab, uint32 l, int32 a, int32 b, @@ -203,17 +202,30 @@ TIFFCIELabToRGBInit(TIFFCIELabToRGB* cielab, TIFFDisplay *display, /* * Free TIFFYCbCrToRGB structure. */ -int +void TIFFCIELabToRGBEnd(TIFFCIELabToRGB* cielab) { - static char module[] = "TIFFCIELabToRGBEnd"; - _TIFFfree(cielab->Yr2r); _TIFFfree(cielab->Yg2g); _TIFFfree(cielab->Yb2b); _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 FIX(x) ((int32)((x) * (1L< RGB conversion and packing routines. The colorspace - * conversion algorithm comes from the IJG v5a code; see below - * for more information on how it works. + * YCbCr -> RGB conversion and packing routines. */ -#define YCbCrtoRGB(dst, yc) { \ - int Y = (yc); \ - dst = PACK( \ - clamptab[Y+Crrtab[Cr]], \ - clamptab[Y + (int)((Cbgtab[Cb]+Crgtab[Cr])>>16)], \ - clamptab[Y+Cbbtab[Cb]]); \ +#define YCbCrtoRGB(dst, Y) { \ + uint32 r, g, b; \ + TIFFYCbCrtoRGB(img->ycbcr, (Y), Cb, Cr, &r, &g, &b); \ + dst = PACK(r, g, b); \ } -#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 @@ -1611,13 +1600,11 @@ static void putcontig8bitYCbCrGenericTile( int v_group ) { - YCbCrSetup; - uint32* cp1 = cp+w+toskew; uint32* cp2 = cp1+w+toskew; uint32* cp3 = cp2+w+toskew; int32 incr = 3*w+4*toskew; - int Cb, Cr; + int32 Cb, Cr; int group_size = v_group * h_group + 2; (void) y; @@ -1674,7 +1661,6 @@ static void putcontig8bitYCbCrGenericTile( */ DECLAREContigPutFunc(putcontig8bitYCbCr44tile) { - YCbCrSetup; uint32* cp1 = cp+w+toskew; uint32* cp2 = cp1+w+toskew; uint32* cp3 = cp2+w+toskew; @@ -1687,8 +1673,8 @@ DECLAREContigPutFunc(putcontig8bitYCbCr44tile) for (; h >= 4; h -= 4) { x = w>>2; do { - int Cb = pp[16]; - int Cr = pp[17]; + int32 Cb = pp[16]; + int32 Cr = pp[17]; YCbCrtoRGB(cp [0], pp[ 0]); YCbCrtoRGB(cp [1], pp[ 1]); @@ -1716,8 +1702,8 @@ DECLAREContigPutFunc(putcontig8bitYCbCr44tile) } else { while (h > 0) { for (x = w; x > 0;) { - int Cb = pp[16]; - int Cr = pp[17]; + int32 Cb = pp[16]; + int32 Cr = pp[17]; switch (x) { default: switch (h) { @@ -1772,7 +1758,6 @@ DECLAREContigPutFunc(putcontig8bitYCbCr44tile) */ DECLAREContigPutFunc(putcontig8bitYCbCr42tile) { - YCbCrSetup; uint32* cp1 = cp+w+toskew; int32 incr = 2*toskew+w; @@ -1782,8 +1767,8 @@ DECLAREContigPutFunc(putcontig8bitYCbCr42tile) for (; h >= 2; h -= 2) { x = w>>2; do { - int Cb = pp[8]; - int Cr = pp[9]; + int32 Cb = pp[8]; + int32 Cr = pp[9]; YCbCrtoRGB(cp [0], pp[0]); YCbCrtoRGB(cp [1], pp[1]); @@ -1803,8 +1788,8 @@ DECLAREContigPutFunc(putcontig8bitYCbCr42tile) } else { while (h > 0) { for (x = w; x > 0;) { - int Cb = pp[8]; - int Cr = pp[9]; + int32 Cb = pp[8]; + int32 Cr = pp[9]; switch (x) { default: switch (h) { @@ -1851,15 +1836,13 @@ DECLAREContigPutFunc(putcontig8bitYCbCr42tile) */ DECLAREContigPutFunc(putcontig8bitYCbCr41tile) { - YCbCrSetup; - (void) y; /* XXX adjust fromskew */ do { x = w>>2; do { - int Cb = pp[4]; - int Cr = pp[5]; + int32 Cb = pp[4]; + int32 Cr = pp[5]; YCbCrtoRGB(cp [0], pp[0]); YCbCrtoRGB(cp [1], pp[1]); @@ -1872,8 +1855,8 @@ DECLAREContigPutFunc(putcontig8bitYCbCr41tile) if( (w&3) != 0 ) { - int Cb = pp[4]; - int Cr = pp[5]; + int32 Cb = pp[4]; + int32 Cr = pp[5]; switch( (w&3) ) { case 3: YCbCrtoRGB(cp [2], pp[2]); @@ -1897,7 +1880,6 @@ DECLAREContigPutFunc(putcontig8bitYCbCr41tile) */ DECLAREContigPutFunc(putcontig8bitYCbCr22tile) { - YCbCrSetup; uint32* cp1 = cp+w+toskew; int32 incr = 2*toskew+w; @@ -1907,8 +1889,8 @@ DECLAREContigPutFunc(putcontig8bitYCbCr22tile) for (; h >= 2; h -= 2) { x = w>>1; do { - int Cb = pp[4]; - int Cr = pp[5]; + int32 Cb = pp[4]; + int32 Cr = pp[5]; YCbCrtoRGB(cp [0], pp[0]); YCbCrtoRGB(cp [1], pp[1]); @@ -1924,8 +1906,8 @@ DECLAREContigPutFunc(putcontig8bitYCbCr22tile) } else { while (h > 0) { for (x = w; x > 0;) { - int Cb = pp[4]; - int Cr = pp[5]; + int32 Cb = pp[4]; + int32 Cr = pp[5]; switch (x) { default: switch (h) { @@ -1962,15 +1944,13 @@ DECLAREContigPutFunc(putcontig8bitYCbCr22tile) */ DECLAREContigPutFunc(putcontig8bitYCbCr21tile) { - YCbCrSetup; - (void) y; fromskew = (fromskew * 4) / 2; do { x = w>>1; do { - int Cb = pp[2]; - int Cr = pp[3]; + int32 Cb = pp[2]; + int32 Cr = pp[3]; YCbCrtoRGB(cp[0], pp[0]); YCbCrtoRGB(cp[1], pp[1]); @@ -1981,8 +1961,8 @@ DECLAREContigPutFunc(putcontig8bitYCbCr21tile) if( (w&1) != 0 ) { - int Cb = pp[2]; - int Cr = pp[3]; + int32 Cb = pp[2]; + int32 Cr = pp[3]; YCbCrtoRGB(cp [0], pp[0]); @@ -2000,15 +1980,13 @@ DECLAREContigPutFunc(putcontig8bitYCbCr21tile) */ DECLAREContigPutFunc(putcontig8bitYCbCr11tile) { - YCbCrSetup; - (void) y; fromskew *= 3; do { x = w; /* was x = w>>1; patched 2000/09/25 warmerda@home.com */ do { - int Cb = pp[1]; - int Cr = pp[2]; + int32 Cb = pp[1]; + int32 Cr = pp[2]; YCbCrtoRGB(*cp++, pp[0]); @@ -2018,7 +1996,6 @@ DECLAREContigPutFunc(putcontig8bitYCbCr11tile) pp += fromskew; } while (--h); } -#undef YCbCrSetup #undef YCbCrtoRGB static tileContigRoutine diff --git a/libtiff/tiffio.h b/libtiff/tiffio.h index 23a37068..557586fc 100644 --- a/libtiff/tiffio.h +++ b/libtiff/tiffio.h @@ -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 @@ -153,8 +153,6 @@ typedef struct { /* YCbCr->RGB support */ int* Cb_b_tab; int32* Cr_g_tab; int32* Cb_g_tab; - float coeffs[3]; /* XXX: no longer required. Will - be removed in the future. */ } TIFFYCbCrToRGB; typedef struct { /* CIE Lab 1976->RGB support */ @@ -169,14 +167,15 @@ typedef struct { /* CIE Lab 1976->RGB support */ extern int TIFFCIELabToRGBInit(TIFFCIELabToRGB*, TIFFDisplay *display, float X0, float Y0, float Z0); -extern int TIFFCIELabToRGBEnd(TIFFCIELabToRGB*); +extern void TIFFCIELabToRGBEnd(TIFFCIELabToRGB*); extern void TIFFCIELabToXYZ(TIFFCIELabToRGB *, uint32, int32, int32, float *, float *, float *); extern void TIFFXYZToRGB(TIFFCIELabToRGB *, float, float, float, uint32 *, uint32 *, uint32 *); -extern int -TIFFYCbCrToRGBInit(TIFFYCbCrToRGB*, float, float, float); +extern int TIFFYCbCrToRGBInit(TIFFYCbCrToRGB*, float, float, float); +extern void TIFFYCbCrtoRGB(TIFFYCbCrToRGB *, uint32, int32, int32, + uint32 *, uint32 *, uint32 *); /* * RGBA-style image support.