AWARE [SYSTEMS] Imaging expertise for the Delphi developer
AWare Systems, Imaging expertise for the Delphi developer, Home TIFF and LibTiff Mailing List Archive

LibTiff Mailing List

TIFF and LibTiff Mailing List Archive
November 2009

Previous Thread
Next Thread

Previous by Thread
Next by Thread

Previous by Date
Next by Date

Contact

The TIFF Mailing List Homepage
This list is run by Frank Warmerdam
Archive maintained by AWare Systems



Valid HTML 4.01!



Thread

2009.11.29 17:02 "Reentrancy patches", by Adam Goode
2009.11.29 17:02 "[PATCH 1/3] Make TIFFGetFieldDefaulted of WhitePoint reentrant", by Adam Goode
2009.11.29 17:02 "[PATCH 2/3] Make TIFFGetFieldDefaulted of ReferenceBlackWhite reentrant", by Adam Goode
2009.11.29 17:02 "[PATCH 3/3] Eliminate static buffer for default YCbCrCoefficients", by Adam Goode
2009.11.29 18:17 "Re: Reentrancy patches", by Bob Friesenhahn

2009.11.29 17:02 "[PATCH 1/3] Make TIFFGetFieldDefaulted of WhitePoint reentrant", by Adam Goode

When custom fields were introduced in 2005, many internal fields
were converted to use custom fields, and TIFFGetFieldDefaulted got
a bit more complicated each time (with TIFFDefaultDirectory getting
simpler). Unfortunately for TIFFTAG_WHITEPOINT, the default result
is returned in a static buffer. If a multi-threaded program would
try to get the default value of WhitePoint, even with different TIFF*
objects, it would go wrong.

This fix returns WhitePoint to a non-custom field, which may not be
perfect, but it does remove the static buffer.
---
 libtiff/tif_aux.c     |   13 ++-----------
 libtiff/tif_dir.c     |   17 +++++++++++++++++
 libtiff/tif_dir.h     |    2 ++
 libtiff/tif_dirinfo.c |    2 +-
 libtiff/tif_print.c   |    7 +++----
 5 files changed, 25 insertions(+), 16 deletions(-)

diff --git a/libtiff/tif_aux.c b/libtiff/tif_aux.c
index 560b5a4..149a95f 100644
--- a/libtiff/tif_aux.c
+++ b/libtiff/tif_aux.c
@@ -201,17 +201,8 @@ TIFFVGetFieldDefaulted(TIFF* tif, uint32 tag, va_list
ap)
 		*va_arg(ap, uint16 *) = td->td_ycbcrpositioning;
 		return (1);
 	case TIFFTAG_WHITEPOINT:
