summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'tiff/libtiff/tif_dir.c')
-rw-r--r--tiff/libtiff/tif_dir.c96
1 files changed, 57 insertions, 39 deletions
diff --git a/tiff/libtiff/tif_dir.c b/tiff/libtiff/tif_dir.c
index f00f8080..1e0a76c3 100644
--- a/tiff/libtiff/tif_dir.c
+++ b/tiff/libtiff/tif_dir.c
@@ -1,5 +1,3 @@
-/* $Id: tif_dir.c,v 1.131 2017-07-11 21:38:04 erouault Exp $ */
-
/*
* Copyright (c) 1988-1997 Sam Leffler
* Copyright (c) 1991-1997 Silicon Graphics, Inc.
@@ -31,7 +29,6 @@
* (and also some miscellaneous stuff)
*/
#include "tiffiop.h"
-#include <float.h>
/*
* These are used in the backwards compatibility code...
@@ -49,8 +46,8 @@ setByteArray(void** vpp, void* vp, size_t nmemb, size_t elem_size)
*vpp = 0;
}
if (vp) {
- tmsize_t bytes = (tmsize_t)(nmemb * elem_size);
- if (elem_size && bytes / elem_size == nmemb)
+ tmsize_t bytes = _TIFFMultiplySSize(NULL, nmemb, elem_size, NULL);
+ if (bytes)
*vpp = (void*) _TIFFmalloc(bytes);
if (*vpp)
_TIFFmemcpy(*vpp, vp, bytes);
@@ -90,13 +87,15 @@ setDoubleArrayOneValue(double** vpp, double value, size_t nmemb)
* Install extra samples information.
*/
static int
-setExtraSamples(TIFFDirectory* td, va_list ap, uint32* v)
+setExtraSamples(TIFF* tif, va_list ap, uint32* v)
{
/* XXX: Unassociated alpha data == 999 is a known Corel Draw bug, see below */
#define EXTRASAMPLE_COREL_UNASSALPHA 999
uint16* va;
uint32 i;
+ TIFFDirectory* td = &tif->tif_dir;
+ static const char module[] = "setExtraSamples";
*v = (uint16) va_arg(ap, uint16_vap);
if ((uint16) *v > td->td_samplesperpixel)
@@ -118,6 +117,18 @@ setExtraSamples(TIFFDirectory* td, va_list ap, uint32* v)
return 0;
}
}
+
+ if ( td->td_transferfunction[0] != NULL && (td->td_samplesperpixel - *v > 1) &&
+ !(td->td_samplesperpixel - td->td_extrasamples > 1))
+ {
+ TIFFWarningExt(tif->tif_clientdata,module,
+ "ExtraSamples tag value is changing, "
+ "but TransferFunction was read with a different value. Cancelling it");
+ TIFFClrFieldBit(tif,FIELD_TRANSFERFUNCTION);
+ _TIFFfree(td->td_transferfunction[0]);
+ td->td_transferfunction[0] = NULL;
+ }
+
td->td_extrasamples = (uint16) *v;
_TIFFsetShortArray(&td->td_sampleinfo, va, td->td_extrasamples);
return 1;
@@ -155,15 +166,6 @@ bad:
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
_TIFFVSetField(TIFF* tif, uint32 tag, va_list ap)
{
@@ -287,6 +289,18 @@ _TIFFVSetField(TIFF* tif, uint32 tag, va_list ap)
_TIFFfree(td->td_smaxsamplevalue);
td->td_smaxsamplevalue = NULL;
}
+ /* Test if 3 transfer functions instead of just one are now needed
+ See http://bugzilla.maptools.org/show_bug.cgi?id=2820 */
+ if( td->td_transferfunction[0] != NULL && (v - td->td_extrasamples > 1) &&
+ !(td->td_samplesperpixel - td->td_extrasamples > 1))
+ {
+ TIFFWarningExt(tif->tif_clientdata,module,
+ "SamplesPerPixel tag value is changing, "
+ "but TransferFunction was read with a different value. Cancelling it");
+ TIFFClrFieldBit(tif,FIELD_TRANSFERFUNCTION);
+ _TIFFfree(td->td_transferfunction[0]);
+ td->td_transferfunction[0] = NULL;
+ }
}
td->td_samplesperpixel = (uint16) v;
break;
@@ -322,13 +336,13 @@ _TIFFVSetField(TIFF* tif, uint32 tag, va_list ap)
dblval = va_arg(ap, double);
if( dblval < 0 )
goto badvaluedouble;
- td->td_xresolution = TIFFClampDoubleToFloat( dblval );
+ td->td_xresolution = _TIFFClampDoubleToFloat( dblval );
break;
case TIFFTAG_YRESOLUTION:
dblval = va_arg(ap, double);
if( dblval < 0 )
goto badvaluedouble;
- td->td_yresolution = TIFFClampDoubleToFloat( dblval );
+ td->td_yresolution = _TIFFClampDoubleToFloat( dblval );
break;
case TIFFTAG_PLANARCONFIG:
v = (uint16) va_arg(ap, uint16_vap);
@@ -337,10 +351,10 @@ _TIFFVSetField(TIFF* tif, uint32 tag, va_list ap)
td->td_planarconfig = (uint16) v;
break;
case TIFFTAG_XPOSITION:
- td->td_xposition = TIFFClampDoubleToFloat( va_arg(ap, double) );
+ td->td_xposition = _TIFFClampDoubleToFloat( va_arg(ap, double) );
break;
case TIFFTAG_YPOSITION:
- td->td_yposition = TIFFClampDoubleToFloat( va_arg(ap, double) );
+ td->td_yposition = _TIFFClampDoubleToFloat( va_arg(ap, double) );
break;
case TIFFTAG_RESOLUTIONUNIT:
v = (uint16) va_arg(ap, uint16_vap);
@@ -363,7 +377,7 @@ _TIFFVSetField(TIFF* tif, uint32 tag, va_list ap)
_TIFFsetShortArray(&td->td_colormap[2], va_arg(ap, uint16*), v32);
break;
case TIFFTAG_EXTRASAMPLES:
- if (!setExtraSamples(td, ap, &v))
+ if (!setExtraSamples(tif, ap, &v))
goto badvalue;
break;
case TIFFTAG_MATTEING:
@@ -686,7 +700,7 @@ _TIFFVSetField(TIFF* tif, uint32 tag, va_list ap)
case TIFF_SRATIONAL:
case TIFF_FLOAT:
{
- float v2 = TIFFClampDoubleToFloat(va_arg(ap, double));
+ float v2 = _TIFFClampDoubleToFloat(va_arg(ap, double));
_TIFFmemcpy(val, &v2, tv_size);
}
break;
@@ -863,14 +877,24 @@ _TIFFVGetField(TIFF* tif, uint32 tag, va_list ap)
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 (i.e. EXIF)
+ */
+ if (fip->field_bit == FIELD_CUSTOM) {
+ standard_tag = 0;
+ }
- if( tag == TIFFTAG_NUMBEROFINKS )
+ if( standard_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)
+ if (tv->info->field_tag != standard_tag)
continue;
if( tv->value == NULL )
return 0;
@@ -892,16 +916,6 @@ _TIFFVGetField(TIFF* tif, uint32 tag, va_list ap)
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 (i.e. EXIF)
- */
- if (fip->field_bit == FIELD_CUSTOM) {
- standard_tag = 0;
- }
-
switch (standard_tag) {
case TIFFTAG_SUBFILETYPE:
*va_arg(ap, uint32*) = td->td_subfiletype;
@@ -1004,12 +1018,12 @@ _TIFFVGetField(TIFF* tif, uint32 tag, va_list ap)
case TIFFTAG_STRIPOFFSETS:
case TIFFTAG_TILEOFFSETS:
_TIFFFillStriles( tif );
- *va_arg(ap, uint64**) = td->td_stripoffset;
+ *va_arg(ap, uint64**) = td->td_stripoffset_p;
break;
case TIFFTAG_STRIPBYTECOUNTS:
case TIFFTAG_TILEBYTECOUNTS:
_TIFFFillStriles( tif );
- *va_arg(ap, uint64**) = td->td_stripbytecount;
+ *va_arg(ap, uint64**) = td->td_stripbytecount_p;
break;
case TIFFTAG_MATTEING:
*va_arg(ap, uint16*) =
@@ -1067,6 +1081,9 @@ _TIFFVGetField(TIFF* tif, uint32 tag, va_list ap)
if (td->td_samplesperpixel - td->td_extrasamples > 1) {
*va_arg(ap, uint16**) = td->td_transferfunction[1];
*va_arg(ap, uint16**) = td->td_transferfunction[2];
+ } else {
+ *va_arg(ap, uint16**) = NULL;
+ *va_arg(ap, uint16**) = NULL;
}
break;
case TIFFTAG_REFERENCEBLACKWHITE:
@@ -1265,8 +1282,9 @@ TIFFFreeDirectory(TIFF* tif)
CleanupField(td_transferfunction[0]);
CleanupField(td_transferfunction[1]);
CleanupField(td_transferfunction[2]);
- CleanupField(td_stripoffset);
- CleanupField(td_stripbytecount);
+ CleanupField(td_stripoffset_p);
+ CleanupField(td_stripbytecount_p);
+ td->td_stripoffsetbyteallocsize = 0;
TIFFClrFieldBit(tif, FIELD_YCBCRSUBSAMPLING);
TIFFClrFieldBit(tif, FIELD_YCBCRPOSITIONING);
@@ -1279,10 +1297,8 @@ TIFFFreeDirectory(TIFF* tif)
td->td_customValueCount = 0;
CleanupField(td_customValues);
-#if defined(DEFER_STRILE_LOAD)
_TIFFmemset( &(td->td_stripoffset_entry), 0, sizeof(TIFFDirEntry));
_TIFFmemset( &(td->td_stripbytecount_entry), 0, sizeof(TIFFDirEntry));
-#endif
}
#undef CleanupField
@@ -1370,7 +1386,9 @@ TIFFDefaultDirectory(TIFF* tif)
td->td_tilewidth = 0;
td->td_tilelength = 0;
td->td_tiledepth = 1;
+#ifdef STRIPBYTECOUNTSORTED_UNUSED
td->td_stripbytecountsorted = 1; /* Our own arrays always sorted. */
+#endif
td->td_resolutionunit = RESUNIT_INCH;
td->td_sampleformat = SAMPLEFORMAT_UINT;
td->td_imagedepth = 1;