5601 lines
		
	
	
		
			136 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			5601 lines
		
	
	
		
			136 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
/* $Id: tif_dirread.c,v 1.174 2012-02-01 02:24:47 fwarmerdam Exp $ */
 | 
						|
 | 
						|
/*
 | 
						|
 * Copyright (c) 1988-1997 Sam Leffler
 | 
						|
 * Copyright (c) 1991-1997 Silicon Graphics, Inc.
 | 
						|
 *
 | 
						|
 * Permission to use, copy, modify, distribute, and sell this software and
 | 
						|
 * its documentation for any purpose is hereby granted without fee, provided
 | 
						|
 * that (i) the above copyright notices and this permission notice appear in
 | 
						|
 * all copies of the software and related documentation, and (ii) the names of
 | 
						|
 * Sam Leffler and Silicon Graphics may not be used in any advertising or
 | 
						|
 * publicity relating to the software without the specific, prior written
 | 
						|
 * permission of Sam Leffler and Silicon Graphics.
 | 
						|
 *
 | 
						|
 * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND,
 | 
						|
 * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY
 | 
						|
 * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
 | 
						|
 *
 | 
						|
 * IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR
 | 
						|
 * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND,
 | 
						|
 * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
 | 
						|
 * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF
 | 
						|
 * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
 | 
						|
 * OF THIS SOFTWARE.
 | 
						|
 */
 | 
						|
 | 
						|
/*
 | 
						|
 * TIFF Library.
 | 
						|
 *
 | 
						|
 * Directory Read Support Routines.
 | 
						|
 */
 | 
						|
 | 
						|
/* Suggested pending improvements:
 | 
						|
 * - add a field 'ignore' to the TIFFDirEntry structure, to flag status,
 | 
						|
 *   eliminating current use of the IGNORE value, and therefore eliminating
 | 
						|
 *   current irrational behaviour on tags with tag id code 0
 | 
						|
 * - add a field 'field_info' to the TIFFDirEntry structure, and set that with
 | 
						|
 *   the pointer to the appropriate TIFFField structure early on in
 | 
						|
 *   TIFFReadDirectory, so as to eliminate current possibly repetitive lookup.
 | 
						|
 */
 | 
						|
 | 
						|
#include "tiffiop.h"
 | 
						|
 | 
						|
#define IGNORE 0          /* tag placeholder used below */
 | 
						|
#define FAILED_FII    ((uint32) -1)
 | 
						|
 | 
						|
#ifdef HAVE_IEEEFP
 | 
						|
# define TIFFCvtIEEEFloatToNative(tif, n, fp)
 | 
						|
# define TIFFCvtIEEEDoubleToNative(tif, n, dp)
 | 
						|
#else
 | 
						|
extern void TIFFCvtIEEEFloatToNative(TIFF*, uint32, float*);
 | 
						|
extern void TIFFCvtIEEEDoubleToNative(TIFF*, uint32, double*);
 | 
						|
#endif
 | 
						|
 | 
						|
enum TIFFReadDirEntryErr {
 | 
						|
	TIFFReadDirEntryErrOk = 0,
 | 
						|
	TIFFReadDirEntryErrCount = 1,
 | 
						|
	TIFFReadDirEntryErrType = 2,
 | 
						|
	TIFFReadDirEntryErrIo = 3,
 | 
						|
	TIFFReadDirEntryErrRange = 4,
 | 
						|
	TIFFReadDirEntryErrPsdif = 5,
 | 
						|
	TIFFReadDirEntryErrSizesan = 6,
 | 
						|
	TIFFReadDirEntryErrAlloc = 7,
 | 
						|
};
 | 
						|
 | 
						|
static enum TIFFReadDirEntryErr TIFFReadDirEntryByte(TIFF* tif, TIFFDirEntry* direntry, uint8* value);
 | 
						|
static enum TIFFReadDirEntryErr TIFFReadDirEntryShort(TIFF* tif, TIFFDirEntry* direntry, uint16* value);
 | 
						|
static enum TIFFReadDirEntryErr TIFFReadDirEntryLong(TIFF* tif, TIFFDirEntry* direntry, uint32* value);
 | 
						|
static enum TIFFReadDirEntryErr TIFFReadDirEntryLong8(TIFF* tif, TIFFDirEntry* direntry, uint64* value);
 | 
						|
static enum TIFFReadDirEntryErr TIFFReadDirEntryFloat(TIFF* tif, TIFFDirEntry* direntry, float* value);
 | 
						|
static enum TIFFReadDirEntryErr TIFFReadDirEntryDouble(TIFF* tif, TIFFDirEntry* direntry, double* value);
 | 
						|
static enum TIFFReadDirEntryErr TIFFReadDirEntryIfd8(TIFF* tif, TIFFDirEntry* direntry, uint64* value);
 | 
						|
 | 
						|
static enum TIFFReadDirEntryErr TIFFReadDirEntryArray(TIFF* tif, TIFFDirEntry* direntry, uint32* count, uint32 desttypesize, void** value);
 | 
						|
static enum TIFFReadDirEntryErr TIFFReadDirEntryByteArray(TIFF* tif, TIFFDirEntry* direntry, uint8** value);
 | 
						|
static enum TIFFReadDirEntryErr TIFFReadDirEntrySbyteArray(TIFF* tif, TIFFDirEntry* direntry, int8** value);
 | 
						|
static enum TIFFReadDirEntryErr TIFFReadDirEntryShortArray(TIFF* tif, TIFFDirEntry* direntry, uint16** value);
 | 
						|
static enum TIFFReadDirEntryErr TIFFReadDirEntrySshortArray(TIFF* tif, TIFFDirEntry* direntry, int16** value);
 | 
						|
static enum TIFFReadDirEntryErr TIFFReadDirEntryLongArray(TIFF* tif, TIFFDirEntry* direntry, uint32** value);
 | 
						|
static enum TIFFReadDirEntryErr TIFFReadDirEntrySlongArray(TIFF* tif, TIFFDirEntry* direntry, int32** value);
 | 
						|
static enum TIFFReadDirEntryErr TIFFReadDirEntryLong8Array(TIFF* tif, TIFFDirEntry* direntry, uint64** value);
 | 
						|
static enum TIFFReadDirEntryErr TIFFReadDirEntrySlong8Array(TIFF* tif, TIFFDirEntry* direntry, int64** value);
 | 
						|
static enum TIFFReadDirEntryErr TIFFReadDirEntryFloatArray(TIFF* tif, TIFFDirEntry* direntry, float** value);
 | 
						|
static enum TIFFReadDirEntryErr TIFFReadDirEntryDoubleArray(TIFF* tif, TIFFDirEntry* direntry, double** value);
 | 
						|
static enum TIFFReadDirEntryErr TIFFReadDirEntryIfd8Array(TIFF* tif, TIFFDirEntry* direntry, uint64** value);
 | 
						|
 | 
						|
static enum TIFFReadDirEntryErr TIFFReadDirEntryPersampleShort(TIFF* tif, TIFFDirEntry* direntry, uint16* value);
 | 
						|
#if 0
 | 
						|
static enum TIFFReadDirEntryErr TIFFReadDirEntryPersampleDouble(TIFF* tif, TIFFDirEntry* direntry, double* value);
 | 
						|
#endif
 | 
						|
 | 
						|
static void TIFFReadDirEntryCheckedByte(TIFF* tif, TIFFDirEntry* direntry, uint8* value);
 | 
						|
static void TIFFReadDirEntryCheckedSbyte(TIFF* tif, TIFFDirEntry* direntry, int8* value);
 | 
						|
static void TIFFReadDirEntryCheckedShort(TIFF* tif, TIFFDirEntry* direntry, uint16* value);
 | 
						|
static void TIFFReadDirEntryCheckedSshort(TIFF* tif, TIFFDirEntry* direntry, int16* value);
 | 
						|
static void TIFFReadDirEntryCheckedLong(TIFF* tif, TIFFDirEntry* direntry, uint32* value);
 | 
						|
static void TIFFReadDirEntryCheckedSlong(TIFF* tif, TIFFDirEntry* direntry, int32* value);
 | 
						|
static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckedLong8(TIFF* tif, TIFFDirEntry* direntry, uint64* value);
 | 
						|
static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckedSlong8(TIFF* tif, TIFFDirEntry* direntry, int64* value);
 | 
						|
static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckedRational(TIFF* tif, TIFFDirEntry* direntry, double* value);
 | 
						|
static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckedSrational(TIFF* tif, TIFFDirEntry* direntry, double* value);
 | 
						|
static void TIFFReadDirEntryCheckedFloat(TIFF* tif, TIFFDirEntry* direntry, float* value);
 | 
						|
static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckedDouble(TIFF* tif, TIFFDirEntry* direntry, double* value);
 | 
						|
 | 
						|
static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckRangeByteSbyte(int8 value);
 | 
						|
static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckRangeByteShort(uint16 value);
 | 
						|
static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckRangeByteSshort(int16 value);
 | 
						|
static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckRangeByteLong(uint32 value);
 | 
						|
static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckRangeByteSlong(int32 value);
 | 
						|
static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckRangeByteLong8(uint64 value);
 | 
						|
static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckRangeByteSlong8(int64 value);
 | 
						|
 | 
						|
static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckRangeSbyteByte(uint8 value);
 | 
						|
static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckRangeSbyteShort(uint16 value);
 | 
						|
static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckRangeSbyteSshort(int16 value);
 | 
						|
static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckRangeSbyteLong(uint32 value);
 | 
						|
static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckRangeSbyteSlong(int32 value);
 | 
						|
static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckRangeSbyteLong8(uint64 value);
 | 
						|
static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckRangeSbyteSlong8(int64 value);
 | 
						|
 | 
						|
static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckRangeShortSbyte(int8 value);
 | 
						|
static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckRangeShortSshort(int16 value);
 | 
						|
static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckRangeShortLong(uint32 value);
 | 
						|
static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckRangeShortSlong(int32 value);
 | 
						|
static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckRangeShortLong8(uint64 value);
 | 
						|
static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckRangeShortSlong8(int64 value);
 | 
						|
 | 
						|
static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckRangeSshortShort(uint16 value);
 | 
						|
static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckRangeSshortLong(uint32 value);
 | 
						|
static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckRangeSshortSlong(int32 value);
 | 
						|
static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckRangeSshortLong8(uint64 value);
 | 
						|
static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckRangeSshortSlong8(int64 value);
 | 
						|
 | 
						|
static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckRangeLongSbyte(int8 value);
 | 
						|
static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckRangeLongSshort(int16 value);
 | 
						|
static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckRangeLongSlong(int32 value);
 | 
						|
static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckRangeLongLong8(uint64 value);
 | 
						|
static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckRangeLongSlong8(int64 value);
 | 
						|
 | 
						|
static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckRangeSlongLong(uint32 value);
 | 
						|
static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckRangeSlongLong8(uint64 value);
 | 
						|
static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckRangeSlongSlong8(int64 value);
 | 
						|
 | 
						|
static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckRangeLong8Sbyte(int8 value);
 | 
						|
static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckRangeLong8Sshort(int16 value);
 | 
						|
static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckRangeLong8Slong(int32 value);
 | 
						|
static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckRangeLong8Slong8(int64 value);
 | 
						|
 | 
						|
static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckRangeSlong8Long8(uint64 value);
 | 
						|
 | 
						|
static enum TIFFReadDirEntryErr TIFFReadDirEntryData(TIFF* tif, uint64 offset, tmsize_t size, void* dest);
 | 
						|
static void TIFFReadDirEntryOutputErr(TIFF* tif, enum TIFFReadDirEntryErr err, const char* module, const char* tagname, int recover);
 | 
						|
 | 
						|
static void TIFFReadDirectoryCheckOrder(TIFF* tif, TIFFDirEntry* dir, uint16 dircount);
 | 
						|
static TIFFDirEntry* TIFFReadDirectoryFindEntry(TIFF* tif, TIFFDirEntry* dir, uint16 dircount, uint16 tagid);
 | 
						|
static void TIFFReadDirectoryFindFieldInfo(TIFF* tif, uint16 tagid, uint32* fii);
 | 
						|
 | 
						|
static int EstimateStripByteCounts(TIFF* tif, TIFFDirEntry* dir, uint16 dircount);
 | 
						|
static void MissingRequired(TIFF*, const char*);
 | 
						|
static int TIFFCheckDirOffset(TIFF* tif, uint64 diroff);
 | 
						|
static int CheckDirCount(TIFF*, TIFFDirEntry*, uint32);
 | 
						|
static uint16 TIFFFetchDirectory(TIFF* tif, uint64 diroff, TIFFDirEntry** pdir, uint64* nextdiroff);
 | 
						|
static int TIFFFetchNormalTag(TIFF*, TIFFDirEntry*, int recover);
 | 
						|
static int TIFFFetchStripThing(TIFF* tif, TIFFDirEntry* dir, uint32 nstrips, uint64** lpp);
 | 
						|
static int TIFFFetchSubjectDistance(TIFF*, TIFFDirEntry*);
 | 
						|
static void ChopUpSingleUncompressedStrip(TIFF*);
 | 
						|
static uint64 TIFFReadUInt64(const uint8 *value);
 | 
						|
 | 
						|
typedef union _UInt64Aligned_t
 | 
						|
{
 | 
						|
        double d;
 | 
						|
	uint64 l;
 | 
						|
	uint32 i[2];
 | 
						|
	uint16 s[4];
 | 
						|
	uint8  c[8];
 | 
						|
} UInt64Aligned_t;
 | 
						|
 | 
						|
/*
 | 
						|
  Unaligned safe copy of a uint64 value from an octet array.
 | 
						|
*/
 | 
						|
static uint64 TIFFReadUInt64(const uint8 *value)
 | 
						|
{
 | 
						|
	UInt64Aligned_t result;
 | 
						|
 | 
						|
	result.c[0]=value[0];
 | 
						|
	result.c[1]=value[1];
 | 
						|
	result.c[2]=value[2];
 | 
						|
	result.c[3]=value[3];
 | 
						|
	result.c[4]=value[4];
 | 
						|
	result.c[5]=value[5];
 | 
						|
	result.c[6]=value[6];
 | 
						|
	result.c[7]=value[7];
 | 
						|
 | 
						|
	return result.l;
 | 
						|
}
 | 
						|
 | 
						|
static enum TIFFReadDirEntryErr TIFFReadDirEntryByte(TIFF* tif, TIFFDirEntry* direntry, uint8* value)
 | 
						|
{
 | 
						|
	enum TIFFReadDirEntryErr err;
 | 
						|
	if (direntry->tdir_count!=1)
 | 
						|
		return(TIFFReadDirEntryErrCount);
 | 
						|
	switch (direntry->tdir_type)
 | 
						|
	{
 | 
						|
		case TIFF_BYTE:
 | 
						|
			TIFFReadDirEntryCheckedByte(tif,direntry,value);
 | 
						|
			return(TIFFReadDirEntryErrOk);
 | 
						|
		case TIFF_SBYTE:
 | 
						|
			{
 | 
						|
				int8 m;
 | 
						|
				TIFFReadDirEntryCheckedSbyte(tif,direntry,&m);
 | 
						|
				err=TIFFReadDirEntryCheckRangeByteSbyte(m);
 | 
						|
				if (err!=TIFFReadDirEntryErrOk)
 | 
						|
					return(err);
 | 
						|
				*value=(uint8)m;
 | 
						|
				return(TIFFReadDirEntryErrOk);
 | 
						|
			}
 | 
						|
		case TIFF_SHORT:
 | 
						|
			{
 | 
						|
				uint16 m;
 | 
						|
				TIFFReadDirEntryCheckedShort(tif,direntry,&m);
 | 
						|
				err=TIFFReadDirEntryCheckRangeByteShort(m);
 | 
						|
				if (err!=TIFFReadDirEntryErrOk)
 | 
						|
					return(err);
 | 
						|
				*value=(uint8)m;
 | 
						|
				return(TIFFReadDirEntryErrOk);
 | 
						|
			}
 | 
						|
		case TIFF_SSHORT:
 | 
						|
			{
 | 
						|
				int16 m;
 | 
						|
				TIFFReadDirEntryCheckedSshort(tif,direntry,&m);
 | 
						|
				err=TIFFReadDirEntryCheckRangeByteSshort(m);
 | 
						|
				if (err!=TIFFReadDirEntryErrOk)
 | 
						|
					return(err);
 | 
						|
				*value=(uint8)m;
 | 
						|
				return(TIFFReadDirEntryErrOk);
 | 
						|
			}
 | 
						|
		case TIFF_LONG:
 | 
						|
			{
 | 
						|
				uint32 m;
 | 
						|
				TIFFReadDirEntryCheckedLong(tif,direntry,&m);
 | 
						|
				err=TIFFReadDirEntryCheckRangeByteLong(m);
 | 
						|
				if (err!=TIFFReadDirEntryErrOk)
 | 
						|
					return(err);
 | 
						|
				*value=(uint8)m;
 | 
						|
				return(TIFFReadDirEntryErrOk);
 | 
						|
			}
 | 
						|
		case TIFF_SLONG:
 | 
						|
			{
 | 
						|
				int32 m;
 | 
						|
				TIFFReadDirEntryCheckedSlong(tif,direntry,&m);
 | 
						|
				err=TIFFReadDirEntryCheckRangeByteSlong(m);
 | 
						|
				if (err!=TIFFReadDirEntryErrOk)
 | 
						|
					return(err);
 | 
						|
				*value=(uint8)m;
 | 
						|
				return(TIFFReadDirEntryErrOk);
 | 
						|
			}
 | 
						|
		case TIFF_LONG8:
 | 
						|
			{
 | 
						|
				uint64 m;
 | 
						|
				err=TIFFReadDirEntryCheckedLong8(tif,direntry,&m);
 | 
						|
				if (err!=TIFFReadDirEntryErrOk)
 | 
						|
					return(err);
 | 
						|
				err=TIFFReadDirEntryCheckRangeByteLong8(m);
 | 
						|
				if (err!=TIFFReadDirEntryErrOk)
 | 
						|
					return(err);
 | 
						|
				*value=(uint8)m;
 | 
						|
				return(TIFFReadDirEntryErrOk);
 | 
						|
			}
 | 
						|
		case TIFF_SLONG8:
 | 
						|
			{
 | 
						|
				int64 m;
 | 
						|
				err=TIFFReadDirEntryCheckedSlong8(tif,direntry,&m);
 | 
						|
				if (err!=TIFFReadDirEntryErrOk)
 | 
						|
					return(err);
 | 
						|
				err=TIFFReadDirEntryCheckRangeByteSlong8(m);
 | 
						|
				if (err!=TIFFReadDirEntryErrOk)
 | 
						|
					return(err);
 | 
						|
				*value=(uint8)m;
 | 
						|
				return(TIFFReadDirEntryErrOk);
 | 
						|
			}
 | 
						|
		default:
 | 
						|
			return(TIFFReadDirEntryErrType);
 | 
						|
	}
 | 
						|
}
 | 
						|
 | 
						|
