upgraded to libtiff v4.0.4

This commit is contained in:
Aaron Boxer 2014-12-09 14:33:38 -05:00 committed by Antonin Descampe
parent eadfad7a50
commit 6b0a8e3a0f
29 changed files with 1543 additions and 849 deletions

View File

@ -1,151 +1,164 @@
EXPORTS TIFFOpen EXPORTS TIFFAccessTagMethods
TIFFOpenW
TIFFGetVersion
TIFFCleanup
TIFFClose
TIFFFlush
TIFFFlushData
TIFFGetField
TIFFVGetField
TIFFGetFieldDefaulted
TIFFVGetFieldDefaulted
TIFFGetTagListEntry
TIFFGetTagListCount
TIFFReadDirectory
TIFFScanlineSize64
TIFFScanlineSize
TIFFStripSize64
TIFFStripSize
TIFFVStripSize64
TIFFVStripSize
TIFFRawStripSize64
TIFFRawStripSize
TIFFTileRowSize64
TIFFTileRowSize
TIFFTileSize64
TIFFTileSize
TIFFVTileSize64
TIFFVTileSize
TIFFFileno
TIFFSetFileno
TIFFGetMode
TIFFIsTiled
TIFFIsByteSwapped
TIFFIsBigEndian
TIFFIsMSB2LSB
TIFFIsUpSampled
TIFFCIELabToRGBInit TIFFCIELabToRGBInit
TIFFCIELabToXYZ TIFFCIELabToXYZ
TIFFXYZToRGB TIFFCheckTile
TIFFYCbCrToRGBInit TIFFCheckpointDirectory
TIFFYCbCrtoRGB TIFFCleanup
TIFFCurrentRow TIFFClientOpen
TIFFClientdata
TIFFClose
TIFFComputeStrip
TIFFComputeTile
TIFFCreateCustomDirectory
TIFFCreateDirectory
TIFFCreateEXIFDirectory
TIFFCurrentDirOffset
TIFFCurrentDirectory TIFFCurrentDirectory
TIFFCurrentRow
TIFFCurrentStrip TIFFCurrentStrip
TIFFCurrentTile TIFFCurrentTile
TIFFDataWidth TIFFDataWidth
TIFFReadBufferSetup
TIFFWriteBufferSetup
TIFFSetupStrips
TIFFLastDirectory
TIFFSetDirectory
TIFFSetSubDirectory
TIFFUnlinkDirectory
TIFFSetField
TIFFVSetField
TIFFCheckpointDirectory
TIFFWriteDirectory
TIFFRewriteDirectory
TIFFPrintDirectory
TIFFReadScanline
TIFFWriteScanline
TIFFReadRGBAImage
TIFFReadRGBAImageOriented
TIFFFdOpen
TIFFClientOpen
TIFFFileName
TIFFError
TIFFErrorExt
TIFFWarning
TIFFWarningExt
TIFFSetErrorHandler
TIFFSetErrorHandlerExt
TIFFSetWarningHandler
TIFFSetWarningHandlerExt
TIFFComputeTile
TIFFCheckTile
TIFFNumberOfTiles
TIFFReadTile
TIFFWriteTile
TIFFComputeStrip
TIFFNumberOfStrips
TIFFRGBAImageBegin
TIFFRGBAImageGet
TIFFRGBAImageEnd
TIFFReadEncodedStrip
TIFFReadRawStrip
TIFFReadEncodedTile
TIFFReadRawTile
TIFFReadRGBATile
TIFFReadRGBAStrip
TIFFWriteEncodedStrip
TIFFWriteRawStrip
TIFFWriteEncodedTile
TIFFWriteRawTile
TIFFSetWriteOffset
TIFFSwabFloat
TIFFSwabDouble
TIFFSwabShort
TIFFSwabLong
TIFFSwabArrayOfShort
TIFFSwabArrayOfLong
TIFFSwabArrayOfFloat
TIFFSwabArrayOfDouble
TIFFSwabArrayOfTriples
TIFFReverseBits
TIFFGetBitRevTable
TIFFDefaultStripSize TIFFDefaultStripSize
TIFFDefaultTileSize TIFFDefaultTileSize
TIFFRasterScanlineSize64 TIFFError
TIFFRasterScanlineSize TIFFErrorExt
_TIFFmalloc TIFFFdOpen
_TIFFrealloc TIFFFieldDataType
_TIFFfree TIFFFieldName
_TIFFmemset TIFFFieldPassCount
_TIFFmemcpy TIFFFieldReadCount
_TIFFmemcmp TIFFFieldTag
TIFFCreateDirectory
TIFFSetTagExtender
TIFFFieldWithName TIFFFieldWithName
TIFFFieldWithTag TIFFFieldWithTag
TIFFCurrentDirOffset TIFFFieldWriteCount
TIFFWriteCheck TIFFFileName
TIFFRGBAImageOK TIFFFileno
TIFFNumberOfDirectories TIFFFindCODEC
TIFFSetFileName
TIFFSetClientdata
TIFFSetMode
TIFFClientdata
TIFFGetReadProc
TIFFGetWriteProc
TIFFGetSeekProc
TIFFGetCloseProc
TIFFGetSizeProc
TIFFGetMapFileProc
TIFFGetUnmapFileProc
TIFFIsCODECConfigured
TIFFGetConfiguredCODECs
TIFFFindCODEC
TIFFRegisterCODEC
TIFFUnRegisterCODEC
TIFFFreeDirectory
TIFFReadCustomDirectory
TIFFReadEXIFDirectory
TIFFAccessTagMethods
TIFFGetClientInfo
TIFFSetClientInfo
TIFFSwabLong8
TIFFSwabArrayOfLong8
TIFFFindField TIFFFindField
TIFFUnsetField TIFFFlush
TIFFFlushData
TIFFFreeDirectory
TIFFGetBitRevTable
TIFFGetClientInfo
TIFFGetCloseProc
TIFFGetConfiguredCODECs
TIFFGetField
TIFFGetFieldDefaulted
TIFFGetMapFileProc
TIFFGetMode
TIFFGetReadProc
TIFFGetSeekProc
TIFFGetSizeProc
TIFFGetTagListCount
TIFFGetTagListEntry
TIFFGetUnmapFileProc
TIFFGetVersion
TIFFGetWriteProc
TIFFIsBigEndian
TIFFIsByteSwapped
TIFFIsCODECConfigured
TIFFIsMSB2LSB
TIFFIsTiled
TIFFIsUpSampled
TIFFLastDirectory
TIFFMergeFieldInfo TIFFMergeFieldInfo
TIFFNumberOfDirectories
TIFFNumberOfStrips
TIFFNumberOfTiles
TIFFOpen
TIFFOpenW
TIFFPrintDirectory
TIFFRGBAImageBegin
TIFFRGBAImageEnd
TIFFRGBAImageGet
TIFFRGBAImageOK
TIFFRasterScanlineSize
TIFFRasterScanlineSize64
TIFFRawStripSize
TIFFRawStripSize64
TIFFReadBufferSetup
TIFFReadCustomDirectory
TIFFReadDirectory
TIFFReadEXIFDirectory
TIFFReadEncodedStrip
TIFFReadEncodedTile
TIFFReadRGBAImage
TIFFReadRGBAImageOriented
TIFFReadRGBAStrip
TIFFReadRGBATile
TIFFReadRawStrip
TIFFReadRawTile
TIFFReadScanline
TIFFReadTile
TIFFRegisterCODEC
TIFFReverseBits
TIFFRewriteDirectory
TIFFScanlineSize
TIFFScanlineSize64
TIFFSetClientInfo
TIFFSetClientdata
TIFFSetCompressionScheme
TIFFSetDirectory
TIFFSetErrorHandler
TIFFSetErrorHandlerExt
TIFFSetField
TIFFSetFileName
TIFFSetFileno
TIFFSetMode
TIFFSetSubDirectory
TIFFSetTagExtender
TIFFSetWarningHandler
TIFFSetWarningHandlerExt
TIFFSetWriteOffset
TIFFSetupStrips
TIFFStripSize
TIFFStripSize64
TIFFSwabArrayOfDouble
TIFFSwabArrayOfFloat
TIFFSwabArrayOfLong
TIFFSwabArrayOfLong8
TIFFSwabArrayOfShort
TIFFSwabArrayOfTriples
TIFFSwabDouble
TIFFSwabFloat
TIFFSwabLong
TIFFSwabLong8
TIFFSwabShort
TIFFTileRowSize
TIFFTileRowSize64
TIFFTileSize
TIFFTileSize64
TIFFUnRegisterCODEC
TIFFUnlinkDirectory
TIFFUnsetField
TIFFVGetField
TIFFVGetFieldDefaulted
TIFFVSetField
TIFFVStripSize
TIFFVStripSize64
TIFFVTileSize
TIFFVTileSize64
TIFFWarning
TIFFWarningExt
TIFFWriteBufferSetup
TIFFWriteCheck
TIFFWriteCustomDirectory
TIFFWriteDirectory
TIFFWriteEncodedStrip
TIFFWriteEncodedTile
TIFFWriteRawStrip
TIFFWriteRawTile
TIFFWriteScanline
TIFFWriteTile
TIFFXYZToRGB
TIFFYCbCrToRGBInit
TIFFYCbCrtoRGB
_TIFFCheckMalloc
_TIFFCheckRealloc
_TIFFRewriteField
_TIFFfree
_TIFFmalloc
_TIFFmemcmp
_TIFFmemcpy
_TIFFmemset
_TIFFrealloc

View File

@ -1,4 +1,4 @@
/* $Id: tif_codec.c,v 1.15 2010-12-14 12:53:00 dron Exp $ */ /* $Id: tif_codec.c,v 1.16 2013-05-02 14:44:29 tgl Exp $ */
/* /*
* Copyright (c) 1988-1997 Sam Leffler * Copyright (c) 1988-1997 Sam Leffler
@ -108,7 +108,8 @@ _notConfigured(TIFF* tif)
const TIFFCodec* c = TIFFFindCODEC(tif->tif_dir.td_compression); const TIFFCodec* c = TIFFFindCODEC(tif->tif_dir.td_compression);
char compression_code[20]; char compression_code[20];
sprintf( compression_code, "%d", tif->tif_dir.td_compression ); snprintf(compression_code, sizeof(compression_code), "%d",
tif->tif_dir.td_compression );
TIFFErrorExt(tif->tif_clientdata, tif->tif_name, TIFFErrorExt(tif->tif_clientdata, tif->tif_name,
"%s compression support is not configured", "%s compression support is not configured",
c ? c->name : compression_code ); c ? c->name : compression_code );

View File

@ -27,6 +27,10 @@
/* Define to 1 if you have the <assert.h> header file. */ /* Define to 1 if you have the <assert.h> header file. */
#undef HAVE_ASSERT_H #undef HAVE_ASSERT_H
/* Define to 1 if you have the declaration of `optarg', and to 0 if you don't.
*/
#undef HAVE_DECL_OPTARG
/* Define to 1 if you have the <dlfcn.h> header file. */ /* Define to 1 if you have the <dlfcn.h> header file. */
#undef HAVE_DLFCN_H #undef HAVE_DLFCN_H
@ -79,12 +83,6 @@
/* Define to 1 if you have the `lfind' function. */ /* Define to 1 if you have the `lfind' function. */
#undef HAVE_LFIND #undef HAVE_LFIND
/* Define to 1 if you have the `c' library (-lc). */
#undef HAVE_LIBC
/* Define to 1 if you have the `m' library (-lm). */
#undef HAVE_LIBM
/* Define to 1 if you have the <limits.h> header file. */ /* Define to 1 if you have the <limits.h> header file. */
#undef HAVE_LIMITS_H #undef HAVE_LIMITS_H
@ -197,8 +195,7 @@
/* Support LogLuv high dynamic range encoding */ /* Support LogLuv high dynamic range encoding */
#undef LOGLUV_SUPPORT #undef LOGLUV_SUPPORT
/* Define to the sub-directory in which libtool stores uninstalled libraries. /* Define to the sub-directory where libtool stores uninstalled libraries. */
*/
#undef LT_OBJDIR #undef LT_OBJDIR
/* Support LZMA2 compression */ /* Support LZMA2 compression */
@ -213,9 +210,6 @@
/* Support NeXT 2-bit RLE algorithm */ /* Support NeXT 2-bit RLE algorithm */
#undef NEXT_SUPPORT #undef NEXT_SUPPORT
/* Define to 1 if your C compiler doesn't accept -c and -o together. */
#undef NO_MINUS_C_MINUS_O
/* Support Old JPEG compresson (read-only) */ /* Support Old JPEG compresson (read-only) */
#undef OJPEG_SUPPORT #undef OJPEG_SUPPORT
@ -262,6 +256,9 @@
/* The size of `signed short', as computed by sizeof. */ /* The size of `signed short', as computed by sizeof. */
#undef SIZEOF_SIGNED_SHORT #undef SIZEOF_SIGNED_SHORT
/* The size of `size_t', as computed by sizeof. */
#undef SIZEOF_SIZE_T
/* The size of `unsigned char *', as computed by sizeof. */ /* The size of `unsigned char *', as computed by sizeof. */
#undef SIZEOF_UNSIGNED_CHAR_P #undef SIZEOF_UNSIGNED_CHAR_P
@ -317,6 +314,12 @@
/* Pointer difference type */ /* Pointer difference type */
#undef TIFF_PTRDIFF_T #undef TIFF_PTRDIFF_T
/* Size type formatter */
#undef TIFF_SIZE_FORMAT
/* Unsigned size type */
#undef TIFF_SIZE_T
/* Signed size type formatter */ /* Signed size type formatter */
#undef TIFF_SSIZE_FORMAT #undef TIFF_SSIZE_FORMAT
@ -371,6 +374,11 @@
/* Support Deflate compression */ /* Support Deflate compression */
#undef ZIP_SUPPORT #undef ZIP_SUPPORT
/* Enable large inode numbers on Mac OS X 10.5. */
#ifndef _DARWIN_USE_64_BIT_INODE
# define _DARWIN_USE_64_BIT_INODE 1
#endif
/* Number of bits in a file offset, on hosts where this is settable. */ /* Number of bits in a file offset, on hosts where this is settable. */
#undef _FILE_OFFSET_BITS #undef _FILE_OFFSET_BITS

View File

@ -1,4 +1,4 @@
/* $Id: tif_dir.c,v 1.108 2012-02-01 01:51:00 fwarmerdam Exp $ */ /* $Id: tif_dir.c,v 1.121 2015-05-31 23:11:43 bfriesen Exp $ */
/* /*
* Copyright (c) 1988-1997 Sam Leffler * Copyright (c) 1988-1997 Sam Leffler
@ -122,6 +122,10 @@ setExtraSamples(TIFFDirectory* td, va_list ap, uint32* v)
#undef EXTRASAMPLE_COREL_UNASSALPHA #undef EXTRASAMPLE_COREL_UNASSALPHA
} }
/*
* Confirm we have "samplesperpixel" ink names separated by \0. Returns
* zero if the ink names are not as expected.
*/
static uint32 static uint32
checkInkNamesString(TIFF* tif, uint32 slen, const char* s) checkInkNamesString(TIFF* tif, uint32 slen, const char* s)
{ {
@ -132,9 +136,9 @@ checkInkNamesString(TIFF* tif, uint32 slen, const char* s)
const char* ep = s+slen; const char* ep = s+slen;
const char* cp = s; const char* cp = s;
for (; i > 0; i--) { for (; i > 0; i--) {
for (; *cp != '\0'; cp++) for (; cp < ep && *cp != '\0'; cp++) {}
if (cp >= ep) if (cp >= ep)
goto bad; goto bad;
cp++; /* skip \0 */ cp++; /* skip \0 */
} }
return ((uint32)(cp-s)); return ((uint32)(cp-s));
@ -156,9 +160,23 @@ _TIFFVSetField(TIFF* tif, uint32 tag, va_list ap)
TIFFDirectory* td = &tif->tif_dir; TIFFDirectory* td = &tif->tif_dir;
int status = 1; int status = 1;
uint32 v32, i, v; uint32 v32, i, v;
double dblval;
char* s; char* s;
const TIFFField *fip = TIFFFindField(tif, tag, TIFF_ANY);
uint32 standard_tag = tag;
if( fip == NULL ) /* cannot happen since OkToChangeTag() already checks it */
return 0;
/*
* We want to force the custom code to be used for custom
* fields even if the tag happens to match a well known
* one - important for reinterpreted handling of standard
* tag values in custom directories (ie. EXIF)
*/
if (fip->field_bit == FIELD_CUSTOM) {
standard_tag = 0;
}
switch (tag) { switch (standard_tag) {
case TIFFTAG_SUBFILETYPE: case TIFFTAG_SUBFILETYPE:
td->td_subfiletype = (uint32) va_arg(ap, uint32); td->td_subfiletype = (uint32) va_arg(ap, uint32);
break; break;
@ -267,10 +285,16 @@ _TIFFVSetField(TIFF* tif, uint32 tag, va_list ap)
setDoubleArrayOneValue(&td->td_smaxsamplevalue, va_arg(ap, double), td->td_samplesperpixel); setDoubleArrayOneValue(&td->td_smaxsamplevalue, va_arg(ap, double), td->td_samplesperpixel);
break; break;
case TIFFTAG_XRESOLUTION: case TIFFTAG_XRESOLUTION:
td->td_xresolution = (float) va_arg(ap, double); dblval = va_arg(ap, double);
if( dblval < 0 )
goto badvaluedouble;
td->td_xresolution = (float) dblval;
break; break;
case TIFFTAG_YRESOLUTION: case TIFFTAG_YRESOLUTION:
td->td_yresolution = (float) va_arg(ap, double); dblval = va_arg(ap, double);
if( dblval < 0 )
goto badvaluedouble;
td->td_yresolution = (float) dblval;
break; break;
case TIFFTAG_PLANARCONFIG: case TIFFTAG_PLANARCONFIG:
v = (uint16) va_arg(ap, uint16_vap); v = (uint16) va_arg(ap, uint16_vap);
@ -423,7 +447,6 @@ _TIFFVSetField(TIFF* tif, uint32 tag, va_list ap)
default: { default: {
TIFFTagValue *tv; TIFFTagValue *tv;
int tv_size, iCustom; int tv_size, iCustom;
const TIFFField *fip = TIFFFindField(tif, tag, TIFF_ANY);
/* /*
* This can happen if multiple images are open with different * This can happen if multiple images are open with different
@ -434,11 +457,11 @@ _TIFFVSetField(TIFF* tif, uint32 tag, va_list ap)
* happens, for example, when tiffcp is used to convert between * happens, for example, when tiffcp is used to convert between
* compression schemes and codec-specific tags are blindly copied. * compression schemes and codec-specific tags are blindly copied.
*/ */
if(fip == NULL || fip->field_bit != FIELD_CUSTOM) { if(fip->field_bit != FIELD_CUSTOM) {
TIFFErrorExt(tif->tif_clientdata, module, TIFFErrorExt(tif->tif_clientdata, module,
"%s: Invalid %stag \"%s\" (not supported by codec)", "%s: Invalid %stag \"%s\" (not supported by codec)",
tif->tif_name, isPseudoTag(tag) ? "pseudo-" : "", tif->tif_name, isPseudoTag(tag) ? "pseudo-" : "",
fip ? fip->field_name : "Unknown"); fip->field_name);
status = 0; status = 0;
break; break;
} }
@ -550,102 +573,99 @@ _TIFFVSetField(TIFF* tif, uint32 tag, va_list ap)
goto end; goto end;
} }
if ((fip->field_passcount if (fip->field_tag == TIFFTAG_DOTRANGE
|| fip->field_writecount == TIFF_VARIABLE && strcmp(fip->field_name,"DotRange") == 0) {
|| fip->field_writecount == TIFF_VARIABLE2 /* TODO: This is an evil exception and should not have been
|| fip->field_writecount == TIFF_SPP handled this way ... likely best if we move it into
|| tv->count > 1) the directory structure with an explicit field in
&& fip->field_tag != TIFFTAG_PAGENUMBER libtiff 4.1 and assign it a FIELD_ value */
&& fip->field_tag != TIFFTAG_HALFTONEHINTS uint16 v[2];
&& fip->field_tag != TIFFTAG_YCBCRSUBSAMPLING v[0] = (uint16)va_arg(ap, int);
&& fip->field_tag != TIFFTAG_DOTRANGE) { v[1] = (uint16)va_arg(ap, int);
_TIFFmemcpy(tv->value, &v, 4);
}
else if (fip->field_passcount
|| fip->field_writecount == TIFF_VARIABLE
|| fip->field_writecount == TIFF_VARIABLE2
|| fip->field_writecount == TIFF_SPP
|| tv->count > 1) {
_TIFFmemcpy(tv->value, va_arg(ap, void *), _TIFFmemcpy(tv->value, va_arg(ap, void *),
tv->count * tv_size); tv->count * tv_size);
} else { } else {
/*
* XXX: The following loop required to handle
* TIFFTAG_PAGENUMBER, TIFFTAG_HALFTONEHINTS,
* TIFFTAG_YCBCRSUBSAMPLING and TIFFTAG_DOTRANGE tags.
* These tags are actually arrays and should be passed as
* array pointers to TIFFSetField() function, but actually
* passed as a list of separate values. This behaviour
* must be changed in the future!
*/
int i;
char *val = (char *)tv->value; char *val = (char *)tv->value;
assert( tv->count == 1 );
for (i = 0; i < tv->count; i++, val += tv_size) { switch (fip->field_type) {
switch (fip->field_type) { case TIFF_BYTE:
case TIFF_BYTE: case TIFF_UNDEFINED:
case TIFF_UNDEFINED: {
{ uint8 v = (uint8)va_arg(ap, int);
uint8 v = (uint8)va_arg(ap, int); _TIFFmemcpy(val, &v, tv_size);
_TIFFmemcpy(val, &v, tv_size);
}
break;
case TIFF_SBYTE:
{
int8 v = (int8)va_arg(ap, int);
_TIFFmemcpy(val, &v, tv_size);
}
break;
case TIFF_SHORT:
{
uint16 v = (uint16)va_arg(ap, int);
_TIFFmemcpy(val, &v, tv_size);
}
break;
case TIFF_SSHORT:
{
int16 v = (int16)va_arg(ap, int);
_TIFFmemcpy(val, &v, tv_size);
}
break;
case TIFF_LONG:
case TIFF_IFD:
{
uint32 v = va_arg(ap, uint32);
_TIFFmemcpy(val, &v, tv_size);
}
break;
case TIFF_SLONG:
{
int32 v = va_arg(ap, int32);
_TIFFmemcpy(val, &v, tv_size);
}
break;
case TIFF_LONG8:
case TIFF_IFD8:
{
uint64 v = va_arg(ap, uint64);
_TIFFmemcpy(val, &v, tv_size);
}
break;
case TIFF_SLONG8:
{
int64 v = va_arg(ap, int64);
_TIFFmemcpy(val, &v, tv_size);
}
break;
case TIFF_RATIONAL:
case TIFF_SRATIONAL:
case TIFF_FLOAT:
{
float v = (float)va_arg(ap, double);
_TIFFmemcpy(val, &v, tv_size);
}
break;
case TIFF_DOUBLE:
{
double v = va_arg(ap, double);
_TIFFmemcpy(val, &v, tv_size);
}
break;
default:
_TIFFmemset(val, 0, tv_size);
status = 0;
break;
} }
break;
case TIFF_SBYTE:
{
int8 v = (int8)va_arg(ap, int);
_TIFFmemcpy(val, &v, tv_size);
}
break;
case TIFF_SHORT:
{
uint16 v = (uint16)va_arg(ap, int);
_TIFFmemcpy(val, &v, tv_size);
}
break;
case TIFF_SSHORT:
{
int16 v = (int16)va_arg(ap, int);
_TIFFmemcpy(val, &v, tv_size);
}
break;
case TIFF_LONG:
case TIFF_IFD:
{
uint32 v = va_arg(ap, uint32);
_TIFFmemcpy(val, &v, tv_size);
}
break;
case TIFF_SLONG:
{
int32 v = va_arg(ap, int32);
_TIFFmemcpy(val, &v, tv_size);
}
break;
case TIFF_LONG8:
case TIFF_IFD8:
{
uint64 v = va_arg(ap, uint64);
_TIFFmemcpy(val, &v, tv_size);
}
break;
case TIFF_SLONG8:
{
int64 v = va_arg(ap, int64);
_TIFFmemcpy(val, &v, tv_size);
}
break;
case TIFF_RATIONAL:
case TIFF_SRATIONAL:
case TIFF_FLOAT:
{
float v = (float)va_arg(ap, double);
_TIFFmemcpy(val, &v, tv_size);
}
break;
case TIFF_DOUBLE:
{
double v = va_arg(ap, double);
_TIFFmemcpy(val, &v, tv_size);
}
break;
default:
_TIFFmemset(val, 0, tv_size);
status = 0;
break;
} }
} }
} }
@ -681,6 +701,16 @@ badvalue32:
va_end(ap); va_end(ap);
} }
return (0); return (0);
badvaluedouble:
{
const TIFFField* fip=TIFFFieldWithTag(tif,tag);
TIFFErrorExt(tif->tif_clientdata, module,
"%s: Bad value %f for \"%s\" tag",
tif->tif_name, dblval,
fip ? fip->field_name : "Unknown");
va_end(ap);
}
return (0);
} }
/* /*
@ -795,8 +825,22 @@ _TIFFVGetField(TIFF* tif, uint32 tag, va_list ap)
{ {
TIFFDirectory* td = &tif->tif_dir; TIFFDirectory* td = &tif->tif_dir;
int ret_val = 1; int ret_val = 1;
uint32 standard_tag = tag;
const TIFFField* fip = TIFFFindField(tif, tag, TIFF_ANY);
if( fip == NULL ) /* cannot happen since TIFFGetField() already checks it */
return 0;
/*
* We want to force the custom code to be used for custom
* fields even if the tag happens to match a well known
* one - important for reinterpreted handling of standard
* tag values in custom directories (ie. EXIF)
*/
if (fip->field_bit == FIELD_CUSTOM) {
standard_tag = 0;
}
switch (tag) { switch (standard_tag) {
case TIFFTAG_SUBFILETYPE: case TIFFTAG_SUBFILETYPE:
*va_arg(ap, uint32*) = td->td_subfiletype; *va_arg(ap, uint32*) = td->td_subfiletype;
break; break;
@ -971,8 +1015,6 @@ _TIFFVGetField(TIFF* tif, uint32 tag, va_list ap)
break; break;
default: default:
{ {
const TIFFField* fip =
TIFFFindField(tif, tag, TIFF_ANY);
int i; int i;
/* /*
@ -984,14 +1026,14 @@ _TIFFVGetField(TIFF* tif, uint32 tag, va_list ap)
* get a tag that is not valid for the image's * get a tag that is not valid for the image's
* codec then we'll arrive here. * codec then we'll arrive here.
*/ */
if( fip == NULL || fip->field_bit != FIELD_CUSTOM ) if( fip->field_bit != FIELD_CUSTOM )
{ {
TIFFErrorExt(tif->tif_clientdata, "_TIFFVGetField", TIFFErrorExt(tif->tif_clientdata, "_TIFFVGetField",
"%s: Invalid %stag \"%s\" " "%s: Invalid %stag \"%s\" "
"(not supported by codec)", "(not supported by codec)",
tif->tif_name, tif->tif_name,
isPseudoTag(tag) ? "pseudo-" : "", isPseudoTag(tag) ? "pseudo-" : "",
fip ? fip->field_name : "Unknown"); fip->field_name);
ret_val = 0; ret_val = 0;
break; break;
} }
@ -1013,84 +1055,85 @@ _TIFFVGetField(TIFF* tif, uint32 tag, va_list ap)
*va_arg(ap, uint16*) = (uint16)tv->count; *va_arg(ap, uint16*) = (uint16)tv->count;
*va_arg(ap, void **) = tv->value; *va_arg(ap, void **) = tv->value;
ret_val = 1; ret_val = 1;
} else if (fip->field_tag == TIFFTAG_DOTRANGE
&& strcmp(fip->field_name,"DotRange") == 0) {
/* TODO: This is an evil exception and should not have been
handled this way ... likely best if we move it into
the directory structure with an explicit field in
libtiff 4.1 and assign it a FIELD_ value */
*va_arg(ap, uint16*) = ((uint16 *)tv->value)[0];
*va_arg(ap, uint16*) = ((uint16 *)tv->value)[1];
ret_val = 1;
} else { } else {
if ((fip->field_type == TIFF_ASCII if (fip->field_type == TIFF_ASCII
|| fip->field_readcount == TIFF_VARIABLE || fip->field_readcount == TIFF_VARIABLE
|| fip->field_readcount == TIFF_VARIABLE2 || fip->field_readcount == TIFF_VARIABLE2
|| fip->field_readcount == TIFF_SPP || fip->field_readcount == TIFF_SPP
|| tv->count > 1) || tv->count > 1) {
&& fip->field_tag != TIFFTAG_PAGENUMBER
&& fip->field_tag != TIFFTAG_HALFTONEHINTS
&& fip->field_tag != TIFFTAG_YCBCRSUBSAMPLING
&& fip->field_tag != TIFFTAG_DOTRANGE) {
*va_arg(ap, void **) = tv->value; *va_arg(ap, void **) = tv->value;
ret_val = 1; ret_val = 1;
} else { } else {
int j;
char *val = (char *)tv->value; char *val = (char *)tv->value;
assert( tv->count == 1 );
for (j = 0; j < tv->count; switch (fip->field_type) {
j++, val += _TIFFDataSize(tv->info->field_type)) { case TIFF_BYTE:
switch (fip->field_type) { case TIFF_UNDEFINED:
case TIFF_BYTE: *va_arg(ap, uint8*) =
case TIFF_UNDEFINED: *(uint8 *)val;
*va_arg(ap, uint8*) = ret_val = 1;
*(uint8 *)val; break;
ret_val = 1; case TIFF_SBYTE:
break; *va_arg(ap, int8*) =
case TIFF_SBYTE: *(int8 *)val;
*va_arg(ap, int8*) = ret_val = 1;
*(int8 *)val; break;
ret_val = 1; case TIFF_SHORT:
break; *va_arg(ap, uint16*) =
case TIFF_SHORT: *(uint16 *)val;
*va_arg(ap, uint16*) = ret_val = 1;
*(uint16 *)val; break;
ret_val = 1; case TIFF_SSHORT:
break; *va_arg(ap, int16*) =
case TIFF_SSHORT: *(int16 *)val;
*va_arg(ap, int16*) = ret_val = 1;
*(int16 *)val; break;
ret_val = 1; case TIFF_LONG:
break; case TIFF_IFD:
case TIFF_LONG: *va_arg(ap, uint32*) =
case TIFF_IFD: *(uint32 *)val;
*va_arg(ap, uint32*) = ret_val = 1;
*(uint32 *)val; break;
ret_val = 1; case TIFF_SLONG:
break; *va_arg(ap, int32*) =
case TIFF_SLONG: *(int32 *)val;
*va_arg(ap, int32*) = ret_val = 1;
*(int32 *)val; break;
ret_val = 1; case TIFF_LONG8:
break; case TIFF_IFD8:
case TIFF_LONG8: *va_arg(ap, uint64*) =
case TIFF_IFD8: *(uint64 *)val;
*va_arg(ap, uint64*) = ret_val = 1;
*(uint64 *)val; break;
ret_val = 1; case TIFF_SLONG8:
break; *va_arg(ap, int64*) =
case TIFF_SLONG8: *(int64 *)val;
*va_arg(ap, int64*) = ret_val = 1;
*(int64 *)val; break;
ret_val = 1; case TIFF_RATIONAL:
break; case TIFF_SRATIONAL:
case TIFF_RATIONAL: case TIFF_FLOAT:
case TIFF_SRATIONAL: *va_arg(ap, float*) =
case TIFF_FLOAT: *(float *)val;
*va_arg(ap, float*) = ret_val = 1;
*(float *)val; break;
ret_val = 1; case TIFF_DOUBLE:
break; *va_arg(ap, double*) =
case TIFF_DOUBLE: *(double *)val;
*va_arg(ap, double*) = ret_val = 1;
*(double *)val; break;
ret_val = 1; default:
break; ret_val = 0;
default: break;
ret_val = 0;
break;
}
} }
} }
} }
@ -1214,6 +1257,35 @@ TIFFCreateDirectory(TIFF* tif)
return 0; return 0;
} }
int
TIFFCreateCustomDirectory(TIFF* tif, const TIFFFieldArray* infoarray)
{
TIFFDefaultDirectory(tif);
/*
* Reset the field definitions to match the application provided list.
* Hopefully TIFFDefaultDirectory() won't have done anything irreversable
* based on it's assumption this is an image directory.
*/
_TIFFSetupFields(tif, infoarray);
tif->tif_diroff = 0;
tif->tif_nextdiroff = 0;
tif->tif_curoff = 0;
tif->tif_row = (uint32) -1;
tif->tif_curstrip = (uint32) -1;
return 0;
}
int
TIFFCreateEXIFDirectory(TIFF* tif)
{
const TIFFFieldArray* exifFieldArray;
exifFieldArray = _TIFFGetExifFields();
return TIFFCreateCustomDirectory(tif, exifFieldArray);
}
/* /*
* Setup a default directory structure. * Setup a default directory structure.
*/ */
@ -1250,8 +1322,20 @@ TIFFDefaultDirectory(TIFF* tif)
tif->tif_tagmethods.printdir = NULL; tif->tif_tagmethods.printdir = NULL;
/* /*
* Give client code a chance to install their own * Give client code a chance to install their own
* tag extensions & methods, prior to compression overloads. * tag extensions & methods, prior to compression overloads,
* but do some prior cleanup first. (http://trac.osgeo.org/gdal/ticket/5054)
*/ */
if (tif->tif_nfieldscompat > 0) {
uint32 i;
for (i = 0; i < tif->tif_nfieldscompat; i++) {
if (tif->tif_fieldscompat[i].allocated_size)
_TIFFfree(tif->tif_fieldscompat[i].fields);
}
_TIFFfree(tif->tif_fieldscompat);
tif->tif_nfieldscompat = 0;
tif->tif_fieldscompat = NULL;
}
if (_TIFFextender) if (_TIFFextender)
(*_TIFFextender)(tif); (*_TIFFextender)(tif);
(void) TIFFSetField(tif, TIFFTAG_COMPRESSION, COMPRESSION_NONE); (void) TIFFSetField(tif, TIFFTAG_COMPRESSION, COMPRESSION_NONE);
@ -1292,6 +1376,7 @@ TIFFAdvanceDirectory(TIFF* tif, uint64* nextdir, uint64* off)
if (((uint64)poffa!=poff)||(poffb<poffa)||(poffb<(tmsize_t)sizeof(uint16))||(poffb>tif->tif_size)) if (((uint64)poffa!=poff)||(poffb<poffa)||(poffb<(tmsize_t)sizeof(uint16))||(poffb>tif->tif_size))
{ {
TIFFErrorExt(tif->tif_clientdata,module,"Error fetching directory count"); TIFFErrorExt(tif->tif_clientdata,module,"Error fetching directory count");
*nextdir=0;
return(0); return(0);
} }
_TIFFmemcpy(&dircount,tif->tif_base+poffa,sizeof(uint16)); _TIFFmemcpy(&dircount,tif->tif_base+poffa,sizeof(uint16));
@ -1401,7 +1486,8 @@ TIFFAdvanceDirectory(TIFF* tif, uint64* nextdir, uint64* off)
(void) TIFFSeekFile(tif, (void) TIFFSeekFile(tif,
dircount16*20, SEEK_CUR); dircount16*20, SEEK_CUR);
if (!ReadOK(tif, nextdir, sizeof (uint64))) { if (!ReadOK(tif, nextdir, sizeof (uint64))) {
TIFFErrorExt(tif->tif_clientdata, module, "%s: Error fetching directory link", TIFFErrorExt(tif->tif_clientdata, module,
"%s: Error fetching directory link",
tif->tif_name); tif->tif_name);
return (0); return (0);
} }
@ -1418,6 +1504,7 @@ TIFFAdvanceDirectory(TIFF* tif, uint64* nextdir, uint64* off)
uint16 uint16
TIFFNumberOfDirectories(TIFF* tif) TIFFNumberOfDirectories(TIFF* tif)
{ {
static const char module[] = "TIFFNumberOfDirectories";
uint64 nextdir; uint64 nextdir;
uint16 n; uint16 n;
if (!(tif->tif_flags&TIFF_BIGTIFF)) if (!(tif->tif_flags&TIFF_BIGTIFF))
@ -1426,7 +1513,18 @@ TIFFNumberOfDirectories(TIFF* tif)
nextdir = tif->tif_header.big.tiff_diroff; nextdir = tif->tif_header.big.tiff_diroff;
n = 0; n = 0;
while (nextdir != 0 && TIFFAdvanceDirectory(tif, &nextdir, NULL)) while (nextdir != 0 && TIFFAdvanceDirectory(tif, &nextdir, NULL))
n++; {
if (n != 65535) {
++n;
}
else
{
TIFFErrorExt(tif->tif_clientdata, module,
"Directory count exceeded 65535 limit,"
" giving up on counting.");
return (65535);
}
}
return (n); return (n);
} }

