This source file includes following definitions.
- TIFFReadUInt64
- TIFFReadDirEntryByte
- TIFFReadDirEntryShort
- TIFFReadDirEntryLong
- TIFFReadDirEntryLong8
- TIFFReadDirEntryFloat
- TIFFReadDirEntryDouble
- TIFFReadDirEntryIfd8
- TIFFReadDirEntryArray
- TIFFReadDirEntryByteArray
- TIFFReadDirEntrySbyteArray
- TIFFReadDirEntryShortArray
- TIFFReadDirEntrySshortArray
- TIFFReadDirEntryLongArray
- TIFFReadDirEntrySlongArray
- TIFFReadDirEntryLong8Array
- TIFFReadDirEntrySlong8Array
- TIFFReadDirEntryFloatArray
- TIFFReadDirEntryDoubleArray
- TIFFReadDirEntryIfd8Array
- TIFFReadDirEntryPersampleShort
- TIFFReadDirEntryPersampleDouble
- TIFFReadDirEntryCheckedByte
- TIFFReadDirEntryCheckedSbyte
- TIFFReadDirEntryCheckedShort
- TIFFReadDirEntryCheckedSshort
- TIFFReadDirEntryCheckedLong
- TIFFReadDirEntryCheckedSlong
- TIFFReadDirEntryCheckedLong8
- TIFFReadDirEntryCheckedSlong8
- TIFFReadDirEntryCheckedRational
- TIFFReadDirEntryCheckedSrational
- TIFFReadDirEntryCheckedFloat
- TIFFReadDirEntryCheckedDouble
- TIFFReadDirEntryCheckRangeByteSbyte
- TIFFReadDirEntryCheckRangeByteShort
- TIFFReadDirEntryCheckRangeByteSshort
- TIFFReadDirEntryCheckRangeByteLong
- TIFFReadDirEntryCheckRangeByteSlong
- TIFFReadDirEntryCheckRangeByteLong8
- TIFFReadDirEntryCheckRangeByteSlong8
- TIFFReadDirEntryCheckRangeSbyteByte
- TIFFReadDirEntryCheckRangeSbyteShort
- TIFFReadDirEntryCheckRangeSbyteSshort
- TIFFReadDirEntryCheckRangeSbyteLong
- TIFFReadDirEntryCheckRangeSbyteSlong
- TIFFReadDirEntryCheckRangeSbyteLong8
- TIFFReadDirEntryCheckRangeSbyteSlong8
- TIFFReadDirEntryCheckRangeShortSbyte
- TIFFReadDirEntryCheckRangeShortSshort
- TIFFReadDirEntryCheckRangeShortLong
- TIFFReadDirEntryCheckRangeShortSlong
- TIFFReadDirEntryCheckRangeShortLong8
- TIFFReadDirEntryCheckRangeShortSlong8
- TIFFReadDirEntryCheckRangeSshortShort
- TIFFReadDirEntryCheckRangeSshortLong
- TIFFReadDirEntryCheckRangeSshortSlong
- TIFFReadDirEntryCheckRangeSshortLong8
- TIFFReadDirEntryCheckRangeSshortSlong8
- TIFFReadDirEntryCheckRangeLongSbyte
- TIFFReadDirEntryCheckRangeLongSshort
- TIFFReadDirEntryCheckRangeLongSlong
- TIFFReadDirEntryCheckRangeLongLong8
- TIFFReadDirEntryCheckRangeLongSlong8
- TIFFReadDirEntryCheckRangeSlongLong
- TIFFReadDirEntryCheckRangeSlongLong8
- TIFFReadDirEntryCheckRangeSlongSlong8
- TIFFReadDirEntryCheckRangeLong8Sbyte
- TIFFReadDirEntryCheckRangeLong8Sshort
- TIFFReadDirEntryCheckRangeLong8Slong
- TIFFReadDirEntryCheckRangeLong8Slong8
- TIFFReadDirEntryCheckRangeSlong8Long8
- TIFFReadDirEntryData
- TIFFReadDirEntryOutputErr
- TIFFReadDirectory
- TIFFReadDirectoryCheckOrder
- TIFFReadDirectoryFindEntry
- TIFFReadDirectoryFindFieldInfo
- TIFFReadCustomDirectory
- TIFFReadEXIFDirectory
- EstimateStripByteCounts
- MissingRequired
- TIFFCheckDirOffset
- CheckDirCount
- TIFFFetchDirectory
- TIFFFetchNormalTag
- TIFFFetchStripThing
- TIFFFetchSubjectDistance
- ChopUpSingleUncompressedStrip
- _TIFFFillStriles
#include "tiffiop.h"
#define IGNORE 0
#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;
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)
*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)
*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;
if ((uint64)(2147483647/typesize)<direntry->tdir_count)
return(TIFFReadDirEntryErrSizesan);
if ((uint64)(2147483647/desttypesize)<direntry->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; 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 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; 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 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);
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; 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)
*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++)
*mb++=(float)(*ma++);
}
break;
}
_TIFFfree(origdata);
if (err!=TIFFReadDirEntryErrOk)
{
_TIFFfree(data);
return(err);
}
*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)
*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);
if (err!=TIFFReadDirEntryErrOk)
{
_TIFFfree(data);
return(err);
}
*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);
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;
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);
}
#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);
}
#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 {
tmsize_t ma,mb;
ma=(tmsize_t)offset;
mb=ma+size;
if (((uint64)ma!=offset)||(mb<ma)||(mb<size)||(mb>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);
break;
}
} else {
switch (err) {
case TIFFReadDirEntryErrCount:
TIFFErrorExt(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);
break;
}
}
}
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;
tif->tif_diroff=tif->tif_nextdiroff;
if (!TIFFCheckDirOffset(tif,tif->tif_nextdiroff))
return 0;
(*tif->tif_cleanup)(tif);
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);
{
TIFFDirEntry* ma;
uint16 mb;
for (ma=dir, mb=0; mb<dircount; ma++, mb++)
{
TIFFDirEntry* na;
uint16 nb;
for (na=ma+1, nb=mb+1; nb<dircount; na++, nb++)
{
if (ma->tdir_tag==na->tdir_tag)
na->tdir_tag=IGNORE;
}
}
}
tif->tif_flags &= ~TIFF_BEENWRITING;
tif->tif_flags &= ~TIFF_BUF4WRITE;
TIFFFreeDirectory(tif);
TIFFDefaultDirectory(tif);
TIFFSetField(tif,TIFFTAG_PLANARCONFIG,PLANARCONFIG_CONTIG);
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)
{
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;
}
for (di=0, dp=dir; di<dircount; di++, dp++)
{
if (dp->tdir_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);
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;
}
}
}
}
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");
}
}
}
if (!TIFFFieldSet(tif,FIELD_IMAGEDIMENSIONS))
{
MissingRequired(tif,"ImageLength");
goto bad;
}
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)) {
TIFFSetFieldBit(tif, FIELD_STRIPOFFSETS);
} else {
MissingRequired(tif,
isTiled(tif) ? "TileOffsets" : "StripOffsets");
goto bad;
}
}
for (di=0, dp=dir; di<dircount; di++, dp++)
{
switch (dp->tdir_tag)
{
case IGNORE:
break;
case TIFFTAG_MINSAMPLEVALUE:
case TIFFTAG_MAXSAMPLEVALUE:
case TIFFTAG_BITSPERSAMPLE:
case TIFFTAG_DATATYPE:
case TIFFTAG_SAMPLEFORMAT:
{
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;
}
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;
countpersample=(1L<<tif->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;
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;
default:
(void) TIFFFetchNormalTag(tif, dp, TRUE);
break;
}
}
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))
{
if (!TIFFSetField(tif,TIFFTAG_SAMPLESPERPIXEL,1))
goto bad;
}
}
}
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;
}
}
if (tif->tif_dir.td_compression!=COMPRESSION_OJPEG)
{
if (!TIFFFieldSet(tif, FIELD_STRIPBYTECOUNTS)) {
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;
#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) {
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 ) {
TIFFWarningExt(tif->tif_clientdata, module,
"Wrong \"StripByteCounts\" field, ignoring and calculating from imagelength");
if (EstimateStripByteCounts(tif, dir, dircount) < 0)
goto bad;
#endif
}
}
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->tif_dir.td_bitspersample)-1);
}
#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
(*tif->tif_fixuptags)(tif);
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);
}
tif->tif_flags &= ~TIFF_DIRTYDIRECT;
tif->tif_flags &= ~TIFF_DIRTYSTRIP;
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; n<dircount; n++, o++)
{
if (o->tdir_tag<m)
{
TIFFWarningExt(tif->tif_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; n<dircount; m++, n++)
{
if (m->tdir_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;
}
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; di<dircount; di++, dp++)
{
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);
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
{
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
{
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;
}
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;
_TIFFFillStriles( tif );
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;
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;
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);
}
static int
TIFFCheckDirOffset(TIFF* tif, uint64 diroff)
{
uint16 n;
if (diroff == 0)
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;
new_dirlist = (uint64*)_TIFFCheckRealloc(tif, tif->tif_dirlist,
tif->tif_dirnumber, 2 * sizeof(uint64), "for IFD list");
if (!new_dirlist)
return 0;
tif->tif_dirlistsize = 2 * tif->tif_dirnumber;
tif->tif_dirlist = new_dirlist;
}
tif->tif_dirlist[tif->tif_dirnumber - 1] = diroff;
return 1;
}
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);
}
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;
}
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);
}
if (!(tif->tif_flags&TIFF_BIGTIFF))
{
m=off+sizeof(uint16);
if ((m<off)||(m<(tmsize_t)sizeof(uint16))||(m>tif->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 ((m<off)||(m<(tmsize_t)sizeof(uint64))||(m>tif->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 ((m<off)||(m<(tmsize_t)(dircount16*dirsize))||(m>tif->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 ((m<off)||(m<(tmsize_t)sizeof(uint32))||(m>tif->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 ((m<off)||(m<(tmsize_t)sizeof(uint64))||(m>tif->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; n<dircount16; n++)
{
if (tif->tif_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;
}
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->set_field_type!=TIFF_SETGET_OTHER);
assert(fip->set_field_type!=TIFF_SETGET_INT);
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;
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)
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)
;
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)
;
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)
;
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)
;
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);
break;
}
if (err!=TIFFReadDirEntryErrOk)
{
TIFFReadDirEntryOutputErr(tif,err,module,fip ? fip->field_name : "unknown tagname",recover);
return(0);
}
return(1);
}
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);
}
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)
n=-1.0;
else
n=(double)m.i[0]/(double)m.i[1];
return(TIFFSetField(tif,dir->tdir_tag,n));
}
else
{
TIFFReadDirEntryOutputErr(tif,err,module,"SubjectDistance",TRUE);
return(0);
}
}
static void
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);
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;
if (rowsperstrip >= td->td_rowsperstrip)
return;
nstrips64 = TIFFhowmany_64(bytecount, stripbytes);
if ((nstrips64==0)||(nstrips64>0xFFFFFFFF))
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) {
if (newcounts != NULL)
_TIFFfree(newcounts);
if (newoffsets != NULL)
_TIFFfree(newoffsets);
return;
}
for (strip = 0; strip < nstrips32; strip++) {
if (stripbytes > bytecount)
stripbytes = bytecount;
newcounts[strip] = stripbytes;
newoffsets[strip] = offset;
offset += stripbytes;
bytecount -= stripbytes;
}
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
(void) tif;
return 1;
#endif
}