static enum TIFFReadDirEntryErr TIFFReadDirEntryShort(TIFF* tif, TIFFDirEntry* direntry, uint16* value)
 | 
						|
{
 | 
						|
	enum TIFFReadDirEntryErr err;
 | 
						|
	if (direntry->tdir_count!=1)
 | 
						|
		return(TIFFReadDirEntryErrCount);
 | 
						|
	switch (direntry->tdir_type)
 | 
						|
	{
 | 
						|
		case TIFF_BYTE:
 | 
						|
			{
 | 
						|
				uint8 m;
 | 
						|
				TIFFReadDirEntryCheckedByte(tif,direntry,&m);
 | 
						|
				*value=(uint16)m;
 | 
						|
				return(TIFFReadDirEntryErrOk);
 | 
						|
			}
 | 
						|
		case TIFF_SBYTE:
 | 
						|
			{
 | 
						|
				int8 m;
 | 
						|
				TIFFReadDirEntryCheckedSbyte(tif,direntry,&m);
 | 
						|
				err=TIFFReadDirEntryCheckRangeShortSbyte(m);
 | 
						|
				if (err!=TIFFReadDirEntryErrOk)
 | 
						|
					return(err);
 | 
						|
				*value=(uint16)m;
 | 
						|
				return(TIFFReadDirEntryErrOk);
 | 
						|
			}
 | 
						|
		case TIFF_SHORT:
 | 
						|
			TIFFReadDirEntryCheckedShort(tif,direntry,value);
 | 
						|
			return(TIFFReadDirEntryErrOk);
 | 
						|
		case TIFF_SSHORT:
 | 
						|
			{
 | 
						|
				int16 m;
 | 
						|
				TIFFReadDirEntryCheckedSshort(tif,direntry,&m);
 | 
						|
				err=TIFFReadDirEntryCheckRangeShortSshort(m);
 | 
						|
				if (err!=TIFFReadDirEntryErrOk)
 | 
						|
					return(err);
 | 
						|
				*value=(uint16)m;
 | 
						|
				return(TIFFReadDirEntryErrOk);
 | 
						|
			}
 | 
						|
		case TIFF_LONG:
 | 
						|
			{
 | 
						|
				uint32 m;
 | 
						|
				TIFFReadDirEntryCheckedLong(tif,direntry,&m);
 | 
						|
				err=TIFFReadDirEntryCheckRangeShortLong(m);
 | 
						|
				if (err!=TIFFReadDirEntryErrOk)
 | 
						|
					return(err);
 | 
						|
				*value=(uint16)m;
 | 
						|
				return(TIFFReadDirEntryErrOk);
 | 
						|
			}
 | 
						|
		case TIFF_SLONG:
 | 
						|
			{
 | 
						|
				int32 m;
 | 
						|
				TIFFReadDirEntryCheckedSlong(tif,direntry,&m);
 | 
						|
				err=TIFFReadDirEntryCheckRangeShortSlong(m);
 | 
						|
				if (err!=TIFFReadDirEntryErrOk)
 | 
						|
					return(err);
 | 
						|
				*value=(uint16)m;
 | 
						|
				return(TIFFReadDirEntryErrOk);
 | 
						|
			}
 | 
						|
		case TIFF_LONG8:
 | 
						|
			{
 | 
						|
				uint64 m;
 | 
						|
				err=TIFFReadDirEntryCheckedLong8(tif,direntry,&m);
 | 
						|
				if (err!=TIFFReadDirEntryErrOk)
 | 
						|
					return(err);
 | 
						|
				err=TIFFReadDirEntryCheckRangeShortLong8(m);
 | 
						|
				if (err!=TIFFReadDirEntryErrOk)
 | 
						|
					return(err);
 | 
						|
				*value=(uint16)m;
 | 
						|
				return(TIFFReadDirEntryErrOk);
 | 
						|
			}
 | 
						|
		case TIFF_SLONG8:
 | 
						|
			{
 | 
						|
				int64 m;
 | 
						|
				err=TIFFReadDirEntryCheckedSlong8(tif,direntry,&m);
 | 
						|
				if (err!=TIFFReadDirEntryErrOk)
 | 
						|
					return(err);
 | 
						|
				err=TIFFReadDirEntryCheckRangeShortSlong8(m);
 | 
						|
				if (err!=TIFFReadDirEntryErrOk)
 | 
						|
					return(err);
 | 
						|
				*value=(uint16)m;
 | 
						|
				return(TIFFReadDirEntryErrOk);
 | 
						|
			}
 | 
						|
		default:
 | 
						|
			return(TIFFReadDirEntryErrType);
 | 
						|
	}
 | 
						|
}
 | 
						|
 | 
						|
static enum TIFFReadDirEntryErr TIFFReadDirEntryLong(TIFF* tif, TIFFDirEntry* direntry, uint32* value)
 | 
						|
{
 | 
						|
	enum TIFFReadDirEntryErr err;
 | 
						|
	if (direntry->tdir_count!=1)
 | 
						|
		return(TIFFReadDirEntryErrCount);
 | 
						|
	switch (direntry->tdir_type)
 | 
						|
	{
 | 
						|
		case TIFF_BYTE:
 | 
						|
			{
 | 
						|
				uint8 m;
 | 
						|
				TIFFReadDirEntryCheckedByte(tif,direntry,&m);
 | 
						|
				*value=(uint32)m;
 | 
						|
				return(TIFFReadDirEntryErrOk);
 | 
						|
			}
 | 
						|
		case TIFF_SBYTE:
 | 
						|
			{
 | 
						|
				int8 m;
 | 
						|
				TIFFReadDirEntryCheckedSbyte(tif,direntry,&m);
 | 
						|
				err=TIFFReadDirEntryCheckRangeLongSbyte(m);
 | 
						|
				if (err!=TIFFReadDirEntryErrOk)
 | 
						|
					return(err);
 | 
						|
				*value=(uint32)m;
 | 
						|
				return(TIFFReadDirEntryErrOk);
 | 
						|
			}
 | 
						|
		case TIFF_SHORT:
 | 
						|
			{
 | 
						|
				uint16 m;
 | 
						|
				TIFFReadDirEntryCheckedShort(tif,direntry,&m);
 | 
						|
				*value=(uint32)m;
 | 
						|
				return(TIFFReadDirEntryErrOk);
 | 
						|
			}
 | 
						|
		case TIFF_SSHORT:
 | 
						|
			{
 | 
						|
				int16 m;
 | 
						|
				TIFFReadDirEntryCheckedSshort(tif,direntry,&m);
 | 
						|
				err=TIFFReadDirEntryCheckRangeLongSshort(m);
 | 
						|
				if (err!=TIFFReadDirEntryErrOk)
 | 
						|
					return(err);
 | 
						|
				*value=(uint32)m;
 | 
						|
				return(TIFFReadDirEntryErrOk);
 | 
						|
			}
 | 
						|
		case TIFF_LONG:
 | 
						|
			TIFFReadDirEntryCheckedLong(tif,direntry,value);
 | 
						|
			return(TIFFReadDirEntryErrOk);
 | 
						|
		case TIFF_SLONG:
 | 
						|
			{
 | 
						|
				int32 m;
 | 
						|
				TIFFReadDirEntryCheckedSlong(tif,direntry,&m);
 | 
						|
				err=TIFFReadDirEntryCheckRangeLongSlong(m);
 | 
						|
				if (err!=TIFFReadDirEntryErrOk)
 | 
						|
					return(err);
 | 
						|
				*value=(uint32)m;
 | 
						|
				return(TIFFReadDirEntryErrOk);
 | 
						|
			}
 | 
						|
		case TIFF_LONG8:
 | 
						|
			{
 | 
						|
				uint64 m;
 | 
						|
				err=TIFFReadDirEntryCheckedLong8(tif,direntry,&m);
 | 
						|
				if (err!=TIFFReadDirEntryErrOk)
 | 
						|
					return(err);
 | 
						|
				err=TIFFReadDirEntryCheckRangeLongLong8(m);
 | 
						|
				if (err!=TIFFReadDirEntryErrOk)
 | 
						|
					return(err);
 | 
						|
				*value=(uint32)m;
 | 
						|
				return(TIFFReadDirEntryErrOk);
 | 
						|
			}
 | 
						|
		case TIFF_SLONG8:
 | 
						|
			{
 | 
						|
				int64 m;
 | 
						|
				err=TIFFReadDirEntryCheckedSlong8(tif,direntry,&m);
 | 
						|
				if (err!=TIFFReadDirEntryErrOk)
 | 
						|
					return(err);
 | 
						|
				err=TIFFReadDirEntryCheckRangeLongSlong8(m);
 | 
						|
				if (err!=TIFFReadDirEntryErrOk)
 | 
						|
					return(err);
 | 
						|
				*value=(uint32)m;
 | 
						|
				return(TIFFReadDirEntryErrOk);
 | 
						|
			}
 | 
						|
		default:
 | 
						|
			return(TIFFReadDirEntryErrType);
 | 
						|
	}
 | 
						|
}
 | 
						|
 | 
						|
static enum TIFFReadDirEntryErr TIFFReadDirEntryLong8(TIFF* tif, TIFFDirEntry* direntry, uint64* value)
 | 
						|
{
 | 
						|
	enum TIFFReadDirEntryErr err;
 | 
						|
	if (direntry->tdir_count!=1)
 | 
						|
		return(TIFFReadDirEntryErrCount);
 | 
						|
	switch (direntry->tdir_type)
 | 
						|
	{
 | 
						|
		case TIFF_BYTE:
 | 
						|
			{
 | 
						|
				uint8 m;
 | 
						|
				TIFFReadDirEntryCheckedByte(tif,direntry,&m);
 | 
						|
				*value=(uint64)m;
 | 
						|
				return(TIFFReadDirEntryErrOk);
 | 
						|
			}
 | 
						|
		case TIFF_SBYTE:
 | 
						|
			{
 | 
						|
				int8 m;
 | 
						|
				TIFFReadDirEntryCheckedSbyte(tif,direntry,&m);
 | 
						|
				err=TIFFReadDirEntryCheckRangeLong8Sbyte(m);
 | 
						|
				if (err!=TIFFReadDirEntryErrOk)
 | 
						|
					return(err);
 | 
						|
				*value=(uint64)m;
 | 
						|
				return(TIFFReadDirEntryErrOk);
 | 
						|
			}
 | 
						|
		case TIFF_SHORT:
 | 
						|
			{
 | 
						|
				uint16 m;
 | 
						|
				TIFFReadDirEntryCheckedShort(tif,direntry,&m);
 | 
						|
				*value=(uint64)m;
 | 
						|
				return(TIFFReadDirEntryErrOk);
 | 
						|
			}
 | 
						|
		case TIFF_SSHORT:
 | 
						|
			{
 | 
						|
				int16 m;
 | 
						|
				TIFFReadDirEntryCheckedSshort(tif,direntry,&m);
 | 
						|
				err=TIFFReadDirEntryCheckRangeLong8Sshort(m);
 | 
						|
				if (err!=TIFFReadDirEntryErrOk)
 | 
						|
					return(err);
 | 
						|
				*value=(uint64)m;
 | 
						|
				return(TIFFReadDirEntryErrOk);
 | 
						|
			}
 | 
						|
		case TIFF_LONG:
 | 
						|
			{
 | 
						|
				uint32 m;
 | 
						|
				TIFFReadDirEntryCheckedLong(tif,direntry,&m);
 | 
						|
				*value=(uint64)m;
 | 
						|
				return(TIFFReadDirEntryErrOk);
 | 
						|
			}
 | 
						|
		case TIFF_SLONG:
 | 
						|
			{
 | 
						|
				int32 m;
 | 
						|
				TIFFReadDirEntryCheckedSlong(tif,direntry,&m);
 | 
						|
				err=TIFFReadDirEntryCheckRangeLong8Slong(m);
 | 
						|
				if (err!=TIFFReadDirEntryErrOk)
 | 
						|
					return(err);
 | 
						|
				*value=(uint64)m;
 | 
						|
				return(TIFFReadDirEntryErrOk);
 | 
						|
			}
 | 
						|
		case TIFF_LONG8:
 | 
						|
			err=TIFFReadDirEntryCheckedLong8(tif,direntry,value);
 | 
						|
			return(err);
 | 
						|
		case TIFF_SLONG8:
 | 
						|
			{
 | 
						|
				int64 m;
 | 
						|
				err=TIFFReadDirEntryCheckedSlong8(tif,direntry,&m);
 | 
						|
				if (err!=TIFFReadDirEntryErrOk)
 | 
						|
					return(err);
 | 
						|
				err=TIFFReadDirEntryCheckRangeLong8Slong8(m);
 | 
						|
				if (err!=TIFFReadDirEntryErrOk)
 | 
						|
					return(err);
 | 
						|
				*value=(uint64)m;
 | 
						|
				return(TIFFReadDirEntryErrOk);
 | 
						|
			}
 | 
						|
		default:
 | 
						|
			return(TIFFReadDirEntryErrType);
 | 
						|
	}
 | 
						|
}
 | 
						|
 | 
						|
static enum TIFFReadDirEntryErr TIFFReadDirEntryFloat(TIFF* tif, TIFFDirEntry* direntry, float* value)
 | 
						|
{
 | 
						|
	enum TIFFReadDirEntryErr err;
 | 
						|
	if (direntry->tdir_count!=1)
 | 
						|
		return(TIFFReadDirEntryErrCount);
 | 
						|
	switch (direntry->tdir_type)
 | 
						|
	{
 | 
						|
		case TIFF_BYTE:
 | 
						|
			{
 | 
						|
				uint8 m;
 | 
						|
				TIFFReadDirEntryCheckedByte(tif,direntry,&m);
 | 
						|
				*value=(float)m;
 | 
						|
				return(TIFFReadDirEntryErrOk);
 | 
						|
			}
 | 
						|
		case TIFF_SBYTE:
 | 
						|
			{
 | 
						|
				int8 m;
 | 
						|
				TIFFReadDirEntryCheckedSbyte(tif,direntry,&m);
 | 
						|
				*value=(float)m;
 | 
						|
				return(TIFFReadDirEntryErrOk);
 | 
						|
			}
 | 
						|
		case TIFF_SHORT:
 | 
						|
			{
 | 
						|
				uint16 m;
 | 
						|
				TIFFReadDirEntryCheckedShort(tif,direntry,&m);
 | 
						|
				*value=(float)m;
 | 
						|
				return(TIFFReadDirEntryErrOk);
 | 
						|
			}
 | 
						|
		case TIFF_SSHORT:
 | 
						|
			{
 | 
						|
				int16 m;
 | 
						|
				TIFFReadDirEntryCheckedSshort(tif,direntry,&m);
 | 
						|
				*value=(float)m;
 | 
						|
				return(TIFFReadDirEntryErrOk);
 | 
						|
			}
 | 
						|
		case TIFF_LONG:
 | 
						|
			{
 | 
						|
				uint32 m;
 | 
						|
				TIFFReadDirEntryCheckedLong(tif,direntry,&m);
 | 
						|
				*value=(float)m;
 | 
						|
				return(TIFFReadDirEntryErrOk);
 | 
						|
			}
 | 
						|
		case TIFF_SLONG:
 | 
						|
			{
 | 
						|
				int32 m;
 | 
						|
				TIFFReadDirEntryCheckedSlong(tif,direntry,&m);
 | 
						|
				*value=(float)m;
 | 
						|
				return(TIFFReadDirEntryErrOk);
 | 
						|
			}
 | 
						|
		case TIFF_LONG8:
 | 
						|
			{
 | 
						|
				uint64 m;
 | 
						|
				err=TIFFReadDirEntryCheckedLong8(tif,direntry,&m);
 | 
						|
				if (err!=TIFFReadDirEntryErrOk)
 | 
						|
					return(err);
 | 
						|
#if defined(__WIN32__) && (_MSC_VER < 1500)
 | 
						|
				/*
 | 
						|
				 * XXX: MSVC 6.0 does not support conversion
 | 
						|
				 * of 64-bit integers into floating point
 | 
						|
				 * values.
 | 
						|
				 */
 | 
						|
				*value = _TIFFUInt64ToFloat(m);
 | 
						|
#else
 | 
						|
				*value=(float)m;
 | 
						|
#endif
 | 
						|
				return(TIFFReadDirEntryErrOk);
 | 
						|
			}
 | 
						|
		case TIFF_SLONG8:
 | 
						|
			{
 | 
						|
				int64 m;
 | 
						|
				err=TIFFReadDirEntryCheckedSlong8(tif,direntry,&m);
 | 
						|
				if (err!=TIFFReadDirEntryErrOk)
 | 
						|
					return(err);
 | 
						|
				*value=(float)m;
 | 
						|
				return(TIFFReadDirEntryErrOk);
 | 
						|
			}
 | 
						|
		case TIFF_RATIONAL:
 | 
						|
			{
 | 
						|
				double m;
 | 
						|
				err=TIFFReadDirEntryCheckedRational(tif,direntry,&m);
 | 
						|
				if (err!=TIFFReadDirEntryErrOk)
 | 
						|
					return(err);
 | 
						|
				*value=(float)m;
 | 
						|
				return(TIFFReadDirEntryErrOk);
 | 
						|
			}
 | 
						|
		case TIFF_SRATIONAL:
 | 
						|
			{
 | 
						|
				double m;
 | 
						|
				err=TIFFReadDirEntryCheckedSrational(tif,direntry,&m);
 | 
						|
				if (err!=TIFFReadDirEntryErrOk)
 | 
						|
					return(err);
 | 
						|
				*value=(float)m;
 | 
						|
				return(TIFFReadDirEntryErrOk);
 | 
						|
			}
 | 
						|
		case TIFF_FLOAT:
 | 
						|
			TIFFReadDirEntryCheckedFloat(tif,direntry,value);
 | 
						|
			return(TIFFReadDirEntryErrOk);
 | 
						|
		case TIFF_DOUBLE:
 | 
						|
			{
 | 
						|
				double m;
 | 
						|
				err=TIFFReadDirEntryCheckedDouble(tif,direntry,&m);
 | 
						|
				if (err!=TIFFReadDirEntryErrOk)
 | 
						|
					return(err);
 | 
						|
				*value=(float)m;
 | 
						|
				return(TIFFReadDirEntryErrOk);
 | 
						|
			}
 | 
						|
		default:
 | 
						|
			return(TIFFReadDirEntryErrType);
 | 
						|
	}
 | 
						|
}
 | 
						|
 | 
						|
static enum TIFFReadDirEntryErr TIFFReadDirEntryDouble(TIFF* tif, TIFFDirEntry* direntry, double* value)
 | 
						|
{
 | 
						|
	enum TIFFReadDirEntryErr err;
 | 
						|
	if (direntry->tdir_count!=1)
 | 
						|
		return(TIFFReadDirEntryErrCount);
 | 
						|
	switch (direntry->tdir_type)
 | 
						|
	{
 | 
						|
		case TIFF_BYTE:
 | 
						|
			{
 | 
						|
				uint8 m;
 | 
						|
				TIFFReadDirEntryCheckedByte(tif,direntry,&m);
 | 
						|
				*value=(double)m;
 | 
						|
				return(TIFFReadDirEntryErrOk);
 | 
						|
			}
 | 
						|
		case TIFF_SBYTE:
 | 
						|
			{
 | 
						|
				int8 m;
 | 
						|
				TIFFReadDirEntryCheckedSbyte(tif,direntry,&m);
 | 
						|
				*value=(double)m;
 | 
						|
				return(TIFFReadDirEntryErrOk);
 | 
						|
			}
 | 
						|
		case TIFF_SHORT:
 | 
						|
			{
 | 
						|
				uint16 m;
 | 
						|
				TIFFReadDirEntryCheckedShort(tif,direntry,&m);
 | 
						|
				*value=(double)m;
 | 
						|
				return(TIFFReadDirEntryErrOk);
 | 
						|
			}
 | 
						|
		case TIFF_SSHORT:
 | 
						|
			{
 | 
						|
				int16 m;
 | 
						|
				TIFFReadDirEntryCheckedSshort(tif,direntry,&m);
 | 
						|
				*value=(double)m;
 | 
						|
				return(TIFFReadDirEntryErrOk);
 | 
						|
			}
 | 
						|
		case TIFF_LONG:
 | 
						|
			{
 | 
						|
				uint32 m;
 | 
						|
				TIFFReadDirEntryCheckedLong(tif,direntry,&m);
 | 
						|
				*value=(double)m;
 | 
						|
				return(TIFFReadDirEntryErrOk);
 | 
						|
			}
 | 
						|
		case TIFF_SLONG:
 | 
						|
			{
 | 
						|
				int32 m;
 | 
						|
				TIFFReadDirEntryCheckedSlong(tif,direntry,&m);
 | 
						|
				*value=(double)m;
 | 
						|
				return(TIFFReadDirEntryErrOk);
 | 
						|
			}
 | 
						|
		case TIFF_LONG8:
 | 
						|
			{
 | 
						|
				uint64 m;
 | 
						|
				err=TIFFReadDirEntryCheckedLong8(tif,direntry,&m);
 | 
						|
				if (err!=TIFFReadDirEntryErrOk)
 | 
						|
					return(err);
 | 
						|
#if defined(__WIN32__) && (_MSC_VER < 1500)
 | 
						|
				/*
 | 
						|
				 * XXX: MSVC 6.0 does not support conversion
 | 
						|
				 * of 64-bit integers into floating point
 | 
						|
				 * values.
 | 
						|
				 */
 | 
						|
				*value = _TIFFUInt64ToDouble(m);
 | 
						|
#else
 | 
						|
				*value = (double)m;
 | 
						|
#endif
 | 
						|
				return(TIFFReadDirEntryErrOk);
 | 
						|
			}
 | 
						|
		case TIFF_SLONG8:
 | 
						|
			{
 | 
						|
				int64 m;
 | 
						|
				err=TIFFReadDirEntryCheckedSlong8(tif,direntry,&m);
 | 
						|
				if (err!=TIFFReadDirEntryErrOk)
 | 
						|
					return(err);
 | 
						|
				*value=(double)m;
 | 
						|
				return(TIFFReadDirEntryErrOk);
 | 
						|
			}
 | 
						|
		case TIFF_RATIONAL:
 | 
						|
			err=TIFFReadDirEntryCheckedRational(tif,direntry,value);
 | 
						|
			return(err);
 | 
						|
		case TIFF_SRATIONAL:
 | 
						|
			err=TIFFReadDirEntryCheckedSrational(tif,direntry,value);
 | 
						|
			return(err);
 | 
						|
		case TIFF_FLOAT:
 | 
						|
			{
 | 
						|
				float m;
 | 
						|
				TIFFReadDirEntryCheckedFloat(tif,direntry,&m);
 | 
						|
				*value=(double)m;
 | 
						|
				return(TIFFReadDirEntryErrOk);
 | 
						|
			}
 | 
						|
		case TIFF_DOUBLE:
 | 
						|
			err=TIFFReadDirEntryCheckedDouble(tif,direntry,value);
 | 
						|
			return(err);
 | 
						|
		default:
 | 
						|
			return(TIFFReadDirEntryErrType);
 | 
						|
	}
 | 
						|
}
 | 
						|
 | 
						|
