Commit f937ad5a authored by Alexandre Julliard's avatar Alexandre Julliard

tiff: Import upstream release 4.4.0.

parent be227979
......@@ -80,10 +80,15 @@ TIFFCleanup(TIFF* tif)
for (i = 0; i < tif->tif_nfields; i++) {
TIFFField *fld = tif->tif_fields[i];
if (fld->field_bit == FIELD_CUSTOM &&
strncmp("Tag ", fld->field_name, 4) == 0) {
_TIFFfree(fld->field_name);
_TIFFfree(fld);
if (fld->field_name != NULL) {
if (fld->field_bit == FIELD_CUSTOM &&
/* caution: tif_fields[i] must not be the beginning of a fields-array.
* Otherwise the following tags are also freed with the first free().
*/
TIFFFieldIsAnonymous(fld)) {
_TIFFfree(fld->field_name);
_TIFFfree(fld);
}
}
}
......
......@@ -99,7 +99,7 @@
#define PACKAGE_NAME "LibTIFF Software"
/* Define to the full name and version of this package. */
#define PACKAGE_STRING "LibTIFF Software 4.3.0"
#define PACKAGE_STRING "LibTIFF Software 4.4.0"
/* Define to the one symbol short name of this package. */
#define PACKAGE_TARNAME "tiff"
......@@ -108,10 +108,10 @@
#define PACKAGE_URL ""
/* Define to the version of this package. */
#define PACKAGE_VERSION "4.3.0"
#define PACKAGE_VERSION "4.4.0"
/* The size of `size_t', as computed by sizeof. */
/* #undef SIZEOF_SIZE_T */
#define SIZEOF_SIZE_T 4
/* Default size of the strip in bytes (when strip chopping enabled) */
#define STRIP_SIZE_DEFAULT 8192
......@@ -120,7 +120,7 @@
#define USE_WIN32_FILEIO 1
/* Version number of package */
#define VERSION "4.3.0"
#define VERSION "4.4.0"
/* Support webp compression */
/* #undef WEBP_SUPPORT */
......
......@@ -40,7 +40,7 @@
#define DATATYPE_IEEEFP 3 /* !IEEE floating point data */
static void
setByteArray(void** vpp, void* vp, size_t nmemb, size_t elem_size)
setByteArray(void** vpp, const void* vp, size_t nmemb, size_t elem_size)
{
if (*vpp) {
_TIFFfree(*vpp);
......@@ -54,22 +54,20 @@ setByteArray(void** vpp, void* vp, size_t nmemb, size_t elem_size)
_TIFFmemcpy(*vpp, vp, bytes);
}
}
void _TIFFsetByteArray(void** vpp, void* vp, uint32_t n)
void _TIFFsetByteArray(void** vpp, const void* vp, uint32_t n)
{ setByteArray(vpp, vp, n, 1); }
void _TIFFsetString(char** cpp, char* cp)
{ setByteArray((void**) cpp, (void*) cp, strlen(cp)+1, 1); }
static void _TIFFsetNString(char** cpp, char* cp, uint32_t n)
{ setByteArray((void**) cpp, (void*) cp, n, 1); }
void _TIFFsetShortArray(uint16_t** wpp, uint16_t* wp, uint32_t n)
{ setByteArray((void**) wpp, (void*) wp, n, sizeof (uint16_t)); }
void _TIFFsetLongArray(uint32_t** lpp, uint32_t* lp, uint32_t n)
{ setByteArray((void**) lpp, (void*) lp, n, sizeof (uint32_t)); }
static void _TIFFsetLong8Array(uint64_t** lpp, uint64_t* lp, uint32_t n)
{ setByteArray((void**) lpp, (void*) lp, n, sizeof (uint64_t)); }
void _TIFFsetFloatArray(float** fpp, float* fp, uint32_t n)
{ setByteArray((void**) fpp, (void*) fp, n, sizeof (float)); }
void _TIFFsetDoubleArray(double** dpp, double* dp, uint32_t n)
{ setByteArray((void**) dpp, (void*) dp, n, sizeof (double)); }
static void _TIFFsetNString(char** cpp, const char* cp, uint32_t n)
{ setByteArray((void**) cpp, cp, n, 1); }
void _TIFFsetShortArray(uint16_t** wpp, const uint16_t* wp, uint32_t n)
{ setByteArray((void**) wpp, wp, n, sizeof (uint16_t)); }
void _TIFFsetLongArray(uint32_t** lpp, const uint32_t* lp, uint32_t n)
{ setByteArray((void**) lpp, lp, n, sizeof (uint32_t)); }
static void _TIFFsetLong8Array(uint64_t** lpp, const uint64_t* lp, uint32_t n)
{ setByteArray((void**) lpp, lp, n, sizeof (uint64_t)); }
void _TIFFsetFloatArray(float** fpp, const float* fp, uint32_t n)
{ setByteArray((void**) fpp, fp, n, sizeof (float)); }
void _TIFFsetDoubleArray(double** dpp, const double* dp, uint32_t n)
{ setByteArray((void**) dpp, dp, n, sizeof (double)); }
static void
setDoubleArrayOneValue(double** vpp, double value, size_t nmemb)
......@@ -228,7 +226,7 @@ _TIFFVSetField(TIFF* tif, uint32_t tag, va_list ap)
case TIFFTAG_COMPRESSION:
v = (uint16_t) va_arg(ap, uint16_vap);
/*
* If we're changing the compression scheme, the notify the
* If we're changing the compression scheme, notify the
* previous module so that it can cleanup any state it's
* setup.
*/
......@@ -335,13 +333,13 @@ _TIFFVSetField(TIFF* tif, uint32_t tag, va_list ap)
break;
case TIFFTAG_XRESOLUTION:
dblval = va_arg(ap, double);
if( dblval < 0 )
if( dblval != dblval || dblval < 0 )
goto badvaluedouble;
td->td_xresolution = _TIFFClampDoubleToFloat( dblval );
break;
case TIFFTAG_YRESOLUTION:
dblval = va_arg(ap, double);
if( dblval < 0 )
if( dblval != dblval || dblval < 0 )
goto badvaluedouble;
td->td_yresolution = _TIFFClampDoubleToFloat( dblval );
break;
......@@ -559,11 +557,8 @@ _TIFFVSetField(TIFF* tif, uint32_t tag, va_list ap)
/*
* Set custom value ... save a copy of the custom tag value.
*/
tv_size = _TIFFDataSize(fip->field_type);
/*--: Rational2Double: For Rationals evaluate "set_field_type" to determine internal storage size. */
if (fip->field_type == TIFF_RATIONAL || fip->field_type == TIFF_SRATIONAL) {
tv_size = _TIFFSetGetFieldSize(fip->set_field_type);
}
tv_size = TIFFFieldSetGetSize(fip);
if (tv_size == 0) {
status = 0;
TIFFErrorExt(tif->tif_clientdata, module,
......@@ -576,17 +571,28 @@ _TIFFVSetField(TIFF* tif, uint32_t tag, va_list ap)
if (fip->field_type == TIFF_ASCII)
{
uint32_t ma;
char* mb;
const char* mb;
if (fip->field_passcount)
{
assert(fip->field_writecount==TIFF_VARIABLE2);
ma=(uint32_t)va_arg(ap, uint32_t);
mb=(char*)va_arg(ap,char*);
mb=(const char*)va_arg(ap,const char*);
}
else
{
mb=(char*)va_arg(ap,char*);
ma=(uint32_t)(strlen(mb) + 1);
mb=(const char*)va_arg(ap,const char*);
size_t len = strlen(mb) + 1;
if( len >= 0x80000000U )
{
status = 0;
TIFFErrorExt(tif->tif_clientdata, module,
"%s: Too long string value for \"%s\". "
"Maximum supported is 2147483647 bytes",
tif->tif_name,
fip->field_name);
goto end;
}
ma=(uint32_t)len;
}
tv->count=ma;
setByteArray(&tv->value,mb,ma,1);
......@@ -1041,11 +1047,15 @@ _TIFFVGetField(TIFF* tif, uint32_t tag, va_list ap)
case TIFFTAG_TILEOFFSETS:
_TIFFFillStriles( tif );
*va_arg(ap, const uint64_t**) = td->td_stripoffset_p;
if( td->td_stripoffset_p == NULL )
ret_val = 0;
break;
case TIFFTAG_STRIPBYTECOUNTS:
case TIFFTAG_TILEBYTECOUNTS:
_TIFFFillStriles( tif );
*va_arg(ap, const uint64_t**) = td->td_stripbytecount_p;
if( td->td_stripbytecount_p == NULL )
ret_val = 0;
break;
case TIFFTAG_MATTEING:
*va_arg(ap, uint16_t*) =
......@@ -1224,7 +1234,7 @@ _TIFFVGetField(TIFF* tif, uint32_t tag, va_list ap)
case TIFF_SRATIONAL:
{
/*-- Rational2Double: For Rationals evaluate "set_field_type" to determine internal storage size and return value size. */
int tv_size = _TIFFSetGetFieldSize(fip->set_field_type);
int tv_size = TIFFFieldSetGetSize(fip);
if (tv_size == 8) {
*va_arg(ap, double*) = *(double *)val;
ret_val = 1;
......@@ -1819,6 +1829,7 @@ TIFFUnlinkDirectory(TIFF* tif, uint16_t dirn)
TIFFDefaultDirectory(tif);
tif->tif_diroff = 0; /* force link on next write */
tif->tif_nextdiroff = 0; /* next write must be at end */
tif->tif_lastdiroff = 0; /* will be updated on next link */
tif->tif_curoff = 0;
tif->tif_row = (uint32_t) -1;
tif->tif_curstrip = (uint32_t) -1;
......
......@@ -282,11 +282,11 @@ struct _TIFFFieldArray {
};
struct _TIFFField {
uint32_t field_tag; /* field's tag */
uint32_t field_tag; /* field's tag */
short field_readcount; /* read count/TIFF_VARIABLE/TIFF_SPP */
short field_writecount; /* write count/TIFF_VARIABLE */
TIFFDataType field_type; /* type of associated data */
uint32_t reserved; /* reserved for future extension */
uint32_t field_anonymous; /* if true, this is a unknown / anonymous tag */
TIFFSetGetFieldType set_field_type; /* type to be passed to TIFFSetField */
TIFFSetGetFieldType get_field_type; /* type to be passed to TIFFGetField */
unsigned short field_bit; /* bit in fieldsset bit vector */
......
......@@ -149,7 +149,7 @@ tiffFields[] = {
{ TIFFTAG_COPYRIGHT, -1, -1, TIFF_ASCII, 0, TIFF_SETGET_ASCII, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "Copyright", NULL },
/* end Pixar tags */
{ TIFFTAG_RICHTIFFIPTC, -3, -3, TIFF_UNDEFINED, 0, TIFF_SETGET_C32_UINT8, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 1, "RichTIFFIPTC", NULL },
{ TIFFTAG_PHOTOSHOP, -3, -3, TIFF_BYTE, 0, TIFF_SETGET_C32_UINT8, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 1, "Photoshop", NULL },
{ TIFFTAG_PHOTOSHOP, -3, -3, TIFF_BYTE, 0, TIFF_SETGET_C32_UINT8, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 1, "Photoshop", NULL },
/*--: EXIFIFD and GPSIFD specified as TIFF_LONG by Aware-Systems and not TIFF_IFD8 as in original LibTiff.
* However, for IFD-like tags, libtiff uses the data type TIFF_IFD8 in tiffFields[]-tag definition combined with
* a special handling procedure in order to write either a 32-bit value and the TIFF_IFD type-id into ClassicTIFF files
......@@ -162,6 +162,7 @@ tiffFields[] = {
{ TIFFTAG_FAXRECVTIME, 1, 1, TIFF_LONG, 0, TIFF_SETGET_UINT32, TIFF_SETGET_UINT32, FIELD_CUSTOM, TRUE, FALSE, "FaxRecvTime", NULL },
{ TIFFTAG_FAXDCS, -1, -1, TIFF_ASCII, 0, TIFF_SETGET_ASCII, TIFF_SETGET_ASCII, FIELD_CUSTOM, TRUE, FALSE, "FaxDcs", NULL },
{ TIFFTAG_STONITS, 1, 1, TIFF_DOUBLE, 0, TIFF_SETGET_DOUBLE, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 0, "StoNits", NULL },
{ TIFFTAG_IMAGESOURCEDATA, -3, -3, TIFF_UNDEFINED, 0, TIFF_SETGET_C32_UINT8, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 1, "Adobe Photoshop Document Data Block", NULL },
{ TIFFTAG_INTEROPERABILITYIFD, 1, 1, TIFF_IFD8, 0, TIFF_SETGET_UNDEFINED, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 0, "InteroperabilityIFDOffset", NULL },
/* begin DNG tags */
{ TIFFTAG_DNGVERSION, 4, 4, TIFF_BYTE, 0, TIFF_SETGET_C0_UINT8, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 0, "DNGVersion", NULL },
......@@ -419,11 +420,16 @@ _TIFFSetupFields(TIFF* tif, const TIFFFieldArray* fieldarray)
for (i = 0; i < tif->tif_nfields; i++) {
TIFFField *fld = tif->tif_fields[i];
if (fld->field_bit == FIELD_CUSTOM &&
strncmp("Tag ", fld->field_name, 4) == 0) {
if (fld->field_name != NULL) {
if (fld->field_bit == FIELD_CUSTOM &&
TIFFFieldIsAnonymous(fld)) {
_TIFFfree(fld->field_name);
/* caution: tif_fields[i] must not be the beginning of a fields-array.
* Otherwise the following tags are also freed with the first free().
*/
_TIFFfree(fld);
}
}
}
_TIFFfree(tif->tif_fields);
......@@ -530,7 +536,7 @@ _TIFFPrintFieldInfo(TIFF* tif, FILE* fd)
}
/*
* Return size of TIFFDataType in bytes
* Return size of TIFFDataType within TIFF-file in bytes
*/
int
TIFFDataWidth(TIFFDataType type)
......@@ -563,55 +569,29 @@ TIFFDataWidth(TIFFDataType type)
}
}
/*
* Return size of TIFFDataType in bytes.
*
* XXX: We need a separate function to determine the space needed
* to store the value. For TIFF_RATIONAL values TIFFDataWidth() returns 8,
* but we use 4-byte float to represent rationals.
*/
int
_TIFFDataSize(TIFFDataType type)
{
switch (type)
{
case TIFF_BYTE:
case TIFF_SBYTE:
case TIFF_ASCII:
case TIFF_UNDEFINED:
return 1;
case TIFF_SHORT:
case TIFF_SSHORT:
return 2;
case TIFF_LONG:
case TIFF_SLONG:
case TIFF_FLOAT:
case TIFF_IFD:
case TIFF_RATIONAL:
case TIFF_SRATIONAL:
return 4;
case TIFF_DOUBLE:
case TIFF_LONG8:
case TIFF_SLONG8:
case TIFF_IFD8:
return 8;
default:
return 0;
}
}
/*
* Rational2Double:
* Return size of TIFFSetGetFieldType in bytes.
*
* XXX: TIFF_RATIONAL values for FIELD_CUSTOM are stored internally as 4-byte float.
* However, some of them should be stored internally as 8-byte double.
* This is now managed by the SetGetField of the tag-definition!
/*
* Return internal storage size of TIFFSetGetFieldType in bytes.
* TIFFSetField() and TIFFGetField() have to provide the parameter accordingly.
* Replaces internal functions _TIFFDataSize() and _TIFFSetGetFieldSize()
* with now extern available function TIFFFieldSetGetSize().
*/
int
_TIFFSetGetFieldSize(TIFFSetGetFieldType setgettype)
int
TIFFFieldSetGetSize(const TIFFField* fip)
{
switch (setgettype)
/*
* TIFFSetField() and TIFFGetField() must provide the parameter accordingly to
* the definition of "set_field_type" of the tag definition in dir_info.c.
* This function returns the data size for that purpose.
*
* Furthermore, this data size is also used for the internal storage,
* even for TIFF_RATIONAL values for FIELD_CUSTOM, which are stored internally as 4-byte float,
* but some of them should be stored internally as 8-byte double,
* depending on the "set_field_type" _FLOAT_ or _DOUBLE_.
*/
if (fip == NULL) return 0;
switch (fip->set_field_type)
{
case TIFF_SETGET_UNDEFINED:
case TIFF_SETGET_ASCII:
......@@ -619,7 +599,7 @@ _TIFFSetGetFieldSize(TIFFSetGetFieldType setgettype)
case TIFF_SETGET_C16_ASCII:
case TIFF_SETGET_C32_ASCII:
case TIFF_SETGET_OTHER:
return 0;
return 1;
case TIFF_SETGET_UINT8:
case TIFF_SETGET_SINT8:
case TIFF_SETGET_C0_UINT8:
......@@ -673,7 +653,48 @@ _TIFFSetGetFieldSize(TIFFSetGetFieldType setgettype)
default:
return 0;
}
} /*-- _TIFFSetGetFieldSize --- */
} /*-- TIFFFieldSetGetSize() --- */
/*
* Return size of count parameter of TIFFSetField() and TIFFGetField()
* and also if it is required: 0=none, 2=uint16_t, 4=uint32_t
*/
int
TIFFFieldSetGetCountSize(const TIFFField* fip)
{
if (fip == NULL) return 0;
switch (fip->set_field_type) {
case TIFF_SETGET_C16_ASCII:
case TIFF_SETGET_C16_UINT8:
case TIFF_SETGET_C16_SINT8:
case TIFF_SETGET_C16_UINT16:
case TIFF_SETGET_C16_SINT16:
case TIFF_SETGET_C16_UINT32:
case TIFF_SETGET_C16_SINT32:
case TIFF_SETGET_C16_FLOAT:
case TIFF_SETGET_C16_UINT64:
case TIFF_SETGET_C16_SINT64:
case TIFF_SETGET_C16_DOUBLE:
case TIFF_SETGET_C16_IFD8:
return 2;
case TIFF_SETGET_C32_ASCII:
case TIFF_SETGET_C32_UINT8:
case TIFF_SETGET_C32_SINT8:
case TIFF_SETGET_C32_UINT16:
case TIFF_SETGET_C32_SINT16:
case TIFF_SETGET_C32_UINT32:
case TIFF_SETGET_C32_SINT32:
case TIFF_SETGET_C32_FLOAT:
case TIFF_SETGET_C32_UINT64:
case TIFF_SETGET_C32_SINT64:
case TIFF_SETGET_C32_DOUBLE:
case TIFF_SETGET_C32_IFD8:
return 4;
default:
return 0;
}
} /*-- TIFFFieldSetGetCountSize() --- */
const TIFFField*
......@@ -788,6 +809,12 @@ TIFFFieldWriteCount(const TIFFField* fip)
return fip->field_writecount;
}
int
TIFFFieldIsAnonymous(const TIFFField *fip)
{
return fip->field_anonymous;
}
const TIFFField*
_TIFFFindOrRegisterField(TIFF *tif, uint32_t tag, TIFFDataType dt)
......@@ -819,7 +846,7 @@ _TIFFCreateAnonField(TIFF *tif, uint32_t tag, TIFFDataType field_type)
fld->field_readcount = TIFF_VARIABLE2;
fld->field_writecount = TIFF_VARIABLE2;
fld->field_type = field_type;
fld->reserved = 0;
fld->field_anonymous = 1; /* indicate that this is an anonymous / unknown tag */
switch (field_type)
{
case TIFF_BYTE:
......@@ -892,6 +919,8 @@ _TIFFCreateAnonField(TIFF *tif, uint32_t tag, TIFFDataType field_type)
/*
* note that this name is a special sign to TIFFClose() and
* _TIFFSetupFields() to free the field
* Update:
* This special sign is replaced by fld->field_anonymous flag.
*/
(void) snprintf(fld->field_name, 32, "Tag %d", (int) tag);
......@@ -1102,7 +1131,7 @@ TIFFMergeFieldInfo(TIFF* tif, const TIFFFieldInfo info[], uint32_t n)
tp->field_readcount = info[i].field_readcount;
tp->field_writecount = info[i].field_writecount;
tp->field_type = info[i].field_type;
tp->reserved = 0;
tp->field_anonymous = 0;
tp->set_field_type =
_TIFFSetGetType(info[i].field_type,
info[i].field_readcount,
......@@ -1114,6 +1143,11 @@ TIFFMergeFieldInfo(TIFF* tif, const TIFFFieldInfo info[], uint32_t n)
tp->field_bit = info[i].field_bit;
tp->field_oktochange = info[i].field_oktochange;
tp->field_passcount = info[i].field_passcount;
if (info[i].field_name == NULL) {
TIFFErrorExt(tif->tif_clientdata, module,
"Field_name of %d.th allocation tag %d is NULL", i, info[i].field_tag);
return -1;
}
tp->field_name = info[i].field_name;
tp->field_subfields = NULL;
tp++;
......
......@@ -300,6 +300,12 @@ TIFFRewriteDirectory( TIFF *tif )
return (0);
}
}
else if( tif->tif_diroff > 0xFFFFFFFFU )
{
TIFFErrorExt(tif->tif_clientdata, module,
"tif->tif_diroff exceeds 32 bit range allowed for Classic TIFF");
return (0);
}
else
{
uint32_t nextdir;
......@@ -337,6 +343,8 @@ TIFFRewriteDirectory( TIFF *tif )
return (0);
}
tif->tif_diroff=0;
/* Force a full-traversal to reach the zeroed pointer */
tif->tif_lastdiroff=0;
break;
}
nextdir=nextnextdir;
......@@ -403,6 +411,8 @@ TIFFRewriteDirectory( TIFF *tif )
return (0);
}
tif->tif_diroff=0;
/* Force a full-traversal to reach the zeroed pointer */
tif->tif_lastdiroff=0;
break;
}
nextdir=nextnextdir;
......@@ -477,6 +487,12 @@ TIFFWriteDirectorySec(TIFF* tif, int isimage, int imagedone, uint64_t* pdiroff)
}
tif->tif_flags &= ~(TIFF_BEENWRITING|TIFF_BUFFERSETUP);
}
if (TIFFFieldSet(tif,FIELD_COMPRESSION) && (tif->tif_dir.td_compression == COMPRESSION_DEFLATE)) {
TIFFWarningExt(tif->tif_clientdata, module,
"Creating TIFF with legacy Deflate codec identifier, "
"COMPRESSION_ADOBE_DEFLATE is more widely supported");
}
dir=NULL;
dirmem=NULL;
dirsize=0;
......@@ -814,7 +830,7 @@ TIFFWriteDirectorySec(TIFF* tif, int isimage, int imagedone, uint64_t* pdiroff)
{
/*-- Rational2Double: For Rationals evaluate "set_field_type" to determine internal storage size. */
int tv_size;
tv_size = _TIFFSetGetFieldSize(tif->tif_dir.td_customValues[m].info->set_field_type);
tv_size = TIFFFieldSetGetSize(tif->tif_dir.td_customValues[m].info);
if (tv_size == 8) {
if (!TIFFWriteDirectoryTagRationalDoubleArray(tif,&ndir,dir,tag,count,tif->tif_dir.td_customValues[m].value))
goto bad;
......@@ -833,7 +849,7 @@ TIFFWriteDirectorySec(TIFF* tif, int isimage, int imagedone, uint64_t* pdiroff)
{
/*-- Rational2Double: For Rationals evaluate "set_field_type" to determine internal storage size. */
int tv_size;
tv_size = _TIFFSetGetFieldSize(tif->tif_dir.td_customValues[m].info->set_field_type);
tv_size = TIFFFieldSetGetSize(tif->tif_dir.td_customValues[m].info);
if (tv_size == 8) {
if (!TIFFWriteDirectoryTagSrationalDoubleArray(tif,&ndir,dir,tag,count,tif->tif_dir.td_customValues[m].value))
goto bad;
......@@ -1774,10 +1790,12 @@ static int _WriteAsType(TIFF* tif, uint64_t strile_size, uint64_t uncompressed_t
else if ( compression == COMPRESSION_JPEG ||
compression == COMPRESSION_LZW ||
compression == COMPRESSION_ADOBE_DEFLATE ||
compression == COMPRESSION_DEFLATE ||
compression == COMPRESSION_LZMA ||
compression == COMPRESSION_LERC ||
compression == COMPRESSION_ZSTD ||
compression == COMPRESSION_WEBP )
compression == COMPRESSION_WEBP ||
compression == COMPRESSION_JXL )
{
/* For a few select compression types, we assume that in the worst */
/* case the compressed size will be 10 times the uncompressed size */
......@@ -3058,7 +3076,12 @@ TIFFWriteDirectoryTagData(TIFF* tif, uint32_t* ndir, TIFFDirEntry* dir, uint16_t
TIFFErrorExt(tif->tif_clientdata,module,"IO error writing tag data");
return(0);
}
assert(datalength<0x80000000UL);
if (datalength >= 0x80000000UL)
{
TIFFErrorExt(tif->tif_clientdata,module,
"libtiff does not allow writing more than 2147483647 bytes in a tag");
return(0);
}
if (!WriteOK(tif,data,(tmsize_t)datalength))
{
TIFFErrorExt(tif->tif_clientdata,module,"IO error writing tag data");
......@@ -3161,6 +3184,7 @@ TIFFLinkDirectory(TIFF* tif)
* First directory, overwrite offset in header.
*/
tif->tif_header.classic.tiff_diroff = (uint32_t) tif->tif_diroff;
tif->tif_lastdiroff = tif->tif_diroff;
(void) TIFFSeekFile(tif,4, SEEK_SET);
if (!WriteOK(tif, &m, 4)) {
TIFFErrorExt(tif->tif_clientdata, tif->tif_name,
......@@ -3172,7 +3196,13 @@ TIFFLinkDirectory(TIFF* tif)
/*
* Not the first directory, search to the last and append.
*/
nextdir = tif->tif_header.classic.tiff_diroff;
if (tif->tif_lastdiroff != 0) {
nextdir = (uint32_t) tif->tif_lastdiroff;
}
else {
nextdir = tif->tif_header.classic.tiff_diroff;
}
while(1) {
uint16_t dircount;
uint32_t nextnextdir;
......@@ -3203,6 +3233,7 @@ TIFFLinkDirectory(TIFF* tif)
"Error writing directory link");
return (0);
}
tif->tif_lastdiroff = tif->tif_diroff;
break;
}
nextdir=nextnextdir;
......@@ -3220,6 +3251,7 @@ TIFFLinkDirectory(TIFF* tif)
* First directory, overwrite offset in header.
*/
tif->tif_header.big.tiff_diroff = tif->tif_diroff;
tif->tif_lastdiroff = tif->tif_diroff;
(void) TIFFSeekFile(tif,8, SEEK_SET);
if (!WriteOK(tif, &m, 8)) {
TIFFErrorExt(tif->tif_clientdata, tif->tif_name,
......@@ -3231,7 +3263,12 @@ TIFFLinkDirectory(TIFF* tif)
/*
* Not the first directory, search to the last and append.
*/
nextdir = tif->tif_header.big.tiff_diroff;
if (tif->tif_lastdiroff != 0) {
nextdir = tif->tif_lastdiroff;
}
else {
nextdir = tif->tif_header.big.tiff_diroff;
}
while(1) {
uint64_t dircount64;
uint16_t dircount;
......@@ -3270,6 +3307,7 @@ TIFFLinkDirectory(TIFF* tif)
"Error writing directory link");
return (0);
}
tif->tif_lastdiroff = tif->tif_diroff;
break;
}
nextdir=nextnextdir;
......@@ -3668,7 +3706,16 @@ _TIFFRewriteField(TIFF* tif, uint16_t tag, TIFFDataType in_datatype,
}
else
{
memcpy( &entry_offset, buf_to_write, count*TIFFDataWidth(datatype));
if( count*TIFFDataWidth(datatype) == 4 )
{
uint32_t value;
memcpy( &value, buf_to_write, count*TIFFDataWidth(datatype));
entry_offset = value;
}
else
{
memcpy( &entry_offset, buf_to_write, count*TIFFDataWidth(datatype));
}
}
_TIFFfree( buf_to_write );
......
......@@ -327,6 +327,20 @@ Fax3Decode2D(TIFF* tif, uint8_t* buf, tmsize_t occ, uint16_t s)
}
#undef SWAP
# define FILL(n, cp) \
for (int32_t ifill = 0; ifill < (n); ++ifill) \
{ \
(cp)[ifill] = 0xff; \
} \
(cp) += (n);
# define ZERO(n, cp) \
for (int32_t izero = 0; izero < (n); ++izero) \
{ \
(cp)[izero] = 0; \
} \
(cp) += (n);
/*
* Bit-fill a row according to the white/black
* runs generated during G3/G4 decoding.
......@@ -338,7 +352,8 @@ _TIFFFax3fillruns(unsigned char* buf, uint32_t* runs, uint32_t* erun, uint32_t l
{ 0x00, 0x80, 0xc0, 0xe0, 0xf0, 0xf8, 0xfc, 0xfe, 0xff };
unsigned char* cp;
uint32_t x, bx, run;
int32_t n;
int32_t n, nw;
int64_t* lp;
if ((erun-runs)&1)
*erun++ = 0;
......@@ -356,8 +371,21 @@ _TIFFFax3fillruns(unsigned char* buf, uint32_t* runs, uint32_t* erun, uint32_t l
run -= 8-bx;
}
if( (n = run >> 3) != 0 ) { /* multiple bytes to fill */
memset( cp, 0, n );
cp += n;
if ((n/sizeof (int64_t)) > 1) {
/*
* Align to int64_tword boundary and fill.
*/
for (; n && !isAligned(cp, int64_t); n--)
*cp++ = 0x00;
lp = (int64_t*) cp;
nw = (int32_t)(n / sizeof (int64_t));
n -= nw * sizeof (int64_t);
do {
*lp++ = 0L;
} while (--nw);
cp = (unsigned char*) lp;
}
ZERO(n, cp);
run &= 7;
}
if (run)
......@@ -378,8 +406,21 @@ _TIFFFax3fillruns(unsigned char* buf, uint32_t* runs, uint32_t* erun, uint32_t l
run -= 8-bx;
}
if( (n = run>>3) != 0 ) { /* multiple bytes to fill */
memset( cp, 0xff, n );
cp += n;
if ((n/sizeof (int64_t)) > 1) {
/*
* Align to int64_t boundary and fill.
*/
for (; n && !isAligned(cp, int64_t); n--)
*cp++ = 0xff;
lp = (int64_t*) cp;
nw = (int32_t)(n / sizeof (int64_t));
n -= nw * sizeof (int64_t);
do {
*lp++ = -1L;
} while (--nw);
cp = (unsigned char*) lp;
}
FILL(n, cp);
run &= 7;
}
/* Explicit 0xff masking to make icc -check=conversions happy */
......
This source diff could not be displayed because it is too large. You can view the blob instead.
......@@ -579,7 +579,7 @@ LogLuvEncode32(TIFF* tif, uint8_t* bp, tmsize_t cc, uint16_t s)
uint32_t* tp;
uint32_t b;
tmsize_t occ;
int rc=0, mask;
int rc=0;
tmsize_t beg;
(void)s;
......@@ -603,6 +603,7 @@ LogLuvEncode32(TIFF* tif, uint8_t* bp, tmsize_t cc, uint16_t s)
op = tif->tif_rawcp;
occ = tif->tif_rawdatasize - tif->tif_rawcc;
for (shft = 24; shft >= 0; shft -=8) {
const uint32_t mask = 0xffU << shft; /* find next run */
for (i = 0; i < npixels; i += rc) {
if (occ < 4) {
tif->tif_rawcp = op;
......@@ -612,7 +613,6 @@ LogLuvEncode32(TIFF* tif, uint8_t* bp, tmsize_t cc, uint16_t s)
op = tif->tif_rawcp;
occ = tif->tif_rawdatasize - tif->tif_rawcc;
}
mask = 0xff << shft; /* find next run */
for (beg = i; beg < npixels; beg += rc) {
b = tp[beg] & mask;
rc = 1;
......@@ -804,7 +804,7 @@ L16fromY(LogLuvState* sp, uint8_t* op, tmsize_t n)
static
#endif
void
XYZtoRGB24(float xyz[3], uint8_t rgb[3])
XYZtoRGB24(float* xyz, uint8_t* rgb)
{
double r, g, b;
/* assume CCIR-709 primaries */
......@@ -958,7 +958,7 @@ uv_decode(double *up, double *vp, int c) /* decode (u',v') index */
static
#endif
void
LogLuv24toXYZ(uint32_t p, float XYZ[3])
LogLuv24toXYZ(uint32_t p, float* XYZ)
{
int Ce;
double L, u, v, s, x, y;
......@@ -986,7 +986,7 @@ LogLuv24toXYZ(uint32_t p, float XYZ[3])
static
#endif
uint32_t
LogLuv24fromXYZ(float XYZ[3], int em)
LogLuv24fromXYZ(float* XYZ, int em)
{
int Le, Ce;
double u, v, s;
......@@ -1099,7 +1099,7 @@ Luv24fromLuv48(LogLuvState* sp, uint8_t* op, tmsize_t n)
static
#endif
void
LogLuv32toXYZ(uint32_t p, float XYZ[3])
LogLuv32toXYZ(uint32_t p, float* XYZ)
{
double L, u, v, s, x, y;
/* decode luminance */
......@@ -1124,7 +1124,7 @@ LogLuv32toXYZ(uint32_t p, float XYZ[3])
static
#endif
uint32_t
LogLuv32fromXYZ(float XYZ[3], int em)
LogLuv32fromXYZ(float* XYZ, int em)
{
unsigned int Le, ue, ve;
double u, v, s;
......
......@@ -96,7 +96,6 @@ TIFFClientOpen(
assert(sizeof(int32_t) == 4);
assert(sizeof(uint64_t) == 8);
assert(sizeof(int64_t) == 8);
assert(sizeof(tmsize_t)==sizeof(void*));
{
union{
uint8_t a8[2];
......@@ -354,6 +353,7 @@ TIFFClientOpen(
if (!TIFFDefaultDirectory(tif))
goto bad;
tif->tif_diroff = 0;
tif->tif_lastdiroff = 0;
tif->tif_dirlist = NULL;
tif->tif_dirlistsize = 0;
tif->tif_dirnumber = 0;
......@@ -481,8 +481,6 @@ TIFFClientOpen(
* Setup initial directory.
*/
if (TIFFReadDirectory(tif)) {
tif->tif_rawcc = (tmsize_t)-1;
tif->tif_flags |= TIFF_BUFFERSETUP;
return (tif);
}
break;
......@@ -670,6 +668,15 @@ TIFFIsBigEndian(TIFF* tif)
}
/*
* Return nonzero if given file is BigTIFF style.
*/
int
TIFFIsBigTIFF(TIFF *tif)
{
return (tif->tif_header.common.tiff_version == TIFF_VERSION_BIG);
}
/*
* Return pointer to file read method.
*/
TIFFReadWriteProc
......
......@@ -214,23 +214,17 @@ static int
PackBitsDecode(TIFF* tif, uint8_t* op, tmsize_t occ, uint16_t s)
{
static const char module[] = "PackBitsDecode";
char *bp;
int8_t *bp;
tmsize_t cc;
long n;
int b;
(void) s;
bp = (char*) tif->tif_rawcp;
bp = (int8_t*) tif->tif_rawcp;
cc = tif->tif_rawcc;
while (cc > 0 && occ > 0) {
n = (long) *bp++;
cc--;
/*
* Watch out for compilers that
* don't sign extend chars...
*/
if (n >= 128)
n -= 256;
if (n < 0) { /* replicate next byte -n+1 times */
if (n == -128) /* nop */
continue;
......
......@@ -35,13 +35,17 @@
static int horAcc8(TIFF* tif, uint8_t* cp0, tmsize_t cc);
static int horAcc16(TIFF* tif, uint8_t* cp0, tmsize_t cc);
static int horAcc32(TIFF* tif, uint8_t* cp0, tmsize_t cc);
static int horAcc64(TIFF* tif, uint8_t* cp0, tmsize_t cc);
static int swabHorAcc16(TIFF* tif, uint8_t* cp0, tmsize_t cc);
static int swabHorAcc32(TIFF* tif, uint8_t* cp0, tmsize_t cc);
static int swabHorAcc64(TIFF* tif, uint8_t* cp0, tmsize_t cc);
static int horDiff8(TIFF* tif, uint8_t* cp0, tmsize_t cc);
static int horDiff16(TIFF* tif, uint8_t* cp0, tmsize_t cc);
static int horDiff32(TIFF* tif, uint8_t* cp0, tmsize_t cc);
static int horDiff64(TIFF* tif, uint8_t* cp0, tmsize_t cc);
static int swabHorDiff16(TIFF* tif, uint8_t* cp0, tmsize_t cc);
static int swabHorDiff32(TIFF* tif, uint8_t* cp0, tmsize_t cc);
static int swabHorDiff64(TIFF* tif, uint8_t* cp0, tmsize_t cc);
static int fpAcc(TIFF* tif, uint8_t* cp0, tmsize_t cc);
static int fpDiff(TIFF* tif, uint8_t* cp0, tmsize_t cc);
static int PredictorDecodeRow(TIFF* tif, uint8_t* op0, tmsize_t occ0, uint16_t s);
......@@ -64,7 +68,8 @@ PredictorSetup(TIFF* tif)
case PREDICTOR_HORIZONTAL:
if (td->td_bitspersample != 8
&& td->td_bitspersample != 16
&& td->td_bitspersample != 32) {
&& td->td_bitspersample != 32
&& td->td_bitspersample != 64) {
TIFFErrorExt(tif->tif_clientdata, module,
"Horizontal differencing \"Predictor\" not supported with %"PRIu16"-bit samples",
td->td_bitspersample);
......@@ -126,6 +131,7 @@ PredictorSetupDecode(TIFF* tif)
case 8: sp->decodepfunc = horAcc8; break;
case 16: sp->decodepfunc = horAcc16; break;
case 32: sp->decodepfunc = horAcc32; break;
case 64: sp->decodepfunc = horAcc64; break;
}
/*
* Override default decoding method with one that does the
......@@ -155,6 +161,9 @@ PredictorSetupDecode(TIFF* tif)
} else if (sp->decodepfunc == horAcc32) {
sp->decodepfunc = swabHorAcc32;
tif->tif_postdecode = _TIFFNoPostDecode;
} else if (sp->decodepfunc == horAcc64) {
sp->decodepfunc = swabHorAcc64;
tif->tif_postdecode = _TIFFNoPostDecode;
}
}
}
......@@ -205,6 +214,7 @@ PredictorSetupEncode(TIFF* tif)
case 8: sp->encodepfunc = horDiff8; break;
case 16: sp->encodepfunc = horDiff16; break;
case 32: sp->encodepfunc = horDiff32; break;
case 64: sp->encodepfunc = horDiff64; break;
}
/*
* Override default encoding method with one that does the
......@@ -234,6 +244,9 @@ PredictorSetupEncode(TIFF* tif)
} else if (sp->encodepfunc == horDiff32) {
sp->encodepfunc = swabHorDiff32;
tif->tif_postdecode = _TIFFNoPostDecode;
} else if (sp->encodepfunc == horDiff64) {
sp->encodepfunc = swabHorDiff64;
tif->tif_postdecode = _TIFFNoPostDecode;
}
}
}
......@@ -403,6 +416,41 @@ horAcc32(TIFF* tif, uint8_t* cp0, tmsize_t cc)
return 1;
}
static int
swabHorAcc64(TIFF* tif, uint8_t* cp0, tmsize_t cc)
{
uint64_t* wp = (uint64_t*) cp0;
tmsize_t wc = cc / 8;
TIFFSwabArrayOfLong8(wp, wc);
return horAcc64(tif, cp0, cc);
}
TIFF_NOSANITIZE_UNSIGNED_INT_OVERFLOW
static int
horAcc64(TIFF* tif, uint8_t* cp0, tmsize_t cc)
{
tmsize_t stride = PredictorState(tif)->stride;
uint64_t* wp = (uint64_t*) cp0;
tmsize_t wc = cc / 8;
if ((cc % (8 * stride)) != 0)
{
TIFFErrorExt(tif->tif_clientdata, "horAcc64",
"%s", "cc%(8*stride))!=0");
return 0;
}
if (wc > stride) {
wc -= stride;
do {
REPEAT4(stride, wp[stride] += wp[0]; wp++)
wc -= stride;
} while (wc > 0);
}
return 1;
}
/*
* Floating point predictor accumulation routine.
*/
......@@ -638,6 +686,46 @@ swabHorDiff32(TIFF* tif, uint8_t* cp0, tmsize_t cc)
return 1;
}
TIFF_NOSANITIZE_UNSIGNED_INT_OVERFLOW
static int
horDiff64(TIFF* tif, uint8_t* cp0, tmsize_t cc)
{
TIFFPredictorState* sp = PredictorState(tif);
tmsize_t stride = sp->stride;
uint64_t *wp = (uint64_t*) cp0;
tmsize_t wc = cc/8;
if ((cc % (8 * stride)) != 0)
{
TIFFErrorExt(tif->tif_clientdata, "horDiff64",
"%s", "(cc%(8*stride))!=0");
return 0;
}
if (wc > stride) {
wc -= stride;
wp += wc - 1;
do {
REPEAT4(stride, wp[stride] -= wp[0]; wp--)
wc -= stride;
} while (wc > 0);
}
return 1;
}
static int
swabHorDiff64(TIFF* tif, uint8_t* cp0, tmsize_t cc)
{
uint64_t* wp = (uint64_t*) cp0;
tmsize_t wc = cc / 8;
if (!horDiff64(tif, cp0, cc))
return 0;
TIFFSwabArrayOfLong8(wp, wc);
return 1;
}
/*
* Floating point predictor differencing routine.
*/
......
......@@ -751,15 +751,12 @@ TIFFFillStrip(TIFF* tif, uint32_t strip)
(bytecount - 4096) / 10 > (uint64_t)stripsize )
{
uint64_t newbytecount = (uint64_t)stripsize * 10 + 4096;
if( newbytecount == 0 || newbytecount > (uint64_t)TIFF_INT64_MAX )
{
TIFFErrorExt(tif->tif_clientdata, module,
"Too large strip byte count %"PRIu64", strip %"PRIu32". Limiting to %"PRIu64,
bytecount,
strip,
newbytecount);
bytecount = newbytecount;
}
TIFFErrorExt(tif->tif_clientdata, module,
"Too large strip byte count %"PRIu64", strip %"PRIu32". Limiting to %"PRIu64,
bytecount,
strip,
newbytecount);
bytecount = newbytecount;
}
}
......@@ -1145,15 +1142,12 @@ TIFFFillTile(TIFF* tif, uint32_t tile)
(bytecount - 4096) / 10 > (uint64_t)stripsize )
{
uint64_t newbytecount = (uint64_t)stripsize * 10 + 4096;
if( newbytecount == 0 || newbytecount > (uint64_t)TIFF_INT64_MAX )
{
TIFFErrorExt(tif->tif_clientdata, module,
"Too large tile byte count %"PRIu64", tile %"PRIu32". Limiting to %"PRIu64,
bytecount,
tile,
newbytecount);
bytecount = newbytecount;
}
TIFFErrorExt(tif->tif_clientdata, module,
"Too large tile byte count %"PRIu64", tile %"PRIu32". Limiting to %"PRIu64,
bytecount,
tile,
newbytecount);
bytecount = newbytecount;
}
}
......
......@@ -28,6 +28,7 @@
*/
#include "tiffiop.h"
#include <stdlib.h>
#include <windows.h>
......
......@@ -124,18 +124,12 @@ TIFFWriteScanline(TIFF* tif, void* buf, uint32_t row, uint16_t sample)
return (-1);
tif->tif_flags |= TIFF_CODERSETUP;
}
tif->tif_rawcc = 0;
tif->tif_rawcp = tif->tif_rawdata;
if( td->td_stripbytecount_p[strip] > 0 )
{
/* if we are writing over existing tiles, zero length */
td->td_stripbytecount_p[strip] = 0;
/* this forces TIFFAppendToStrip() to do a seek */
tif->tif_curoff = 0;
}
/* this informs TIFFAppendToStrip() we have changed strip */
tif->tif_curoff = 0;
if (!(*tif->tif_preencode)(tif, sample))
return (-1);
......@@ -194,10 +188,6 @@ static int _TIFFReserveLargeEnoughWriteBuffer(TIFF* tif, uint32_t strip_or_tile)
(tmsize_t)TIFFroundup_64(safe_buffer_size, 1024))) )
return 0;
}
/* Force TIFFAppendToStrip() to consider placing data at end
of file. */
tif->tif_curoff = 0;
}
return 1;
}
......@@ -235,7 +225,7 @@ TIFFWriteEncodedStrip(TIFF* tif, uint32_t strip, void* data, tmsize_t cc)
if (!TIFFGrowStrips(tif, 1, module))
return ((tmsize_t) -1);
td->td_stripsperimage =
TIFFhowmany_32(td->td_imagelength, td->td_rowsperstrip);
TIFFhowmany_32(td->td_imagelength, td->td_rowsperstrip);
}
/*
* Handle delayed allocation of data buffer. This
......@@ -246,8 +236,12 @@ TIFFWriteEncodedStrip(TIFF* tif, uint32_t strip, void* data, tmsize_t cc)
return ((tmsize_t) -1);
tif->tif_flags |= TIFF_BUF4WRITE;
tif->tif_curstrip = strip;
/* this informs TIFFAppendToStrip() we have changed or reset strip */
tif->tif_curoff = 0;
if( !_TIFFReserveLargeEnoughWriteBuffer(tif, strip) ) {
return ((tmsize_t)(-1));
}
......@@ -346,7 +340,12 @@ TIFFWriteRawStrip(TIFF* tif, uint32_t strip, void* data, tmsize_t cc)
if (!TIFFGrowStrips(tif, 1, module))
return ((tmsize_t) -1);
}
tif->tif_curstrip = strip;
/* this informs TIFFAppendToStrip() we have changed or reset strip */
tif->tif_curoff = 0;
if (td->td_stripsperimage == 0) {
TIFFErrorExt(tif->tif_clientdata, module,"Zero strips per image");
return ((tmsize_t) -1);
......@@ -412,8 +411,12 @@ TIFFWriteEncodedTile(TIFF* tif, uint32_t tile, void* data, tmsize_t cc)
return ((tmsize_t)(-1));
tif->tif_flags |= TIFF_BUF4WRITE;
tif->tif_curtile = tile;
/* this informs TIFFAppendToStrip() we have changed or reset tile */
tif->tif_curoff = 0;
if( !_TIFFReserveLargeEnoughWriteBuffer(tif, tile) ) {
return ((tmsize_t)(-1));
}
......@@ -421,7 +424,7 @@ TIFFWriteEncodedTile(TIFF* tif, uint32_t tile, void* data, tmsize_t cc)
tif->tif_rawcc = 0;
tif->tif_rawcp = tif->tif_rawdata;
/*
/*
* Compute tiles per row & per column to compute
* current row and column
*/
......@@ -583,7 +586,7 @@ TIFFWriteCheck(TIFF* tif, int tiles, const char* module)
}
_TIFFFillStriles( tif );
/*
* On the first write verify all the required information
* has been setup and initialize any data structures that
......@@ -600,7 +603,7 @@ TIFFWriteCheck(TIFF* tif, int tiles, const char* module)
return (0);
}
if (tif->tif_dir.td_samplesperpixel == 1) {
/*
/*
* Planarconfiguration is irrelevant in case of single band
* images and need not be included. We will set it anyway,
* because this field is used in other parts of library even
......@@ -741,18 +744,21 @@ TIFFAppendToStrip(TIFF* tif, uint32_t strip, uint8_t* data, tmsize_t cc)
static const char module[] = "TIFFAppendToStrip";
TIFFDirectory *td = &tif->tif_dir;
uint64_t m;
int64_t old_byte_count = -1;
int64_t old_byte_count = -1;
if (td->td_stripoffset_p[strip] == 0 || tif->tif_curoff == 0) {
if( tif->tif_curoff == 0 )
tif->tif_lastvalidoff = 0;
if (td->td_stripoffset_p[strip] == 0 || tif->tif_curoff == 0) {
assert(td->td_nstrips > 0);
if( td->td_stripbytecount_p[strip] != 0
&& td->td_stripoffset_p[strip] != 0
if( td->td_stripbytecount_p[strip] != 0
&& td->td_stripoffset_p[strip] != 0
&& td->td_stripbytecount_p[strip] >= (uint64_t) cc )
{
/*
/*
* There is already tile data on disk, and the new tile
* data we have will fit in the same space. The only
* data we have will fit in the same space. The only
* aspect of this that is risky is that there could be
* more data to append to this strip before we are done
* depending on how we are getting called.
......@@ -763,11 +769,13 @@ TIFFAppendToStrip(TIFF* tif, uint32_t strip, uint8_t* data, tmsize_t cc)
(unsigned long)tif->tif_row);
return (0);
}
tif->tif_lastvalidoff = td->td_stripoffset_p[strip] + td->td_stripbytecount_p[strip];
}
else
{
/*
* Seek to end of file, and set that as our location to
/*
* Seek to end of file, and set that as our location to
* write this strip.
*/
td->td_stripoffset_p[strip] = TIFFSeekFile(tif, 0, SEEK_END);
......@@ -791,6 +799,84 @@ TIFFAppendToStrip(TIFF* tif, uint32_t strip, uint8_t* data, tmsize_t cc)
TIFFErrorExt(tif->tif_clientdata, module, "Maximum TIFF file size exceeded");
return (0);
}
if( tif->tif_lastvalidoff != 0 && m > tif->tif_lastvalidoff &&
td->td_stripbytecount_p[strip] > 0 )
{
/* Ouch: we have detected that we are rewriting in place a strip/tile */
/* with several calls to TIFFAppendToStrip(). The first call was with */
/* a size smaller than the previous size of the strip/tile, so we */
/* opted to rewrite in place, but a following call causes us to go */
/* outsize of the strip/tile area, so we have to finally go for a */
/* append-at-end-of-file strategy, and start by moving what we already */
/* wrote. */
tmsize_t tempSize;
void* temp;
uint64_t offsetRead;
uint64_t offsetWrite;
uint64_t toCopy = td->td_stripbytecount_p[strip];
if( toCopy < 1024 * 1024 )
tempSize = (tmsize_t)toCopy;
else
tempSize = 1024 * 1024;
offsetRead = td->td_stripoffset_p[strip];
offsetWrite = TIFFSeekFile(tif, 0, SEEK_END);
m = offsetWrite + toCopy + cc;
if (!(tif->tif_flags&TIFF_BIGTIFF) && m != (uint32_t)m)
{
TIFFErrorExt(tif->tif_clientdata, module, "Maximum TIFF file size exceeded");
return (0);
}
temp = _TIFFmalloc(tempSize);
if (temp == NULL) {
TIFFErrorExt(tif->tif_clientdata, module, "No space for output buffer");
return (0);
}
tif->tif_flags |= TIFF_DIRTYSTRIP;
td->td_stripoffset_p[strip] = offsetWrite;
td->td_stripbytecount_p[strip] = 0;
/* Move data written by previous calls to us at end of file */
while( toCopy > 0 )
{
if( !SeekOK(tif, offsetRead) ) {
TIFFErrorExt(tif->tif_clientdata, module, "Seek error");
_TIFFfree(temp);
return (0);
}
if( !ReadOK(tif, temp, tempSize) ) {
TIFFErrorExt(tif->tif_clientdata, module, "Cannot read");
_TIFFfree(temp);
return (0);
}
if (!SeekOK(tif, offsetWrite) ) {
TIFFErrorExt(tif->tif_clientdata, module, "Seek error");
_TIFFfree(temp);
return (0);
}
if( !WriteOK(tif, temp, tempSize) ) {
TIFFErrorExt(tif->tif_clientdata, module, "Cannot write");
_TIFFfree(temp);
return (0);
}
offsetRead += tempSize;
offsetWrite += tempSize;
td->td_stripbytecount_p[strip] += tempSize;
toCopy -= tempSize;
}
_TIFFfree(temp);
/* Append the data of this call */
offsetWrite += cc;
m = offsetWrite;
}
if (!WriteOK(tif, data, cc)) {
TIFFErrorExt(tif->tif_clientdata, module, "Write error at scanline %lu",
(unsigned long) tif->tif_row);
......@@ -801,7 +887,7 @@ TIFFAppendToStrip(TIFF* tif, uint32_t strip, uint8_t* data, tmsize_t cc)
if((int64_t) td->td_stripbytecount_p[strip] != old_byte_count )
tif->tif_flags |= TIFF_DIRTYSTRIP;
return (1);
}
......@@ -845,6 +931,7 @@ void
TIFFSetWriteOffset(TIFF* tif, toff_t off)
{
tif->tif_curoff = off;
tif->tif_lastvalidoff = 0;
}
/* vim: set ts=8 sts=8 sw=8 noet: */
......
......@@ -196,7 +196,7 @@ typedef enum {
/* compression codes 32908-32911 are reserved for Pixar */
#define COMPRESSION_PIXARFILM 32908 /* Pixar companded 10bit LZW */
#define COMPRESSION_PIXARLOG 32909 /* Pixar companded 11bit ZIP */
#define COMPRESSION_DEFLATE 32946 /* Deflate compression */
#define COMPRESSION_DEFLATE 32946 /* Deflate compression, legacy tag */
#define COMPRESSION_ADOBE_DEFLATE 8 /* Deflate compression,
as recognized by Adobe */
/* compression code 32947 is reserved for Oceana Matrix <dev@oceana.com> */
......
......@@ -58,7 +58,7 @@
#define CCITT_SUPPORT 1
/* Support JPEG compression (requires IJG JPEG library) */
#define JPEG_SUPPORT 1
/* #undef JPEG_SUPPORT */
/* Support JBIG compression (requires JBIG-KIT library) */
/* #undef JBIG_SUPPORT */
......
......@@ -328,6 +328,9 @@ extern TIFFDataType TIFFFieldDataType(const TIFFField*);
extern int TIFFFieldPassCount(const TIFFField*);
extern int TIFFFieldReadCount(const TIFFField*);
extern int TIFFFieldWriteCount(const TIFFField*);
extern int TIFFFieldSetGetSize(const TIFFField*); /* returns internal storage size of TIFFSetGetFieldType in bytes. */
extern int TIFFFieldSetGetCountSize(const TIFFField*); /* returns size of count parameter 0=none, 2=uint16_t, 4=uint32_t */
extern int TIFFFieldIsAnonymous(const TIFFField *);
typedef int (*TIFFVSetMethod)(TIFF*, uint32_t, va_list);
typedef int (*TIFFVGetMethod)(TIFF*, uint32_t, va_list);
......@@ -384,9 +387,10 @@ extern int TIFFIsByteSwapped(TIFF*);
extern int TIFFIsUpSampled(TIFF*);
extern int TIFFIsMSB2LSB(TIFF*);
extern int TIFFIsBigEndian(TIFF*);
extern int TIFFIsBigTIFF(TIFF*);
extern TIFFReadWriteProc TIFFGetReadProc(TIFF*);
extern TIFFReadWriteProc TIFFGetWriteProc(TIFF*);
extern TIFFSeekProc TIFFGetSeekProc(TIFF*);
extern TIFFSeekProc TIFFGetSeekProc(TIFF*);
extern TIFFCloseProc TIFFGetCloseProc(TIFF*);
extern TIFFSizeProc TIFFGetSizeProc(TIFF*);
extern TIFFMapFileProc TIFFGetMapFileProc(TIFF*);
......@@ -483,7 +487,7 @@ extern tmsize_t TIFFWriteEncodedStrip(TIFF* tif, uint32_t strip, void* data, tms
extern tmsize_t TIFFWriteRawStrip(TIFF* tif, uint32_t strip, void* data, tmsize_t cc);
extern tmsize_t TIFFWriteEncodedTile(TIFF* tif, uint32_t tile, void* data, tmsize_t cc);
extern tmsize_t TIFFWriteRawTile(TIFF* tif, uint32_t tile, void* data, tmsize_t cc);
extern int TIFFDataWidth(TIFFDataType); /* table of tag datatype widths */
extern int TIFFDataWidth(TIFFDataType); /* table of tag datatype widths within TIFF file. */
extern void TIFFSetWriteOffset(TIFF* tif, toff_t off);
extern void TIFFSwabShort(uint16_t*);
extern void TIFFSwabLong(uint32_t*);
......
......@@ -2,23 +2,23 @@
* Copyright (c) 1988-1997 Sam Leffler
* Copyright (c) 1991-1997 Silicon Graphics, Inc.
*
* Permission to use, copy, modify, distribute, and sell this software and
* Permission to use, copy, modify, distribute, and sell this software and
* its documentation for any purpose is hereby granted without fee, provided
* that (i) the above copyright notices and this permission notice appear in
* all copies of the software and related documentation, and (ii) the names of
* Sam Leffler and Silicon Graphics may not be used in any advertising or
* publicity relating to the software without the specific, prior written
* permission of Sam Leffler and Silicon Graphics.
*
* THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND,
* EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY
* WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
*
*
* THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND,
* EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY
* WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
*
* IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR
* ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND,
* OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
* WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF
* LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
* WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF
* LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
* OF THIS SOFTWARE.
*/
......@@ -43,7 +43,7 @@
#ifdef HAVE_ASSERT_H
# include <assert.h>
#else
# define assert(x)
# define assert(x)
#endif
#include "tiffio.h"
......@@ -117,6 +117,7 @@ struct tiff {
#define TIFF_CHOPPEDUPARRAYS 0x4000000U /* set when allocChoppedUpStripArrays() has modified strip array */
uint64_t tif_diroff; /* file offset of current directory */
uint64_t tif_nextdiroff; /* file offset of following directory */
uint64_t tif_lastdiroff; /* file offset of last directory written so far */
uint64_t* tif_dirlist; /* list of offsets to already seen directories to prevent IFD looping */
uint16_t tif_dirlistsize; /* number of entries in offset list */
uint16_t tif_dirnumber; /* number of already seen directories */
......@@ -132,6 +133,7 @@ struct tiff {
uint16_t tif_curdir; /* current directory (index) */
uint32_t tif_curstrip; /* current strip for read/write */
uint64_t tif_curoff; /* current offset for read/write */
uint64_t tif_lastvalidoff; /* last valid offset allowed for rewrite in place. Used only by TIFFAppendToStrip() */
uint64_t tif_dataoff; /* current offset for writing dir */
/* SubIFD support */
uint16_t tif_nsubifd; /* remaining subifds to write */
......@@ -337,17 +339,12 @@ extern int TIFFSetCompressionScheme(TIFF* tif, int scheme);
extern int TIFFSetDefaultCompressionState(TIFF* tif);
extern uint32_t _TIFFDefaultStripSize(TIFF* tif, uint32_t s);
extern void _TIFFDefaultTileSize(TIFF* tif, uint32_t* tw, uint32_t* th);
extern int _TIFFDataSize(TIFFDataType type);
/*--: Rational2Double: Return size of TIFFSetGetFieldType in bytes. */
extern int _TIFFSetGetFieldSize(TIFFSetGetFieldType setgettype);
extern void _TIFFsetByteArray(void**, void*, uint32_t);
extern void _TIFFsetString(char**, char*);
extern void _TIFFsetShortArray(uint16_t**, uint16_t*, uint32_t);
extern void _TIFFsetLongArray(uint32_t**, uint32_t*, uint32_t);
extern void _TIFFsetFloatArray(float**, float*, uint32_t);
extern void _TIFFsetDoubleArray(double**, double*, uint32_t);
extern void _TIFFsetByteArray(void**, const void*, uint32_t);
extern void _TIFFsetShortArray(uint16_t**, const uint16_t*, uint32_t);
extern void _TIFFsetLongArray(uint32_t**, const uint32_t*, uint32_t);
extern void _TIFFsetFloatArray(float**, const float*, uint32_t);
extern void _TIFFsetDoubleArray(double**, const double*, uint32_t);
extern void _TIFFprintAscii(FILE*, const char*);
extern void _TIFFprintAsciiTag(FILE*, const char*, const char*);
......
#define TIFFLIB_VERSION_STR "LIBTIFF, Version 4.3.0\nCopyright (c) 1988-1996 Sam Leffler\nCopyright (c) 1991-1996 Silicon Graphics, Inc."
#define TIFFLIB_VERSION_STR "LIBTIFF, Version 4.4.0\nCopyright (c) 1988-1996 Sam Leffler\nCopyright (c) 1991-1996 Silicon Graphics, Inc."
/*
* This define can be used in code that requires
* compilation-related definitions specific to a
......@@ -6,4 +6,4 @@
* version checking should be done based on the
* string returned by TIFFGetVersion.
*/
#define TIFFLIB_VERSION 20210416
#define TIFFLIB_VERSION 20220520
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment