summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authordron <dron>2003-12-03 19:54:03 +0000
committerdron <dron>2003-12-03 19:54:03 +0000
commit60d72680fdd391cd9425e95351ff4c158fd9cfad (patch)
tree7e959469f3b960a1ec9f79a8bdcd2637b432d516
parentf14a846b48afcef09da594254d72b39d28238b24 (diff)
downloadlibtiff-60d72680fdd391cd9425e95351ff4c158fd9cfad.tar.gz
Improvements in CIE Lab conversion code. Start moving YCbCr stuff to the
tif_color.c module.
-rw-r--r--libtiff/tif_color.c262
-rw-r--r--libtiff/tif_getimage.c204
-rw-r--r--libtiff/tiffio.h17
3 files changed, 253 insertions, 230 deletions
diff --git a/libtiff/tif_color.c b/libtiff/tif_color.c
index f6c0e60d..2c3c2831 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.1 2003-11-13 19:46:39 dron Exp $ */
+/* $Header: /cvs/maptools/cvsroot/libtiff/libtiff/tif_color.c,v 1.2 2003-12-03 19:54:03 dron Exp $ */
/*
* Copyright (c) 1988-1997 Sam Leffler
@@ -27,7 +27,7 @@
/*
* CIE L*a*b* to CIE XYZ and CIE XYZ to RGB conversion routines are taken
* from the VIPS library (http://www.vips.ecs.soton.ac.uk) with
- * the permission of John Cupitt, the author.
+ * the permission of John Cupitt, the VIPS author.
*/
/*
@@ -44,31 +44,31 @@
* reference white tristimuli can be specified.
*/
void
-TIFFCIELabToXYZ(uint32 l, int32 a, int32 b, float *X, float *Y, float *Z,
- float X0, float Y0, float Z0)
+TIFFCIELabToXYZ(TIFFCIELabToRGB *cielab, uint32 l, int32 a, int32 b,
+ float *X, float *Y, float *Z)
{
float L = (float)l * 100.0 / 255.0;
float cby, tmp;
if( L < 8.856 ) {
- *Y = (L * Y0) / 903.292;
- cby = 7.787 * (*Y / Y0) + 16.0 / 116.0;
+ *Y = (L * cielab->Y0) / 903.292;
+ cby = 7.787 * (*Y / cielab->Y0) + 16.0 / 116.0;
} else {
cby = (L + 16.0) / 116.0;
- *Y = Y0 * cby * cby * cby;
+ *Y = cielab->Y0 * cby * cby * cby;
}
tmp = (double)a / 500.0 + cby;
if( tmp < 0.2069 )
- *X = X0 * (tmp - 0.13793) / 7.787;
+ *X = cielab->X0 * (tmp - 0.13793) / 7.787;
else
- *X = X0 * tmp * tmp * tmp;
+ *X = cielab->X0 * tmp * tmp * tmp;
tmp = cby - (double)b / 200.0;
if( tmp < 0.2069 )
- *Z = Z0 * (tmp - 0.13793) / 7.787;
+ *Z = cielab->Z0 * (tmp - 0.13793) / 7.787;
else
- *Z = Z0 * tmp * tmp * tmp;
+ *Z = cielab->Z0 * tmp * tmp * tmp;
}
/*
@@ -116,118 +116,170 @@ TIFFXYZToRGB(TIFFCIELabToRGB *cielab, float X, float Y, float Z,
* the Yr,Yb,Yg <=> r,g,b conversions.
*/
int
-TIFFCIELabToRGBInit(TIFFCIELabToRGB** cielab)
+TIFFCIELabToRGBInit(TIFFCIELabToRGB* cielab, TIFFDisplay *display,
+ float X0, float Y0, float Z0)
{
static char module[] = "TIFFCIELabToRGBInit";
int i;
float gamma;
- TIFFDisplay sRGB_display = {
- { /* XYZ -> luminance matrix */
- { 3.2410, -1.5374, -0.4986 },
- { -0.9692, 1.8760, 0.0416 },
- { 0.0556, -0.2040, 1.0570 }
- },
- 100, 100, 100, /* Light o/p for reference white */
- 255, 255, 255, /* Pixel values for ref. white */
- 1, 1, 1, /* Residual light o/p for black pixel */
- 2.4, 2.4, 2.4, /* Gamma values for the three guns */
- };
-
-
- if (!(*cielab)) {
- *cielab = (TIFFCIELabToRGB *)
- _TIFFmalloc(sizeof(TIFFCIELabToRGB));
- if (*cielab == NULL) {
- TIFFError(module,
- "No space for CIE L*a*b* control structure");
- return -1;
- }
-
- (*cielab)->range = 1500;
-
- (*cielab)->display =
- (TIFFDisplay *)_TIFFmalloc(sizeof(TIFFDisplay));
- if ((*cielab) == NULL) {
- TIFFError(module, "No space for display structure");
- _TIFFfree(*cielab);
- *cielab = 0;
- return -1;
- }
-
- (*cielab)->Yr2r = (float *)
- _TIFFmalloc(((*cielab)->range + 1) * sizeof(float));
- if ((*cielab)->Yr2r == NULL) {
- TIFFError(module, "No space for Red conversion array");
- _TIFFfree((*cielab)->display);
- _TIFFfree(*cielab);
- *cielab = 0;
- return -1;
- }
-
- (*cielab)->Yg2g = (float *)
- _TIFFmalloc(((*cielab)->range + 1) * sizeof(float));
- if ((*cielab)->Yg2g == NULL) {
- TIFFError(module,
- "No space for Green conversion array");
- _TIFFfree((*cielab)->Yr2r);
- _TIFFfree((*cielab)->display);
- _TIFFfree(*cielab);
- *cielab = 0;
- return -1;
- }
-
- (*cielab)->Yb2b = (float *)
- _TIFFmalloc(((*cielab)->range + 1) * sizeof(float));
- if ((*cielab)->Yb2b == NULL) {
- TIFFError(module, "No space for Blue conversion array");
- _TIFFfree((*cielab)->Yb2b);
- _TIFFfree((*cielab)->Yr2r);
- _TIFFfree((*cielab)->display);
- _TIFFfree(*cielab);
- *cielab = 0;
- return -1;
- }
-
- _TIFFmemcpy((*cielab)->display, &sRGB_display,
- sizeof(TIFFDisplay));
+ cielab->range = 1500;
+
+ cielab->display = (TIFFDisplay *)_TIFFmalloc(sizeof(TIFFDisplay));
+ if (cielab == NULL) {
+ TIFFError(module, "No space for display structure");
+ return -1;
+ }
+
+ cielab->Yr2r = (float *)
+ _TIFFmalloc((cielab->range + 1) * sizeof(float));
+ if (cielab->Yr2r == NULL) {
+ TIFFError(module, "No space for Red conversion array");
+ _TIFFfree(cielab->display);
+ return -1;
+ }
+
+ cielab->Yg2g = (float *)
+ _TIFFmalloc((cielab->range + 1) * sizeof(float));
+ if (cielab->Yg2g == NULL) {
+ TIFFError(module,
+ "No space for Green conversion array");
+ _TIFFfree(cielab->Yr2r);
+ _TIFFfree(cielab->display);
+ return -1;
+ }
+
+ cielab->Yb2b = (float *)
+ _TIFFmalloc((cielab->range + 1) * sizeof(float));
+ if (cielab->Yb2b == NULL) {
+ TIFFError(module, "No space for Blue conversion array");
+ _TIFFfree(cielab->Yb2b);
+ _TIFFfree(cielab->Yr2r);
+ _TIFFfree(cielab->display);
+ return -1;
}
+ _TIFFmemcpy(cielab->display, display, sizeof(TIFFDisplay));
+
/* Red */
- gamma = 1.0 / (*cielab)->display->d_gammaR ;
- (*cielab)->rstep =
- ((*cielab)->display->d_YCR - (*cielab)->display->d_Y0R)
- / (*cielab)->range;
- for(i = 0; i <= (*cielab)->range; i++) {
- (*cielab)->Yr2r[i] =
- (*cielab)->display->d_Vrwr
- * (pow((double)i / (*cielab)->range, gamma));
+ gamma = 1.0 / cielab->display->d_gammaR ;
+ cielab->rstep =
+ (cielab->display->d_YCR - cielab->display->d_Y0R)
+ / cielab->range;
+ for(i = 0; i <= cielab->range; i++) {
+ cielab->Yr2r[i] = cielab->display->d_Vrwr
+ * (pow((double)i / cielab->range, gamma));
}
/* Green */
- gamma = 1.0 / (*cielab)->display->d_gammaG ;
- (*cielab)->gstep =
- ((*cielab)->display->d_YCR - (*cielab)->display->d_Y0R)
- / (*cielab)->range;
- for(i = 0; i <= (*cielab)->range; i++) {
- (*cielab)->Yg2g[i] =
- (*cielab)->display->d_Vrwg
- * (pow((double)i / (*cielab)->range, gamma));
+ gamma = 1.0 / cielab->display->d_gammaG ;
+ cielab->gstep =
+ (cielab->display->d_YCR - cielab->display->d_Y0R)
+ / cielab->range;
+ for(i = 0; i <= cielab->range; i++) {
+ cielab->Yg2g[i] = cielab->display->d_Vrwg
+ * (pow((double)i / cielab->range, gamma));
}
/* Blue */
- gamma = 1.0 / (*cielab)->display->d_gammaB ;
- (*cielab)->bstep =
- ((*cielab)->display->d_YCR - (*cielab)->display->d_Y0R)
- / (*cielab)->range;
- for(i = 0; i <= (*cielab)->range; i++) {
- (*cielab)->Yb2b[i] =
- (*cielab)->display->d_Vrwb
- * (pow((double)i / (*cielab)->range, gamma));
+ gamma = 1.0 / cielab->display->d_gammaB ;
+ cielab->bstep =
+ (cielab->display->d_YCR - cielab->display->d_Y0R)
+ / cielab->range;
+ for(i = 0; i <= cielab->range; i++) {
+ cielab->Yb2b[i] = cielab->display->d_Vrwb
+ * (pow((double)i / cielab->range, gamma));
}
+ /* Init reference white point */
+ cielab->X0 = X0;
+ cielab->Y0 = Y0;
+ cielab->Z0 = Z0;
+
return 0;
}
+/*
+ * Free TIFFYCbCrToRGB structure.
+ */
+int
+TIFFCIELabToRGBEnd(TIFFCIELabToRGB* cielab)
+{
+ static char module[] = "TIFFCIELabToRGBEnd";
+
+ _TIFFfree(cielab->Yr2r);
+ _TIFFfree(cielab->Yg2g);
+ _TIFFfree(cielab->Yb2b);
+ _TIFFfree(cielab->display);
+}
+
+#define SHIFT 16
+#define FIX(x) ((int32)((x) * (1L<<SHIFT) + 0.5))
+#define ONE_HALF ((int32)(1<<(SHIFT-1)))
+
+/*
+ * Initialize the YCbCr->RGB conversion tables. The conversion
+ * is done according to the 6.0 spec:
+ *
+ * R = Y + Cr*(2 - 2*LumaRed)
+ * B = Y + Cb*(2 - 2*LumaBlue)
+ * G = Y
+ * - LumaBlue*Cb*(2-2*LumaBlue)/LumaGreen
+ * - LumaRed*Cr*(2-2*LumaRed)/LumaGreen
+ *
+ * To avoid floating point arithmetic the fractional constants that
+ * come out of the equations are represented as fixed point values
+ * in the range 0...2^16. We also eliminate multiplications by
+ * pre-calculating possible values indexed by Cb and Cr (this code
+ * assumes conversion is being done for 8-bit samples).
+ */
+int
+TIFFYCbCrToRGBInit(TIFFYCbCrToRGB* ycbcr,
+ float LumaRed, float LumaGreen, float LumaBlue)
+{
+ TIFFRGBValue* clamptab;
+ int i;
+
+ clamptab = (TIFFRGBValue*)(
+ (tidata_t) ycbcr+TIFFroundup(sizeof (TIFFYCbCrToRGB), sizeof (long)));
+ _TIFFmemset(clamptab, 0, 256); /* v < 0 => 0 */
+ ycbcr->clamptab = (clamptab += 256);
+ for (i = 0; i < 256; i++)
+ clamptab[i] = (TIFFRGBValue) i;
+ _TIFFmemset(clamptab+256, 255, 2*256); /* v > 255 => 255 */
+ { float f1 = 2-2*LumaRed; int32 D1 = FIX(f1);
+ float f2 = LumaRed*f1/LumaGreen; int32 D2 = -FIX(f2);
+ float f3 = 2-2*LumaBlue; int32 D3 = FIX(f3);
+ float f4 = LumaBlue*f3/LumaGreen; int32 D4 = -FIX(f4);
+ int x;
+
+ ycbcr->Cr_r_tab = (int*) (clamptab + 3*256);
+ ycbcr->Cb_b_tab = ycbcr->Cr_r_tab + 256;
+ ycbcr->Cr_g_tab = (int32*) (ycbcr->Cb_b_tab + 256);
+ ycbcr->Cb_g_tab = ycbcr->Cr_g_tab + 256;
+ /*
+ * i is the actual input pixel value in the range 0..255
+ * Cb and Cr values are in the range -128..127 (actually
+ * they are in a range defined by the ReferenceBlackWhite
+ * tag) so there is some range shifting to do here when
+ * constructing tables indexed by the raw pixel data.
+ *
+ * XXX handle ReferenceBlackWhite correctly to calculate
+ * Cb/Cr values to use in constructing the tables.
+ */
+ for (i = 0, x = -128; i < 256; i++, x++) {
+ ycbcr->Cr_r_tab[i] = (int)((D1*x + ONE_HALF)>>SHIFT);
+ ycbcr->Cb_b_tab[i] = (int)((D3*x + ONE_HALF)>>SHIFT);
+ ycbcr->Cr_g_tab[i] = D2*x;
+ ycbcr->Cb_g_tab[i] = D4*x + ONE_HALF;
+ }
+ }
+
+ return 0;
+}
+#undef SHIFT
+#undef ONE_HALF
+#undef FIX
+
diff --git a/libtiff/tif_getimage.c b/libtiff/tif_getimage.c
index a57de514..12a9402d 100644
--- a/libtiff/tif_getimage.c
+++ b/libtiff/tif_getimage.c
@@ -1,4 +1,4 @@
-/* $Header: /cvs/maptools/cvsroot/libtiff/libtiff/tif_getimage.c,v 1.30 2003-12-03 15:40:14 dron Exp $ */
+/* $Header: /cvs/maptools/cvsroot/libtiff/libtiff/tif_getimage.c,v 1.31 2003-12-03 19:54:03 dron Exp $ */
/*
* Copyright (c) 1991-1997 Sam Leffler
@@ -42,10 +42,29 @@ static int pickTileSeparateCase(TIFFRGBAImage*);
static const char photoTag[] = "PhotometricInterpretation";
+/*
+ * Helper constants used in Orientation tag handling
+ */
#define FLIP_VERTICALLY 0x01
#define FLIP_HORIZONTALLY 0x02
/*
+ * Color conversion constants. We will define display types here.
+ */
+
+TIFFDisplay display_sRGB = {
+ { /* XYZ -> luminance matrix */
+ { 3.2410, -1.5374, -0.4986 },
+ { -0.9692, 1.8760, 0.0416 },
+ { 0.0556, -0.2040, 1.0570 }
+ },
+ 100, 100, 100, /* Light o/p for reference white */
+ 255, 255, 255, /* Pixel values for ref. white */
+ 1, 1, 1, /* Residual light o/p for black pixel */
+ 2.4, 2.4, 2.4, /* Gamma values for the three guns */
+};
+
+/*
* Check the image to see if TIFFReadRGBAImage can deal with it.
* 1/0 is returned according to whether or not the image can
* be handled. If 0 is returned, emsg contains the reason
@@ -174,10 +193,7 @@ TIFFRGBAImageEnd(TIFFRGBAImage* img)
if (img->ycbcr)
_TIFFfree(img->ycbcr), img->ycbcr = NULL;
if (img->cielab) {
- _TIFFfree(img->cielab->Yr2r);
- _TIFFfree(img->cielab->Yg2g);
- _TIFFfree(img->cielab->Yb2b);
- _TIFFfree(img->cielab->display);
+ TIFFCIELabToRGBEnd(img->cielab);
_TIFFfree(img->cielab), img->cielab = NULL;
}
@@ -1540,11 +1556,11 @@ DECLAREContigPutFunc(putcontig8bitCIELab)
fromskew *= 3;
while (h-- > 0) {
for (x = w; x-- > 0;) {
- TIFFCIELabToXYZ((u_char)pp[0],
+ TIFFCIELabToXYZ(img->cielab,
+ (u_char)pp[0],
(signed char)pp[1],
(signed char)pp[2],
- &X, &Y, &Z,
- D50_X0, D50_Y0, D50_Z0);
+ &X, &Y, &Z);
TIFFXYZToRGB(img->cielab, X, Y, Z, &r, &g, &b);
*cp++ = PACK(r, g, b);
pp += 3;
@@ -2005,128 +2021,76 @@ DECLAREContigPutFunc(putcontig8bitYCbCr11tile)
#undef YCbCrSetup
#undef YCbCrtoRGB
-#define LumaRed coeffs[0]
-#define LumaGreen coeffs[1]
-#define LumaBlue coeffs[2]
-#define SHIFT 16
-#define FIX(x) ((int32)((x) * (1L<<SHIFT) + 0.5))
-#define ONE_HALF ((int32)(1<<(SHIFT-1)))
-
-/*
- * Initialize the YCbCr->RGB conversion tables. The conversion
- * is done according to the 6.0 spec:
- *
- * R = Y + Cr*(2 - 2*LumaRed)
- * B = Y + Cb*(2 - 2*LumaBlue)
- * G = Y
- * - LumaBlue*Cb*(2-2*LumaBlue)/LumaGreen
- * - LumaRed*Cr*(2-2*LumaRed)/LumaGreen
- *
- * To avoid floating point arithmetic the fractional constants that
- * come out of the equations are represented as fixed point values
- * in the range 0...2^16. We also eliminate multiplications by
- * pre-calculating possible values indexed by Cb and Cr (this code
- * assumes conversion is being done for 8-bit samples).
- */
-static void
-TIFFYCbCrToRGBInit(TIFFYCbCrToRGB* ycbcr, TIFF* tif)
-{
- TIFFRGBValue* clamptab;
- float* coeffs;
- int i;
-
- clamptab = (TIFFRGBValue*)(
- (tidata_t) ycbcr+TIFFroundup(sizeof (TIFFYCbCrToRGB), sizeof (long)));
- _TIFFmemset(clamptab, 0, 256); /* v < 0 => 0 */
- ycbcr->clamptab = (clamptab += 256);
- for (i = 0; i < 256; i++)
- clamptab[i] = (TIFFRGBValue) i;
- _TIFFmemset(clamptab+256, 255, 2*256); /* v > 255 => 255 */
- TIFFGetFieldDefaulted(tif, TIFFTAG_YCBCRCOEFFICIENTS, &coeffs);
- _TIFFmemcpy(ycbcr->coeffs, coeffs, 3*sizeof (float));
- { float f1 = 2-2*LumaRed; int32 D1 = FIX(f1);
- float f2 = LumaRed*f1/LumaGreen; int32 D2 = -FIX(f2);
- float f3 = 2-2*LumaBlue; int32 D3 = FIX(f3);
- float f4 = LumaBlue*f3/LumaGreen; int32 D4 = -FIX(f4);
- int x;
-
- ycbcr->Cr_r_tab = (int*) (clamptab + 3*256);
- ycbcr->Cb_b_tab = ycbcr->Cr_r_tab + 256;
- ycbcr->Cr_g_tab = (int32*) (ycbcr->Cb_b_tab + 256);
- ycbcr->Cb_g_tab = ycbcr->Cr_g_tab + 256;
- /*
- * i is the actual input pixel value in the range 0..255
- * Cb and Cr values are in the range -128..127 (actually
- * they are in a range defined by the ReferenceBlackWhite
- * tag) so there is some range shifting to do here when
- * constructing tables indexed by the raw pixel data.
- *
- * XXX handle ReferenceBlackWhite correctly to calculate
- * Cb/Cr values to use in constructing the tables.
- */
- for (i = 0, x = -128; i < 256; i++, x++) {
- ycbcr->Cr_r_tab[i] = (int)((D1*x + ONE_HALF)>>SHIFT);
- ycbcr->Cb_b_tab[i] = (int)((D3*x + ONE_HALF)>>SHIFT);
- ycbcr->Cr_g_tab[i] = D2*x;
- ycbcr->Cb_g_tab[i] = D4*x + ONE_HALF;
- }
- }
-}
-#undef SHIFT
-#undef ONE_HALF
-#undef FIX
-#undef LumaBlue
-#undef LumaGreen
-#undef LumaRed
-
static tileContigRoutine
initYCbCrConversion(TIFFRGBAImage* img)
{
- uint16 hs, vs;
-
- if (img->ycbcr == NULL) {
- img->ycbcr = (TIFFYCbCrToRGB*) _TIFFmalloc(
- TIFFroundup(sizeof (TIFFYCbCrToRGB), sizeof (long))
- + 4*256*sizeof (TIFFRGBValue)
- + 2*256*sizeof (int)
- + 2*256*sizeof (int32)
- );
+ static char module[] = "initCIELabConversion";
+
+ float *coeffs;
+ uint16 hs, vs;
+
if (img->ycbcr == NULL) {
- TIFFError(TIFFFileName(img->tif),
- "No space for YCbCr->RGB conversion state");
- return (NULL);
+ img->ycbcr = (TIFFYCbCrToRGB*) _TIFFmalloc(
+ TIFFroundup(sizeof (TIFFYCbCrToRGB), sizeof (long))
+ + 4*256*sizeof (TIFFRGBValue)
+ + 2*256*sizeof (int)
+ + 2*256*sizeof (int32)
+ );
+ if (img->ycbcr == NULL) {
+ TIFFError(module,
+ "No space for YCbCr->RGB conversion state");
+ return (NULL);
+ }
}
- TIFFYCbCrToRGBInit(img->ycbcr, img->tif);
- } else {
- float* coeffs;
TIFFGetFieldDefaulted(img->tif, TIFFTAG_YCBCRCOEFFICIENTS, &coeffs);
- if (_TIFFmemcmp(coeffs, img->ycbcr->coeffs, 3*sizeof (float)) != 0)
- TIFFYCbCrToRGBInit(img->ycbcr, img->tif);
- }
- /*
- * The 6.0 spec says that subsampling must be
- * one of 1, 2, or 4, and that vertical subsampling
- * must always be <= horizontal subsampling; so
- * there are only a few possibilities and we just
- * enumerate the cases.
- */
- TIFFGetFieldDefaulted(img->tif, TIFFTAG_YCBCRSUBSAMPLING, &hs, &vs);
- switch ((hs<<4)|vs) {
- case 0x44: return (putcontig8bitYCbCr44tile);
- case 0x42: return (putcontig8bitYCbCr42tile);
- case 0x41: return (putcontig8bitYCbCr41tile);
- case 0x22: return (putcontig8bitYCbCr22tile);
- case 0x21: return (putcontig8bitYCbCr21tile);
- case 0x11: return (putcontig8bitYCbCr11tile);
- }
- return (NULL);
+ if (TIFFYCbCrToRGBInit(img->ycbcr,
+ coeffs[0], coeffs[1], coeffs[2]) < 0)
+ return NULL;
+
+ /*
+ * The 6.0 spec says that subsampling must be
+ * one of 1, 2, or 4, and that vertical subsampling
+ * must always be <= horizontal subsampling; so
+ * there are only a few possibilities and we just
+ * enumerate the cases.
+ */
+ TIFFGetFieldDefaulted(img->tif, TIFFTAG_YCBCRSUBSAMPLING, &hs, &vs);
+ switch ((hs<<4)|vs) {
+ case 0x44: return (putcontig8bitYCbCr44tile);
+ case 0x42: return (putcontig8bitYCbCr42tile);
+ case 0x41: return (putcontig8bitYCbCr41tile);
+ case 0x22: return (putcontig8bitYCbCr22tile);
+ case 0x21: return (putcontig8bitYCbCr21tile);
+ case 0x11: return (putcontig8bitYCbCr11tile);
+ }
+
+ return (NULL);
}
static tileContigRoutine
-initCIELabToRGBConversion(TIFFRGBAImage* img)
+initCIELabConversion(TIFFRGBAImage* img)
{
- TIFFCIELabToRGBInit(&img->cielab);
+ static char module[] = "initCIELabConversion";
+
+ if (!img->cielab) {
+ img->cielab = (TIFFCIELabToRGB *)
+ _TIFFmalloc(sizeof(TIFFCIELabToRGB));
+ if (!img->cielab) {
+ TIFFError(module,
+ "No space for CIE L*a*b*->RGB conversion state.");
+ return NULL;
+ }
+ }
+
+ if (TIFFCIELabToRGBInit(img->cielab, &display_sRGB,
+ D50_X0, D50_Y0, D50_Z0) < 0) {
+ TIFFError(module,
+ "Failed to initialize CIE L*a*b*->RGB conversion state.");
+ _TIFFfree(img->cielab);
+ return NULL;
+ }
+
return putcontig8bitCIELab;
}
@@ -2430,7 +2394,7 @@ pickTileContigCase(TIFFRGBAImage* img)
break;
case PHOTOMETRIC_CIELAB:
if (img->bitspersample == 8)
- put = initCIELabToRGBConversion(img);
+ put = initCIELabConversion(img);
break;
}
}
diff --git a/libtiff/tiffio.h b/libtiff/tiffio.h
index 436e055b..23a37068 100644
--- a/libtiff/tiffio.h
+++ b/libtiff/tiffio.h
@@ -1,4 +1,4 @@
-/* $Header: /cvs/maptools/cvsroot/libtiff/libtiff/tiffio.h,v 1.21 2003-12-03 15:40:14 dron Exp $ */
+/* $Header: /cvs/maptools/cvsroot/libtiff/libtiff/tiffio.h,v 1.22 2003-12-03 19:54:03 dron Exp $ */
/*
* Copyright (c) 1988-1997 Sam Leffler
@@ -153,7 +153,8 @@ typedef struct { /* YCbCr->RGB support */
int* Cb_b_tab;
int32* Cr_g_tab;
int32* Cb_g_tab;
- float coeffs[3]; /* cached for repeated use */
+ float coeffs[3]; /* XXX: no longer required. Will
+ be removed in the future. */
} TIFFYCbCrToRGB;
typedef struct { /* CIE Lab 1976->RGB support */
@@ -163,14 +164,20 @@ typedef struct { /* CIE Lab 1976->RGB support */
float* Yg2g; /* Conversion of Yg to g */
float* Yb2b; /* Conversion of Yb to b */
float rstep, gstep, bstep;
+ float X0, Y0, Z0; /* Reference white point */
} TIFFCIELabToRGB;
-extern int TIFFCIELabToRGBInit(TIFFCIELabToRGB**);
-extern void TIFFCIELabToXYZ(uint32, int32, int32, float *, float *, float *,
- float, float, float);
+extern int TIFFCIELabToRGBInit(TIFFCIELabToRGB*, TIFFDisplay *display,
+ float X0, float Y0, float Z0);
+extern int 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);
+
/*
* RGBA-style image support.
*/