static enum TIFFReadDirEntryErr TIFFReadDirEntryIfd8(TIFF* tif, TIFFDirEntry* direntry, uint64* value)
 | 
						|
{
 | 
						|
	enum TIFFReadDirEntryErr err;
 | 
						|
	if (direntry->tdir_count!=1)
 | 
						|
		return(TIFFReadDirEntryErrCount);
 | 
						|
	switch (direntry->tdir_type)
 | 
						|
	{
 | 
						|
		case TIFF_LONG:
 | 
						|
		case TIFF_IFD:
 | 
						|
			{
 | 
						|
				uint32 m;
 | 
						|
				TIFFReadDirEntryCheckedLong(tif,direntry,&m);
 | 
						|
				*value=(uint64)m;
 | 
						|
				return(TIFFReadDirEntryErrOk);
 | 
						|
			}
 | 
						|
		case TIFF_LONG8:
 | 
						|
		case TIFF_IFD8:
 | 
						|
			err=TIFFReadDirEntryCheckedLong8(tif,direntry,value);
 | 
						|
			return(err);
 | 
						|
		default:
 | 
						|
			return(TIFFReadDirEntryErrType);
 | 
						|
	}
 | 
						|
}
 | 
						|
 | 
						|
static enum TIFFReadDirEntryErr TIFFReadDirEntryArray(TIFF* tif, TIFFDirEntry* direntry, uint32* count, uint32 desttypesize, void** value)
 | 
						|
{
 | 
						|
	int typesize;
 | 
						|
	uint32 datasize;
 | 
						|
	void* data;
 | 
						|
	typesize=TIFFDataWidth(direntry->tdir_type);
 | 
						|
	if ((direntry->tdir_count==0)||(typesize==0))
 | 
						|
	{
 | 
						|
		*value=0;
 | 
						|
		return(TIFFReadDirEntryErrOk);
 | 
						|
	}
 | 
						|
        (void) desttypesize;
 | 
						|
 | 
						|
        /* 
 | 
						|
         * As a sanity check, make sure we have no more than a 2GB tag array 
 | 
						|
         * in either the current data type or the dest data type.  This also
 | 
						|
         * avoids problems with overflow of tmsize_t on 32bit systems.
 | 
						|
         */
 | 
						|
	if ((uint64)(2147483647/typesize)<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)
 | 
						|
					/*
 | 
						|
					 * XXX: MSVC 6.0 does not support
 | 
						|
					 * conversion of 64-bit integers into
 | 
						|
					 * floating point values.
 | 
						|
					 */
 | 
						|
					*mb++ = _TIFFUInt64ToFloat(*ma++);
 | 
						|
#else
 | 
						|
					*mb++ = (float)(*ma++);
 | 
						|
#endif
 | 
						|
				}
 | 
						|
			}
 | 
						|
			break;
 | 
						|
		case TIFF_SLONG8:
 | 
						|
			{
 | 
						|
				int64* ma;
 | 
						|
				float* mb;
 | 
						|
				uint32 n;
 | 
						|
				ma=(int64*)origdata;
 | 
						|
				mb=data;
 | 
						|
				for (n=0; n<count; n++)
 | 
						|
				{
 | 
						|
					if (tif->tif_flags&TIFF_SWAB)
 | 
						|
						TIFFSwabLong8((uint64*)ma);
 | 
						|
					*mb++=(float)(*ma++);
 | 
						|
				}
 | 
						|
			}
 | 
						|
			break;
 | 
						|
		case TIFF_RATIONAL:
 | 
						|
			{
 | 
						|
				uint32* ma;
 | 
						|
				uint32 maa;
 | 
						|
				uint32 mab;
 | 
						|
				float* mb;
 | 
						|
				uint32 n;
 | 
						|
				ma=(uint32*)origdata;
 | 
						|
				mb=data;
 | 
						|
				for (n=0; n<count; n++)
 | 
						|
				{
 | 
						|
					if (tif->tif_flags&TIFF_SWAB)
 | 
						|
						TIFFSwabLong(ma);
 | 
						|
					maa=*ma++;
 | 
						|
					if (tif->tif_flags&TIFF_SWAB)
 | 
						|
						TIFFSwabLong(ma);
 | 
						|
					mab=*ma++;
 | 
						|
					if (mab==0)
 | 
						|
						*mb++=0.0;
 | 
						|
					else
 | 
						|
						*mb++=(float)maa/(float)mab;
 | 
						|
				}
 | 
						|
			}
 | 
						|
			break;
 | 
						|
		case TIFF_SRATIONAL:
 | 
						|
			{
 | 
						|
				uint32* ma;
 | 
						|
				int32 maa;
 | 
						|
				uint32 mab;
 | 
						|
				float* mb;
 | 
						|
				uint32 n;
 | 
						|
				ma=(uint32*)origdata;
 | 
						|
				mb=data;
 | 
						|
				for (n=0; n<count; n++)
 | 
						|
				{
 | 
						|
					if (tif->tif_flags&TIFF_SWAB)
 | 
						|
						TIFFSwabLong(ma);
 | 
						|
					maa=*(int32*)ma;
 | 
						|
					ma++;
 | 
						|
					if (tif->tif_flags&TIFF_SWAB)
 | 
						|
						TIFFSwabLong(ma);
 | 
						|
					mab=*ma++;
 | 
						|
					if (mab==0)
 | 
						|
						*mb++=0.0;
 | 
						|
					else
 | 
						|
						*mb++=(float)maa/(float)mab;
 | 
						|
				}
 | 
						|
			}
 | 
						|
			break;
 | 
						|
		case TIFF_DOUBLE:
 | 
						|
			{
 | 
						|
				double* ma;
 | 
						|
				float* mb;
 | 
						|
				uint32 n;
 | 
						|
				if (tif->tif_flags&TIFF_SWAB)
 | 
						|
					TIFFSwabArrayOfLong8((uint64*)origdata,count);
 | 
						|
				TIFFCvtIEEEDoubleToNative(tif,count,(double*)origdata);
 | 
						|
				ma=(double*)origdata;
 | 
						|
				mb=data;
 | 
						|
				for (n=0; n<count; n++)
 | 
						|
					*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)
 | 
						|
					/*
 | 
						|
					 * XXX: MSVC 6.0 does not support
 | 
						|
					 * conversion of 64-bit integers into
 | 
						|
					 * floating point values.
 | 
						|
					 */
 | 
						|
					*mb++ = _TIFFUInt64ToDouble(*ma++);
 | 
						|
#else
 | 
						|
					*mb++ = (double)(*ma++);
 | 
						|
#endif
 | 
						|
				}
 | 
						|
			}
 | 
						|
			break;
 | 
						|
		case TIFF_SLONG8:
 | 
						|
			{
 | 
						|
				int64* ma;
 | 
						|
				double* mb;
 | 
						|
				uint32 n;
 | 
						|
				ma=(int64*)origdata;
 | 
						|
				mb=data;
 | 
						|
				for (n=0; n<count; n++)
 | 
						|
				{
 | 
						|
					if (tif->tif_flags&TIFF_SWAB)
 | 
						|
						TIFFSwabLong8((uint64*)ma);
 | 
						|
					*mb++=(double)(*ma++);
 | 
						|
				}
 | 
						|
			}
 | 
						|
			break;
 | 
						|
		case TIFF_RATIONAL:
 | 
						|
			{
 | 
						|
				uint32* ma;
 | 
						|
				uint32 maa;
 | 
						|
				uint32 mab;
 | 
						|
				double* mb;
 | 
						|
				uint32 n;
 | 
						|
				ma=(uint32*)origdata;
 | 
						|
				mb=data;
 | 
						|
				for (n=0; n<count; n++)
 | 
						|
				{
 | 
						|
					if (tif->tif_flags&TIFF_SWAB)
 | 
						|
						TIFFSwabLong(ma);
 | 
						|
					maa=*ma++;
 | 
						|
					if (tif->tif_flags&TIFF_SWAB)
 | 
						|
						TIFFSwabLong(ma);
 | 
						|
					mab=*ma++;
 | 
						|
					if (mab==0)
 | 
						|
						*mb++=0.0;
 | 
						|
					else
 | 
						|
						*mb++=(double)maa/(double)mab;
 | 
						|
				}
 | 
						|
			}
 | 
						|
			break;
 | 
						|
		case TIFF_SRATIONAL:
 | 
						|
			{
 | 
						|
				uint32* ma;
 | 
						|
				int32 maa;
 | 
						|
				uint32 mab;
 | 
						|
				double* mb;
 | 
						|
				uint32 n;
 | 
						|
				ma=(uint32*)origdata;
 | 
						|
				mb=data;
 | 
						|
				for (n=0; n<count; n++)
 | 
						|
				{
 | 
						|
					if (tif->tif_flags&TIFF_SWAB)
 | 
						|
						TIFFSwabLong(ma);
 | 
						|
					maa=*(int32*)ma;
 | 
						|
					ma++;
 | 
						|
					if (tif->tif_flags&TIFF_SWAB)
 | 
						|
						TIFFSwabLong(ma);
 | 
						|
					mab=*ma++;
 | 
						|
					if (mab==0)
 | 
						|
						*mb++=0.0;
 | 
						|
					else
 | 
						|
						*mb++=(double)maa/(double)mab;
 | 
						|
				}
 | 
						|
			}
 | 
						|
			break;
 | 
						|
		case TIFF_FLOAT:
 | 
						|
			{
 | 
						|
				float* ma;
 | 
						|
				double* mb;
 | 
						|
				uint32 n;
 | 
						|
				if (tif->tif_flags&TIFF_SWAB)
 | 
						|
					TIFFSwabArrayOfLong((uint32*)origdata,count);  
 | 
						|
				TIFFCvtIEEEFloatToNative(tif,count,(float*)origdata);
 | 
						|
				ma=(float*)origdata;
 | 
						|
				mb=data;
 | 
						|
				for (n=0; n<count; n++)
 | 
						|
					*mb++=(double)(*ma++);
 | 
						|
			}
 | 
						|
			break;
 | 
						|
	}
 | 
						|
	_TIFFfree(origdata);
 | 
						|
	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;
 | 
						|
	/* *value=*(uint16*)(&direntry->tdir_offset); */
 | 
						|
	if (tif->tif_flags&TIFF_SWAB)
 | 
						|
		TIFFSwabShort(value);
 | 
						|
}
 | 
						|
 | 
						|
static void TIFFReadDirEntryCheckedSshort(TIFF* tif, TIFFDirEntry* direntry, int16* value)
 | 
						|
{
 | 
						|
	*value=*(int16*)(&direntry->tdir_offset);
 | 
						|
	if (tif->tif_flags&TIFF_SWAB)
 | 
						|
		TIFFSwabShort((uint16*)value);
 | 
						|
}
 | 
						|
 | 
						|
static void TIFFReadDirEntryCheckedLong(TIFF* tif, TIFFDirEntry* direntry, uint32* value)
 | 
						|
{
 | 
						|
	*value=*(uint32*)(&direntry->tdir_offset);
 | 
						|
	if (tif->tif_flags&TIFF_SWAB)
 | 
						|
		TIFFSwabLong(value);
 | 
						|
}
 | 
						|
 | 
						|
static void TIFFReadDirEntryCheckedSlong(TIFF* tif, TIFFDirEntry* direntry, int32* value)
 | 
						|
{
 | 
						|
	*value=*(int32*)(&direntry->tdir_offset);
 | 
						|
	if (tif->tif_flags&TIFF_SWAB)
 | 
						|
		TIFFSwabLong((uint32*)value);
 | 
						|
}
 | 
						|
 | 
						|
static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckedLong8(TIFF* tif, TIFFDirEntry* direntry, uint64* value)
 | 
						|
{
 | 
						|
	if (!(tif->tif_flags&TIFF_BIGTIFF))
 | 
						|
	{
 | 
						|
		enum TIFFReadDirEntryErr err;
 | 
						|
		uint32 offset = direntry->tdir_offset.toff_long;
 | 
						|
		if (tif->tif_flags&TIFF_SWAB)
 | 
						|
			TIFFSwabLong(&offset);
 | 
						|
		err=TIFFReadDirEntryData(tif,offset,8,value);
 | 
						|
		if (err!=TIFFReadDirEntryErrOk)
 | 
						|
			return(err);
 | 
						|
	}
 | 
						|
	else
 | 
						|
		*value = direntry->tdir_offset.toff_long8;
 | 
						|
	if (tif->tif_flags&TIFF_SWAB)
 | 
						|
		TIFFSwabLong8(value);
 | 
						|
	return(TIFFReadDirEntryErrOk);
 | 
						|
}
 | 
						|
 | 
						|
static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckedSlong8(TIFF* tif, TIFFDirEntry* direntry, int64* value)
 | 
						|
{
 | 
						|
	if (!(tif->tif_flags&TIFF_BIGTIFF))
 | 
						|
	{
 | 
						|
		enum TIFFReadDirEntryErr err;
 | 
						|
		uint32 offset = direntry->tdir_offset.toff_long;
 | 
						|
		if (tif->tif_flags&TIFF_SWAB)
 | 
						|
			TIFFSwabLong(&offset);
 | 
						|
		err=TIFFReadDirEntryData(tif,offset,8,value);
 | 
						|
		if (err!=TIFFReadDirEntryErrOk)
 | 
						|
			return(err);
 | 
						|
	}
 | 
						|
	else
 | 
						|
		*value=*(int64*)(&direntry->tdir_offset);
 | 
						|
	if (tif->tif_flags&TIFF_SWAB)
 | 
						|
		TIFFSwabLong8((uint64*)value);
 | 
						|
	return(TIFFReadDirEntryErrOk);
 | 
						|
}
 | 
						|
 | 
						|
static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckedRational(TIFF* tif, TIFFDirEntry* direntry, double* value)
 | 
						|
{
 | 
						|
	UInt64Aligned_t m;
 | 
						|
 | 
						|
	assert(sizeof(double)==8);
 | 
						|
	assert(sizeof(uint64)==8);
 | 
						|
	assert(sizeof(uint32)==4);
 | 
						|
	if (!(tif->tif_flags&TIFF_BIGTIFF))
 | 
						|
	{
 | 
						|
		enum TIFFReadDirEntryErr err;
 | 
						|
		uint32 offset = direntry->tdir_offset.toff_long;
 | 
						|
		if (tif->tif_flags&TIFF_SWAB)
 | 
						|
			TIFFSwabLong(&offset);
 | 
						|
		err=TIFFReadDirEntryData(tif,offset,8,m.i);
 | 
						|
		if (err!=TIFFReadDirEntryErrOk)
 | 
						|
			return(err);
 | 
						|
	}
 | 
						|
	else
 | 
						|
		m.l = direntry->tdir_offset.toff_long8;
 | 
						|
	if (tif->tif_flags&TIFF_SWAB)
 | 
						|
		TIFFSwabArrayOfLong(m.i,2);
 | 
						|
	if (m.i[0]==0)
 | 
						|
		*value=0.0;
 | 
						|
	else
 | 
						|
		*value=(double)m.i[0]/(double)m.i[1];
 | 
						|
	return(TIFFReadDirEntryErrOk);
 | 
						|
}
 | 
						|
 | 
						|
static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckedSrational(TIFF* tif, TIFFDirEntry* direntry, double* value)
 | 
						|
{
 | 
						|
	UInt64Aligned_t m;
 | 
						|
	assert(sizeof(double)==8);
 | 
						|
	assert(sizeof(uint64)==8);
 | 
						|
	assert(sizeof(int32)==4);
 | 
						|
	assert(sizeof(uint32)==4);
 | 
						|
	if (!(tif->tif_flags&TIFF_BIGTIFF))
 | 
						|
	{
 | 
						|
		enum TIFFReadDirEntryErr err;
 | 
						|
		uint32 offset = direntry->tdir_offset.toff_long;
 | 
						|
		if (tif->tif_flags&TIFF_SWAB)
 | 
						|
			TIFFSwabLong(&offset);
 | 
						|
		err=TIFFReadDirEntryData(tif,offset,8,m.i);
 | 
						|
		if (err!=TIFFReadDirEntryErrOk)
 | 
						|
			return(err);
 | 
						|
	}
 | 
						|
	else
 | 
						|
		m.l=direntry->tdir_offset.toff_long8;
 | 
						|
	if (tif->tif_flags&TIFF_SWAB)
 | 
						|
		TIFFSwabArrayOfLong(m.i,2);
 | 
						|
	if ((int32)m.i[0]==0)
 | 
						|
		*value=0.0;
 | 
						|
	else
 | 
						|
		*value=(double)((int32)m.i[0])/(double)m.i[1];
 | 
						|
	return(TIFFReadDirEntryErrOk);
 | 
						|
}
 | 
						|
 | 
						|
static void TIFFReadDirEntryCheckedFloat(TIFF* tif, TIFFDirEntry* direntry, float* value)
 | 
						|
{
 | 
						|
         union
 | 
						|
	 {
 | 
						|
	   float  f;
 | 
						|
	   uint32 i;
 | 
						|
	 } float_union;
 | 
						|
	assert(sizeof(float)==4);
 | 
						|
	assert(sizeof(uint32)==4);
 | 
						|
	assert(sizeof(float_union)==4);
 | 
						|
	float_union.i=*(uint32*)(&direntry->tdir_offset);
 | 
						|
	*value=float_union.f;
 | 
						|
	if (tif->tif_flags&TIFF_SWAB)
 | 
						|
		TIFFSwabLong((uint32*)value);
 | 
						|
}
 | 
						|
 | 
						|
static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckedDouble(TIFF* tif, TIFFDirEntry* direntry, double* value)
 | 
						|
{
 | 
						|
	assert(sizeof(double)==8);
 | 
						|
	assert(sizeof(uint64)==8);
 | 
						|
	assert(sizeof(UInt64Aligned_t)==8);
 | 
						|
	if (!(tif->tif_flags&TIFF_BIGTIFF))
 | 
						|
	{
 | 
						|
		enum TIFFReadDirEntryErr err;
 | 
						|
		uint32 offset = direntry->tdir_offset.toff_long;
 | 
						|
		if (tif->tif_flags&TIFF_SWAB)
 | 
						|
			TIFFSwabLong(&offset);
 | 
						|
		err=TIFFReadDirEntryData(tif,offset,8,value);
 | 
						|
		if (err!=TIFFReadDirEntryErrOk)
 | 
						|
			return(err);
 | 
						|
	}
 | 
						|
	else
 | 
						|
	{
 | 
						|
	       UInt64Aligned_t uint64_union;
 | 
						|
	       uint64_union.l=direntry->tdir_offset.toff_long8;
 | 
						|
	       *value=uint64_union.d;
 | 
						|
	}
 | 
						|
	if (tif->tif_flags&TIFF_SWAB)
 | 
						|
		TIFFSwabLong8((uint64*)value);
 | 
						|
	return(TIFFReadDirEntryErrOk);
 | 
						|
}
 | 
						|
 | 
						|
static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckRangeByteSbyte(int8 value)
 | 
						|
{
 | 
						|
	if (value<0)
 | 
						|
		return(TIFFReadDirEntryErrRange);
 | 
						|
	else
 | 
						|
		return(TIFFReadDirEntryErrOk);
 | 
						|
}
 | 
						|
 | 
						|
static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckRangeByteShort(uint16 value)
 | 
						|
{
 | 
						|
	if (value>0xFF)
 | 
						|
		return(TIFFReadDirEntryErrRange);
 | 
						|
	else
 | 
						|
		return(TIFFReadDirEntryErrOk);
 | 
						|
}
 | 
						|
 | 
						|
static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckRangeByteSshort(int16 value)
 | 
						|
{
 | 
						|
	if ((value<0)||(value>0xFF))
 | 
						|
		return(TIFFReadDirEntryErrRange);
 | 
						|
	else
 | 
						|
		return(TIFFReadDirEntryErrOk);
 | 
						|
}
 | 
						|
 | 
						|
static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckRangeByteLong(uint32 value)
 | 
						|
{
 | 
						|
	if (value>0xFF)
 | 
						|
		return(TIFFReadDirEntryErrRange);
 | 
						|
	else
 | 
						|
		return(TIFFReadDirEntryErrOk);
 | 
						|
}
 | 
						|
 | 
						|
static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckRangeByteSlong(int32 value)
 | 
						|
{
 | 
						|
	if ((value<0)||(value>0xFF))
 | 
						|
		return(TIFFReadDirEntryErrRange);
 | 
						|
	else
 | 
						|
		return(TIFFReadDirEntryErrOk);
 | 
						|
}
 | 
						|
 | 
						|