View File

@ -1,4 +1,4 @@
/* $Id: tif_dirinfo.c,v 1.114 2011-05-17 00:21:17 fwarmerdam Exp $ */ /* $Id: tif_dirinfo.c,v 1.121 2014-05-07 01:58:46 bfriesen Exp $ */
/* /*
* Copyright (c) 1988-1997 Sam Leffler * Copyright (c) 1988-1997 Sam Leffler
@ -37,7 +37,7 @@
* *
* NOTE: The second field (field_readcount) and third field (field_writecount) * NOTE: The second field (field_readcount) and third field (field_writecount)
* sometimes use the values TIFF_VARIABLE (-1), TIFF_VARIABLE2 (-3) * sometimes use the values TIFF_VARIABLE (-1), TIFF_VARIABLE2 (-3)
* and TIFFTAG_SPP (-2). The macros should be used but would throw off * and TIFF_SPP (-2). The macros should be used but would throw off
* the formatting of the code, so please interprete the -1, -2 and -3 * the formatting of the code, so please interprete the -1, -2 and -3
* values accordingly. * values accordingly.
*/ */
@ -128,6 +128,8 @@ tiffFields[] = {
{ TIFFTAG_PIXAR_FOVCOT, 1, 1, TIFF_FLOAT, 0, TIFF_SETGET_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "FieldOfViewCotangent", NULL }, { TIFFTAG_PIXAR_FOVCOT, 1, 1, TIFF_FLOAT, 0, TIFF_SETGET_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "FieldOfViewCotangent", NULL },
{ TIFFTAG_PIXAR_MATRIX_WORLDTOSCREEN, 16, 16, TIFF_FLOAT, 0, TIFF_SETGET_C0_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "MatrixWorldToScreen", NULL }, { TIFFTAG_PIXAR_MATRIX_WORLDTOSCREEN, 16, 16, TIFF_FLOAT, 0, TIFF_SETGET_C0_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "MatrixWorldToScreen", NULL },
{ TIFFTAG_PIXAR_MATRIX_WORLDTOCAMERA, 16, 16, TIFF_FLOAT, 0, TIFF_SETGET_C0_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "MatrixWorldToCamera", NULL }, { TIFFTAG_PIXAR_MATRIX_WORLDTOCAMERA, 16, 16, TIFF_FLOAT, 0, TIFF_SETGET_C0_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "MatrixWorldToCamera", NULL },
{ TIFFTAG_CFAREPEATPATTERNDIM, 2, 2, TIFF_SHORT, 0, TIFF_SETGET_C0_UINT16, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 0, "CFARepeatPatternDim", NULL },
{ TIFFTAG_CFAPATTERN, 4, 4, TIFF_BYTE, 0, TIFF_SETGET_C0_UINT8, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 0, "CFAPattern" , NULL},
{ TIFFTAG_COPYRIGHT, -1, -1, TIFF_ASCII, 0, TIFF_SETGET_ASCII, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "Copyright", NULL }, { TIFFTAG_COPYRIGHT, -1, -1, TIFF_ASCII, 0, TIFF_SETGET_ASCII, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "Copyright", NULL },
/* end Pixar tags */ /* end Pixar tags */
{ TIFFTAG_RICHTIFFIPTC, -3, -3, TIFF_LONG, 0, TIFF_SETGET_C32_UINT32, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 1, "RichTIFFIPTC", NULL }, { TIFFTAG_RICHTIFFIPTC, -3, -3, TIFF_LONG, 0, TIFF_SETGET_C32_UINT32, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 1, "RichTIFFIPTC", NULL },
@ -190,9 +192,23 @@ tiffFields[] = {
{ TIFFTAG_ASSHOTPREPROFILEMATRIX, -1, -1, TIFF_SRATIONAL, 0, TIFF_SETGET_C16_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 1, "AsShotPreProfileMatrix", NULL }, { TIFFTAG_ASSHOTPREPROFILEMATRIX, -1, -1, TIFF_SRATIONAL, 0, TIFF_SETGET_C16_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 1, "AsShotPreProfileMatrix", NULL },
{ TIFFTAG_CURRENTICCPROFILE, -1, -1, TIFF_UNDEFINED, 0, TIFF_SETGET_C16_UINT8, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 1, "CurrentICCProfile", NULL }, { TIFFTAG_CURRENTICCPROFILE, -1, -1, TIFF_UNDEFINED, 0, TIFF_SETGET_C16_UINT8, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 1, "CurrentICCProfile", NULL },
{ TIFFTAG_CURRENTPREPROFILEMATRIX, -1, -1, TIFF_SRATIONAL, 0, TIFF_SETGET_C16_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 1, "CurrentPreProfileMatrix", NULL }, { TIFFTAG_CURRENTPREPROFILEMATRIX, -1, -1, TIFF_SRATIONAL, 0, TIFF_SETGET_C16_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 1, "CurrentPreProfileMatrix", NULL },
/* end DNG tags */
/* begin pseudo tags */
{ TIFFTAG_PERSAMPLE, 0, 0, TIFF_SHORT, 0, TIFF_SETGET_UNDEFINED, TIFF_SETGET_UNDEFINED, FIELD_PSEUDO, TRUE, FALSE, "PerSample", NULL}, { TIFFTAG_PERSAMPLE, 0, 0, TIFF_SHORT, 0, TIFF_SETGET_UNDEFINED, TIFF_SETGET_UNDEFINED, FIELD_PSEUDO, TRUE, FALSE, "PerSample", NULL},
/* end DNG tags */
/* begin TIFF/FX tags */
{ TIFFTAG_INDEXED, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 0, "Indexed", NULL },
{ TIFFTAG_GLOBALPARAMETERSIFD, 1, 1, TIFF_IFD8, 0, TIFF_SETGET_IFD8, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 0, "GlobalParametersIFD", NULL },
{ TIFFTAG_PROFILETYPE, 1, 1, TIFF_LONG, 0, TIFF_SETGET_UINT32, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 0, "ProfileType", NULL },
{ TIFFTAG_FAXPROFILE, 1, 1, TIFF_BYTE, 0, TIFF_SETGET_UINT8, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 0, "FaxProfile", NULL },
{ TIFFTAG_CODINGMETHODS, 1, 1, TIFF_LONG, 0, TIFF_SETGET_UINT32, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 0, "CodingMethods", NULL },
{ TIFFTAG_VERSIONYEAR, 4, 4, TIFF_BYTE, 0, TIFF_SETGET_C0_UINT8, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 0, "VersionYear", NULL },
{ TIFFTAG_MODENUMBER, 1, 1, TIFF_BYTE, 0, TIFF_SETGET_UINT8, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 0, "ModeNumber", NULL },
{ TIFFTAG_DECODE, -1, -1, TIFF_SRATIONAL, 0, TIFF_SETGET_C16_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 1, "Decode", NULL },
{ TIFFTAG_IMAGEBASECOLOR, -1, -1, TIFF_SHORT, 0, TIFF_SETGET_C16_UINT16, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 1, "ImageBaseColor", NULL },
{ TIFFTAG_T82OPTIONS, 1, 1, TIFF_LONG, 0, TIFF_SETGET_UINT32, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 0, "T82Options", NULL },
{ TIFFTAG_STRIPROWCOUNTS, -1, -1, TIFF_LONG, 0, TIFF_SETGET_C16_UINT32, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 1, "StripRowCounts", NULL },
{ TIFFTAG_IMAGELAYER, 2, 2, TIFF_LONG, 0, TIFF_SETGET_C0_UINT32, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 0, "ImageLayer", NULL },
/* end TIFF/FX tags */
/* begin pseudo tags */
}; };
static TIFFField static TIFFField
@ -348,7 +364,7 @@ _TIFFMergeFields(TIFF* tif, const TIFFField info[], uint32 n)
{ {
static const char module[] = "_TIFFMergeFields"; static const char module[] = "_TIFFMergeFields";
static const char reason[] = "for fields array"; static const char reason[] = "for fields array";
TIFFField** tp; /* TIFFField** tp; */
uint32 i; uint32 i;
tif->tif_foundfield = NULL; tif->tif_foundfield = NULL;
@ -369,7 +385,7 @@ _TIFFMergeFields(TIFF* tif, const TIFFField info[], uint32 n)
return 0; return 0;
} }
tp = tif->tif_fields + tif->tif_nfields; /* tp = tif->tif_fields + tif->tif_nfields; */
for (i = 0; i < n; i++) { for (i = 0; i < n; i++) {
const TIFFField *fip = const TIFFField *fip =
TIFFFindField(tif, info[i].field_tag, TIFF_ANY); TIFFFindField(tif, info[i].field_tag, TIFF_ANY);
@ -556,6 +572,42 @@ TIFFFieldWithName(TIFF* tif, const char *field_name)
return (fip); return (fip);
} }
uint32
TIFFFieldTag(const TIFFField* fip)
{
return fip->field_tag;
}
const char *
TIFFFieldName(const TIFFField* fip)
{
return fip->field_name;
}
TIFFDataType
TIFFFieldDataType(const TIFFField* fip)
{
return fip->field_type;
}
int
TIFFFieldPassCount(const TIFFField* fip)
{
return fip->field_passcount;
}
int
TIFFFieldReadCount(const TIFFField* fip)
{
return fip->field_readcount;
}
int
TIFFFieldWriteCount(const TIFFField* fip)
{
return fip->field_writecount;
}
const TIFFField* const TIFFField*
_TIFFFindOrRegisterField(TIFF *tif, uint32 tag, TIFFDataType dt) _TIFFFindOrRegisterField(TIFF *tif, uint32 tag, TIFFDataType dt)
@ -661,7 +713,7 @@ _TIFFCreateAnonField(TIFF *tif, uint32 tag, TIFFDataType field_type)
* note that this name is a special sign to TIFFClose() and * note that this name is a special sign to TIFFClose() and
* _TIFFSetupFields() to free the field * _TIFFSetupFields() to free the field
*/ */
sprintf(fld->field_name, "Tag %d", (int) tag); snprintf(fld->field_name, 32, "Tag %d", (int) tag);
return fld; return fld;
} }

View File

