| /* | 
 |  * Copyright (c) 1988-1997 Sam Leffler | 
 |  * Copyright (c) 1991-1997 Silicon Graphics, Inc. | 
 |  * | 
 |  * 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. | 
 |  * | 
 |  * 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 | 
 |  * OF THIS SOFTWARE. | 
 |  */ | 
 |  | 
 | /* | 
 |  * TIFF Library. | 
 |  * | 
 |  * Directory Read Support Routines. | 
 |  */ | 
 |  | 
 | /* Suggested pending improvements: | 
 |  * - add a field 'field_info' to the TIFFDirEntry structure, and set that with | 
 |  *   the pointer to the appropriate TIFFField structure early on in | 
 |  *   TIFFReadDirectory, so as to eliminate current possibly repetitive lookup. | 
 |  */ | 
 |  | 
 | #include "tiffconf.h" | 
 | #include "tiffiop.h" | 
 | #include <float.h> | 
 | #include <limits.h> | 
 | #include <stdlib.h> | 
 | #include <string.h> | 
 |  | 
 | #define FAILED_FII ((uint32_t)-1) | 
 |  | 
 | #ifdef HAVE_IEEEFP | 
 | #define TIFFCvtIEEEFloatToNative(tif, n, fp) | 
 | #define TIFFCvtIEEEDoubleToNative(tif, n, dp) | 
 | #else | 
 | extern void TIFFCvtIEEEFloatToNative(TIFF *, uint32_t, float *); | 
 | extern void TIFFCvtIEEEDoubleToNative(TIFF *, uint32_t, double *); | 
 | #endif | 
 |  | 
 | enum TIFFReadDirEntryErr | 
 | { | 
 |     TIFFReadDirEntryErrOk = 0, | 
 |     TIFFReadDirEntryErrCount = 1, | 
 |     TIFFReadDirEntryErrType = 2, | 
 |     TIFFReadDirEntryErrIo = 3, | 
 |     TIFFReadDirEntryErrRange = 4, | 
 |     TIFFReadDirEntryErrPsdif = 5, | 
 |     TIFFReadDirEntryErrSizesan = 6, | 
 |     TIFFReadDirEntryErrAlloc = 7, | 
 | }; | 
 |  | 
 | static enum TIFFReadDirEntryErr | 
 | TIFFReadDirEntryByte(TIFF *tif, TIFFDirEntry *direntry, uint8_t *value); | 
 | static enum TIFFReadDirEntryErr | 
 | TIFFReadDirEntrySbyte(TIFF *tif, TIFFDirEntry *direntry, int8_t *value); | 
 | static enum TIFFReadDirEntryErr | 
 | TIFFReadDirEntryShort(TIFF *tif, TIFFDirEntry *direntry, uint16_t *value); | 
 | static enum TIFFReadDirEntryErr | 
 | TIFFReadDirEntrySshort(TIFF *tif, TIFFDirEntry *direntry, int16_t *value); | 
 | static enum TIFFReadDirEntryErr | 
 | TIFFReadDirEntryLong(TIFF *tif, TIFFDirEntry *direntry, uint32_t *value); | 
 | static enum TIFFReadDirEntryErr | 
 | TIFFReadDirEntrySlong(TIFF *tif, TIFFDirEntry *direntry, int32_t *value); | 
 | static enum TIFFReadDirEntryErr | 
 | TIFFReadDirEntryLong8(TIFF *tif, TIFFDirEntry *direntry, uint64_t *value); | 
 | static enum TIFFReadDirEntryErr | 
 | TIFFReadDirEntrySlong8(TIFF *tif, TIFFDirEntry *direntry, int64_t *value); | 
 | static enum TIFFReadDirEntryErr | 
 | TIFFReadDirEntryFloat(TIFF *tif, TIFFDirEntry *direntry, float *value); | 
 | static enum TIFFReadDirEntryErr | 
 | TIFFReadDirEntryDouble(TIFF *tif, TIFFDirEntry *direntry, double *value); | 
 | static enum TIFFReadDirEntryErr | 
 | TIFFReadDirEntryIfd8(TIFF *tif, TIFFDirEntry *direntry, uint64_t *value); | 
 |  | 
 | static enum TIFFReadDirEntryErr | 
 | TIFFReadDirEntryArray(TIFF *tif, TIFFDirEntry *direntry, uint32_t *count, | 
 |                       uint32_t desttypesize, void **value); | 
 | static enum TIFFReadDirEntryErr | 
 | TIFFReadDirEntryByteArray(TIFF *tif, TIFFDirEntry *direntry, uint8_t **value); | 
 | static enum TIFFReadDirEntryErr | 
 | TIFFReadDirEntrySbyteArray(TIFF *tif, TIFFDirEntry *direntry, int8_t **value); | 
 | static enum TIFFReadDirEntryErr | 
 | TIFFReadDirEntryShortArray(TIFF *tif, TIFFDirEntry *direntry, uint16_t **value); | 
 | static enum TIFFReadDirEntryErr | 
 | TIFFReadDirEntrySshortArray(TIFF *tif, TIFFDirEntry *direntry, int16_t **value); | 
 | static enum TIFFReadDirEntryErr | 
 | TIFFReadDirEntryLongArray(TIFF *tif, TIFFDirEntry *direntry, uint32_t **value); | 
 | static enum TIFFReadDirEntryErr | 
 | TIFFReadDirEntrySlongArray(TIFF *tif, TIFFDirEntry *direntry, int32_t **value); | 
 | static enum TIFFReadDirEntryErr | 
 | TIFFReadDirEntryLong8Array(TIFF *tif, TIFFDirEntry *direntry, uint64_t **value); | 
 | static enum TIFFReadDirEntryErr | 
 | TIFFReadDirEntrySlong8Array(TIFF *tif, TIFFDirEntry *direntry, int64_t **value); | 
 | static enum TIFFReadDirEntryErr | 
 | TIFFReadDirEntryFloatArray(TIFF *tif, TIFFDirEntry *direntry, float **value); | 
 | static enum TIFFReadDirEntryErr | 
 | TIFFReadDirEntryDoubleArray(TIFF *tif, TIFFDirEntry *direntry, double **value); | 
 | static enum TIFFReadDirEntryErr | 
 | TIFFReadDirEntryIfd8Array(TIFF *tif, TIFFDirEntry *direntry, uint64_t **value); | 
 |  | 
 | static enum TIFFReadDirEntryErr | 
 | TIFFReadDirEntryPersampleShort(TIFF *tif, TIFFDirEntry *direntry, | 
 |                                uint16_t *value); | 
 |  | 
 | static void TIFFReadDirEntryCheckedByte(TIFF *tif, TIFFDirEntry *direntry, | 
 |                                         uint8_t *value); | 
 | static void TIFFReadDirEntryCheckedSbyte(TIFF *tif, TIFFDirEntry *direntry, | 
 |                                          int8_t *value); | 
 | static void TIFFReadDirEntryCheckedShort(TIFF *tif, TIFFDirEntry *direntry, | 
 |                                          uint16_t *value); | 
 | static void TIFFReadDirEntryCheckedSshort(TIFF *tif, TIFFDirEntry *direntry, | 
 |                                           int16_t *value); | 
 | static void TIFFReadDirEntryCheckedLong(TIFF *tif, TIFFDirEntry *direntry, | 
 |                                         uint32_t *value); | 
 | static void TIFFReadDirEntryCheckedSlong(TIFF *tif, TIFFDirEntry *direntry, | 
 |                                          int32_t *value); | 
 | static enum TIFFReadDirEntryErr | 
 | TIFFReadDirEntryCheckedLong8(TIFF *tif, TIFFDirEntry *direntry, | 
 |                              uint64_t *value); | 
 | static enum TIFFReadDirEntryErr | 
 | TIFFReadDirEntryCheckedSlong8(TIFF *tif, TIFFDirEntry *direntry, | 
 |                               int64_t *value); | 
 | static enum TIFFReadDirEntryErr | 
 | TIFFReadDirEntryCheckedRational(TIFF *tif, TIFFDirEntry *direntry, | 
 |                                 double *value); | 
 | static enum TIFFReadDirEntryErr | 
 | TIFFReadDirEntryCheckedSrational(TIFF *tif, TIFFDirEntry *direntry, | 
 |                                  double *value); | 
 | static void TIFFReadDirEntryCheckedFloat(TIFF *tif, TIFFDirEntry *direntry, | 
 |                                          float *value); | 
 | static enum TIFFReadDirEntryErr | 
 | TIFFReadDirEntryCheckedDouble(TIFF *tif, TIFFDirEntry *direntry, double *value); | 
 | #if 0 | 
 | static enum TIFFReadDirEntryErr | 
 | TIFFReadDirEntryCheckedRationalDirect(TIFF *tif, TIFFDirEntry *direntry, | 
 |                                       TIFFRational_t *value); | 
 | #endif | 
 | static enum TIFFReadDirEntryErr | 
 | TIFFReadDirEntryCheckRangeByteSbyte(int8_t value); | 
 | static enum TIFFReadDirEntryErr | 
 | TIFFReadDirEntryCheckRangeByteShort(uint16_t value); | 
 | static enum TIFFReadDirEntryErr | 
 | TIFFReadDirEntryCheckRangeByteSshort(int16_t value); | 
 | static enum TIFFReadDirEntryErr | 
 | TIFFReadDirEntryCheckRangeByteLong(uint32_t value); | 
 | static enum TIFFReadDirEntryErr | 
 | TIFFReadDirEntryCheckRangeByteSlong(int32_t value); | 
 | static enum TIFFReadDirEntryErr | 
 | TIFFReadDirEntryCheckRangeByteLong8(uint64_t value); | 
 | static enum TIFFReadDirEntryErr | 
 | TIFFReadDirEntryCheckRangeByteSlong8(int64_t value); | 
 |  | 
 | static enum TIFFReadDirEntryErr | 
 | TIFFReadDirEntryCheckRangeSbyteByte(uint8_t value); | 
 | static enum TIFFReadDirEntryErr | 
 | TIFFReadDirEntryCheckRangeSbyteShort(uint16_t value); | 
 | static enum TIFFReadDirEntryErr | 
 | TIFFReadDirEntryCheckRangeSbyteSshort(int16_t value); | 
 | static enum TIFFReadDirEntryErr | 
 | TIFFReadDirEntryCheckRangeSbyteLong(uint32_t value); | 
 | static enum TIFFReadDirEntryErr | 
 | TIFFReadDirEntryCheckRangeSbyteSlong(int32_t value); | 
 | static enum TIFFReadDirEntryErr | 
 | TIFFReadDirEntryCheckRangeSbyteLong8(uint64_t value); | 
 | static enum TIFFReadDirEntryErr | 
 | TIFFReadDirEntryCheckRangeSbyteSlong8(int64_t value); | 
 |  | 
 | static enum TIFFReadDirEntryErr | 
 | TIFFReadDirEntryCheckRangeShortSbyte(int8_t value); | 
 | static enum TIFFReadDirEntryErr | 
 | TIFFReadDirEntryCheckRangeShortSshort(int16_t value); | 
 | static enum TIFFReadDirEntryErr | 
 | TIFFReadDirEntryCheckRangeShortLong(uint32_t value); | 
 | static enum TIFFReadDirEntryErr | 
 | TIFFReadDirEntryCheckRangeShortSlong(int32_t value); | 
 | static enum TIFFReadDirEntryErr | 
 | TIFFReadDirEntryCheckRangeShortLong8(uint64_t value); | 
 | static enum TIFFReadDirEntryErr | 
 | TIFFReadDirEntryCheckRangeShortSlong8(int64_t value); | 
 |  | 
 | static enum TIFFReadDirEntryErr | 
 | TIFFReadDirEntryCheckRangeSshortShort(uint16_t value); | 
 | static enum TIFFReadDirEntryErr | 
 | TIFFReadDirEntryCheckRangeSshortLong(uint32_t value); | 
 | static enum TIFFReadDirEntryErr | 
 | TIFFReadDirEntryCheckRangeSshortSlong(int32_t value); | 
 | static enum TIFFReadDirEntryErr | 
 | TIFFReadDirEntryCheckRangeSshortLong8(uint64_t value); | 
 | static enum TIFFReadDirEntryErr | 
 | TIFFReadDirEntryCheckRangeSshortSlong8(int64_t value); | 
 |  | 
 | static enum TIFFReadDirEntryErr | 
 | TIFFReadDirEntryCheckRangeLongSbyte(int8_t value); | 
 | static enum TIFFReadDirEntryErr | 
 | TIFFReadDirEntryCheckRangeLongSshort(int16_t value); | 
 | static enum TIFFReadDirEntryErr | 
 | TIFFReadDirEntryCheckRangeLongSlong(int32_t value); | 
 | static enum TIFFReadDirEntryErr | 
 | TIFFReadDirEntryCheckRangeLongLong8(uint64_t value); | 
 | static enum TIFFReadDirEntryErr | 
 | TIFFReadDirEntryCheckRangeLongSlong8(int64_t value); | 
 |  | 
 | static enum TIFFReadDirEntryErr | 
 | TIFFReadDirEntryCheckRangeSlongLong(uint32_t value); | 
 | static enum TIFFReadDirEntryErr | 
 | TIFFReadDirEntryCheckRangeSlongLong8(uint64_t value); | 
 | static enum TIFFReadDirEntryErr | 
 | TIFFReadDirEntryCheckRangeSlongSlong8(int64_t value); | 
 |  | 
 | static enum TIFFReadDirEntryErr | 
 | TIFFReadDirEntryCheckRangeLong8Sbyte(int8_t value); | 
 | static enum TIFFReadDirEntryErr | 
 | TIFFReadDirEntryCheckRangeLong8Sshort(int16_t value); | 
 | static enum TIFFReadDirEntryErr | 
 | TIFFReadDirEntryCheckRangeLong8Slong(int32_t value); | 
 | static enum TIFFReadDirEntryErr | 
 | TIFFReadDirEntryCheckRangeLong8Slong8(int64_t value); | 
 |  | 
 | static enum TIFFReadDirEntryErr | 
 | TIFFReadDirEntryCheckRangeSlong8Long8(uint64_t value); | 
 |  | 
 | static enum TIFFReadDirEntryErr TIFFReadDirEntryData(TIFF *tif, uint64_t offset, | 
 |                                                      tmsize_t size, void *dest); | 
 | static void TIFFReadDirEntryOutputErr(TIFF *tif, enum TIFFReadDirEntryErr err, | 
 |                                       const char *module, const char *tagname, | 
 |                                       int recover); | 
 |  | 
 | static void TIFFReadDirectoryCheckOrder(TIFF *tif, TIFFDirEntry *dir, | 
 |                                         uint16_t dircount); | 
 | static TIFFDirEntry *TIFFReadDirectoryFindEntry(TIFF *tif, TIFFDirEntry *dir, | 
 |                                                 uint16_t dircount, | 
 |                                                 uint16_t tagid); | 
 | static void TIFFReadDirectoryFindFieldInfo(TIFF *tif, uint16_t tagid, | 
 |                                            uint32_t *fii); | 
 |  | 
 | static int EstimateStripByteCounts(TIFF *tif, TIFFDirEntry *dir, | 
 |                                    uint16_t dircount); | 
 | static void MissingRequired(TIFF *, const char *); | 
 | static int CheckDirCount(TIFF *, TIFFDirEntry *, uint32_t); | 
 | static uint16_t TIFFFetchDirectory(TIFF *tif, uint64_t diroff, | 
 |                                    TIFFDirEntry **pdir, uint64_t *nextdiroff); | 
 | static int TIFFFetchNormalTag(TIFF *, TIFFDirEntry *, int recover); | 
 | static int TIFFFetchStripThing(TIFF *tif, TIFFDirEntry *dir, uint32_t nstrips, | 
 |                                uint64_t **lpp); | 
 | static int TIFFFetchSubjectDistance(TIFF *, TIFFDirEntry *); | 
 | static void ChopUpSingleUncompressedStrip(TIFF *); | 
 | static void TryChopUpUncompressedBigTiff(TIFF *); | 
 | static uint64_t TIFFReadUInt64(const uint8_t *value); | 
 | static int _TIFFGetMaxColorChannels(uint16_t photometric); | 
 |  | 
 | static int _TIFFFillStrilesInternal(TIFF *tif, int loadStripByteCount); | 
 |  | 
 | typedef union _UInt64Aligned_t | 
 | { | 
 |     double d; | 
 |     uint64_t l; | 
 |     uint32_t i[2]; | 
 |     uint16_t s[4]; | 
 |     uint8_t c[8]; | 
 | } UInt64Aligned_t; | 
 |  | 
 | /* | 
 |   Unaligned safe copy of a uint64_t value from an octet array. | 
 | */ | 
 | static uint64_t TIFFReadUInt64(const uint8_t *value) | 
 | { | 
 |     UInt64Aligned_t result; | 
 |  | 
 |     result.c[0] = value[0]; | 
 |     result.c[1] = value[1]; | 
 |     result.c[2] = value[2]; | 
 |     result.c[3] = value[3]; | 
 |     result.c[4] = value[4]; | 
 |     result.c[5] = value[5]; | 
 |     result.c[6] = value[6]; | 
 |     result.c[7] = value[7]; | 
 |  | 
 |     return result.l; | 
 | } | 
 |  | 
 | static enum TIFFReadDirEntryErr | 
 | TIFFReadDirEntryByte(TIFF *tif, TIFFDirEntry *direntry, uint8_t *value) | 
 | { | 
 |     enum TIFFReadDirEntryErr err; | 
 |     if (direntry->tdir_count != 1) | 
 |         return (TIFFReadDirEntryErrCount); | 
 |     switch (direntry->tdir_type) | 
 |     { | 
 |         case TIFF_BYTE: | 
 |         case TIFF_UNDEFINED: /* Support to read TIFF_UNDEFINED with | 
 |                                 field_readcount==1 */ | 
 |             TIFFReadDirEntryCheckedByte(tif, direntry, value); | 
 |             return (TIFFReadDirEntryErrOk); | 
 |         case TIFF_SBYTE: | 
 |         { | 
 |             int8_t m; | 
 |             TIFFReadDirEntryCheckedSbyte(tif, direntry, &m); | 
 |             err = TIFFReadDirEntryCheckRangeByteSbyte(m); | 
 |             if (err != TIFFReadDirEntryErrOk) | 
 |                 return (err); | 
 |             *value = (uint8_t)m; | 
 |             return (TIFFReadDirEntryErrOk); | 
 |         } | 
 |         case TIFF_SHORT: | 
 |         { | 
 |             uint16_t m; | 
 |             TIFFReadDirEntryCheckedShort(tif, direntry, &m); | 
 |             err = TIFFReadDirEntryCheckRangeByteShort(m); | 
 |             if (err != TIFFReadDirEntryErrOk) | 
 |                 return (err); | 
 |             *value = (uint8_t)m; | 
 |             return (TIFFReadDirEntryErrOk); | 
 |         } | 
 |         case TIFF_SSHORT: | 
 |         { | 
 |             int16_t m; | 
 |             TIFFReadDirEntryCheckedSshort(tif, direntry, &m); | 
 |             err = TIFFReadDirEntryCheckRangeByteSshort(m); | 
 |             if (err != TIFFReadDirEntryErrOk) | 
 |                 return (err); | 
 |             *value = (uint8_t)m; | 
 |             return (TIFFReadDirEntryErrOk); | 
 |         } | 
 |         case TIFF_LONG: | 
 |         { | 
 |             uint32_t m; | 
 |             TIFFReadDirEntryCheckedLong(tif, direntry, &m); | 
 |             err = TIFFReadDirEntryCheckRangeByteLong(m); | 
 |             if (err != TIFFReadDirEntryErrOk) | 
 |                 return (err); | 
 |             *value = (uint8_t)m; | 
 |             return (TIFFReadDirEntryErrOk); | 
 |         } | 
 |         case TIFF_SLONG: | 
 |         { | 
 |             int32_t m; | 
 |             TIFFReadDirEntryCheckedSlong(tif, direntry, &m); | 
 |             err = TIFFReadDirEntryCheckRangeByteSlong(m); | 
 |             if (err != TIFFReadDirEntryErrOk) | 
 |                 return (err); | 
 |             *value = (uint8_t)m; | 
 |             return (TIFFReadDirEntryErrOk); | 
 |         } | 
 |         case TIFF_LONG8: | 
 |         { | 
 |             uint64_t m; | 
 |             err = TIFFReadDirEntryCheckedLong8(tif, direntry, &m); | 
 |             if (err != TIFFReadDirEntryErrOk) | 
 |                 return (err); | 
 |             err = TIFFReadDirEntryCheckRangeByteLong8(m); | 
 |             if (err != TIFFReadDirEntryErrOk) | 
 |                 return (err); | 
 |             *value = (uint8_t)m; | 
 |             return (TIFFReadDirEntryErrOk); | 
 |         } | 
 |         case TIFF_SLONG8: | 
 |         { | 
 |             int64_t m; | 
 |             err = TIFFReadDirEntryCheckedSlong8(tif, direntry, &m); | 
 |             if (err != TIFFReadDirEntryErrOk) | 
 |                 return (err); | 
 |             err = TIFFReadDirEntryCheckRangeByteSlong8(m); | 
 |             if (err != TIFFReadDirEntryErrOk) | 
 |                 return (err); | 
 |             *value = (uint8_t)m; | 
 |             return (TIFFReadDirEntryErrOk); | 
 |         } | 
 |         default: | 
 |             return (TIFFReadDirEntryErrType); | 
 |     } | 
 | } | 
 |  | 
 | static enum TIFFReadDirEntryErr | 
 | TIFFReadDirEntrySbyte(TIFF *tif, TIFFDirEntry *direntry, int8_t *value) | 
 | { | 
 |     enum TIFFReadDirEntryErr err; | 
 |     if (direntry->tdir_count != 1) | 
 |         return (TIFFReadDirEntryErrCount); | 
 |     switch (direntry->tdir_type) | 
 |     { | 
 |         case TIFF_BYTE: | 
 |         case TIFF_UNDEFINED: /* Support to read TIFF_UNDEFINED with | 
 |                                 field_readcount==1 */ | 
 |         { | 
 |             uint8_t m; | 
 |             TIFFReadDirEntryCheckedByte(tif, direntry, &m); | 
 |             err = TIFFReadDirEntryCheckRangeSbyteByte(m); | 
 |             if (err != TIFFReadDirEntryErrOk) | 
 |                 return (err); | 
 |             *value = (int8_t)m; | 
 |             return (TIFFReadDirEntryErrOk); | 
 |         } | 
 |         case TIFF_SBYTE: | 
 |         { | 
 |             TIFFReadDirEntryCheckedSbyte(tif, direntry, value); | 
 |             return (TIFFReadDirEntryErrOk); | 
 |         } | 
 |         case TIFF_SHORT: | 
 |         { | 
 |             uint16_t m; | 
 |             TIFFReadDirEntryCheckedShort(tif, direntry, &m); | 
 |             err = TIFFReadDirEntryCheckRangeSbyteShort(m); | 
 |             if (err != TIFFReadDirEntryErrOk) | 
 |                 return (err); | 
 |             *value = (int8_t)m; | 
 |             return (TIFFReadDirEntryErrOk); | 
 |         } | 
 |         case TIFF_SSHORT: | 
 |         { | 
 |             int16_t m; | 
 |             TIFFReadDirEntryCheckedSshort(tif, direntry, &m); | 
 |             err = TIFFReadDirEntryCheckRangeSbyteSshort(m); | 
 |             if (err != TIFFReadDirEntryErrOk) | 
 |                 return (err); | 
 |             *value = (int8_t)m; | 
 |             return (TIFFReadDirEntryErrOk); | 
 |         } | 
 |         case TIFF_LONG: | 
 |         { | 
 |             uint32_t m; | 
 |             TIFFReadDirEntryCheckedLong(tif, direntry, &m); | 
 |             err = TIFFReadDirEntryCheckRangeSbyteLong(m); | 
 |             if (err != TIFFReadDirEntryErrOk) | 
 |                 return (err); | 
 |             *value = (int8_t)m; | 
 |             return (TIFFReadDirEntryErrOk); | 
 |         } | 
 |         case TIFF_SLONG: | 
 |         { | 
 |             int32_t m; | 
 |             TIFFReadDirEntryCheckedSlong(tif, direntry, &m); | 
 |             err = TIFFReadDirEntryCheckRangeSbyteSlong(m); | 
 |             if (err != TIFFReadDirEntryErrOk) | 
 |                 return (err); | 
 |             *value = (int8_t)m; | 
 |             return (TIFFReadDirEntryErrOk); | 
 |         } | 
 |         case TIFF_LONG8: | 
 |         { | 
 |             uint64_t m; | 
 |             err = TIFFReadDirEntryCheckedLong8(tif, direntry, &m); | 
 |             if (err != TIFFReadDirEntryErrOk) | 
 |                 return (err); | 
 |             err = TIFFReadDirEntryCheckRangeSbyteLong8(m); | 
 |             if (err != TIFFReadDirEntryErrOk) | 
 |                 return (err); | 
 |             *value = (int8_t)m; | 
 |             return (TIFFReadDirEntryErrOk); | 
 |         } | 
 |         case TIFF_SLONG8: | 
 |         { | 
 |             int64_t m; | 
 |             err = TIFFReadDirEntryCheckedSlong8(tif, direntry, &m); | 
 |             if (err != TIFFReadDirEntryErrOk) | 
 |                 return (err); | 
 |             err = TIFFReadDirEntryCheckRangeSbyteSlong8(m); | 
 |             if (err != TIFFReadDirEntryErrOk) | 
 |                 return (err); | 
 |             *value = (int8_t)m; | 
 |             return (TIFFReadDirEntryErrOk); | 
 |         } | 
 |         default: | 
 |             return (TIFFReadDirEntryErrType); | 
 |     } | 
 | } /*-- TIFFReadDirEntrySbyte() --*/ | 
 |  | 
 | static enum TIFFReadDirEntryErr | 
 | TIFFReadDirEntryShort(TIFF *tif, TIFFDirEntry *direntry, uint16_t *value) | 
 | { | 
 |     enum TIFFReadDirEntryErr err; | 
 |     if (direntry->tdir_count != 1) | 
 |         return (TIFFReadDirEntryErrCount); | 
 |     switch (direntry->tdir_type) | 
 |     { | 
 |         case TIFF_BYTE: | 
 |         { | 
 |             uint8_t m; | 
 |             TIFFReadDirEntryCheckedByte(tif, direntry, &m); | 
 |             *value = (uint16_t)m; | 
 |             return (TIFFReadDirEntryErrOk); | 
 |         } | 
 |         case TIFF_SBYTE: | 
 |         { | 
 |             int8_t m; | 
 |             TIFFReadDirEntryCheckedSbyte(tif, direntry, &m); | 
 |             err = TIFFReadDirEntryCheckRangeShortSbyte(m); | 
 |             if (err != TIFFReadDirEntryErrOk) | 
 |                 return (err); | 
 |             *value = (uint16_t)m; | 
 |             return (TIFFReadDirEntryErrOk); | 
 |         } | 
 |         case TIFF_SHORT: | 
 |             TIFFReadDirEntryCheckedShort(tif, direntry, value); | 
 |             return (TIFFReadDirEntryErrOk); | 
 |         case TIFF_SSHORT: | 
 |         { | 
 |             int16_t m; | 
 |             TIFFReadDirEntryCheckedSshort(tif, direntry, &m); | 
 |             err = TIFFReadDirEntryCheckRangeShortSshort(m); | 
 |             if (err != TIFFReadDirEntryErrOk) | 
 |                 return (err); | 
 |             *value = (uint16_t)m; | 
 |             return (TIFFReadDirEntryErrOk); | 
 |         } | 
 |         case TIFF_LONG: | 
 |         { | 
 |             uint32_t m; | 
 |             TIFFReadDirEntryCheckedLong(tif, direntry, &m); | 
 |             err = TIFFReadDirEntryCheckRangeShortLong(m); | 
 |             if (err != TIFFReadDirEntryErrOk) | 
 |                 return (err); | 
 |             *value = (uint16_t)m; | 
 |             return (TIFFReadDirEntryErrOk); | 
 |         } | 
 |         case TIFF_SLONG: | 
 |         { | 
 |             int32_t m; | 
 |             TIFFReadDirEntryCheckedSlong(tif, direntry, &m); | 
 |             err = TIFFReadDirEntryCheckRangeShortSlong(m); | 
 |             if (err != TIFFReadDirEntryErrOk) | 
 |                 return (err); | 
 |             *value = (uint16_t)m; | 
 |             return (TIFFReadDirEntryErrOk); | 
 |         } | 
 |         case TIFF_LONG8: | 
 |         { | 
 |             uint64_t m; | 
 |             err = TIFFReadDirEntryCheckedLong8(tif, direntry, &m); | 
 |             if (err != TIFFReadDirEntryErrOk) | 
 |                 return (err); | 
 |             err = TIFFReadDirEntryCheckRangeShortLong8(m); | 
 |             if (err != TIFFReadDirEntryErrOk) | 
 |                 return (err); | 
 |             *value = (uint16_t)m; | 
 |             return (TIFFReadDirEntryErrOk); | 
 |         } | 
 |         case TIFF_SLONG8: | 
 |         { | 
 |             int64_t m; | 
 |             err = TIFFReadDirEntryCheckedSlong8(tif, direntry, &m); | 
 |             if (err != TIFFReadDirEntryErrOk) | 
 |                 return (err); | 
 |             err = TIFFReadDirEntryCheckRangeShortSlong8(m); | 
 |             if (err != TIFFReadDirEntryErrOk) | 
 |                 return (err); | 
 |             *value = (uint16_t)m; | 
 |             return (TIFFReadDirEntryErrOk); | 
 |         } | 
 |         default: | 
 |             return (TIFFReadDirEntryErrType); | 
 |     } | 
 | } /*-- TIFFReadDirEntryShort() --*/ | 
 |  | 
 | static enum TIFFReadDirEntryErr | 
 | TIFFReadDirEntrySshort(TIFF *tif, TIFFDirEntry *direntry, int16_t *value) | 
 | { | 
 |     enum TIFFReadDirEntryErr err; | 
 |     if (direntry->tdir_count != 1) | 
 |         return (TIFFReadDirEntryErrCount); | 
 |     switch (direntry->tdir_type) | 
 |     { | 
 |         case TIFF_BYTE: | 
 |         { | 
 |             uint8_t m; | 
 |             TIFFReadDirEntryCheckedByte(tif, direntry, &m); | 
 |             *value = (int16_t)m; | 
 |             return (TIFFReadDirEntryErrOk); | 
 |         } | 
 |         case TIFF_SBYTE: | 
 |         { | 
 |             int8_t m; | 
 |             TIFFReadDirEntryCheckedSbyte(tif, direntry, &m); | 
 |             *value = (int16_t)m; | 
 |             return (TIFFReadDirEntryErrOk); | 
 |         } | 
 |         case TIFF_SHORT: | 
 |         { | 
 |             uint16_t m; | 
 |             TIFFReadDirEntryCheckedShort(tif, direntry, &m); | 
 |             err = TIFFReadDirEntryCheckRangeSshortShort(m); | 
 |             if (err != TIFFReadDirEntryErrOk) | 
 |                 return (err); | 
 |             *value = (uint16_t)m; | 
 |             return (TIFFReadDirEntryErrOk); | 
 |         } | 
 |         case TIFF_SSHORT: | 
 |             TIFFReadDirEntryCheckedSshort(tif, direntry, value); | 
 |             return (TIFFReadDirEntryErrOk); | 
 |         case TIFF_LONG: | 
 |         { | 
 |             uint32_t m; | 
 |             TIFFReadDirEntryCheckedLong(tif, direntry, &m); | 
 |             err = TIFFReadDirEntryCheckRangeSshortLong(m); | 
 |             if (err != TIFFReadDirEntryErrOk) | 
 |                 return (err); | 
 |             *value = (int16_t)m; | 
 |             return (TIFFReadDirEntryErrOk); | 
 |         } | 
 |         case TIFF_SLONG: | 
 |         { | 
 |             int32_t m; | 
 |             TIFFReadDirEntryCheckedSlong(tif, direntry, &m); | 
 |             err = TIFFReadDirEntryCheckRangeSshortSlong(m); | 
 |             if (err != TIFFReadDirEntryErrOk) | 
 |                 return (err); | 
 |             *value = (int16_t)m; | 
 |             return (TIFFReadDirEntryErrOk); | 
 |         } | 
 |         case TIFF_LONG8: | 
 |         { | 
 |             uint64_t m; | 
 |             err = TIFFReadDirEntryCheckedLong8(tif, direntry, &m); | 
 |             if (err != TIFFReadDirEntryErrOk) | 
 |                 return (err); | 
 |             err = TIFFReadDirEntryCheckRangeSshortLong8(m); | 
 |             if (err != TIFFReadDirEntryErrOk) | 
 |                 return (err); | 
 |             *value = (int16_t)m; | 
 |             return (TIFFReadDirEntryErrOk); | 
 |         } | 
 |         case TIFF_SLONG8: | 
 |         { | 
 |             int64_t m; | 
 |             err = TIFFReadDirEntryCheckedSlong8(tif, direntry, &m); | 
 |             if (err != TIFFReadDirEntryErrOk) | 
 |                 return (err); | 
 |             err = TIFFReadDirEntryCheckRangeSshortSlong8(m); | 
 |             if (err != TIFFReadDirEntryErrOk) | 
 |                 return (err); | 
 |             *value = (int16_t)m; | 
 |             return (TIFFReadDirEntryErrOk); | 
 |         } | 
 |         default: | 
 |             return (TIFFReadDirEntryErrType); | 
 |     } | 
 | } /*-- TIFFReadDirEntrySshort() --*/ | 
 |  | 
 | static enum TIFFReadDirEntryErr | 
 | TIFFReadDirEntryLong(TIFF *tif, TIFFDirEntry *direntry, uint32_t *value) | 
 | { | 
 |     enum TIFFReadDirEntryErr err; | 
 |     if (direntry->tdir_count != 1) | 
 |         return (TIFFReadDirEntryErrCount); | 
 |     switch (direntry->tdir_type) | 
 |     { | 
 |         case TIFF_BYTE: | 
 |         { | 
 |             uint8_t m; | 
 |             TIFFReadDirEntryCheckedByte(tif, direntry, &m); | 
 |             *value = (uint32_t)m; | 
 |             return (TIFFReadDirEntryErrOk); | 
 |         } | 
 |         case TIFF_SBYTE: | 
 |         { | 
 |             int8_t m; | 
 |             TIFFReadDirEntryCheckedSbyte(tif, direntry, &m); | 
 |             err = TIFFReadDirEntryCheckRangeLongSbyte(m); | 
 |             if (err != TIFFReadDirEntryErrOk) | 
 |                 return (err); | 
 |             *value = (uint32_t)m; | 
 |             return (TIFFReadDirEntryErrOk); | 
 |         } | 
 |         case TIFF_SHORT: | 
 |         { | 
 |             uint16_t m; | 
 |             TIFFReadDirEntryCheckedShort(tif, direntry, &m); | 
 |             *value = (uint32_t)m; | 
 |             return (TIFFReadDirEntryErrOk); | 
 |         } | 
 |         case TIFF_SSHORT: | 
 |         { | 
 |             int16_t m; | 
 |             TIFFReadDirEntryCheckedSshort(tif, direntry, &m); | 
 |             err = TIFFReadDirEntryCheckRangeLongSshort(m); | 
 |             if (err != TIFFReadDirEntryErrOk) | 
 |                 return (err); | 
 |             *value = (uint32_t)m; | 
 |             return (TIFFReadDirEntryErrOk); | 
 |         } | 
 |         case TIFF_LONG: | 
 |             TIFFReadDirEntryCheckedLong(tif, direntry, value); | 
 |             return (TIFFReadDirEntryErrOk); | 
 |         case TIFF_SLONG: | 
 |         { | 
 |             int32_t m; | 
 |             TIFFReadDirEntryCheckedSlong(tif, direntry, &m); | 
 |             err = TIFFReadDirEntryCheckRangeLongSlong(m); | 
 |             if (err != TIFFReadDirEntryErrOk) | 
 |                 return (err); | 
 |             *value = (uint32_t)m; | 
 |             return (TIFFReadDirEntryErrOk); | 
 |         } | 
 |         case TIFF_LONG8: | 
 |         { | 
 |             uint64_t m; | 
 |             err = TIFFReadDirEntryCheckedLong8(tif, direntry, &m); | 
 |             if (err != TIFFReadDirEntryErrOk) | 
 |                 return (err); | 
 |             err = TIFFReadDirEntryCheckRangeLongLong8(m); | 
 |             if (err != TIFFReadDirEntryErrOk) | 
 |                 return (err); | 
 |             *value = (uint32_t)m; | 
 |             return (TIFFReadDirEntryErrOk); | 
 |         } | 
 |         case TIFF_SLONG8: | 
 |         { | 
 |             int64_t m; | 
 |             err = TIFFReadDirEntryCheckedSlong8(tif, direntry, &m); | 
 |             if (err != TIFFReadDirEntryErrOk) | 
 |                 return (err); | 
 |             err = TIFFReadDirEntryCheckRangeLongSlong8(m); | 
 |             if (err != TIFFReadDirEntryErrOk) | 
 |                 return (err); | 
 |             *value = (uint32_t)m; | 
 |             return (TIFFReadDirEntryErrOk); | 
 |         } | 
 |         default: | 
 |             return (TIFFReadDirEntryErrType); | 
 |     } | 
 | } /*-- TIFFReadDirEntryLong() --*/ | 
 |  | 
 | static enum TIFFReadDirEntryErr | 
 | TIFFReadDirEntrySlong(TIFF *tif, TIFFDirEntry *direntry, int32_t *value) | 
 | { | 
 |     enum TIFFReadDirEntryErr err; | 
 |     if (direntry->tdir_count != 1) | 
 |         return (TIFFReadDirEntryErrCount); | 
 |     switch (direntry->tdir_type) | 
 |     { | 
 |         case TIFF_BYTE: | 
 |         { | 
 |             uint8_t m; | 
 |             TIFFReadDirEntryCheckedByte(tif, direntry, &m); | 
 |             *value = (int32_t)m; | 
 |             return (TIFFReadDirEntryErrOk); | 
 |         } | 
 |         case TIFF_SBYTE: | 
 |         { | 
 |             int8_t m; | 
 |             TIFFReadDirEntryCheckedSbyte(tif, direntry, &m); | 
 |             *value = (int32_t)m; | 
 |             return (TIFFReadDirEntryErrOk); | 
 |         } | 
 |         case TIFF_SHORT: | 
 |         { | 
 |             uint16_t m; | 
 |             TIFFReadDirEntryCheckedShort(tif, direntry, &m); | 
 |             *value = (int32_t)m; | 
 |             return (TIFFReadDirEntryErrOk); | 
 |         } | 
 |         case TIFF_SSHORT: | 
 |         { | 
 |             int16_t m; | 
 |             TIFFReadDirEntryCheckedSshort(tif, direntry, &m); | 
 |             *value = (int32_t)m; | 
 |             return (TIFFReadDirEntryErrOk); | 
 |         } | 
 |         case TIFF_LONG: | 
 |         { | 
 |             uint32_t m; | 
 |             TIFFReadDirEntryCheckedLong(tif, direntry, &m); | 
 |             err = TIFFReadDirEntryCheckRangeSlongLong(m); | 
 |             if (err != TIFFReadDirEntryErrOk) | 
 |                 return (err); | 
 |             *value = (int32_t)m; | 
 |             return (TIFFReadDirEntryErrOk); | 
 |         } | 
 |         case TIFF_SLONG: | 
 |             TIFFReadDirEntryCheckedSlong(tif, direntry, value); | 
 |             return (TIFFReadDirEntryErrOk); | 
 |         case TIFF_LONG8: | 
 |         { | 
 |             uint64_t m; | 
 |             err = TIFFReadDirEntryCheckedLong8(tif, direntry, &m); | 
 |             if (err != TIFFReadDirEntryErrOk) | 
 |                 return (err); | 
 |             err = TIFFReadDirEntryCheckRangeSlongLong8(m); | 
 |             if (err != TIFFReadDirEntryErrOk) | 
 |                 return (err); | 
 |             *value = (int32_t)m; | 
 |             return (TIFFReadDirEntryErrOk); | 
 |         } | 
 |         case TIFF_SLONG8: | 
 |         { | 
 |             int64_t m; | 
 |             err = TIFFReadDirEntryCheckedSlong8(tif, direntry, &m); | 
 |             if (err != TIFFReadDirEntryErrOk) | 
 |                 return (err); | 
 |             err = TIFFReadDirEntryCheckRangeSlongSlong8(m); | 
 |             if (err != TIFFReadDirEntryErrOk) | 
 |                 return (err); | 
 |             *value = (int32_t)m; | 
 |             return (TIFFReadDirEntryErrOk); | 
 |         } | 
 |         default: | 
 |             return (TIFFReadDirEntryErrType); | 
 |     } | 
 | } /*-- TIFFReadDirEntrySlong() --*/ | 
 |  | 
 | static enum TIFFReadDirEntryErr | 
 | TIFFReadDirEntryLong8(TIFF *tif, TIFFDirEntry *direntry, uint64_t *value) | 
 | { | 
 |     enum TIFFReadDirEntryErr err; | 
 |     if (direntry->tdir_count != 1) | 
 |         return (TIFFReadDirEntryErrCount); | 
 |     switch (direntry->tdir_type) | 
 |     { | 
 |         case TIFF_BYTE: | 
 |         { | 
 |             uint8_t m; | 
 |             TIFFReadDirEntryCheckedByte(tif, direntry, &m); | 
 |             *value = (uint64_t)m; | 
 |             return (TIFFReadDirEntryErrOk); | 
 |         } | 
 |         case TIFF_SBYTE: | 
 |         { | 
 |             int8_t m; | 
 |             TIFFReadDirEntryCheckedSbyte(tif, direntry, &m); | 
 |             err = TIFFReadDirEntryCheckRangeLong8Sbyte(m); | 
 |             if (err != TIFFReadDirEntryErrOk) | 
 |                 return (err); | 
 |             *value = (uint64_t)m; | 
 |             return (TIFFReadDirEntryErrOk); | 
 |         } | 
 |         case TIFF_SHORT: | 
 |         { | 
 |             uint16_t m; | 
 |             TIFFReadDirEntryCheckedShort(tif, direntry, &m); | 
 |             *value = (uint64_t)m; | 
 |             return (TIFFReadDirEntryErrOk); | 
 |         } | 
 |         case TIFF_SSHORT: | 
 |         { | 
 |             int16_t m; | 
 |             TIFFReadDirEntryCheckedSshort(tif, direntry, &m); | 
 |             err = TIFFReadDirEntryCheckRangeLong8Sshort(m); | 
 |             if (err != TIFFReadDirEntryErrOk) | 
 |                 return (err); | 
 |             *value = (uint64_t)m; | 
 |             return (TIFFReadDirEntryErrOk); | 
 |         } | 
 |         case TIFF_LONG: | 
 |         { | 
 |             uint32_t m; | 
 |             TIFFReadDirEntryCheckedLong(tif, direntry, &m); | 
 |             *value = (uint64_t)m; | 
 |             return (TIFFReadDirEntryErrOk); | 
 |         } | 
 |         case TIFF_SLONG: | 
 |         { | 
 |             int32_t m; | 
 |             TIFFReadDirEntryCheckedSlong(tif, direntry, &m); | 
 |             err = TIFFReadDirEntryCheckRangeLong8Slong(m); | 
 |             if (err != TIFFReadDirEntryErrOk) | 
 |                 return (err); | 
 |             *value = (uint64_t)m; | 
 |             return (TIFFReadDirEntryErrOk); | 
 |         } | 
 |         case TIFF_LONG8: | 
 |             err = TIFFReadDirEntryCheckedLong8(tif, direntry, value); | 
 |             return (err); | 
 |         case TIFF_SLONG8: | 
 |         { | 
 |             int64_t m; | 
 |             err = TIFFReadDirEntryCheckedSlong8(tif, direntry, &m); | 
 |             if (err != TIFFReadDirEntryErrOk) | 
 |                 return (err); | 
 |             err = TIFFReadDirEntryCheckRangeLong8Slong8(m); | 
 |             if (err != TIFFReadDirEntryErrOk) | 
 |                 return (err); | 
 |             *value = (uint64_t)m; | 
 |             return (TIFFReadDirEntryErrOk); | 
 |         } | 
 |         default: | 
 |             return (TIFFReadDirEntryErrType); | 
 |     } | 
 | } /*-- TIFFReadDirEntryLong8() --*/ | 
 |  | 
 | static enum TIFFReadDirEntryErr | 
 | TIFFReadDirEntrySlong8(TIFF *tif, TIFFDirEntry *direntry, int64_t *value) | 
 | { | 
 |     enum TIFFReadDirEntryErr err; | 
 |     if (direntry->tdir_count != 1) | 
 |         return (TIFFReadDirEntryErrCount); | 
 |     switch (direntry->tdir_type) | 
 |     { | 
 |         case TIFF_BYTE: | 
 |         { | 
 |             uint8_t m; | 
 |             TIFFReadDirEntryCheckedByte(tif, direntry, &m); | 
 |             *value = (int64_t)m; | 
 |             return (TIFFReadDirEntryErrOk); | 
 |         } | 
 |         case TIFF_SBYTE: | 
 |         { | 
 |             int8_t m; | 
 |             TIFFReadDirEntryCheckedSbyte(tif, direntry, &m); | 
 |             *value = (int64_t)m; | 
 |             return (TIFFReadDirEntryErrOk); | 
 |         } | 
 |         case TIFF_SHORT: | 
 |         { | 
 |             uint16_t m; | 
 |             TIFFReadDirEntryCheckedShort(tif, direntry, &m); | 
 |             *value = (int64_t)m; | 
 |             return (TIFFReadDirEntryErrOk); | 
 |         } | 
 |         case TIFF_SSHORT: | 
 |         { | 
 |             int16_t m; | 
 |             TIFFReadDirEntryCheckedSshort(tif, direntry, &m); | 
 |             *value = (int64_t)m; | 
 |             return (TIFFReadDirEntryErrOk); | 
 |         } | 
 |         case TIFF_LONG: | 
 |         { | 
 |             uint32_t m; | 
 |             TIFFReadDirEntryCheckedLong(tif, direntry, &m); | 
 |             *value = (int64_t)m; | 
 |             return (TIFFReadDirEntryErrOk); | 
 |         } | 
 |         case TIFF_SLONG: | 
 |         { | 
 |             int32_t m; | 
 |             TIFFReadDirEntryCheckedSlong(tif, direntry, &m); | 
 |             *value = (int64_t)m; | 
 |             return (TIFFReadDirEntryErrOk); | 
 |         } | 
 |         case TIFF_LONG8: | 
 |         { | 
 |             uint64_t m; | 
 |             err = TIFFReadDirEntryCheckedLong8(tif, direntry, &m); | 
 |             if (err != TIFFReadDirEntryErrOk) | 
 |                 return (err); | 
 |             err = TIFFReadDirEntryCheckRangeSlong8Long8(m); | 
 |             if (err != TIFFReadDirEntryErrOk) | 
 |                 return (err); | 
 |             *value = (int64_t)m; | 
 |             return (TIFFReadDirEntryErrOk); | 
 |         } | 
 |         case TIFF_SLONG8: | 
 |             err = TIFFReadDirEntryCheckedSlong8(tif, direntry, value); | 
 |             return (err); | 
 |         default: | 
 |             return (TIFFReadDirEntryErrType); | 
 |     } | 
 | } /*-- TIFFReadDirEntrySlong8() --*/ | 
 |  | 
 | static enum TIFFReadDirEntryErr | 
 | TIFFReadDirEntryFloat(TIFF *tif, TIFFDirEntry *direntry, float *value) | 
 | { | 
 |     enum TIFFReadDirEntryErr err; | 
 |     if (direntry->tdir_count != 1) | 
 |         return (TIFFReadDirEntryErrCount); | 
 |     switch (direntry->tdir_type) | 
 |     { | 
 |         case TIFF_BYTE: | 
 |         { | 
 |             uint8_t m; | 
 |             TIFFReadDirEntryCheckedByte(tif, direntry, &m); | 
 |             *value = (float)m; | 
 |             return (TIFFReadDirEntryErrOk); | 
 |         } | 
 |         case TIFF_SBYTE: | 
 |         { | 
 |             int8_t m; | 
 |             TIFFReadDirEntryCheckedSbyte(tif, direntry, &m); | 
 |             *value = (float)m; | 
 |             return (TIFFReadDirEntryErrOk); | 
 |         } | 
 |         case TIFF_SHORT: | 
 |         { | 
 |             uint16_t m; | 
 |             TIFFReadDirEntryCheckedShort(tif, direntry, &m); | 
 |             *value = (float)m; | 
 |             return (TIFFReadDirEntryErrOk); | 
 |         } | 
 |         case TIFF_SSHORT: | 
 |         { | 
 |             int16_t m; | 
 |             TIFFReadDirEntryCheckedSshort(tif, direntry, &m); | 
 |             *value = (float)m; | 
 |             return (TIFFReadDirEntryErrOk); | 
 |         } | 
 |         case TIFF_LONG: | 
 |         { | 
 |             uint32_t m; | 
 |             TIFFReadDirEntryCheckedLong(tif, direntry, &m); | 
 |             *value = (float)m; | 
 |             return (TIFFReadDirEntryErrOk); | 
 |         } | 
 |         case TIFF_SLONG: | 
 |         { | 
 |             int32_t m; | 
 |             TIFFReadDirEntryCheckedSlong(tif, direntry, &m); | 
 |             *value = (float)m; | 
 |             return (TIFFReadDirEntryErrOk); | 
 |         } | 
 |         case TIFF_LONG8: | 
 |         { | 
 |             uint64_t m; | 
 |             err = TIFFReadDirEntryCheckedLong8(tif, direntry, &m); | 
 |             if (err != TIFFReadDirEntryErrOk) | 
 |                 return (err); | 
 |             *value = (float)m; | 
 |             return (TIFFReadDirEntryErrOk); | 
 |         } | 
 |         case TIFF_SLONG8: | 
 |         { | 
 |             int64_t m; | 
 |             err = TIFFReadDirEntryCheckedSlong8(tif, direntry, &m); | 
 |             if (err != TIFFReadDirEntryErrOk) | 
 |                 return (err); | 
 |             *value = (float)m; | 
 |             return (TIFFReadDirEntryErrOk); | 
 |         } | 
 |         case TIFF_RATIONAL: | 
 |         { | 
 |             double m; | 
 |             err = TIFFReadDirEntryCheckedRational(tif, direntry, &m); | 
 |             if (err != TIFFReadDirEntryErrOk) | 
 |                 return (err); | 
 |             *value = (float)m; | 
 |             return (TIFFReadDirEntryErrOk); | 
 |         } | 
 |         case TIFF_SRATIONAL: | 
 |         { | 
 |             double m; | 
 |             err = TIFFReadDirEntryCheckedSrational(tif, direntry, &m); | 
 |             if (err != TIFFReadDirEntryErrOk) | 
 |                 return (err); | 
 |             *value = (float)m; | 
 |             return (TIFFReadDirEntryErrOk); | 
 |         } | 
 |         case TIFF_FLOAT: | 
 |             TIFFReadDirEntryCheckedFloat(tif, direntry, value); | 
 |             return (TIFFReadDirEntryErrOk); | 
 |         case TIFF_DOUBLE: | 
 |         { | 
 |             double m; | 
 |             err = TIFFReadDirEntryCheckedDouble(tif, direntry, &m); | 
 |             if (err != TIFFReadDirEntryErrOk) | 
 |                 return (err); | 
 |             if ((m > FLT_MAX) || (m < -FLT_MAX)) | 
 |                 return (TIFFReadDirEntryErrRange); | 
 |             *value = (float)m; | 
 |             return (TIFFReadDirEntryErrOk); | 
 |         } | 
 |         default: | 
 |             return (TIFFReadDirEntryErrType); | 
 |     } | 
 | } | 
 |  | 
 | static enum TIFFReadDirEntryErr | 
 | TIFFReadDirEntryDouble(TIFF *tif, TIFFDirEntry *direntry, double *value) | 
 | { | 
 |     enum TIFFReadDirEntryErr err; | 
 |     if (direntry->tdir_count != 1) | 
 |         return (TIFFReadDirEntryErrCount); | 
 |     switch (direntry->tdir_type) | 
 |     { | 
 |         case TIFF_BYTE: | 
 |         { | 
 |             uint8_t m; | 
 |             TIFFReadDirEntryCheckedByte(tif, direntry, &m); | 
 |             *value = (double)m; | 
 |             return (TIFFReadDirEntryErrOk); | 
 |         } | 
 |         case TIFF_SBYTE: | 
 |         { | 
 |             int8_t m; | 
 |             TIFFReadDirEntryCheckedSbyte(tif, direntry, &m); | 
 |             *value = (double)m; | 
 |             return (TIFFReadDirEntryErrOk); | 
 |         } | 
 |         case TIFF_SHORT: | 
 |         { | 
 |             uint16_t m; | 
 |             TIFFReadDirEntryCheckedShort(tif, direntry, &m); | 
 |             *value = (double)m; | 
 |             return (TIFFReadDirEntryErrOk); | 
 |         } | 
 |         case TIFF_SSHORT: | 
 |         { | 
 |             int16_t m; | 
 |             TIFFReadDirEntryCheckedSshort(tif, direntry, &m); | 
 |             *value = (double)m; | 
 |             return (TIFFReadDirEntryErrOk); | 
 |         } | 
 |         case TIFF_LONG: | 
 |         { | 
 |             uint32_t m; | 
 |             TIFFReadDirEntryCheckedLong(tif, direntry, &m); | 
 |             *value = (double)m; | 
 |             return (TIFFReadDirEntryErrOk); | 
 |         } | 
 |         case TIFF_SLONG: | 
 |         { | 
 |             int32_t m; | 
 |             TIFFReadDirEntryCheckedSlong(tif, direntry, &m); | 
 |             *value = (double)m; | 
 |             return (TIFFReadDirEntryErrOk); | 
 |         } | 
 |         case TIFF_LONG8: | 
 |         { | 
 |             uint64_t m; | 
 |             err = TIFFReadDirEntryCheckedLong8(tif, direntry, &m); | 
 |             if (err != TIFFReadDirEntryErrOk) | 
 |                 return (err); | 
 |             *value = (double)m; | 
 |             return (TIFFReadDirEntryErrOk); | 
 |         } | 
 |         case TIFF_SLONG8: | 
 |         { | 
 |             int64_t m; | 
 |             err = TIFFReadDirEntryCheckedSlong8(tif, direntry, &m); | 
 |             if (err != TIFFReadDirEntryErrOk) | 
 |                 return (err); | 
 |             *value = (double)m; | 
 |             return (TIFFReadDirEntryErrOk); | 
 |         } | 
 |         case TIFF_RATIONAL: | 
 |             err = TIFFReadDirEntryCheckedRational(tif, direntry, value); | 
 |             return (err); | 
 |         case TIFF_SRATIONAL: | 
 |             err = TIFFReadDirEntryCheckedSrational(tif, direntry, value); | 
 |             return (err); | 
 |         case TIFF_FLOAT: | 
 |         { | 
 |             float m; | 
 |             TIFFReadDirEntryCheckedFloat(tif, direntry, &m); | 
 |             *value = (double)m; | 
 |             return (TIFFReadDirEntryErrOk); | 
 |         } | 
 |         case TIFF_DOUBLE: | 
 |             err = TIFFReadDirEntryCheckedDouble(tif, direntry, value); | 
 |             return (err); | 
 |         default: | 
 |             return (TIFFReadDirEntryErrType); | 
 |     } | 
 | } | 
 |  | 
 | static enum TIFFReadDirEntryErr | 
 | TIFFReadDirEntryIfd8(TIFF *tif, TIFFDirEntry *direntry, uint64_t *value) | 
 | { | 
 |     enum TIFFReadDirEntryErr err; | 
 |     if (direntry->tdir_count != 1) | 
 |         return (TIFFReadDirEntryErrCount); | 
 |     switch (direntry->tdir_type) | 
 |     { | 
 |         case TIFF_LONG: | 
 |         case TIFF_IFD: | 
 |         { | 
 |             uint32_t m; | 
 |             TIFFReadDirEntryCheckedLong(tif, direntry, &m); | 
 |             *value = (uint64_t)m; | 
 |             return (TIFFReadDirEntryErrOk); | 
 |         } | 
 |         case TIFF_LONG8: | 
 |         case TIFF_IFD8: | 
 |             err = TIFFReadDirEntryCheckedLong8(tif, direntry, value); | 
 |             return (err); | 
 |         default: | 
 |             return (TIFFReadDirEntryErrType); | 
 |     } | 
 | } | 
 |  | 
 | #define INITIAL_THRESHOLD (1024 * 1024) | 
 | #define THRESHOLD_MULTIPLIER 10 | 
 | #define MAX_THRESHOLD                                                          \ | 
 |     (THRESHOLD_MULTIPLIER * THRESHOLD_MULTIPLIER * THRESHOLD_MULTIPLIER *      \ | 
 |      INITIAL_THRESHOLD) | 
 |  | 
 | static enum TIFFReadDirEntryErr TIFFReadDirEntryDataAndRealloc(TIFF *tif, | 
 |                                                                uint64_t offset, | 
 |                                                                tmsize_t size, | 
 |                                                                void **pdest) | 
 | { | 
 | #if SIZEOF_SIZE_T == 8 | 
 |     tmsize_t threshold = INITIAL_THRESHOLD; | 
 | #endif | 
 |     tmsize_t already_read = 0; | 
 |  | 
 |     assert(!isMapped(tif)); | 
 |  | 
 |     if (!SeekOK(tif, offset)) | 
 |         return (TIFFReadDirEntryErrIo); | 
 |  | 
 |     /* On 64 bit processes, read first a maximum of 1 MB, then 10 MB, etc */ | 
 |     /* so as to avoid allocating too much memory in case the file is too */ | 
 |     /* short. We could ask for the file size, but this might be */ | 
 |     /* expensive with some I/O layers (think of reading a gzipped file) */ | 
 |     /* Restrict to 64 bit processes, so as to avoid reallocs() */ | 
 |     /* on 32 bit processes where virtual memory is scarce.  */ | 
 |     while (already_read < size) | 
 |     { | 
 |         void *new_dest; | 
 |         tmsize_t bytes_read; | 
 |         tmsize_t to_read = size - already_read; | 
 | #if SIZEOF_SIZE_T == 8 | 
 |         if (to_read >= threshold && threshold < MAX_THRESHOLD) | 
 |         { | 
 |             to_read = threshold; | 
 |             threshold *= THRESHOLD_MULTIPLIER; | 
 |         } | 
 | #endif | 
 |  | 
 |         new_dest = | 
 |             (uint8_t *)_TIFFreallocExt(tif, *pdest, already_read + to_read); | 
 |         if (new_dest == NULL) | 
 |         { | 
 |             TIFFErrorExtR(tif, tif->tif_name, | 
 |                           "Failed to allocate memory for %s " | 
 |                           "(%" TIFF_SSIZE_FORMAT | 
 |                           " elements of %" TIFF_SSIZE_FORMAT " bytes each)", | 
 |                           "TIFFReadDirEntryArray", (tmsize_t)1, | 
 |                           already_read + to_read); | 
 |             return TIFFReadDirEntryErrAlloc; | 
 |         } | 
 |         *pdest = new_dest; | 
 |  | 
 |         bytes_read = TIFFReadFile(tif, (char *)*pdest + already_read, to_read); | 
 |         already_read += bytes_read; | 
 |         if (bytes_read != to_read) | 
 |         { | 
 |             return TIFFReadDirEntryErrIo; | 
 |         } | 
 |     } | 
 |     return TIFFReadDirEntryErrOk; | 
 | } | 
 |  | 
 | /* Caution: if raising that value, make sure int32 / uint32 overflows can't | 
 |  * occur elsewhere */ | 
 | #define MAX_SIZE_TAG_DATA 2147483647U | 
 |  | 
 | static enum TIFFReadDirEntryErr | 
 | TIFFReadDirEntryArrayWithLimit(TIFF *tif, TIFFDirEntry *direntry, | 
 |                                uint32_t *count, uint32_t desttypesize, | 
 |                                void **value, uint64_t maxcount) | 
 | { | 
 |     int typesize; | 
 |     uint32_t datasize; | 
 |     void *data; | 
 |     uint64_t target_count64; | 
 |     int original_datasize_clamped; | 
 |     typesize = TIFFDataWidth(direntry->tdir_type); | 
 |  | 
 |     target_count64 = | 
 |         (direntry->tdir_count > maxcount) ? maxcount : direntry->tdir_count; | 
 |  | 
 |     if ((target_count64 == 0) || (typesize == 0)) | 
 |     { | 
 |         *value = 0; | 
 |         return (TIFFReadDirEntryErrOk); | 
 |     } | 
 |     (void)desttypesize; | 
 |  | 
 |     /* We just want to know if the original tag size is more than 4 bytes | 
 |      * (classic TIFF) or 8 bytes (BigTIFF) | 
 |      */ | 
 |     original_datasize_clamped = | 
 |         ((direntry->tdir_count > 10) ? 10 : (int)direntry->tdir_count) * | 
 |         typesize; | 
 |  | 
 |     /* | 
 |      * As a sanity check, make sure we have no more than a 2GB tag array | 
 |      * in either the current data type or the dest data type.  This also | 
 |      * avoids problems with overflow of tmsize_t on 32bit systems. | 
 |      */ | 
 |     if ((uint64_t)(MAX_SIZE_TAG_DATA / typesize) < target_count64) | 
 |         return (TIFFReadDirEntryErrSizesan); | 
 |     if ((uint64_t)(MAX_SIZE_TAG_DATA / desttypesize) < target_count64) | 
 |         return (TIFFReadDirEntryErrSizesan); | 
 |  | 
 |     *count = (uint32_t)target_count64; | 
 |     datasize = (*count) * typesize; | 
 |     assert((tmsize_t)datasize > 0); | 
 |  | 
 |     if (datasize > 100 * 1024 * 1024) | 
 |     { | 
 |         /* Before allocating a huge amount of memory for corrupted files, check | 
 |          * if size of requested memory is not greater than file size. | 
 |          */ | 
 |         const uint64_t filesize = TIFFGetFileSize(tif); | 
 |         if (datasize > filesize) | 
 |         { | 
 |             TIFFWarningExtR(tif, "ReadDirEntryArray", | 
 |                             "Requested memory size for tag %d (0x%x) %" PRIu32 | 
 |                             " is greater than filesize %" PRIu64 | 
 |                             ". Memory not allocated, tag not read", | 
 |                             direntry->tdir_tag, direntry->tdir_tag, datasize, | 
 |                             filesize); | 
 |             return (TIFFReadDirEntryErrAlloc); | 
 |         } | 
 |     } | 
 |  | 
 |     if (isMapped(tif) && datasize > (uint64_t)tif->tif_size) | 
 |         return TIFFReadDirEntryErrIo; | 
 |  | 
 |     if (!isMapped(tif) && (((tif->tif_flags & TIFF_BIGTIFF) && datasize > 8) || | 
 |                            (!(tif->tif_flags & TIFF_BIGTIFF) && datasize > 4))) | 
 |     { | 
 |         data = NULL; | 
 |     } | 
 |     else | 
 |     { | 
 |         data = _TIFFCheckMalloc(tif, *count, typesize, "ReadDirEntryArray"); | 
 |         if (data == 0) | 
 |             return (TIFFReadDirEntryErrAlloc); | 
 |     } | 
 |     if (!(tif->tif_flags & TIFF_BIGTIFF)) | 
 |     { | 
 |         /* Only the condition on original_datasize_clamped. The second | 
 |          * one is implied, but Coverity Scan cannot see it. */ | 
 |         if (original_datasize_clamped <= 4 && datasize <= 4) | 
 |             _TIFFmemcpy(data, &direntry->tdir_offset, datasize); | 
 |         else | 
 |         { | 
 |             enum TIFFReadDirEntryErr err; | 
 |             uint32_t offset = direntry->tdir_offset.toff_long; | 
 |             if (tif->tif_flags & TIFF_SWAB) | 
 |                 TIFFSwabLong(&offset); | 
 |             if (isMapped(tif)) | 
 |                 err = TIFFReadDirEntryData(tif, (uint64_t)offset, | 
 |                                            (tmsize_t)datasize, data); | 
 |             else | 
 |                 err = TIFFReadDirEntryDataAndRealloc(tif, (uint64_t)offset, | 
 |                                                      (tmsize_t)datasize, &data); | 
 |             if (err != TIFFReadDirEntryErrOk) | 
 |             { | 
 |                 _TIFFfreeExt(tif, data); | 
 |                 return (err); | 
 |             } | 
 |         } | 
 |     } | 
 |     else | 
 |     { | 
 |         /* See above comment for the Classic TIFF case */ | 
 |         if (original_datasize_clamped <= 8 && datasize <= 8) | 
 |             _TIFFmemcpy(data, &direntry->tdir_offset, datasize); | 
 |         else | 
 |         { | 
 |             enum TIFFReadDirEntryErr err; | 
 |             uint64_t offset = direntry->tdir_offset.toff_long8; | 
 |             if (tif->tif_flags & TIFF_SWAB) | 
 |                 TIFFSwabLong8(&offset); | 
 |             if (isMapped(tif)) | 
 |                 err = TIFFReadDirEntryData(tif, (uint64_t)offset, | 
 |                                            (tmsize_t)datasize, data); | 
 |             else | 
 |                 err = TIFFReadDirEntryDataAndRealloc(tif, (uint64_t)offset, | 
 |                                                      (tmsize_t)datasize, &data); | 
 |             if (err != TIFFReadDirEntryErrOk) | 
 |             { | 
 |                 _TIFFfreeExt(tif, data); | 
 |                 return (err); | 
 |             } | 
 |         } | 
 |     } | 
 |     *value = data; | 
 |     return (TIFFReadDirEntryErrOk); | 
 | } | 
 |  | 
 | static enum TIFFReadDirEntryErr | 
 | TIFFReadDirEntryArray(TIFF *tif, TIFFDirEntry *direntry, uint32_t *count, | 
 |                       uint32_t desttypesize, void **value) | 
 | { | 
 |     return TIFFReadDirEntryArrayWithLimit(tif, direntry, count, desttypesize, | 
 |                                           value, ~((uint64_t)0)); | 
 | } | 
 |  | 
 | static enum TIFFReadDirEntryErr | 
 | TIFFReadDirEntryByteArray(TIFF *tif, TIFFDirEntry *direntry, uint8_t **value) | 
 | { | 
 |     enum TIFFReadDirEntryErr err; | 
 |     uint32_t count; | 
 |     void *origdata; | 
 |     uint8_t *data; | 
 |     switch (direntry->tdir_type) | 
 |     { | 
 |         case TIFF_ASCII: | 
 |         case TIFF_UNDEFINED: | 
 |         case TIFF_BYTE: | 
 |         case TIFF_SBYTE: | 
 |         case TIFF_SHORT: | 
 |         case TIFF_SSHORT: | 
 |         case TIFF_LONG: | 
 |         case TIFF_SLONG: | 
 |         case TIFF_LONG8: | 
 |         case TIFF_SLONG8: | 
 |             break; | 
 |         default: | 
 |             return (TIFFReadDirEntryErrType); | 
 |     } | 
 |     err = TIFFReadDirEntryArray(tif, direntry, &count, 1, &origdata); | 
 |     if ((err != TIFFReadDirEntryErrOk) || (origdata == 0)) | 
 |     { | 
 |         *value = 0; | 
 |         return (err); | 
 |     } | 
 |     switch (direntry->tdir_type) | 
 |     { | 
 |         case TIFF_ASCII: | 
 |         case TIFF_UNDEFINED: | 
 |         case TIFF_BYTE: | 
 |             *value = (uint8_t *)origdata; | 
 |             return (TIFFReadDirEntryErrOk); | 
 |         case TIFF_SBYTE: | 
 |         { | 
 |             int8_t *m; | 
 |             uint32_t n; | 
 |             m = (int8_t *)origdata; | 
 |             for (n = 0; n < count; n++) | 
 |             { | 
 |                 err = TIFFReadDirEntryCheckRangeByteSbyte(*m); | 
 |                 if (err != TIFFReadDirEntryErrOk) | 
 |                 { | 
 |                     _TIFFfreeExt(tif, origdata); | 
 |                     return (err); | 
 |                 } | 
 |                 m++; | 
 |             } | 
 |             *value = (uint8_t *)origdata; | 
 |             return (TIFFReadDirEntryErrOk); | 
 |         } | 
 |     } | 
 |     data = (uint8_t *)_TIFFmallocExt(tif, count); | 
 |     if (data == 0) | 
 |     { | 
 |         _TIFFfreeExt(tif, origdata); | 
 |         return (TIFFReadDirEntryErrAlloc); | 
 |     } | 
 |     switch (direntry->tdir_type) | 
 |     { | 
 |         case TIFF_SHORT: | 
 |         { | 
 |             uint16_t *ma; | 
 |             uint8_t *mb; | 
 |             uint32_t n; | 
 |             ma = (uint16_t *)origdata; | 
 |             mb = data; | 
 |             for (n = 0; n < count; n++) | 
 |             { | 
 |                 if (tif->tif_flags & TIFF_SWAB) | 
 |                     TIFFSwabShort(ma); | 
 |                 err = TIFFReadDirEntryCheckRangeByteShort(*ma); | 
 |                 if (err != TIFFReadDirEntryErrOk) | 
 |                     break; | 
 |                 *mb++ = (uint8_t)(*ma++); | 
 |             } | 
 |         } | 
 |         break; | 
 |         case TIFF_SSHORT: | 
 |         { | 
 |             int16_t *ma; | 
 |             uint8_t *mb; | 
 |             uint32_t n; | 
 |             ma = (int16_t *)origdata; | 
 |             mb = data; | 
 |             for (n = 0; n < count; n++) | 
 |             { | 
 |                 if (tif->tif_flags & TIFF_SWAB) | 
 |                     TIFFSwabShort((uint16_t *)ma); | 
 |                 err = TIFFReadDirEntryCheckRangeByteSshort(*ma); | 
 |                 if (err != TIFFReadDirEntryErrOk) | 
 |                     break; | 
 |                 *mb++ = (uint8_t)(*ma++); | 
 |             } | 
 |         } | 
 |         break; | 
 |         case TIFF_LONG: | 
 |         { | 
 |             uint32_t *ma; | 
 |             uint8_t *mb; | 
 |             uint32_t n; | 
 |             ma = (uint32_t *)origdata; | 
 |             mb = data; | 
 |             for (n = 0; n < count; n++) | 
 |             { | 
 |                 if (tif->tif_flags & TIFF_SWAB) | 
 |                     TIFFSwabLong(ma); | 
 |                 err = TIFFReadDirEntryCheckRangeByteLong(*ma); | 
 |                 if (err != TIFFReadDirEntryErrOk) | 
 |                     break; | 
 |                 *mb++ = (uint8_t)(*ma++); | 
 |             } | 
 |         } | 
 |         break; | 
 |         case TIFF_SLONG: | 
 |         { | 
 |             int32_t *ma; | 
 |             uint8_t *mb; | 
 |             uint32_t n; | 
 |             ma = (int32_t *)origdata; | 
 |             mb = data; | 
 |             for (n = 0; n < count; n++) | 
 |             { | 
 |                 if (tif->tif_flags & TIFF_SWAB) | 
 |                     TIFFSwabLong((uint32_t *)ma); | 
 |                 err = TIFFReadDirEntryCheckRangeByteSlong(*ma); | 
 |                 if (err != TIFFReadDirEntryErrOk) | 
 |                     break; | 
 |                 *mb++ = (uint8_t)(*ma++); | 
 |             } | 
 |         } | 
 |         break; | 
 |         case TIFF_LONG8: | 
 |         { | 
 |             uint64_t *ma; | 
 |             uint8_t *mb; | 
 |             uint32_t n; | 
 |             ma = (uint64_t *)origdata; | 
 |             mb = data; | 
 |             for (n = 0; n < count; n++) | 
 |             { | 
 |                 if (tif->tif_flags & TIFF_SWAB) | 
 |                     TIFFSwabLong8(ma); | 
 |                 err = TIFFReadDirEntryCheckRangeByteLong8(*ma); | 
 |                 if (err != TIFFReadDirEntryErrOk) | 
 |                     break; | 
 |                 *mb++ = (uint8_t)(*ma++); | 
 |             } | 
 |         } | 
 |         break; | 
 |         case TIFF_SLONG8: | 
 |         { | 
 |             int64_t *ma; | 
 |             uint8_t *mb; | 
 |             uint32_t n; | 
 |             ma = (int64_t *)origdata; | 
 |             mb = data; | 
 |             for (n = 0; n < count; n++) | 
 |             { | 
 |                 if (tif->tif_flags & TIFF_SWAB) | 
 |                     TIFFSwabLong8((uint64_t *)ma); | 
 |                 err = TIFFReadDirEntryCheckRangeByteSlong8(*ma); | 
 |                 if (err != TIFFReadDirEntryErrOk) | 
 |                     break; | 
 |                 *mb++ = (uint8_t)(*ma++); | 
 |             } | 
 |         } | 
 |         break; | 
 |     } | 
 |     _TIFFfreeExt(tif, origdata); | 
 |     if (err != TIFFReadDirEntryErrOk) | 
 |     { | 
 |         _TIFFfreeExt(tif, data); | 
 |         return (err); | 
 |     } | 
 |     *value = data; | 
 |     return (TIFFReadDirEntryErrOk); | 
 | } | 
 |  | 
 | static enum TIFFReadDirEntryErr | 
 | TIFFReadDirEntrySbyteArray(TIFF *tif, TIFFDirEntry *direntry, int8_t **value) | 
 | { | 
 |     enum TIFFReadDirEntryErr err; | 
 |     uint32_t count; | 
 |     void *origdata; | 
 |     int8_t *data; | 
 |     switch (direntry->tdir_type) | 
 |     { | 
 |         case TIFF_UNDEFINED: | 
 |         case TIFF_BYTE: | 
 |         case TIFF_SBYTE: | 
 |         case TIFF_SHORT: | 
 |         case TIFF_SSHORT: | 
 |         case TIFF_LONG: | 
 |         case TIFF_SLONG: | 
 |         case TIFF_LONG8: | 
 |         case TIFF_SLONG8: | 
 |             break; | 
 |         default: | 
 |             return (TIFFReadDirEntryErrType); | 
 |     } | 
 |     err = TIFFReadDirEntryArray(tif, direntry, &count, 1, &origdata); | 
 |     if ((err != TIFFReadDirEntryErrOk) || (origdata == 0)) | 
 |     { | 
 |         *value = 0; | 
 |         return (err); | 
 |     } | 
 |     switch (direntry->tdir_type) | 
 |     { | 
 |         case TIFF_UNDEFINED: | 
 |         case TIFF_BYTE: | 
 |         { | 
 |             uint8_t *m; | 
 |             uint32_t n; | 
 |             m = (uint8_t *)origdata; | 
 |             for (n = 0; n < count; n++) | 
 |             { | 
 |                 err = TIFFReadDirEntryCheckRangeSbyteByte(*m); | 
 |                 if (err != TIFFReadDirEntryErrOk) | 
 |                 { | 
 |                     _TIFFfreeExt(tif, origdata); | 
 |                     return (err); | 
 |                 } | 
 |                 m++; | 
 |             } | 
 |             *value = (int8_t *)origdata; | 
 |             return (TIFFReadDirEntryErrOk); | 
 |         } | 
 |         case TIFF_SBYTE: | 
 |             *value = (int8_t *)origdata; | 
 |             return (TIFFReadDirEntryErrOk); | 
 |     } | 
 |     data = (int8_t *)_TIFFmallocExt(tif, count); | 
 |     if (data == 0) | 
 |     { | 
 |         _TIFFfreeExt(tif, origdata); | 
 |         return (TIFFReadDirEntryErrAlloc); | 
 |     } | 
 |     switch (direntry->tdir_type) | 
 |     { | 
 |         case TIFF_SHORT: | 
 |         { | 
 |             uint16_t *ma; | 
 |             int8_t *mb; | 
 |             uint32_t n; | 
 |             ma = (uint16_t *)origdata; | 
 |             mb = data; | 
 |             for (n = 0; n < count; n++) | 
 |             { | 
 |                 if (tif->tif_flags & TIFF_SWAB) | 
 |                     TIFFSwabShort(ma); | 
 |                 err = TIFFReadDirEntryCheckRangeSbyteShort(*ma); | 
 |                 if (err != TIFFReadDirEntryErrOk) | 
 |                     break; | 
 |                 *mb++ = (int8_t)(*ma++); | 
 |             } | 
 |         } | 
 |         break; | 
 |         case TIFF_SSHORT: | 
 |         { | 
 |             int16_t *ma; | 
 |             int8_t *mb; | 
 |             uint32_t n; | 
 |             ma = (int16_t *)origdata; | 
 |             mb = data; | 
 |             for (n = 0; n < count; n++) | 
 |             { | 
 |                 if (tif->tif_flags & TIFF_SWAB) | 
 |                     TIFFSwabShort((uint16_t *)ma); | 
 |                 err = TIFFReadDirEntryCheckRangeSbyteSshort(*ma); | 
 |                 if (err != TIFFReadDirEntryErrOk) | 
 |                     break; | 
 |                 *mb++ = (int8_t)(*ma++); | 
 |             } | 
 |         } | 
 |         break; | 
 |         case TIFF_LONG: | 
 |         { | 
 |             uint32_t *ma; | 
 |             int8_t *mb; | 
 |             uint32_t n; | 
 |             ma = (uint32_t *)origdata; | 
 |             mb = data; | 
 |             for (n = 0; n < count; n++) | 
 |             { | 
 |                 if (tif->tif_flags & TIFF_SWAB) | 
 |                     TIFFSwabLong(ma); | 
 |                 err = TIFFReadDirEntryCheckRangeSbyteLong(*ma); | 
 |                 if (err != TIFFReadDirEntryErrOk) | 
 |                     break; | 
 |                 *mb++ = (int8_t)(*ma++); | 
 |             } | 
 |         } | 
 |         break; | 
 |         case TIFF_SLONG: | 
 |         { | 
 |             int32_t *ma; | 
 |             int8_t *mb; | 
 |             uint32_t n; | 
 |             ma = (int32_t *)origdata; | 
 |             mb = data; | 
 |             for (n = 0; n < count; n++) | 
 |             { | 
 |                 if (tif->tif_flags & TIFF_SWAB) | 
 |                     TIFFSwabLong((uint32_t *)ma); | 
 |                 err = TIFFReadDirEntryCheckRangeSbyteSlong(*ma); | 
 |                 if (err != TIFFReadDirEntryErrOk) | 
 |                     break; | 
 |                 *mb++ = (int8_t)(*ma++); | 
 |             } | 
 |         } | 
 |         break; | 
 |         case TIFF_LONG8: | 
 |         { | 
 |             uint64_t *ma; | 
 |             int8_t *mb; | 
 |             uint32_t n; | 
 |             ma = (uint64_t *)origdata; | 
 |             mb = data; | 
 |             for (n = 0; n < count; n++) | 
 |             { | 
 |                 if (tif->tif_flags & TIFF_SWAB) | 
 |                     TIFFSwabLong8(ma); | 
 |                 err = TIFFReadDirEntryCheckRangeSbyteLong8(*ma); | 
 |                 if (err != TIFFReadDirEntryErrOk) | 
 |                     break; | 
 |                 *mb++ = (int8_t)(*ma++); | 
 |             } | 
 |         } | 
 |         break; | 
 |         case TIFF_SLONG8: | 
 |         { | 
 |             int64_t *ma; | 
 |             int8_t *mb; | 
 |             uint32_t n; | 
 |             ma = (int64_t *)origdata; | 
 |             mb = data; | 
 |             for (n = 0; n < count; n++) | 
 |             { | 
 |                 if (tif->tif_flags & TIFF_SWAB) | 
 |                     TIFFSwabLong8((uint64_t *)ma); | 
 |                 err = TIFFReadDirEntryCheckRangeSbyteSlong8(*ma); | 
 |                 if (err != TIFFReadDirEntryErrOk) | 
 |                     break; | 
 |                 *mb++ = (int8_t)(*ma++); | 
 |             } | 
 |         } | 
 |         break; | 
 |     } | 
 |     _TIFFfreeExt(tif, origdata); | 
 |     if (err != TIFFReadDirEntryErrOk) | 
 |     { | 
 |         _TIFFfreeExt(tif, data); | 
 |         return (err); | 
 |     } | 
 |     *value = data; | 
 |     return (TIFFReadDirEntryErrOk); | 
 | } | 
 |  | 
 | static enum TIFFReadDirEntryErr | 
 | TIFFReadDirEntryShortArray(TIFF *tif, TIFFDirEntry *direntry, uint16_t **value) | 
 | { | 
 |     enum TIFFReadDirEntryErr err; | 
 |     uint32_t count; | 
 |     void *origdata; | 
 |     uint16_t *data; | 
 |     switch (direntry->tdir_type) | 
 |     { | 
 |         case TIFF_BYTE: | 
 |         case TIFF_SBYTE: | 
 |         case TIFF_SHORT: | 
 |         case TIFF_SSHORT: | 
 |         case TIFF_LONG: | 
 |         case TIFF_SLONG: | 
 |         case TIFF_LONG8: | 
 |         case TIFF_SLONG8: | 
 |             break; | 
 |         default: | 
 |             return (TIFFReadDirEntryErrType); | 
 |     } | 
 |     err = TIFFReadDirEntryArray(tif, direntry, &count, 2, &origdata); | 
 |     if ((err != TIFFReadDirEntryErrOk) || (origdata == 0)) | 
 |     { | 
 |         *value = 0; | 
 |         return (err); | 
 |     } | 
 |     switch (direntry->tdir_type) | 
 |     { | 
 |         case TIFF_SHORT: | 
 |             *value = (uint16_t *)origdata; | 
 |             if (tif->tif_flags & TIFF_SWAB) | 
 |                 TIFFSwabArrayOfShort(*value, count); | 
 |             return (TIFFReadDirEntryErrOk); | 
 |         case TIFF_SSHORT: | 
 |         { | 
 |             int16_t *m; | 
 |             uint32_t n; | 
 |             m = (int16_t *)origdata; | 
 |             for (n = 0; n < count; n++) | 
 |             { | 
 |                 if (tif->tif_flags & TIFF_SWAB) | 
 |                     TIFFSwabShort((uint16_t *)m); | 
 |                 err = TIFFReadDirEntryCheckRangeShortSshort(*m); | 
 |                 if (err != TIFFReadDirEntryErrOk) | 
 |                 { | 
 |                     _TIFFfreeExt(tif, origdata); | 
 |                     return (err); | 
 |                 } | 
 |                 m++; | 
 |             } | 
 |             *value = (uint16_t *)origdata; | 
 |             return (TIFFReadDirEntryErrOk); | 
 |         } | 
 |     } | 
 |     data = (uint16_t *)_TIFFmallocExt(tif, count * 2); | 
 |     if (data == 0) | 
 |     { | 
 |         _TIFFfreeExt(tif, origdata); | 
 |         return (TIFFReadDirEntryErrAlloc); | 
 |     } | 
 |     switch (direntry->tdir_type) | 
 |     { | 
 |         case TIFF_BYTE: | 
 |         { | 
 |             uint8_t *ma; | 
 |             uint16_t *mb; | 
 |             uint32_t n; | 
 |             ma = (uint8_t *)origdata; | 
 |             mb = data; | 
 |             for (n = 0; n < count; n++) | 
 |                 *mb++ = (uint16_t)(*ma++); | 
 |         } | 
 |         break; | 
 |         case TIFF_SBYTE: | 
 |         { | 
 |             int8_t *ma; | 
 |             uint16_t *mb; | 
 |             uint32_t n; | 
 |             ma = (int8_t *)origdata; | 
 |             mb = data; | 
 |             for (n = 0; n < count; n++) | 
 |             { | 
 |                 err = TIFFReadDirEntryCheckRangeShortSbyte(*ma); | 
 |                 if (err != TIFFReadDirEntryErrOk) | 
 |                     break; | 
 |                 *mb++ = (uint16_t)(*ma++); | 
 |             } | 
 |         } | 
 |         break; | 
 |         case TIFF_LONG: | 
 |         { | 
 |             uint32_t *ma; | 
 |             uint16_t *mb; | 
 |             uint32_t n; | 
 |             ma = (uint32_t *)origdata; | 
 |             mb = data; | 
 |             for (n = 0; n < count; n++) | 
 |             { | 
 |                 if (tif->tif_flags & TIFF_SWAB) | 
 |                     TIFFSwabLong(ma); | 
 |                 err = TIFFReadDirEntryCheckRangeShortLong(*ma); | 
 |                 if (err != TIFFReadDirEntryErrOk) | 
 |                     break; | 
 |                 *mb++ = (uint16_t)(*ma++); | 
 |             } | 
 |         } | 
 |         break; | 
 |         case TIFF_SLONG: | 
 |         { | 
 |             int32_t *ma; | 
 |             uint16_t *mb; | 
 |             uint32_t n; | 
 |             ma = (int32_t *)origdata; | 
 |             mb = data; | 
 |             for (n = 0; n < count; n++) | 
 |             { | 
 |                 if (tif->tif_flags & TIFF_SWAB) | 
 |                     TIFFSwabLong((uint32_t *)ma); | 
 |                 err = TIFFReadDirEntryCheckRangeShortSlong(*ma); | 
 |                 if (err != TIFFReadDirEntryErrOk) | 
 |                     break; | 
 |                 *mb++ = (uint16_t)(*ma++); | 
 |             } | 
 |         } | 
 |         break; | 
 |         case TIFF_LONG8: | 
 |         { | 
 |             uint64_t *ma; | 
 |             uint16_t *mb; | 
 |             uint32_t n; | 
 |             ma = (uint64_t *)origdata; | 
 |             mb = data; | 
 |             for (n = 0; n < count; n++) | 
 |             { | 
 |                 if (tif->tif_flags & TIFF_SWAB) | 
 |                     TIFFSwabLong8(ma); | 
 |                 err = TIFFReadDirEntryCheckRangeShortLong8(*ma); | 
 |                 if (err != TIFFReadDirEntryErrOk) | 
 |                     break; | 
 |                 *mb++ = (uint16_t)(*ma++); | 
 |             } | 
 |         } | 
 |         break; | 
 |         case TIFF_SLONG8: | 
 |         { | 
 |             int64_t *ma; | 
 |             uint16_t *mb; | 
 |             uint32_t n; | 
 |             ma = (int64_t *)origdata; | 
 |             mb = data; | 
 |             for (n = 0; n < count; n++) | 
 |             { | 
 |                 if (tif->tif_flags & TIFF_SWAB) | 
 |                     TIFFSwabLong8((uint64_t *)ma); | 
 |                 err = TIFFReadDirEntryCheckRangeShortSlong8(*ma); | 
 |                 if (err != TIFFReadDirEntryErrOk) | 
 |                     break; | 
 |                 *mb++ = (uint16_t)(*ma++); | 
 |             } | 
 |         } | 
 |         break; | 
 |     } | 
 |     _TIFFfreeExt(tif, origdata); | 
 |     if (err != TIFFReadDirEntryErrOk) | 
 |     { | 
 |         _TIFFfreeExt(tif, data); | 
 |         return (err); | 
 |     } | 
 |     *value = data; | 
 |     return (TIFFReadDirEntryErrOk); | 
 | } | 
 |  | 
 | static enum TIFFReadDirEntryErr | 
 | TIFFReadDirEntrySshortArray(TIFF *tif, TIFFDirEntry *direntry, int16_t **value) | 
 | { | 
 |     enum TIFFReadDirEntryErr err; | 
 |     uint32_t count; | 
 |     void *origdata; | 
 |     int16_t *data; | 
 |     switch (direntry->tdir_type) | 
 |     { | 
 |         case TIFF_BYTE: | 
 |         case TIFF_SBYTE: | 
 |         case TIFF_SHORT: | 
 |         case TIFF_SSHORT: | 
 |         case TIFF_LONG: | 
 |         case TIFF_SLONG: | 
 |         case TIFF_LONG8: | 
 |         case TIFF_SLONG8: | 
 |             break; | 
 |         default: | 
 |             return (TIFFReadDirEntryErrType); | 
 |     } | 
 |     err = TIFFReadDirEntryArray(tif, direntry, &count, 2, &origdata); | 
 |     if ((err != TIFFReadDirEntryErrOk) || (origdata == 0)) | 
 |     { | 
 |         *value = 0; | 
 |         return (err); | 
 |     } | 
 |     switch (direntry->tdir_type) | 
 |     { | 
 |         case TIFF_SHORT: | 
 |         { | 
 |             uint16_t *m; | 
 |             uint32_t n; | 
 |             m = (uint16_t *)origdata; | 
 |             for (n = 0; n < count; n++) | 
 |             { | 
 |                 if (tif->tif_flags & TIFF_SWAB) | 
 |                     TIFFSwabShort(m); | 
 |                 err = TIFFReadDirEntryCheckRangeSshortShort(*m); | 
 |                 if (err != TIFFReadDirEntryErrOk) | 
 |                 { | 
 |                     _TIFFfreeExt(tif, origdata); | 
 |                     return (err); | 
 |                 } | 
 |                 m++; | 
 |             } | 
 |             *value = (int16_t *)origdata; | 
 |             return (TIFFReadDirEntryErrOk); | 
 |         } | 
 |         case TIFF_SSHORT: | 
 |             *value = (int16_t *)origdata; | 
 |             if (tif->tif_flags & TIFF_SWAB) | 
 |                 TIFFSwabArrayOfShort((uint16_t *)(*value), count); | 
 |             return (TIFFReadDirEntryErrOk); | 
 |     } | 
 |     data = (int16_t *)_TIFFmallocExt(tif, count * 2); | 
 |     if (data == 0) | 
 |     { | 
 |         _TIFFfreeExt(tif, origdata); | 
 |         return (TIFFReadDirEntryErrAlloc); | 
 |     } | 
 |     switch (direntry->tdir_type) | 
 |     { | 
 |         case TIFF_BYTE: | 
 |         { | 
 |             uint8_t *ma; | 
 |             int16_t *mb; | 
 |             uint32_t n; | 
 |             ma = (uint8_t *)origdata; | 
 |             mb = data; | 
 |             for (n = 0; n < count; n++) | 
 |                 *mb++ = (int16_t)(*ma++); | 
 |         } | 
 |         break; | 
 |         case TIFF_SBYTE: | 
 |         { | 
 |             int8_t *ma; | 
 |             int16_t *mb; | 
 |             uint32_t n; | 
 |             ma = (int8_t *)origdata; | 
 |             mb = data; | 
 |             for (n = 0; n < count; n++) | 
 |                 *mb++ = (int16_t)(*ma++); | 
 |         } | 
 |         break; | 
 |         case TIFF_LONG: | 
 |         { | 
 |             uint32_t *ma; | 
 |             int16_t *mb; | 
 |             uint32_t n; | 
 |             ma = (uint32_t *)origdata; | 
 |             mb = data; | 
 |             for (n = 0; n < count; n++) | 
 |             { | 
 |                 if (tif->tif_flags & TIFF_SWAB) | 
 |                     TIFFSwabLong(ma); | 
 |                 err = TIFFReadDirEntryCheckRangeSshortLong(*ma); | 
 |                 if (err != TIFFReadDirEntryErrOk) | 
 |                     break; | 
 |                 *mb++ = (int16_t)(*ma++); | 
 |             } | 
 |         } | 
 |         break; | 
 |         case TIFF_SLONG: | 
 |         { | 
 |             int32_t *ma; | 
 |             int16_t *mb; | 
 |             uint32_t n; | 
 |             ma = (int32_t *)origdata; | 
 |             mb = data; | 
 |             for (n = 0; n < count; n++) | 
 |             { | 
 |                 if (tif->tif_flags & TIFF_SWAB) | 
 |                     TIFFSwabLong((uint32_t *)ma); | 
 |                 err = TIFFReadDirEntryCheckRangeSshortSlong(*ma); | 
 |                 if (err != TIFFReadDirEntryErrOk) | 
 |                     break; | 
 |                 *mb++ = (int16_t)(*ma++); | 
 |             } | 
 |         } | 
 |         break; | 
 |         case TIFF_LONG8: | 
 |         { | 
 |             uint64_t *ma; | 
 |             int16_t *mb; | 
 |             uint32_t n; | 
 |             ma = (uint64_t *)origdata; | 
 |             mb = data; | 
 |             for (n = 0; n < count; n++) | 
 |             { | 
 |                 if (tif->tif_flags & TIFF_SWAB) | 
 |                     TIFFSwabLong8(ma); | 
 |                 err = TIFFReadDirEntryCheckRangeSshortLong8(*ma); | 
 |                 if (err != TIFFReadDirEntryErrOk) | 
 |                     break; | 
 |                 *mb++ = (int16_t)(*ma++); | 
 |             } | 
 |         } | 
 |         break; | 
 |         case TIFF_SLONG8: | 
 |         { | 
 |             int64_t *ma; | 
 |             int16_t *mb; | 
 |             uint32_t n; | 
 |             ma = (int64_t *)origdata; | 
 |             mb = data; | 
 |             for (n = 0; n < count; n++) | 
 |             { | 
 |                 if (tif->tif_flags & TIFF_SWAB) | 
 |                     TIFFSwabLong8((uint64_t *)ma); | 
 |                 err = TIFFReadDirEntryCheckRangeSshortSlong8(*ma); | 
 |                 if (err != TIFFReadDirEntryErrOk) | 
 |                     break; | 
 |                 *mb++ = (int16_t)(*ma++); | 
 |             } | 
 |         } | 
 |         break; | 
 |     } | 
 |     _TIFFfreeExt(tif, origdata); | 
 |     if (err != TIFFReadDirEntryErrOk) | 
 |     { | 
 |         _TIFFfreeExt(tif, data); | 
 |         return (err); | 
 |     } | 
 |     *value = data; | 
 |     return (TIFFReadDirEntryErrOk); | 
 | } | 
 |  | 
 | static enum TIFFReadDirEntryErr | 
 | TIFFReadDirEntryLongArray(TIFF *tif, TIFFDirEntry *direntry, uint32_t **value) | 
 | { | 
 |     enum TIFFReadDirEntryErr err; | 
 |     uint32_t count; | 
 |     void *origdata; | 
 |     uint32_t *data; | 
 |     switch (direntry->tdir_type) | 
 |     { | 
 |         case TIFF_BYTE: | 
 |         case TIFF_SBYTE: | 
 |         case TIFF_SHORT: | 
 |         case TIFF_SSHORT: | 
 |         case TIFF_LONG: | 
 |         case TIFF_SLONG: | 
 |         case TIFF_LONG8: | 
 |         case TIFF_SLONG8: | 
 |             break; | 
 |         default: | 
 |             return (TIFFReadDirEntryErrType); | 
 |     } | 
 |     err = TIFFReadDirEntryArray(tif, direntry, &count, 4, &origdata); | 
 |     if ((err != TIFFReadDirEntryErrOk) || (origdata == 0)) | 
 |     { | 
 |         *value = 0; | 
 |         return (err); | 
 |     } | 
 |     switch (direntry->tdir_type) | 
 |     { | 
 |         case TIFF_LONG: | 
 |             *value = (uint32_t *)origdata; | 
 |             if (tif->tif_flags & TIFF_SWAB) | 
 |                 TIFFSwabArrayOfLong(*value, count); | 
 |             return (TIFFReadDirEntryErrOk); | 
 |         case TIFF_SLONG: | 
 |         { | 
 |             int32_t *m; | 
 |             uint32_t n; | 
 |             m = (int32_t *)origdata; | 
 |             for (n = 0; n < count; n++) | 
 |             { | 
 |                 if (tif->tif_flags & TIFF_SWAB) | 
 |                     TIFFSwabLong((uint32_t *)m); | 
 |                 err = TIFFReadDirEntryCheckRangeLongSlong(*m); | 
 |                 if (err != TIFFReadDirEntryErrOk) | 
 |                 { | 
 |                     _TIFFfreeExt(tif, origdata); | 
 |                     return (err); | 
 |                 } | 
 |                 m++; | 
 |             } | 
 |             *value = (uint32_t *)origdata; | 
 |             return (TIFFReadDirEntryErrOk); | 
 |         } | 
 |     } | 
 |     data = (uint32_t *)_TIFFmallocExt(tif, count * 4); | 
 |     if (data == 0) | 
 |     { | 
 |         _TIFFfreeExt(tif, origdata); | 
 |         return (TIFFReadDirEntryErrAlloc); | 
 |     } | 
 |     switch (direntry->tdir_type) | 
 |     { | 
 |         case TIFF_BYTE: | 
 |         { | 
 |             uint8_t *ma; | 
 |             uint32_t *mb; | 
 |             uint32_t n; | 
 |             ma = (uint8_t *)origdata; | 
 |             mb = data; | 
 |             for (n = 0; n < count; n++) | 
 |                 *mb++ = (uint32_t)(*ma++); | 
 |         } | 
 |         break; | 
 |         case TIFF_SBYTE: | 
 |         { | 
 |             int8_t *ma; | 
 |             uint32_t *mb; | 
 |             uint32_t n; | 
 |             ma = (int8_t *)origdata; | 
 |             mb = data; | 
 |             for (n = 0; n < count; n++) | 
 |             { | 
 |                 err = TIFFReadDirEntryCheckRangeLongSbyte(*ma); | 
 |                 if (err != TIFFReadDirEntryErrOk) | 
 |                     break; | 
 |                 *mb++ = (uint32_t)(*ma++); | 
 |             } | 
 |         } | 
 |         break; | 
 |         case TIFF_SHORT: | 
 |         { | 
 |             uint16_t *ma; | 
 |             uint32_t *mb; | 
 |             uint32_t n; | 
 |             ma = (uint16_t *)origdata; | 
 |             mb = data; | 
 |             for (n = 0; n < count; n++) | 
 |             { | 
 |                 if (tif->tif_flags & TIFF_SWAB) | 
 |                     TIFFSwabShort(ma); | 
 |                 *mb++ = (uint32_t)(*ma++); | 
 |             } | 
 |         } | 
 |         break; | 
 |         case TIFF_SSHORT: | 
 |         { | 
 |             int16_t *ma; | 
 |             uint32_t *mb; | 
 |             uint32_t n; | 
 |             ma = (int16_t *)origdata; | 
 |             mb = data; | 
 |             for (n = 0; n < count; n++) | 
 |             { | 
 |                 if (tif->tif_flags & TIFF_SWAB) | 
 |                     TIFFSwabShort((uint16_t *)ma); | 
 |                 err = TIFFReadDirEntryCheckRangeLongSshort(*ma); | 
 |                 if (err != TIFFReadDirEntryErrOk) | 
 |                     break; | 
 |                 *mb++ = (uint32_t)(*ma++); | 
 |             } | 
 |         } | 
 |         break; | 
 |         case TIFF_LONG8: | 
 |         { | 
 |             uint64_t *ma; | 
 |             uint32_t *mb; | 
 |             uint32_t n; | 
 |             ma = (uint64_t *)origdata; | 
 |             mb = data; | 
 |             for (n = 0; n < count; n++) | 
 |             { | 
 |                 if (tif->tif_flags & TIFF_SWAB) | 
 |                     TIFFSwabLong8(ma); | 
 |                 err = TIFFReadDirEntryCheckRangeLongLong8(*ma); | 
 |                 if (err != TIFFReadDirEntryErrOk) | 
 |                     break; | 
 |                 *mb++ = (uint32_t)(*ma++); | 
 |             } | 
 |         } | 
 |         break; | 
 |         case TIFF_SLONG8: | 
 |         { | 
 |             int64_t *ma; | 
 |             uint32_t *mb; | 
 |             uint32_t n; | 
 |             ma = (int64_t *)origdata; | 
 |             mb = data; | 
 |             for (n = 0; n < count; n++) | 
 |             { | 
 |                 if (tif->tif_flags & TIFF_SWAB) | 
 |                     TIFFSwabLong8((uint64_t *)ma); | 
 |                 err = TIFFReadDirEntryCheckRangeLongSlong8(*ma); | 
 |                 if (err != TIFFReadDirEntryErrOk) | 
 |                     break; | 
 |                 *mb++ = (uint32_t)(*ma++); | 
 |             } | 
 |         } | 
 |         break; | 
 |     } | 
 |     _TIFFfreeExt(tif, origdata); | 
 |     if (err != TIFFReadDirEntryErrOk) | 
 |     { | 
 |         _TIFFfreeExt(tif, data); | 
 |         return (err); | 
 |     } | 
 |     *value = data; | 
 |     return (TIFFReadDirEntryErrOk); | 
 | } | 
 |  | 
 | static enum TIFFReadDirEntryErr | 
 | TIFFReadDirEntrySlongArray(TIFF *tif, TIFFDirEntry *direntry, int32_t **value) | 
 | { | 
 |     enum TIFFReadDirEntryErr err; | 
 |     uint32_t count; | 
 |     void *origdata; | 
 |     int32_t *data; | 
 |     switch (direntry->tdir_type) | 
 |     { | 
 |         case TIFF_BYTE: | 
 |         case TIFF_SBYTE: | 
 |         case TIFF_SHORT: | 
 |         case TIFF_SSHORT: | 
 |         case TIFF_LONG: | 
 |         case TIFF_SLONG: | 
 |         case TIFF_LONG8: | 
 |         case TIFF_SLONG8: | 
 |             break; | 
 |         default: | 
 |             return (TIFFReadDirEntryErrType); | 
 |     } | 
 |     err = TIFFReadDirEntryArray(tif, direntry, &count, 4, &origdata); | 
 |     if ((err != TIFFReadDirEntryErrOk) || (origdata == 0)) | 
 |     { | 
 |         *value = 0; | 
 |         return (err); | 
 |     } | 
 |     switch (direntry->tdir_type) | 
 |     { | 
 |         case TIFF_LONG: | 
 |         { | 
 |             uint32_t *m; | 
 |             uint32_t n; | 
 |             m = (uint32_t *)origdata; | 
 |             for (n = 0; n < count; n++) | 
 |             { | 
 |                 if (tif->tif_flags & TIFF_SWAB) | 
 |                     TIFFSwabLong((uint32_t *)m); | 
 |                 err = TIFFReadDirEntryCheckRangeSlongLong(*m); | 
 |                 if (err != TIFFReadDirEntryErrOk) | 
 |                 { | 
 |                     _TIFFfreeExt(tif, origdata); | 
 |                     return (err); | 
 |                 } | 
 |                 m++; | 
 |             } | 
 |             *value = (int32_t *)origdata; | 
 |             return (TIFFReadDirEntryErrOk); | 
 |         } | 
 |         case TIFF_SLONG: | 
 |             *value = (int32_t *)origdata; | 
 |             if (tif->tif_flags & TIFF_SWAB) | 
 |                 TIFFSwabArrayOfLong((uint32_t *)(*value), count); | 
 |             return (TIFFReadDirEntryErrOk); | 
 |     } | 
 |     data = (int32_t *)_TIFFmallocExt(tif, count * 4); | 
 |     if (data == 0) | 
 |     { | 
 |         _TIFFfreeExt(tif, origdata); | 
 |         return (TIFFReadDirEntryErrAlloc); | 
 |     } | 
 |     switch (direntry->tdir_type) | 
 |     { | 
 |         case TIFF_BYTE: | 
 |         { | 
 |             uint8_t *ma; | 
 |             int32_t *mb; | 
 |             uint32_t n; | 
 |             ma = (uint8_t *)origdata; | 
 |             mb = data; | 
 |             for (n = 0; n < count; n++) | 
 |                 *mb++ = (int32_t)(*ma++); | 
 |         } | 
 |         break; | 
 |         case TIFF_SBYTE: | 
 |         { | 
 |             int8_t *ma; | 
 |             int32_t *mb; | 
 |             uint32_t n; | 
 |             ma = (int8_t *)origdata; | 
 |             mb = data; | 
 |             for (n = 0; n < count; n++) | 
 |                 *mb++ = (int32_t)(*ma++); | 
 |         } | 
 |         break; | 
 |         case TIFF_SHORT: | 
 |         { | 
 |             uint16_t *ma; | 
 |             int32_t *mb; | 
 |             uint32_t n; | 
 |             ma = (uint16_t *)origdata; | 
 |             mb = data; | 
 |             for (n = 0; n < count; n++) | 
 |             { | 
 |                 if (tif->tif_flags & TIFF_SWAB) | 
 |                     TIFFSwabShort(ma); | 
 |                 *mb++ = (int32_t)(*ma++); | 
 |             } | 
 |         } | 
 |         break; | 
 |         case TIFF_SSHORT: | 
 |         { | 
 |             int16_t *ma; | 
 |             int32_t *mb; | 
 |             uint32_t n; | 
 |             ma = (int16_t *)origdata; | 
 |             mb = data; | 
 |             for (n = 0; n < count; n++) | 
 |             { | 
 |                 if (tif->tif_flags & TIFF_SWAB) | 
 |                     TIFFSwabShort((uint16_t *)ma); | 
 |                 *mb++ = (int32_t)(*ma++); | 
 |             } | 
 |         } | 
 |         break; | 
 |         case TIFF_LONG8: | 
 |         { | 
 |             uint64_t *ma; | 
 |             int32_t *mb; | 
 |             uint32_t n; | 
 |             ma = (uint64_t *)origdata; | 
 |             mb = data; | 
 |             for (n = 0; n < count; n++) | 
 |             { | 
 |                 if (tif->tif_flags & TIFF_SWAB) | 
 |                     TIFFSwabLong8(ma); | 
 |                 err = TIFFReadDirEntryCheckRangeSlongLong8(*ma); | 
 |                 if (err != TIFFReadDirEntryErrOk) | 
 |                     break; | 
 |                 *mb++ = (int32_t)(*ma++); | 
 |             } | 
 |         } | 
 |         break; | 
 |         case TIFF_SLONG8: | 
 |         { | 
 |             int64_t *ma; | 
 |             int32_t *mb; | 
 |             uint32_t n; | 
 |             ma = (int64_t *)origdata; | 
 |             mb = data; | 
 |             for (n = 0; n < count; n++) | 
 |             { | 
 |                 if (tif->tif_flags & TIFF_SWAB) | 
 |                     TIFFSwabLong8((uint64_t *)ma); | 
 |                 err = TIFFReadDirEntryCheckRangeSlongSlong8(*ma); | 
 |                 if (err != TIFFReadDirEntryErrOk) | 
 |                     break; | 
 |                 *mb++ = (int32_t)(*ma++); | 
 |             } | 
 |         } | 
 |         break; | 
 |     } | 
 |     _TIFFfreeExt(tif, origdata); | 
 |     if (err != TIFFReadDirEntryErrOk) | 
 |     { | 
 |         _TIFFfreeExt(tif, data); | 
 |         return (err); | 
 |     } | 
 |     *value = data; | 
 |     return (TIFFReadDirEntryErrOk); | 
 | } | 
 |  | 
 | static enum TIFFReadDirEntryErr | 
 | TIFFReadDirEntryLong8ArrayWithLimit(TIFF *tif, TIFFDirEntry *direntry, | 
 |                                     uint64_t **value, uint64_t maxcount) | 
 | { | 
 |     enum TIFFReadDirEntryErr err; | 
 |     uint32_t count; | 
 |     void *origdata; | 
 |     uint64_t *data; | 
 |     switch (direntry->tdir_type) | 
 |     { | 
 |         case TIFF_BYTE: | 
 |         case TIFF_SBYTE: | 
 |         case TIFF_SHORT: | 
 |         case TIFF_SSHORT: | 
 |         case TIFF_LONG: | 
 |         case TIFF_SLONG: | 
 |         case TIFF_LONG8: | 
 |         case TIFF_SLONG8: | 
 |             break; | 
 |         default: | 
 |             return (TIFFReadDirEntryErrType); | 
 |     } | 
 |     err = TIFFReadDirEntryArrayWithLimit(tif, direntry, &count, 8, &origdata, | 
 |                                          maxcount); | 
 |     if ((err != TIFFReadDirEntryErrOk) || (origdata == 0)) | 
 |     { | 
 |         *value = 0; | 
 |         return (err); | 
 |     } | 
 |     switch (direntry->tdir_type) | 
 |     { | 
 |         case TIFF_LONG8: | 
 |             *value = (uint64_t *)origdata; | 
 |             if (tif->tif_flags & TIFF_SWAB) | 
 |                 TIFFSwabArrayOfLong8(*value, count); | 
 |             return (TIFFReadDirEntryErrOk); | 
 |         case TIFF_SLONG8: | 
 |         { | 
 |             int64_t *m; | 
 |             uint32_t n; | 
 |             m = (int64_t *)origdata; | 
 |             for (n = 0; n < count; n++) | 
 |             { | 
 |                 if (tif->tif_flags & TIFF_SWAB) | 
 |                     TIFFSwabLong8((uint64_t *)m); | 
 |                 err = TIFFReadDirEntryCheckRangeLong8Slong8(*m); | 
 |                 if (err != TIFFReadDirEntryErrOk) | 
 |                 { | 
 |                     _TIFFfreeExt(tif, origdata); | 
 |                     return (err); | 
 |                 } | 
 |                 m++; | 
 |             } | 
 |             *value = (uint64_t *)origdata; | 
 |             return (TIFFReadDirEntryErrOk); | 
 |         } | 
 |     } | 
 |     data = (uint64_t *)_TIFFmallocExt(tif, count * 8); | 
 |     if (data == 0) | 
 |     { | 
 |         _TIFFfreeExt(tif, origdata); | 
 |         return (TIFFReadDirEntryErrAlloc); | 
 |     } | 
 |     switch (direntry->tdir_type) | 
 |     { | 
 |         case TIFF_BYTE: | 
 |         { | 
 |             uint8_t *ma; | 
 |             uint64_t *mb; | 
 |             uint32_t n; | 
 |             ma = (uint8_t *)origdata; | 
 |             mb = data; | 
 |             for (n = 0; n < count; n++) | 
 |                 *mb++ = (uint64_t)(*ma++); | 
 |         } | 
 |         break; | 
 |         case TIFF_SBYTE: | 
 |         { | 
 |             int8_t *ma; | 
 |             uint64_t *mb; | 
 |             uint32_t n; | 
 |             ma = (int8_t *)origdata; | 
 |             mb = data; | 
 |             for (n = 0; n < count; n++) | 
 |             { | 
 |                 err = TIFFReadDirEntryCheckRangeLong8Sbyte(*ma); | 
 |                 if (err != TIFFReadDirEntryErrOk) | 
 |                     break; | 
 |                 *mb++ = (uint64_t)(*ma++); | 
 |             } | 
 |         } | 
 |         break; | 
 |         case TIFF_SHORT: | 
 |         { | 
 |             uint16_t *ma; | 
 |             uint64_t *mb; | 
 |             uint32_t n; | 
 |             ma = (uint16_t *)origdata; | 
 |             mb = data; | 
 |             for (n = 0; n < count; n++) | 
 |             { | 
 |                 if (tif->tif_flags & TIFF_SWAB) | 
 |                     TIFFSwabShort(ma); | 
 |                 *mb++ = (uint64_t)(*ma++); | 
 |             } | 
 |         } | 
 |         break; | 
 |         case TIFF_SSHORT: | 
 |         { | 
 |             int16_t *ma; | 
 |             uint64_t *mb; | 
 |             uint32_t n; | 
 |             ma = (int16_t *)origdata; | 
 |             mb = data; | 
 |             for (n = 0; n < count; n++) | 
 |             { | 
 |                 if (tif->tif_flags & TIFF_SWAB) | 
 |                     TIFFSwabShort((uint16_t *)ma); | 
 |                 err = TIFFReadDirEntryCheckRangeLong8Sshort(*ma); | 
 |                 if (err != TIFFReadDirEntryErrOk) | 
 |                     break; | 
 |                 *mb++ = (uint64_t)(*ma++); | 
 |             } | 
 |         } | 
 |         break; | 
 |         case TIFF_LONG: | 
 |         { | 
 |             uint32_t *ma; | 
 |             uint64_t *mb; | 
 |             uint32_t n; | 
 |             ma = (uint32_t *)origdata; | 
 |             mb = data; | 
 |             for (n = 0; n < count; n++) | 
 |             { | 
 |                 if (tif->tif_flags & TIFF_SWAB) | 
 |                     TIFFSwabLong(ma); | 
 |                 *mb++ = (uint64_t)(*ma++); | 
 |             } | 
 |         } | 
 |         break; | 
 |         case TIFF_SLONG: | 
 |         { | 
 |             int32_t *ma; | 
 |             uint64_t *mb; | 
 |             uint32_t n; | 
 |             ma = (int32_t *)origdata; | 
 |             mb = data; | 
 |             for (n = 0; n < count; n++) | 
 |             { | 
 |                 if (tif->tif_flags & TIFF_SWAB) | 
 |                     TIFFSwabLong((uint32_t *)ma); | 
 |                 err = TIFFReadDirEntryCheckRangeLong8Slong(*ma); | 
 |                 if (err != TIFFReadDirEntryErrOk) | 
 |                     break; | 
 |                 *mb++ = (uint64_t)(*ma++); | 
 |             } | 
 |         } | 
 |         break; | 
 |     } | 
 |     _TIFFfreeExt(tif, origdata); | 
 |     if (err != TIFFReadDirEntryErrOk) | 
 |     { | 
 |         _TIFFfreeExt(tif, data); | 
 |         return (err); | 
 |     } | 
 |     *value = data; | 
 |     return (TIFFReadDirEntryErrOk); | 
 | } | 
 |  | 
 | static enum TIFFReadDirEntryErr | 
 | TIFFReadDirEntryLong8Array(TIFF *tif, TIFFDirEntry *direntry, uint64_t **value) | 
 | { | 
 |     return TIFFReadDirEntryLong8ArrayWithLimit(tif, direntry, value, | 
 |                                                ~((uint64_t)0)); | 
 | } | 
 |  | 
 | static enum TIFFReadDirEntryErr | 
 | TIFFReadDirEntrySlong8Array(TIFF *tif, TIFFDirEntry *direntry, int64_t **value) | 
 | { | 
 |     enum TIFFReadDirEntryErr err; | 
 |     uint32_t count; | 
 |     void *origdata; | 
 |     int64_t *data; | 
 |     switch (direntry->tdir_type) | 
 |     { | 
 |         case TIFF_BYTE: | 
 |         case TIFF_SBYTE: | 
 |         case TIFF_SHORT: | 
 |         case TIFF_SSHORT: | 
 |         case TIFF_LONG: | 
 |         case TIFF_SLONG: | 
 |         case TIFF_LONG8: | 
 |         case TIFF_SLONG8: | 
 |             break; | 
 |         default: | 
 |             return (TIFFReadDirEntryErrType); | 
 |     } | 
 |     err = TIFFReadDirEntryArray(tif, direntry, &count, 8, &origdata); | 
 |     if ((err != TIFFReadDirEntryErrOk) || (origdata == 0)) | 
 |     { | 
 |         *value = 0; | 
 |         return (err); | 
 |     } | 
 |     switch (direntry->tdir_type) | 
 |     { | 
 |         case TIFF_LONG8: | 
 |         { | 
 |             uint64_t *m; | 
 |             uint32_t n; | 
 |             m = (uint64_t *)origdata; | 
 |             for (n = 0; n < count; n++) | 
 |             { | 
 |                 if (tif->tif_flags & TIFF_SWAB) | 
 |                     TIFFSwabLong8(m); | 
 |                 err = TIFFReadDirEntryCheckRangeSlong8Long8(*m); | 
 |                 if (err != TIFFReadDirEntryErrOk) | 
 |                 { | 
 |                     _TIFFfreeExt(tif, origdata); | 
 |                     return (err); | 
 |                 } | 
 |                 m++; | 
 |             } | 
 |             *value = (int64_t *)origdata; | 
 |             return (TIFFReadDirEntryErrOk); | 
 |         } | 
 |         case TIFF_SLONG8: | 
 |             *value = (int64_t *)origdata; | 
 |             if (tif->tif_flags & TIFF_SWAB) | 
 |                 TIFFSwabArrayOfLong8((uint64_t *)(*value), count); | 
 |             return (TIFFReadDirEntryErrOk); | 
 |     } | 
 |     data = (int64_t *)_TIFFmallocExt(tif, count * 8); | 
 |     if (data == 0) | 
 |     { | 
 |         _TIFFfreeExt(tif, origdata); | 
 |         return (TIFFReadDirEntryErrAlloc); | 
 |     } | 
 |     switch (direntry->tdir_type) | 
 |     { | 
 |         case TIFF_BYTE: | 
 |         { | 
 |             uint8_t *ma; | 
 |             int64_t *mb; | 
 |             uint32_t n; | 
 |             ma = (uint8_t *)origdata; | 
 |             mb = data; | 
 |             for (n = 0; n < count; n++) | 
 |                 *mb++ = (int64_t)(*ma++); | 
 |         } | 
 |         break; | 
 |         case TIFF_SBYTE: | 
 |         { | 
 |             int8_t *ma; | 
 |             int64_t *mb; | 
 |             uint32_t n; | 
 |             ma = (int8_t *)origdata; | 
 |             mb = data; | 
 |             for (n = 0; n < count; n++) | 
 |                 *mb++ = (int64_t)(*ma++); | 
 |         } | 
 |         break; | 
 |         case TIFF_SHORT: | 
 |         { | 
 |             uint16_t *ma; | 
 |             int64_t *mb; | 
 |             uint32_t n; | 
 |             ma = (uint16_t *)origdata; | 
 |             mb = data; | 
 |             for (n = 0; n < count; n++) | 
 |             { | 
 |                 if (tif->tif_flags & TIFF_SWAB) | 
 |                     TIFFSwabShort(ma); | 
 |                 *mb++ = (int64_t)(*ma++); | 
 |             } | 
 |         } | 
 |         break; | 
 |         case TIFF_SSHORT: | 
 |         { | 
 |             int16_t *ma; | 
 |             int64_t *mb; | 
 |             uint32_t n; | 
 |             ma = (int16_t *)origdata; | 
 |             mb = data; | 
 |             for (n = 0; n < count; n++) | 
 |             { | 
 |                 if (tif->tif_flags & TIFF_SWAB) | 
 |                     TIFFSwabShort((uint16_t *)ma); | 
 |                 *mb++ = (int64_t)(*ma++); | 
 |             } | 
 |         } | 
 |         break; | 
 |         case TIFF_LONG: | 
 |         { | 
 |             uint32_t *ma; | 
 |             int64_t *mb; | 
 |             uint32_t n; | 
 |             ma = (uint32_t *)origdata; | 
 |             mb = data; | 
 |             for (n = 0; n < count; n++) | 
 |             { | 
 |                 if (tif->tif_flags & TIFF_SWAB) | 
 |                     TIFFSwabLong(ma); | 
 |                 *mb++ = (int64_t)(*ma++); | 
 |             } | 
 |         } | 
 |         break; | 
 |         case TIFF_SLONG: | 
 |         { | 
 |             int32_t *ma; | 
 |             int64_t *mb; | 
 |             uint32_t n; | 
 |             ma = (int32_t *)origdata; | 
 |             mb = data; | 
 |             for (n = 0; n < count; n++) | 
 |             { | 
 |                 if (tif->tif_flags & TIFF_SWAB) | 
 |                     TIFFSwabLong((uint32_t *)ma); | 
 |                 *mb++ = (int64_t)(*ma++); | 
 |             } | 
 |         } | 
 |         break; | 
 |     } | 
 |     _TIFFfreeExt(tif, origdata); | 
 |     *value = data; | 
 |     return (TIFFReadDirEntryErrOk); | 
 | } | 
 |  | 
 | static enum TIFFReadDirEntryErr | 
 | TIFFReadDirEntryFloatArray(TIFF *tif, TIFFDirEntry *direntry, float **value) | 
 | { | 
 |     enum TIFFReadDirEntryErr err; | 
 |     uint32_t count; | 
 |     void *origdata; | 
 |     float *data; | 
 |     switch (direntry->tdir_type) | 
 |     { | 
 |         case TIFF_BYTE: | 
 |         case TIFF_SBYTE: | 
 |         case TIFF_SHORT: | 
 |         case TIFF_SSHORT: | 
 |         case TIFF_LONG: | 
 |         case TIFF_SLONG: | 
 |         case TIFF_LONG8: | 
 |         case TIFF_SLONG8: | 
 |         case TIFF_RATIONAL: | 
 |         case TIFF_SRATIONAL: | 
 |         case TIFF_FLOAT: | 
 |         case TIFF_DOUBLE: | 
 |             break; | 
 |         default: | 
 |             return (TIFFReadDirEntryErrType); | 
 |     } | 
 |     err = TIFFReadDirEntryArray(tif, direntry, &count, 4, &origdata); | 
 |     if ((err != TIFFReadDirEntryErrOk) || (origdata == 0)) | 
 |     { | 
 |         *value = 0; | 
 |         return (err); | 
 |     } | 
 |     switch (direntry->tdir_type) | 
 |     { | 
 |         case TIFF_FLOAT: | 
 |             if (tif->tif_flags & TIFF_SWAB) | 
 |                 TIFFSwabArrayOfLong((uint32_t *)origdata, count); | 
 |             TIFFCvtIEEEDoubleToNative(tif, count, (float *)origdata); | 
 |             *value = (float *)origdata; | 
 |             return (TIFFReadDirEntryErrOk); | 
 |     } | 
 |     data = (float *)_TIFFmallocExt(tif, count * sizeof(float)); | 
 |     if (data == 0) | 
 |     { | 
 |         _TIFFfreeExt(tif, origdata); | 
 |         return (TIFFReadDirEntryErrAlloc); | 
 |     } | 
 |     switch (direntry->tdir_type) | 
 |     { | 
 |         case TIFF_BYTE: | 
 |         { | 
 |             uint8_t *ma; | 
 |             float *mb; | 
 |             uint32_t n; | 
 |             ma = (uint8_t *)origdata; | 
 |             mb = data; | 
 |             for (n = 0; n < count; n++) | 
 |                 *mb++ = (float)(*ma++); | 
 |         } | 
 |         break; | 
 |         case TIFF_SBYTE: | 
 |         { | 
 |             int8_t *ma; | 
 |             float *mb; | 
 |             uint32_t n; | 
 |             ma = (int8_t *)origdata; | 
 |             mb = data; | 
 |             for (n = 0; n < count; n++) | 
 |                 *mb++ = (float)(*ma++); | 
 |         } | 
 |         break; | 
 |         case TIFF_SHORT: | 
 |         { | 
 |             uint16_t *ma; | 
 |             float *mb; | 
 |             uint32_t n; | 
 |             ma = (uint16_t *)origdata; | 
 |             mb = data; | 
 |             for (n = 0; n < count; n++) | 
 |             { | 
 |                 if (tif->tif_flags & TIFF_SWAB) | 
 |                     TIFFSwabShort(ma); | 
 |                 *mb++ = (float)(*ma++); | 
 |             } | 
 |         } | 
 |         break; | 
 |         case TIFF_SSHORT: | 
 |         { | 
 |             int16_t *ma; | 
 |             float *mb; | 
 |             uint32_t n; | 
 |             ma = (int16_t *)origdata; | 
 |             mb = data; | 
 |             for (n = 0; n < count; n++) | 
 |             { | 
 |                 if (tif->tif_flags & TIFF_SWAB) | 
 |                     TIFFSwabShort((uint16_t *)ma); | 
 |                 *mb++ = (float)(*ma++); | 
 |             } | 
 |         } | 
 |         break; | 
 |         case TIFF_LONG: | 
 |         { | 
 |             uint32_t *ma; | 
 |             float *mb; | 
 |             uint32_t n; | 
 |             ma = (uint32_t *)origdata; | 
 |             mb = data; | 
 |             for (n = 0; n < count; n++) | 
 |             { | 
 |                 if (tif->tif_flags & TIFF_SWAB) | 
 |                     TIFFSwabLong(ma); | 
 |                 *mb++ = (float)(*ma++); | 
 |             } | 
 |         } | 
 |         break; | 
 |         case TIFF_SLONG: | 
 |         { | 
 |             int32_t *ma; | 
 |             float *mb; | 
 |             uint32_t n; | 
 |             ma = (int32_t *)origdata; | 
 |             mb = data; | 
 |             for (n = 0; n < count; n++) | 
 |             { | 
 |                 if (tif->tif_flags & TIFF_SWAB) | 
 |                     TIFFSwabLong((uint32_t *)ma); | 
 |                 *mb++ = (float)(*ma++); | 
 |             } | 
 |         } | 
 |         break; | 
 |         case TIFF_LONG8: | 
 |         { | 
 |             uint64_t *ma; | 
 |             float *mb; | 
 |             uint32_t n; | 
 |             ma = (uint64_t *)origdata; | 
 |             mb = data; | 
 |             for (n = 0; n < count; n++) | 
 |             { | 
 |                 if (tif->tif_flags & TIFF_SWAB) | 
 |                     TIFFSwabLong8(ma); | 
 |                 *mb++ = (float)(*ma++); | 
 |             } | 
 |         } | 
 |         break; | 
 |         case TIFF_SLONG8: | 
 |         { | 
 |             int64_t *ma; | 
 |             float *mb; | 
 |             uint32_t n; | 
 |             ma = (int64_t *)origdata; | 
 |             mb = data; | 
 |             for (n = 0; n < count; n++) | 
 |             { | 
 |                 if (tif->tif_flags & TIFF_SWAB) | 
 |                     TIFFSwabLong8((uint64_t *)ma); | 
 |                 *mb++ = (float)(*ma++); | 
 |             } | 
 |         } | 
 |         break; | 
 |         case TIFF_RATIONAL: | 
 |         { | 
 |             uint32_t *ma; | 
 |             uint32_t maa; | 
 |             uint32_t mab; | 
 |             float *mb; | 
 |             uint32_t n; | 
 |             ma = (uint32_t *)origdata; | 
 |             mb = data; | 
 |             for (n = 0; n < count; n++) | 
 |             { | 
 |                 if (tif->tif_flags & TIFF_SWAB) | 
 |                     TIFFSwabLong(ma); | 
 |                 maa = *ma++; | 
 |                 if (tif->tif_flags & TIFF_SWAB) | 
 |                     TIFFSwabLong(ma); | 
 |                 mab = *ma++; | 
 |                 if (mab == 0) | 
 |                     *mb++ = 0.0; | 
 |                 else | 
 |                     *mb++ = (float)maa / (float)mab; | 
 |             } | 
 |         } | 
 |         break; | 
 |         case TIFF_SRATIONAL: | 
 |         { | 
 |             uint32_t *ma; | 
 |             int32_t maa; | 
 |             uint32_t mab; | 
 |             float *mb; | 
 |             uint32_t n; | 
 |             ma = (uint32_t *)origdata; | 
 |             mb = data; | 
 |             for (n = 0; n < count; n++) | 
 |             { | 
 |                 if (tif->tif_flags & TIFF_SWAB) | 
 |                     TIFFSwabLong(ma); | 
 |                 maa = *(int32_t *)ma; | 
 |                 ma++; | 
 |                 if (tif->tif_flags & TIFF_SWAB) | 
 |                     TIFFSwabLong(ma); | 
 |                 mab = *ma++; | 
 |                 if (mab == 0) | 
 |                     *mb++ = 0.0; | 
 |                 else | 
 |                     *mb++ = (float)maa / (float)mab; | 
 |             } | 
 |         } | 
 |         break; | 
 |         case TIFF_DOUBLE: | 
 |         { | 
 |             double *ma; | 
 |             float *mb; | 
 |             uint32_t n; | 
 |             if (tif->tif_flags & TIFF_SWAB) | 
 |                 TIFFSwabArrayOfLong8((uint64_t *)origdata, count); | 
 |             TIFFCvtIEEEDoubleToNative(tif, count, (double *)origdata); | 
 |             ma = (double *)origdata; | 
 |             mb = data; | 
 |             for (n = 0; n < count; n++) | 
 |             { | 
 |                 double val = *ma++; | 
 |                 if (val > FLT_MAX) | 
 |                     val = FLT_MAX; | 
 |                 else if (val < -FLT_MAX) | 
 |                     val = -FLT_MAX; | 
 |                 *mb++ = (float)val; | 
 |             } | 
 |         } | 
 |         break; | 
 |     } | 
 |     _TIFFfreeExt(tif, origdata); | 
 |     *value = data; | 
 |     return (TIFFReadDirEntryErrOk); | 
 | } | 
 |  | 
 | static enum TIFFReadDirEntryErr | 
 | TIFFReadDirEntryDoubleArray(TIFF *tif, TIFFDirEntry *direntry, double **value) | 
 | { | 
 |     enum TIFFReadDirEntryErr err; | 
 |     uint32_t count; | 
 |     void *origdata; | 
 |     double *data; | 
 |     switch (direntry->tdir_type) | 
 |     { | 
 |         case TIFF_BYTE: | 
 |         case TIFF_SBYTE: | 
 |         case TIFF_SHORT: | 
 |         case TIFF_SSHORT: | 
 |         case TIFF_LONG: | 
 |         case TIFF_SLONG: | 
 |         case TIFF_LONG8: | 
 |         case TIFF_SLONG8: | 
 |         case TIFF_RATIONAL: | 
 |         case TIFF_SRATIONAL: | 
 |         case TIFF_FLOAT: | 
 |         case TIFF_DOUBLE: | 
 |             break; | 
 |         default: | 
 |             return (TIFFReadDirEntryErrType); | 
 |     } | 
 |     err = TIFFReadDirEntryArray(tif, direntry, &count, 8, &origdata); | 
 |     if ((err != TIFFReadDirEntryErrOk) || (origdata == 0)) | 
 |     { | 
 |         *value = 0; | 
 |         return (err); | 
 |     } | 
 |     switch (direntry->tdir_type) | 
 |     { | 
 |         case TIFF_DOUBLE: | 
 |             if (tif->tif_flags & TIFF_SWAB) | 
 |                 TIFFSwabArrayOfLong8((uint64_t *)origdata, count); | 
 |             TIFFCvtIEEEDoubleToNative(tif, count, (double *)origdata); | 
 |             *value = (double *)origdata; | 
 |             return (TIFFReadDirEntryErrOk); | 
 |     } | 
 |     data = (double *)_TIFFmallocExt(tif, count * sizeof(double)); | 
 |     if (data == 0) | 
 |     { | 
 |         _TIFFfreeExt(tif, origdata); | 
 |         return (TIFFReadDirEntryErrAlloc); | 
 |     } | 
 |     switch (direntry->tdir_type) | 
 |     { | 
 |         case TIFF_BYTE: | 
 |         { | 
 |             uint8_t *ma; | 
 |             double *mb; | 
 |             uint32_t n; | 
 |             ma = (uint8_t *)origdata; | 
 |             mb = data; | 
 |             for (n = 0; n < count; n++) | 
 |                 *mb++ = (double)(*ma++); | 
 |         } | 
 |         break; | 
 |         case TIFF_SBYTE: | 
 |         { | 
 |             int8_t *ma; | 
 |             double *mb; | 
 |             uint32_t n; | 
 |             ma = (int8_t *)origdata; | 
 |             mb = data; | 
 |             for (n = 0; n < count; n++) | 
 |                 *mb++ = (double)(*ma++); | 
 |         } | 
 |         break; | 
 |         case TIFF_SHORT: | 
 |         { | 
 |             uint16_t *ma; | 
 |             double *mb; | 
 |             uint32_t n; | 
 |             ma = (uint16_t *)origdata; | 
 |             mb = data; | 
 |             for (n = 0; n < count; n++) | 
 |             { | 
 |                 if (tif->tif_flags & TIFF_SWAB) | 
 |                     TIFFSwabShort(ma); | 
 |                 *mb++ = (double)(*ma++); | 
 |             } | 
 |         } | 
 |         break; | 
 |         case TIFF_SSHORT: | 
 |         { | 
 |             int16_t *ma; | 
 |             double *mb; | 
 |             uint32_t n; | 
 |             ma = (int16_t *)origdata; | 
 |             mb = data; | 
 |             for (n = 0; n < count; n++) | 
 |             { | 
 |                 if (tif->tif_flags & TIFF_SWAB) | 
 |                     TIFFSwabShort((uint16_t *)ma); | 
 |                 *mb++ = (double)(*ma++); | 
 |             } | 
 |         } | 
 |         break; | 
 |         case TIFF_LONG: | 
 |         { | 
 |             uint32_t *ma; | 
 |             double *mb; | 
 |             uint32_t n; | 
 |             ma = (uint32_t *)origdata; | 
 |             mb = data; | 
 |             for (n = 0; n < count; n++) | 
 |             { | 
 |                 if (tif->tif_flags & TIFF_SWAB) | 
 |                     TIFFSwabLong(ma); | 
 |                 *mb++ = (double)(*ma++); | 
 |             } | 
 |         } | 
 |         break; | 
 |         case TIFF_SLONG: | 
 |         { | 
 |             int32_t *ma; | 
 |             double *mb; | 
 |             uint32_t n; | 
 |             ma = (int32_t *)origdata; | 
 |             mb = data; | 
 |             for (n = 0; n < count; n++) | 
 |             { | 
 |                 if (tif->tif_flags & TIFF_SWAB) | 
 |                     TIFFSwabLong((uint32_t *)ma); | 
 |                 *mb++ = (double)(*ma++); | 
 |             } | 
 |         } | 
 |         break; | 
 |         case TIFF_LONG8: | 
 |         { | 
 |             uint64_t *ma; | 
 |             double *mb; | 
 |             uint32_t n; | 
 |             ma = (uint64_t *)origdata; | 
 |             mb = data; | 
 |             for (n = 0; n < count; n++) | 
 |             { | 
 |                 if (tif->tif_flags & TIFF_SWAB) | 
 |                     TIFFSwabLong8(ma); | 
 |                 *mb++ = (double)(*ma++); | 
 |             } | 
 |         } | 
 |         break; | 
 |         case TIFF_SLONG8: | 
 |         { | 
 |             int64_t *ma; | 
 |             double *mb; | 
 |             uint32_t n; | 
 |             ma = (int64_t *)origdata; | 
 |             mb = data; | 
 |             for (n = 0; n < count; n++) | 
 |             { | 
 |                 if (tif->tif_flags & TIFF_SWAB) | 
 |                     TIFFSwabLong8((uint64_t *)ma); | 
 |                 *mb++ = (double)(*ma++); | 
 |             } | 
 |         } | 
 |         break; | 
 |         case TIFF_RATIONAL: | 
 |         { | 
 |             uint32_t *ma; | 
 |             uint32_t maa; | 
 |             uint32_t mab; | 
 |             double *mb; | 
 |             uint32_t n; | 
 |             ma = (uint32_t *)origdata; | 
 |             mb = data; | 
 |             for (n = 0; n < count; n++) | 
 |             { | 
 |                 if (tif->tif_flags & TIFF_SWAB) | 
 |                     TIFFSwabLong(ma); | 
 |                 maa = *ma++; | 
 |                 if (tif->tif_flags & TIFF_SWAB) | 
 |                     TIFFSwabLong(ma); | 
 |                 mab = *ma++; | 
 |                 if (mab == 0) | 
 |                     *mb++ = 0.0; | 
 |                 else | 
 |                     *mb++ = (double)maa / (double)mab; | 
 |             } | 
 |         } | 
 |         break; | 
 |         case TIFF_SRATIONAL: | 
 |         { | 
 |             uint32_t *ma; | 
 |             int32_t maa; | 
 |             uint32_t mab; | 
 |             double *mb; | 
 |             uint32_t n; | 
 |             ma = (uint32_t *)origdata; | 
 |             mb = data; | 
 |             for (n = 0; n < count; n++) | 
 |             { | 
 |                 if (tif->tif_flags & TIFF_SWAB) | 
 |                     TIFFSwabLong(ma); | 
 |                 maa = *(int32_t *)ma; | 
 |                 ma++; | 
 |                 if (tif->tif_flags & TIFF_SWAB) | 
 |                     TIFFSwabLong(ma); | 
 |                 mab = *ma++; | 
 |                 if (mab == 0) | 
 |                     *mb++ = 0.0; | 
 |                 else | 
 |                     *mb++ = (double)maa / (double)mab; | 
 |             } | 
 |         } | 
 |         break; | 
 |         case TIFF_FLOAT: | 
 |         { | 
 |             float *ma; | 
 |             double *mb; | 
 |             uint32_t n; | 
 |             if (tif->tif_flags & TIFF_SWAB) | 
 |                 TIFFSwabArrayOfLong((uint32_t *)origdata, count); | 
 |             TIFFCvtIEEEFloatToNative(tif, count, (float *)origdata); | 
 |             ma = (float *)origdata; | 
 |             mb = data; | 
 |             for (n = 0; n < count; n++) | 
 |                 *mb++ = (double)(*ma++); | 
 |         } | 
 |         break; | 
 |     } | 
 |     _TIFFfreeExt(tif, origdata); | 
 |     *value = data; | 
 |     return (TIFFReadDirEntryErrOk); | 
 | } | 
 |  | 
 | static enum TIFFReadDirEntryErr | 
 | TIFFReadDirEntryIfd8Array(TIFF *tif, TIFFDirEntry *direntry, uint64_t **value) | 
 | { | 
 |     enum TIFFReadDirEntryErr err; | 
 |     uint32_t count; | 
 |     void *origdata; | 
 |     uint64_t *data; | 
 |     switch (direntry->tdir_type) | 
 |     { | 
 |         case TIFF_LONG: | 
 |         case TIFF_LONG8: | 
 |         case TIFF_IFD: | 
 |         case TIFF_IFD8: | 
 |             break; | 
 |         default: | 
 |             return (TIFFReadDirEntryErrType); | 
 |     } | 
 |     err = TIFFReadDirEntryArray(tif, direntry, &count, 8, &origdata); | 
 |     if ((err != TIFFReadDirEntryErrOk) || (origdata == 0)) | 
 |     { | 
 |         *value = 0; | 
 |         return (err); | 
 |     } | 
 |     switch (direntry->tdir_type) | 
 |     { | 
 |         case TIFF_LONG8: | 
 |         case TIFF_IFD8: | 
 |             *value = (uint64_t *)origdata; | 
 |             if (tif->tif_flags & TIFF_SWAB) | 
 |                 TIFFSwabArrayOfLong8(*value, count); | 
 |             return (TIFFReadDirEntryErrOk); | 
 |     } | 
 |     data = (uint64_t *)_TIFFmallocExt(tif, count * 8); | 
 |     if (data == 0) | 
 |     { | 
 |         _TIFFfreeExt(tif, origdata); | 
 |         return (TIFFReadDirEntryErrAlloc); | 
 |     } | 
 |     switch (direntry->tdir_type) | 
 |     { | 
 |         case TIFF_LONG: | 
 |         case TIFF_IFD: | 
 |         { | 
 |             uint32_t *ma; | 
 |             uint64_t *mb; | 
 |             uint32_t n; | 
 |             ma = (uint32_t *)origdata; | 
 |             mb = data; | 
 |             for (n = 0; n < count; n++) | 
 |             { | 
 |                 if (tif->tif_flags & TIFF_SWAB) | 
 |                     TIFFSwabLong(ma); | 
 |                 *mb++ = (uint64_t)(*ma++); | 
 |             } | 
 |         } | 
 |         break; | 
 |     } | 
 |     _TIFFfreeExt(tif, origdata); | 
 |     *value = data; | 
 |     return (TIFFReadDirEntryErrOk); | 
 | } | 
 |  | 
 | static enum TIFFReadDirEntryErr | 
 | TIFFReadDirEntryPersampleShort(TIFF *tif, TIFFDirEntry *direntry, | 
 |                                uint16_t *value) | 
 | { | 
 |     enum TIFFReadDirEntryErr err; | 
 |     uint16_t *m; | 
 |     uint16_t *na; | 
 |     uint16_t nb; | 
 |     if (direntry->tdir_count < (uint64_t)tif->tif_dir.td_samplesperpixel) | 
 |         return (TIFFReadDirEntryErrCount); | 
 |     err = TIFFReadDirEntryShortArray(tif, direntry, &m); | 
 |     if (err != TIFFReadDirEntryErrOk || m == NULL) | 
 |         return (err); | 
 |     na = m; | 
 |     nb = tif->tif_dir.td_samplesperpixel; | 
 |     *value = *na++; | 
 |     nb--; | 
 |     while (nb > 0) | 
 |     { | 
 |         if (*na++ != *value) | 
 |         { | 
 |             err = TIFFReadDirEntryErrPsdif; | 
 |             break; | 
 |         } | 
 |         nb--; | 
 |     } | 
 |     _TIFFfreeExt(tif, m); | 
 |     return (err); | 
 | } | 
 |  | 
 | static void TIFFReadDirEntryCheckedByte(TIFF *tif, TIFFDirEntry *direntry, | 
 |                                         uint8_t *value) | 
 | { | 
 |     (void)tif; | 
 |     *value = *(uint8_t *)(&direntry->tdir_offset); | 
 | } | 
 |  | 
 | static void TIFFReadDirEntryCheckedSbyte(TIFF *tif, TIFFDirEntry *direntry, | 
 |                                          int8_t *value) | 
 | { | 
 |     (void)tif; | 
 |     *value = *(int8_t *)(&direntry->tdir_offset); | 
 | } | 
 |  | 
 | static void TIFFReadDirEntryCheckedShort(TIFF *tif, TIFFDirEntry *direntry, | 
 |                                          uint16_t *value) | 
 | { | 
 |     *value = direntry->tdir_offset.toff_short; | 
 |     /* *value=*(uint16_t*)(&direntry->tdir_offset); */ | 
 |     if (tif->tif_flags & TIFF_SWAB) | 
 |         TIFFSwabShort(value); | 
 | } | 
 |  | 
 | static void TIFFReadDirEntryCheckedSshort(TIFF *tif, TIFFDirEntry *direntry, | 
 |                                           int16_t *value) | 
 | { | 
 |     *value = *(int16_t *)(&direntry->tdir_offset); | 
 |     if (tif->tif_flags & TIFF_SWAB) | 
 |         TIFFSwabShort((uint16_t *)value); | 
 | } | 
 |  | 
 | static void TIFFReadDirEntryCheckedLong(TIFF *tif, TIFFDirEntry *direntry, | 
 |                                         uint32_t *value) | 
 | { | 
 |     *value = *(uint32_t *)(&direntry->tdir_offset); | 
 |     if (tif->tif_flags & TIFF_SWAB) | 
 |         TIFFSwabLong(value); | 
 | } | 
 |  | 
 | static void TIFFReadDirEntryCheckedSlong(TIFF *tif, TIFFDirEntry *direntry, | 
 |                                          int32_t *value) | 
 | { | 
 |     *value = *(int32_t *)(&direntry->tdir_offset); | 
 |     if (tif->tif_flags & TIFF_SWAB) | 
 |         TIFFSwabLong((uint32_t *)value); | 
 | } | 
 |  | 
 | static enum TIFFReadDirEntryErr | 
 | TIFFReadDirEntryCheckedLong8(TIFF *tif, TIFFDirEntry *direntry, uint64_t *value) | 
 | { | 
 |     if (!(tif->tif_flags & TIFF_BIGTIFF)) | 
 |     { | 
 |         enum TIFFReadDirEntryErr err; | 
 |         uint32_t offset = direntry->tdir_offset.toff_long; | 
 |         if (tif->tif_flags & TIFF_SWAB) | 
 |             TIFFSwabLong(&offset); | 
 |         err = TIFFReadDirEntryData(tif, offset, 8, value); | 
 |         if (err != TIFFReadDirEntryErrOk) | 
 |             return (err); | 
 |     } | 
 |     else | 
 |         *value = direntry->tdir_offset.toff_long8; | 
 |     if (tif->tif_flags & TIFF_SWAB) | 
 |         TIFFSwabLong8(value); | 
 |     return (TIFFReadDirEntryErrOk); | 
 | } | 
 |  | 
 | static enum TIFFReadDirEntryErr | 
 | TIFFReadDirEntryCheckedSlong8(TIFF *tif, TIFFDirEntry *direntry, int64_t *value) | 
 | { | 
 |     if (!(tif->tif_flags & TIFF_BIGTIFF)) | 
 |     { | 
 |         enum TIFFReadDirEntryErr err; | 
 |         uint32_t offset = direntry->tdir_offset.toff_long; | 
 |         if (tif->tif_flags & TIFF_SWAB) | 
 |             TIFFSwabLong(&offset); | 
 |         err = TIFFReadDirEntryData(tif, offset, 8, value); | 
 |         if (err != TIFFReadDirEntryErrOk) | 
 |             return (err); | 
 |     } | 
 |     else | 
 |         *value = *(int64_t *)(&direntry->tdir_offset); | 
 |     if (tif->tif_flags & TIFF_SWAB) | 
 |         TIFFSwabLong8((uint64_t *)value); | 
 |     return (TIFFReadDirEntryErrOk); | 
 | } | 
 |  | 
 | static enum TIFFReadDirEntryErr | 
 | TIFFReadDirEntryCheckedRational(TIFF *tif, TIFFDirEntry *direntry, | 
 |                                 double *value) | 
 | { | 
 |     UInt64Aligned_t m; | 
 |  | 
 |     assert(sizeof(double) == 8); | 
 |     assert(sizeof(uint64_t) == 8); | 
 |     assert(sizeof(uint32_t) == 4); | 
 |     if (!(tif->tif_flags & TIFF_BIGTIFF)) | 
 |     { | 
 |         enum TIFFReadDirEntryErr err; | 
 |         uint32_t offset = direntry->tdir_offset.toff_long; | 
 |         if (tif->tif_flags & TIFF_SWAB) | 
 |             TIFFSwabLong(&offset); | 
 |         err = TIFFReadDirEntryData(tif, offset, 8, m.i); | 
 |         if (err != TIFFReadDirEntryErrOk) | 
 |             return (err); | 
 |     } | 
 |     else | 
 |         m.l = direntry->tdir_offset.toff_long8; | 
 |     if (tif->tif_flags & TIFF_SWAB) | 
 |         TIFFSwabArrayOfLong(m.i, 2); | 
 |     /* Not completely sure what we should do when m.i[1]==0, but some */ | 
 |     /* sanitizers do not like division by 0.0: */ | 
 |     /* http://bugzilla.maptools.org/show_bug.cgi?id=2644 */ | 
 |     if (m.i[0] == 0 || m.i[1] == 0) | 
 |         *value = 0.0; | 
 |     else | 
 |         *value = (double)m.i[0] / (double)m.i[1]; | 
 |     return (TIFFReadDirEntryErrOk); | 
 | } | 
 |  | 
 | static enum TIFFReadDirEntryErr | 
 | TIFFReadDirEntryCheckedSrational(TIFF *tif, TIFFDirEntry *direntry, | 
 |                                  double *value) | 
 | { | 
 |     UInt64Aligned_t m; | 
 |     assert(sizeof(double) == 8); | 
 |     assert(sizeof(uint64_t) == 8); | 
 |     assert(sizeof(int32_t) == 4); | 
 |     assert(sizeof(uint32_t) == 4); | 
 |     if (!(tif->tif_flags & TIFF_BIGTIFF)) | 
 |     { | 
 |         enum TIFFReadDirEntryErr err; | 
 |         uint32_t offset = direntry->tdir_offset.toff_long; | 
 |         if (tif->tif_flags & TIFF_SWAB) | 
 |             TIFFSwabLong(&offset); | 
 |         err = TIFFReadDirEntryData(tif, offset, 8, m.i); | 
 |         if (err != TIFFReadDirEntryErrOk) | 
 |             return (err); | 
 |     } | 
 |     else | 
 |         m.l = direntry->tdir_offset.toff_long8; | 
 |     if (tif->tif_flags & TIFF_SWAB) | 
 |         TIFFSwabArrayOfLong(m.i, 2); | 
 |     /* Not completely sure what we should do when m.i[1]==0, but some */ | 
 |     /* sanitizers do not like division by 0.0: */ | 
 |     /* http://bugzilla.maptools.org/show_bug.cgi?id=2644 */ | 
 |     if ((int32_t)m.i[0] == 0 || m.i[1] == 0) | 
 |         *value = 0.0; | 
 |     else | 
 |         *value = (double)((int32_t)m.i[0]) / (double)m.i[1]; | 
 |     return (TIFFReadDirEntryErrOk); | 
 | } | 
 |  | 
 | #if 0 | 
 | static enum TIFFReadDirEntryErr | 
 | TIFFReadDirEntryCheckedRationalDirect(TIFF *tif, TIFFDirEntry *direntry, | 
 |                                       TIFFRational_t *value) | 
 | { /*--: SetGetRATIONAL_directly:_CustomTag: Read rational (and signed rationals) | 
 |      directly --*/ | 
 |     UInt64Aligned_t m; | 
 |  | 
 |     assert(sizeof(double) == 8); | 
 |     assert(sizeof(uint64_t) == 8); | 
 |     assert(sizeof(uint32_t) == 4); | 
 |  | 
 |     if (direntry->tdir_count != 1) | 
 |         return (TIFFReadDirEntryErrCount); | 
 |  | 
 |     if (direntry->tdir_type != TIFF_RATIONAL && | 
 |         direntry->tdir_type != TIFF_SRATIONAL) | 
 |         return (TIFFReadDirEntryErrType); | 
 |  | 
 |     if (!(tif->tif_flags & TIFF_BIGTIFF)) | 
 |     { | 
 |         enum TIFFReadDirEntryErr err; | 
 |         uint32_t offset = direntry->tdir_offset.toff_long; | 
 |         if (tif->tif_flags & TIFF_SWAB) | 
 |             TIFFSwabLong(&offset); | 
 |         err = TIFFReadDirEntryData(tif, offset, 8, m.i); | 
 |         if (err != TIFFReadDirEntryErrOk) | 
 |             return (err); | 
 |     } | 
 |     else | 
 |     { | 
 |         m.l = direntry->tdir_offset.toff_long8; | 
 |     } | 
 |  | 
 |     if (tif->tif_flags & TIFF_SWAB) | 
 |         TIFFSwabArrayOfLong(m.i, 2); | 
 |  | 
 |     value->uNum = m.i[0]; | 
 |     value->uDenom = m.i[1]; | 
 |     return (TIFFReadDirEntryErrOk); | 
 | } /*-- TIFFReadDirEntryCheckedRationalDirect() --*/ | 
 | #endif | 
 |  | 
 | static void TIFFReadDirEntryCheckedFloat(TIFF *tif, TIFFDirEntry *direntry, | 
 |                                          float *value) | 
 | { | 
 |     union | 
 |     { | 
 |         float f; | 
 |         uint32_t i; | 
 |     } float_union; | 
 |     assert(sizeof(float) == 4); | 
 |     assert(sizeof(uint32_t) == 4); | 
 |     assert(sizeof(float_union) == 4); | 
 |     float_union.i = *(uint32_t *)(&direntry->tdir_offset); | 
 |     *value = float_union.f; | 
 |     if (tif->tif_flags & TIFF_SWAB) | 
 |         TIFFSwabLong((uint32_t *)value); | 
 | } | 
 |  | 
 | static enum TIFFReadDirEntryErr | 
 | TIFFReadDirEntryCheckedDouble(TIFF *tif, TIFFDirEntry *direntry, double *value) | 
 | { | 
 |     assert(sizeof(double) == 8); | 
 |     assert(sizeof(uint64_t) == 8); | 
 |     assert(sizeof(UInt64Aligned_t) == 8); | 
 |     if (!(tif->tif_flags & TIFF_BIGTIFF)) | 
 |     { | 
 |         enum TIFFReadDirEntryErr err; | 
 |         uint32_t offset = direntry->tdir_offset.toff_long; | 
 |         if (tif->tif_flags & TIFF_SWAB) | 
 |             TIFFSwabLong(&offset); | 
 |         err = TIFFReadDirEntryData(tif, offset, 8, value); | 
 |         if (err != TIFFReadDirEntryErrOk) | 
 |             return (err); | 
 |     } | 
 |     else | 
 |     { | 
 |         UInt64Aligned_t uint64_union; | 
 |         uint64_union.l = direntry->tdir_offset.toff_long8; | 
 |         *value = uint64_union.d; | 
 |     } | 
 |     if (tif->tif_flags & TIFF_SWAB) | 
 |         TIFFSwabLong8((uint64_t *)value); | 
 |     return (TIFFReadDirEntryErrOk); | 
 | } | 
 |  | 
 | static enum TIFFReadDirEntryErr | 
 | TIFFReadDirEntryCheckRangeByteSbyte(int8_t value) | 
 | { | 
 |     if (value < 0) | 
 |         return (TIFFReadDirEntryErrRange); | 
 |     else | 
 |         return (TIFFReadDirEntryErrOk); | 
 | } | 
 |  | 
 | static enum TIFFReadDirEntryErr | 
 | TIFFReadDirEntryCheckRangeByteShort(uint16_t value) | 
 | { | 
 |     if (value > 0xFF) | 
 |         return (TIFFReadDirEntryErrRange); | 
 |     else | 
 |         return (TIFFReadDirEntryErrOk); | 
 | } | 
 |  | 
 | static enum TIFFReadDirEntryErr | 
 | TIFFReadDirEntryCheckRangeByteSshort(int16_t value) | 
 | { | 
 |     if ((value < 0) || (value > 0xFF)) | 
 |         return (TIFFReadDirEntryErrRange); | 
 |     else | 
 |         return (TIFFReadDirEntryErrOk); | 
 | } | 
 |  | 
 | static enum TIFFReadDirEntryErr | 
 | TIFFReadDirEntryCheckRangeByteLong(uint32_t value) | 
 | { | 
 |     if (value > 0xFF) | 
 |         return (TIFFReadDirEntryErrRange); | 
 |     else | 
 |         return (TIFFReadDirEntryErrOk); | 
 | } | 
 |  | 
 | static enum TIFFReadDirEntryErr | 
 | TIFFReadDirEntryCheckRangeByteSlong(int32_t value) | 
 | { | 
 |     if ((value < 0) || (value > 0xFF)) | 
 |         return (TIFFReadDirEntryErrRange); | 
 |     else | 
 |         return (TIFFReadDirEntryErrOk); | 
 | } | 
 |  | 
 | static enum TIFFReadDirEntryErr | 
 | TIFFReadDirEntryCheckRangeByteLong8(uint64_t value) | 
 | { | 
 |     if (value > 0xFF) | 
 |         return (TIFFReadDirEntryErrRange); | 
 |     else | 
 |         return (TIFFReadDirEntryErrOk); | 
 | } | 
 |  | 
 | static enum TIFFReadDirEntryErr | 
 | TIFFReadDirEntryCheckRangeByteSlong8(int64_t value) | 
 | { | 
 |     if ((value < 0) || (value > 0xFF)) | 
 |         return (TIFFReadDirEntryErrRange); | 
 |     else | 
 |         return (TIFFReadDirEntryErrOk); | 
 | } | 
 |  | 
 | static enum TIFFReadDirEntryErr | 
 | TIFFReadDirEntryCheckRangeSbyteByte(uint8_t value) | 
 | { | 
 |     if (value > 0x7F) | 
 |         return (TIFFReadDirEntryErrRange); | 
 |     else | 
 |         return (TIFFReadDirEntryErrOk); | 
 | } | 
 |  | 
 | static enum TIFFReadDirEntryErr | 
 | TIFFReadDirEntryCheckRangeSbyteShort(uint16_t value) | 
 | { | 
 |     if (value > 0x7F) | 
 |         return (TIFFReadDirEntryErrRange); | 
 |     else | 
 |         return (TIFFReadDirEntryErrOk); | 
 | } | 
 |  | 
 | static enum TIFFReadDirEntryErr | 
 | TIFFReadDirEntryCheckRangeSbyteSshort(int16_t value) | 
 | { | 
 |     if ((value < -0x80) || (value > 0x7F)) | 
 |         return (TIFFReadDirEntryErrRange); | 
 |     else | 
 |         return (TIFFReadDirEntryErrOk); | 
 | } | 
 |  | 
 | static enum TIFFReadDirEntryErr | 
 | TIFFReadDirEntryCheckRangeSbyteLong(uint32_t value) | 
 | { | 
 |     if (value > 0x7F) | 
 |         return (TIFFReadDirEntryErrRange); | 
 |     else | 
 |         return (TIFFReadDirEntryErrOk); | 
 | } | 
 |  | 
 | static enum TIFFReadDirEntryErr | 
 | TIFFReadDirEntryCheckRangeSbyteSlong(int32_t value) | 
 | { | 
 |     if ((value < -0x80) || (value > 0x7F)) | 
 |         return (TIFFReadDirEntryErrRange); | 
 |     else | 
 |         return (TIFFReadDirEntryErrOk); | 
 | } | 
 |  | 
 | static enum TIFFReadDirEntryErr | 
 | TIFFReadDirEntryCheckRangeSbyteLong8(uint64_t value) | 
 | { | 
 |     if (value > 0x7F) | 
 |         return (TIFFReadDirEntryErrRange); | 
 |     else | 
 |         return (TIFFReadDirEntryErrOk); | 
 | } | 
 |  | 
 | static enum TIFFReadDirEntryErr | 
 | TIFFReadDirEntryCheckRangeSbyteSlong8(int64_t value) | 
 | { | 
 |     if ((value < -0x80) || (value > 0x7F)) | 
 |         return (TIFFReadDirEntryErrRange); | 
 |     else | 
 |         return (TIFFReadDirEntryErrOk); | 
 | } | 
 |  | 
 | static enum TIFFReadDirEntryErr | 
 | TIFFReadDirEntryCheckRangeShortSbyte(int8_t value) | 
 | { | 
 |     if (value < 0) | 
 |         return (TIFFReadDirEntryErrRange); | 
 |     else | 
 |         return (TIFFReadDirEntryErrOk); | 
 | } | 
 |  | 
 | static enum TIFFReadDirEntryErr | 
 | TIFFReadDirEntryCheckRangeShortSshort(int16_t value) | 
 | { | 
 |     if (value < 0) | 
 |         return (TIFFReadDirEntryErrRange); | 
 |     else | 
 |         return (TIFFReadDirEntryErrOk); | 
 | } | 
 |  | 
 | static enum TIFFReadDirEntryErr | 
 | TIFFReadDirEntryCheckRangeShortLong(uint32_t value) | 
 | { | 
 |     if (value > 0xFFFF) | 
 |         return (TIFFReadDirEntryErrRange); | 
 |     else | 
 |         return (TIFFReadDirEntryErrOk); | 
 | } | 
 |  | 
 | static enum TIFFReadDirEntryErr | 
 | TIFFReadDirEntryCheckRangeShortSlong(int32_t value) | 
 | { | 
 |     if ((value < 0) || (value > 0xFFFF)) | 
 |         return (TIFFReadDirEntryErrRange); | 
 |     else | 
 |         return (TIFFReadDirEntryErrOk); | 
 | } | 
 |  | 
 | static enum TIFFReadDirEntryErr | 
 | TIFFReadDirEntryCheckRangeShortLong8(uint64_t value) | 
 | { | 
 |     if (value > 0xFFFF) | 
 |         return (TIFFReadDirEntryErrRange); | 
 |     else | 
 |         return (TIFFReadDirEntryErrOk); | 
 | } | 
 |  | 
 | static enum TIFFReadDirEntryErr | 
 | TIFFReadDirEntryCheckRangeShortSlong8(int64_t value) | 
 | { | 
 |     if ((value < 0) || (value > 0xFFFF)) | 
 |         return (TIFFReadDirEntryErrRange); | 
 |     else | 
 |         return (TIFFReadDirEntryErrOk); | 
 | } | 
 |  | 
 | static enum TIFFReadDirEntryErr | 
 | TIFFReadDirEntryCheckRangeSshortShort(uint16_t value) | 
 | { | 
 |     if (value > 0x7FFF) | 
 |         return (TIFFReadDirEntryErrRange); | 
 |     else | 
 |         return (TIFFReadDirEntryErrOk); | 
 | } | 
 |  | 
 | static enum TIFFReadDirEntryErr | 
 | TIFFReadDirEntryCheckRangeSshortLong(uint32_t value) | 
 | { | 
 |     if (value > 0x7FFF) | 
 |         return (TIFFReadDirEntryErrRange); | 
 |     else | 
 |         return (TIFFReadDirEntryErrOk); | 
 | } | 
 |  | 
 | static enum TIFFReadDirEntryErr | 
 | TIFFReadDirEntryCheckRangeSshortSlong(int32_t value) | 
 | { | 
 |     if ((value < -0x8000) || (value > 0x7FFF)) | 
 |         return (TIFFReadDirEntryErrRange); | 
 |     else | 
 |         return (TIFFReadDirEntryErrOk); | 
 | } | 
 |  | 
 | static enum TIFFReadDirEntryErr | 
 | TIFFReadDirEntryCheckRangeSshortLong8(uint64_t value) | 
 | { | 
 |     if (value > 0x7FFF) | 
 |         return (TIFFReadDirEntryErrRange); | 
 |     else | 
 |         return (TIFFReadDirEntryErrOk); | 
 | } | 
 |  | 
 | static enum TIFFReadDirEntryErr | 
 | TIFFReadDirEntryCheckRangeSshortSlong8(int64_t value) | 
 | { | 
 |     if ((value < -0x8000) || (value > 0x7FFF)) | 
 |         return (TIFFReadDirEntryErrRange); | 
 |     else | 
 |         return (TIFFReadDirEntryErrOk); | 
 | } | 
 |  | 
 | static enum TIFFReadDirEntryErr | 
 | TIFFReadDirEntryCheckRangeLongSbyte(int8_t value) | 
 | { | 
 |     if (value < 0) | 
 |         return (TIFFReadDirEntryErrRange); | 
 |     else | 
 |         return (TIFFReadDirEntryErrOk); | 
 | } | 
 |  | 
 | static enum TIFFReadDirEntryErr | 
 | TIFFReadDirEntryCheckRangeLongSshort(int16_t value) | 
 | { | 
 |     if (value < 0) | 
 |         return (TIFFReadDirEntryErrRange); | 
 |     else | 
 |         return (TIFFReadDirEntryErrOk); | 
 | } | 
 |  | 
 | static enum TIFFReadDirEntryErr | 
 | TIFFReadDirEntryCheckRangeLongSlong(int32_t value) | 
 | { | 
 |     if (value < 0) | 
 |         return (TIFFReadDirEntryErrRange); | 
 |     else | 
 |         return (TIFFReadDirEntryErrOk); | 
 | } | 
 |  | 
 | static enum TIFFReadDirEntryErr | 
 | TIFFReadDirEntryCheckRangeLongLong8(uint64_t value) | 
 | { | 
 |     if (value > UINT32_MAX) | 
 |         return (TIFFReadDirEntryErrRange); | 
 |     else | 
 |         return (TIFFReadDirEntryErrOk); | 
 | } | 
 |  | 
 | static enum TIFFReadDirEntryErr | 
 | TIFFReadDirEntryCheckRangeLongSlong8(int64_t value) | 
 | { | 
 |     if ((value < 0) || (value > (int64_t)UINT32_MAX)) | 
 |         return (TIFFReadDirEntryErrRange); | 
 |     else | 
 |         return (TIFFReadDirEntryErrOk); | 
 | } | 
 |  | 
 | static enum TIFFReadDirEntryErr | 
 | TIFFReadDirEntryCheckRangeSlongLong(uint32_t value) | 
 | { | 
 |     if (value > 0x7FFFFFFFUL) | 
 |         return (TIFFReadDirEntryErrRange); | 
 |     else | 
 |         return (TIFFReadDirEntryErrOk); | 
 | } | 
 |  | 
 | /* Check that the 8-byte unsigned value can fit in a 4-byte unsigned range */ | 
 | static enum TIFFReadDirEntryErr | 
 | TIFFReadDirEntryCheckRangeSlongLong8(uint64_t value) | 
 | { | 
 |     if (value > 0x7FFFFFFF) | 
 |         return (TIFFReadDirEntryErrRange); | 
 |     else | 
 |         return (TIFFReadDirEntryErrOk); | 
 | } | 
 |  | 
 | /* Check that the 8-byte signed value can fit in a 4-byte signed range */ | 
 | static enum TIFFReadDirEntryErr | 
 | TIFFReadDirEntryCheckRangeSlongSlong8(int64_t value) | 
 | { | 
 |     if ((value < 0 - ((int64_t)0x7FFFFFFF + 1)) || (value > 0x7FFFFFFF)) | 
 |         return (TIFFReadDirEntryErrRange); | 
 |     else | 
 |         return (TIFFReadDirEntryErrOk); | 
 | } | 
 |  | 
 | static enum TIFFReadDirEntryErr | 
 | TIFFReadDirEntryCheckRangeLong8Sbyte(int8_t value) | 
 | { | 
 |     if (value < 0) | 
 |         return (TIFFReadDirEntryErrRange); | 
 |     else | 
 |         return (TIFFReadDirEntryErrOk); | 
 | } | 
 |  | 
 | static enum TIFFReadDirEntryErr | 
 | TIFFReadDirEntryCheckRangeLong8Sshort(int16_t value) | 
 | { | 
 |     if (value < 0) | 
 |         return (TIFFReadDirEntryErrRange); | 
 |     else | 
 |         return (TIFFReadDirEntryErrOk); | 
 | } | 
 |  | 
 | static enum TIFFReadDirEntryErr | 
 | TIFFReadDirEntryCheckRangeLong8Slong(int32_t value) | 
 | { | 
 |     if (value < 0) | 
 |         return (TIFFReadDirEntryErrRange); | 
 |     else | 
 |         return (TIFFReadDirEntryErrOk); | 
 | } | 
 |  | 
 | static enum TIFFReadDirEntryErr | 
 | TIFFReadDirEntryCheckRangeLong8Slong8(int64_t value) | 
 | { | 
 |     if (value < 0) | 
 |         return (TIFFReadDirEntryErrRange); | 
 |     else | 
 |         return (TIFFReadDirEntryErrOk); | 
 | } | 
 |  | 
 | static enum TIFFReadDirEntryErr | 
 | TIFFReadDirEntryCheckRangeSlong8Long8(uint64_t value) | 
 | { | 
 |     if (value > INT64_MAX) | 
 |         return (TIFFReadDirEntryErrRange); | 
 |     else | 
 |         return (TIFFReadDirEntryErrOk); | 
 | } | 
 |  | 
 | static enum TIFFReadDirEntryErr TIFFReadDirEntryData(TIFF *tif, uint64_t offset, | 
 |                                                      tmsize_t size, void *dest) | 
 | { | 
 |     assert(size > 0); | 
 |     if (!isMapped(tif)) | 
 |     { | 
 |         if (!SeekOK(tif, offset)) | 
 |             return (TIFFReadDirEntryErrIo); | 
 |         if (!ReadOK(tif, dest, size)) | 
 |             return (TIFFReadDirEntryErrIo); | 
 |     } | 
 |     else | 
 |     { | 
 |         size_t ma, mb; | 
 |         ma = (size_t)offset; | 
 |         if ((uint64_t)ma != offset || ma > (~(size_t)0) - (size_t)size) | 
 |         { | 
 |             return TIFFReadDirEntryErrIo; | 
 |         } | 
 |         mb = ma + size; | 
 |         if (mb > (uint64_t)tif->tif_size) | 
 |             return (TIFFReadDirEntryErrIo); | 
 |         _TIFFmemcpy(dest, tif->tif_base + ma, size); | 
 |     } | 
 |     return (TIFFReadDirEntryErrOk); | 
 | } | 
 |  | 
 | static void TIFFReadDirEntryOutputErr(TIFF *tif, enum TIFFReadDirEntryErr err, | 
 |                                       const char *module, const char *tagname, | 
 |                                       int recover) | 
 | { | 
 |     if (!recover) | 
 |     { | 
 |         switch (err) | 
 |         { | 
 |             case TIFFReadDirEntryErrCount: | 
 |                 TIFFErrorExtR(tif, module, "Incorrect count for \"%s\"", | 
 |                               tagname); | 
 |                 break; | 
 |             case TIFFReadDirEntryErrType: | 
 |                 TIFFErrorExtR(tif, module, "Incompatible type for \"%s\"", | 
 |                               tagname); | 
 |                 break; | 
 |             case TIFFReadDirEntryErrIo: | 
 |                 TIFFErrorExtR(tif, module, "IO error during reading of \"%s\"", | 
 |                               tagname); | 
 |                 break; | 
 |             case TIFFReadDirEntryErrRange: | 
 |                 TIFFErrorExtR(tif, module, "Incorrect value for \"%s\"", | 
 |                               tagname); | 
 |                 break; | 
 |             case TIFFReadDirEntryErrPsdif: | 
 |                 TIFFErrorExtR( | 
 |                     tif, module, | 
 |                     "Cannot handle different values per sample for \"%s\"", | 
 |                     tagname); | 
 |                 break; | 
 |             case TIFFReadDirEntryErrSizesan: | 
 |                 TIFFErrorExtR(tif, module, | 
 |                               "Sanity check on size of \"%s\" value failed", | 
 |                               tagname); | 
 |                 break; | 
 |             case TIFFReadDirEntryErrAlloc: | 
 |                 TIFFErrorExtR(tif, module, "Out of memory reading of \"%s\"", | 
 |                               tagname); | 
 |                 break; | 
 |             default: | 
 |                 assert(0); /* we should never get here */ | 
 |                 break; | 
 |         } | 
 |     } | 
 |     else | 
 |     { | 
 |         switch (err) | 
 |         { | 
 |             case TIFFReadDirEntryErrCount: | 
 |                 TIFFWarningExtR(tif, module, | 
 |                                 "Incorrect count for \"%s\"; tag ignored", | 
 |                                 tagname); | 
 |                 break; | 
 |             case TIFFReadDirEntryErrType: | 
 |                 TIFFWarningExtR(tif, module, | 
 |                                 "Incompatible type for \"%s\"; tag ignored", | 
 |                                 tagname); | 
 |                 break; | 
 |             case TIFFReadDirEntryErrIo: | 
 |                 TIFFWarningExtR( | 
 |                     tif, module, | 
 |                     "IO error during reading of \"%s\"; tag ignored", tagname); | 
 |                 break; | 
 |             case TIFFReadDirEntryErrRange: | 
 |                 TIFFWarningExtR(tif, module, | 
 |                                 "Incorrect value for \"%s\"; tag ignored", | 
 |                                 tagname); | 
 |                 break; | 
 |             case TIFFReadDirEntryErrPsdif: | 
 |                 TIFFWarningExtR(tif, module, | 
 |                                 "Cannot handle different values per sample for " | 
 |                                 "\"%s\"; tag ignored", | 
 |                                 tagname); | 
 |                 break; | 
 |             case TIFFReadDirEntryErrSizesan: | 
 |                 TIFFWarningExtR( | 
 |                     tif, module, | 
 |                     "Sanity check on size of \"%s\" value failed; tag ignored", | 
 |                     tagname); | 
 |                 break; | 
 |             case TIFFReadDirEntryErrAlloc: | 
 |                 TIFFWarningExtR(tif, module, | 
 |                                 "Out of memory reading of \"%s\"; tag ignored", | 
 |                                 tagname); | 
 |                 break; | 
 |             default: | 
 |                 assert(0); /* we should never get here */ | 
 |                 break; | 
 |         } | 
 |     } | 
 | } | 
 |  | 
 | /* | 
 |  * Return the maximum number of color channels specified for a given photometric | 
 |  * type. 0 is returned if photometric type isn't supported or no default value | 
 |  * is defined by the specification. | 
 |  */ | 
 | static int _TIFFGetMaxColorChannels(uint16_t photometric) | 
 | { | 
 |     switch (photometric) | 
 |     { | 
 |         case PHOTOMETRIC_PALETTE: | 
 |         case PHOTOMETRIC_MINISWHITE: | 
 |         case PHOTOMETRIC_MINISBLACK: | 
 |             return 1; | 
 |         case PHOTOMETRIC_YCBCR: | 
 |         case PHOTOMETRIC_RGB: | 
 |         case PHOTOMETRIC_CIELAB: | 
 |         case PHOTOMETRIC_LOGLUV: | 
 |         case PHOTOMETRIC_ITULAB: | 
 |         case PHOTOMETRIC_ICCLAB: | 
 |             return 3; | 
 |         case PHOTOMETRIC_SEPARATED: | 
 |         case PHOTOMETRIC_MASK: | 
 |             return 4; | 
 |         case PHOTOMETRIC_LOGL: | 
 |         case PHOTOMETRIC_CFA: | 
 |         default: | 
 |             return 0; | 
 |     } | 
 | } | 
 |  | 
 | static int ByteCountLooksBad(TIFF *tif) | 
 | { | 
 |     /* | 
 |      * Assume we have wrong StripByteCount value (in case | 
 |      * of single strip) in following cases: | 
 |      *   - it is equal to zero along with StripOffset; | 
 |      *   - it is larger than file itself (in case of uncompressed | 
 |      *     image); | 
 |      *   - it is smaller than the size of the bytes per row | 
 |      *     multiplied on the number of rows.  The last case should | 
 |      *     not be checked in the case of writing new image, | 
 |      *     because we may do not know the exact strip size | 
 |      *     until the whole image will be written and directory | 
 |      *     dumped out. | 
 |      */ | 
 |     uint64_t bytecount = TIFFGetStrileByteCount(tif, 0); | 
 |     uint64_t offset = TIFFGetStrileOffset(tif, 0); | 
 |     uint64_t filesize; | 
 |  | 
 |     if (offset == 0) | 
 |         return 0; | 
 |     if (bytecount == 0) | 
 |         return 1; | 
 |     if (tif->tif_dir.td_compression != COMPRESSION_NONE) | 
 |         return 0; | 
 |     filesize = TIFFGetFileSize(tif); | 
 |     if (offset <= filesize && bytecount > filesize - offset) | 
 |         return 1; | 
 |     if (tif->tif_mode == O_RDONLY) | 
 |     { | 
 |         uint64_t scanlinesize = TIFFScanlineSize64(tif); | 
 |         if (tif->tif_dir.td_imagelength > 0 && | 
 |             scanlinesize > UINT64_MAX / tif->tif_dir.td_imagelength) | 
 |         { | 
 |             return 1; | 
 |         } | 
 |         if (bytecount < scanlinesize * tif->tif_dir.td_imagelength) | 
 |             return 1; | 
 |     } | 
 |     return 0; | 
 | } | 
 |  | 
 | /* | 
 |  * To evaluate the IFD data size when reading, save the offset and data size of | 
 |  * all data that does not fit into the IFD entries themselves. | 
 |  */ | 
 | static bool EvaluateIFDdatasizeReading(TIFF *tif, TIFFDirEntry *dp) | 
 | { | 
 |     const uint64_t data_width = TIFFDataWidth(dp->tdir_type); | 
 |     if (data_width != 0 && dp->tdir_count > UINT64_MAX / data_width) | 
 |     { | 
 |         TIFFErrorExtR(tif, "EvaluateIFDdatasizeReading", | 
 |                       "Too large IFD data size"); | 
 |         return false; | 
 |     } | 
 |     const uint64_t datalength = dp->tdir_count * data_width; | 
 |     if (datalength > ((tif->tif_flags & TIFF_BIGTIFF) ? 0x8U : 0x4U)) | 
 |     { | 
 |         if (tif->tif_dir.td_dirdatasize_read > UINT64_MAX - datalength) | 
 |         { | 
 |             TIFFErrorExtR(tif, "EvaluateIFDdatasizeReading", | 
 |                           "Too large IFD data size"); | 
 |             return false; | 
 |         } | 
 |         tif->tif_dir.td_dirdatasize_read += datalength; | 
 |         if (!(tif->tif_flags & TIFF_BIGTIFF)) | 
 |         { | 
 |             /* The offset of TIFFDirEntry are not swapped when read in. That has | 
 |              * to be done when used. */ | 
 |             uint32_t offset = dp->tdir_offset.toff_long; | 
 |             if (tif->tif_flags & TIFF_SWAB) | 
 |                 TIFFSwabLong(&offset); | 
 |             tif->tif_dir | 
 |                 .td_dirdatasize_offsets[tif->tif_dir.td_dirdatasize_Noffsets] | 
 |                 .offset = (uint64_t)offset; | 
 |         } | 
 |         else | 
 |         { | 
 |             tif->tif_dir | 
 |                 .td_dirdatasize_offsets[tif->tif_dir.td_dirdatasize_Noffsets] | 
 |                 .offset = dp->tdir_offset.toff_long8; | 
 |             if (tif->tif_flags & TIFF_SWAB) | 
 |                 TIFFSwabLong8( | 
 |                     &tif->tif_dir | 
 |                          .td_dirdatasize_offsets[tif->tif_dir | 
 |                                                      .td_dirdatasize_Noffsets] | 
 |                          .offset); | 
 |         } | 
 |         tif->tif_dir | 
 |             .td_dirdatasize_offsets[tif->tif_dir.td_dirdatasize_Noffsets] | 
 |             .length = datalength; | 
 |         tif->tif_dir.td_dirdatasize_Noffsets++; | 
 |     } | 
 |     return true; | 
 | } | 
 |  | 
 | /* | 
 |  * Compare function for qsort() sorting TIFFEntryOffsetAndLength array entries. | 
 |  */ | 
 | static int cmpTIFFEntryOffsetAndLength(const void *a, const void *b) | 
 | { | 
 |     const TIFFEntryOffsetAndLength *ta = (const TIFFEntryOffsetAndLength *)a; | 
 |     const TIFFEntryOffsetAndLength *tb = (const TIFFEntryOffsetAndLength *)b; | 
 |     /* Compare offsets */ | 
 |     if (ta->offset > tb->offset) | 
 |         return 1; | 
 |     else if (ta->offset < tb->offset) | 
 |         return -1; | 
 |     else | 
 |         return 0; | 
 | } | 
 |  | 
 | /* | 
 |  * Determine the IFD data size after reading an IFD from the file that can be | 
 |  * overwritten and saving it in tif_dir.td_dirdatasize_read. This data size | 
 |  * includes the IFD entries themselves as well as the data that does not fit | 
 |  * directly into the IFD entries but is located directly after the IFD entries | 
 |  * in the file. | 
 |  */ | 
 | static void CalcFinalIFDdatasizeReading(TIFF *tif, uint16_t dircount) | 
 | { | 
 |     /* IFD data size is only needed if file-writing is enabled. | 
 |      * This also avoids the seek() to EOF to determine the file size, which | 
 |      * causes the stdin-streaming-friendly mode of libtiff for GDAL to fail. */ | 
 |     if (tif->tif_mode == O_RDONLY) | 
 |         return; | 
 |  | 
 |     /* Sort TIFFEntryOffsetAndLength array in ascending order. */ | 
 |     qsort(tif->tif_dir.td_dirdatasize_offsets, | 
 |           tif->tif_dir.td_dirdatasize_Noffsets, | 
 |           sizeof(TIFFEntryOffsetAndLength), cmpTIFFEntryOffsetAndLength); | 
 |  | 
 |     /* Get offset of end of IFD entry space. */ | 
 |     uint64_t IFDendoffset; | 
 |     if (!(tif->tif_flags & TIFF_BIGTIFF)) | 
 |         IFDendoffset = tif->tif_diroff + 2 + dircount * 12 + 4; | 
 |     else | 
 |         IFDendoffset = tif->tif_diroff + 8 + dircount * 20 + 8; | 
 |  | 
 |     /* Check which offsets are right behind IFD entries. However, LibTIFF | 
 |      * increments the writing address for every external data to an even offset. | 
 |      * Thus gaps of 1 byte can occur. */ | 
 |     uint64_t size = 0; | 
 |     uint64_t offset; | 
 |     uint32_t i; | 
 |     for (i = 0; i < tif->tif_dir.td_dirdatasize_Noffsets; i++) | 
 |     { | 
 |         offset = tif->tif_dir.td_dirdatasize_offsets[i].offset; | 
 |         if (offset == IFDendoffset) | 
 |         { | 
 |             size += tif->tif_dir.td_dirdatasize_offsets[i].length; | 
 |             IFDendoffset += tif->tif_dir.td_dirdatasize_offsets[i].length; | 
 |         } | 
 |         else if (offset == IFDendoffset + 1) | 
 |         { | 
 |             /* Add gap byte after previous IFD data set. */ | 
 |             size += tif->tif_dir.td_dirdatasize_offsets[i].length + 1; | 
 |             IFDendoffset += tif->tif_dir.td_dirdatasize_offsets[i].length; | 
 |         } | 
 |         else | 
 |         { | 
 |             /* Further data is no more continuously after IFD */ | 
 |             break; | 
 |         } | 
 |     } | 
 |     /* Check for gap byte of some easy cases. This should cover 90% of cases. | 
 |      * Otherwise, IFD will be re-written even it might be safely overwritten. */ | 
 |     if (tif->tif_nextdiroff != 0) | 
 |     { | 
 |         if (tif->tif_nextdiroff == IFDendoffset + 1) | 
 |             size++; | 
 |     } | 
 |     else | 
 |     { | 
 |         /* Check for IFD data ends at EOF. Then IFD can always be safely | 
 |          * overwritten. */ | 
 |         offset = TIFFSeekFile(tif, 0, SEEK_END); | 
 |         if (offset == IFDendoffset) | 
 |         { | 
 |             tif->tif_dir.td_dirdatasize_read = UINT64_MAX; | 
 |             return; | 
 |         } | 
 |     } | 
 |  | 
 |     /* Finally, add the size of the IFD tag entries themselves. */ | 
 |     if (!(tif->tif_flags & TIFF_BIGTIFF)) | 
 |         tif->tif_dir.td_dirdatasize_read = 2 + dircount * 12 + 4 + size; | 
 |     else | 
 |         tif->tif_dir.td_dirdatasize_read = 8 + dircount * 20 + 8 + size; | 
 | } /*-- CalcFinalIFDdatasizeReading() --*/ | 
 |  | 
 | /* | 
 |  * Read the next TIFF directory from a file and convert it to the internal | 
 |  * format. We read directories sequentially. | 
 |  */ | 
 | int TIFFReadDirectory(TIFF *tif) | 
 | { | 
 |     static const char module[] = "TIFFReadDirectory"; | 
 |     TIFFDirEntry *dir; | 
 |     uint16_t dircount; | 
 |     TIFFDirEntry *dp; | 
 |     uint16_t di; | 
 |     const TIFFField *fip; | 
 |     uint32_t fii = FAILED_FII; | 
 |     toff_t nextdiroff; | 
 |     int bitspersample_read = FALSE; | 
 |     int color_channels; | 
 |  | 
 |     if (tif->tif_nextdiroff == 0) | 
 |     { | 
 |         /* In this special case, tif_diroff needs also to be set to 0. | 
 |          * This is behind the last IFD, thus no checking or reading necessary. | 
 |          */ | 
 |         tif->tif_diroff = tif->tif_nextdiroff; | 
 |         return 0; | 
 |     } | 
 |  | 
 |     nextdiroff = tif->tif_nextdiroff; | 
 |     /* tif_curdir++ and tif_nextdiroff should only be updated after SUCCESSFUL | 
 |      * reading of the directory. Otherwise, invalid IFD offsets could corrupt | 
 |      * the IFD list. */ | 
 |     if (!_TIFFCheckDirNumberAndOffset(tif, | 
 |                                       tif->tif_curdir == | 
 |                                               TIFF_NON_EXISTENT_DIR_NUMBER | 
 |                                           ? 0 | 
 |                                           : tif->tif_curdir + 1, | 
 |                                       nextdiroff)) | 
 |     { | 
 |         return 0; /* bad offset (IFD looping or more than TIFF_MAX_DIR_COUNT | 
 |                      IFDs) */ | 
 |     } | 
 |     dircount = TIFFFetchDirectory(tif, nextdiroff, &dir, &tif->tif_nextdiroff); | 
 |     if (!dircount) | 
 |     { | 
 |         TIFFErrorExtR(tif, module, | 
 |                       "Failed to read directory at offset %" PRIu64, | 
 |                       nextdiroff); | 
 |         return 0; | 
 |     } | 
 |     /* Set global values after a valid directory has been fetched. | 
 |      * tif_diroff is already set to nextdiroff in TIFFFetchDirectory() in the | 
 |      * beginning. */ | 
 |     if (tif->tif_curdir == TIFF_NON_EXISTENT_DIR_NUMBER) | 
 |         tif->tif_curdir = 0; | 
 |     else | 
 |         tif->tif_curdir++; | 
 |  | 
 |     TIFFReadDirectoryCheckOrder(tif, dir, dircount); | 
 |  | 
 |     /* | 
 |      * Mark duplicates of any tag to be ignored (bugzilla 1994) | 
 |      * to avoid certain pathological problems. | 
 |      */ | 
 |     { | 
 |         TIFFDirEntry *ma; | 
 |         uint16_t mb; | 
 |         for (ma = dir, mb = 0; mb < dircount; ma++, mb++) | 
 |         { | 
 |             TIFFDirEntry *na; | 
 |             uint16_t nb; | 
 |             for (na = ma + 1, nb = mb + 1; nb < dircount; na++, nb++) | 
 |             { | 
 |                 if (ma->tdir_tag == na->tdir_tag) | 
 |                 { | 
 |                     na->tdir_ignore = TRUE; | 
 |                 } | 
 |             } | 
 |         } | 
 |     } | 
 |  | 
 |     tif->tif_flags &= ~TIFF_BEENWRITING; /* reset before new dir */ | 
 |     tif->tif_flags &= ~TIFF_BUF4WRITE;   /* reset before new dir */ | 
 |     tif->tif_flags &= ~TIFF_CHOPPEDUPARRAYS; | 
 |  | 
 |     /* free any old stuff and reinit */ | 
 |     (*tif->tif_cleanup)(tif); /* cleanup any previous compression state */ | 
 |     TIFFFreeDirectory(tif); | 
 |     TIFFDefaultDirectory(tif); | 
 |  | 
 |     /* After setup a fresh directory indicate that now active IFD is also | 
 |      * present on file, even if its entries could not be read successfully | 
 |      * below.  */ | 
 |     tif->tif_dir.td_iswrittentofile = TRUE; | 
 |  | 
 |     /* Allocate arrays for offset values outside IFD entry for IFD data size | 
 |      * checking. Note: Counter are reset within TIFFFreeDirectory(). */ | 
 |     tif->tif_dir.td_dirdatasize_offsets = | 
 |         (TIFFEntryOffsetAndLength *)_TIFFmallocExt( | 
 |             tif, dircount * sizeof(TIFFEntryOffsetAndLength)); | 
 |     if (tif->tif_dir.td_dirdatasize_offsets == NULL) | 
 |     { | 
 |         TIFFErrorExtR( | 
 |             tif, module, | 
 |             "Failed to allocate memory for counting IFD data size at reading"); | 
 |         goto bad; | 
 |     } | 
 |     /* | 
 |      * Electronic Arts writes gray-scale TIFF files | 
 |      * without a PlanarConfiguration directory entry. | 
 |      * Thus we setup a default value here, even though | 
 |      * the TIFF spec says there is no default value. | 
 |      * After PlanarConfiguration is preset in TIFFDefaultDirectory() | 
 |      * the following setting is not needed, but does not harm either. | 
 |      */ | 
 |     TIFFSetField(tif, TIFFTAG_PLANARCONFIG, PLANARCONFIG_CONTIG); | 
 |     /* | 
 |      * Setup default value and then make a pass over | 
 |      * the fields to check type and tag information, | 
 |      * and to extract info required to size data | 
 |      * structures.  A second pass is made afterwards | 
 |      * to read in everything not taken in the first pass. | 
 |      * But we must process the Compression tag first | 
 |      * 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 | 
 |      * tag value because older TIFF specs permitted Compression | 
 |      * to be written as a SamplesPerPixel-count tag entry. | 
 |      * Thus if we don't first figure out the correct SamplesPerPixel | 
 |      * 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). | 
 |      */ | 
 |     dp = | 
 |         TIFFReadDirectoryFindEntry(tif, dir, dircount, TIFFTAG_SAMPLESPERPIXEL); | 
 |     if (dp) | 
 |     { | 
 |         if (!TIFFFetchNormalTag(tif, dp, 0)) | 
 |             goto bad; | 
 |         dp->tdir_ignore = TRUE; | 
 |     } | 
 |     dp = TIFFReadDirectoryFindEntry(tif, dir, dircount, TIFFTAG_COMPRESSION); | 
 |     if (dp) | 
 |     { | 
 |         /* | 
 |          * The 5.0 spec says the Compression tag has one value, while | 
 |          * earlier specs say it has one value per sample.  Because of | 
 |          * this, we accept the tag if one value is supplied with either | 
 |          * count. | 
 |          */ | 
 |         uint16_t value; | 
 |         enum TIFFReadDirEntryErr err; | 
 |         err = TIFFReadDirEntryShort(tif, dp, &value); | 
 |         if (err == TIFFReadDirEntryErrCount) | 
 |             err = TIFFReadDirEntryPersampleShort(tif, dp, &value); | 
 |         if (err != TIFFReadDirEntryErrOk) | 
 |         { | 
 |             TIFFReadDirEntryOutputErr(tif, err, module, "Compression", 0); | 
 |             goto bad; | 
 |         } | 
 |         if (!TIFFSetField(tif, TIFFTAG_COMPRESSION, value)) | 
 |             goto bad; | 
 |         dp->tdir_ignore = TRUE; | 
 |     } | 
 |     else | 
 |     { | 
 |         if (!TIFFSetField(tif, TIFFTAG_COMPRESSION, COMPRESSION_NONE)) | 
 |             goto bad; | 
 |     } | 
 |     /* | 
 |      * First real pass over the directory. | 
 |      */ | 
 |     for (di = 0, dp = dir; di < dircount; di++, dp++) | 
 |     { | 
 |         if (!dp->tdir_ignore) | 
 |         { | 
 |             TIFFReadDirectoryFindFieldInfo(tif, dp->tdir_tag, &fii); | 
 |             if (fii == FAILED_FII) | 
 |             { | 
 |                 TIFFWarningExtR(tif, module, | 
 |                                 "Unknown field with tag %" PRIu16 " (0x%" PRIx16 | 
 |                                 ") encountered", | 
 |                                 dp->tdir_tag, dp->tdir_tag); | 
 |                 /* the following knowingly leaks the | 
 |                    anonymous field structure */ | 
 |                 const TIFFField *fld = _TIFFCreateAnonField( | 
 |                     tif, dp->tdir_tag, (TIFFDataType)dp->tdir_type); | 
 |                 if (fld == NULL || !_TIFFMergeFields(tif, fld, 1)) | 
 |                 { | 
 |                     TIFFWarningExtR( | 
 |                         tif, module, | 
 |                         "Registering anonymous field with tag %" PRIu16 | 
 |                         " (0x%" PRIx16 ") failed", | 
 |                         dp->tdir_tag, dp->tdir_tag); | 
 |                     dp->tdir_ignore = TRUE; | 
 |                 } | 
 |                 else | 
 |                 { | 
 |                     TIFFReadDirectoryFindFieldInfo(tif, dp->tdir_tag, &fii); | 
 |                     assert(fii != FAILED_FII); | 
 |                 } | 
 |             } | 
 |         } | 
 |         if (!dp->tdir_ignore) | 
 |         { | 
 |             fip = tif->tif_fields[fii]; | 
 |             if (fip->field_bit == FIELD_IGNORE) | 
 |                 dp->tdir_ignore = TRUE; | 
 |             else | 
 |             { | 
 |                 switch (dp->tdir_tag) | 
 |                 { | 
 |                     case TIFFTAG_STRIPOFFSETS: | 
 |                     case TIFFTAG_STRIPBYTECOUNTS: | 
 |                     case TIFFTAG_TILEOFFSETS: | 
 |                     case TIFFTAG_TILEBYTECOUNTS: | 
 |                         TIFFSetFieldBit(tif, fip->field_bit); | 
 |                         break; | 
 |                     case TIFFTAG_IMAGEWIDTH: | 
 |                     case TIFFTAG_IMAGELENGTH: | 
 |                     case TIFFTAG_IMAGEDEPTH: | 
 |                     case TIFFTAG_TILELENGTH: | 
 |                     case TIFFTAG_TILEWIDTH: | 
 |                     case TIFFTAG_TILEDEPTH: | 
 |                     case TIFFTAG_PLANARCONFIG: | 
 |                     case TIFFTAG_ROWSPERSTRIP: | 
 |                     case TIFFTAG_EXTRASAMPLES: | 
 |                         if (!TIFFFetchNormalTag(tif, dp, 0)) | 
 |                             goto bad; | 
 |                         dp->tdir_ignore = TRUE; | 
 |                         break; | 
 |                     default: | 
 |                         if (!_TIFFCheckFieldIsValidForCodec(tif, dp->tdir_tag)) | 
 |                             dp->tdir_ignore = TRUE; | 
 |                         break; | 
 |                 } | 
 |             } | 
 |         } | 
 |     } | 
 |     /* | 
 |      * XXX: OJPEG hack. | 
 |      * If a) compression is OJPEG, b) planarconfig tag says it's separate, | 
 |      * c) strip offsets/bytecounts tag are both present and | 
 |      * d) both contain exactly one value, then we consistently find | 
 |      * that the buggy implementation of the buggy compression scheme | 
 |      * matches contig planarconfig best. So we 'fix-up' the tag here | 
 |      */ | 
 |     if ((tif->tif_dir.td_compression == COMPRESSION_OJPEG) && | 
 |         (tif->tif_dir.td_planarconfig == PLANARCONFIG_SEPARATE)) | 
 |     { | 
 |         if (!_TIFFFillStriles(tif)) | 
 |             goto bad; | 
 |         dp = TIFFReadDirectoryFindEntry(tif, dir, dircount, | 
 |                                         TIFFTAG_STRIPOFFSETS); | 
 |         if ((dp != 0) && (dp->tdir_count == 1)) | 
 |         { | 
 |             dp = TIFFReadDirectoryFindEntry(tif, dir, dircount, | 
 |                                             TIFFTAG_STRIPBYTECOUNTS); | 
 |             if ((dp != 0) && (dp->tdir_count == 1)) | 
 |             { | 
 |                 tif->tif_dir.td_planarconfig = PLANARCONFIG_CONTIG; | 
 |                 TIFFWarningExtR(tif, module, | 
 |                                 "Planarconfig tag value assumed incorrect, " | 
 |                                 "assuming data is contig instead of chunky"); | 
 |             } | 
 |         } | 
 |     } | 
 |     /* | 
 |      * Allocate directory structure and setup defaults. | 
 |      */ | 
 |     if (!TIFFFieldSet(tif, FIELD_IMAGEDIMENSIONS)) | 
 |     { | 
 |         MissingRequired(tif, "ImageLength"); | 
 |         goto bad; | 
 |     } | 
 |  | 
 |     /* | 
 |      * Second pass: extract other information. | 
 |      */ | 
 |     for (di = 0, dp = dir; di < dircount; di++, dp++) | 
 |     { | 
 |         if (!dp->tdir_ignore) | 
 |         { | 
 |             switch (dp->tdir_tag) | 
 |             { | 
 |                 case TIFFTAG_MINSAMPLEVALUE: | 
 |                 case TIFFTAG_MAXSAMPLEVALUE: | 
 |                 case TIFFTAG_BITSPERSAMPLE: | 
 |                 case TIFFTAG_DATATYPE: | 
 |                 case TIFFTAG_SAMPLEFORMAT: | 
 |                     /* | 
 |                      * The MinSampleValue, MaxSampleValue, BitsPerSample | 
 |                      * DataType and SampleFormat tags are supposed to be | 
 |                      * written as one value/sample, but some vendors | 
 |                      * incorrectly write one value only -- so we accept | 
 |                      * that as well (yuck). Other vendors write correct | 
 |                      * value for NumberOfSamples, but incorrect one for | 
 |                      * BitsPerSample and friends, and we will read this | 
 |                      * too. | 
 |                      */ | 
 |                     { | 
 |                         uint16_t value; | 
 |                         enum TIFFReadDirEntryErr err; | 
 |                         err = TIFFReadDirEntryShort(tif, dp, &value); | 
 |                         if (!EvaluateIFDdatasizeReading(tif, dp)) | 
 |                             goto bad; | 
 |                         if (err == TIFFReadDirEntryErrCount) | 
 |                             err = | 
 |                                 TIFFReadDirEntryPersampleShort(tif, dp, &value); | 
 |                         if (err != TIFFReadDirEntryErrOk) | 
 |                         { | 
 |                             fip = TIFFFieldWithTag(tif, dp->tdir_tag); | 
 |                             TIFFReadDirEntryOutputErr( | 
 |                                 tif, err, module, | 
 |                                 fip ? fip->field_name : "unknown tagname", 0); | 
 |                             goto bad; | 
 |                         } | 
 |                         if (!TIFFSetField(tif, dp->tdir_tag, value)) | 
 |                             goto bad; | 
 |                         if (dp->tdir_tag == TIFFTAG_BITSPERSAMPLE) | 
 |                             bitspersample_read = TRUE; | 
 |                     } | 
 |                     break; | 
 |                 case TIFFTAG_SMINSAMPLEVALUE: | 
 |                 case TIFFTAG_SMAXSAMPLEVALUE: | 
 |                 { | 
 |  | 
 |                     double *data = NULL; | 
 |                     enum TIFFReadDirEntryErr err; | 
 |                     uint32_t saved_flags; | 
 |                     int m; | 
 |                     if (dp->tdir_count != | 
 |                         (uint64_t)tif->tif_dir.td_samplesperpixel) | 
 |                         err = TIFFReadDirEntryErrCount; | 
 |                     else | 
 |                         err = TIFFReadDirEntryDoubleArray(tif, dp, &data); | 
 |                     if (!EvaluateIFDdatasizeReading(tif, dp)) | 
 |                         goto bad; | 
 |                     if (err != TIFFReadDirEntryErrOk) | 
 |                     { | 
 |                         fip = TIFFFieldWithTag(tif, dp->tdir_tag); | 
 |                         TIFFReadDirEntryOutputErr( | 
 |                             tif, err, module, | 
 |                             fip ? fip->field_name : "unknown tagname", 0); | 
 |                         goto bad; | 
 |                     } | 
 |                     saved_flags = tif->tif_flags; | 
 |                     tif->tif_flags |= TIFF_PERSAMPLE; | 
 |                     m = TIFFSetField(tif, dp->tdir_tag, data); | 
 |                     tif->tif_flags = saved_flags; | 
 |                     _TIFFfreeExt(tif, data); | 
 |                     if (!m) | 
 |                         goto bad; | 
 |                 } | 
 |                 break; | 
 |                 case TIFFTAG_STRIPOFFSETS: | 
 |                 case TIFFTAG_TILEOFFSETS: | 
 |                 { | 
 |                     switch (dp->tdir_type) | 
 |                     { | 
 |                         case TIFF_SHORT: | 
 |                         case TIFF_LONG: | 
 |                         case TIFF_LONG8: | 
 |                             break; | 
 |                         default: | 
 |                             /* Warn except if directory typically created with | 
 |                              * TIFFDeferStrileArrayWriting() */ | 
 |                             if (!(tif->tif_mode == O_RDWR && | 
 |                                   dp->tdir_count == 0 && dp->tdir_type == 0 && | 
 |                                   dp->tdir_offset.toff_long8 == 0)) | 
 |                             { | 
 |                                 fip = TIFFFieldWithTag(tif, dp->tdir_tag); | 
 |                                 TIFFWarningExtR( | 
 |                                     tif, module, "Invalid data type for tag %s", | 
 |                                     fip ? fip->field_name : "unknown tagname"); | 
 |                             } | 
 |                             break; | 
 |                     } | 
 |                     _TIFFmemcpy(&(tif->tif_dir.td_stripoffset_entry), dp, | 
 |                                 sizeof(TIFFDirEntry)); | 
 |                     if (!EvaluateIFDdatasizeReading(tif, dp)) | 
 |                         goto bad; | 
 |                 } | 
 |                 break; | 
 |                 case TIFFTAG_STRIPBYTECOUNTS: | 
 |                 case TIFFTAG_TILEBYTECOUNTS: | 
 |                 { | 
 |                     switch (dp->tdir_type) | 
 |                     { | 
 |                         case TIFF_SHORT: | 
 |                         case TIFF_LONG: | 
 |                         case TIFF_LONG8: | 
 |                             break; | 
 |                         default: | 
 |                             /* Warn except if directory typically created with | 
 |                              * TIFFDeferStrileArrayWriting() */ | 
 |                             if (!(tif->tif_mode == O_RDWR && | 
 |                                   dp->tdir_count == 0 && dp->tdir_type == 0 && | 
 |                                   dp->tdir_offset.toff_long8 == 0)) | 
 |                             { | 
 |                                 fip = TIFFFieldWithTag(tif, dp->tdir_tag); | 
 |                                 TIFFWarningExtR( | 
 |                                     tif, module, "Invalid data type for tag %s", | 
 |                                     fip ? fip->field_name : "unknown tagname"); | 
 |                             } | 
 |                             break; | 
 |                     } | 
 |                     _TIFFmemcpy(&(tif->tif_dir.td_stripbytecount_entry), dp, | 
 |                                 sizeof(TIFFDirEntry)); | 
 |                     if (!EvaluateIFDdatasizeReading(tif, dp)) | 
 |                         goto bad; | 
 |                 } | 
 |                 break; | 
 |                 case TIFFTAG_COLORMAP: | 
 |                 case TIFFTAG_TRANSFERFUNCTION: | 
 |                 { | 
 |                     enum TIFFReadDirEntryErr err; | 
 |                     uint32_t countpersample; | 
 |                     uint32_t countrequired; | 
 |                     uint32_t incrementpersample; | 
 |                     uint16_t *value = NULL; | 
 |                     /* It would be dangerous to instantiate those tag values */ | 
 |                     /* since if td_bitspersample has not yet been read (due to | 
 |                      */ | 
 |                     /* unordered tags), it could be read afterwards with a */ | 
 |                     /* values greater than the default one (1), which may cause | 
 |                      */ | 
 |                     /* crashes in user code */ | 
 |                     if (!bitspersample_read) | 
 |                     { | 
 |                         fip = TIFFFieldWithTag(tif, dp->tdir_tag); | 
 |                         TIFFWarningExtR( | 
 |                             tif, module, | 
 |                             "Ignoring %s since BitsPerSample tag not found", | 
 |                             fip ? fip->field_name : "unknown tagname"); | 
 |                         continue; | 
 |                     } | 
 |                     /* ColorMap or TransferFunction for high bit */ | 
 |                     /* depths do not make much sense and could be */ | 
 |                     /* used as a denial of service vector */ | 
 |                     if (tif->tif_dir.td_bitspersample > 24) | 
 |                     { | 
 |                         fip = TIFFFieldWithTag(tif, dp->tdir_tag); | 
 |                         TIFFWarningExtR( | 
 |                             tif, module, | 
 |                             "Ignoring %s because BitsPerSample=%" PRIu16 ">24", | 
 |                             fip ? fip->field_name : "unknown tagname", | 
 |                             tif->tif_dir.td_bitspersample); | 
 |                         continue; | 
 |                     } | 
 |                     countpersample = (1U << tif->tif_dir.td_bitspersample); | 
 |                     if ((dp->tdir_tag == TIFFTAG_TRANSFERFUNCTION) && | 
 |                         (dp->tdir_count == (uint64_t)countpersample)) | 
 |                     { | 
 |                         countrequired = countpersample; | 
 |                         incrementpersample = 0; | 
 |                     } | 
 |                     else | 
 |                     { | 
 |                         countrequired = 3 * countpersample; | 
 |                         incrementpersample = countpersample; | 
 |                     } | 
 |                     if (dp->tdir_count != (uint64_t)countrequired) | 
 |                         err = TIFFReadDirEntryErrCount; | 
 |                     else | 
 |                         err = TIFFReadDirEntryShortArray(tif, dp, &value); | 
 |                     if (!EvaluateIFDdatasizeReading(tif, dp)) | 
 |                         goto bad; | 
 |                     if (err != TIFFReadDirEntryErrOk) | 
 |                     { | 
 |                         fip = TIFFFieldWithTag(tif, dp->tdir_tag); | 
 |                         TIFFReadDirEntryOutputErr( | 
 |                             tif, err, module, | 
 |                             fip ? fip->field_name : "unknown tagname", 1); | 
 |                     } | 
 |                     else | 
 |                     { | 
 |                         TIFFSetField(tif, dp->tdir_tag, value, | 
 |                                      value + incrementpersample, | 
 |                                      value + 2 * incrementpersample); | 
 |                         _TIFFfreeExt(tif, value); | 
 |                     } | 
 |                 } | 
 |                 break; | 
 |                     /* BEGIN REV 4.0 COMPATIBILITY */ | 
 |                 case TIFFTAG_OSUBFILETYPE: | 
 |                 { | 
 |                     uint16_t valueo; | 
 |                     uint32_t value; | 
 |                     if (TIFFReadDirEntryShort(tif, dp, &valueo) == | 
 |                         TIFFReadDirEntryErrOk) | 
 |                     { | 
 |                         switch (valueo) | 
 |                         { | 
 |                             case OFILETYPE_REDUCEDIMAGE: | 
 |                                 value = FILETYPE_REDUCEDIMAGE; | 
 |                                 break; | 
 |                             case OFILETYPE_PAGE: | 
 |                                 value = FILETYPE_PAGE; | 
 |                                 break; | 
 |                             default: | 
 |                                 value = 0; | 
 |                                 break; | 
 |                         } | 
 |                         if (value != 0) | 
 |                             TIFFSetField(tif, TIFFTAG_SUBFILETYPE, value); | 
 |                     } | 
 |                 } | 
 |                 break; | 
 |                 /* END REV 4.0 COMPATIBILITY */ | 
 | #if 0 | 
 |                 case TIFFTAG_EP_BATTERYLEVEL: | 
 |                     /* TIFFTAG_EP_BATTERYLEVEL can be RATIONAL or ASCII. | 
 |                      * LibTiff defines it as ASCII and converts RATIONAL to an | 
 |                      * ASCII string. */ | 
 |                     switch (dp->tdir_type) | 
 |                     { | 
 |                         case TIFF_RATIONAL: | 
 |                         { | 
 |                             /* Read rational and convert to ASCII*/ | 
 |                             enum TIFFReadDirEntryErr err; | 
 |                             TIFFRational_t rValue; | 
 |                             err = TIFFReadDirEntryCheckedRationalDirect( | 
 |                                 tif, dp, &rValue); | 
 |                             if (err != TIFFReadDirEntryErrOk) | 
 |                             { | 
 |                                 fip = TIFFFieldWithTag(tif, dp->tdir_tag); | 
 |                                 TIFFReadDirEntryOutputErr( | 
 |                                     tif, err, module, | 
 |                                     fip ? fip->field_name : "unknown tagname", | 
 |                                     1); | 
 |                             } | 
 |                             else | 
 |                             { | 
 |                                 char szAux[32]; | 
 |                                 snprintf(szAux, sizeof(szAux) - 1, "%d/%d", | 
 |                                          rValue.uNum, rValue.uDenom); | 
 |                                 TIFFSetField(tif, dp->tdir_tag, szAux); | 
 |                             } | 
 |                         } | 
 |                         break; | 
 |                         case TIFF_ASCII: | 
 |                             (void)TIFFFetchNormalTag(tif, dp, TRUE); | 
 |                             break; | 
 |                         default: | 
 |                             fip = TIFFFieldWithTag(tif, dp->tdir_tag); | 
 |                             TIFFWarningExtR(tif, module, | 
 |                                             "Invalid data type for tag %s. " | 
 |                                             "ASCII or RATIONAL expected", | 
 |                                             fip ? fip->field_name | 
 |                                                 : "unknown tagname"); | 
 |                             break; | 
 |                     } | 
 |                     break; | 
 | #endif | 
 |                 default: | 
 |                     (void)TIFFFetchNormalTag(tif, dp, TRUE); | 
 |                     break; | 
 |             } /* -- switch (dp->tdir_tag) -- */ | 
 |         }     /* -- if (!dp->tdir_ignore) */ | 
 |     }         /* -- for-loop -- */ | 
 |  | 
 |     /* Evaluate final IFD data size. */ | 
 |     CalcFinalIFDdatasizeReading(tif, dircount); | 
 |  | 
 |     /* | 
 |      * OJPEG hack: | 
 |      * - If a) compression is OJPEG, and b) photometric tag is missing, | 
 |      * then we consistently find that photometric should be YCbCr | 
 |      * - If a) compression is OJPEG, and b) photometric tag says it's RGB, | 
 |      * then we consistently find that the buggy implementation of the | 
 |      * buggy compression scheme matches photometric YCbCr instead. | 
 |      * - If a) compression is OJPEG, and b) bitspersample tag is missing, | 
 |      * then we consistently find bitspersample should be 8. | 
 |      * - If a) compression is OJPEG, b) samplesperpixel tag is missing, | 
 |      * and c) photometric is RGB or YCbCr, then we consistently find | 
 |      * samplesperpixel should be 3 | 
 |      * - If a) compression is OJPEG, b) samplesperpixel tag is missing, | 
 |      * and c) photometric is MINISWHITE or MINISBLACK, then we consistently | 
 |      * find samplesperpixel should be 3 | 
 |      */ | 
 |     if (tif->tif_dir.td_compression == COMPRESSION_OJPEG) | 
 |     { | 
 |         if (!TIFFFieldSet(tif, FIELD_PHOTOMETRIC)) | 
 |         { | 
 |             TIFFWarningExtR( | 
 |                 tif, module, | 
 |                 "Photometric tag is missing, assuming data is YCbCr"); | 
 |             if (!TIFFSetField(tif, TIFFTAG_PHOTOMETRIC, PHOTOMETRIC_YCBCR)) | 
 |                 goto bad; | 
 |         } | 
 |         else if (tif->tif_dir.td_photometric == PHOTOMETRIC_RGB) | 
 |         { | 
 |             tif->tif_dir.td_photometric = PHOTOMETRIC_YCBCR; | 
 |             TIFFWarningExtR(tif, module, | 
 |                             "Photometric tag value assumed incorrect, " | 
 |                             "assuming data is YCbCr instead of RGB"); | 
 |         } | 
 |         if (!TIFFFieldSet(tif, FIELD_BITSPERSAMPLE)) | 
 |         { | 
 |             TIFFWarningExtR( | 
 |                 tif, module, | 
 |                 "BitsPerSample tag is missing, assuming 8 bits per sample"); | 
 |             if (!TIFFSetField(tif, TIFFTAG_BITSPERSAMPLE, 8)) | 
 |                 goto bad; | 
 |         } | 
 |         if (!TIFFFieldSet(tif, FIELD_SAMPLESPERPIXEL)) | 
 |         { | 
 |             if (tif->tif_dir.td_photometric == PHOTOMETRIC_RGB) | 
 |             { | 
 |                 TIFFWarningExtR(tif, module, | 
 |                                 "SamplesPerPixel tag is missing, " | 
 |                                 "assuming correct SamplesPerPixel value is 3"); | 
 |                 if (!TIFFSetField(tif, TIFFTAG_SAMPLESPERPIXEL, 3)) | 
 |                     goto bad; | 
 |             } | 
 |             if (tif->tif_dir.td_photometric == PHOTOMETRIC_YCBCR) | 
 |             { | 
 |                 TIFFWarningExtR(tif, module, | 
 |                                 "SamplesPerPixel tag is missing, " | 
 |                                 "applying correct SamplesPerPixel value of 3"); | 
 |                 if (!TIFFSetField(tif, TIFFTAG_SAMPLESPERPIXEL, 3)) | 
 |                     goto bad; | 
 |             } | 
 |             else if ((tif->tif_dir.td_photometric == PHOTOMETRIC_MINISWHITE) || | 
 |                      (tif->tif_dir.td_photometric == PHOTOMETRIC_MINISBLACK)) | 
 |             { | 
 |                 /* | 
 |                  * SamplesPerPixel tag is missing, but is not required | 
 |                  * by spec.  Assume correct SamplesPerPixel value of 1. | 
 |                  */ | 
 |                 if (!TIFFSetField(tif, TIFFTAG_SAMPLESPERPIXEL, 1)) | 
 |                     goto bad; | 
 |             } | 
 |         } | 
 |     } | 
 |  | 
 |     /* | 
 |      * Setup appropriate structures (by strip or by tile) | 
 |      * We do that only after the above OJPEG hack which alters SamplesPerPixel | 
 |      * and thus influences the number of strips in the separate planarconfig. | 
 |      */ | 
 |     if (!TIFFFieldSet(tif, FIELD_TILEDIMENSIONS)) | 
 |     { | 
 |         tif->tif_dir.td_nstrips = TIFFNumberOfStrips(tif); | 
 |         tif->tif_dir.td_tilewidth = tif->tif_dir.td_imagewidth; | 
 |         tif->tif_dir.td_tilelength = tif->tif_dir.td_rowsperstrip; | 
 |         tif->tif_dir.td_tiledepth = tif->tif_dir.td_imagedepth; | 
 |         tif->tif_flags &= ~TIFF_ISTILED; | 
 |     } | 
 |     else | 
 |     { | 
 |         tif->tif_dir.td_nstrips = TIFFNumberOfTiles(tif); | 
 |         tif->tif_flags |= TIFF_ISTILED; | 
 |     } | 
 |     if (!tif->tif_dir.td_nstrips) | 
 |     { | 
 |         TIFFErrorExtR(tif, module, "Cannot handle zero number of %s", | 
 |                       isTiled(tif) ? "tiles" : "strips"); | 
 |         goto bad; | 
 |     } | 
 |     if (tif->tif_dir.td_nstrips > INT_MAX) | 
 |     { | 
 |         TIFFErrorExt(tif->tif_clientdata, module, | 
 |                      "Cannot handle %u number of %s", | 
 |                      tif->tif_dir.td_nstrips, | 
 |                      isTiled(tif) ? "tiles" : "strips"); | 
 |         goto bad; | 
 |     } | 
 |     tif->tif_dir.td_stripsperimage = tif->tif_dir.td_nstrips; | 
 |     if (tif->tif_dir.td_planarconfig == PLANARCONFIG_SEPARATE) | 
 |         tif->tif_dir.td_stripsperimage /= tif->tif_dir.td_samplesperpixel; | 
 |     if (!TIFFFieldSet(tif, FIELD_STRIPOFFSETS)) | 
 |     { | 
 | #ifdef OJPEG_SUPPORT | 
 |         if ((tif->tif_dir.td_compression == COMPRESSION_OJPEG) && | 
 |             (isTiled(tif) == 0) && (tif->tif_dir.td_nstrips == 1)) | 
 |         { | 
 |             /* | 
 |              * XXX: OJPEG hack. | 
 |              * If a) compression is OJPEG, b) it's not a tiled TIFF, | 
 |              * and c) the number of strips is 1, | 
 |              * then we tolerate the absence of stripoffsets tag, | 
 |              * because, presumably, all required data is in the | 
 |              * JpegInterchangeFormat stream. | 
 |              */ | 
 |             TIFFSetFieldBit(tif, FIELD_STRIPOFFSETS); | 
 |         } | 
 |         else | 
 | #endif | 
 |         { | 
 |             MissingRequired(tif, isTiled(tif) ? "TileOffsets" : "StripOffsets"); | 
 |             goto bad; | 
 |         } | 
 |     } | 
 |  | 
 |     if (tif->tif_mode == O_RDWR && | 
 |         tif->tif_dir.td_stripoffset_entry.tdir_tag != 0 && | 
 |         tif->tif_dir.td_stripoffset_entry.tdir_count == 0 && | 
 |         tif->tif_dir.td_stripoffset_entry.tdir_type == 0 && | 
 |         tif->tif_dir.td_stripoffset_entry.tdir_offset.toff_long8 == 0 && | 
 |         tif->tif_dir.td_stripbytecount_entry.tdir_tag != 0 && | 
 |         tif->tif_dir.td_stripbytecount_entry.tdir_count == 0 && | 
 |         tif->tif_dir.td_stripbytecount_entry.tdir_type == 0 && | 
 |         tif->tif_dir.td_stripbytecount_entry.tdir_offset.toff_long8 == 0) | 
 |     { | 
 |         /* Directory typically created with TIFFDeferStrileArrayWriting() */ | 
 |         TIFFSetupStrips(tif); | 
 |     } | 
 |     else if (!(tif->tif_flags & TIFF_DEFERSTRILELOAD)) | 
 |     { | 
 |         if (tif->tif_dir.td_stripoffset_entry.tdir_tag != 0) | 
 |         { | 
 |             if (!TIFFFetchStripThing(tif, &(tif->tif_dir.td_stripoffset_entry), | 
 |                                      tif->tif_dir.td_nstrips, | 
 |                                      &tif->tif_dir.td_stripoffset_p)) | 
 |             { | 
 |                 goto bad; | 
 |             } | 
 |         } | 
 |         if (tif->tif_dir.td_stripbytecount_entry.tdir_tag != 0) | 
 |         { | 
 |             if (!TIFFFetchStripThing( | 
 |                     tif, &(tif->tif_dir.td_stripbytecount_entry), | 
 |                     tif->tif_dir.td_nstrips, &tif->tif_dir.td_stripbytecount_p)) | 
 |             { | 
 |                 goto bad; | 
 |             } | 
 |         } | 
 |     } | 
 |  | 
 |     /* | 
 |      * Make sure all non-color channels are extrasamples. | 
 |      * If it's not the case, define them as such. | 
 |      */ | 
 |     color_channels = _TIFFGetMaxColorChannels(tif->tif_dir.td_photometric); | 
 |     if (color_channels && | 
 |         tif->tif_dir.td_samplesperpixel - tif->tif_dir.td_extrasamples > | 
 |             color_channels) | 
 |     { | 
 |         uint16_t old_extrasamples; | 
 |         uint16_t *new_sampleinfo; | 
 |  | 
 |         TIFFWarningExtR( | 
 |             tif, module, | 
 |             "Sum of Photometric type-related " | 
 |             "color channels and ExtraSamples doesn't match SamplesPerPixel. " | 
 |             "Defining non-color channels as ExtraSamples."); | 
 |  | 
 |         old_extrasamples = tif->tif_dir.td_extrasamples; | 
 |         tif->tif_dir.td_extrasamples = | 
 |             (uint16_t)(tif->tif_dir.td_samplesperpixel - color_channels); | 
 |  | 
 |         // sampleinfo should contain information relative to these new extra | 
 |         // samples | 
 |         new_sampleinfo = (uint16_t *)_TIFFcallocExt( | 
 |             tif, tif->tif_dir.td_extrasamples, sizeof(uint16_t)); | 
 |         if (!new_sampleinfo) | 
 |         { | 
 |             TIFFErrorExtR(tif, module, | 
 |                           "Failed to allocate memory for " | 
 |                           "temporary new sampleinfo array " | 
 |                           "(%" PRIu16 " 16 bit elements)", | 
 |                           tif->tif_dir.td_extrasamples); | 
 |             goto bad; | 
 |         } | 
 |  | 
 |         if (old_extrasamples > 0) | 
 |             memcpy(new_sampleinfo, tif->tif_dir.td_sampleinfo, | 
 |                    old_extrasamples * sizeof(uint16_t)); | 
 |         _TIFFsetShortArrayExt(tif, &tif->tif_dir.td_sampleinfo, new_sampleinfo, | 
 |                               tif->tif_dir.td_extrasamples); | 
 |         _TIFFfreeExt(tif, new_sampleinfo); | 
 |     } | 
 |  | 
 |     /* | 
 |      * Verify Palette image has a Colormap. | 
 |      */ | 
 |     if (tif->tif_dir.td_photometric == PHOTOMETRIC_PALETTE && | 
 |         !TIFFFieldSet(tif, FIELD_COLORMAP)) | 
 |     { | 
 |         if (tif->tif_dir.td_bitspersample >= 8 && | 
 |             tif->tif_dir.td_samplesperpixel == 3) | 
 |             tif->tif_dir.td_photometric = PHOTOMETRIC_RGB; | 
 |         else if (tif->tif_dir.td_bitspersample >= 8) | 
 |             tif->tif_dir.td_photometric = PHOTOMETRIC_MINISBLACK; | 
 |         else | 
 |         { | 
 |             MissingRequired(tif, "Colormap"); | 
 |             goto bad; | 
 |         } | 
 |     } | 
 |     /* | 
 |      * OJPEG hack: | 
 |      * We do no further messing with strip/tile offsets/bytecounts in OJPEG | 
 |      * TIFFs | 
 |      */ | 
 |     if (tif->tif_dir.td_compression != COMPRESSION_OJPEG) | 
 |     { | 
 |         /* | 
 |          * Attempt to deal with a missing StripByteCounts tag. | 
 |          */ | 
 |         if (!TIFFFieldSet(tif, FIELD_STRIPBYTECOUNTS)) | 
 |         { | 
 |             /* | 
 |              * Some manufacturers violate the spec by not giving | 
 |              * the size of the strips.  In this case, assume there | 
 |              * is one uncompressed strip of data. | 
 |              */ | 
 |             if ((tif->tif_dir.td_planarconfig == PLANARCONFIG_CONTIG && | 
 |                  tif->tif_dir.td_nstrips > 1) || | 
 |                 (tif->tif_dir.td_planarconfig == PLANARCONFIG_SEPARATE && | 
 |                  tif->tif_dir.td_nstrips != | 
 |                      (uint32_t)tif->tif_dir.td_samplesperpixel)) | 
 |             { | 
 |                 MissingRequired(tif, "StripByteCounts"); | 
 |                 goto bad; | 
 |             } | 
 |             TIFFWarningExtR( | 
 |                 tif, module, | 
 |                 "TIFF directory is missing required " | 
 |                 "\"StripByteCounts\" field, calculating from imagelength"); | 
 |             if (EstimateStripByteCounts(tif, dir, dircount) < 0) | 
 |                 goto bad; | 
 |         } | 
 |         else if (tif->tif_dir.td_nstrips == 1 && | 
 |                  !(tif->tif_flags & TIFF_ISTILED) && ByteCountLooksBad(tif)) | 
 |         { | 
 |             /* | 
 |              * XXX: Plexus (and others) sometimes give a value of | 
 |              * zero for a tag when they don't know what the | 
 |              * correct value is!  Try and handle the simple case | 
 |              * of estimating the size of a one strip image. | 
 |              */ | 
 |             TIFFWarningExtR(tif, module, | 
 |                             "Bogus \"StripByteCounts\" field, ignoring and " | 
 |                             "calculating from imagelength"); | 
 |             if (EstimateStripByteCounts(tif, dir, dircount) < 0) | 
 |                 goto bad; | 
 |         } | 
 |         else if (!(tif->tif_flags & TIFF_DEFERSTRILELOAD) && | 
 |                  tif->tif_dir.td_planarconfig == PLANARCONFIG_CONTIG && | 
 |                  tif->tif_dir.td_nstrips > 2 && | 
 |                  tif->tif_dir.td_compression == COMPRESSION_NONE && | 
 |                  TIFFGetStrileByteCount(tif, 0) != | 
 |                      TIFFGetStrileByteCount(tif, 1) && | 
 |                  TIFFGetStrileByteCount(tif, 0) != 0 && | 
 |                  TIFFGetStrileByteCount(tif, 1) != 0) | 
 |         { | 
 |             /* | 
 |              * XXX: Some vendors fill StripByteCount array with | 
 |              * absolutely wrong values (it can be equal to | 
 |              * StripOffset array, for example). Catch this case | 
 |              * here. | 
 |              * | 
 |              * We avoid this check if deferring strile loading | 
 |              * as it would always force us to load the strip/tile | 
 |              * information. | 
 |              */ | 
 |             TIFFWarningExtR(tif, module, | 
 |                             "Wrong \"StripByteCounts\" field, ignoring and " | 
 |                             "calculating from imagelength"); | 
 |             if (EstimateStripByteCounts(tif, dir, dircount) < 0) | 
 |                 goto bad; | 
 |         } | 
 |     } | 
 |     if (dir) | 
 |     { | 
 |         _TIFFfreeExt(tif, dir); | 
 |         dir = NULL; | 
 |     } | 
 |     if (!TIFFFieldSet(tif, FIELD_MAXSAMPLEVALUE)) | 
 |     { | 
 |         if (tif->tif_dir.td_bitspersample >= 16) | 
 |             tif->tif_dir.td_maxsamplevalue = 0xFFFF; | 
 |         else | 
 |             tif->tif_dir.td_maxsamplevalue = | 
 |                 (uint16_t)((1L << tif->tif_dir.td_bitspersample) - 1); | 
 |     } | 
 |  | 
 | #ifdef STRIPBYTECOUNTSORTED_UNUSED | 
 |     /* | 
 |      * XXX: We can optimize checking for the strip bounds using the sorted | 
 |      * bytecounts array. See also comments for TIFFAppendToStrip() | 
 |      * function in tif_write.c. | 
 |      */ | 
 |     if (!(tif->tif_flags & TIFF_DEFERSTRILELOAD) && tif->tif_dir.td_nstrips > 1) | 
 |     { | 
 |         uint32_t strip; | 
 |  | 
 |         tif->tif_dir.td_stripbytecountsorted = 1; | 
 |         for (strip = 1; strip < tif->tif_dir.td_nstrips; strip++) | 
 |         { | 
 |             if (TIFFGetStrileOffset(tif, strip - 1) > | 
 |                 TIFFGetStrileOffset(tif, strip)) | 
 |             { | 
 |                 tif->tif_dir.td_stripbytecountsorted = 0; | 
 |                 break; | 
 |             } | 
 |         } | 
 |     } | 
 | #endif | 
 |  | 
 |     /* | 
 |      * An opportunity for compression mode dependent tag fixup | 
 |      */ | 
 |     (*tif->tif_fixuptags)(tif); | 
 |  | 
 |     /* | 
 |      * Some manufacturers make life difficult by writing | 
 |      * large amounts of uncompressed data as a single strip. | 
 |      * This is contrary to the recommendations of the spec. | 
 |      * The following makes an attempt at breaking such images | 
 |      * into strips closer to the recommended 8k bytes.  A | 
 |      * side effect, however, is that the RowsPerStrip tag | 
 |      * value may be changed. | 
 |      */ | 
 |     if ((tif->tif_dir.td_planarconfig == PLANARCONFIG_CONTIG) && | 
 |         (tif->tif_dir.td_nstrips == 1) && | 
 |         (tif->tif_dir.td_compression == COMPRESSION_NONE) && | 
 |         ((tif->tif_flags & (TIFF_STRIPCHOP | TIFF_ISTILED)) == TIFF_STRIPCHOP)) | 
 |     { | 
 |         ChopUpSingleUncompressedStrip(tif); | 
 |     } | 
 |  | 
 |     /* There are also uncompressed striped files with strips larger than */ | 
 |     /* 2 GB, which make them unfriendly with a lot of code. If possible, */ | 
 |     /* try to expose smaller "virtual" strips. */ | 
 |     if (tif->tif_dir.td_planarconfig == PLANARCONFIG_CONTIG && | 
 |         tif->tif_dir.td_compression == COMPRESSION_NONE && | 
 |         (tif->tif_flags & (TIFF_STRIPCHOP | TIFF_ISTILED)) == TIFF_STRIPCHOP && | 
 |         TIFFStripSize64(tif) > 0x7FFFFFFFUL) | 
 |     { | 
 |         TryChopUpUncompressedBigTiff(tif); | 
 |     } | 
 |  | 
 |     /* | 
 |      * Clear the dirty directory flag. | 
 |      */ | 
 |     tif->tif_flags &= ~TIFF_DIRTYDIRECT; | 
 |     tif->tif_flags &= ~TIFF_DIRTYSTRIP; | 
 |  | 
 |     /* | 
 |      * Reinitialize i/o since we are starting on a new directory. | 
 |      */ | 
 |     tif->tif_row = (uint32_t)-1; | 
 |     tif->tif_curstrip = (uint32_t)-1; | 
 |     tif->tif_col = (uint32_t)-1; | 
 |     tif->tif_curtile = (uint32_t)-1; | 
 |     tif->tif_tilesize = (tmsize_t)-1; | 
 |  | 
 |     tif->tif_scanlinesize = TIFFScanlineSize(tif); | 
 |     if (!tif->tif_scanlinesize) | 
 |     { | 
 |         TIFFErrorExtR(tif, module, "Cannot handle zero scanline size"); | 
 |         return (0); | 
 |     } | 
 |  | 
 |     if (isTiled(tif)) | 
 |     { | 
 |         tif->tif_tilesize = TIFFTileSize(tif); | 
 |         if (!tif->tif_tilesize) | 
 |         { | 
 |             TIFFErrorExtR(tif, module, "Cannot handle zero tile size"); | 
 |             return (0); | 
 |         } | 
 |     } | 
 |     else | 
 |     { | 
 |         if (!TIFFStripSize(tif)) | 
 |         { | 
 |             TIFFErrorExtR(tif, module, "Cannot handle zero strip size"); | 
 |             return (0); | 
 |         } | 
 |     } | 
 |     return (1); | 
 | bad: | 
 |     if (dir) | 
 |         _TIFFfreeExt(tif, dir); | 
 |     return (0); | 
 | } /*-- TIFFReadDirectory() --*/ | 
 |  | 
 | static void TIFFReadDirectoryCheckOrder(TIFF *tif, TIFFDirEntry *dir, | 
 |                                         uint16_t dircount) | 
 | { | 
 |     static const char module[] = "TIFFReadDirectoryCheckOrder"; | 
 |     uint32_t m; | 
 |     uint16_t n; | 
 |     TIFFDirEntry *o; | 
 |     m = 0; | 
 |     for (n = 0, o = dir; n < dircount; n++, o++) | 
 |     { | 
 |         if (o->tdir_tag < m) | 
 |         { | 
 |             TIFFWarningExtR(tif, module, | 
 |                             "Invalid TIFF directory; tags are not sorted in " | 
 |                             "ascending order"); | 
 |             break; | 
 |         } | 
 |         m = o->tdir_tag + 1; | 
 |     } | 
 | } | 
 |  | 
 | static TIFFDirEntry *TIFFReadDirectoryFindEntry(TIFF *tif, TIFFDirEntry *dir, | 
 |                                                 uint16_t dircount, | 
 |                                                 uint16_t tagid) | 
 | { | 
 |     TIFFDirEntry *m; | 
 |     uint16_t n; | 
 |     (void)tif; | 
 |     for (m = dir, n = 0; n < dircount; m++, n++) | 
 |     { | 
 |         if (m->tdir_tag == tagid) | 
 |             return (m); | 
 |     } | 
 |     return (0); | 
 | } | 
 |  | 
 | static void TIFFReadDirectoryFindFieldInfo(TIFF *tif, uint16_t tagid, | 
 |                                            uint32_t *fii) | 
 | { | 
 |     int32_t ma, mb, mc; | 
 |     ma = -1; | 
 |     mc = (int32_t)tif->tif_nfields; | 
 |     while (1) | 
 |     { | 
 |         if (ma + 1 == mc) | 
 |         { | 
 |             *fii = FAILED_FII; | 
 |             return; | 
 |         } | 
 |         mb = (ma + mc) / 2; | 
 |         if (tif->tif_fields[mb]->field_tag == (uint32_t)tagid) | 
 |             break; | 
 |         if (tif->tif_fields[mb]->field_tag < (uint32_t)tagid) | 
 |             ma = mb; | 
 |         else | 
 |             mc = mb; | 
 |     } | 
 |     while (1) | 
 |     { | 
 |         if (mb == 0) | 
 |             break; | 
 |         if (tif->tif_fields[mb - 1]->field_tag != (uint32_t)tagid) | 
 |             break; | 
 |         mb--; | 
 |     } | 
 |     *fii = mb; | 
 | } | 
 |  | 
 | /* | 
 |  * Read custom directory from the arbitrary offset. | 
 |  * The code is very similar to TIFFReadDirectory(). | 
 |  */ | 
 | int TIFFReadCustomDirectory(TIFF *tif, toff_t diroff, | 
 |                             const TIFFFieldArray *infoarray) | 
 | { | 
 |     static const char module[] = "TIFFReadCustomDirectory"; | 
 |     TIFFDirEntry *dir; | 
 |     uint16_t dircount; | 
 |     TIFFDirEntry *dp; | 
 |     uint16_t di; | 
 |     const TIFFField *fip; | 
 |     uint32_t fii; | 
 |  | 
 |     dircount = TIFFFetchDirectory(tif, diroff, &dir, NULL); | 
 |     if (!dircount) | 
 |     { | 
 |         TIFFErrorExtR(tif, module, | 
 |                       "Failed to read custom directory at offset %" PRIu64, | 
 |                       diroff); | 
 |         return 0; | 
 |     } | 
 |     TIFFReadDirectoryCheckOrder(tif, dir, dircount); | 
 |  | 
 |     /* | 
 |      * Mark duplicates of any tag to be ignored (bugzilla 1994) | 
 |      * to avoid certain pathological problems. | 
 |      */ | 
 |     { | 
 |         TIFFDirEntry *ma; | 
 |         uint16_t mb; | 
 |         for (ma = dir, mb = 0; mb < dircount; ma++, mb++) | 
 |         { | 
 |             TIFFDirEntry *na; | 
 |             uint16_t nb; | 
 |             for (na = ma + 1, nb = mb + 1; nb < dircount; na++, nb++) | 
 |             { | 
 |                 if (ma->tdir_tag == na->tdir_tag) | 
 |                 { | 
 |                     na->tdir_ignore = TRUE; | 
 |                 } | 
 |             } | 
 |         } | 
 |     } | 
 |  | 
 |     /* Free any old stuff and reinit. */ | 
 |     (*tif->tif_cleanup)(tif); /* cleanup any previous compression state */ | 
 |     TIFFFreeDirectory(tif); | 
 |     /* Even if custom directories do not need the default settings of a standard | 
 |      * IFD, the pointer to the TIFFSetField() and TIFFGetField() (i.e. | 
 |      * tif->tif_tagmethods.vsetfield and tif->tif_tagmethods.vgetfield) need to | 
 |      * be initialized, which is done in TIFFDefaultDirectory(). | 
 |      * After that, the field array for the custom tags needs to be setup again. | 
 |      */ | 
 |     TIFFDefaultDirectory(tif); | 
 |     _TIFFSetupFields(tif, infoarray); | 
 |  | 
 |     /* Allocate arrays for offset values outside IFD entry for IFD data size | 
 |      * checking. Note: Counter are reset within TIFFFreeDirectory(). */ | 
 |     tif->tif_dir.td_dirdatasize_offsets = | 
 |         (TIFFEntryOffsetAndLength *)_TIFFmallocExt( | 
 |             tif, dircount * sizeof(TIFFEntryOffsetAndLength)); | 
 |     if (tif->tif_dir.td_dirdatasize_offsets == NULL) | 
 |     { | 
 |         TIFFErrorExtR( | 
 |             tif, module, | 
 |             "Failed to allocate memory for counting IFD data size at reading"); | 
 |         if (dir) | 
 |             _TIFFfreeExt(tif, dir); | 
 |         return 0; | 
 |     } | 
 |  | 
 |     for (di = 0, dp = dir; di < dircount; di++, dp++) | 
 |     { | 
 |         TIFFReadDirectoryFindFieldInfo(tif, dp->tdir_tag, &fii); | 
 |         if (fii == FAILED_FII) | 
 |         { | 
 |             TIFFWarningExtR(tif, module, | 
 |                             "Unknown field with tag %" PRIu16 " (0x%" PRIx16 | 
 |                             ") encountered", | 
 |                             dp->tdir_tag, dp->tdir_tag); | 
 |             const TIFFField *fld = _TIFFCreateAnonField( | 
 |                 tif, dp->tdir_tag, (TIFFDataType)dp->tdir_type); | 
 |             if (fld == NULL || !_TIFFMergeFields(tif, fld, 1)) | 
 |             { | 
 |                 TIFFWarningExtR(tif, module, | 
 |                                 "Registering anonymous field with tag %" PRIu16 | 
 |                                 " (0x%" PRIx16 ") failed", | 
 |                                 dp->tdir_tag, dp->tdir_tag); | 
 |                 dp->tdir_ignore = TRUE; | 
 |             } | 
 |             else | 
 |             { | 
 |                 TIFFReadDirectoryFindFieldInfo(tif, dp->tdir_tag, &fii); | 
 |                 assert(fii != FAILED_FII); | 
 |             } | 
 |         } | 
 |         if (!dp->tdir_ignore) | 
 |         { | 
 |             fip = tif->tif_fields[fii]; | 
 |             if (fip->field_bit == FIELD_IGNORE) | 
 |                 dp->tdir_ignore = TRUE; | 
 |             else | 
 |             { | 
 |                 /* check data type */ | 
 |                 while ((fip->field_type != TIFF_ANY) && | 
 |                        (fip->field_type != dp->tdir_type)) | 
 |                 { | 
 |                     fii++; | 
 |                     if ((fii == tif->tif_nfields) || | 
 |                         (tif->tif_fields[fii]->field_tag != | 
 |                          (uint32_t)dp->tdir_tag)) | 
 |                     { | 
 |                         fii = 0xFFFF; | 
 |                         break; | 
 |                     } | 
 |                     fip = tif->tif_fields[fii]; | 
 |                 } | 
 |                 if (fii == 0xFFFF) | 
 |                 { | 
 |                     TIFFWarningExtR(tif, module, | 
 |                                     "Wrong data type %" PRIu16 | 
 |                                     " for \"%s\"; tag ignored", | 
 |                                     dp->tdir_type, fip->field_name); | 
 |                     dp->tdir_ignore = TRUE; | 
 |                 } | 
 |                 else | 
 |                 { | 
 |                     /* check count if known in advance */ | 
 |                     if ((fip->field_readcount != TIFF_VARIABLE) && | 
 |                         (fip->field_readcount != TIFF_VARIABLE2)) | 
 |                     { | 
 |                         uint32_t expected; | 
 |                         if (fip->field_readcount == TIFF_SPP) | 
 |                             expected = | 
 |                                 (uint32_t)tif->tif_dir.td_samplesperpixel; | 
 |                         else | 
 |                             expected = (uint32_t)fip->field_readcount; | 
 |                         if (!CheckDirCount(tif, dp, expected)) | 
 |                             dp->tdir_ignore = TRUE; | 
 |                     } | 
 |                 } | 
 |             } | 
 |             if (!dp->tdir_ignore) | 
 |             { | 
 |                 switch (dp->tdir_tag) | 
 |                 { | 
 |                     case EXIFTAG_SUBJECTDISTANCE: | 
 |                         if (!TIFFFieldIsAnonymous(fip)) | 
 |                         { | 
 |                             /* should only be called on a Exif directory */ | 
 |                             /* when exifFields[] is active */ | 
 |                             (void)TIFFFetchSubjectDistance(tif, dp); | 
 |                         } | 
 |                         else | 
 |                         { | 
 |                             (void)TIFFFetchNormalTag(tif, dp, TRUE); | 
 |                         } | 
 |                         break; | 
 |                     default: | 
 |                         (void)TIFFFetchNormalTag(tif, dp, TRUE); | 
 |                         break; | 
 |                 } | 
 |             } /*-- if (!dp->tdir_ignore) */ | 
 |         } | 
 |     } | 
 |     /* Evaluate final IFD data size. */ | 
 |     CalcFinalIFDdatasizeReading(tif, dircount); | 
 |  | 
 |     /* To be able to return from SubIFD or custom-IFD to main-IFD */ | 
 |     tif->tif_setdirectory_force_absolute = TRUE; | 
 |     if (dir) | 
 |         _TIFFfreeExt(tif, dir); | 
 |     return 1; | 
 | } | 
 |  | 
 | /* | 
 |  * EXIF is important special case of custom IFD, so we have a special | 
 |  * function to read it. | 
 |  */ | 
 | int TIFFReadEXIFDirectory(TIFF *tif, toff_t diroff) | 
 | { | 
 |     return TIFFReadCustomDirectory(tif, diroff, _TIFFGetExifFields()); | 
 | } | 
 |  | 
 | /* | 
 |  *--: EXIF-GPS custom directory reading as another special case of custom IFD. | 
 |  */ | 
 | int TIFFReadGPSDirectory(TIFF *tif, toff_t diroff) | 
 | { | 
 |     return TIFFReadCustomDirectory(tif, diroff, _TIFFGetGpsFields()); | 
 | } | 
 |  | 
 | static int EstimateStripByteCounts(TIFF *tif, TIFFDirEntry *dir, | 
 |                                    uint16_t dircount) | 
 | { | 
 |     static const char module[] = "EstimateStripByteCounts"; | 
 |  | 
 |     TIFFDirEntry *dp; | 
 |     TIFFDirectory *td = &tif->tif_dir; | 
 |     uint32_t strip; | 
 |  | 
 |     /* Do not try to load stripbytecount as we will compute it */ | 
 |     if (!_TIFFFillStrilesInternal(tif, 0)) | 
 |         return -1; | 
 |  | 
 |     const uint64_t allocsize = (uint64_t)td->td_nstrips * sizeof(uint64_t); | 
 |     uint64_t filesize = 0; | 
 |     if (allocsize > 100 * 1024 * 1024) | 
 |     { | 
 |         /* Before allocating a huge amount of memory for corrupted files, check | 
 |          * if size of requested memory is not greater than file size. */ | 
 |         filesize = TIFFGetFileSize(tif); | 
 |         if (allocsize > filesize) | 
 |         { | 
 |             TIFFWarningExtR( | 
 |                 tif, module, | 
 |                 "Requested memory size for StripByteCounts of %" PRIu64 | 
 |                 " is greater than filesize %" PRIu64 ". Memory not allocated", | 
 |                 allocsize, filesize); | 
 |             return -1; | 
 |         } | 
 |     } | 
 |  | 
 |     if (td->td_stripbytecount_p) | 
 |         _TIFFfreeExt(tif, td->td_stripbytecount_p); | 
 |     td->td_stripbytecount_p = (uint64_t *)_TIFFCheckMalloc( | 
 |         tif, td->td_nstrips, sizeof(uint64_t), "for \"StripByteCounts\" array"); | 
 |     if (td->td_stripbytecount_p == NULL) | 
 |         return -1; | 
 |  | 
 |     if (td->td_compression != COMPRESSION_NONE) | 
 |     { | 
 |         uint64_t space; | 
 |         uint16_t n; | 
 |         if (!(tif->tif_flags & TIFF_BIGTIFF)) | 
 |             space = sizeof(TIFFHeaderClassic) + 2 + dircount * 12 + 4; | 
 |         else | 
 |             space = sizeof(TIFFHeaderBig) + 8 + dircount * 20 + 8; | 
 |         /* calculate amount of space used by indirect values */ | 
 |         for (dp = dir, n = dircount; n > 0; n--, dp++) | 
 |         { | 
 |             uint32_t typewidth; | 
 |             uint64_t datasize; | 
 |             typewidth = TIFFDataWidth((TIFFDataType)dp->tdir_type); | 
 |             if (typewidth == 0) | 
 |             { | 
 |                 TIFFErrorExtR( | 
 |                     tif, module, | 
 |                     "Cannot determine size of unknown tag type %" PRIu16, | 
 |                     dp->tdir_type); | 
 |                 return -1; | 
 |             } | 
 |             if (dp->tdir_count > UINT64_MAX / typewidth) | 
 |                 return -1; | 
 |             datasize = (uint64_t)typewidth * dp->tdir_count; | 
 |             if (!(tif->tif_flags & TIFF_BIGTIFF)) | 
 |             { | 
 |                 if (datasize <= 4) | 
 |                     datasize = 0; | 
 |             } | 
 |             else | 
 |             { | 
 |                 if (datasize <= 8) | 
 |                     datasize = 0; | 
 |             } | 
 |             if (space > UINT64_MAX - datasize) | 
 |                 return -1; | 
 |             space += datasize; | 
 |         } | 
 |         if (filesize == 0) | 
 |             filesize = TIFFGetFileSize(tif); | 
 |         if (filesize < space) | 
 |             /* we should perhaps return in error ? */ | 
 |             space = filesize; | 
 |         else | 
 |             space = filesize - space; | 
 |         if (td->td_planarconfig == PLANARCONFIG_SEPARATE) | 
 |             space /= td->td_samplesperpixel; | 
 |         for (strip = 0; strip < td->td_nstrips; strip++) | 
 |             td->td_stripbytecount_p[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 (td->td_stripoffset_p[strip] > | 
 |             UINT64_MAX - td->td_stripbytecount_p[strip]) | 
 |             return -1; | 
 |         if (td->td_stripoffset_p[strip] + td->td_stripbytecount_p[strip] > | 
 |             filesize) | 
 |         { | 
 |             if (td->td_stripoffset_p[strip] >= filesize) | 
 |             { | 
 |                 /* Not sure what we should in that case... */ | 
 |                 td->td_stripbytecount_p[strip] = 0; | 
 |             } | 
 |             else | 
 |             { | 
 |                 td->td_stripbytecount_p[strip] = | 
 |                     filesize - td->td_stripoffset_p[strip]; | 
 |             } | 
 |         } | 
 |     } | 
 |     else if (isTiled(tif)) | 
 |     { | 
 |         uint64_t bytespertile = TIFFTileSize64(tif); | 
 |  | 
 |         for (strip = 0; strip < td->td_nstrips; strip++) | 
 |             td->td_stripbytecount_p[strip] = bytespertile; | 
 |     } | 
 |     else | 
 |     { | 
 |         uint64_t rowbytes = TIFFScanlineSize64(tif); | 
 |         uint32_t rowsperstrip = td->td_imagelength / td->td_stripsperimage; | 
 |         for (strip = 0; strip < td->td_nstrips; strip++) | 
 |         { | 
 |             if (rowbytes > 0 && rowsperstrip > UINT64_MAX / rowbytes) | 
 |                 return -1; | 
 |             td->td_stripbytecount_p[strip] = rowbytes * rowsperstrip; | 
 |         } | 
 |     } | 
 |     TIFFSetFieldBit(tif, FIELD_STRIPBYTECOUNTS); | 
 |     if (!TIFFFieldSet(tif, FIELD_ROWSPERSTRIP)) | 
 |         td->td_rowsperstrip = td->td_imagelength; | 
 |     return 1; | 
 | } | 
 |  | 
 | static void MissingRequired(TIFF *tif, const char *tagname) | 
 | { | 
 |     static const char module[] = "MissingRequired"; | 
 |  | 
 |     TIFFErrorExtR(tif, module, | 
 |                   "TIFF directory is missing required \"%s\" field", tagname); | 
 | } | 
 |  | 
 | static unsigned long hashFuncOffsetToNumber(const void *elt) | 
 | { | 
 |     const TIFFOffsetAndDirNumber *offsetAndDirNumber = | 
 |         (const TIFFOffsetAndDirNumber *)elt; | 
 |     const uint32_t hash = (uint32_t)(offsetAndDirNumber->offset >> 32) ^ | 
 |                           ((uint32_t)offsetAndDirNumber->offset & 0xFFFFFFFFU); | 
 |     return hash; | 
 | } | 
 |  | 
 | static bool equalFuncOffsetToNumber(const void *elt1, const void *elt2) | 
 | { | 
 |     const TIFFOffsetAndDirNumber *offsetAndDirNumber1 = | 
 |         (const TIFFOffsetAndDirNumber *)elt1; | 
 |     const TIFFOffsetAndDirNumber *offsetAndDirNumber2 = | 
 |         (const TIFFOffsetAndDirNumber *)elt2; | 
 |     return offsetAndDirNumber1->offset == offsetAndDirNumber2->offset; | 
 | } | 
 |  | 
 | static unsigned long hashFuncNumberToOffset(const void *elt) | 
 | { | 
 |     const TIFFOffsetAndDirNumber *offsetAndDirNumber = | 
 |         (const TIFFOffsetAndDirNumber *)elt; | 
 |     return offsetAndDirNumber->dirNumber; | 
 | } | 
 |  | 
 | static bool equalFuncNumberToOffset(const void *elt1, const void *elt2) | 
 | { | 
 |     const TIFFOffsetAndDirNumber *offsetAndDirNumber1 = | 
 |         (const TIFFOffsetAndDirNumber *)elt1; | 
 |     const TIFFOffsetAndDirNumber *offsetAndDirNumber2 = | 
 |         (const TIFFOffsetAndDirNumber *)elt2; | 
 |     return offsetAndDirNumber1->dirNumber == offsetAndDirNumber2->dirNumber; | 
 | } | 
 |  | 
 | /* | 
 |  * Check the directory number and offset against the list of already seen | 
 |  * directory numbers and offsets. This is a trick to prevent IFD looping. | 
 |  * The one can create TIFF file with looped directory pointers. We will | 
 |  * maintain a list of already seen directories and check every IFD offset | 
 |  * and its IFD number against that list. However, the offset of an IFD number | 
 |  * can change - e.g. when writing updates to file. | 
 |  * Returns 1 if all is ok; 0 if last directory or IFD loop is encountered, | 
 |  * or an error has occurred. | 
 |  */ | 
 | int _TIFFCheckDirNumberAndOffset(TIFF *tif, tdir_t dirn, uint64_t diroff) | 
 | { | 
 |     if (diroff == 0) /* no more directories */ | 
 |         return 0; | 
 |  | 
 |     if (tif->tif_map_dir_offset_to_number == NULL) | 
 |     { | 
 |         tif->tif_map_dir_offset_to_number = TIFFHashSetNew( | 
 |             hashFuncOffsetToNumber, equalFuncOffsetToNumber, free); | 
 |         if (tif->tif_map_dir_offset_to_number == NULL) | 
 |         { | 
 |             TIFFErrorExtR(tif, "_TIFFCheckDirNumberAndOffset", | 
 |                           "Not enough memory"); | 
 |             return 1; | 
 |         } | 
 |     } | 
 |  | 
 |     if (tif->tif_map_dir_number_to_offset == NULL) | 
 |     { | 
 |         /* No free callback for this map, as it shares the same items as | 
 |          * tif->tif_map_dir_offset_to_number. */ | 
 |         tif->tif_map_dir_number_to_offset = TIFFHashSetNew( | 
 |             hashFuncNumberToOffset, equalFuncNumberToOffset, NULL); | 
 |         if (tif->tif_map_dir_number_to_offset == NULL) | 
 |         { | 
 |             TIFFErrorExtR(tif, "_TIFFCheckDirNumberAndOffset", | 
 |                           "Not enough memory"); | 
 |             return 1; | 
 |         } | 
 |     } | 
 |  | 
 |     /* Check if offset is already in the list: | 
 |      * - yes: check, if offset is at the same IFD number - if not, it is an IFD | 
 |      * loop | 
 |      * -  no: add to list or update offset at that IFD number | 
 |      */ | 
 |     TIFFOffsetAndDirNumber entry; | 
 |     entry.offset = diroff; | 
 |     entry.dirNumber = dirn; | 
 |  | 
 |     TIFFOffsetAndDirNumber *foundEntry = | 
 |         (TIFFOffsetAndDirNumber *)TIFFHashSetLookup( | 
 |             tif->tif_map_dir_offset_to_number, &entry); | 
 |     if (foundEntry) | 
 |     { | 
 |         if (foundEntry->dirNumber == dirn) | 
 |         { | 
 |             return 1; | 
 |         } | 
 |         else | 
 |         { | 
 |             TIFFWarningExtR(tif, "_TIFFCheckDirNumberAndOffset", | 
 |                             "TIFF directory %d has IFD looping to directory %u " | 
 |                             "at offset 0x%" PRIx64 " (%" PRIu64 ")", | 
 |                             (int)dirn - 1, foundEntry->dirNumber, diroff, | 
 |                             diroff); | 
 |             return 0; | 
 |         } | 
 |     } | 
 |  | 
 |     /* Check if offset of an IFD has been changed and update offset of that IFD | 
 |      * number. */ | 
 |     foundEntry = (TIFFOffsetAndDirNumber *)TIFFHashSetLookup( | 
 |         tif->tif_map_dir_number_to_offset, &entry); | 
 |     if (foundEntry) | 
 |     { | 
 |         if (foundEntry->offset != diroff) | 
 |         { | 
 |             TIFFOffsetAndDirNumber entryOld; | 
 |             entryOld.offset = foundEntry->offset; | 
 |             entryOld.dirNumber = dirn; | 
 |             /* We must remove first from tif_map_dir_number_to_offset as the */ | 
 |             /* entry is owned (and thus freed) by */ | 
 |             /* tif_map_dir_offset_to_number */ | 
 |             TIFFOffsetAndDirNumber *foundEntryOld = | 
 |                 (TIFFOffsetAndDirNumber *)TIFFHashSetLookup( | 
 |                     tif->tif_map_dir_number_to_offset, &entryOld); | 
 |             if (foundEntryOld) | 
 |             { | 
 |                 TIFFHashSetRemove(tif->tif_map_dir_number_to_offset, | 
 |                                   foundEntryOld); | 
 |             } | 
 |             foundEntryOld = (TIFFOffsetAndDirNumber *)TIFFHashSetLookup( | 
 |                 tif->tif_map_dir_offset_to_number, &entryOld); | 
 |             if (foundEntryOld) | 
 |             { | 
 |                 TIFFHashSetRemove(tif->tif_map_dir_offset_to_number, | 
 |                                   foundEntryOld); | 
 |             } | 
 |  | 
 |             TIFFOffsetAndDirNumber *entryPtr = (TIFFOffsetAndDirNumber *)malloc( | 
 |                 sizeof(TIFFOffsetAndDirNumber)); | 
 |             if (entryPtr == NULL) | 
 |             { | 
 |                 return 0; | 
 |             } | 
 |  | 
 |             /* Add IFD offset and dirn to IFD directory list */ | 
 |             *entryPtr = entry; | 
 |  | 
 |             if (!TIFFHashSetInsert(tif->tif_map_dir_offset_to_number, entryPtr)) | 
 |             { | 
 |                 TIFFErrorExtR( | 
 |                     tif, "_TIFFCheckDirNumberAndOffset", | 
 |                     "Insertion in tif_map_dir_offset_to_number failed"); | 
 |                 return 0; | 
 |             } | 
 |             if (!TIFFHashSetInsert(tif->tif_map_dir_number_to_offset, entryPtr)) | 
 |             { | 
 |                 TIFFErrorExtR( | 
 |                     tif, "_TIFFCheckDirNumberAndOffset", | 
 |                     "Insertion in tif_map_dir_number_to_offset failed"); | 
 |                 return 0; | 
 |             } | 
 |         } | 
 |         return 1; | 
 |     } | 
 |  | 
 |     /* Arbitrary (hopefully big enough) limit */ | 
 |     if (TIFFHashSetSize(tif->tif_map_dir_offset_to_number) >= | 
 |         TIFF_MAX_DIR_COUNT) | 
 |     { | 
 |         TIFFErrorExtR(tif, "_TIFFCheckDirNumberAndOffset", | 
 |                       "Cannot handle more than %u TIFF directories", | 
 |                       TIFF_MAX_DIR_COUNT); | 
 |         return 0; | 
 |     } | 
 |  | 
 |     TIFFOffsetAndDirNumber *entryPtr = | 
 |         (TIFFOffsetAndDirNumber *)malloc(sizeof(TIFFOffsetAndDirNumber)); | 
 |     if (entryPtr == NULL) | 
 |     { | 
 |         TIFFErrorExtR(tif, "_TIFFCheckDirNumberAndOffset", | 
 |                       "malloc(sizeof(TIFFOffsetAndDirNumber)) failed"); | 
 |         return 0; | 
 |     } | 
 |  | 
 |     /* Add IFD offset and dirn to IFD directory list */ | 
 |     *entryPtr = entry; | 
 |  | 
 |     if (!TIFFHashSetInsert(tif->tif_map_dir_offset_to_number, entryPtr)) | 
 |     { | 
 |         TIFFErrorExtR(tif, "_TIFFCheckDirNumberAndOffset", | 
 |                       "Insertion in tif_map_dir_offset_to_number failed"); | 
 |         return 0; | 
 |     } | 
 |     if (!TIFFHashSetInsert(tif->tif_map_dir_number_to_offset, entryPtr)) | 
 |     { | 
 |         TIFFErrorExtR(tif, "_TIFFCheckDirNumberAndOffset", | 
 |                       "Insertion in tif_map_dir_number_to_offset failed"); | 
 |         return 0; | 
 |     } | 
 |  | 
 |     return 1; | 
 | } /* --- _TIFFCheckDirNumberAndOffset() ---*/ | 
 |  | 
 | /* | 
 |  * Retrieve the matching IFD directory number of a given IFD offset | 
 |  * from the list of directories already seen. | 
 |  * Returns 1 if the offset was in the list and the directory number | 
 |  * can be returned. | 
 |  * Otherwise returns 0 or if an error occurred. | 
 |  */ | 
 | int _TIFFGetDirNumberFromOffset(TIFF *tif, uint64_t diroff, tdir_t *dirn) | 
 | { | 
 |     if (diroff == 0) /* no more directories */ | 
 |         return 0; | 
 |  | 
 |     /* Check if offset is already in the list and return matching directory | 
 |      * number. Otherwise update IFD list using TIFFNumberOfDirectories() and | 
 |      * search again in IFD list. | 
 |      */ | 
 |     if (tif->tif_map_dir_offset_to_number == NULL) | 
 |         return 0; | 
 |     TIFFOffsetAndDirNumber entry; | 
 |     entry.offset = diroff; | 
 |     entry.dirNumber = 0; /* not used */ | 
 |  | 
 |     TIFFOffsetAndDirNumber *foundEntry = | 
 |         (TIFFOffsetAndDirNumber *)TIFFHashSetLookup( | 
 |             tif->tif_map_dir_offset_to_number, &entry); | 
 |     if (foundEntry) | 
 |     { | 
 |         *dirn = foundEntry->dirNumber; | 
 |         return 1; | 
 |     } | 
 |  | 
 |     /* This updates the directory list for all main-IFDs in the file. */ | 
 |     TIFFNumberOfDirectories(tif); | 
 |  | 
 |     foundEntry = (TIFFOffsetAndDirNumber *)TIFFHashSetLookup( | 
 |         tif->tif_map_dir_offset_to_number, &entry); | 
 |     if (foundEntry) | 
 |     { | 
 |         *dirn = foundEntry->dirNumber; | 
 |         return 1; | 
 |     } | 
 |  | 
 |     return 0; | 
 | } /*--- _TIFFGetDirNumberFromOffset() ---*/ | 
 |  | 
 | /* | 
 |  * Retrieve the matching IFD directory offset of a given IFD number | 
 |  * from the list of directories already seen. | 
 |  * Returns 1 if the offset was in the list of already seen IFDs and the | 
 |  * directory offset can be returned. The directory list is not updated. | 
 |  * Otherwise returns 0 or if an error occurred. | 
 |  */ | 
 | int _TIFFGetOffsetFromDirNumber(TIFF *tif, tdir_t dirn, uint64_t *diroff) | 
 | { | 
 |  | 
 |     if (tif->tif_map_dir_number_to_offset == NULL) | 
 |         return 0; | 
 |     TIFFOffsetAndDirNumber entry; | 
 |     entry.offset = 0; /* not used */ | 
 |     entry.dirNumber = dirn; | 
 |  | 
 |     TIFFOffsetAndDirNumber *foundEntry = | 
 |         (TIFFOffsetAndDirNumber *)TIFFHashSetLookup( | 
 |             tif->tif_map_dir_number_to_offset, &entry); | 
 |     if (foundEntry) | 
 |     { | 
 |         *diroff = foundEntry->offset; | 
 |         return 1; | 
 |     } | 
 |  | 
 |     return 0; | 
 | } /*--- _TIFFGetOffsetFromDirNumber() ---*/ | 
 |  | 
 | /* | 
 |  * Remove an entry from the directory list of already seen directories | 
 |  * by directory offset. | 
 |  * If an entry is to be removed from the list, it is also okay if the entry | 
 |  * is not in the list or the list does not exist. | 
 |  */ | 
 | int _TIFFRemoveEntryFromDirectoryListByOffset(TIFF *tif, uint64_t diroff) | 
 | { | 
 |     if (tif->tif_map_dir_offset_to_number == NULL) | 
 |         return 1; | 
 |  | 
 |     TIFFOffsetAndDirNumber entryOld; | 
 |     entryOld.offset = diroff; | 
 |     entryOld.dirNumber = 0; | 
 |     /* We must remove first from tif_map_dir_number_to_offset as the | 
 |      * entry is owned (and thus freed) by tif_map_dir_offset_to_number. | 
 |      * However, we need firstly to find the directory number from offset. */ | 
 |  | 
 |     TIFFOffsetAndDirNumber *foundEntryOldOff = | 
 |         (TIFFOffsetAndDirNumber *)TIFFHashSetLookup( | 
 |             tif->tif_map_dir_offset_to_number, &entryOld); | 
 |     if (foundEntryOldOff) | 
 |     { | 
 |         entryOld.dirNumber = foundEntryOldOff->dirNumber; | 
 |         if (tif->tif_map_dir_number_to_offset != NULL) | 
 |         { | 
 |             TIFFOffsetAndDirNumber *foundEntryOldDir = | 
 |                 (TIFFOffsetAndDirNumber *)TIFFHashSetLookup( | 
 |                     tif->tif_map_dir_number_to_offset, &entryOld); | 
 |             if (foundEntryOldDir) | 
 |             { | 
 |                 TIFFHashSetRemove(tif->tif_map_dir_number_to_offset, | 
 |                                   foundEntryOldDir); | 
 |                 TIFFHashSetRemove(tif->tif_map_dir_offset_to_number, | 
 |                                   foundEntryOldOff); | 
 |                 return 1; | 
 |             } | 
 |         } | 
 |         else | 
 |         { | 
 |             TIFFErrorExtR(tif, "_TIFFRemoveEntryFromDirectoryListByOffset", | 
 |                           "Unexpectedly tif_map_dir_number_to_offset is " | 
 |                           "missing but tif_map_dir_offset_to_number exists."); | 
 |             return 0; | 
 |         } | 
 |     } | 
 |     return 1; | 
 | } /*--- _TIFFRemoveEntryFromDirectoryListByOffset() ---*/ | 
 |  | 
 | /* | 
 |  * Check the count field of a directory entry against a known value.  The | 
 |  * caller is expected to skip/ignore the tag if there is a mismatch. | 
 |  */ | 
 | static int CheckDirCount(TIFF *tif, TIFFDirEntry *dir, uint32_t count) | 
 | { | 
 |     if ((uint64_t)count > dir->tdir_count) | 
 |     { | 
 |         const TIFFField *fip = TIFFFieldWithTag(tif, dir->tdir_tag); | 
 |         TIFFWarningExtR(tif, tif->tif_name, | 
 |                         "incorrect count for field \"%s\" (%" PRIu64 | 
 |                         ", expecting %" PRIu32 "); tag ignored", | 
 |                         fip ? fip->field_name : "unknown tagname", | 
 |                         dir->tdir_count, count); | 
 |         return (0); | 
 |     } | 
 |     else if ((uint64_t)count < dir->tdir_count) | 
 |     { | 
 |         const TIFFField *fip = TIFFFieldWithTag(tif, dir->tdir_tag); | 
 |         TIFFWarningExtR(tif, tif->tif_name, | 
 |                         "incorrect count for field \"%s\" (%" PRIu64 | 
 |                         ", expecting %" PRIu32 "); tag trimmed", | 
 |                         fip ? fip->field_name : "unknown tagname", | 
 |                         dir->tdir_count, count); | 
 |         dir->tdir_count = count; | 
 |         return (1); | 
 |     } | 
 |     return (1); | 
 | } | 
 |  | 
 | /* | 
 |  * Read IFD structure from the specified offset. If the pointer to | 
 |  * nextdiroff variable has been specified, read it too. Function returns a | 
 |  * number of fields in the directory or 0 if failed. | 
 |  */ | 
 | static uint16_t TIFFFetchDirectory(TIFF *tif, uint64_t diroff, | 
 |                                    TIFFDirEntry **pdir, uint64_t *nextdiroff) | 
 | { | 
 |     static const char module[] = "TIFFFetchDirectory"; | 
 |  | 
 |     void *origdir; | 
 |     uint16_t dircount16; | 
 |     uint32_t dirsize; | 
 |     TIFFDirEntry *dir; | 
 |     uint8_t *ma; | 
 |     TIFFDirEntry *mb; | 
 |     uint16_t n; | 
 |  | 
 |     assert(pdir); | 
 |  | 
 |     tif->tif_diroff = diroff; | 
 |     if (nextdiroff) | 
 |         *nextdiroff = 0; | 
 |     if (!isMapped(tif)) | 
 |     { | 
 |         if (!SeekOK(tif, tif->tif_diroff)) | 
 |         { | 
 |             TIFFErrorExtR(tif, module, | 
 |                           "%s: Seek error accessing TIFF directory", | 
 |                           tif->tif_name); | 
 |             return 0; | 
 |         } | 
 |         if (!(tif->tif_flags & TIFF_BIGTIFF)) | 
 |         { | 
 |             if (!ReadOK(tif, &dircount16, sizeof(uint16_t))) | 
 |             { | 
 |                 TIFFErrorExtR(tif, module, | 
 |                               "%s: Can not read TIFF directory count", | 
 |                               tif->tif_name); | 
 |                 return 0; | 
 |             } | 
 |             if (tif->tif_flags & TIFF_SWAB) | 
 |                 TIFFSwabShort(&dircount16); | 
 |             if (dircount16 > 4096) | 
 |             { | 
 |                 TIFFErrorExtR(tif, module, | 
 |                               "Sanity check on directory count failed, this is " | 
 |                               "probably not a valid IFD offset"); | 
 |                 return 0; | 
 |             } | 
 |             dirsize = 12; | 
 |         } | 
 |         else | 
 |         { | 
 |             uint64_t dircount64; | 
 |             if (!ReadOK(tif, &dircount64, sizeof(uint64_t))) | 
 |             { | 
 |                 TIFFErrorExtR(tif, module, | 
 |                               "%s: Can not read TIFF directory count", | 
 |                               tif->tif_name); | 
 |                 return 0; | 
 |             } | 
 |             if (tif->tif_flags & TIFF_SWAB) | 
 |                 TIFFSwabLong8(&dircount64); | 
 |             if (dircount64 > 4096) | 
 |             { | 
 |                 TIFFErrorExtR(tif, module, | 
 |                               "Sanity check on directory count failed, this is " | 
 |                               "probably not a valid IFD offset"); | 
 |                 return 0; | 
 |             } | 
 |             dircount16 = (uint16_t)dircount64; | 
 |             dirsize = 20; | 
 |         } | 
 |         origdir = _TIFFCheckMalloc(tif, dircount16, dirsize, | 
 |                                    "to read TIFF directory"); | 
 |         if (origdir == NULL) | 
 |             return 0; | 
 |         if (!ReadOK(tif, origdir, (tmsize_t)(dircount16 * dirsize))) | 
 |         { | 
 |             TIFFErrorExtR(tif, module, "%.100s: Can not read TIFF directory", | 
 |                           tif->tif_name); | 
 |             _TIFFfreeExt(tif, origdir); | 
 |             return 0; | 
 |         } | 
 |         /* | 
 |          * Read offset to next directory for sequential scans if | 
 |          * needed. | 
 |          */ | 
 |         if (nextdiroff) | 
 |         { | 
 |             if (!(tif->tif_flags & TIFF_BIGTIFF)) | 
 |             { | 
 |                 uint32_t nextdiroff32; | 
 |                 if (!ReadOK(tif, &nextdiroff32, sizeof(uint32_t))) | 
 |                     nextdiroff32 = 0; | 
 |                 if (tif->tif_flags & TIFF_SWAB) | 
 |                     TIFFSwabLong(&nextdiroff32); | 
 |                 *nextdiroff = nextdiroff32; | 
 |             } | 
 |             else | 
 |             { | 
 |                 if (!ReadOK(tif, nextdiroff, sizeof(uint64_t))) | 
 |                     *nextdiroff = 0; | 
 |                 if (tif->tif_flags & TIFF_SWAB) | 
 |                     TIFFSwabLong8(nextdiroff); | 
 |             } | 
 |         } | 
 |     } | 
 |     else | 
 |     { | 
 |         tmsize_t m; | 
 |         tmsize_t off; | 
 |         if (tif->tif_diroff > (uint64_t)INT64_MAX) | 
 |         { | 
 |             TIFFErrorExtR(tif, module, "Can not read TIFF directory count"); | 
 |             return (0); | 
 |         } | 
 |         off = (tmsize_t)tif->tif_diroff; | 
 |  | 
 |         /* | 
 |          * Check for integer overflow when validating the dir_off, | 
 |          * otherwise a very high offset may cause an OOB read and | 
 |          * crash the client. Make two comparisons instead of | 
 |          * | 
 |          *  off + sizeof(uint16_t) > tif->tif_size | 
 |          * | 
 |          * to avoid overflow. | 
 |          */ | 
 |         if (!(tif->tif_flags & TIFF_BIGTIFF)) | 
 |         { | 
 |             m = off + sizeof(uint16_t); | 
 |             if ((m < off) || (m < (tmsize_t)sizeof(uint16_t)) || | 
 |                 (m > tif->tif_size)) | 
 |             { | 
 |                 TIFFErrorExtR(tif, module, "Can not read TIFF directory count"); | 
 |                 return 0; | 
 |             } | 
 |             else | 
 |             { | 
 |                 _TIFFmemcpy(&dircount16, tif->tif_base + off, sizeof(uint16_t)); | 
 |             } | 
 |             off += sizeof(uint16_t); | 
 |             if (tif->tif_flags & TIFF_SWAB) | 
 |                 TIFFSwabShort(&dircount16); | 
 |             if (dircount16 > 4096) | 
 |             { | 
 |                 TIFFErrorExtR(tif, module, | 
 |                               "Sanity check on directory count failed, this is " | 
 |                               "probably not a valid IFD offset"); | 
 |                 return 0; | 
 |             } | 
 |             dirsize = 12; | 
 |         } | 
 |         else | 
 |         { | 
 |             uint64_t dircount64; | 
 |             m = off + sizeof(uint64_t); | 
 |             if ((m < off) || (m < (tmsize_t)sizeof(uint64_t)) || | 
 |                 (m > tif->tif_size)) | 
 |             { | 
 |                 TIFFErrorExtR(tif, module, "Can not read TIFF directory count"); | 
 |                 return 0; | 
 |             } | 
 |             else | 
 |             { | 
 |                 _TIFFmemcpy(&dircount64, tif->tif_base + off, sizeof(uint64_t)); | 
 |             } | 
 |             off += sizeof(uint64_t); | 
 |             if (tif->tif_flags & TIFF_SWAB) | 
 |                 TIFFSwabLong8(&dircount64); | 
 |             if (dircount64 > 4096) | 
 |             { | 
 |                 TIFFErrorExtR(tif, module, | 
 |                               "Sanity check on directory count failed, this is " | 
 |                               "probably not a valid IFD offset"); | 
 |                 return 0; | 
 |             } | 
 |             dircount16 = (uint16_t)dircount64; | 
 |             dirsize = 20; | 
 |         } | 
 |         if (dircount16 == 0) | 
 |         { | 
 |             TIFFErrorExtR(tif, module, | 
 |                           "Sanity check on directory count failed, zero tag " | 
 |                           "directories not supported"); | 
 |             return 0; | 
 |         } | 
 |         /* Before allocating a huge amount of memory for corrupted files, check | 
 |          * if size of requested memory is not greater than file size. */ | 
 |         uint64_t filesize = TIFFGetFileSize(tif); | 
 |         uint64_t allocsize = (uint64_t)dircount16 * dirsize; | 
 |         if (allocsize > filesize) | 
 |         { | 
 |             TIFFWarningExtR( | 
 |                 tif, module, | 
 |                 "Requested memory size for TIFF directory of %" PRIu64 | 
 |                 " is greater than filesize %" PRIu64 | 
 |                 ". Memory not allocated, TIFF directory not read", | 
 |                 allocsize, filesize); | 
 |             return 0; | 
 |         } | 
 |         origdir = _TIFFCheckMalloc(tif, dircount16, dirsize, | 
 |                                    "to read TIFF directory"); | 
 |         if (origdir == NULL) | 
 |             return 0; | 
 |         m = off + dircount16 * dirsize; | 
 |         if ((m < off) || (m < (tmsize_t)(dircount16 * dirsize)) || | 
 |             (m > tif->tif_size)) | 
 |         { | 
 |             TIFFErrorExtR(tif, module, "Can not read TIFF directory"); | 
 |             _TIFFfreeExt(tif, origdir); | 
 |             return 0; | 
 |         } | 
 |         else | 
 |         { | 
 |             _TIFFmemcpy(origdir, tif->tif_base + off, dircount16 * dirsize); | 
 |         } | 
 |         if (nextdiroff) | 
 |         { | 
 |             off += dircount16 * dirsize; | 
 |             if (!(tif->tif_flags & TIFF_BIGTIFF)) | 
 |             { | 
 |                 uint32_t nextdiroff32; | 
 |                 m = off + sizeof(uint32_t); | 
 |                 if ((m < off) || (m < (tmsize_t)sizeof(uint32_t)) || | 
 |                     (m > tif->tif_size)) | 
 |                     nextdiroff32 = 0; | 
 |                 else | 
 |                     _TIFFmemcpy(&nextdiroff32, tif->tif_base + off, | 
 |                                 sizeof(uint32_t)); | 
 |                 if (tif->tif_flags & TIFF_SWAB) | 
 |                     TIFFSwabLong(&nextdiroff32); | 
 |                 *nextdiroff = nextdiroff32; | 
 |             } | 
 |             else | 
 |             { | 
 |                 m = off + sizeof(uint64_t); | 
 |                 if ((m < off) || (m < (tmsize_t)sizeof(uint64_t)) || | 
 |                     (m > tif->tif_size)) | 
 |                     *nextdiroff = 0; | 
 |                 else | 
 |                     _TIFFmemcpy(nextdiroff, tif->tif_base + off, | 
 |                                 sizeof(uint64_t)); | 
 |                 if (tif->tif_flags & TIFF_SWAB) | 
 |                     TIFFSwabLong8(nextdiroff); | 
 |             } | 
 |         } | 
 |     } | 
 |     /* No check against filesize needed here because "dir" should have same size | 
 |      * than "origdir" checked above. */ | 
 |     dir = (TIFFDirEntry *)_TIFFCheckMalloc( | 
 |         tif, dircount16, sizeof(TIFFDirEntry), "to read TIFF directory"); | 
 |     if (dir == 0) | 
 |     { | 
 |         _TIFFfreeExt(tif, origdir); | 
 |         return 0; | 
 |     } | 
 |     ma = (uint8_t *)origdir; | 
 |     mb = dir; | 
 |     for (n = 0; n < dircount16; n++) | 
 |     { | 
 |         mb->tdir_ignore = FALSE; | 
 |         if (tif->tif_flags & TIFF_SWAB) | 
 |             TIFFSwabShort((uint16_t *)ma); | 
 |         mb->tdir_tag = *(uint16_t *)ma; | 
 |         ma += sizeof(uint16_t); | 
 |         if (tif->tif_flags & TIFF_SWAB) | 
 |             TIFFSwabShort((uint16_t *)ma); | 
 |         mb->tdir_type = *(uint16_t *)ma; | 
 |         ma += sizeof(uint16_t); | 
 |         if (!(tif->tif_flags & TIFF_BIGTIFF)) | 
 |         { | 
 |             if (tif->tif_flags & TIFF_SWAB) | 
 |                 TIFFSwabLong((uint32_t *)ma); | 
 |             mb->tdir_count = (uint64_t)(*(uint32_t *)ma); | 
 |             ma += sizeof(uint32_t); | 
 |             mb->tdir_offset.toff_long8 = 0; | 
 |             *(uint32_t *)(&mb->tdir_offset) = *(uint32_t *)ma; | 
 |             ma += sizeof(uint32_t); | 
 |         } | 
 |         else | 
 |         { | 
 |             if (tif->tif_flags & TIFF_SWAB) | 
 |                 TIFFSwabLong8((uint64_t *)ma); | 
 |             mb->tdir_count = TIFFReadUInt64(ma); | 
 |             ma += sizeof(uint64_t); | 
 |             mb->tdir_offset.toff_long8 = TIFFReadUInt64(ma); | 
 |             ma += sizeof(uint64_t); | 
 |         } | 
 |         mb++; | 
 |     } | 
 |     _TIFFfreeExt(tif, origdir); | 
 |     *pdir = dir; | 
 |     return dircount16; | 
 | } | 
 |  | 
 | /* | 
 |  * Fetch a tag that is not handled by special case code. | 
 |  */ | 
 | static int TIFFFetchNormalTag(TIFF *tif, TIFFDirEntry *dp, int recover) | 
 | { | 
 |     static const char module[] = "TIFFFetchNormalTag"; | 
 |     enum TIFFReadDirEntryErr err; | 
 |     uint32_t fii; | 
 |     const TIFFField *fip = NULL; | 
 |     TIFFReadDirectoryFindFieldInfo(tif, dp->tdir_tag, &fii); | 
 |     if (fii == FAILED_FII) | 
 |     { | 
 |         TIFFErrorExtR(tif, "TIFFFetchNormalTag", | 
 |                       "No definition found for tag %" PRIu16, dp->tdir_tag); | 
 |         return 0; | 
 |     } | 
 |     fip = tif->tif_fields[fii]; | 
 |     assert(fip != NULL); /* should not happen */ | 
 |     assert(fip->set_field_type != | 
 |            TIFF_SETGET_OTHER); /* if so, we shouldn't arrive here but deal with | 
 |                                   this in specialized code */ | 
 |     assert(fip->set_field_type != | 
 |            TIFF_SETGET_INT); /* if so, we shouldn't arrive here as this is only | 
 |                                 the case for pseudo-tags */ | 
 |     err = TIFFReadDirEntryErrOk; | 
 |     switch (fip->set_field_type) | 
 |     { | 
 |         case TIFF_SETGET_UNDEFINED: | 
 |             TIFFErrorExtR( | 
 |                 tif, "TIFFFetchNormalTag", | 
 |                 "Defined set_field_type of custom tag %u (%s) is " | 
 |                 "TIFF_SETGET_UNDEFINED and thus tag is not read from file", | 
 |                 fip->field_tag, fip->field_name); | 
 |             break; | 
 |         case TIFF_SETGET_ASCII: | 
 |         { | 
 |             uint8_t *data; | 
 |             assert(fip->field_passcount == 0); | 
 |             err = TIFFReadDirEntryByteArray(tif, dp, &data); | 
 |             if (err == TIFFReadDirEntryErrOk) | 
 |             { | 
 |                 size_t mb = 0; | 
 |                 int n; | 
 |                 if (data != NULL) | 
 |                 { | 
 |                     if (dp->tdir_count > 0 && data[dp->tdir_count - 1] == 0) | 
 |                     { | 
 |                         /* optimization: if data is known to be 0 terminated, we | 
 |                          * can use strlen() */ | 
 |                         mb = strlen((const char *)data); | 
 |                     } | 
 |                     else | 
 |                     { | 
 |                         /* general case. equivalent to non-portable */ | 
 |                         /* mb = strnlen((const char*)data, | 
 |                          * (uint32_t)dp->tdir_count); */ | 
 |                         uint8_t *ma = data; | 
 |                         while (mb < (uint32_t)dp->tdir_count) | 
 |                         { | 
 |                             if (*ma == 0) | 
 |                                 break; | 
 |                             ma++; | 
 |                             mb++; | 
 |                         } | 
 |                     } | 
 |                 } | 
 |                 if (!EvaluateIFDdatasizeReading(tif, dp)) | 
 |                 { | 
 |                     if (data != NULL) | 
 |                         _TIFFfreeExt(tif, data); | 
 |                     return (0); | 
 |                 } | 
 |                 if (mb + 1 < (uint32_t)dp->tdir_count) | 
 |                     TIFFWarningExtR( | 
 |                         tif, module, | 
 |                         "ASCII value for tag \"%s\" contains null byte in " | 
 |                         "value; value incorrectly truncated during reading due " | 
 |                         "to implementation limitations", | 
 |                         fip->field_name); | 
 |                 else if (mb + 1 > (uint32_t)dp->tdir_count) | 
 |                 { | 
 |                     TIFFWarningExtR(tif, module, | 
 |                                     "ASCII value for tag \"%s\" does not end " | 
 |                                     "in null byte. Forcing it to be null", | 
 |                                     fip->field_name); | 
 |                     /* TIFFReadDirEntryArrayWithLimit() ensures this can't be | 
 |                      * larger than MAX_SIZE_TAG_DATA */ | 
 |                     assert((uint32_t)dp->tdir_count + 1 == dp->tdir_count + 1); | 
 |                     uint8_t *o = | 
 |                         _TIFFmallocExt(tif, (uint32_t)dp->tdir_count + 1); | 
 |                     if (o == NULL) | 
 |                     { | 
 |                         if (data != NULL) | 
 |                             _TIFFfreeExt(tif, data); | 
 |                         return (0); | 
 |                     } | 
 |                     if (dp->tdir_count > 0) | 
 |                     { | 
 |                         _TIFFmemcpy(o, data, (uint32_t)dp->tdir_count); | 
 |                     } | 
 |                     o[(uint32_t)dp->tdir_count] = 0; | 
 |                     if (data != 0) | 
 |                         _TIFFfreeExt(tif, data); | 
 |                     data = o; | 
 |                 } | 
 |                 n = TIFFSetField(tif, dp->tdir_tag, data); | 
 |                 if (data != 0) | 
 |                     _TIFFfreeExt(tif, data); | 
 |                 if (!n) | 
 |                     return (0); | 
 |             } | 
 |         } | 
 |         break; | 
 |         case TIFF_SETGET_UINT8: | 
 |         { | 
 |             uint8_t data = 0; | 
 |             assert(fip->field_readcount == 1); | 
 |             assert(fip->field_passcount == 0); | 
 |             err = TIFFReadDirEntryByte(tif, dp, &data); | 
 |             if (err == TIFFReadDirEntryErrOk) | 
 |             { | 
 |                 if (!TIFFSetField(tif, dp->tdir_tag, data)) | 
 |                     return (0); | 
 |             } | 
 |         } | 
 |         break; | 
 |         case TIFF_SETGET_SINT8: | 
 |         { | 
 |             int8_t data = 0; | 
 |             assert(fip->field_readcount == 1); | 
 |             assert(fip->field_passcount == 0); | 
 |             err = TIFFReadDirEntrySbyte(tif, dp, &data); | 
 |             if (err == TIFFReadDirEntryErrOk) | 
 |             { | 
 |                 if (!TIFFSetField(tif, dp->tdir_tag, data)) | 
 |                     return (0); | 
 |             } | 
 |         } | 
 |         break; | 
 |         case TIFF_SETGET_UINT16: | 
 |         { | 
 |             uint16_t data; | 
 |             assert(fip->field_readcount == 1); | 
 |             assert(fip->field_passcount == 0); | 
 |             err = TIFFReadDirEntryShort(tif, dp, &data); | 
 |             if (err == TIFFReadDirEntryErrOk) | 
 |             { | 
 |                 if (!TIFFSetField(tif, dp->tdir_tag, data)) | 
 |                     return (0); | 
 |             } | 
 |         } | 
 |         break; | 
 |         case TIFF_SETGET_SINT16: | 
 |         { | 
 |             int16_t data; | 
 |             assert(fip->field_readcount == 1); | 
 |             assert(fip->field_passcount == 0); | 
 |             err = TIFFReadDirEntrySshort(tif, dp, &data); | 
 |             if (err == TIFFReadDirEntryErrOk) | 
 |             { | 
 |                 if (!TIFFSetField(tif, dp->tdir_tag, data)) | 
 |                     return (0); | 
 |             } | 
 |         } | 
 |         break; | 
 |         case TIFF_SETGET_UINT32: | 
 |         { | 
 |             uint32_t data; | 
 |             assert(fip->field_readcount == 1); | 
 |             assert(fip->field_passcount == 0); | 
 |             err = TIFFReadDirEntryLong(tif, dp, &data); | 
 |             if (err == TIFFReadDirEntryErrOk) | 
 |             { | 
 |                 if (!TIFFSetField(tif, dp->tdir_tag, data)) | 
 |                     return (0); | 
 |             } | 
 |         } | 
 |         break; | 
 |         case TIFF_SETGET_SINT32: | 
 |         { | 
 |             int32_t data; | 
 |             assert(fip->field_readcount == 1); | 
 |             assert(fip->field_passcount == 0); | 
 |             err = TIFFReadDirEntrySlong(tif, dp, &data); | 
 |             if (err == TIFFReadDirEntryErrOk) | 
 |             { | 
 |                 if (!TIFFSetField(tif, dp->tdir_tag, data)) | 
 |                     return (0); | 
 |             } | 
 |         } | 
 |         break; | 
 |         case TIFF_SETGET_UINT64: | 
 |         { | 
 |             uint64_t data; | 
 |             assert(fip->field_readcount == 1); | 
 |             assert(fip->field_passcount == 0); | 
 |             err = TIFFReadDirEntryLong8(tif, dp, &data); | 
 |             if (err == TIFFReadDirEntryErrOk) | 
 |             { | 
 |                 if (!EvaluateIFDdatasizeReading(tif, dp)) | 
 |                     return 0; | 
 |                 if (!TIFFSetField(tif, dp->tdir_tag, data)) | 
 |                     return (0); | 
 |             } | 
 |         } | 
 |         break; | 
 |         case TIFF_SETGET_SINT64: | 
 |         { | 
 |             int64_t data; | 
 |             assert(fip->field_readcount == 1); | 
 |             assert(fip->field_passcount == 0); | 
 |             err = TIFFReadDirEntrySlong8(tif, dp, &data); | 
 |             if (err == TIFFReadDirEntryErrOk) | 
 |             { | 
 |                 if (!EvaluateIFDdatasizeReading(tif, dp)) | 
 |                     return 0; | 
 |                 if (!TIFFSetField(tif, dp->tdir_tag, data)) | 
 |                     return (0); | 
 |             } | 
 |         } | 
 |         break; | 
 |         case TIFF_SETGET_FLOAT: | 
 |         { | 
 |             float data; | 
 |             assert(fip->field_readcount == 1); | 
 |             assert(fip->field_passcount == 0); | 
 |             err = TIFFReadDirEntryFloat(tif, dp, &data); | 
 |             if (err == TIFFReadDirEntryErrOk) | 
 |             { | 
 |                 if (!EvaluateIFDdatasizeReading(tif, dp)) | 
 |                     return 0; | 
 |                 if (!TIFFSetField(tif, dp->tdir_tag, data)) | 
 |                     return (0); | 
 |             } | 
 |         } | 
 |         break; | 
 |         case TIFF_SETGET_DOUBLE: | 
 |         { | 
 |             double data; | 
 |             assert(fip->field_readcount == 1); | 
 |             assert(fip->field_passcount == 0); | 
 |             err = TIFFReadDirEntryDouble(tif, dp, &data); | 
 |             if (err == TIFFReadDirEntryErrOk) | 
 |             { | 
 |                 if (!EvaluateIFDdatasizeReading(tif, dp)) | 
 |                     return 0; | 
 |                 if (!TIFFSetField(tif, dp->tdir_tag, data)) | 
 |                     return (0); | 
 |             } | 
 |         } | 
 |         break; | 
 |         case TIFF_SETGET_IFD8: | 
 |         { | 
 |             uint64_t data; | 
 |             assert(fip->field_readcount == 1); | 
 |             assert(fip->field_passcount == 0); | 
 |             err = TIFFReadDirEntryIfd8(tif, dp, &data); | 
 |             if (err == TIFFReadDirEntryErrOk) | 
 |             { | 
 |                 if (!EvaluateIFDdatasizeReading(tif, dp)) | 
 |                     return 0; | 
 |                 if (!TIFFSetField(tif, dp->tdir_tag, data)) | 
 |                     return (0); | 
 |             } | 
 |         } | 
 |         break; | 
 |         case TIFF_SETGET_UINT16_PAIR: | 
 |         { | 
 |             uint16_t *data; | 
 |             assert(fip->field_readcount == 2); | 
 |             assert(fip->field_passcount == 0); | 
 |             if (dp->tdir_count != 2) | 
 |             { | 
 |                 TIFFWarningExtR(tif, module, | 
 |                                 "incorrect count for field \"%s\", expected 2, " | 
 |                                 "got %" PRIu64, | 
 |                                 fip->field_name, dp->tdir_count); | 
 |                 return (0); | 
 |             } | 
 |             err = TIFFReadDirEntryShortArray(tif, dp, &data); | 
 |             if (err == TIFFReadDirEntryErrOk) | 
 |             { | 
 |                 int m; | 
 |                 assert(data); /* avoid CLang static Analyzer false positive */ | 
 |                 m = TIFFSetField(tif, dp->tdir_tag, data[0], data[1]); | 
 |                 _TIFFfreeExt(tif, data); | 
 |                 if (!m) | 
 |                     return (0); | 
 |             } | 
 |         } | 
 |         break; | 
 |         case TIFF_SETGET_C0_UINT8: | 
 |         { | 
 |             uint8_t *data; | 
 |             assert(fip->field_readcount >= 1); | 
 |             assert(fip->field_passcount == 0); | 
 |             if (dp->tdir_count != (uint64_t)fip->field_readcount) | 
 |             { | 
 |                 TIFFWarningExtR(tif, module, | 
 |                                 "incorrect count for field \"%s\", expected " | 
 |                                 "%d, got %" PRIu64, | 
 |                                 fip->field_name, (int)fip->field_readcount, | 
 |                                 dp->tdir_count); | 
 |                 return (0); | 
 |             } | 
 |             else | 
 |             { | 
 |                 err = TIFFReadDirEntryByteArray(tif, dp, &data); | 
 |                 if (err == TIFFReadDirEntryErrOk) | 
 |                 { | 
 |                     if (!EvaluateIFDdatasizeReading(tif, dp)) | 
 |                     { | 
 |                         if (data != 0) | 
 |                             _TIFFfreeExt(tif, data); | 
 |                         return 0; | 
 |                     } | 
 |                     int m; | 
 |                     m = TIFFSetField(tif, dp->tdir_tag, data); | 
 |                     if (data != 0) | 
 |                         _TIFFfreeExt(tif, data); | 
 |                     if (!m) | 
 |                         return (0); | 
 |                 } | 
 |             } | 
 |         } | 
 |         break; | 
 |         case TIFF_SETGET_C0_SINT8: | 
 |         { | 
 |             int8_t *data; | 
 |             assert(fip->field_readcount >= 1); | 
 |             assert(fip->field_passcount == 0); | 
 |             if (dp->tdir_count != (uint64_t)fip->field_readcount) | 
 |             { | 
 |                 TIFFWarningExtR(tif, module, | 
 |                                 "incorrect count for field \"%s\", expected " | 
 |                                 "%d, got %" PRIu64, | 
 |                                 fip->field_name, (int)fip->field_readcount, | 
 |                                 dp->tdir_count); | 
 |                 return (0); | 
 |             } | 
 |             else | 
 |             { | 
 |                 err = TIFFReadDirEntrySbyteArray(tif, dp, &data); | 
 |                 if (err == TIFFReadDirEntryErrOk) | 
 |                 { | 
 |                     if (!EvaluateIFDdatasizeReading(tif, dp)) | 
 |                     { | 
 |                         if (data != 0) | 
 |                             _TIFFfreeExt(tif, data); | 
 |                         return 0; | 
 |                     } | 
 |                     int m; | 
 |                     m = TIFFSetField(tif, dp->tdir_tag, data); | 
 |                     if (data != 0) | 
 |                         _TIFFfreeExt(tif, data); | 
 |                     if (!m) | 
 |                         return (0); | 
 |                 } | 
 |             } | 
 |         } | 
 |         break; | 
 |         case TIFF_SETGET_C0_UINT16: | 
 |         { | 
 |             uint16_t *data; | 
 |             assert(fip->field_readcount >= 1); | 
 |             assert(fip->field_passcount == 0); | 
 |             if (dp->tdir_count != (uint64_t)fip->field_readcount) | 
 |             { | 
 |                 TIFFWarningExtR(tif, module, | 
 |                                 "incorrect count for field \"%s\", expected " | 
 |                                 "%d, got %" PRIu64, | 
 |                                 fip->field_name, (int)fip->field_readcount, | 
 |                                 dp->tdir_count); | 
 |                 return (0); | 
 |             } | 
 |             else | 
 |             { | 
 |                 err = TIFFReadDirEntryShortArray(tif, dp, &data); | 
 |                 if (err == TIFFReadDirEntryErrOk) | 
 |                 { | 
 |                     if (!EvaluateIFDdatasizeReading(tif, dp)) | 
 |                     { | 
 |                         if (data != 0) | 
 |                             _TIFFfreeExt(tif, data); | 
 |                         return 0; | 
 |                     } | 
 |                     int m; | 
 |                     m = TIFFSetField(tif, dp->tdir_tag, data); | 
 |                     if (data != 0) | 
 |                         _TIFFfreeExt(tif, data); | 
 |                     if (!m) | 
 |                         return (0); | 
 |                 } | 
 |             } | 
 |         } | 
 |         break; | 
 |         case TIFF_SETGET_C0_SINT16: | 
 |         { | 
 |             int16_t *data; | 
 |             assert(fip->field_readcount >= 1); | 
 |             assert(fip->field_passcount == 0); | 
 |             if (dp->tdir_count != (uint64_t)fip->field_readcount) | 
 |             { | 
 |                 TIFFWarningExtR(tif, module, | 
 |                                 "incorrect count for field \"%s\", expected " | 
 |                                 "%d, got %" PRIu64, | 
 |                                 fip->field_name, (int)fip->field_readcount, | 
 |                                 dp->tdir_count); | 
 |                 return (0); | 
 |             } | 
 |             else | 
 |             { | 
 |                 err = TIFFReadDirEntrySshortArray(tif, dp, &data); | 
 |                 if (err == TIFFReadDirEntryErrOk) | 
 |                 { | 
 |                     if (!EvaluateIFDdatasizeReading(tif, dp)) | 
 |                     { | 
 |                         if (data != 0) | 
 |                             _TIFFfreeExt(tif, data); | 
 |                         return 0; | 
 |                     } | 
 |                     int m; | 
 |                     m = TIFFSetField(tif, dp->tdir_tag, data); | 
 |                     if (data != 0) | 
 |                         _TIFFfreeExt(tif, data); | 
 |                     if (!m) | 
 |                         return (0); | 
 |                 } | 
 |             } | 
 |         } | 
 |         break; | 
 |         case TIFF_SETGET_C0_UINT32: | 
 |         { | 
 |             uint32_t *data; | 
 |             assert(fip->field_readcount >= 1); | 
 |             assert(fip->field_passcount == 0); | 
 |             if (dp->tdir_count != (uint64_t)fip->field_readcount) | 
 |             { | 
 |                 TIFFWarningExtR(tif, module, | 
 |                                 "incorrect count for field \"%s\", expected " | 
 |                                 "%d, got %" PRIu64, | 
 |                                 fip->field_name, (int)fip->field_readcount, | 
 |                                 dp->tdir_count); | 
 |                 return (0); | 
 |             } | 
 |             else | 
 |             { | 
 |                 err = TIFFReadDirEntryLongArray(tif, dp, &data); | 
 |                 if (err == TIFFReadDirEntryErrOk) | 
 |                 { | 
 |                     if (!EvaluateIFDdatasizeReading(tif, dp)) | 
 |                     { | 
 |                         if (data != 0) | 
 |                             _TIFFfreeExt(tif, data); | 
 |                         return 0; | 
 |                     } | 
 |                     int m; | 
 |                     m = TIFFSetField(tif, dp->tdir_tag, data); | 
 |                     if (data != 0) | 
 |                         _TIFFfreeExt(tif, data); | 
 |                     if (!m) | 
 |                         return (0); | 
 |                 } | 
 |             } | 
 |         } | 
 |         break; | 
 |         case TIFF_SETGET_C0_SINT32: | 
 |         { | 
 |             int32_t *data; | 
 |             assert(fip->field_readcount >= 1); | 
 |             assert(fip->field_passcount == 0); | 
 |             if (dp->tdir_count != (uint64_t)fip->field_readcount) | 
 |             { | 
 |                 TIFFWarningExtR(tif, module, | 
 |                                 "incorrect count for field \"%s\", expected " | 
 |                                 "%d, got %" PRIu64, | 
 |                                 fip->field_name, (int)fip->field_readcount, | 
 |                                 dp->tdir_count); | 
 |                 return (0); | 
 |             } | 
 |             else | 
 |             { | 
 |                 err = TIFFReadDirEntrySlongArray(tif, dp, &data); | 
 |                 if (err == TIFFReadDirEntryErrOk) | 
 |                 { | 
 |                     if (!EvaluateIFDdatasizeReading(tif, dp)) | 
 |                     { | 
 |                         if (data != 0) | 
 |                             _TIFFfreeExt(tif, data); | 
 |                         return 0; | 
 |                     } | 
 |                     int m; | 
 |                     m = TIFFSetField(tif, dp->tdir_tag, data); | 
 |                     if (data != 0) | 
 |                         _TIFFfreeExt(tif, data); | 
 |                     if (!m) | 
 |                         return (0); | 
 |                 } | 
 |             } | 
 |         } | 
 |         break; | 
 |         case TIFF_SETGET_C0_UINT64: | 
 |         { | 
 |             uint64_t *data; | 
 |             assert(fip->field_readcount >= 1); | 
 |             assert(fip->field_passcount == 0); | 
 |             if (dp->tdir_count != (uint64_t)fip->field_readcount) | 
 |             { | 
 |                 TIFFWarningExtR(tif, module, | 
 |                                 "incorrect count for field \"%s\", expected " | 
 |                                 "%d, got %" PRIu64, | 
 |                                 fip->field_name, (int)fip->field_readcount, | 
 |                                 dp->tdir_count); | 
 |                 return (0); | 
 |             } | 
 |             else | 
 |             { | 
 |                 err = TIFFReadDirEntryLong8Array(tif, dp, &data); | 
 |                 if (err == TIFFReadDirEntryErrOk) | 
 |                 { | 
 |                     if (!EvaluateIFDdatasizeReading(tif, dp)) | 
 |                     { | 
 |                         if (data != 0) | 
 |                             _TIFFfreeExt(tif, data); | 
 |                         return 0; | 
 |                     } | 
 |                     int m; | 
 |                     m = TIFFSetField(tif, dp->tdir_tag, data); | 
 |                     if (data != 0) | 
 |                         _TIFFfreeExt(tif, data); | 
 |                     if (!m) | 
 |                         return (0); | 
 |                 } | 
 |             } | 
 |         } | 
 |         break; | 
 |         case TIFF_SETGET_C0_SINT64: | 
 |         { | 
 |             int64_t *data; | 
 |             assert(fip->field_readcount >= 1); | 
 |             assert(fip->field_passcount == 0); | 
 |             if (dp->tdir_count != (uint64_t)fip->field_readcount) | 
 |             { | 
 |                 TIFFWarningExtR(tif, module, | 
 |                                 "incorrect count for field \"%s\", expected " | 
 |                                 "%d, got %" PRIu64, | 
 |                                 fip->field_name, (int)fip->field_readcount, | 
 |                                 dp->tdir_count); | 
 |                 return (0); | 
 |             } | 
 |             else | 
 |             { | 
 |                 err = TIFFReadDirEntrySlong8Array(tif, dp, &data); | 
 |                 if (err == TIFFReadDirEntryErrOk) | 
 |                 { | 
 |                     if (!EvaluateIFDdatasizeReading(tif, dp)) | 
 |                     { | 
 |                         if (data != 0) | 
 |                             _TIFFfreeExt(tif, data); | 
 |                         return 0; | 
 |                     } | 
 |                     int m; | 
 |                     m = TIFFSetField(tif, dp->tdir_tag, data); | 
 |                     if (data != 0) | 
 |                         _TIFFfreeExt(tif, data); | 
 |                     if (!m) | 
 |                         return (0); | 
 |                 } | 
 |             } | 
 |         } | 
 |         break; | 
 |         case TIFF_SETGET_C0_FLOAT: | 
 |         { | 
 |             float *data; | 
 |             assert(fip->field_readcount >= 1); | 
 |             assert(fip->field_passcount == 0); | 
 |             if (dp->tdir_count != (uint64_t)fip->field_readcount) | 
 |             { | 
 |                 TIFFWarningExtR(tif, module, | 
 |                                 "incorrect count for field \"%s\", expected " | 
 |                                 "%d, got %" PRIu64, | 
 |                                 fip->field_name, (int)fip->field_readcount, | 
 |                                 dp->tdir_count); | 
 |                 return (0); | 
 |             } | 
 |             else | 
 |             { | 
 |                 err = TIFFReadDirEntryFloatArray(tif, dp, &data); | 
 |                 if (err == TIFFReadDirEntryErrOk) | 
 |                 { | 
 |                     if (!EvaluateIFDdatasizeReading(tif, dp)) | 
 |                     { | 
 |                         if (data != 0) | 
 |                             _TIFFfreeExt(tif, data); | 
 |                         return 0; | 
 |                     } | 
 |                     int m; | 
 |                     m = TIFFSetField(tif, dp->tdir_tag, data); | 
 |                     if (data != 0) | 
 |                         _TIFFfreeExt(tif, data); | 
 |                     if (!m) | 
 |                         return (0); | 
 |                 } | 
 |             } | 
 |         } | 
 |         break; | 
 |         /*--: Rational2Double: Extend for Double Arrays and Rational-Arrays read | 
 |          * into Double-Arrays. */ | 
 |         case TIFF_SETGET_C0_DOUBLE: | 
 |         { | 
 |             double *data; | 
 |             assert(fip->field_readcount >= 1); | 
 |             assert(fip->field_passcount == 0); | 
 |             if (dp->tdir_count != (uint64_t)fip->field_readcount) | 
 |             { | 
 |                 TIFFWarningExtR(tif, module, | 
 |                                 "incorrect count for field \"%s\", expected " | 
 |                                 "%d, got %" PRIu64, | 
 |                                 fip->field_name, (int)fip->field_readcount, | 
 |                                 dp->tdir_count); | 
 |                 return (0); | 
 |             } | 
 |             else | 
 |             { | 
 |                 err = TIFFReadDirEntryDoubleArray(tif, dp, &data); | 
 |                 if (err == TIFFReadDirEntryErrOk) | 
 |                 { | 
 |                     if (!EvaluateIFDdatasizeReading(tif, dp)) | 
 |                     { | 
 |                         if (data != 0) | 
 |                             _TIFFfreeExt(tif, data); | 
 |                         return 0; | 
 |                     } | 
 |                     int m; | 
 |                     m = TIFFSetField(tif, dp->tdir_tag, data); | 
 |                     if (data != 0) | 
 |                         _TIFFfreeExt(tif, data); | 
 |                     if (!m) | 
 |                         return (0); | 
 |                 } | 
 |             } | 
 |         } | 
 |         break; | 
 |         case TIFF_SETGET_C16_ASCII: | 
 |         { | 
 |             uint8_t *data; | 
 |             assert(fip->field_readcount == TIFF_VARIABLE); | 
 |             assert(fip->field_passcount == 1); | 
 |             if (dp->tdir_count > 0xFFFF) | 
 |                 err = TIFFReadDirEntryErrCount; | 
 |             else | 
 |             { | 
 |                 err = TIFFReadDirEntryByteArray(tif, dp, &data); | 
 |                 if (err == TIFFReadDirEntryErrOk) | 
 |                 { | 
 |                     if (!EvaluateIFDdatasizeReading(tif, dp)) | 
 |                     { | 
 |                         if (data != 0) | 
 |                             _TIFFfreeExt(tif, data); | 
 |                         return 0; | 
 |                     } | 
 |                     int m; | 
 |                     if (data != 0 && dp->tdir_count > 0 && | 
 |                         data[dp->tdir_count - 1] != '\0') | 
 |                     { | 
 |                         TIFFWarningExtR(tif, module, | 
 |                                         "ASCII value for ASCII array tag " | 
 |                                         "\"%s\" does not end in null " | 
 |                                         "byte. Forcing it to be null", | 
 |                                         fip->field_name); | 
 |                         /* Enlarge buffer and add terminating null. */ | 
 |                         uint8_t *o = | 
 |                             _TIFFmallocExt(tif, (uint32_t)dp->tdir_count + 1); | 
 |                         if (o == NULL) | 
 |                         { | 
 |                             if (data != NULL) | 
 |                                 _TIFFfreeExt(tif, data); | 
 |                             return (0); | 
 |                         } | 
 |                         if (dp->tdir_count > 0) | 
 |                         { | 
 |                             _TIFFmemcpy(o, data, (uint32_t)dp->tdir_count); | 
 |                         } | 
 |                         o[(uint32_t)dp->tdir_count] = 0; | 
 |                         dp->tdir_count++; /* Increment for added null. */ | 
 |                         if (data != 0) | 
 |                             _TIFFfreeExt(tif, data); | 
 |                         data = o; | 
 |                     } | 
 |                     m = TIFFSetField(tif, dp->tdir_tag, | 
 |                                      (uint16_t)(dp->tdir_count), data); | 
 |                     if (data != 0) | 
 |                         _TIFFfreeExt(tif, data); | 
 |                     if (!m) | 
 |                         return (0); | 
 |                 } | 
 |             } | 
 |         } | 
 |         break; | 
 |         case TIFF_SETGET_C16_UINT8: | 
 |         { | 
 |             uint8_t *data; | 
 |             assert(fip->field_readcount == TIFF_VARIABLE); | 
 |             assert(fip->field_passcount == 1); | 
 |             if (dp->tdir_count > 0xFFFF) | 
 |                 err = TIFFReadDirEntryErrCount; | 
 |             else | 
 |             { | 
 |                 err = TIFFReadDirEntryByteArray(tif, dp, &data); | 
 |                 if (err == TIFFReadDirEntryErrOk) | 
 |                 { | 
 |                     if (!EvaluateIFDdatasizeReading(tif, dp)) | 
 |                     { | 
 |                         if (data != 0) | 
 |                             _TIFFfreeExt(tif, data); | 
 |                         return 0; | 
 |                     } | 
 |                     int m; | 
 |                     m = TIFFSetField(tif, dp->tdir_tag, | 
 |                                      (uint16_t)(dp->tdir_count), data); | 
 |                     if (data != 0) | 
 |                         _TIFFfreeExt(tif, data); | 
 |                     if (!m) | 
 |                         return (0); | 
 |                 } | 
 |             } | 
 |         } | 
 |         break; | 
 |         case TIFF_SETGET_C16_SINT8: | 
 |         { | 
 |             int8_t *data; | 
 |             assert(fip->field_readcount == TIFF_VARIABLE); | 
 |             assert(fip->field_passcount == 1); | 
 |             if (dp->tdir_count > 0xFFFF) | 
 |                 err = TIFFReadDirEntryErrCount; | 
 |             else | 
 |             { | 
 |                 err = TIFFReadDirEntrySbyteArray(tif, dp, &data); | 
 |                 if (err == TIFFReadDirEntryErrOk) | 
 |                 { | 
 |                     if (!EvaluateIFDdatasizeReading(tif, dp)) | 
 |                     { | 
 |                         if (data != 0) | 
 |                             _TIFFfreeExt(tif, data); | 
 |                         return 0; | 
 |                     } | 
 |                     int m; | 
 |                     m = TIFFSetField(tif, dp->tdir_tag, | 
 |                                      (uint16_t)(dp->tdir_count), data); | 
 |                     if (data != 0) | 
 |                         _TIFFfreeExt(tif, data); | 
 |                     if (!m) | 
 |                         return (0); | 
 |                 } | 
 |             } | 
 |         } | 
 |         break; | 
 |         case TIFF_SETGET_C16_UINT16: | 
 |         { | 
 |             uint16_t *data; | 
 |             assert(fip->field_readcount == TIFF_VARIABLE); | 
 |             assert(fip->field_passcount == 1); | 
 |             if (dp->tdir_count > 0xFFFF) | 
 |                 err = TIFFReadDirEntryErrCount; | 
 |             else | 
 |             { | 
 |                 err = TIFFReadDirEntryShortArray(tif, dp, &data); | 
 |                 if (err == TIFFReadDirEntryErrOk) | 
 |                 { | 
 |                     if (!EvaluateIFDdatasizeReading(tif, dp)) | 
 |                     { | 
 |                         if (data != 0) | 
 |                             _TIFFfreeExt(tif, data); | 
 |                         return 0; | 
 |                     } | 
 |                     int m; | 
 |                     m = TIFFSetField(tif, dp->tdir_tag, | 
 |                                      (uint16_t)(dp->tdir_count), data); | 
 |                     if (data != 0) | 
 |                         _TIFFfreeExt(tif, data); | 
 |                     if (!m) | 
 |                         return (0); | 
 |                 } | 
 |             } | 
 |         } | 
 |         break; | 
 |         case TIFF_SETGET_C16_SINT16: | 
 |         { | 
 |             int16_t *data; | 
 |             assert(fip->field_readcount == TIFF_VARIABLE); | 
 |             assert(fip->field_passcount == 1); | 
 |             if (dp->tdir_count > 0xFFFF) | 
 |                 err = TIFFReadDirEntryErrCount; | 
 |             else | 
 |             { | 
 |                 err = TIFFReadDirEntrySshortArray(tif, dp, &data); | 
 |                 if (err == TIFFReadDirEntryErrOk) | 
 |                 { | 
 |                     if (!EvaluateIFDdatasizeReading(tif, dp)) | 
 |                     { | 
 |                         if (data != 0) | 
 |                             _TIFFfreeExt(tif, data); | 
 |                         return 0; | 
 |                     } | 
 |                     int m; | 
 |                     m = TIFFSetField(tif, dp->tdir_tag, | 
 |                                      (uint16_t)(dp->tdir_count), data); | 
 |                     if (data != 0) | 
 |                         _TIFFfreeExt(tif, data); | 
 |                     if (!m) | 
 |                         return (0); | 
 |                 } | 
 |             } | 
 |         } | 
 |         break; | 
 |         case TIFF_SETGET_C16_UINT32: | 
 |         { | 
 |             uint32_t *data; | 
 |             assert(fip->field_readcount == TIFF_VARIABLE); | 
 |             assert(fip->field_passcount == 1); | 
 |             if (dp->tdir_count > 0xFFFF) | 
 |                 err = TIFFReadDirEntryErrCount; | 
 |             else | 
 |             { | 
 |                 err = TIFFReadDirEntryLongArray(tif, dp, &data); | 
 |                 if (err == TIFFReadDirEntryErrOk) | 
 |                 { | 
 |                     if (!EvaluateIFDdatasizeReading(tif, dp)) | 
 |                     { | 
 |                         if (data != 0) | 
 |                             _TIFFfreeExt(tif, data); | 
 |                         return 0; | 
 |                     } | 
 |                     int m; | 
 |                     m = TIFFSetField(tif, dp->tdir_tag, | 
 |                                      (uint16_t)(dp->tdir_count), data); | 
 |                     if (data != 0) | 
 |                         _TIFFfreeExt(tif, data); | 
 |                     if (!m) | 
 |                         return (0); | 
 |                 } | 
 |             } | 
 |         } | 
 |         break; | 
 |         case TIFF_SETGET_C16_SINT32: | 
 |         { | 
 |             int32_t *data; | 
 |             assert(fip->field_readcount == TIFF_VARIABLE); | 
 |             assert(fip->field_passcount == 1); | 
 |             if (dp->tdir_count > 0xFFFF) | 
 |                 err = TIFFReadDirEntryErrCount; | 
 |             else | 
 |             { | 
 |                 err = TIFFReadDirEntrySlongArray(tif, dp, &data); | 
 |                 if (err == TIFFReadDirEntryErrOk) | 
 |                 { | 
 |                     if (!EvaluateIFDdatasizeReading(tif, dp)) | 
 |                     { | 
 |                         if (data != 0) | 
 |                             _TIFFfreeExt(tif, data); | 
 |                         return 0; | 
 |                     } | 
 |                     int m; | 
 |                     m = TIFFSetField(tif, dp->tdir_tag, | 
 |                                      (uint16_t)(dp->tdir_count), data); | 
 |                     if (data != 0) | 
 |                         _TIFFfreeExt(tif, data); | 
 |                     if (!m) | 
 |                         return (0); | 
 |                 } | 
 |             } | 
 |         } | 
 |         break; | 
 |         case TIFF_SETGET_C16_UINT64: | 
 |         { | 
 |             uint64_t *data; | 
 |             assert(fip->field_readcount == TIFF_VARIABLE); | 
 |             assert(fip->field_passcount == 1); | 
 |             if (dp->tdir_count > 0xFFFF) | 
 |                 err = TIFFReadDirEntryErrCount; | 
 |             else | 
 |             { | 
 |                 err = TIFFReadDirEntryLong8Array(tif, dp, &data); | 
 |                 if (err == TIFFReadDirEntryErrOk) | 
 |                 { | 
 |                     if (!EvaluateIFDdatasizeReading(tif, dp)) | 
 |                     { | 
 |                         if (data != 0) | 
 |                             _TIFFfreeExt(tif, data); | 
 |                         return 0; | 
 |                     } | 
 |                     int m; | 
 |                     m = TIFFSetField(tif, dp->tdir_tag, | 
 |                                      (uint16_t)(dp->tdir_count), data); | 
 |                     if (data != 0) | 
 |                         _TIFFfreeExt(tif, data); | 
 |                     if (!m) | 
 |                         return (0); | 
 |                 } | 
 |             } | 
 |         } | 
 |         break; | 
 |         case TIFF_SETGET_C16_SINT64: | 
 |         { | 
 |             int64_t *data; | 
 |             assert(fip->field_readcount == TIFF_VARIABLE); | 
 |             assert(fip->field_passcount == 1); | 
 |             if (dp->tdir_count > 0xFFFF) | 
 |                 err = TIFFReadDirEntryErrCount; | 
 |             else | 
 |             { | 
 |                 err = TIFFReadDirEntrySlong8Array(tif, dp, &data); | 
 |                 if (err == TIFFReadDirEntryErrOk) | 
 |                 { | 
 |                     if (!EvaluateIFDdatasizeReading(tif, dp)) | 
 |                     { | 
 |                         if (data != 0) | 
 |                             _TIFFfreeExt(tif, data); | 
 |                         return 0; | 
 |                     } | 
 |                     int m; | 
 |                     m = TIFFSetField(tif, dp->tdir_tag, | 
 |                                      (uint16_t)(dp->tdir_count), data); | 
 |                     if (data != 0) | 
 |                         _TIFFfreeExt(tif, data); | 
 |                     if (!m) | 
 |                         return (0); | 
 |                 } | 
 |             } | 
 |         } | 
 |         break; | 
 |         case TIFF_SETGET_C16_FLOAT: | 
 |         { | 
 |             float *data; | 
 |             assert(fip->field_readcount == TIFF_VARIABLE); | 
 |             assert(fip->field_passcount == 1); | 
 |             if (dp->tdir_count > 0xFFFF) | 
 |                 err = TIFFReadDirEntryErrCount; | 
 |             else | 
 |             { | 
 |                 err = TIFFReadDirEntryFloatArray(tif, dp, &data); | 
 |                 if (err == TIFFReadDirEntryErrOk) | 
 |                 { | 
 |                     if (!EvaluateIFDdatasizeReading(tif, dp)) | 
 |                     { | 
 |                         if (data != 0) | 
 |                             _TIFFfreeExt(tif, data); | 
 |                         return 0; | 
 |                     } | 
 |                     int m; | 
 |                     m = TIFFSetField(tif, dp->tdir_tag, | 
 |                                      (uint16_t)(dp->tdir_count), data); | 
 |                     if (data != 0) | 
 |                         _TIFFfreeExt(tif, data); | 
 |                     if (!m) | 
 |                         return (0); | 
 |                 } | 
 |             } | 
 |         } | 
 |         break; | 
 |         case TIFF_SETGET_C16_DOUBLE: | 
 |         { | 
 |             double *data; | 
 |             assert(fip->field_readcount == TIFF_VARIABLE); | 
 |             assert(fip->field_passcount == 1); | 
 |             if (dp->tdir_count > 0xFFFF) | 
 |                 err = TIFFReadDirEntryErrCount; | 
 |             else | 
 |             { | 
 |                 err = TIFFReadDirEntryDoubleArray(tif, dp, &data); | 
 |                 if (err == TIFFReadDirEntryErrOk) | 
 |                 { | 
 |                     if (!EvaluateIFDdatasizeReading(tif, dp)) | 
 |                     { | 
 |                         if (data != 0) | 
 |                             _TIFFfreeExt(tif, data); | 
 |                         return 0; | 
 |                     } | 
 |                     int m; | 
 |                     m = TIFFSetField(tif, dp->tdir_tag, | 
 |                                      (uint16_t)(dp->tdir_count), data); | 
 |                     if (data != 0) | 
 |                         _TIFFfreeExt(tif, data); | 
 |                     if (!m) | 
 |                         return (0); | 
 |                 } | 
 |             } | 
 |         } | 
 |         break; | 
 |         case TIFF_SETGET_C16_IFD8: | 
 |         { | 
 |             uint64_t *data; | 
 |             assert(fip->field_readcount == TIFF_VARIABLE); | 
 |             assert(fip->field_passcount == 1); | 
 |             if (dp->tdir_count > 0xFFFF) | 
 |                 err = TIFFReadDirEntryErrCount; | 
 |             else | 
 |             { | 
 |                 err = TIFFReadDirEntryIfd8Array(tif, dp, &data); | 
 |                 if (err == TIFFReadDirEntryErrOk) | 
 |                 { | 
 |                     if (!EvaluateIFDdatasizeReading(tif, dp)) | 
 |                     { | 
 |                         if (data != 0) | 
 |                             _TIFFfreeExt(tif, data); | 
 |                         return 0; | 
 |                     } | 
 |                     int m; | 
 |                     m = TIFFSetField(tif, dp->tdir_tag, | 
 |                                      (uint16_t)(dp->tdir_count), data); | 
 |                     if (data != 0) | 
 |                         _TIFFfreeExt(tif, data); | 
 |                     if (!m) | 
 |                         return (0); | 
 |                 } | 
 |             } | 
 |         } | 
 |         break; | 
 |         case TIFF_SETGET_C32_ASCII: | 
 |         { | 
 |             uint8_t *data; | 
 |             assert(fip->field_readcount == TIFF_VARIABLE2); | 
 |             assert(fip->field_passcount == 1); | 
 |             err = TIFFReadDirEntryByteArray(tif, dp, &data); | 
 |             if (err == TIFFReadDirEntryErrOk) | 
 |             { | 
 |                 if (!EvaluateIFDdatasizeReading(tif, dp)) | 
 |                 { | 
 |                     if (data != 0) | 
 |                         _TIFFfreeExt(tif, data); | 
 |                     return 0; | 
 |                 } | 
 |                 int m; | 
 |                 if (data != 0 && dp->tdir_count > 0 && | 
 |                     data[dp->tdir_count - 1] != '\0') | 
 |                 { | 
 |                     TIFFWarningExtR( | 
 |                         tif, module, | 
 |                         "ASCII value for ASCII array tag \"%s\" does not end " | 
 |                         "in null byte. Forcing it to be null", | 
 |                         fip->field_name); | 
 |                     /* Enlarge buffer and add terminating null. */ | 
 |                     uint8_t *o = | 
 |                         _TIFFmallocExt(tif, (uint32_t)dp->tdir_count + 1); | 
 |                     if (o == NULL) | 
 |                     { | 
 |                         if (data != NULL) | 
 |                             _TIFFfreeExt(tif, data); | 
 |                         return (0); | 
 |                     } | 
 |                     if (dp->tdir_count > 0) | 
 |                     { | 
 |                         _TIFFmemcpy(o, data, (uint32_t)dp->tdir_count); | 
 |                     } | 
 |                     o[(uint32_t)dp->tdir_count] = 0; | 
 |                     dp->tdir_count++; /* Increment for added null. */ | 
 |                     if (data != 0) | 
 |                         _TIFFfreeExt(tif, data); | 
 |                     data = o; | 
 |                 } | 
 |                 m = TIFFSetField(tif, dp->tdir_tag, (uint32_t)(dp->tdir_count), | 
 |                                  data); | 
 |                 if (data != 0) | 
 |                     _TIFFfreeExt(tif, data); | 
 |                 if (!m) | 
 |                     return (0); | 
 |             } | 
 |         } | 
 |         break; | 
 |         case TIFF_SETGET_C32_UINT8: | 
 |         { | 
 |             uint8_t *data; | 
 |             uint32_t count = 0; | 
 |             assert(fip->field_readcount == TIFF_VARIABLE2); | 
 |             assert(fip->field_passcount == 1); | 
 |             if (fip->field_tag == TIFFTAG_RICHTIFFIPTC && | 
 |                 dp->tdir_type == TIFF_LONG) | 
 |             { | 
 |                 /* Adobe's software (wrongly) writes RichTIFFIPTC tag with | 
 |                  * data type LONG instead of UNDEFINED. Work around this | 
 |                  * frequently found issue */ | 
 |                 void *origdata; | 
 |                 err = TIFFReadDirEntryArray(tif, dp, &count, 4, &origdata); | 
 |                 if ((err != TIFFReadDirEntryErrOk) || (origdata == 0)) | 
 |                 { | 
 |                     data = NULL; | 
 |                 } | 
 |                 else | 
 |                 { | 
 |                     if (tif->tif_flags & TIFF_SWAB) | 
 |                         TIFFSwabArrayOfLong((uint32_t *)origdata, count); | 
 |                     data = (uint8_t *)origdata; | 
 |                     count = (uint32_t)(count * 4); | 
 |                 } | 
 |             } | 
 |             else | 
 |             { | 
 |                 err = TIFFReadDirEntryByteArray(tif, dp, &data); | 
 |                 count = (uint32_t)(dp->tdir_count); | 
 |             } | 
 |             if (err == TIFFReadDirEntryErrOk) | 
 |             { | 
 |                 if (!EvaluateIFDdatasizeReading(tif, dp)) | 
 |                 { | 
 |                     if (data != 0) | 
 |                         _TIFFfreeExt(tif, data); | 
 |                     return 0; | 
 |                 } | 
 |                 int m; | 
 |                 m = TIFFSetField(tif, dp->tdir_tag, count, data); | 
 |                 if (data != 0) | 
 |                     _TIFFfreeExt(tif, data); | 
 |                 if (!m) | 
 |                     return (0); | 
 |             } | 
 |         } | 
 |         break; | 
 |         case TIFF_SETGET_C32_SINT8: | 
 |         { | 
 |             int8_t *data = NULL; | 
 |             assert(fip->field_readcount == TIFF_VARIABLE2); | 
 |             assert(fip->field_passcount == 1); | 
 |             err = TIFFReadDirEntrySbyteArray(tif, dp, &data); | 
 |             if (err == TIFFReadDirEntryErrOk) | 
 |             { | 
 |                 if (!EvaluateIFDdatasizeReading(tif, dp)) | 
 |                 { | 
 |                     if (data != 0) | 
 |                         _TIFFfreeExt(tif, data); | 
 |                     return 0; | 
 |                 } | 
 |                 int m; | 
 |                 m = TIFFSetField(tif, dp->tdir_tag, (uint32_t)(dp->tdir_count), | 
 |                                  data); | 
 |                 if (data != 0) | 
 |                     _TIFFfreeExt(tif, data); | 
 |                 if (!m) | 
 |                     return (0); | 
 |             } | 
 |         } | 
 |         break; | 
 |         case TIFF_SETGET_C32_UINT16: | 
 |         { | 
 |             uint16_t *data; | 
 |             assert(fip->field_readcount == TIFF_VARIABLE2); | 
 |             assert(fip->field_passcount == 1); | 
 |             err = TIFFReadDirEntryShortArray(tif, dp, &data); | 
 |             if (err == TIFFReadDirEntryErrOk) | 
 |             { | 
 |                 if (!EvaluateIFDdatasizeReading(tif, dp)) | 
 |                 { | 
 |                     if (data != 0) | 
 |                         _TIFFfreeExt(tif, data); | 
 |                     return 0; | 
 |                 } | 
 |                 int m; | 
 |                 m = TIFFSetField(tif, dp->tdir_tag, (uint32_t)(dp->tdir_count), | 
 |                                  data); | 
 |                 if (data != 0) | 
 |                     _TIFFfreeExt(tif, data); | 
 |                 if (!m) | 
 |                     return (0); | 
 |             } | 
 |         } | 
 |         break; | 
 |         case TIFF_SETGET_C32_SINT16: | 
 |         { | 
 |             int16_t *data = NULL; | 
 |             assert(fip->field_readcount == TIFF_VARIABLE2); | 
 |             assert(fip->field_passcount == 1); | 
 |             err = TIFFReadDirEntrySshortArray(tif, dp, &data); | 
 |             if (err == TIFFReadDirEntryErrOk) | 
 |             { | 
 |                 if (!EvaluateIFDdatasizeReading(tif, dp)) | 
 |                 { | 
 |                     if (data != 0) | 
 |                         _TIFFfreeExt(tif, data); | 
 |                     return 0; | 
 |                 } | 
 |                 int m; | 
 |                 m = TIFFSetField(tif, dp->tdir_tag, (uint32_t)(dp->tdir_count), | 
 |                                  data); | 
 |                 if (data != 0) | 
 |                     _TIFFfreeExt(tif, data); | 
 |                 if (!m) | 
 |                     return (0); | 
 |             } | 
 |         } | 
 |         break; | 
 |         case TIFF_SETGET_C32_UINT32: | 
 |         { | 
 |             uint32_t *data; | 
 |             assert(fip->field_readcount == TIFF_VARIABLE2); | 
 |             assert(fip->field_passcount == 1); | 
 |             err = TIFFReadDirEntryLongArray(tif, dp, &data); | 
 |             if (err == TIFFReadDirEntryErrOk) | 
 |             { | 
 |                 if (!EvaluateIFDdatasizeReading(tif, dp)) | 
 |                 { | 
 |                     if (data != 0) | 
 |                         _TIFFfreeExt(tif, data); | 
 |                     return 0; | 
 |                 } | 
 |                 int m; | 
 |                 m = TIFFSetField(tif, dp->tdir_tag, (uint32_t)(dp->tdir_count), | 
 |                                  data); | 
 |                 if (data != 0) | 
 |                     _TIFFfreeExt(tif, data); | 
 |                 if (!m) | 
 |                     return (0); | 
 |             } | 
 |         } | 
 |         break; | 
 |         case TIFF_SETGET_C32_SINT32: | 
 |         { | 
 |             int32_t *data = NULL; | 
 |             assert(fip->field_readcount == TIFF_VARIABLE2); | 
 |             assert(fip->field_passcount == 1); | 
 |             err = TIFFReadDirEntrySlongArray(tif, dp, &data); | 
 |             if (err == TIFFReadDirEntryErrOk) | 
 |             { | 
 |                 if (!EvaluateIFDdatasizeReading(tif, dp)) | 
 |                 { | 
 |                     if (data != 0) | 
 |                         _TIFFfreeExt(tif, data); | 
 |                     return 0; | 
 |                 } | 
 |                 int m; | 
 |                 m = TIFFSetField(tif, dp->tdir_tag, (uint32_t)(dp->tdir_count), | 
 |                                  data); | 
 |                 if (data != 0) | 
 |                     _TIFFfreeExt(tif, data); | 
 |                 if (!m) | 
 |                     return (0); | 
 |             } | 
 |         } | 
 |         break; | 
 |         case TIFF_SETGET_C32_UINT64: | 
 |         { | 
 |             uint64_t *data; | 
 |             assert(fip->field_readcount == TIFF_VARIABLE2); | 
 |             assert(fip->field_passcount == 1); | 
 |             err = TIFFReadDirEntryLong8Array(tif, dp, &data); | 
 |             if (err == TIFFReadDirEntryErrOk) | 
 |             { | 
 |                 if (!EvaluateIFDdatasizeReading(tif, dp)) | 
 |                 { | 
 |                     if (data != 0) | 
 |                         _TIFFfreeExt(tif, data); | 
 |                     return 0; | 
 |                 } | 
 |                 int m; | 
 |                 m = TIFFSetField(tif, dp->tdir_tag, (uint32_t)(dp->tdir_count), | 
 |                                  data); | 
 |                 if (data != 0) | 
 |                     _TIFFfreeExt(tif, data); | 
 |                 if (!m) | 
 |                     return (0); | 
 |             } | 
 |         } | 
 |         break; | 
 |         case TIFF_SETGET_C32_SINT64: | 
 |         { | 
 |             int64_t *data = NULL; | 
 |             assert(fip->field_readcount == TIFF_VARIABLE2); | 
 |             assert(fip->field_passcount == 1); | 
 |             err = TIFFReadDirEntrySlong8Array(tif, dp, &data); | 
 |             if (err == TIFFReadDirEntryErrOk) | 
 |             { | 
 |                 if (!EvaluateIFDdatasizeReading(tif, dp)) | 
 |                 { | 
 |                     if (data != 0) | 
 |                         _TIFFfreeExt(tif, data); | 
 |                     return 0; | 
 |                 } | 
 |                 int m; | 
 |                 m = TIFFSetField(tif, dp->tdir_tag, (uint32_t)(dp->tdir_count), | 
 |                                  data); | 
 |                 if (data != 0) | 
 |                     _TIFFfreeExt(tif, data); | 
 |                 if (!m) | 
 |                     return (0); | 
 |             } | 
 |         } | 
 |         break; | 
 |         case TIFF_SETGET_C32_FLOAT: | 
 |         { | 
 |             float *data; | 
 |             assert(fip->field_readcount == TIFF_VARIABLE2); | 
 |             assert(fip->field_passcount == 1); | 
 |             err = TIFFReadDirEntryFloatArray(tif, dp, &data); | 
 |             if (err == TIFFReadDirEntryErrOk) | 
 |             { | 
 |                 if (!EvaluateIFDdatasizeReading(tif, dp)) | 
 |                 { | 
 |                     if (data != 0) | 
 |                         _TIFFfreeExt(tif, data); | 
 |                     return 0; | 
 |                 } | 
 |                 int m; | 
 |                 m = TIFFSetField(tif, dp->tdir_tag, (uint32_t)(dp->tdir_count), | 
 |                                  data); | 
 |                 if (data != 0) | 
 |                     _TIFFfreeExt(tif, data); | 
 |                 if (!m) | 
 |                     return (0); | 
 |             } | 
 |         } | 
 |         break; | 
 |         case TIFF_SETGET_C32_DOUBLE: | 
 |         { | 
 |             double *data; | 
 |             assert(fip->field_readcount == TIFF_VARIABLE2); | 
 |             assert(fip->field_passcount == 1); | 
 |             err = TIFFReadDirEntryDoubleArray(tif, dp, &data); | 
 |             if (err == TIFFReadDirEntryErrOk) | 
 |             { | 
 |                 if (!EvaluateIFDdatasizeReading(tif, dp)) | 
 |                 { | 
 |                     if (data != 0) | 
 |                         _TIFFfreeExt(tif, data); | 
 |                     return 0; | 
 |                 } | 
 |                 int m; | 
 |                 m = TIFFSetField(tif, dp->tdir_tag, (uint32_t)(dp->tdir_count), | 
 |                                  data); | 
 |                 if (data != 0) | 
 |                     _TIFFfreeExt(tif, data); | 
 |                 if (!m) | 
 |                     return (0); | 
 |             } | 
 |         } | 
 |         break; | 
 |         case TIFF_SETGET_C32_IFD8: | 
 |         { | 
 |             uint64_t *data; | 
 |             assert(fip->field_readcount == TIFF_VARIABLE2); | 
 |             assert(fip->field_passcount == 1); | 
 |             err = TIFFReadDirEntryIfd8Array(tif, dp, &data); | 
 |             if (err == TIFFReadDirEntryErrOk) | 
 |             { | 
 |                 if (!EvaluateIFDdatasizeReading(tif, dp)) | 
 |                 { | 
 |                     if (data != 0) | 
 |                         _TIFFfreeExt(tif, data); | 
 |                     return 0; | 
 |                 } | 
 |                 int m; | 
 |                 m = TIFFSetField(tif, dp->tdir_tag, (uint32_t)(dp->tdir_count), | 
 |                                  data); | 
 |                 if (data != 0) | 
 |                     _TIFFfreeExt(tif, data); | 
 |                 if (!m) | 
 |                     return (0); | 
 |             } | 
 |         } | 
 |         break; | 
 |         default: | 
 |             assert(0); /* we should never get here */ | 
 |             break; | 
 |     } | 
 |     if (err != TIFFReadDirEntryErrOk) | 
 |     { | 
 |         TIFFReadDirEntryOutputErr(tif, err, module, fip->field_name, recover); | 
 |         return (0); | 
 |     } | 
 |     return (1); | 
 | } | 
 |  | 
 | /* | 
 |  * Fetch a set of offsets or lengths. | 
 |  * While this routine says "strips", in fact it's also used for tiles. | 
 |  */ | 
 | static int TIFFFetchStripThing(TIFF *tif, TIFFDirEntry *dir, uint32_t nstrips, | 
 |                                uint64_t **lpp) | 
 | { | 
 |     static const char module[] = "TIFFFetchStripThing"; | 
 |     enum TIFFReadDirEntryErr err; | 
 |     uint64_t *data; | 
 |     err = TIFFReadDirEntryLong8ArrayWithLimit(tif, dir, &data, nstrips); | 
 |     if (err != TIFFReadDirEntryErrOk) | 
 |     { | 
 |         const TIFFField *fip = TIFFFieldWithTag(tif, dir->tdir_tag); | 
 |         TIFFReadDirEntryOutputErr(tif, err, module, | 
 |                                   fip ? fip->field_name : "unknown tagname", 0); | 
 |         return (0); | 
 |     } | 
 |     if (dir->tdir_count < (uint64_t)nstrips) | 
 |     { | 
 |         uint64_t *resizeddata; | 
 |         const TIFFField *fip = TIFFFieldWithTag(tif, dir->tdir_tag); | 
 |         const char *pszMax = getenv("LIBTIFF_STRILE_ARRAY_MAX_RESIZE_COUNT"); | 
 |         uint32_t max_nstrips = 1000000; | 
 |         if (pszMax) | 
 |             max_nstrips = (uint32_t)atoi(pszMax); | 
 |         TIFFReadDirEntryOutputErr(tif, TIFFReadDirEntryErrCount, module, | 
 |                                   fip ? fip->field_name : "unknown tagname", | 
 |                                   (nstrips <= max_nstrips)); | 
 |  | 
 |         if (nstrips > max_nstrips) | 
 |         { | 
 |             _TIFFfreeExt(tif, data); | 
 |             return (0); | 
 |         } | 
 |  | 
 |         const uint64_t allocsize = (uint64_t)nstrips * sizeof(uint64_t); | 
 |         if (allocsize > 100 * 1024 * 1024) | 
 |         { | 
 |             /* Before allocating a huge amount of memory for corrupted files, | 
 |              * check if size of requested memory is not greater than file size. | 
 |              */ | 
 |             const uint64_t filesize = TIFFGetFileSize(tif); | 
 |             if (allocsize > filesize) | 
 |             { | 
 |                 TIFFWarningExtR( | 
 |                     tif, module, | 
 |                     "Requested memory size for StripArray of %" PRIu64 | 
 |                     " is greater than filesize %" PRIu64 | 
 |                     ". Memory not allocated", | 
 |                     allocsize, filesize); | 
 |                 _TIFFfreeExt(tif, data); | 
 |                 return (0); | 
 |             } | 
 |         } | 
 |         resizeddata = (uint64_t *)_TIFFCheckMalloc( | 
 |             tif, nstrips, sizeof(uint64_t), "for strip array"); | 
 |         if (resizeddata == 0) | 
 |         { | 
 |             _TIFFfreeExt(tif, data); | 
 |             return (0); | 
 |         } | 
 |         if (dir->tdir_count) | 
 |             _TIFFmemcpy(resizeddata, data, | 
 |                         (uint32_t)dir->tdir_count * sizeof(uint64_t)); | 
 |         _TIFFmemset(resizeddata + (uint32_t)dir->tdir_count, 0, | 
 |                     (nstrips - (uint32_t)dir->tdir_count) * sizeof(uint64_t)); | 
 |         _TIFFfreeExt(tif, data); | 
 |         data = resizeddata; | 
 |     } | 
 |     *lpp = data; | 
 |     return (1); | 
 | } | 
 |  | 
 | /* | 
 |  * Fetch and set the SubjectDistance EXIF tag. | 
 |  */ | 
 | static int TIFFFetchSubjectDistance(TIFF *tif, TIFFDirEntry *dir) | 
 | { | 
 |     static const char module[] = "TIFFFetchSubjectDistance"; | 
 |     enum TIFFReadDirEntryErr err; | 
 |     UInt64Aligned_t m; | 
 |     m.l = 0; | 
 |     assert(sizeof(double) == 8); | 
 |     assert(sizeof(uint64_t) == 8); | 
 |     assert(sizeof(uint32_t) == 4); | 
 |     if (dir->tdir_count != 1) | 
 |         err = TIFFReadDirEntryErrCount; | 
 |     else if (dir->tdir_type != TIFF_RATIONAL) | 
 |         err = TIFFReadDirEntryErrType; | 
 |     else | 
 |     { | 
 |         if (!(tif->tif_flags & TIFF_BIGTIFF)) | 
 |         { | 
 |             uint32_t offset; | 
 |             offset = *(uint32_t *)(&dir->tdir_offset); | 
 |             if (tif->tif_flags & TIFF_SWAB) | 
 |                 TIFFSwabLong(&offset); | 
 |             err = TIFFReadDirEntryData(tif, offset, 8, m.i); | 
 |         } | 
 |         else | 
 |         { | 
 |             m.l = dir->tdir_offset.toff_long8; | 
 |             err = TIFFReadDirEntryErrOk; | 
 |         } | 
 |     } | 
 |     if (err == TIFFReadDirEntryErrOk) | 
 |     { | 
 |         double n; | 
 |         if (tif->tif_flags & TIFF_SWAB) | 
 |             TIFFSwabArrayOfLong(m.i, 2); | 
 |         if (m.i[0] == 0) | 
 |             n = 0.0; | 
 |         else if (m.i[0] == 0xFFFFFFFF || m.i[1] == 0) | 
 |             /* | 
 |              * XXX: Numerator 0xFFFFFFFF means that we have infinite | 
 |              * distance. Indicate that with a negative floating point | 
 |              * SubjectDistance value. | 
 |              */ | 
 |             n = -1.0; | 
 |         else | 
 |             n = (double)m.i[0] / (double)m.i[1]; | 
 |         return (TIFFSetField(tif, dir->tdir_tag, n)); | 
 |     } | 
 |     else | 
 |     { | 
 |         TIFFReadDirEntryOutputErr(tif, err, module, "SubjectDistance", TRUE); | 
 |         return (0); | 
 |     } | 
 | } | 
 |  | 
 | static void allocChoppedUpStripArrays(TIFF *tif, uint32_t nstrips, | 
 |                                       uint64_t stripbytes, | 
 |                                       uint32_t rowsperstrip) | 
 | { | 
 |     TIFFDirectory *td = &tif->tif_dir; | 
 |     uint64_t bytecount; | 
 |     uint64_t offset; | 
 |     uint64_t last_offset; | 
 |     uint64_t last_bytecount; | 
 |     uint32_t i; | 
 |     uint64_t *newcounts; | 
 |     uint64_t *newoffsets; | 
 |  | 
 |     offset = TIFFGetStrileOffset(tif, 0); | 
 |     last_offset = TIFFGetStrileOffset(tif, td->td_nstrips - 1); | 
 |     last_bytecount = TIFFGetStrileByteCount(tif, td->td_nstrips - 1); | 
 |     if (last_offset > UINT64_MAX - last_bytecount || | 
 |         last_offset + last_bytecount < offset) | 
 |     { | 
 |         return; | 
 |     } | 
 |     bytecount = last_offset + last_bytecount - offset; | 
 |  | 
 |     /* Before allocating a huge amount of memory for corrupted files, check if | 
 |      * size of StripByteCount and StripOffset tags is not greater than | 
 |      * file size. | 
 |      */ | 
 |     const uint64_t allocsize = (uint64_t)nstrips * sizeof(uint64_t) * 2; | 
 |     if (allocsize > 100 * 1024 * 1024) | 
 |     { | 
 |         const uint64_t filesize = TIFFGetFileSize(tif); | 
 |         if (allocsize > filesize) | 
 |         { | 
 |             TIFFWarningExtR(tif, "allocChoppedUpStripArrays", | 
 |                             "Requested memory size for StripByteCount and " | 
 |                             "StripOffsets %" PRIu64 | 
 |                             " is greater than filesize %" PRIu64 | 
 |                             ". Memory not allocated", | 
 |                             allocsize, filesize); | 
 |             return; | 
 |         } | 
 |     } | 
 |  | 
 |     newcounts = | 
 |         (uint64_t *)_TIFFCheckMalloc(tif, nstrips, sizeof(uint64_t), | 
 |                                      "for chopped \"StripByteCounts\" array"); | 
 |     newoffsets = (uint64_t *)_TIFFCheckMalloc( | 
 |         tif, nstrips, sizeof(uint64_t), "for chopped \"StripOffsets\" array"); | 
 |     if (newcounts == NULL || newoffsets == NULL) | 
 |     { | 
 |         /* | 
 |          * Unable to allocate new strip information, give up and use | 
 |          * the original one strip information. | 
 |          */ | 
 |         if (newcounts != NULL) | 
 |             _TIFFfreeExt(tif, newcounts); | 
 |         if (newoffsets != NULL) | 
 |             _TIFFfreeExt(tif, newoffsets); | 
 |         return; | 
 |     } | 
 |  | 
 |     /* | 
 |      * Fill the strip information arrays with new bytecounts and offsets | 
 |      * that reflect the broken-up format. | 
 |      */ | 
 |     for (i = 0; i < nstrips; i++) | 
 |     { | 
 |         if (stripbytes > bytecount) | 
 |             stripbytes = bytecount; | 
 |         newcounts[i] = stripbytes; | 
 |         newoffsets[i] = stripbytes ? offset : 0; | 
 |         offset += stripbytes; | 
 |         bytecount -= stripbytes; | 
 |     } | 
 |  | 
 |     /* | 
 |      * Replace old single strip info with multi-strip info. | 
 |      */ | 
 |     td->td_stripsperimage = td->td_nstrips = nstrips; | 
 |     TIFFSetField(tif, TIFFTAG_ROWSPERSTRIP, rowsperstrip); | 
 |  | 
 |     _TIFFfreeExt(tif, td->td_stripbytecount_p); | 
 |     _TIFFfreeExt(tif, td->td_stripoffset_p); | 
 |     td->td_stripbytecount_p = newcounts; | 
 |     td->td_stripoffset_p = newoffsets; | 
 | #ifdef STRIPBYTECOUNTSORTED_UNUSED | 
 |     td->td_stripbytecountsorted = 1; | 
 | #endif | 
 |     tif->tif_flags |= TIFF_CHOPPEDUPARRAYS; | 
 | } | 
 |  | 
 | /* | 
 |  * Replace a single strip (tile) of uncompressed data by multiple strips | 
 |  * (tiles), each approximately STRIP_SIZE_DEFAULT bytes. This is useful for | 
 |  * dealing with large images or for dealing with machines with a limited | 
 |  * amount memory. | 
 |  */ | 
 | static void ChopUpSingleUncompressedStrip(TIFF *tif) | 
 | { | 
 |     register TIFFDirectory *td = &tif->tif_dir; | 
 |     uint64_t bytecount; | 
 |     uint64_t offset; | 
 |     uint32_t rowblock; | 
 |     uint64_t rowblockbytes; | 
 |     uint64_t stripbytes; | 
 |     uint32_t nstrips; | 
 |     uint32_t rowsperstrip; | 
 |  | 
 |     bytecount = TIFFGetStrileByteCount(tif, 0); | 
 |     /* On a newly created file, just re-opened to be filled, we */ | 
 |     /* don't want strip chop to trigger as it is going to cause issues */ | 
 |     /* later ( StripOffsets and StripByteCounts improperly filled) . */ | 
 |     if (bytecount == 0 && tif->tif_mode != O_RDONLY) | 
 |         return; | 
 |     offset = TIFFGetStrileByteCount(tif, 0); | 
 |     assert(td->td_planarconfig == PLANARCONFIG_CONTIG); | 
 |     if ((td->td_photometric == PHOTOMETRIC_YCBCR) && (!isUpSampled(tif))) | 
 |         rowblock = td->td_ycbcrsubsampling[1]; | 
 |     else | 
 |         rowblock = 1; | 
 |     rowblockbytes = TIFFVTileSize64(tif, rowblock); | 
 |     /* | 
 |      * Make the rows hold at least one scanline, but fill specified amount | 
 |      * of data if possible. | 
 |      */ | 
 |     if (rowblockbytes > STRIP_SIZE_DEFAULT) | 
 |     { | 
 |         stripbytes = rowblockbytes; | 
 |         rowsperstrip = rowblock; | 
 |     } | 
 |     else if (rowblockbytes > 0) | 
 |     { | 
 |         uint32_t rowblocksperstrip; | 
 |         rowblocksperstrip = (uint32_t)(STRIP_SIZE_DEFAULT / rowblockbytes); | 
 |         rowsperstrip = rowblocksperstrip * rowblock; | 
 |         stripbytes = rowblocksperstrip * rowblockbytes; | 
 |     } | 
 |     else | 
 |         return; | 
 |  | 
 |     /* | 
 |      * never increase the number of rows per strip | 
 |      */ | 
 |     if (rowsperstrip >= td->td_rowsperstrip || rowsperstrip == 0) | 
 |         return; | 
 |     nstrips = TIFFhowmany_32(td->td_imagelength, rowsperstrip); | 
 |     if (nstrips == 0) | 
 |         return; | 
 |  | 
 |     /* If we are going to allocate a lot of memory, make sure that the */ | 
 |     /* file is as big as needed */ | 
 |     if (tif->tif_mode == O_RDONLY && nstrips > 1000000 && | 
 |         (offset >= TIFFGetFileSize(tif) || | 
 |          stripbytes > (TIFFGetFileSize(tif) - offset) / (nstrips - 1))) | 
 |     { | 
 |         return; | 
 |     } | 
 |  | 
 |     allocChoppedUpStripArrays(tif, nstrips, stripbytes, rowsperstrip); | 
 | } | 
 |  | 
 | /* | 
 |  * Replace a file with contiguous strips > 2 GB of uncompressed data by | 
 |  * multiple smaller strips. This is useful for | 
 |  * dealing with large images or for dealing with machines with a limited | 
 |  * amount memory. | 
 |  */ | 
 | static void TryChopUpUncompressedBigTiff(TIFF *tif) | 
 | { | 
 |     TIFFDirectory *td = &tif->tif_dir; | 
 |     uint32_t rowblock; | 
 |     uint64_t rowblockbytes; | 
 |     uint32_t i; | 
 |     uint64_t stripsize; | 
 |     uint32_t rowblocksperstrip; | 
 |     uint32_t rowsperstrip; | 
 |     uint64_t stripbytes; | 
 |     uint32_t nstrips; | 
 |  | 
 |     stripsize = TIFFStripSize64(tif); | 
 |  | 
 |     assert(tif->tif_dir.td_planarconfig == PLANARCONFIG_CONTIG); | 
 |     assert(tif->tif_dir.td_compression == COMPRESSION_NONE); | 
 |     assert((tif->tif_flags & (TIFF_STRIPCHOP | TIFF_ISTILED)) == | 
 |            TIFF_STRIPCHOP); | 
 |     assert(stripsize > 0x7FFFFFFFUL); | 
 |  | 
 |     /* On a newly created file, just re-opened to be filled, we */ | 
 |     /* don't want strip chop to trigger as it is going to cause issues */ | 
 |     /* later ( StripOffsets and StripByteCounts improperly filled) . */ | 
 |     if (TIFFGetStrileByteCount(tif, 0) == 0 && tif->tif_mode != O_RDONLY) | 
 |         return; | 
 |  | 
 |     if ((td->td_photometric == PHOTOMETRIC_YCBCR) && (!isUpSampled(tif))) | 
 |         rowblock = td->td_ycbcrsubsampling[1]; | 
 |     else | 
 |         rowblock = 1; | 
 |     rowblockbytes = TIFFVStripSize64(tif, rowblock); | 
 |     if (rowblockbytes == 0 || rowblockbytes > 0x7FFFFFFFUL) | 
 |     { | 
 |         /* In case of file with gigantic width */ | 
 |         return; | 
 |     } | 
 |  | 
 |     /* Check that the strips are contiguous and of the expected size */ | 
 |     for (i = 0; i < td->td_nstrips; i++) | 
 |     { | 
 |         if (i == td->td_nstrips - 1) | 
 |         { | 
 |             if (TIFFGetStrileByteCount(tif, i) < | 
 |                 TIFFVStripSize64(tif, | 
 |                                  td->td_imagelength - i * td->td_rowsperstrip)) | 
 |             { | 
 |                 return; | 
 |             } | 
 |         } | 
 |         else | 
 |         { | 
 |             if (TIFFGetStrileByteCount(tif, i) != stripsize) | 
 |             { | 
 |                 return; | 
 |             } | 
 |             if (i > 0 && TIFFGetStrileOffset(tif, i) != | 
 |                              TIFFGetStrileOffset(tif, i - 1) + | 
 |                                  TIFFGetStrileByteCount(tif, i - 1)) | 
 |             { | 
 |                 return; | 
 |             } | 
 |         } | 
 |     } | 
 |  | 
 |     /* Aim for 512 MB strips (that will still be manageable by 32 bit builds */ | 
 |     rowblocksperstrip = (uint32_t)(512 * 1024 * 1024 / rowblockbytes); | 
 |     if (rowblocksperstrip == 0) | 
 |         rowblocksperstrip = 1; | 
 |     rowsperstrip = rowblocksperstrip * rowblock; | 
 |     stripbytes = rowblocksperstrip * rowblockbytes; | 
 |     assert(stripbytes <= 0x7FFFFFFFUL); | 
 |  | 
 |     if (rowsperstrip == 0) | 
 |         return; | 
 |     nstrips = TIFFhowmany_32(td->td_imagelength, rowsperstrip); | 
 |     if (nstrips == 0) | 
 |         return; | 
 |  | 
 |     /* If we are going to allocate a lot of memory, make sure that the */ | 
 |     /* file is as big as needed */ | 
 |     if (tif->tif_mode == O_RDONLY && nstrips > 1000000) | 
 |     { | 
 |         uint64_t last_offset = TIFFGetStrileOffset(tif, td->td_nstrips - 1); | 
 |         uint64_t filesize = TIFFGetFileSize(tif); | 
 |         uint64_t last_bytecount = | 
 |             TIFFGetStrileByteCount(tif, td->td_nstrips - 1); | 
 |         if (last_offset > filesize || last_bytecount > filesize - last_offset) | 
 |         { | 
 |             return; | 
 |         } | 
 |     } | 
 |  | 
 |     allocChoppedUpStripArrays(tif, nstrips, stripbytes, rowsperstrip); | 
 | } | 
 |  | 
 | TIFF_NOSANITIZE_UNSIGNED_INT_OVERFLOW | 
 | static uint64_t _TIFFUnsanitizedAddUInt64AndInt(uint64_t a, int b) | 
 | { | 
 |     return a + b; | 
 | } | 
 |  | 
 | /* Read the value of [Strip|Tile]Offset or [Strip|Tile]ByteCount around | 
 |  * strip/tile of number strile. Also fetch the neighbouring values using a | 
 |  * 4096 byte page size. | 
 |  */ | 
 | static int _TIFFPartialReadStripArray(TIFF *tif, TIFFDirEntry *dirent, | 
 |                                       int strile, uint64_t *panVals) | 
 | { | 
 |     static const char module[] = "_TIFFPartialReadStripArray"; | 
 | #define IO_CACHE_PAGE_SIZE 4096 | 
 |  | 
 |     size_t sizeofval; | 
 |     const int bSwab = (tif->tif_flags & TIFF_SWAB) != 0; | 
 |     int sizeofvalint; | 
 |     uint64_t nBaseOffset; | 
 |     uint64_t nOffset; | 
 |     uint64_t nOffsetStartPage; | 
 |     uint64_t nOffsetEndPage; | 
 |     tmsize_t nToRead; | 
 |     tmsize_t nRead; | 
 |     uint64_t nLastStripOffset; | 
 |     int iStartBefore; | 
 |     int i; | 
 |     const uint32_t arraySize = tif->tif_dir.td_stripoffsetbyteallocsize; | 
 |     unsigned char buffer[2 * IO_CACHE_PAGE_SIZE]; | 
 |  | 
 |     assert(dirent->tdir_count > 4); | 
 |  | 
 |     if (dirent->tdir_type == TIFF_SHORT) | 
 |     { | 
 |         sizeofval = sizeof(uint16_t); | 
 |     } | 
 |     else if (dirent->tdir_type == TIFF_LONG) | 
 |     { | 
 |         sizeofval = sizeof(uint32_t); | 
 |     } | 
 |     else if (dirent->tdir_type == TIFF_LONG8) | 
 |     { | 
 |         sizeofval = sizeof(uint64_t); | 
 |     } | 
 |     else if (dirent->tdir_type == TIFF_SLONG8) | 
 |     { | 
 |         /* Non conformant but used by some images as in */ | 
 |         /* https://github.com/OSGeo/gdal/issues/2165 */ | 
 |         sizeofval = sizeof(int64_t); | 
 |     } | 
 |     else | 
 |     { | 
 |         TIFFErrorExtR(tif, module, | 
 |                       "Invalid type for [Strip|Tile][Offset/ByteCount] tag"); | 
 |         panVals[strile] = 0; | 
 |         return 0; | 
 |     } | 
 |     sizeofvalint = (int)(sizeofval); | 
 |  | 
 |     if (tif->tif_flags & TIFF_BIGTIFF) | 
 |     { | 
 |         uint64_t offset = dirent->tdir_offset.toff_long8; | 
 |         if (bSwab) | 
 |             TIFFSwabLong8(&offset); | 
 |         nBaseOffset = offset; | 
 |     } | 
 |     else | 
 |     { | 
 |         uint32_t offset = dirent->tdir_offset.toff_long; | 
 |         if (bSwab) | 
 |             TIFFSwabLong(&offset); | 
 |         nBaseOffset = offset; | 
 |     } | 
 |     /* To avoid later unsigned integer overflows */ | 
 |     if (nBaseOffset > (uint64_t)INT64_MAX) | 
 |     { | 
 |         TIFFErrorExtR(tif, module, "Cannot read offset/size for strile %d", | 
 |                       strile); | 
 |         panVals[strile] = 0; | 
 |         return 0; | 
 |     } | 
 |     nOffset = nBaseOffset + sizeofval * strile; | 
 |     nOffsetStartPage = (nOffset / IO_CACHE_PAGE_SIZE) * IO_CACHE_PAGE_SIZE; | 
 |     nOffsetEndPage = nOffsetStartPage + IO_CACHE_PAGE_SIZE; | 
 |  | 
 |     if (nOffset + sizeofval > nOffsetEndPage) | 
 |         nOffsetEndPage += IO_CACHE_PAGE_SIZE; | 
 | #undef IO_CACHE_PAGE_SIZE | 
 |  | 
 |     nLastStripOffset = nBaseOffset + arraySize * sizeofval; | 
 |     if (nLastStripOffset < nOffsetEndPage) | 
 |         nOffsetEndPage = nLastStripOffset; | 
 |     if (nOffsetStartPage >= nOffsetEndPage) | 
 |     { | 
 |         TIFFErrorExtR(tif, module, "Cannot read offset/size for strile %d", | 
 |                       strile); | 
 |         panVals[strile] = 0; | 
 |         return 0; | 
 |     } | 
 |     if (!SeekOK(tif, nOffsetStartPage)) | 
 |     { | 
 |         panVals[strile] = 0; | 
 |         return 0; | 
 |     } | 
 |  | 
 |     nToRead = (tmsize_t)(nOffsetEndPage - nOffsetStartPage); | 
 |     nRead = TIFFReadFile(tif, buffer, nToRead); | 
 |     if (nRead < nToRead) | 
 |     { | 
 |         TIFFErrorExtR(tif, module, | 
 |                       "Cannot read offset/size for strile around ~%d", strile); | 
 |         return 0; | 
 |     } | 
 |     iStartBefore = -(int)((nOffset - nOffsetStartPage) / sizeofval); | 
 |     if (strile + iStartBefore < 0) | 
 |         iStartBefore = -strile; | 
 |     for (i = iStartBefore; | 
 |          (uint32_t)(strile + i) < arraySize && | 
 |          _TIFFUnsanitizedAddUInt64AndInt(nOffset, (i + 1) * sizeofvalint) <= | 
 |              nOffsetEndPage; | 
 |          ++i) | 
 |     { | 
 |         if (dirent->tdir_type == TIFF_SHORT) | 
 |         { | 
 |             uint16_t val; | 
 |             memcpy(&val, | 
 |                    buffer + (nOffset - nOffsetStartPage) + i * sizeofvalint, | 
 |                    sizeof(val)); | 
 |             if (bSwab) | 
 |                 TIFFSwabShort(&val); | 
 |             panVals[strile + i] = val; | 
 |         } | 
 |         else if (dirent->tdir_type == TIFF_LONG) | 
 |         { | 
 |             uint32_t val; | 
 |             memcpy(&val, | 
 |                    buffer + (nOffset - nOffsetStartPage) + i * sizeofvalint, | 
 |                    sizeof(val)); | 
 |             if (bSwab) | 
 |                 TIFFSwabLong(&val); | 
 |             panVals[strile + i] = val; | 
 |         } | 
 |         else if (dirent->tdir_type == TIFF_LONG8) | 
 |         { | 
 |             uint64_t val; | 
 |             memcpy(&val, | 
 |                    buffer + (nOffset - nOffsetStartPage) + i * sizeofvalint, | 
 |                    sizeof(val)); | 
 |             if (bSwab) | 
 |                 TIFFSwabLong8(&val); | 
 |             panVals[strile + i] = val; | 
 |         } | 
 |         else /* if( dirent->tdir_type == TIFF_SLONG8 ) */ | 
 |         { | 
 |             /* Non conformant data type */ | 
 |             int64_t val; | 
 |             memcpy(&val, | 
 |                    buffer + (nOffset - nOffsetStartPage) + i * sizeofvalint, | 
 |                    sizeof(val)); | 
 |             if (bSwab) | 
 |                 TIFFSwabLong8((uint64_t *)&val); | 
 |             panVals[strile + i] = (uint64_t)val; | 
 |         } | 
 |     } | 
 |     return 1; | 
 | } | 
 |  | 
 | static int _TIFFFetchStrileValue(TIFF *tif, uint32_t strile, | 
 |                                  TIFFDirEntry *dirent, uint64_t **parray) | 
 | { | 
 |     static const char module[] = "_TIFFFetchStrileValue"; | 
 |     TIFFDirectory *td = &tif->tif_dir; | 
 |     if (strile >= dirent->tdir_count) | 
 |     { | 
 |         return 0; | 
 |     } | 
 |     if (strile >= td->td_stripoffsetbyteallocsize) | 
 |     { | 
 |         uint32_t nStripArrayAllocBefore = td->td_stripoffsetbyteallocsize; | 
 |         uint32_t nStripArrayAllocNew; | 
 |         uint64_t nArraySize64; | 
 |         size_t nArraySize; | 
 |         uint64_t *offsetArray; | 
 |         uint64_t *bytecountArray; | 
 |  | 
 |         if (strile > 1000000) | 
 |         { | 
 |             uint64_t filesize = TIFFGetFileSize(tif); | 
 |             /* Avoid excessive memory allocation attempt */ | 
 |             /* For such a big blockid we need at least a TIFF_LONG per strile */ | 
 |             /* for the offset array. */ | 
 |             if (strile > filesize / sizeof(uint32_t)) | 
 |             { | 
 |                 TIFFErrorExtR(tif, module, "File too short"); | 
 |                 return 0; | 
 |             } | 
 |         } | 
 |  | 
 |         if (td->td_stripoffsetbyteallocsize == 0 && | 
 |             td->td_nstrips < 1024 * 1024) | 
 |         { | 
 |             nStripArrayAllocNew = td->td_nstrips; | 
 |         } | 
 |         else | 
 |         { | 
 | #define TIFF_MAX(a, b) (((a) > (b)) ? (a) : (b)) | 
 | #define TIFF_MIN(a, b) (((a) < (b)) ? (a) : (b)) | 
 |             nStripArrayAllocNew = TIFF_MAX(strile + 1, 1024U * 512U); | 
 |             if (nStripArrayAllocNew < 0xFFFFFFFFU / 2) | 
 |                 nStripArrayAllocNew *= 2; | 
 |             nStripArrayAllocNew = TIFF_MIN(nStripArrayAllocNew, td->td_nstrips); | 
 |         } | 
 |         assert(strile < nStripArrayAllocNew); | 
 |         nArraySize64 = (uint64_t)sizeof(uint64_t) * nStripArrayAllocNew; | 
 |         nArraySize = (size_t)(nArraySize64); | 
 | #if SIZEOF_SIZE_T == 4 | 
 |         if (nArraySize != nArraySize64) | 
 |         { | 
 |             TIFFErrorExtR(tif, module, | 
 |                           "Cannot allocate strip offset and bytecount arrays"); | 
 |             return 0; | 
 |         } | 
 | #endif | 
 |         offsetArray = (uint64_t *)(_TIFFreallocExt(tif, td->td_stripoffset_p, | 
 |                                                    nArraySize)); | 
 |         bytecountArray = (uint64_t *)(_TIFFreallocExt( | 
 |             tif, td->td_stripbytecount_p, nArraySize)); | 
 |         if (offsetArray) | 
 |             td->td_stripoffset_p = offsetArray; | 
 |         if (bytecountArray) | 
 |             td->td_stripbytecount_p = bytecountArray; | 
 |         if (offsetArray && bytecountArray) | 
 |         { | 
 |             td->td_stripoffsetbyteallocsize = nStripArrayAllocNew; | 
 |             /* Initialize new entries to ~0 / -1 */ | 
 |             /* coverity[overrun-buffer-arg] */ | 
 |             memset(td->td_stripoffset_p + nStripArrayAllocBefore, 0xFF, | 
 |                    (td->td_stripoffsetbyteallocsize - nStripArrayAllocBefore) * | 
 |                        sizeof(uint64_t)); | 
 |             /* coverity[overrun-buffer-arg] */ | 
 |             memset(td->td_stripbytecount_p + nStripArrayAllocBefore, 0xFF, | 
 |                    (td->td_stripoffsetbyteallocsize - nStripArrayAllocBefore) * | 
 |                        sizeof(uint64_t)); | 
 |         } | 
 |         else | 
 |         { | 
 |             TIFFErrorExtR(tif, module, | 
 |                           "Cannot allocate strip offset and bytecount arrays"); | 
 |             _TIFFfreeExt(tif, td->td_stripoffset_p); | 
 |             td->td_stripoffset_p = NULL; | 
 |             _TIFFfreeExt(tif, td->td_stripbytecount_p); | 
 |             td->td_stripbytecount_p = NULL; | 
 |             td->td_stripoffsetbyteallocsize = 0; | 
 |         } | 
 |     } | 
 |     if (*parray == NULL || strile >= td->td_stripoffsetbyteallocsize) | 
 |         return 0; | 
 |  | 
 |     if (~((*parray)[strile]) == 0) | 
 |     { | 
 |         if (!_TIFFPartialReadStripArray(tif, dirent, strile, *parray)) | 
 |         { | 
 |             (*parray)[strile] = 0; | 
 |             return 0; | 
 |         } | 
 |     } | 
 |  | 
 |     return 1; | 
 | } | 
 |  | 
 | static uint64_t _TIFFGetStrileOffsetOrByteCountValue(TIFF *tif, uint32_t strile, | 
 |                                                      TIFFDirEntry *dirent, | 
 |                                                      uint64_t **parray, | 
 |                                                      int *pbErr) | 
 | { | 
 |     TIFFDirectory *td = &tif->tif_dir; | 
 |     if (pbErr) | 
 |         *pbErr = 0; | 
 |     if ((tif->tif_flags & TIFF_DEFERSTRILELOAD) && | 
 |         !(tif->tif_flags & TIFF_CHOPPEDUPARRAYS)) | 
 |     { | 
 |         if (!(tif->tif_flags & TIFF_LAZYSTRILELOAD) || | 
 |             /* If the values may fit in the toff_long/toff_long8 member */ | 
 |             /* then use _TIFFFillStriles to simplify _TIFFFetchStrileValue */ | 
 |             dirent->tdir_count <= 4) | 
 |         { | 
 |             if (!_TIFFFillStriles(tif)) | 
 |             { | 
 |                 if (pbErr) | 
 |                     *pbErr = 1; | 
 |                 /* Do not return, as we want this function to always */ | 
 |                 /* return the same value if called several times with */ | 
 |                 /* the same arguments */ | 
 |             } | 
 |         } | 
 |         else | 
 |         { | 
 |             if (!_TIFFFetchStrileValue(tif, strile, dirent, parray)) | 
 |             { | 
 |                 if (pbErr) | 
 |                     *pbErr = 1; | 
 |                 return 0; | 
 |             } | 
 |         } | 
 |     } | 
 |     if (*parray == NULL || strile >= td->td_nstrips) | 
 |     { | 
 |         if (pbErr) | 
 |             *pbErr = 1; | 
 |         return 0; | 
 |     } | 
 |     return (*parray)[strile]; | 
 | } | 
 |  | 
 | /* Return the value of the TileOffsets/StripOffsets array for the specified | 
 |  * tile/strile */ | 
 | uint64_t TIFFGetStrileOffset(TIFF *tif, uint32_t strile) | 
 | { | 
 |     return TIFFGetStrileOffsetWithErr(tif, strile, NULL); | 
 | } | 
 |  | 
 | /* Return the value of the TileOffsets/StripOffsets array for the specified | 
 |  * tile/strile */ | 
 | uint64_t TIFFGetStrileOffsetWithErr(TIFF *tif, uint32_t strile, int *pbErr) | 
 | { | 
 |     TIFFDirectory *td = &tif->tif_dir; | 
 |     return _TIFFGetStrileOffsetOrByteCountValue(tif, strile, | 
 |                                                 &(td->td_stripoffset_entry), | 
 |                                                 &(td->td_stripoffset_p), pbErr); | 
 | } | 
 |  | 
 | /* Return the value of the TileByteCounts/StripByteCounts array for the | 
 |  * specified tile/strile */ | 
 | uint64_t TIFFGetStrileByteCount(TIFF *tif, uint32_t strile) | 
 | { | 
 |     return TIFFGetStrileByteCountWithErr(tif, strile, NULL); | 
 | } | 
 |  | 
 | /* Return the value of the TileByteCounts/StripByteCounts array for the | 
 |  * specified tile/strile */ | 
 | uint64_t TIFFGetStrileByteCountWithErr(TIFF *tif, uint32_t strile, int *pbErr) | 
 | { | 
 |     TIFFDirectory *td = &tif->tif_dir; | 
 |     return _TIFFGetStrileOffsetOrByteCountValue( | 
 |         tif, strile, &(td->td_stripbytecount_entry), &(td->td_stripbytecount_p), | 
 |         pbErr); | 
 | } | 
 |  | 
 | int _TIFFFillStriles(TIFF *tif) { return _TIFFFillStrilesInternal(tif, 1); } | 
 |  | 
 | static int _TIFFFillStrilesInternal(TIFF *tif, int loadStripByteCount) | 
 | { | 
 |     register TIFFDirectory *td = &tif->tif_dir; | 
 |     int return_value = 1; | 
 |  | 
 |     /* Do not do anything if TIFF_DEFERSTRILELOAD is not set */ | 
 |     if (!(tif->tif_flags & TIFF_DEFERSTRILELOAD) || | 
 |         (tif->tif_flags & TIFF_CHOPPEDUPARRAYS) != 0) | 
 |         return 1; | 
 |  | 
 |     if (tif->tif_flags & TIFF_LAZYSTRILELOAD) | 
 |     { | 
 |         /* In case of lazy loading, reload completely the arrays */ | 
 |         _TIFFfreeExt(tif, td->td_stripoffset_p); | 
 |         _TIFFfreeExt(tif, td->td_stripbytecount_p); | 
 |         td->td_stripoffset_p = NULL; | 
 |         td->td_stripbytecount_p = NULL; | 
 |         td->td_stripoffsetbyteallocsize = 0; | 
 |         tif->tif_flags &= ~TIFF_LAZYSTRILELOAD; | 
 |     } | 
 |  | 
 |     /* If stripoffset array is already loaded, exit with success */ | 
 |     if (td->td_stripoffset_p != NULL) | 
 |         return 1; | 
 |  | 
 |     /* If tdir_count was canceled, then we already got there, but in error */ | 
 |     if (td->td_stripoffset_entry.tdir_count == 0) | 
 |         return 0; | 
 |  | 
 |     if (!TIFFFetchStripThing(tif, &(td->td_stripoffset_entry), td->td_nstrips, | 
 |                              &td->td_stripoffset_p)) | 
 |     { | 
 |         return_value = 0; | 
 |     } | 
 |  | 
 |     if (loadStripByteCount && | 
 |         !TIFFFetchStripThing(tif, &(td->td_stripbytecount_entry), | 
 |                              td->td_nstrips, &td->td_stripbytecount_p)) | 
 |     { | 
 |         return_value = 0; | 
 |     } | 
 |  | 
 |     _TIFFmemset(&(td->td_stripoffset_entry), 0, sizeof(TIFFDirEntry)); | 
 |     _TIFFmemset(&(td->td_stripbytecount_entry), 0, sizeof(TIFFDirEntry)); | 
 |  | 
 | #ifdef STRIPBYTECOUNTSORTED_UNUSED | 
 |     if (tif->tif_dir.td_nstrips > 1 && return_value == 1) | 
 |     { | 
 |         uint32_t strip; | 
 |  | 
 |         tif->tif_dir.td_stripbytecountsorted = 1; | 
 |         for (strip = 1; strip < tif->tif_dir.td_nstrips; strip++) | 
 |         { | 
 |             if (tif->tif_dir.td_stripoffset_p[strip - 1] > | 
 |                 tif->tif_dir.td_stripoffset_p[strip]) | 
 |             { | 
 |                 tif->tif_dir.td_stripbytecountsorted = 0; | 
 |                 break; | 
 |             } | 
 |         } | 
 |     } | 
 | #endif | 
 |  | 
 |     return return_value; | 
 | } |