AWARE [SYSTEMS]
AWare Systems, , 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
Archive maintained by AWare Systems



New Datamatrix section



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 2/3] Make TIFFGetFieldDefaulted of ReferenceBlackWhite 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_REFERENCEBLACKWHITE, the
default result is returned in a static buffer. If a
multi-threaded program would try to get the default value of
ReferenceBlackWhite, even with different TIFF* objects, it would
go wrong.

This fix returns ReferenceBlackWhite to a non-custom field, which
may not be perfect, but it does remove the static buffers.
---
 libtiff/tif_aux.c     |   60
 +++++++++++++++++++++++++++----------------------
 libtiff/tif_dir.c     |    8 ++++++
 libtiff/tif_dir.h     |    2 +
 libtiff/tif_dirinfo.c |    2 +-
 4 files changed, 44 insertions(+), 28 deletions(-)

diff --git a/libtiff/tif_aux.c b/libtiff/tif_aux.c
index 149a95f..e8d89f4 100644
--- a/libtiff/tif_aux.c
+++ b/libtiff/tif_aux.c
@@ -100,6 +100,35 @@ bad:
 	return 0;
 }
 
+static int
+TIFFDefaultRefBlackWhite(TIFFDirectory* td)
+{
+	int i;
+
+	if (!(td->td_refblackwhite = (float *)_TIFFmalloc(6*sizeof (float))))
+		return 0;
+        if (td->td_photometric == PHOTOMETRIC_YCBCR) {
+		/*
+		 * YCbCr (Class Y) images must have the ReferenceBlackWhite
+		 * tag set. Fix the broken images, which lacks that tag.
+		 */
+		td->td_refblackwhite[0] = 0.0F;
+		td->td_refblackwhite[1] = td->td_refblackwhite[3] =
+			td->td_refblackwhite[5] = 255.0F;
+		td->td_refblackwhite[2] = td->td_refblackwhite[4] = 128.0F;
+	} else {
+		/*
+		 * Assume RGB (Class R)
+		 */
+		for (i = 0; i < 3; i++) {
+		    td->td_refblackwhite[2*i+0] = 0;
+		    td->td_refblackwhite[2*i+1] =
+			    (float)((1L<<td->td_bitspersample)-1L);
+		}
+	}
+	return 1;
+}
+
 /*
  * Like TIFFGetField, but return any default
  * value if the tag is not present in the directory.
@@ -216,33 +245,10 @@ TIFFVGetFieldDefaulted(TIFF* tif, uint32 tag, va_list
ap)
 		}
 		return (1);
 	case TIFFTAG_REFERENCEBLACKWHITE:
-		{
-			int i;
-			static float ycbcr_refblackwhite[] = 
-			{ 0.0F, 255.0F, 128.0F, 255.0F, 128.0F, 255.0F };
-			static float rgb_refblackwhite[6];
-
-			for (i = 0; i < 3; i++) {
-				rgb_refblackwhite[2 * i + 0] = 0.0F;
-				rgb_refblackwhite[2 * i + 1] =
-					(float)((1L<<td->td_bitspersample)-1L);
-			}
-			
-			if (td->td_photometric == PHOTOMETRIC_YCBCR) {
-				/*
-				 * YCbCr (Class Y) images must have the
-				 * ReferenceBlackWhite tag set. Fix the
-				 * broken images, which lacks that tag.
-				 */
-				*va_arg(ap, float **) = ycbcr_refblackwhite;
-			} else {
-				/*
-				 * Assume RGB (Class R)
-				 */
-				*va_arg(ap, float **) = rgb_refblackwhite;
-			}
-			return 1;
-		}
+		if (!td->td_refblackwhite && !TIFFDefaultRefBlackWhite(td))
+			return (0);
+		*va_arg(ap, float **) = td->td_refblackwhite;
+		return (1);
 	}
 	return 0;
 }
diff --git a/libtiff/tif_dir.c b/libtiff/tif_dir.c
index 6556cac..56863df 100644
--- a/libtiff/tif_dir.c
+++ b/libtiff/tif_dir.c
@@ -381,6 +381,10 @@ _TIFFVSetField(TIFF* tif, uint32 tag, va_list ap)
 			_TIFFsetShortArray(&td->td_transferfunction[i],
 			    va_arg(ap, uint16*), 1L<<td->td_bitspersample);
 		break;