static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckRangeByteLong8(uint64 value)
 | 
						|
{
 | 
						|
	if (value>0xFF)
 | 
						|
		return(TIFFReadDirEntryErrRange);
 | 
						|
	else
 | 
						|
		return(TIFFReadDirEntryErrOk);
 | 
						|
}
 | 
						|
 | 
						|
static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckRangeByteSlong8(int64 value)
 | 
						|
{
 | 
						|
	if ((value<0)||(value>0xFF))
 | 
						|
		return(TIFFReadDirEntryErrRange);
 | 
						|
	else
 | 
						|
		return(TIFFReadDirEntryErrOk);
 | 
						|
}
 | 
						|
 | 
						|
static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckRangeSbyteByte(uint8 value)
 | 
						|
{
 | 
						|
	if (value>0x7F)
 | 
						|
		return(TIFFReadDirEntryErrRange);
 | 
						|
	else
 | 
						|
		return(TIFFReadDirEntryErrOk);
 | 
						|
}
 | 
						|
 | 
						|
static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckRangeSbyteShort(uint16 value)
 | 
						|
{
 | 
						|
	if (value>0x7F)
 | 
						|
		return(TIFFReadDirEntryErrRange);
 | 
						|
	else
 | 
						|
		return(TIFFReadDirEntryErrOk);
 | 
						|
}
 | 
						|
 | 
						|
static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckRangeSbyteSshort(int16 value)
 | 
						|
{
 | 
						|
	if ((value<-0x80)||(value>0x7F))
 | 
						|
		return(TIFFReadDirEntryErrRange);
 | 
						|
	else
 | 
						|
		return(TIFFReadDirEntryErrOk);
 | 
						|
}
 | 
						|
 | 
						|
static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckRangeSbyteLong(uint32 value)
 | 
						|
{
 | 
						|
	if (value>0x7F)
 | 
						|
		return(TIFFReadDirEntryErrRange);
 | 
						|
	else
 | 
						|
		return(TIFFReadDirEntryErrOk);
 | 
						|
}
 | 
						|
 | 
						|
static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckRangeSbyteSlong(int32 value)
 | 
						|
{
 | 
						|
	if ((value<-0x80)||(value>0x7F))
 | 
						|
		return(TIFFReadDirEntryErrRange);
 | 
						|
	else
 | 
						|
		return(TIFFReadDirEntryErrOk);
 | 
						|
}
 | 
						|
 | 
						|
static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckRangeSbyteLong8(uint64 value)
 | 
						|
{
 | 
						|
	if (value>0x7F)
 | 
						|
		return(TIFFReadDirEntryErrRange);
 | 
						|
	else
 | 
						|
		return(TIFFReadDirEntryErrOk);
 | 
						|
}
 | 
						|
 | 
						|
static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckRangeSbyteSlong8(int64 value)
 | 
						|
{
 | 
						|
	if ((value<-0x80)||(value>0x7F))
 | 
						|
		return(TIFFReadDirEntryErrRange);
 | 
						|
	else
 | 
						|
		return(TIFFReadDirEntryErrOk);
 | 
						|
}
 | 
						|
 | 
						|
static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckRangeShortSbyte(int8 value)
 | 
						|
{
 | 
						|
	if (value<0)
 | 
						|
		return(TIFFReadDirEntryErrRange);
 | 
						|
	else
 | 
						|
		return(TIFFReadDirEntryErrOk);
 | 
						|
}
 | 
						|
 | 
						|
static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckRangeShortSshort(int16 value)
 | 
						|
{
 | 
						|
	if (value<0)
 | 
						|
		return(TIFFReadDirEntryErrRange);
 | 
						|
	else
 | 
						|
		return(TIFFReadDirEntryErrOk);
 | 
						|
}
 | 
						|
 | 
						|
static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckRangeShortLong(uint32 value)
 | 
						|
{
 | 
						|
	if (value>0xFFFF)
 | 
						|
		return(TIFFReadDirEntryErrRange);
 | 
						|
	else
 | 
						|
		return(TIFFReadDirEntryErrOk);
 | 
						|
}
 | 
						|
 | 
						|
static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckRangeShortSlong(int32 value)
 | 
						|
{
 | 
						|
	if ((value<0)||(value>0xFFFF))
 | 
						|
		return(TIFFReadDirEntryErrRange);
 | 
						|
	else
 | 
						|
		return(TIFFReadDirEntryErrOk);
 | 
						|
}
 | 
						|
 | 
						|
static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckRangeShortLong8(uint64 value)
 | 
						|
{
 | 
						|
	if (value>0xFFFF)
 | 
						|
		return(TIFFReadDirEntryErrRange);
 | 
						|
	else
 | 
						|
		return(TIFFReadDirEntryErrOk);
 | 
						|
}
 | 
						|
 | 
						|
static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckRangeShortSlong8(int64 value)
 | 
						|
{
 | 
						|
	if ((value<0)||(value>0xFFFF))
 | 
						|
		return(TIFFReadDirEntryErrRange);
 | 
						|
	else
 | 
						|
		return(TIFFReadDirEntryErrOk);
 | 
						|
}
 | 
						|
 | 
						|
static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckRangeSshortShort(uint16 value)
 | 
						|
{
 | 
						|
	if (value>0x7FFF)
 | 
						|
		return(TIFFReadDirEntryErrRange);
 | 
						|
	else
 | 
						|
		return(TIFFReadDirEntryErrOk);
 | 
						|
}
 | 
						|
 | 
						|
static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckRangeSshortLong(uint32 value)
 | 
						|
{
 | 
						|
	if (value>0x7FFF)
 | 
						|
		return(TIFFReadDirEntryErrRange);
 | 
						|
	else
 | 
						|
		return(TIFFReadDirEntryErrOk);
 | 
						|
}
 | 
						|
 | 
						|
static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckRangeSshortSlong(int32 value)
 | 
						|
{
 | 
						|
	if ((value<-0x8000)||(value>0x7FFF))
 | 
						|
		return(TIFFReadDirEntryErrRange);
 | 
						|
	else
 | 
						|
		return(TIFFReadDirEntryErrOk);
 | 
						|
}
 | 
						|
 | 
						|
static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckRangeSshortLong8(uint64 value)
 | 
						|
{
 | 
						|
	if (value>0x7FFF)
 | 
						|
		return(TIFFReadDirEntryErrRange);
 | 
						|
	else
 | 
						|
		return(TIFFReadDirEntryErrOk);
 | 
						|
}
 | 
						|
 | 
						|
static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckRangeSshortSlong8(int64 value)
 | 
						|
{
 | 
						|
	if ((value<-0x8000)||(value>0x7FFF))
 | 
						|
		return(TIFFReadDirEntryErrRange);
 | 
						|
	else
 | 
						|
		return(TIFFReadDirEntryErrOk);
 | 
						|
}
 | 
						|
 | 
						|
static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckRangeLongSbyte(int8 value)
 | 
						|
{
 | 
						|
	if (value<0)
 | 
						|
		return(TIFFReadDirEntryErrRange);
 | 
						|
	else
 | 
						|
		return(TIFFReadDirEntryErrOk);
 | 
						|
}
 | 
						|
 | 
						|
static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckRangeLongSshort(int16 value)
 | 
						|
{
 | 
						|
	if (value<0)
 | 
						|
		return(TIFFReadDirEntryErrRange);
 | 
						|
	else
 | 
						|
		return(TIFFReadDirEntryErrOk);
 | 
						|
}
 | 
						|
 | 
						|
static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckRangeLongSlong(int32 value)
 | 
						|
{
 | 
						|
	if (value<0)
 | 
						|
		return(TIFFReadDirEntryErrRange);
 | 
						|
	else
 | 
						|
		return(TIFFReadDirEntryErrOk);
 | 
						|
}
 | 
						|
 | 
						|
/*
 | 
						|
 * Largest 32-bit unsigned integer value.
 | 
						|
 */
 | 
						|
#if defined(__WIN32__) && defined(_MSC_VER)
 | 
						|
# define TIFF_UINT32_MAX 0xFFFFFFFFI64
 | 
						|
#else
 | 
						|
# define TIFF_UINT32_MAX 0xFFFFFFFFLL
 | 
						|
#endif
 | 
						|
 | 
						|
static enum TIFFReadDirEntryErr
 | 
						|
TIFFReadDirEntryCheckRangeLongLong8(uint64 value)
 | 
						|
{
 | 
						|
	if (value > TIFF_UINT32_MAX)
 | 
						|
		return(TIFFReadDirEntryErrRange);
 | 
						|
	else
 | 
						|
		return(TIFFReadDirEntryErrOk);
 | 
						|
}
 | 
						|
 | 
						|
static enum TIFFReadDirEntryErr
 | 
						|
TIFFReadDirEntryCheckRangeLongSlong8(int64 value)
 | 
						|
{
 | 
						|
	if ((value<0) || (value > TIFF_UINT32_MAX))
 | 
						|
		return(TIFFReadDirEntryErrRange);
 | 
						|
	else
 | 
						|
		return(TIFFReadDirEntryErrOk);
 | 
						|
}
 | 
						|
 | 
						|
#undef TIFF_UINT32_MAX
 | 
						|
 | 
						|
static enum TIFFReadDirEntryErr
 | 
						|
TIFFReadDirEntryCheckRangeSlongLong(uint32 value)
 | 
						|
{
 | 
						|
	if (value > 0x7FFFFFFFUL)
 | 
						|
		return(TIFFReadDirEntryErrRange);
 | 
						|
	else
 | 
						|
		return(TIFFReadDirEntryErrOk);
 | 
						|
}
 | 
						|
 | 
						|
static enum TIFFReadDirEntryErr
 | 
						|
TIFFReadDirEntryCheckRangeSlongLong8(uint64 value)
 | 
						|
{
 | 
						|
	if (value > 0x7FFFFFFFUL)
 | 
						|
		return(TIFFReadDirEntryErrRange);
 | 
						|
	else
 | 
						|
		return(TIFFReadDirEntryErrOk);
 | 
						|
}
 | 
						|
 | 
						|
static enum TIFFReadDirEntryErr
 | 
						|
TIFFReadDirEntryCheckRangeSlongSlong8(int64 value)
 | 
						|
{
 | 
						|
	if ((value < 0L-0x80000000L) || (value > 0x7FFFFFFFL))
 | 
						|
		return(TIFFReadDirEntryErrRange);
 | 
						|
	else
 | 
						|
		return(TIFFReadDirEntryErrOk);
 | 
						|
}
 | 
						|
 | 
						|
static enum TIFFReadDirEntryErr
 | 
						|
TIFFReadDirEntryCheckRangeLong8Sbyte(int8 value)
 | 
						|
{
 | 
						|
	if (value < 0)
 | 
						|
		return(TIFFReadDirEntryErrRange);
 | 
						|
	else
 | 
						|
		return(TIFFReadDirEntryErrOk);
 | 
						|
}
 | 
						|
 | 
						|
static enum TIFFReadDirEntryErr
 | 
						|
TIFFReadDirEntryCheckRangeLong8Sshort(int16 value)
 | 
						|
{
 | 
						|
	if (value < 0)
 | 
						|
		return(TIFFReadDirEntryErrRange);
 | 
						|
	else
 | 
						|
		return(TIFFReadDirEntryErrOk);
 | 
						|
}
 | 
						|
 | 
						|
static enum TIFFReadDirEntryErr
 | 
						|
TIFFReadDirEntryCheckRangeLong8Slong(int32 value)
 | 
						|
{
 | 
						|
	if (value < 0)
 | 
						|
		return(TIFFReadDirEntryErrRange);
 | 
						|
	else
 | 
						|
		return(TIFFReadDirEntryErrOk);
 | 
						|
}
 | 
						|
 | 
						|
static enum TIFFReadDirEntryErr
 | 
						|
TIFFReadDirEntryCheckRangeLong8Slong8(int64 value)
 | 
						|
{
 | 
						|
	if (value < 0)
 | 
						|
		return(TIFFReadDirEntryErrRange);
 | 
						|
	else
 | 
						|
		return(TIFFReadDirEntryErrOk);
 | 
						|
}
 | 
						|
 | 
						|
/*
 | 
						|
 * Largest 64-bit signed integer value.
 | 
						|
 */
 | 
						|
#if defined(__WIN32__) && defined(_MSC_VER)
 | 
						|
# define TIFF_INT64_MAX 0x7FFFFFFFFFFFFFFFI64
 | 
						|
#else
 | 
						|
# define TIFF_INT64_MAX 0x7FFFFFFFFFFFFFFFLL
 | 
						|
#endif
 | 
						|
 | 
						|
static enum TIFFReadDirEntryErr
 | 
						|
TIFFReadDirEntryCheckRangeSlong8Long8(uint64 value)
 | 
						|
{
 | 
						|
	if (value > TIFF_INT64_MAX)
 | 
						|
		return(TIFFReadDirEntryErrRange);
 | 
						|
	else
 | 
						|
		return(TIFFReadDirEntryErrOk);
 | 
						|
}
 | 
						|
 | 
						|
#undef TIFF_INT64_MAX
 | 
						|
 | 
						|
static enum TIFFReadDirEntryErr
 | 
						|
TIFFReadDirEntryData(TIFF* tif, uint64 offset, tmsize_t size, void* dest)
 | 
						|
{
 | 
						|
	assert(size>0);
 | 
						|
	if (!isMapped(tif)) {
 | 
						|
		if (!SeekOK(tif,offset))
 | 
						|
			return(TIFFReadDirEntryErrIo);
 | 
						|
		if (!ReadOK(tif,dest,size))
 | 
						|
			return(TIFFReadDirEntryErrIo);
 | 
						|
	} else {
 | 
						|
		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);   /* we should never get here */
 | 
						|
				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);   /* we should never get here */
 | 
						|
				break;
 | 
						|
		}
 | 
						|
	}
 | 
						|
}
 | 
						|
 | 
						|
/*
 | 
						|
 * Read the next TIFF directory from a file and convert it to the internal
 | 
						|
 * format. We read directories sequentially.
 | 
						|
 */
 | 
						|
int
 | 
						|
