[LIBTIFF]

- Update to version 4.0.8
CORE-13451

svn path=/trunk/; revision=75101
This commit is contained in:
Thomas Faber 2017-06-18 17:50:12 +00:00
parent 7e43425f53
commit a916000ce2
25 changed files with 863 additions and 234 deletions

View file

@ -1,4 +1,4 @@
/* $Id: tif_color.c,v 1.22 2016-09-04 21:32:56 erouault Exp $ */ /* $Id: tif_color.c,v 1.23 2017-05-13 18:17:34 erouault Exp $ */
/* /*
* Copyright (c) 1988-1997 Sam Leffler * Copyright (c) 1988-1997 Sam Leffler
@ -199,6 +199,23 @@ TIFFYCbCrtoRGB(TIFFYCbCrToRGB *ycbcr, uint32 Y, int32 Cb, int32 Cr,
*b = CLAMP(i, 0, 255); *b = CLAMP(i, 0, 255);
} }
/* Clamp function for sanitization purposes. Normally clamping should not */
/* occur for well behaved chroma and refBlackWhite coefficients */
static float CLAMPw(float v, float vmin, float vmax)
{
if( v < vmin )
{
/* printf("%f clamped to %f\n", v, vmin); */
return vmin;
}
if( v > vmax )
{
/* printf("%f clamped to %f\n", v, vmax); */
return vmax;
}
return v;
}
/* /*
* Initialize the YCbCr->RGB conversion tables. The conversion * Initialize the YCbCr->RGB conversion tables. The conversion
* is done according to the 6.0 spec: * is done according to the 6.0 spec:
@ -238,10 +255,10 @@ TIFFYCbCrToRGBInit(TIFFYCbCrToRGB* ycbcr, float *luma, float *refBlackWhite)
ycbcr->Cb_g_tab = ycbcr->Cr_g_tab + 256; ycbcr->Cb_g_tab = ycbcr->Cr_g_tab + 256;
ycbcr->Y_tab = ycbcr->Cb_g_tab + 256; ycbcr->Y_tab = ycbcr->Cb_g_tab + 256;
{ float f1 = 2-2*LumaRed; int32 D1 = FIX(f1); { float f1 = 2-2*LumaRed; int32 D1 = FIX(CLAMP(f1,0.0F,2.0F));
float f2 = LumaRed*f1/LumaGreen; int32 D2 = -FIX(f2); float f2 = LumaRed*f1/LumaGreen; int32 D2 = -FIX(CLAMP(f2,0.0F,2.0F));
float f3 = 2-2*LumaBlue; int32 D3 = FIX(f3); float f3 = 2-2*LumaBlue; int32 D3 = FIX(CLAMP(f3,0.0F,2.0F));
float f4 = LumaBlue*f3/LumaGreen; int32 D4 = -FIX(f4); float f4 = LumaBlue*f3/LumaGreen; int32 D4 = -FIX(CLAMP(f4,0.0F,2.0F));
int x; int x;
#undef LumaBlue #undef LumaBlue
@ -256,17 +273,20 @@ TIFFYCbCrToRGBInit(TIFFYCbCrToRGB* ycbcr, float *luma, float *refBlackWhite)
* constructing tables indexed by the raw pixel data. * constructing tables indexed by the raw pixel data.
*/ */
for (i = 0, x = -128; i < 256; i++, x++) { for (i = 0, x = -128; i < 256; i++, x++) {
int32 Cr = (int32)Code2V(x, refBlackWhite[4] - 128.0F, int32 Cr = (int32)CLAMPw(Code2V(x, refBlackWhite[4] - 128.0F,
refBlackWhite[5] - 128.0F, 127); refBlackWhite[5] - 128.0F, 127),
int32 Cb = (int32)Code2V(x, refBlackWhite[2] - 128.0F, -128.0F * 64, 128.0F * 64);
refBlackWhite[3] - 128.0F, 127); int32 Cb = (int32)CLAMPw(Code2V(x, refBlackWhite[2] - 128.0F,
refBlackWhite[3] - 128.0F, 127),
-128.0F * 64, 128.0F * 64);
ycbcr->Cr_r_tab[i] = (int32)((D1*Cr + ONE_HALF)>>SHIFT); ycbcr->Cr_r_tab[i] = (int32)((D1*Cr + ONE_HALF)>>SHIFT);
ycbcr->Cb_b_tab[i] = (int32)((D3*Cb + ONE_HALF)>>SHIFT); ycbcr->Cb_b_tab[i] = (int32)((D3*Cb + ONE_HALF)>>SHIFT);
ycbcr->Cr_g_tab[i] = D2*Cr; ycbcr->Cr_g_tab[i] = D2*Cr;
ycbcr->Cb_g_tab[i] = D4*Cb + ONE_HALF; ycbcr->Cb_g_tab[i] = D4*Cb + ONE_HALF;
ycbcr->Y_tab[i] = ycbcr->Y_tab[i] =
(int32)Code2V(x + 128, refBlackWhite[0], refBlackWhite[1], 255); (int32)CLAMPw(Code2V(x + 128, refBlackWhite[0], refBlackWhite[1], 255),
-128.0F * 64, 128.0F * 64);
} }
} }

View file

