libtiff: Properly handle "DotRange" tag as it can be either byte or short size and

https://github.com/libsdl-org/libtiff/commit/90fc5cf9cfbe525c7b53f8c4080c2f88f8c63266

From 90fc5cf9cfbe525c7b53f8c4080c2f88f8c63266 Mon Sep 17 00:00:00 2001
From: Andrey Kiselev <[EMAIL REDACTED]>
Date: Tue, 6 Jul 2010 14:05:30 +0000
Subject: [PATCH] Properly handle "DotRange" tag as it can be either byte or
 short size and should be set and read by value, not as an array. As per bug
 http://bugzilla.maptools.org/show_bug.cgi?id=2116

---
 ChangeLog              |  7 ++++++
 libtiff/tif_dirwrite.c | 48 ++++++++++++++++++++++++++++++------------
 libtiff/tif_print.c    |  6 +-----
 3 files changed, 43 insertions(+), 18 deletions(-)

diff --git a/ChangeLog b/ChangeLog
index ab365435..762d2c58 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,10 @@
+2010-07-02  Andrey Kiselev  <dron@ak4719.spb.edu>
+
+	* libtiff/{tif_dirwrite.c, tif_print.c}: Properly handle "DotRange"
+	tag as it can be either byte or short size and should be set and read
+	by value, not as an array. As per bug
+	http://bugzilla.maptools.org/show_bug.cgi?id=2116
+
 2010-07-02  Andrey Kiselev  <dron@ak4719.spb.edu>
 
 	* libtiff/tif_getimage.c: Avoid wrong math du to the signed/unsigned
diff --git a/libtiff/tif_dirwrite.c b/libtiff/tif_dirwrite.c
index 8d308c42..a9f2ec79 100644
--- a/libtiff/tif_dirwrite.c
+++ b/libtiff/tif_dirwrite.c
@@ -1,4 +1,4 @@
-/* $Id: tif_dirwrite.c,v 1.37.2.7 2010-06-08 18:50:42 bfriesen Exp $ */
+/* $Id: tif_dirwrite.c,v 1.37.2.8 2010-07-06 14:05:30 dron Exp $ */
 
 /*
  * Copyright (c) 1988-1997 Sam Leffler
@@ -42,6 +42,7 @@ extern	void TIFFCvtNativeToIEEEDouble(TIFF*, uint32, double*);
 static	int TIFFWriteNormalTag(TIFF*, TIFFDirEntry*, const TIFFFieldInfo*);
 static	void TIFFSetupShortLong(TIFF*, ttag_t, TIFFDirEntry*, uint32);
 static	void TIFFSetupShort(TIFF*, ttag_t, TIFFDirEntry*, uint16);
+static	int TIFFSetupBytePair(TIFF*, ttag_t, TIFFDirEntry*);
 static	int TIFFSetupShortPair(TIFF*, ttag_t, TIFFDirEntry*);
 static	int TIFFWritePerSampleShorts(TIFF*, ttag_t, TIFFDirEntry*);
 static	int TIFFWritePerSampleAnys(TIFF*, TIFFDataType, ttag_t, TIFFDirEntry*);
@@ -291,12 +292,6 @@ _TIFFWriteDirectory(TIFF* tif, int done)
 			    _TIFFSampleToTagType(tif), fip->field_tag, dir))
 				goto bad;
 			break;
-		case FIELD_PAGENUMBER:
-		case FIELD_HALFTONEHINTS:
-		case FIELD_YCBCRSUBSAMPLING:
-			if (!TIFFSetupShortPair(tif, fip->field_tag, dir))
-				goto bad;
-			break;
 		case FIELD_INKNAMES:
 			if (!TIFFWriteInkNames(tif, dir))
 				goto bad;
@@ -336,12 +331,22 @@ _TIFFWriteDirectory(TIFF* tif, int done)
 			}
 			break;
 		default:
-			/* XXX: Should be fixed and removed. */
-			if (fip->field_tag == TIFFTAG_DOTRANGE) {
-				if (!TIFFSetupShortPair(tif, fip->field_tag, dir))
-					goto bad;
-			}
-			else if (!TIFFWriteNormalTag(tif, dir, fip))
+			/*
+			 * XXX: Should be fixed and removed. See comments
+			 * related to these tags in tif_dir.c.
+			 */
+			if (fip->field_tag == TIFFTAG_PAGENUMBER
+			    || fip->field_tag == TIFFTAG_HALFTONEHINTS
+			    || fip->field_tag == TIFFTAG_YCBCRSUBSAMPLING
+			    || fip->field_tag == TIFFTAG_DOTRANGE) {
+				if (fip->field_type == TIFF_BYTE) {
+					if (!TIFFSetupBytePair(tif, fip->field_tag, dir))
+						goto bad;
+				} else if (fip->field_type == TIFF_SHORT) {
+					if (!TIFFSetupShortPair(tif, fip->field_tag, dir))
+						goto bad;
+				}
+			} else if (!TIFFWriteNormalTag(tif, dir, fip))
 				goto bad;
 			break;
 		}
@@ -875,6 +880,23 @@ TIFFWritePerSampleAnys(TIFF* tif,
 }
 #undef NITEMS
 
+/*
+ * Setup a pair of bytes that are returned by
+ * value, rather than as a reference to an array.
+ */
+static int
+TIFFSetupBytePair(TIFF* tif, ttag_t tag, TIFFDirEntry* dir)
+{
+	char v[2];
+
+	TIFFGetField(tif, tag, &v[0], &v[1]);
+
+	dir->tdir_tag = (uint16) tag;
+	dir->tdir_type = (uint16) TIFF_BYTE;
+	dir->tdir_count = 2;
+	return (TIFFWriteByteArray(tif, dir, v));
+}
+
 /*
  * Setup a pair of shorts that are returned by
  * value, rather than as a reference to an array.
diff --git a/libtiff/tif_print.c b/libtiff/tif_print.c
index eb4b1e70..7634f6e0 100644
--- a/libtiff/tif_print.c
+++ b/libtiff/tif_print.c
@@ -1,4 +1,4 @@
-/* $Id: tif_print.c,v 1.36.2.4 2010-06-08 18:50:42 bfriesen Exp $ */
+/* $Id: tif_print.c,v 1.36.2.5 2010-07-06 14:05:30 dron Exp $ */
 
 /*
  * Copyright (c) 1988-1997 Sam Leffler
@@ -132,10 +132,6 @@ _TIFFPrettyPrintField(TIFF* tif, FILE* fd, ttag_t tag,
 					break;
 			}
 			return 1;
-		case TIFFTAG_DOTRANGE:
-			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;