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++;
......
......@@ -38,6 +38,7 @@
#include "tiffiop.h"
#include <float.h>
#include <stdlib.h>
#include <string.h>
#define FAILED_FII ((uint32_t) -1)
......@@ -61,9 +62,13 @@ enum TIFFReadDirEntryErr {
};
static enum TIFFReadDirEntryErr TIFFReadDirEntryByte(TIFF* tif, TIFFDirEntry* direntry, uint8_t* value);
static enum TIFFReadDirEntryErr TIFFReadDirEntrySbyte(TIFF * tif, TIFFDirEntry * direntry, int8_t * value);
static enum TIFFReadDirEntryErr TIFFReadDirEntryShort(TIFF* tif, TIFFDirEntry* direntry, uint16_t* value);
static enum TIFFReadDirEntryErr TIFFReadDirEntrySshort(TIFF * tif, TIFFDirEntry * direntry, int16_t * value);
static enum TIFFReadDirEntryErr TIFFReadDirEntryLong(TIFF* tif, TIFFDirEntry* direntry, uint32_t* value);
static enum TIFFReadDirEntryErr TIFFReadDirEntrySlong(TIFF * tif, TIFFDirEntry * direntry, int32_t * value);
static enum TIFFReadDirEntryErr TIFFReadDirEntryLong8(TIFF* tif, TIFFDirEntry* direntry, uint64_t* value);
static enum TIFFReadDirEntryErr TIFFReadDirEntrySlong8(TIFF * tif, TIFFDirEntry * direntry, int64_t * value);
static enum TIFFReadDirEntryErr TIFFReadDirEntryFloat(TIFF* tif, TIFFDirEntry* direntry, float* value);
static enum TIFFReadDirEntryErr TIFFReadDirEntryDouble(TIFF* tif, TIFFDirEntry* direntry, double* value);
static enum TIFFReadDirEntryErr TIFFReadDirEntryIfd8(TIFF* tif, TIFFDirEntry* direntry, uint64_t* value);
......@@ -285,6 +290,98 @@ static enum TIFFReadDirEntryErr TIFFReadDirEntryByte(TIFF* tif, TIFFDirEntry* di
}
}
static enum TIFFReadDirEntryErr TIFFReadDirEntrySbyte(TIFF *tif, TIFFDirEntry *direntry, int8_t *value)
{
enum TIFFReadDirEntryErr err;
if (direntry->tdir_count != 1)
return(TIFFReadDirEntryErrCount);
switch (direntry->tdir_type)
{
case TIFF_BYTE:
case TIFF_UNDEFINED: /* Support to read TIFF_UNDEFINED with field_readcount==1 */
{
uint8_t m;
TIFFReadDirEntryCheckedByte(tif,direntry,&m);
err=TIFFReadDirEntryCheckRangeSbyteByte(m);
if (err!=TIFFReadDirEntryErrOk)
return(err);
*value=(int8_t)m;
return(TIFFReadDirEntryErrOk);
}
case TIFF_SBYTE:
{
TIFFReadDirEntryCheckedSbyte(tif, direntry, value);
return(TIFFReadDirEntryErrOk);
}
case TIFF_SHORT:
{
uint16_t m;
TIFFReadDirEntryCheckedShort(tif, direntry, &m);
err = TIFFReadDirEntryCheckRangeSbyteShort(m);
if (err != TIFFReadDirEntryErrOk)
return(err);
*value = (int8_t)m;
return(TIFFReadDirEntryErrOk);
}
case TIFF_SSHORT:
{
int16_t m;
TIFFReadDirEntryCheckedSshort(tif, direntry, &m);
err = TIFFReadDirEntryCheckRangeSbyteSshort(m);
if (err != TIFFReadDirEntryErrOk)
return(err);
*value = (int8_t)m;
return(TIFFReadDirEntryErrOk);
}
case TIFF_LONG:
{
uint32_t m;
TIFFReadDirEntryCheckedLong(tif, direntry, &m);
err = TIFFReadDirEntryCheckRangeSbyteLong(m);
if (err != TIFFReadDirEntryErrOk)
return(err);
*value = (int8_t)m;
return(TIFFReadDirEntryErrOk);
}
case TIFF_SLONG:
{
int32_t m;
TIFFReadDirEntryCheckedSlong(tif, direntry, &m);
err = TIFFReadDirEntryCheckRangeSbyteSlong(m);
if (err != TIFFReadDirEntryErrOk)
return(err);
*value = (int8_t)m;
return(TIFFReadDirEntryErrOk);
}
case TIFF_LONG8:
{
uint64_t m;
err = TIFFReadDirEntryCheckedLong8(tif, direntry, &m);
if (err != TIFFReadDirEntryErrOk)
return(err);
err = TIFFReadDirEntryCheckRangeSbyteLong8(m);
if (err != TIFFReadDirEntryErrOk)
return(err);
*value = (int8_t)m;
return(TIFFReadDirEntryErrOk);
}
case TIFF_SLONG8:
{
int64_t m;
err = TIFFReadDirEntryCheckedSlong8(tif, direntry, &m);
if (err != TIFFReadDirEntryErrOk)
return(err);
err = TIFFReadDirEntryCheckRangeSbyteSlong8(m);
if (err != TIFFReadDirEntryErrOk)
return(err);
*value = (int8_t)m;
return(TIFFReadDirEntryErrOk);
}
default:
return(TIFFReadDirEntryErrType);
}
} /*-- TIFFReadDirEntrySbyte() --*/
static enum TIFFReadDirEntryErr TIFFReadDirEntryShort(TIFF* tif, TIFFDirEntry* direntry, uint16_t* value)
{
enum TIFFReadDirEntryErr err;
......@@ -369,7 +466,91 @@ static enum TIFFReadDirEntryErr TIFFReadDirEntryShort(TIFF* tif, TIFFDirEntry* d
default:
return(TIFFReadDirEntryErrType);
}
}
} /*-- TIFFReadDirEntryShort() --*/
static enum TIFFReadDirEntryErr TIFFReadDirEntrySshort(TIFF *tif, TIFFDirEntry *direntry, int16_t *value)
{
enum TIFFReadDirEntryErr err;
if (direntry->tdir_count != 1)
return(TIFFReadDirEntryErrCount);
switch (direntry->tdir_type)
{
case TIFF_BYTE:
{
uint8_t m;
TIFFReadDirEntryCheckedByte(tif, direntry, &m);
*value = (int16_t)m;
return(TIFFReadDirEntryErrOk);
}
case TIFF_SBYTE:
{
int8_t m;
TIFFReadDirEntryCheckedSbyte(tif, direntry, &m);
*value = (int16_t)m;
return(TIFFReadDirEntryErrOk);
}
case TIFF_SHORT:
{
uint16_t m;
TIFFReadDirEntryCheckedShort(tif, direntry, &m);
err = TIFFReadDirEntryCheckRangeSshortShort(m);
if (err != TIFFReadDirEntryErrOk)
return(err);
*value = (uint16_t)m;
return(TIFFReadDirEntryErrOk);
}
case TIFF_SSHORT:
TIFFReadDirEntryCheckedSshort(tif, direntry, value);
return(TIFFReadDirEntryErrOk);
case TIFF_LONG:
{
uint32_t m;
TIFFReadDirEntryCheckedLong(tif, direntry, &m);
err = TIFFReadDirEntryCheckRangeSshortLong(m);
if (err != TIFFReadDirEntryErrOk)
return(err);
*value = (int16_t)m;
return(TIFFReadDirEntryErrOk);
}
case TIFF_SLONG:
{
int32_t m;
TIFFReadDirEntryCheckedSlong(tif, direntry, &m);
err = TIFFReadDirEntryCheckRangeSshortSlong(m);
if (err != TIFFReadDirEntryErrOk)
return(err);
*value = (int16_t)m;
return(TIFFReadDirEntryErrOk);
}
case TIFF_LONG8:
{
uint64_t m;
err = TIFFReadDirEntryCheckedLong8(tif, direntry, &m);
if (err != TIFFReadDirEntryErrOk)
return(err);
err = TIFFReadDirEntryCheckRangeSshortLong8(m);
if (err != TIFFReadDirEntryErrOk)
return(err);
*value = (int16_t)m;
return(TIFFReadDirEntryErrOk);
}
case TIFF_SLONG8:
{
int64_t m;
err = TIFFReadDirEntryCheckedSlong8(tif, direntry, &m);
if (err != TIFFReadDirEntryErrOk)
return(err);
err = TIFFReadDirEntryCheckRangeSshortSlong8(m);
if (err != TIFFReadDirEntryErrOk)
return(err);
*value = (int16_t)m;
return(TIFFReadDirEntryErrOk);
}
default:
return(TIFFReadDirEntryErrType);
}
} /*-- TIFFReadDirEntrySshort() --*/
static enum TIFFReadDirEntryErr TIFFReadDirEntryLong(TIFF* tif, TIFFDirEntry* direntry, uint32_t* value)
{
......@@ -452,7 +633,84 @@ static enum TIFFReadDirEntryErr TIFFReadDirEntryLong(TIFF* tif, TIFFDirEntry* di
default:
return(TIFFReadDirEntryErrType);
}
}
} /*-- TIFFReadDirEntryLong() --*/
static enum TIFFReadDirEntryErr TIFFReadDirEntrySlong(TIFF *tif, TIFFDirEntry *direntry, int32_t *value)
{
enum TIFFReadDirEntryErr err;
if (direntry->tdir_count != 1)
return(TIFFReadDirEntryErrCount);
switch (direntry->tdir_type)
{
case TIFF_BYTE:
{
uint8_t m;
TIFFReadDirEntryCheckedByte(tif, direntry, &m);
*value = (int32_t)m;
return(TIFFReadDirEntryErrOk);
}
case TIFF_SBYTE:
{
int8_t m;
TIFFReadDirEntryCheckedSbyte(tif, direntry, &m);
*value = (int32_t)m;
return(TIFFReadDirEntryErrOk);
}
case TIFF_SHORT:
{
uint16_t m;
TIFFReadDirEntryCheckedShort(tif, direntry, &m);
*value = (int32_t)m;
return(TIFFReadDirEntryErrOk);
}
case TIFF_SSHORT:
{
int16_t m;
TIFFReadDirEntryCheckedSshort(tif, direntry, &m);
*value = (int32_t)m;
return(TIFFReadDirEntryErrOk);
}
case TIFF_LONG:
{
uint32_t m;
TIFFReadDirEntryCheckedLong(tif, direntry, &m);
err = TIFFReadDirEntryCheckRangeSlongLong(m);
if (err != TIFFReadDirEntryErrOk)
return(err);
*value = (int32_t)m;
return(TIFFReadDirEntryErrOk);
}
case TIFF_SLONG:
TIFFReadDirEntryCheckedSlong(tif, direntry, value);
return(TIFFReadDirEntryErrOk);
case TIFF_LONG8:
{
uint64_t m;
err = TIFFReadDirEntryCheckedLong8(tif, direntry, &m);
if (err != TIFFReadDirEntryErrOk)
return(err);
err = TIFFReadDirEntryCheckRangeSlongLong8(m);
if (err != TIFFReadDirEntryErrOk)
return(err);
*value = (int32_t)m;
return(TIFFReadDirEntryErrOk);
}
case TIFF_SLONG8:
{
int64_t m;
err = TIFFReadDirEntryCheckedSlong8(tif, direntry, &m);
if (err != TIFFReadDirEntryErrOk)
return(err);
err = TIFFReadDirEntryCheckRangeSlongSlong8(m);
if (err != TIFFReadDirEntryErrOk)
return(err);
*value = (int32_t)m;
return(TIFFReadDirEntryErrOk);
}
default:
return(TIFFReadDirEntryErrType);
}
} /*-- TIFFReadDirEntrySlong() --*/
static enum TIFFReadDirEntryErr TIFFReadDirEntryLong8(TIFF* tif, TIFFDirEntry* direntry, uint64_t* value)
{
......@@ -530,7 +788,77 @@ static enum TIFFReadDirEntryErr TIFFReadDirEntryLong8(TIFF* tif, TIFFDirEntry* d
default:
return(TIFFReadDirEntryErrType);
}
}
} /*-- TIFFReadDirEntryLong8() --*/
static enum TIFFReadDirEntryErr TIFFReadDirEntrySlong8(TIFF *tif, TIFFDirEntry *direntry, int64_t *value)
{
enum TIFFReadDirEntryErr err;
if (direntry->tdir_count != 1)
return(TIFFReadDirEntryErrCount);
switch (direntry->tdir_type)
{
case TIFF_BYTE:
{
uint8_t m;
TIFFReadDirEntryCheckedByte(tif, direntry, &m);
*value = (int64_t)m;
return(TIFFReadDirEntryErrOk);
}
case TIFF_SBYTE:
{
int8_t m;
TIFFReadDirEntryCheckedSbyte(tif, direntry, &m);
*value = (int64_t)m;
return(TIFFReadDirEntryErrOk);
}
case TIFF_SHORT:
{
uint16_t m;
TIFFReadDirEntryCheckedShort(tif, direntry, &m);
*value = (int64_t)m;
return(TIFFReadDirEntryErrOk);
}
case TIFF_SSHORT:
{
int16_t m;
TIFFReadDirEntryCheckedSshort(tif, direntry, &m);
*value = (int64_t)m;
return(TIFFReadDirEntryErrOk);
}
case TIFF_LONG:
{
uint32_t m;
TIFFReadDirEntryCheckedLong(tif, direntry, &m);
*value = (int64_t)m;
return(TIFFReadDirEntryErrOk);
}
case TIFF_SLONG:
{
int32_t m;
TIFFReadDirEntryCheckedSlong(tif, direntry, &m);
*value = (int64_t)m;
return(TIFFReadDirEntryErrOk);
}
case TIFF_LONG8:
{
uint64_t m;
err = TIFFReadDirEntryCheckedLong8(tif, direntry, &m);
if (err != TIFFReadDirEntryErrOk)
return(err);
err = TIFFReadDirEntryCheckRangeSlong8Long8(m);
if (err != TIFFReadDirEntryErrOk)
return(err);
*value = (int64_t)m;
return(TIFFReadDirEntryErrOk);
}
case TIFF_SLONG8:
err = TIFFReadDirEntryCheckedSlong8(tif, direntry, value);
return(err);
default:
return(TIFFReadDirEntryErrType);
}
} /*-- TIFFReadDirEntrySlong8() --*/
static enum TIFFReadDirEntryErr TIFFReadDirEntryFloat(TIFF* tif, TIFFDirEntry* direntry, float* value)
{
......@@ -826,6 +1154,10 @@ static enum TIFFReadDirEntryErr TIFFReadDirEntryDataAndRealloc(
return TIFFReadDirEntryErrOk;
}
/* Caution: if raising that value, make sure int32 / uint32 overflows can't occur
* elsewhere */
#define MAX_SIZE_TAG_DATA 2147483647U
static enum TIFFReadDirEntryErr TIFFReadDirEntryArrayWithLimit(
TIFF* tif, TIFFDirEntry* direntry, uint32_t* count, uint32_t desttypesize,
void** value, uint64_t maxcount)
......@@ -858,9 +1190,9 @@ static enum TIFFReadDirEntryErr TIFFReadDirEntryArrayWithLimit(
* in either the current data type or the dest data type. This also
* avoids problems with overflow of tmsize_t on 32bit systems.
*/
if ((uint64_t)(2147483647 / typesize) < target_count64)
if ((uint64_t)(MAX_SIZE_TAG_DATA / typesize) < target_count64)
return(TIFFReadDirEntryErrSizesan);
if ((uint64_t)(2147483647 / desttypesize) < target_count64)
if ((uint64_t)(MAX_SIZE_TAG_DATA / desttypesize) < target_count64)
return(TIFFReadDirEntryErrSizesan);
*count=(uint32_t)target_count64;
......@@ -3794,50 +4126,7 @@ TIFFReadDirectory(TIFF* tif)
MissingRequired(tif,"ImageLength");
goto bad;
}
/*
* Setup appropriate structures (by strip or by tile)
*/
if (!TIFFFieldSet(tif, FIELD_TILEDIMENSIONS)) {
tif->tif_dir.td_nstrips = TIFFNumberOfStrips(tif);
tif->tif_dir.td_tilewidth = tif->tif_dir.td_imagewidth;
tif->tif_dir.td_tilelength = tif->tif_dir.td_rowsperstrip;
tif->tif_dir.td_tiledepth = tif->tif_dir.td_imagedepth;
tif->tif_flags &= ~TIFF_ISTILED;
} else {
tif->tif_dir.td_nstrips = TIFFNumberOfTiles(tif);
tif->tif_flags |= TIFF_ISTILED;
}
if (!tif->tif_dir.td_nstrips) {
TIFFErrorExt(tif->tif_clientdata, module,
"Cannot handle zero number of %s",
isTiled(tif) ? "tiles" : "strips");
goto bad;
}
tif->tif_dir.td_stripsperimage = tif->tif_dir.td_nstrips;
if (tif->tif_dir.td_planarconfig == PLANARCONFIG_SEPARATE)
tif->tif_dir.td_stripsperimage /= tif->tif_dir.td_samplesperpixel;
if (!TIFFFieldSet(tif, FIELD_STRIPOFFSETS)) {
#ifdef OJPEG_SUPPORT
if ((tif->tif_dir.td_compression==COMPRESSION_OJPEG) &&
(isTiled(tif)==0) &&
(tif->tif_dir.td_nstrips==1)) {
/*
* XXX: OJPEG hack.
* If a) compression is OJPEG, b) it's not a tiled TIFF,
* and c) the number of strips is 1,
* then we tolerate the absence of stripoffsets tag,
* because, presumably, all required data is in the
* JpegInterchangeFormat stream.
*/
TIFFSetFieldBit(tif, FIELD_STRIPOFFSETS);
} else
#endif
{
MissingRequired(tif,
isTiled(tif) ? "TileOffsets" : "StripOffsets");
goto bad;
}
}
/*
* Second pass: extract other information.
*/
......@@ -4042,41 +4331,6 @@ TIFFReadDirectory(TIFF* tif)
} /* -- if (!dp->tdir_ignore) */
} /* -- for-loop -- */
if( tif->tif_mode == O_RDWR &&
tif->tif_dir.td_stripoffset_entry.tdir_tag != 0 &&
tif->tif_dir.td_stripoffset_entry.tdir_count == 0 &&
tif->tif_dir.td_stripoffset_entry.tdir_type == 0 &&
tif->tif_dir.td_stripoffset_entry.tdir_offset.toff_long8 == 0 &&
tif->tif_dir.td_stripbytecount_entry.tdir_tag != 0 &&
tif->tif_dir.td_stripbytecount_entry.tdir_count == 0 &&
tif->tif_dir.td_stripbytecount_entry.tdir_type == 0 &&
tif->tif_dir.td_stripbytecount_entry.tdir_offset.toff_long8 == 0 )
{
/* Directory typically created with TIFFDeferStrileArrayWriting() */
TIFFSetupStrips(tif);
}
else if( !(tif->tif_flags&TIFF_DEFERSTRILELOAD) )
{
if( tif->tif_dir.td_stripoffset_entry.tdir_tag != 0 )
{
if (!TIFFFetchStripThing(tif,&(tif->tif_dir.td_stripoffset_entry),
tif->tif_dir.td_nstrips,
&tif->tif_dir.td_stripoffset_p))
{
goto bad;
}
}
if( tif->tif_dir.td_stripbytecount_entry.tdir_tag != 0 )
{
if (!TIFFFetchStripThing(tif,&(tif->tif_dir.td_stripbytecount_entry),
tif->tif_dir.td_nstrips,
&tif->tif_dir.td_stripbytecount_p))
{
goto bad;
}
}
}
/*
* OJPEG hack:
* - If a) compression is OJPEG, and b) photometric tag is missing,
......@@ -4148,6 +4402,88 @@ TIFFReadDirectory(TIFF* tif)
}
/*
* Setup appropriate structures (by strip or by tile)
* We do that only after the above OJPEG hack which alters SamplesPerPixel
* and thus influences the number of strips in the separate planarconfig.
*/
if (!TIFFFieldSet(tif, FIELD_TILEDIMENSIONS)) {
tif->tif_dir.td_nstrips = TIFFNumberOfStrips(tif);
tif->tif_dir.td_tilewidth = tif->tif_dir.td_imagewidth;
tif->tif_dir.td_tilelength = tif->tif_dir.td_rowsperstrip;
tif->tif_dir.td_tiledepth = tif->tif_dir.td_imagedepth;
tif->tif_flags &= ~TIFF_ISTILED;
} else {
tif->tif_dir.td_nstrips = TIFFNumberOfTiles(tif);
tif->tif_flags |= TIFF_ISTILED;
}
if (!tif->tif_dir.td_nstrips) {
TIFFErrorExt(tif->tif_clientdata, module,
"Cannot handle zero number of %s",
isTiled(tif) ? "tiles" : "strips");
goto bad;
}
tif->tif_dir.td_stripsperimage = tif->tif_dir.td_nstrips;
if (tif->tif_dir.td_planarconfig == PLANARCONFIG_SEPARATE)
tif->tif_dir.td_stripsperimage /= tif->tif_dir.td_samplesperpixel;
if (!TIFFFieldSet(tif, FIELD_STRIPOFFSETS)) {
#ifdef OJPEG_SUPPORT
if ((tif->tif_dir.td_compression==COMPRESSION_OJPEG) &&
(isTiled(tif)==0) &&
(tif->tif_dir.td_nstrips==1)) {
/*
* XXX: OJPEG hack.
* If a) compression is OJPEG, b) it's not a tiled TIFF,
* and c) the number of strips is 1,
* then we tolerate the absence of stripoffsets tag,
* because, presumably, all required data is in the
* JpegInterchangeFormat stream.
*/
TIFFSetFieldBit(tif, FIELD_STRIPOFFSETS);
} else
#endif
{
MissingRequired(tif,
isTiled(tif) ? "TileOffsets" : "StripOffsets");
goto bad;
}
}
if( tif->tif_mode == O_RDWR &&
tif->tif_dir.td_stripoffset_entry.tdir_tag != 0 &&
tif->tif_dir.td_stripoffset_entry.tdir_count == 0 &&
tif->tif_dir.td_stripoffset_entry.tdir_type == 0 &&
tif->tif_dir.td_stripoffset_entry.tdir_offset.toff_long8 == 0 &&
tif->tif_dir.td_stripbytecount_entry.tdir_tag != 0 &&
tif->tif_dir.td_stripbytecount_entry.tdir_count == 0 &&
tif->tif_dir.td_stripbytecount_entry.tdir_type == 0 &&
tif->tif_dir.td_stripbytecount_entry.tdir_offset.toff_long8 == 0 )
{
/* Directory typically created with TIFFDeferStrileArrayWriting() */
TIFFSetupStrips(tif);
}
else if( !(tif->tif_flags&TIFF_DEFERSTRILELOAD) )
{
if( tif->tif_dir.td_stripoffset_entry.tdir_tag != 0 )
{
if (!TIFFFetchStripThing(tif,&(tif->tif_dir.td_stripoffset_entry),
tif->tif_dir.td_nstrips,
&tif->tif_dir.td_stripoffset_p))
{
goto bad;
}
}
if( tif->tif_dir.td_stripbytecount_entry.tdir_tag != 0 )
{
if (!TIFFFetchStripThing(tif,&(tif->tif_dir.td_stripbytecount_entry),
tif->tif_dir.td_nstrips,
&tif->tif_dir.td_stripbytecount_p))
{
goto bad;
}
}
}
/*
* Make sure all non-color channels are extrasamples.
* If it's not the case, define them as such.
*/
......@@ -4173,7 +4509,8 @@ TIFFReadDirectory(TIFF* tif)
goto bad;
}
memcpy(new_sampleinfo, tif->tif_dir.td_sampleinfo, old_extrasamples * sizeof(uint16_t));
if (old_extrasamples > 0)
memcpy(new_sampleinfo, tif->tif_dir.td_sampleinfo, old_extrasamples * sizeof(uint16_t));
_TIFFsetShortArray(&tif->tif_dir.td_sampleinfo, new_sampleinfo, tif->tif_dir.td_extrasamples);
_TIFFfree(new_sampleinfo);
}
......@@ -4527,7 +4864,14 @@ TIFFReadCustomDirectory(TIFF* tif, toff_t diroff,
switch (dp->tdir_tag)
{
case EXIFTAG_SUBJECTDISTANCE:
(void)TIFFFetchSubjectDistance(tif, dp);
if(!TIFFFieldIsAnonymous(fip)) {
/* should only be called on a Exif directory */
/* when exifFields[] is active */
(void)TIFFFetchSubjectDistance(tif, dp);
}
else {
(void)TIFFFetchNormalTag(tif, dp, TRUE);
}
break;
default:
(void)TIFFFetchNormalTag(tif, dp, TRUE);
......@@ -5050,18 +5394,28 @@ TIFFFetchNormalTag(TIFF* tif, TIFFDirEntry* dp, int recover)
err=TIFFReadDirEntryByteArray(tif,dp,&data);
if (err==TIFFReadDirEntryErrOk)
{
uint32_t mb = 0;
size_t mb = 0;
int n;
if (data != NULL)
{
uint8_t* ma = data;
while (mb<(uint32_t)dp->tdir_count)
{
if (*ma==0)
break;
ma++;
mb++;
}
if (dp->tdir_count > 0 && data[dp->tdir_count - 1] == 0)
{
/* optimization: if data is known to be 0 terminated, we can use strlen() */
mb = strlen((const char*)data);
}
else
{
/* general case. equivalent to non-portable */
/* mb = strnlen((const char*)data, (uint32_t)dp->tdir_count); */
uint8_t* ma = data;
while (mb<(uint32_t)dp->tdir_count)
{
if (*ma==0)
break;
ma++;
mb++;
}
}
}
if (mb+1<(uint32_t)dp->tdir_count)
TIFFWarningExt(tif->tif_clientdata,module,"ASCII value for tag \"%s\" contains null byte in value; value incorrectly truncated during reading due to implementation limitations",fip->field_name);
......@@ -5069,17 +5423,19 @@ TIFFFetchNormalTag(TIFF* tif, TIFFDirEntry* dp, int recover)
{
uint8_t* o;
TIFFWarningExt(tif->tif_clientdata,module,"ASCII value for tag \"%s\" does not end in null byte",fip->field_name);
if ((uint32_t)dp->tdir_count + 1 != dp->tdir_count + 1)
o=NULL;
else
o=_TIFFmalloc((uint32_t)dp->tdir_count + 1);
/* TIFFReadDirEntryArrayWithLimit() ensures this can't be larger than MAX_SIZE_TAG_DATA */
assert((uint32_t)dp->tdir_count + 1 == dp->tdir_count + 1);
o=_TIFFmalloc((uint32_t)dp->tdir_count + 1);
if (o==NULL)
{
if (data!=NULL)
_TIFFfree(data);
return(0);
}
_TIFFmemcpy(o,data,(uint32_t)dp->tdir_count);
if (dp->tdir_count > 0 )
{
_TIFFmemcpy(o,data,(uint32_t)dp->tdir_count);
}
o[(uint32_t)dp->tdir_count]=0;
if (data!=0)
_TIFFfree(data);
......@@ -5106,6 +5462,19 @@ TIFFFetchNormalTag(TIFF* tif, TIFFDirEntry* dp, int recover)
}
}
break;
case TIFF_SETGET_SINT8:
{
int8_t data = 0;
assert(fip->field_readcount == 1);
assert(fip->field_passcount == 0);
err = TIFFReadDirEntrySbyte(tif, dp, &data);
if (err == TIFFReadDirEntryErrOk)
{
if (!TIFFSetField(tif, dp->tdir_tag, data))
return(0);
}
}
break;
case TIFF_SETGET_UINT16:
{
uint16_t data;
......@@ -5119,6 +5488,19 @@ TIFFFetchNormalTag(TIFF* tif, TIFFDirEntry* dp, int recover)
}
}
break;
case TIFF_SETGET_SINT16:
{
int16_t data;
assert(fip->field_readcount==1);
assert(fip->field_passcount==0);
err=TIFFReadDirEntrySshort(tif,dp,&data);
if (err==TIFFReadDirEntryErrOk)
{
if (!TIFFSetField(tif,dp->tdir_tag,data))
return(0);
}
}
break;
case TIFF_SETGET_UINT32:
{
uint32_t data;
......@@ -5132,6 +5514,19 @@ TIFFFetchNormalTag(TIFF* tif, TIFFDirEntry* dp, int recover)
}
}
break;
case TIFF_SETGET_SINT32:
{
int32_t data;
assert(fip->field_readcount==1);
assert(fip->field_passcount==0);
err=TIFFReadDirEntrySlong(tif,dp,&data);
if (err==TIFFReadDirEntryErrOk)
{
if (!TIFFSetField(tif,dp->tdir_tag,data))
return(0);
}
}
break;
case TIFF_SETGET_UINT64:
{
uint64_t data;
......@@ -5145,6 +5540,19 @@ TIFFFetchNormalTag(TIFF* tif, TIFFDirEntry* dp, int recover)
}
}
break;
case TIFF_SETGET_SINT64:
{
int64_t data;
assert(fip->field_readcount==1);
assert(fip->field_passcount==0);
err=TIFFReadDirEntrySlong8(tif,dp,&data);
if (err==TIFFReadDirEntryErrOk)
{
if (!TIFFSetField(tif,dp->tdir_tag,data))
return(0);
}
}
break;
case TIFF_SETGET_FLOAT:
{
float data;
......@@ -5199,7 +5607,7 @@ TIFFFetchNormalTag(TIFF* tif, TIFFDirEntry* dp, int recover)
if (err==TIFFReadDirEntryErrOk)
{
int m;
assert(data); /* avoid CLang static Analyzer false positive */
assert(data); /* avoid CLang static Analyzer false positive */
m=TIFFSetField(tif,dp->tdir_tag,data[0],data[1]);
_TIFFfree(data);
if (!m)
......@@ -5214,9 +5622,9 @@ TIFFFetchNormalTag(TIFF* tif, TIFFDirEntry* dp, int recover)
assert(fip->field_passcount==0);
if (dp->tdir_count!=(uint64_t)fip->field_readcount) {
TIFFWarningExt(tif->tif_clientdata,module,
"incorrect count for field \"%s\", expected %d, got %"PRIu64,
fip->field_name,(int) fip->field_readcount, dp->tdir_count);
return 0;
"incorrect count for field \"%s\", expected %d, got %"PRIu64,
fip->field_name,(int) fip->field_readcount, dp->tdir_count);
return(0);
}
else
{
......@@ -5233,13 +5641,43 @@ TIFFFetchNormalTag(TIFF* tif, TIFFDirEntry* dp, int recover)
}
}
break;
case TIFF_SETGET_C0_SINT8:
{
int8_t * data;
assert(fip->field_readcount>=1);
assert(fip->field_passcount==0);
if (dp->tdir_count!=(uint64_t)fip->field_readcount) {
TIFFWarningExt(tif->tif_clientdata, module,
"incorrect count for field \"%s\", expected %d, got %"PRIu64,
fip->field_name, (int)fip->field_readcount, dp->tdir_count);
return(0);
}
else
{
err=TIFFReadDirEntrySbyteArray(tif,dp,&data);
if (err==TIFFReadDirEntryErrOk)
{
int m;
m=TIFFSetField(tif,dp->tdir_tag,data);
if (data!=0)
_TIFFfree(data);
if (!m)
return(0);
}
}
}
break;
case TIFF_SETGET_C0_UINT16:
{
uint16_t* data;
assert(fip->field_readcount>=1);
assert(fip->field_passcount==0);
if (dp->tdir_count!=(uint64_t)fip->field_readcount)
/* corrupt file */;
if (dp->tdir_count != (uint64_t)fip->field_readcount) {
TIFFWarningExt(tif->tif_clientdata, module,
"incorrect count for field \"%s\", expected %d, got %"PRIu64,
fip->field_name, (int)fip->field_readcount, dp->tdir_count);
return(0);
}
else
{
err=TIFFReadDirEntryShortArray(tif,dp,&data);
......@@ -5255,13 +5693,43 @@ TIFFFetchNormalTag(TIFF* tif, TIFFDirEntry* dp, int recover)
}
}
break;
case TIFF_SETGET_C0_SINT16:
{
int16_t* data;
assert(fip->field_readcount>=1);
assert(fip->field_passcount==0);
if (dp->tdir_count != (uint64_t)fip->field_readcount) {
TIFFWarningExt(tif->tif_clientdata, module,
"incorrect count for field \"%s\", expected %d, got %"PRIu64,
fip->field_name, (int)fip->field_readcount, dp->tdir_count);
return(0);
}
else
{
err=TIFFReadDirEntrySshortArray(tif,dp,&data);
if (err==TIFFReadDirEntryErrOk)
{
int m;
m=TIFFSetField(tif,dp->tdir_tag,data);
if (data!=0)
_TIFFfree(data);
if (!m)
return(0);
}
}
}
break;
case TIFF_SETGET_C0_UINT32:
{
uint32_t* data;
assert(fip->field_readcount>=1);
assert(fip->field_passcount==0);
if (dp->tdir_count!=(uint64_t)fip->field_readcount)
/* corrupt file */;
if (dp->tdir_count != (uint64_t)fip->field_readcount) {
TIFFWarningExt(tif->tif_clientdata, module,
"incorrect count for field \"%s\", expected %d, got %"PRIu64,
fip->field_name, (int)fip->field_readcount, dp->tdir_count);
return(0);
}
else
{
err=TIFFReadDirEntryLongArray(tif,dp,&data);
......@@ -5277,13 +5745,93 @@ TIFFFetchNormalTag(TIFF* tif, TIFFDirEntry* dp, int recover)
}
}
break;
case TIFF_SETGET_C0_SINT32:
{
int32_t* data;
assert(fip->field_readcount>=1);
assert(fip->field_passcount==0);
if (dp->tdir_count != (uint64_t)fip->field_readcount) {
TIFFWarningExt(tif->tif_clientdata, module,
"incorrect count for field \"%s\", expected %d, got %"PRIu64,
fip->field_name, (int)fip->field_readcount, dp->tdir_count);
return(0);
}
else
{
err=TIFFReadDirEntrySlongArray(tif,dp,&data);
if (err==TIFFReadDirEntryErrOk)
{
int m;
m=TIFFSetField(tif,dp->tdir_tag,data);
if (data!=0)
_TIFFfree(data);
if (!m)
return(0);
}
}
}
break;
case TIFF_SETGET_C0_UINT64:
{
uint64_t *data;
assert(fip->field_readcount >= 1);
assert(fip->field_passcount == 0);
if (dp->tdir_count != (uint64_t)fip->field_readcount) {
TIFFWarningExt(tif->tif_clientdata, module,
"incorrect count for field \"%s\", expected %d, got %"PRIu64,
fip->field_name, (int)fip->field_readcount, dp->tdir_count);
return(0);
} else
{
err = TIFFReadDirEntryLong8Array(tif, dp, &data);
if (err == TIFFReadDirEntryErrOk)
{
int m;
m = TIFFSetField(tif, dp->tdir_tag, data);
if (data != 0)
_TIFFfree(data);
if (!m)
return(0);
}
}
}
break;
case TIFF_SETGET_C0_SINT64:
{
int64_t *data;
assert(fip->field_readcount >= 1);
assert(fip->field_passcount == 0);
if (dp->tdir_count != (uint64_t)fip->field_readcount) {
TIFFWarningExt(tif->tif_clientdata, module,
"incorrect count for field \"%s\", expected %d, got %"PRIu64,
fip->field_name, (int)fip->field_readcount, dp->tdir_count);
return(0);
} else
{
err = TIFFReadDirEntrySlong8Array(tif, dp, &data);
if (err == TIFFReadDirEntryErrOk)
{
int m;
m = TIFFSetField(tif, dp->tdir_tag, data);
if (data != 0)
_TIFFfree(data);
if (!m)
return(0);
}
}
}
break;
case TIFF_SETGET_C0_FLOAT:
{
float* data;
assert(fip->field_readcount>=1);
assert(fip->field_passcount==0);
if (dp->tdir_count!=(uint64_t)fip->field_readcount)
/* corrupt file */;
if (dp->tdir_count != (uint64_t)fip->field_readcount) {
TIFFWarningExt(tif->tif_clientdata, module,
"incorrect count for field \"%s\", expected %d, got %"PRIu64,
fip->field_name, (int)fip->field_readcount, dp->tdir_count);
return(0);
}
else
{
err=TIFFReadDirEntryFloatArray(tif,dp,&data);
......@@ -5305,8 +5853,12 @@ TIFFFetchNormalTag(TIFF* tif, TIFFDirEntry* dp, int recover)
double* data;
assert(fip->field_readcount>=1);
assert(fip->field_passcount==0);
if (dp->tdir_count!=(uint64_t)fip->field_readcount)
/* corrupt file */;
if (dp->tdir_count != (uint64_t)fip->field_readcount) {
TIFFWarningExt(tif->tif_clientdata, module,
"incorrect count for field \"%s\", expected %d, got %"PRIu64,
fip->field_name, (int)fip->field_readcount, dp->tdir_count);
return(0);
}
else
{
err=TIFFReadDirEntryDoubleArray(tif,dp,&data);
......@@ -5371,6 +5923,28 @@ TIFFFetchNormalTag(TIFF* tif, TIFFDirEntry* dp, int recover)
}
}
break;
case TIFF_SETGET_C16_SINT8:
{
int8_t* data;
assert(fip->field_readcount==TIFF_VARIABLE);
assert(fip->field_passcount==1);
if (dp->tdir_count>0xFFFF)
err=TIFFReadDirEntryErrCount;
else
{
err=TIFFReadDirEntrySbyteArray(tif,dp,&data);
if (err==TIFFReadDirEntryErrOk)
{
int m;
m=TIFFSetField(tif,dp->tdir_tag,(uint16_t)(dp->tdir_count),data);
if (data!=0)
_TIFFfree(data);
if (!m)
return(0);
}
}
}
break;
case TIFF_SETGET_C16_UINT16:
{
uint16_t* data;
......@@ -5393,6 +5967,28 @@ TIFFFetchNormalTag(TIFF* tif, TIFFDirEntry* dp, int recover)
}
}
break;
case TIFF_SETGET_C16_SINT16:
{
int16_t* data;
assert(fip->field_readcount==TIFF_VARIABLE);
assert(fip->field_passcount==1);
if (dp->tdir_count>0xFFFF)
err=TIFFReadDirEntryErrCount;
else
{
err=TIFFReadDirEntrySshortArray(tif,dp,&data);
if (err==TIFFReadDirEntryErrOk)
{
int m;
m=TIFFSetField(tif,dp->tdir_tag,(uint16_t)(dp->tdir_count),data);
if (data!=0)
_TIFFfree(data);
if (!m)
return(0);
}
}
}
break;
case TIFF_SETGET_C16_UINT32:
{
uint32_t* data;
......@@ -5415,6 +6011,28 @@ TIFFFetchNormalTag(TIFF* tif, TIFFDirEntry* dp, int recover)
}
}
break;
case TIFF_SETGET_C16_SINT32:
{
int32_t* data;
assert(fip->field_readcount==TIFF_VARIABLE);
assert(fip->field_passcount==1);
if (dp->tdir_count>0xFFFF)
err=TIFFReadDirEntryErrCount;
else
{
err=TIFFReadDirEntrySlongArray(tif,dp,&data);
if (err==TIFFReadDirEntryErrOk)
{
int m;
m=TIFFSetField(tif,dp->tdir_tag,(uint16_t)(dp->tdir_count),data);
if (data!=0)
_TIFFfree(data);
if (!m)
return(0);
}
}
}
break;
case TIFF_SETGET_C16_UINT64:
{
uint64_t* data;
......@@ -5437,6 +6055,28 @@ TIFFFetchNormalTag(TIFF* tif, TIFFDirEntry* dp, int recover)
}
}
break;
case TIFF_SETGET_C16_SINT64:
{
int64_t* data;
assert(fip->field_readcount==TIFF_VARIABLE);
assert(fip->field_passcount==1);
if (dp->tdir_count>0xFFFF)
err=TIFFReadDirEntryErrCount;
else
{
err=TIFFReadDirEntrySlong8Array(tif,dp,&data);
if (err==TIFFReadDirEntryErrOk)
{
int m;
m=TIFFSetField(tif,dp->tdir_tag,(uint16_t)(dp->tdir_count),data);
if (data!=0)
_TIFFfree(data);
if (!m)
return(0);
}
}
}
break;
case TIFF_SETGET_C16_FLOAT:
{
float* data;
......@@ -5514,8 +6154,8 @@ TIFFFetchNormalTag(TIFF* tif, TIFFDirEntry* dp, int recover)
int m;
if( data != 0 && dp->tdir_count > 0 && data[dp->tdir_count-1] != '\0' )
{
TIFFWarningExt(tif->tif_clientdata,module,"ASCII value for tag \"%s\" does not end in null byte. Forcing it to be null",fip->field_name);
data[dp->tdir_count-1] = '\0';
TIFFWarningExt(tif->tif_clientdata,module,"ASCII value for tag \"%s\" does not end in null byte. Forcing it to be null",fip->field_name);
data[dp->tdir_count-1] = '\0';
}
m=TIFFSetField(tif, dp->tdir_tag, (uint32_t)(dp->tdir_count), data);
if (data!=0)
......@@ -5765,8 +6405,9 @@ TIFFFetchStripThing(TIFF* tif, TIFFDirEntry* dir, uint32_t nstrips, uint64_t** l
_TIFFfree(data);
return(0);
}
_TIFFmemcpy(resizeddata,data, (uint32_t)dir->tdir_count * sizeof(uint64_t));
_TIFFmemset(resizeddata+(uint32_t)dir->tdir_count, 0, (nstrips - (uint32_t)dir->tdir_count) * sizeof(uint64_t));
if( dir->tdir_count )
_TIFFmemcpy(resizeddata,data, (uint32_t)dir->tdir_count * sizeof(uint64_t));
_TIFFmemset(resizeddata+(uint32_t)dir->tdir_count, 0, (nstrips - (uint32_t)dir->tdir_count) * sizeof(uint64_t));
_TIFFfree(data);
data=resizeddata;
}
......
......@@ -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;
......
/*
* Copyright (c) 1988-1997 Sam Leffler
* Copyright (c) 1991-1997 Silicon Graphics, Inc.
* Copyright (c) 2022 Even Rouault
*
* 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.
*/
#include "tiffiop.h"
#ifdef LZW_SUPPORT
/*
* TIFF Library.
* TIFF Library.
* Rev 5.0 Lempel-Ziv & Welch Compression Support
*
* This code is derived from the compress program whose code is
......@@ -36,8 +37,13 @@
*/
#include "tif_predict.h"
#include <stdbool.h>
#include <stdio.h>
/* Select the plausible largest natural integer type for the architecture */
#define SIZEOF_WORDTYPE SIZEOF_SIZE_T
typedef size_t WordType;
/*
* NB: The 5.0 spec describes a different algorithm than Aldus
* implements. Specifically, Aldus does code length transitions
......@@ -52,13 +58,6 @@
* Future revisions to the TIFF spec are expected to "clarify this issue".
*/
#define LZW_COMPAT /* include backwards compatibility code */
/*
* Each strip of data is supposed to be terminated by a CODE_EOI.
* If the following #define is included, the decoder will also
* check for end-of-strip w/o seeing this code. This makes the
* library more robust, but also slower.
*/
#define LZW_CHECKEOS /* include checks for strips w/o EOI code */
#define MAXCODE(n) ((1L<<(n))-1)
/*
......@@ -92,7 +91,7 @@ typedef struct {
unsigned short nbits; /* # of bits/code */
unsigned short maxcode; /* maximum code for lzw_nbits */
unsigned short free_ent; /* next free entry in hash table */
unsigned long nextdata; /* next bits of i/o */
WordType nextdata; /* next bits of i/o */
long nextbits; /* # of valid bits in lzw_nextdata */
int rw_mode; /* preserve rw_mode from init */
......@@ -119,8 +118,10 @@ typedef struct {
typedef struct code_ent {
struct code_ent *next;
unsigned short length; /* string len, including this token */
unsigned char value; /* data value */
/* firstchar should be placed immediately before value in this structure */
unsigned char firstchar; /* first token of string */
unsigned char value; /* data value */
bool repeated;
} code_t;
typedef int (*decodeFunc)(TIFF*, uint8_t*, tmsize_t, uint16_t);
......@@ -130,25 +131,24 @@ typedef struct {
/* Decoding specific data */
long dec_nbitsmask; /* lzw_nbits 1 bits, right adjusted */
long dec_restart; /* restart count */
#ifdef LZW_CHECKEOS
tmsize_t dec_restart; /* restart count */
uint64_t dec_bitsleft; /* available bits in raw data */
tmsize_t old_tif_rawcc; /* value of tif_rawcc at the end of the previous TIFLZWDecode() call */
#endif
decodeFunc dec_decode; /* regular or backwards compatible */
code_t* dec_codep; /* current recognized code */
code_t* dec_oldcodep; /* previously recognized code */
code_t* dec_free_entp; /* next free entry */
code_t* dec_maxcodep; /* max available entry */
code_t* dec_codetab; /* kept separate for small machines */
int read_error; /* whether a read error has occured, and which should cause further reads in the same strip/tile to be aborted */
/* Encoding specific data */
int enc_oldcode; /* last code encountered */
long enc_checkpoint; /* point at which to clear table */
tmsize_t enc_checkpoint; /* point at which to clear table */
#define CHECK_GAP 10000 /* enc_ratio check interval */
long enc_ratio; /* current compression ratio */
long enc_incount; /* (input) data bytes encoded */
long enc_outcount; /* encoded (output) bytes */
tmsize_t enc_ratio; /* current compression ratio */
tmsize_t enc_incount; /* (input) data bytes encoded */
tmsize_t enc_outcount; /* encoded (output) bytes */
uint8_t* enc_rawlimit; /* bound on tif_rawdata buffer */
hash_t* enc_hashtab; /* kept separate for small machines */
} LZWCodecState;
......@@ -167,26 +167,6 @@ static void cl_hash(LZWCodecState*);
* LZW Decoder.
*/
#ifdef LZW_CHECKEOS
/*
* This check shouldn't be necessary because each
* strip is suppose to be terminated with CODE_EOI.
*/
#define NextCode(_tif, _sp, _bp, _code, _get) { \
if ((_sp)->dec_bitsleft < (uint64_t)nbits) { \
TIFFWarningExt(_tif->tif_clientdata, module, \
"LZWDecode: Strip %"PRIu32" not terminated with EOI code", \
_tif->tif_curstrip); \
_code = CODE_EOI; \
} else { \
_get(_sp,_bp,_code); \
(_sp)->dec_bitsleft -= nbits; \
} \
}
#else
#define NextCode(tif, sp, bp, code, get) get(sp, bp, code)
#endif
static int
LZWFixupTags(TIFF* tif)
{
......@@ -236,17 +216,17 @@ LZWSetupDecode(TIFF* tif)
*/
code = 255;
do {
sp->dec_codetab[code].value = (unsigned char)code;
sp->dec_codetab[code].firstchar = (unsigned char)code;
sp->dec_codetab[code].value = (unsigned char)code;
sp->dec_codetab[code].repeated = true;
sp->dec_codetab[code].length = 1;
sp->dec_codetab[code].next = NULL;
} while (code--);
/*
* Zero-out the unused entries
*/
/* Silence false positive */
/* coverity[overrun-buffer-arg] */
_TIFFmemset(&sp->dec_codetab[CODE_CLEAR], 0,
* Zero-out the unused entries */
/* Silence false positive */
/* coverity[overrun-buffer-arg] */
memset(&sp->dec_codetab[CODE_CLEAR], 0,
(CODE_FIRST - CODE_CLEAR) * sizeof (code_t));
}
return (1);
......@@ -316,11 +296,9 @@ LZWPreDecode(TIFF* tif, uint16_t s)
sp->dec_restart = 0;
sp->dec_nbitsmask = MAXCODE(BITS_MIN);
#ifdef LZW_CHECKEOS
sp->dec_bitsleft = 0;
sp->old_tif_rawcc = 0;
#endif
sp->dec_free_entp = sp->dec_codetab + CODE_FIRST;
sp->old_tif_rawcc = 0;
sp->dec_free_entp = sp->dec_codetab - 1 ; // + CODE_FIRST;
/*
* Zero entries that are not yet filled in. We do
* this to guard against bogus input data that causes
......@@ -328,65 +306,114 @@ LZWPreDecode(TIFF* tif, uint16_t s)
* come up with a way to safely bounds-check input codes
* while decoding then you can remove this operation.
*/
_TIFFmemset(sp->dec_free_entp, 0, (CSIZE-CODE_FIRST)*sizeof (code_t));
sp->dec_oldcodep = &sp->dec_codetab[-1];
sp->dec_oldcodep = &sp->dec_codetab[0];
sp->dec_maxcodep = &sp->dec_codetab[sp->dec_nbitsmask-1];
sp->read_error = 0;
return (1);
}
/*
* Decode a "hunk of data".
*/
#define GetNextCode(sp, bp, code) { \
nextdata = (nextdata<<8) | *(bp)++; \
nextbits += 8; \
if (nextbits < nbits) { \
nextdata = (nextdata<<8) | *(bp)++; \
nextbits += 8; \
} \
code = (hcode_t)((nextdata >> (nextbits-nbits)) & nbitsmask); \
nextbits -= nbits; \
}
static void
codeLoop(TIFF* tif, const char* module)
{
TIFFErrorExt(tif->tif_clientdata, module,
"Bogus encoding, loop in the code table; scanline %"PRIu32,
tif->tif_row);
}
/* Get the next 32 or 64-bit from the input data */
#ifdef WORDS_BIGENDIAN
# define GetNextData(nextdata, bp) memcpy(&nextdata, bp, sizeof(nextdata))
#elif SIZEOF_WORDTYPE == 8
# if defined(__GNUC__) && defined(__x86_64__)
# define GetNextData(nextdata, bp) nextdata = __builtin_bswap64(*(uint64_t*)(bp))
# elif defined(_M_X64)
# define GetNextData(nextdata, bp) nextdata = _byteswap_uint64(*(uint64_t*)(bp))
# elif defined(__GNUC__)
# define GetNextData(nextdata, bp) memcpy(&nextdata, bp, sizeof(nextdata)); \
nextdata = __builtin_bswap64(nextdata)
# else
# define GetNextData(nextdata, bp) nextdata = (((uint64_t)bp[0]) << 56) | \
(((uint64_t)bp[1]) << 48) | \
(((uint64_t)bp[2]) << 40) | \
(((uint64_t)bp[3]) << 32) | \
(((uint64_t)bp[4]) << 24) | \
(((uint64_t)bp[5]) << 16) | \
(((uint64_t)bp[6]) << 8) | \
(((uint64_t)bp[7]))
# endif
#elif SIZEOF_WORDTYPE == 4
# if defined(__GNUC__) && defined(__i386__)
# define GetNextData(nextdata, bp) nextdata = __builtin_bswap32(*(uint32_t*)(bp))
# elif defined(_M_X86)
# define GetNextData(nextdata, bp) nextdata = _byteswap_ulong(*(unsigned long*)(bp))
# elif defined(__GNUC__)
# define GetNextData(nextdata, bp) memcpy(&nextdata, bp, sizeof(nextdata)); \
nextdata = __builtin_bswap32(nextdata)
# else
# define GetNextData(nextdata, bp) nextdata = (((uint32_t)bp[0]) << 24) | \
(((uint32_t)bp[1]) << 16) | \
(((uint32_t)bp[2]) << 8) | \
(((uint32_t)bp[3]))
# endif
#else
# error "Unhandled SIZEOF_WORDTYPE"
#endif
#define GetNextCodeLZW() do { \
nextbits -= nbits; \
if (nextbits < 0) { \
if (dec_bitsleft >= 8 * SIZEOF_WORDTYPE) { \
unsigned codetmp = (unsigned)(nextdata << (-nextbits)); \
GetNextData(nextdata, bp); \
bp += SIZEOF_WORDTYPE; \
nextbits += 8 * SIZEOF_WORDTYPE; \
dec_bitsleft -= 8 * SIZEOF_WORDTYPE; \
code = (WordType)((codetmp | (nextdata >> nextbits)) & nbitsmask); \
break; \
} \
else {\
if( dec_bitsleft < 8) { \
goto no_eoi; \
}\
nextdata = (nextdata<<8) | *(bp)++; \
nextbits += 8; \
dec_bitsleft -= 8; \
if( nextbits < 0 ) { \
if( dec_bitsleft < 8) { \
goto no_eoi; \
}\
nextdata = (nextdata<<8) | *(bp)++; \
nextbits += 8; \
dec_bitsleft -= 8; \
} \
} \
} \
code = (WordType)((nextdata >> nextbits) & nbitsmask); \
} while(0)
static int
LZWDecode(TIFF* tif, uint8_t* op0, tmsize_t occ0, uint16_t s)
{
static const char module[] = "LZWDecode";
LZWCodecState *sp = DecoderState(tif);
char *op = (char*) op0;
long occ = (long) occ0;
char *tp;
unsigned char *bp;
hcode_t code;
int len;
uint8_t *op = (uint8_t*) op0;
tmsize_t occ = occ0;
uint8_t *bp;
long nbits, nextbits, nbitsmask;
unsigned long nextdata;
code_t *codep, *free_entp, *maxcodep, *oldcodep;
WordType nextdata;
code_t *free_entp, *maxcodep, *oldcodep;
(void) s;
assert(sp != NULL);
assert(sp->dec_codetab != NULL);
assert(sp->dec_codetab != NULL);
if (sp->read_error) {
return 0;
}
/*
Fail if value does not fit in long.
*/
if ((tmsize_t) occ != occ0)
return (0);
/*
* Restart interrupted output operation.
*/
if (sp->dec_restart) {
long residue;
tmsize_t residue;
codep = sp->dec_codep;
code_t* codep = sp->dec_codep;
residue = codep->length - sp->dec_restart;
if (residue > occ) {
/*
......@@ -400,7 +427,7 @@ LZWDecode(TIFF* tif, uint8_t* op0, tmsize_t occ0, uint16_t s)
codep = codep->next;
} while (--residue > occ && codep);
if (codep) {
tp = op + occ;
uint8_t* tp = op + occ;
do {
*--tp = codep->value;
codep = codep->next;
......@@ -413,21 +440,17 @@ LZWDecode(TIFF* tif, uint8_t* op0, tmsize_t occ0, uint16_t s)
*/
op += residue;
occ -= residue;
tp = op;
uint8_t* tp = op;
do {
int t;
--tp;
t = codep->value;
*--tp = codep->value;
codep = codep->next;
*tp = (char)t;
} while (--residue && codep);
sp->dec_restart = 0;
}
bp = (unsigned char *)tif->tif_rawcp;
#ifdef LZW_CHECKEOS
bp = (uint8_t*)tif->tif_rawcp;
sp->dec_bitsleft += (((uint64_t)tif->tif_rawcc - sp->old_tif_rawcc) << 3);
#endif
uint64_t dec_bitsleft = sp->dec_bitsleft;
nbits = sp->lzw_nbits;
nextdata = sp->lzw_nextdata;
nextbits = sp->lzw_nextbits;
......@@ -435,128 +458,236 @@ LZWDecode(TIFF* tif, uint8_t* op0, tmsize_t occ0, uint16_t s)
oldcodep = sp->dec_oldcodep;
free_entp = sp->dec_free_entp;
maxcodep = sp->dec_maxcodep;
code_t* const dec_codetab = sp->dec_codetab;
code_t* codep;
if (occ == 0) {
goto after_loop;
}
begin:
{
WordType code;
GetNextCodeLZW();
codep = dec_codetab + code;
if (code >= CODE_FIRST)
goto code_above_or_equal_to_258;
if (code < 256)
goto code_below_256;
if (code == CODE_EOI)
goto after_loop;
goto code_clear;
code_below_256:
{
if (codep > free_entp)
goto error_code;
free_entp->next = oldcodep;
free_entp->firstchar = oldcodep->firstchar;
free_entp->length = oldcodep->length+1;
free_entp->value = (uint8_t)code;
free_entp->repeated = (bool)(oldcodep->repeated & (oldcodep->value == code));
if (++free_entp > maxcodep) {
if (++nbits > BITS_MAX) /* should not happen for a conformant encoder */
nbits = BITS_MAX;
nbitsmask = MAXCODE(nbits);
maxcodep = dec_codetab + nbitsmask-1;
if( free_entp >= &dec_codetab[CSIZE] )
{
/* At that point, the next valid states are either EOI or a */
/* CODE_CLEAR. If a regular code is read, at the next */
/* attempt at registering a new entry, we will error out */
/* due to setting free_entp before any valid code */
free_entp = dec_codetab - 1;
}
}
oldcodep = codep;
*op++ = (uint8_t)code;
occ--;
if (occ == 0)
goto after_loop;
goto begin;
}
while (occ > 0) {
NextCode(tif, sp, bp, code, GetNextCode);
if (code == CODE_EOI)
break;
if (code == CODE_CLEAR) {
do {
free_entp = sp->dec_codetab + CODE_FIRST;
_TIFFmemset(free_entp, 0,
(CSIZE - CODE_FIRST) * sizeof (code_t));
nbits = BITS_MIN;
nbitsmask = MAXCODE(BITS_MIN);
maxcodep = sp->dec_codetab + nbitsmask-1;
NextCode(tif, sp, bp, code, GetNextCode);
} while (code == CODE_CLEAR); /* consecutive CODE_CLEAR codes */
if (code == CODE_EOI)
break;
if (code > CODE_CLEAR) {
TIFFErrorExt(tif->tif_clientdata, tif->tif_name,
"LZWDecode: Corrupted LZW table at scanline %"PRIu32,
tif->tif_row);
return (0);
}
*op++ = (char)code;
occ--;
oldcodep = sp->dec_codetab + code;
continue;
}
codep = sp->dec_codetab + code;
code_above_or_equal_to_258:
{
/*
* Add the new entry to the code table.
*/
if (codep >= free_entp)
{
if (codep != free_entp)
goto error_code;
free_entp->value = oldcodep->firstchar;
}
else
{
free_entp->value = codep->firstchar;
}
free_entp->repeated = (bool)(oldcodep->repeated & (oldcodep->value == free_entp->value));
free_entp->next = oldcodep;
free_entp->firstchar = oldcodep->firstchar;
free_entp->length = oldcodep->length+1;
if (++free_entp > maxcodep) {
if (++nbits > BITS_MAX) /* should not happen for a conformant encoder */
nbits = BITS_MAX;
nbitsmask = MAXCODE(nbits);
maxcodep = dec_codetab + nbitsmask-1;
if (free_entp >= &dec_codetab[CSIZE])
{
/* At that point, the next valid states are either EOI or a */
/* CODE_CLEAR. If a regular code is read, at the next */
/* attempt at registering a new entry, we will error out */
/* due to setting free_entp before any valid code */
free_entp = dec_codetab - 1;
}
}
oldcodep = codep;
/*
* Code maps to a string, copy string
* value to output (written in reverse).
*/
/* tiny bit faster on x86_64 to store in unsigned short than int */
unsigned short len = codep->length;
if (len < 3) /* equivalent to len == 2 given all other conditions */
{
if (occ <= 2)
{
if (occ == 2)
{
memcpy(op, &(codep->firstchar), 2);
op += 2;
occ -= 2;
goto after_loop;
}
goto too_short_buffer;
}
/*
* Add the new entry to the code table.
*/
if (free_entp < &sp->dec_codetab[0] ||
free_entp >= &sp->dec_codetab[CSIZE]) {
TIFFErrorExt(tif->tif_clientdata, module,
"Corrupted LZW table at scanline %"PRIu32,
tif->tif_row);
return (0);
}
memcpy(op, &(codep->firstchar), 2);
op += 2;
occ -= 2;
goto begin; /* we can save the comparison occ > 0 */
}
if (len == 3)
{
if (occ <= 3)
{
if (occ == 3)
{
op[0] = codep->firstchar;
op[1] = codep->next->value;
op[2] = codep->value;
op += 3;
occ -= 3;
goto after_loop;
}
goto too_short_buffer;
}
free_entp->next = oldcodep;
if (free_entp->next < &sp->dec_codetab[0] ||
free_entp->next >= &sp->dec_codetab[CSIZE]) {
TIFFErrorExt(tif->tif_clientdata, module,
"Corrupted LZW table at scanline %"PRIu32,
tif->tif_row);
return (0);
}
free_entp->firstchar = free_entp->next->firstchar;
free_entp->length = free_entp->next->length+1;
free_entp->value = (codep < free_entp) ?
codep->firstchar : free_entp->firstchar;
if (++free_entp > maxcodep) {
if (++nbits > BITS_MAX) /* should not happen */
nbits = BITS_MAX;
nbitsmask = MAXCODE(nbits);
maxcodep = sp->dec_codetab + nbitsmask-1;
}
oldcodep = codep;
if (code >= 256) {
/*
* Code maps to a string, copy string
* value to output (written in reverse).
*/
if(codep->length == 0) {
TIFFErrorExt(tif->tif_clientdata, module,
"Wrong length of decoded string: "
"data probably corrupted at scanline %"PRIu32,
tif->tif_row);
return (0);
}
if (codep->length > occ) {
/*
* String is too long for decode buffer,
* locate portion that will fit, copy to
* the decode buffer, and setup restart
* logic for the next decoding call.
*/
sp->dec_codep = codep;
do {
codep = codep->next;
} while (codep && codep->length > occ);
if (codep) {
sp->dec_restart = (long)occ;
tp = op + occ;
do {
*--tp = codep->value;
codep = codep->next;
} while (--occ && codep);
if (codep)
codeLoop(tif, module);
}
break;
}
len = codep->length;
tp = op + len;
do {
int t;
--tp;
t = codep->value;
codep = codep->next;
*tp = (char)t;
} while (codep && tp > op);
if (codep) {
codeLoop(tif, module);
break;
}
assert(occ >= len);
op += len;
occ -= len;
} else {
*op++ = (char)code;
occ--;
}
}
op[0] = codep->firstchar;
op[1] = codep->next->value;
op[2] = codep->value;
op += 3;
occ -= 3;
goto begin; /* we can save the comparison occ > 0 */
}
if (len > occ)
{
goto too_short_buffer;
}
if (codep->repeated)
{
memset(op, codep->value, len);
op += len;
occ -= len;
if (occ == 0)
goto after_loop;
goto begin;
}
uint8_t* tp = op + len;
assert(len >= 4);
*--tp = codep->value;
codep = codep->next;
*--tp = codep->value;
codep = codep->next;
*--tp = codep->value;
codep = codep->next;
*--tp = codep->value;
if (tp > op)
{
do {
codep = codep->next;
*--tp = codep->value;
} while (tp > op);
}
assert(occ >= len);
op += len;
occ -= len;
if (occ == 0)
goto after_loop;
goto begin;
}
code_clear:
{
free_entp = dec_codetab + CODE_FIRST;
nbits = BITS_MIN;
nbitsmask = MAXCODE(BITS_MIN);
maxcodep = dec_codetab + nbitsmask-1;
do {
GetNextCodeLZW();
} while (code == CODE_CLEAR); /* consecutive CODE_CLEAR codes */
if (code == CODE_EOI)
goto after_loop;
if (code > CODE_EOI) {
goto error_code;
}
*op++ = (uint8_t)code;
occ--;
oldcodep = dec_codetab + code;
if (occ == 0)
goto after_loop;
goto begin;
}
}
too_short_buffer:
{
/*
* String is too long for decode buffer,
* locate portion that will fit, copy to
* the decode buffer, and setup restart
* logic for the next decoding call.
*/
sp->dec_codep = codep;
do {
codep = codep->next;
} while (codep->length > occ);
sp->dec_restart = occ;
uint8_t* tp = op + occ;
do {
*--tp = codep->value;
codep = codep->next;
} while (--occ);
}
after_loop:
tif->tif_rawcc -= (tmsize_t)((uint8_t*) bp - tif->tif_rawcp );
tif->tif_rawcp = (uint8_t*) bp;
#ifdef LZW_CHECKEOS
sp->old_tif_rawcc = tif->tif_rawcc;
#endif
sp->dec_bitsleft = dec_bitsleft;
sp->lzw_nbits = (unsigned short) nbits;
sp->lzw_nextdata = nextdata;
sp->lzw_nextbits = nextbits;
......@@ -567,14 +698,41 @@ LZWDecode(TIFF* tif, uint8_t* op0, tmsize_t occ0, uint16_t s)
if (occ > 0) {
TIFFErrorExt(tif->tif_clientdata, module,
"Not enough data at scanline %"PRIu32" (short %ld bytes)",
tif->tif_row, occ);
"Not enough data at scanline %"PRIu32" (short %"PRIu64" bytes)",
tif->tif_row, (uint64_t)occ);
return (0);
}
return (1);
no_eoi:
TIFFErrorExt(tif->tif_clientdata, module,
"LZWDecode: Strip %"PRIu32" not terminated with EOI code",
tif->tif_curstrip);
return 0;
error_code:
sp->read_error = 1;
TIFFErrorExt(tif->tif_clientdata, tif->tif_name, "Using code not yet in table");
return 0;
}
#ifdef LZW_COMPAT
/*
* This check shouldn't be necessary because each
* strip is suppose to be terminated with CODE_EOI.
*/
#define NextCode(_tif, _sp, _bp, _code, _get, dec_bitsleft) { \
if (dec_bitsleft < (uint64_t)nbits) { \
TIFFWarningExt(_tif->tif_clientdata, module, \
"LZWDecode: Strip %"PRIu32" not terminated with EOI code", \
_tif->tif_curstrip); \
_code = CODE_EOI; \
} else { \
_get(_sp,_bp,_code); \
dec_bitsleft -= nbits; \
} \
}
/*
* Decode a "hunk of data" for old images.
*/
......@@ -595,29 +753,24 @@ LZWDecodeCompat(TIFF* tif, uint8_t* op0, tmsize_t occ0, uint16_t s)
{
static const char module[] = "LZWDecodeCompat";
LZWCodecState *sp = DecoderState(tif);
char *op = (char*) op0;
long occ = (long) occ0;
char *tp;
unsigned char *bp;
uint8_t *op = (uint8_t*) op0;
tmsize_t occ = occ0;
uint8_t *tp;
uint8_t *bp;
int code, nbits;
int len;
long nextbits, nextdata, nbitsmask;
long nextbits, nbitsmask;
WordType nextdata;
code_t *codep, *free_entp, *maxcodep, *oldcodep;
(void) s;
assert(sp != NULL);
/*
Fail if value does not fit in long.
*/
if ((tmsize_t) occ != occ0)
return (0);
/*
* Restart interrupted output operation.
*/
if (sp->dec_restart) {
long residue;
tmsize_t residue;
codep = sp->dec_codep;
residue = codep->length - sp->dec_restart;
......@@ -652,10 +805,11 @@ LZWDecodeCompat(TIFF* tif, uint8_t* op0, tmsize_t occ0, uint16_t s)
sp->dec_restart = 0;
}
bp = (unsigned char *)tif->tif_rawcp;
#ifdef LZW_CHECKEOS
bp = (uint8_t*)tif->tif_rawcp;
sp->dec_bitsleft += (((uint64_t)tif->tif_rawcc - sp->old_tif_rawcc) << 3);
#endif
uint64_t dec_bitsleft = sp->dec_bitsleft;
nbits = sp->lzw_nbits;
nextdata = sp->lzw_nextdata;
nextbits = sp->lzw_nextbits;
......@@ -665,7 +819,7 @@ LZWDecodeCompat(TIFF* tif, uint8_t* op0, tmsize_t occ0, uint16_t s)
maxcodep = sp->dec_maxcodep;
while (occ > 0) {
NextCode(tif, sp, bp, code, GetNextCodeCompat);
NextCode(tif, sp, bp, code, GetNextCodeCompat, dec_bitsleft);
if (code == CODE_EOI)
break;
if (code == CODE_CLEAR) {
......@@ -676,7 +830,7 @@ LZWDecodeCompat(TIFF* tif, uint8_t* op0, tmsize_t occ0, uint16_t s)
nbits = BITS_MIN;
nbitsmask = MAXCODE(BITS_MIN);
maxcodep = sp->dec_codetab + nbitsmask;
NextCode(tif, sp, bp, code, GetNextCodeCompat);
NextCode(tif, sp, bp, code, GetNextCodeCompat, dec_bitsleft);
} while (code == CODE_CLEAR); /* consecutive CODE_CLEAR codes */
if (code == CODE_EOI)
break;
......@@ -686,7 +840,7 @@ LZWDecodeCompat(TIFF* tif, uint8_t* op0, tmsize_t occ0, uint16_t s)
tif->tif_row);
return (0);
}
*op++ = (char)code;
*op++ = (uint8_t)code;
occ--;
oldcodep = sp->dec_codetab + code;
continue;
......@@ -755,26 +909,24 @@ LZWDecodeCompat(TIFF* tif, uint8_t* op0, tmsize_t occ0, uint16_t s)
len = codep->length;
tp = op + len;
do {
int t;
--tp;
t = codep->value;
*--tp = codep->value;
codep = codep->next;
*tp = (char)t;
} while (codep && tp > op);
assert(occ >= len);
op += len;
occ -= len;
} else {
*op++ = (char)code;
*op++ = (uint8_t)code;
occ--;
}
}
tif->tif_rawcc -= (tmsize_t)((uint8_t*) bp - tif->tif_rawcp );
tif->tif_rawcp = (uint8_t*) bp;
#ifdef LZW_CHECKEOS
sp->old_tif_rawcc = tif->tif_rawcc;
#endif
sp->dec_bitsleft = dec_bitsleft;
sp->lzw_nbits = (unsigned short)nbits;
sp->lzw_nextdata = nextdata;
sp->lzw_nextbits = nextbits;
......@@ -785,8 +937,8 @@ LZWDecodeCompat(TIFF* tif, uint8_t* op0, tmsize_t occ0, uint16_t s)
if (occ > 0) {
TIFFErrorExt(tif->tif_clientdata, module,
"Not enough data at scanline %"PRIu32" (short %ld bytes)",
tif->tif_row, occ);
"Not enough data at scanline %"PRIu32" (short %"PRIu64" bytes)",
tif->tif_row, (uint64_t)occ);
return (0);
}
return (1);
......@@ -872,16 +1024,16 @@ LZWPreEncode(TIFF* tif, uint16_t s)
/*
* Encode a chunk of pixels.
*
* Uses an open addressing double hashing (no chaining) on the
* Uses an open addressing double hashing (no chaining) on the
* prefix code/next character combination. We do a variant of
* Knuth's algorithm D (vol. 3, sec. 6.4) along with G. Knott's
* relatively-prime secondary probe. Here, the modular division
* first probe is gives way to a faster exclusive-or manipulation.
* first probe is gives way to a faster exclusive-or manipulation.
* Also do block compression with an adaptive reset, whereby the
* code table is cleared when the compression ratio decreases,
* but after the table fills. The variable-length output codes
* are re-sized at this point, and a CODE_CLEAR is generated
* for the decoder.
* for the decoder.
*/
static int
LZWEncode(TIFF* tif, uint8_t* bp, tmsize_t cc, uint16_t s)
......@@ -892,8 +1044,8 @@ LZWEncode(TIFF* tif, uint8_t* bp, tmsize_t cc, uint16_t s)
register int h, c;
hcode_t ent;
long disp;
long incount, outcount, checkpoint;
unsigned long nextdata;
tmsize_t incount, outcount, checkpoint;
WordType nextdata;
long nextbits;
int free_ent, maxcode, nbits;
uint8_t* op;
......@@ -1005,7 +1157,7 @@ LZWEncode(TIFF* tif, uint8_t* bp, tmsize_t cc, uint16_t s)
assert(nbits <= BITS_MAX);
maxcode = (int) MAXCODE(nbits);
} else if (incount >= checkpoint) {
long rat;
tmsize_t rat;
/*
* Check compression ratio and, if things seem
* to be slipping, clear the hash table and
......@@ -1057,8 +1209,8 @@ LZWPostEncode(TIFF* tif)
register LZWCodecState *sp = EncoderState(tif);
uint8_t* op = tif->tif_rawcp;
long nextbits = sp->lzw_nextbits;
unsigned long nextdata = sp->lzw_nextdata;
long outcount = sp->enc_outcount;
WordType nextdata = sp->lzw_nextdata;
tmsize_t outcount = sp->enc_outcount;
int nbits = sp->lzw_nbits;
if (op > sp->enc_rawlimit) {
......@@ -1092,9 +1244,10 @@ LZWPostEncode(TIFF* tif)
}
PutNextCode(op, CODE_EOI);
/* Explicit 0xff masking to make icc -check=conversions happy */
if (nextbits > 0)
if (nextbits > 0)
*op++ = (unsigned char)((nextdata << (8-nextbits))&0xff);
tif->tif_rawcc = (tmsize_t)(op - tif->tif_rawdata);
(void)outcount;
return (1);
}
......@@ -1162,7 +1315,7 @@ TIFFInitLZW(TIFF* tif, int scheme)
/*
* Install codec methods.
*/
tif->tif_fixuptags = LZWFixupTags;
tif->tif_fixuptags = LZWFixupTags;
tif->tif_setupdecode = LZWSetupDecode;
tif->tif_predecode = LZWPreDecode;
tif->tif_decoderow = LZWDecode;
......@@ -1181,7 +1334,7 @@ TIFFInitLZW(TIFF* tif, int scheme)
(void) TIFFPredictorInit(tif);
return (1);
bad:
TIFFErrorExt(tif->tif_clientdata, module,
TIFFErrorExt(tif->tif_clientdata, module,
"No space for LZW state block");
return (0);
}
......
......@@ -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