TIFFReadDirectory(TIFF* tif)
 | 
						|
{
 | 
						|
	static const char module[] = "TIFFReadDirectory";
 | 
						|
	TIFFDirEntry* dir;
 | 
						|
	uint16 dircount;
 | 
						|
	TIFFDirEntry* dp;
 | 
						|
	uint16 di;
 | 
						|
	const TIFFField* fip;
 | 
						|
	uint32 fii=FAILED_FII;
 | 
						|
        toff_t nextdiroff;
 | 
						|
	tif->tif_diroff=tif->tif_nextdiroff;
 | 
						|
	if (!TIFFCheckDirOffset(tif,tif->tif_nextdiroff))
 | 
						|
		return 0;           /* last offset or bad offset (IFD looping) */
 | 
						|
	(*tif->tif_cleanup)(tif);   /* cleanup any previous compression state */
 | 
						|
	tif->tif_curdir++;
 | 
						|
        nextdiroff = tif->tif_nextdiroff;
 | 
						|
	dircount=TIFFFetchDirectory(tif,nextdiroff,&dir,&tif->tif_nextdiroff);
 | 
						|
	if (!dircount)
 | 
						|
	{
 | 
						|
		TIFFErrorExt(tif->tif_clientdata,module,
 | 
						|
		    "Failed to read directory at offset " TIFF_UINT64_FORMAT,nextdiroff);
 | 
						|
		return 0;
 | 
						|
	}
 | 
						|
	TIFFReadDirectoryCheckOrder(tif,dir,dircount);
 | 
						|
 | 
						|
        /*
 | 
						|
         * Mark duplicates of any tag to be ignored (bugzilla 1994)
 | 
						|
         * to avoid certain pathological problems.
 | 
						|
         */
 | 
						|
	{
 | 
						|
		TIFFDirEntry* ma;
 | 
						|
		uint16 mb;
 | 
						|
		for (ma=dir, mb=0; 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;    /* reset before new dir */
 | 
						|
	tif->tif_flags &= ~TIFF_BUF4WRITE;      /* reset before new dir */
 | 
						|
	/* free any old stuff and reinit */
 | 
						|
	TIFFFreeDirectory(tif);
 | 
						|
	TIFFDefaultDirectory(tif);
 | 
						|
	/*
 | 
						|
	 * Electronic Arts writes gray-scale TIFF files
 | 
						|
	 * without a PlanarConfiguration directory entry.
 | 
						|
	 * Thus we setup a default value here, even though
 | 
						|
	 * the TIFF spec says there is no default value.
 | 
						|
	 */
 | 
						|
	TIFFSetField(tif,TIFFTAG_PLANARCONFIG,PLANARCONFIG_CONTIG);
 | 
						|
	/*
 | 
						|
	 * Setup default value and then make a pass over
 | 
						|
	 * the fields to check type and tag information,
 | 
						|
	 * and to extract info required to size data
 | 
						|
	 * structures.  A second pass is made afterwards
 | 
						|
	 * to read in everthing not taken in the first pass.
 | 
						|
	 * But we must process the Compression tag first
 | 
						|
	 * in order to merge in codec-private tag definitions (otherwise
 | 
						|
	 * we may get complaints about unknown tags).  However, the
 | 
						|
	 * Compression tag may be dependent on the SamplesPerPixel
 | 
						|
	 * tag value because older TIFF specs permited Compression
 | 
						|
	 * to be written as a SamplesPerPixel-count tag entry.
 | 
						|
	 * Thus if we don't first figure out the correct SamplesPerPixel
 | 
						|
	 * tag value then we may end up ignoring the Compression tag
 | 
						|
	 * value because it has an incorrect count value (if the
 | 
						|
	 * true value of SamplesPerPixel is not 1).
 | 
						|
	 */
 | 
						|
	dp=TIFFReadDirectoryFindEntry(tif,dir,dircount,TIFFTAG_SAMPLESPERPIXEL);
 | 
						|
	if (dp)
 | 
						|
	{
 | 
						|
		if (!TIFFFetchNormalTag(tif,dp,0))
 | 
						|
			goto bad;
 | 
						|
		dp->tdir_tag=IGNORE;
 | 
						|
	}
 | 
						|
	dp=TIFFReadDirectoryFindEntry(tif,dir,dircount,TIFFTAG_COMPRESSION);
 | 
						|
	if (dp)
 | 
						|
	{
 | 
						|
		/*
 | 
						|
		 * The 5.0 spec says the Compression tag has one value, while
 | 
						|
		 * earlier specs say it has one value per sample.  Because of
 | 
						|
		 * this, we accept the tag if one value is supplied with either
 | 
						|
		 * count.
 | 
						|
		 */
 | 
						|
		uint16 value;
 | 
						|
		enum TIFFReadDirEntryErr err;
 | 
						|
		err=TIFFReadDirEntryShort(tif,dp,&value);
 | 
						|
		if (err==TIFFReadDirEntryErrCount)
 | 
						|
			err=TIFFReadDirEntryPersampleShort(tif,dp,&value);
 | 
						|
		if (err!=TIFFReadDirEntryErrOk)
 | 
						|
		{
 | 
						|
			TIFFReadDirEntryOutputErr(tif,err,module,"Compression",0);
 | 
						|
			goto bad;
 | 
						|
		}
 | 
						|
		if (!TIFFSetField(tif,TIFFTAG_COMPRESSION,value))
 | 
						|
			goto bad;
 | 
						|
		dp->tdir_tag=IGNORE;
 | 
						|
	}
 | 
						|
	else
 | 
						|
	{
 | 
						|
		if (!TIFFSetField(tif,TIFFTAG_COMPRESSION,COMPRESSION_NONE))
 | 
						|
			goto bad;
 | 
						|
	}
 | 
						|
	/*
 | 
						|
	 * First real pass over the directory.
 | 
						|
	 */
 | 
						|
	for (di=0, dp=dir; 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);
 | 
						|
                                /* the following knowingly leaks the 
 | 
						|
                                   anonymous field structure */
 | 
						|
				if (!_TIFFMergeFields(tif,
 | 
						|
					_TIFFCreateAnonField(tif,
 | 
						|
						dp->tdir_tag,
 | 
						|
						(TIFFDataType) dp->tdir_type),
 | 
						|
					1)) {
 | 
						|
					TIFFWarningExt(tif->tif_clientdata,
 | 
						|
					    module,
 | 
						|
					    "Registering anonymous field with tag %d (0x%x) failed",
 | 
						|
					    dp->tdir_tag,
 | 
						|
					    dp->tdir_tag);
 | 
						|
					dp->tdir_tag=IGNORE;
 | 
						|
				} else {
 | 
						|
					TIFFReadDirectoryFindFieldInfo(tif,dp->tdir_tag,&fii);
 | 
						|
					assert(fii != FAILED_FII);
 | 
						|
				}
 | 
						|
			}
 | 
						|
		}
 | 
						|
		if (dp->tdir_tag!=IGNORE)
 | 
						|
		{
 | 
						|
			fip=tif->tif_fields[fii];
 | 
						|
			if (fip->field_bit==FIELD_IGNORE)
 | 
						|
				dp->tdir_tag=IGNORE;
 | 
						|
			else
 | 
						|
			{
 | 
						|
				switch (dp->tdir_tag)
 | 
						|
				{
 | 
						|
					case TIFFTAG_STRIPOFFSETS:
 | 
						|
					case TIFFTAG_STRIPBYTECOUNTS:
 | 
						|
					case TIFFTAG_TILEOFFSETS:
 | 
						|
					case TIFFTAG_TILEBYTECOUNTS:
 | 
						|
						TIFFSetFieldBit(tif,fip->field_bit);
 | 
						|
						break;
 | 
						|
					case TIFFTAG_IMAGEWIDTH:
 | 
						|
					case TIFFTAG_IMAGELENGTH:
 | 
						|
					case TIFFTAG_IMAGEDEPTH:
 | 
						|
					case TIFFTAG_TILELENGTH:
 | 
						|
					case TIFFTAG_TILEWIDTH:
 | 
						|
					case TIFFTAG_TILEDEPTH:
 | 
						|
					case TIFFTAG_PLANARCONFIG:
 | 
						|
					case TIFFTAG_ROWSPERSTRIP:
 | 
						|
					case TIFFTAG_EXTRASAMPLES:
 | 
						|
						if (!TIFFFetchNormalTag(tif,dp,0))
 | 
						|
							goto bad;
 | 
						|
						dp->tdir_tag=IGNORE;
 | 
						|
						break;
 | 
						|
				}
 | 
						|
			}
 | 
						|
		}
 | 
						|
	}
 | 
						|
	/*
 | 
						|
	 * XXX: OJPEG hack.
 | 
						|
	 * If a) compression is OJPEG, b) planarconfig tag says it's separate,
 | 
						|
	 * c) strip offsets/bytecounts tag are both present and
 | 
						|
	 * d) both contain exactly one value, then we consistently find
 | 
						|
	 * that the buggy implementation of the buggy compression scheme
 | 
						|
	 * matches contig planarconfig best. So we 'fix-up' the tag here
 | 
						|
	 */
 | 
						|
	if ((tif->tif_dir.td_compression==COMPRESSION_OJPEG)&&
 | 
						|
	    (tif->tif_dir.td_planarconfig==PLANARCONFIG_SEPARATE))
 | 
						|
	{
 | 
						|
        if (!_TIFFFillStriles(tif))
 | 
						|
            goto bad;
 | 
						|
		dp=TIFFReadDirectoryFindEntry(tif,dir,dircount,TIFFTAG_STRIPOFFSETS);
 | 
						|
		if ((dp!=0)&&(dp->tdir_count==1))
 | 
						|
		{
 | 
						|
			dp=TIFFReadDirectoryFindEntry(tif,dir,dircount,
 | 
						|
			    TIFFTAG_STRIPBYTECOUNTS);
 | 
						|
			if ((dp!=0)&&(dp->tdir_count==1))
 | 
						|
			{
 | 
						|
				tif->tif_dir.td_planarconfig=PLANARCONFIG_CONTIG;
 | 
						|
				TIFFWarningExt(tif->tif_clientdata,module,
 | 
						|
				    "Planarconfig tag value assumed incorrect, "
 | 
						|
				    "assuming data is contig instead of chunky");
 | 
						|
			}
 | 
						|
		}
 | 
						|
	}
 | 
						|
	/*
 | 
						|
	 * Allocate directory structure and setup defaults.
 | 
						|
	 */
 | 
						|
	if (!TIFFFieldSet(tif,FIELD_IMAGEDIMENSIONS))
 | 
						|
	{
 | 
						|
		MissingRequired(tif,"ImageLength");
 | 
						|
		goto bad;
 | 
						|
	}
 | 
						|
	/*
 | 
						|
	 * Setup appropriate structures (by strip or by tile)
 | 
						|
	 */
 | 
						|
	if (!TIFFFieldSet(tif, FIELD_TILEDIMENSIONS)) {
 | 
						|
		tif->tif_dir.td_nstrips = TIFFNumberOfStrips(tif);  
 | 
						|
		tif->tif_dir.td_tilewidth = tif->tif_dir.td_imagewidth;
 | 
						|
		tif->tif_dir.td_tilelength = tif->tif_dir.td_rowsperstrip;
 | 
						|
		tif->tif_dir.td_tiledepth = tif->tif_dir.td_imagedepth;
 | 
						|
		tif->tif_flags &= ~TIFF_ISTILED;
 | 
						|
	} else {
 | 
						|
		tif->tif_dir.td_nstrips = TIFFNumberOfTiles(tif);
 | 
						|
		tif->tif_flags |= TIFF_ISTILED;
 | 
						|
	}
 | 
						|
	if (!tif->tif_dir.td_nstrips) {
 | 
						|
		TIFFErrorExt(tif->tif_clientdata, module,
 | 
						|
		    "Cannot handle zero number of %s",
 | 
						|
		    isTiled(tif) ? "tiles" : "strips");
 | 
						|
		goto bad;
 | 
						|
	}
 | 
						|
	tif->tif_dir.td_stripsperimage = tif->tif_dir.td_nstrips;
 | 
						|
	if (tif->tif_dir.td_planarconfig == PLANARCONFIG_SEPARATE)
 | 
						|
		tif->tif_dir.td_stripsperimage /= tif->tif_dir.td_samplesperpixel;
 | 
						|
	if (!TIFFFieldSet(tif, FIELD_STRIPOFFSETS)) {
 | 
						|
		if ((tif->tif_dir.td_compression==COMPRESSION_OJPEG) &&
 | 
						|
		    (isTiled(tif)==0) &&
 | 
						|
		    (tif->tif_dir.td_nstrips==1)) {
 | 
						|
			/*
 | 
						|
			 * XXX: OJPEG hack.
 | 
						|
			 * If a) compression is OJPEG, b) it's not a tiled TIFF,
 | 
						|
			 * and c) the number of strips is 1,
 | 
						|
			 * then we tolerate the absence of stripoffsets tag,
 | 
						|
			 * because, presumably, all required data is in the
 | 
						|
			 * JpegInterchangeFormat stream.
 | 
						|
			 */
 | 
						|
			TIFFSetFieldBit(tif, FIELD_STRIPOFFSETS);
 | 
						|
		} else {
 | 
						|
			MissingRequired(tif,
 | 
						|
				isTiled(tif) ? "TileOffsets" : "StripOffsets");
 | 
						|
			goto bad;
 | 
						|
		}
 | 
						|
	}
 | 
						|
	/*
 | 
						|
	 * Second pass: extract other information.
 | 
						|
	 */
 | 
						|
	for (di=0, dp=dir; 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:
 | 
						|
				/*
 | 
						|
				 * The MinSampleValue, MaxSampleValue, BitsPerSample
 | 
						|
				 * DataType and SampleFormat tags are supposed to be
 | 
						|
				 * written as one value/sample, but some vendors
 | 
						|
				 * incorrectly write one value only -- so we accept
 | 
						|
				 * that as well (yech). Other vendors write correct
 | 
						|
				 * value for NumberOfSamples, but incorrect one for
 | 
						|
				 * BitsPerSample and friends, and we will read this
 | 
						|
				 * too.
 | 
						|
				 */
 | 
						|
				{
 | 
						|
					uint16 value;
 | 
						|
					enum TIFFReadDirEntryErr err;
 | 
						|
					err=TIFFReadDirEntryShort(tif,dp,&value);
 | 
						|
					if (err==TIFFReadDirEntryErrCount)
 | 
						|
						err=TIFFReadDirEntryPersampleShort(tif,dp,&value);
 | 
						|
					if (err!=TIFFReadDirEntryErrOk)
 | 
						|
					{
 | 
						|
						fip = TIFFFieldWithTag(tif,dp->tdir_tag);
 | 
						|
						TIFFReadDirEntryOutputErr(tif,err,module,fip ? fip->field_name : "unknown tagname",0);
 | 
						|
						goto bad;
 | 
						|
					}
 | 
						|
					if (!TIFFSetField(tif,dp->tdir_tag,value))
 | 
						|
						goto bad;
 | 
						|
				}
 | 
						|
				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;
 | 
						|
/* BEGIN REV 4.0 COMPATIBILITY */
 | 
						|
			case TIFFTAG_OSUBFILETYPE:
 | 
						|
				{
 | 
						|
					uint16 valueo;
 | 
						|
					uint32 value;
 | 
						|
					if (TIFFReadDirEntryShort(tif,dp,&valueo)==TIFFReadDirEntryErrOk)
 | 
						|
					{
 | 
						|
						switch (valueo)
 | 
						|
						{
 | 
						|
							case OFILETYPE_REDUCEDIMAGE: value=FILETYPE_REDUCEDIMAGE; break;
 | 
						|
							case OFILETYPE_PAGE: value=FILETYPE_PAGE; break;
 | 
						|
							default: value=0; break;
 | 
						|
						}
 | 
						|
						if (value!=0)
 | 
						|
							TIFFSetField(tif,TIFFTAG_SUBFILETYPE,value);
 | 
						|
					}
 | 
						|
				}
 | 
						|
				break;
 | 
						|
/* END REV 4.0 COMPATIBILITY */
 | 
						|
			default:
 | 
						|
				(void) TIFFFetchNormalTag(tif, dp, TRUE);
 | 
						|
				break;
 | 
						|
		}
 | 
						|
	}
 | 
						|
	/*
 | 
						|
	 * OJPEG hack:
 | 
						|
	 * - If a) compression is OJPEG, and b) photometric tag is missing,
 | 
						|
	 * then we consistently find that photometric should be YCbCr
 | 
						|
	 * - If a) compression is OJPEG, and b) photometric tag says it's RGB,
 | 
						|
	 * then we consistently find that the buggy implementation of the
 | 
						|
	 * buggy compression scheme matches photometric YCbCr instead.
 | 
						|
	 * - If a) compression is OJPEG, and b) bitspersample tag is missing,
 | 
						|
	 * then we consistently find bitspersample should be 8.
 | 
						|
	 * - If a) compression is OJPEG, b) samplesperpixel tag is missing,
 | 
						|
	 * and c) photometric is RGB or YCbCr, then we consistently find
 | 
						|
	 * samplesperpixel should be 3
 | 
						|
	 * - If a) compression is OJPEG, b) samplesperpixel tag is missing,
 | 
						|
	 * and c) photometric is MINISWHITE or MINISBLACK, then we consistently
 | 
						|
	 * find samplesperpixel should be 3
 | 
						|
	 */
 | 
						|
	if (tif->tif_dir.td_compression==COMPRESSION_OJPEG)
 | 
						|
	{
 | 
						|
		if (!TIFFFieldSet(tif,FIELD_PHOTOMETRIC))
 | 
						|
		{
 | 
						|
			TIFFWarningExt(tif->tif_clientdata, module,
 | 
						|
			    "Photometric tag is missing, assuming data is YCbCr");
 | 
						|
			if (!TIFFSetField(tif,TIFFTAG_PHOTOMETRIC,PHOTOMETRIC_YCBCR))
 | 
						|
				goto bad;
 | 
						|
		}
 | 
						|
		else if (tif->tif_dir.td_photometric==PHOTOMETRIC_RGB)
 | 
						|
		{
 | 
						|
			tif->tif_dir.td_photometric=PHOTOMETRIC_YCBCR;
 | 
						|
			TIFFWarningExt(tif->tif_clientdata, module,
 | 
						|
			    "Photometric tag value assumed incorrect, "
 | 
						|
			    "assuming data is YCbCr instead of RGB");
 | 
						|
		}
 | 
						|
		if (!TIFFFieldSet(tif,FIELD_BITSPERSAMPLE))
 | 
						|
		{
 | 
						|
			TIFFWarningExt(tif->tif_clientdata,module,
 | 
						|
			    "BitsPerSample tag is missing, assuming 8 bits per sample");
 | 
						|
			if (!TIFFSetField(tif,TIFFTAG_BITSPERSAMPLE,8))
 | 
						|
				goto bad;
 | 
						|
		}
 | 
						|
		if (!TIFFFieldSet(tif,FIELD_SAMPLESPERPIXEL))
 | 
						|
		{
 | 
						|
			if (tif->tif_dir.td_photometric==PHOTOMETRIC_RGB)
 | 
						|
			{
 | 
						|
				TIFFWarningExt(tif->tif_clientdata,module,
 | 
						|
				    "SamplesPerPixel tag is missing, "
 | 
						|
				    "assuming correct SamplesPerPixel value is 3");
 | 
						|
				if (!TIFFSetField(tif,TIFFTAG_SAMPLESPERPIXEL,3))
 | 
						|
					goto bad;
 | 
						|
			}
 | 
						|
			if (tif->tif_dir.td_photometric==PHOTOMETRIC_YCBCR)
 | 
						|
			{
 | 
						|
				TIFFWarningExt(tif->tif_clientdata,module,
 | 
						|
				    "SamplesPerPixel tag is missing, "
 | 
						|
				    "applying correct SamplesPerPixel value of 3");
 | 
						|
				if (!TIFFSetField(tif,TIFFTAG_SAMPLESPERPIXEL,3))
 | 
						|
					goto bad;
 | 
						|
			}
 | 
						|
			else if ((tif->tif_dir.td_photometric==PHOTOMETRIC_MINISWHITE)
 | 
						|
				 || (tif->tif_dir.td_photometric==PHOTOMETRIC_MINISBLACK))
 | 
						|
			{
 | 
						|
				/*
 | 
						|
				 * SamplesPerPixel tag is missing, but is not required
 | 
						|
				 * by spec.  Assume correct SamplesPerPixel value of 1.
 | 
						|
				 */
 | 
						|
				if (!TIFFSetField(tif,TIFFTAG_SAMPLESPERPIXEL,1))
 | 
						|
					goto bad;
 | 
						|
			}
 | 
						|
		}
 | 
						|
	}
 | 
						|
	/*
 | 
						|
	 * Verify Palette image has a Colormap.
 | 
						|
	 */
 | 
						|
	if (tif->tif_dir.td_photometric == PHOTOMETRIC_PALETTE &&
 | 
						|
	    !TIFFFieldSet(tif, FIELD_COLORMAP)) {
 | 
						|
		if ( tif->tif_dir.td_bitspersample>=8 && tif->tif_dir.td_samplesperpixel==3)
 | 
						|
			tif->tif_dir.td_photometric = PHOTOMETRIC_RGB;
 | 
						|
		else if (tif->tif_dir.td_bitspersample>=8)
 | 
						|
			tif->tif_dir.td_photometric = PHOTOMETRIC_MINISBLACK;
 | 
						|
		else {
 | 
						|
			MissingRequired(tif, "Colormap");
 | 
						|
			goto bad;
 | 
						|
		}
 | 
						|
	}
 | 
						|
	/*
 | 
						|
	 * OJPEG hack:
 | 
						|
	 * We do no further messing with strip/tile offsets/bytecounts in OJPEG
 | 
						|
	 * TIFFs
 | 
						|
	 */
 | 
						|
	if (tif->tif_dir.td_compression!=COMPRESSION_OJPEG)
 | 
						|
	{
 | 
						|
		/*
 | 
						|
		 * Attempt to deal with a missing StripByteCounts tag.
 | 
						|
		 */
 | 
						|
		if (!TIFFFieldSet(tif, FIELD_STRIPBYTECOUNTS)) {
 | 
						|
			/*
 | 
						|
			 * Some manufacturers violate the spec by not giving
 | 
						|
			 * the size of the strips.  In this case, assume there
 | 
						|
			 * is one uncompressed strip of data.
 | 
						|
			 */
 | 
						|
			if ((tif->tif_dir.td_planarconfig == PLANARCONFIG_CONTIG &&
 | 
						|
			    tif->tif_dir.td_nstrips > 1) ||
 | 
						|
			    (tif->tif_dir.td_planarconfig == PLANARCONFIG_SEPARATE &&
 | 
						|
			     tif->tif_dir.td_nstrips != (uint32)tif->tif_dir.td_samplesperpixel)) {
 | 
						|
			    MissingRequired(tif, "StripByteCounts");
 | 
						|
			    goto bad;
 | 
						|
			}
 | 
						|
			TIFFWarningExt(tif->tif_clientdata, module,
 | 
						|
				"TIFF directory is missing required "
 | 
						|
				"\"StripByteCounts\" field, calculating from imagelength");
 | 
						|
			if (EstimateStripByteCounts(tif, dir, dircount) < 0)
 | 
						|
			    goto bad;
 | 
						|
		/*
 | 
						|
		 * Assume we have wrong StripByteCount value (in case
 | 
						|
		 * of single strip) in following cases:
 | 
						|
		 *   - it is equal to zero along with StripOffset;
 | 
						|
		 *   - it is larger than file itself (in case of uncompressed
 | 
						|
		 *     image);
 | 
						|
		 *   - it is smaller than the size of the bytes per row
 | 
						|
		 *     multiplied on the number of rows.  The last case should
 | 
						|
		 *     not be checked in the case of writing new image,
 | 
						|
		 *     because we may do not know the exact strip size
 | 
						|
		 *     until the whole image will be written and directory
 | 
						|
		 *     dumped out.
 | 
						|
		 */
 | 
						|
		#define	BYTECOUNTLOOKSBAD \
 | 
						|
		    ( (tif->tif_dir.td_stripbytecount[0] == 0 && tif->tif_dir.td_stripoffset[0] != 0) || \
 | 
						|
		      (tif->tif_dir.td_compression == COMPRESSION_NONE && \
 | 
						|
		       tif->tif_dir.td_stripbytecount[0] > TIFFGetFileSize(tif) - tif->tif_dir.td_stripoffset[0]) || \
 | 
						|
		      (tif->tif_mode == O_RDONLY && \
 | 
						|
		       tif->tif_dir.td_compression == COMPRESSION_NONE && \
 | 
						|
		       tif->tif_dir.td_stripbytecount[0] < TIFFScanlineSize64(tif) * tif->tif_dir.td_imagelength) )
 | 
						|
 | 
						|
		} else if (tif->tif_dir.td_nstrips == 1
 | 
						|
                           && _TIFFFillStriles(tif)
 | 
						|
			   && tif->tif_dir.td_stripoffset[0] != 0
 | 
						|
			   && BYTECOUNTLOOKSBAD) {
 | 
						|
			/*
 | 
						|
			 * XXX: Plexus (and others) sometimes give a value of
 | 
						|
			 * zero for a tag when they don't know what the
 | 
						|
			 * correct value is!  Try and handle the simple case
 | 
						|
			 * of estimating the size of a one strip image.
 | 
						|
			 */
 | 
						|
			TIFFWarningExt(tif->tif_clientdata, module,
 | 
						|
			    "Bogus \"StripByteCounts\" field, ignoring and calculating from imagelength");
 | 
						|
			if(EstimateStripByteCounts(tif, dir, dircount) < 0)
 | 
						|
			    goto bad;
 | 
						|
 | 
						|
#if !defined(DEFER_STRILE_LOAD)
 | 
						|
		} else if (tif->tif_dir.td_planarconfig == PLANARCONFIG_CONTIG
 | 
						|
			   && tif->tif_dir.td_nstrips > 2
 | 
						|
			   && tif->tif_dir.td_compression == COMPRESSION_NONE
 | 
						|
			   && tif->tif_dir.td_stripbytecount[0] != tif->tif_dir.td_stripbytecount[1]
 | 
						|
			   && tif->tif_dir.td_stripbytecount[0] != 0
 | 
						|
			   && tif->tif_dir.td_stripbytecount[1] != 0 ) {
 | 
						|
			/*
 | 
						|
			 * XXX: Some vendors fill StripByteCount array with
 | 
						|
			 * absolutely wrong values (it can be equal to
 | 
						|
			 * StripOffset array, for example). Catch this case
 | 
						|
			 * here.
 | 
						|
                         *
 | 
						|
                         * We avoid this check if deferring strile loading
 | 
						|
                         * as it would always force us to load the strip/tile
 | 
						|
                         * information.
 | 
						|
			 */
 | 
						|
			TIFFWarningExt(tif->tif_clientdata, module,
 | 
						|
			    "Wrong \"StripByteCounts\" field, ignoring and calculating from imagelength");
 | 
						|
			if (EstimateStripByteCounts(tif, dir, dircount) < 0)
 | 
						|
			    goto bad;
 | 
						|
#endif /* !defined(DEFER_STRILE_LOAD) */                        
 | 
						|
		}
 | 
						|
	}
 | 
						|
	if (dir)
 | 
						|
	{
 | 
						|
		_TIFFfree(dir);
 | 
						|
		dir=NULL;
 | 
						|
	}
 | 
						|
	if (!TIFFFieldSet(tif, FIELD_MAXSAMPLEVALUE))
 | 
						|
	{
 | 
						|
		if (tif->tif_dir.td_bitspersample>=16)
 | 
						|
			tif->tif_dir.td_maxsamplevalue=0xFFFF;
 | 
						|
		else
 | 
						|
			tif->tif_dir.td_maxsamplevalue = (uint16)((1L<<tif->tif_dir.td_bitspersample)-1);
 | 
						|
	}
 | 
						|
	/*
 | 
						|
	 * XXX: We can optimize checking for the strip bounds using the sorted
 | 
						|
	 * bytecounts array. See also comments for TIFFAppendToStrip()
 | 
						|
	 * function in tif_write.c.
 | 
						|
	 */
 | 
						|