@ -1,4 +1,4 @@
/* $Id: tif_dir.c,v 1.127 2016-10-25 21:35:15 erouault Exp $ */ /* $Id: tif_dir.c,v 1.130 2017-05-17 21:54:05 erouault Exp $ */
/* /*
* Copyright (c) 1988-1997 Sam Leffler * Copyright (c) 1988-1997 Sam Leffler
@ -32,6 +32,7 @@
*/ */
#include <precomp.h> #include <precomp.h>
#include <float.h>
/* /*
* These are used in the backwards compatibility code... * These are used in the backwards compatibility code...
@ -155,6 +156,15 @@ bad:
return (0); return (0);
} }
static float TIFFClampDoubleToFloat( double val )
{
if( val > FLT_MAX )
return FLT_MAX;
if( val < -FLT_MAX )
return -FLT_MAX;
return (float)val;
}
static int static int
_TIFFVSetField(TIFF* tif, uint32 tag, va_list ap) _TIFFVSetField(TIFF* tif, uint32 tag, va_list ap)
{ {
@ -313,13 +323,13 @@ _TIFFVSetField(TIFF* tif, uint32 tag, va_list ap)
dblval = va_arg(ap, double); dblval = va_arg(ap, double);
if( dblval < 0 ) if( dblval < 0 )
goto badvaluedouble; goto badvaluedouble;
td->td_xresolution = (float) dblval; td->td_xresolution = TIFFClampDoubleToFloat( dblval );
break; break;
case TIFFTAG_YRESOLUTION: case TIFFTAG_YRESOLUTION:
dblval = va_arg(ap, double); dblval = va_arg(ap, double);
if( dblval < 0 ) if( dblval < 0 )
goto badvaluedouble; goto badvaluedouble;
td->td_yresolution = (float) dblval; td->td_yresolution = TIFFClampDoubleToFloat( dblval );
break; break;
case TIFFTAG_PLANARCONFIG: case TIFFTAG_PLANARCONFIG:
v = (uint16) va_arg(ap, uint16_vap); v = (uint16) va_arg(ap, uint16_vap);
@ -328,10 +338,10 @@ _TIFFVSetField(TIFF* tif, uint32 tag, va_list ap)
td->td_planarconfig = (uint16) v; td->td_planarconfig = (uint16) v;
break; break;
case TIFFTAG_XPOSITION: case TIFFTAG_XPOSITION:
td->td_xposition = (float) va_arg(ap, double); td->td_xposition = TIFFClampDoubleToFloat( va_arg(ap, double) );
break; break;
case TIFFTAG_YPOSITION: case TIFFTAG_YPOSITION:
td->td_yposition = (float) va_arg(ap, double); td->td_yposition = TIFFClampDoubleToFloat( va_arg(ap, double) );
break; break;
case TIFFTAG_RESOLUTIONUNIT: case TIFFTAG_RESOLUTIONUNIT:
v = (uint16) va_arg(ap, uint16_vap); v = (uint16) va_arg(ap, uint16_vap);
@ -677,7 +687,7 @@ _TIFFVSetField(TIFF* tif, uint32 tag, va_list ap)
case TIFF_SRATIONAL: case TIFF_SRATIONAL:
case TIFF_FLOAT: case TIFF_FLOAT:
{ {
float v2 = (float)va_arg(ap, double); float v2 = TIFFClampDoubleToFloat(va_arg(ap, double));
_TIFFmemcpy(val, &v2, tv_size); _TIFFmemcpy(val, &v2, tv_size);
} }
break; break;
@ -855,6 +865,32 @@ _TIFFVGetField(TIFF* tif, uint32 tag, va_list ap)
if( fip == NULL ) /* cannot happen since TIFFGetField() already checks it */ if( fip == NULL ) /* cannot happen since TIFFGetField() already checks it */
return 0; return 0;
if( tag == TIFFTAG_NUMBEROFINKS )
{
int i;
for (i = 0; i < td->td_customValueCount; i++) {
uint16 val;
TIFFTagValue *tv = td->td_customValues + i;
if (tv->info->field_tag != tag)
continue;
val = *(uint16 *)tv->value;
/* Truncate to SamplesPerPixel, since the */
/* setting code for INKNAMES assume that there are SamplesPerPixel */
/* inknames. */
/* Fixes http://bugzilla.maptools.org/show_bug.cgi?id=2599 */
if( val > td->td_samplesperpixel )
{
TIFFWarningExt(tif->tif_clientdata,"_TIFFVGetField",
"Truncating NumberOfInks from %u to %u",
val, td->td_samplesperpixel);
val = td->td_samplesperpixel;
}
*va_arg(ap, uint16*) = val;
return 1;
}
return 0;
}
/* /*
* We want to force the custom code to be used for custom * We want to force the custom code to be used for custom
* fields even if the tag happens to match a well known * fields even if the tag happens to match a well known

View file

@ -1,4 +1,4 @@
/* $Id: tif_dirread.c,v 1.204 2016-11-16 15:14:15 erouault Exp $ */ /* $Id: tif_dirread.c,v 1.208 2017-04-27 15:46:22 erouault Exp $ */
/* /*
* Copyright (c) 1988-1997 Sam Leffler * Copyright (c) 1988-1997 Sam Leffler
@ -40,6 +40,7 @@
*/ */
#include <precomp.h> #include <precomp.h>
#include <float.h>
#define IGNORE 0 /* tag placeholder used below */ #define IGNORE 0 /* tag placeholder used below */
#define FAILED_FII ((uint32) -1) #define FAILED_FII ((uint32) -1)
@ -2406,7 +2407,14 @@ static enum TIFFReadDirEntryErr TIFFReadDirEntryFloatArray(TIFF* tif, TIFFDirEnt
ma=(double*)origdata; ma=(double*)origdata;
mb=data; mb=data;
for (n=0; n<count; n++) for (n=0; n<count; n++)
*mb++=(float)(*ma++); {
double val = *ma++;
if( val > FLT_MAX )
val = FLT_MAX;
else if( val < -FLT_MAX )
val = -FLT_MAX;
*mb++=(float)val;
}
} }
break; break;
} }
@ -2872,7 +2880,10 @@ static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckedRational(TIFF* tif, TIFFD
m.l = direntry->tdir_offset.toff_long8; m.l = direntry->tdir_offset.toff_long8;
if (tif->tif_flags&TIFF_SWAB) if (tif->tif_flags&TIFF_SWAB)
TIFFSwabArrayOfLong(m.i,2); TIFFSwabArrayOfLong(m.i,2);
if (m.i[0]==0) /* Not completely sure what we should do when m.i[1]==0, but some */
/* sanitizers do not like division by 0.0: */
/* http://bugzilla.maptools.org/show_bug.cgi?id=2644 */
if (m.i[0]==0 || m.i[1]==0)
*value=0.0; *value=0.0;
else else
*value=(double)m.i[0]/(double)m.i[1]; *value=(double)m.i[0]/(double)m.i[1];
@ -2900,7 +2911,10 @@ static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckedSrational(TIFF* tif, TIFF
m.l=direntry->tdir_offset.toff_long8; m.l=direntry->tdir_offset.toff_long8;
if (tif->tif_flags&TIFF_SWAB) if (tif->tif_flags&TIFF_SWAB)
TIFFSwabArrayOfLong(m.i,2); TIFFSwabArrayOfLong(m.i,2);
if ((int32)m.i[0]==0) /* Not completely sure what we should do when m.i[1]==0, but some */
/* sanitizers do not like division by 0.0: */
/* http://bugzilla.maptools.org/show_bug.cgi?id=2644 */
if ((int32)m.i[0]==0 || m.i[1]==0)
*value=0.0; *value=0.0;
else else
*value=(double)((int32)m.i[0])/(double)m.i[1]; *value=(double)((int32)m.i[0])/(double)m.i[1];
@ -3724,6 +3738,14 @@ TIFFReadDirectory(TIFF* tif)
_TIFFmemcpy( &(tif->tif_dir.td_stripoffset_entry), _TIFFmemcpy( &(tif->tif_dir.td_stripoffset_entry),
dp, sizeof(TIFFDirEntry) ); dp, sizeof(TIFFDirEntry) );
#else #else
if( tif->tif_dir.td_stripoffset != NULL )
{
TIFFErrorExt(tif->tif_clientdata, module,
"tif->tif_dir.td_stripoffset is "
"already allocated. Likely duplicated "
"StripOffsets/TileOffsets tag");
goto bad;
}
if (!TIFFFetchStripThing(tif,dp,tif->tif_dir.td_nstrips,&tif->tif_dir.td_stripoffset)) if (!TIFFFetchStripThing(tif,dp,tif->tif_dir.td_nstrips,&tif->tif_dir.td_stripoffset))
goto bad; goto bad;
#endif #endif
@ -3734,6 +3756,14 @@ TIFFReadDirectory(TIFF* tif)
_TIFFmemcpy( &(tif->tif_dir.td_stripbytecount_entry), _TIFFmemcpy( &(tif->tif_dir.td_stripbytecount_entry),
dp, sizeof(TIFFDirEntry) ); dp, sizeof(TIFFDirEntry) );
#else #else
if( tif->tif_dir.td_stripbytecount != NULL )
{
TIFFErrorExt(tif->tif_clientdata, module,
"tif->tif_dir.td_stripbytecount is "
"already allocated. Likely duplicated "
"StripByteCounts/TileByteCounts tag");
goto bad;
}
if (!TIFFFetchStripThing(tif,dp,tif->tif_dir.td_nstrips,&tif->tif_dir.td_stripbytecount)) if (!TIFFFetchStripThing(tif,dp,tif->tif_dir.td_nstrips,&tif->tif_dir.td_stripbytecount))
goto bad; goto bad;
#endif #endif
@ -5502,8 +5532,7 @@ ChopUpSingleUncompressedStrip(TIFF* tif)
uint64 rowblockbytes; uint64 rowblockbytes;
uint64 stripbytes; uint64 stripbytes;
uint32 strip; uint32 strip;
uint64 nstrips64; uint32 nstrips;
uint32 nstrips32;
uint32 rowsperstrip; uint32 rowsperstrip;
uint64* newcounts; uint64* newcounts;
uint64* newoffsets; uint64* newoffsets;
@ -5534,18 +5563,17 @@ ChopUpSingleUncompressedStrip(TIFF* tif)
return; return;
/* /*
* never increase the number of strips in an image * never increase the number of rows per strip
*/ */
if (rowsperstrip >= td->td_rowsperstrip) if (rowsperstrip >= td->td_rowsperstrip)
return; return;
nstrips64 = TIFFhowmany_64(bytecount, stripbytes); nstrips = TIFFhowmany_32(td->td_imagelength, rowsperstrip);
if ((nstrips64==0)||(nstrips64>0xFFFFFFFF)) /* something is wonky, do nothing. */ if( nstrips == 0 )
return; return;
nstrips32 = (uint32)nstrips64;
newcounts = (uint64*) _TIFFCheckMalloc(tif, nstrips32, sizeof (uint64), newcounts = (uint64*) _TIFFCheckMalloc(tif, nstrips, sizeof (uint64),
"for chopped \"StripByteCounts\" array"); "for chopped \"StripByteCounts\" array");
newoffsets = (uint64*) _TIFFCheckMalloc(tif, nstrips32, sizeof (uint64), newoffsets = (uint64*) _TIFFCheckMalloc(tif, nstrips, sizeof (uint64),
"for chopped \"StripOffsets\" array"); "for chopped \"StripOffsets\" array");
if (newcounts == NULL || newoffsets == NULL) { if (newcounts == NULL || newoffsets == NULL) {
/* /*
@ -5562,18 +5590,18 @@ ChopUpSingleUncompressedStrip(TIFF* tif)
* Fill the strip information arrays with new bytecounts and offsets * Fill the strip information arrays with new bytecounts and offsets
* that reflect the broken-up format. * that reflect the broken-up format.
*/ */
for (strip = 0; strip < nstrips32; strip++) { for (strip = 0; strip < nstrips; strip++) {
if (stripbytes > bytecount) if (stripbytes > bytecount)
stripbytes = bytecount; stripbytes = bytecount;
newcounts[strip] = stripbytes; newcounts[strip] = stripbytes;
newoffsets[strip] = offset; newoffsets[strip] = stripbytes ? offset : 0;
offset += stripbytes; offset += stripbytes;
bytecount -= stripbytes; bytecount -= stripbytes;
} }
/* /*
* Replace old single strip info with multi-strip info. * Replace old single strip info with multi-strip info.
*/ */
td->td_stripsperimage = td->td_nstrips = nstrips32; td->td_stripsperimage = td->td_nstrips = nstrips;
TIFFSetField(tif, TIFFTAG_ROWSPERSTRIP, rowsperstrip); TIFFSetField(tif, TIFFTAG_ROWSPERSTRIP, rowsperstrip);
_TIFFfree(td->td_stripbytecount); _TIFFfree(td->td_stripbytecount);

View file

@ -1,4 +1,4 @@
/* $Id: tif_dirwrite.c,v 1.83 2016-10-25 21:35:15 erouault Exp $ */ /* $Id: tif_dirwrite.c,v 1.85 2017-01-11 16:09:02 erouault Exp $ */
/* /*
* Copyright (c) 1988-1997 Sam Leffler * Copyright (c) 1988-1997 Sam Leffler
@ -31,6 +31,7 @@
*/ */
#include <precomp.h> #include <precomp.h>
#include <float.h>
#ifdef HAVE_IEEEFP #ifdef HAVE_IEEEFP
#define TIFFCvtNativeToIEEEFloat(tif, n, fp) #define TIFFCvtNativeToIEEEFloat(tif, n, fp)
@ -940,6 +941,69 @@ bad:
return(0); return(0);
} }
static float TIFFClampDoubleToFloat( double val )
{
if( val > FLT_MAX )
return FLT_MAX;
if( val < -FLT_MAX )
return -FLT_MAX;
return (float)val;
}
static int8 TIFFClampDoubleToInt8( double val )
{
if( val > 127 )
return 127;
if( val < -128 || val != val )
return -128;
return (int8)val;
}
static int16 TIFFClampDoubleToInt16( double val )
{
if( val > 32767 )
return 32767;
if( val < -32768 || val != val )
return -32768;
return (int16)val;
}
static int32 TIFFClampDoubleToInt32( double val )
{
if( val > 0x7FFFFFFF )
return 0x7FFFFFFF;
if( val < -0x7FFFFFFF-1 || val != val )
return -0x7FFFFFFF-1;
return (int32)val;
}
static uint8 TIFFClampDoubleToUInt8( double val )
{
if( val < 0 )
return 0;
if( val > 255 || val != val )
return 255;
return (uint8)val;
}
static uint16 TIFFClampDoubleToUInt16( double val )
{
if( val < 0 )
return 0;
if( val > 65535 || val != val )
return 65535;
return (uint16)val;
}
static uint32 TIFFClampDoubleToUInt32( double val )
{
if( val < 0 )
return 0;
if( val > 0xFFFFFFFFU || val != val )
return 0xFFFFFFFFU;
return (uint32)val;
}
static int static int
TIFFWriteDirectoryTagSampleformatArray(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, double* value) TIFFWriteDirectoryTagSampleformatArray(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, double* value)
{ {
@ -960,7 +1024,7 @@ TIFFWriteDirectoryTagSampleformatArray(TIFF* tif, uint32* ndir, TIFFDirEntry* di
if (tif->tif_dir.td_bitspersample<=32) if (tif->tif_dir.td_bitspersample<=32)
{ {
for (i = 0; i < count; ++i) for (i = 0; i < count; ++i)
((float*)conv)[i] = (float)value[i]; ((float*)conv)[i] = TIFFClampDoubleToFloat(value[i]);
ok = TIFFWriteDirectoryTagFloatArray(tif,ndir,dir,tag,count,(float*)conv); ok = TIFFWriteDirectoryTagFloatArray(tif,ndir,dir,tag,count,(float*)conv);
} }
else else
@ -972,19 +1036,19 @@ TIFFWriteDirectoryTagSampleformatArray(TIFF* tif, uint32* ndir, TIFFDirEntry* di
if (tif->tif_dir.td_bitspersample<=8) if (tif->tif_dir.td_bitspersample<=8)
{ {
for (i = 0; i < count; ++i) for (i = 0; i < count; ++i)
((int8*)conv)[i] = (int8)value[i]; ((int8*)conv)[i] = TIFFClampDoubleToInt8(value[i]);
ok = TIFFWriteDirectoryTagSbyteArray(tif,ndir,dir,tag,count,(int8*)conv); ok = TIFFWriteDirectoryTagSbyteArray(tif,ndir,dir,tag,count,(int8*)conv);
} }
else if (tif->tif_dir.td_bitspersample<=16) else if (tif->tif_dir.td_bitspersample<=16)
{ {
for (i = 0; i < count; ++i) for (i = 0; i < count; ++i)
((int16*)conv)[i] = (int16)value[i]; ((int16*)conv)[i] = TIFFClampDoubleToInt16(value[i]);
ok = TIFFWriteDirectoryTagSshortArray(tif,ndir,dir,tag,count,(int16*)conv); ok = TIFFWriteDirectoryTagSshortArray(tif,ndir,dir,tag,count,(int16*)conv);
} }
else else
{ {
for (i = 0; i < count; ++i) for (i = 0; i < count; ++i)
((int32*)conv)[i] = (int32)value[i]; ((int32*)conv)[i] = TIFFClampDoubleToInt32(value[i]);
ok = TIFFWriteDirectoryTagSlongArray(tif,ndir,dir,tag,count,(int32*)conv); ok = TIFFWriteDirectoryTagSlongArray(tif,ndir,dir,tag,count,(int32*)conv);
} }
break; break;
@ -992,19 +1056,19 @@ TIFFWriteDirectoryTagSampleformatArray(TIFF* tif, uint32* ndir, TIFFDirEntry* di
if (tif->tif_dir.td_bitspersample<=8) if (tif->tif_dir.td_bitspersample<=8)
{ {
for (i = 0; i < count; ++i) for (i = 0; i < count; ++i)
((uint8*)conv)[i] = (uint8)value[i]; ((uint8*)conv)[i] = TIFFClampDoubleToUInt8(value[i]);
ok = TIFFWriteDirectoryTagByteArray(tif,ndir,dir,tag,count,(uint8*)conv); ok = TIFFWriteDirectoryTagByteArray(tif,ndir,dir,tag,count,(uint8*)conv);
} }
else if (tif->tif_dir.td_bitspersample<=16) else if (tif->tif_dir.td_bitspersample<=16)
{ {
for (i = 0; i < count; ++i) for (i = 0; i < count; ++i)
((uint16*)conv)[i] = (uint16)value[i]; ((uint16*)conv)[i] = TIFFClampDoubleToUInt16(value[i]);
ok = TIFFWriteDirectoryTagShortArray(tif,ndir,dir,tag,count,(uint16*)conv); ok = TIFFWriteDirectoryTagShortArray(tif,ndir,dir,tag,count,(uint16*)conv);
} }
else else
{ {
for (i = 0; i < count; ++i) for (i = 0; i < count; ++i)
((uint32*)conv)[i] = (uint32)value[i]; ((uint32*)conv)[i] = TIFFClampDoubleToUInt32(value[i]);
ok = TIFFWriteDirectoryTagLongArray(tif,ndir,dir,tag,count,(uint32*)conv); ok = TIFFWriteDirectoryTagLongArray(tif,ndir,dir,tag,count,(uint32*)conv);
} }
break; break;
@ -2095,15 +2159,25 @@ TIFFWriteDirectoryTagCheckedSlong8Array(TIFF* tif, uint32* ndir, TIFFDirEntry* d
static int static int
TIFFWriteDirectoryTagCheckedRational(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, double value) TIFFWriteDirectoryTagCheckedRational(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, double value)
{ {
static const char module[] = "TIFFWriteDirectoryTagCheckedRational";
uint32 m[2]; uint32 m[2];
assert(value>=0.0);
assert(sizeof(uint32)==4); assert(sizeof(uint32)==4);
if (value<=0.0) if( value < 0 )
{
TIFFErrorExt(tif->tif_clientdata,module,"Negative value is illegal");
return 0;
}
else if( value != value )
{
TIFFErrorExt(tif->tif_clientdata,module,"Not-a-number value is illegal");
return 0;
}
else if (value==0.0)
{ {
m[0]=0; m[0]=0;
m[1]=1; m[1]=1;
} }
else if (value==(double)(uint32)value) else if (value <= 0xFFFFFFFFU && value==(double)(uint32)value)
{ {
m[0]=(uint32)value; m[0]=(uint32)value;
m[1]=1; m[1]=1;
@ -2144,12 +2218,13 @@ TIFFWriteDirectoryTagCheckedRationalArray(TIFF* tif, uint32* ndir, TIFFDirEntry*
} }
for (na=value, nb=m, nc=0; nc<count; na++, nb+=2, nc++) for (na=value, nb=m, nc=0; nc<count; na++, nb+=2, nc++)
{ {
if (*na<=0.0) if (*na<=0.0 || *na != *na)
{ {
nb[0]=0; nb[0]=0;
nb[1]=1; nb[1]=1;
} }
else if (*na==(float)(uint32)(*na)) else if (*na >= 0 && *na <= (float)0xFFFFFFFFU &&
*na==(float)(uint32)(*na))
{ {
nb[0]=(uint32)(*na); nb[0]=(uint32)(*na);
nb[1]=1; nb[1]=1;

View file

@ -1,4 +1,4 @@
/* $Id: tif_fax3.c,v 1.78 2016-09-04 21:32:56 erouault Exp $ */ /* $Id: tif_fax3.c,v 1.80 2017-04-27 19:50:01 erouault Exp $ */
/* /*
* Copyright (c) 1990-1997 Sam Leffler * Copyright (c) 1990-1997 Sam Leffler
@ -330,34 +330,64 @@ Fax3Decode2D(TIFF* tif, uint8* buf, tmsize_t occ, uint16 s)
#if SIZEOF_UNSIGNED_LONG == 8 #if SIZEOF_UNSIGNED_LONG == 8
# define FILL(n, cp) \ # define FILL(n, cp) \
switch (n) { \ switch (n) { \
case 15:(cp)[14] = 0xff; case 14:(cp)[13] = 0xff; case 13: (cp)[12] = 0xff;\ case 15:(cp)[14] = 0xff; /*-fallthrough*/ \
case 12:(cp)[11] = 0xff; case 11:(cp)[10] = 0xff; case 10: (cp)[9] = 0xff;\ case 14:(cp)[13] = 0xff; /*-fallthrough*/ \
case 9: (cp)[8] = 0xff; case 8: (cp)[7] = 0xff; case 7: (cp)[6] = 0xff;\ case 13:(cp)[12] = 0xff; /*-fallthrough*/ \
case 6: (cp)[5] = 0xff; case 5: (cp)[4] = 0xff; case 4: (cp)[3] = 0xff;\ case 12:(cp)[11] = 0xff; /*-fallthrough*/ \
case 3: (cp)[2] = 0xff; case 2: (cp)[1] = 0xff; \ case 11:(cp)[10] = 0xff; /*-fallthrough*/ \
case 1: (cp)[0] = 0xff; (cp) += (n); case 0: ; \ case 10: (cp)[9] = 0xff; /*-fallthrough*/ \
case 9: (cp)[8] = 0xff; /*-fallthrough*/ \
case 8: (cp)[7] = 0xff; /*-fallthrough*/ \
case 7: (cp)[6] = 0xff; /*-fallthrough*/ \
case 6: (cp)[5] = 0xff; /*-fallthrough*/ \
case 5: (cp)[4] = 0xff; /*-fallthrough*/ \
case 4: (cp)[3] = 0xff; /*-fallthrough*/ \
case 3: (cp)[2] = 0xff; /*-fallthrough*/ \
case 2: (cp)[1] = 0xff; /*-fallthrough*/ \
case 1: (cp)[0] = 0xff; (cp) += (n); /*-fallthrough*/ \
case 0: ; \
} }
# define ZERO(n, cp) \ # define ZERO(n, cp) \
switch (n) { \ switch (n) { \
case 15:(cp)[14] = 0; case 14:(cp)[13] = 0; case 13: (cp)[12] = 0; \ case 15:(cp)[14] = 0; /*-fallthrough*/ \
case 12:(cp)[11] = 0; case 11:(cp)[10] = 0; case 10: (cp)[9] = 0; \ case 14:(cp)[13] = 0; /*-fallthrough*/ \
case 9: (cp)[8] = 0; case 8: (cp)[7] = 0; case 7: (cp)[6] = 0; \ case 13:(cp)[12] = 0; /*-fallthrough*/ \
case 6: (cp)[5] = 0; case 5: (cp)[4] = 0; case 4: (cp)[3] = 0; \ case 12:(cp)[11] = 0; /*-fallthrough*/ \
case 3: (cp)[2] = 0; case 2: (cp)[1] = 0; \ case 11:(cp)[10] = 0; /*-fallthrough*/ \
case 1: (cp)[0] = 0; (cp) += (n); case 0: ; \ case 10: (cp)[9] = 0; /*-fallthrough*/ \
case 9: (cp)[8] = 0; /*-fallthrough*/ \
case 8: (cp)[7] = 0; /*-fallthrough*/ \
case 7: (cp)[6] = 0; /*-fallthrough*/ \
case 6: (cp)[5] = 0; /*-fallthrough*/ \
case 5: (cp)[4] = 0; /*-fallthrough*/ \
case 4: (cp)[3] = 0; /*-fallthrough*/ \
case 3: (cp)[2] = 0; /*-fallthrough*/ \
case 2: (cp)[1] = 0; /*-fallthrough*/ \
case 1: (cp)[0] = 0; (cp) += (n); /*-fallthrough*/ \
case 0: ; \
} }
#else #else
# define FILL(n, cp) \ # define FILL(n, cp) \
switch (n) { \ switch (n) { \
case 7: (cp)[6] = 0xff; case 6: (cp)[5] = 0xff; case 5: (cp)[4] = 0xff; \ case 7: (cp)[6] = 0xff; /*-fallthrough*/ \
case 4: (cp)[3] = 0xff; case 3: (cp)[2] = 0xff; case 2: (cp)[1] = 0xff; \ case 6: (cp)[5] = 0xff; /*-fallthrough*/ \
case 1: (cp)[0] = 0xff; (cp) += (n); case 0: ; \ case 5: (cp)[4] = 0xff; /*-fallthrough*/ \
case 4: (cp)[3] = 0xff; /*-fallthrough*/ \
case 3: (cp)[2] = 0xff; /*-fallthrough*/ \
case 2: (cp)[1] = 0xff; /*-fallthrough*/ \
case 1: (cp)[0] = 0xff; (cp) += (n); /*-fallthrough*/ \
case 0: ; \
} }
# define ZERO(n, cp) \ # define ZERO(n, cp) \
switch (n) { \ switch (n) { \
case 7: (cp)[6] = 0; case 6: (cp)[5] = 0; case 5: (cp)[4] = 0; \ case 7: (cp)[6] = 0; /*-fallthrough*/ \
case 4: (cp)[3] = 0; case 3: (cp)[2] = 0; case 2: (cp)[1] = 0; \ case 6: (cp)[5] = 0; /*-fallthrough*/ \
case 1: (cp)[0] = 0; (cp) += (n); case 0: ; \ case 5: (cp)[4] = 0; /*-fallthrough*/ \
case 4: (cp)[3] = 0; /*-fallthrough*/ \
case 3: (cp)[2] = 0; /*-fallthrough*/ \
case 2: (cp)[1] = 0; /*-fallthrough*/ \
case 1: (cp)[0] = 0; (cp) += (n); /*-fallthrough*/ \
case 0: ; \
} }
#endif #endif
@ -1100,7 +1130,7 @@ Fax3PostEncode(TIFF* tif)
static void static void
Fax3Close(TIFF* tif) Fax3Close(TIFF* tif)
{ {
if ((Fax3State(tif)->mode & FAXMODE_NORTC) == 0) { if ((Fax3State(tif)->mode & FAXMODE_NORTC) == 0 && tif->tif_rawcp) {
Fax3CodecState* sp = EncoderState(tif); Fax3CodecState* sp = EncoderState(tif);
unsigned int code = EOL; unsigned int code = EOL;
unsigned int length = 12; unsigned int length = 12;
@ -1322,6 +1352,7 @@ InitCCITTFax3(TIFF* tif)
"No space for state block"); "No space for state block");
return (0); return (0);
} }
_TIFFmemset(tif->tif_data, 0, sizeof (Fax3CodecState));
sp = Fax3State(tif); sp = Fax3State(tif);
sp->rw_mode = tif->tif_mode; sp->rw_mode = tif->tif_mode;

View file

@ -1,4 +1,4 @@
/* $Id: tif_getimage.c,v 1.98 2016-11-18 02:47:45 bfriesen Exp $ */ /* $Id: tif_getimage.c,v 1.106 2017-05-20 11:29:02 erouault Exp $ */
/* /*
* Copyright (c) 1991-1997 Sam Leffler * Copyright (c) 1991-1997 Sam Leffler
@ -284,6 +284,13 @@ TIFFRGBAImageBegin(TIFFRGBAImage* img, TIFF* tif, int stop, char emsg[1024])
img->redcmap = NULL; img->redcmap = NULL;
img->greencmap = NULL; img->greencmap = NULL;
img->bluecmap = NULL; img->bluecmap = NULL;
img->Map = NULL;
img->BWmap = NULL;
img->PALmap = NULL;
img->ycbcr = NULL;
img->cielab = NULL;
img->UaToAa = NULL;
img->Bitdepth16To8 = NULL;
img->req_orientation = ORIENTATION_BOTLEFT; /* It is the default */ img->req_orientation = ORIENTATION_BOTLEFT; /* It is the default */
img->tif = tif; img->tif = tif;
@ -469,13 +476,6 @@ TIFFRGBAImageBegin(TIFFRGBAImage* img, TIFF* tif, int stop, char emsg[1024])
photoTag, img->photometric); photoTag, img->photometric);
goto fail_return; goto fail_return;
} }
img->Map = NULL;
img->BWmap = NULL;
img->PALmap = NULL;
img->ycbcr = NULL;
img->cielab = NULL;
img->UaToAa = NULL;
img->Bitdepth16To8 = NULL;
TIFFGetField(tif, TIFFTAG_IMAGEWIDTH, &img->width); TIFFGetField(tif, TIFFTAG_IMAGEWIDTH, &img->width);
TIFFGetField(tif, TIFFTAG_IMAGELENGTH, &img->height); TIFFGetField(tif, TIFFTAG_IMAGELENGTH, &img->height);
TIFFGetFieldDefaulted(tif, TIFFTAG_ORIENTATION, &img->orientation); TIFFGetFieldDefaulted(tif, TIFFTAG_ORIENTATION, &img->orientation);
@ -495,10 +495,7 @@ TIFFRGBAImageBegin(TIFFRGBAImage* img, TIFF* tif, int stop, char emsg[1024])
return 1; return 1;
fail_return: fail_return:
_TIFFfree( img->redcmap ); TIFFRGBAImageEnd( img );
_TIFFfree( img->greencmap );
_TIFFfree( img->bluecmap );
img->redcmap = img->greencmap = img->bluecmap = NULL;
return 0; return 0;
} }
@ -703,7 +700,7 @@ gtTileContig(TIFFRGBAImage* img, uint32* raster, uint32 w, uint32 h)
this_toskew = toskew; this_toskew = toskew;
} }
y += (flip & FLIP_VERTICALLY ? -(int32) nrow : (int32) nrow); y += ((flip & FLIP_VERTICALLY) ? -(int32) nrow : (int32) nrow);
} }
_TIFFfree(buf); _TIFFfree(buf);
@ -872,7 +869,7 @@ gtTileSeparate(TIFFRGBAImage* img, uint32* raster, uint32 w, uint32 h)
this_toskew = toskew; this_toskew = toskew;
} }
y += (flip & FLIP_VERTICALLY ?-(int32) nrow : (int32) nrow); y += ((flip & FLIP_VERTICALLY) ?-(int32) nrow : (int32) nrow);
} }
if (flip & FLIP_HORIZONTALLY) { if (flip & FLIP_HORIZONTALLY) {
@ -963,7 +960,7 @@ gtStripContig(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); ((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);
} }
if (flip & FLIP_HORIZONTALLY) { if (flip & FLIP_HORIZONTALLY) {
@ -1098,7 +1095,7 @@ gtStripSeparate(TIFFRGBAImage* img, uint32* raster, uint32 w, uint32 h)
((tmsize_t) img->col_offset * img->samplesperpixel); ((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);
} }
if (flip & FLIP_HORIZONTALLY) { if (flip & FLIP_HORIZONTALLY) {
@ -1137,11 +1134,15 @@ gtStripSeparate(TIFFRGBAImage* img, uint32* raster, uint32 w, uint32 h)
#define REPEAT2(op) op; op #define REPEAT2(op) op; op
#define CASE8(x,op) \ #define CASE8(x,op) \
switch (x) { \ switch (x) { \
case 7: op; case 6: op; case 5: op; \ case 7: op; /*-fallthrough*/ \
case 4: op; case 3: op; case 2: op; \ case 6: op; /*-fallthrough*/ \
case 5: op; /*-fallthrough*/ \
case 4: op; /*-fallthrough*/ \
case 3: op; /*-fallthrough*/ \
case 2: op; /*-fallthrough*/ \
case 1: op; \ case 1: op; \
} }
#define CASE4(x,op) switch (x) { case 3: op; case 2: op; case 1: op; } #define CASE4(x,op) switch (x) { case 3: op; /*-fallthrough*/ case 2: op; /*-fallthrough*/ case 1: op; }
#define NOP #define NOP
#define UNROLL8(w, op1, op2) { \ #define UNROLL8(w, op1, op2) { \
@ -1306,7 +1307,7 @@ DECLAREContigPutFunc(putagreytile)
while (h-- > 0) { while (h-- > 0) {
for (x = w; x-- > 0;) for (x = w; x-- > 0;)
{ {
*cp++ = BWmap[*pp][0] & (*(pp+1) << 24 | ~A1); *cp++ = BWmap[*pp][0] & ((uint32)*(pp+1) << 24 | ~A1);
pp += samplesperpixel; pp += samplesperpixel;
} }
cp += toskew; cp += toskew;
@ -2047,9 +2048,9 @@ DECLAREContigPutFunc(putcontig8bitYCbCr41tile)
int32 Cr = pp[5]; int32 Cr = pp[5];
switch( (w&3) ) { switch( (w&3) ) {
case 3: YCbCrtoRGB(cp [2], pp[2]); case 3: YCbCrtoRGB(cp [2], pp[2]); /*-fallthrough*/
case 2: YCbCrtoRGB(cp [1], pp[1]); case 2: YCbCrtoRGB(cp [1], pp[1]); /*-fallthrough*/
case 1: YCbCrtoRGB(cp [0], pp[0]); case 1: YCbCrtoRGB(cp [0], pp[0]); /*-fallthrough*/
case 0: break; case 0: break;
} }
@ -2239,6 +2240,11 @@ DECLARESepPutFunc(putseparate8bitYCbCr11tile)
} }
#undef YCbCrtoRGB #undef YCbCrtoRGB
static int isInRefBlackWhiteRange(float f)
{
return f >= (float)(-0x7FFFFFFF + 128) && f <= (float)0x7FFFFFFF;
}
static int static int
initYCbCrConversion(TIFFRGBAImage* img) initYCbCrConversion(TIFFRGBAImage* img)
{ {
@ -2263,6 +2269,31 @@ initYCbCrConversion(TIFFRGBAImage* img)
TIFFGetFieldDefaulted(img->tif, TIFFTAG_YCBCRCOEFFICIENTS, &luma); TIFFGetFieldDefaulted(img->tif, TIFFTAG_YCBCRCOEFFICIENTS, &luma);
TIFFGetFieldDefaulted(img->tif, TIFFTAG_REFERENCEBLACKWHITE, TIFFGetFieldDefaulted(img->tif, TIFFTAG_REFERENCEBLACKWHITE,
&refBlackWhite); &refBlackWhite);
/* Do some validation to avoid later issues. Detect NaN for now */
/* and also if lumaGreen is zero since we divide by it later */
if( luma[0] != luma[0] ||
luma[1] != luma[1] ||
luma[1] == 0.0 ||
luma[2] != luma[2] )
{
TIFFErrorExt(img->tif->tif_clientdata, module,
"Invalid values for YCbCrCoefficients tag");
return (0);
}
if( !isInRefBlackWhiteRange(refBlackWhite[0]) ||
!isInRefBlackWhiteRange(refBlackWhite[1]) ||
!isInRefBlackWhiteRange(refBlackWhite[2]) ||
!isInRefBlackWhiteRange(refBlackWhite[3]) ||
!isInRefBlackWhiteRange(refBlackWhite[4]) ||
!isInRefBlackWhiteRange(refBlackWhite[5]) )
{
TIFFErrorExt(img->tif->tif_clientdata, module,
"Invalid values for ReferenceBlackWhite tag");
return (0);
}
if (TIFFYCbCrToRGBInit(img->ycbcr, luma, refBlackWhite) < 0) if (TIFFYCbCrToRGBInit(img->ycbcr, luma, refBlackWhite) < 0)
return(0); return(0);
return (1); return (1);
@ -2816,6 +2847,13 @@ BuildMapBitdepth16To8(TIFFRGBAImage* img)
int int
TIFFReadRGBAStrip(TIFF* tif, uint32 row, uint32 * raster ) TIFFReadRGBAStrip(TIFF* tif, uint32 row, uint32 * raster )
{
return TIFFReadRGBAStripExt(tif, row, raster, 0 );
}
int
TIFFReadRGBAStripExt(TIFF* tif, uint32 row, uint32 * raster, int stop_on_error)
{ {
char emsg[1024] = ""; char emsg[1024] = "";
TIFFRGBAImage img; TIFFRGBAImage img;
@ -2837,7 +2875,7 @@ TIFFReadRGBAStrip(TIFF* tif, uint32 row, uint32 * raster )
return (0); return (0);
} }
if (TIFFRGBAImageOK(tif, emsg) && TIFFRGBAImageBegin(&img, tif, 0, emsg)) { if (TIFFRGBAImageOK(tif, emsg) && TIFFRGBAImageBegin(&img, tif, stop_on_error, emsg)) {
img.row_offset = row; img.row_offset = row;
img.col_offset = 0; img.col_offset = 0;
@ -2867,6 +2905,13 @@ TIFFReadRGBAStrip(TIFF* tif, uint32 row, uint32 * raster )
int int
TIFFReadRGBATile(TIFF* tif, uint32 col, uint32 row, uint32 * raster) TIFFReadRGBATile(TIFF* tif, uint32 col, uint32 row, uint32 * raster)
{
return TIFFReadRGBATileExt(tif, col, row, raster, 0 );
}
int
TIFFReadRGBATileExt(TIFF* tif, uint32 col, uint32 row, uint32 * raster, int stop_on_error )
{ {
char emsg[1024] = ""; char emsg[1024] = "";
TIFFRGBAImage img; TIFFRGBAImage img;
@ -2902,7 +2947,7 @@ TIFFReadRGBATile(TIFF* tif, uint32 col, uint32 row, uint32 * raster)
*/ */
if (!TIFFRGBAImageOK(tif, emsg) if (!TIFFRGBAImageOK(tif, emsg)
|| !TIFFRGBAImageBegin(&img, tif, 0, emsg)) { || !TIFFRGBAImageBegin(&img, tif, stop_on_error, emsg)) {
TIFFErrorExt(tif->tif_clientdata, TIFFFileName(tif), "%s", emsg); TIFFErrorExt(tif->tif_clientdata, TIFFFileName(tif), "%s", emsg);
return( 0 ); return( 0 );
} }

View file

@ -1,4 +1,4 @@
/* $Id: tif_jpeg.c,v 1.123 2016-01-23 21:20:34 erouault Exp $ */ /* $Id: tif_jpeg.c,v 1.127 2017-01-31 13:02:27 erouault Exp $ */
/* /*
* Copyright (c) 1994-1997 Sam Leffler * Copyright (c) 1994-1997 Sam Leffler
@ -698,9 +698,11 @@ static int
JPEGFixupTags(TIFF* tif) JPEGFixupTags(TIFF* tif)
{ {
#ifdef CHECK_JPEG_YCBCR_SUBSAMPLING #ifdef CHECK_JPEG_YCBCR_SUBSAMPLING
JPEGState* sp = JState(tif);
if ((tif->tif_dir.td_photometric==PHOTOMETRIC_YCBCR)&& if ((tif->tif_dir.td_photometric==PHOTOMETRIC_YCBCR)&&
(tif->tif_dir.td_planarconfig==PLANARCONFIG_CONTIG)&& (tif->tif_dir.td_planarconfig==PLANARCONFIG_CONTIG)&&
(tif->tif_dir.td_samplesperpixel==3)) (tif->tif_dir.td_samplesperpixel==3) &&
!sp->ycbcrsampling_fetched)
JPEGFixupTagsSubsampling(tif); JPEGFixupTagsSubsampling(tif);
#endif #endif
@ -1627,6 +1629,20 @@ JPEGSetupEncode(TIFF* tif)
case PHOTOMETRIC_YCBCR: case PHOTOMETRIC_YCBCR:
sp->h_sampling = td->td_ycbcrsubsampling[0]; sp->h_sampling = td->td_ycbcrsubsampling[0];
sp->v_sampling = td->td_ycbcrsubsampling[1]; sp->v_sampling = td->td_ycbcrsubsampling[1];
if( sp->h_sampling == 0 || sp->v_sampling == 0 )
{
TIFFErrorExt(tif->tif_clientdata, module,
"Invalig horizontal/vertical sampling value");
return (0);
}
if( td->td_bitspersample > 16 )
{
TIFFErrorExt(tif->tif_clientdata, module,
"BitsPerSample %d not allowed for JPEG",
td->td_bitspersample);
return (0);
}
/* /*
* A ReferenceBlackWhite field *must* be present since the * A ReferenceBlackWhite field *must* be present since the
* default value is inappropriate for YCbCr. Fill in the * default value is inappropriate for YCbCr. Fill in the
@ -2292,6 +2308,15 @@ static int JPEGInitializeLibJPEG( TIFF * tif, int decompress )
} else { } else {
if (!TIFFjpeg_create_compress(sp)) if (!TIFFjpeg_create_compress(sp))
return (0); return (0);
#ifndef TIFF_JPEG_MAX_MEMORY_TO_USE
#define TIFF_JPEG_MAX_MEMORY_TO_USE (10 * 1024 * 1024)
#endif
/* Increase the max memory usable. This helps when creating files */
/* with "big" tile, without using libjpeg temporary files. */
/* For example a 512x512 tile with 3 bands */
/* requires 1.5 MB which is above libjpeg 1MB default */
if( sp->cinfo.c.mem->max_memory_to_use < TIFF_JPEG_MAX_MEMORY_TO_USE )
sp->cinfo.c.mem->max_memory_to_use = TIFF_JPEG_MAX_MEMORY_TO_USE;
} }
sp->cinfo_initialized = TRUE; sp->cinfo_initialized = TRUE;

View file

@ -1,4 +1,4 @@
/* $Id: tif_luv.c,v 1.43 2016-09-04 21:32:56 erouault Exp $ */ /* $Id: tif_luv.c,v 1.47 2017-05-14 10:17:27 erouault Exp $ */
/* /*
* Copyright (c) 1997 Greg Ward Larson * Copyright (c) 1997 Greg Ward Larson
@ -159,6 +159,7 @@
typedef struct logLuvState LogLuvState; typedef struct logLuvState LogLuvState;
struct logLuvState { struct logLuvState {
int encoder_state; /* 1 if encoder correctly initialized */
int user_datafmt; /* user data format */ int user_datafmt; /* user data format */
int encode_meth; /* encoding method */ int encode_meth; /* encoding method */
int pixel_size; /* bytes per pixel */ int pixel_size; /* bytes per pixel */
@ -473,7 +474,7 @@ LogL16Encode(TIFF* tif, uint8* bp, tmsize_t cc, uint16 s)
tif->tif_rawcp = op; tif->tif_rawcp = op;
tif->tif_rawcc = tif->tif_rawdatasize - occ; tif->tif_rawcc = tif->tif_rawdatasize - occ;
if (!TIFFFlushData1(tif)) if (!TIFFFlushData1(tif))
return (-1); return (0);
op = tif->tif_rawcp; op = tif->tif_rawcp;
occ = tif->tif_rawdatasize - tif->tif_rawcc; occ = tif->tif_rawdatasize - tif->tif_rawcc;
} }
@ -505,7 +506,7 @@ LogL16Encode(TIFF* tif, uint8* bp, tmsize_t cc, uint16 s)
tif->tif_rawcp = op; tif->tif_rawcp = op;
tif->tif_rawcc = tif->tif_rawdatasize - occ; tif->tif_rawcc = tif->tif_rawdatasize - occ;
if (!TIFFFlushData1(tif)) if (!TIFFFlushData1(tif))
return (-1); return (0);
op = tif->tif_rawcp; op = tif->tif_rawcp;
occ = tif->tif_rawdatasize - tif->tif_rawcc; occ = tif->tif_rawdatasize - tif->tif_rawcc;
} }
@ -565,7 +566,7 @@ LogLuvEncode24(TIFF* tif, uint8* bp, tmsize_t cc, uint16 s)
tif->tif_rawcp = op; tif->tif_rawcp = op;
tif->tif_rawcc = tif->tif_rawdatasize - occ; tif->tif_rawcc = tif->tif_rawdatasize - occ;
if (!TIFFFlushData1(tif)) if (!TIFFFlushData1(tif))
return (-1); return (0);
op = tif->tif_rawcp; op = tif->tif_rawcp;
occ = tif->tif_rawdatasize - tif->tif_rawcc; occ = tif->tif_rawdatasize - tif->tif_rawcc;
} }
@ -624,7 +625,7 @@ LogLuvEncode32(TIFF* tif, uint8* bp, tmsize_t cc, uint16 s)
tif->tif_rawcp = op; tif->tif_rawcp = op;
tif->tif_rawcc = tif->tif_rawdatasize - occ; tif->tif_rawcc = tif->tif_rawdatasize - occ;
if (!TIFFFlushData1(tif)) if (!TIFFFlushData1(tif))
return (-1); return (0);
op = tif->tif_rawcp; op = tif->tif_rawcp;
occ = tif->tif_rawdatasize - tif->tif_rawcc; occ = tif->tif_rawdatasize - tif->tif_rawcc;
} }
@ -656,7 +657,7 @@ LogLuvEncode32(TIFF* tif, uint8* bp, tmsize_t cc, uint16 s)
tif->tif_rawcp = op; tif->tif_rawcp = op;
tif->tif_rawcc = tif->tif_rawdatasize - occ; tif->tif_rawcc = tif->tif_rawdatasize - occ;
if (!TIFFFlushData1(tif)) if (!TIFFFlushData1(tif))
return (-1); return (0);
op = tif->tif_rawcp; op = tif->tif_rawcp;
occ = tif->tif_rawdatasize - tif->tif_rawcc; occ = tif->tif_rawdatasize - tif->tif_rawcc;
} }
@ -1264,15 +1265,16 @@ LogL16GuessDataFmt(TIFFDirectory *td)
return (SGILOGDATAFMT_UNKNOWN); return (SGILOGDATAFMT_UNKNOWN);
} }
#define TIFF_SIZE_T_MAX ((size_t) ~ ((size_t)0))
#define TIFF_TMSIZE_T_MAX (tmsize_t)(TIFF_SIZE_T_MAX >> 1)
static tmsize_t static tmsize_t
multiply_ms(tmsize_t m1, tmsize_t m2) multiply_ms(tmsize_t m1, tmsize_t m2)
{ {
tmsize_t bytes = m1 * m2; if( m1 == 0 || m2 > TIFF_TMSIZE_T_MAX / m1 )
return 0;
if (m1 && bytes / m1 != m2) return m1 * m2;
bytes = 0;
return bytes;
} }
static int static int
@ -1313,8 +1315,10 @@ LogL16InitState(TIFF* tif)
} }
if( isTiled(tif) ) if( isTiled(tif) )
sp->tbuflen = multiply_ms(td->td_tilewidth, td->td_tilelength); sp->tbuflen = multiply_ms(td->td_tilewidth, td->td_tilelength);
else else if( td->td_rowsperstrip != (uint32)-1 )
sp->tbuflen = multiply_ms(td->td_imagewidth, td->td_rowsperstrip); sp->tbuflen = multiply_ms(td->td_imagewidth, td->td_rowsperstrip);
else
sp->tbuflen = multiply_ms(td->td_imagewidth, td->td_imagelength);
if (multiply_ms(sp->tbuflen, sizeof (int16)) == 0 || if (multiply_ms(sp->tbuflen, sizeof (int16)) == 0 ||
(sp->tbuf = (uint8*) _TIFFmalloc(sp->tbuflen * sizeof (int16))) == NULL) { (sp->tbuf = (uint8*) _TIFFmalloc(sp->tbuflen * sizeof (int16))) == NULL) {
TIFFErrorExt(tif->tif_clientdata, module, "No space for SGILog translation buffer"); TIFFErrorExt(tif->tif_clientdata, module, "No space for SGILog translation buffer");
@ -1553,6 +1557,7 @@ LogLuvSetupEncode(TIFF* tif)
td->td_photometric, "must be either LogLUV or LogL"); td->td_photometric, "must be either LogLUV or LogL");
break; break;
} }
sp->encoder_state = 1;
return (1); return (1);
notsupported: notsupported:
TIFFErrorExt(tif->tif_clientdata, module, TIFFErrorExt(tif->tif_clientdata, module,
@ -1564,19 +1569,27 @@ notsupported:
static void static void
LogLuvClose(TIFF* tif) LogLuvClose(TIFF* tif)
{ {
LogLuvState* sp = (LogLuvState*) tif->tif_data;
TIFFDirectory *td = &tif->tif_dir; TIFFDirectory *td = &tif->tif_dir;
assert(sp != 0);
/* /*
* For consistency, we always want to write out the same * For consistency, we always want to write out the same
* bitspersample and sampleformat for our TIFF file, * bitspersample and sampleformat for our TIFF file,
* regardless of the data format being used by the application. * regardless of the data format being used by the application.
* Since this routine is called after tags have been set but * Since this routine is called after tags have been set but
* before they have been recorded in the file, we reset them here. * before they have been recorded in the file, we reset them here.
* Note: this is really a nasty approach. See PixarLogClose
*/ */
if( sp->encoder_state )
{
/* See PixarLogClose. Might avoid issues with tags whose size depends
* on those below, but not completely sure this is enough. */
td->td_samplesperpixel = td->td_samplesperpixel =
(td->td_photometric == PHOTOMETRIC_LOGL) ? 1 : 3; (td->td_photometric == PHOTOMETRIC_LOGL) ? 1 : 3;
td->td_bitspersample = 16; td->td_bitspersample = 16;
td->td_sampleformat = SAMPLEFORMAT_INT; td->td_sampleformat = SAMPLEFORMAT_INT;
}
} }
static void static void

View file

@ -1,4 +1,4 @@
/* $Id: tif_lzw.c,v 1.52 2016-09-04 21:32:56 erouault Exp $ */ /* $Id: tif_lzw.c,v 1.55 2017-05-17 09:38:58 erouault Exp $ */
/* /*
* Copyright (c) 1988-1997 Sam Leffler * Copyright (c) 1988-1997 Sam Leffler
@ -319,7 +319,7 @@ LZWPreDecode(TIFF* tif, uint16 s)
sp->dec_restart = 0; sp->dec_restart = 0;
sp->dec_nbitsmask = MAXCODE(BITS_MIN); sp->dec_nbitsmask = MAXCODE(BITS_MIN);
#ifdef LZW_CHECKEOS #ifdef LZW_CHECKEOS
sp->dec_bitsleft = ((uint64)tif->tif_rawcc) << 3; sp->dec_bitsleft = 0;
#endif #endif
sp->dec_free_entp = sp->dec_codetab + CODE_FIRST; sp->dec_free_entp = sp->dec_codetab + CODE_FIRST;
/* /*
@ -426,6 +426,9 @@ LZWDecode(TIFF* tif, uint8* op0, tmsize_t occ0, uint16 s)
} }
bp = (unsigned char *)tif->tif_rawcp; bp = (unsigned char *)tif->tif_rawcp;
#ifdef LZW_CHECKEOS
sp->dec_bitsleft = (((uint64)tif->tif_rawcc) << 3);
#endif
nbits = sp->lzw_nbits; nbits = sp->lzw_nbits;
nextdata = sp->lzw_nextdata; nextdata = sp->lzw_nextdata;
nextbits = sp->lzw_nextbits; nextbits = sp->lzw_nextbits;
@ -550,6 +553,7 @@ LZWDecode(TIFF* tif, uint8* op0, tmsize_t occ0, uint16 s)
} }
} }
tif->tif_rawcc -= (tmsize_t)( (uint8*) bp - tif->tif_rawcp );
tif->tif_rawcp = (uint8*) bp; tif->tif_rawcp = (uint8*) bp;
sp->lzw_nbits = (unsigned short) nbits; sp->lzw_nbits = (unsigned short) nbits;
sp->lzw_nextdata = nextdata; sp->lzw_nextdata = nextdata;
@ -970,7 +974,8 @@ LZWEncode(TIFF* tif, uint8* bp, tmsize_t cc, uint16 s)
*/ */
if (op > limit) { if (op > limit) {
tif->tif_rawcc = (tmsize_t)(op - tif->tif_rawdata); tif->tif_rawcc = (tmsize_t)(op - tif->tif_rawdata);
TIFFFlushData1(tif); if( !TIFFFlushData1(tif) )
return 0;
op = tif->tif_rawdata; op = tif->tif_rawdata;
} }
PutNextCode(op, ent); PutNextCode(op, ent);
@ -1055,12 +1060,32 @@ LZWPostEncode(TIFF* tif)
if (op > sp->enc_rawlimit) { if (op > sp->enc_rawlimit) {
tif->tif_rawcc = (tmsize_t)(op - tif->tif_rawdata); tif->tif_rawcc = (tmsize_t)(op - tif->tif_rawdata);
TIFFFlushData1(tif); if( !TIFFFlushData1(tif) )
return 0;
op = tif->tif_rawdata; op = tif->tif_rawdata;
} }
if (sp->enc_oldcode != (hcode_t) -1) { if (sp->enc_oldcode != (hcode_t) -1) {
int free_ent = sp->lzw_free_ent;
PutNextCode(op, sp->enc_oldcode); PutNextCode(op, sp->enc_oldcode);
sp->enc_oldcode = (hcode_t) -1; sp->enc_oldcode = (hcode_t) -1;
free_ent ++;
if (free_ent == CODE_MAX-1) {
/* table is full, emit clear code and reset */
outcount = 0;
PutNextCode(op, CODE_CLEAR);
nbits = BITS_MIN;
} else {
/*
* If the next entry is going to be too big for
* the code size, then increase it, if possible.
*/
if (free_ent > sp->lzw_maxcode) {
nbits++;
assert(nbits <= BITS_MAX);
}
}
} }
PutNextCode(op, CODE_EOI); PutNextCode(op, CODE_EOI);
/* Explicit 0xff masking to make icc -check=conversions happy */ /* Explicit 0xff masking to make icc -check=conversions happy */

View file

@ -1,4 +1,4 @@
/* $Id: tif_ojpeg.c,v 1.65 2016-09-04 21:32:56 erouault Exp $ */ /* $Id: tif_ojpeg.c,v 1.69 2017-04-27 17:29:26 erouault 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
@ -245,6 +245,7 @@ typedef enum {
typedef struct { typedef struct {
TIFF* tif; TIFF* tif;
int decoder_ok;
#ifndef LIBJPEG_ENCAP_EXTERNAL #ifndef LIBJPEG_ENCAP_EXTERNAL
JMP_BUF exit_jmpbuf; JMP_BUF exit_jmpbuf;
#endif #endif
@ -723,6 +724,7 @@ OJPEGPreDecode(TIFF* tif, uint16 s)
} }
sp->write_curstrile++; sp->write_curstrile++;
} }
sp->decoder_ok = 1;
return(1); return(1);
} }
@ -785,8 +787,14 @@ OJPEGPreDecodeSkipScanlines(TIFF* tif)
static int static int
OJPEGDecode(TIFF* tif, uint8* buf, tmsize_t cc, uint16 s) OJPEGDecode(TIFF* tif, uint8* buf, tmsize_t cc, uint16 s)
{ {
static const char module[]="OJPEGDecode";
OJPEGState* sp=(OJPEGState*)tif->tif_data; OJPEGState* sp=(OJPEGState*)tif->tif_data;
(void)s; (void)s;
if( !sp->decoder_ok )
{
TIFFErrorExt(tif->tif_clientdata,module,"Cannot decode: decoder not correctly initialized");
return 0;
}
if (sp->libjpeg_jpeg_query_style==0) if (sp->libjpeg_jpeg_query_style==0)
{ {
if (OJPEGDecodeRaw(tif,buf,cc)==0) if (OJPEGDecodeRaw(tif,buf,cc)==0)
@ -1783,7 +1791,12 @@ OJPEGReadHeaderInfoSecTablesQTable(TIFF* tif)
TIFFSeekFile(tif,sp->qtable_offset[m],SEEK_SET); TIFFSeekFile(tif,sp->qtable_offset[m],SEEK_SET);
p=(uint32)TIFFReadFile(tif,&ob[sizeof(uint32)+5],64); p=(uint32)TIFFReadFile(tif,&ob[sizeof(uint32)+5],64);
if (p!=64) if (p!=64)
{
_TIFFfree(ob);
return(0); return(0);
}
if (sp->qtable[m]!=0)
_TIFFfree(sp->qtable[m]);
sp->qtable[m]=ob; sp->qtable[m]=ob;
sp->sof_tq[m]=m; sp->sof_tq[m]=m;
} }
@ -1847,7 +1860,12 @@ OJPEGReadHeaderInfoSecTablesDcTable(TIFF* tif)
rb[sizeof(uint32)+5+n]=o[n]; rb[sizeof(uint32)+5+n]=o[n];
p=(uint32)TIFFReadFile(tif,&(rb[sizeof(uint32)+21]),q); p=(uint32)TIFFReadFile(tif,&(rb[sizeof(uint32)+21]),q);
if (p!=q) if (p!=q)
{
_TIFFfree(rb);
return(0); return(0);
}
if (sp->dctable[m]!=0)
_TIFFfree(sp->dctable[m]);
sp->dctable[m]=rb; sp->dctable[m]=rb;
sp->sos_tda[m]=(m<<4); sp->sos_tda[m]=(m<<4);
} }
@ -1911,7 +1929,12 @@ OJPEGReadHeaderInfoSecTablesAcTable(TIFF* tif)
rb[sizeof(uint32)+5+n]=o[n]; rb[sizeof(uint32)+5+n]=o[n];
p=(uint32)TIFFReadFile(tif,&(rb[sizeof(uint32)+21]),q); p=(uint32)TIFFReadFile(tif,&(rb[sizeof(uint32)+21]),q);
if (p!=q) if (p!=q)
{
_TIFFfree(rb);
return(0); return(0);
}
if (sp->actable[m]!=0)
_TIFFfree(sp->actable[m]);
sp->actable[m]=rb; sp->actable[m]=rb;
sp->sos_tda[m]=(sp->sos_tda[m]|m); sp->sos_tda[m]=(sp->sos_tda[m]|m);
} }

View file

@ -1,4 +1,4 @@
/* $Id: tif_open.c,v 1.47 2016-01-23 21:20:34 erouault Exp $ */ /* $Id: tif_open.c,v 1.48 2016-11-20 22:29:47 erouault Exp $ */
/* /*
* Copyright (c) 1988-1997 Sam Leffler * Copyright (c) 1988-1997 Sam Leffler
@ -280,10 +280,10 @@ TIFFClientOpen(
* Setup header and write. * Setup header and write.
*/ */
#ifdef WORDS_BIGENDIAN #ifdef WORDS_BIGENDIAN
tif->tif_header.common.tiff_magic = tif->tif_flags & TIFF_SWAB tif->tif_header.common.tiff_magic = (tif->tif_flags & TIFF_SWAB)
? TIFF_LITTLEENDIAN : TIFF_BIGENDIAN; ? TIFF_LITTLEENDIAN : TIFF_BIGENDIAN;
#else #else
tif->tif_header.common.tiff_magic = tif->tif_flags & TIFF_SWAB tif->tif_header.common.tiff_magic = (tif->tif_flags & TIFF_SWAB)
? TIFF_BIGENDIAN : TIFF_LITTLEENDIAN; ? TIFF_BIGENDIAN : TIFF_LITTLEENDIAN;
#endif #endif
if (!(tif->tif_flags&TIFF_BIGTIFF)) if (!(tif->tif_flags&TIFF_BIGTIFF))

View file

@ -1,4 +1,4 @@
/* $Id: tif_packbits.c,v 1.24 2016-09-04 21:32:56 erouault Exp $ */ /* $Id: tif_packbits.c,v 1.26 2017-05-14 02:26:07 erouault Exp $ */
/* /*
* Copyright (c) 1988-1997 Sam Leffler * Copyright (c) 1988-1997 Sam Leffler
@ -100,7 +100,7 @@ PackBitsEncode(TIFF* tif, uint8* buf, tmsize_t cc, uint16 s)
slop = (long)(op - lastliteral); slop = (long)(op - lastliteral);
tif->tif_rawcc += (tmsize_t)(lastliteral - tif->tif_rawcp); tif->tif_rawcc += (tmsize_t)(lastliteral - tif->tif_rawcp);
if (!TIFFFlushData1(tif)) if (!TIFFFlushData1(tif))
return (-1); return (0);
op = tif->tif_rawcp; op = tif->tif_rawcp;
while (slop-- > 0) while (slop-- > 0)
*op++ = *lastliteral++; *op++ = *lastliteral++;
@ -108,7 +108,7 @@ PackBitsEncode(TIFF* tif, uint8* buf, tmsize_t cc, uint16 s)
} else { } else {
tif->tif_rawcc += (tmsize_t)(op - tif->tif_rawcp); tif->tif_rawcc += (tmsize_t)(op - tif->tif_rawcp);
if (!TIFFFlushData1(tif)) if (!TIFFFlushData1(tif))
return (-1); return (0);
op = tif->tif_rawcp; op = tif->tif_rawcp;
} }
} }
@ -245,6 +245,12 @@ PackBitsDecode(TIFF* tif, uint8* op, tmsize_t occ, uint16 s)
(unsigned long) ((tmsize_t)n - occ)); (unsigned long) ((tmsize_t)n - occ));
n = (long)occ; n = (long)occ;
} }
if( cc == 0 )
{
TIFFWarningExt(tif->tif_clientdata, module,
"Terminating PackBitsDecode due to lack of data.");
break;
}
occ -= n; occ -= n;
b = *bp++; b = *bp++;
cc--; cc--;

View file

@ -1,4 +1,4 @@
/* $Id: tif_pixarlog.c,v 1.48 2016-09-23 22:12:18 erouault Exp $ */ /* $Id: tif_pixarlog.c,v 1.53 2017-05-17 09:53:06 erouault Exp $ */
/* /*
* Copyright (c) 1996-1997 Sam Leffler * Copyright (c) 1996-1997 Sam Leffler
@ -637,29 +637,27 @@ PixarLogGuessDataFmt(TIFFDirectory *td)
return guess; return guess;
} }
#define TIFF_SIZE_T_MAX ((size_t) ~ ((size_t)0))
#define TIFF_TMSIZE_T_MAX (tmsize_t)(TIFF_SIZE_T_MAX >> 1)
static tmsize_t static tmsize_t
multiply_ms(tmsize_t m1, tmsize_t m2) multiply_ms(tmsize_t m1, tmsize_t m2)
{ {
tmsize_t bytes = m1 * m2; if( m1 == 0 || m2 > TIFF_TMSIZE_T_MAX / m1 )
return 0;
if (m1 && bytes / m1 != m2) return m1 * m2;
bytes = 0;
return bytes;
} }
static tmsize_t static tmsize_t
add_ms(tmsize_t m1, tmsize_t m2) add_ms(tmsize_t m1, tmsize_t m2)
{ {
tmsize_t bytes = m1 + m2;
/* if either input is zero, assume overflow already occurred */ /* if either input is zero, assume overflow already occurred */
if (m1 == 0 || m2 == 0) if (m1 == 0 || m2 == 0)
bytes = 0; return 0;
else if (bytes <= m1 || bytes <= m2) else if (m1 > TIFF_TMSIZE_T_MAX - m2)
bytes = 0; return 0;
return bytes; return m1 + m2;
} }
static int static int
@ -679,6 +677,12 @@ PixarLogSetupDecode(TIFF* tif)
assert(sp != NULL); assert(sp != NULL);
/* This function can possibly be called several times by */
/* PredictorSetupDecode() if this function succeeds but */
/* PredictorSetup() fails */
if( (sp->state & PLSTATE_INIT) != 0 )
return 1;
/* Make sure no byte swapping happens on the data /* Make sure no byte swapping happens on the data
* after decompression. */ * after decompression. */
tif->tif_postdecode = _TIFFNoPostDecode; tif->tif_postdecode = _TIFFNoPostDecode;
@ -700,6 +704,9 @@ PixarLogSetupDecode(TIFF* tif)
if (sp->user_datafmt == PIXARLOGDATAFMT_UNKNOWN) if (sp->user_datafmt == PIXARLOGDATAFMT_UNKNOWN)
sp->user_datafmt = PixarLogGuessDataFmt(td); sp->user_datafmt = PixarLogGuessDataFmt(td);
if (sp->user_datafmt == PIXARLOGDATAFMT_UNKNOWN) { if (sp->user_datafmt == PIXARLOGDATAFMT_UNKNOWN) {
_TIFFfree(sp->tbuf);
sp->tbuf = NULL;
sp->tbuf_size = 0;
TIFFErrorExt(tif->tif_clientdata, module, TIFFErrorExt(tif->tif_clientdata, module,
"PixarLog compression can't handle bits depth/data format combination (depth: %d)", "PixarLog compression can't handle bits depth/data format combination (depth: %d)",
td->td_bitspersample); td->td_bitspersample);
@ -707,6 +714,9 @@ PixarLogSetupDecode(TIFF* tif)
} }
if (inflateInit(&sp->stream) != Z_OK) { if (inflateInit(&sp->stream) != Z_OK) {
_TIFFfree(sp->tbuf);
sp->tbuf = NULL;
sp->tbuf_size = 0;
TIFFErrorExt(tif->tif_clientdata, module, "%s", sp->stream.msg ? sp->stream.msg : "(null)"); TIFFErrorExt(tif->tif_clientdata, module, "%s", sp->stream.msg ? sp->stream.msg : "(null)");
return (0); return (0);
} else { } else {
@ -775,6 +785,10 @@ PixarLogDecode(TIFF* tif, uint8* op, tmsize_t occ, uint16 s)
(void) s; (void) s;
assert(sp != NULL); assert(sp != NULL);
sp->stream.next_in = tif->tif_rawcp;
sp->stream.avail_in = (uInt) tif->tif_rawcc;
sp->stream.next_out = (unsigned char *) sp->tbuf; sp->stream.next_out = (unsigned char *) sp->tbuf;
assert(sizeof(sp->stream.avail_out)==4); /* if this assert gets raised, assert(sizeof(sp->stream.avail_out)==4); /* if this assert gets raised,
we need to simplify this code to reflect a ZLib that is likely updated we need to simplify this code to reflect a ZLib that is likely updated
@ -820,6 +834,9 @@ PixarLogDecode(TIFF* tif, uint8* op, tmsize_t occ, uint16 s)
return (0); return (0);
} }
tif->tif_rawcp = sp->stream.next_in;
tif->tif_rawcc = sp->stream.avail_in;
up = sp->tbuf; up = sp->tbuf;
/* Swap bytes in the data if from a different endian machine. */ /* Swap bytes in the data if from a different endian machine. */
if (tif->tif_flags & TIFF_SWAB) if (tif->tif_flags & TIFF_SWAB)
@ -1234,8 +1251,10 @@ PixarLogPostEncode(TIFF* tif)
static void static void
PixarLogClose(TIFF* tif) PixarLogClose(TIFF* tif)
{ {
PixarLogState* sp = (PixarLogState*) tif->tif_data;
TIFFDirectory *td = &tif->tif_dir; TIFFDirectory *td = &tif->tif_dir;
assert(sp != 0);
/* In a really sneaky (and really incorrect, and untruthful, and /* In a really sneaky (and really incorrect, and untruthful, and
* troublesome, and error-prone) maneuver that completely goes against * troublesome, and error-prone) maneuver that completely goes against
* the spirit of TIFF, and breaks TIFF, on close, we covertly * the spirit of TIFF, and breaks TIFF, on close, we covertly
@ -1244,8 +1263,19 @@ PixarLogClose(TIFF* tif)
* readers that don't know about PixarLog, or how to set * readers that don't know about PixarLog, or how to set
* the PIXARLOGDATFMT pseudo-tag. * the PIXARLOGDATFMT pseudo-tag.
*/ */
if (sp->state&PLSTATE_INIT) {
/* We test the state to avoid an issue such as in
* http://bugzilla.maptools.org/show_bug.cgi?id=2604
* What appends in that case is that the bitspersample is 1 and
* a TransferFunction is set. The size of the TransferFunction
* depends on 1<<bitspersample. So if we increase it, an access
* out of the buffer will happen at directory flushing.
* Another option would be to clear those targs.
*/
td->td_bitspersample = 8; td->td_bitspersample = 8;
td->td_sampleformat = SAMPLEFORMAT_UINT; td->td_sampleformat = SAMPLEFORMAT_UINT;
}
} }
static void static void

View file

@ -1,4 +1,4 @@
/* $Id: tif_predict.c,v 1.40 2016-11-04 09:19:13 erouault Exp $ */ /* $Id: tif_predict.c,v 1.43 2017-05-10 15:21:16 erouault Exp $ */
/* /*
* Copyright (c) 1988-1997 Sam Leffler * Copyright (c) 1988-1997 Sam Leffler
@ -118,6 +118,9 @@ PredictorSetupDecode(TIFF* tif)
TIFFPredictorState* sp = PredictorState(tif); TIFFPredictorState* sp = PredictorState(tif);
TIFFDirectory* td = &tif->tif_dir; TIFFDirectory* td = &tif->tif_dir;
/* Note: when PredictorSetup() fails, the effets of setupdecode() */
/* will not be "cancelled" so setupdecode() might be robust to */
/* be called several times. */
if (!(*sp->setupdecode)(tif) || !PredictorSetup(tif)) if (!(*sp->setupdecode)(tif) || !PredictorSetup(tif))
return 0; return 0;
@ -260,11 +263,12 @@ PredictorSetupEncode(TIFF* tif)
#define REPEAT4(n, op) \ #define REPEAT4(n, op) \
switch (n) { \ switch (n) { \
default: { tmsize_t i; for (i = n-4; i > 0; i--) { op; } } \ default: { \
case 4: op; \ tmsize_t i; for (i = n-4; i > 0; i--) { op; } } /*-fallthrough*/ \
case 3: op; \ case 4: op; /*-fallthrough*/ \
case 2: op; \ case 3: op; /*-fallthrough*/ \
case 1: op; \ case 2: op; /*-fallthrough*/ \
case 1: op; /*-fallthrough*/ \
case 0: ; \ case 0: ; \
} }
@ -798,7 +802,7 @@ PredictorPrintDir(TIFF* tif, FILE* fd, long flags)
case 2: fprintf(fd, "horizontal differencing "); break; case 2: fprintf(fd, "horizontal differencing "); break;
case 3: fprintf(fd, "floating point predictor "); break; case 3: fprintf(fd, "floating point predictor "); break;
} }
fprintf(fd, "%u (0x%x)\n", sp->predictor, sp->predictor); fprintf(fd, "%d (0x%x)\n", sp->predictor, sp->predictor);
} }
if (sp->printdir) if (sp->printdir)
(*sp->printdir)(tif, fd, flags); (*sp->printdir)(tif, fd, flags);