-		{
-			static float whitepoint[2];
-
-			/* TIFF 6.0 specification tells that it is no default
-			   value for the WhitePoint, but AdobePhotoshop TIFF
-			   Technical Note tells that it should be CIE D50. */
-			whitepoint[0] =	D50_X0 / (D50_X0 + D50_Y0 + D50_Z0);
-			whitepoint[1] =	D50_Y0 / (D50_X0 + D50_Y0 + D50_Z0);
-			*va_arg(ap, float **) = whitepoint;
-			return 1;
-		}
+		*va_arg(ap, float**) = td->td_whitepoint;
+		return (1);
 	case TIFFTAG_TRANSFERFUNCTION:
 		if (!td->td_transferfunction[0] &&
 		    !TIFFDefaultTransferFunction(td)) {
diff --git a/libtiff/tif_dir.c b/libtiff/tif_dir.c
index 7e24622..6556cac 100644
--- a/libtiff/tif_dir.c
+++ b/libtiff/tif_dir.c
@@ -372,6 +372,9 @@ _TIFFVSetField(TIFF* tif, uint32 tag, va_list ap)
 		td->td_ycbcrsubsampling[0] = (uint16) va_arg(ap, uint16_vap);
 		td->td_ycbcrsubsampling[1] = (uint16) va_arg(ap, uint16_vap);
 		break;
+	case TIFFTAG_WHITEPOINT:
+		_TIFFsetFloatArray(&td->td_whitepoint, va_arg(ap, float*), 2);
+		break;
 	case TIFFTAG_TRANSFERFUNCTION:
 		v = (td->td_samplesperpixel - td->td_extrasamples) > 1 ? 3 : 1;
 		for (i = 0; i < v; i++)
@@ -880,6 +883,9 @@ _TIFFVGetField(TIFF* tif, uint32 tag, va_list ap)
 			*va_arg(ap, uint16*) = td->td_ycbcrsubsampling[0];
 			*va_arg(ap, uint16*) = td->td_ycbcrsubsampling[1];
 			break;
+		case TIFFTAG_WHITEPOINT:
+			*va_arg(ap, float**) = td->td_whitepoint;
+			break;
 		case TIFFTAG_TRANSFERFUNCTION:
 			*va_arg(ap, uint16**) = td->td_transferfunction[0];
 			if (td->td_samplesperpixel - td->td_extrasamples > 1) {
@@ -1075,6 +1081,7 @@ TIFFFreeDirectory(TIFF* tif)
 	CleanupField(td_sampleinfo);
 	CleanupField(td_subifd);
 	CleanupField(td_inknames);
+	CleanupField(td_whitepoint);
 	CleanupField(td_transferfunction[0]);
 	CleanupField(td_transferfunction[1]);
 	CleanupField(td_transferfunction[2]);
@@ -1156,6 +1163,16 @@ TIFFDefaultDirectory(TIFF* tif)
 	td->td_ycbcrsubsampling[0] = 2;
 	td->td_ycbcrsubsampling[1] = 2;
 	td->td_ycbcrpositioning = YCBCRPOSITION_CENTERED;
+
+	/* TIFF 6.0 specification tells that it is no default
+	   value for the WhitePoint, but AdobePhotoshop TIFF
+	   Technical Note tells that it should be CIE D50. */
+	td->td_whitepoint = (float *) _TIFFmalloc(2 * sizeof (float));
+	if (!td->td_whitepoint)
+		return 0;
+	td->td_whitepoint[0] = D50_X0 / (D50_X0 + D50_Y0 + D50_Z0);
+	td->td_whitepoint[1] = D50_Y0 / (D50_X0 + D50_Y0 + D50_Z0);
+
 	tif->tif_postdecode = _TIFFNoPostDecode;  
 	tif->tif_foundfield = NULL;
 	tif->tif_tagmethods.vsetfield = _TIFFVSetField;  
diff --git a/libtiff/tif_dir.h b/libtiff/tif_dir.h
index a0d333f..49e463e 100644
--- a/libtiff/tif_dir.h
+++ b/libtiff/tif_dir.h
@@ -81,6 +81,7 @@ typedef struct {
 	uint16  td_ycbcrsubsampling[2];
 	uint16  td_ycbcrpositioning;
 	/* Colorimetry parameters */
+	float*	td_whitepoint;
 	uint16* td_transferfunction[3];
 	/* CMYK parameters */
 	int     td_inknameslen;
@@ -136,6 +137,7 @@ typedef struct {
 #define FIELD_HALFTONEHINTS            37
 #define FIELD_YCBCRSUBSAMPLING         39
 #define FIELD_YCBCRPOSITIONING         40
+#define FIELD_WHITEPOINT               42
 #define FIELD_TRANSFERFUNCTION         44
 #define FIELD_INKNAMES                 46
 #define FIELD_SUBIFD                   49
diff --git a/libtiff/tif_dirinfo.c b/libtiff/tif_dirinfo.c
index fa4935a..b88fca7 100644
--- a/libtiff/tif_dirinfo.c
+++ b/libtiff/tif_dirinfo.c
@@ -87,7 +87,7 @@ tiffFields[] = {
 	{ TIFFTAG_DATETIME, 20, 20, TIFF_ASCII, 0, TIFF_SETGET_ASCII,
 	TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "DateTime", NULL },
 	{ TIFFTAG_ARTIST, -1, -1, TIFF_ASCII, 0, TIFF_SETGET_ASCII,
 	TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "Artist", NULL },
 	{ TIFFTAG_HOSTCOMPUTER, -1, -1, TIFF_ASCII, 0, TIFF_SETGET_ASCII,
 	TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "HostComputer", NULL },
-	{ TIFFTAG_WHITEPOINT, 2, 2, TIFF_RATIONAL, 0, TIFF_SETGET_C0_FLOAT,
TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "WhitePoint", NULL },
+	{ TIFFTAG_WHITEPOINT, 2, 2, TIFF_RATIONAL, 0, TIFF_SETGET_C0_FLOAT,
TIFF_SETGET_UNDEFINED, FIELD_WHITEPOINT, 1, 0, "WhitePoint", NULL },
 	{ TIFFTAG_PRIMARYCHROMATICITIES, 6, 6, TIFF_RATIONAL, 0,
 	TIFF_SETGET_C0_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0,
 	"PrimaryChromaticities", NULL },
 	{ TIFFTAG_COLORMAP, -1, -1, TIFF_SHORT, 0, TIFF_SETGET_OTHER,
 	TIFF_SETGET_UNDEFINED, FIELD_COLORMAP, 1, 0, "ColorMap", NULL },
 	{ TIFFTAG_HALFTONEHINTS, 2, 2, TIFF_SHORT, 0, TIFF_SETGET_UINT16_PAIR,
 	TIFF_SETGET_UNDEFINED, FIELD_HALFTONEHINTS, 1, 0, "HalftoneHints", NULL },
diff --git a/libtiff/tif_print.c b/libtiff/tif_print.c
index 4b19964..10c1ece 100644
--- a/libtiff/tif_print.c
+++ b/libtiff/tif_print.c
@@ -159,10 +159,6 @@ _TIFFPrettyPrintField(TIFF* tif, FILE* fd, uint32 tag,
 			fprintf(fd, "  Dot Range: %u-%u\n",
 			    ((uint16*)raw_data)[0], ((uint16*)raw_data)[1]);
 			return 1;
-		case TIFFTAG_WHITEPOINT:
-			fprintf(fd, "  White Point: %g-%g\n",
-			    ((float *)raw_data)[0], ((float *)raw_data)[1]);
-			return 1;
 		case TIFFTAG_REFERENCEBLACKWHITE:
 		{
 			uint16 i;
@@ -497,6 +493,9 @@ TIFFPrintDirectory(TIFF* tif, FILE* fd, long flags)
 		} else
 			fprintf(fd, "(present)\n");
 	}
+	if (TIFFFieldSet(tif,FIELD_WHITEPOINT))
+		fprintf(fd, "  White Point: %g-%g\n",
+		    td->td_whitepoint[0], td->td_whitepoint[1]);
 	if (TIFFFieldSet(tif,FIELD_TRANSFERFUNCTION)) {
 		fprintf(fd, "  Transfer Function: ");
 		if (flags & TIFFPRINT_CURVES) {
-- 
1.6.5.2