#if !defined(DEFER_STRILE_LOAD)        
 | 
						|
	if (tif->tif_dir.td_nstrips > 1) {
 | 
						|
		uint32 strip;
 | 
						|
 | 
						|
		tif->tif_dir.td_stripbytecountsorted = 1;
 | 
						|
		for (strip = 1; strip < tif->tif_dir.td_nstrips; strip++) {
 | 
						|
			if (tif->tif_dir.td_stripoffset[strip - 1] >
 | 
						|
			    tif->tif_dir.td_stripoffset[strip]) {
 | 
						|
				tif->tif_dir.td_stripbytecountsorted = 0;
 | 
						|
				break;
 | 
						|
			}
 | 
						|
		}
 | 
						|
	}
 | 
						|
#endif /* !defined(DEFER_STRILE_LOAD) */
 | 
						|
        
 | 
						|
	/*
 | 
						|
	 * An opportunity for compression mode dependent tag fixup
 | 
						|
	 */
 | 
						|
	(*tif->tif_fixuptags)(tif);
 | 
						|
 | 
						|
	/*
 | 
						|
	 * Some manufacturers make life difficult by writing
 | 
						|
	 * large amounts of uncompressed data as a single strip.
 | 
						|
	 * This is contrary to the recommendations of the spec.
 | 
						|
	 * The following makes an attempt at breaking such images
 | 
						|
	 * into strips closer to the recommended 8k bytes.  A
 | 
						|
	 * side effect, however, is that the RowsPerStrip tag
 | 
						|
	 * value may be changed.
 | 
						|
	 */
 | 
						|
	if ((tif->tif_dir.td_planarconfig==PLANARCONFIG_CONTIG)&&
 | 
						|
	    (tif->tif_dir.td_nstrips==1)&&
 | 
						|
	    (tif->tif_dir.td_compression==COMPRESSION_NONE)&&  
 | 
						|
	    ((tif->tif_flags&(TIFF_STRIPCHOP|TIFF_ISTILED))==TIFF_STRIPCHOP))
 | 
						|
    {
 | 
						|
        if ( !_TIFFFillStriles(tif) || !tif->tif_dir.td_stripbytecount )
 | 
						|
            return 0;
 | 
						|
		ChopUpSingleUncompressedStrip(tif);
 | 
						|
    }
 | 
						|
 | 
						|
        /*
 | 
						|
         * Clear the dirty directory flag. 
 | 
						|
         */
 | 
						|
	tif->tif_flags &= ~TIFF_DIRTYDIRECT;
 | 
						|
	tif->tif_flags &= ~TIFF_DIRTYSTRIP;
 | 
						|
 | 
						|
	/*
 | 
						|
	 * Reinitialize i/o since we are starting on a new directory.
 | 
						|
	 */
 | 
						|
	tif->tif_row = (uint32) -1;
 | 
						|
	tif->tif_curstrip = (uint32) -1;
 | 
						|
	tif->tif_col = (uint32) -1;
 | 
						|
	tif->tif_curtile = (uint32) -1;
 | 
						|
	tif->tif_tilesize = (tmsize_t) -1;
 | 
						|
 | 
						|
	tif->tif_scanlinesize = TIFFScanlineSize(tif);
 | 
						|
	if (!tif->tif_scanlinesize) {
 | 
						|
		TIFFErrorExt(tif->tif_clientdata, module,
 | 
						|
		    "Cannot handle zero scanline size");
 | 
						|
		return (0);
 | 
						|
	}
 | 
						|
 | 
						|
	if (isTiled(tif)) {
 | 
						|
		tif->tif_tilesize = TIFFTileSize(tif);
 | 
						|
		if (!tif->tif_tilesize) {
 | 
						|
			TIFFErrorExt(tif->tif_clientdata, module,
 | 
						|
			     "Cannot handle zero tile size");
 | 
						|
			return (0);
 | 
						|
		}
 | 
						|
	} else {
 | 
						|
		if (!TIFFStripSize(tif)) {
 | 
						|
			TIFFErrorExt(tif->tif_clientdata, module,
 | 
						|
			    "Cannot handle zero strip size");
 | 
						|
			return (0);
 | 
						|
		}
 | 
						|
	}
 | 
						|
	return (1);
 | 
						|
bad:
 | 
						|
	if (dir)
 | 
						|
		_TIFFfree(dir);
 | 
						|
	return (0);
 | 
						|
}
 | 
						|
 | 
						|
static void
 | 
						|
TIFFReadDirectoryCheckOrder(TIFF* tif, TIFFDirEntry* dir, uint16 dircount)
 | 
						|
{
 | 
						|
	static const char module[] = "TIFFReadDirectoryCheckOrder";
 | 
						|
	uint16 m;
 | 
						|
	uint16 n;
 | 
						|
	TIFFDirEntry* o;
 | 
						|
	m=0;
 | 
						|
	for (n=0, o=dir; 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;
 | 
						|
}
 | 
						|
 | 
						|
/*
 | 
						|
 * Read custom directory from the arbitarry offset.
 | 
						|
 * The code is very similar to TIFFReadDirectory().
 | 
						|
 */
 | 
						|
int
 | 
						|
TIFFReadCustomDirectory(TIFF* tif, toff_t diroff,
 | 
						|
			const TIFFFieldArray* infoarray)
 | 
						|
{
 | 
						|
	static const char module[] = "TIFFReadCustomDirectory";
 | 
						|
	TIFFDirEntry* dir;
 | 
						|
	uint16 dircount;
 | 
						|
	TIFFDirEntry* dp;
 | 
						|
	uint16 di;
 | 
						|
	const TIFFField* fip;
 | 
						|
	uint32 fii;
 | 
						|
	_TIFFSetupFields(tif, infoarray);
 | 
						|
	dircount=TIFFFetchDirectory(tif,diroff,&dir,NULL);
 | 
						|
	if (!dircount)
 | 
						|
	{
 | 
						|
		TIFFErrorExt(tif->tif_clientdata,module,
 | 
						|
		    "Failed to read custom directory at offset " TIFF_UINT64_FORMAT,diroff);
 | 
						|
		return 0;
 | 
						|
	}
 | 
						|
	TIFFFreeDirectory(tif);
 | 
						|
	_TIFFmemset(&tif->tif_dir, 0, sizeof(TIFFDirectory));
 | 
						|
	TIFFReadDirectoryCheckOrder(tif,dir,dircount);
 | 
						|
	for (di=0, dp=dir; 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
 | 
						|
			{
 | 
						|
				/* check data type */
 | 
						|
				while ((fip->field_type!=TIFF_ANY)&&(fip->field_type!=dp->tdir_type))
 | 
						|
				{
 | 
						|
					fii++;
 | 
						|
					if ((fii==tif->tif_nfields)||
 | 
						|
					    (tif->tif_fields[fii]->field_tag!=(uint32)dp->tdir_tag))
 | 
						|
					{
 | 
						|
						fii=0xFFFF;
 | 
						|
						break;
 | 
						|
					}
 | 
						|
					fip=tif->tif_fields[fii];
 | 
						|
				}
 | 
						|
				if (fii==0xFFFF)
 | 
						|
				{
 | 
						|
					TIFFWarningExt(tif->tif_clientdata, module,
 | 
						|
					    "Wrong data type %d for \"%s\"; tag ignored",
 | 
						|
					    dp->tdir_type,fip->field_name);
 | 
						|
					dp->tdir_tag=IGNORE;
 | 
						|
				}
 | 
						|
				else
 | 
						|
				{
 | 
						|
					/* check count if known in advance */
 | 
						|
					if ((fip->field_readcount!=TIFF_VARIABLE)&&
 | 
						|
					    (fip->field_readcount!=TIFF_VARIABLE2))
 | 
						|
					{
 | 
						|
						uint32 expected;
 | 
						|
						if (fip->field_readcount==TIFF_SPP)
 | 
						|
							expected=(uint32)tif->tif_dir.td_samplesperpixel;
 | 
						|
						else
 | 
						|
							expected=(uint32)fip->field_readcount;
 | 
						|
						if (!CheckDirCount(tif,dp,expected))
 | 
						|
							dp->tdir_tag=IGNORE;
 | 
						|
					}
 | 
						|
				}
 | 
						|
			}
 | 
						|
			switch (dp->tdir_tag)
 | 
						|
			{
 | 
						|
				case IGNORE:
 | 
						|
					break;
 | 
						|
				case EXIFTAG_SUBJECTDISTANCE:
 | 
						|
					(void) TIFFFetchSubjectDistance(tif,dp);
 | 
						|
					break;
 | 
						|
				default:
 | 
						|
					(void) TIFFFetchNormalTag(tif, dp, TRUE);
 | 
						|
					break;
 | 
						|
			}
 | 
						|
		}
 | 
						|
	}
 | 
						|
	if (dir)
 | 
						|
		_TIFFfree(dir);
 | 
						|
	return 1;
 | 
						|
}
 | 
						|
 | 
						|
/*
 | 
						|
 * EXIF is important special case of custom IFD, so we have a special
 | 
						|
 * function to read it.
 | 
						|
 */
 | 
						|
int
 | 
						|
TIFFReadEXIFDirectory(TIFF* tif, toff_t diroff)
 | 
						|
{
 | 
						|
	const TIFFFieldArray* exifFieldArray;
 | 
						|
	exifFieldArray = _TIFFGetExifFields();
 | 
						|
	return TIFFReadCustomDirectory(tif, diroff, exifFieldArray);  
 | 
						|
}
 | 
						|
 | 
						|
static int
 | 
						|
EstimateStripByteCounts(TIFF* tif, TIFFDirEntry* dir, uint16 dircount)
 | 
						|
{
 | 
						|
	static const char module[] = "EstimateStripByteCounts";
 | 
						|
 | 
						|
	TIFFDirEntry *dp;
 | 
						|
	TIFFDirectory *td = &tif->tif_dir;
 | 
						|
	uint32 strip;
 | 
						|
 | 
						|
    _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;
 | 
						|
		/* calculate amount of space used by indirect values */
 | 
						|
		for (dp = dir, n = dircount; n > 0; n--, dp++)
 | 
						|
		{
 | 
						|
			uint32 typewidth = TIFFDataWidth((TIFFDataType) dp->tdir_type);
 | 
						|
			uint64 datasize;
 | 
						|
			typewidth = TIFFDataWidth((TIFFDataType) dp->tdir_type);
 | 
						|
			if (typewidth == 0) {
 | 
						|
				TIFFErrorExt(tif->tif_clientdata, module,
 | 
						|
				    "Cannot determine size of unknown tag type %d",
 | 
						|
				    dp->tdir_type);
 | 
						|
				return -1;
 | 
						|
			}
 | 
						|
			datasize=(uint64)typewidth*dp->tdir_count;
 | 
						|
			if (!(tif->tif_flags&TIFF_BIGTIFF))
 | 
						|
			{
 | 
						|
				if (datasize<=4)
 | 
						|
					datasize=0;
 | 
						|
			}
 | 
						|
			else
 | 
						|
			{
 | 
						|
				if (datasize<=8)
 | 
						|
					datasize=0;
 | 
						|
			}
 | 
						|
			space+=datasize;
 | 
						|
		}
 | 
						|
		space = filesize - space;
 | 
						|
		if (td->td_planarconfig == PLANARCONFIG_SEPARATE)
 | 
						|
			space /= td->td_samplesperpixel;
 | 
						|
		for (strip = 0; strip < td->td_nstrips; strip++)
 | 
						|
			td->td_stripbytecount[strip] = space;
 | 
						|
		/*
 | 
						|
		 * This gross hack handles the case were the offset to
 | 
						|
		 * the last strip is past the place where we think the strip
 | 
						|
		 * should begin.  Since a strip of data must be contiguous,
 | 
						|
		 * it's safe to assume that we've overestimated the amount
 | 
						|
		 * of data in the strip and trim this number back accordingly.
 | 
						|
		 */
 | 
						|
		strip--;
 | 
						|
		if (td->td_stripoffset[strip]+td->td_stripbytecount[strip] > filesize)
 | 
						|
			td->td_stripbytecount[strip] = filesize - td->td_stripoffset[strip];
 | 
						|
	} else if (isTiled(tif)) {
 | 
						|
		uint64 bytespertile = TIFFTileSize64(tif);
 | 
						|
 | 
						|
		for (strip = 0; strip < td->td_nstrips; strip++)
 | 
						|
		    td->td_stripbytecount[strip] = bytespertile;
 | 
						|
	} else {
 | 
						|
		uint64 rowbytes = TIFFScanlineSize64(tif);
 | 
						|
		uint32 rowsperstrip = td->td_imagelength/td->td_stripsperimage;
 | 
						|
		for (strip = 0; strip < td->td_nstrips; strip++)
 | 
						|
			td->td_stripbytecount[strip] = rowbytes * rowsperstrip;
 | 
						|
	}
 | 
						|
	TIFFSetFieldBit(tif, FIELD_STRIPBYTECOUNTS);
 | 
						|
	if (!TIFFFieldSet(tif, FIELD_ROWSPERSTRIP))
 | 
						|
		td->td_rowsperstrip = td->td_imagelength;
 | 
						|
	return 1;
 | 
						|
}
 | 
						|
 | 
						|
static void
 | 
						|
MissingRequired(TIFF* tif, const char* tagname)
 | 
						|
{
 | 
						|
	static const char module[] = "MissingRequired";
 | 
						|
 | 
						|
	TIFFErrorExt(tif->tif_clientdata, module,
 | 
						|
	    "TIFF directory is missing required \"%s\" field",
 | 
						|
	    tagname);
 | 
						|
}
 | 
						|
 | 
						|
/*
 | 
						|
 * Check the directory offset against the list of already seen directory
 | 
						|
 * offsets. This is a trick to prevent IFD looping. The one can create TIFF
 | 
						|
 * file with looped directory pointers. We will maintain a list of already
 | 
						|
 * seen directories and check every IFD offset against that list.
 | 
						|
 */
 | 
						|
static int
 | 
						|
TIFFCheckDirOffset(TIFF* tif, uint64 diroff)
 | 
						|
{
 | 
						|
	uint16 n;
 | 
						|
 | 
						|
	if (diroff == 0)			/* no more directories */
 | 
						|
		return 0;
 | 
						|
 | 
						|
	for (n = 0; n < tif->tif_dirnumber && tif->tif_dirlist; n++) {
 | 
						|
		if (tif->tif_dirlist[n] == diroff)
 | 
						|
			return 0;
 | 
						|
	}
 | 
						|
 | 
						|
	tif->tif_dirnumber++;
 | 
						|
 | 
						|
	if (tif->tif_dirnumber > tif->tif_dirlistsize) {
 | 
						|
		uint64* new_dirlist;
 | 
						|
 | 
						|
		/*
 | 
						|
		 * XXX: Reduce memory allocation granularity of the dirlist
 | 
						|
		 * array.
 | 
						|
		 */
 | 
						|
		new_dirlist = (uint64*)_TIFFCheckRealloc(tif, tif->tif_dirlist,
 | 
						|
		    tif->tif_dirnumber, 2 * sizeof(uint64), "for IFD list");
 | 
						|
		if (!new_dirlist)
 | 
						|
			return 0;
 | 
						|
		tif->tif_dirlistsize = 2 * tif->tif_dirnumber;
 | 
						|
		tif->tif_dirlist = new_dirlist;
 | 
						|
	}
 | 
						|
 | 
						|
	tif->tif_dirlist[tif->tif_dirnumber - 1] = diroff;
 | 
						|
 | 
						|
	return 1;
 | 
						|
}
 | 
						|
 | 
						|
/*
 | 
						|
 * Check the count field of a directory entry against a known value.  The
 | 
						|
 * caller is expected to skip/ignore the tag if there is a mismatch.
 | 
						|
 */
 | 
						|
static int
 | 
						|
CheckDirCount(TIFF* tif, TIFFDirEntry* dir, uint32 count)
 | 
						|
{
 | 
						|
	if ((uint64)count > dir->tdir_count) {
 | 
						|
		const TIFFField* fip = TIFFFieldWithTag(tif, dir->tdir_tag);
 | 
						|
		TIFFWarningExt(tif->tif_clientdata, tif->tif_name,
 | 
						|
	"incorrect count for field \"%s\" (" TIFF_UINT64_FORMAT ", expecting %u); tag ignored",
 | 
						|
		    fip ? fip->field_name : "unknown tagname",
 | 
						|
		    dir->tdir_count, count);
 | 
						|
		return (0);
 | 
						|
	} else if ((uint64)count < dir->tdir_count) {
 | 
						|
		const TIFFField* fip = TIFFFieldWithTag(tif, dir->tdir_tag);
 | 
						|
		TIFFWarningExt(tif->tif_clientdata, tif->tif_name,
 | 
						|
	"incorrect count for field \"%s\" (" TIFF_UINT64_FORMAT ", expecting %u); tag trimmed",
 | 
						|
		    fip ? fip->field_name : "unknown tagname",
 | 
						|
		    dir->tdir_count, count);
 | 
						|
		dir->tdir_count = count;
 | 
						|
		return (1);
 | 
						|
	}
 | 
						|
	return (1);
 | 
						|
}
 | 
						|
 | 
						|
/*
 | 
						|
 * Read IFD structure from the specified offset. If the pointer to
 | 
						|
 * nextdiroff variable has been specified, read it too. Function returns a
 | 
						|
 * number of fields in the directory or 0 if failed.
 | 
						|
 */
 | 
						|
static uint16
 | 
						|