@ -1,4 +1,4 @@
/* $Id: tif_dirread.c,v 1.174 2012-02-01 02:24:47 fwarmerdam Exp $ */ /* $Id: tif_dirread.c,v 1.187 2015-05-31 21:09:33 bfriesen Exp $ */
/* /*
* Copyright (c) 1988-1997 Sam Leffler * Copyright (c) 1988-1997 Sam Leffler
@ -2172,11 +2172,6 @@ static enum TIFFReadDirEntryErr TIFFReadDirEntrySlong8Array(TIFF* tif, TIFFDirEn
break; break;
} }
_TIFFfree(origdata); _TIFFfree(origdata);
if (err!=TIFFReadDirEntryErrOk)
{
_TIFFfree(data);
return(err);
}
*value=data; *value=data;
return(TIFFReadDirEntryErrOk); return(TIFFReadDirEntryErrOk);
} }
@ -2414,11 +2409,6 @@ static enum TIFFReadDirEntryErr TIFFReadDirEntryFloatArray(TIFF* tif, TIFFDirEnt
break; break;
} }
_TIFFfree(origdata); _TIFFfree(origdata);
if (err!=TIFFReadDirEntryErrOk)
{
_TIFFfree(data);
return(err);
}
*value=data; *value=data;
return(TIFFReadDirEntryErrOk); return(TIFFReadDirEntryErrOk);
} }
@ -2657,11 +2647,6 @@ TIFFReadDirEntryDoubleArray(TIFF* tif, TIFFDirEntry* direntry, double** value)
break; break;
} }
_TIFFfree(origdata); _TIFFfree(origdata);
if (err!=TIFFReadDirEntryErrOk)
{
_TIFFfree(data);
return(err);
}
*value=data; *value=data;
return(TIFFReadDirEntryErrOk); return(TIFFReadDirEntryErrOk);
} }
@ -2723,11 +2708,6 @@ static enum TIFFReadDirEntryErr TIFFReadDirEntryIfd8Array(TIFF* tif, TIFFDirEntr
break; break;
} }
_TIFFfree(origdata); _TIFFfree(origdata);
if (err!=TIFFReadDirEntryErrOk)
{
_TIFFfree(data);
return(err);
}
*value=data; *value=data;
return(TIFFReadDirEntryErrOk); return(TIFFReadDirEntryErrOk);
} }
@ -3313,10 +3293,15 @@ TIFFReadDirEntryData(TIFF* tif, uint64 offset, tmsize_t size, void* dest)
if (!ReadOK(tif,dest,size)) if (!ReadOK(tif,dest,size))
return(TIFFReadDirEntryErrIo); return(TIFFReadDirEntryErrIo);
} else { } else {
tmsize_t ma,mb; size_t ma,mb;
ma=(tmsize_t)offset; ma=(size_t)offset;
mb=ma+size; mb=ma+size;
if (((uint64)ma!=offset)||(mb<ma)||(mb<size)||(mb>tif->tif_size)) if (((uint64)ma!=offset)
|| (mb < ma)
|| (mb - ma != (size_t) size)
|| (mb < (size_t)size)
|| (mb > (size_t)tif->tif_size)
)
return(TIFFReadDirEntryErrIo); return(TIFFReadDirEntryErrIo);
_TIFFmemcpy(dest,tif->tif_base+ma,size); _TIFFmemcpy(dest,tif->tif_base+ma,size);
} }
@ -3369,7 +3354,7 @@ static void TIFFReadDirEntryOutputErr(TIFF* tif, enum TIFFReadDirEntryErr err, c
} else { } else {
switch (err) { switch (err) {
case TIFFReadDirEntryErrCount: case TIFFReadDirEntryErrCount:
TIFFErrorExt(tif->tif_clientdata, module, TIFFWarningExt(tif->tif_clientdata, module,
"Incorrect count for \"%s\"; tag ignored", "Incorrect count for \"%s\"; tag ignored",
tagname); tagname);
break; break;
@ -3425,6 +3410,8 @@ TIFFReadDirectory(TIFF* tif)
const TIFFField* fip; const TIFFField* fip;
uint32 fii=FAILED_FII; uint32 fii=FAILED_FII;
toff_t nextdiroff; toff_t nextdiroff;
int bitspersample_read = FALSE;
tif->tif_diroff=tif->tif_nextdiroff; tif->tif_diroff=tif->tif_nextdiroff;
if (!TIFFCheckDirOffset(tif,tif->tif_nextdiroff)) if (!TIFFCheckDirOffset(tif,tif->tif_nextdiroff))
return 0; /* last offset or bad offset (IFD looping) */ return 0; /* last offset or bad offset (IFD looping) */
@ -3701,6 +3688,8 @@ TIFFReadDirectory(TIFF* tif)
} }
if (!TIFFSetField(tif,dp->tdir_tag,value)) if (!TIFFSetField(tif,dp->tdir_tag,value))
goto bad; goto bad;
if( dp->tdir_tag == TIFFTAG_BITSPERSAMPLE )
bitspersample_read = TRUE;
} }
break; break;
case TIFFTAG_SMINSAMPLEVALUE: case TIFFTAG_SMINSAMPLEVALUE:
@ -3758,6 +3747,19 @@ TIFFReadDirectory(TIFF* tif)
uint32 countrequired; uint32 countrequired;
uint32 incrementpersample; uint32 incrementpersample;
uint16* value=NULL; uint16* value=NULL;
/* It would be dangerous to instanciate those tag values */
/* since if td_bitspersample has not yet been read (due to */
/* unordered tags), it could be read afterwards with a */
/* values greater than the default one (1), which may cause */
/* crashes in user code */
if( !bitspersample_read )
{
fip = TIFFFieldWithTag(tif,dp->tdir_tag);
TIFFWarningExt(tif->tif_clientdata,module,
"Ignoring %s since BitsPerSample tag not found",
fip ? fip->field_name : "unknown tagname");
continue;
}
countpersample=(1L<<tif->tif_dir.td_bitspersample); countpersample=(1L<<tif->tif_dir.td_bitspersample);
if ((dp->tdir_tag==TIFFTAG_TRANSFERFUNCTION)&&(dp->tdir_count==(uint64)countpersample)) if ((dp->tdir_tag==TIFFTAG_TRANSFERFUNCTION)&&(dp->tdir_count==(uint64)countpersample))
{ {
@ -4273,7 +4275,8 @@ EstimateStripByteCounts(TIFF* tif, TIFFDirEntry* dir, uint16 dircount)
TIFFDirectory *td = &tif->tif_dir; TIFFDirectory *td = &tif->tif_dir;
uint32 strip; uint32 strip;
_TIFFFillStriles( tif ); if( !_TIFFFillStriles( tif ) )
return -1;
if (td->td_stripbytecount) if (td->td_stripbytecount)
_TIFFfree(td->td_stripbytecount); _TIFFfree(td->td_stripbytecount);
@ -4372,6 +4375,11 @@ TIFFCheckDirOffset(TIFF* tif, uint64 diroff)
if (diroff == 0) /* no more directories */ if (diroff == 0) /* no more directories */
return 0; return 0;
if (tif->tif_dirnumber == 65535) {
TIFFErrorExt(tif->tif_clientdata, "TIFFCheckDirOffset",
"Cannot handle more than 65535 TIFF directories");
return 0;
}
for (n = 0; n < tif->tif_dirnumber && tif->tif_dirlist; n++) { for (n = 0; n < tif->tif_dirnumber && tif->tif_dirlist; n++) {
if (tif->tif_dirlist[n] == diroff) if (tif->tif_dirlist[n] == diroff)
@ -4391,7 +4399,10 @@ TIFFCheckDirOffset(TIFF* tif, uint64 diroff)
tif->tif_dirnumber, 2 * sizeof(uint64), "for IFD list"); tif->tif_dirnumber, 2 * sizeof(uint64), "for IFD list");
if (!new_dirlist) if (!new_dirlist)
return 0; return 0;
tif->tif_dirlistsize = 2 * tif->tif_dirnumber; if( tif->tif_dirnumber >= 32768 )
tif->tif_dirlistsize = 65535;
else
tif->tif_dirlistsize = 2 * tif->tif_dirnumber;
tif->tif_dirlist = new_dirlist; tif->tif_dirlist = new_dirlist;
} }
@ -4703,6 +4714,7 @@ TIFFFetchNormalTag(TIFF* tif, TIFFDirEntry* dp, int recover)
return 0; return 0;
} }
fip=tif->tif_fields[fii]; fip=tif->tif_fields[fii];
assert(fip != NULL); /* should not happen */
assert(fip->set_field_type!=TIFF_SETGET_OTHER); /* if so, we shouldn't arrive here but deal with this in specialized code */ assert(fip->set_field_type!=TIFF_SETGET_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 */ 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; err=TIFFReadDirEntryErrOk;
@ -4761,7 +4773,7 @@ TIFFFetchNormalTag(TIFF* tif, TIFFDirEntry* dp, int recover)
break; break;
case TIFF_SETGET_UINT8: case TIFF_SETGET_UINT8:
{ {
uint8 data; uint8 data=0;
assert(fip->field_readcount==1); assert(fip->field_readcount==1);
assert(fip->field_passcount==0); assert(fip->field_passcount==0);
err=TIFFReadDirEntryByte(tif,dp,&data); err=TIFFReadDirEntryByte(tif,dp,&data);
@ -4855,8 +4867,12 @@ TIFFFetchNormalTag(TIFF* tif, TIFFDirEntry* dp, int recover)
uint16* data; uint16* data;
assert(fip->field_readcount==2); assert(fip->field_readcount==2);
assert(fip->field_passcount==0); assert(fip->field_passcount==0);
if (dp->tdir_count!=2) if (dp->tdir_count!=2) {
TIFFWarningExt(tif->tif_clientdata,module,
"incorrect count for field \"%s\", expected 2, got %d",
fip->field_name,(int)dp->tdir_count);
return(0); return(0);
}
err=TIFFReadDirEntryShortArray(tif,dp,&data); err=TIFFReadDirEntryShortArray(tif,dp,&data);
if (err==TIFFReadDirEntryErrOk) if (err==TIFFReadDirEntryErrOk)
{ {
@ -4873,8 +4889,12 @@ TIFFFetchNormalTag(TIFF* tif, TIFFDirEntry* dp, int recover)
uint8* data; uint8* data;
assert(fip->field_readcount>=1); assert(fip->field_readcount>=1);
assert(fip->field_passcount==0); assert(fip->field_passcount==0);
if (dp->tdir_count!=(uint64)fip->field_readcount) if (dp->tdir_count!=(uint64)fip->field_readcount) {
/* corrupt file */; TIFFWarningExt(tif->tif_clientdata,module,
"incorrect count for field \"%s\", expected %d, got %d",
fip->field_name,(int) fip->field_readcount, (int)dp->tdir_count);
return 0;
}
else else
{ {
err=TIFFReadDirEntryByteArray(tif,dp,&data); err=TIFFReadDirEntryByteArray(tif,dp,&data);
@ -5342,7 +5362,7 @@ TIFFFetchNormalTag(TIFF* tif, TIFFDirEntry* dp, int recover)
} }
if (err!=TIFFReadDirEntryErrOk) if (err!=TIFFReadDirEntryErrOk)
{ {
TIFFReadDirEntryOutputErr(tif,err,module,fip ? fip->field_name : "unknown tagname",recover); TIFFReadDirEntryOutputErr(tif,err,module,fip->field_name,recover);
return(0); return(0);
} }
return(1); return(1);

View File

@ -1,4 +1,4 @@
/* $Id: tif_dirwrite.c,v 1.76 2011-02-18 20:53:04 fwarmerdam Exp $ */ /* $Id: tif_dirwrite.c,v 1.78 2015-05-31 00:38:46 bfriesen Exp $ */
/* /*
* Copyright (c) 1988-1997 Sam Leffler * Copyright (c) 1988-1997 Sam Leffler
@ -2570,7 +2570,7 @@ _TIFFRewriteField(TIFF* tif, uint16 tag, TIFFDataType in_datatype,
tmsize_t count, void* data) tmsize_t count, void* data)
{ {
static const char module[] = "TIFFResetField"; static const char module[] = "TIFFResetField";
const TIFFField* fip = NULL; /* const TIFFField* fip = NULL; */
uint16 dircount; uint16 dircount;
tmsize_t dirsize; tmsize_t dirsize;
uint8 direntry_raw[20]; uint8 direntry_raw[20];
@ -2586,7 +2586,7 @@ _TIFFRewriteField(TIFF* tif, uint16 tag, TIFFDataType in_datatype,
/* -------------------------------------------------------------------- */ /* -------------------------------------------------------------------- */
/* Find field definition. */ /* Find field definition. */
/* -------------------------------------------------------------------- */ /* -------------------------------------------------------------------- */
fip = TIFFFindField(tif, tag, TIFF_ANY); /*fip =*/ TIFFFindField(tif, tag, TIFF_ANY);
/* -------------------------------------------------------------------- */ /* -------------------------------------------------------------------- */
/* Do some checking this is a straight forward case. */ /* Do some checking this is a straight forward case. */
@ -2839,14 +2839,15 @@ _TIFFRewriteField(TIFF* tif, uint16 tag, TIFFDataType in_datatype,
"Error writing directory link"); "Error writing directory link");
return (0); return (0);
} }
_TIFFfree( buf_to_write );
} }
else else
{ {
memcpy( &entry_offset, buf_to_write, count*TIFFDataWidth(datatype)); memcpy( &entry_offset, buf_to_write, count*TIFFDataWidth(datatype));
} }
_TIFFfree( buf_to_write );
buf_to_write = 0;
/* -------------------------------------------------------------------- */ /* -------------------------------------------------------------------- */
/* Adjust the directory entry. */ /* Adjust the directory entry. */
/* -------------------------------------------------------------------- */ /* -------------------------------------------------------------------- */

View File

@ -1,4 +1,4 @@
/* $Id: tif_fax3.c,v 1.72 2010-06-09 17:17:13 bfriesen Exp $ */ /* $Id: tif_fax3.c,v 1.74 2012-06-21 02:01:31 fwarmerdam Exp $ */
/* /*
* Copyright (c) 1990-1997 Sam Leffler * Copyright (c) 1990-1997 Sam Leffler
@ -526,6 +526,7 @@ Fax3SetupState(TIFF* tif)
"for Group 3/4 run arrays"); "for Group 3/4 run arrays");
if (dsp->runs == NULL) if (dsp->runs == NULL)
return (0); return (0);
memset( dsp->runs, 0, TIFFSafeMultiply(uint32,nruns,2)*sizeof(uint32));
dsp->curruns = dsp->runs; dsp->curruns = dsp->runs;
if (needsRefLine) if (needsRefLine)
dsp->refruns = dsp->runs + nruns; dsp->refruns = dsp->runs + nruns;

View File

@ -1,4 +1,4 @@
/* $Id: tif_getimage.c,v 1.78 2011-02-23 21:46:09 fwarmerdam Exp $ */ /* $Id: tif_getimage.c,v 1.90 2015-06-17 01:34:08 bfriesen Exp $ */
/* /*
* Copyright (c) 1991-1997 Sam Leffler * Copyright (c) 1991-1997 Sam Leffler
@ -182,8 +182,23 @@ TIFFRGBAImageOK(TIFF* tif, char emsg[1024])
"Planarconfiguration", td->td_planarconfig); "Planarconfiguration", td->td_planarconfig);
return (0); return (0);
} }
if( td->td_samplesperpixel != 3 )
{
sprintf(emsg,
"Sorry, can not handle image with %s=%d",
"Samples/pixel", td->td_samplesperpixel);
return 0;
}
break; break;
case PHOTOMETRIC_CIELAB: case PHOTOMETRIC_CIELAB:
if( td->td_samplesperpixel != 3 || td->td_bitspersample != 8 )
{
sprintf(emsg,
"Sorry, can not handle image with %s=%d and %s=%d",
"Samples/pixel", td->td_samplesperpixel,
"Bits/sample", td->td_bitspersample);
return 0;
}
break; break;
default: default:
sprintf(emsg, "Sorry, can not handle image with %s=%d", sprintf(emsg, "Sorry, can not handle image with %s=%d",
@ -597,6 +612,10 @@ gtTileContig(TIFFRGBAImage* img, uint32* raster, uint32 w, uint32 h)
int32 fromskew, toskew; int32 fromskew, toskew;
uint32 nrow; uint32 nrow;
int ret = 1, flip; int ret = 1, flip;
uint32 this_tw, tocol;
int32 this_toskew, leftmost_toskew;
int32 leftmost_fromskew;
uint32 leftmost_tw;
buf = (unsigned char*) _TIFFmalloc(TIFFTileSize(tif)); buf = (unsigned char*) _TIFFmalloc(TIFFTileSize(tif));
if (buf == 0) { if (buf == 0) {
@ -617,37 +636,50 @@ gtTileContig(TIFFRGBAImage* img, uint32* raster, uint32 w, uint32 h)
toskew = -(int32)(tw - w); toskew = -(int32)(tw - w);
} }
/*
* Leftmost tile is clipped on left side if col_offset > 0.
*/
leftmost_fromskew = img->col_offset % tw;
leftmost_tw = tw - leftmost_fromskew;
leftmost_toskew = toskew + leftmost_fromskew;
for (row = 0; row < h; row += nrow) for (row = 0; row < h; row += nrow)
{ {
rowstoread = th - (row + img->row_offset) % th; rowstoread = th - (row + img->row_offset) % th;
nrow = (row + rowstoread > h ? h - row : rowstoread); nrow = (row + rowstoread > h ? h - row : rowstoread);
for (col = 0; col < w; col += tw) fromskew = leftmost_fromskew;
this_tw = leftmost_tw;
this_toskew = leftmost_toskew;
tocol = 0;
col = img->col_offset;
while (tocol < w)
{ {
if (TIFFReadTile(tif, buf, col+img->col_offset, if (TIFFReadTile(tif, buf, col,
row+img->row_offset, 0, 0)==(tmsize_t)(-1) && img->stoponerr) row+img->row_offset, 0, 0)==(tmsize_t)(-1) && img->stoponerr)
{ {
ret = 0; ret = 0;
break; break;
} }
pos = ((row+img->row_offset) % th) * TIFFTileRowSize(tif) + \
pos = ((row+img->row_offset) % th) * TIFFTileRowSize(tif); ((tmsize_t) fromskew * img->samplesperpixel);
if (tocol + this_tw > w)
if (col + tw > w) {
{ /*
/* * Rightmost tile is clipped on right side.
* Tile is clipped horizontally. Calculate */
* visible portion and skewing factors. fromskew = tw - (w - tocol);
*/ this_tw = tw - fromskew;
uint32 npix = w - col; this_toskew = toskew + fromskew;
fromskew = tw - npix; }
(*put)(img, raster+y*w+col, col, y, (*put)(img, raster+y*w+tocol, tocol, y, this_tw, nrow, fromskew, this_toskew, buf + pos);
npix, nrow, fromskew, toskew + fromskew, buf + pos); tocol += this_tw;
} col += this_tw;
else /*
{ * After the leftmost tile, tiles are no longer clipped on left side.
(*put)(img, raster+y*w+col, col, y, tw, nrow, 0, toskew, buf + pos); */
} fromskew = 0;
} this_tw = tw;
this_toskew = toskew;
}
y += (flip & FLIP_VERTICALLY ? -(int32) nrow : (int32) nrow); y += (flip & FLIP_VERTICALLY ? -(int32) nrow : (int32) nrow);
} }
@ -692,19 +724,29 @@ gtTileSeparate(TIFFRGBAImage* img, uint32* raster, uint32 w, uint32 h)
unsigned char* p2; unsigned char* p2;
unsigned char* pa; unsigned char* pa;
tmsize_t tilesize; tmsize_t tilesize;
tmsize_t bufsize;
int32 fromskew, toskew; int32 fromskew, toskew;
int alpha = img->alpha; int alpha = img->alpha;
uint32 nrow; uint32 nrow;
int ret = 1, flip; int ret = 1, flip;
int colorchannels; int colorchannels;
uint32 this_tw, tocol;
int32 this_toskew, leftmost_toskew;
int32 leftmost_fromskew;
uint32 leftmost_tw;
tilesize = TIFFTileSize(tif); tilesize = TIFFTileSize(tif);
buf = (unsigned char*) _TIFFmalloc((alpha?4:3)*tilesize); bufsize = TIFFSafeMultiply(tmsize_t,alpha?4:3,tilesize);
if (bufsize == 0) {
TIFFErrorExt(tif->tif_clientdata, TIFFFileName(tif), "Integer overflow in %s", "gtTileSeparate");
return (0);
}
buf = (unsigned char*) _TIFFmalloc(bufsize);
if (buf == 0) { if (buf == 0) {
TIFFErrorExt(tif->tif_clientdata, TIFFFileName(tif), "%s", "No space for tile buffer"); TIFFErrorExt(tif->tif_clientdata, TIFFFileName(tif), "%s", "No space for tile buffer");
return (0); return (0);
} }
_TIFFmemset(buf, 0, (alpha?4:3)*tilesize); _TIFFmemset(buf, 0, bufsize);
p0 = buf; p0 = buf;
p1 = p0 + tilesize; p1 = p0 + tilesize;
p2 = p1 + tilesize; p2 = p1 + tilesize;
@ -736,20 +778,31 @@ gtTileSeparate(TIFFRGBAImage* img, uint32* raster, uint32 w, uint32 h)
break; break;
} }
/*
* Leftmost tile is clipped on left side if col_offset > 0.
*/
leftmost_fromskew = img->col_offset % tw;
leftmost_tw = tw - leftmost_fromskew;
leftmost_toskew = toskew + leftmost_fromskew;
for (row = 0; row < h; row += nrow) for (row = 0; row < h; row += nrow)
{ {
rowstoread = th - (row + img->row_offset) % th; rowstoread = th - (row + img->row_offset) % th;
nrow = (row + rowstoread > h ? h - row : rowstoread); nrow = (row + rowstoread > h ? h - row : rowstoread);
for (col = 0; col < w; col += tw) fromskew = leftmost_fromskew;
this_tw = leftmost_tw;
this_toskew = leftmost_toskew;
tocol = 0;
col = img->col_offset;
while (tocol < w)
{ {
if (TIFFReadTile(tif, p0, col+img->col_offset, if (TIFFReadTile(tif, p0, col,
row+img->row_offset,0,0)==(tmsize_t)(-1) && img->stoponerr) row+img->row_offset,0,0)==(tmsize_t)(-1) && img->stoponerr)
{ {
ret = 0; ret = 0;
break; break;
} }
if (colorchannels > 1 if (colorchannels > 1
&& TIFFReadTile(tif, p1, col+img->col_offset, && TIFFReadTile(tif, p1, col,
row+img->row_offset,0,1) == (tmsize_t)(-1) row+img->row_offset,0,1) == (tmsize_t)(-1)
&& img->stoponerr) && img->stoponerr)
{ {
@ -757,7 +810,7 @@ gtTileSeparate(TIFFRGBAImage* img, uint32* raster, uint32 w, uint32 h)
break; break;
} }
if (colorchannels > 1 if (colorchannels > 1
&& TIFFReadTile(tif, p2, col+img->col_offset, && TIFFReadTile(tif, p2, col,
row+img->row_offset,0,2) == (tmsize_t)(-1) row+img->row_offset,0,2) == (tmsize_t)(-1)
&& img->stoponerr) && img->stoponerr)
{ {
@ -765,7 +818,7 @@ gtTileSeparate(TIFFRGBAImage* img, uint32* raster, uint32 w, uint32 h)
break; break;
} }
if (alpha if (alpha
&& TIFFReadTile(tif,pa,col+img->col_offset, && TIFFReadTile(tif,pa,col,
row+img->row_offset,0,colorchannels) == (tmsize_t)(-1) row+img->row_offset,0,colorchannels) == (tmsize_t)(-1)
&& img->stoponerr) && img->stoponerr)
{ {
@ -773,23 +826,27 @@ gtTileSeparate(TIFFRGBAImage* img, uint32* raster, uint32 w, uint32 h)
break; break;
} }
pos = ((row+img->row_offset) % th) * TIFFTileRowSize(tif); pos = ((row+img->row_offset) % th) * TIFFTileRowSize(tif) + \
((tmsize_t) fromskew * img->samplesperpixel);
if (col + tw > w) if (tocol + this_tw > w)
{ {
/* /*
* Tile is clipped horizontally. Calculate * Rightmost tile is clipped on right side.
* visible portion and skewing factors.
*/ */
uint32 npix = w - col; fromskew = tw - (w - tocol);
fromskew = tw - npix; this_tw = tw - fromskew;
(*put)(img, raster+y*w+col, col, y, this_toskew = toskew + fromskew;
npix, nrow, fromskew, toskew + fromskew,
p0 + pos, p1 + pos, p2 + pos, (alpha?(pa+pos):NULL));
} else {
(*put)(img, raster+y*w+col, col, y,
tw, nrow, 0, toskew, p0 + pos, p1 + pos, p2 + pos, (alpha?(pa+pos):NULL));
} }
(*put)(img, raster+y*w+tocol, tocol, y, this_tw, nrow, fromskew, this_toskew, \
p0 + pos, p1 + pos, p2 + pos, (alpha?(pa+pos):NULL));
tocol += this_tw;
col += this_tw;
/*
* After the leftmost tile, tiles are no longer clipped on left side.
*/
fromskew = 0;
this_tw = tw;
this_toskew = toskew;
} }
y += (flip & FLIP_VERTICALLY ?-(int32) nrow : (int32) nrow); y += (flip & FLIP_VERTICALLY ?-(int32) nrow : (int32) nrow);
@ -836,6 +893,12 @@ gtStripContig(TIFFRGBAImage* img, uint32* raster, uint32 w, uint32 h)
int32 fromskew, toskew; int32 fromskew, toskew;
int ret = 1, flip; int ret = 1, flip;
TIFFGetFieldDefaulted(tif, TIFFTAG_YCBCRSUBSAMPLING, &subsamplinghor, &subsamplingver);
if( subsamplingver == 0 ) {
TIFFErrorExt(tif->tif_clientdata, TIFFFileName(tif), "Invalid vertical YCbCr subsampling");
return (0);
}
buf = (unsigned char*) _TIFFmalloc(TIFFStripSize(tif)); buf = (unsigned char*) _TIFFmalloc(TIFFStripSize(tif));
if (buf == 0) { if (buf == 0) {
TIFFErrorExt(tif->tif_clientdata, TIFFFileName(tif), "No space for strip buffer"); TIFFErrorExt(tif->tif_clientdata, TIFFFileName(tif), "No space for strip buffer");
@ -853,7 +916,7 @@ gtStripContig(TIFFRGBAImage* img, uint32* raster, uint32 w, uint32 h)
} }
TIFFGetFieldDefaulted(tif, TIFFTAG_ROWSPERSTRIP, &rowsperstrip); TIFFGetFieldDefaulted(tif, TIFFTAG_ROWSPERSTRIP, &rowsperstrip);
TIFFGetFieldDefaulted(tif, TIFFTAG_YCBCRSUBSAMPLING, &subsamplinghor, &subsamplingver);
scanline = TIFFScanlineSize(tif); scanline = TIFFScanlineSize(tif);
fromskew = (w < imagewidth ? imagewidth - w : 0); fromskew = (w < imagewidth ? imagewidth - w : 0);
for (row = 0; row < h; row += nrow) for (row = 0; row < h; row += nrow)
@ -873,7 +936,8 @@ gtStripContig(TIFFRGBAImage* img, uint32* raster, uint32 w, uint32 h)
break; break;
} }
pos = ((row + img->row_offset) % rowsperstrip) * scanline; pos = ((row + img->row_offset) % rowsperstrip) * scanline + \
((tmsize_t) img->col_offset * img->samplesperpixel);
(*put)(img, raster+y*w, 0, y, w, nrow, fromskew, toskew, buf + pos); (*put)(img, raster+y*w, 0, y, w, nrow, fromskew, toskew, buf + pos);
y += (flip & FLIP_VERTICALLY ? -(int32) nrow : (int32) nrow); y += (flip & FLIP_VERTICALLY ? -(int32) nrow : (int32) nrow);
} }
@ -917,17 +981,23 @@ gtStripSeparate(TIFFRGBAImage* img, uint32* raster, uint32 w, uint32 h)
uint32 rowsperstrip, offset_row; uint32 rowsperstrip, offset_row;
uint32 imagewidth = img->width; uint32 imagewidth = img->width;
tmsize_t stripsize; tmsize_t stripsize;
tmsize_t bufsize;
int32 fromskew, toskew; int32 fromskew, toskew;
int alpha = img->alpha; int alpha = img->alpha;
int ret = 1, flip, colorchannels; int ret = 1, flip, colorchannels;
stripsize = TIFFStripSize(tif); stripsize = TIFFStripSize(tif);
p0 = buf = (unsigned char *)_TIFFmalloc((alpha?4:3)*stripsize); bufsize = TIFFSafeMultiply(tmsize_t,alpha?4:3,stripsize);
if (bufsize == 0) {
TIFFErrorExt(tif->tif_clientdata, TIFFFileName(tif), "Integer overflow in %s", "gtStripSeparate");
return (0);
}
p0 = buf = (unsigned char *)_TIFFmalloc(bufsize);
if (buf == 0) { if (buf == 0) {
TIFFErrorExt(tif->tif_clientdata, TIFFFileName(tif), "No space for tile buffer"); TIFFErrorExt(tif->tif_clientdata, TIFFFileName(tif), "No space for tile buffer");
return (0); return (0);
} }
_TIFFmemset(buf, 0, (alpha?4:3)*stripsize); _TIFFmemset(buf, 0, bufsize);
p1 = p0 + stripsize; p1 = p0 + stripsize;
p2 = p1 + stripsize; p2 = p1 + stripsize;
pa = (alpha?(p2+stripsize):NULL); pa = (alpha?(p2+stripsize):NULL);
@ -998,7 +1068,8 @@ gtStripSeparate(TIFFRGBAImage* img, uint32* raster, uint32 w, uint32 h)
} }
} }
pos = ((row + img->row_offset) % rowsperstrip) * scanline; pos = ((row + img->row_offset) % rowsperstrip) * scanline + \
((tmsize_t) img->col_offset * img->samplesperpixel);
(*put)(img, raster+y*w, 0, y, w, nrow, fromskew, toskew, p0 + pos, p1 + pos, (*put)(img, raster+y*w, 0, y, w, nrow, fromskew, toskew, p0 + pos, p1 + pos,
p2 + pos, (alpha?(pa+pos):NULL)); p2 + pos, (alpha?(pa+pos):NULL));
y += (flip & FLIP_VERTICALLY ? -(int32) nrow : (int32) nrow); y += (flip & FLIP_VERTICALLY ? -(int32) nrow : (int32) nrow);
@ -1196,6 +1267,26 @@ DECLAREContigPutFunc(putgreytile)
} }
} }
/*
* 8-bit greyscale with associated alpha => colormap/RGBA
*/
DECLAREContigPutFunc(putagreytile)
{
int samplesperpixel = img->samplesperpixel;
uint32** BWmap = img->BWmap;
(void) y;
while (h-- > 0) {
for (x = w; x-- > 0;)
{
*cp++ = BWmap[*pp][0] & (*(pp+1) << 24 | ~A1);
pp += samplesperpixel;
}
cp += toskew;
pp += fromskew;
}
}
/* /*
* 16-bit greyscale => colormap/RGB * 16-bit greyscale => colormap/RGB
*/ */
@ -1494,6 +1585,26 @@ DECLARESepPutFunc(putRGBAAseparate8bittile)
} }
} }
/*
* 8-bit unpacked CMYK samples => RGBA
*/
DECLARESepPutFunc(putCMYKseparate8bittile)
{
(void) img; (void) y;
while (h-- > 0) {
uint32 rv, gv, bv, kv;
for (x = w; x-- > 0;) {
kv = 255 - *a++;
rv = (kv*(255-*r++))/255;
gv = (kv*(255-*g++))/255;
bv = (kv*(255-*b++))/255;
*cp++ = PACK4(rv,gv,bv,255);
}
SKEW4(r, g, b, a, fromskew);
cp += toskew;
}
}
/* /*
* 8-bit unpacked samples => RGBA w/ unassociated alpha * 8-bit unpacked samples => RGBA w/ unassociated alpha
*/ */
@ -1800,7 +1911,7 @@ DECLAREContigPutFunc(putcontig8bitYCbCr42tile)
(void) y; (void) y;
fromskew = (fromskew * 10) / 4; fromskew = (fromskew * 10) / 4;
if ((h & 3) == 0 && (w & 1) == 0) { if ((w & 3) == 0 && (h & 1) == 0) {
for (; h >= 2; h -= 2) { for (; h >= 2; h -= 2) {
x = w>>2; x = w>>2;
do { do {
@ -1877,7 +1988,7 @@ DECLAREContigPutFunc(putcontig8bitYCbCr41tile)
/* XXX adjust fromskew */ /* XXX adjust fromskew */
do { do {
x = w>>2; x = w>>2;
do { while(x>0) {
int32 Cb = pp[4]; int32 Cb = pp[4];
int32 Cr = pp[5]; int32 Cr = pp[5];
@ -1888,7 +1999,8 @@ DECLAREContigPutFunc(putcontig8bitYCbCr41tile)
cp += 4; cp += 4;
pp += 6; pp += 6;
} while (--x); x--;
}
if( (w&3) != 0 ) if( (w&3) != 0 )
{ {
@ -1979,7 +2091,7 @@ DECLAREContigPutFunc(putcontig8bitYCbCr21tile)
fromskew = (fromskew * 4) / 2; fromskew = (fromskew * 4) / 2;
do { do {
x = w>>1; x = w>>1;
do { while(x>0) {
int32 Cb = pp[2]; int32 Cb = pp[2];
int32 Cr = pp[3]; int32 Cr = pp[3];
@ -1988,7 +2100,8 @@ DECLAREContigPutFunc(putcontig8bitYCbCr21tile)
cp += 2; cp += 2;
pp += 4; pp += 4;
} while (--x); x --;
}
if( (w&1) != 0 ) if( (w&1) != 0 )
{ {
@ -2461,7 +2574,10 @@ PickContigCase(TIFFRGBAImage* img)
img->put.contig = put16bitbwtile; img->put.contig = put16bitbwtile;
break; break;
case 8: case 8:
img->put.contig = putgreytile; if (img->alpha && img->samplesperpixel == 2)
img->put.contig = putagreytile;
else
img->put.contig = putgreytile;
break; break;
case 4: case 4:
img->put.contig = put4bitbwtile; img->put.contig = put4bitbwtile;
@ -2486,7 +2602,7 @@ PickContigCase(TIFFRGBAImage* img)
* must always be <= horizontal subsampling; so * must always be <= horizontal subsampling; so
* there are only a few possibilities and we just * there are only a few possibilities and we just
* enumerate the cases. * enumerate the cases.
* Joris: added support for the [1,2] case, nonetheless, to accomodate * Joris: added support for the [1,2] case, nonetheless, to accommodate
* some OJPEG files * some OJPEG files
*/ */
uint16 SubsamplingHor; uint16 SubsamplingHor;
@ -2540,58 +2656,65 @@ PickSeparateCase(TIFFRGBAImage* img)
img->get = TIFFIsTiled(img->tif) ? gtTileSeparate : gtStripSeparate; img->get = TIFFIsTiled(img->tif) ? gtTileSeparate : gtStripSeparate;
img->put.separate = NULL; img->put.separate = NULL;
switch (img->photometric) { switch (img->photometric) {
case PHOTOMETRIC_MINISWHITE: case PHOTOMETRIC_MINISWHITE:
case PHOTOMETRIC_MINISBLACK: case PHOTOMETRIC_MINISBLACK:
/* greyscale images processed pretty much as RGB by gtTileSeparate */ /* greyscale images processed pretty much as RGB by gtTileSeparate */
case PHOTOMETRIC_RGB: case PHOTOMETRIC_RGB:
switch (img->bitspersample) { switch (img->bitspersample) {
case 8: case 8:
if (img->alpha == EXTRASAMPLE_ASSOCALPHA) if (img->alpha == EXTRASAMPLE_ASSOCALPHA)
img->put.separate = putRGBAAseparate8bittile; img->put.separate = putRGBAAseparate8bittile;
else if (img->alpha == EXTRASAMPLE_UNASSALPHA) else if (img->alpha == EXTRASAMPLE_UNASSALPHA)
{ {
if (BuildMapUaToAa(img)) if (BuildMapUaToAa(img))
img->put.separate = putRGBUAseparate8bittile; img->put.separate = putRGBUAseparate8bittile;
} }
else else
img->put.separate = putRGBseparate8bittile; img->put.separate = putRGBseparate8bittile;
break; break;
case 16: case 16:
if (img->alpha == EXTRASAMPLE_ASSOCALPHA) if (img->alpha == EXTRASAMPLE_ASSOCALPHA)
{ {
if (BuildMapBitdepth16To8(img)) if (BuildMapBitdepth16To8(img))
img->put.separate = putRGBAAseparate16bittile; img->put.separate = putRGBAAseparate16bittile;
} }
else if (img->alpha == EXTRASAMPLE_UNASSALPHA) else if (img->alpha == EXTRASAMPLE_UNASSALPHA)
{ {
if (BuildMapBitdepth16To8(img) && if (BuildMapBitdepth16To8(img) &&
BuildMapUaToAa(img)) BuildMapUaToAa(img))
img->put.separate = putRGBUAseparate16bittile; img->put.separate = putRGBUAseparate16bittile;
} }
else else
{ {
if (BuildMapBitdepth16To8(img)) if (BuildMapBitdepth16To8(img))
img->put.separate = putRGBseparate16bittile; img->put.separate = putRGBseparate16bittile;
}
break;
} }
break; break;
case PHOTOMETRIC_YCBCR: }
if ((img->bitspersample==8) && (img->samplesperpixel==3)) break;
case PHOTOMETRIC_SEPARATED:
if (img->bitspersample == 8 && img->samplesperpixel == 4)
{
img->alpha = 1; // Not alpha, but seems like the only way to get 4th band
img->put.separate = putCMYKseparate8bittile;
}
break;
case PHOTOMETRIC_YCBCR:
if ((img->bitspersample==8) && (img->samplesperpixel==3))
{
if (initYCbCrConversion(img)!=0)
{ {
if (initYCbCrConversion(img)!=0) uint16 hs, vs;
{ TIFFGetFieldDefaulted(img->tif, TIFFTAG_YCBCRSUBSAMPLING, &hs, &vs);
uint16 hs, vs; switch ((hs<<4)|vs) {
TIFFGetFieldDefaulted(img->tif, TIFFTAG_YCBCRSUBSAMPLING, &hs, &vs); case 0x11:
switch ((hs<<4)|vs) { img->put.separate = putseparate8bitYCbCr11tile;
case 0x11: break;
img->put.separate = putseparate8bitYCbCr11tile; /* TODO: add other cases here */
break;
/* TODO: add other cases here */
}
} }
} }
break; }
break;
} }
return ((img->get!=NULL) && (img->put.separate!=NULL)); return ((img->get!=NULL) && (img->put.separate!=NULL));
} }

View File

@ -1,4 +1,4 @@
/* $Id: tif_jpeg.c,v 1.105 2012-02-01 01:51:00 fwarmerdam Exp $ */ /* $Id: tif_jpeg.c,v 1.118 2015-06-10 13:17:41 bfriesen Exp $ */
/* /*
* Copyright (c) 1994-1997 Sam Leffler * Copyright (c) 1994-1997 Sam Leffler
@ -658,7 +658,9 @@ alloc_downsampled_buffers(TIFF* tif, jpeg_component_info* comp_info,
#define JPEG_MARKER_SOF0 0xC0 #define JPEG_MARKER_SOF0 0xC0
#define JPEG_MARKER_SOF1 0xC1 #define JPEG_MARKER_SOF1 0xC1
#define JPEG_MARKER_SOF3 0xC3 #define JPEG_MARKER_SOF2 0xC2
#define JPEG_MARKER_SOF9 0xC9
#define JPEG_MARKER_SOF10 0xCA
#define JPEG_MARKER_DHT 0xC4 #define JPEG_MARKER_DHT 0xC4
#define JPEG_MARKER_SOI 0xD8 #define JPEG_MARKER_SOI 0xD8
#define JPEG_MARKER_SOS 0xDA #define JPEG_MARKER_SOS 0xDA
@ -729,6 +731,7 @@ JPEGFixupTagsSubsampling(TIFF* tif)
_TIFFFillStriles( tif ); _TIFFFillStriles( tif );
if( tif->tif_dir.td_stripbytecount == NULL if( tif->tif_dir.td_stripbytecount == NULL
|| tif->tif_dir.td_stripoffset == NULL
|| tif->tif_dir.td_stripbytecount[0] == 0 ) || tif->tif_dir.td_stripbytecount[0] == 0 )
{ {
/* Do not even try to check if the first strip/tile does not /* Do not even try to check if the first strip/tile does not
@ -816,8 +819,11 @@ JPEGFixupTagsSubsamplingSec(struct JPEGFixupTagsSubsamplingData* data)
JPEGFixupTagsSubsamplingSkip(data,n); JPEGFixupTagsSubsamplingSkip(data,n);
} }
break; break;
case JPEG_MARKER_SOF0: case JPEG_MARKER_SOF0: /* Baseline sequential Huffman */
case JPEG_MARKER_SOF1: case JPEG_MARKER_SOF1: /* Extended sequential Huffman */
case JPEG_MARKER_SOF2: /* Progressive Huffman: normally not allowed by TechNote, but that doesn't hurt supporting it */
case JPEG_MARKER_SOF9: /* Extended sequential arithmetic */
case JPEG_MARKER_SOF10: /* Progressive arithmetic: normally not allowed by TechNote, but that doesn't hurt supporting it */
/* this marker contains the subsampling factors we're scanning for */ /* this marker contains the subsampling factors we're scanning for */
{ {
uint16 n; uint16 n;
@ -992,7 +998,7 @@ JPEGSetupDecode(TIFF* tif)
/* /*
* Set up for decoding a strip or tile. * Set up for decoding a strip or tile.
*/ */
static int /*ARGSUSED*/ static int
JPEGPreDecode(TIFF* tif, uint16 s) JPEGPreDecode(TIFF* tif, uint16 s)
{ {
JPEGState *sp = JState(tif); JPEGState *sp = JState(tif);
@ -1095,50 +1101,13 @@ JPEGPreDecode(TIFF* tif, uint16 s)
/* Component 0 should have expected sampling factors */ /* Component 0 should have expected sampling factors */
if (sp->cinfo.d.comp_info[0].h_samp_factor != sp->h_sampling || if (sp->cinfo.d.comp_info[0].h_samp_factor != sp->h_sampling ||
sp->cinfo.d.comp_info[0].v_samp_factor != sp->v_sampling) { sp->cinfo.d.comp_info[0].v_samp_factor != sp->v_sampling) {
TIFFWarningExt(tif->tif_clientdata, module, TIFFErrorExt(tif->tif_clientdata, module,
"Improper JPEG sampling factors %d,%d\n" "Improper JPEG sampling factors %d,%d\n"
"Apparently should be %d,%d.", "Apparently should be %d,%d.",
sp->cinfo.d.comp_info[0].h_samp_factor, sp->cinfo.d.comp_info[0].h_samp_factor,
sp->cinfo.d.comp_info[0].v_samp_factor, sp->cinfo.d.comp_info[0].v_samp_factor,
sp->h_sampling, sp->v_sampling); sp->h_sampling, sp->v_sampling);
return (0);
/*
* There are potential security issues here
* for decoders that have already allocated
* buffers based on the expected sampling
* factors. Lets check the sampling factors
* dont exceed what we were expecting.
*/
if (sp->cinfo.d.comp_info[0].h_samp_factor
> sp->h_sampling
|| sp->cinfo.d.comp_info[0].v_samp_factor
> sp->v_sampling) {
TIFFErrorExt(tif->tif_clientdata,
module,
"Cannot honour JPEG sampling factors"
" that exceed those specified.");
return (0);
}
/*
* XXX: Files written by the Intergraph software
* has different sampling factors stored in the
* TIFF tags and in the JPEG structures. We will
* try to deduce Intergraph files by the presense
* of the tag 33918.
*/
if (!TIFFFindField(tif, 33918, TIFF_ANY)) {
TIFFWarningExt(tif->tif_clientdata, module,
"Decompressor will try reading with "
"sampling %d,%d.",
sp->cinfo.d.comp_info[0].h_samp_factor,
sp->cinfo.d.comp_info[0].v_samp_factor);
sp->h_sampling = (uint16)
sp->cinfo.d.comp_info[0].h_samp_factor;
sp->v_sampling = (uint16)
sp->cinfo.d.comp_info[0].v_samp_factor;
}
} }
/* Rest should have sampling factors 1,1 */ /* Rest should have sampling factors 1,1 */
for (ci = 1; ci < sp->cinfo.d.num_components; ci++) { for (ci = 1; ci < sp->cinfo.d.num_components; ci++) {
@ -1160,11 +1129,11 @@ JPEGPreDecode(TIFF* tif, uint16 s)
if (td->td_planarconfig == PLANARCONFIG_CONTIG && if (td->td_planarconfig == PLANARCONFIG_CONTIG &&
sp->photometric == PHOTOMETRIC_YCBCR && sp->photometric == PHOTOMETRIC_YCBCR &&
sp->jpegcolormode == JPEGCOLORMODE_RGB) { sp->jpegcolormode == JPEGCOLORMODE_RGB) {
/* Convert YCbCr to RGB */ /* Convert YCbCr to RGB */
sp->cinfo.d.jpeg_color_space = JCS_YCbCr; sp->cinfo.d.jpeg_color_space = JCS_YCbCr;
sp->cinfo.d.out_color_space = JCS_RGB; sp->cinfo.d.out_color_space = JCS_RGB;
} else { } else {
/* Suppress colorspace handling */ /* Suppress colorspace handling */
sp->cinfo.d.jpeg_color_space = JCS_UNKNOWN; sp->cinfo.d.jpeg_color_space = JCS_UNKNOWN;
sp->cinfo.d.out_color_space = JCS_UNKNOWN; sp->cinfo.d.out_color_space = JCS_UNKNOWN;
if (td->td_planarconfig == PLANARCONFIG_CONTIG && if (td->td_planarconfig == PLANARCONFIG_CONTIG &&
@ -1175,6 +1144,9 @@ JPEGPreDecode(TIFF* tif, uint16 s)
if (downsampled_output) { if (downsampled_output) {
/* Need to use raw-data interface to libjpeg */ /* Need to use raw-data interface to libjpeg */
sp->cinfo.d.raw_data_out = TRUE; sp->cinfo.d.raw_data_out = TRUE;
#if JPEG_LIB_VERSION >= 70
sp->cinfo.d.do_fancy_upsampling = FALSE;
#endif /* JPEG_LIB_VERSION >= 70 */
tif->tif_decoderow = DecodeRowError; tif->tif_decoderow = DecodeRowError;
tif->tif_decodestrip = JPEGDecodeRaw; tif->tif_decodestrip = JPEGDecodeRaw;
tif->tif_decodetile = JPEGDecodeRaw; tif->tif_decodetile = JPEGDecodeRaw;
@ -1202,6 +1174,63 @@ JPEGPreDecode(TIFF* tif, uint16 s)
* Decode a chunk of pixels. * Decode a chunk of pixels.
* "Standard" case: returned data is not downsampled. * "Standard" case: returned data is not downsampled.
*/ */
#if !JPEG_LIB_MK1_OR_12BIT
static int
JPEGDecode(TIFF* tif, uint8* buf, tmsize_t cc, uint16 s)
{
JPEGState *sp = JState(tif);
tmsize_t nrows;
(void) s;
/*
** Update available information, buffer may have been refilled
** between decode requests
*/
sp->src.next_input_byte = (const JOCTET*) tif->tif_rawcp;
sp->src.bytes_in_buffer = (size_t) tif->tif_rawcc;
if( sp->bytesperline == 0 )
return 0;
nrows = cc / sp->bytesperline;
if (cc % sp->bytesperline)
TIFFWarningExt(tif->tif_clientdata, tif->tif_name,
"fractional scanline not read");
if( nrows > (tmsize_t) sp->cinfo.d.image_height )
nrows = sp->cinfo.d.image_height;
/* data is expected to be read in multiples of a scanline */
if (nrows)
{
do
{
/*
* In the libjpeg6b-9a 8bit case. We read directly into
* the TIFF buffer.
*/
JSAMPROW bufptr = (JSAMPROW)buf;
if (TIFFjpeg_read_scanlines(sp, &bufptr, 1) != 1)
return (0);
++tif->tif_row;
buf += sp->bytesperline;
cc -= sp->bytesperline;
} while (--nrows > 0);
}
/* Update information on consumed data */
tif->tif_rawcp = (uint8*) sp->src.next_input_byte;
tif->tif_rawcc = sp->src.bytes_in_buffer;
/* Close down the decompressor if we've finished the strip or tile. */
return sp->cinfo.d.output_scanline < sp->cinfo.d.output_height
|| TIFFjpeg_finish_decompress(sp);
}
#endif /* !JPEG_LIB_MK1_OR_12BIT */
#if JPEG_LIB_MK1_OR_12BIT
/*ARGSUSED*/ static int /*ARGSUSED*/ static int
JPEGDecode(TIFF* tif, uint8* buf, tmsize_t cc, uint16 s) JPEGDecode(TIFF* tif, uint8* buf, tmsize_t cc, uint16 s)
{ {
@ -1221,91 +1250,81 @@ JPEGDecode(TIFF* tif, uint8* buf, tmsize_t cc, uint16 s)
nrows = cc / sp->bytesperline; nrows = cc / sp->bytesperline;
if (cc % sp->bytesperline) if (cc % sp->bytesperline)
TIFFWarningExt(tif->tif_clientdata, tif->tif_name, "fractional scanline not read"); TIFFWarningExt(tif->tif_clientdata, tif->tif_name,
"fractional scanline not read");
if( nrows > (tmsize_t) sp->cinfo.d.image_height ) if( nrows > (tmsize_t) sp->cinfo.d.image_height )
nrows = sp->cinfo.d.image_height; nrows = sp->cinfo.d.image_height;
/* data is expected to be read in multiples of a scanline */ /* data is expected to be read in multiples of a scanline */
if (nrows) if (nrows)
{ {
JSAMPROW line_work_buf = NULL; JSAMPROW line_work_buf = NULL;
/* /*
* For 6B, only use temporary buffer for 12 bit imagery. * For 6B, only use temporary buffer for 12 bit imagery.
* For Mk1 always use it. * For Mk1 always use it.
*/ */
#if !defined(JPEG_LIB_MK1) if( sp->cinfo.d.data_precision == 12 )
if( sp->cinfo.d.data_precision == 12 ) {
#endif line_work_buf = (JSAMPROW)
{ _TIFFmalloc(sizeof(short) * sp->cinfo.d.output_width
line_work_buf = (JSAMPROW) * sp->cinfo.d.num_components );
_TIFFmalloc(sizeof(short) * sp->cinfo.d.output_width }
* sp->cinfo.d.num_components );
}
do { do
if( line_work_buf != NULL ) {
{ if( line_work_buf != NULL )
/* {
* In the MK1 case, we aways read into a 16bit buffer, and then /*
* pack down to 12bit or 8bit. In 6B case we only read into 16 * In the MK1 case, we aways read into a 16bit
* bit buffer for 12bit data, which we need to repack. * buffer, and then pack down to 12bit or 8bit.
*/ * In 6B case we only read into 16 bit buffer
if (TIFFjpeg_read_scanlines(sp, &line_work_buf, 1) != 1) * for 12bit data, which we need to repack.
return (0); */
if (TIFFjpeg_read_scanlines(sp, &line_work_buf, 1) != 1)
return (0);
if( sp->cinfo.d.data_precision == 12 ) if( sp->cinfo.d.data_precision == 12 )
{ {
int value_pairs = (sp->cinfo.d.output_width int value_pairs = (sp->cinfo.d.output_width
* sp->cinfo.d.num_components) / 2; * sp->cinfo.d.num_components) / 2;
int iPair; int iPair;
for( iPair = 0; iPair < value_pairs; iPair++ ) for( iPair = 0; iPair < value_pairs; iPair++ )
{ {
unsigned char *out_ptr = unsigned char *out_ptr =
((unsigned char *) buf) + iPair * 3; ((unsigned char *) buf) + iPair * 3;
JSAMPLE *in_ptr = line_work_buf + iPair * 2; JSAMPLE *in_ptr = line_work_buf + iPair * 2;
out_ptr[0] = (in_ptr[0] & 0xff0) >> 4; out_ptr[0] = (in_ptr[0] & 0xff0) >> 4;
out_ptr[1] = ((in_ptr[0] & 0xf) << 4) out_ptr[1] = ((in_ptr[0] & 0xf) << 4)
| ((in_ptr[1] & 0xf00) >> 8); | ((in_ptr[1] & 0xf00) >> 8);
out_ptr[2] = ((in_ptr[1] & 0xff) >> 0); out_ptr[2] = ((in_ptr[1] & 0xff) >> 0);
} }
} }
else if( sp->cinfo.d.data_precision == 8 ) else if( sp->cinfo.d.data_precision == 8 )
{ {
int value_count = (sp->cinfo.d.output_width int value_count = (sp->cinfo.d.output_width
* sp->cinfo.d.num_components); * sp->cinfo.d.num_components);
int iValue; int iValue;
for( iValue = 0; iValue < value_count; iValue++ ) for( iValue = 0; iValue < value_count; iValue++ )
{ {
((unsigned char *) buf)[iValue] = ((unsigned char *) buf)[iValue] =
line_work_buf[iValue] & 0xff; line_work_buf[iValue] & 0xff;
} }
} }
} }
else
{
/*
* In the libjpeg6b 8bit case. We read directly into the
* TIFF buffer.
*/
JSAMPROW bufptr = (JSAMPROW)buf;
if (TIFFjpeg_read_scanlines(sp, &bufptr, 1) != 1) ++tif->tif_row;
return (0); buf += sp->bytesperline;
} cc -= sp->bytesperline;
} while (--nrows > 0);
++tif->tif_row; if( line_work_buf != NULL )
buf += sp->bytesperline; _TIFFfree( line_work_buf );
cc -= sp->bytesperline; }
} while (--nrows > 0);
if( line_work_buf != NULL )
_TIFFfree( line_work_buf );
}
/* Update information on consumed data */ /* Update information on consumed data */
tif->tif_rawcp = (uint8*) sp->src.next_input_byte; tif->tif_rawcp = (uint8*) sp->src.next_input_byte;
@ -1313,8 +1332,9 @@ JPEGDecode(TIFF* tif, uint8* buf, tmsize_t cc, uint16 s)
/* Close down the decompressor if we've finished the strip or tile. */ /* Close down the decompressor if we've finished the strip or tile. */
return sp->cinfo.d.output_scanline < sp->cinfo.d.output_height return sp->cinfo.d.output_scanline < sp->cinfo.d.output_height
|| TIFFjpeg_finish_decompress(sp); || TIFFjpeg_finish_decompress(sp);
} }
#endif /* JPEG_LIB_MK1_OR_12BIT */
/*ARGSUSED*/ static int /*ARGSUSED*/ static int
DecodeRowError(TIFF* tif, uint8* buf, tmsize_t cc, uint16 s) DecodeRowError(TIFF* tif, uint8* buf, tmsize_t cc, uint16 s)
@ -1349,8 +1369,8 @@ JPEGDecodeRaw(TIFF* tif, uint8* buf, tmsize_t cc, uint16 s)
#if defined(JPEG_LIB_MK1_OR_12BIT) #if defined(JPEG_LIB_MK1_OR_12BIT)
unsigned short* tmpbuf = _TIFFmalloc(sizeof(unsigned short) * unsigned short* tmpbuf = _TIFFmalloc(sizeof(unsigned short) *
sp->cinfo.d.output_width * sp->cinfo.d.output_width *
sp->cinfo.d.num_components); sp->cinfo.d.num_components);
if(tmpbuf==NULL) { if(tmpbuf==NULL) {
TIFFErrorExt(tif->tif_clientdata, "JPEGDecodeRaw", TIFFErrorExt(tif->tif_clientdata, "JPEGDecodeRaw",
"Out of memory"); "Out of memory");
@ -1362,10 +1382,10 @@ JPEGDecodeRaw(TIFF* tif, uint8* buf, tmsize_t cc, uint16 s)
jpeg_component_info *compptr; jpeg_component_info *compptr;
int ci, clumpoffset; int ci, clumpoffset;
if( cc < sp->bytesperline * sp->v_sampling ) { if( cc < sp->bytesperline ) {
TIFFErrorExt(tif->tif_clientdata, "JPEGDecodeRaw", TIFFErrorExt(tif->tif_clientdata, "JPEGDecodeRaw",
"application buffer not large enough for all data."); "application buffer not large enough for all data.");
return 0; return 0;
} }
/* Reload downsampled-data buffer if needed */ /* Reload downsampled-data buffer if needed */
@ -1381,20 +1401,25 @@ JPEGDecodeRaw(TIFF* tif, uint8* buf, tmsize_t cc, uint16 s)
*/ */
clumpoffset = 0; /* first sample in clump */ clumpoffset = 0; /* first sample in clump */
for (ci = 0, compptr = sp->cinfo.d.comp_info; for (ci = 0, compptr = sp->cinfo.d.comp_info;
ci < sp->cinfo.d.num_components; ci < sp->cinfo.d.num_components;
ci++, compptr++) { ci++, compptr++) {
int hsamp = compptr->h_samp_factor; int hsamp = compptr->h_samp_factor;
int vsamp = compptr->v_samp_factor; int vsamp = compptr->v_samp_factor;
int ypos; int ypos;
for (ypos = 0; ypos < vsamp; ypos++) { for (ypos = 0; ypos < vsamp; ypos++) {
JSAMPLE *inptr = sp->ds_buffer[ci][sp->scancount*vsamp + ypos]; JSAMPLE *inptr = sp->ds_buffer[ci][sp->scancount*vsamp + ypos];
JDIMENSION nclump;
#if defined(JPEG_LIB_MK1_OR_12BIT) #if defined(JPEG_LIB_MK1_OR_12BIT)
JSAMPLE *outptr = (JSAMPLE*)tmpbuf + clumpoffset; JSAMPLE *outptr = (JSAMPLE*)tmpbuf + clumpoffset;
#else #else
JSAMPLE *outptr = (JSAMPLE*)buf + clumpoffset; JSAMPLE *outptr = (JSAMPLE*)buf + clumpoffset;
if (cc < (tmsize_t) (clumpoffset + samples_per_clump*(clumps_per_line-1) + hsamp)) {
TIFFErrorExt(tif->tif_clientdata, "JPEGDecodeRaw",
"application buffer not large enough for all data, possible subsampling issue");
return 0;
}
#endif #endif
JDIMENSION nclump;
if (hsamp == 1) { if (hsamp == 1) {
/* fast path for at least Cb and Cr */ /* fast path for at least Cb and Cr */
@ -1405,7 +1430,7 @@ JPEGDecodeRaw(TIFF* tif, uint8* buf, tmsize_t cc, uint16 s)
} else { } else {
int xpos; int xpos;
/* general case */ /* general case */
for (nclump = clumps_per_line; nclump-- > 0; ) { for (nclump = clumps_per_line; nclump-- > 0; ) {
for (xpos = 0; xpos < hsamp; xpos++) for (xpos = 0; xpos < hsamp; xpos++)
outptr[xpos] = *inptr++; outptr[xpos] = *inptr++;
@ -1428,9 +1453,9 @@ JPEGDecodeRaw(TIFF* tif, uint8* buf, tmsize_t cc, uint16 s)
} }
} }
else else
{ /* 12-bit */ { /* 12-bit */
int value_pairs = (sp->cinfo.d.output_width int value_pairs = (sp->cinfo.d.output_width
* sp->cinfo.d.num_components) / 2; * sp->cinfo.d.num_components) / 2;
int iPair; int iPair;
for( iPair = 0; iPair < value_pairs; iPair++ ) for( iPair = 0; iPair < value_pairs; iPair++ )
{ {
@ -1438,7 +1463,7 @@ JPEGDecodeRaw(TIFF* tif, uint8* buf, tmsize_t cc, uint16 s)
JSAMPLE *in_ptr = (JSAMPLE *) (tmpbuf + iPair * 2); JSAMPLE *in_ptr = (JSAMPLE *) (tmpbuf + iPair * 2);
out_ptr[0] = (in_ptr[0] & 0xff0) >> 4; out_ptr[0] = (in_ptr[0] & 0xff0) >> 4;
out_ptr[1] = ((in_ptr[0] & 0xf) << 4) out_ptr[1] = ((in_ptr[0] & 0xf) << 4)
| ((in_ptr[1] & 0xf00) >> 8); | ((in_ptr[1] & 0xf00) >> 8);
out_ptr[2] = ((in_ptr[1] & 0xff) >> 0); out_ptr[2] = ((in_ptr[1] & 0xff) >> 0);
} }
} }
@ -1447,12 +1472,9 @@ JPEGDecodeRaw(TIFF* tif, uint8* buf, tmsize_t cc, uint16 s)
sp->scancount ++; sp->scancount ++;
tif->tif_row += sp->v_sampling; tif->tif_row += sp->v_sampling;
/*
buf += clumps_per_line*samples_per_clump; buf += sp->bytesperline;
cc -= clumps_per_line*samples_per_clump; cc -= sp->bytesperline;
*/
buf += sp->bytesperline * sp->v_sampling;
cc -= sp->bytesperline * sp->v_sampling;
nrows -= sp->v_sampling; nrows -= sp->v_sampling;
} while (nrows > 0); } while (nrows > 0);
@ -1465,7 +1487,7 @@ JPEGDecodeRaw(TIFF* tif, uint8* buf, tmsize_t cc, uint16 s)
/* Close down the decompressor if done. */ /* Close down the decompressor if done. */
return sp->cinfo.d.output_scanline < sp->cinfo.d.output_height return sp->cinfo.d.output_scanline < sp->cinfo.d.output_height
|| TIFFjpeg_finish_decompress(sp); || TIFFjpeg_finish_decompress(sp);
} }
@ -1482,6 +1504,15 @@ unsuppress_quant_table (JPEGState* sp, int tblno)
qtbl->sent_table = FALSE; qtbl->sent_table = FALSE;
} }
static void
suppress_quant_table (JPEGState* sp, int tblno)
{
JQUANT_TBL* qtbl;
if ((qtbl = sp->cinfo.c.quant_tbl_ptrs[tblno]) != NULL)
qtbl->sent_table = TRUE;
}
static void static void
unsuppress_huff_table (JPEGState* sp, int tblno) unsuppress_huff_table (JPEGState* sp, int tblno)
{ {
@ -1493,6 +1524,17 @@ unsuppress_huff_table (JPEGState* sp, int tblno)
htbl->sent_table = FALSE; htbl->sent_table = FALSE;
} }
static void
suppress_huff_table (JPEGState* sp, int tblno)
{
JHUFF_TBL* htbl;
if ((htbl = sp->cinfo.c.dc_huff_tbl_ptrs[tblno]) != NULL)
htbl->sent_table = TRUE;
if ((htbl = sp->cinfo.c.ac_huff_tbl_ptrs[tblno]) != NULL)
htbl->sent_table = TRUE;
}
static int static int
prepare_JPEGTables(TIFF* tif) prepare_JPEGTables(TIFF* tif)
{ {
@ -1542,17 +1584,38 @@ JPEGSetupEncode(TIFF* tif)
assert(sp != NULL); assert(sp != NULL);
assert(!sp->cinfo.comm.is_decompressor); assert(!sp->cinfo.comm.is_decompressor);
sp->photometric = td->td_photometric;
/* /*
* Initialize all JPEG parameters to default values. * Initialize all JPEG parameters to default values.
* Note that jpeg_set_defaults needs legal values for * Note that jpeg_set_defaults needs legal values for
* in_color_space and input_components. * in_color_space and input_components.
*/ */
sp->cinfo.c.in_color_space = JCS_UNKNOWN; if (td->td_planarconfig == PLANARCONFIG_CONTIG) {
sp->cinfo.c.input_components = 1; sp->cinfo.c.input_components = td->td_samplesperpixel;
if (sp->photometric == PHOTOMETRIC_YCBCR) {
if (sp->jpegcolormode == JPEGCOLORMODE_RGB) {
sp->cinfo.c.in_color_space = JCS_RGB;
} else {
sp->cinfo.c.in_color_space = JCS_YCbCr;
}
} else {
if ((td->td_photometric == PHOTOMETRIC_MINISWHITE || td->td_photometric == PHOTOMETRIC_MINISBLACK) && td->td_samplesperpixel == 1)
sp->cinfo.c.in_color_space = JCS_GRAYSCALE;
else if (td->td_photometric == PHOTOMETRIC_RGB && td->td_samplesperpixel == 3)
sp->cinfo.c.in_color_space = JCS_RGB;
else if (td->td_photometric == PHOTOMETRIC_SEPARATED && td->td_samplesperpixel == 4)
sp->cinfo.c.in_color_space = JCS_CMYK;
else
sp->cinfo.c.in_color_space = JCS_UNKNOWN;
}
} else {
sp->cinfo.c.input_components = 1;
sp->cinfo.c.in_color_space = JCS_UNKNOWN;
}
if (!TIFFjpeg_set_defaults(sp)) if (!TIFFjpeg_set_defaults(sp))
return (0); return (0);
/* Set per-file parameters */ /* Set per-file parameters */
sp->photometric = td->td_photometric;
switch (sp->photometric) { switch (sp->photometric) {
case PHOTOMETRIC_YCBCR: case PHOTOMETRIC_YCBCR:
sp->h_sampling = td->td_ycbcrsubsampling[0]; sp->h_sampling = td->td_ycbcrsubsampling[0];
@ -1712,10 +1775,7 @@ JPEGPreEncode(TIFF* tif, uint16 s)
if (td->td_planarconfig == PLANARCONFIG_CONTIG) { if (td->td_planarconfig == PLANARCONFIG_CONTIG) {
sp->cinfo.c.input_components = td->td_samplesperpixel; sp->cinfo.c.input_components = td->td_samplesperpixel;
if (sp->photometric == PHOTOMETRIC_YCBCR) { if (sp->photometric == PHOTOMETRIC_YCBCR) {
if (sp->jpegcolormode == JPEGCOLORMODE_RGB) { if (sp->jpegcolormode != JPEGCOLORMODE_RGB) {
sp->cinfo.c.in_color_space = JCS_RGB;
} else {
sp->cinfo.c.in_color_space = JCS_YCbCr;
if (sp->h_sampling != 1 || sp->v_sampling != 1) if (sp->h_sampling != 1 || sp->v_sampling != 1)
downsampled_input = TRUE; downsampled_input = TRUE;
} }
@ -1728,21 +1788,11 @@ JPEGPreEncode(TIFF* tif, uint16 s)
sp->cinfo.c.comp_info[0].h_samp_factor = sp->h_sampling; sp->cinfo.c.comp_info[0].h_samp_factor = sp->h_sampling;
sp->cinfo.c.comp_info[0].v_samp_factor = sp->v_sampling; sp->cinfo.c.comp_info[0].v_samp_factor = sp->v_sampling;
} else { } else {
if ((td->td_photometric == PHOTOMETRIC_MINISWHITE || td->td_photometric == PHOTOMETRIC_MINISBLACK) && td->td_samplesperpixel == 1)
sp->cinfo.c.in_color_space = JCS_GRAYSCALE;
else if (td->td_photometric == PHOTOMETRIC_RGB)
sp->cinfo.c.in_color_space = JCS_RGB;
else if (td->td_photometric == PHOTOMETRIC_SEPARATED && td->td_samplesperpixel == 4)
sp->cinfo.c.in_color_space = JCS_CMYK;
else
sp->cinfo.c.in_color_space = JCS_UNKNOWN;
if (!TIFFjpeg_set_colorspace(sp, sp->cinfo.c.in_color_space)) if (!TIFFjpeg_set_colorspace(sp, sp->cinfo.c.in_color_space))
return (0); return (0);
/* jpeg_set_colorspace set all sampling factors to 1 */ /* jpeg_set_colorspace set all sampling factors to 1 */
} }
} else { } else {
sp->cinfo.c.input_components = 1;
sp->cinfo.c.in_color_space = JCS_UNKNOWN;
if (!TIFFjpeg_set_colorspace(sp, JCS_UNKNOWN)) if (!TIFFjpeg_set_colorspace(sp, JCS_UNKNOWN))
return (0); return (0);
sp->cinfo.c.comp_info[0].component_id = s; sp->cinfo.c.comp_info[0].component_id = s;
@ -1757,14 +1807,30 @@ JPEGPreEncode(TIFF* tif, uint16 s)
sp->cinfo.c.write_JFIF_header = FALSE; sp->cinfo.c.write_JFIF_header = FALSE;
sp->cinfo.c.write_Adobe_marker = FALSE; sp->cinfo.c.write_Adobe_marker = FALSE;
/* set up table handling correctly */ /* set up table handling correctly */
if (!TIFFjpeg_set_quality(sp, sp->jpegquality, FALSE)) /* calling TIFFjpeg_set_quality() causes quantization tables to be flagged */
/* as being to be emitted, which we don't want in the JPEGTABLESMODE_QUANT */
/* mode, so we must manually suppress them. However TIFFjpeg_set_quality() */
/* should really be called when dealing with files with directories with */
/* mixed qualities. see http://trac.osgeo.org/gdal/ticket/3539 */
if (!TIFFjpeg_set_quality(sp, sp->jpegquality, FALSE))
return (0); return (0);
if (! (sp->jpegtablesmode & JPEGTABLESMODE_QUANT)) { if (sp->jpegtablesmode & JPEGTABLESMODE_QUANT) {
suppress_quant_table(sp, 0);
suppress_quant_table(sp, 1);
}
else {
unsuppress_quant_table(sp, 0); unsuppress_quant_table(sp, 0);
unsuppress_quant_table(sp, 1); unsuppress_quant_table(sp, 1);
} }
if (sp->jpegtablesmode & JPEGTABLESMODE_HUFF) if (sp->jpegtablesmode & JPEGTABLESMODE_HUFF)
{
/* Explicit suppression is only needed if we did not go through the */
/* prepare_JPEGTables() code path, which may be the case if updating */
/* an existing file */
suppress_huff_table(sp, 0);
suppress_huff_table(sp, 1);
sp->cinfo.c.optimize_coding = FALSE; sp->cinfo.c.optimize_coding = FALSE;
}
else else
sp->cinfo.c.optimize_coding = TRUE; sp->cinfo.c.optimize_coding = TRUE;
if (downsampled_input) { if (downsampled_input) {
@ -1998,13 +2064,10 @@ JPEGCleanup(TIFF* tif)
tif->tif_tagmethods.vgetfield = sp->vgetparent; tif->tif_tagmethods.vgetfield = sp->vgetparent;
tif->tif_tagmethods.vsetfield = sp->vsetparent; tif->tif_tagmethods.vsetfield = sp->vsetparent;
tif->tif_tagmethods.printdir = sp->printdir; tif->tif_tagmethods.printdir = sp->printdir;
if( sp->cinfo_initialized )
if( sp != NULL ) { TIFFjpeg_destroy(sp); /* release libjpeg resources */
if( sp->cinfo_initialized ) if (sp->jpegtables) /* tag value */
TIFFjpeg_destroy(sp); /* release libjpeg resources */ _TIFFfree(sp->jpegtables);
if (sp->jpegtables) /* tag value */
_TIFFfree(sp->jpegtables);
}
_TIFFfree(tif->tif_data); /* release local state */ _TIFFfree(tif->tif_data); /* release local state */
tif->tif_data = NULL; tif->tif_data = NULL;

View File

@ -1,4 +1,4 @@
/* $Id: tif_luv.c,v 1.35 2011-04-02 20:54:09 bfriesen Exp $ */ /* $Id: tif_luv.c,v 1.40 2015-06-21 01:09:09 bfriesen Exp $ */
/* /*
* Copyright (c) 1997 Greg Ward Larson * Copyright (c) 1997 Greg Ward Larson
@ -379,6 +379,9 @@ LogLuvDecodeStrip(TIFF* tif, uint8* bp, tmsize_t cc, uint16 s)
{ {
tmsize_t rowlen = TIFFScanlineSize(tif); tmsize_t rowlen = TIFFScanlineSize(tif);
if (rowlen == 0)
return 0;
assert(cc%rowlen == 0); assert(cc%rowlen == 0);
while (cc && (*tif->tif_decoderow)(tif, bp, rowlen, s)) while (cc && (*tif->tif_decoderow)(tif, bp, rowlen, s))
bp += rowlen, cc -= rowlen; bp += rowlen, cc -= rowlen;
@ -395,6 +398,9 @@ LogLuvDecodeTile(TIFF* tif, uint8* bp, tmsize_t cc, uint16 s)
{ {
tmsize_t rowlen = TIFFTileRowSize(tif); tmsize_t rowlen = TIFFTileRowSize(tif);
if (rowlen == 0)
return 0;
assert(cc%rowlen == 0); assert(cc%rowlen == 0);
while (cc && (*tif->tif_decoderow)(tif, bp, rowlen, s)) while (cc && (*tif->tif_decoderow)(tif, bp, rowlen, s))
bp += rowlen, cc -= rowlen; bp += rowlen, cc -= rowlen;
@ -644,6 +650,9 @@ LogLuvEncodeStrip(TIFF* tif, uint8* bp, tmsize_t cc, uint16 s)
{ {
tmsize_t rowlen = TIFFScanlineSize(tif); tmsize_t rowlen = TIFFScanlineSize(tif);
if (rowlen == 0)
return 0;
assert(cc%rowlen == 0); assert(cc%rowlen == 0);
while (cc && (*tif->tif_encoderow)(tif, bp, rowlen, s) == 1) while (cc && (*tif->tif_encoderow)(tif, bp, rowlen, s) == 1)
bp += rowlen, cc -= rowlen; bp += rowlen, cc -= rowlen;
@ -659,6 +668,9 @@ LogLuvEncodeTile(TIFF* tif, uint8* bp, tmsize_t cc, uint16 s)
{ {
tmsize_t rowlen = TIFFTileRowSize(tif); tmsize_t rowlen = TIFFTileRowSize(tif);
if (rowlen == 0)
return 0;
assert(cc%rowlen == 0); assert(cc%rowlen == 0);
while (cc && (*tif->tif_encoderow)(tif, bp, rowlen, s) == 1) while (cc && (*tif->tif_encoderow)(tif, bp, rowlen, s) == 1)
bp += rowlen, cc -= rowlen; bp += rowlen, cc -= rowlen;
@ -683,7 +695,9 @@ LogLuvEncodeTile(TIFF* tif, uint8* bp, tmsize_t cc, uint16 s)
#ifndef M_PI #ifndef M_PI
#define M_PI 3.14159265358979323846 #define M_PI 3.14159265358979323846
#endif #endif
#undef log2 /* Conflict with C'99 function */
#define log2(x) ((1./M_LN2)*log(x)) #define log2(x) ((1./M_LN2)*log(x))
#undef exp2 /* Conflict with C'99 function */
#define exp2(x) exp(M_LN2*(x)) #define exp2(x) exp(M_LN2*(x))
#define itrunc(x,m) ((m)==SGILOGENCODE_NODITHER ? \ #define itrunc(x,m) ((m)==SGILOGENCODE_NODITHER ? \

View File

@ -1,4 +1,4 @@
/* $Id: tif_lzw.c,v 1.45 2011-04-02 20:54:09 bfriesen Exp $ */ /* $Id: tif_lzw.c,v 1.47 2015-06-13 05:03:50 faxguy Exp $ */
/* /*
* Copyright (c) 1988-1997 Sam Leffler * Copyright (c) 1988-1997 Sam Leffler
@ -268,6 +268,8 @@ LZWPreDecode(TIFF* tif, uint16 s)
if( sp->dec_codetab == NULL ) if( sp->dec_codetab == NULL )
{ {
tif->tif_setupdecode( tif ); tif->tif_setupdecode( tif );
if( sp->dec_codetab == NULL )
return (0);
} }
/* /*
@ -434,16 +436,18 @@ LZWDecode(TIFF* tif, uint8* op0, tmsize_t occ0, uint16 s)
if (code == CODE_EOI) if (code == CODE_EOI)
break; break;
if (code == CODE_CLEAR) { if (code == CODE_CLEAR) {
free_entp = sp->dec_codetab + CODE_FIRST; do {
_TIFFmemset(free_entp, 0, free_entp = sp->dec_codetab + CODE_FIRST;
(CSIZE - CODE_FIRST) * sizeof (code_t)); _TIFFmemset(free_entp, 0,
nbits = BITS_MIN; (CSIZE - CODE_FIRST) * sizeof (code_t));
nbitsmask = MAXCODE(BITS_MIN); nbits = BITS_MIN;
maxcodep = sp->dec_codetab + nbitsmask-1; nbitsmask = MAXCODE(BITS_MIN);
NextCode(tif, sp, bp, code, GetNextCode); maxcodep = sp->dec_codetab + nbitsmask-1;
NextCode(tif, sp, bp, code, GetNextCode);
} while (code == CODE_CLEAR); /* consecutive CODE_CLEAR codes */
if (code == CODE_EOI) if (code == CODE_EOI)
break; break;
if (code >= CODE_CLEAR) { if (code > CODE_CLEAR) {
TIFFErrorExt(tif->tif_clientdata, tif->tif_name, TIFFErrorExt(tif->tif_clientdata, tif->tif_name,
"LZWDecode: Corrupted LZW table at scanline %d", "LZWDecode: Corrupted LZW table at scanline %d",
tif->tif_row); tif->tif_row);
@ -653,16 +657,18 @@ LZWDecodeCompat(TIFF* tif, uint8* op0, tmsize_t occ0, uint16 s)
if (code == CODE_EOI) if (code == CODE_EOI)
break; break;
if (code == CODE_CLEAR) { if (code == CODE_CLEAR) {
free_entp = sp->dec_codetab + CODE_FIRST; do {
_TIFFmemset(free_entp, 0, free_entp = sp->dec_codetab + CODE_FIRST;
(CSIZE - CODE_FIRST) * sizeof (code_t)); _TIFFmemset(free_entp, 0,
nbits = BITS_MIN; (CSIZE - CODE_FIRST) * sizeof (code_t));
nbitsmask = MAXCODE(BITS_MIN); nbits = BITS_MIN;
maxcodep = sp->dec_codetab + nbitsmask; nbitsmask = MAXCODE(BITS_MIN);
NextCode(tif, sp, bp, code, GetNextCodeCompat); maxcodep = sp->dec_codetab + nbitsmask;
NextCode(tif, sp, bp, code, GetNextCodeCompat);
} while (code == CODE_CLEAR); /* consecutive CODE_CLEAR codes */
if (code == CODE_EOI) if (code == CODE_EOI)
break; break;
if (code >= CODE_CLEAR) { if (code > CODE_CLEAR) {
TIFFErrorExt(tif->tif_clientdata, tif->tif_name, TIFFErrorExt(tif->tif_clientdata, tif->tif_name,
"LZWDecode: Corrupted LZW table at scanline %d", "LZWDecode: Corrupted LZW table at scanline %d",
tif->tif_row); tif->tif_row);

View File

@ -1,4 +1,4 @@
/* $Id: tif_next.c,v 1.13 2010-03-10 18:56:48 bfriesen Exp $ */ /* $Id: tif_next.c,v 1.16 2014-12-29 12:09:11 erouault Exp $ */
/* /*
* Copyright (c) 1988-1997 Sam Leffler * Copyright (c) 1988-1997 Sam Leffler
@ -71,7 +71,7 @@ NeXTDecode(TIFF* tif, uint8* buf, tmsize_t occ, uint16 s)
TIFFErrorExt(tif->tif_clientdata, module, "Fractional scanlines cannot be read"); TIFFErrorExt(tif->tif_clientdata, module, "Fractional scanlines cannot be read");
return (0); return (0);
} }
for (row = buf; occ > 0; occ -= scanline, row += scanline) { for (row = buf; cc > 0 && occ > 0; occ -= scanline, row += scanline) {
n = *bp++, cc--; n = *bp++, cc--;
switch (n) { switch (n) {
case LITERALROW: case LITERALROW:
@ -90,6 +90,8 @@ NeXTDecode(TIFF* tif, uint8* buf, tmsize_t occ, uint16 s)
* The scanline has a literal span that begins at some * The scanline has a literal span that begins at some
* offset. * offset.
*/ */
if( cc < 4 )
goto bad;
off = (bp[0] * 256) + bp[1]; off = (bp[0] * 256) + bp[1];
n = (bp[2] * 256) + bp[3]; n = (bp[2] * 256) + bp[3];
if (cc < 4+n || off+n > scanline) if (cc < 4+n || off+n > scanline)
@ -102,6 +104,8 @@ NeXTDecode(TIFF* tif, uint8* buf, tmsize_t occ, uint16 s)
default: { default: {
uint32 npixels = 0, grey; uint32 npixels = 0, grey;
uint32 imagewidth = tif->tif_dir.td_imagewidth; uint32 imagewidth = tif->tif_dir.td_imagewidth;
if( isTiled(tif) )
imagewidth = tif->tif_dir.td_tilewidth;
/* /*
* The scanline is composed of a sequence of constant * The scanline is composed of a sequence of constant
@ -139,10 +143,27 @@ bad:
return (0); return (0);
} }
static int
NeXTPreDecode(TIFF* tif, uint16 s)
{
static const char module[] = "NeXTPreDecode";
TIFFDirectory *td = &tif->tif_dir;
(void)s;
if( td->td_bitspersample != 2 )
{
TIFFErrorExt(tif->tif_clientdata, module, "Unsupported BitsPerSample = %d",
td->td_bitspersample);
return (0);
}
return (1);
}
int int
TIFFInitNeXT(TIFF* tif, int scheme) TIFFInitNeXT(TIFF* tif, int scheme)
{ {
(void) scheme; (void) scheme;
tif->tif_predecode = NeXTPreDecode;
tif->tif_decoderow = NeXTDecode; tif->tif_decoderow = NeXTDecode;
tif->tif_decodestrip = NeXTDecode; tif->tif_decodestrip = NeXTDecode;
tif->tif_decodetile = NeXTDecode; tif->tif_decodetile = NeXTDecode;

View File

@ -1,4 +1,4 @@
/* $Id: tif_ojpeg.c,v 1.54 2011-05-31 17:05:07 bfriesen Exp $ */ /* $Id: tif_ojpeg.c,v 1.60 2015-05-31 00:38:46 bfriesen Exp $ */
/* WARNING: The type of JPEG encapsulation defined by the TIFF Version 6.0 /* WARNING: The type of JPEG encapsulation defined by the TIFF Version 6.0
specification is now totally obsolete and deprecated for new applications and specification is now totally obsolete and deprecated for new applications and
@ -39,7 +39,7 @@
OF THIS SOFTWARE. OF THIS SOFTWARE.
Joris Van Damme and/or AWare Systems may be available for custom Joris Van Damme and/or AWare Systems may be available for custom
developement. If you like what you see, and need anything similar or related, development. If you like what you see, and need anything similar or related,
contact <info@awaresystems.be>. contact <info@awaresystems.be>.
*/ */
@ -141,7 +141,7 @@
* OJPEG_BUFFER: Define the size of the desired buffer here. Should be small enough so as to guarantee * OJPEG_BUFFER: Define the size of the desired buffer here. Should be small enough so as to guarantee
* instant processing, optimal streaming and optimal use of processor cache, but also big * instant processing, optimal streaming and optimal use of processor cache, but also big
* enough so as to not result in significant call overhead. It should be at least a few * enough so as to not result in significant call overhead. It should be at least a few
* bytes to accomodate some structures (this is verified in asserts), but it would not be * bytes to accommodate some structures (this is verified in asserts), but it would not be
* sensible to make it this small anyway, and it should be at most 64K since it is indexed * sensible to make it this small anyway, and it should be at most 64K since it is indexed
* with uint16. We recommend 2K. * with uint16. We recommend 2K.
* EGYPTIANWALK: You could also define EGYPTIANWALK here, but it is not used anywhere and has * EGYPTIANWALK: You could also define EGYPTIANWALK here, but it is not used anywhere and has
@ -528,6 +528,8 @@ OJPEGVSetField(TIFF* tif, uint32 tag, va_list ap)
uint32 ma; uint32 ma;
uint64* mb; uint64* mb;
uint32 n; uint32 n;
const TIFFField* fip;
switch(tag) switch(tag)
{ {
case TIFFTAG_JPEGIFOFFSET: case TIFFTAG_JPEGIFOFFSET:
@ -597,7 +599,10 @@ OJPEGVSetField(TIFF* tif, uint32 tag, va_list ap)
default: default:
return (*sp->vsetparent)(tif,tag,ap); return (*sp->vsetparent)(tif,tag,ap);
} }
TIFFSetFieldBit(tif,TIFFFieldWithTag(tif,tag)->field_bit); fip = TIFFFieldWithTag(tif,tag);
if( fip == NULL ) /* shouldn't happen */
return(0);
TIFFSetFieldBit(tif,fip->field_bit);
tif->tif_flags|=TIFF_DIRTYDIRECT; tif->tif_flags|=TIFF_DIRTYDIRECT;
return(1); return(1);
} }
@ -1146,7 +1151,9 @@ OJPEGWriteHeaderInfo(TIFF* tif)
OJPEGState* sp=(OJPEGState*)tif->tif_data; OJPEGState* sp=(OJPEGState*)tif->tif_data;
uint8** m; uint8** m;
uint32 n; uint32 n;
assert(sp->libjpeg_session_active==0); /* if a previous attempt failed, don't try again */
if (sp->libjpeg_session_active != 0)
return 0;
sp->out_state=ososSoi; sp->out_state=ososSoi;
sp->restart_index=0; sp->restart_index=0;
jpeg_std_error(&(sp->libjpeg_jpeg_error_mgr)); jpeg_std_error(&(sp->libjpeg_jpeg_error_mgr));
@ -1490,14 +1497,17 @@ OJPEGReadHeaderInfoSecStreamDht(TIFF* tif)
nb[sizeof(uint32)+1]=JPEG_MARKER_DHT; nb[sizeof(uint32)+1]=JPEG_MARKER_DHT;
nb[sizeof(uint32)+2]=(m>>8); nb[sizeof(uint32)+2]=(m>>8);
nb[sizeof(uint32)+3]=(m&255); nb[sizeof(uint32)+3]=(m&255);
if (OJPEGReadBlock(sp,m-2,&nb[sizeof(uint32)+4])==0) if (OJPEGReadBlock(sp,m-2,&nb[sizeof(uint32)+4])==0) {
_TIFFfree(nb);
return(0); return(0);
}
o=nb[sizeof(uint32)+4]; o=nb[sizeof(uint32)+4];
if ((o&240)==0) if ((o&240)==0)
{ {
if (3<o) if (3<o)
{ {
TIFFErrorExt(tif->tif_clientdata,module,"Corrupt DHT marker in JPEG data"); TIFFErrorExt(tif->tif_clientdata,module,"Corrupt DHT marker in JPEG data");
_TIFFfree(nb);
return(0); return(0);
} }
if (sp->dctable[o]!=0) if (sp->dctable[o]!=0)
@ -1509,12 +1519,14 @@ OJPEGReadHeaderInfoSecStreamDht(TIFF* tif)
if ((o&240)!=16) if ((o&240)!=16)
{ {
TIFFErrorExt(tif->tif_clientdata,module,"Corrupt DHT marker in JPEG data"); TIFFErrorExt(tif->tif_clientdata,module,"Corrupt DHT marker in JPEG data");
_TIFFfree(nb);
return(0); return(0);
} }
o&=15; o&=15;
if (3<o) if (3<o)
{ {
TIFFErrorExt(tif->tif_clientdata,module,"Corrupt DHT marker in JPEG data"); TIFFErrorExt(tif->tif_clientdata,module,"Corrupt DHT marker in JPEG data");
_TIFFfree(nb);
return(0); return(0);
} }
if (sp->actable[o]!=0) if (sp->actable[o]!=0)
@ -1953,7 +1965,13 @@ OJPEGReadBufferFill(OJPEGState* sp)
break; break;
case osibsJpegInterchangeFormat: case osibsJpegInterchangeFormat:
sp->in_buffer_source=osibsStrile; sp->in_buffer_source=osibsStrile;
break;
case osibsStrile: case osibsStrile:
if (!_TIFFFillStriles( sp->tif )
|| sp->tif->tif_dir.td_stripoffset == NULL
|| sp->tif->tif_dir.td_stripbytecount == NULL)
return 0;
if (sp->in_buffer_next_strile==sp->in_buffer_strile_count) if (sp->in_buffer_next_strile==sp->in_buffer_strile_count)
sp->in_buffer_source=osibsEof; sp->in_buffer_source=osibsEof;
else else

View File

@ -1,4 +1,4 @@
/* $Id: tif_packbits.c,v 1.20 2010-03-10 18:56:49 bfriesen Exp $ */ /* $Id: tif_packbits.c,v 1.22 2012-06-20 05:25:33 fwarmerdam Exp $ */
/* /*
* Copyright (c) 1988-1997 Sam Leffler * Copyright (c) 1988-1997 Sam Leffler
@ -241,7 +241,7 @@ PackBitsDecode(TIFF* tif, uint8* op, tmsize_t occ, uint16 s)
n = (long)occ; n = (long)occ;
} }
occ -= n; occ -= n;
b = *bp++, cc--; /* TODO: may be reading past input buffer here when input data is corrupt or ends prematurely */ b = *bp++, cc--;
while (n-- > 0) while (n-- > 0)
*op++ = (uint8) b; *op++ = (uint8) b;
} else { /* copy next n+1 bytes literally */ } else { /* copy next n+1 bytes literally */
@ -252,7 +252,13 @@ PackBitsDecode(TIFF* tif, uint8* op, tmsize_t occ, uint16 s)
(unsigned long) ((tmsize_t)n - occ + 1)); (unsigned long) ((tmsize_t)n - occ + 1));
n = (long)occ - 1; n = (long)occ - 1;
} }
_TIFFmemcpy(op, bp, ++n); /* TODO: may be reading past input buffer here when input data is corrupt or ends prematurely */ if (cc < (tmsize_t) (n+1))
{
TIFFWarningExt(tif->tif_clientdata, module,
"Terminating PackBitsDecode due to lack of data.");
break;
}
_TIFFmemcpy(op, bp, ++n);
op += n; occ -= n; op += n; occ -= n;
bp += n; cc -= n; bp += n; cc -= n;
} }

View File

@ -1,4 +1,4 @@
/* $Id: tif_pixarlog.c,v 1.35 2011-01-06 16:00:23 fwarmerdam Exp $ */ /* $Id: tif_pixarlog.c,v 1.39 2012-12-10 17:27:13 tgl Exp $ */
/* /*
* Copyright (c) 1996-1997 Sam Leffler * Copyright (c) 1996-1997 Sam Leffler
@ -120,9 +120,9 @@ horizontalAccumulateF(uint16 *wp, int n, int stride, float *op,
if (n >= stride) { if (n >= stride) {
mask = CODE_MASK; mask = CODE_MASK;
if (stride == 3) { if (stride == 3) {
t0 = ToLinearF[cr = wp[0]]; t0 = ToLinearF[cr = (wp[0] & mask)];
t1 = ToLinearF[cg = wp[1]]; t1 = ToLinearF[cg = (wp[1] & mask)];
t2 = ToLinearF[cb = wp[2]]; t2 = ToLinearF[cb = (wp[2] & mask)];
op[0] = t0; op[0] = t0;
op[1] = t1; op[1] = t1;
op[2] = t2; op[2] = t2;
@ -139,10 +139,10 @@ horizontalAccumulateF(uint16 *wp, int n, int stride, float *op,
op[2] = t2; op[2] = t2;
} }
} else if (stride == 4) { } else if (stride == 4) {
t0 = ToLinearF[cr = wp[0]]; t0 = ToLinearF[cr = (wp[0] & mask)];
t1 = ToLinearF[cg = wp[1]]; t1 = ToLinearF[cg = (wp[1] & mask)];
t2 = ToLinearF[cb = wp[2]]; t2 = ToLinearF[cb = (wp[2] & mask)];
t3 = ToLinearF[ca = wp[3]]; t3 = ToLinearF[ca = (wp[3] & mask)];
op[0] = t0; op[0] = t0;
op[1] = t1; op[1] = t1;
op[2] = t2; op[2] = t2;
@ -186,9 +186,9 @@ horizontalAccumulate12(uint16 *wp, int n, int stride, int16 *op,
if (n >= stride) { if (n >= stride) {
mask = CODE_MASK; mask = CODE_MASK;
if (stride == 3) { if (stride == 3) {
t0 = ToLinearF[cr = wp[0]] * SCALE12; t0 = ToLinearF[cr = (wp[0] & mask)] * SCALE12;
t1 = ToLinearF[cg = wp[1]] * SCALE12; t1 = ToLinearF[cg = (wp[1] & mask)] * SCALE12;
t2 = ToLinearF[cb = wp[2]] * SCALE12; t2 = ToLinearF[cb = (wp[2] & mask)] * SCALE12;
op[0] = CLAMP12(t0); op[0] = CLAMP12(t0);
op[1] = CLAMP12(t1); op[1] = CLAMP12(t1);
op[2] = CLAMP12(t2); op[2] = CLAMP12(t2);
@ -205,10 +205,10 @@ horizontalAccumulate12(uint16 *wp, int n, int stride, int16 *op,
op[2] = CLAMP12(t2); op[2] = CLAMP12(t2);
} }
} else if (stride == 4) { } else if (stride == 4) {
t0 = ToLinearF[cr = wp[0]] * SCALE12; t0 = ToLinearF[cr = (wp[0] & mask)] * SCALE12;
t1 = ToLinearF[cg = wp[1]] * SCALE12; t1 = ToLinearF[cg = (wp[1] & mask)] * SCALE12;
t2 = ToLinearF[cb = wp[2]] * SCALE12; t2 = ToLinearF[cb = (wp[2] & mask)] * SCALE12;
t3 = ToLinearF[ca = wp[3]] * SCALE12; t3 = ToLinearF[ca = (wp[3] & mask)] * SCALE12;
op[0] = CLAMP12(t0); op[0] = CLAMP12(t0);
op[1] = CLAMP12(t1); op[1] = CLAMP12(t1);
op[2] = CLAMP12(t2); op[2] = CLAMP12(t2);
@ -250,9 +250,9 @@ horizontalAccumulate16(uint16 *wp, int n, int stride, uint16 *op,
if (n >= stride) { if (n >= stride) {
mask = CODE_MASK; mask = CODE_MASK;
if (stride == 3) { if (stride == 3) {
op[0] = ToLinear16[cr = wp[0]]; op[0] = ToLinear16[cr = (wp[0] & mask)];
op[1] = ToLinear16[cg = wp[1]]; op[1] = ToLinear16[cg = (wp[1] & mask)];
op[2] = ToLinear16[cb = wp[2]]; op[2] = ToLinear16[cb = (wp[2] & mask)];
n -= 3; n -= 3;
while (n > 0) { while (n > 0) {
wp += 3; wp += 3;
@ -263,10 +263,10 @@ horizontalAccumulate16(uint16 *wp, int n, int stride, uint16 *op,
op[2] = ToLinear16[(cb += wp[2]) & mask]; op[2] = ToLinear16[(cb += wp[2]) & mask];
} }
} else if (stride == 4) { } else if (stride == 4) {
op[0] = ToLinear16[cr = wp[0]]; op[0] = ToLinear16[cr = (wp[0] & mask)];
op[1] = ToLinear16[cg = wp[1]]; op[1] = ToLinear16[cg = (wp[1] & mask)];
op[2] = ToLinear16[cb = wp[2]]; op[2] = ToLinear16[cb = (wp[2] & mask)];
op[3] = ToLinear16[ca = wp[3]]; op[3] = ToLinear16[ca = (wp[3] & mask)];
n -= 4; n -= 4;
while (n > 0) { while (n > 0) {
wp += 4; wp += 4;
@ -345,9 +345,9 @@ horizontalAccumulate8(uint16 *wp, int n, int stride, unsigned char *op,
if (n >= stride) { if (n >= stride) {
mask = CODE_MASK; mask = CODE_MASK;
if (stride == 3) { if (stride == 3) {
op[0] = ToLinear8[cr = wp[0]]; op[0] = ToLinear8[cr = (wp[0] & mask)];
op[1] = ToLinear8[cg = wp[1]]; op[1] = ToLinear8[cg = (wp[1] & mask)];
op[2] = ToLinear8[cb = wp[2]]; op[2] = ToLinear8[cb = (wp[2] & mask)];
n -= 3; n -= 3;
while (n > 0) { while (n > 0) {
n -= 3; n -= 3;
@ -358,10 +358,10 @@ horizontalAccumulate8(uint16 *wp, int n, int stride, unsigned char *op,
op[2] = ToLinear8[(cb += wp[2]) & mask]; op[2] = ToLinear8[(cb += wp[2]) & mask];
} }
} else if (stride == 4) { } else if (stride == 4) {
op[0] = ToLinear8[cr = wp[0]]; op[0] = ToLinear8[cr = (wp[0] & mask)];
op[1] = ToLinear8[cg = wp[1]]; op[1] = ToLinear8[cg = (wp[1] & mask)];
op[2] = ToLinear8[cb = wp[2]]; op[2] = ToLinear8[cb = (wp[2] & mask)];
op[3] = ToLinear8[ca = wp[3]]; op[3] = ToLinear8[ca = (wp[3] & mask)];
n -= 4; n -= 4;
while (n > 0) { while (n > 0) {
n -= 4; n -= 4;
@ -396,9 +396,9 @@ horizontalAccumulate8abgr(uint16 *wp, int n, int stride, unsigned char *op,
mask = CODE_MASK; mask = CODE_MASK;
if (stride == 3) { if (stride == 3) {
op[0] = 0; op[0] = 0;
t1 = ToLinear8[cb = wp[2]]; t1 = ToLinear8[cb = (wp[2] & mask)];
t2 = ToLinear8[cg = wp[1]]; t2 = ToLinear8[cg = (wp[1] & mask)];
t3 = ToLinear8[cr = wp[0]]; t3 = ToLinear8[cr = (wp[0] & mask)];
op[1] = t1; op[1] = t1;
op[2] = t2; op[2] = t2;
op[3] = t3; op[3] = t3;
@ -416,10 +416,10 @@ horizontalAccumulate8abgr(uint16 *wp, int n, int stride, unsigned char *op,
op[3] = t3; op[3] = t3;
} }
} else if (stride == 4) { } else if (stride == 4) {
t0 = ToLinear8[ca = wp[3]]; t0 = ToLinear8[ca = (wp[3] & mask)];
t1 = ToLinear8[cb = wp[2]]; t1 = ToLinear8[cb = (wp[2] & mask)];
t2 = ToLinear8[cg = wp[1]]; t2 = ToLinear8[cg = (wp[1] & mask)];
t3 = ToLinear8[cr = wp[0]]; t3 = ToLinear8[cr = (wp[0] & mask)];
op[0] = t0; op[0] = t0;
op[1] = t1; op[1] = t1;
op[2] = t2; op[2] = t2;
@ -644,6 +644,20 @@ multiply_ms(tmsize_t m1, tmsize_t m2)
return bytes; return bytes;
} }
static tmsize_t
add_ms(tmsize_t m1, tmsize_t m2)
{
tmsize_t bytes = m1 + m2;
/* if either input is zero, assume overflow already occurred */
if (m1 == 0 || m2 == 0)
bytes = 0;
else if (bytes <= m1 || bytes <= m2)
bytes = 0;
return bytes;
}
static int static int
PixarLogFixupTags(TIFF* tif) PixarLogFixupTags(TIFF* tif)
{ {
@ -671,6 +685,8 @@ PixarLogSetupDecode(TIFF* tif)
td->td_samplesperpixel : 1); td->td_samplesperpixel : 1);
tbuf_size = multiply_ms(multiply_ms(multiply_ms(sp->stride, td->td_imagewidth), tbuf_size = multiply_ms(multiply_ms(multiply_ms(sp->stride, td->td_imagewidth),
td->td_rowsperstrip), sizeof(uint16)); td->td_rowsperstrip), sizeof(uint16));
/* add one more stride in case input ends mid-stride */
tbuf_size = add_ms(tbuf_size, sizeof(uint16) * sp->stride);
if (tbuf_size == 0) if (tbuf_size == 0)
return (0); /* TODO: this is an error return without error report through TIFFErrorExt */ return (0); /* TODO: this is an error return without error report through TIFFErrorExt */
sp->tbuf = (uint16 *) _TIFFmalloc(tbuf_size); sp->tbuf = (uint16 *) _TIFFmalloc(tbuf_size);

View File

@ -1,4 +1,4 @@
/* $Id: tif_print.c,v 1.54 2011-04-02 20:54:09 bfriesen Exp $ */ /* $Id: tif_print.c,v 1.61 2012-12-12 22:50:18 tgl Exp $ */
/* /*
* Copyright (c) 1988-1997 Sam Leffler * Copyright (c) 1988-1997 Sam Leffler
@ -34,6 +34,9 @@
#include <ctype.h> #include <ctype.h>
static void
_TIFFprintAsciiBounded(FILE* fd, const char* cp, int max_chars);
static const char *photoNames[] = { static const char *photoNames[] = {
"min-is-white", /* PHOTOMETRIC_MINISWHITE */ "min-is-white", /* PHOTOMETRIC_MINISWHITE */
"min-is-black", /* PHOTOMETRIC_MINISBLACK */ "min-is-black", /* PHOTOMETRIC_MINISBLACK */
@ -44,6 +47,8 @@ static const char *photoNames[] = {
"YCbCr", /* PHOTOMETRIC_YCBCR */ "YCbCr", /* PHOTOMETRIC_YCBCR */
"7 (0x7)", "7 (0x7)",
"CIE L*a*b*", /* PHOTOMETRIC_CIELAB */ "CIE L*a*b*", /* PHOTOMETRIC_CIELAB */
"ICC L*a*b*", /* PHOTOMETRIC_ICCLAB */
"ITU L*a*b*" /* PHOTOMETRIC_ITULAB */
}; };
#define NPHOTONAMES (sizeof (photoNames) / sizeof (photoNames[0])) #define NPHOTONAMES (sizeof (photoNames) / sizeof (photoNames[0]))
@ -135,34 +140,51 @@ _TIFFPrintField(FILE* fd, const TIFFField *fip,
} }
static int static int
_TIFFPrettyPrintField(TIFF* tif, FILE* fd, uint32 tag, _TIFFPrettyPrintField(TIFF* tif, const TIFFField *fip, FILE* fd, uint32 tag,
uint32 value_count, void *raw_data) uint32 value_count, void *raw_data)
{ {
(void) tif; (void) tif;
/* do not try to pretty print auto-defined fields */
if (strncmp(fip->field_name,"Tag ", 4) == 0) {
return 0;
}
switch (tag) switch (tag)
{ {
case TIFFTAG_INKSET: case TIFFTAG_INKSET:
fprintf(fd, " Ink Set: "); if (value_count == 2 && fip->field_type == TIFF_SHORT) {
switch (*((uint16*)raw_data)) { fprintf(fd, " Ink Set: ");
switch (*((uint16*)raw_data)) {
case INKSET_CMYK: case INKSET_CMYK:
fprintf(fd, "CMYK\n"); fprintf(fd, "CMYK\n");
break; break;
default: default:
fprintf(fd, "%u (0x%x)\n", fprintf(fd, "%u (0x%x)\n",
*((uint16*)raw_data), *((uint16*)raw_data),
*((uint16*)raw_data)); *((uint16*)raw_data));
break; break;
}
return 1;
} }
return 1; return 0;
case TIFFTAG_DOTRANGE: case TIFFTAG_DOTRANGE:
fprintf(fd, " Dot Range: %u-%u\n", if (value_count == 2 && fip->field_type == TIFF_SHORT) {
((uint16*)raw_data)[0], ((uint16*)raw_data)[1]); fprintf(fd, " Dot Range: %u-%u\n",
return 1; ((uint16*)raw_data)[0], ((uint16*)raw_data)[1]);
return 1;
}
return 0;
case TIFFTAG_WHITEPOINT: case TIFFTAG_WHITEPOINT:
fprintf(fd, " White Point: %g-%g\n", if (value_count == 2 && fip->field_type == TIFF_RATIONAL) {
((float *)raw_data)[0], ((float *)raw_data)[1]); fprintf(fd, " White Point: %g-%g\n",
return 1; ((float *)raw_data)[0], ((float *)raw_data)[1]);
return 1;
}
return 0;
case TIFFTAG_XMLPACKET: case TIFFTAG_XMLPACKET:
{ {
uint32 i; uint32 i;
@ -182,19 +204,25 @@ _TIFFPrettyPrintField(TIFF* tif, FILE* fd, uint32 tag,
" RichTIFFIPTC Data: <present>, %lu bytes\n", " RichTIFFIPTC Data: <present>, %lu bytes\n",
(unsigned long) value_count * 4); (unsigned long) value_count * 4);
return 1; return 1;
case TIFFTAG_PHOTOSHOP: case TIFFTAG_PHOTOSHOP:
fprintf(fd, " Photoshop Data: <present>, %lu bytes\n", fprintf(fd, " Photoshop Data: <present>, %lu bytes\n",
(unsigned long) value_count); (unsigned long) value_count);
return 1; return 1;
case TIFFTAG_ICCPROFILE: case TIFFTAG_ICCPROFILE:
fprintf(fd, " ICC Profile: <present>, %lu bytes\n", fprintf(fd, " ICC Profile: <present>, %lu bytes\n",
(unsigned long) value_count); (unsigned long) value_count);
return 1; return 1;
case TIFFTAG_STONITS: case TIFFTAG_STONITS:
fprintf(fd, if (value_count == 1 && fip->field_type == TIFF_DOUBLE) {
" Sample to Nits conversion factor: %.4e\n", fprintf(fd,
*((double*)raw_data)); " Sample to Nits conversion factor: %.4e\n",
return 1; *((double*)raw_data));
return 1;
}
return 0;
} }
return 0; return 0;
@ -364,9 +392,13 @@ TIFFPrintDirectory(TIFF* tif, FILE* fd, long flags)
fprintf(fd, " Ink Names: "); fprintf(fd, " Ink Names: ");
i = td->td_samplesperpixel; i = td->td_samplesperpixel;
sep = ""; sep = "";
for (cp = td->td_inknames; i > 0; cp = strchr(cp,'\0')+1, i--) { for (cp = td->td_inknames;
i > 0 && cp < td->td_inknames + td->td_inknameslen;
cp = strchr(cp,'\0')+1, i--) {
int max_chars =
td->td_inknameslen - (cp - td->td_inknames);
fputs(sep, fd); fputs(sep, fd);
_TIFFprintAscii(fd, cp); _TIFFprintAsciiBounded(fd, cp, max_chars);
sep = ", "; sep = ", ";
} }
fputs("\n", fd); fputs("\n", fd);
@ -449,14 +481,16 @@ TIFFPrintDirectory(TIFF* tif, FILE* fd, long flags)
if (TIFFFieldSet(tif,FIELD_MAXSAMPLEVALUE)) if (TIFFFieldSet(tif,FIELD_MAXSAMPLEVALUE))
fprintf(fd, " Max Sample Value: %u\n", td->td_maxsamplevalue); fprintf(fd, " Max Sample Value: %u\n", td->td_maxsamplevalue);
if (TIFFFieldSet(tif,FIELD_SMINSAMPLEVALUE)) { if (TIFFFieldSet(tif,FIELD_SMINSAMPLEVALUE)) {
int count = (tif->tif_flags & TIFF_PERSAMPLE) ? td->td_samplesperpixel : 1;
fprintf(fd, " SMin Sample Value:"); fprintf(fd, " SMin Sample Value:");
for (i = 0; i < td->td_samplesperpixel; ++i) for (i = 0; i < count; ++i)
fprintf(fd, " %g", td->td_sminsamplevalue[i]); fprintf(fd, " %g", td->td_sminsamplevalue[i]);
fprintf(fd, "\n"); fprintf(fd, "\n");
} }
if (TIFFFieldSet(tif,FIELD_SMAXSAMPLEVALUE)) { if (TIFFFieldSet(tif,FIELD_SMAXSAMPLEVALUE)) {
int count = (tif->tif_flags & TIFF_PERSAMPLE) ? td->td_samplesperpixel : 1;
fprintf(fd, " SMax Sample Value:"); fprintf(fd, " SMax Sample Value:");
for (i = 0; i < td->td_samplesperpixel; ++i) for (i = 0; i < count; ++i)
fprintf(fd, " %g", td->td_smaxsamplevalue[i]); fprintf(fd, " %g", td->td_smaxsamplevalue[i]);
fprintf(fd, "\n"); fprintf(fd, "\n");
} }
@ -548,8 +582,19 @@ TIFFPrintDirectory(TIFF* tif, FILE* fd, long flags)
continue; continue;
if(fip->field_passcount) { if(fip->field_passcount) {
if(TIFFGetField(tif, tag, &value_count, &raw_data) != 1) if (fip->field_readcount == TIFF_VARIABLE2 ) {
if(TIFFGetField(tif, tag, &value_count, &raw_data) != 1)
continue;
} else if (fip->field_readcount == TIFF_VARIABLE ) {
uint16 small_value_count;
if(TIFFGetField(tif, tag, &small_value_count, &raw_data) != 1)
continue;
value_count = small_value_count;
} else {
assert (fip->field_readcount == TIFF_VARIABLE
|| fip->field_readcount == TIFF_VARIABLE2);
continue; continue;
}
} else { } else {
if (fip->field_readcount == TIFF_VARIABLE if (fip->field_readcount == TIFF_VARIABLE
|| fip->field_readcount == TIFF_VARIABLE2) || fip->field_readcount == TIFF_VARIABLE2)
@ -558,21 +603,23 @@ TIFFPrintDirectory(TIFF* tif, FILE* fd, long flags)
value_count = td->td_samplesperpixel; value_count = td->td_samplesperpixel;
else else
value_count = fip->field_readcount; value_count = fip->field_readcount;
if ((fip->field_type == TIFF_ASCII if (fip->field_tag == TIFFTAG_DOTRANGE
|| fip->field_readcount == TIFF_VARIABLE && strcmp(fip->field_name,"DotRange") == 0) {
|| fip->field_readcount == TIFF_VARIABLE2 /* TODO: This is an evil exception and should not have been
|| fip->field_readcount == TIFF_SPP handled this way ... likely best if we move it into
|| value_count > 1) the directory structure with an explicit field in
&& fip->field_tag != TIFFTAG_PAGENUMBER libtiff 4.1 and assign it a FIELD_ value */
&& fip->field_tag != TIFFTAG_HALFTONEHINTS static uint16 dotrange[2];
&& fip->field_tag != TIFFTAG_YCBCRSUBSAMPLING raw_data = dotrange;
&& fip->field_tag != TIFFTAG_DOTRANGE) { TIFFGetField(tif, tag, dotrange+0, dotrange+1);
} else if (fip->field_type == TIFF_ASCII
|| fip->field_readcount == TIFF_VARIABLE
|| fip->field_readcount == TIFF_VARIABLE2
|| fip->field_readcount == TIFF_SPP
|| value_count > 1) {
if(TIFFGetField(tif, tag, &raw_data) != 1) if(TIFFGetField(tif, tag, &raw_data) != 1)
continue; continue;
} else if (fip->field_tag != TIFFTAG_PAGENUMBER } else {
&& fip->field_tag != TIFFTAG_HALFTONEHINTS
&& fip->field_tag != TIFFTAG_YCBCRSUBSAMPLING
&& fip->field_tag != TIFFTAG_DOTRANGE) {
raw_data = _TIFFmalloc( raw_data = _TIFFmalloc(
_TIFFDataSize(fip->field_type) _TIFFDataSize(fip->field_type)
* value_count); * value_count);
@ -581,26 +628,6 @@ TIFFPrintDirectory(TIFF* tif, FILE* fd, long flags)
_TIFFfree(raw_data); _TIFFfree(raw_data);
continue; continue;
} }
} else {
/*
* XXX: Should be fixed and removed,
* see the notes related to
* TIFFTAG_PAGENUMBER,
* TIFFTAG_HALFTONEHINTS,
* TIFFTAG_YCBCRSUBSAMPLING and
* TIFFTAG_DOTRANGE tags in tif_dir.c.
*/
char *tmp;
raw_data = _TIFFmalloc(
_TIFFDataSize(fip->field_type)
* value_count);
tmp = raw_data;
mem_alloc = 1;
if(TIFFGetField(tif, tag, tmp,
tmp + _TIFFDataSize(fip->field_type)) != 1) {
_TIFFfree(raw_data);
continue;
}
} }
} }
@ -610,7 +637,7 @@ TIFFPrintDirectory(TIFF* tif, FILE* fd, long flags)
* _TIFFPrettyPrintField() fall down and print it as * _TIFFPrettyPrintField() fall down and print it as
* any other tag. * any other tag.
*/ */
if (!_TIFFPrettyPrintField(tif, fd, tag, value_count, raw_data)) if (!_TIFFPrettyPrintField(tif, fip, fd, tag, value_count, raw_data))
_TIFFPrintField(fd, fip, value_count, raw_data); _TIFFPrintField(fd, fip, value_count, raw_data);
if(mem_alloc) if(mem_alloc)
@ -648,7 +675,13 @@ TIFFPrintDirectory(TIFF* tif, FILE* fd, long flags)
void void
_TIFFprintAscii(FILE* fd, const char* cp) _TIFFprintAscii(FILE* fd, const char* cp)
{ {
for (; *cp != '\0'; cp++) { _TIFFprintAsciiBounded( fd, cp, strlen(cp));
}
static void
_TIFFprintAsciiBounded(FILE* fd, const char* cp, int max_chars)
{
for (; max_chars > 0 && *cp != '\0'; cp++, max_chars--) {
const char* tp; const char* tp;
if (isprint((int)*cp)) { if (isprint((int)*cp)) {

View File

@ -1,4 +1,4 @@
/* $Id: tif_read.c,v 1.38 2011-12-09 03:29:10 fwarmerdam Exp $ */ /* $Id: tif_read.c,v 1.45 2015-06-07 22:35:40 bfriesen Exp $ */
/* /*
* Copyright (c) 1988-1997 Sam Leffler * Copyright (c) 1988-1997 Sam Leffler
@ -47,10 +47,10 @@ TIFFFillStripPartial( TIFF *tif, int strip, tmsize_t read_ahead, int restart )
{ {
static const char module[] = "TIFFFillStripPartial"; static const char module[] = "TIFFFillStripPartial";
register TIFFDirectory *td = &tif->tif_dir; register TIFFDirectory *td = &tif->tif_dir;
uint64 unused_data; tmsize_t unused_data;
uint64 read_offset; uint64 read_offset;
tmsize_t cc, to_read; tmsize_t cc, to_read;
tmsize_t bytecountm; /* tmsize_t bytecountm; */
if (!_TIFFFillStriles( tif ) || !tif->tif_dir.td_stripbytecount) if (!_TIFFFillStriles( tif ) || !tif->tif_dir.td_stripbytecount)
return 0; return 0;
@ -61,7 +61,7 @@ TIFFFillStripPartial( TIFF *tif, int strip, tmsize_t read_ahead, int restart )
* bound on the size of a buffer we'll use?). * bound on the size of a buffer we'll use?).
*/ */
bytecountm=(tmsize_t) td->td_stripbytecount[strip]; /* bytecountm=(tmsize_t) td->td_stripbytecount[strip]; */
if (read_ahead*2 > tif->tif_rawdatasize) { if (read_ahead*2 > tif->tif_rawdatasize) {
assert( restart ); assert( restart );
@ -93,6 +93,7 @@ TIFFFillStripPartial( TIFF *tif, int strip, tmsize_t read_ahead, int restart )
if( unused_data > 0 ) if( unused_data > 0 )
{ {
assert((tif->tif_flags&TIFF_BUFFERMMAP)==0);
memmove( tif->tif_rawdata, tif->tif_rawcp, unused_data ); memmove( tif->tif_rawdata, tif->tif_rawcp, unused_data );
} }
@ -116,10 +117,11 @@ TIFFFillStripPartial( TIFF *tif, int strip, tmsize_t read_ahead, int restart )
if( (uint64) to_read > td->td_stripbytecount[strip] if( (uint64) to_read > td->td_stripbytecount[strip]
- tif->tif_rawdataoff - tif->tif_rawdataloaded ) - tif->tif_rawdataoff - tif->tif_rawdataloaded )
{ {
to_read = td->td_stripbytecount[strip] to_read = (tmsize_t) td->td_stripbytecount[strip]
- tif->tif_rawdataoff - tif->tif_rawdataloaded; - tif->tif_rawdataoff - tif->tif_rawdataloaded;
} }
assert((tif->tif_flags&TIFF_BUFFERMMAP)==0);
cc = TIFFReadFile(tif, tif->tif_rawdata + unused_data, to_read); cc = TIFFReadFile(tif, tif->tif_rawdata + unused_data, to_read);
if (cc != to_read) { if (cc != to_read) {
@ -145,8 +147,10 @@ TIFFFillStripPartial( TIFF *tif, int strip, tmsize_t read_ahead, int restart )
tif->tif_rawcp = tif->tif_rawdata; tif->tif_rawcp = tif->tif_rawdata;
if (!isFillOrder(tif, td->td_fillorder) && if (!isFillOrder(tif, td->td_fillorder) &&
(tif->tif_flags & TIFF_NOBITREV) == 0) (tif->tif_flags & TIFF_NOBITREV) == 0) {
assert((tif->tif_flags&TIFF_BUFFERMMAP)==0);
TIFFReverseBits(tif->tif_rawdata + unused_data, to_read ); TIFFReverseBits(tif->tif_rawdata + unused_data, to_read );
}
/* /*
** When starting a strip from the beginning we need to ** When starting a strip from the beginning we need to
@ -454,7 +458,7 @@ TIFFReadRawStrip(TIFF* tif, uint32 strip, void* buf, tmsize_t size)
return ((tmsize_t)(-1)); return ((tmsize_t)(-1));
} }
bytecount = td->td_stripbytecount[strip]; bytecount = td->td_stripbytecount[strip];
if (bytecount <= 0) { if ((int64)bytecount <= 0) {
#if defined(__WIN32__) && (defined(_MSC_VER) || defined(__MINGW32__)) #if defined(__WIN32__) && (defined(_MSC_VER) || defined(__MINGW32__))
TIFFErrorExt(tif->tif_clientdata, module, TIFFErrorExt(tif->tif_clientdata, module,
"%I64u: Invalid strip byte count, strip %lu", "%I64u: Invalid strip byte count, strip %lu",
@ -494,7 +498,7 @@ TIFFFillStrip(TIFF* tif, uint32 strip)
if ((tif->tif_flags&TIFF_NOREADRAW)==0) if ((tif->tif_flags&TIFF_NOREADRAW)==0)
{ {
uint64 bytecount = td->td_stripbytecount[strip]; uint64 bytecount = td->td_stripbytecount[strip];
if (bytecount <= 0) { if ((int64)bytecount <= 0) {
#if defined(__WIN32__) && (defined(_MSC_VER) || defined(__MINGW32__)) #if defined(__WIN32__) && (defined(_MSC_VER) || defined(__MINGW32__))
TIFFErrorExt(tif->tif_clientdata, module, TIFFErrorExt(tif->tif_clientdata, module,
"Invalid strip byte count %I64u, strip %lu", "Invalid strip byte count %I64u, strip %lu",
@ -522,8 +526,11 @@ TIFFFillStrip(TIFF* tif, uint32 strip)
* buffer (if they try to, the application will get a * buffer (if they try to, the application will get a
* fault since the file is mapped read-only). * fault since the file is mapped read-only).
*/ */
if ((tif->tif_flags & TIFF_MYBUFFER) && tif->tif_rawdata) if ((tif->tif_flags & TIFF_MYBUFFER) && tif->tif_rawdata) {
_TIFFfree(tif->tif_rawdata); _TIFFfree(tif->tif_rawdata);
tif->tif_rawdata = NULL;
tif->tif_rawdatasize = 0;
}
tif->tif_flags &= ~TIFF_MYBUFFER; tif->tif_flags &= ~TIFF_MYBUFFER;
/* /*
* We must check for overflow, potentially causing * We must check for overflow, potentially causing
@ -565,6 +572,14 @@ TIFFFillStrip(TIFF* tif, uint32 strip)
tif->tif_rawdata = tif->tif_base + (tmsize_t)td->td_stripoffset[strip]; tif->tif_rawdata = tif->tif_base + (tmsize_t)td->td_stripoffset[strip];
tif->tif_rawdataoff = 0; tif->tif_rawdataoff = 0;
tif->tif_rawdataloaded = (tmsize_t) bytecount; tif->tif_rawdataloaded = (tmsize_t) bytecount;
/*
* When we have tif_rawdata reference directly into the memory mapped file
* we need to be pretty careful about how we use the rawdata. It is not
* a general purpose working buffer as it normally otherwise is. So we
* keep track of this fact to avoid using it improperly.
*/
tif->tif_flags |= TIFF_BUFFERMMAP;
} else { } else {
/* /*
* Expand raw data buffer, if needed, to hold data * Expand raw data buffer, if needed, to hold data
@ -589,6 +604,11 @@ TIFFFillStrip(TIFF* tif, uint32 strip)
if (!TIFFReadBufferSetup(tif, 0, bytecountm)) if (!TIFFReadBufferSetup(tif, 0, bytecountm))
return (0); return (0);
} }
if (tif->tif_flags&TIFF_BUFFERMMAP) {
tif->tif_curstrip = NOSTRIP;
if (!TIFFReadBufferSetup(tif, 0, bytecountm))
return (0);
}
if (TIFFReadRawStrip1(tif, strip, tif->tif_rawdata, if (TIFFReadRawStrip1(tif, strip, tif->tif_rawdata,
bytecountm, module) != bytecountm) bytecountm, module) != bytecountm)
return (0); return (0);
@ -781,7 +801,7 @@ TIFFFillTile(TIFF* tif, uint32 tile)
if ((tif->tif_flags&TIFF_NOREADRAW)==0) if ((tif->tif_flags&TIFF_NOREADRAW)==0)
{ {
uint64 bytecount = td->td_stripbytecount[tile]; uint64 bytecount = td->td_stripbytecount[tile];
if (bytecount <= 0) { if ((int64)bytecount <= 0) {
#if defined(__WIN32__) && (defined(_MSC_VER) || defined(__MINGW32__)) #if defined(__WIN32__) && (defined(_MSC_VER) || defined(__MINGW32__))
TIFFErrorExt(tif->tif_clientdata, module, TIFFErrorExt(tif->tif_clientdata, module,
"%I64u: Invalid tile byte count, tile %lu", "%I64u: Invalid tile byte count, tile %lu",
@ -809,8 +829,11 @@ TIFFFillTile(TIFF* tif, uint32 tile)
* buffer (if they try to, the application will get a * buffer (if they try to, the application will get a
* fault since the file is mapped read-only). * fault since the file is mapped read-only).
*/ */
if ((tif->tif_flags & TIFF_MYBUFFER) && tif->tif_rawdata) if ((tif->tif_flags & TIFF_MYBUFFER) && tif->tif_rawdata) {
_TIFFfree(tif->tif_rawdata); _TIFFfree(tif->tif_rawdata);
tif->tif_rawdata = NULL;
tif->tif_rawdatasize = 0;
}
tif->tif_flags &= ~TIFF_MYBUFFER; tif->tif_flags &= ~TIFF_MYBUFFER;
/* /*
* We must check for overflow, potentially causing * We must check for overflow, potentially causing
@ -831,6 +854,7 @@ TIFFFillTile(TIFF* tif, uint32 tile)
tif->tif_base + (tmsize_t)td->td_stripoffset[tile]; tif->tif_base + (tmsize_t)td->td_stripoffset[tile];
tif->tif_rawdataoff = 0; tif->tif_rawdataoff = 0;
tif->tif_rawdataloaded = (tmsize_t) bytecount; tif->tif_rawdataloaded = (tmsize_t) bytecount;
tif->tif_flags |= TIFF_BUFFERMMAP;
} else { } else {
/* /*
* Expand raw data buffer, if needed, to hold data * Expand raw data buffer, if needed, to hold data
@ -855,6 +879,12 @@ TIFFFillTile(TIFF* tif, uint32 tile)
if (!TIFFReadBufferSetup(tif, 0, bytecountm)) if (!TIFFReadBufferSetup(tif, 0, bytecountm))
return (0); return (0);
} }
if (tif->tif_flags&TIFF_BUFFERMMAP) {
tif->tif_curtile = NOTILE;
if (!TIFFReadBufferSetup(tif, 0, bytecountm))
return (0);
}
if (TIFFReadRawTile1(tif, tile, tif->tif_rawdata, if (TIFFReadRawTile1(tif, tile, tif->tif_rawdata,
bytecountm, module) != bytecountm) bytecountm, module) != bytecountm)
return (0); return (0);
@ -886,10 +916,13 @@ TIFFReadBufferSetup(TIFF* tif, void* bp, tmsize_t size)
static const char module[] = "TIFFReadBufferSetup"; static const char module[] = "TIFFReadBufferSetup";
assert((tif->tif_flags&TIFF_NOREADRAW)==0); assert((tif->tif_flags&TIFF_NOREADRAW)==0);
tif->tif_flags &= ~TIFF_BUFFERMMAP;
if (tif->tif_rawdata) { if (tif->tif_rawdata) {
if (tif->tif_flags & TIFF_MYBUFFER) if (tif->tif_flags & TIFF_MYBUFFER)
_TIFFfree(tif->tif_rawdata); _TIFFfree(tif->tif_rawdata);
tif->tif_rawdata = NULL; tif->tif_rawdata = NULL;
tif->tif_rawdatasize = 0;
} }
if (bp) { if (bp) {
tif->tif_rawdatasize = size; tif->tif_rawdatasize = size;
@ -897,8 +930,11 @@ TIFFReadBufferSetup(TIFF* tif, void* bp, tmsize_t size)
tif->tif_flags &= ~TIFF_MYBUFFER; tif->tif_flags &= ~TIFF_MYBUFFER;
} else { } else {
tif->tif_rawdatasize = (tmsize_t)TIFFroundup_64((uint64)size, 1024); tif->tif_rawdatasize = (tmsize_t)TIFFroundup_64((uint64)size, 1024);
if (tif->tif_rawdatasize==0) if (tif->tif_rawdatasize==0) {
tif->tif_rawdatasize=(tmsize_t)(-1); TIFFErrorExt(tif->tif_clientdata, module,
"Invalid buffer size");
return (0);
}
tif->tif_rawdata = (uint8*) _TIFFmalloc(tif->tif_rawdatasize); tif->tif_rawdata = (uint8*) _TIFFmalloc(tif->tif_rawdatasize);
tif->tif_flags |= TIFF_MYBUFFER; tif->tif_flags |= TIFF_MYBUFFER;
} }
@ -954,10 +990,12 @@ TIFFStartStrip(TIFF* tif, uint32 strip)
static int static int
TIFFStartTile(TIFF* tif, uint32 tile) TIFFStartTile(TIFF* tif, uint32 tile)
{ {
static const char module[] = "TIFFStartTile";
TIFFDirectory *td = &tif->tif_dir; TIFFDirectory *td = &tif->tif_dir;
uint32 howmany32;
if (!_TIFFFillStriles( tif ) || !tif->tif_dir.td_stripbytecount) if (!_TIFFFillStriles( tif ) || !tif->tif_dir.td_stripbytecount)
return 0; return 0;
if ((tif->tif_flags & TIFF_CODERSETUP) == 0) { if ((tif->tif_flags & TIFF_CODERSETUP) == 0) {
if (!(*tif->tif_setupdecode)(tif)) if (!(*tif->tif_setupdecode)(tif))
@ -965,12 +1003,18 @@ TIFFStartTile(TIFF* tif, uint32 tile)
tif->tif_flags |= TIFF_CODERSETUP; tif->tif_flags |= TIFF_CODERSETUP;
} }
tif->tif_curtile = tile; tif->tif_curtile = tile;
tif->tif_row = howmany32=TIFFhowmany_32(td->td_imagewidth, td->td_tilewidth);
(tile % TIFFhowmany_32(td->td_imagewidth, td->td_tilewidth)) * if (howmany32 == 0) {
td->td_tilelength; TIFFErrorExt(tif->tif_clientdata,module,"Zero tiles");
tif->tif_col = return 0;
(tile % TIFFhowmany_32(td->td_imagelength, td->td_tilelength)) * }
td->td_tilewidth; tif->tif_row = (tile % howmany32) * td->td_tilelength;
howmany32=TIFFhowmany_32(td->td_imagelength, td->td_tilelength);
if (howmany32 == 0) {
TIFFErrorExt(tif->tif_clientdata,module,"Zero tiles");
return 0;
}
tif->tif_col = (tile % howmany32) * td->td_tilewidth;
tif->tif_flags &= ~TIFF_BUF4WRITE; tif->tif_flags &= ~TIFF_BUF4WRITE;
if (tif->tif_flags&TIFF_NOREADRAW) if (tif->tif_flags&TIFF_NOREADRAW)
{ {

View File

@ -1,4 +1,4 @@
/* $Id: tif_stream.cxx,v 1.11 2010-12-11 23:12:29 faxguy Exp $ */ /* $Id: tif_stream.cxx,v 1.13 2015-05-28 01:50:22 bfriesen Exp $ */
/* /*
* Copyright (c) 1988-1996 Sam Leffler * Copyright (c) 1988-1996 Sam Leffler
@ -340,12 +340,16 @@ _tiffisCloseProc(thandle_t fd)
static int static int
_tiffDummyMapProc(thandle_t , void** base, toff_t* size ) _tiffDummyMapProc(thandle_t , void** base, toff_t* size )
{ {
(void) base;
(void) size;
return (0); return (0);
} }
static void static void
_tiffDummyUnmapProc(thandle_t , void* base, toff_t size ) _tiffDummyUnmapProc(thandle_t , void* base, toff_t size )
{ {
(void) base;
(void) size;
} }
/* /*
@ -417,9 +421,10 @@ TIFFStreamOpen(const char* name, istream *is)
/* vim: set ts=8 sts=8 sw=8 noet: */ /* vim: set ts=8 sts=8 sw=8 noet: */
/* /*
Local Variables: * Local Variables:
mode: c * mode: c
indent-tabs-mode: true * c-basic-offset: 8
c-basic-offset: 8 * fill-column: 78
End: * End:
*/ */

View File

@ -1,4 +1,4 @@
/* $Id: tif_strip.c,v 1.34 2011-04-02 20:54:09 bfriesen Exp $ */ /* $Id: tif_strip.c,v 1.36 2015-06-07 22:35:40 bfriesen Exp $ */
/* /*
* Copyright (c) 1991-1997 Sam Leffler * Copyright (c) 1991-1997 Sam Leffler
@ -107,11 +107,13 @@ TIFFVStripSize64(TIFF* tif, uint32 nrows)
} }
TIFFGetFieldDefaulted(tif,TIFFTAG_YCBCRSUBSAMPLING,ycbcrsubsampling+0, TIFFGetFieldDefaulted(tif,TIFFTAG_YCBCRSUBSAMPLING,ycbcrsubsampling+0,
ycbcrsubsampling+1); ycbcrsubsampling+1);
if (((ycbcrsubsampling[0]!=1)&&(ycbcrsubsampling[0]!=2)&&(ycbcrsubsampling[0]!=4)) || if ((ycbcrsubsampling[0] != 1 && ycbcrsubsampling[0] != 2 && ycbcrsubsampling[0] != 4)
((ycbcrsubsampling[1]!=1)&&(ycbcrsubsampling[1]!=2)&&(ycbcrsubsampling[1]!=4))) ||(ycbcrsubsampling[1] != 1 && ycbcrsubsampling[1] != 2 && ycbcrsubsampling[1] != 4))
{ {
TIFFErrorExt(tif->tif_clientdata,module, TIFFErrorExt(tif->tif_clientdata,module,
"Invalid YCbCr subsampling"); "Invalid YCbCr subsampling (%dx%d)",
ycbcrsubsampling[0],
ycbcrsubsampling[1] );
return 0; return 0;
} }
samplingblock_samples=ycbcrsubsampling[0]*ycbcrsubsampling[1]+2; samplingblock_samples=ycbcrsubsampling[0]*ycbcrsubsampling[1]+2;
@ -315,7 +317,14 @@ TIFFScanlineSize64(TIFF* tif)
} }
} }
else else
{
scanline_size=TIFFhowmany_64(_TIFFMultiply64(tif,td->td_imagewidth,td->td_bitspersample,module),8); scanline_size=TIFFhowmany_64(_TIFFMultiply64(tif,td->td_imagewidth,td->td_bitspersample,module),8);
}
if (scanline_size == 0)
{
TIFFErrorExt(tif->tif_clientdata,module,"Computed scanline size is zero");
return 0;
}
return(scanline_size); return(scanline_size);
} }
tmsize_t tmsize_t
@ -326,8 +335,7 @@ TIFFScanlineSize(TIFF* tif)
tmsize_t n; tmsize_t n;
m=TIFFScanlineSize64(tif); m=TIFFScanlineSize64(tif);
n=(tmsize_t)m; n=(tmsize_t)m;
if ((uint64)n!=m) if ((uint64)n!=m) {
{
TIFFErrorExt(tif->tif_clientdata,module,"Integer arithmetic overflow"); TIFFErrorExt(tif->tif_clientdata,module,"Integer arithmetic overflow");
n=0; n=0;
} }

View File

@ -1,4 +1,4 @@
/* $Id: tif_tile.c,v 1.22 2010-07-01 15:33:28 dron Exp $ */ /* $Id: tif_tile.c,v 1.24 2015-06-07 22:35:40 bfriesen Exp $ */
/* /*
* Copyright (c) 1991-1997 Sam Leffler * Copyright (c) 1991-1997 Sam Leffler
@ -143,17 +143,40 @@ TIFFNumberOfTiles(TIFF* tif)
uint64 uint64
TIFFTileRowSize64(TIFF* tif) TIFFTileRowSize64(TIFF* tif)
{ {
static const char module[] = "TIFFTileRowSize64";
TIFFDirectory *td = &tif->tif_dir; TIFFDirectory *td = &tif->tif_dir;
uint64 rowsize; uint64 rowsize;
uint64 tilerowsize;
if (td->td_tilelength == 0 || td->td_tilewidth == 0) if (td->td_tilelength == 0)
{
TIFFErrorExt(tif->tif_clientdata,module,"Tile length is zero");
return 0;
}
if (td->td_tilewidth == 0)
{
TIFFErrorExt(tif->tif_clientdata,module,"Tile width is zero");
return (0); return (0);
}
rowsize = _TIFFMultiply64(tif, td->td_bitspersample, td->td_tilewidth, rowsize = _TIFFMultiply64(tif, td->td_bitspersample, td->td_tilewidth,
"TIFFTileRowSize"); "TIFFTileRowSize");
if (td->td_planarconfig == PLANARCONFIG_CONTIG) if (td->td_planarconfig == PLANARCONFIG_CONTIG)
{
if (td->td_samplesperpixel == 0)
{
TIFFErrorExt(tif->tif_clientdata,module,"Samples per pixel is zero");
return 0;
}
rowsize = _TIFFMultiply64(tif, rowsize, td->td_samplesperpixel, rowsize = _TIFFMultiply64(tif, rowsize, td->td_samplesperpixel,
"TIFFTileRowSize"); "TIFFTileRowSize");
return (TIFFhowmany8_64(rowsize)); }
tilerowsize=TIFFhowmany8_64(rowsize);
if (tilerowsize == 0)
{
TIFFErrorExt(tif->tif_clientdata,module,"Computed tile row size is zero");
return 0;
}
return (tilerowsize);
} }
tmsize_t tmsize_t
TIFFTileRowSize(TIFF* tif) TIFFTileRowSize(TIFF* tif)
@ -203,12 +226,13 @@ TIFFVTileSize64(TIFF* tif, uint32 nrows)
uint64 samplingrow_size; uint64 samplingrow_size;
TIFFGetFieldDefaulted(tif,TIFFTAG_YCBCRSUBSAMPLING,ycbcrsubsampling+0, TIFFGetFieldDefaulted(tif,TIFFTAG_YCBCRSUBSAMPLING,ycbcrsubsampling+0,
ycbcrsubsampling+1); ycbcrsubsampling+1);
assert((ycbcrsubsampling[0]==1)||(ycbcrsubsampling[0]==2)||(ycbcrsubsampling[0]==4)); if ((ycbcrsubsampling[0] != 1 && ycbcrsubsampling[0] != 2 && ycbcrsubsampling[0] != 4)
assert((ycbcrsubsampling[1]==1)||(ycbcrsubsampling[1]==2)||(ycbcrsubsampling[1]==4)); ||(ycbcrsubsampling[1] != 1 && ycbcrsubsampling[1] != 2 && ycbcrsubsampling[1] != 4))
if (ycbcrsubsampling[0]*ycbcrsubsampling[1]==0)
{ {
TIFFErrorExt(tif->tif_clientdata,module, TIFFErrorExt(tif->tif_clientdata,module,
"Invalid YCbCr subsampling"); "Invalid YCbCr subsampling (%dx%d)",
ycbcrsubsampling[0],
ycbcrsubsampling[1] );
return 0; return 0;
} }
samplingblock_samples=ycbcrsubsampling[0]*ycbcrsubsampling[1]+2; samplingblock_samples=ycbcrsubsampling[0]*ycbcrsubsampling[1]+2;

View File

@ -1,4 +1,4 @@
/* $Id: tif_unix.c,v 1.22 2010-03-10 18:56:49 bfriesen Exp $ */ /* $Id: tif_unix.c,v 1.26 2015-06-16 15:33:17 erouault Exp $ */
/* /*
* Copyright (c) 1988-1997 Sam Leffler * Copyright (c) 1988-1997 Sam Leffler
@ -55,53 +55,69 @@
#include "tiffiop.h" #include "tiffiop.h"
typedef union fd_as_handle_union
{
int fd;
thandle_t h;
} fd_as_handle_union_t;
static tmsize_t static tmsize_t
_tiffReadProc(thandle_t fd, void* buf, tmsize_t size) _tiffReadProc(thandle_t fd, void* buf, tmsize_t size)
{ {
fd_as_handle_union_t fdh;
size_t size_io = (size_t) size; size_t size_io = (size_t) size;
if ((tmsize_t) size_io != size) if ((tmsize_t) size_io != size)
{ {
errno=EINVAL; errno=EINVAL;
return (tmsize_t) -1; return (tmsize_t) -1;
} }
return ((tmsize_t) read((int) fd, buf, size_io)); fdh.h = fd;
return ((tmsize_t) read(fdh.fd, buf, size_io));
} }
static tmsize_t static tmsize_t
_tiffWriteProc(thandle_t fd, void* buf, tmsize_t size) _tiffWriteProc(thandle_t fd, void* buf, tmsize_t size)
{ {
fd_as_handle_union_t fdh;
size_t size_io = (size_t) size; size_t size_io = (size_t) size;
if ((tmsize_t) size_io != size) if ((tmsize_t) size_io != size)
{ {
errno=EINVAL; errno=EINVAL;
return (tmsize_t) -1; return (tmsize_t) -1;
} }
return ((tmsize_t) write((int) fd, buf, size_io)); fdh.h = fd;
return ((tmsize_t) write(fdh.fd, buf, size_io));
} }
static uint64 static uint64
_tiffSeekProc(thandle_t fd, uint64 off, int whence) _tiffSeekProc(thandle_t fd, uint64 off, int whence)
{ {
fd_as_handle_union_t fdh;
off_t off_io = (off_t) off; off_t off_io = (off_t) off;
if ((uint64) off_io != off) if ((uint64) off_io != off)
{ {
errno=EINVAL; errno=EINVAL;
return (uint64) -1; /* this is really gross */ return (uint64) -1; /* this is really gross */
} }
return((uint64)lseek((int)fd,off_io,whence)); fdh.h = fd;
return((uint64)lseek(fdh.fd,off_io,whence));
} }
static int static int
_tiffCloseProc(thandle_t fd) _tiffCloseProc(thandle_t fd)
{ {
return(close((int)fd)); fd_as_handle_union_t fdh;
fdh.h = fd;
return(close(fdh.fd));
} }
static uint64 static uint64
_tiffSizeProc(thandle_t fd) _tiffSizeProc(thandle_t fd)
{ {
struct stat sb; struct stat sb;
if (fstat((int)fd,&sb)<0) fd_as_handle_union_t fdh;
fdh.h = fd;
if (fstat(fdh.fd,&sb)<0)
return(0); return(0);
else else
return((uint64)sb.st_size); return((uint64)sb.st_size);
@ -116,8 +132,10 @@ _tiffMapProc(thandle_t fd, void** pbase, toff_t* psize)
uint64 size64 = _tiffSizeProc(fd); uint64 size64 = _tiffSizeProc(fd);
tmsize_t sizem = (tmsize_t)size64; tmsize_t sizem = (tmsize_t)size64;
if ((uint64)sizem==size64) { if ((uint64)sizem==size64) {
fd_as_handle_union_t fdh;
fdh.h = fd;
*pbase = (void*) *pbase = (void*)
mmap(0, (size_t)sizem, PROT_READ, MAP_SHARED, (int) fd, 0); mmap(0, (size_t)sizem, PROT_READ, MAP_SHARED, fdh.fd, 0);
if (*pbase != (void*) -1) { if (*pbase != (void*) -1) {
*psize = (tmsize_t)sizem; *psize = (tmsize_t)sizem;
return (1); return (1);
@ -155,8 +173,10 @@ TIFFFdOpen(int fd, const char* name, const char* mode)
{ {
TIFF* tif; TIFF* tif;
fd_as_handle_union_t fdh;
fdh.fd = fd;
tif = TIFFClientOpen(name, mode, tif = TIFFClientOpen(name, mode,
(thandle_t) fd, fdh.h,
_tiffReadProc, _tiffWriteProc, _tiffReadProc, _tiffWriteProc,
_tiffSeekProc, _tiffCloseProc, _tiffSizeProc, _tiffSeekProc, _tiffCloseProc, _tiffSizeProc,
_tiffMapProc, _tiffUnmapProc); _tiffMapProc, _tiffUnmapProc);
@ -186,7 +206,11 @@ TIFFOpen(const char* name, const char* mode)
fd = open(name, m, 0666); fd = open(name, m, 0666);
if (fd < 0) { if (fd < 0) {
TIFFErrorExt(0, module, "%s: Cannot open", name); if (errno > 0 && strerror(errno) != NULL ) {
TIFFErrorExt(0, module, "%s: %s", name, strerror(errno) );
} else {
TIFFErrorExt(0, module, "%s: Cannot open", name);
}
return ((TIFF *)0); return ((TIFF *)0);
} }
@ -253,6 +277,9 @@ TIFFOpenW(const wchar_t* name, const char* mode)
void* void*
_TIFFmalloc(tmsize_t s) _TIFFmalloc(tmsize_t s)
{ {
if (s == 0)
return ((void *) NULL);
return (malloc((size_t) s)); return (malloc((size_t) s));
} }

View File

@ -1,4 +1,4 @@
/* $Id: tif_win32.c,v 1.39 2011-12-22 17:07:57 bfriesen Exp $ */ /* $Id: tif_win32.c,v 1.40 2012-11-18 17:51:52 bfriesen Exp $ */
/* /*
* Copyright (c) 1988-1997 Sam Leffler * Copyright (c) 1988-1997 Sam Leffler
@ -329,6 +329,9 @@ TIFFOpenW(const wchar_t* name, const char* mode)
void* void*
_TIFFmalloc(tmsize_t s) _TIFFmalloc(tmsize_t s)
{ {
if (s == 0)
return ((void *) NULL);
return (malloc((size_t) s)); return (malloc((size_t) s));
} }

View File

@ -1,4 +1,4 @@
/* $Id: tif_write.c,v 1.36 2011-02-18 20:53:04 fwarmerdam Exp $ */ /* $Id: tif_write.c,v 1.42 2015-06-07 23:00:23 bfriesen Exp $ */
/* /*
* Copyright (c) 1988-1997 Sam Leffler * Copyright (c) 1988-1997 Sam Leffler
@ -115,6 +115,10 @@ TIFFWriteScanline(TIFF* tif, void* buf, uint32 row, uint16 sample)
if (strip >= td->td_stripsperimage && imagegrew) if (strip >= td->td_stripsperimage && imagegrew)
td->td_stripsperimage = td->td_stripsperimage =
TIFFhowmany_32(td->td_imagelength,td->td_rowsperstrip); TIFFhowmany_32(td->td_imagelength,td->td_rowsperstrip);
if (td->td_stripsperimage == 0) {
TIFFErrorExt(tif->tif_clientdata, module, "Zero strips per image");
return (-1);
}
tif->tif_row = tif->tif_row =
(strip % td->td_stripsperimage) * td->td_rowsperstrip; (strip % td->td_stripsperimage) * td->td_rowsperstrip;
if ((tif->tif_flags & TIFF_CODERSETUP) == 0) { if ((tif->tif_flags & TIFF_CODERSETUP) == 0) {
@ -220,23 +224,39 @@ TIFFWriteEncodedStrip(TIFF* tif, uint32 strip, void* data, tmsize_t cc)
tif->tif_flags |= TIFF_BUF4WRITE; tif->tif_flags |= TIFF_BUF4WRITE;
tif->tif_curstrip = strip; tif->tif_curstrip = strip;
if (td->td_stripsperimage == 0) {
TIFFErrorExt(tif->tif_clientdata, module, "Zero strips per image");
return ((tmsize_t) -1);
}
tif->tif_row = (strip % td->td_stripsperimage) * td->td_rowsperstrip; tif->tif_row = (strip % td->td_stripsperimage) * td->td_rowsperstrip;
if ((tif->tif_flags & TIFF_CODERSETUP) == 0) { if ((tif->tif_flags & TIFF_CODERSETUP) == 0) {
if (!(*tif->tif_setupencode)(tif)) if (!(*tif->tif_setupencode)(tif))
return ((tmsize_t) -1); return ((tmsize_t) -1);
tif->tif_flags |= TIFF_CODERSETUP; tif->tif_flags |= TIFF_CODERSETUP;
} }
tif->tif_rawcc = 0;
tif->tif_rawcp = tif->tif_rawdata;
if( td->td_stripbytecount[strip] > 0 ) if( td->td_stripbytecount[strip] > 0 )
{ {
/* Make sure that at the first attempt of rewriting the tile, we will have */
/* more bytes available in the output buffer than the previous byte count, */
/* so that TIFFAppendToStrip() will detect the overflow when it is called the first */
/* time if the new compressed tile is bigger than the older one. (GDAL #4771) */
if( tif->tif_rawdatasize <= (tmsize_t)td->td_stripbytecount[strip] )
{
if( !(TIFFWriteBufferSetup(tif, NULL,
(tmsize_t)TIFFroundup_64((uint64)(td->td_stripbytecount[strip] + 1), 1024))) )
return ((tmsize_t)(-1));
}
/* Force TIFFAppendToStrip() to consider placing data at end /* Force TIFFAppendToStrip() to consider placing data at end
of file. */ of file. */
tif->tif_curoff = 0; tif->tif_curoff = 0;
} }
tif->tif_rawcc = 0;
tif->tif_rawcp = tif->tif_rawdata;
tif->tif_flags &= ~TIFF_POSTENCODE; tif->tif_flags &= ~TIFF_POSTENCODE;
sample = (uint16)(strip / td->td_stripsperimage); sample = (uint16)(strip / td->td_stripsperimage);
if (!(*tif->tif_preencode)(tif, sample)) if (!(*tif->tif_preencode)(tif, sample))
@ -300,6 +320,10 @@ TIFFWriteRawStrip(TIFF* tif, uint32 strip, void* data, tmsize_t cc)
return ((tmsize_t) -1); return ((tmsize_t) -1);
} }
tif->tif_curstrip = strip; tif->tif_curstrip = strip;
if (td->td_stripsperimage == 0) {
TIFFErrorExt(tif->tif_clientdata, module,"Zero strips per image");
return ((tmsize_t) -1);
}
tif->tif_row = (strip % td->td_stripsperimage) * td->td_rowsperstrip; tif->tif_row = (strip % td->td_stripsperimage) * td->td_rowsperstrip;
return (TIFFAppendToStrip(tif, strip, (uint8*) data, cc) ? return (TIFFAppendToStrip(tif, strip, (uint8*) data, cc) ?
cc : (tmsize_t) -1); cc : (tmsize_t) -1);
@ -342,6 +366,7 @@ TIFFWriteEncodedTile(TIFF* tif, uint32 tile, void* data, tmsize_t cc)
static const char module[] = "TIFFWriteEncodedTile"; static const char module[] = "TIFFWriteEncodedTile";
TIFFDirectory *td; TIFFDirectory *td;
uint16 sample; uint16 sample;
uint32 howmany32;
if (!WRITECHECKTILES(tif, module)) if (!WRITECHECKTILES(tif, module))
return ((tmsize_t)(-1)); return ((tmsize_t)(-1));
@ -362,24 +387,43 @@ TIFFWriteEncodedTile(TIFF* tif, uint32 tile, void* data, tmsize_t cc)
tif->tif_flags |= TIFF_BUF4WRITE; tif->tif_flags |= TIFF_BUF4WRITE;
tif->tif_curtile = tile; tif->tif_curtile = tile;
tif->tif_rawcc = 0;
tif->tif_rawcp = tif->tif_rawdata;
if( td->td_stripbytecount[tile] > 0 ) if( td->td_stripbytecount[tile] > 0 )
{ {
/* Make sure that at the first attempt of rewriting the tile, we will have */
/* more bytes available in the output buffer than the previous byte count, */
/* so that TIFFAppendToStrip() will detect the overflow when it is called the first */
/* time if the new compressed tile is bigger than the older one. (GDAL #4771) */
if( tif->tif_rawdatasize <= (tmsize_t) td->td_stripbytecount[tile] )
{
if( !(TIFFWriteBufferSetup(tif, NULL,
(tmsize_t)TIFFroundup_64((uint64)(td->td_stripbytecount[tile] + 1), 1024))) )
return ((tmsize_t)(-1));
}
/* Force TIFFAppendToStrip() to consider placing data at end /* Force TIFFAppendToStrip() to consider placing data at end
of file. */ of file. */
tif->tif_curoff = 0; tif->tif_curoff = 0;
} }
tif->tif_rawcc = 0;
tif->tif_rawcp = tif->tif_rawdata;
/* /*
* Compute tiles per row & per column to compute * Compute tiles per row & per column to compute
* current row and column * current row and column
*/ */
tif->tif_row = (tile % TIFFhowmany_32(td->td_imagelength, td->td_tilelength)) howmany32=TIFFhowmany_32(td->td_imagelength, td->td_tilelength);
* td->td_tilelength; if (howmany32 == 0) {
tif->tif_col = (tile % TIFFhowmany_32(td->td_imagewidth, td->td_tilewidth)) TIFFErrorExt(tif->tif_clientdata,module,"Zero tiles");
* td->td_tilewidth; return ((tmsize_t)(-1));
}
tif->tif_row = (tile % howmany32) * td->td_tilelength;
howmany32=TIFFhowmany_32(td->td_imagewidth, td->td_tilewidth);
if (howmany32 == 0) {
TIFFErrorExt(tif->tif_clientdata,module,"Zero tiles");
return ((tmsize_t)(-1));
}
tif->tif_col = (tile % howmany32) * td->td_tilewidth;
if ((tif->tif_flags & TIFF_CODERSETUP) == 0) { if ((tif->tif_flags & TIFF_CODERSETUP) == 0) {
if (!(*tif->tif_setupencode)(tif)) if (!(*tif->tif_setupencode)(tif))

View File

@ -1,4 +1,4 @@
/* $Id: tif_zip.c,v 1.31 2011-01-06 16:00:23 fwarmerdam Exp $ */ /* $Id: tif_zip.c,v 1.33 2014-12-25 18:29:11 erouault Exp $ */
/* /*
* Copyright (c) 1995-1997 Sam Leffler * Copyright (c) 1995-1997 Sam Leffler
@ -36,7 +36,7 @@
* of the library: this code assumes the 1.0 API and also depends on * of the library: this code assumes the 1.0 API and also depends on
* the ability to write the zlib header multiple times (one per strip) * the ability to write the zlib header multiple times (one per strip)
* which was not possible with versions prior to 0.95. Note also that * which was not possible with versions prior to 0.95. Note also that
* older versions of this codec avoided this bug by supressing the header * older versions of this codec avoided this bug by suppressing the header
* entirely. This means that files written with the old library cannot * entirely. This means that files written with the old library cannot
* be read; they should be converted to a different compression scheme * be read; they should be converted to a different compression scheme
* and then reconverted. * and then reconverted.
@ -61,6 +61,8 @@
#error "Antiquated ZLIB software; you must use version 1.0 or later" #error "Antiquated ZLIB software; you must use version 1.0 or later"
#endif #endif
#define SAFE_MSG(sp) ((sp)->stream.msg == NULL ? "" : (sp)->stream.msg)
/* /*
* State block for each open TIFF * State block for each open TIFF
* file using ZIP compression/decompression. * file using ZIP compression/decompression.
@ -106,7 +108,7 @@ ZIPSetupDecode(TIFF* tif)
} }
if (inflateInit(&sp->stream) != Z_OK) { if (inflateInit(&sp->stream) != Z_OK) {
TIFFErrorExt(tif->tif_clientdata, module, "%s", sp->stream.msg); TIFFErrorExt(tif->tif_clientdata, module, "%s", SAFE_MSG(sp));
return (0); return (0);
} else { } else {
sp->state |= ZSTATE_INIT_DECODE; sp->state |= ZSTATE_INIT_DECODE;
@ -174,14 +176,14 @@ ZIPDecode(TIFF* tif, uint8* op, tmsize_t occ, uint16 s)
if (state == Z_DATA_ERROR) { if (state == Z_DATA_ERROR) {
TIFFErrorExt(tif->tif_clientdata, module, TIFFErrorExt(tif->tif_clientdata, module,
"Decoding error at scanline %lu, %s", "Decoding error at scanline %lu, %s",
(unsigned long) tif->tif_row, sp->stream.msg); (unsigned long) tif->tif_row, SAFE_MSG(sp));
if (inflateSync(&sp->stream) != Z_OK) if (inflateSync(&sp->stream) != Z_OK)
return (0); return (0);
continue; continue;
} }
if (state != Z_OK) { if (state != Z_OK) {
TIFFErrorExt(tif->tif_clientdata, module, "ZLib error: %s", TIFFErrorExt(tif->tif_clientdata, module,
sp->stream.msg); "ZLib error: %s", SAFE_MSG(sp));
return (0); return (0);
} }
} while (sp->stream.avail_out > 0); } while (sp->stream.avail_out > 0);
@ -211,7 +213,7 @@ ZIPSetupEncode(TIFF* tif)
} }
if (deflateInit(&sp->stream, sp->zipquality) != Z_OK) { if (deflateInit(&sp->stream, sp->zipquality) != Z_OK) {
TIFFErrorExt(tif->tif_clientdata, module, "%s", sp->stream.msg); TIFFErrorExt(tif->tif_clientdata, module, "%s", SAFE_MSG(sp));
return (0); return (0);
} else { } else {
sp->state |= ZSTATE_INIT_ENCODE; sp->state |= ZSTATE_INIT_ENCODE;
@ -273,8 +275,9 @@ ZIPEncode(TIFF* tif, uint8* bp, tmsize_t cc, uint16 s)
} }
do { do {
if (deflate(&sp->stream, Z_NO_FLUSH) != Z_OK) { if (deflate(&sp->stream, Z_NO_FLUSH) != Z_OK) {
TIFFErrorExt(tif->tif_clientdata, module, "Encoder error: %s", TIFFErrorExt(tif->tif_clientdata, module,
sp->stream.msg); "Encoder error: %s",
SAFE_MSG(sp));
return (0); return (0);
} }
if (sp->stream.avail_out == 0) { if (sp->stream.avail_out == 0) {
@ -313,8 +316,8 @@ ZIPPostEncode(TIFF* tif)
} }
break; break;
default: default:
TIFFErrorExt(tif->tif_clientdata, module, "ZLib error: %s", TIFFErrorExt(tif->tif_clientdata, module,
sp->stream.msg); "ZLib error: %s", SAFE_MSG(sp));
return (0); return (0);
} }
} while (state != Z_STREAM_END); } while (state != Z_STREAM_END);
@ -359,7 +362,7 @@ ZIPVSetField(TIFF* tif, uint32 tag, va_list ap)
if (deflateParams(&sp->stream, if (deflateParams(&sp->stream,
sp->zipquality, Z_DEFAULT_STRATEGY) != Z_OK) { sp->zipquality, Z_DEFAULT_STRATEGY) != Z_OK) {
TIFFErrorExt(tif->tif_clientdata, module, "ZLib error: %s", TIFFErrorExt(tif->tif_clientdata, module, "ZLib error: %s",
sp->stream.msg); SAFE_MSG(sp));
return (0); return (0);
} }
} }

View File

@ -1,4 +1,4 @@
/* $Id: tiff.h,v 1.67 2011-01-24 21:06:32 olivier Exp $ */ /* $Id: tiff.h,v 1.69 2014-04-02 17:23:06 fwarmerdam Exp $ */
/* /*
* Copyright (c) 1988-1997 Sam Leffler * Copyright (c) 1988-1997 Sam Leffler
@ -166,6 +166,8 @@ typedef enum {
#define COMPRESSION_LZW 5 /* Lempel-Ziv & Welch */ #define COMPRESSION_LZW 5 /* Lempel-Ziv & Welch */
#define COMPRESSION_OJPEG 6 /* !6.0 JPEG */ #define COMPRESSION_OJPEG 6 /* !6.0 JPEG */
#define COMPRESSION_JPEG 7 /* %JPEG DCT compression */ #define COMPRESSION_JPEG 7 /* %JPEG DCT compression */
#define COMPRESSION_T85 9 /* !TIFF/FX T.85 JBIG compression */
#define COMPRESSION_T43 10 /* !TIFF/FX T.43 colour by layered JBIG compression */
#define COMPRESSION_NEXT 32766 /* NeXT 2-bit RLE */ #define COMPRESSION_NEXT 32766 /* NeXT 2-bit RLE */
#define COMPRESSION_CCITTRLEW 32771 /* #1 w/ word alignment */ #define COMPRESSION_CCITTRLEW 32771 /* #1 w/ word alignment */
#define COMPRESSION_PACKBITS 32773 /* Macintosh RLE */ #define COMPRESSION_PACKBITS 32773 /* Macintosh RLE */
@ -199,6 +201,7 @@ typedef enum {
#define PHOTOMETRIC_CIELAB 8 /* !1976 CIE L*a*b* */ #define PHOTOMETRIC_CIELAB 8 /* !1976 CIE L*a*b* */
#define PHOTOMETRIC_ICCLAB 9 /* ICC L*a*b* [Adobe TIFF Technote 4] */ #define PHOTOMETRIC_ICCLAB 9 /* ICC L*a*b* [Adobe TIFF Technote 4] */
#define PHOTOMETRIC_ITULAB 10 /* ITU L*a*b* */ #define PHOTOMETRIC_ITULAB 10 /* ITU L*a*b* */
#define PHOTOMETRIC_CFA 32803 /* color filter array */
#define PHOTOMETRIC_LOGL 32844 /* CIE Log2(L) */ #define PHOTOMETRIC_LOGL 32844 /* CIE Log2(L) */
#define PHOTOMETRIC_LOGLUV 32845 /* CIE Log2(L) (u',v') */ #define PHOTOMETRIC_LOGLUV 32845 /* CIE Log2(L) (u',v') */
#define TIFFTAG_THRESHHOLDING 263 /* +thresholding used on data */ #define TIFFTAG_THRESHHOLDING 263 /* +thresholding used on data */
@ -319,6 +322,30 @@ typedef enum {
[Adobe TIFF Technote 3] */ [Adobe TIFF Technote 3] */
#define TIFFTAG_JPEGTABLES 347 /* %JPEG table stream */ #define TIFFTAG_JPEGTABLES 347 /* %JPEG table stream */
#define TIFFTAG_OPIPROXY 351 /* %OPI Proxy [Adobe TIFF technote] */ #define TIFFTAG_OPIPROXY 351 /* %OPI Proxy [Adobe TIFF technote] */
/* Tags 400-435 are from the TIFF/FX spec */
#define TIFFTAG_GLOBALPARAMETERSIFD 400 /* ! */
#define TIFFTAG_PROFILETYPE 401 /* ! */
#define PROFILETYPE_UNSPECIFIED 0 /* ! */
#define PROFILETYPE_G3_FAX 1 /* ! */
#define TIFFTAG_FAXPROFILE 402 /* ! */
#define FAXPROFILE_S 1 /* !TIFF/FX FAX profile S */
#define FAXPROFILE_F 2 /* !TIFF/FX FAX profile F */
#define FAXPROFILE_J 3 /* !TIFF/FX FAX profile J */
#define FAXPROFILE_C 4 /* !TIFF/FX FAX profile C */
#define FAXPROFILE_L 5 /* !TIFF/FX FAX profile L */
#define FAXPROFILE_M 6 /* !TIFF/FX FAX profile LM */
#define TIFFTAG_CODINGMETHODS 403 /* !TIFF/FX coding methods */
#define CODINGMETHODS_T4_1D (1 << 1) /* !T.4 1D */
#define CODINGMETHODS_T4_2D (1 << 2) /* !T.4 2D */
#define CODINGMETHODS_T6 (1 << 3) /* !T.6 */
#define CODINGMETHODS_T85 (1 << 4) /* !T.85 JBIG */
#define CODINGMETHODS_T42 (1 << 5) /* !T.42 JPEG */
#define CODINGMETHODS_T43 (1 << 6) /* !T.43 colour by layered JBIG */
#define TIFFTAG_VERSIONYEAR 404 /* !TIFF/FX version year */
#define TIFFTAG_MODENUMBER 405 /* !TIFF/FX mode number */
#define TIFFTAG_DECODE 433 /* !TIFF/FX decode */
#define TIFFTAG_IMAGEBASECOLOR 434 /* !TIFF/FX image base colour */
#define TIFFTAG_T82OPTIONS 435 /* !TIFF/FX T.82 options */
/* /*
* Tags 512-521 are obsoleted by Technical Note #2 which specifies a * Tags 512-521 are obsoleted by Technical Note #2 which specifies a
* revised JPEG-in-TIFF scheme. * revised JPEG-in-TIFF scheme.
@ -340,6 +367,7 @@ typedef enum {
#define YCBCRPOSITION_CENTERED 1 /* !as in PostScript Level 2 */ #define YCBCRPOSITION_CENTERED 1 /* !as in PostScript Level 2 */
#define YCBCRPOSITION_COSITED 2 /* !as in CCIR 601-1 */ #define YCBCRPOSITION_COSITED 2 /* !as in CCIR 601-1 */
#define TIFFTAG_REFERENCEBLACKWHITE 532 /* !colorimetry info */ #define TIFFTAG_REFERENCEBLACKWHITE 532 /* !colorimetry info */
#define TIFFTAG_STRIPROWCOUNTS 559 /* !TIFF/FX strip row counts */
#define TIFFTAG_XMLPACKET 700 /* %XML packet #define TIFFTAG_XMLPACKET 700 /* %XML packet
[Adobe XMP Specification, [Adobe XMP Specification,
January 2004 */ January 2004 */
@ -375,6 +403,8 @@ typedef enum {
#define TIFFTAG_PIXAR_MATRIX_WORLDTOCAMERA 33306 #define TIFFTAG_PIXAR_MATRIX_WORLDTOCAMERA 33306
/* tag 33405 is a private tag registered to Eastman Kodak */ /* tag 33405 is a private tag registered to Eastman Kodak */
#define TIFFTAG_WRITERSERIALNUMBER 33405 /* device serial number */ #define TIFFTAG_WRITERSERIALNUMBER 33405 /* device serial number */
#define TIFFTAG_CFAREPEATPATTERNDIM 33421 /* dimensions of CFA pattern */
#define TIFFTAG_CFAPATTERN 33422 /* color filter array pattern */
/* tag 33432 is listed in the 6.0 spec w/ unknown ownership */ /* tag 33432 is listed in the 6.0 spec w/ unknown ownership */
#define TIFFTAG_COPYRIGHT 33432 /* copyright string */ #define TIFFTAG_COPYRIGHT 33432 /* copyright string */
/* IPTC TAG from RichTIFF specifications */ /* IPTC TAG from RichTIFF specifications */
@ -406,6 +436,7 @@ typedef enum {
#define TIFFTAG_EXIFIFD 34665 /* Pointer to EXIF private directory */ #define TIFFTAG_EXIFIFD 34665 /* Pointer to EXIF private directory */
/* tag 34750 is a private tag registered to Adobe? */ /* tag 34750 is a private tag registered to Adobe? */
#define TIFFTAG_ICCPROFILE 34675 /* ICC profile data */ #define TIFFTAG_ICCPROFILE 34675 /* ICC profile data */
#define TIFFTAG_IMAGELAYER 34732 /* !TIFF/FX image layer information */
/* tag 34750 is a private tag registered to Pixel Magic */ /* tag 34750 is a private tag registered to Pixel Magic */
#define TIFFTAG_JBIGOPTIONS 34750 /* JBIG options */ #define TIFFTAG_JBIGOPTIONS 34750 /* JBIG options */
#define TIFFTAG_GPSIFD 34853 /* Pointer to GPS private directory */ #define TIFFTAG_GPSIFD 34853 /* Pointer to GPS private directory */

View File

@ -1,4 +1,4 @@
/* $Id: tiffio.h,v 1.89 2012-02-18 16:20:26 bfriesen Exp $ */ /* $Id: tiffio.h,v 1.91 2012-07-29 15:45:29 tgl Exp $ */
/* /*
* Copyright (c) 1988-1997 Sam Leffler * Copyright (c) 1988-1997 Sam Leffler
@ -319,6 +319,13 @@ extern const TIFFField* TIFFFindField(TIFF *, uint32, TIFFDataType);
extern const TIFFField* TIFFFieldWithTag(TIFF*, uint32); extern const TIFFField* TIFFFieldWithTag(TIFF*, uint32);
extern const TIFFField* TIFFFieldWithName(TIFF*, const char *); extern const TIFFField* TIFFFieldWithName(TIFF*, const char *);
extern uint32 TIFFFieldTag(const TIFFField*);
extern const char* TIFFFieldName(const TIFFField*);
extern TIFFDataType TIFFFieldDataType(const TIFFField*);
extern int TIFFFieldPassCount(const TIFFField*);
extern int TIFFFieldReadCount(const TIFFField*);
extern int TIFFFieldWriteCount(const TIFFField*);
typedef int (*TIFFVSetMethod)(TIFF*, uint32, va_list); typedef int (*TIFFVSetMethod)(TIFF*, uint32, va_list);
typedef int (*TIFFVGetMethod)(TIFF*, uint32, va_list); typedef int (*TIFFVGetMethod)(TIFF*, uint32, va_list);
typedef void (*TIFFPrintMethod)(TIFF*, FILE*, long); typedef void (*TIFFPrintMethod)(TIFF*, FILE*, long);
@ -392,6 +399,8 @@ extern int TIFFSetupStrips(TIFF *);
extern int TIFFWriteCheck(TIFF*, int, const char *); extern int TIFFWriteCheck(TIFF*, int, const char *);
extern void TIFFFreeDirectory(TIFF*); extern void TIFFFreeDirectory(TIFF*);
extern int TIFFCreateDirectory(TIFF*); extern int TIFFCreateDirectory(TIFF*);
extern int TIFFCreateCustomDirectory(TIFF*,const TIFFFieldArray*);
extern int TIFFCreateEXIFDirectory(TIFF*);
extern int TIFFLastDirectory(TIFF*); extern int TIFFLastDirectory(TIFF*);
extern int TIFFSetDirectory(TIFF*, uint16); extern int TIFFSetDirectory(TIFF*, uint16);
extern int TIFFSetSubDirectory(TIFF*, uint64); extern int TIFFSetSubDirectory(TIFF*, uint64);
@ -400,6 +409,7 @@ extern int TIFFSetField(TIFF*, uint32, ...);
extern int TIFFVSetField(TIFF*, uint32, va_list); extern int TIFFVSetField(TIFF*, uint32, va_list);
extern int TIFFUnsetField(TIFF*, uint32); extern int TIFFUnsetField(TIFF*, uint32);
extern int TIFFWriteDirectory(TIFF *); extern int TIFFWriteDirectory(TIFF *);
extern int TIFFWriteCustomDirectory(TIFF *, uint64 *);
extern int TIFFCheckpointDirectory(TIFF *); extern int TIFFCheckpointDirectory(TIFF *);
extern int TIFFRewriteDirectory(TIFF *); extern int TIFFRewriteDirectory(TIFF *);

View File

@ -1,4 +1,4 @@
/* $Id: tiffiop.h,v 1.82 2011-02-18 20:53:05 fwarmerdam Exp $ */ /* $Id: tiffiop.h,v 1.84 2012-05-30 01:50:17 fwarmerdam Exp $ */
/* /*
* Copyright (c) 1988-1997 Sam Leffler * Copyright (c) 1988-1997 Sam Leffler
@ -121,6 +121,7 @@ struct tiff {
#define TIFF_BUF4WRITE 0x100000 /* rawcc bytes are for writing */ #define TIFF_BUF4WRITE 0x100000 /* rawcc bytes are for writing */
#define TIFF_DIRTYSTRIP 0x200000 /* stripoffsets/stripbytecount dirty*/ #define TIFF_DIRTYSTRIP 0x200000 /* stripoffsets/stripbytecount dirty*/
#define TIFF_PERSAMPLE 0x400000 /* get/set per sample tags as arrays */ #define TIFF_PERSAMPLE 0x400000 /* get/set per sample tags as arrays */
#define TIFF_BUFFERMMAP 0x800000 /* read buffer (tif_rawdata) points into mmap() memory */
uint64 tif_diroff; /* file offset of current directory */ uint64 tif_diroff; /* file offset of current directory */
uint64 tif_nextdiroff; /* file offset of following directory */ uint64 tif_nextdiroff; /* file offset of following directory */
uint64* tif_dirlist; /* list of offsets to already seen directories to prevent IFD looping */ uint64* tif_dirlist; /* list of offsets to already seen directories to prevent IFD looping */
@ -250,7 +251,7 @@ struct tiff {
#define TIFFroundup_64(x, y) (TIFFhowmany_64(x,y)*(y)) #define TIFFroundup_64(x, y) (TIFFhowmany_64(x,y)*(y))
/* Safe multiply which returns zero if there is an integer overflow */ /* Safe multiply which returns zero if there is an integer overflow */
#define TIFFSafeMultiply(t,v,m) ((((t)m != (t)0) && (((t)((v*m)/m)) == (t)v)) ? (t)(v*m) : (t)0) #define TIFFSafeMultiply(t,v,m) ((((t)(m) != (t)0) && (((t)(((v)*(m))/(m))) == (t)(v))) ? (t)((v)*(m)) : (t)0)
#define TIFFmax(A,B) ((A)>(B)?(A):(B)) #define TIFFmax(A,B) ((A)>(B)?(A):(B))
#define TIFFmin(A,B) ((A)<(B)?(A):(B)) #define TIFFmin(A,B) ((A)<(B)?(A):(B))

View File

@ -1,4 +1,4 @@
#define TIFFLIB_VERSION_STR "LIBTIFF, Version 4.0.1\nCopyright (c) 1988-1996 Sam Leffler\nCopyright (c) 1991-1996 Silicon Graphics, Inc." #define TIFFLIB_VERSION_STR "LIBTIFF, Version 4.0.4\nCopyright (c) 1988-1996 Sam Leffler\nCopyright (c) 1991-1996 Silicon Graphics, Inc."
/* /*
* This define can be used in code that requires * This define can be used in code that requires
* compilation-related definitions specific to a * compilation-related definitions specific to a
@ -6,4 +6,4 @@
* version checking should be done based on the * version checking should be done based on the
* string returned by TIFFGetVersion. * string returned by TIFFGetVersion.
*/ */
#define TIFFLIB_VERSION 20120218 #define TIFFLIB_VERSION 20150621