+	case TIFFTAG_REFERENCEBLACKWHITE:
+		/* XXX should check for null range */
+		_TIFFsetFloatArray(&td->td_refblackwhite, va_arg(ap, float*), 6);
+		break;
 	case TIFFTAG_INKNAMES:
 		v = (uint16) va_arg(ap, uint16_vap);
 		s = va_arg(ap, char*);
@@ -893,6 +897,9 @@ _TIFFVGetField(TIFF* tif, uint32 tag, va_list ap)
 				*va_arg(ap, uint16**) = td->td_transferfunction[2];
 			}
 			break;
+		case TIFFTAG_REFERENCEBLACKWHITE:
+			*va_arg(ap, float**) = td->td_refblackwhite;
+			break;
 		case TIFFTAG_INKNAMES:
 			*va_arg(ap, char**) = td->td_inknames;
 			break;
@@ -1082,6 +1089,7 @@ TIFFFreeDirectory(TIFF* tif)
 	CleanupField(td_subifd);
 	CleanupField(td_inknames);
 	CleanupField(td_whitepoint);
+	CleanupField(td_refblackwhite);
 	CleanupField(td_transferfunction[0]);
 	CleanupField(td_transferfunction[1]);
 	CleanupField(td_transferfunction[2]);
diff --git a/libtiff/tif_dir.h b/libtiff/tif_dir.h
index 49e463e..70b68f2 100644
--- a/libtiff/tif_dir.h
+++ b/libtiff/tif_dir.h
@@ -82,6 +82,7 @@ typedef struct {
 	uint16  td_ycbcrpositioning;
 	/* Colorimetry parameters */
 	float*	td_whitepoint;
+	float*	td_refblackwhite;
 	uint16* td_transferfunction[3];
 	/* CMYK parameters */
 	int     td_inknameslen;
@@ -137,6 +138,7 @@ typedef struct {
 #define FIELD_HALFTONEHINTS            37
 #define FIELD_YCBCRSUBSAMPLING         39
 #define FIELD_YCBCRPOSITIONING         40
+#define	FIELD_REFBLACKWHITE            41
 #define FIELD_WHITEPOINT               42
 #define FIELD_TRANSFERFUNCTION         44
 #define FIELD_INKNAMES                 46
diff --git a/libtiff/tif_dirinfo.c b/libtiff/tif_dirinfo.c
index b88fca7..4a927aa 100644
--- a/libtiff/tif_dirinfo.c
+++ b/libtiff/tif_dirinfo.c
@@ -112,7 +112,7 @@ tiffFields[] = {
 	{ TIFFTAG_YCBCRCOEFFICIENTS, 3, 3, TIFF_RATIONAL, 0, TIFF_SETGET_C0_FLOAT,
 	TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 0, "YCbCrCoefficients", NULL },
 	{ TIFFTAG_YCBCRSUBSAMPLING, 2, 2, TIFF_SHORT, 0, TIFF_SETGET_UINT16_PAIR,
 	TIFF_SETGET_UNDEFINED, FIELD_YCBCRSUBSAMPLING, 0, 0, "YCbCrSubsampling",
 	NULL },
 	{ TIFFTAG_YCBCRPOSITIONING, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UINT16,
 	TIFF_SETGET_UNDEFINED, FIELD_YCBCRPOSITIONING, 0, 0, "YCbCrPositioning",
 	NULL },
-	{ TIFFTAG_REFERENCEBLACKWHITE, 6, 6, TIFF_RATIONAL, 0,
TIFF_SETGET_C0_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0,
"ReferenceBlackWhite", NULL },
+	{ TIFFTAG_REFERENCEBLACKWHITE, 6, 6, TIFF_RATIONAL, 0,
TIFF_SETGET_C0_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_REFBLACKWHITE, 1, 0,
"ReferenceBlackWhite", NULL },
 	{ TIFFTAG_XMLPACKET, -3, -3, TIFF_BYTE, 0, TIFF_SETGET_C32_UINT8,
 	TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 1, "XMLPacket", NULL },
 	/* begin SGI tags */
 	{ TIFFTAG_MATTEING, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UINT16,
 	TIFF_SETGET_UNDEFINED, FIELD_EXTRASAMPLES, 0, 0, "Matteing", NULL },
-- 
1.6.5.2