TIFFFetchDirectory(TIFF* tif, uint64 diroff, TIFFDirEntry** pdir,
 | 
						|
                   uint64 *nextdiroff)
 | 
						|
{
 | 
						|
	static const char module[] = "TIFFFetchDirectory";
 | 
						|
 | 
						|
	void* origdir;
 | 
						|
	uint16 dircount16;
 | 
						|
	uint32 dirsize;
 | 
						|
	TIFFDirEntry* dir;
 | 
						|
	uint8* ma;
 | 
						|
	TIFFDirEntry* mb;
 | 
						|
	uint16 n;
 | 
						|
 | 
						|
	assert(pdir);
 | 
						|
 | 
						|
	tif->tif_diroff = diroff;
 | 
						|
	if (nextdiroff)
 | 
						|
		*nextdiroff = 0;
 | 
						|
	if (!isMapped(tif)) {
 | 
						|
		if (!SeekOK(tif, tif->tif_diroff)) {
 | 
						|
			TIFFErrorExt(tif->tif_clientdata, module,
 | 
						|
				"%s: Seek error accessing TIFF directory",
 | 
						|
				tif->tif_name);
 | 
						|
			return 0;
 | 
						|
		}
 | 
						|
		if (!(tif->tif_flags&TIFF_BIGTIFF))
 | 
						|
		{
 | 
						|
			if (!ReadOK(tif, &dircount16, sizeof (uint16))) {
 | 
						|
				TIFFErrorExt(tif->tif_clientdata, module,
 | 
						|
				    "%s: Can not read TIFF directory count",
 | 
						|
				    tif->tif_name);
 | 
						|
				return 0;
 | 
						|
			}
 | 
						|
			if (tif->tif_flags & TIFF_SWAB)
 | 
						|
				TIFFSwabShort(&dircount16);
 | 
						|
			if (dircount16>4096)
 | 
						|
			{
 | 
						|
				TIFFErrorExt(tif->tif_clientdata, module,
 | 
						|
				    "Sanity check on directory count failed, this is probably not a valid IFD offset");
 | 
						|
				return 0;
 | 
						|
			}
 | 
						|
			dirsize = 12;
 | 
						|
		} else {
 | 
						|
			uint64 dircount64;
 | 
						|
			if (!ReadOK(tif, &dircount64, sizeof (uint64))) {
 | 
						|
				TIFFErrorExt(tif->tif_clientdata, module,
 | 
						|
					"%s: Can not read TIFF directory count",
 | 
						|
					tif->tif_name);
 | 
						|
				return 0;
 | 
						|
			}
 | 
						|
			if (tif->tif_flags & TIFF_SWAB)
 | 
						|
				TIFFSwabLong8(&dircount64);
 | 
						|
			if (dircount64>4096)
 | 
						|
			{
 | 
						|
				TIFFErrorExt(tif->tif_clientdata, module,
 | 
						|
				    "Sanity check on directory count failed, this is probably not a valid IFD offset");
 | 
						|
				return 0;
 | 
						|
			}
 | 
						|
			dircount16 = (uint16)dircount64;
 | 
						|
			dirsize = 20;
 | 
						|
		}
 | 
						|
		origdir = _TIFFCheckMalloc(tif, dircount16,
 | 
						|
		    dirsize, "to read TIFF directory");
 | 
						|
		if (origdir == NULL)
 | 
						|
			return 0;
 | 
						|
		if (!ReadOK(tif, origdir, (tmsize_t)(dircount16*dirsize))) {
 | 
						|
			TIFFErrorExt(tif->tif_clientdata, module,
 | 
						|
				"%.100s: Can not read TIFF directory",
 | 
						|
				tif->tif_name);
 | 
						|
			_TIFFfree(origdir);
 | 
						|
			return 0;
 | 
						|
		}
 | 
						|
		/*
 | 
						|
		 * Read offset to next directory for sequential scans if
 | 
						|
		 * needed.
 | 
						|
		 */
 | 
						|
		if (nextdiroff)
 | 
						|
		{
 | 
						|
			if (!(tif->tif_flags&TIFF_BIGTIFF))
 | 
						|
			{
 | 
						|
				uint32 nextdiroff32;
 | 
						|
				if (!ReadOK(tif, &nextdiroff32, sizeof(uint32)))
 | 
						|
					nextdiroff32 = 0;
 | 
						|
				if (tif->tif_flags&TIFF_SWAB)
 | 
						|
					TIFFSwabLong(&nextdiroff32);
 | 
						|
				*nextdiroff=nextdiroff32;
 | 
						|
			} else {
 | 
						|
				if (!ReadOK(tif, nextdiroff, sizeof(uint64)))
 | 
						|
					*nextdiroff = 0;
 | 
						|
				if (tif->tif_flags&TIFF_SWAB)
 | 
						|
					TIFFSwabLong8(nextdiroff);
 | 
						|
			}
 | 
						|
		}
 | 
						|
	} else {
 | 
						|
		tmsize_t m;
 | 
						|
		tmsize_t off = (tmsize_t) tif->tif_diroff;
 | 
						|
		if ((uint64)off!=tif->tif_diroff)
 | 
						|
		{
 | 
						|
			TIFFErrorExt(tif->tif_clientdata,module,"Can not read TIFF directory count");
 | 
						|
			return(0);
 | 
						|
		}
 | 
						|
 | 
						|
		/*
 | 
						|
		 * Check for integer overflow when validating the dir_off,
 | 
						|
		 * otherwise a very high offset may cause an OOB read and
 | 
						|
		 * crash the client. Make two comparisons instead of
 | 
						|
		 *
 | 
						|
		 *  off + sizeof(uint16) > tif->tif_size
 | 
						|
		 *
 | 
						|
		 * to avoid overflow.
 | 
						|
		 */
 | 
						|
		if (!(tif->tif_flags&TIFF_BIGTIFF))
 | 
						|
		{
 | 
						|
			m=off+sizeof(uint16);
 | 
						|
			if ((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;
 | 
						|
}
 | 
						|
 | 
						|
/*
 | 
						|
 * Fetch a tag that is not handled by special case code.
 | 
						|
 */
 | 
						|
static int
 | 
						|
TIFFFetchNormalTag(TIFF* tif, TIFFDirEntry* dp, int recover)
 | 
						|
{
 | 
						|
	static const char module[] = "TIFFFetchNormalTag";
 | 
						|
	enum TIFFReadDirEntryErr err;
 | 
						|
	uint32 fii;
 | 
						|
	const TIFFField* fip = NULL;
 | 
						|
	TIFFReadDirectoryFindFieldInfo(tif,dp->tdir_tag,&fii);
 | 
						|
        if( fii == FAILED_FII )
 | 
						|
        {
 | 
						|
            TIFFErrorExt(tif->tif_clientdata, "TIFFFetchNormalTag",
 | 
						|
                         "No definition found for tag %d",
 | 
						|
                         dp->tdir_tag);
 | 
						|
            return 0;
 | 
						|
        }
 | 
						|
	fip=tif->tif_fields[fii];
 | 
						|
	assert(fip->set_field_type!=TIFF_SETGET_OTHER);  /* if so, we shouldn't arrive here but deal with this in specialized code */
 | 
						|
	assert(fip->set_field_type!=TIFF_SETGET_INT);    /* if so, we shouldn't arrive here as this is only the case for pseudo-tags */
 | 
						|
	err=TIFFReadDirEntryErrOk;
 | 
						|
	switch (fip->set_field_type)
 | 
						|
	{
 | 
						|
		case TIFF_SETGET_UNDEFINED:
 | 
						|
			break;
 | 
						|
		case TIFF_SETGET_ASCII:
 | 
						|
			{
 | 
						|
				uint8* data;
 | 
						|
				assert(fip->field_passcount==0);
 | 
						|
				err=TIFFReadDirEntryByteArray(tif,dp,&data);
 | 
						|
				if (err==TIFFReadDirEntryErrOk)
 | 
						|
				{
 | 
						|
					uint8* ma;
 | 
						|
					uint32 mb;
 | 
						|
					int n;
 | 
						|
					ma=data;
 | 
						|
					mb=0;
 | 
						|
					while (mb<(uint32)dp->tdir_count)
 | 
						|
					{
 | 
						|
						if (*ma==0)
 | 
						|
							break;
 | 
						|
						ma++;
 | 
						|
						mb++;
 | 
						|
					}
 | 
						|
					if (mb+1<(uint32)dp->tdir_count)
 | 
						|
						TIFFWarningExt(tif->tif_clientdata,module,"ASCII value for tag \"%s\" contains null byte in value; value incorrectly truncated during reading due to implementation limitations",fip->field_name);
 | 
						|
					else if (mb+1>(uint32)dp->tdir_count)
 | 
						|
					{
 | 
						|
						uint8* o;
 | 
						|
						TIFFWarningExt(tif->tif_clientdata,module,"ASCII value for tag \"%s\" does not end in null byte",fip->field_name);
 | 
						|
						if ((uint32)dp->tdir_count+1!=dp->tdir_count+1)
 | 
						|
							o=NULL;
 | 
						|
						else
 | 
						|
							o=_TIFFmalloc((uint32)dp->tdir_count+1);
 | 
						|
						if (o==NULL)
 | 
						|
						{
 | 
						|
							if (data!=NULL)
 | 
						|
								_TIFFfree(data);
 | 
						|
							return(0);
 | 
						|
						}
 | 
						|
						_TIFFmemcpy(o,data,(uint32)dp->tdir_count);
 | 
						|
						o[(uint32)dp->tdir_count]=0;
 | 
						|
						if (data!=0)
 | 
						|
							_TIFFfree(data);
 | 
						|
						data=o;
 | 
						|
					}
 | 
						|
					n=TIFFSetField(tif,dp->tdir_tag,data);
 | 
						|
					if (data!=0)
 | 
						|
						_TIFFfree(data);
 | 
						|
					if (!n)
 | 
						|
						return(0);
 | 
						|
				}
 | 
						|
			}
 | 
						|
			break;
 | 
						|
		case TIFF_SETGET_UINT8:
 | 
						|
			{
 | 
						|
				uint8 data;
 | 
						|
				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)
 | 
						|
                                    /* corrupt file */;
 | 
						|
				else
 | 
						|
				{
 | 
						|
					err=TIFFReadDirEntryByteArray(tif,dp,&data);
 | 
						|
					if (err==TIFFReadDirEntryErrOk)
 | 
						|
					{
 | 
						|
						int m;
 | 
						|
						m=TIFFSetField(tif,dp->tdir_tag,data);
 | 
						|
						if (data!=0)
 | 
						|
							_TIFFfree(data);
 | 
						|
						if (!m)
 | 
						|
							return(0);
 | 
						|
					}
 | 
						|
				}
 | 
						|
			}
 | 
						|
			break;
 | 
						|
		case TIFF_SETGET_C0_UINT16:
 | 
						|
			{
 | 
						|
				uint16* data;
 | 
						|
				assert(fip->field_readcount>=1);
 | 
						|
				assert(fip->field_passcount==0);
 | 
						|
				if (dp->tdir_count!=(uint64)fip->field_readcount)
 | 
						|
                                    /* corrupt file */;
 | 
						|
				else
 | 
						|
				{
 | 
						|
					err=TIFFReadDirEntryShortArray(tif,dp,&data);
 | 
						|
					if (err==TIFFReadDirEntryErrOk)
 | 
						|
					{
 | 
						|
						int m;
 | 
						|
						m=TIFFSetField(tif,dp->tdir_tag,data);
 | 
						|
						if (data!=0)
 | 
						|
							_TIFFfree(data);
 | 
						|
						if (!m)
 | 
						|
							return(0);
 | 
						|
					}
 | 
						|
				}
 | 
						|
			}
 | 
						|
			break;
 | 
						|
		case TIFF_SETGET_C0_UINT32:
 | 
						|
			{
 | 
						|
				uint32* data;
 | 
						|
				assert(fip->field_readcount>=1);
 | 
						|
				assert(fip->field_passcount==0);
 | 
						|
				if (dp->tdir_count!=(uint64)fip->field_readcount)
 | 
						|
                                    /* corrupt file */;
 | 
						|
				else
 | 
						|
				{
 | 
						|
					err=TIFFReadDirEntryLongArray(tif,dp,&data);
 | 
						|
					if (err==TIFFReadDirEntryErrOk)
 | 
						|
					{
 | 
						|
						int m;
 | 
						|
						m=TIFFSetField(tif,dp->tdir_tag,data);
 | 
						|
						if (data!=0)
 | 
						|
							_TIFFfree(data);
 | 
						|
						if (!m)
 | 
						|
							return(0);
 | 
						|
					}
 | 
						|
				}
 | 
						|
			}
 | 
						|
			break;
 | 
						|
		case TIFF_SETGET_C0_FLOAT:
 | 
						|
			{
 | 
						|
				float* data;
 | 
						|
				assert(fip->field_readcount>=1);
 | 
						|
				assert(fip->field_passcount==0);
 | 
						|
				if (dp->tdir_count!=(uint64)fip->field_readcount)
 | 
						|
                                    /* corrupt file */;
 | 
						|
				else
 | 
						|
				{
 | 
						|
					err=TIFFReadDirEntryFloatArray(tif,dp,&data);
 | 
						|
					if (err==TIFFReadDirEntryErrOk)
 | 
						|
					{
 | 
						|
						int m;
 | 
						|
						m=TIFFSetField(tif,dp->tdir_tag,data);
 | 
						|
						if (data!=0)
 | 
						|
							_TIFFfree(data);
 | 
						|
						if (!m)
 | 
						|
							return(0);
 | 
						|
					}
 | 
						|
				}
 | 
						|
			}
 | 
						|
			break;
 | 
						|
		case TIFF_SETGET_C16_ASCII:
 | 
						|
			{
 | 
						|
				uint8* data;
 | 
						|
				assert(fip->field_readcount==TIFF_VARIABLE);
 | 
						|
				assert(fip->field_passcount==1);
 | 
						|
				if (dp->tdir_count>0xFFFF)
 | 
						|
					err=TIFFReadDirEntryErrCount;
 | 
						|
				else
 | 
						|
				{
 | 
						|
					err=TIFFReadDirEntryByteArray(tif,dp,&data);
 | 
						|
					if (err==TIFFReadDirEntryErrOk)
 | 
						|
					{
 | 
						|
						int m;
 | 
						|
						m=TIFFSetField(tif,dp->tdir_tag,(uint16)(dp->tdir_count),data);
 | 
						|
						if (data!=0)
 | 
						|
							_TIFFfree(data);
 | 
						|
						if (!m)
 | 
						|
							return(0);
 | 
						|
					}
 | 
						|
				}
 | 
						|
			}
 | 
						|
			break;
 | 
						|
		case TIFF_SETGET_C16_UINT8:
 | 
						|
			{
 | 
						|
				uint8* data;
 | 
						|
				assert(fip->field_readcount==TIFF_VARIABLE);
 | 
						|
				assert(fip->field_passcount==1);
 | 
						|
				if (dp->tdir_count>0xFFFF)
 | 
						|
					err=TIFFReadDirEntryErrCount;
 | 
						|
				else
 | 
						|
				{
 | 
						|
					err=TIFFReadDirEntryByteArray(tif,dp,&data);
 | 
						|
					if (err==TIFFReadDirEntryErrOk)
 | 
						|
					{
 | 
						|
						int m;
 | 
						|
						m=TIFFSetField(tif,dp->tdir_tag,(uint16)(dp->tdir_count),data);
 | 
						|
						if (data!=0)
 | 
						|
							_TIFFfree(data);
 | 
						|
						if (!m)
 | 
						|
							return(0);
 | 
						|
					}
 | 
						|
				}
 | 
						|
			}
 | 
						|
			break;
 | 
						|
		case TIFF_SETGET_C16_UINT16:
 | 
						|
			{
 | 
						|
				uint16* data;
 | 
						|
				assert(fip->field_readcount==TIFF_VARIABLE);
 | 
						|
				assert(fip->field_passcount==1);
 | 
						|
				if (dp->tdir_count>0xFFFF)
 | 
						|
					err=TIFFReadDirEntryErrCount;
 | 
						|
				else
 | 
						|
				{
 | 
						|
					err=TIFFReadDirEntryShortArray(tif,dp,&data);
 | 
						|
					if (err==TIFFReadDirEntryErrOk)
 | 
						|
					{
 | 
						|
						int m;
 | 
						|
						m=TIFFSetField(tif,dp->tdir_tag,(uint16)(dp->tdir_count),data);
 | 
						|
						if (data!=0)
 | 
						|
							_TIFFfree(data);
 | 
						|
						if (!m)
 | 
						|
							return(0);
 | 
						|
					}
 | 
						|
				}
 | 
						|
			}
 | 
						|
			break;
 | 
						|
		case TIFF_SETGET_C16_UINT32:
 | 
						|
			{
 | 
						|
				uint32* data;
 | 
						|
				assert(fip->field_readcount==TIFF_VARIABLE);
 | 
						|
				assert(fip->field_passcount==1);
 | 
						|
				if (dp->tdir_count>0xFFFF)
 | 
						|
					err=TIFFReadDirEntryErrCount;
 | 
						|
				else
 | 
						|
				{
 | 
						|
					err=TIFFReadDirEntryLongArray(tif,dp,&data);
 | 
						|
					if (err==TIFFReadDirEntryErrOk)
 | 
						|
					{
 | 
						|
						int m;
 | 
						|
						m=TIFFSetField(tif,dp->tdir_tag,(uint16)(dp->tdir_count),data);
 | 
						|
						if (data!=0)
 | 
						|
							_TIFFfree(data);
 | 
						|
						if (!m)
 | 
						|
							return(0);
 | 
						|
					}
 | 
						|
				}
 | 
						|
			}
 | 
						|
			break;
 | 
						|
		case TIFF_SETGET_C16_UINT64:
 | 
						|
			{
 | 
						|
				uint64* data;
 | 
						|
				assert(fip->field_readcount==TIFF_VARIABLE);
 | 
						|
				assert(fip->field_passcount==1);
 | 
						|
				if (dp->tdir_count>0xFFFF)
 | 
						|
					err=TIFFReadDirEntryErrCount;
 | 
						|
				else
 | 
						|
				{
 | 
						|
					err=TIFFReadDirEntryLong8Array(tif,dp,&data);
 | 
						|
					if (err==TIFFReadDirEntryErrOk)
 | 
						|
					{
 | 
						|
						int m;
 | 
						|
						m=TIFFSetField(tif,dp->tdir_tag,(uint16)(dp->tdir_count),data);
 | 
						|
						if (data!=0)
 | 
						|
							_TIFFfree(data);
 | 
						|
						if (!m)
 | 
						|
							return(0);
 | 
						|
					}
 | 
						|
				}
 | 
						|
			}
 | 
						|
			break;
 | 
						|
		case TIFF_SETGET_C16_FLOAT:
 | 
						|
			{
 | 
						|
				float* data;
 | 
						|
				assert(fip->field_readcount==TIFF_VARIABLE);
 | 
						|
				assert(fip->field_passcount==1);
 | 
						|
				if (dp->tdir_count>0xFFFF)
 | 
						|
					err=TIFFReadDirEntryErrCount;
 | 
						|
				else
 | 
						|
				{
 | 
						|
					err=TIFFReadDirEntryFloatArray(tif,dp,&data);
 | 
						|
					if (err==TIFFReadDirEntryErrOk)
 | 
						|
					{
 | 
						|
						int m;
 | 
						|
						m=TIFFSetField(tif,dp->tdir_tag,(uint16)(dp->tdir_count),data);
 | 
						|
						if (data!=0)
 | 
						|
							_TIFFfree(data);
 | 
						|
						if (!m)
 | 
						|
							return(0);
 | 
						|
					}
 | 
						|
				}
 | 
						|
			}
 | 
						|
			break;
 | 
						|
		case TIFF_SETGET_C16_DOUBLE:
 | 
						|
			{
 | 
						|
				double* data;
 | 
						|
				assert(fip->field_readcount==TIFF_VARIABLE);
 | 
						|
				assert(fip->field_passcount==1);
 | 
						|
				if (dp->tdir_count>0xFFFF)
 | 
						|
					err=TIFFReadDirEntryErrCount;
 | 
						|
				else
 | 
						|
				{
 | 
						|
					err=TIFFReadDirEntryDoubleArray(tif,dp,&data);
 | 
						|
					if (err==TIFFReadDirEntryErrOk)
 | 
						|
					{
 | 
						|
						int m;
 | 
						|
						m=TIFFSetField(tif,dp->tdir_tag,(uint16)(dp->tdir_count),data);
 | 
						|
						if (data!=0)
 | 
						|
							_TIFFfree(data);
 | 
						|
						if (!m)
 | 
						|
							return(0);
 | 
						|
					}
 | 
						|
				}
 | 
						|
			}
 | 
						|
			break;
 | 
						|
		case TIFF_SETGET_C16_IFD8:
 | 
						|
			{
 | 
						|
				uint64* data;
 | 
						|
				assert(fip->field_readcount==TIFF_VARIABLE);
 | 
						|
				assert(fip->field_passcount==1);
 | 
						|
				if (dp->tdir_count>0xFFFF)
 | 
						|
					err=TIFFReadDirEntryErrCount;
 | 
						|
				else
 | 
						|
				{
 | 
						|
					err=TIFFReadDirEntryIfd8Array(tif,dp,&data);
 | 
						|
					if (err==TIFFReadDirEntryErrOk)
 | 
						|
					{
 | 
						|
						int m;
 | 
						|
						m=TIFFSetField(tif,dp->tdir_tag,(uint16)(dp->tdir_count),data);
 | 
						|
						if (data!=0)
 | 
						|
							_TIFFfree(data);
 | 
						|
						if (!m)
 | 
						|
							return(0);
 | 
						|
					}
 | 
						|
				}
 | 
						|
			}
 | 
						|
			break;
 | 
						|
		case TIFF_SETGET_C32_ASCII:
 | 
						|
			{
 | 
						|
				uint8* data;
 | 
						|
				assert(fip->field_readcount==TIFF_VARIABLE2);
 | 
						|
				assert(fip->field_passcount==1);
 | 
						|
				err=TIFFReadDirEntryByteArray(tif,dp,&data);
 | 
						|
				if (err==TIFFReadDirEntryErrOk)
 | 
						|
				{
 | 
						|
					int m;
 | 
						|
					m=TIFFSetField(tif,dp->tdir_tag,(uint32)(dp->tdir_count),data);
 | 
						|
					if (data!=0)
 | 
						|
						_TIFFfree(data);
 | 
						|
					if (!m)
 | 
						|
						return(0);
 | 
						|
				}
 | 
						|
			}
 | 
						|
			break;
 | 
						|
		case TIFF_SETGET_C32_UINT8:
 | 
						|
			{
 | 
						|
				uint8* data;
 | 
						|
				assert(fip->field_readcount==TIFF_VARIABLE2);
 | 
						|
				assert(fip->field_passcount==1);
 | 
						|
				err=TIFFReadDirEntryByteArray(tif,dp,&data);
 | 
						|
				if (err==TIFFReadDirEntryErrOk)
 | 
						|
				{
 | 
						|
					int m;
 | 
						|
					m=TIFFSetField(tif,dp->tdir_tag,(uint32)(dp->tdir_count),data);
 | 
						|
					if (data!=0)
 | 
						|
						_TIFFfree(data);
 | 
						|
					if (!m)
 | 
						|
						return(0);
 | 
						|
				}
 | 
						|
			}
 | 
						|
			break;
 | 
						|
		case TIFF_SETGET_C32_SINT8:
 | 
						|
			{
 | 
						|
				int8* data = NULL;
 | 
						|
				assert(fip->field_readcount==TIFF_VARIABLE2);
 | 
						|
				assert(fip->field_passcount==1);
 | 
						|
				err=TIFFReadDirEntrySbyteArray(tif,dp,&data);
 | 
						|
				if (err==TIFFReadDirEntryErrOk)
 | 
						|
				{
 | 
						|
					int m;
 | 
						|
					m=TIFFSetField(tif,dp->tdir_tag,(uint32)(dp->tdir_count),data);
 | 
						|
					if (data!=0)
 | 
						|
						_TIFFfree(data);
 | 
						|
					if (!m)
 | 
						|
						return(0);
 | 
						|
				}
 | 
						|
			}
 | 
						|
			break;
 | 
						|
		case TIFF_SETGET_C32_UINT16:
 | 
						|
			{
 | 
						|
				uint16* data;
 | 
						|
				assert(fip->field_readcount==TIFF_VARIABLE2);
 | 
						|
				assert(fip->field_passcount==1);
 | 
						|
				err=TIFFReadDirEntryShortArray(tif,dp,&data);
 | 
						|
				if (err==TIFFReadDirEntryErrOk)
 | 
						|
				{
 | 
						|
					int m;
 | 
						|
					m=TIFFSetField(tif,dp->tdir_tag,(uint32)(dp->tdir_count),data);
 | 
						|
					if (data!=0)
 | 
						|
						_TIFFfree(data);
 | 
						|
					if (!m)
 | 
						|
						return(0);
 | 
						|
				}
 | 
						|
			}
 | 
						|
			break;
 | 
						|
		case TIFF_SETGET_C32_SINT16:
 | 
						|
			{
 | 
						|
				int16* data = NULL;
 | 
						|
				assert(fip->field_readcount==TIFF_VARIABLE2);
 | 
						|
				assert(fip->field_passcount==1);
 | 
						|
				err=TIFFReadDirEntrySshortArray(tif,dp,&data);
 | 
						|
				if (err==TIFFReadDirEntryErrOk)
 | 
						|
				{
 | 
						|
					int m;
 | 
						|
					m=TIFFSetField(tif,dp->tdir_tag,(uint32)(dp->tdir_count),data);
 | 
						|
					if (data!=0)
 | 
						|
						_TIFFfree(data);
 | 
						|
					if (!m)
 | 
						|
						return(0);
 | 
						|
				}
 | 
						|
			}
 | 
						|
			break;
 | 
						|
		case TIFF_SETGET_C32_UINT32:
 | 
						|
			{
 | 
						|
				uint32* data;
 | 
						|
				assert(fip->field_readcount==TIFF_VARIABLE2);
 | 
						|
				assert(fip->field_passcount==1);
 | 
						|
				err=TIFFReadDirEntryLongArray(tif,dp,&data);
 | 
						|
				if (err==TIFFReadDirEntryErrOk)
 | 
						|
				{
 | 
						|
					int m;
 | 
						|
					m=TIFFSetField(tif,dp->tdir_tag,(uint32)(dp->tdir_count),data);
 | 
						|
					if (data!=0)
 | 
						|
						_TIFFfree(data);
 | 
						|
					if (!m)
 | 
						|
						return(0);
 | 
						|
				}
 | 
						|
			}
 | 
						|
			break;
 | 
						|
		case TIFF_SETGET_C32_SINT32:
 | 
						|
			{
 | 
						|
				int32* data = NULL;
 | 
						|
				assert(fip->field_readcount==TIFF_VARIABLE2);
 | 
						|
				assert(fip->field_passcount==1);
 | 
						|
				err=TIFFReadDirEntrySlongArray(tif,dp,&data);
 | 
						|
				if (err==TIFFReadDirEntryErrOk)
 | 
						|
				{
 | 
						|
					int m;
 | 
						|
					m=TIFFSetField(tif,dp->tdir_tag,(uint32)(dp->tdir_count),data);
 | 
						|
					if (data!=0)
 | 
						|
						_TIFFfree(data);
 | 
						|
					if (!m)
 | 
						|
						return(0);
 | 
						|
				}
 | 
						|
			}
 | 
						|
			break;
 | 
						|
		case TIFF_SETGET_C32_UINT64:
 | 
						|
			{
 | 
						|
				uint64* data;
 | 
						|
				assert(fip->field_readcount==TIFF_VARIABLE2);
 | 
						|
				assert(fip->field_passcount==1);
 | 
						|
				err=TIFFReadDirEntryLong8Array(tif,dp,&data);
 | 
						|
				if (err==TIFFReadDirEntryErrOk)
 | 
						|
				{
 | 
						|
					int m;
 | 
						|
					m=TIFFSetField(tif,dp->tdir_tag,(uint32)(dp->tdir_count),data);
 | 
						|
					if (data!=0)
 | 
						|
						_TIFFfree(data);
 | 
						|
					if (!m)
 | 
						|
						return(0);
 | 
						|
				}
 | 
						|
			}
 | 
						|
			break;
 | 
						|
		case TIFF_SETGET_C32_SINT64:
 | 
						|
			{
 | 
						|
				int64* data = NULL;
 | 
						|
				assert(fip->field_readcount==TIFF_VARIABLE2);
 | 
						|
				assert(fip->field_passcount==1);
 | 
						|
				err=TIFFReadDirEntrySlong8Array(tif,dp,&data);
 | 
						|
				if (err==TIFFReadDirEntryErrOk)
 | 
						|
				{
 | 
						|
					int m;
 | 
						|
					m=TIFFSetField(tif,dp->tdir_tag,(uint32)(dp->tdir_count),data);
 | 
						|
					if (data!=0)
 | 
						|
						_TIFFfree(data);
 | 
						|
					if (!m)
 | 
						|
						return(0);
 | 
						|
				}
 | 
						|
			}
 | 
						|
			break;
 | 
						|
		case TIFF_SETGET_C32_FLOAT:
 | 
						|
			{
 | 
						|
				float* data;
 | 
						|
				assert(fip->field_readcount==TIFF_VARIABLE2);
 | 
						|
				assert(fip->field_passcount==1);
 | 
						|
				err=TIFFReadDirEntryFloatArray(tif,dp,&data);
 | 
						|
				if (err==TIFFReadDirEntryErrOk)
 | 
						|
				{
 | 
						|
					int m;
 | 
						|
					m=TIFFSetField(tif,dp->tdir_tag,(uint32)(dp->tdir_count),data);
 | 
						|
					if (data!=0)
 | 
						|
						_TIFFfree(data);
 | 
						|
					if (!m)
 | 
						|
						return(0);
 | 
						|
				}
 | 
						|
			}
 | 
						|
			break;
 | 
						|
		case TIFF_SETGET_C32_DOUBLE:
 | 
						|
			{
 | 
						|
				double* data;
 | 
						|
				assert(fip->field_readcount==TIFF_VARIABLE2);
 | 
						|
				assert(fip->field_passcount==1);
 | 
						|
				err=TIFFReadDirEntryDoubleArray(tif,dp,&data);
 | 
						|
				if (err==TIFFReadDirEntryErrOk)
 | 
						|
				{
 | 
						|
					int m;
 | 
						|
					m=TIFFSetField(tif,dp->tdir_tag,(uint32)(dp->tdir_count),data);
 | 
						|
					if (data!=0)
 | 
						|
						_TIFFfree(data);
 | 
						|
					if (!m)
 | 
						|
						return(0);
 | 
						|
				}
 | 
						|
			}
 | 
						|
			break;
 | 
						|
		case TIFF_SETGET_C32_IFD8:
 | 
						|
			{
 | 
						|
				uint64* data;
 | 
						|
				assert(fip->field_readcount==TIFF_VARIABLE2);
 | 
						|
				assert(fip->field_passcount==1);
 | 
						|
				err=TIFFReadDirEntryIfd8Array(tif,dp,&data);
 | 
						|
				if (err==TIFFReadDirEntryErrOk)
 | 
						|
				{
 | 
						|
					int m;
 | 
						|
					m=TIFFSetField(tif,dp->tdir_tag,(uint32)(dp->tdir_count),data);
 | 
						|
					if (data!=0)
 | 
						|
						_TIFFfree(data);
 | 
						|
					if (!m)
 | 
						|
						return(0);
 | 
						|
				}
 | 
						|
			}
 | 
						|
			break;
 | 
						|
		default:
 | 
						|
			assert(0);    /* we should never get here */
 | 
						|
			break;
 | 
						|
	}
 | 
						|
	if (err!=TIFFReadDirEntryErrOk)
 | 
						|
	{
 | 
						|
		TIFFReadDirEntryOutputErr(tif,err,module,fip ? fip->field_name : "unknown tagname",recover);
 | 
						|
		return(0);
 | 
						|
	}
 | 
						|
	return(1);
 | 
						|
}
 | 
						|
 | 
						|
/*
 | 
						|
 * Fetch a set of offsets or lengths.
 | 
						|
 * While this routine says "strips", in fact it's also used for tiles.
 | 
						|
 */
 | 
						|
static int
 | 
						|
TIFFFetchStripThing(TIFF* tif, TIFFDirEntry* dir, uint32 nstrips, uint64** lpp)
 | 
						|
{
 | 
						|
	static const char module[] = "TIFFFetchStripThing";
 | 
						|
	enum TIFFReadDirEntryErr err;
 | 
						|
	uint64* data;
 | 
						|
	err=TIFFReadDirEntryLong8Array(tif,dir,&data);
 | 
						|
	if (err!=TIFFReadDirEntryErrOk)
 | 
						|
	{
 | 
						|
		const TIFFField* fip = TIFFFieldWithTag(tif,dir->tdir_tag); 
 | 
						|
		TIFFReadDirEntryOutputErr(tif,err,module,fip ? fip->field_name : "unknown tagname",0);
 | 
						|
		return(0);
 | 
						|
	}
 | 
						|
	if (dir->tdir_count!=(uint64)nstrips)
 | 
						|
	{
 | 
						|
		uint64* resizeddata;
 | 
						|
		resizeddata=(uint64*)_TIFFCheckMalloc(tif,nstrips,sizeof(uint64),"for strip array");
 | 
						|
		if (resizeddata==0) {
 | 
						|
			_TIFFfree(data);
 | 
						|
			return(0);
 | 
						|
		}
 | 
						|
		if (dir->tdir_count<(uint64)nstrips)
 | 
						|
		{
 | 
						|
			_TIFFmemcpy(resizeddata,data,(uint32)dir->tdir_count*sizeof(uint64));
 | 
						|
			_TIFFmemset(resizeddata+(uint32)dir->tdir_count,0,(nstrips-(uint32)dir->tdir_count)*sizeof(uint64));
 | 
						|
		}
 | 
						|
		else
 | 
						|
			_TIFFmemcpy(resizeddata,data,nstrips*sizeof(uint64));
 | 
						|
		_TIFFfree(data);
 | 
						|
		data=resizeddata;
 | 
						|
	}
 | 
						|
	*lpp=data;
 | 
						|
	return(1);
 | 
						|
}
 | 
						|
 | 
						|
/*
 | 
						|
 * Fetch and set the SubjectDistance EXIF tag.
 | 
						|
 */
 | 
						|
static int
 | 
						|
TIFFFetchSubjectDistance(TIFF* tif, TIFFDirEntry* dir)
 | 
						|
{
 | 
						|
	static const char module[] = "TIFFFetchSubjectDistance";
 | 
						|
	enum TIFFReadDirEntryErr err;
 | 
						|
	UInt64Aligned_t m;
 | 
						|
    m.l=0;
 | 
						|
	assert(sizeof(double)==8);
 | 
						|
	assert(sizeof(uint64)==8);
 | 
						|
	assert(sizeof(uint32)==4);
 | 
						|
	if (dir->tdir_count!=1)
 | 
						|
		err=TIFFReadDirEntryErrCount;
 | 
						|
	else if (dir->tdir_type!=TIFF_RATIONAL)
 | 
						|
		err=TIFFReadDirEntryErrType;
 | 
						|
	else
 | 
						|
	{
 | 
						|
		if (!(tif->tif_flags&TIFF_BIGTIFF))
 | 
						|
		{
 | 
						|
			uint32 offset;
 | 
						|
			offset=*(uint32*)(&dir->tdir_offset);
 | 
						|
			if (tif->tif_flags&TIFF_SWAB)
 | 
						|
				TIFFSwabLong(&offset);
 | 
						|
			err=TIFFReadDirEntryData(tif,offset,8,m.i);
 | 
						|
		}
 | 
						|
		else
 | 
						|
		{
 | 
						|
			m.l=dir->tdir_offset.toff_long8;
 | 
						|
			err=TIFFReadDirEntryErrOk;
 | 
						|
		}
 | 
						|
	}
 | 
						|
	if (err==TIFFReadDirEntryErrOk)
 | 
						|
	{
 | 
						|
		double n;
 | 
						|
		if (tif->tif_flags&TIFF_SWAB)
 | 
						|
			TIFFSwabArrayOfLong(m.i,2);
 | 
						|
		if (m.i[0]==0)
 | 
						|
			n=0.0;
 | 
						|
		else if (m.i[0]==0xFFFFFFFF)
 | 
						|
			/*
 | 
						|
			 * XXX: Numerator 0xFFFFFFFF means that we have infinite
 | 
						|
			 * distance. Indicate that with a negative floating point
 | 
						|
			 * SubjectDistance value.
 | 
						|
			 */
 | 
						|
			n=-1.0;
 | 
						|
		else
 | 
						|
			n=(double)m.i[0]/(double)m.i[1];
 | 
						|
		return(TIFFSetField(tif,dir->tdir_tag,n));
 | 
						|
	}
 | 
						|
	else
 | 
						|
	{
 | 
						|
		TIFFReadDirEntryOutputErr(tif,err,module,"SubjectDistance",TRUE);
 | 
						|
		return(0);
 | 
						|
	}
 | 
						|
}
 | 
						|
 | 
						|
/*
 | 
						|
 * Replace a single strip (tile) of uncompressed data by multiple strips
 | 
						|
 * (tiles), each approximately STRIP_SIZE_DEFAULT bytes. This is useful for
 | 
						|
 * dealing with large images or for dealing with machines with a limited
 | 
						|
 * amount memory.
 | 
						|
 */
 | 
						|
static void
 | 
						|
ChopUpSingleUncompressedStrip(TIFF* tif)
 | 
						|
{
 | 
						|
	register TIFFDirectory *td = &tif->tif_dir;
 | 
						|
	uint64 bytecount;
 | 
						|
	uint64 offset;
 | 
						|
	uint32 rowblock;
 | 
						|
	uint64 rowblockbytes;
 | 
						|
	uint64 stripbytes;
 | 
						|
	uint32 strip;
 | 
						|
	uint64 nstrips64;
 | 
						|
	uint32 nstrips32;
 | 
						|
	uint32 rowsperstrip;
 | 
						|
	uint64* newcounts;
 | 
						|
	uint64* newoffsets;
 | 
						|
 | 
						|
	bytecount = td->td_stripbytecount[0];
 | 
						|
	offset = td->td_stripoffset[0];
 | 
						|
	assert(td->td_planarconfig == PLANARCONFIG_CONTIG);
 | 
						|
	if ((td->td_photometric == PHOTOMETRIC_YCBCR)&&
 | 
						|
	    (!isUpSampled(tif)))
 | 
						|
		rowblock = td->td_ycbcrsubsampling[1];
 | 
						|
	else
 | 
						|
		rowblock = 1;
 | 
						|
	rowblockbytes = TIFFVTileSize64(tif, rowblock);
 | 
						|
	/*
 | 
						|
	 * Make the rows hold at least one scanline, but fill specified amount
 | 
						|
	 * of data if possible.
 | 
						|
	 */
 | 
						|
	if (rowblockbytes > STRIP_SIZE_DEFAULT) {
 | 
						|
		stripbytes = rowblockbytes;
 | 
						|
		rowsperstrip = rowblock;
 | 
						|
	} else if (rowblockbytes > 0 ) {
 | 
						|
		uint32 rowblocksperstrip;
 | 
						|
		rowblocksperstrip = (uint32) (STRIP_SIZE_DEFAULT / rowblockbytes);
 | 
						|
		rowsperstrip = rowblocksperstrip * rowblock;
 | 
						|
		stripbytes = rowblocksperstrip * rowblockbytes;
 | 
						|
	}
 | 
						|
	else
 | 
						|
	    return;
 | 
						|
 | 
						|
	/*
 | 
						|
	 * never increase the number of strips in an image
 | 
						|
	 */
 | 
						|
	if (rowsperstrip >= td->td_rowsperstrip)
 | 
						|
		return;
 | 
						|
	nstrips64 = TIFFhowmany_64(bytecount, stripbytes);
 | 
						|
	if ((nstrips64==0)||(nstrips64>0xFFFFFFFF)) /* something is wonky, do nothing. */
 | 
						|
	    return;
 | 
						|
	nstrips32 = (uint32)nstrips64;
 | 
						|
 | 
						|
	newcounts = (uint64*) _TIFFCheckMalloc(tif, nstrips32, sizeof (uint64),
 | 
						|
				"for chopped \"StripByteCounts\" array");
 | 
						|
	newoffsets = (uint64*) _TIFFCheckMalloc(tif, nstrips32, sizeof (uint64),
 | 
						|
				"for chopped \"StripOffsets\" array");
 | 
						|
	if (newcounts == NULL || newoffsets == NULL) {
 | 
						|
		/*
 | 
						|
		 * Unable to allocate new strip information, give up and use
 | 
						|
		 * the original one strip information.
 | 
						|
		 */
 | 
						|
		if (newcounts != NULL)
 | 
						|
			_TIFFfree(newcounts);
 | 
						|
		if (newoffsets != NULL)
 | 
						|
			_TIFFfree(newoffsets);
 | 
						|
		return;
 | 
						|
	}
 | 
						|
	/*
 | 
						|
	 * Fill the strip information arrays with new bytecounts and offsets
 | 
						|
	 * that reflect the broken-up format.
 | 
						|
	 */
 | 
						|
	for (strip = 0; strip < nstrips32; strip++) {
 | 
						|
		if (stripbytes > bytecount)
 | 
						|
			stripbytes = bytecount;
 | 
						|
		newcounts[strip] = stripbytes;
 | 
						|
		newoffsets[strip] = offset;
 | 
						|
		offset += stripbytes;
 | 
						|
		bytecount -= stripbytes;
 | 
						|
	}
 | 
						|
	/*
 | 
						|
	 * Replace old single strip info with multi-strip info.
 | 
						|
	 */
 | 
						|
	td->td_stripsperimage = td->td_nstrips = nstrips32;
 | 
						|
	TIFFSetField(tif, TIFFTAG_ROWSPERSTRIP, rowsperstrip);
 | 
						|
 | 
						|
	_TIFFfree(td->td_stripbytecount);
 | 
						|
	_TIFFfree(td->td_stripoffset);
 | 
						|
	td->td_stripbytecount = newcounts;
 | 
						|
	td->td_stripoffset = newoffsets;
 | 
						|
	td->td_stripbytecountsorted = 1;
 | 
						|
}
 | 
						|
 | 
						|
int _TIFFFillStriles( TIFF *tif )
 | 
						|
{
 | 
						|
#if defined(DEFER_STRILE_LOAD)
 | 
						|
        register TIFFDirectory *td = &tif->tif_dir;
 | 
						|
        int return_value = 1;
 | 
						|
 | 
						|
        if( td->td_stripoffset != NULL )
 | 
						|
                return 1;
 | 
						|
 | 
						|
        if( td->td_stripoffset_entry.tdir_count == 0 )
 | 
						|
                return 0;
 | 
						|
 | 
						|
        if (!TIFFFetchStripThing(tif,&(td->td_stripoffset_entry),
 | 
						|
                                 td->td_nstrips,&td->td_stripoffset))
 | 
						|
        {
 | 
						|
                return_value = 0;
 | 
						|
        }
 | 
						|
 | 
						|
        if (!TIFFFetchStripThing(tif,&(td->td_stripbytecount_entry),
 | 
						|
                                 td->td_nstrips,&td->td_stripbytecount))
 | 
						|
        {
 | 
						|
                return_value = 0;
 | 
						|
        }
 | 
						|
 | 
						|
        _TIFFmemset( &(td->td_stripoffset_entry), 0, sizeof(TIFFDirEntry));
 | 
						|
        _TIFFmemset( &(td->td_stripbytecount_entry), 0, sizeof(TIFFDirEntry));
 | 
						|
 | 
						|
	if (tif->tif_dir.td_nstrips > 1 && return_value == 1 ) {
 | 
						|
		uint32 strip;
 | 
						|
 | 
						|
		tif->tif_dir.td_stripbytecountsorted = 1;
 | 
						|
		for (strip = 1; strip < tif->tif_dir.td_nstrips; strip++) {
 | 
						|
			if (tif->tif_dir.td_stripoffset[strip - 1] >
 | 
						|
			    tif->tif_dir.td_stripoffset[strip]) {
 | 
						|
				tif->tif_dir.td_stripbytecountsorted = 0;
 | 
						|
				break;
 | 
						|
			}
 | 
						|
		}
 | 
						|
	}
 | 
						|
 | 
						|
        return return_value;
 | 
						|
#else /* !defined(DEFER_STRILE_LOAD) */
 | 
						|
        (void) tif;
 | 
						|
        return 1;
 | 
						|
#endif 
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
/* vim: set ts=8 sts=8 sw=8 noet: */
 | 
						|
/*
 | 
						|
 * Local Variables:
 | 
						|
 * mode: c
 | 
						|
 * c-basic-offset: 8
 | 
						|
 * fill-column: 78
 | 
						|
 * End:
 | 
						|
 */
 |