libtiff: Finally fix bug http://bugzilla.remotesensing.org/show_bug.cgi?id=1274 by

From ea593c11a76b47ae6020c9849314e93761c18211 Mon Sep 17 00:00:00 2001
From: Andrey Kiselev <[EMAIL REDACTED]>
Date: Sat, 7 Apr 2007 14:58:30 +0000
Subject: [PATCH] Finally fix bug
 http://bugzilla.remotesensing.org/show_bug.cgi?id=1274 by introducing
 _TIFFMergeFieldInfo() returning integer error status instead of void in case
 of problems with field merging (e.g., if the field with such a tag already
 registered). TIFFMergeFieldInfo() in public API remains void. Use
 _TIFFMergeFieldInfo() everywhere and check returned value.

---
 libtiff/tif_dir.h      |   10 +-
 libtiff/tif_dirinfo.c  |  171 +++---
 libtiff/tif_dirread.c  | 1230 +++++++++++++++-------------------------
 libtiff/tif_fax3.c     |   35 +-
 libtiff/tif_jbig.c     |   19 +-
 libtiff/tif_jpeg.c     |   20 +-
 libtiff/tif_luv.c      |   18 +-
 libtiff/tif_ojpeg.c    |   14 +-
 libtiff/tif_pixarlog.c |   18 +-
 libtiff/tif_predict.c  |   17 +-
 libtiff/tif_zip.c      |   19 +-
 11 files changed, 676 insertions(+), 895 deletions(-)

diff --git a/libtiff/tif_dir.h b/libtiff/tif_dir.h
index eaf7855a..87959e31 100644
--- a/libtiff/tif_dir.h
+++ b/libtiff/tif_dir.h
@@ -1,4 +1,4 @@
-/* $Id: tif_dir.h,v 1.31 2007-03-17 04:41:29 joris Exp $ */
+/* $Id: tif_dir.h,v 1.30.2.1 2007-04-07 14:58:30 dron Exp $ */
 
 /*
  * Copyright (c) 1988-1997 Sam Leffler
@@ -156,11 +156,11 @@ typedef	struct {
 #define	FIELD_LAST			(32*FIELD_SETLONGS-1)
 
 #define	TIFFExtractData(tif, type, v) \
-    ((uint32) ((tif)->tif_header.common.tiff_magic == TIFF_BIGENDIAN ? \
-	((v) >> (tif)->tif_typeshift[type]) & (tif)->tif_typemask[type] : \
+    ((uint32) ((tif)->tif_header.tiff_magic == TIFF_BIGENDIAN ? \
+        ((v) >> (tif)->tif_typeshift[type]) & (tif)->tif_typemask[type] : \
 	(v) & (tif)->tif_typemask[type]))
 #define	TIFFInsertData(tif, type, v) \
-    ((uint32) ((tif)->tif_header.common.tiff_magic == TIFF_BIGENDIAN ? \
+    ((uint32) ((tif)->tif_header.tiff_magic == TIFF_BIGENDIAN ? \
         ((v) & (tif)->tif_typemask[type]) << (tif)->tif_typeshift[type] : \
 	(v) & (tif)->tif_typemask[type]))
 
@@ -180,6 +180,7 @@ extern "C" {
 extern	const TIFFFieldInfo *_TIFFGetFieldInfo(size_t *);
 extern	const TIFFFieldInfo *_TIFFGetExifFieldInfo(size_t *);
 extern	void _TIFFSetupFieldInfo(TIFF*, const TIFFFieldInfo[], size_t);
+extern	int _TIFFMergeFieldInfo(TIFF*, const TIFFFieldInfo[], int);
 extern	void _TIFFPrintFieldInfo(TIFF*, FILE*);
 extern	TIFFDataType _TIFFSampleToTagType(TIFF*);
 extern  const TIFFFieldInfo* _TIFFFindOrRegisterFieldInfo( TIFF *tif,
@@ -188,7 +189,6 @@ extern  const TIFFFieldInfo* _TIFFFindOrRegisterFieldInfo( TIFF *tif,
 extern  TIFFFieldInfo* _TIFFCreateAnonFieldInfo( TIFF *tif, ttag_t tag,
                                                  TIFFDataType dt );
 
-#define _TIFFMergeFieldInfo	    TIFFMergeFieldInfo
 #define _TIFFFindFieldInfo	    TIFFFindFieldInfo
 #define _TIFFFindFieldInfoByName    TIFFFindFieldInfoByName
 #define _TIFFFieldWithTag	    TIFFFieldWithTag
diff --git a/libtiff/tif_dirinfo.c b/libtiff/tif_dirinfo.c
index 515e04c0..9c75e4a3 100644
--- a/libtiff/tif_dirinfo.c
+++ b/libtiff/tif_dirinfo.c
@@ -1,4 +1,4 @@
-/* $Id: tif_dirinfo.c,v 1.66 2007-03-17 04:41:29 joris Exp $ */
+/* $Id: tif_dirinfo.c,v 1.65.2.1 2007-04-07 14:58:30 dron Exp $ */
 
 /*
  * Copyright (c) 1988-1997 Sam Leffler
@@ -544,7 +544,11 @@ _TIFFSetupFieldInfo(TIFF* tif, const TIFFFieldInfo info[], size_t n)
 		_TIFFfree(tif->tif_fieldinfo);
 		tif->tif_nfields = 0;
 	}
-	_TIFFMergeFieldInfo(tif, info, n);
+	if (!_TIFFMergeFieldInfo(tif, info, n))
+	{
+		TIFFErrorExt(tif->tif_clientdata, "_TIFFSetupFieldInfo",
+			     "Setting up field info failed");
+	}
 }
 
 static int
@@ -554,9 +558,10 @@ tagCompare(const void* a, const void* b)
 	const TIFFFieldInfo* tb = *(const TIFFFieldInfo**) b;
 	/* NB: be careful of return values for 16-bit platforms */
 	if (ta->field_tag != tb->field_tag)
