Commit f937ad5a authored by Alexandre Julliard's avatar Alexandre Julliard

tiff: Import upstream release 4.4.0.

parent be227979
...@@ -80,12 +80,17 @@ TIFFCleanup(TIFF* tif) ...@@ -80,12 +80,17 @@ TIFFCleanup(TIFF* tif)
for (i = 0; i < tif->tif_nfields; i++) { for (i = 0; i < tif->tif_nfields; i++) {
TIFFField *fld = tif->tif_fields[i]; TIFFField *fld = tif->tif_fields[i];
if (fld->field_name != NULL) {
if (fld->field_bit == FIELD_CUSTOM && if (fld->field_bit == FIELD_CUSTOM &&
strncmp("Tag ", fld->field_name, 4) == 0) { /* 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->field_name);
_TIFFfree(fld); _TIFFfree(fld);
} }
} }
}
_TIFFfree(tif->tif_fields); _TIFFfree(tif->tif_fields);
} }
......
...@@ -99,7 +99,7 @@ ...@@ -99,7 +99,7 @@
#define PACKAGE_NAME "LibTIFF Software" #define PACKAGE_NAME "LibTIFF Software"
/* Define to the full name and version of this package. */ /* 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 to the one symbol short name of this package. */
#define PACKAGE_TARNAME "tiff" #define PACKAGE_TARNAME "tiff"
...@@ -108,10 +108,10 @@ ...@@ -108,10 +108,10 @@
#define PACKAGE_URL "" #define PACKAGE_URL ""
/* Define to the version of this package. */ /* 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. */ /* 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) */ /* Default size of the strip in bytes (when strip chopping enabled) */
#define STRIP_SIZE_DEFAULT 8192 #define STRIP_SIZE_DEFAULT 8192
...@@ -120,7 +120,7 @@ ...@@ -120,7 +120,7 @@
#define USE_WIN32_FILEIO 1 #define USE_WIN32_FILEIO 1
/* Version number of package */ /* Version number of package */
#define VERSION "4.3.0" #define VERSION "4.4.0"
/* Support webp compression */ /* Support webp compression */
/* #undef WEBP_SUPPORT */ /* #undef WEBP_SUPPORT */
......
...@@ -40,7 +40,7 @@ ...@@ -40,7 +40,7 @@
#define DATATYPE_IEEEFP 3 /* !IEEE floating point data */ #define DATATYPE_IEEEFP 3 /* !IEEE floating point data */
static void 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) { if (*vpp) {
_TIFFfree(*vpp); _TIFFfree(*vpp);
...@@ -54,22 +54,20 @@ setByteArray(void** vpp, void* vp, size_t nmemb, size_t elem_size) ...@@ -54,22 +54,20 @@ setByteArray(void** vpp, void* vp, size_t nmemb, size_t elem_size)
_TIFFmemcpy(*vpp, vp, bytes); _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); } { setByteArray(vpp, vp, n, 1); }
void _TIFFsetString(char** cpp, char* cp) static void _TIFFsetNString(char** cpp, const char* cp, uint32_t n)
{ setByteArray((void**) cpp, (void*) cp, strlen(cp)+1, 1); } { setByteArray((void**) cpp, cp, n, 1); }
static void _TIFFsetNString(char** cpp, char* cp, uint32_t n) void _TIFFsetShortArray(uint16_t** wpp, const uint16_t* wp, uint32_t n)
{ setByteArray((void**) cpp, (void*) cp, n, 1); } { setByteArray((void**) wpp, wp, n, sizeof (uint16_t)); }
void _TIFFsetShortArray(uint16_t** wpp, uint16_t* wp, uint32_t n) void _TIFFsetLongArray(uint32_t** lpp, const uint32_t* lp, uint32_t n)
{ setByteArray((void**) wpp, (void*) wp, n, sizeof (uint16_t)); } { setByteArray((void**) lpp, lp, n, sizeof (uint32_t)); }
void _TIFFsetLongArray(uint32_t** lpp, uint32_t* lp, uint32_t n) static void _TIFFsetLong8Array(uint64_t** lpp, const uint64_t* lp, uint32_t n)
{ setByteArray((void**) lpp, (void*) lp, n, sizeof (uint32_t)); } { setByteArray((void**) lpp, lp, n, sizeof (uint64_t)); }
static void _TIFFsetLong8Array(uint64_t** lpp, uint64_t* lp, uint32_t n) void _TIFFsetFloatArray(float** fpp, const float* fp, uint32_t n)
{ setByteArray((void**) lpp, (void*) lp, n, sizeof (uint64_t)); } { setByteArray((void**) fpp, fp, n, sizeof (float)); }
void _TIFFsetFloatArray(float** fpp, float* fp, uint32_t n) void _TIFFsetDoubleArray(double** dpp, const double* dp, uint32_t n)
{ setByteArray((void**) fpp, (void*) fp, n, sizeof (float)); } { setByteArray((void**) dpp, dp, n, sizeof (double)); }
void _TIFFsetDoubleArray(double** dpp, double* dp, uint32_t n)
{ setByteArray((void**) dpp, (void*) dp, n, sizeof (double)); }
static void static void
setDoubleArrayOneValue(double** vpp, double value, size_t nmemb) setDoubleArrayOneValue(double** vpp, double value, size_t nmemb)
...@@ -228,7 +226,7 @@ _TIFFVSetField(TIFF* tif, uint32_t tag, va_list ap) ...@@ -228,7 +226,7 @@ _TIFFVSetField(TIFF* tif, uint32_t tag, va_list ap)
case TIFFTAG_COMPRESSION: case TIFFTAG_COMPRESSION:
v = (uint16_t) va_arg(ap, uint16_vap); 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 * previous module so that it can cleanup any state it's
* setup. * setup.
*/ */
...@@ -335,13 +333,13 @@ _TIFFVSetField(TIFF* tif, uint32_t tag, va_list ap) ...@@ -335,13 +333,13 @@ _TIFFVSetField(TIFF* tif, uint32_t tag, va_list ap)
break; break;
case TIFFTAG_XRESOLUTION: case TIFFTAG_XRESOLUTION:
dblval = va_arg(ap, double); dblval = va_arg(ap, double);
if( dblval < 0 ) if( dblval != dblval || dblval < 0 )
goto badvaluedouble; goto badvaluedouble;
td->td_xresolution = _TIFFClampDoubleToFloat( 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 != dblval || dblval < 0 )
goto badvaluedouble; goto badvaluedouble;
td->td_yresolution = _TIFFClampDoubleToFloat( dblval ); td->td_yresolution = _TIFFClampDoubleToFloat( dblval );
break; break;
...@@ -559,11 +557,8 @@ _TIFFVSetField(TIFF* tif, uint32_t tag, va_list ap) ...@@ -559,11 +557,8 @@ _TIFFVSetField(TIFF* tif, uint32_t tag, va_list ap)
/* /*
* Set custom value ... save a copy of the custom tag value. * 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. */ /*--: 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 = TIFFFieldSetGetSize(fip);
tv_size = _TIFFSetGetFieldSize(fip->set_field_type);
}
if (tv_size == 0) { if (tv_size == 0) {
status = 0; status = 0;
TIFFErrorExt(tif->tif_clientdata, module, TIFFErrorExt(tif->tif_clientdata, module,
...@@ -576,17 +571,28 @@ _TIFFVSetField(TIFF* tif, uint32_t tag, va_list ap) ...@@ -576,17 +571,28 @@ _TIFFVSetField(TIFF* tif, uint32_t tag, va_list ap)
if (fip->field_type == TIFF_ASCII) if (fip->field_type == TIFF_ASCII)
{ {
uint32_t ma; uint32_t ma;
char* mb; const char* mb;
if (fip->field_passcount) if (fip->field_passcount)
{ {
assert(fip->field_writecount==TIFF_VARIABLE2); assert(fip->field_writecount==TIFF_VARIABLE2);
ma=(uint32_t)va_arg(ap, uint32_t); ma=(uint32_t)va_arg(ap, uint32_t);
mb=(char*)va_arg(ap,char*); mb=(const char*)va_arg(ap,const char*);
} }
else else
{ {
mb=(char*)va_arg(ap,char*); mb=(const char*)va_arg(ap,const char*);
ma=(uint32_t)(strlen(mb) + 1); 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; tv->count=ma;
setByteArray(&tv->value,mb,ma,1); setByteArray(&tv->value,mb,ma,1);
...@@ -1041,11 +1047,15 @@ _TIFFVGetField(TIFF* tif, uint32_t tag, va_list ap) ...@@ -1041,11 +1047,15 @@ _TIFFVGetField(TIFF* tif, uint32_t tag, va_list ap)
case TIFFTAG_TILEOFFSETS: case TIFFTAG_TILEOFFSETS:
_TIFFFillStriles( tif ); _TIFFFillStriles( tif );
*va_arg(ap, const uint64_t**) = td->td_stripoffset_p; *va_arg(ap, const uint64_t**) = td->td_stripoffset_p;
if( td->td_stripoffset_p == NULL )
ret_val = 0;
break; break;
case TIFFTAG_STRIPBYTECOUNTS: case TIFFTAG_STRIPBYTECOUNTS:
case TIFFTAG_TILEBYTECOUNTS: case TIFFTAG_TILEBYTECOUNTS:
_TIFFFillStriles( tif ); _TIFFFillStriles( tif );
*va_arg(ap, const uint64_t**) = td->td_stripbytecount_p; *va_arg(ap, const uint64_t**) = td->td_stripbytecount_p;
if( td->td_stripbytecount_p == NULL )
ret_val = 0;
break; break;
case TIFFTAG_MATTEING: case TIFFTAG_MATTEING:
*va_arg(ap, uint16_t*) = *va_arg(ap, uint16_t*) =
...@@ -1224,7 +1234,7 @@ _TIFFVGetField(TIFF* tif, uint32_t tag, va_list ap) ...@@ -1224,7 +1234,7 @@ _TIFFVGetField(TIFF* tif, uint32_t tag, va_list ap)
case TIFF_SRATIONAL: case TIFF_SRATIONAL:
{ {
/*-- Rational2Double: For Rationals evaluate "set_field_type" to determine internal storage size and return value size. */ /*-- 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) { if (tv_size == 8) {
*va_arg(ap, double*) = *(double *)val; *va_arg(ap, double*) = *(double *)val;
ret_val = 1; ret_val = 1;
...@@ -1819,6 +1829,7 @@ TIFFUnlinkDirectory(TIFF* tif, uint16_t dirn) ...@@ -1819,6 +1829,7 @@ TIFFUnlinkDirectory(TIFF* tif, uint16_t dirn)
TIFFDefaultDirectory(tif); TIFFDefaultDirectory(tif);
tif->tif_diroff = 0; /* force link on next write */ tif->tif_diroff = 0; /* force link on next write */
tif->tif_nextdiroff = 0; /* next write must be at end */ 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_curoff = 0;
tif->tif_row = (uint32_t) -1; tif->tif_row = (uint32_t) -1;
tif->tif_curstrip = (uint32_t) -1; tif->tif_curstrip = (uint32_t) -1;
......
...@@ -286,7 +286,7 @@ struct _TIFFField { ...@@ -286,7 +286,7 @@ struct _TIFFField {
short field_readcount; /* read count/TIFF_VARIABLE/TIFF_SPP */ short field_readcount; /* read count/TIFF_VARIABLE/TIFF_SPP */
short field_writecount; /* write count/TIFF_VARIABLE */ short field_writecount; /* write count/TIFF_VARIABLE */
TIFFDataType field_type; /* type of associated data */ 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 set_field_type; /* type to be passed to TIFFSetField */
TIFFSetGetFieldType get_field_type; /* type to be passed to TIFFGetField */ TIFFSetGetFieldType get_field_type; /* type to be passed to TIFFGetField */
unsigned short field_bit; /* bit in fieldsset bit vector */ unsigned short field_bit; /* bit in fieldsset bit vector */
......
...@@ -149,7 +149,7 @@ tiffFields[] = { ...@@ -149,7 +149,7 @@ tiffFields[] = {
{ TIFFTAG_COPYRIGHT, -1, -1, TIFF_ASCII, 0, TIFF_SETGET_ASCII, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "Copyright", NULL }, { TIFFTAG_COPYRIGHT, -1, -1, TIFF_ASCII, 0, TIFF_SETGET_ASCII, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "Copyright", NULL },
/* end Pixar tags */ /* end Pixar tags */
{ TIFFTAG_RICHTIFFIPTC, -3, -3, TIFF_UNDEFINED, 0, TIFF_SETGET_C32_UINT8, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 1, "RichTIFFIPTC", NULL }, { 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. /*--: 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 * 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 * 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[] = { ...@@ -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_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_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_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 }, { TIFFTAG_INTEROPERABILITYIFD, 1, 1, TIFF_IFD8, 0, TIFF_SETGET_UNDEFINED, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 0, "InteroperabilityIFDOffset", NULL },
/* begin DNG tags */ /* begin DNG tags */
{ TIFFTAG_DNGVERSION, 4, 4, TIFF_BYTE, 0, TIFF_SETGET_C0_UINT8, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 0, "DNGVersion", NULL }, { TIFFTAG_DNGVERSION, 4, 4, TIFF_BYTE, 0, TIFF_SETGET_C0_UINT8, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 0, "DNGVersion", NULL },
...@@ -419,12 +420,17 @@ _TIFFSetupFields(TIFF* tif, const TIFFFieldArray* fieldarray) ...@@ -419,12 +420,17 @@ _TIFFSetupFields(TIFF* tif, const TIFFFieldArray* fieldarray)
for (i = 0; i < tif->tif_nfields; i++) { for (i = 0; i < tif->tif_nfields; i++) {
TIFFField *fld = tif->tif_fields[i]; TIFFField *fld = tif->tif_fields[i];
if (fld->field_name != NULL) {
if (fld->field_bit == FIELD_CUSTOM && if (fld->field_bit == FIELD_CUSTOM &&
strncmp("Tag ", fld->field_name, 4) == 0) { TIFFFieldIsAnonymous(fld)) {
_TIFFfree(fld->field_name); _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(fld);
} }
} }
}
_TIFFfree(tif->tif_fields); _TIFFfree(tif->tif_fields);
tif->tif_fields = NULL; tif->tif_fields = NULL;
...@@ -530,7 +536,7 @@ _TIFFPrintFieldInfo(TIFF* tif, FILE* fd) ...@@ -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 int
TIFFDataWidth(TIFFDataType type) TIFFDataWidth(TIFFDataType type)
...@@ -563,55 +569,29 @@ TIFFDataWidth(TIFFDataType type) ...@@ -563,55 +569,29 @@ TIFFDataWidth(TIFFDataType type)
} }
} }
/* /*
* Return size of TIFFDataType in bytes. * Return internal storage size of TIFFSetGetFieldType in bytes.
* * TIFFSetField() and TIFFGetField() have to provide the parameter accordingly.
* XXX: We need a separate function to determine the space needed * Replaces internal functions _TIFFDataSize() and _TIFFSetGetFieldSize()
* to store the value. For TIFF_RATIONAL values TIFFDataWidth() returns 8, * with now extern available function TIFFFieldSetGetSize().
* but we use 4-byte float to represent rationals.
*/ */
int int
_TIFFDataSize(TIFFDataType type) TIFFFieldSetGetSize(const TIFFField* fip)
{ {
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: * TIFFSetField() and TIFFGetField() must provide the parameter accordingly to
* Return size of TIFFSetGetFieldType in bytes. * the definition of "set_field_type" of the tag definition in dir_info.c.
* This function returns the data size for that purpose.
* *
* XXX: TIFF_RATIONAL values for FIELD_CUSTOM are stored internally as 4-byte float. * Furthermore, this data size is also used for the internal storage,
* However, some of them should be stored internally as 8-byte double. * even for TIFF_RATIONAL values for FIELD_CUSTOM, which are stored internally as 4-byte float,
* This is now managed by the SetGetField of the tag-definition! * but some of them should be stored internally as 8-byte double,
*/ * depending on the "set_field_type" _FLOAT_ or _DOUBLE_.
int */
_TIFFSetGetFieldSize(TIFFSetGetFieldType setgettype) if (fip == NULL) return 0;
{
switch (setgettype) switch (fip->set_field_type)
{ {
case TIFF_SETGET_UNDEFINED: case TIFF_SETGET_UNDEFINED:
case TIFF_SETGET_ASCII: case TIFF_SETGET_ASCII:
...@@ -619,7 +599,7 @@ _TIFFSetGetFieldSize(TIFFSetGetFieldType setgettype) ...@@ -619,7 +599,7 @@ _TIFFSetGetFieldSize(TIFFSetGetFieldType setgettype)
case TIFF_SETGET_C16_ASCII: case TIFF_SETGET_C16_ASCII:
case TIFF_SETGET_C32_ASCII: case TIFF_SETGET_C32_ASCII:
case TIFF_SETGET_OTHER: case TIFF_SETGET_OTHER:
return 0; return 1;
case TIFF_SETGET_UINT8: case TIFF_SETGET_UINT8:
case TIFF_SETGET_SINT8: case TIFF_SETGET_SINT8:
case TIFF_SETGET_C0_UINT8: case TIFF_SETGET_C0_UINT8:
...@@ -673,7 +653,48 @@ _TIFFSetGetFieldSize(TIFFSetGetFieldType setgettype) ...@@ -673,7 +653,48 @@ _TIFFSetGetFieldSize(TIFFSetGetFieldType setgettype)
default: default:
return 0; 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* const TIFFField*
...@@ -788,6 +809,12 @@ TIFFFieldWriteCount(const TIFFField* fip) ...@@ -788,6 +809,12 @@ TIFFFieldWriteCount(const TIFFField* fip)
return fip->field_writecount; return fip->field_writecount;
} }
int
TIFFFieldIsAnonymous(const TIFFField *fip)
{
return fip->field_anonymous;
}
const TIFFField* const TIFFField*
_TIFFFindOrRegisterField(TIFF *tif, uint32_t tag, TIFFDataType dt) _TIFFFindOrRegisterField(TIFF *tif, uint32_t tag, TIFFDataType dt)
...@@ -819,7 +846,7 @@ _TIFFCreateAnonField(TIFF *tif, uint32_t tag, TIFFDataType field_type) ...@@ -819,7 +846,7 @@ _TIFFCreateAnonField(TIFF *tif, uint32_t tag, TIFFDataType field_type)
fld->field_readcount = TIFF_VARIABLE2; fld->field_readcount = TIFF_VARIABLE2;
fld->field_writecount = TIFF_VARIABLE2; fld->field_writecount = TIFF_VARIABLE2;
fld->field_type = field_type; fld->field_type = field_type;
fld->reserved = 0; fld->field_anonymous = 1; /* indicate that this is an anonymous / unknown tag */
switch (field_type) switch (field_type)
{ {
case TIFF_BYTE: case TIFF_BYTE:
...@@ -892,6 +919,8 @@ _TIFFCreateAnonField(TIFF *tif, uint32_t tag, TIFFDataType field_type) ...@@ -892,6 +919,8 @@ _TIFFCreateAnonField(TIFF *tif, uint32_t tag, TIFFDataType field_type)
/* /*
* note that this name is a special sign to TIFFClose() and * note that this name is a special sign to TIFFClose() and
* _TIFFSetupFields() to free the field * _TIFFSetupFields() to free the field
* Update:
* This special sign is replaced by fld->field_anonymous flag.
*/ */
(void) snprintf(fld->field_name, 32, "Tag %d", (int) tag); (void) snprintf(fld->field_name, 32, "Tag %d", (int) tag);
...@@ -1102,7 +1131,7 @@ TIFFMergeFieldInfo(TIFF* tif, const TIFFFieldInfo info[], uint32_t n) ...@@ -1102,7 +1131,7 @@ TIFFMergeFieldInfo(TIFF* tif, const TIFFFieldInfo info[], uint32_t n)
tp->field_readcount = info[i].field_readcount; tp->field_readcount = info[i].field_readcount;
tp->field_writecount = info[i].field_writecount; tp->field_writecount = info[i].field_writecount;
tp->field_type = info[i].field_type; tp->field_type = info[i].field_type;
tp->reserved = 0; tp->field_anonymous = 0;
tp->set_field_type = tp->set_field_type =
_TIFFSetGetType(info[i].field_type, _TIFFSetGetType(info[i].field_type,
info[i].field_readcount, info[i].field_readcount,
...@@ -1114,6 +1143,11 @@ TIFFMergeFieldInfo(TIFF* tif, const TIFFFieldInfo info[], uint32_t n) ...@@ -1114,6 +1143,11 @@ TIFFMergeFieldInfo(TIFF* tif, const TIFFFieldInfo info[], uint32_t n)
tp->field_bit = info[i].field_bit; tp->field_bit = info[i].field_bit;
tp->field_oktochange = info[i].field_oktochange; tp->field_oktochange = info[i].field_oktochange;
tp->field_passcount = info[i].field_passcount; 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_name = info[i].field_name;
tp->field_subfields = NULL; tp->field_subfields = NULL;
tp++; tp++;
......
...@@ -300,6 +300,12 @@ TIFFRewriteDirectory( TIFF *tif ) ...@@ -300,6 +300,12 @@ TIFFRewriteDirectory( TIFF *tif )
return (0); 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 else
{ {
uint32_t nextdir; uint32_t nextdir;
...@@ -337,6 +343,8 @@ TIFFRewriteDirectory( TIFF *tif ) ...@@ -337,6 +343,8 @@ TIFFRewriteDirectory( TIFF *tif )
return (0); return (0);
} }
tif->tif_diroff=0; tif->tif_diroff=0;
/* Force a full-traversal to reach the zeroed pointer */
tif->tif_lastdiroff=0;
break; break;
} }
nextdir=nextnextdir; nextdir=nextnextdir;
...@@ -403,6 +411,8 @@ TIFFRewriteDirectory( TIFF *tif ) ...@@ -403,6 +411,8 @@ TIFFRewriteDirectory( TIFF *tif )
return (0); return (0);
} }
tif->tif_diroff=0; tif->tif_diroff=0;
/* Force a full-traversal to reach the zeroed pointer */
tif->tif_lastdiroff=0;
break; break;
} }
nextdir=nextnextdir; nextdir=nextnextdir;
...@@ -477,6 +487,12 @@ TIFFWriteDirectorySec(TIFF* tif, int isimage, int imagedone, uint64_t* pdiroff) ...@@ -477,6 +487,12 @@ TIFFWriteDirectorySec(TIFF* tif, int isimage, int imagedone, uint64_t* pdiroff)
} }
tif->tif_flags &= ~(TIFF_BEENWRITING|TIFF_BUFFERSETUP); 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; dir=NULL;
dirmem=NULL; dirmem=NULL;
dirsize=0; dirsize=0;
...@@ -814,7 +830,7 @@ TIFFWriteDirectorySec(TIFF* tif, int isimage, int imagedone, uint64_t* pdiroff) ...@@ -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. */ /*-- Rational2Double: For Rationals evaluate "set_field_type" to determine internal storage size. */
int tv_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 (tv_size == 8) {
if (!TIFFWriteDirectoryTagRationalDoubleArray(tif,&ndir,dir,tag,count,tif->tif_dir.td_customValues[m].value)) if (!TIFFWriteDirectoryTagRationalDoubleArray(tif,&ndir,dir,tag,count,tif->tif_dir.td_customValues[m].value))
goto bad; goto bad;
...@@ -833,7 +849,7 @@ TIFFWriteDirectorySec(TIFF* tif, int isimage, int imagedone, uint64_t* pdiroff) ...@@ -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. */ /*-- Rational2Double: For Rationals evaluate "set_field_type" to determine internal storage size. */
int tv_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 (tv_size == 8) {
if (!TIFFWriteDirectoryTagSrationalDoubleArray(tif,&ndir,dir,tag,count,tif->tif_dir.td_customValues[m].value)) if (!TIFFWriteDirectoryTagSrationalDoubleArray(tif,&ndir,dir,tag,count,tif->tif_dir.td_customValues[m].value))
goto bad; goto bad;
...@@ -1774,10 +1790,12 @@ static int _WriteAsType(TIFF* tif, uint64_t strile_size, uint64_t uncompressed_t ...@@ -1774,10 +1790,12 @@ static int _WriteAsType(TIFF* tif, uint64_t strile_size, uint64_t uncompressed_t
else if ( compression == COMPRESSION_JPEG || else if ( compression == COMPRESSION_JPEG ||
compression == COMPRESSION_LZW || compression == COMPRESSION_LZW ||
compression == COMPRESSION_ADOBE_DEFLATE || compression == COMPRESSION_ADOBE_DEFLATE ||
compression == COMPRESSION_DEFLATE ||
compression == COMPRESSION_LZMA || compression == COMPRESSION_LZMA ||
compression == COMPRESSION_LERC || compression == COMPRESSION_LERC ||
compression == COMPRESSION_ZSTD || compression == COMPRESSION_ZSTD ||
compression == COMPRESSION_WEBP ) compression == COMPRESSION_WEBP ||
compression == COMPRESSION_JXL )
{ {
/* For a few select compression types, we assume that in the worst */ /* For a few select compression types, we assume that in the worst */
/* case the compressed size will be 10 times the uncompressed size */ /* 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 ...@@ -3058,7 +3076,12 @@ TIFFWriteDirectoryTagData(TIFF* tif, uint32_t* ndir, TIFFDirEntry* dir, uint16_t
TIFFErrorExt(tif->tif_clientdata,module,"IO error writing tag data"); TIFFErrorExt(tif->tif_clientdata,module,"IO error writing tag data");
return(0); 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)) if (!WriteOK(tif,data,(tmsize_t)datalength))
{ {
TIFFErrorExt(tif->tif_clientdata,module,"IO error writing tag data"); TIFFErrorExt(tif->tif_clientdata,module,"IO error writing tag data");
...@@ -3161,6 +3184,7 @@ TIFFLinkDirectory(TIFF* tif) ...@@ -3161,6 +3184,7 @@ TIFFLinkDirectory(TIFF* tif)
* First directory, overwrite offset in header. * First directory, overwrite offset in header.
*/ */
tif->tif_header.classic.tiff_diroff = (uint32_t) tif->tif_diroff; tif->tif_header.classic.tiff_diroff = (uint32_t) tif->tif_diroff;
tif->tif_lastdiroff = tif->tif_diroff;
(void) TIFFSeekFile(tif,4, SEEK_SET); (void) TIFFSeekFile(tif,4, SEEK_SET);
if (!WriteOK(tif, &m, 4)) { if (!WriteOK(tif, &m, 4)) {
TIFFErrorExt(tif->tif_clientdata, tif->tif_name, TIFFErrorExt(tif->tif_clientdata, tif->tif_name,
...@@ -3172,7 +3196,13 @@ TIFFLinkDirectory(TIFF* tif) ...@@ -3172,7 +3196,13 @@ TIFFLinkDirectory(TIFF* tif)
/* /*
* Not the first directory, search to the last and append. * Not the first directory, search to the last and append.
*/ */
if (tif->tif_lastdiroff != 0) {
nextdir = (uint32_t) tif->tif_lastdiroff;
}
else {
nextdir = tif->tif_header.classic.tiff_diroff; nextdir = tif->tif_header.classic.tiff_diroff;
}
while(1) { while(1) {
uint16_t dircount; uint16_t dircount;
uint32_t nextnextdir; uint32_t nextnextdir;
...@@ -3203,6 +3233,7 @@ TIFFLinkDirectory(TIFF* tif) ...@@ -3203,6 +3233,7 @@ TIFFLinkDirectory(TIFF* tif)
"Error writing directory link"); "Error writing directory link");
return (0); return (0);
} }
tif->tif_lastdiroff = tif->tif_diroff;
break; break;
} }
nextdir=nextnextdir; nextdir=nextnextdir;
...@@ -3220,6 +3251,7 @@ TIFFLinkDirectory(TIFF* tif) ...@@ -3220,6 +3251,7 @@ TIFFLinkDirectory(TIFF* tif)
* First directory, overwrite offset in header. * First directory, overwrite offset in header.
*/ */
tif->tif_header.big.tiff_diroff = tif->tif_diroff; tif->tif_header.big.tiff_diroff = tif->tif_diroff;
tif->tif_lastdiroff = tif->tif_diroff;
(void) TIFFSeekFile(tif,8, SEEK_SET); (void) TIFFSeekFile(tif,8, SEEK_SET);
if (!WriteOK(tif, &m, 8)) { if (!WriteOK(tif, &m, 8)) {
TIFFErrorExt(tif->tif_clientdata, tif->tif_name, TIFFErrorExt(tif->tif_clientdata, tif->tif_name,
...@@ -3231,7 +3263,12 @@ TIFFLinkDirectory(TIFF* tif) ...@@ -3231,7 +3263,12 @@ TIFFLinkDirectory(TIFF* tif)
/* /*
* Not the first directory, search to the last and append. * Not the first directory, search to the last and append.
*/ */
if (tif->tif_lastdiroff != 0) {
nextdir = tif->tif_lastdiroff;
}
else {
nextdir = tif->tif_header.big.tiff_diroff; nextdir = tif->tif_header.big.tiff_diroff;
}
while(1) { while(1) {
uint64_t dircount64; uint64_t dircount64;
uint16_t dircount; uint16_t dircount;
...@@ -3270,6 +3307,7 @@ TIFFLinkDirectory(TIFF* tif) ...@@ -3270,6 +3307,7 @@ TIFFLinkDirectory(TIFF* tif)
"Error writing directory link"); "Error writing directory link");
return (0); return (0);
} }
tif->tif_lastdiroff = tif->tif_diroff;
break; break;
} }
nextdir=nextnextdir; nextdir=nextnextdir;
...@@ -3668,8 +3706,17 @@ _TIFFRewriteField(TIFF* tif, uint16_t tag, TIFFDataType in_datatype, ...@@ -3668,8 +3706,17 @@ _TIFFRewriteField(TIFF* tif, uint16_t tag, TIFFDataType in_datatype,
} }
else else
{ {
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)); memcpy( &entry_offset, buf_to_write, count*TIFFDataWidth(datatype));
} }
}
_TIFFfree( buf_to_write ); _TIFFfree( buf_to_write );
buf_to_write = 0; buf_to_write = 0;
......
...@@ -327,6 +327,20 @@ Fax3Decode2D(TIFF* tif, uint8_t* buf, tmsize_t occ, uint16_t s) ...@@ -327,6 +327,20 @@ Fax3Decode2D(TIFF* tif, uint8_t* buf, tmsize_t occ, uint16_t s)
} }
#undef SWAP #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 * Bit-fill a row according to the white/black
* runs generated during G3/G4 decoding. * runs generated during G3/G4 decoding.
...@@ -338,7 +352,8 @@ _TIFFFax3fillruns(unsigned char* buf, uint32_t* runs, uint32_t* erun, uint32_t l ...@@ -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 }; { 0x00, 0x80, 0xc0, 0xe0, 0xf0, 0xf8, 0xfc, 0xfe, 0xff };
unsigned char* cp; unsigned char* cp;
uint32_t x, bx, run; uint32_t x, bx, run;
int32_t n; int32_t n, nw;
int64_t* lp;
if ((erun-runs)&1) if ((erun-runs)&1)
*erun++ = 0; *erun++ = 0;
...@@ -356,8 +371,21 @@ _TIFFFax3fillruns(unsigned char* buf, uint32_t* runs, uint32_t* erun, uint32_t l ...@@ -356,8 +371,21 @@ _TIFFFax3fillruns(unsigned char* buf, uint32_t* runs, uint32_t* erun, uint32_t l
run -= 8-bx; run -= 8-bx;
} }
if( (n = run >> 3) != 0 ) { /* multiple bytes to fill */ if( (n = run >> 3) != 0 ) { /* multiple bytes to fill */
memset( cp, 0, n ); if ((n/sizeof (int64_t)) > 1) {
cp += n; /*
* 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; run &= 7;
} }
if (run) if (run)
...@@ -378,8 +406,21 @@ _TIFFFax3fillruns(unsigned char* buf, uint32_t* runs, uint32_t* erun, uint32_t l ...@@ -378,8 +406,21 @@ _TIFFFax3fillruns(unsigned char* buf, uint32_t* runs, uint32_t* erun, uint32_t l
run -= 8-bx; run -= 8-bx;
} }
if( (n = run>>3) != 0 ) { /* multiple bytes to fill */ if( (n = run>>3) != 0 ) { /* multiple bytes to fill */
memset( cp, 0xff, n ); if ((n/sizeof (int64_t)) > 1) {
cp += n; /*
* 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; run &= 7;
} }
/* Explicit 0xff masking to make icc -check=conversions happy */ /* Explicit 0xff masking to make icc -check=conversions happy */
......
...@@ -579,7 +579,7 @@ LogLuvEncode32(TIFF* tif, uint8_t* bp, tmsize_t cc, uint16_t s) ...@@ -579,7 +579,7 @@ LogLuvEncode32(TIFF* tif, uint8_t* bp, tmsize_t cc, uint16_t s)
uint32_t* tp; uint32_t* tp;
uint32_t b; uint32_t b;
tmsize_t occ; tmsize_t occ;
int rc=0, mask; int rc=0;
tmsize_t beg; tmsize_t beg;
(void)s; (void)s;
...@@ -603,6 +603,7 @@ LogLuvEncode32(TIFF* tif, uint8_t* bp, tmsize_t cc, uint16_t s) ...@@ -603,6 +603,7 @@ LogLuvEncode32(TIFF* tif, uint8_t* bp, tmsize_t cc, uint16_t s)
op = tif->tif_rawcp; op = tif->tif_rawcp;
occ = tif->tif_rawdatasize - tif->tif_rawcc; occ = tif->tif_rawdatasize - tif->tif_rawcc;
for (shft = 24; shft >= 0; shft -=8) { for (shft = 24; shft >= 0; shft -=8) {
const uint32_t mask = 0xffU << shft; /* find next run */
for (i = 0; i < npixels; i += rc) { for (i = 0; i < npixels; i += rc) {
if (occ < 4) { if (occ < 4) {
tif->tif_rawcp = op; tif->tif_rawcp = op;
...@@ -612,7 +613,6 @@ LogLuvEncode32(TIFF* tif, uint8_t* bp, tmsize_t cc, uint16_t s) ...@@ -612,7 +613,6 @@ LogLuvEncode32(TIFF* tif, uint8_t* bp, tmsize_t cc, uint16_t s)
op = tif->tif_rawcp; op = tif->tif_rawcp;
occ = tif->tif_rawdatasize - tif->tif_rawcc; occ = tif->tif_rawdatasize - tif->tif_rawcc;
} }
mask = 0xff << shft; /* find next run */
for (beg = i; beg < npixels; beg += rc) { for (beg = i; beg < npixels; beg += rc) {
b = tp[beg] & mask; b = tp[beg] & mask;
rc = 1; rc = 1;
...@@ -804,7 +804,7 @@ L16fromY(LogLuvState* sp, uint8_t* op, tmsize_t n) ...@@ -804,7 +804,7 @@ L16fromY(LogLuvState* sp, uint8_t* op, tmsize_t n)
static static
#endif #endif
void void
XYZtoRGB24(float xyz[3], uint8_t rgb[3]) XYZtoRGB24(float* xyz, uint8_t* rgb)
{ {
double r, g, b; double r, g, b;
/* assume CCIR-709 primaries */ /* assume CCIR-709 primaries */
...@@ -958,7 +958,7 @@ uv_decode(double *up, double *vp, int c) /* decode (u',v') index */ ...@@ -958,7 +958,7 @@ uv_decode(double *up, double *vp, int c) /* decode (u',v') index */
static static
#endif #endif
void void
LogLuv24toXYZ(uint32_t p, float XYZ[3]) LogLuv24toXYZ(uint32_t p, float* XYZ)
{ {
int Ce; int Ce;
double L, u, v, s, x, y; double L, u, v, s, x, y;
...@@ -986,7 +986,7 @@ LogLuv24toXYZ(uint32_t p, float XYZ[3]) ...@@ -986,7 +986,7 @@ LogLuv24toXYZ(uint32_t p, float XYZ[3])
static static
#endif #endif
uint32_t uint32_t
LogLuv24fromXYZ(float XYZ[3], int em) LogLuv24fromXYZ(float* XYZ, int em)
{ {
int Le, Ce; int Le, Ce;
double u, v, s; double u, v, s;
...@@ -1099,7 +1099,7 @@ Luv24fromLuv48(LogLuvState* sp, uint8_t* op, tmsize_t n) ...@@ -1099,7 +1099,7 @@ Luv24fromLuv48(LogLuvState* sp, uint8_t* op, tmsize_t n)
static static
#endif #endif
void void
LogLuv32toXYZ(uint32_t p, float XYZ[3]) LogLuv32toXYZ(uint32_t p, float* XYZ)
{ {
double L, u, v, s, x, y; double L, u, v, s, x, y;
/* decode luminance */ /* decode luminance */
...@@ -1124,7 +1124,7 @@ LogLuv32toXYZ(uint32_t p, float XYZ[3]) ...@@ -1124,7 +1124,7 @@ LogLuv32toXYZ(uint32_t p, float XYZ[3])
static static
#endif #endif
uint32_t uint32_t
LogLuv32fromXYZ(float XYZ[3], int em) LogLuv32fromXYZ(float* XYZ, int em)
{ {
unsigned int Le, ue, ve; unsigned int Le, ue, ve;
double u, v, s; double u, v, s;
......
...@@ -96,7 +96,6 @@ TIFFClientOpen( ...@@ -96,7 +96,6 @@ TIFFClientOpen(
assert(sizeof(int32_t) == 4); assert(sizeof(int32_t) == 4);
assert(sizeof(uint64_t) == 8); assert(sizeof(uint64_t) == 8);
assert(sizeof(int64_t) == 8); assert(sizeof(int64_t) == 8);
assert(sizeof(tmsize_t)==sizeof(void*));
{ {
union{ union{
uint8_t a8[2]; uint8_t a8[2];
...@@ -354,6 +353,7 @@ TIFFClientOpen( ...@@ -354,6 +353,7 @@ TIFFClientOpen(
if (!TIFFDefaultDirectory(tif)) if (!TIFFDefaultDirectory(tif))
goto bad; goto bad;
tif->tif_diroff = 0; tif->tif_diroff = 0;
tif->tif_lastdiroff = 0;
tif->tif_dirlist = NULL; tif->tif_dirlist = NULL;
tif->tif_dirlistsize = 0; tif->tif_dirlistsize = 0;
tif->tif_dirnumber = 0; tif->tif_dirnumber = 0;
...@@ -481,8 +481,6 @@ TIFFClientOpen( ...@@ -481,8 +481,6 @@ TIFFClientOpen(
* Setup initial directory. * Setup initial directory.
*/ */
if (TIFFReadDirectory(tif)) { if (TIFFReadDirectory(tif)) {
tif->tif_rawcc = (tmsize_t)-1;
tif->tif_flags |= TIFF_BUFFERSETUP;
return (tif); return (tif);
} }
break; break;
...@@ -670,6 +668,15 @@ TIFFIsBigEndian(TIFF* tif) ...@@ -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. * Return pointer to file read method.
*/ */
TIFFReadWriteProc TIFFReadWriteProc
......
...@@ -214,23 +214,17 @@ static int ...@@ -214,23 +214,17 @@ static int
PackBitsDecode(TIFF* tif, uint8_t* op, tmsize_t occ, uint16_t s) PackBitsDecode(TIFF* tif, uint8_t* op, tmsize_t occ, uint16_t s)
{ {
static const char module[] = "PackBitsDecode"; static const char module[] = "PackBitsDecode";
char *bp; int8_t *bp;
tmsize_t cc; tmsize_t cc;
long n; long n;
int b; int b;
(void) s; (void) s;
bp = (char*) tif->tif_rawcp; bp = (int8_t*) tif->tif_rawcp;
cc = tif->tif_rawcc; cc = tif->tif_rawcc;
while (cc > 0 && occ > 0) { while (cc > 0 && occ > 0) {
n = (long) *bp++; n = (long) *bp++;
cc--; 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 < 0) { /* replicate next byte -n+1 times */
if (n == -128) /* nop */ if (n == -128) /* nop */
continue; continue;
......
...@@ -35,13 +35,17 @@ ...@@ -35,13 +35,17 @@
static int horAcc8(TIFF* tif, uint8_t* cp0, tmsize_t cc); static int horAcc8(TIFF* tif, uint8_t* cp0, tmsize_t cc);
static int horAcc16(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 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 swabHorAcc16(TIFF* tif, uint8_t* cp0, tmsize_t cc);
static int swabHorAcc32(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 horDiff8(TIFF* tif, uint8_t* cp0, tmsize_t cc);
static int horDiff16(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 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 swabHorDiff16(TIFF* tif, uint8_t* cp0, tmsize_t cc);
static int swabHorDiff32(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 fpAcc(TIFF* tif, uint8_t* cp0, tmsize_t cc);
static int fpDiff(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); static int PredictorDecodeRow(TIFF* tif, uint8_t* op0, tmsize_t occ0, uint16_t s);
...@@ -64,7 +68,8 @@ PredictorSetup(TIFF* tif) ...@@ -64,7 +68,8 @@ PredictorSetup(TIFF* tif)
case PREDICTOR_HORIZONTAL: case PREDICTOR_HORIZONTAL:
if (td->td_bitspersample != 8 if (td->td_bitspersample != 8
&& td->td_bitspersample != 16 && td->td_bitspersample != 16
&& td->td_bitspersample != 32) { && td->td_bitspersample != 32
&& td->td_bitspersample != 64) {
TIFFErrorExt(tif->tif_clientdata, module, TIFFErrorExt(tif->tif_clientdata, module,
"Horizontal differencing \"Predictor\" not supported with %"PRIu16"-bit samples", "Horizontal differencing \"Predictor\" not supported with %"PRIu16"-bit samples",
td->td_bitspersample); td->td_bitspersample);
...@@ -126,6 +131,7 @@ PredictorSetupDecode(TIFF* tif) ...@@ -126,6 +131,7 @@ PredictorSetupDecode(TIFF* tif)
case 8: sp->decodepfunc = horAcc8; break; case 8: sp->decodepfunc = horAcc8; break;
case 16: sp->decodepfunc = horAcc16; break; case 16: sp->decodepfunc = horAcc16; break;
case 32: sp->decodepfunc = horAcc32; break; case 32: sp->decodepfunc = horAcc32; break;
case 64: sp->decodepfunc = horAcc64; break;
} }
/* /*
* Override default decoding method with one that does the * Override default decoding method with one that does the
...@@ -155,6 +161,9 @@ PredictorSetupDecode(TIFF* tif) ...@@ -155,6 +161,9 @@ PredictorSetupDecode(TIFF* tif)
} else if (sp->decodepfunc == horAcc32) { } else if (sp->decodepfunc == horAcc32) {
sp->decodepfunc = swabHorAcc32; sp->decodepfunc = swabHorAcc32;
tif->tif_postdecode = _TIFFNoPostDecode; tif->tif_postdecode = _TIFFNoPostDecode;
} else if (sp->decodepfunc == horAcc64) {
sp->decodepfunc = swabHorAcc64;
tif->tif_postdecode = _TIFFNoPostDecode;
} }
} }
} }
...@@ -205,6 +214,7 @@ PredictorSetupEncode(TIFF* tif) ...@@ -205,6 +214,7 @@ PredictorSetupEncode(TIFF* tif)
case 8: sp->encodepfunc = horDiff8; break; case 8: sp->encodepfunc = horDiff8; break;
case 16: sp->encodepfunc = horDiff16; break; case 16: sp->encodepfunc = horDiff16; break;
case 32: sp->encodepfunc = horDiff32; break; case 32: sp->encodepfunc = horDiff32; break;
case 64: sp->encodepfunc = horDiff64; break;
} }
/* /*
* Override default encoding method with one that does the * Override default encoding method with one that does the
...@@ -234,6 +244,9 @@ PredictorSetupEncode(TIFF* tif) ...@@ -234,6 +244,9 @@ PredictorSetupEncode(TIFF* tif)
} else if (sp->encodepfunc == horDiff32) { } else if (sp->encodepfunc == horDiff32) {
sp->encodepfunc = swabHorDiff32; sp->encodepfunc = swabHorDiff32;
tif->tif_postdecode = _TIFFNoPostDecode; 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) ...@@ -403,6 +416,41 @@ horAcc32(TIFF* tif, uint8_t* cp0, tmsize_t cc)
return 1; 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. * Floating point predictor accumulation routine.
*/ */
...@@ -638,6 +686,46 @@ swabHorDiff32(TIFF* tif, uint8_t* cp0, tmsize_t cc) ...@@ -638,6 +686,46 @@ swabHorDiff32(TIFF* tif, uint8_t* cp0, tmsize_t cc)
return 1; 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. * Floating point predictor differencing routine.
*/ */
......
...@@ -751,8 +751,6 @@ TIFFFillStrip(TIFF* tif, uint32_t strip) ...@@ -751,8 +751,6 @@ TIFFFillStrip(TIFF* tif, uint32_t strip)
(bytecount - 4096) / 10 > (uint64_t)stripsize ) (bytecount - 4096) / 10 > (uint64_t)stripsize )
{ {
uint64_t newbytecount = (uint64_t)stripsize * 10 + 4096; uint64_t newbytecount = (uint64_t)stripsize * 10 + 4096;
if( newbytecount == 0 || newbytecount > (uint64_t)TIFF_INT64_MAX )
{
TIFFErrorExt(tif->tif_clientdata, module, TIFFErrorExt(tif->tif_clientdata, module,
"Too large strip byte count %"PRIu64", strip %"PRIu32". Limiting to %"PRIu64, "Too large strip byte count %"PRIu64", strip %"PRIu32". Limiting to %"PRIu64,
bytecount, bytecount,
...@@ -761,7 +759,6 @@ TIFFFillStrip(TIFF* tif, uint32_t strip) ...@@ -761,7 +759,6 @@ TIFFFillStrip(TIFF* tif, uint32_t strip)
bytecount = newbytecount; bytecount = newbytecount;
} }
} }
}
if (isMapped(tif)) { if (isMapped(tif)) {
/* /*
...@@ -1145,8 +1142,6 @@ TIFFFillTile(TIFF* tif, uint32_t tile) ...@@ -1145,8 +1142,6 @@ TIFFFillTile(TIFF* tif, uint32_t tile)
(bytecount - 4096) / 10 > (uint64_t)stripsize ) (bytecount - 4096) / 10 > (uint64_t)stripsize )
{ {
uint64_t newbytecount = (uint64_t)stripsize * 10 + 4096; uint64_t newbytecount = (uint64_t)stripsize * 10 + 4096;
if( newbytecount == 0 || newbytecount > (uint64_t)TIFF_INT64_MAX )
{
TIFFErrorExt(tif->tif_clientdata, module, TIFFErrorExt(tif->tif_clientdata, module,
"Too large tile byte count %"PRIu64", tile %"PRIu32". Limiting to %"PRIu64, "Too large tile byte count %"PRIu64", tile %"PRIu32". Limiting to %"PRIu64,
bytecount, bytecount,
...@@ -1155,7 +1150,6 @@ TIFFFillTile(TIFF* tif, uint32_t tile) ...@@ -1155,7 +1150,6 @@ TIFFFillTile(TIFF* tif, uint32_t tile)
bytecount = newbytecount; bytecount = newbytecount;
} }
} }
}
if (isMapped(tif)) { if (isMapped(tif)) {
/* /*
......
...@@ -28,6 +28,7 @@ ...@@ -28,6 +28,7 @@
*/ */
#include "tiffiop.h" #include "tiffiop.h"
#include <stdlib.h>
#include <windows.h> #include <windows.h>
......
...@@ -128,14 +128,8 @@ TIFFWriteScanline(TIFF* tif, void* buf, uint32_t row, uint16_t sample) ...@@ -128,14 +128,8 @@ TIFFWriteScanline(TIFF* tif, void* buf, uint32_t row, uint16_t sample)
tif->tif_rawcc = 0; tif->tif_rawcc = 0;
tif->tif_rawcp = tif->tif_rawdata; tif->tif_rawcp = tif->tif_rawdata;
if( td->td_stripbytecount_p[strip] > 0 ) /* this informs TIFFAppendToStrip() we have changed strip */
{
/* 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; tif->tif_curoff = 0;
}
if (!(*tif->tif_preencode)(tif, sample)) if (!(*tif->tif_preencode)(tif, sample))
return (-1); return (-1);
...@@ -194,10 +188,6 @@ static int _TIFFReserveLargeEnoughWriteBuffer(TIFF* tif, uint32_t strip_or_tile) ...@@ -194,10 +188,6 @@ static int _TIFFReserveLargeEnoughWriteBuffer(TIFF* tif, uint32_t strip_or_tile)
(tmsize_t)TIFFroundup_64(safe_buffer_size, 1024))) ) (tmsize_t)TIFFroundup_64(safe_buffer_size, 1024))) )
return 0; return 0;
} }
/* Force TIFFAppendToStrip() to consider placing data at end
of file. */
tif->tif_curoff = 0;
} }
return 1; return 1;
} }
...@@ -246,8 +236,12 @@ TIFFWriteEncodedStrip(TIFF* tif, uint32_t strip, void* data, tmsize_t cc) ...@@ -246,8 +236,12 @@ TIFFWriteEncodedStrip(TIFF* tif, uint32_t strip, void* data, tmsize_t cc)
return ((tmsize_t) -1); return ((tmsize_t) -1);
tif->tif_flags |= TIFF_BUF4WRITE; tif->tif_flags |= TIFF_BUF4WRITE;
tif->tif_curstrip = strip; tif->tif_curstrip = strip;
/* this informs TIFFAppendToStrip() we have changed or reset strip */
tif->tif_curoff = 0;
if( !_TIFFReserveLargeEnoughWriteBuffer(tif, strip) ) { if( !_TIFFReserveLargeEnoughWriteBuffer(tif, strip) ) {
return ((tmsize_t)(-1)); return ((tmsize_t)(-1));
} }
...@@ -346,7 +340,12 @@ TIFFWriteRawStrip(TIFF* tif, uint32_t strip, void* data, tmsize_t cc) ...@@ -346,7 +340,12 @@ TIFFWriteRawStrip(TIFF* tif, uint32_t strip, void* data, tmsize_t cc)
if (!TIFFGrowStrips(tif, 1, module)) if (!TIFFGrowStrips(tif, 1, module))
return ((tmsize_t) -1); return ((tmsize_t) -1);
} }
tif->tif_curstrip = strip; tif->tif_curstrip = strip;
/* this informs TIFFAppendToStrip() we have changed or reset strip */
tif->tif_curoff = 0;
if (td->td_stripsperimage == 0) { if (td->td_stripsperimage == 0) {
TIFFErrorExt(tif->tif_clientdata, module,"Zero strips per image"); TIFFErrorExt(tif->tif_clientdata, module,"Zero strips per image");
return ((tmsize_t) -1); return ((tmsize_t) -1);
...@@ -412,8 +411,12 @@ TIFFWriteEncodedTile(TIFF* tif, uint32_t tile, void* data, tmsize_t cc) ...@@ -412,8 +411,12 @@ TIFFWriteEncodedTile(TIFF* tif, uint32_t tile, void* data, tmsize_t cc)
return ((tmsize_t)(-1)); return ((tmsize_t)(-1));
tif->tif_flags |= TIFF_BUF4WRITE; tif->tif_flags |= TIFF_BUF4WRITE;
tif->tif_curtile = tile; tif->tif_curtile = tile;
/* this informs TIFFAppendToStrip() we have changed or reset tile */
tif->tif_curoff = 0;
if( !_TIFFReserveLargeEnoughWriteBuffer(tif, tile) ) { if( !_TIFFReserveLargeEnoughWriteBuffer(tif, tile) ) {
return ((tmsize_t)(-1)); return ((tmsize_t)(-1));
} }
...@@ -743,6 +746,9 @@ TIFFAppendToStrip(TIFF* tif, uint32_t strip, uint8_t* data, tmsize_t cc) ...@@ -743,6 +746,9 @@ TIFFAppendToStrip(TIFF* tif, uint32_t strip, uint8_t* data, tmsize_t cc)
uint64_t m; uint64_t m;
int64_t old_byte_count = -1; int64_t old_byte_count = -1;
if( tif->tif_curoff == 0 )
tif->tif_lastvalidoff = 0;
if (td->td_stripoffset_p[strip] == 0 || tif->tif_curoff == 0) { if (td->td_stripoffset_p[strip] == 0 || tif->tif_curoff == 0) {
assert(td->td_nstrips > 0); assert(td->td_nstrips > 0);
...@@ -763,6 +769,8 @@ TIFFAppendToStrip(TIFF* tif, uint32_t strip, uint8_t* data, tmsize_t cc) ...@@ -763,6 +769,8 @@ TIFFAppendToStrip(TIFF* tif, uint32_t strip, uint8_t* data, tmsize_t cc)
(unsigned long)tif->tif_row); (unsigned long)tif->tif_row);
return (0); return (0);
} }
tif->tif_lastvalidoff = td->td_stripoffset_p[strip] + td->td_stripbytecount_p[strip];
} }
else else
{ {
...@@ -791,6 +799,84 @@ TIFFAppendToStrip(TIFF* tif, uint32_t strip, uint8_t* data, tmsize_t cc) ...@@ -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"); TIFFErrorExt(tif->tif_clientdata, module, "Maximum TIFF file size exceeded");
return (0); 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)) { if (!WriteOK(tif, data, cc)) {
TIFFErrorExt(tif->tif_clientdata, module, "Write error at scanline %lu", TIFFErrorExt(tif->tif_clientdata, module, "Write error at scanline %lu",
(unsigned long) tif->tif_row); (unsigned long) tif->tif_row);
...@@ -845,6 +931,7 @@ void ...@@ -845,6 +931,7 @@ void
TIFFSetWriteOffset(TIFF* tif, toff_t off) TIFFSetWriteOffset(TIFF* tif, toff_t off)
{ {
tif->tif_curoff = off; tif->tif_curoff = off;
tif->tif_lastvalidoff = 0;
} }
/* vim: set ts=8 sts=8 sw=8 noet: */ /* vim: set ts=8 sts=8 sw=8 noet: */
......
...@@ -196,7 +196,7 @@ typedef enum { ...@@ -196,7 +196,7 @@ typedef enum {
/* compression codes 32908-32911 are reserved for Pixar */ /* compression codes 32908-32911 are reserved for Pixar */
#define COMPRESSION_PIXARFILM 32908 /* Pixar companded 10bit LZW */ #define COMPRESSION_PIXARFILM 32908 /* Pixar companded 10bit LZW */
#define COMPRESSION_PIXARLOG 32909 /* Pixar companded 11bit ZIP */ #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, #define COMPRESSION_ADOBE_DEFLATE 8 /* Deflate compression,
as recognized by Adobe */ as recognized by Adobe */
/* compression code 32947 is reserved for Oceana Matrix <dev@oceana.com> */ /* compression code 32947 is reserved for Oceana Matrix <dev@oceana.com> */
......
...@@ -58,7 +58,7 @@ ...@@ -58,7 +58,7 @@
#define CCITT_SUPPORT 1 #define CCITT_SUPPORT 1
/* Support JPEG compression (requires IJG JPEG library) */ /* Support JPEG compression (requires IJG JPEG library) */
#define JPEG_SUPPORT 1 /* #undef JPEG_SUPPORT */
/* Support JBIG compression (requires JBIG-KIT library) */ /* Support JBIG compression (requires JBIG-KIT library) */
/* #undef JBIG_SUPPORT */ /* #undef JBIG_SUPPORT */
......
...@@ -328,6 +328,9 @@ extern TIFFDataType TIFFFieldDataType(const TIFFField*); ...@@ -328,6 +328,9 @@ extern TIFFDataType TIFFFieldDataType(const TIFFField*);
extern int TIFFFieldPassCount(const TIFFField*); extern int TIFFFieldPassCount(const TIFFField*);
extern int TIFFFieldReadCount(const TIFFField*); extern int TIFFFieldReadCount(const TIFFField*);
extern int TIFFFieldWriteCount(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 (*TIFFVSetMethod)(TIFF*, uint32_t, va_list);
typedef int (*TIFFVGetMethod)(TIFF*, uint32_t, va_list); typedef int (*TIFFVGetMethod)(TIFF*, uint32_t, va_list);
...@@ -384,6 +387,7 @@ extern int TIFFIsByteSwapped(TIFF*); ...@@ -384,6 +387,7 @@ extern int TIFFIsByteSwapped(TIFF*);
extern int TIFFIsUpSampled(TIFF*); extern int TIFFIsUpSampled(TIFF*);
extern int TIFFIsMSB2LSB(TIFF*); extern int TIFFIsMSB2LSB(TIFF*);
extern int TIFFIsBigEndian(TIFF*); extern int TIFFIsBigEndian(TIFF*);
extern int TIFFIsBigTIFF(TIFF*);
extern TIFFReadWriteProc TIFFGetReadProc(TIFF*); extern TIFFReadWriteProc TIFFGetReadProc(TIFF*);
extern TIFFReadWriteProc TIFFGetWriteProc(TIFF*); extern TIFFReadWriteProc TIFFGetWriteProc(TIFF*);
extern TIFFSeekProc TIFFGetSeekProc(TIFF*); extern TIFFSeekProc TIFFGetSeekProc(TIFF*);
...@@ -483,7 +487,7 @@ extern tmsize_t TIFFWriteEncodedStrip(TIFF* tif, uint32_t strip, void* data, tms ...@@ -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 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 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 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 TIFFSetWriteOffset(TIFF* tif, toff_t off);
extern void TIFFSwabShort(uint16_t*); extern void TIFFSwabShort(uint16_t*);
extern void TIFFSwabLong(uint32_t*); extern void TIFFSwabLong(uint32_t*);
......
...@@ -117,6 +117,7 @@ struct tiff { ...@@ -117,6 +117,7 @@ struct tiff {
#define TIFF_CHOPPEDUPARRAYS 0x4000000U /* set when allocChoppedUpStripArrays() has modified strip array */ #define TIFF_CHOPPEDUPARRAYS 0x4000000U /* set when allocChoppedUpStripArrays() has modified strip array */
uint64_t tif_diroff; /* file offset of current directory */ uint64_t tif_diroff; /* file offset of current directory */
uint64_t tif_nextdiroff; /* file offset of following 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 */ 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_dirlistsize; /* number of entries in offset list */
uint16_t tif_dirnumber; /* number of already seen directories */ uint16_t tif_dirnumber; /* number of already seen directories */
...@@ -132,6 +133,7 @@ struct tiff { ...@@ -132,6 +133,7 @@ struct tiff {
uint16_t tif_curdir; /* current directory (index) */ uint16_t tif_curdir; /* current directory (index) */
uint32_t tif_curstrip; /* current strip for read/write */ uint32_t tif_curstrip; /* current strip for read/write */
uint64_t tif_curoff; /* current offset 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 */ uint64_t tif_dataoff; /* current offset for writing dir */
/* SubIFD support */ /* SubIFD support */
uint16_t tif_nsubifd; /* remaining subifds to write */ uint16_t tif_nsubifd; /* remaining subifds to write */
...@@ -337,17 +339,12 @@ extern int TIFFSetCompressionScheme(TIFF* tif, int scheme); ...@@ -337,17 +339,12 @@ extern int TIFFSetCompressionScheme(TIFF* tif, int scheme);
extern int TIFFSetDefaultCompressionState(TIFF* tif); extern int TIFFSetDefaultCompressionState(TIFF* tif);
extern uint32_t _TIFFDefaultStripSize(TIFF* tif, uint32_t s); extern uint32_t _TIFFDefaultStripSize(TIFF* tif, uint32_t s);
extern void _TIFFDefaultTileSize(TIFF* tif, uint32_t* tw, uint32_t* th); extern void _TIFFDefaultTileSize(TIFF* tif, uint32_t* tw, uint32_t* th);
extern int _TIFFDataSize(TIFFDataType type);
/*--: Rational2Double: Return size of TIFFSetGetFieldType in bytes. */ extern void _TIFFsetByteArray(void**, const void*, uint32_t);
extern int _TIFFSetGetFieldSize(TIFFSetGetFieldType setgettype); extern void _TIFFsetShortArray(uint16_t**, const uint16_t*, uint32_t);
extern void _TIFFsetLongArray(uint32_t**, const uint32_t*, uint32_t);
extern void _TIFFsetByteArray(void**, void*, uint32_t); extern void _TIFFsetFloatArray(float**, const float*, uint32_t);
extern void _TIFFsetString(char**, char*); extern void _TIFFsetDoubleArray(double**, const double*, uint32_t);
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 _TIFFprintAscii(FILE*, const char*); extern void _TIFFprintAscii(FILE*, const char*);
extern void _TIFFprintAsciiTag(FILE*, const char*, 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 * 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 @@ ...@@ -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 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