View file

@ -1,4 +1,4 @@
/* $Id: tif_print.c,v 1.64 2015-12-06 22:19:56 erouault Exp $ */ /* $Id: tif_print.c,v 1.65 2016-11-20 22:31:22 erouault Exp $ */
/* /*
* Copyright (c) 1988-1997 Sam Leffler * Copyright (c) 1988-1997 Sam Leffler
@ -263,7 +263,7 @@ TIFFPrintDirectory(TIFF* tif, FILE* fd, long flags)
if (td->td_subfiletype & FILETYPE_MASK) if (td->td_subfiletype & FILETYPE_MASK)
fprintf(fd, "%stransparency mask", sep); fprintf(fd, "%stransparency mask", sep);
fprintf(fd, " (%lu = 0x%lx)\n", fprintf(fd, " (%lu = 0x%lx)\n",
(long) td->td_subfiletype, (long) td->td_subfiletype); (unsigned long) td->td_subfiletype, (long) td->td_subfiletype);
} }
if (TIFFFieldSet(tif,FIELD_IMAGEDIMENSIONS)) { if (TIFFFieldSet(tif,FIELD_IMAGEDIMENSIONS)) {
fprintf(fd, " Image Width: %lu Image Length: %lu", fprintf(fd, " Image Width: %lu Image Length: %lu",
@ -522,7 +522,7 @@ TIFFPrintDirectory(TIFF* tif, FILE* fd, long flags)
fprintf(fd, "\n"); fprintf(fd, "\n");
n = 1L<<td->td_bitspersample; n = 1L<<td->td_bitspersample;
for (l = 0; l < n; l++) for (l = 0; l < n; l++)
fprintf(fd, " %5lu: %5u %5u %5u\n", fprintf(fd, " %5ld: %5u %5u %5u\n",
l, l,
td->td_colormap[0][l], td->td_colormap[0][l],
td->td_colormap[1][l], td->td_colormap[1][l],
@ -545,7 +545,7 @@ TIFFPrintDirectory(TIFF* tif, FILE* fd, long flags)
n = 1L<<td->td_bitspersample; n = 1L<<td->td_bitspersample;
for (l = 0; l < n; l++) { for (l = 0; l < n; l++) {
uint16 i; uint16 i;
fprintf(fd, " %2lu: %5u", fprintf(fd, " %2ld: %5u",
l, td->td_transferfunction[0][l]); l, td->td_transferfunction[0][l]);
for (i = 1; i < td->td_samplesperpixel; i++) for (i = 1; i < td->td_samplesperpixel; i++)
fprintf(fd, " %5u", fprintf(fd, " %5u",
@ -662,7 +662,7 @@ TIFFPrintDirectory(TIFF* tif, FILE* fd, long flags)
uint32 s; uint32 s;
fprintf(fd, " %lu %s:\n", fprintf(fd, " %lu %s:\n",
(long) td->td_nstrips, (unsigned long) td->td_nstrips,
isTiled(tif) ? "Tiles" : "Strips"); isTiled(tif) ? "Tiles" : "Strips");
for (s = 0; s < td->td_nstrips; s++) for (s = 0; s < td->td_nstrips; s++)
#if defined(__WIN32__) && (defined(_MSC_VER) || defined(__MINGW32__)) #if defined(__WIN32__) && (defined(_MSC_VER) || defined(__MINGW32__))

View file

@ -1,4 +1,4 @@
/* $Id: tif_read.c,v 1.49 2016-07-10 18:00:21 erouault Exp $ */ /* $Id: tif_read.c,v 1.59 2017-05-13 15:34:06 erouault Exp $ */
/* /*
* Copyright (c) 1988-1997 Sam Leffler * Copyright (c) 1988-1997 Sam Leffler
@ -48,6 +48,121 @@ TIFFReadRawTile1(TIFF* tif, uint32 tile, void* buf, tmsize_t size, const char* m
#define NOSTRIP ((uint32)(-1)) /* undefined state */ #define NOSTRIP ((uint32)(-1)) /* undefined state */
#define NOTILE ((uint32)(-1)) /* undefined state */ #define NOTILE ((uint32)(-1)) /* undefined state */
#define INITIAL_THRESHOLD (1024 * 1024)
#define THRESHOLD_MULTIPLIER 10
#define MAX_THRESHOLD (THRESHOLD_MULTIPLIER * THRESHOLD_MULTIPLIER * THRESHOLD_MULTIPLIER * INITIAL_THRESHOLD)
/* Read 'size' bytes in tif_rawdata buffer starting at offset 'rawdata_offset'
* Returns 1 in case of success, 0 otherwise. */
static int TIFFReadAndRealloc( TIFF* tif, tmsize_t size,
tmsize_t rawdata_offset,
int is_strip, uint32 strip_or_tile,
const char* module )
{
#if SIZEOF_VOIDP == 8 || SIZEOF_SIZE_T == 8
tmsize_t threshold = INITIAL_THRESHOLD;
#endif
tmsize_t already_read = 0;
/* On 64 bit processes, read first a maximum of 1 MB, then 10 MB, etc */
/* so as to avoid allocating too much memory in case the file is too */
/* short. We could ask for the file size, but this might be */
/* expensive with some I/O layers (think of reading a gzipped file) */
/* Restrict to 64 bit processes, so as to avoid reallocs() */
/* on 32 bit processes where virtual memory is scarce. */
while( already_read < size )
{
tmsize_t bytes_read;
tmsize_t to_read = size - already_read;
#if SIZEOF_VOIDP == 8 || SIZEOF_SIZE_T == 8
if( to_read >= threshold && threshold < MAX_THRESHOLD &&
already_read + to_read + rawdata_offset > tif->tif_rawdatasize )
{
to_read = threshold;
threshold *= THRESHOLD_MULTIPLIER;
}
#endif
if (already_read + to_read + rawdata_offset > tif->tif_rawdatasize) {
uint8* new_rawdata;
assert((tif->tif_flags & TIFF_MYBUFFER) != 0);
tif->tif_rawdatasize = (tmsize_t)TIFFroundup_64(
(uint64)already_read + to_read + rawdata_offset, 1024);
if (tif->tif_rawdatasize==0) {
TIFFErrorExt(tif->tif_clientdata, module,
"Invalid buffer size");
return 0;
}
new_rawdata = (uint8*) _TIFFrealloc(
tif->tif_rawdata, tif->tif_rawdatasize);
if( new_rawdata == 0 )
{
TIFFErrorExt(tif->tif_clientdata, module,
"No space for data buffer at scanline %lu",
(unsigned long) tif->tif_row);
_TIFFfree(tif->tif_rawdata);
tif->tif_rawdata = 0;
tif->tif_rawdatasize = 0;
return 0;
}
tif->tif_rawdata = new_rawdata;
}
bytes_read = TIFFReadFile(tif,
tif->tif_rawdata + rawdata_offset + already_read, to_read);
already_read += bytes_read;
if (bytes_read != to_read) {
memset( tif->tif_rawdata + rawdata_offset + already_read, 0,
tif->tif_rawdatasize - rawdata_offset - already_read );
#if defined(__WIN32__) && (defined(_MSC_VER) || defined(__MINGW32__))
if( is_strip )
{
TIFFErrorExt(tif->tif_clientdata, module,
"Read error at scanline %lu; got %I64u bytes, "
"expected %I64u",
(unsigned long) tif->tif_row,
(unsigned __int64) already_read,
(unsigned __int64) size);
}
else
{
TIFFErrorExt(tif->tif_clientdata, module,
"Read error at row %lu, col %lu, tile %lu; "
"got %I64u bytes, expected %I64u",
(unsigned long) tif->tif_row,
(unsigned long) tif->tif_col,
(unsigned long) strip_or_tile,
(unsigned __int64) already_read,
(unsigned __int64) size);
}
#else
if( is_strip )
{
TIFFErrorExt(tif->tif_clientdata, module,
"Read error at scanline %lu; got %llu bytes, "
"expected %llu",
(unsigned long) tif->tif_row,
(unsigned long long) already_read,
(unsigned long long) size);
}
else
{
TIFFErrorExt(tif->tif_clientdata, module,
"Read error at row %lu, col %lu, tile %lu; "
"got %llu bytes, expected %llu",
(unsigned long) tif->tif_row,
(unsigned long) tif->tif_col,
(unsigned long) strip_or_tile,
(unsigned long long) already_read,
(unsigned long long) size);
}
#endif
return 0;
}
}
return 1;
}
static int static int
TIFFFillStripPartial( TIFF *tif, int strip, tmsize_t read_ahead, int restart ) TIFFFillStripPartial( TIFF *tif, int strip, tmsize_t read_ahead, int restart )
{ {
@ -55,7 +170,8 @@ TIFFFillStripPartial( TIFF *tif, int strip, tmsize_t read_ahead, int restart )
register TIFFDirectory *td = &tif->tif_dir; register TIFFDirectory *td = &tif->tif_dir;
tmsize_t unused_data; tmsize_t unused_data;
uint64 read_offset; uint64 read_offset;
tmsize_t cc, to_read; tmsize_t to_read;
tmsize_t read_ahead_mod;
/* tmsize_t bytecountm; */ /* tmsize_t bytecountm; */
if (!_TIFFFillStriles( tif ) || !tif->tif_dir.td_stripbytecount) if (!_TIFFFillStriles( tif ) || !tif->tif_dir.td_stripbytecount)
@ -68,7 +184,14 @@ TIFFFillStripPartial( TIFF *tif, int strip, tmsize_t read_ahead, int restart )
*/ */
/* bytecountm=(tmsize_t) td->td_stripbytecount[strip]; */ /* bytecountm=(tmsize_t) td->td_stripbytecount[strip]; */
if (read_ahead*2 > tif->tif_rawdatasize) {
/* Not completely sure where the * 2 comes from, but probably for */
/* an exponentional growth strategy of tif_rawdatasize */
if( read_ahead < TIFF_TMSIZE_T_MAX / 2 )
read_ahead_mod = read_ahead * 2;
else
read_ahead_mod = read_ahead;
if (read_ahead_mod > tif->tif_rawdatasize) {
assert( restart ); assert( restart );
tif->tif_curstrip = NOSTRIP; tif->tif_curstrip = NOSTRIP;
@ -78,8 +201,6 @@ TIFFFillStripPartial( TIFF *tif, int strip, tmsize_t read_ahead, int restart )
(unsigned long) strip); (unsigned long) strip);
return (0); return (0);
} }
if (!TIFFReadBufferSetup(tif, 0, read_ahead*2))
return (0);
} }
if( restart ) if( restart )
@ -119,6 +240,9 @@ TIFFFillStripPartial( TIFF *tif, int strip, tmsize_t read_ahead, int restart )
/* /*
** How much do we want to read? ** How much do we want to read?
*/ */
if( read_ahead_mod > tif->tif_rawdatasize )
to_read = read_ahead_mod - unused_data;
else
to_read = tif->tif_rawdatasize - unused_data; to_read = tif->tif_rawdatasize - unused_data;
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 )
@ -128,22 +252,11 @@ TIFFFillStripPartial( TIFF *tif, int strip, tmsize_t read_ahead, int restart )
} }
assert((tif->tif_flags&TIFF_BUFFERMMAP)==0); assert((tif->tif_flags&TIFF_BUFFERMMAP)==0);
cc = TIFFReadFile(tif, tif->tif_rawdata + unused_data, to_read); if( !TIFFReadAndRealloc( tif, to_read, unused_data,
1, /* is_strip */
if (cc != to_read) { 0, /* strip_or_tile */
#if defined(__WIN32__) && (defined(_MSC_VER) || defined(__MINGW32__)) module) )
TIFFErrorExt(tif->tif_clientdata, module, {
"Read error at scanline %lu; got %I64u bytes, expected %I64u",
(unsigned long) tif->tif_row,
(unsigned __int64) cc,
(unsigned __int64) to_read);
#else
TIFFErrorExt(tif->tif_clientdata, module,
"Read error at scanline %lu; got %llu bytes, expected %llu",
(unsigned long) tif->tif_row,
(unsigned long long) cc,
(unsigned long long) to_read);
#endif
return 0; return 0;
} }
@ -165,7 +278,10 @@ TIFFFillStripPartial( TIFF *tif, int strip, tmsize_t read_ahead, int restart )
if( restart ) if( restart )
return TIFFStartStrip(tif, strip); return TIFFStartStrip(tif, strip);
else else
{
tif->tif_rawcc = tif->tif_rawdataloaded;
return 1; return 1;
}
} }
/* /*
@ -219,9 +335,20 @@ TIFFSeek(TIFF* tif, uint32 row, uint16 sample )
#endif #endif
if( !whole_strip ) if( !whole_strip )
{
/* 16 is for YCbCr mode where we may need to read 16 */
/* lines at a time to get a decompressed line, and 5000 */
/* is some constant value, for example for JPEG tables */
if( tif->tif_scanlinesize < TIFF_TMSIZE_T_MAX / 16 &&
tif->tif_scanlinesize * 16 < TIFF_TMSIZE_T_MAX - 5000 )
{ {
read_ahead = tif->tif_scanlinesize * 16 + 5000; read_ahead = tif->tif_scanlinesize * 16 + 5000;
} }
else
{
read_ahead = tif->tif_scanlinesize;
}
}
/* /*
* If we haven't loaded this strip, do so now, possibly * If we haven't loaded this strip, do so now, possibly
@ -347,7 +474,7 @@ TIFFReadEncodedStrip(TIFF* tif, uint32 strip, void* buf, tmsize_t size)
rowsperstrip=td->td_rowsperstrip; rowsperstrip=td->td_rowsperstrip;
if (rowsperstrip>td->td_imagelength) if (rowsperstrip>td->td_imagelength)
rowsperstrip=td->td_imagelength; rowsperstrip=td->td_imagelength;
stripsperplane=((td->td_imagelength+rowsperstrip-1)/rowsperstrip); stripsperplane= TIFFhowmany_32_maxuint_compat(td->td_imagelength, rowsperstrip);
stripinplane=(strip%stripsperplane); stripinplane=(strip%stripsperplane);
plane=(uint16)(strip/stripsperplane); plane=(uint16)(strip/stripsperplane);
rows=td->td_imagelength-stripinplane*rowsperstrip; rows=td->td_imagelength-stripinplane*rowsperstrip;
@ -421,16 +548,25 @@ TIFFReadRawStrip1(TIFF* tif, uint32 strip, void* buf, tmsize_t size,
return ((tmsize_t)(-1)); return ((tmsize_t)(-1));
} }
} else { } else {
tmsize_t ma,mb; tmsize_t ma = 0;
tmsize_t n; tmsize_t n;
ma=(tmsize_t)td->td_stripoffset[strip]; if ((td->td_stripoffset[strip] > (uint64)TIFF_TMSIZE_T_MAX)||
mb=ma+size; ((ma=(tmsize_t)td->td_stripoffset[strip])>tif->tif_size))
if ((td->td_stripoffset[strip] > (uint64)TIFF_TMSIZE_T_MAX)||(ma>tif->tif_size)) {
n=0; n=0;
else if ((mb<ma)||(mb<size)||(mb>tif->tif_size)) }
else if( ma > TIFF_TMSIZE_T_MAX - size )
{
n=0;
}
else
{
tmsize_t mb=ma+size;
if (mb>tif->tif_size)
n=tif->tif_size-ma; n=tif->tif_size-ma;
else else
n=size; n=size;
}
if (n!=size) { if (n!=size) {
#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,
@ -455,6 +591,43 @@ TIFFReadRawStrip1(TIFF* tif, uint32 strip, void* buf, tmsize_t size,
return (size); return (size);
} }
static tmsize_t
TIFFReadRawStripOrTile2(TIFF* tif, uint32 strip_or_tile, int is_strip,
tmsize_t size, const char* module)
{
TIFFDirectory *td = &tif->tif_dir;
assert( !isMapped(tif) );
assert((tif->tif_flags&TIFF_NOREADRAW)==0);
if (!SeekOK(tif, td->td_stripoffset[strip_or_tile])) {
if( is_strip )
{
TIFFErrorExt(tif->tif_clientdata, module,
"Seek error at scanline %lu, strip %lu",
(unsigned long) tif->tif_row,
(unsigned long) strip_or_tile);
}
else
{
TIFFErrorExt(tif->tif_clientdata, module,
"Seek error at row %lu, col %lu, tile %lu",
(unsigned long) tif->tif_row,
(unsigned long) tif->tif_col,
(unsigned long) strip_or_tile);
}
return ((tmsize_t)(-1));
}
if( !TIFFReadAndRealloc( tif, size, 0, is_strip,
strip_or_tile, module ) )
{
return ((tmsize_t)(-1));
}
return (size);
}
/* /*
* Read a strip of data from the file. * Read a strip of data from the file.
*/ */
@ -536,6 +709,39 @@ TIFFFillStrip(TIFF* tif, uint32 strip)
#endif #endif
return (0); return (0);
} }
/* To avoid excessive memory allocations: */
/* Byte count should normally not be larger than a number of */
/* times the uncompressed size plus some margin */
if( bytecount > 1024 * 1024 )
{
/* 10 and 4096 are just values that could be adjusted. */
/* Hopefully they are safe enough for all codecs */
tmsize_t stripsize = TIFFStripSize(tif);
if( stripsize != 0 &&
(bytecount - 4096) / 10 > (uint64)stripsize )
{
uint64 newbytecount = (uint64)stripsize * 10 + 4096;
if( (int64)newbytecount >= 0 )
{
#if defined(__WIN32__) && (defined(_MSC_VER) || defined(__MINGW32__))
TIFFWarningExt(tif->tif_clientdata, module,
"Too large strip byte count %I64u, strip %lu. Limiting to %I64u",
(unsigned __int64) bytecount,
(unsigned long) strip,
(unsigned __int64) newbytecount);
#else
TIFFErrorExt(tif->tif_clientdata, module,
"Too large strip byte count %llu, strip %lu. Limiting to %llu",
(unsigned long long) bytecount,
(unsigned long) strip,
(unsigned long long) newbytecount);
#endif
bytecount = newbytecount;
}
}
}
if (isMapped(tif) && if (isMapped(tif) &&
(isFillOrder(tif, td->td_fillorder) (isFillOrder(tif, td->td_fillorder)
|| (tif->tif_flags & TIFF_NOBITREV))) { || (tif->tif_flags & TIFF_NOBITREV))) {
@ -625,17 +831,36 @@ TIFFFillStrip(TIFF* tif, uint32 strip)
(unsigned long) strip); (unsigned long) strip);
return (0); return (0);
} }
if (!TIFFReadBufferSetup(tif, 0, bytecountm))
return (0);
} }
if (tif->tif_flags&TIFF_BUFFERMMAP) { if (tif->tif_flags&TIFF_BUFFERMMAP) {
tif->tif_curstrip = NOSTRIP; tif->tif_curstrip = NOSTRIP;
if (!TIFFReadBufferSetup(tif, 0, bytecountm)) tif->tif_rawdata = NULL;
tif->tif_rawdatasize = 0;
tif->tif_flags &= ~TIFF_BUFFERMMAP;
}
if( isMapped(tif) )
{
if (bytecountm > tif->tif_rawdatasize &&
!TIFFReadBufferSetup(tif, 0, bytecountm))
{
return (0); 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);
}
}
else
{
if (TIFFReadRawStripOrTile2(tif, strip, 1,
bytecountm, module) != bytecountm)
{
return (0);
}
}
tif->tif_rawdataoff = 0; tif->tif_rawdataoff = 0;
tif->tif_rawdataloaded = bytecountm; tif->tif_rawdataloaded = bytecountm;
@ -918,18 +1143,36 @@ TIFFFillTile(TIFF* tif, uint32 tile)
(unsigned long) tile); (unsigned long) tile);
return (0); return (0);
} }
if (!TIFFReadBufferSetup(tif, 0, bytecountm))
return (0);
} }
if (tif->tif_flags&TIFF_BUFFERMMAP) { if (tif->tif_flags&TIFF_BUFFERMMAP) {
tif->tif_curtile = NOTILE; tif->tif_curtile = NOTILE;
if (!TIFFReadBufferSetup(tif, 0, bytecountm)) tif->tif_rawdata = NULL;
return (0); tif->tif_rawdatasize = 0;
tif->tif_flags &= ~TIFF_BUFFERMMAP;
} }
if( isMapped(tif) )
{
if (bytecountm > tif->tif_rawdatasize &&
!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);
}
}
else
{
if (TIFFReadRawStripOrTile2(tif, tile, 0,
bytecountm, module) != bytecountm)
{
return (0);
}
}
tif->tif_rawdataoff = 0; tif->tif_rawdataoff = 0;
tif->tif_rawdataloaded = bytecountm; tif->tif_rawdataloaded = bytecountm;
@ -977,7 +1220,9 @@ TIFFReadBufferSetup(TIFF* tif, void* bp, tmsize_t size)
"Invalid buffer size"); "Invalid buffer size");
return (0); return (0);
} }
tif->tif_rawdata = (uint8*) _TIFFmalloc(tif->tif_rawdatasize); /* Initialize to zero to avoid uninitialized buffers in case of */
/* short reads (http://bugzilla.maptools.org/show_bug.cgi?id=2651) */
tif->tif_rawdata = (uint8*) _TIFFcalloc(1, tif->tif_rawdatasize);
tif->tif_flags |= TIFF_MYBUFFER; tif->tif_flags |= TIFF_MYBUFFER;
} }
if (tif->tif_rawdata == NULL) { if (tif->tif_rawdata == NULL) {
@ -1019,6 +1264,9 @@ TIFFStartStrip(TIFF* tif, uint32 strip)
else else
{ {
tif->tif_rawcp = tif->tif_rawdata; tif->tif_rawcp = tif->tif_rawdata;
if( tif->tif_rawdataloaded > 0 )
tif->tif_rawcc = tif->tif_rawdataloaded;
else
tif->tif_rawcc = (tmsize_t)td->td_stripbytecount[strip]; tif->tif_rawcc = (tmsize_t)td->td_stripbytecount[strip];
} }
return ((*tif->tif_predecode)(tif, return ((*tif->tif_predecode)(tif,

View file

@ -1,4 +1,4 @@
/* $Id: tif_strip.c,v 1.37 2016-11-09 23:00:49 erouault Exp $ */ /* $Id: tif_strip.c,v 1.38 2016-12-03 11:02:15 erouault Exp $ */
/* /*
* Copyright (c) 1991-1997 Sam Leffler * Copyright (c) 1991-1997 Sam Leffler
@ -64,15 +64,6 @@ TIFFNumberOfStrips(TIFF* tif)
TIFFDirectory *td = &tif->tif_dir; TIFFDirectory *td = &tif->tif_dir;
uint32 nstrips; uint32 nstrips;
/* If the value was already computed and store in td_nstrips, then return it,
since ChopUpSingleUncompressedStrip might have altered and resized the
since the td_stripbytecount and td_stripoffset arrays to the new value
after the initial affectation of td_nstrips = TIFFNumberOfStrips() in
tif_dirread.c ~line 3612.
See http://bugzilla.maptools.org/show_bug.cgi?id=2587 */
if( td->td_nstrips )
return td->td_nstrips;
nstrips = (td->td_rowsperstrip == (uint32) -1 ? 1 : nstrips = (td->td_rowsperstrip == (uint32) -1 ? 1 :
TIFFhowmany_32(td->td_imagelength, td->td_rowsperstrip)); TIFFhowmany_32(td->td_imagelength, td->td_rowsperstrip));
if (td->td_planarconfig == PLANARCONFIG_SEPARATE) if (td->td_planarconfig == PLANARCONFIG_SEPARATE)

View file

@ -1,4 +1,4 @@
/* $Id: tif_unix.c,v 1.27 2015-08-19 02:31:04 bfriesen Exp $ */ /* $Id: tif_unix.c,v 1.28 2017-01-11 19:02:49 erouault Exp $ */
/* /*
* Copyright (c) 1988-1997 Sam Leffler * Copyright (c) 1988-1997 Sam Leffler
@ -316,6 +316,14 @@ _TIFFmalloc(tmsize_t s)
return (malloc((size_t) s)); return (malloc((size_t) s));
} }
void* _TIFFcalloc(tmsize_t nmemb, tmsize_t siz)
{
if( nmemb == 0 || siz == 0 )
return ((void *) NULL);
return calloc((size_t) nmemb, (size_t)siz);
}
void void
_TIFFfree(void* p) _TIFFfree(void* p)
{ {

View file

@ -1,4 +1,4 @@
/* $Id: tif_win32.c,v 1.41 2015-08-23 20:12:44 bfriesen Exp $ */ /* $Id: tif_win32.c,v 1.42 2017-01-11 19:02:49 erouault Exp $ */
/* /*
* Copyright (c) 1988-1997 Sam Leffler * Copyright (c) 1988-1997 Sam Leffler
@ -364,6 +364,14 @@ _TIFFmalloc(tmsize_t s)
return (malloc((size_t) s)); return (malloc((size_t) s));
} }
void* _TIFFcalloc(tmsize_t nmemb, tmsize_t siz)
{
if( nmemb == 0 || siz == 0 )
return ((void *) NULL);
return calloc((size_t) nmemb, (size_t)siz);
}
void void
_TIFFfree(void* p) _TIFFfree(void* p)
{ {

View file

@ -1,4 +1,4 @@
/* $Id: tif_write.c,v 1.45 2016-09-23 22:12:18 erouault Exp $ */ /* $Id: tif_write.c,v 1.46 2016-12-03 21:57:44 erouault Exp $ */
/* /*
* Copyright (c) 1988-1997 Sam Leffler * Copyright (c) 1988-1997 Sam Leffler

View file

@ -1,4 +1,4 @@
/* $Id: tif_zip.c,v 1.36 2016-11-12 16:48:28 erouault Exp $ */ /* $Id: tif_zip.c,v 1.37 2017-05-10 15:21:16 erouault Exp $ */
/* /*
* Copyright (c) 1995-1997 Sam Leffler * Copyright (c) 1995-1997 Sam Leffler
@ -108,7 +108,11 @@ ZIPSetupDecode(TIFF* tif)
sp->state = 0; sp->state = 0;
} }
if (inflateInit(&sp->stream) != Z_OK) { /* This function can possibly be called several times by */
/* PredictorSetupDecode() if this function succeeds but */
/* PredictorSetup() fails */
if ((sp->state & ZSTATE_INIT_DECODE) == 0 &&
inflateInit(&sp->stream) != Z_OK) {
TIFFErrorExt(tif->tif_clientdata, module, "%s", SAFE_MSG(sp)); TIFFErrorExt(tif->tif_clientdata, module, "%s", SAFE_MSG(sp));
return (0); return (0);
} else { } else {

View file

@ -1,4 +1,4 @@
/* $Id: tif_fax3.h,v 1.11 2016-01-23 21:20:34 erouault Exp $ */ /* $Id: tif_fax3.h,v 1.13 2016-12-14 18:36:27 faxguy Exp $ */
/* /*
* Copyright (c) 1990-1997 Sam Leffler * Copyright (c) 1990-1997 Sam Leffler
@ -81,10 +81,12 @@ extern void _TIFFFax3fillruns(unsigned char*, uint32*, uint32*, uint32);
#define S_MakeUp 11 #define S_MakeUp 11
#define S_EOL 12 #define S_EOL 12
/* WARNING: do not change the layout of this structure as the HylaFAX software */
/* really depends on it. See http://bugzilla.maptools.org/show_bug.cgi?id=2636 */
typedef struct { /* state table entry */ typedef struct { /* state table entry */
unsigned char State; /* see above */ unsigned char State; /* see above */
unsigned char Width; /* width of code in bits */ unsigned char Width; /* width of code in bits */
uint16 Param; /* unsigned 16-bit run length in bits */ uint32 Param; /* unsigned 32-bit run length in bits (holds on 16 bit actually, but cannot be changed. See above warning) */
} TIFFFaxTabEnt; } TIFFFaxTabEnt;
extern const TIFFFaxTabEnt TIFFFaxMainTable[]; extern const TIFFFaxTabEnt TIFFFaxMainTable[];

View file

@ -1,4 +1,4 @@
/* $Id: tiffio.h,v 1.92 2016-01-23 21:20:34 erouault Exp $ */ /* $Id: tiffio.h,v 1.94 2017-01-11 19:02:49 erouault Exp $ */
/* /*
* Copyright (c) 1988-1997 Sam Leffler * Copyright (c) 1988-1997 Sam Leffler
@ -295,6 +295,7 @@ extern TIFFCodec* TIFFGetConfiguredCODECs(void);
*/ */
extern void* _TIFFmalloc(tmsize_t s); extern void* _TIFFmalloc(tmsize_t s);
extern void* _TIFFcalloc(tmsize_t nmemb, tmsize_t siz);
extern void* _TIFFrealloc(void* p, tmsize_t s); extern void* _TIFFrealloc(void* p, tmsize_t s);
extern void _TIFFmemset(void* p, int v, tmsize_t c); extern void _TIFFmemset(void* p, int v, tmsize_t c);
extern void _TIFFmemcpy(void* d, const void* s, tmsize_t c); extern void _TIFFmemcpy(void* d, const void* s, tmsize_t c);
@ -432,6 +433,8 @@ extern int TIFFReadRGBAImageOriented(TIFF*, uint32, uint32, uint32*, int, int);
extern int TIFFReadRGBAStrip(TIFF*, uint32, uint32 * ); extern int TIFFReadRGBAStrip(TIFF*, uint32, uint32 * );
extern int TIFFReadRGBATile(TIFF*, uint32, uint32, uint32 * ); extern int TIFFReadRGBATile(TIFF*, uint32, uint32, uint32 * );
extern int TIFFReadRGBAStripExt(TIFF*, uint32, uint32 *, int stop_on_error );
extern int TIFFReadRGBATileExt(TIFF*, uint32, uint32, uint32 *, int stop_on_error );
extern int TIFFRGBAImageOK(TIFF*, char [1024]); extern int TIFFRGBAImageOK(TIFF*, char [1024]);
extern int TIFFRGBAImageBegin(TIFFRGBAImage*, TIFF*, int, char [1024]); extern int TIFFRGBAImageBegin(TIFFRGBAImage*, TIFF*, int, char [1024]);
extern int TIFFRGBAImageGet(TIFFRGBAImage*, uint32*, uint32, uint32); extern int TIFFRGBAImageGet(TIFFRGBAImage*, uint32*, uint32, uint32);

View file

@ -1,4 +1,4 @@
/* $Id: tiffiop.h,v 1.89 2016-01-23 21:20:34 erouault Exp $ */ /* $Id: tiffiop.h,v 1.90 2016-12-02 21:56:56 erouault Exp $ */
/* /*
* Copyright (c) 1988-1997 Sam Leffler * Copyright (c) 1988-1997 Sam Leffler
@ -250,6 +250,10 @@ struct tiff {
#define TIFFhowmany_32(x, y) (((uint32)x < (0xffffffff - (uint32)(y-1))) ? \ #define TIFFhowmany_32(x, y) (((uint32)x < (0xffffffff - (uint32)(y-1))) ? \
((((uint32)(x))+(((uint32)(y))-1))/((uint32)(y))) : \ ((((uint32)(x))+(((uint32)(y))-1))/((uint32)(y))) : \
0U) 0U)
/* Variant of TIFFhowmany_32() that doesn't return 0 if x close to MAXUINT. */
/* Caution: TIFFhowmany_32_maxuint_compat(x,y)*y might overflow */
#define TIFFhowmany_32_maxuint_compat(x, y) \
(((uint32)(x) / (uint32)(y)) + ((((uint32)(x) % (uint32)(y)) != 0) ? 1 : 0))
#define TIFFhowmany8_32(x) (((x)&0x07)?((uint32)(x)>>3)+1:(uint32)(x)>>3) #define TIFFhowmany8_32(x) (((x)&0x07)?((uint32)(x)>>3)+1:(uint32)(x)>>3)
#define TIFFroundup_32(x, y) (TIFFhowmany_32(x,y)*(y)) #define TIFFroundup_32(x, y) (TIFFhowmany_32(x,y)*(y))
#define TIFFhowmany_64(x, y) ((((uint64)(x))+(((uint64)(y))-1))/((uint64)(y))) #define TIFFhowmany_64(x, y) ((((uint64)(x))+(((uint64)(y))-1))/((uint64)(y)))

View file

@ -1,4 +1,4 @@
#define TIFFLIB_VERSION_STR "LIBTIFF, Version 4.0.7\nCopyright (c) 1988-1996 Sam Leffler\nCopyright (c) 1991-1996 Silicon Graphics, Inc." #define TIFFLIB_VERSION_STR "LIBTIFF, Version 4.0.8\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 20161119 #define TIFFLIB_VERSION 20170521