-		return (ta->field_tag < tb->field_tag ? -1 : 1);
+		return (int)ta->field_tag - (int)tb->field_tag;
 	else
-		return ((int)tb->field_type - (int)ta->field_type);
+		return (ta->field_type == TIFF_ANY) ?
+			0 : ((int)tb->field_type - (int)ta->field_type);
 }
 
 static int
@@ -564,22 +569,49 @@ tagNameCompare(const void* a, const void* b)
 {
 	const TIFFFieldInfo* ta = *(const TIFFFieldInfo**) a;
 	const TIFFFieldInfo* tb = *(const TIFFFieldInfo**) b;
+	int ret = strcmp(ta->field_name, tb->field_name);
 
-        return strcmp(ta->field_name, tb->field_name);
+	if (ret)
+		return ret;
+	else
+		return (ta->field_type == TIFF_ANY) ?
+			0 : ((int)tb->field_type - (int)ta->field_type);
 }
 
 void
+TIFFMergeFieldInfo(TIFF* tif, const TIFFFieldInfo info[], int n)
+{
+	if (_TIFFMergeFieldInfo(tif, info, n) < 0)
+	{
+		TIFFErrorExt(tif->tif_clientdata, "TIFFMergeFieldInfo",
+			     "Merging block of %d fields failed", n);
+	}
+}
+
+int
 _TIFFMergeFieldInfo(TIFF* tif, const TIFFFieldInfo info[], int n)
 {
 	TIFFFieldInfo** tp;
 	int i;
 
+	for (i = 0; i < n; i++) {
+		const TIFFFieldInfo *fip =
+			_TIFFFindFieldInfo(tif, info[i].field_tag, TIFF_ANY);
+		if (fip) {
+			TIFFErrorExt(tif->tif_clientdata, "_TIFFMergeFieldInfo",
+			"Field with tag %lu is already registered as \"%s\"",
+				     (unsigned int) info[i].field_tag,
+				     fip->field_name);
+			return 0;
+		}
+	}
+
         tif->tif_foundfield = NULL;
 
 	if (tif->tif_nfields > 0) {
 		tif->tif_fieldinfo = (TIFFFieldInfo**)
 		    _TIFFrealloc(tif->tif_fieldinfo,
-			(tif->tif_nfields+n) * sizeof (TIFFFieldInfo*));
+			(tif->tif_nfields + n) * sizeof (TIFFFieldInfo*));
 	} else {
 		tif->tif_fieldinfo = (TIFFFieldInfo**)
 		    _TIFFmalloc(n * sizeof (TIFFFieldInfo*));
@@ -592,6 +624,8 @@ _TIFFMergeFieldInfo(TIFF* tif, const TIFFFieldInfo info[], int n)
         /* Sort the field info by tag number */
         qsort(tif->tif_fieldinfo, tif->tif_nfields += n,
 	      sizeof (TIFFFieldInfo*), tagCompare);
+
+	return n;
 }
 
 void
@@ -623,29 +657,26 @@ TIFFDataWidth(TIFFDataType type)
 {
 	switch(type)
 	{
-		case 0:  /* nothing */
-		case TIFF_BYTE:
-		case TIFF_ASCII:
-		case TIFF_SBYTE:
-		case TIFF_UNDEFINED:
-			return 1;
-		case TIFF_SHORT:
-		case TIFF_SSHORT:
-			return 2;
-		case TIFF_LONG:
-		case TIFF_SLONG:
-		case TIFF_FLOAT:
-		case TIFF_IFD:
-			return 4;
-		case TIFF_RATIONAL:
-		case TIFF_SRATIONAL:
-		case TIFF_DOUBLE:
-		case TIFF_LONG8:
-		case TIFF_SLONG8:
-		case TIFF_IFD8:
-			return 8;
-		default:
-			return 0; /* will return 0 for unknown types */
+	case 0:  /* nothing */
+	case 1:  /* TIFF_BYTE */
+	case 2:  /* TIFF_ASCII */
+	case 6:  /* TIFF_SBYTE */
+	case 7:  /* TIFF_UNDEFINED */
+		return 1;
+	case 3:  /* TIFF_SHORT */
+	case 8:  /* TIFF_SSHORT */
+		return 2;
+	case 4:  /* TIFF_LONG */
+	case 9:  /* TIFF_SLONG */
+	case 11: /* TIFF_FLOAT */
+        case 13: /* TIFF_IFD */
+		return 4;
+	case 5:  /* TIFF_RATIONAL */
+	case 10: /* TIFF_SRATIONAL */
+	case 12: /* TIFF_DOUBLE */
+		return 8;
+	default:
+		return 0; /* will return 0 for unknown types */
 	}
 }
 
