libtiff: * libtiff/tif_dir.h: Restore ReferenceBlackWhite as a non-custom

https://github.com/libsdl-org/libtiff/commit/a92ac0b6cb98cc233001e7170d6f5c81bca7b541

From a92ac0b6cb98cc233001e7170d6f5c81bca7b541 Mon Sep 17 00:00:00 2001
From: Bob Friesenhahn <[EMAIL REDACTED]>
Date: Wed, 9 Jun 2010 21:15:27 +0000
Subject: [PATCH] * libtiff/tif_dir.h: Restore ReferenceBlackWhite as a
 non-custom field.  This avoids a multi-thread reentrancy problem as well as
 fixing output of wrong tag value due to redundant definitions for the same
 tag in the tiffFieldInfo[] array.  Resolves
 http://bugzilla.maptools.org/show_bug.cgi?id=2185

---
 ChangeLog             |  6 +++++
 libtiff/tif_aux.c     | 62 ++++++++++++++++++++++++-------------------
 libtiff/tif_dir.c     | 10 ++++++-
 libtiff/tif_dir.h     |  4 ++-
 libtiff/tif_dirinfo.c |  6 ++---
 5 files changed, 55 insertions(+), 33 deletions(-)

diff --git a/ChangeLog b/ChangeLog
index d15478e3..5342c7bf 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,11 @@
 2010-06-09  Bob Friesenhahn  <bfriesen@simple.dallas.tx.us>
 
+	* libtiff/tif_dir.h: Restore ReferenceBlackWhite as a non-custom
+	field.  This avoids a multi-thread reentrancy problem as well as
+	fixing output of wrong tag value due to redundant definitions for
+	the same tag in the tiffFieldInfo[] array.  Resolves
+	http://bugzilla.maptools.org/show_bug.cgi?id=2185
+
 	* libtiff/tif_fax3.c (Fax3SetupState): Yesterday's fix for
 	CVE-2010-1411 was not complete.
 
diff --git a/libtiff/tif_aux.c b/libtiff/tif_aux.c
index 53d4a6cf..272f0d9b 100644
--- a/libtiff/tif_aux.c
+++ b/libtiff/tif_aux.c
@@ -1,4 +1,4 @@
-/* $Id: tif_aux.c,v 1.20.2.2 2010-06-08 19:13:03 bfriesen Exp $ */
+/* $Id: tif_aux.c,v 1.20.2.3 2010-06-09 21:15:27 bfriesen Exp $ */
 
 /*
  * Copyright (c) 1991-1997 Sam Leffler
@@ -102,6 +102,35 @@ TIFFDefaultTransferFunction(TIFFDirectory* td)
 	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.
@@ -227,33 +256,10 @@ TIFFVGetFieldDefaulted(TIFF* tif, ttag_t 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 373dde77..ac44b381 100644
--- a/libtiff/tif_dir.c
+++ b/libtiff/tif_dir.c
@@ -1,4 +1,4 @@
-/* $Id: tif_dir.c,v 1.75.2.4 2010-06-08 18:50:41 bfriesen Exp $ */
+/* $Id: tif_dir.c,v 1.75.2.5 2010-06-09 21:15:27 bfriesen Exp $ */
 
 /*
  * Copyright (c) 1988-1997 Sam Leffler
@@ -377,6 +377,10 @@ _TIFFVSetField(TIFF* tif, ttag_t 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 = va_arg(ap, uint32);
 		s = va_arg(ap, char*);
@@ -815,6 +819,9 @@ _TIFFVGetField(TIFF* tif, ttag_t 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;
@@ -989,6 +996,7 @@ TIFFFreeDirectory(TIFF* tif)
 	CleanupField(td_sampleinfo);
 	CleanupField(td_subifd);
 	CleanupField(td_inknames);
+	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 3b1cc33d..515af199 100644
--- a/libtiff/tif_dir.h
+++ b/libtiff/tif_dir.h
@@ -1,4 +1,4 @@
-/* $Id: tif_dir.h,v 1.30.2.2 2010-06-08 18:50:41 bfriesen Exp $ */
+/* $Id: tif_dir.h,v 1.30.2.3 2010-06-09 21:15:27 bfriesen Exp $ */
 
 /*
  * Copyright (c) 1988-1997 Sam Leffler
@@ -75,6 +75,7 @@ typedef	struct {
 	uint16  td_ycbcrsubsampling[2];
 	uint16  td_ycbcrpositioning;
 	/* Colorimetry parameters */
+	float*	td_refblackwhite;
 	uint16* td_transferfunction[3];
 	/* CMYK parameters */
 	int     td_inknameslen;
@@ -133,6 +134,7 @@ typedef	struct {
 #define	FIELD_HALFTONEHINTS		37
 #define FIELD_YCBCRSUBSAMPLING		39
 #define FIELD_YCBCRPOSITIONING		40
+#define	FIELD_REFBLACKWHITE		41
 #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 9a19136e..0a77c971 100644
--- a/libtiff/tif_dirinfo.c
+++ b/libtiff/tif_dirinfo.c
@@ -1,4 +1,4 @@
-/* $Id: tif_dirinfo.c,v 1.65.2.8 2010-06-08 18:50:42 bfriesen Exp $ */
+/* $Id: tif_dirinfo.c,v 1.65.2.9 2010-06-09 21:15:27 bfriesen Exp $ */
 
 /*
  * Copyright (c) 1988-1997 Sam Leffler
@@ -217,10 +217,10 @@ tiffFieldInfo[] = {
       0,	0,	"YCbCrSubsampling" },
     { TIFFTAG_YCBCRPOSITIONING,	 1, 1,	TIFF_SHORT,	FIELD_YCBCRPOSITIONING,
       0,	0,	"YCbCrPositioning" },
-    { TIFFTAG_REFERENCEBLACKWHITE, 6, 6, TIFF_RATIONAL,	FIELD_CUSTOM,
+    { TIFFTAG_REFERENCEBLACKWHITE, 6, 6, TIFF_RATIONAL,	FIELD_REFBLACKWHITE,
       1,	0,	"ReferenceBlackWhite" },
 /* XXX temporarily accept LONG for backwards compatibility */
-    { TIFFTAG_REFERENCEBLACKWHITE, 6, 6, TIFF_LONG,	FIELD_CUSTOM,
+    { TIFFTAG_REFERENCEBLACKWHITE, 6, 6, TIFF_LONG,	FIELD_REFBLACKWHITE,
       1,	0,	"ReferenceBlackWhite" },
     { TIFFTAG_XMLPACKET,	-3,-3,	TIFF_BYTE,	FIELD_CUSTOM,
       0,	1,	"XMLPacket" },