From d479dd1aab1c1cb907932c6595b0ef33523fc797 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B6rg=20Frings-F=C3=BCrst?= Date: Fri, 6 Nov 2015 07:14:47 +0100 Subject: Imported Upstream version 1.8.3 --- tiff/libtiff/tif_dirread.c | 5640 -------------------------------------------- 1 file changed, 5640 deletions(-) delete mode 100755 tiff/libtiff/tif_dirread.c (limited to 'tiff/libtiff/tif_dirread.c') diff --git a/tiff/libtiff/tif_dirread.c b/tiff/libtiff/tif_dirread.c deleted file mode 100755 index 7835a7c..0000000 --- a/tiff/libtiff/tif_dirread.c +++ /dev/null @@ -1,5640 +0,0 @@ -/* $Id: tif_dirread.c,v 1.183 2015-01-03 18:03:40 erouault Exp $ */ - -/* - * Copyright (c) 1988-1997 Sam Leffler - * Copyright (c) 1991-1997 Silicon Graphics, Inc. - * - * Permission to use, copy, modify, distribute, and sell this software and - * 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 'ignore' to the TIFFDirEntry structure, to flag status, - * eliminating current use of the IGNORE value, and therefore eliminating - * current irrational behaviour on tags with tag id code 0 - * - 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 "tiffiop.h" - -#define IGNORE 0 /* tag placeholder used below */ -#define FAILED_FII ((uint32) -1) - -#ifdef HAVE_IEEEFP -# define TIFFCvtIEEEFloatToNative(tif, n, fp) -# define TIFFCvtIEEEDoubleToNative(tif, n, dp) -#else -extern void TIFFCvtIEEEFloatToNative(TIFF*, uint32, float*); -extern void TIFFCvtIEEEDoubleToNative(TIFF*, uint32, 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* value); -static enum TIFFReadDirEntryErr TIFFReadDirEntryShort(TIFF* tif, TIFFDirEntry* direntry, uint16* value); -static enum TIFFReadDirEntryErr TIFFReadDirEntryLong(TIFF* tif, TIFFDirEntry* direntry, uint32* value); -static enum TIFFReadDirEntryErr TIFFReadDirEntryLong8(TIFF* tif, TIFFDirEntry* direntry, uint64* 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* value); - -static enum TIFFReadDirEntryErr TIFFReadDirEntryArray(TIFF* tif, TIFFDirEntry* direntry, uint32* count, uint32 desttypesize, void** value); -static enum TIFFReadDirEntryErr TIFFReadDirEntryByteArray(TIFF* tif, TIFFDirEntry* direntry, uint8** value); -static enum TIFFReadDirEntryErr TIFFReadDirEntrySbyteArray(TIFF* tif, TIFFDirEntry* direntry, int8** value); -static enum TIFFReadDirEntryErr TIFFReadDirEntryShortArray(TIFF* tif, TIFFDirEntry* direntry, uint16** value); -static enum TIFFReadDirEntryErr TIFFReadDirEntrySshortArray(TIFF* tif, TIFFDirEntry* direntry, int16** value); -static enum TIFFReadDirEntryErr TIFFReadDirEntryLongArray(TIFF* tif, TIFFDirEntry* direntry, uint32** value); -static enum TIFFReadDirEntryErr TIFFReadDirEntrySlongArray(TIFF* tif, TIFFDirEntry* direntry, int32** value); -static enum TIFFReadDirEntryErr TIFFReadDirEntryLong8Array(TIFF* tif, TIFFDirEntry* direntry, uint64** value); -static enum TIFFReadDirEntryErr TIFFReadDirEntrySlong8Array(TIFF* tif, TIFFDirEntry* direntry, int64** 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** value); - -static enum TIFFReadDirEntryErr TIFFReadDirEntryPersampleShort(TIFF* tif, TIFFDirEntry* direntry, uint16* value); -#if 0 -static enum TIFFReadDirEntryErr TIFFReadDirEntryPersampleDouble(TIFF* tif, TIFFDirEntry* direntry, double* value); -#endif - -static void TIFFReadDirEntryCheckedByte(TIFF* tif, TIFFDirEntry* direntry, uint8* value); -static void TIFFReadDirEntryCheckedSbyte(TIFF* tif, TIFFDirEntry* direntry, int8* value); -static void TIFFReadDirEntryCheckedShort(TIFF* tif, TIFFDirEntry* direntry, uint16* value); -static void TIFFReadDirEntryCheckedSshort(TIFF* tif, TIFFDirEntry* direntry, int16* value); -static void TIFFReadDirEntryCheckedLong(TIFF* tif, TIFFDirEntry* direntry, uint32* value); -static void TIFFReadDirEntryCheckedSlong(TIFF* tif, TIFFDirEntry* direntry, int32* value); -static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckedLong8(TIFF* tif, TIFFDirEntry* direntry, uint64* value); -static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckedSlong8(TIFF* tif, TIFFDirEntry* direntry, int64* 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); - -static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckRangeByteSbyte(int8 value); -static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckRangeByteShort(uint16 value); -static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckRangeByteSshort(int16 value); -static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckRangeByteLong(uint32 value); -static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckRangeByteSlong(int32 value); -static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckRangeByteLong8(uint64 value); -static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckRangeByteSlong8(int64 value); - -static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckRangeSbyteByte(uint8 value); -static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckRangeSbyteShort(uint16 value); -static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckRangeSbyteSshort(int16 value); -static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckRangeSbyteLong(uint32 value); -static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckRangeSbyteSlong(int32 value); -static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckRangeSbyteLong8(uint64 value); -static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckRangeSbyteSlong8(int64 value); - -static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckRangeShortSbyte(int8 value); -static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckRangeShortSshort(int16 value); -static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckRangeShortLong(uint32 value); -static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckRangeShortSlong(int32 value); -static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckRangeShortLong8(uint64 value); -static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckRangeShortSlong8(int64 value); - -static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckRangeSshortShort(uint16 value); -static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckRangeSshortLong(uint32 value); -static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckRangeSshortSlong(int32 value); -static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckRangeSshortLong8(uint64 value); -static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckRangeSshortSlong8(int64 value); - -static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckRangeLongSbyte(int8 value); -static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckRangeLongSshort(int16 value); -static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckRangeLongSlong(int32 value); -static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckRangeLongLong8(uint64 value); -static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckRangeLongSlong8(int64 value); - -static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckRangeSlongLong(uint32 value); -static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckRangeSlongLong8(uint64 value); -static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckRangeSlongSlong8(int64 value); - -static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckRangeLong8Sbyte(int8 value); -static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckRangeLong8Sshort(int16 value); -static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckRangeLong8Slong(int32 value); -static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckRangeLong8Slong8(int64 value); - -static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckRangeSlong8Long8(uint64 value); - -static enum TIFFReadDirEntryErr TIFFReadDirEntryData(TIFF* tif, uint64 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 dircount); -static TIFFDirEntry* TIFFReadDirectoryFindEntry(TIFF* tif, TIFFDirEntry* dir, uint16 dircount, uint16 tagid); -static void TIFFReadDirectoryFindFieldInfo(TIFF* tif, uint16 tagid, uint32* fii); - -static int EstimateStripByteCounts(TIFF* tif, TIFFDirEntry* dir, uint16 dircount); -static void MissingRequired(TIFF*, const char*); -static int TIFFCheckDirOffset(TIFF* tif, uint64 diroff); -static int CheckDirCount(TIFF*, TIFFDirEntry*, uint32); -static uint16 TIFFFetchDirectory(TIFF* tif, uint64 diroff, TIFFDirEntry** pdir, uint64* nextdiroff); -static int TIFFFetchNormalTag(TIFF*, TIFFDirEntry*, int recover); -static int TIFFFetchStripThing(TIFF* tif, TIFFDirEntry* dir, uint32 nstrips, uint64** lpp); -static int TIFFFetchSubjectDistance(TIFF*, TIFFDirEntry*); -static void ChopUpSingleUncompressedStrip(TIFF*); -static uint64 TIFFReadUInt64(const uint8 *value); - -typedef union _UInt64Aligned_t -{ - double d; - uint64 l; - uint32 i[2]; - uint16 s[4]; - uint8 c[8]; -} UInt64Aligned_t; - -/* - Unaligned safe copy of a uint64 value from an octet array. -*/ -static uint64 TIFFReadUInt64(const uint8 *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* value) -{ - enum TIFFReadDirEntryErr err; - if (direntry->tdir_count!=1) - return(TIFFReadDirEntryErrCount); - switch (direntry->tdir_type) - { - case TIFF_BYTE: - TIFFReadDirEntryCheckedByte(tif,direntry,value); - return(TIFFReadDirEntryErrOk); - case TIFF_SBYTE: - { - int8 m; - TIFFReadDirEntryCheckedSbyte(tif,direntry,&m); - err=TIFFReadDirEntryCheckRangeByteSbyte(m); - if (err!=TIFFReadDirEntryErrOk) - return(err); - *value=(uint8)m; - return(TIFFReadDirEntryErrOk); - } - case TIFF_SHORT: - { - uint16 m; - TIFFReadDirEntryCheckedShort(tif,direntry,&m); - err=TIFFReadDirEntryCheckRangeByteShort(m); - if (err!=TIFFReadDirEntryErrOk) - return(err); - *value=(uint8)m; - return(TIFFReadDirEntryErrOk); - } - case TIFF_SSHORT: - { - int16 m; - TIFFReadDirEntryCheckedSshort(tif,direntry,&m); - err=TIFFReadDirEntryCheckRangeByteSshort(m); - if (err!=TIFFReadDirEntryErrOk) - return(err); - *value=(uint8)m; - return(TIFFReadDirEntryErrOk); - } - case TIFF_LONG: - { - uint32 m; - TIFFReadDirEntryCheckedLong(tif,direntry,&m); - err=TIFFReadDirEntryCheckRangeByteLong(m); - if (err!=TIFFReadDirEntryErrOk) - return(err); - *value=(uint8)m; - return(TIFFReadDirEntryErrOk); - } - case TIFF_SLONG: - { - int32 m; - TIFFReadDirEntryCheckedSlong(tif,direntry,&m); - err=TIFFReadDirEntryCheckRangeByteSlong(m); - if (err!=TIFFReadDirEntryErrOk) - return(err); - *value=(uint8)m; - return(TIFFReadDirEntryErrOk); - } - case TIFF_LONG8: - { - uint64 m; - err=TIFFReadDirEntryCheckedLong8(tif,direntry,&m); - if (err!=TIFFReadDirEntryErrOk) - return(err); - err=TIFFReadDirEntryCheckRangeByteLong8(m); - if (err!=TIFFReadDirEntryErrOk) - return(err); - *value=(uint8)m; - return(TIFFReadDirEntryErrOk); - } - case TIFF_SLONG8: - { - int64 m; - err=TIFFReadDirEntryCheckedSlong8(tif,direntry,&m); - if (err!=TIFFReadDirEntryErrOk) - return(err); - err=TIFFReadDirEntryCheckRangeByteSlong8(m); - if (err!=TIFFReadDirEntryErrOk) - return(err); - *value=(uint8)m; - return(TIFFReadDirEntryErrOk); - } - default: - return(TIFFReadDirEntryErrType); - } -} - -static enum TIFFReadDirEntryErr TIFFReadDirEntryShort(TIFF* tif, TIFFDirEntry* direntry, uint16* value) -{ - enum TIFFReadDirEntryErr err; - if (direntry->tdir_count!=1) - return(TIFFReadDirEntryErrCount); - switch (direntry->tdir_type) - { - case TIFF_BYTE: - { - uint8 m; - TIFFReadDirEntryCheckedByte(tif,direntry,&m); - *value=(uint16)m; - return(TIFFReadDirEntryErrOk); - } - case TIFF_SBYTE: - { - int8 m; - TIFFReadDirEntryCheckedSbyte(tif,direntry,&m); - err=TIFFReadDirEntryCheckRangeShortSbyte(m); - if (err!=TIFFReadDirEntryErrOk) - return(err); - *value=(uint16)m; - return(TIFFReadDirEntryErrOk); - } - case TIFF_SHORT: - TIFFReadDirEntryCheckedShort(tif,direntry,value); - return(TIFFReadDirEntryErrOk); - case TIFF_SSHORT: - { - int16 m; - TIFFReadDirEntryCheckedSshort(tif,direntry,&m); - err=TIFFReadDirEntryCheckRangeShortSshort(m); - if (err!=TIFFReadDirEntryErrOk) - return(err); - *value=(uint16)m; - return(TIFFReadDirEntryErrOk); - } - case TIFF_LONG: - { - uint32 m; - TIFFReadDirEntryCheckedLong(tif,direntry,&m); - err=TIFFReadDirEntryCheckRangeShortLong(m); - if (err!=TIFFReadDirEntryErrOk) - return(err); - *value=(uint16)m; - return(TIFFReadDirEntryErrOk); - } - case TIFF_SLONG: - { - int32 m; - TIFFReadDirEntryCheckedSlong(tif,direntry,&m); - err=TIFFReadDirEntryCheckRangeShortSlong(m); - if (err!=TIFFReadDirEntryErrOk) - return(err); - *value=(uint16)m; - return(TIFFReadDirEntryErrOk); - } - case TIFF_LONG8: - { - uint64 m; - err=TIFFReadDirEntryCheckedLong8(tif,direntry,&m); - if (err!=TIFFReadDirEntryErrOk) - return(err); - err=TIFFReadDirEntryCheckRangeShortLong8(m); - if (err!=TIFFReadDirEntryErrOk) - return(err); - *value=(uint16)m; - return(TIFFReadDirEntryErrOk); - } - case TIFF_SLONG8: - { - int64 m; - err=TIFFReadDirEntryCheckedSlong8(tif,direntry,&m); - if (err!=TIFFReadDirEntryErrOk) - return(err); - err=TIFFReadDirEntryCheckRangeShortSlong8(m); - if (err!=TIFFReadDirEntryErrOk) - return(err); - *value=(uint16)m; - return(TIFFReadDirEntryErrOk); - } - default: - return(TIFFReadDirEntryErrType); - } -} - -static enum TIFFReadDirEntryErr TIFFReadDirEntryLong(TIFF* tif, TIFFDirEntry* direntry, uint32* value) -{ - enum TIFFReadDirEntryErr err; - if (direntry->tdir_count!=1) - return(TIFFReadDirEntryErrCount); - switch (direntry->tdir_type) - { - case TIFF_BYTE: - { - uint8 m; - TIFFReadDirEntryCheckedByte(tif,direntry,&m); - *value=(uint32)m; - return(TIFFReadDirEntryErrOk); - } - case TIFF_SBYTE: - { - int8 m; - TIFFReadDirEntryCheckedSbyte(tif,direntry,&m); - err=TIFFReadDirEntryCheckRangeLongSbyte(m); - if (err!=TIFFReadDirEntryErrOk) - return(err); - *value=(uint32)m; - return(TIFFReadDirEntryErrOk); - } - case TIFF_SHORT: - { - uint16 m; - TIFFReadDirEntryCheckedShort(tif,direntry,&m); - *value=(uint32)m; - return(TIFFReadDirEntryErrOk); - } - case TIFF_SSHORT: - { - int16 m; - TIFFReadDirEntryCheckedSshort(tif,direntry,&m); - err=TIFFReadDirEntryCheckRangeLongSshort(m); - if (err!=TIFFReadDirEntryErrOk) - return(err); - *value=(uint32)m; - return(TIFFReadDirEntryErrOk); - } - case TIFF_LONG: - TIFFReadDirEntryCheckedLong(tif,direntry,value); - return(TIFFReadDirEntryErrOk); - case TIFF_SLONG: - { - int32 m; - TIFFReadDirEntryCheckedSlong(tif,direntry,&m); - err=TIFFReadDirEntryCheckRangeLongSlong(m); - if (err!=TIFFReadDirEntryErrOk) - return(err); - *value=(uint32)m; - return(TIFFReadDirEntryErrOk); - } - case TIFF_LONG8: - { - uint64 m; - err=TIFFReadDirEntryCheckedLong8(tif,direntry,&m); - if (err!=TIFFReadDirEntryErrOk) - return(err); - err=TIFFReadDirEntryCheckRangeLongLong8(m); - if (err!=TIFFReadDirEntryErrOk) - return(err); - *value=(uint32)m; - return(TIFFReadDirEntryErrOk); - } - case TIFF_SLONG8: - { - int64 m; - err=TIFFReadDirEntryCheckedSlong8(tif,direntry,&m); - if (err!=TIFFReadDirEntryErrOk) - return(err); - err=TIFFReadDirEntryCheckRangeLongSlong8(m); - if (err!=TIFFReadDirEntryErrOk) - return(err); - *value=(uint32)m; - return(TIFFReadDirEntryErrOk); - } - default: - return(TIFFReadDirEntryErrType); - } -} - -static enum TIFFReadDirEntryErr TIFFReadDirEntryLong8(TIFF* tif, TIFFDirEntry* direntry, uint64* value) -{ - enum TIFFReadDirEntryErr err; - if (direntry->tdir_count!=1) - return(TIFFReadDirEntryErrCount); - switch (direntry->tdir_type) - { - case TIFF_BYTE: - { - uint8 m; - TIFFReadDirEntryCheckedByte(tif,direntry,&m); - *value=(uint64)m; - return(TIFFReadDirEntryErrOk); - } - case TIFF_SBYTE: - { - int8 m; - TIFFReadDirEntryCheckedSbyte(tif,direntry,&m); - err=TIFFReadDirEntryCheckRangeLong8Sbyte(m); - if (err!=TIFFReadDirEntryErrOk) - return(err); - *value=(uint64)m; - return(TIFFReadDirEntryErrOk); - } - case TIFF_SHORT: - { - uint16 m; - TIFFReadDirEntryCheckedShort(tif,direntry,&m); - *value=(uint64)m; - return(TIFFReadDirEntryErrOk); - } - case TIFF_SSHORT: - { - int16 m; - TIFFReadDirEntryCheckedSshort(tif,direntry,&m); - err=TIFFReadDirEntryCheckRangeLong8Sshort(m); - if (err!=TIFFReadDirEntryErrOk) - return(err); - *value=(uint64)m; - return(TIFFReadDirEntryErrOk); - } - case TIFF_LONG: - { - uint32 m; - TIFFReadDirEntryCheckedLong(tif,direntry,&m); - *value=(uint64)m; - return(TIFFReadDirEntryErrOk); - } - case TIFF_SLONG: - { - int32 m; - TIFFReadDirEntryCheckedSlong(tif,direntry,&m); - err=TIFFReadDirEntryCheckRangeLong8Slong(m); - if (err!=TIFFReadDirEntryErrOk) - return(err); - *value=(uint64)m; - return(TIFFReadDirEntryErrOk); - } - case TIFF_LONG8: - err=TIFFReadDirEntryCheckedLong8(tif,direntry,value); - return(err); - case TIFF_SLONG8: - { - int64 m; - err=TIFFReadDirEntryCheckedSlong8(tif,direntry,&m); - if (err!=TIFFReadDirEntryErrOk) - return(err); - err=TIFFReadDirEntryCheckRangeLong8Slong8(m); - if (err!=TIFFReadDirEntryErrOk) - return(err); - *value=(uint64)m; - return(TIFFReadDirEntryErrOk); - } - default: - return(TIFFReadDirEntryErrType); - } -} - -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 m; - TIFFReadDirEntryCheckedByte(tif,direntry,&m); - *value=(float)m; - return(TIFFReadDirEntryErrOk); - } - case TIFF_SBYTE: - { - int8 m; - TIFFReadDirEntryCheckedSbyte(tif,direntry,&m); - *value=(float)m; - return(TIFFReadDirEntryErrOk); - } - case TIFF_SHORT: - { - uint16 m; - TIFFReadDirEntryCheckedShort(tif,direntry,&m); - *value=(float)m; - return(TIFFReadDirEntryErrOk); - } - case TIFF_SSHORT: - { - int16 m; - TIFFReadDirEntryCheckedSshort(tif,direntry,&m); - *value=(float)m; - return(TIFFReadDirEntryErrOk); - } - case TIFF_LONG: - { - uint32 m; - TIFFReadDirEntryCheckedLong(tif,direntry,&m); - *value=(float)m; - return(TIFFReadDirEntryErrOk); - } - case TIFF_SLONG: - { - int32 m; - TIFFReadDirEntryCheckedSlong(tif,direntry,&m); - *value=(float)m; - return(TIFFReadDirEntryErrOk); - } - case TIFF_LONG8: - { - uint64 m; - err=TIFFReadDirEntryCheckedLong8(tif,direntry,&m); - if (err!=TIFFReadDirEntryErrOk) - return(err); -#if defined(__WIN32__) && (_MSC_VER < 1500) - /* - * XXX: MSVC 6.0 does not support conversion - * of 64-bit integers into floating point - * values. - */ - *value = _TIFFUInt64ToFloat(m); -#else - *value=(float)m; -#endif - return(TIFFReadDirEntryErrOk); - } - case TIFF_SLONG8: - { - int64 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); - *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 m; - TIFFReadDirEntryCheckedByte(tif,direntry,&m); - *value=(double)m; - return(TIFFReadDirEntryErrOk); - } - case TIFF_SBYTE: - { - int8 m; - TIFFReadDirEntryCheckedSbyte(tif,direntry,&m); - *value=(double)m; - return(TIFFReadDirEntryErrOk); - } - case TIFF_SHORT: - { - uint16 m; - TIFFReadDirEntryCheckedShort(tif,direntry,&m); - *value=(double)m; - return(TIFFReadDirEntryErrOk); - } - case TIFF_SSHORT: - { - int16 m; - TIFFReadDirEntryCheckedSshort(tif,direntry,&m); - *value=(double)m; - return(TIFFReadDirEntryErrOk); - } - case TIFF_LONG: - { - uint32 m; - TIFFReadDirEntryCheckedLong(tif,direntry,&m); - *value=(double)m; - return(TIFFReadDirEntryErrOk); - } - case TIFF_SLONG: - { - int32 m; - TIFFReadDirEntryCheckedSlong(tif,direntry,&m); - *value=(double)m; - return(TIFFReadDirEntryErrOk); - } - case TIFF_LONG8: - { - uint64 m; - err=TIFFReadDirEntryCheckedLong8(tif,direntry,&m); - if (err!=TIFFReadDirEntryErrOk) - return(err); -#if defined(__WIN32__) && (_MSC_VER < 1500) - /* - * XXX: MSVC 6.0 does not support conversion - * of 64-bit integers into floating point - * values. - */ - *value = _TIFFUInt64ToDouble(m); -#else - *value = (double)m; -#endif - return(TIFFReadDirEntryErrOk); - } - case TIFF_SLONG8: - { - int64 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* value) -{ - enum TIFFReadDirEntryErr err; - if (direntry->tdir_count!=1) - return(TIFFReadDirEntryErrCount); - switch (direntry->tdir_type) - { - case TIFF_LONG: - case TIFF_IFD: - { - uint32 m; - TIFFReadDirEntryCheckedLong(tif,direntry,&m); - *value=(uint64)m; - return(TIFFReadDirEntryErrOk); - } - case TIFF_LONG8: - case TIFF_IFD8: - err=TIFFReadDirEntryCheckedLong8(tif,direntry,value); - return(err); - default: - return(TIFFReadDirEntryErrType); - } -} - -static enum TIFFReadDirEntryErr TIFFReadDirEntryArray(TIFF* tif, TIFFDirEntry* direntry, uint32* count, uint32 desttypesize, void** value) -{ - int typesize; - uint32 datasize; - void* data; - typesize=TIFFDataWidth(direntry->tdir_type); - if ((direntry->tdir_count==0)||(typesize==0)) - { - *value=0; - return(TIFFReadDirEntryErrOk); - } - (void) desttypesize; - - /* - * 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)(2147483647/typesize)tdir_count) - return(TIFFReadDirEntryErrSizesan); - if ((uint64)(2147483647/desttypesize)tdir_count) - return(TIFFReadDirEntryErrSizesan); - - *count=(uint32)direntry->tdir_count; - datasize=(*count)*typesize; - assert((tmsize_t)datasize>0); - data=_TIFFCheckMalloc(tif, *count, typesize, "ReadDirEntryArray"); - if (data==0) - return(TIFFReadDirEntryErrAlloc); - if (!(tif->tif_flags&TIFF_BIGTIFF)) - { - if (datasize<=4) - _TIFFmemcpy(data,&direntry->tdir_offset,datasize); - else - { - enum TIFFReadDirEntryErr err; - uint32 offset = direntry->tdir_offset.toff_long; - if (tif->tif_flags&TIFF_SWAB) - TIFFSwabLong(&offset); - err=TIFFReadDirEntryData(tif,(uint64)offset,(tmsize_t)datasize,data); - if (err!=TIFFReadDirEntryErrOk) - { - _TIFFfree(data); - return(err); - } - } - } - else - { - if (datasize<=8) - _TIFFmemcpy(data,&direntry->tdir_offset,datasize); - else - { - enum TIFFReadDirEntryErr err; - uint64 offset = direntry->tdir_offset.toff_long8; - if (tif->tif_flags&TIFF_SWAB) - TIFFSwabLong8(&offset); - err=TIFFReadDirEntryData(tif,offset,(tmsize_t)datasize,data); - if (err!=TIFFReadDirEntryErrOk) - { - _TIFFfree(data); - return(err); - } - } - } - *value=data; - return(TIFFReadDirEntryErrOk); -} - -static enum TIFFReadDirEntryErr TIFFReadDirEntryByteArray(TIFF* tif, TIFFDirEntry* direntry, uint8** value) -{ - enum TIFFReadDirEntryErr err; - uint32 count; - void* origdata; - uint8* 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*)origdata; - return(TIFFReadDirEntryErrOk); - case TIFF_SBYTE: - { - int8* m; - uint32 n; - m=(int8*)origdata; - for (n=0; ntdir_type) - { - case TIFF_SHORT: - { - uint16* ma; - uint8* mb; - uint32 n; - ma=(uint16*)origdata; - mb=data; - for (n=0; ntif_flags&TIFF_SWAB) - TIFFSwabShort(ma); - err=TIFFReadDirEntryCheckRangeByteShort(*ma); - if (err!=TIFFReadDirEntryErrOk) - break; - *mb++=(uint8)(*ma++); - } - } - break; - case TIFF_SSHORT: - { - int16* ma; - uint8* mb; - uint32 n; - ma=(int16*)origdata; - mb=data; - for (n=0; ntif_flags&TIFF_SWAB) - TIFFSwabShort((uint16*)ma); - err=TIFFReadDirEntryCheckRangeByteSshort(*ma); - if (err!=TIFFReadDirEntryErrOk) - break; - *mb++=(uint8)(*ma++); - } - } - break; - case TIFF_LONG: - { - uint32* ma; - uint8* mb; - uint32 n; - ma=(uint32*)origdata; - mb=data; - for (n=0; ntif_flags&TIFF_SWAB) - TIFFSwabLong(ma); - err=TIFFReadDirEntryCheckRangeByteLong(*ma); - if (err!=TIFFReadDirEntryErrOk) - break; - *mb++=(uint8)(*ma++); - } - } - break; - case TIFF_SLONG: - { - int32* ma; - uint8* mb; - uint32 n; - ma=(int32*)origdata; - mb=data; - for (n=0; ntif_flags&TIFF_SWAB) - TIFFSwabLong((uint32*)ma); - err=TIFFReadDirEntryCheckRangeByteSlong(*ma); - if (err!=TIFFReadDirEntryErrOk) - break; - *mb++=(uint8)(*ma++); - } - } - break; - case TIFF_LONG8: - { - uint64* ma; - uint8* mb; - uint32 n; - ma=(uint64*)origdata; - mb=data; - for (n=0; ntif_flags&TIFF_SWAB) - TIFFSwabLong8(ma); - err=TIFFReadDirEntryCheckRangeByteLong8(*ma); - if (err!=TIFFReadDirEntryErrOk) - break; - *mb++=(uint8)(*ma++); - } - } - break; - case TIFF_SLONG8: - { - int64* ma; - uint8* mb; - uint32 n; - ma=(int64*)origdata; - mb=data; - for (n=0; ntif_flags&TIFF_SWAB) - TIFFSwabLong8((uint64*)ma); - err=TIFFReadDirEntryCheckRangeByteSlong8(*ma); - if (err!=TIFFReadDirEntryErrOk) - break; - *mb++=(uint8)(*ma++); - } - } - break; - } - _TIFFfree(origdata); - if (err!=TIFFReadDirEntryErrOk) - { - _TIFFfree(data); - return(err); - } - *value=data; - return(TIFFReadDirEntryErrOk); -} - -static enum TIFFReadDirEntryErr TIFFReadDirEntrySbyteArray(TIFF* tif, TIFFDirEntry* direntry, int8** value) -{ - enum TIFFReadDirEntryErr err; - uint32 count; - void* origdata; - int8* 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* m; - uint32 n; - m=(uint8*)origdata; - for (n=0; ntdir_type) - { - case TIFF_SHORT: - { - uint16* ma; - int8* mb; - uint32 n; - ma=(uint16*)origdata; - mb=data; - for (n=0; ntif_flags&TIFF_SWAB) - TIFFSwabShort(ma); - err=TIFFReadDirEntryCheckRangeSbyteShort(*ma); - if (err!=TIFFReadDirEntryErrOk) - break; - *mb++=(int8)(*ma++); - } - } - break; - case TIFF_SSHORT: - { - int16* ma; - int8* mb; - uint32 n; - ma=(int16*)origdata; - mb=data; - for (n=0; ntif_flags&TIFF_SWAB) - TIFFSwabShort((uint16*)ma); - err=TIFFReadDirEntryCheckRangeSbyteSshort(*ma); - if (err!=TIFFReadDirEntryErrOk) - break; - *mb++=(int8)(*ma++); - } - } - break; - case TIFF_LONG: - { - uint32* ma; - int8* mb; - uint32 n; - ma=(uint32*)origdata; - mb=data; - for (n=0; ntif_flags&TIFF_SWAB) - TIFFSwabLong(ma); - err=TIFFReadDirEntryCheckRangeSbyteLong(*ma); - if (err!=TIFFReadDirEntryErrOk) - break; - *mb++=(int8)(*ma++); - } - } - break; - case TIFF_SLONG: - { - int32* ma; - int8* mb; - uint32 n; - ma=(int32*)origdata; - mb=data; - for (n=0; ntif_flags&TIFF_SWAB) - TIFFSwabLong((uint32*)ma); - err=TIFFReadDirEntryCheckRangeSbyteSlong(*ma); - if (err!=TIFFReadDirEntryErrOk) - break; - *mb++=(int8)(*ma++); - } - } - break; - case TIFF_LONG8: - { - uint64* ma; - int8* mb; - uint32 n; - ma=(uint64*)origdata; - mb=data; - for (n=0; ntif_flags&TIFF_SWAB) - TIFFSwabLong8(ma); - err=TIFFReadDirEntryCheckRangeSbyteLong8(*ma); - if (err!=TIFFReadDirEntryErrOk) - break; - *mb++=(int8)(*ma++); - } - } - break; - case TIFF_SLONG8: - { - int64* ma; - int8* mb; - uint32 n; - ma=(int64*)origdata; - mb=data; - for (n=0; ntif_flags&TIFF_SWAB) - TIFFSwabLong8((uint64*)ma); - err=TIFFReadDirEntryCheckRangeSbyteSlong8(*ma); - if (err!=TIFFReadDirEntryErrOk) - break; - *mb++=(int8)(*ma++); - } - } - break; - } - _TIFFfree(origdata); - if (err!=TIFFReadDirEntryErrOk) - { - _TIFFfree(data); - return(err); - } - *value=data; - return(TIFFReadDirEntryErrOk); -} - -static enum TIFFReadDirEntryErr TIFFReadDirEntryShortArray(TIFF* tif, TIFFDirEntry* direntry, uint16** value) -{ - enum TIFFReadDirEntryErr err; - uint32 count; - void* origdata; - uint16* 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*)origdata; - if (tif->tif_flags&TIFF_SWAB) - TIFFSwabArrayOfShort(*value,count); - return(TIFFReadDirEntryErrOk); - case TIFF_SSHORT: - { - int16* m; - uint32 n; - m=(int16*)origdata; - for (n=0; ntif_flags&TIFF_SWAB) - TIFFSwabShort((uint16*)m); - err=TIFFReadDirEntryCheckRangeShortSshort(*m); - if (err!=TIFFReadDirEntryErrOk) - { - _TIFFfree(origdata); - return(err); - } - m++; - } - *value=(uint16*)origdata; - return(TIFFReadDirEntryErrOk); - } - } - data=(uint16*)_TIFFmalloc(count*2); - if (data==0) - { - _TIFFfree(origdata); - return(TIFFReadDirEntryErrAlloc); - } - switch (direntry->tdir_type) - { - case TIFF_BYTE: - { - uint8* ma; - uint16* mb; - uint32 n; - ma=(uint8*)origdata; - mb=data; - for (n=0; ntif_flags&TIFF_SWAB) - TIFFSwabLong(ma); - err=TIFFReadDirEntryCheckRangeShortLong(*ma); - if (err!=TIFFReadDirEntryErrOk) - break; - *mb++=(uint16)(*ma++); - } - } - break; - case TIFF_SLONG: - { - int32* ma; - uint16* mb; - uint32 n; - ma=(int32*)origdata; - mb=data; - for (n=0; ntif_flags&TIFF_SWAB) - TIFFSwabLong((uint32*)ma); - err=TIFFReadDirEntryCheckRangeShortSlong(*ma); - if (err!=TIFFReadDirEntryErrOk) - break; - *mb++=(uint16)(*ma++); - } - } - break; - case TIFF_LONG8: - { - uint64* ma; - uint16* mb; - uint32 n; - ma=(uint64*)origdata; - mb=data; - for (n=0; ntif_flags&TIFF_SWAB) - TIFFSwabLong8(ma); - err=TIFFReadDirEntryCheckRangeShortLong8(*ma); - if (err!=TIFFReadDirEntryErrOk) - break; - *mb++=(uint16)(*ma++); - } - } - break; - case TIFF_SLONG8: - { - int64* ma; - uint16* mb; - uint32 n; - ma=(int64*)origdata; - mb=data; - for (n=0; ntif_flags&TIFF_SWAB) - TIFFSwabLong8((uint64*)ma); - err=TIFFReadDirEntryCheckRangeShortSlong8(*ma); - if (err!=TIFFReadDirEntryErrOk) - break; - *mb++=(uint16)(*ma++); - } - } - break; - } - _TIFFfree(origdata); - if (err!=TIFFReadDirEntryErrOk) - { - _TIFFfree(data); - return(err); - } - *value=data; - return(TIFFReadDirEntryErrOk); -} - -static enum TIFFReadDirEntryErr TIFFReadDirEntrySshortArray(TIFF* tif, TIFFDirEntry* direntry, int16** value) -{ - enum TIFFReadDirEntryErr err; - uint32 count; - void* origdata; - int16* 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* m; - uint32 n; - m=(uint16*)origdata; - for (n=0; ntif_flags&TIFF_SWAB) - TIFFSwabShort(m); - err=TIFFReadDirEntryCheckRangeSshortShort(*m); - if (err!=TIFFReadDirEntryErrOk) - { - _TIFFfree(origdata); - return(err); - } - m++; - } - *value=(int16*)origdata; - return(TIFFReadDirEntryErrOk); - } - case TIFF_SSHORT: - *value=(int16*)origdata; - if (tif->tif_flags&TIFF_SWAB) - TIFFSwabArrayOfShort((uint16*)(*value),count); - return(TIFFReadDirEntryErrOk); - } - data=(int16*)_TIFFmalloc(count*2); - if (data==0) - { - _TIFFfree(origdata); - return(TIFFReadDirEntryErrAlloc); - } - switch (direntry->tdir_type) - { - case TIFF_BYTE: - { - uint8* ma; - int16* mb; - uint32 n; - ma=(uint8*)origdata; - mb=data; - for (n=0; ntif_flags&TIFF_SWAB) - TIFFSwabLong(ma); - err=TIFFReadDirEntryCheckRangeSshortLong(*ma); - if (err!=TIFFReadDirEntryErrOk) - break; - *mb++=(int16)(*ma++); - } - } - break; - case TIFF_SLONG: - { - int32* ma; - int16* mb; - uint32 n; - ma=(int32*)origdata; - mb=data; - for (n=0; ntif_flags&TIFF_SWAB) - TIFFSwabLong((uint32*)ma); - err=TIFFReadDirEntryCheckRangeSshortSlong(*ma); - if (err!=TIFFReadDirEntryErrOk) - break; - *mb++=(int16)(*ma++); - } - } - break; - case TIFF_LONG8: - { - uint64* ma; - int16* mb; - uint32 n; - ma=(uint64*)origdata; - mb=data; - for (n=0; ntif_flags&TIFF_SWAB) - TIFFSwabLong8(ma); - err=TIFFReadDirEntryCheckRangeSshortLong8(*ma); - if (err!=TIFFReadDirEntryErrOk) - break; - *mb++=(int16)(*ma++); - } - } - break; - case TIFF_SLONG8: - { - int64* ma; - int16* mb; - uint32 n; - ma=(int64*)origdata; - mb=data; - for (n=0; ntif_flags&TIFF_SWAB) - TIFFSwabLong8((uint64*)ma); - err=TIFFReadDirEntryCheckRangeSshortSlong8(*ma); - if (err!=TIFFReadDirEntryErrOk) - break; - *mb++=(int16)(*ma++); - } - } - break; - } - _TIFFfree(origdata); - if (err!=TIFFReadDirEntryErrOk) - { - _TIFFfree(data); - return(err); - } - *value=data; - return(TIFFReadDirEntryErrOk); -} - -static enum TIFFReadDirEntryErr TIFFReadDirEntryLongArray(TIFF* tif, TIFFDirEntry* direntry, uint32** value) -{ - enum TIFFReadDirEntryErr err; - uint32 count; - void* origdata; - uint32* 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*)origdata; - if (tif->tif_flags&TIFF_SWAB) - TIFFSwabArrayOfLong(*value,count); - return(TIFFReadDirEntryErrOk); - case TIFF_SLONG: - { - int32* m; - uint32 n; - m=(int32*)origdata; - for (n=0; ntif_flags&TIFF_SWAB) - TIFFSwabLong((uint32*)m); - err=TIFFReadDirEntryCheckRangeLongSlong(*m); - if (err!=TIFFReadDirEntryErrOk) - { - _TIFFfree(origdata); - return(err); - } - m++; - } - *value=(uint32*)origdata; - return(TIFFReadDirEntryErrOk); - } - } - data=(uint32*)_TIFFmalloc(count*4); - if (data==0) - { - _TIFFfree(origdata); - return(TIFFReadDirEntryErrAlloc); - } - switch (direntry->tdir_type) - { - case TIFF_BYTE: - { - uint8* ma; - uint32* mb; - uint32 n; - ma=(uint8*)origdata; - mb=data; - for (n=0; ntif_flags&TIFF_SWAB) - TIFFSwabShort(ma); - *mb++=(uint32)(*ma++); - } - } - break; - case TIFF_SSHORT: - { - int16* ma; - uint32* mb; - uint32 n; - ma=(int16*)origdata; - mb=data; - for (n=0; ntif_flags&TIFF_SWAB) - TIFFSwabShort((uint16*)ma); - err=TIFFReadDirEntryCheckRangeLongSshort(*ma); - if (err!=TIFFReadDirEntryErrOk) - break; - *mb++=(uint32)(*ma++); - } - } - break; - case TIFF_LONG8: - { - uint64* ma; - uint32* mb; - uint32 n; - ma=(uint64*)origdata; - mb=data; - for (n=0; ntif_flags&TIFF_SWAB) - TIFFSwabLong8(ma); - err=TIFFReadDirEntryCheckRangeLongLong8(*ma); - if (err!=TIFFReadDirEntryErrOk) - break; - *mb++=(uint32)(*ma++); - } - } - break; - case TIFF_SLONG8: - { - int64* ma; - uint32* mb; - uint32 n; - ma=(int64*)origdata; - mb=data; - for (n=0; ntif_flags&TIFF_SWAB) - TIFFSwabLong8((uint64*)ma); - err=TIFFReadDirEntryCheckRangeLongSlong8(*ma); - if (err!=TIFFReadDirEntryErrOk) - break; - *mb++=(uint32)(*ma++); - } - } - break; - } - _TIFFfree(origdata); - if (err!=TIFFReadDirEntryErrOk) - { - _TIFFfree(data); - return(err); - } - *value=data; - return(TIFFReadDirEntryErrOk); -} - -static enum TIFFReadDirEntryErr TIFFReadDirEntrySlongArray(TIFF* tif, TIFFDirEntry* direntry, int32** value) -{ - enum TIFFReadDirEntryErr err; - uint32 count; - void* origdata; - int32* 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* m; - uint32 n; - m=(uint32*)origdata; - for (n=0; ntif_flags&TIFF_SWAB) - TIFFSwabLong((uint32*)m); - err=TIFFReadDirEntryCheckRangeSlongLong(*m); - if (err!=TIFFReadDirEntryErrOk) - { - _TIFFfree(origdata); - return(err); - } - m++; - } - *value=(int32*)origdata; - return(TIFFReadDirEntryErrOk); - } - case TIFF_SLONG: - *value=(int32*)origdata; - if (tif->tif_flags&TIFF_SWAB) - TIFFSwabArrayOfLong((uint32*)(*value),count); - return(TIFFReadDirEntryErrOk); - } - data=(int32*)_TIFFmalloc(count*4); - if (data==0) - { - _TIFFfree(origdata); - return(TIFFReadDirEntryErrAlloc); - } - switch (direntry->tdir_type) - { - case TIFF_BYTE: - { - uint8* ma; - int32* mb; - uint32 n; - ma=(uint8*)origdata; - mb=data; - for (n=0; ntif_flags&TIFF_SWAB) - TIFFSwabShort(ma); - *mb++=(int32)(*ma++); - } - } - break; - case TIFF_SSHORT: - { - int16* ma; - int32* mb; - uint32 n; - ma=(int16*)origdata; - mb=data; - for (n=0; ntif_flags&TIFF_SWAB) - TIFFSwabShort((uint16*)ma); - *mb++=(int32)(*ma++); - } - } - break; - case TIFF_LONG8: - { - uint64* ma; - int32* mb; - uint32 n; - ma=(uint64*)origdata; - mb=data; - for (n=0; ntif_flags&TIFF_SWAB) - TIFFSwabLong8(ma); - err=TIFFReadDirEntryCheckRangeSlongLong8(*ma); - if (err!=TIFFReadDirEntryErrOk) - break; - *mb++=(int32)(*ma++); - } - } - break; - case TIFF_SLONG8: - { - int64* ma; - int32* mb; - uint32 n; - ma=(int64*)origdata; - mb=data; - for (n=0; ntif_flags&TIFF_SWAB) - TIFFSwabLong8((uint64*)ma); - err=TIFFReadDirEntryCheckRangeSlongSlong8(*ma); - if (err!=TIFFReadDirEntryErrOk) - break; - *mb++=(int32)(*ma++); - } - } - break; - } - _TIFFfree(origdata); - if (err!=TIFFReadDirEntryErrOk) - { - _TIFFfree(data); - return(err); - } - *value=data; - return(TIFFReadDirEntryErrOk); -} - -static enum TIFFReadDirEntryErr TIFFReadDirEntryLong8Array(TIFF* tif, TIFFDirEntry* direntry, uint64** value) -{ - enum TIFFReadDirEntryErr err; - uint32 count; - void* origdata; - uint64* 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: - *value=(uint64*)origdata; - if (tif->tif_flags&TIFF_SWAB) - TIFFSwabArrayOfLong8(*value,count); - return(TIFFReadDirEntryErrOk); - case TIFF_SLONG8: - { - int64* m; - uint32 n; - m=(int64*)origdata; - for (n=0; ntif_flags&TIFF_SWAB) - TIFFSwabLong8((uint64*)m); - err=TIFFReadDirEntryCheckRangeLong8Slong8(*m); - if (err!=TIFFReadDirEntryErrOk) - { - _TIFFfree(origdata); - return(err); - } - m++; - } - *value=(uint64*)origdata; - return(TIFFReadDirEntryErrOk); - } - } - data=(uint64*)_TIFFmalloc(count*8); - if (data==0) - { - _TIFFfree(origdata); - return(TIFFReadDirEntryErrAlloc); - } - switch (direntry->tdir_type) - { - case TIFF_BYTE: - { - uint8* ma; - uint64* mb; - uint32 n; - ma=(uint8*)origdata; - mb=data; - for (n=0; ntif_flags&TIFF_SWAB) - TIFFSwabShort(ma); - *mb++=(uint64)(*ma++); - } - } - break; - case TIFF_SSHORT: - { - int16* ma; - uint64* mb; - uint32 n; - ma=(int16*)origdata; - mb=data; - for (n=0; ntif_flags&TIFF_SWAB) - TIFFSwabShort((uint16*)ma); - err=TIFFReadDirEntryCheckRangeLong8Sshort(*ma); - if (err!=TIFFReadDirEntryErrOk) - break; - *mb++=(uint64)(*ma++); - } - } - break; - case TIFF_LONG: - { - uint32* ma; - uint64* mb; - uint32 n; - ma=(uint32*)origdata; - mb=data; - for (n=0; ntif_flags&TIFF_SWAB) - TIFFSwabLong(ma); - *mb++=(uint64)(*ma++); - } - } - break; - case TIFF_SLONG: - { - int32* ma; - uint64* mb; - uint32 n; - ma=(int32*)origdata; - mb=data; - for (n=0; ntif_flags&TIFF_SWAB) - TIFFSwabLong((uint32*)ma); - err=TIFFReadDirEntryCheckRangeLong8Slong(*ma); - if (err!=TIFFReadDirEntryErrOk) - break; - *mb++=(uint64)(*ma++); - } - } - break; - } - _TIFFfree(origdata); - if (err!=TIFFReadDirEntryErrOk) - { - _TIFFfree(data); - return(err); - } - *value=data; - return(TIFFReadDirEntryErrOk); -} - -static enum TIFFReadDirEntryErr TIFFReadDirEntrySlong8Array(TIFF* tif, TIFFDirEntry* direntry, int64** value) -{ - enum TIFFReadDirEntryErr err; - uint32 count; - void* origdata; - int64* 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* m; - uint32 n; - m=(uint64*)origdata; - for (n=0; ntif_flags&TIFF_SWAB) - TIFFSwabLong8(m); - err=TIFFReadDirEntryCheckRangeSlong8Long8(*m); - if (err!=TIFFReadDirEntryErrOk) - { - _TIFFfree(origdata); - return(err); - } - m++; - } - *value=(int64*)origdata; - return(TIFFReadDirEntryErrOk); - } - case TIFF_SLONG8: - *value=(int64*)origdata; - if (tif->tif_flags&TIFF_SWAB) - TIFFSwabArrayOfLong8((uint64*)(*value),count); - return(TIFFReadDirEntryErrOk); - } - data=(int64*)_TIFFmalloc(count*8); - if (data==0) - { - _TIFFfree(origdata); - return(TIFFReadDirEntryErrAlloc); - } - switch (direntry->tdir_type) - { - case TIFF_BYTE: - { - uint8* ma; - int64* mb; - uint32 n; - ma=(uint8*)origdata; - mb=data; - for (n=0; ntif_flags&TIFF_SWAB) - TIFFSwabShort(ma); - *mb++=(int64)(*ma++); - } - } - break; - case TIFF_SSHORT: - { - int16* ma; - int64* mb; - uint32 n; - ma=(int16*)origdata; - mb=data; - for (n=0; ntif_flags&TIFF_SWAB) - TIFFSwabShort((uint16*)ma); - *mb++=(int64)(*ma++); - } - } - break; - case TIFF_LONG: - { - uint32* ma; - int64* mb; - uint32 n; - ma=(uint32*)origdata; - mb=data; - for (n=0; ntif_flags&TIFF_SWAB) - TIFFSwabLong(ma); - *mb++=(int64)(*ma++); - } - } - break; - case TIFF_SLONG: - { - int32* ma; - int64* mb; - uint32 n; - ma=(int32*)origdata; - mb=data; - for (n=0; ntif_flags&TIFF_SWAB) - TIFFSwabLong((uint32*)ma); - *mb++=(int64)(*ma++); - } - } - break; - } - _TIFFfree(origdata); - if (err!=TIFFReadDirEntryErrOk) - { - _TIFFfree(data); - return(err); - } - *value=data; - return(TIFFReadDirEntryErrOk); -} - -static enum TIFFReadDirEntryErr TIFFReadDirEntryFloatArray(TIFF* tif, TIFFDirEntry* direntry, float** value) -{ - enum TIFFReadDirEntryErr err; - uint32 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*)origdata,count); - TIFFCvtIEEEDoubleToNative(tif,count,(float*)origdata); - *value=(float*)origdata; - return(TIFFReadDirEntryErrOk); - } - data=(float*)_TIFFmalloc(count*sizeof(float)); - if (data==0) - { - _TIFFfree(origdata); - return(TIFFReadDirEntryErrAlloc); - } - switch (direntry->tdir_type) - { - case TIFF_BYTE: - { - uint8* ma; - float* mb; - uint32 n; - ma=(uint8*)origdata; - mb=data; - for (n=0; ntif_flags&TIFF_SWAB) - TIFFSwabShort(ma); - *mb++=(float)(*ma++); - } - } - break; - case TIFF_SSHORT: - { - int16* ma; - float* mb; - uint32 n; - ma=(int16*)origdata; - mb=data; - for (n=0; ntif_flags&TIFF_SWAB) - TIFFSwabShort((uint16*)ma); - *mb++=(float)(*ma++); - } - } - break; - case TIFF_LONG: - { - uint32* ma; - float* mb; - uint32 n; - ma=(uint32*)origdata; - mb=data; - for (n=0; ntif_flags&TIFF_SWAB) - TIFFSwabLong(ma); - *mb++=(float)(*ma++); - } - } - break; - case TIFF_SLONG: - { - int32* ma; - float* mb; - uint32 n; - ma=(int32*)origdata; - mb=data; - for (n=0; ntif_flags&TIFF_SWAB) - TIFFSwabLong((uint32*)ma); - *mb++=(float)(*ma++); - } - } - break; - case TIFF_LONG8: - { - uint64* ma; - float* mb; - uint32 n; - ma=(uint64*)origdata; - mb=data; - for (n=0; ntif_flags&TIFF_SWAB) - TIFFSwabLong8(ma); -#if defined(__WIN32__) && (_MSC_VER < 1500) - /* - * XXX: MSVC 6.0 does not support - * conversion of 64-bit integers into - * floating point values. - */ - *mb++ = _TIFFUInt64ToFloat(*ma++); -#else - *mb++ = (float)(*ma++); -#endif - } - } - break; - case TIFF_SLONG8: - { - int64* ma; - float* mb; - uint32 n; - ma=(int64*)origdata; - mb=data; - for (n=0; ntif_flags&TIFF_SWAB) - TIFFSwabLong8((uint64*)ma); - *mb++=(float)(*ma++); - } - } - break; - case TIFF_RATIONAL: - { - uint32* ma; - uint32 maa; - uint32 mab; - float* mb; - uint32 n; - ma=(uint32*)origdata; - mb=data; - for (n=0; ntif_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* ma; - int32 maa; - uint32 mab; - float* mb; - uint32 n; - ma=(uint32*)origdata; - mb=data; - for (n=0; ntif_flags&TIFF_SWAB) - TIFFSwabLong(ma); - maa=*(int32*)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 n; - if (tif->tif_flags&TIFF_SWAB) - TIFFSwabArrayOfLong8((uint64*)origdata,count); - TIFFCvtIEEEDoubleToNative(tif,count,(double*)origdata); - ma=(double*)origdata; - mb=data; - for (n=0; ntdir_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*)origdata,count); - TIFFCvtIEEEDoubleToNative(tif,count,(double*)origdata); - *value=(double*)origdata; - return(TIFFReadDirEntryErrOk); - } - data=(double*)_TIFFmalloc(count*sizeof(double)); - if (data==0) - { - _TIFFfree(origdata); - return(TIFFReadDirEntryErrAlloc); - } - switch (direntry->tdir_type) - { - case TIFF_BYTE: - { - uint8* ma; - double* mb; - uint32 n; - ma=(uint8*)origdata; - mb=data; - for (n=0; ntif_flags&TIFF_SWAB) - TIFFSwabShort(ma); - *mb++=(double)(*ma++); - } - } - break; - case TIFF_SSHORT: - { - int16* ma; - double* mb; - uint32 n; - ma=(int16*)origdata; - mb=data; - for (n=0; ntif_flags&TIFF_SWAB) - TIFFSwabShort((uint16*)ma); - *mb++=(double)(*ma++); - } - } - break; - case TIFF_LONG: - { - uint32* ma; - double* mb; - uint32 n; - ma=(uint32*)origdata; - mb=data; - for (n=0; ntif_flags&TIFF_SWAB) - TIFFSwabLong(ma); - *mb++=(double)(*ma++); - } - } - break; - case TIFF_SLONG: - { - int32* ma; - double* mb; - uint32 n; - ma=(int32*)origdata; - mb=data; - for (n=0; ntif_flags&TIFF_SWAB) - TIFFSwabLong((uint32*)ma); - *mb++=(double)(*ma++); - } - } - break; - case TIFF_LONG8: - { - uint64* ma; - double* mb; - uint32 n; - ma=(uint64*)origdata; - mb=data; - for (n=0; ntif_flags&TIFF_SWAB) - TIFFSwabLong8(ma); -#if defined(__WIN32__) && (_MSC_VER < 1500) - /* - * XXX: MSVC 6.0 does not support - * conversion of 64-bit integers into - * floating point values. - */ - *mb++ = _TIFFUInt64ToDouble(*ma++); -#else - *mb++ = (double)(*ma++); -#endif - } - } - break; - case TIFF_SLONG8: - { - int64* ma; - double* mb; - uint32 n; - ma=(int64*)origdata; - mb=data; - for (n=0; ntif_flags&TIFF_SWAB) - TIFFSwabLong8((uint64*)ma); - *mb++=(double)(*ma++); - } - } - break; - case TIFF_RATIONAL: - { - uint32* ma; - uint32 maa; - uint32 mab; - double* mb; - uint32 n; - ma=(uint32*)origdata; - mb=data; - for (n=0; ntif_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* ma; - int32 maa; - uint32 mab; - double* mb; - uint32 n; - ma=(uint32*)origdata; - mb=data; - for (n=0; ntif_flags&TIFF_SWAB) - TIFFSwabLong(ma); - maa=*(int32*)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 n; - if (tif->tif_flags&TIFF_SWAB) - TIFFSwabArrayOfLong((uint32*)origdata,count); - TIFFCvtIEEEFloatToNative(tif,count,(float*)origdata); - ma=(float*)origdata; - mb=data; - for (n=0; ntdir_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*)origdata; - if (tif->tif_flags&TIFF_SWAB) - TIFFSwabArrayOfLong8(*value,count); - return(TIFFReadDirEntryErrOk); - } - data=(uint64*)_TIFFmalloc(count*8); - if (data==0) - { - _TIFFfree(origdata); - return(TIFFReadDirEntryErrAlloc); - } - switch (direntry->tdir_type) - { - case TIFF_LONG: - case TIFF_IFD: - { - uint32* ma; - uint64* mb; - uint32 n; - ma=(uint32*)origdata; - mb=data; - for (n=0; ntif_flags&TIFF_SWAB) - TIFFSwabLong(ma); - *mb++=(uint64)(*ma++); - } - } - break; - } - _TIFFfree(origdata); - if (err!=TIFFReadDirEntryErrOk) - { - _TIFFfree(data); - return(err); - } - *value=data; - return(TIFFReadDirEntryErrOk); -} - -static enum TIFFReadDirEntryErr TIFFReadDirEntryPersampleShort(TIFF* tif, TIFFDirEntry* direntry, uint16* value) -{ - enum TIFFReadDirEntryErr err; - uint16* m; - uint16* na; - uint16 nb; - if (direntry->tdir_count<(uint64)tif->tif_dir.td_samplesperpixel) - return(TIFFReadDirEntryErrCount); - err=TIFFReadDirEntryShortArray(tif,direntry,&m); - if (err!=TIFFReadDirEntryErrOk) - return(err); - na=m; - nb=tif->tif_dir.td_samplesperpixel; - *value=*na++; - nb--; - while (nb>0) - { - if (*na++!=*value) - { - err=TIFFReadDirEntryErrPsdif; - break; - } - nb--; - } - _TIFFfree(m); - return(err); -} - -#if 0 -static enum TIFFReadDirEntryErr TIFFReadDirEntryPersampleDouble(TIFF* tif, TIFFDirEntry* direntry, double* value) -{ - enum TIFFReadDirEntryErr err; - double* m; - double* na; - uint16 nb; - if (direntry->tdir_count<(uint64)tif->tif_dir.td_samplesperpixel) - return(TIFFReadDirEntryErrCount); - err=TIFFReadDirEntryDoubleArray(tif,direntry,&m); - if (err!=TIFFReadDirEntryErrOk) - return(err); - na=m; - nb=tif->tif_dir.td_samplesperpixel; - *value=*na++; - nb--; - while (nb>0) - { - if (*na++!=*value) - { - err=TIFFReadDirEntryErrPsdif; - break; - } - nb--; - } - _TIFFfree(m); - return(err); -} -#endif - -static void TIFFReadDirEntryCheckedByte(TIFF* tif, TIFFDirEntry* direntry, uint8* value) -{ - (void) tif; - *value=*(uint8*)(&direntry->tdir_offset); -} - -static void TIFFReadDirEntryCheckedSbyte(TIFF* tif, TIFFDirEntry* direntry, int8* value) -{ - (void) tif; - *value=*(int8*)(&direntry->tdir_offset); -} - -static void TIFFReadDirEntryCheckedShort(TIFF* tif, TIFFDirEntry* direntry, uint16* value) -{ - *value = direntry->tdir_offset.toff_short; - /* *value=*(uint16*)(&direntry->tdir_offset); */ - if (tif->tif_flags&TIFF_SWAB) - TIFFSwabShort(value); -} - -static void TIFFReadDirEntryCheckedSshort(TIFF* tif, TIFFDirEntry* direntry, int16* value) -{ - *value=*(int16*)(&direntry->tdir_offset); - if (tif->tif_flags&TIFF_SWAB) - TIFFSwabShort((uint16*)value); -} - -static void TIFFReadDirEntryCheckedLong(TIFF* tif, TIFFDirEntry* direntry, uint32* value) -{ - *value=*(uint32*)(&direntry->tdir_offset); - if (tif->tif_flags&TIFF_SWAB) - TIFFSwabLong(value); -} - -static void TIFFReadDirEntryCheckedSlong(TIFF* tif, TIFFDirEntry* direntry, int32* value) -{ - *value=*(int32*)(&direntry->tdir_offset); - if (tif->tif_flags&TIFF_SWAB) - TIFFSwabLong((uint32*)value); -} - -static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckedLong8(TIFF* tif, TIFFDirEntry* direntry, uint64* value) -{ - if (!(tif->tif_flags&TIFF_BIGTIFF)) - { - enum TIFFReadDirEntryErr err; - uint32 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* value) -{ - if (!(tif->tif_flags&TIFF_BIGTIFF)) - { - enum TIFFReadDirEntryErr err; - uint32 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*)(&direntry->tdir_offset); - if (tif->tif_flags&TIFF_SWAB) - TIFFSwabLong8((uint64*)value); - return(TIFFReadDirEntryErrOk); -} - -static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckedRational(TIFF* tif, TIFFDirEntry* direntry, double* value) -{ - UInt64Aligned_t m; - - assert(sizeof(double)==8); - assert(sizeof(uint64)==8); - assert(sizeof(uint32)==4); - if (!(tif->tif_flags&TIFF_BIGTIFF)) - { - enum TIFFReadDirEntryErr err; - uint32 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); - if (m.i[0]==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)==8); - assert(sizeof(int32)==4); - assert(sizeof(uint32)==4); - if (!(tif->tif_flags&TIFF_BIGTIFF)) - { - enum TIFFReadDirEntryErr err; - uint32 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); - if ((int32)m.i[0]==0) - *value=0.0; - else - *value=(double)((int32)m.i[0])/(double)m.i[1]; - return(TIFFReadDirEntryErrOk); -} - -static void TIFFReadDirEntryCheckedFloat(TIFF* tif, TIFFDirEntry* direntry, float* value) -{ - union - { - float f; - uint32 i; - } float_union; - assert(sizeof(float)==4); - assert(sizeof(uint32)==4); - assert(sizeof(float_union)==4); - float_union.i=*(uint32*)(&direntry->tdir_offset); - *value=float_union.f; - if (tif->tif_flags&TIFF_SWAB) - TIFFSwabLong((uint32*)value); -} - -static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckedDouble(TIFF* tif, TIFFDirEntry* direntry, double* value) -{ - assert(sizeof(double)==8); - assert(sizeof(uint64)==8); - assert(sizeof(UInt64Aligned_t)==8); - if (!(tif->tif_flags&TIFF_BIGTIFF)) - { - enum TIFFReadDirEntryErr err; - uint32 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*)value); - return(TIFFReadDirEntryErrOk); -} - -static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckRangeByteSbyte(int8 value) -{ - if (value<0) - return(TIFFReadDirEntryErrRange); - else - return(TIFFReadDirEntryErrOk); -} - -static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckRangeByteShort(uint16 value) -{ - if (value>0xFF) - return(TIFFReadDirEntryErrRange); - else - return(TIFFReadDirEntryErrOk); -} - -static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckRangeByteSshort(int16 value) -{ - if ((value<0)||(value>0xFF)) - return(TIFFReadDirEntryErrRange); - else - return(TIFFReadDirEntryErrOk); -} - -static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckRangeByteLong(uint32 value) -{ - if (value>0xFF) - return(TIFFReadDirEntryErrRange); - else - return(TIFFReadDirEntryErrOk); -} - -static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckRangeByteSlong(int32 value) -{ - if ((value<0)||(value>0xFF)) - return(TIFFReadDirEntryErrRange); - else - return(TIFFReadDirEntryErrOk); -} - -static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckRangeByteLong8(uint64 value) -{ - if (value>0xFF) - return(TIFFReadDirEntryErrRange); - else - return(TIFFReadDirEntryErrOk); -} - -static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckRangeByteSlong8(int64 value) -{ - if ((value<0)||(value>0xFF)) - return(TIFFReadDirEntryErrRange); - else - return(TIFFReadDirEntryErrOk); -} - -static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckRangeSbyteByte(uint8 value) -{ - if (value>0x7F) - return(TIFFReadDirEntryErrRange); - else - return(TIFFReadDirEntryErrOk); -} - -static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckRangeSbyteShort(uint16 value) -{ - if (value>0x7F) - return(TIFFReadDirEntryErrRange); - else - return(TIFFReadDirEntryErrOk); -} - -static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckRangeSbyteSshort(int16 value) -{ - if ((value<-0x80)||(value>0x7F)) - return(TIFFReadDirEntryErrRange); - else - return(TIFFReadDirEntryErrOk); -} - -static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckRangeSbyteLong(uint32 value) -{ - if (value>0x7F) - return(TIFFReadDirEntryErrRange); - else - return(TIFFReadDirEntryErrOk); -} - -static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckRangeSbyteSlong(int32 value) -{ - if ((value<-0x80)||(value>0x7F)) - return(TIFFReadDirEntryErrRange); - else - return(TIFFReadDirEntryErrOk); -} - -static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckRangeSbyteLong8(uint64 value) -{ - if (value>0x7F) - return(TIFFReadDirEntryErrRange); - else - return(TIFFReadDirEntryErrOk); -} - -static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckRangeSbyteSlong8(int64 value) -{ - if ((value<-0x80)||(value>0x7F)) - return(TIFFReadDirEntryErrRange); - else - return(TIFFReadDirEntryErrOk); -} - -static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckRangeShortSbyte(int8 value) -{ - if (value<0) - return(TIFFReadDirEntryErrRange); - else - return(TIFFReadDirEntryErrOk); -} - -static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckRangeShortSshort(int16 value) -{ - if (value<0) - return(TIFFReadDirEntryErrRange); - else - return(TIFFReadDirEntryErrOk); -} - -static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckRangeShortLong(uint32 value) -{ - if (value>0xFFFF) - return(TIFFReadDirEntryErrRange); - else - return(TIFFReadDirEntryErrOk); -} - -static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckRangeShortSlong(int32 value) -{ - if ((value<0)||(value>0xFFFF)) - return(TIFFReadDirEntryErrRange); - else - return(TIFFReadDirEntryErrOk); -} - -static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckRangeShortLong8(uint64 value) -{ - if (value>0xFFFF) - return(TIFFReadDirEntryErrRange); - else - return(TIFFReadDirEntryErrOk); -} - -static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckRangeShortSlong8(int64 value) -{ - if ((value<0)||(value>0xFFFF)) - return(TIFFReadDirEntryErrRange); - else - return(TIFFReadDirEntryErrOk); -} - -static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckRangeSshortShort(uint16 value) -{ - if (value>0x7FFF) - return(TIFFReadDirEntryErrRange); - else - return(TIFFReadDirEntryErrOk); -} - -static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckRangeSshortLong(uint32 value) -{ - if (value>0x7FFF) - return(TIFFReadDirEntryErrRange); - else - return(TIFFReadDirEntryErrOk); -} - -static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckRangeSshortSlong(int32 value) -{ - if ((value<-0x8000)||(value>0x7FFF)) - return(TIFFReadDirEntryErrRange); - else - return(TIFFReadDirEntryErrOk); -} - -static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckRangeSshortLong8(uint64 value) -{ - if (value>0x7FFF) - return(TIFFReadDirEntryErrRange); - else - return(TIFFReadDirEntryErrOk); -} - -static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckRangeSshortSlong8(int64 value) -{ - if ((value<-0x8000)||(value>0x7FFF)) - return(TIFFReadDirEntryErrRange); - else - return(TIFFReadDirEntryErrOk); -} - -static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckRangeLongSbyte(int8 value) -{ - if (value<0) - return(TIFFReadDirEntryErrRange); - else - return(TIFFReadDirEntryErrOk); -} - -static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckRangeLongSshort(int16 value) -{ - if (value<0) - return(TIFFReadDirEntryErrRange); - else - return(TIFFReadDirEntryErrOk); -} - -static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckRangeLongSlong(int32 value) -{ - if (value<0) - return(TIFFReadDirEntryErrRange); - else - return(TIFFReadDirEntryErrOk); -} - -/* - * Largest 32-bit unsigned integer value. - */ -#if defined(__WIN32__) && defined(_MSC_VER) -# define TIFF_UINT32_MAX 0xFFFFFFFFI64 -#else -# define TIFF_UINT32_MAX 0xFFFFFFFFLL -#endif - -static enum TIFFReadDirEntryErr -TIFFReadDirEntryCheckRangeLongLong8(uint64 value) -{ - if (value > TIFF_UINT32_MAX) - return(TIFFReadDirEntryErrRange); - else - return(TIFFReadDirEntryErrOk); -} - -static enum TIFFReadDirEntryErr -TIFFReadDirEntryCheckRangeLongSlong8(int64 value) -{ - if ((value<0) || (value > TIFF_UINT32_MAX)) - return(TIFFReadDirEntryErrRange); - else - return(TIFFReadDirEntryErrOk); -} - -#undef TIFF_UINT32_MAX - -static enum TIFFReadDirEntryErr -TIFFReadDirEntryCheckRangeSlongLong(uint32 value) -{ - if (value > 0x7FFFFFFFUL) - return(TIFFReadDirEntryErrRange); - else - return(TIFFReadDirEntryErrOk); -} - -static enum TIFFReadDirEntryErr -TIFFReadDirEntryCheckRangeSlongLong8(uint64 value) -{ - if (value > 0x7FFFFFFFUL) - return(TIFFReadDirEntryErrRange); - else - return(TIFFReadDirEntryErrOk); -} - -static enum TIFFReadDirEntryErr -TIFFReadDirEntryCheckRangeSlongSlong8(int64 value) -{ - if ((value < 0L-0x80000000L) || (value > 0x7FFFFFFFL)) - return(TIFFReadDirEntryErrRange); - else - return(TIFFReadDirEntryErrOk); -} - -static enum TIFFReadDirEntryErr -TIFFReadDirEntryCheckRangeLong8Sbyte(int8 value) -{ - if (value < 0) - return(TIFFReadDirEntryErrRange); - else - return(TIFFReadDirEntryErrOk); -} - -static enum TIFFReadDirEntryErr -TIFFReadDirEntryCheckRangeLong8Sshort(int16 value) -{ - if (value < 0) - return(TIFFReadDirEntryErrRange); - else - return(TIFFReadDirEntryErrOk); -} - -static enum TIFFReadDirEntryErr -TIFFReadDirEntryCheckRangeLong8Slong(int32 value) -{ - if (value < 0) - return(TIFFReadDirEntryErrRange); - else - return(TIFFReadDirEntryErrOk); -} - -static enum TIFFReadDirEntryErr -TIFFReadDirEntryCheckRangeLong8Slong8(int64 value) -{ - if (value < 0) - return(TIFFReadDirEntryErrRange); - else - return(TIFFReadDirEntryErrOk); -} - -/* - * Largest 64-bit signed integer value. - */ -#if defined(__WIN32__) && defined(_MSC_VER) -# define TIFF_INT64_MAX 0x7FFFFFFFFFFFFFFFI64 -#else -# define TIFF_INT64_MAX 0x7FFFFFFFFFFFFFFFLL -#endif - -static enum TIFFReadDirEntryErr -TIFFReadDirEntryCheckRangeSlong8Long8(uint64 value) -{ - if (value > TIFF_INT64_MAX) - return(TIFFReadDirEntryErrRange); - else - return(TIFFReadDirEntryErrOk); -} - -#undef TIFF_INT64_MAX - -static enum TIFFReadDirEntryErr -TIFFReadDirEntryData(TIFF* tif, uint64 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; - mb=ma+size; - if (((uint64)ma!=offset) - || (mb < ma) - || (mb - ma != (size_t) size) - || (mb < (size_t)size) - || (mb > (size_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: - TIFFErrorExt(tif->tif_clientdata, module, - "Incorrect count for \"%s\"", - tagname); - break; - case TIFFReadDirEntryErrType: - TIFFErrorExt(tif->tif_clientdata, module, - "Incompatible type for \"%s\"", - tagname); - break; - case TIFFReadDirEntryErrIo: - TIFFErrorExt(tif->tif_clientdata, module, - "IO error during reading of \"%s\"", - tagname); - break; - case TIFFReadDirEntryErrRange: - TIFFErrorExt(tif->tif_clientdata, module, - "Incorrect value for \"%s\"", - tagname); - break; - case TIFFReadDirEntryErrPsdif: - TIFFErrorExt(tif->tif_clientdata, module, - "Cannot handle different values per sample for \"%s\"", - tagname); - break; - case TIFFReadDirEntryErrSizesan: - TIFFErrorExt(tif->tif_clientdata, module, - "Sanity check on size of \"%s\" value failed", - tagname); - break; - case TIFFReadDirEntryErrAlloc: - TIFFErrorExt(tif->tif_clientdata, module, - "Out of memory reading of \"%s\"", - tagname); - break; - default: - assert(0); /* we should never get here */ - break; - } - } else { - switch (err) { - case TIFFReadDirEntryErrCount: - TIFFWarningExt(tif->tif_clientdata, module, - "Incorrect count for \"%s\"; tag ignored", - tagname); - break; - case TIFFReadDirEntryErrType: - TIFFWarningExt(tif->tif_clientdata, module, - "Incompatible type for \"%s\"; tag ignored", - tagname); - break; - case TIFFReadDirEntryErrIo: - TIFFWarningExt(tif->tif_clientdata, module, - "IO error during reading of \"%s\"; tag ignored", - tagname); - break; - case TIFFReadDirEntryErrRange: - TIFFWarningExt(tif->tif_clientdata, module, - "Incorrect value for \"%s\"; tag ignored", - tagname); - break; - case TIFFReadDirEntryErrPsdif: - TIFFWarningExt(tif->tif_clientdata, module, - "Cannot handle different values per sample for \"%s\"; tag ignored", - tagname); - break; - case TIFFReadDirEntryErrSizesan: - TIFFWarningExt(tif->tif_clientdata, module, - "Sanity check on size of \"%s\" value failed; tag ignored", - tagname); - break; - case TIFFReadDirEntryErrAlloc: - TIFFWarningExt(tif->tif_clientdata, module, - "Out of memory reading of \"%s\"; tag ignored", - tagname); - break; - default: - assert(0); /* we should never get here */ - break; - } - } -} - -/* - * 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 dircount; - TIFFDirEntry* dp; - uint16 di; - const TIFFField* fip; - uint32 fii=FAILED_FII; - toff_t nextdiroff; - int bitspersample_read = FALSE; - - tif->tif_diroff=tif->tif_nextdiroff; - if (!TIFFCheckDirOffset(tif,tif->tif_nextdiroff)) - return 0; /* last offset or bad offset (IFD looping) */ - (*tif->tif_cleanup)(tif); /* cleanup any previous compression state */ - tif->tif_curdir++; - nextdiroff = tif->tif_nextdiroff; - dircount=TIFFFetchDirectory(tif,nextdiroff,&dir,&tif->tif_nextdiroff); - if (!dircount) - { - TIFFErrorExt(tif->tif_clientdata,module, - "Failed to read directory at offset " TIFF_UINT64_FORMAT,nextdiroff); - return 0; - } - TIFFReadDirectoryCheckOrder(tif,dir,dircount); - - /* - * Mark duplicates of any tag to be ignored (bugzilla 1994) - * to avoid certain pathological problems. - */ - { - TIFFDirEntry* ma; - uint16 mb; - for (ma=dir, mb=0; mbtdir_tag==na->tdir_tag) - na->tdir_tag=IGNORE; - } - } - } - - tif->tif_flags &= ~TIFF_BEENWRITING; /* reset before new dir */ - tif->tif_flags &= ~TIFF_BUF4WRITE; /* reset before new dir */ - /* free any old stuff and reinit */ - TIFFFreeDirectory(tif); - TIFFDefaultDirectory(tif); - /* - * 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. - */ - 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 everthing 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 permited 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_tag=IGNORE; - } - 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 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_tag=IGNORE; - } - else - { - if (!TIFFSetField(tif,TIFFTAG_COMPRESSION,COMPRESSION_NONE)) - goto bad; - } - /* - * First real pass over the directory. - */ - for (di=0, dp=dir; ditdir_tag!=IGNORE) - { - TIFFReadDirectoryFindFieldInfo(tif,dp->tdir_tag,&fii); - if (fii == FAILED_FII) - { - TIFFWarningExt(tif->tif_clientdata, module, - "Unknown field with tag %d (0x%x) encountered", - dp->tdir_tag,dp->tdir_tag); - /* the following knowingly leaks the - anonymous field structure */ - if (!_TIFFMergeFields(tif, - _TIFFCreateAnonField(tif, - dp->tdir_tag, - (TIFFDataType) dp->tdir_type), - 1)) { - TIFFWarningExt(tif->tif_clientdata, - module, - "Registering anonymous field with tag %d (0x%x) failed", - dp->tdir_tag, - dp->tdir_tag); - dp->tdir_tag=IGNORE; - } else { - TIFFReadDirectoryFindFieldInfo(tif,dp->tdir_tag,&fii); - assert(fii != FAILED_FII); - } - } - } - if (dp->tdir_tag!=IGNORE) - { - fip=tif->tif_fields[fii]; - if (fip->field_bit==FIELD_IGNORE) - dp->tdir_tag=IGNORE; - 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_tag=IGNORE; - 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; - TIFFWarningExt(tif->tif_clientdata,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; - } - /* - * Setup appropriate structures (by strip or by tile) - */ - 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) { - TIFFErrorExt(tif->tif_clientdata, module, - "Cannot handle zero number of %s", - 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)) { - 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 { - MissingRequired(tif, - isTiled(tif) ? "TileOffsets" : "StripOffsets"); - goto bad; - } - } - /* - * Second pass: extract other information. - */ - for (di=0, dp=dir; ditdir_tag) - { - case IGNORE: - break; - 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 (yech). Other vendors write correct - * value for NumberOfSamples, but incorrect one for - * BitsPerSample and friends, and we will read this - * too. - */ - { - uint16 value; - enum TIFFReadDirEntryErr err; - err=TIFFReadDirEntryShort(tif,dp,&value); - 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; - enum TIFFReadDirEntryErr err; - uint32 saved_flags; - int m; - if (dp->tdir_count != (uint64)tif->tif_dir.td_samplesperpixel) - err = TIFFReadDirEntryErrCount; - else - err = TIFFReadDirEntryDoubleArray(tif, dp, &data); - 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; - _TIFFfree(data); - if (!m) - goto bad; - } - break; - case TIFFTAG_STRIPOFFSETS: - case TIFFTAG_TILEOFFSETS: -#if defined(DEFER_STRILE_LOAD) - _TIFFmemcpy( &(tif->tif_dir.td_stripoffset_entry), - dp, sizeof(TIFFDirEntry) ); -#else - if (!TIFFFetchStripThing(tif,dp,tif->tif_dir.td_nstrips,&tif->tif_dir.td_stripoffset)) - goto bad; -#endif - break; - case TIFFTAG_STRIPBYTECOUNTS: - case TIFFTAG_TILEBYTECOUNTS: -#if defined(DEFER_STRILE_LOAD) - _TIFFmemcpy( &(tif->tif_dir.td_stripbytecount_entry), - dp, sizeof(TIFFDirEntry) ); -#else - if (!TIFFFetchStripThing(tif,dp,tif->tif_dir.td_nstrips,&tif->tif_dir.td_stripbytecount)) - goto bad; -#endif - break; - case TIFFTAG_COLORMAP: - case TIFFTAG_TRANSFERFUNCTION: - { - enum TIFFReadDirEntryErr err; - uint32 countpersample; - uint32 countrequired; - uint32 incrementpersample; - uint16* value=NULL; - /* It would be dangerous to instanciate 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); - TIFFWarningExt(tif->tif_clientdata,module, - "Ignoring %s since BitsPerSample tag not found", - fip ? fip->field_name : "unknown tagname"); - continue; - } - countpersample=(1L<tif_dir.td_bitspersample); - if ((dp->tdir_tag==TIFFTAG_TRANSFERFUNCTION)&&(dp->tdir_count==(uint64)countpersample)) - { - countrequired=countpersample; - incrementpersample=0; - } - else - { - countrequired=3*countpersample; - incrementpersample=countpersample; - } - if (dp->tdir_count!=(uint64)countrequired) - err=TIFFReadDirEntryErrCount; - else - err=TIFFReadDirEntryShortArray(tif,dp,&value); - 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); - _TIFFfree(value); - } - } - break; -/* BEGIN REV 4.0 COMPATIBILITY */ - case TIFFTAG_OSUBFILETYPE: - { - uint16 valueo; - uint32 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 */ - default: - (void) TIFFFetchNormalTag(tif, dp, TRUE); - break; - } - } - /* - * 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)) - { - TIFFWarningExt(tif->tif_clientdata, 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; - TIFFWarningExt(tif->tif_clientdata, module, - "Photometric tag value assumed incorrect, " - "assuming data is YCbCr instead of RGB"); - } - if (!TIFFFieldSet(tif,FIELD_BITSPERSAMPLE)) - { - TIFFWarningExt(tif->tif_clientdata,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) - { - TIFFWarningExt(tif->tif_clientdata,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) - { - TIFFWarningExt(tif->tif_clientdata,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; - } - } - } - /* - * 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)tif->tif_dir.td_samplesperpixel)) { - MissingRequired(tif, "StripByteCounts"); - goto bad; - } - TIFFWarningExt(tif->tif_clientdata, module, - "TIFF directory is missing required " - "\"StripByteCounts\" field, calculating from imagelength"); - if (EstimateStripByteCounts(tif, dir, dircount) < 0) - goto bad; - /* - * 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. - */ - #define BYTECOUNTLOOKSBAD \ - ( (tif->tif_dir.td_stripbytecount[0] == 0 && tif->tif_dir.td_stripoffset[0] != 0) || \ - (tif->tif_dir.td_compression == COMPRESSION_NONE && \ - tif->tif_dir.td_stripbytecount[0] > TIFFGetFileSize(tif) - tif->tif_dir.td_stripoffset[0]) || \ - (tif->tif_mode == O_RDONLY && \ - tif->tif_dir.td_compression == COMPRESSION_NONE && \ - tif->tif_dir.td_stripbytecount[0] < TIFFScanlineSize64(tif) * tif->tif_dir.td_imagelength) ) - - } else if (tif->tif_dir.td_nstrips == 1 - && _TIFFFillStriles(tif) - && tif->tif_dir.td_stripoffset[0] != 0 - && BYTECOUNTLOOKSBAD) { - /* - * 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. - */ - TIFFWarningExt(tif->tif_clientdata, module, - "Bogus \"StripByteCounts\" field, ignoring and calculating from imagelength"); - if(EstimateStripByteCounts(tif, dir, dircount) < 0) - goto bad; - -#if !defined(DEFER_STRILE_LOAD) - } else if (tif->tif_dir.td_planarconfig == PLANARCONFIG_CONTIG - && tif->tif_dir.td_nstrips > 2 - && tif->tif_dir.td_compression == COMPRESSION_NONE - && tif->tif_dir.td_stripbytecount[0] != tif->tif_dir.td_stripbytecount[1] - && tif->tif_dir.td_stripbytecount[0] != 0 - && tif->tif_dir.td_stripbytecount[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. - */ - TIFFWarningExt(tif->tif_clientdata, module, - "Wrong \"StripByteCounts\" field, ignoring and calculating from imagelength"); - if (EstimateStripByteCounts(tif, dir, dircount) < 0) - goto bad; -#endif /* !defined(DEFER_STRILE_LOAD) */ - } - } - if (dir) - { - _TIFFfree(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)((1L<tif_dir.td_bitspersample)-1); - } - /* - * 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 !defined(DEFER_STRILE_LOAD) - if (tif->tif_dir.td_nstrips > 1) { - uint32 strip; - - tif->tif_dir.td_stripbytecountsorted = 1; - for (strip = 1; strip < tif->tif_dir.td_nstrips; strip++) { - if (tif->tif_dir.td_stripoffset[strip - 1] > - tif->tif_dir.td_stripoffset[strip]) { - tif->tif_dir.td_stripbytecountsorted = 0; - break; - } - } - } -#endif /* !defined(DEFER_STRILE_LOAD) */ - - /* - * 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)) - { - if ( !_TIFFFillStriles(tif) || !tif->tif_dir.td_stripbytecount ) - return 0; - ChopUpSingleUncompressedStrip(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) -1; - tif->tif_curstrip = (uint32) -1; - tif->tif_col = (uint32) -1; - tif->tif_curtile = (uint32) -1; - tif->tif_tilesize = (tmsize_t) -1; - - tif->tif_scanlinesize = TIFFScanlineSize(tif); - if (!tif->tif_scanlinesize) { - TIFFErrorExt(tif->tif_clientdata, module, - "Cannot handle zero scanline size"); - return (0); - } - - if (isTiled(tif)) { - tif->tif_tilesize = TIFFTileSize(tif); - if (!tif->tif_tilesize) { - TIFFErrorExt(tif->tif_clientdata, module, - "Cannot handle zero tile size"); - return (0); - } - } else { - if (!TIFFStripSize(tif)) { - TIFFErrorExt(tif->tif_clientdata, module, - "Cannot handle zero strip size"); - return (0); - } - } - return (1); -bad: - if (dir) - _TIFFfree(dir); - return (0); -} - -static void -TIFFReadDirectoryCheckOrder(TIFF* tif, TIFFDirEntry* dir, uint16 dircount) -{ - static const char module[] = "TIFFReadDirectoryCheckOrder"; - uint16 m; - uint16 n; - TIFFDirEntry* o; - m=0; - for (n=0, o=dir; ntdir_tagtif_clientdata,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 dircount, uint16 tagid) -{ - TIFFDirEntry* m; - uint16 n; - (void) tif; - for (m=dir, n=0; ntdir_tag==tagid) - return(m); - } - return(0); -} - -static void -TIFFReadDirectoryFindFieldInfo(TIFF* tif, uint16 tagid, uint32* fii) -{ - int32 ma,mb,mc; - ma=-1; - mc=(int32)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)tagid) - break; - if (tif->tif_fields[mb]->field_tag<(uint32)tagid) - ma=mb; - else - mc=mb; - } - while (1) - { - if (mb==0) - break; - if (tif->tif_fields[mb-1]->field_tag!=(uint32)tagid) - break; - mb--; - } - *fii=mb; -} - -/* - * Read custom directory from the arbitarry 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 dircount; - TIFFDirEntry* dp; - uint16 di; - const TIFFField* fip; - uint32 fii; - _TIFFSetupFields(tif, infoarray); - dircount=TIFFFetchDirectory(tif,diroff,&dir,NULL); - if (!dircount) - { - TIFFErrorExt(tif->tif_clientdata,module, - "Failed to read custom directory at offset " TIFF_UINT64_FORMAT,diroff); - return 0; - } - TIFFFreeDirectory(tif); - _TIFFmemset(&tif->tif_dir, 0, sizeof(TIFFDirectory)); - TIFFReadDirectoryCheckOrder(tif,dir,dircount); - for (di=0, dp=dir; ditdir_tag,&fii); - if (fii == FAILED_FII) - { - TIFFWarningExt(tif->tif_clientdata, module, - "Unknown field with tag %d (0x%x) encountered", - dp->tdir_tag, dp->tdir_tag); - if (!_TIFFMergeFields(tif, _TIFFCreateAnonField(tif, - dp->tdir_tag, - (TIFFDataType) dp->tdir_type), - 1)) { - TIFFWarningExt(tif->tif_clientdata, module, - "Registering anonymous field with tag %d (0x%x) failed", - dp->tdir_tag, dp->tdir_tag); - dp->tdir_tag=IGNORE; - } else { - TIFFReadDirectoryFindFieldInfo(tif,dp->tdir_tag,&fii); - assert( fii != FAILED_FII ); - } - } - if (dp->tdir_tag!=IGNORE) - { - fip=tif->tif_fields[fii]; - if (fip->field_bit==FIELD_IGNORE) - dp->tdir_tag=IGNORE; - 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)dp->tdir_tag)) - { - fii=0xFFFF; - break; - } - fip=tif->tif_fields[fii]; - } - if (fii==0xFFFF) - { - TIFFWarningExt(tif->tif_clientdata, module, - "Wrong data type %d for \"%s\"; tag ignored", - dp->tdir_type,fip->field_name); - dp->tdir_tag=IGNORE; - } - else - { - /* check count if known in advance */ - if ((fip->field_readcount!=TIFF_VARIABLE)&& - (fip->field_readcount!=TIFF_VARIABLE2)) - { - uint32 expected; - if (fip->field_readcount==TIFF_SPP) - expected=(uint32)tif->tif_dir.td_samplesperpixel; - else - expected=(uint32)fip->field_readcount; - if (!CheckDirCount(tif,dp,expected)) - dp->tdir_tag=IGNORE; - } - } - } - switch (dp->tdir_tag) - { - case IGNORE: - break; - case EXIFTAG_SUBJECTDISTANCE: - (void) TIFFFetchSubjectDistance(tif,dp); - break; - default: - (void) TIFFFetchNormalTag(tif, dp, TRUE); - break; - } - } - } - if (dir) - _TIFFfree(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) -{ - const TIFFFieldArray* exifFieldArray; - exifFieldArray = _TIFFGetExifFields(); - return TIFFReadCustomDirectory(tif, diroff, exifFieldArray); -} - -static int -EstimateStripByteCounts(TIFF* tif, TIFFDirEntry* dir, uint16 dircount) -{ - static const char module[] = "EstimateStripByteCounts"; - - TIFFDirEntry *dp; - TIFFDirectory *td = &tif->tif_dir; - uint32 strip; - - if( !_TIFFFillStriles( tif ) ) - return -1; - - if (td->td_stripbytecount) - _TIFFfree(td->td_stripbytecount); - td->td_stripbytecount = (uint64*) - _TIFFCheckMalloc(tif, td->td_nstrips, sizeof (uint64), - "for \"StripByteCounts\" array"); - if( td->td_stripbytecount == NULL ) - return -1; - - if (td->td_compression != COMPRESSION_NONE) { - uint64 space; - uint64 filesize; - uint16 n; - filesize = TIFFGetFileSize(tif); - 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 typewidth = TIFFDataWidth((TIFFDataType) dp->tdir_type); - uint64 datasize; - typewidth = TIFFDataWidth((TIFFDataType) dp->tdir_type); - if (typewidth == 0) { - TIFFErrorExt(tif->tif_clientdata, module, - "Cannot determine size of unknown tag type %d", - dp->tdir_type); - return -1; - } - datasize=(uint64)typewidth*dp->tdir_count; - if (!(tif->tif_flags&TIFF_BIGTIFF)) - { - if (datasize<=4) - datasize=0; - } - else - { - if (datasize<=8) - datasize=0; - } - space+=datasize; - } - space = filesize - space; - if (td->td_planarconfig == PLANARCONFIG_SEPARATE) - space /= td->td_samplesperpixel; - for (strip = 0; strip < td->td_nstrips; strip++) - td->td_stripbytecount[strip] = space; - /* - * This gross hack handles the case were the offset to - * the last strip is past the place where we think the strip - * should begin. Since a strip of data must be contiguous, - * it's safe to assume that we've overestimated the amount - * of data in the strip and trim this number back accordingly. - */ - strip--; - if (td->td_stripoffset[strip]+td->td_stripbytecount[strip] > filesize) - td->td_stripbytecount[strip] = filesize - td->td_stripoffset[strip]; - } else if (isTiled(tif)) { - uint64 bytespertile = TIFFTileSize64(tif); - - for (strip = 0; strip < td->td_nstrips; strip++) - td->td_stripbytecount[strip] = bytespertile; - } else { - uint64 rowbytes = TIFFScanlineSize64(tif); - uint32 rowsperstrip = td->td_imagelength/td->td_stripsperimage; - for (strip = 0; strip < td->td_nstrips; strip++) - td->td_stripbytecount[strip] = rowbytes * rowsperstrip; - } - TIFFSetFieldBit(tif, FIELD_STRIPBYTECOUNTS); - if (!TIFFFieldSet(tif, FIELD_ROWSPERSTRIP)) - td->td_rowsperstrip = td->td_imagelength; - return 1; -} - -static void -MissingRequired(TIFF* tif, const char* tagname) -{ - static const char module[] = "MissingRequired"; - - TIFFErrorExt(tif->tif_clientdata, module, - "TIFF directory is missing required \"%s\" field", - tagname); -} - -/* - * Check the directory offset against the list of already seen directory - * 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 against that list. - */ -static int -TIFFCheckDirOffset(TIFF* tif, uint64 diroff) -{ - uint16 n; - - if (diroff == 0) /* no more directories */ - return 0; - if (tif->tif_dirnumber == 65535) { - TIFFErrorExt(tif->tif_clientdata, "TIFFCheckDirOffset", - "Cannot handle more than 65535 TIFF directories"); - return 0; - } - - for (n = 0; n < tif->tif_dirnumber && tif->tif_dirlist; n++) { - if (tif->tif_dirlist[n] == diroff) - return 0; - } - - tif->tif_dirnumber++; - - if (tif->tif_dirnumber > tif->tif_dirlistsize) { - uint64* new_dirlist; - - /* - * XXX: Reduce memory allocation granularity of the dirlist - * array. - */ - new_dirlist = (uint64*)_TIFFCheckRealloc(tif, tif->tif_dirlist, - tif->tif_dirnumber, 2 * sizeof(uint64), "for IFD list"); - if (!new_dirlist) - return 0; - if( tif->tif_dirnumber >= 32768 ) - tif->tif_dirlistsize = 65535; - else - tif->tif_dirlistsize = 2 * tif->tif_dirnumber; - tif->tif_dirlist = new_dirlist; - } - - tif->tif_dirlist[tif->tif_dirnumber - 1] = diroff; - - return 1; -} - -/* - * 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 count) -{ - if ((uint64)count > dir->tdir_count) { - const TIFFField* fip = TIFFFieldWithTag(tif, dir->tdir_tag); - TIFFWarningExt(tif->tif_clientdata, tif->tif_name, - "incorrect count for field \"%s\" (" TIFF_UINT64_FORMAT ", expecting %u); tag ignored", - fip ? fip->field_name : "unknown tagname", - dir->tdir_count, count); - return (0); - } else if ((uint64)count < dir->tdir_count) { - const TIFFField* fip = TIFFFieldWithTag(tif, dir->tdir_tag); - TIFFWarningExt(tif->tif_clientdata, tif->tif_name, - "incorrect count for field \"%s\" (" TIFF_UINT64_FORMAT ", expecting %u); 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 -TIFFFetchDirectory(TIFF* tif, uint64 diroff, TIFFDirEntry** pdir, - uint64 *nextdiroff) -{ - static const char module[] = "TIFFFetchDirectory"; - - void* origdir; - uint16 dircount16; - uint32 dirsize; - TIFFDirEntry* dir; - uint8* ma; - TIFFDirEntry* mb; - uint16 n; - - assert(pdir); - - tif->tif_diroff = diroff; - if (nextdiroff) - *nextdiroff = 0; - if (!isMapped(tif)) { - if (!SeekOK(tif, tif->tif_diroff)) { - TIFFErrorExt(tif->tif_clientdata, module, - "%s: Seek error accessing TIFF directory", - tif->tif_name); - return 0; - } - if (!(tif->tif_flags&TIFF_BIGTIFF)) - { - if (!ReadOK(tif, &dircount16, sizeof (uint16))) { - TIFFErrorExt(tif->tif_clientdata, module, - "%s: Can not read TIFF directory count", - tif->tif_name); - return 0; - } - if (tif->tif_flags & TIFF_SWAB) - TIFFSwabShort(&dircount16); - if (dircount16>4096) - { - TIFFErrorExt(tif->tif_clientdata, module, - "Sanity check on directory count failed, this is probably not a valid IFD offset"); - return 0; - } - dirsize = 12; - } else { - uint64 dircount64; - if (!ReadOK(tif, &dircount64, sizeof (uint64))) { - TIFFErrorExt(tif->tif_clientdata, module, - "%s: Can not read TIFF directory count", - tif->tif_name); - return 0; - } - if (tif->tif_flags & TIFF_SWAB) - TIFFSwabLong8(&dircount64); - if (dircount64>4096) - { - TIFFErrorExt(tif->tif_clientdata, module, - "Sanity check on directory count failed, this is probably not a valid IFD offset"); - return 0; - } - dircount16 = (uint16)dircount64; - dirsize = 20; - } - origdir = _TIFFCheckMalloc(tif, dircount16, - dirsize, "to read TIFF directory"); - if (origdir == NULL) - return 0; - if (!ReadOK(tif, origdir, (tmsize_t)(dircount16*dirsize))) { - TIFFErrorExt(tif->tif_clientdata, module, - "%.100s: Can not read TIFF directory", - tif->tif_name); - _TIFFfree(origdir); - return 0; - } - /* - * Read offset to next directory for sequential scans if - * needed. - */ - if (nextdiroff) - { - if (!(tif->tif_flags&TIFF_BIGTIFF)) - { - uint32 nextdiroff32; - if (!ReadOK(tif, &nextdiroff32, sizeof(uint32))) - nextdiroff32 = 0; - if (tif->tif_flags&TIFF_SWAB) - TIFFSwabLong(&nextdiroff32); - *nextdiroff=nextdiroff32; - } else { - if (!ReadOK(tif, nextdiroff, sizeof(uint64))) - *nextdiroff = 0; - if (tif->tif_flags&TIFF_SWAB) - TIFFSwabLong8(nextdiroff); - } - } - } else { - tmsize_t m; - tmsize_t off = (tmsize_t) tif->tif_diroff; - if ((uint64)off!=tif->tif_diroff) - { - TIFFErrorExt(tif->tif_clientdata,module,"Can not read TIFF directory count"); - return(0); - } - - /* - * 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) > tif->tif_size - * - * to avoid overflow. - */ - if (!(tif->tif_flags&TIFF_BIGTIFF)) - { - m=off+sizeof(uint16); - if ((mtif->tif_size)) { - TIFFErrorExt(tif->tif_clientdata, module, - "Can not read TIFF directory count"); - return 0; - } else { - _TIFFmemcpy(&dircount16, tif->tif_base + off, - sizeof(uint16)); - } - off += sizeof (uint16); - if (tif->tif_flags & TIFF_SWAB) - TIFFSwabShort(&dircount16); - if (dircount16>4096) - { - TIFFErrorExt(tif->tif_clientdata, module, - "Sanity check on directory count failed, this is probably not a valid IFD offset"); - return 0; - } - dirsize = 12; - } - else - { - tmsize_t m; - uint64 dircount64; - m=off+sizeof(uint64); - if ((mtif->tif_size)) { - TIFFErrorExt(tif->tif_clientdata, module, - "Can not read TIFF directory count"); - return 0; - } else { - _TIFFmemcpy(&dircount64, tif->tif_base + off, - sizeof(uint64)); - } - off += sizeof (uint64); - if (tif->tif_flags & TIFF_SWAB) - TIFFSwabLong8(&dircount64); - if (dircount64>4096) - { - TIFFErrorExt(tif->tif_clientdata, module, - "Sanity check on directory count failed, this is probably not a valid IFD offset"); - return 0; - } - dircount16 = (uint16)dircount64; - dirsize = 20; - } - if (dircount16 == 0 ) - { - TIFFErrorExt(tif->tif_clientdata, module, - "Sanity check on directory count failed, zero tag directories not supported"); - return 0; - } - origdir = _TIFFCheckMalloc(tif, dircount16, - dirsize, - "to read TIFF directory"); - if (origdir == NULL) - return 0; - m=off+dircount16*dirsize; - if ((mtif->tif_size)) { - TIFFErrorExt(tif->tif_clientdata, module, - "Can not read TIFF directory"); - _TIFFfree(origdir); - return 0; - } else { - _TIFFmemcpy(origdir, tif->tif_base + off, - dircount16 * dirsize); - } - if (nextdiroff) { - off += dircount16 * dirsize; - if (!(tif->tif_flags&TIFF_BIGTIFF)) - { - uint32 nextdiroff32; - m=off+sizeof(uint32); - if ((mtif->tif_size)) - nextdiroff32 = 0; - else - _TIFFmemcpy(&nextdiroff32, tif->tif_base + off, - sizeof (uint32)); - if (tif->tif_flags&TIFF_SWAB) - TIFFSwabLong(&nextdiroff32); - *nextdiroff = nextdiroff32; - } - else - { - m=off+sizeof(uint64); - if ((mtif->tif_size)) - *nextdiroff = 0; - else - _TIFFmemcpy(nextdiroff, tif->tif_base + off, - sizeof (uint64)); - if (tif->tif_flags&TIFF_SWAB) - TIFFSwabLong8(nextdiroff); - } - } - } - dir = (TIFFDirEntry*)_TIFFCheckMalloc(tif, dircount16, - sizeof(TIFFDirEntry), - "to read TIFF directory"); - if (dir==0) - { - _TIFFfree(origdir); - return 0; - } - ma=(uint8*)origdir; - mb=dir; - for (n=0; ntif_flags&TIFF_SWAB) - TIFFSwabShort((uint16*)ma); - mb->tdir_tag=*(uint16*)ma; - ma+=sizeof(uint16); - if (tif->tif_flags&TIFF_SWAB) - TIFFSwabShort((uint16*)ma); - mb->tdir_type=*(uint16*)ma; - ma+=sizeof(uint16); - if (!(tif->tif_flags&TIFF_BIGTIFF)) - { - if (tif->tif_flags&TIFF_SWAB) - TIFFSwabLong((uint32*)ma); - mb->tdir_count=(uint64)(*(uint32*)ma); - ma+=sizeof(uint32); - *(uint32*)(&mb->tdir_offset)=*(uint32*)ma; - ma+=sizeof(uint32); - } - else - { - if (tif->tif_flags&TIFF_SWAB) - TIFFSwabLong8((uint64*)ma); - mb->tdir_count=TIFFReadUInt64(ma); - ma+=sizeof(uint64); - mb->tdir_offset.toff_long8=TIFFReadUInt64(ma); - ma+=sizeof(uint64); - } - mb++; - } - _TIFFfree(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 fii; - const TIFFField* fip = NULL; - TIFFReadDirectoryFindFieldInfo(tif,dp->tdir_tag,&fii); - if( fii == FAILED_FII ) - { - TIFFErrorExt(tif->tif_clientdata, "TIFFFetchNormalTag", - "No definition found for tag %d", - 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: - break; - case TIFF_SETGET_ASCII: - { - uint8* data; - assert(fip->field_passcount==0); - err=TIFFReadDirEntryByteArray(tif,dp,&data); - if (err==TIFFReadDirEntryErrOk) - { - uint8* ma; - uint32 mb; - int n; - ma=data; - mb=0; - while (mb<(uint32)dp->tdir_count) - { - if (*ma==0) - break; - ma++; - mb++; - } - if (mb+1<(uint32)dp->tdir_count) - TIFFWarningExt(tif->tif_clientdata,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)dp->tdir_count) - { - uint8* o; - TIFFWarningExt(tif->tif_clientdata,module,"ASCII value for tag \"%s\" does not end in null byte",fip->field_name); - if ((uint32)dp->tdir_count+1!=dp->tdir_count+1) - o=NULL; - else - o=_TIFFmalloc((uint32)dp->tdir_count+1); - if (o==NULL) - { - if (data!=NULL) - _TIFFfree(data); - return(0); - } - _TIFFmemcpy(o,data,(uint32)dp->tdir_count); - o[(uint32)dp->tdir_count]=0; - if (data!=0) - _TIFFfree(data); - data=o; - } - n=TIFFSetField(tif,dp->tdir_tag,data); - if (data!=0) - _TIFFfree(data); - if (!n) - return(0); - } - } - break; - case TIFF_SETGET_UINT8: - { - uint8 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_UINT16: - { - uint16 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_UINT32: - { - uint32 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_UINT64: - { - uint64 data; - assert(fip->field_readcount==1); - assert(fip->field_passcount==0); - err=TIFFReadDirEntryLong8(tif,dp,&data); - if (err==TIFFReadDirEntryErrOk) - { - 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 (!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 (!TIFFSetField(tif,dp->tdir_tag,data)) - return(0); - } - } - break; - case TIFF_SETGET_IFD8: - { - uint64 data; - assert(fip->field_readcount==1); - assert(fip->field_passcount==0); - err=TIFFReadDirEntryIfd8(tif,dp,&data); - if (err==TIFFReadDirEntryErrOk) - { - if (!TIFFSetField(tif,dp->tdir_tag,data)) - return(0); - } - } - break; - case TIFF_SETGET_UINT16_PAIR: - { - uint16* data; - assert(fip->field_readcount==2); - assert(fip->field_passcount==0); - if (dp->tdir_count!=2) { - TIFFWarningExt(tif->tif_clientdata,module, - "incorrect count for field \"%s\", expected 2, got %d", - fip->field_name,(int)dp->tdir_count); - return(0); - } - err=TIFFReadDirEntryShortArray(tif,dp,&data); - if (err==TIFFReadDirEntryErrOk) - { - int m; - m=TIFFSetField(tif,dp->tdir_tag,data[0],data[1]); - _TIFFfree(data); - if (!m) - return(0); - } - } - break; - case TIFF_SETGET_C0_UINT8: - { - uint8* data; - assert(fip->field_readcount>=1); - assert(fip->field_passcount==0); - if (dp->tdir_count!=(uint64)fip->field_readcount) { - TIFFWarningExt(tif->tif_clientdata,module, - "incorrect count for field \"%s\", expected %d, got %d", - fip->field_name,(int) fip->field_readcount, (int)dp->tdir_count); - return 0; - } - else - { - err=TIFFReadDirEntryByteArray(tif,dp,&data); - if (err==TIFFReadDirEntryErrOk) - { - int m; - m=TIFFSetField(tif,dp->tdir_tag,data); - if (data!=0) - _TIFFfree(data); - if (!m) - return(0); - } - } - } - break; - case TIFF_SETGET_C0_UINT16: - { - uint16* data; - assert(fip->field_readcount>=1); - assert(fip->field_passcount==0); - if (dp->tdir_count!=(uint64)fip->field_readcount) - /* corrupt file */; - else - { - err=TIFFReadDirEntryShortArray(tif,dp,&data); - if (err==TIFFReadDirEntryErrOk) - { - int m; - m=TIFFSetField(tif,dp->tdir_tag,data); - if (data!=0) - _TIFFfree(data); - if (!m) - return(0); - } - } - } - break; - case TIFF_SETGET_C0_UINT32: - { - uint32* data; - assert(fip->field_readcount>=1); - assert(fip->field_passcount==0); - if (dp->tdir_count!=(uint64)fip->field_readcount) - /* corrupt file */; - else - { - err=TIFFReadDirEntryLongArray(tif,dp,&data); - if (err==TIFFReadDirEntryErrOk) - { - int m; - m=TIFFSetField(tif,dp->tdir_tag,data); - if (data!=0) - _TIFFfree(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)fip->field_readcount) - /* corrupt file */; - else - { - err=TIFFReadDirEntryFloatArray(tif,dp,&data); - if (err==TIFFReadDirEntryErrOk) - { - int m; - m=TIFFSetField(tif,dp->tdir_tag,data); - if (data!=0) - _TIFFfree(data); - if (!m) - return(0); - } - } - } - break; - case TIFF_SETGET_C16_ASCII: - { - uint8* 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) - { - int m; - m=TIFFSetField(tif,dp->tdir_tag,(uint16)(dp->tdir_count),data); - if (data!=0) - _TIFFfree(data); - if (!m) - return(0); - } - } - } - break; - case TIFF_SETGET_C16_UINT8: - { - uint8* 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) - { - int m; - m=TIFFSetField(tif,dp->tdir_tag,(uint16)(dp->tdir_count),data); - if (data!=0) - _TIFFfree(data); - if (!m) - return(0); - } - } - } - break; - case TIFF_SETGET_C16_UINT16: - { - uint16* 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) - { - int m; - m=TIFFSetField(tif,dp->tdir_tag,(uint16)(dp->tdir_count),data); - if (data!=0) - _TIFFfree(data); - if (!m) - return(0); - } - } - } - break; - case TIFF_SETGET_C16_UINT32: - { - uint32* 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) - { - int m; - m=TIFFSetField(tif,dp->tdir_tag,(uint16)(dp->tdir_count),data); - if (data!=0) - _TIFFfree(data); - if (!m) - return(0); - } - } - } - break; - case TIFF_SETGET_C16_UINT64: - { - uint64* 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) - { - int m; - m=TIFFSetField(tif,dp->tdir_tag,(uint16)(dp->tdir_count),data); - if (data!=0) - _TIFFfree(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) - { - int m; - m=TIFFSetField(tif,dp->tdir_tag,(uint16)(dp->tdir_count),data); - if (data!=0) - _TIFFfree(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) - { - int m; - m=TIFFSetField(tif,dp->tdir_tag,(uint16)(dp->tdir_count),data); - if (data!=0) - _TIFFfree(data); - if (!m) - return(0); - } - } - } - break; - case TIFF_SETGET_C16_IFD8: - { - uint64* 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) - { - int m; - m=TIFFSetField(tif,dp->tdir_tag,(uint16)(dp->tdir_count),data); - if (data!=0) - _TIFFfree(data); - if (!m) - return(0); - } - } - } - break; - case TIFF_SETGET_C32_ASCII: - { - uint8* data; - assert(fip->field_readcount==TIFF_VARIABLE2); - assert(fip->field_passcount==1); - err=TIFFReadDirEntryByteArray(tif,dp,&data); - if (err==TIFFReadDirEntryErrOk) - { - int m; - m=TIFFSetField(tif,dp->tdir_tag,(uint32)(dp->tdir_count),data); - if (data!=0) - _TIFFfree(data); - if (!m) - return(0); - } - } - break; - case TIFF_SETGET_C32_UINT8: - { - uint8* data; - assert(fip->field_readcount==TIFF_VARIABLE2); - assert(fip->field_passcount==1); - err=TIFFReadDirEntryByteArray(tif,dp,&data); - if (err==TIFFReadDirEntryErrOk) - { - int m; - m=TIFFSetField(tif,dp->tdir_tag,(uint32)(dp->tdir_count),data); - if (data!=0) - _TIFFfree(data); - if (!m) - return(0); - } - } - break; - case TIFF_SETGET_C32_SINT8: - { - int8* data = NULL; - assert(fip->field_readcount==TIFF_VARIABLE2); - assert(fip->field_passcount==1); - err=TIFFReadDirEntrySbyteArray(tif,dp,&data); - if (err==TIFFReadDirEntryErrOk) - { - int m; - m=TIFFSetField(tif,dp->tdir_tag,(uint32)(dp->tdir_count),data); - if (data!=0) - _TIFFfree(data); - if (!m) - return(0); - } - } - break; - case TIFF_SETGET_C32_UINT16: - { - uint16* data; - assert(fip->field_readcount==TIFF_VARIABLE2); - assert(fip->field_passcount==1); - err=TIFFReadDirEntryShortArray(tif,dp,&data); - if (err==TIFFReadDirEntryErrOk) - { - int m; - m=TIFFSetField(tif,dp->tdir_tag,(uint32)(dp->tdir_count),data); - if (data!=0) - _TIFFfree(data); - if (!m) - return(0); - } - } - break; - case TIFF_SETGET_C32_SINT16: - { - int16* data = NULL; - assert(fip->field_readcount==TIFF_VARIABLE2); - assert(fip->field_passcount==1); - err=TIFFReadDirEntrySshortArray(tif,dp,&data); - if (err==TIFFReadDirEntryErrOk) - { - int m; - m=TIFFSetField(tif,dp->tdir_tag,(uint32)(dp->tdir_count),data); - if (data!=0) - _TIFFfree(data); - if (!m) - return(0); - } - } - break; - case TIFF_SETGET_C32_UINT32: - { - uint32* data; - assert(fip->field_readcount==TIFF_VARIABLE2); - assert(fip->field_passcount==1); - err=TIFFReadDirEntryLongArray(tif,dp,&data); - if (err==TIFFReadDirEntryErrOk) - { - int m; - m=TIFFSetField(tif,dp->tdir_tag,(uint32)(dp->tdir_count),data); - if (data!=0) - _TIFFfree(data); - if (!m) - return(0); - } - } - break; - case TIFF_SETGET_C32_SINT32: - { - int32* data = NULL; - assert(fip->field_readcount==TIFF_VARIABLE2); - assert(fip->field_passcount==1); - err=TIFFReadDirEntrySlongArray(tif,dp,&data); - if (err==TIFFReadDirEntryErrOk) - { - int m; - m=TIFFSetField(tif,dp->tdir_tag,(uint32)(dp->tdir_count),data); - if (data!=0) - _TIFFfree(data); - if (!m) - return(0); - } - } - break; - case TIFF_SETGET_C32_UINT64: - { - uint64* data; - assert(fip->field_readcount==TIFF_VARIABLE2); - assert(fip->field_passcount==1); - err=TIFFReadDirEntryLong8Array(tif,dp,&data); - if (err==TIFFReadDirEntryErrOk) - { - int m; - m=TIFFSetField(tif,dp->tdir_tag,(uint32)(dp->tdir_count),data); - if (data!=0) - _TIFFfree(data); - if (!m) - return(0); - } - } - break; - case TIFF_SETGET_C32_SINT64: - { - int64* data = NULL; - assert(fip->field_readcount==TIFF_VARIABLE2); - assert(fip->field_passcount==1); - err=TIFFReadDirEntrySlong8Array(tif,dp,&data); - if (err==TIFFReadDirEntryErrOk) - { - int m; - m=TIFFSetField(tif,dp->tdir_tag,(uint32)(dp->tdir_count),data); - if (data!=0) - _TIFFfree(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) - { - int m; - m=TIFFSetField(tif,dp->tdir_tag,(uint32)(dp->tdir_count),data); - if (data!=0) - _TIFFfree(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) - { - int m; - m=TIFFSetField(tif,dp->tdir_tag,(uint32)(dp->tdir_count),data); - if (data!=0) - _TIFFfree(data); - if (!m) - return(0); - } - } - break; - case TIFF_SETGET_C32_IFD8: - { - uint64* data; - assert(fip->field_readcount==TIFF_VARIABLE2); - assert(fip->field_passcount==1); - err=TIFFReadDirEntryIfd8Array(tif,dp,&data); - if (err==TIFFReadDirEntryErrOk) - { - int m; - m=TIFFSetField(tif,dp->tdir_tag,(uint32)(dp->tdir_count),data); - if (data!=0) - _TIFFfree(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 nstrips, uint64** lpp) -{ - static const char module[] = "TIFFFetchStripThing"; - enum TIFFReadDirEntryErr err; - uint64* data; - err=TIFFReadDirEntryLong8Array(tif,dir,&data); - 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)nstrips) - { - uint64* resizeddata; - resizeddata=(uint64*)_TIFFCheckMalloc(tif,nstrips,sizeof(uint64),"for strip array"); - if (resizeddata==0) { - _TIFFfree(data); - return(0); - } - if (dir->tdir_count<(uint64)nstrips) - { - _TIFFmemcpy(resizeddata,data,(uint32)dir->tdir_count*sizeof(uint64)); - _TIFFmemset(resizeddata+(uint32)dir->tdir_count,0,(nstrips-(uint32)dir->tdir_count)*sizeof(uint64)); - } - else - _TIFFmemcpy(resizeddata,data,nstrips*sizeof(uint64)); - _TIFFfree(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)==8); - assert(sizeof(uint32)==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 offset; - offset=*(uint32*)(&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) - /* - * 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); - } -} - -/* - * 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 bytecount; - uint64 offset; - uint32 rowblock; - uint64 rowblockbytes; - uint64 stripbytes; - uint32 strip; - uint64 nstrips64; - uint32 nstrips32; - uint32 rowsperstrip; - uint64* newcounts; - uint64* newoffsets; - - bytecount = td->td_stripbytecount[0]; - offset = td->td_stripoffset[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 rowblocksperstrip; - rowblocksperstrip = (uint32) (STRIP_SIZE_DEFAULT / rowblockbytes); - rowsperstrip = rowblocksperstrip * rowblock; - stripbytes = rowblocksperstrip * rowblockbytes; - } - else - return; - - /* - * never increase the number of strips in an image - */ - if (rowsperstrip >= td->td_rowsperstrip) - return; - nstrips64 = TIFFhowmany_64(bytecount, stripbytes); - if ((nstrips64==0)||(nstrips64>0xFFFFFFFF)) /* something is wonky, do nothing. */ - return; - nstrips32 = (uint32)nstrips64; - - newcounts = (uint64*) _TIFFCheckMalloc(tif, nstrips32, sizeof (uint64), - "for chopped \"StripByteCounts\" array"); - newoffsets = (uint64*) _TIFFCheckMalloc(tif, nstrips32, sizeof (uint64), - "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) - _TIFFfree(newcounts); - if (newoffsets != NULL) - _TIFFfree(newoffsets); - return; - } - /* - * Fill the strip information arrays with new bytecounts and offsets - * that reflect the broken-up format. - */ - for (strip = 0; strip < nstrips32; strip++) { - if (stripbytes > bytecount) - stripbytes = bytecount; - newcounts[strip] = stripbytes; - newoffsets[strip] = offset; - offset += stripbytes; - bytecount -= stripbytes; - } - /* - * Replace old single strip info with multi-strip info. - */ - td->td_stripsperimage = td->td_nstrips = nstrips32; - TIFFSetField(tif, TIFFTAG_ROWSPERSTRIP, rowsperstrip); - - _TIFFfree(td->td_stripbytecount); - _TIFFfree(td->td_stripoffset); - td->td_stripbytecount = newcounts; - td->td_stripoffset = newoffsets; - td->td_stripbytecountsorted = 1; -} - -int _TIFFFillStriles( TIFF *tif ) -{ -#if defined(DEFER_STRILE_LOAD) - register TIFFDirectory *td = &tif->tif_dir; - int return_value = 1; - - if( td->td_stripoffset != NULL ) - return 1; - - if( td->td_stripoffset_entry.tdir_count == 0 ) - return 0; - - if (!TIFFFetchStripThing(tif,&(td->td_stripoffset_entry), - td->td_nstrips,&td->td_stripoffset)) - { - return_value = 0; - } - - if (!TIFFFetchStripThing(tif,&(td->td_stripbytecount_entry), - td->td_nstrips,&td->td_stripbytecount)) - { - return_value = 0; - } - - _TIFFmemset( &(td->td_stripoffset_entry), 0, sizeof(TIFFDirEntry)); - _TIFFmemset( &(td->td_stripbytecount_entry), 0, sizeof(TIFFDirEntry)); - - if (tif->tif_dir.td_nstrips > 1 && return_value == 1 ) { - uint32 strip; - - tif->tif_dir.td_stripbytecountsorted = 1; - for (strip = 1; strip < tif->tif_dir.td_nstrips; strip++) { - if (tif->tif_dir.td_stripoffset[strip - 1] > - tif->tif_dir.td_stripoffset[strip]) { - tif->tif_dir.td_stripbytecountsorted = 0; - break; - } - } - } - - return return_value; -#else /* !defined(DEFER_STRILE_LOAD) */ - (void) tif; - return 1; -#endif -} - - -/* vim: set ts=8 sts=8 sw=8 noet: */ -/* - * Local Variables: - * mode: c - * c-basic-offset: 8 - * fill-column: 78 - * End: - */ -- cgit v1.2.3