@@ -659,8 +690,7 @@ TIFFDataWidth(TIFFDataType type)
 int
 _TIFFDataSize(TIFFDataType type)
 {
-	switch (type)
-	{
+	switch (type) {
 		case TIFF_BYTE:
 		case TIFF_SBYTE:
 		case TIFF_ASCII:
@@ -677,9 +707,6 @@ _TIFFDataSize(TIFFDataType type)
 		case TIFF_SRATIONAL:
 		    return 4;
 		case TIFF_DOUBLE:
-		case TIFF_LONG8:
-		case TIFF_SLONG8:
-		case TIFF_IFD8:
 		    return 8;
 		default:
 		    return 0;
@@ -713,67 +740,46 @@ _TIFFSampleToTagType(TIFF* tif)
 const TIFFFieldInfo*
 _TIFFFindFieldInfo(TIFF* tif, ttag_t tag, TIFFDataType dt)
 {
-	int i, n;
-
 	if (tif->tif_foundfield && tif->tif_foundfield->field_tag == tag &&
 	    (dt == TIFF_ANY || dt == tif->tif_foundfield->field_type))
 		return tif->tif_foundfield;
 	/* NB: use sorted search (e.g. binary search) */
-	if(dt != TIFF_ANY) {
-            TIFFFieldInfo key = {0, 0, 0, TIFF_NOTYPE, 0, 0, 0, 0};
-	    TIFFFieldInfo* pkey = &key;
-	    const TIFFFieldInfo **ret;
-
-	    key.field_tag = tag;
-            key.field_type = dt;
-
-	    ret = (const TIFFFieldInfo **) bsearch(&pkey,
-						   tif->tif_fieldinfo, 
-						   tif->tif_nfields,
-						   sizeof(TIFFFieldInfo *), 
-						   tagCompare);
-	    return ret ? *ret : NULL;
-        } else for (i = 0, n = tif->tif_nfields; i < n; i++) {
-		const TIFFFieldInfo* fip = tif->tif_fieldinfo[i];
-		if (fip->field_tag == tag &&
-		    (dt == TIFF_ANY || fip->field_type == dt))
-			return (tif->tif_foundfield = fip);
-	}
-	return (const TIFFFieldInfo *)0;
+        TIFFFieldInfo key = {0, 0, 0, TIFF_NOTYPE, 0, 0, 0, 0};
+	TIFFFieldInfo* pkey = &key;
+	const TIFFFieldInfo **ret;
+
+	key.field_tag = tag;
+        key.field_type = dt;
+
+	ret = (const TIFFFieldInfo **) bsearch(&pkey,
+					       tif->tif_fieldinfo, 
+					       tif->tif_nfields,
+					       sizeof(TIFFFieldInfo *), 
+	    				       tagCompare);
+	return tif->tif_foundfield = (ret ? *ret : NULL);
 }
 
 const TIFFFieldInfo*
 _TIFFFindFieldInfoByName(TIFF* tif, const char *field_name, TIFFDataType dt)
 {
-	int i, n;
-
 	if (tif->tif_foundfield
 	    && streq(tif->tif_foundfield->field_name, field_name)
 	    && (dt == TIFF_ANY || dt == tif->tif_foundfield->field_type))
 		return (tif->tif_foundfield);
 	/* NB: use sorted search (e.g. binary search) */
-	if(dt != TIFF_ANY) {
-            TIFFFieldInfo key = {0, 0, 0, TIFF_NOTYPE, 0, 0, 0, 0};
-	    TIFFFieldInfo* pkey = &key;
-	    const TIFFFieldInfo **ret;
-
-            key.field_name = (char *)field_name;
-            key.field_type = dt;
-
-            ret = (const TIFFFieldInfo **) lfind(&pkey,
-						 tif->tif_fieldinfo, 
-						 &tif->tif_nfields,
-						 sizeof(TIFFFieldInfo *),
-						 tagNameCompare);
-	    return (ret) ? (*ret) : NULL;
-        } else
-		for (i = 0, n = tif->tif_nfields; i < n; i++) {
-			const TIFFFieldInfo* fip = tif->tif_fieldinfo[i];
-			if (streq(fip->field_name, field_name) &&
-			    (dt == TIFF_ANY || fip->field_type == dt))
-				return (tif->tif_foundfield = fip);
-		}
-	return ((const TIFFFieldInfo *)0);
+        TIFFFieldInfo key = {0, 0, 0, TIFF_NOTYPE, 0, 0, 0, 0};
+	TIFFFieldInfo* pkey = &key;
+	const TIFFFieldInfo **ret;
+
+        key.field_name = (char *)field_name;
+        key.field_type = dt;
+
+        ret = (const TIFFFieldInfo **) lfind(&pkey,
+					     tif->tif_fieldinfo, 
+	    				     &tif->tif_nfields,
+	    				     sizeof(TIFFFieldInfo *),
+	    				     tagNameCompare);
+	return tif->tif_foundfield = (ret ? *ret : NULL);
 }
 
 const TIFFFieldInfo*
@@ -814,7 +820,8 @@ _TIFFFindOrRegisterFieldInfo( TIFF *tif, ttag_t tag, TIFFDataType dt )
     if( fld == NULL )
     {
         fld = _TIFFCreateAnonFieldInfo( tif, tag, dt );
-        _TIFFMergeFieldInfo( tif, fld, 1 );
+        if (!_TIFFMergeFieldInfo(tif, fld, 1))
+		return NULL;
     }
 
     return fld;
diff --git a/libtiff/tif_dirread.c b/libtiff/tif_dirread.c
index 3b0a5918..cd1c6907 100644
--- a/libtiff/tif_dirread.c
+++ b/libtiff/tif_dirread.c
@@ -1,26 +1,26 @@
-/* $Id: tif_dirread.c,v 1.95 2007-03-19 12:11:15 joris Exp $ */
+/* $Id: tif_dirread.c,v 1.92.2.1 2007-04-07 14:58:30 dron Exp $ */
 
 /*
  * Copyright (c) 1988-1997 Sam Leffler
  * Copyright (c) 1991-1997 Silicon Graphics, Inc.
  *
- * Permission to use, copy, modify, distribute, and sell this software and
+ * Permission to use, copy, modify, distribute, and sell this software and 
  * its documentation for any purpose is hereby granted without fee, provided
  * that (i) the above copyright notices and this permission notice appear in
  * all copies of the software and related documentation, and (ii) the names of
  * Sam Leffler and Silicon Graphics may not be used in any advertising or
  * publicity relating to the software without the specific, prior written
  * permission of Sam Leffler and Silicon Graphics.
- *
- * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND,
- * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY
- * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
- *
+ * 
+ * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, 
+ * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY 
+ * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.  
+ * 
  * IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR
  * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND,
  * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
- * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF
- * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
+ * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF 
+ * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE 
  * OF THIS SOFTWARE.
  */
 
@@ -37,35 +37,34 @@
 # define	TIFFCvtIEEEFloatToNative(tif, n, fp)
 # define	TIFFCvtIEEEDoubleToNative(tif, n, dp)
 #else
-extern void TIFFCvtIEEEFloatToNative(TIFF*, uint32, float*);
-extern void TIFFCvtIEEEDoubleToNative(TIFF*, uint32, double*);
+extern	void TIFFCvtIEEEFloatToNative(TIFF*, uint32, float*);
+extern	void TIFFCvtIEEEDoubleToNative(TIFF*, uint32, double*);
 #endif
 
-static TIFFDirEntryUnion* TIFFReadDirectoryFind(TIFF* tif, TIFFDirEntryUnion* dir, uint16 dircount, uint16 tagid);
-static int EstimateStripByteCountsClassic(TIFF*, TIFFDirEntryClassic*, uint16);
-static int EstimateStripByteCountsBig(TIFF*, TIFFDirEntryBig*, uint16);
-static void MissingRequired(TIFF*, const char*);
-static int TIFFCheckDirOffset(TIFF* tif, uint64 diroff);
-static int CheckDirCountClassic(TIFF*, TIFFDirEntryClassic*, uint32);
-static int CheckDirCountBig(TIFF*, TIFFDirEntryBig*, uint32);
-static uint16 TIFFFetchDirectory(TIFF* tif, uint64 diroff, TIFFDirEntryUnion** pdir, uint64* nextdiroff);
-static uint32 TIFFFetchData(TIFF*, TIFFDirEntryUnion*, char*);
-static uint32 TIFFFetchString(TIFF*, TIFFDirEntryUnion*, char*);
-static float TIFFFetchRational(TIFF*, TIFFDirEntryUnion*);
-static int TIFFFetchNormalTag(TIFF*, TIFFDirEntryUnion*);
-static int TIFFFetchPerSampleShorts(TIFF*, TIFFDirEntryUnion*, uint16*);
-static int TIFFFetchPerSampleLongs(TIFF*, TIFFDirEntryUnion*, uint32*);
-static int TIFFFetchPerSampleAnys(TIFF*, TIFFDirEntryUnion*, double*);
-static int TIFFFetchShortArray(TIFF*, TIFFDirEntryUnion*, uint16*);
-static int TIFFFetchStripThing(TIFF*, TIFFDirEntryUnion*, long, uint64**);
-static int TIFFFetchRefBlackWhite(TIFF*, TIFFDirEntryUnion*);
-static int TIFFFetchSubjectDistance(TIFF*, TIFFDirEntryUnion*);
-static float TIFFFetchFloat(TIFF*, TIFFDirEntryUnion*);
-static int TIFFFetchFloatArray(TIFF*, TIFFDirEntryUnion*, float*);
-static int TIFFFetchDoubleArray(TIFF*, TIFFDirEntryUnion*, double*);
-static int TIFFFetchAnyArray(TIFF*, TIFFDirEntryUnion*, double*);
-static int TIFFFetchShortPair(TIFF*, TIFFDirEntryUnion*);
-static void ChopUpSingleUncompressedStrip(TIFF*);
+static  TIFFDirEntry* TIFFReadDirectoryFind(TIFFDirEntry* dir,
+					    uint16 dircount, uint16 tagid);
+static	int EstimateStripByteCounts(TIFF*, TIFFDirEntry*, uint16);
+static	void MissingRequired(TIFF*, const char*);
+static	int TIFFCheckDirOffset(TIFF*, toff_t);
+static	int CheckDirCount(TIFF*, TIFFDirEntry*, uint32);
+static	uint16 TIFFFetchDirectory(TIFF*, toff_t, TIFFDirEntry**, toff_t *);
+static	tsize_t TIFFFetchData(TIFF*, TIFFDirEntry*, char*);
+static	tsize_t TIFFFetchString(TIFF*, TIFFDirEntry*, char*);
+static	float TIFFFetchRational(TIFF*, TIFFDirEntry*);
+static	int TIFFFetchNormalTag(TIFF*, TIFFDirEntry*);
+static	int TIFFFetchPerSampleShorts(TIFF*, TIFFDirEntry*, uint16*);
+static	int TIFFFetchPerSampleLongs(TIFF*, TIFFDirEntry*, uint32*);
+static	int TIFFFetchPerSampleAnys(TIFF*, TIFFDirEntry*, double*);
+static	int TIFFFetchShortArray(TIFF*, TIFFDirEntry*, uint16*);
+static	int TIFFFetchStripThing(TIFF*, TIFFDirEntry*, long, uint32**);
+static	int TIFFFetchRefBlackWhite(TIFF*, TIFFDirEntry*);
+static	int TIFFFetchSubjectDistance(TIFF*, TIFFDirEntry*);
+static	float TIFFFetchFloat(TIFF*, TIFFDirEntry*);
+static	int TIFFFetchFloatArray(TIFF*, TIFFDirEntry*, float*);
+static	int TIFFFetchDoubleArray(TIFF*, TIFFDirEntry*, double*);
+static	int TIFFFetchAnyArray(TIFF*, TIFFDirEntry*, double*);
+static	int TIFFFetchShortPair(TIFF*, TIFFDirEntry*);
+static	void ChopUpSingleUncompressedStrip(TIFF*);
 
 /*
  * Read the next TIFF directory from a file and convert it to the internal
@@ -78,7 +77,7 @@ TIFFReadDirectory(TIFF* tif)
 
 	int n;
 	TIFFDirectory* td;
-	TIFFDirEntryUnion *dp, *dir = NULL;
+	TIFFDirEntry *dp, *dir = NULL;
 	uint16 iv;
 	uint32 v;
 	const TIFFFieldInfo* fip;
@@ -126,7 +125,11 @@ TIFFReadDirectory(TIFF* tif)
 	 */
 	TIFFSetField(tif, TIFFTAG_PLANARCONFIG, PLANARCONFIG_CONTIG);
 
-	/* We must process the Compression tag in the first pass
+	/*
+	 * Sigh, we must make a separate pass through the
+	 * directory for the following reason:
+	 *
+	 * We must process the Compression tag in the first pass
 	 * in order to merge in codec-private tag definitions (otherwise
 	 * we may get complaints about unknown tags).  However, the
 	 * Compression tag may be dependent on the SamplesPerPixel
@@ -136,20 +139,24 @@ TIFFReadDirectory(TIFF* tif)
 	 * tag value then we may end up ignoring the Compression tag
 	 * value because it has an incorrect count value (if the
 	 * true value of SamplesPerPixel is not 1).
+	 *
+	 * It sure would have been nice if Aldus had really thought
+	 * this stuff through carefully.
 	 */
-	dp=TIFFReadDirectoryFind(tif,dir,dircount,TIFFTAG_SAMPLESPERPIXEL);
-	if (dp)
-	{
-		if (!TIFFFetchNormalTag(tif,dp))
-			goto bad;
-		dp->common.tdir_tag=IGNORE;
+	for (dp = dir, n = dircount; n > 0; n--, dp++) {
+		if (tif->tif_flags & TIFF_SWAB) {
+			TIFFSwabArrayOfShort(&dp->tdir_tag, 2);
+			TIFFSwabArrayOfLong(&dp->tdir_count, 2);
+		}
+		if (dp->tdir_tag == TIFFTAG_SAMPLESPERPIXEL) {
+			if (!TIFFFetchNormalTag(tif, dp))
+				goto bad;
+			dp->tdir_tag = IGNORE;
+		}
 	}
 	/*
 	 * First real pass over the directory.
 	 */
-
-	dddd
-
 	fix = 0;
 	for (dp = dir, n = dircount; n > 0; n--, dp++) {
 
@@ -164,11 +171,11 @@ TIFFReadDirectory(TIFF* tif)
 		if (dp->tdir_tag < tif->tif_fieldinfo[fix]->field_tag) {
 			if (!diroutoforderwarning) {
 				TIFFWarningExt(tif->tif_clientdata, module,
-				    "%s: invalid TIFF directory; tags are not sorted in ascending order",
-				    tif->tif_name);
+	"%s: invalid TIFF directory; tags are not sorted in ascending order",
+					    tif->tif_name);
 				diroutoforderwarning = 1;
 			}
-			fix = 0;     /* O(n^2) */
+			fix = 0;			/* O(n^2) */
 		}
 		while (fix < tif->tif_nfields &&
 		    tif->tif_fieldinfo[fix]->field_tag < dp->tdir_tag)
@@ -176,37 +183,30 @@ TIFFReadDirectory(TIFF* tif)
 		if (fix >= tif->tif_nfields ||
 		    tif->tif_fieldinfo[fix]->field_tag != dp->tdir_tag) {
 
-			TIFFWarningExt(tif->tif_clientdata,
-			    module,
-			    "%s: unknown field with tag %d (0x%x) encountered",
-			    tif->tif_name,
-			    dp->tdir_tag,
-			    dp->tdir_tag,
-			    dp->tdir_type);
-
-			TIFFMergeFieldInfo(tif,
-			    _TIFFCreateAnonFieldInfo(tif,
-			    dp->tdir_tag,
-			    (TIFFDataType) dp->tdir_type),
-			    1 );
-			/*
-			 * creating anonymous fields prior to
-			 * knowing the compression algorithm
-			 * (ie, when the field info has been
-			 * merged) could cause crashes with
-			 * pathological directories.
-			 */
-			if (compressionknown) {
-				TIFFMergeFieldInfo(tif,
-				    _TIFFCreateAnonFieldInfo(tif,
-				    dp->tdir_tag,
-				    (TIFFDataType) dp->tdir_type),
-				    1);
-			} else
-				goto ignore;
+					TIFFWarningExt(tif->tif_clientdata,
+						       module,
+                        "%s: unknown field with tag %d (0x%x) encountered",
+						       tif->tif_name,
+						       dp->tdir_tag,
+						       dp->tdir_tag,
+						       dp->tdir_type);
+
+					if (!_TIFFMergeFieldInfo(tif,
+						_TIFFCreateAnonFieldInfo(tif,
+						dp->tdir_tag,
+						(TIFFDataType) dp->tdir_type),
+						1))
+					{
+					TIFFErrorExt(tif->tif_clientdata,
+						     module,
+			"Registering anonymous field with tag %d (0x%x) failed",
+						     dp->tdir_tag,
+						     dp->tdir_tag);
+					goto ignore;
+					}
 			fix = 0;
 			while (fix < tif->tif_nfields &&
-			   tif->tif_fieldinfo[fix]->field_tag < dp->tdir_tag)
+			       tif->tif_fieldinfo[fix]->field_tag < dp->tdir_tag)
 				fix++;
 		}
 		/*
@@ -229,9 +229,9 @@ TIFFReadDirectory(TIFF* tif)
 			if (fix >= tif->tif_nfields ||
 			    fip->field_tag != dp->tdir_tag) {
 				TIFFWarningExt(tif->tif_clientdata, module,
-				    "%s: wrong data type %d for \"%s\"; tag ignored",
-				    tif->tif_name, dp->tdir_type,
-				    tif->tif_fieldinfo[fix-1]->field_name);
+			"%s: wrong data type %d for \"%s\"; tag ignored",
+					    tif->tif_name, dp->tdir_type,
+					    tif->tif_fieldinfo[fix-1]->field_name);
 				goto ignore;
 			}
 		}
@@ -742,28 +742,15 @@ TIFFReadDirectory(TIFF* tif)
 	return (0);
 }
 
-static TIFFDirEntryUnion*
-TIFFReadDirectoryFind(TIFF* tif, TIFFDirEntryUnion* dir, uint16 dircount, uint16 tagid)
+static TIFFDirEntry*
+TIFFReadDirectoryFind(TIFFDirEntry* dir, uint16 dircount, uint16 tagid)
 {
-	if (!(tif->tif_flags&TIFF_BIGTIFF))
-	{
-		TIFFDirEntryClassic* m;
-		uint16 n;
-		for (m=dir, n=0; n<dircount; m++, n++)
-		{
-			if (m->tdir_tag==tagid)
-				return((TIFFDirEntryUnion*)m);
-		}
-	}
-	else
+	TIFFDirEntry* m;
+	uint16 n;
+	for (m=dir, n=0; n<dircount; m++, n++)
 	{
-		TIFFDirEntryBig* m;
-		uint16 n;
-		for (m=dir, n=0; n<dircount; m++, n++)
-		{
-			if (m->tdir_tag==tagid)
-				return((TIFFDirEntryUnion*)m);
-		}
+		if (m->tdir_tag==tagid)
+			return(m);
 	}
 	return(0);
 }
@@ -798,6 +785,10 @@ TIFFReadCustomDirectory(TIFF* tif, toff_t diroff,
 
 	fix = 0;
 	for (dp = dir, i = dircount; i > 0; i--, dp++) {
+		if (tif->tif_flags & TIFF_SWAB) {
+			TIFFSwabArrayOfShort(&dp->tdir_tag, 2);
+			TIFFSwabArrayOfLong(&dp->tdir_count, 2);
+		}
 
 		if (fix >= tif->tif_nfields || dp->tdir_tag == IGNORE)
 			continue;
@@ -813,12 +804,17 @@ TIFFReadCustomDirectory(TIFF* tif, toff_t diroff,
                         "%s: unknown field with tag %d (0x%x) encountered",
 				    tif->tif_name, dp->tdir_tag, dp->tdir_tag,
 				    dp->tdir_type);
-
-			TIFFMergeFieldInfo(tif,
-					   _TIFFCreateAnonFieldInfo(tif,
-						dp->tdir_tag,
-						(TIFFDataType)dp->tdir_type),
-					   1);
+			if (!_TIFFMergeFieldInfo(tif,
+						 _TIFFCreateAnonFieldInfo(tif,
+						 dp->tdir_tag,
+						 (TIFFDataType) dp->tdir_type),
+						 1))
+			{
+				TIFFErrorExt(tif->tif_clientdata, module,
+			"Registering anonymous field with tag %d (0x%x) failed",
+					     dp->tdir_tag, dp->tdir_tag);
+				goto ignore;
+			}
 
 			fix = 0;
 			while (fix < tif->tif_nfields &&
@@ -875,7 +871,7 @@ TIFFReadCustomDirectory(TIFF* tif, toff_t diroff,
 				break;
 		}
 	}
-
+	
 	if (dir)
 		_TIFFfree(dir);
 	return 1;
@@ -896,11 +892,11 @@ TIFFReadEXIFDirectory(TIFF* tif, toff_t diroff)
 }
 
 static int
-EstimateStripByteCountsClassic(TIFF* tif, TIFFDirEntryClassic* dir, uint16 dircount)
+EstimateStripByteCounts(TIFF* tif, TIFFDirEntry* dir, uint16 dircount)
 {
-	static const char module[] = "EstimateStripByteCountsClassic";
+	static const char module[] = "EstimateStripByteCounts";
 
-	TIFFDirEntryClassic *dp;
+	TIFFDirEntry *dp;
 	TIFFDirectory *td = &tif->tif_dir;
 	uint32 strip;
 
@@ -910,10 +906,9 @@ EstimateStripByteCountsClassic(TIFF* tif, TIFFDirEntryClassic* dir, uint16 dirco
 	    _TIFFCheckMalloc(tif, td->td_nstrips, sizeof (uint32),
 		"for \"StripByteCounts\" array");
 	if (td->td_compression != COMPRESSION_NONE) {
-		uint32 space = (uint32)(
-		    sizeof(TIFFHeaderClassic)
+		uint32 space = (uint32)(sizeof (TIFFHeader)
 		    + sizeof (uint16)
-		    + (dircount * sizeof (TIFFDirEntryClassic))
+		    + (dircount * sizeof (TIFFDirEntry))
 		    + sizeof (uint32));
 		toff_t filesize = TIFFGetFileSize(tif);
 		uint16 n;
@@ -953,78 +948,7 @@ EstimateStripByteCountsClassic(TIFF* tif, TIFFDirEntryClassic* dir, uint16 dirco
 		uint32 bytespertile = TIFFTileSize(tif);
 
 		for (strip = 0; strip < td->td_nstrips; strip++)
-		    td->td_stripbytecount[strip] = bytespertile;
-	} else {
-		uint32 rowbytes = TIFFScanlineSize(tif);
-		uint32 rowsperstrip = td->td_imagelength/td->td_stripsperimage;
-		for (strip = 0; strip < td->td_nstrips; strip++)
-			td->td_stripbytecount[strip] = rowbytes * rowsperstrip;
-	}
-	TIFFSetFieldBit(tif, FIELD_STRIPBYTECOUNTS);
-	if (!TIFFFieldSet(tif, FIELD_ROWSPERSTRIP))
-		td->td_rowsperstrip = td->td_imagelength;
-	return 1;
-}
-
-static int
-EstimateStripByteCountsBig(TIFF* tif, TIFFDirEntryBig* dir, uint16 dircount)
-{
-	static const char module[] = "EstimateStripByteCountsBig";
-
-	TIFFDirEntryBig *dp;
-	TIFFDirectory *td = &tif->tif_dir;
-	uint32 strip;
-
-	if (td->td_stripbytecount)
-		_TIFFfree(td->td_stripbytecount);
-	td->td_stripbytecount = (uint32*)
-	    _TIFFCheckMalloc(tif, td->td_nstrips, sizeof (uint32),
-		"for \"StripByteCounts\" array");
-	if (td->td_compression != COMPRESSION_NONE) {
-		uint32 space = (uint32)(
-		    sizeof(TIFFHeaderBig)
-		    + sizeof (uint64)
-		    + (dircount * sizeof (TIFFDirEntryBig))
-		    + sizeof (uint64));
-		toff_t filesize = TIFFGetFileSize(tif);
-		uint16 n;
-
-		/* calculate amount of space used by indirect values */
-		for (dp = dir, n = dircount; n > 0; n--, dp++)
-		{
-			uint32 cc = TIFFDataWidth((TIFFDataType) dp->tdir_type);
-			if (cc == 0) {
-				TIFFErrorExt(tif->tif_clientdata, module,
-				    "%s: Cannot determine size of unknown tag type %d",
-				    tif->tif_name, dp->tdir_type);
-				return -1;
-			}
-			cc = cc * dp->tdir_count;
-			if (cc > sizeof (uint64))
-				space += cc;
-		}
-		space = filesize - space;
-		if (td->td_planarconfig == PLANARCONFIG_SEPARATE)
-			space /= td->td_samplesperpixel;
-		for (strip = 0; strip < td->td_nstrips; strip++)
-			td->td_stripbytecount[strip] = space;
-		/*
-		 * This gross hack handles the case were the offset to
-		 * the last strip is past the place where we think the strip
-		 * should begin.  Since a strip of data must be contiguous,
-		 * it's safe to assume that we've overestimated the amount
-		 * of data in the strip and trim this number back accordingly.
-		 */
-		strip--;
-		if (((toff_t)(td->td_stripoffset[strip]+
-			      td->td_stripbytecount[strip])) > filesize)
-			td->td_stripbytecount[strip] =
-			    filesize - td->td_stripoffset[strip];
-	} else if (isTiled(tif)) {
-		uint32 bytespertile = TIFFTileSize(tif);
-
-		for (strip = 0; strip < td->td_nstrips; strip++)
-		    td->td_stripbytecount[strip] = bytespertile;
+                    td->td_stripbytecount[strip] = bytespertile;
 	} else {
 		uint32 rowbytes = TIFFScanlineSize(tif);
 		uint32 rowsperstrip = td->td_imagelength/td->td_stripsperimage;
@@ -1054,7 +978,7 @@ MissingRequired(TIFF* tif, const char* tagname)
  * seen directories and check every IFD offset against that list.
  */
 static int
-TIFFCheckDirOffset(TIFF* tif, uint64 diroff)
+TIFFCheckDirOffset(TIFF* tif, toff_t diroff)
 {
 	uint16 n;
 
@@ -1069,16 +993,16 @@ TIFFCheckDirOffset(TIFF* tif, uint64 diroff)
 	tif->tif_dirnumber++;
 
 	if (tif->tif_dirnumber > tif->tif_dirlistsize) {
-		uint64* new_dirlist;
+		toff_t* new_dirlist;
 
 		/*
 		 * XXX: Reduce memory allocation granularity of the dirlist
 		 * array.
 		 */
-		new_dirlist = (uint64*)_TIFFCheckRealloc(tif,
+		new_dirlist = (toff_t *)_TIFFCheckRealloc(tif,
 							  tif->tif_dirlist,
 							  tif->tif_dirnumber,
-							  2 * sizeof(uint64),
+							  2 * sizeof(toff_t),
 							  "for IFD list");
 		if (!new_dirlist)
 			return 0;
@@ -1096,35 +1020,17 @@ TIFFCheckDirOffset(TIFF* tif, uint64 diroff)
  * caller is expected to skip/ignore the tag if there is a mismatch.
  */
 static int
-CheckDirCountClassic(TIFF* tif, TIFFDirEntryClassic* dir, uint32 count)
-{
-	if (count > dir->tdir_count) {
-		TIFFWarningExt(tif->tif_clientdata, tif->tif_name,
-		    "incorrect count for field \"%s\" (%lu, expecting %lu); tag ignored",
-		    _TIFFFieldWithTag(tif, dir->tdir_tag)->field_name,
-		    dir->tdir_count, count);
-		return (0);
-	} else if (count < dir->tdir_count) {
-		TIFFWarningExt(tif->tif_clientdata, tif->tif_name,
-		    "incorrect count for field \"%s\" (%lu, expecting %lu); tag trimmed",
-		    _TIFFFieldWithTag(tif, dir->tdir_tag)->field_name,
-		    dir->tdir_count, count);
-		return (1);
-	}
-	return (1);
-}
-static int
-CheckDirCountBig(TIFF* tif, TIFFDirEntryBig* dir, uint32 count)
+CheckDirCount(TIFF* tif, TIFFDirEntry* dir, uint32 count)
 {
 	if (count > dir->tdir_count) {
 		TIFFWarningExt(tif->tif_clientdata, tif->tif_name,
-		    "incorrect count for field \"%s\" (%lu, expecting %lu); tag ignored",
+	"incorrect count for field \"%s\" (%lu, expecting %lu); tag ignored",
 		    _TIFFFieldWithTag(tif, dir->tdir_tag)->field_name,
 		    dir->tdir_count, count);
 		return (0);
 	} else if (count < dir->tdir_count) {
 		TIFFWarningExt(tif->tif_clientdata, tif->tif_name,
-		    "incorrect count for field \"%s\" (%lu, expecting %lu); tag trimmed",
+	"incorrect count for field \"%s\" (%lu, expecting %lu); tag trimmed",
 		    _TIFFFieldWithTag(tif, dir->tdir_tag)->field_name,
 		    dir->tdir_count, count);
 		return (1);
@@ -1138,15 +1044,13 @@ CheckDirCountBig(TIFF* tif, TIFFDirEntryBig* dir, uint32 count)
  * number of fields in the directory or 0 if failed.
  */
 static uint16
-TIFFFetchDirectory(TIFF* tif, uint64 diroff, TIFFDirEntryUnion** pdir,
-    uint64 *nextdiroff)
+TIFFFetchDirectory(TIFF* tif, toff_t diroff, TIFFDirEntry **pdir,
+		   toff_t *nextdiroff)
 {
-	static const char module[] = "TIFFFetchDirectoryClassic";
+	static const char module[] = "TIFFFetchDirectory";
 
-	TIFFDirEntryUnion *dir;
-	uint64 dircount64;
-	uint16 dircount16;
-	uint32 dirsize;
+	TIFFDirEntry *dir;
+	uint16 dircount;
 
 	assert(pdir);
 
@@ -1160,46 +1064,20 @@ TIFFFetchDirectory(TIFF* tif, uint64 diroff, TIFFDirEntryUnion** pdir,
 				tif->tif_name);
 			return 0;
 		}
-		if (!(tif->tif_flags&TIFF_BIGTIFF))
-		{
-			if (!ReadOK(tif, &dircount16, sizeof (uint16))) {
-				TIFFErrorExt(tif->tif_clientdata, module,
-				    "%s: Can not read TIFF directory count",
-				    tif->tif_name);
-				return 0;
-			}
-			if (tif->tif_flags & TIFF_SWAB)
-				TIFFSwabShort(&dircount);
-			if (dircount16>4096)
-			{
-				TIFFErrorExt(tif->tif_clientdata, module,
-				    "Sanity check on directory count failed, this is probably not a valid IFD offset");
-				return 0;
-			}
-			dirsize = sizeof(TIFFDirEntryClassic);
-		} else {
-			if (!ReadOK(tif, &dircount64, sizeof (uint64))) {
-				TIFFErrorExt(tif->tif_clientdata, module,
-					"%s: Can not read TIFF directory count",
-					tif->tif_name);
-				return 0;
-			}
-			if (tif->tif_flags & TIFF_SWAB)
-				TIFFSwabLong8(&dircount64);
-			if (dircount64>4096)
-			{
-				TIFFErrorExt(tif->tif_clientdata, module,
-				    "Sanity check on directory count failed, this is probably not a valid IFD offset");
-				return 0;
-			}
-			dircount16 = (uint16)dircount64;
-			dirsize = sizeof(TIFFDirEntryBig);
+		if (!ReadOK(tif, &dircount, sizeof (uint16))) {
+			TIFFErrorExt(tif->tif_clientdata, module,
+				"%s: Can not read TIFF directory count",
+				tif->tif_name);
+			return 0;
 		}
-		dir = (TIFFDirEntryUnion *)_TIFFCheckMalloc(tif, dircount,
-		    dirsize, "to read TIFF directory");
+		if (tif->tif_flags & TIFF_SWAB)
+			TIFFSwabShort(&dircount);
+		dir = (TIFFDirEntry *)_TIFFCheckMalloc(tif, dircount,
+						sizeof (TIFFDirEntry),
+						"to read TIFF directory");
 		if (dir == NULL)
 			return 0;
-		if (!ReadOK(tif, dir, dircount*dirsize)) {
+		if (!ReadOK(tif, dir, dircount*sizeof (TIFFDirEntry))) {
 			TIFFErrorExt(tif->t

(Patch may be truncated, please check the link at the top of this post.)