| /* |
| * Copyright (c) 1988-1997 Sam Leffler |
| * Copyright (c) 1991-1997 Silicon Graphics, Inc. |
| * |
| * Permission to use, copy, modify, distribute, and sell this software and |
| * its documentation for any purpose is hereby granted without fee, provided |
| * that (i) the above copyright notices and this permission notice appear in |
| * all copies of the software and related documentation, and (ii) the names of |
| * Sam Leffler and Silicon Graphics may not be used in any advertising or |
| * publicity relating to the software without the specific, prior written |
| * permission of Sam Leffler and Silicon Graphics. |
| * |
| * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, |
| * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY |
| * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. |
| * |
| * IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR |
| * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, |
| * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, |
| * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF |
| * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE |
| * OF THIS SOFTWARE. |
| */ |
| |
| /* |
| * TIFF Library. |
| * |
| * Directory Read Support Routines. |
| */ |
| |
| /* Suggested pending improvements: |
| * - add a field 'field_info' to the TIFFDirEntry structure, and set that with |
| * the pointer to the appropriate TIFFField structure early on in |
| * TIFFReadDirectory, so as to eliminate current possibly repetitive lookup. |
| */ |
| |
| #include "tiffiop.h" |
| #include <float.h> |
| #include <limits.h> |
| #include <stdlib.h> |
| |
| #define FAILED_FII ((uint32) -1) |
| |
| /* |
| * Largest 64-bit signed integer value. |
| */ |
| #define TIFF_INT64_MAX ((int64)(TIFF_UINT64_MAX >> 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 void TryChopUpUncompressedBigTiff(TIFF*); |
| static uint64 TIFFReadUInt64(const uint8 *value); |
| static int _TIFFGetMaxColorChannels(uint16 photometric); |
| |
| static int _TIFFFillStrilesInternal( TIFF *tif, int loadStripByteCount ); |
| |
| 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: |
| case TIFF_UNDEFINED: /* Support to read TIFF_UNDEFINED with field_readcount==1 */ |
| 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); |
| if ((m > FLT_MAX) || (m < -FLT_MAX)) |
| return(TIFFReadDirEntryErrRange); |
| *value=(float)m; |
| return(TIFFReadDirEntryErrOk); |
| } |
| default: |
| return(TIFFReadDirEntryErrType); |
| } |
| } |
| |
| static enum TIFFReadDirEntryErr TIFFReadDirEntryDouble(TIFF* tif, TIFFDirEntry* direntry, double* value) |
| { |
| enum TIFFReadDirEntryErr err; |
| if (direntry->tdir_count!=1) |
| return(TIFFReadDirEntryErrCount); |
| switch (direntry->tdir_type) |
| { |
| case TIFF_BYTE: |
| { |
| uint8 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); |
| } |
| } |
| |
| |
| #define INITIAL_THRESHOLD (1024 * 1024) |
| #define THRESHOLD_MULTIPLIER 10 |
| #define MAX_THRESHOLD (THRESHOLD_MULTIPLIER * THRESHOLD_MULTIPLIER * THRESHOLD_MULTIPLIER * INITIAL_THRESHOLD) |
| |
| static enum TIFFReadDirEntryErr TIFFReadDirEntryDataAndRealloc( |
| TIFF* tif, uint64 offset, tmsize_t size, void** pdest) |
| { |
| #if SIZEOF_SIZE_T == 8 |
| tmsize_t threshold = INITIAL_THRESHOLD; |
| #endif |
| tmsize_t already_read = 0; |
| |
| assert( !isMapped(tif) ); |
| |
| if (!SeekOK(tif,offset)) |
| return(TIFFReadDirEntryErrIo); |
| |
| /* On 64 bit processes, read first a maximum of 1 MB, then 10 MB, etc */ |
| /* so as to avoid allocating too much memory in case the file is too */ |
| /* short. We could ask for the file size, but this might be */ |
| /* expensive with some I/O layers (think of reading a gzipped file) */ |
| /* Restrict to 64 bit processes, so as to avoid reallocs() */ |
| /* on 32 bit processes where virtual memory is scarce. */ |
| while( already_read < size ) |
| { |
| void* new_dest; |
| tmsize_t bytes_read; |
| tmsize_t to_read = size - already_read; |
| #if SIZEOF_SIZE_T == 8 |
| if( to_read >= threshold && threshold < MAX_THRESHOLD ) |
| { |
| to_read = threshold; |
| threshold *= THRESHOLD_MULTIPLIER; |
| } |
| #endif |
| |
| new_dest = (uint8*) _TIFFrealloc( |
| *pdest, already_read + to_read); |
| if( new_dest == NULL ) |
| { |
| TIFFErrorExt(tif->tif_clientdata, tif->tif_name, |
| "Failed to allocate memory for %s " |
| "(%ld elements of %ld bytes each)", |
| "TIFFReadDirEntryArray", |
| (long) 1, (long) (already_read + to_read)); |
| return TIFFReadDirEntryErrAlloc; |
| } |
| *pdest = new_dest; |
| |
| bytes_read = TIFFReadFile(tif, |
| (char*)*pdest + already_read, to_read); |
| already_read += bytes_read; |
| if (bytes_read != to_read) { |
| return TIFFReadDirEntryErrIo; |
| } |
| } |
| return TIFFReadDirEntryErrOk; |
| } |
| |
| static enum TIFFReadDirEntryErr TIFFReadDirEntryArrayWithLimit( |
| TIFF* tif, TIFFDirEntry* direntry, uint32* count, uint32 desttypesize, |
| void** value, uint64 maxcount) |
| { |
| int typesize; |
| uint32 datasize; |
| void* data; |
| uint64 target_count64; |
| int original_datasize_clamped; |
| typesize=TIFFDataWidth(direntry->tdir_type); |
| |
| target_count64 = (direntry->tdir_count > maxcount) ? |
| maxcount : direntry->tdir_count; |
| |
| if ((target_count64==0)||(typesize==0)) |
| { |
| *value=0; |
| return(TIFFReadDirEntryErrOk); |
| } |
| (void) desttypesize; |
| |
| /* We just want to know if the original tag size is more than 4 bytes |
| * (classic TIFF) or 8 bytes (BigTIFF) |
| */ |
| original_datasize_clamped = |
| ((direntry->tdir_count > 10) ? 10 : (int)direntry->tdir_count) * typesize; |
| |
| /* |
| * As a sanity check, make sure we have no more than a 2GB tag array |
| * in either the current data type or the dest data type. This also |
| * avoids problems with overflow of tmsize_t on 32bit systems. |
| */ |
| if ((uint64)(2147483647/typesize)<target_count64) |
| return(TIFFReadDirEntryErrSizesan); |
| if ((uint64)(2147483647/desttypesize)<target_count64) |
| return(TIFFReadDirEntryErrSizesan); |
| |
| *count=(uint32)target_count64; |
| datasize=(*count)*typesize; |
| assert((tmsize_t)datasize>0); |
| |
| if( isMapped(tif) && datasize > (uint64)tif->tif_size ) |
| return TIFFReadDirEntryErrIo; |
| |
| if( !isMapped(tif) && |
| (((tif->tif_flags&TIFF_BIGTIFF) && datasize > 8) || |
| (!(tif->tif_flags&TIFF_BIGTIFF) && datasize > 4)) ) |
| { |
| data = NULL; |
| } |
| else |
| { |
| data=_TIFFCheckMalloc(tif, *count, typesize, "ReadDirEntryArray"); |
| if (data==0) |
| return(TIFFReadDirEntryErrAlloc); |
| } |
| if (!(tif->tif_flags&TIFF_BIGTIFF)) |
| { |
| if (original_datasize_clamped<=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); |
| if( isMapped(tif) ) |
| err=TIFFReadDirEntryData(tif,(uint64)offset,(tmsize_t)datasize,data); |
| else |
| err=TIFFReadDirEntryDataAndRealloc(tif,(uint64)offset,(tmsize_t)datasize,&data); |
| if (err!=TIFFReadDirEntryErrOk) |
| { |
| _TIFFfree(data); |
| return(err); |
| } |
| } |
| } |
| else |
| { |
| if (original_datasize_clamped<=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); |
| if( isMapped(tif) ) |
| err=TIFFReadDirEntryData(tif,(uint64)offset,(tmsize_t)datasize,data); |
| else |
| err=TIFFReadDirEntryDataAndRealloc(tif,(uint64)offset,(tmsize_t)datasize,&data); |
| if (err!=TIFFReadDirEntryErrOk) |
| { |
| _TIFFfree(data); |
| return(err); |
| } |
| } |
| } |
| *value=data; |
| return(TIFFReadDirEntryErrOk); |
| } |
| |
| static enum TIFFReadDirEntryErr TIFFReadDirEntryArray(TIFF* tif, TIFFDirEntry* direntry, uint32* count, uint32 desttypesize, void** value) |
| { |
| return TIFFReadDirEntryArrayWithLimit(tif, direntry, count, |
| desttypesize, value, ~((uint64)0)); |
| } |
| |
| 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; n<count; n++) |
| { |
| err=TIFFReadDirEntryCheckRangeByteSbyte(*m); |
| if (err!=TIFFReadDirEntryErrOk) |
| { |
| _TIFFfree(origdata); |
| return(err); |
| } |
| m++; |
| } |
| *value=(uint8*)origdata; |
| return(TIFFReadDirEntryErrOk); |
| } |
| } |
| data=(uint8*)_TIFFmalloc(count); |
| if (data==0) |
| { |
| _TIFFfree(origdata); |
| return(TIFFReadDirEntryErrAlloc); |
| } |
| switch (direntry->tdir_type) |
| { |
| case TIFF_SHORT: |
| { |
| uint16* ma; |
| uint8* mb; |
| uint32 n; |
| ma=(uint16*)origdata; |
| mb=data; |
| for (n=0; n<count; n++) |
| { |
| if (tif->tif_flags&TIFF_SWAB) |
| TIFFSwabShort(ma); |
| err=TIFFReadDirEntryCheckRangeByteShort(*ma); |
| if (err!=TIFFReadDirEntryErrOk) |
| break; |
| *mb++=(uint8)(*ma++); |
| } |
| } |
| break; |
| case TIFF_SSHORT: |
| { |
| int16* ma; |
| uint8* mb; |
| uint32 n; |
| ma=(int16*)origdata; |
| mb=data; |
| for (n=0; n<count; n++) |
| { |
| if (tif->tif_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; n<count; n++) |
| { |
| if (tif->tif_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; n<count; n++) |
| { |
| if (tif->tif_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; n<count; n++) |
| { |
| if (tif->tif_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; n<count; n++) |
| { |
| if (tif->tif_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; n<count; n++) |
| { |
| err=TIFFReadDirEntryCheckRangeSbyteByte(*m); |
| if (err!=TIFFReadDirEntryErrOk) |
| { |
| _TIFFfree(origdata); |
| return(err); |
| } |
| m++; |
| } |
| *value=(int8*)origdata; |
| return(TIFFReadDirEntryErrOk); |
| } |
| case TIFF_SBYTE: |
| *value=(int8*)origdata; |
| return(TIFFReadDirEntryErrOk); |
| } |
| data=(int8*)_TIFFmalloc(count); |
| if (data==0) |
| { |
| _TIFFfree(origdata); |
| return(TIFFReadDirEntryErrAlloc); |
| } |
| switch (direntry->tdir_type) |
| { |
| case TIFF_SHORT: |
| { |
| uint16* ma; |
| int8* mb; |
| uint32 n; |
| ma=(uint16*)origdata; |
| mb=data; |
| for (n=0; n<count; n++) |
| { |
| if (tif->tif_flags&TIFF_SWAB) |
| TIFFSwabShort(ma); |
| err=TIFFReadDirEntryCheckRangeSbyteShort(*ma); |
| if (err!=TIFFReadDirEntryErrOk) |
| break; |
| *mb++=(int8)(*ma++); |
| } |
| } |
| break; |
| case TIFF_SSHORT: |
| { |
| int16* ma; |
| int8* mb; |
| uint32 n; |
| ma=(int16*)origdata; |
| mb=data; |
| for (n=0; n<count; n++) |
| { |
| if (tif->tif_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; n<count; n++) |
| { |
| if (tif->tif_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; n<count; n++) |
| { |
| if (tif->tif_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; n<count; n++) |
| { |
| if (tif->tif_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; n<count; n++) |
| { |
| if (tif->tif_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; n<count; n++) |
| { |
| if (tif->tif_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; n<count; n++) |
| *mb++=(uint16)(*ma++); |
| } |
| break; |
| case TIFF_SBYTE: |
| { |
| int8* ma; |
| uint16* mb; |
| uint32 n; |
| ma=(int8*)origdata; |
| mb=data; |
| for (n=0; n<count; n++) |
| { |
| err=TIFFReadDirEntryCheckRangeShortSbyte(*ma); |
| if (err!=TIFFReadDirEntryErrOk) |
| break; |
| *mb++=(uint16)(*ma++); |
| } |
| } |
| break; |
| case TIFF_LONG: |
| { |
| uint32* ma; |
| uint16* mb; |
| uint32 n; |
| ma=(uint32*)origdata; |
| mb=data; |
| for (n=0; n<count; n++) |
| { |
| if (tif->tif_flags&TIFF_SWAB) |
| TIFFSwabLong(ma); |
| err=TIFFReadDirEntryCheckRangeShortLong(*ma); |
| if (err!=TIFFReadDirEntryErrOk) |
| break; |
| *mb++=(uint16)(*ma++); |
| } |
| } |
| break; |
| case TIFF_SLONG: |
| { |
| int32* ma; |
| uint16* mb; |
| uint32 n; |
| ma=(int32*)origdata; |
| mb=data; |
| for (n=0; n<count; n++) |
| { |
| if (tif->tif_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; n<count; n++) |
| { |
| if (tif->tif_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; n<count; n++) |
| { |
| if (tif->tif_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; n<count; n++) |
| { |
| if (tif->tif_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; n<count; n++) |
| *mb++=(int16)(*ma++); |
| } |
| break; |
| case TIFF_SBYTE: |
| { |
| int8* ma; |
| int16* mb; |
| uint32 n; |
| ma=(int8*)origdata; |
| mb=data; |
| for (n=0; n<count; n++) |
| *mb++=(int16)(*ma++); |
| } |
| break; |
| case TIFF_LONG: |
| { |
| uint32* ma; |
| int16* mb; |
| uint32 n; |
| ma=(uint32*)origdata; |
| mb=data; |
| for (n=0; n<count; n++) |
| { |
| if (tif->tif_flags&TIFF_SWAB) |
| TIFFSwabLong(ma); |
| err=TIFFReadDirEntryCheckRangeSshortLong(*ma); |
| if (err!=TIFFReadDirEntryErrOk) |
| break; |
| *mb++=(int16)(*ma++); |
| } |
| } |
| break; |
| case TIFF_SLONG: |
| { |
| int32* ma; |
| int16* mb; |
| uint32 n; |
| ma=(int32*)origdata; |
| mb=data; |
| for (n=0; n<count; n++) |
| { |
| if (tif->tif_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; n<count; n++) |
| { |
| if (tif->tif_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; n<count; n++) |
| { |
| if (tif->tif_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; n<count; n++) |
| { |
| if (tif->tif_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; n<count; n++) |
| *mb++=(uint32)(*ma++); |
| } |
| break; |
| case TIFF_SBYTE: |
| { |
| int8* ma; |
| uint32* mb; |
| uint32 n; |
| ma=(int8*)origdata; |
| mb=data; |
| for (n=0; n<count; n++) |
| { |
| err=TIFFReadDirEntryCheckRangeLongSbyte(*ma); |
| if (err!=TIFFReadDirEntryErrOk) |
| break; |
| *mb++=(uint32)(*ma++); |
| } |
| } |
| break; |
| case TIFF_SHORT: |
| { |
| uint16* ma; |
| uint32* mb; |
| uint32 n; |
| ma=(uint16*)origdata; |
| mb=data; |
| for (n=0; n<count; n++) |
| { |
| if (tif->tif_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; n<count; n++) |
| { |
| if (tif->tif_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; n<count; n++) |
| { |
| if (tif->tif_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; n<count; n++) |
| { |
| if (tif->tif_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; n<count; n++) |
| { |
| if (tif->tif_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; n<count; n++) |
| *mb++=(int32)(*ma++); |
| } |
| break; |
| case TIFF_SBYTE: |
| { |
| int8* ma; |
| int32* mb; |
| uint32 n; |
| ma=(int8*)origdata; |
| mb=data; |
| for (n=0; n<count; n++) |
| *mb++=(int32)(*ma++); |
| } |
| break; |
| case TIFF_SHORT: |
| { |
| uint16* ma; |
| int32* mb; |
| uint32 n; |
| ma=(uint16*)origdata; |
| mb=data; |
| for (n=0; n<count; n++) |
| { |
| if (tif->tif_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; n<count; n++) |
| { |
| if (tif->tif_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; n<count; n++) |
| { |
| if (tif->tif_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; n<count; n++) |
| { |
| if (tif->tif_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 TIFFReadDirEntryLong8ArrayWithLimit( |
| TIFF* tif, TIFFDirEntry* direntry, uint64** value, uint64 maxcount) |
| { |
| 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=TIFFReadDirEntryArrayWithLimit(tif,direntry,&count,8,&origdata,maxcount); |
| if ((err!=TIFFReadDirEntryErrOk)||(origdata==0)) |
| { |
| *value=0; |
| return(err); |
| } |
| switch (direntry->tdir_type) |
| { |
| case TIFF_LONG8: |
| *value=(uint64*)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; n<count; n++) |
| { |
| if (tif->tif_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; n<count; n++) |
| *mb++=(uint64)(*ma++); |
| } |
| break; |
| case TIFF_SBYTE: |
| { |
| int8* ma; |
| uint64* mb; |
| uint32 n; |
| ma=(int8*)origdata; |
| mb=data; |
| for (n=0; n<count; n++) |
| { |
| err=TIFFReadDirEntryCheckRangeLong8Sbyte(*ma); |
| if (err!=TIFFReadDirEntryErrOk) |
| break; |
| *mb++=(uint64)(*ma++); |
| } |
| } |
| break; |
| case TIFF_SHORT: |
| { |
| uint16* ma; |
| uint64* mb; |
| uint32 n; |
| ma=(uint16*)origdata; |
| mb=data; |
| for (n=0; n<count; n++) |
| { |
| if (tif->tif_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; n<count; n++) |
| { |
| if (tif->tif_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; n<count; n++) |
| { |
| if (tif->tif_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; n<count; n++) |
| { |
| if (tif->tif_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 TIFFReadDirEntryLong8Array(TIFF* tif, TIFFDirEntry* direntry, uint64** value) |
| { |
| return TIFFReadDirEntryLong8ArrayWithLimit(tif, direntry, value, ~((uint64)0)); |
| } |
| |
| 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; n<count; n++) |
| { |
| if (tif->tif_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; n<count; n++) |
| *mb++=(int64)(*ma++); |
| } |
| break; |
| case TIFF_SBYTE: |
| { |
| int8* ma; |
| int64* mb; |
| uint32 n; |
| ma=(int8*)origdata; |
| mb=data; |
| for (n=0; n<count; n++) |
| *mb++=(int64)(*ma++); |
| } |
| break; |
| case TIFF_SHORT: |
| { |
| uint16* ma; |
| int64* mb; |
| uint32 n; |
| ma=(uint16*)origdata; |
| mb=data; |
| for (n=0; n<count; n++) |
| { |
| if (tif->tif_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; n<count; n++) |
| { |
| if (tif->tif_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; n<count; n++) |
| { |
| if (tif->tif_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; n<count; n++) |
| { |
| if (tif->tif_flags&TIFF_SWAB) |
| TIFFSwabLong((uint32*)ma); |
| *mb++=(int64)(*ma++); |
| } |
| } |
| break; |
| } |
| _TIFFfree(origdata); |
| *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; n<count; n++) |
| *mb++=(float)(*ma++); |
| } |
| break; |
| case TIFF_SBYTE: |
| { |
| int8* ma; |
| float* mb; |
| uint32 n; |
| ma=(int8*)origdata; |
| mb=data; |
| for (n=0; n<count; n++) |
| *mb++=(float)(*ma++); |
| } |
| break; |
| case TIFF_SHORT: |
| { |
| uint16* ma; |
| float* mb; |
| uint32 n; |
| ma=(uint16*)origdata; |
| mb=data; |
| for (n=0; n<count; n++) |
| { |
| if (tif->tif_flags&TIFF_SWAB) |
| TIFFSwabShort(ma); |
| *mb++=(float)(*ma++); |
| } |
| } |
| break; |
| case TIFF_SSHORT: |
| { |
| int16* ma; |
| float* mb; |
| uint32 n; |
| ma=(int16*)origdata; |
| mb=data; |
| for (n=0; n<count; n++) |
| { |
| if (tif->tif_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; n<count; n++) |
| { |
| if (tif->tif_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; n<count; n++) |
| { |
| if (tif->tif_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; n<count; n++) |
| { |
| if (tif->tif_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; n<count; n++) |
| { |
| if (tif->tif_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; n<count; n++) |
| { |
| if (tif->tif_flags&TIFF_SWAB) |
| TIFFSwabLong(ma); |
| maa=*ma++; |
| if (tif->tif_flags&TIFF_SWAB) |
| TIFFSwabLong(ma); |
| mab=*ma++; |
| if (mab==0) |
| *mb++=0.0; |
| else |
| *mb++=(float)maa/(float)mab; |
| } |
| } |
| break; |
| case TIFF_SRATIONAL: |
| { |
| uint32* ma; |
| int32 maa; |
| uint32 mab; |
| float* mb; |
| uint32 n; |
| ma=(uint32*)origdata; |
| mb=data; |
| for (n=0; n<count; n++) |
| { |
| if (tif->tif_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; n<count; n++) |
| { |
| double val = *ma++; |
| if( val > FLT_MAX ) |
| val = FLT_MAX; |
| else if( val < -FLT_MAX ) |
| val = -FLT_MAX; |
| *mb++=(float)val; |
| } |
| } |
| break; |
| } |
| _TIFFfree(origdata); |
| *value=data; |
| return(TIFFReadDirEntryErrOk); |
| } |
| |
| static enum TIFFReadDirEntryErr |
| TIFFReadDirEntryDoubleArray(TIFF* tif, TIFFDirEntry* direntry, double** value) |
| { |
| enum TIFFReadDirEntryErr err; |
| uint32 count; |
| void* origdata; |
| double* data; |
| switch (direntry->tdir_type) |
| { |
| case TIFF_BYTE: |
| case TIFF_SBYTE: |
| case TIFF_SHORT: |
| case TIFF_SSHORT: |
| case TIFF_LONG: |
| case TIFF_SLONG: |
| case TIFF_LONG8: |
| case TIFF_SLONG8: |
| case TIFF_RATIONAL: |
| case TIFF_SRATIONAL: |
| case TIFF_FLOAT: |
| case TIFF_DOUBLE: |
| break; |
| default: |
| return(TIFFReadDirEntryErrType); |
| } |
| err=TIFFReadDirEntryArray(tif,direntry,&count,8,&origdata); |
| if ((err!=TIFFReadDirEntryErrOk)||(origdata==0)) |
| { |
| *value=0; |
| return(err); |
| } |
| switch (direntry->tdir_type) |
| { |
| case TIFF_DOUBLE: |
| if (tif->tif_flags&TIFF_SWAB) |
| TIFFSwabArrayOfLong8((uint64*)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; n<count; n++) |
| *mb++=(double)(*ma++); |
| } |
| break; |
| case TIFF_SBYTE: |
| { |
| int8* ma; |
| double* mb; |
| uint32 n; |
| ma=(int8*)origdata; |
| mb=data; |
| for (n=0; n<count; n++) |
| *mb++=(double)(*ma++); |
| } |
| break; |
| case TIFF_SHORT: |
| { |
| uint16* ma; |
| double* mb; |
| uint32 n; |
| ma=(uint16*)origdata; |
| mb=data; |
| for (n=0; n<count; n++) |
| { |
| if (tif->tif_flags&TIFF_SWAB) |
| TIFFSwabShort(ma); |
| *mb++=(double)(*ma++); |
| } |
| } |
| break; |
| case TIFF_SSHORT: |
| { |
| int16* ma; |
| double* mb; |
| uint32 n; |
| ma=(int16*)origdata; |
| mb=data; |
| for (n=0; n<count; n++) |
| { |
| if (tif->tif_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; n<count; n++) |
| { |
| if (tif->tif_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; n<count; n++) |
| { |
| if (tif->tif_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; n<count; n++) |
| { |
| if (tif->tif_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; n<count; n++) |
| { |
| if (tif->tif_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; n<count; n++) |
| { |
| if (tif->tif_flags&TIFF_SWAB) |
| TIFFSwabLong(ma); |
| maa=*ma++; |
| if (tif->tif_flags&TIFF_SWAB) |
| TIFFSwabLong(ma); |
| mab=*ma++; |
| if (mab==0) |
| *mb++=0.0; |
| else |
| *mb++=(double)maa/(double)mab; |
| } |
| } |
| break; |
| case TIFF_SRATIONAL: |
| { |
| uint32* ma; |
| int32 maa; |
| uint32 mab; |
| double* mb; |
| uint32 n; |
| ma=(uint32*)origdata; |
| mb=data; |
| for (n=0; n<count; n++) |
| { |
| if (tif->tif_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; n<count; n++) |
| *mb++=(double)(*ma++); |
| } |
| break; |
| } |
| _TIFFfree(origdata); |
| *value=data; |
| return(TIFFReadDirEntryErrOk); |
| } |
| |
| static enum TIFFReadDirEntryErr TIFFReadDirEntryIfd8Array(TIFF* tif, TIFFDirEntry* direntry, uint64** value) |
| { |
| enum TIFFReadDirEntryErr err; |
| uint32 count; |
| void* origdata; |
| uint64* data; |
| switch (direntry->tdir_type) |
| { |
| case TIFF_LONG: |
| case TIFF_LONG8: |
| case TIFF_IFD: |
| case TIFF_IFD8: |
| break; |
| default: |
| return(TIFFReadDirEntryErrType); |
| } |
| err=TIFFReadDirEntryArray(tif,direntry,&count,8,&origdata); |
| if ((err!=TIFFReadDirEntryErrOk)||(origdata==0)) |
| { |
| *value=0; |
| return(err); |
| } |
| switch (direntry->tdir_type) |
| { |
| case TIFF_LONG8: |
| case TIFF_IFD8: |
| *value=(uint64*)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; n<count; n++) |
| { |
| if (tif->tif_flags&TIFF_SWAB) |
| TIFFSwabLong(ma); |
| *mb++=(uint64)(*ma++); |
| } |
| } |
| break; |
| } |
| _TIFFfree(origdata); |
| *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 || m == NULL) |
| return(err); |
| na=m; |
| nb=tif->tif_dir.td_samplesperpixel; |
| *value=*na++; |
| nb--; |
| while (nb>0) |
| { |
| if (*na++!=*value) |
| { |
| err=TIFFReadDirEntryErrPsdif; |
| break; |
| } |
| nb--; |
| } |
| _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); |
| /* Not completely sure what we should do when m.i[1]==0, but some */ |
| /* sanitizers do not like division by 0.0: */ |
| /* http://bugzilla.maptools.org/show_bug.cgi?id=2644 */ |
| if (m.i[0]==0 || m.i[1]==0) |
| *value=0.0; |
| else |
| *value=(double)m.i[0]/(double)m.i[1]; |
| return(TIFFReadDirEntryErrOk); |
| } |
| |
| static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckedSrational(TIFF* tif, TIFFDirEntry* direntry, double* value) |
|