mirror of
https://gitlab.winehq.org/wine/wine.git
synced 2024-11-19 17:06:04 -07:00
tiff: Import upstream release 4.7.0.
This commit is contained in:
parent
8f7fd7c739
commit
6ffad0c8e3
23 changed files with 1630 additions and 537 deletions
|
@ -385,53 +385,6 @@ int TIFFGetFieldDefaulted(TIFF *tif, uint32_t tag, ...)
|
|||
return (ok);
|
||||
}
|
||||
|
||||
struct _Int64Parts
|
||||
{
|
||||
int32_t low, high;
|
||||
};
|
||||
|
||||
typedef union
|
||||
{
|
||||
struct _Int64Parts part;
|
||||
int64_t value;
|
||||
} _Int64;
|
||||
|
||||
float _TIFFUInt64ToFloat(uint64_t ui64)
|
||||
{
|
||||
_Int64 i;
|
||||
|
||||
i.value = ui64;
|
||||
if (i.part.high >= 0)
|
||||
{
|
||||
return (float)i.value;
|
||||
}
|
||||
else
|
||||
{
|
||||
long double df;
|
||||
df = (long double)i.value;
|
||||
df += 18446744073709551616.0; /* adding 2**64 */
|
||||
return (float)df;
|
||||
}
|
||||
}
|
||||
|
||||
double _TIFFUInt64ToDouble(uint64_t ui64)
|
||||
{
|
||||
_Int64 i;
|
||||
|
||||
i.value = ui64;
|
||||
if (i.part.high >= 0)
|
||||
{
|
||||
return (double)i.value;
|
||||
}
|
||||
else
|
||||
{
|
||||
long double df;
|
||||
df = (long double)i.value;
|
||||
df += 18446744073709551616.0; /* adding 2**64 */
|
||||
return (double)df;
|
||||
}
|
||||
}
|
||||
|
||||
float _TIFFClampDoubleToFloat(double val)
|
||||
{
|
||||
if (val > FLT_MAX)
|
||||
|
|
|
@ -110,6 +110,14 @@ void TIFFCleanup(TIFF *tif)
|
|||
_TIFFfreeExt(tif, tif->tif_fieldscompat);
|
||||
}
|
||||
|
||||
if (tif->tif_cur_cumulated_mem_alloc != 0)
|
||||
{
|
||||
TIFFErrorExtR(tif, "TIFFCleanup",
|
||||
"tif_cur_cumulated_mem_alloc = %" PRIu64 " whereas it "
|
||||
"should be 0",
|
||||
(uint64_t)tif->tif_cur_cumulated_mem_alloc);
|
||||
}
|
||||
|
||||
_TIFFfreeExt(NULL, tif);
|
||||
}
|
||||
|
||||
|
|
|
@ -211,7 +211,7 @@ static uint16_t countInkNamesString(TIFF *tif, uint32_t slen, const char *s)
|
|||
}
|
||||
bad:
|
||||
TIFFErrorExtR(tif, "TIFFSetField",
|
||||
"%s: Invalid InkNames value; no NUL at given buffer end "
|
||||
"%s: Invalid InkNames value; no null at given buffer end "
|
||||
"location %" PRIu32 ", after %" PRIu16 " ink",
|
||||
tif->tif_name, slen, i);
|
||||
return (0);
|
||||
|
@ -1652,6 +1652,17 @@ void TIFFFreeDirectory(TIFF *tif)
|
|||
|
||||
_TIFFmemset(&(td->td_stripoffset_entry), 0, sizeof(TIFFDirEntry));
|
||||
_TIFFmemset(&(td->td_stripbytecount_entry), 0, sizeof(TIFFDirEntry));
|
||||
|
||||
/* Reset some internal parameters for IFD data size checking. */
|
||||
tif->tif_dir.td_dirdatasize_read = 0;
|
||||
tif->tif_dir.td_dirdatasize_write = 0;
|
||||
if (tif->tif_dir.td_dirdatasize_offsets != NULL)
|
||||
{
|
||||
_TIFFfreeExt(tif, tif->tif_dir.td_dirdatasize_offsets);
|
||||
tif->tif_dir.td_dirdatasize_offsets = NULL;
|
||||
tif->tif_dir.td_dirdatasize_Noffsets = 0;
|
||||
}
|
||||
tif->tif_dir.td_iswrittentofile = FALSE;
|
||||
}
|
||||
#undef CleanupField
|
||||
|
||||
|
@ -1676,18 +1687,23 @@ TIFFExtendProc TIFFSetTagExtender(TIFFExtendProc extender)
|
|||
*/
|
||||
int TIFFCreateDirectory(TIFF *tif)
|
||||
{
|
||||
/* Free previously allocated memory and setup default values. */
|
||||
TIFFFreeDirectory(tif);
|
||||
TIFFDefaultDirectory(tif);
|
||||
tif->tif_diroff = 0;
|
||||
tif->tif_nextdiroff = 0;
|
||||
tif->tif_curoff = 0;
|
||||
tif->tif_row = (uint32_t)-1;
|
||||
tif->tif_curstrip = (uint32_t)-1;
|
||||
tif->tif_dir.td_iswrittentofile = FALSE;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int TIFFCreateCustomDirectory(TIFF *tif, const TIFFFieldArray *infoarray)
|
||||
{
|
||||
/* Free previously allocated memory and setup default values. */
|
||||
TIFFFreeDirectory(tif);
|
||||
TIFFDefaultDirectory(tif);
|
||||
|
||||
/*
|
||||
|
@ -1848,7 +1864,9 @@ static int TIFFAdvanceDirectory(TIFF *tif, uint64_t *nextdiroff, uint64_t *off,
|
|||
if (((uint64_t)poffa != poff) || (poffb < poffa) ||
|
||||
(poffb < (tmsize_t)sizeof(uint16_t)) || (poffb > tif->tif_size))
|
||||
{
|
||||
TIFFErrorExtR(tif, module, "Error fetching directory count");
|
||||
TIFFErrorExtR(tif, module,
|
||||
"%s:%d: %s: Error fetching directory count",
|
||||
__FILE__, __LINE__, tif->tif_name);
|
||||
*nextdiroff = 0;
|
||||
return (0);
|
||||
}
|
||||
|
@ -1877,14 +1895,18 @@ static int TIFFAdvanceDirectory(TIFF *tif, uint64_t *nextdiroff, uint64_t *off,
|
|||
uint16_t dircount16;
|
||||
if (poff > (uint64_t)TIFF_TMSIZE_T_MAX - sizeof(uint64_t))
|
||||
{
|
||||
TIFFErrorExtR(tif, module, "Error fetching directory count");
|
||||
TIFFErrorExtR(tif, module,
|
||||
"%s:%d: %s: Error fetching directory count",
|
||||
__FILE__, __LINE__, tif->tif_name);
|
||||
return (0);
|
||||
}
|
||||
poffa = (tmsize_t)poff;
|
||||
poffb = poffa + sizeof(uint64_t);
|
||||
if (poffb > tif->tif_size)
|
||||
{
|
||||
TIFFErrorExtR(tif, module, "Error fetching directory count");
|
||||
TIFFErrorExtR(tif, module,
|
||||
"%s:%d: %s: Error fetching directory count",
|
||||
__FILE__, __LINE__, tif->tif_name);
|
||||
return (0);
|
||||
}
|
||||
_TIFFmemcpy(&dircount64, tif->tif_base + poffa, sizeof(uint64_t));
|
||||
|
@ -1926,8 +1948,9 @@ static int TIFFAdvanceDirectory(TIFF *tif, uint64_t *nextdiroff, uint64_t *off,
|
|||
if (!SeekOK(tif, *nextdiroff) ||
|
||||
!ReadOK(tif, &dircount, sizeof(uint16_t)))
|
||||
{
|
||||
TIFFErrorExtR(tif, module, "%s: Error fetching directory count",
|
||||
tif->tif_name);
|
||||
TIFFErrorExtR(tif, module,
|
||||
"%s:%d: %s: Error fetching directory count",
|
||||
__FILE__, __LINE__, tif->tif_name);
|
||||
return (0);
|
||||
}
|
||||
if (tif->tif_flags & TIFF_SWAB)
|
||||
|
@ -1953,15 +1976,18 @@ static int TIFFAdvanceDirectory(TIFF *tif, uint64_t *nextdiroff, uint64_t *off,
|
|||
if (!SeekOK(tif, *nextdiroff) ||
|
||||
!ReadOK(tif, &dircount64, sizeof(uint64_t)))
|
||||
{
|
||||
TIFFErrorExtR(tif, module, "%s: Error fetching directory count",
|
||||
tif->tif_name);
|
||||
TIFFErrorExtR(tif, module,
|
||||
"%s:%d: %s: Error fetching directory count",
|
||||
__FILE__, __LINE__, tif->tif_name);
|
||||
return (0);
|
||||
}
|
||||
if (tif->tif_flags & TIFF_SWAB)
|
||||
TIFFSwabLong8(&dircount64);
|
||||
if (dircount64 > 0xFFFF)
|
||||
{
|
||||
TIFFErrorExtR(tif, module, "Error fetching directory count");
|
||||
TIFFErrorExtR(tif, module,
|
||||
"%s:%d: %s: Error fetching directory count",
|
||||
__FILE__, __LINE__, tif->tif_name);
|
||||
return (0);
|
||||
}
|
||||
dircount16 = (uint16_t)dircount64;
|
||||
|
@ -2018,6 +2044,8 @@ tdir_t TIFFNumberOfDirectories(TIFF *tif)
|
|||
{
|
||||
++n;
|
||||
}
|
||||
/* Update number of main-IFDs in file. */
|
||||
tif->tif_curdircount = n;
|
||||
return (n);
|
||||
}
|
||||
|
||||
|
@ -2100,7 +2128,19 @@ int TIFFSetDirectory(TIFF *tif, tdir_t dirn)
|
|||
tif->tif_curdir = TIFF_NON_EXISTENT_DIR_NUMBER;
|
||||
else
|
||||
tif->tif_curdir--;
|
||||
return (TIFFReadDirectory(tif));
|
||||
|
||||
tdir_t curdir = tif->tif_curdir;
|
||||
|
||||
int retval = TIFFReadDirectory(tif);
|
||||
|
||||
if (!retval && tif->tif_curdir == curdir)
|
||||
{
|
||||
/* If tif_curdir has not be incremented, TIFFFetchDirectory() in
|
||||
* TIFFReadDirectory() has failed and tif_curdir shall be set
|
||||
* specifically. */
|
||||
tif->tif_curdir = TIFF_NON_EXISTENT_DIR_NUMBER;
|
||||
}
|
||||
return (retval);
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -2125,8 +2165,11 @@ int TIFFSetSubDirectory(TIFF *tif, uint64_t diroff)
|
|||
int8_t probablySubIFD = 0;
|
||||
if (diroff == 0)
|
||||
{
|
||||
/* Special case to invalidate the tif_lastdiroff member. */
|
||||
/* Special case to set tif_diroff=0, which is done in
|
||||
* TIFFReadDirectory() below to indicate that the currently read IFD is
|
||||
* treated as a new, fresh IFD. */
|
||||
tif->tif_curdir = TIFF_NON_EXISTENT_DIR_NUMBER;
|
||||
tif->tif_dir.td_iswrittentofile = FALSE;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -2136,32 +2179,40 @@ int TIFFSetSubDirectory(TIFF *tif, uint64_t diroff)
|
|||
probablySubIFD = 1;
|
||||
}
|
||||
/* -1 because TIFFReadDirectory() will increment tif_curdir. */
|
||||
tif->tif_curdir =
|
||||
curdir == 0 ? TIFF_NON_EXISTENT_DIR_NUMBER : curdir - 1;
|
||||
if (curdir >= 1)
|
||||
tif->tif_curdir = curdir - 1;
|
||||
else
|
||||
tif->tif_curdir = TIFF_NON_EXISTENT_DIR_NUMBER;
|
||||
}
|
||||
curdir = tif->tif_curdir;
|
||||
|
||||
tif->tif_nextdiroff = diroff;
|
||||
retval = TIFFReadDirectory(tif);
|
||||
/* If failed, curdir was not incremented in TIFFReadDirectory(), so set it
|
||||
* back, but leave it for diroff==0. */
|
||||
if (!retval && diroff != 0)
|
||||
|
||||
/* tif_curdir is incremented in TIFFReadDirectory(), but if it has not been
|
||||
* incremented, TIFFFetchDirectory() has failed there and tif_curdir shall
|
||||
* be set specifically. */
|
||||
if (!retval && diroff != 0 && tif->tif_curdir == curdir)
|
||||
{
|
||||
if (tif->tif_curdir == TIFF_NON_EXISTENT_DIR_NUMBER)
|
||||
tif->tif_curdir = 0;
|
||||
else
|
||||
tif->tif_curdir++;
|
||||
tif->tif_curdir = TIFF_NON_EXISTENT_DIR_NUMBER;
|
||||
}
|
||||
if (retval && probablySubIFD)
|
||||
|
||||
if (probablySubIFD)
|
||||
{
|
||||
/* Reset IFD list to start new one for SubIFD chain and also start
|
||||
* SubIFD chain with tif_curdir=0. */
|
||||
_TIFFCleanupIFDOffsetAndNumberMaps(tif); /* invalidate IFD loop lists */
|
||||
tif->tif_curdir = 0; /* first directory of new chain */
|
||||
/* add this offset to new IFD list */
|
||||
_TIFFCheckDirNumberAndOffset(tif, tif->tif_curdir, diroff);
|
||||
if (retval)
|
||||
{
|
||||
/* Reset IFD list to start new one for SubIFD chain and also start
|
||||
* SubIFD chain with tif_curdir=0 for IFD loop checking. */
|
||||
/* invalidate IFD loop lists */
|
||||
_TIFFCleanupIFDOffsetAndNumberMaps(tif);
|
||||
tif->tif_curdir = 0; /* first directory of new chain */
|
||||
/* add this offset to new IFD list */
|
||||
_TIFFCheckDirNumberAndOffset(tif, tif->tif_curdir, diroff);
|
||||
}
|
||||
/* To be able to return from SubIFD or custom-IFD to main-IFD */
|
||||
tif->tif_setdirectory_force_absolute = TRUE;
|
||||
}
|
||||
|
||||
return (retval);
|
||||
}
|
||||
|
||||
|
@ -2257,9 +2308,11 @@ int TIFFUnlinkDirectory(TIFF *tif, tdir_t dirn)
|
|||
}
|
||||
else
|
||||
{
|
||||
/* Need local swap because nextdir has to be used unswapped below. */
|
||||
uint64_t nextdir64 = nextdir;
|
||||
if (tif->tif_flags & TIFF_SWAB)
|
||||
TIFFSwabLong8(&nextdir);
|
||||
if (!WriteOK(tif, &nextdir, sizeof(uint64_t)))
|
||||
TIFFSwabLong8(&nextdir64);
|
||||
if (!WriteOK(tif, &nextdir64, sizeof(uint64_t)))
|
||||
{
|
||||
TIFFErrorExtR(tif, module, "Error writing directory link");
|
||||
return (0);
|
||||
|
@ -2303,6 +2356,10 @@ int TIFFUnlinkDirectory(TIFF *tif, tdir_t dirn)
|
|||
tif->tif_row = (uint32_t)-1;
|
||||
tif->tif_curstrip = (uint32_t)-1;
|
||||
tif->tif_curdir = TIFF_NON_EXISTENT_DIR_NUMBER;
|
||||
if (tif->tif_curdircount > 0)
|
||||
tif->tif_curdircount--;
|
||||
else
|
||||
tif->tif_curdircount = TIFF_NON_EXISTENT_DIR_NUMBER;
|
||||
_TIFFCleanupIFDOffsetAndNumberMaps(tif); /* invalidate IFD loop lists */
|
||||
return (1);
|
||||
}
|
||||
|
|
|
@ -65,6 +65,12 @@ typedef struct
|
|||
tif_dirread.c */
|
||||
} TIFFDirEntry;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
uint64_t offset;
|
||||
uint64_t length;
|
||||
} TIFFEntryOffsetAndLength; /* auxiliary for evaluating size of IFD data */
|
||||
|
||||
/*
|
||||
* Internal format of a TIFF directory entry.
|
||||
*/
|
||||
|
@ -115,6 +121,9 @@ typedef struct
|
|||
#ifdef STRIPBYTECOUNTSORTED_UNUSED
|
||||
int td_stripbytecountsorted; /* is the bytecount array sorted ascending? */
|
||||
#endif
|
||||
/* Be aware that the parameters of td_stripoffset_entry and
|
||||
* td_stripbytecount_entry are swapped but tdir_offset is not
|
||||
* and has to be swapped when used. */
|
||||
TIFFDirEntry td_stripoffset_entry; /* for deferred loading */
|
||||
TIFFDirEntry td_stripbytecount_entry; /* for deferred loading */
|
||||
uint16_t td_nsubifd;
|
||||
|
@ -135,6 +144,24 @@ typedef struct
|
|||
|
||||
unsigned char
|
||||
td_deferstrilearraywriting; /* see TIFFDeferStrileArrayWriting() */
|
||||
|
||||
unsigned char
|
||||
td_iswrittentofile; /* indicates if current IFD is present on file */
|
||||
|
||||
/* LibTIFF writes all data that does not fit into the IFD entries directly
|
||||
* after the IFD tag entry part. When reading, only the IFD data directly
|
||||
* and continuously behind the IFD tags is taken into account for the IFD
|
||||
* data size.*/
|
||||
uint64_t td_dirdatasize_write; /* auxiliary for evaluating size of IFD data
|
||||
to be written */
|
||||
uint64_t td_dirdatasize_read; /* auxiliary for evaluating size of IFD data
|
||||
read from file */
|
||||
uint32_t td_dirdatasize_Noffsets; /* auxiliary counter for
|
||||
tif_dir.td_dirdatasize_offsets array */
|
||||
TIFFEntryOffsetAndLength
|
||||
*td_dirdatasize_offsets; /* auxiliary array for all offsets of IFD tag
|
||||
entries with data outside the IFD tag
|
||||
entries. */
|
||||
} TIFFDirectory;
|
||||
|
||||
/*
|
||||
|
@ -308,11 +335,10 @@ extern "C"
|
|||
TIFFDataType field_type; /* type of associated data */
|
||||
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 */
|
||||
TIFFSetGetFieldType set_field_type; /* type to be passed to TIFFSetField
|
||||
and TIFFGetField*/
|
||||
TIFFSetGetFieldType get_field_type; /* not used */
|
||||
unsigned short field_bit; /* bit in fieldsset bit vector */
|
||||
unsigned char field_oktochange; /* if true, can change while writing */
|
||||
unsigned char field_passcount; /* if true, pass dir count on set */
|
||||
char *field_name; /* ASCII name */
|
||||
|
|
|
@ -213,8 +213,6 @@ static const TIFFField tiffFields[] = {
|
|||
{TIFFTAG_CURRENTPREPROFILEMATRIX, -1, -1, TIFF_SRATIONAL, 0, TIFF_SETGET_C16_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 1, "CurrentPreProfileMatrix", NULL},
|
||||
{TIFFTAG_PERSAMPLE, 0, 0, TIFF_SHORT, 0, TIFF_SETGET_UNDEFINED, TIFF_SETGET_UNDEFINED, FIELD_PSEUDO, TRUE, FALSE, "PerSample", NULL},
|
||||
#if 0
|
||||
/* TODO: revert above #if 0 for TIFF 4.6.0 */
|
||||
|
||||
/* begin DNG 1.2.0.0 tags */
|
||||
{TIFFTAG_COLORIMETRICREFERENCE, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "ColorimetricReference", NULL},
|
||||
{TIFFTAG_CAMERACALIBRATIONSIGNATURE, -1, -1, TIFF_BYTE, 0, TIFF_SETGET_C16_UINT8, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 1, "CameraCalibrationSignature", NULL},
|
||||
|
@ -282,9 +280,11 @@ static const TIFFField tiffFields[] = {
|
|||
{TIFFTAG_ILLUMINANTDATA2, -3, -3, TIFF_UNDEFINED, 0, TIFF_SETGET_C32_UINT8, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 1, "IlluminantData2", NULL},
|
||||
{TIFFTAG_ILLUMINANTDATA3, -3, -3, TIFF_UNDEFINED, 0, TIFF_SETGET_C32_UINT8, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 1, "IlluminantData3", NULL},
|
||||
/* end DNG tags */
|
||||
#endif
|
||||
/* begin TIFF/EP tags */
|
||||
{TIFFTAG_EP_CFAREPEATPATTERNDIM, 2, 2, TIFF_SHORT, 0, TIFF_SETGET_C0_UINT16, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "EP CFARepeatPatternDim", NULL},
|
||||
{TIFFTAG_EP_CFAPATTERN, -1, -1, TIFF_BYTE, 0, TIFF_SETGET_C16_UINT8, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 1, "EP CFAPattern", NULL},
|
||||
#if 0
|
||||
/* TIFFTAG_EP_BATTERYLEVEL can be RATIONAL or ASCII.
|
||||
* LibTiff defines it as ASCII and converts RATIONAL to an ASCII string. */
|
||||
{TIFFTAG_EP_BATTERYLEVEL, -1, -1, TIFF_ASCII, 0, TIFF_SETGET_ASCII, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "EP BatteryLevel", NULL},
|
||||
|
@ -887,7 +887,7 @@ const TIFFField *_TIFFFindOrRegisterField(TIFF *tif, uint32_t tag,
|
|||
if (fld == NULL)
|
||||
{
|
||||
fld = _TIFFCreateAnonField(tif, tag, dt);
|
||||
if (!_TIFFMergeFields(tif, fld, 1))
|
||||
if (fld == NULL || !_TIFFMergeFields(tif, fld, 1))
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
@ -1197,12 +1197,24 @@ int TIFFMergeFieldInfo(TIFF *tif, const TIFFFieldInfo info[], uint32_t n)
|
|||
for (i = 0; i < n; i++)
|
||||
{
|
||||
tp->field_tag = info[i].field_tag;
|
||||
if (info[i].field_readcount < TIFF_VARIABLE2 ||
|
||||
info[i].field_readcount == 0 ||
|
||||
info[i].field_writecount < TIFF_VARIABLE2 ||
|
||||
info[i].field_writecount == 0)
|
||||
{
|
||||
/* The fields (field_readcount) and (field_writecount) may use the
|
||||
* values TIFF_VARIABLE (-1), TIFF_SPP (-2), TIFF_VARIABLE2 (-3). */
|
||||
TIFFErrorExtR(tif, module,
|
||||
"The value of field_readcount and field_writecount "
|
||||
"must be greater than or equal to -3 and not zero.");
|
||||
return -1;
|
||||
}
|
||||
tp->field_readcount = info[i].field_readcount;
|
||||
tp->field_writecount = info[i].field_writecount;
|
||||
tp->field_type = info[i].field_type;
|
||||
tp->field_anonymous = 0;
|
||||
tp->set_field_type =
|
||||
_TIFFSetGetType(info[i].field_type, info[i].field_readcount,
|
||||
_TIFFSetGetType(info[i].field_type, info[i].field_writecount,
|
||||
info[i].field_passcount);
|
||||
tp->get_field_type =
|
||||
_TIFFSetGetType(info[i].field_type, info[i].field_readcount,
|
||||
|
|
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
|
@ -41,6 +41,14 @@
|
|||
#include "t4.h"
|
||||
#include <stdio.h>
|
||||
|
||||
#ifndef EOF_REACHED_COUNT_THRESHOLD
|
||||
/* Arbitrary threshold to avoid corrupted single-strip files with extremely
|
||||
* large imageheight to cause apparently endless looping, such as in
|
||||
* https://gitlab.com/libtiff/libtiff/-/issues/583
|
||||
*/
|
||||
#define EOF_REACHED_COUNT_THRESHOLD 8192
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Compression+decompression state blocks are
|
||||
* derived from this ``base state'' block.
|
||||
|
@ -77,6 +85,8 @@ typedef struct
|
|||
uint32_t data; /* current i/o byte/word */
|
||||
int bit; /* current i/o bit in byte */
|
||||
int EOLcnt; /* count of EOL codes recognized */
|
||||
int eofReachedCount; /* number of times decode has been called with
|
||||
EOF already reached */
|
||||
TIFFFaxFillFunc fill; /* fill routine */
|
||||
uint32_t *runs; /* b&w runs for current/previous row */
|
||||
uint32_t nruns; /* size of the refruns / curruns arrays */
|
||||
|
@ -120,6 +130,7 @@ typedef struct
|
|||
int EOLcnt; /* # EOL codes recognized */ \
|
||||
const unsigned char *bitmap = sp->bitmap; /* input data bit reverser */ \
|
||||
const TIFFFaxTabEnt *TabEnt
|
||||
|
||||
#define DECLARE_STATE_2D(tif, sp, mod) \
|
||||
DECLARE_STATE(tif, sp, mod); \
|
||||
int b1; /* next change on prev line */ \
|
||||
|
@ -162,6 +173,7 @@ static int Fax3PreDecode(TIFF *tif, uint16_t s)
|
|||
sp->bit = 0; /* force initial read */
|
||||
sp->data = 0;
|
||||
sp->EOLcnt = 0; /* force initial scan for EOL */
|
||||
sp->eofReachedCount = 0;
|
||||
/*
|
||||
* Decoder assumes lsb-to-msb bit order. Note that we select
|
||||
* this here rather than in Fax3SetupState so that viewers can
|
||||
|
@ -232,7 +244,12 @@ static void Fax3PrematureEOF(const char *module, TIFF *tif, uint32_t line,
|
|||
line, isTiled(tif) ? "tile" : "strip",
|
||||
(isTiled(tif) ? tif->tif_curtile : tif->tif_curstrip), a0);
|
||||
}
|
||||
#define prematureEOF(a0) Fax3PrematureEOF(module, tif, sp->line, a0)
|
||||
#define prematureEOF(a0) \
|
||||
do \
|
||||
{ \
|
||||
Fax3PrematureEOF(module, tif, sp->line, a0); \
|
||||
++sp->eofReachedCount; \
|
||||
} while (0)
|
||||
|
||||
#define Nop
|
||||
|
||||
|
@ -252,6 +269,14 @@ static int Fax3Decode1D(TIFF *tif, uint8_t *buf, tmsize_t occ, uint16_t s)
|
|||
TIFFErrorExtR(tif, module, "Fractional scanlines cannot be read");
|
||||
return (-1);
|
||||
}
|
||||
if (sp->eofReachedCount >= EOF_REACHED_COUNT_THRESHOLD)
|
||||
{
|
||||
TIFFErrorExtR(
|
||||
tif, module,
|
||||
"End of file has already been reached %d times within that strip",
|
||||
sp->eofReachedCount);
|
||||
return (-1);
|
||||
}
|
||||
CACHE_STATE(tif, sp);
|
||||
thisrun = sp->curruns;
|
||||
while (occ > 0)
|
||||
|
@ -302,6 +327,14 @@ static int Fax3Decode2D(TIFF *tif, uint8_t *buf, tmsize_t occ, uint16_t s)
|
|||
TIFFErrorExtR(tif, module, "Fractional scanlines cannot be read");
|
||||
return (-1);
|
||||
}
|
||||
if (sp->eofReachedCount >= EOF_REACHED_COUNT_THRESHOLD)
|
||||
{
|
||||
TIFFErrorExtR(
|
||||
tif, module,
|
||||
"End of file has already been reached %d times within that strip",
|
||||
sp->eofReachedCount);
|
||||
return (-1);
|
||||
}
|
||||
CACHE_STATE(tif, sp);
|
||||
while (occ > 0)
|
||||
{
|
||||
|
@ -536,7 +569,11 @@ static int Fax3SetupState(TIFF *tif)
|
|||
|
||||
TIFFroundup and TIFFSafeMultiply return zero on integer overflow
|
||||
*/
|
||||
dsp->runs = (uint32_t *)NULL;
|
||||
if (dsp->runs != NULL)
|
||||
{
|
||||
_TIFFfreeExt(tif, dsp->runs);
|
||||
dsp->runs = (uint32_t *)NULL;
|
||||
}
|
||||
dsp->nruns = TIFFroundup_32(rowpixels + 1, 32);
|
||||
if (needsRefLine)
|
||||
{
|
||||
|
@ -578,6 +615,10 @@ static int Fax3SetupState(TIFF *tif)
|
|||
* is referenced. The reference line must
|
||||
* be initialized to be ``white'' (done elsewhere).
|
||||
*/
|
||||
if (esp->refline != NULL)
|
||||
{
|
||||
_TIFFfreeExt(tif, esp->refline);
|
||||
}
|
||||
esp->refline = (unsigned char *)_TIFFmallocExt(tif, rowbytes);
|
||||
if (esp->refline == NULL)
|
||||
{
|
||||
|
@ -1514,7 +1555,16 @@ static int Fax4Decode(TIFF *tif, uint8_t *buf, tmsize_t occ, uint16_t s)
|
|||
TIFFErrorExtR(tif, module, "Fractional scanlines cannot be read");
|
||||
return (-1);
|
||||
}
|
||||
if (sp->eofReachedCount >= EOF_REACHED_COUNT_THRESHOLD)
|
||||
{
|
||||
TIFFErrorExtR(
|
||||
tif, module,
|
||||
"End of file has already been reached %d times within that strip",
|
||||
sp->eofReachedCount);
|
||||
return (-1);
|
||||
}
|
||||
CACHE_STATE(tif, sp);
|
||||
int start = sp->line;
|
||||
while (occ > 0)
|
||||
{
|
||||
a0 = 0;
|
||||
|
@ -1563,7 +1613,9 @@ static int Fax4Decode(TIFF *tif, uint8_t *buf, tmsize_t occ, uint16_t s)
|
|||
}
|
||||
(*sp->fill)(buf, thisrun, pa, lastx);
|
||||
UNCACHE_STATE(tif, sp);
|
||||
return (sp->line ? 1 : -1); /* don't error on badly-terminated strips */
|
||||
return (sp->line != start
|
||||
? 1
|
||||
: -1); /* don't error on badly-terminated strips */
|
||||
}
|
||||
UNCACHE_STATE(tif, sp);
|
||||
return (1);
|
||||
|
|
|
@ -146,7 +146,7 @@ TIFFHashSet *TIFFHashSetNew(TIFFHashSetHashFunc fnHashFunc,
|
|||
set->fnEqualFunc = fnEqualFunc ? fnEqualFunc : TIFFHashSetEqualPointer;
|
||||
set->fnFreeEltFunc = fnFreeEltFunc;
|
||||
set->nSize = 0;
|
||||
set->tabList = (TIFFList **)(calloc(sizeof(TIFFList *), 53));
|
||||
set->tabList = (TIFFList **)(calloc(53, sizeof(TIFFList *)));
|
||||
if (set->tabList == NULL)
|
||||
{
|
||||
free(set);
|
||||
|
@ -367,7 +367,7 @@ static bool TIFFHashSetRehash(TIFFHashSet *set)
|
|||
{
|
||||
int nNewAllocatedSize = anPrimes[set->nIndiceAllocatedSize];
|
||||
TIFFList **newTabList =
|
||||
(TIFFList **)(calloc(sizeof(TIFFList *), nNewAllocatedSize));
|
||||
(TIFFList **)(calloc(nNewAllocatedSize, sizeof(TIFFList *)));
|
||||
if (newTabList == NULL)
|
||||
return false;
|
||||
#ifdef HASH_DEBUG
|
||||
|
|
|
@ -73,43 +73,6 @@ int TIFFReInitJPEG_12(TIFF *tif, const JPEGOtherSettings *otherSettings,
|
|||
int scheme, int is_encode);
|
||||
int TIFFJPEGIsFullStripRequired_12(TIFF *tif);
|
||||
|
||||
/* We undefine FAR to avoid conflict with JPEG definition */
|
||||
|
||||
#ifdef FAR
|
||||
#undef FAR
|
||||
#endif
|
||||
|
||||
/*
|
||||
Libjpeg's jmorecfg.h defines INT16 and INT32, but only if XMD_H is
|
||||
not defined. Unfortunately, the MinGW and Borland compilers include
|
||||
a typedef for INT32, which causes a conflict. MSVC does not include
|
||||
a conflicting typedef given the headers which are included.
|
||||
*/
|
||||
#if defined(__BORLANDC__) || defined(__MINGW32__)
|
||||
#define XMD_H 1
|
||||
#endif
|
||||
|
||||
/*
|
||||
The windows RPCNDR.H file defines boolean, but defines it with the
|
||||
unsigned char size. You should compile JPEG library using appropriate
|
||||
definitions in jconfig.h header, but many users compile library in wrong
|
||||
way. That causes errors of the following type:
|
||||
|
||||
"JPEGLib: JPEG parameter struct mismatch: library thinks size is 432,
|
||||
caller expects 464"
|
||||
|
||||
For such users we will fix the problem here. See install.doc file from
|
||||
the JPEG library distribution for details.
|
||||
*/
|
||||
|
||||
/* Define "boolean" as unsigned char, not int, per Windows custom. */
|
||||
#if defined(__WIN32__) && !defined(__MINGW32__)
|
||||
#ifndef __RPCNDR_H__ /* don't conflict if rpcndr.h already read */
|
||||
typedef unsigned char boolean;
|
||||
#endif
|
||||
#define HAVE_BOOLEAN /* prevent jmorecfg.h from redefining it */
|
||||
#endif
|
||||
|
||||
#include "jerror.h"
|
||||
#include "jpeglib.h"
|
||||
|
||||
|
@ -125,18 +88,18 @@ typedef unsigned char boolean;
|
|||
* 16bit value?
|
||||
*/
|
||||
|
||||
/* HAVE_JPEGTURBO_DUAL_MODE_8_12 is defined for libjpeg-turbo >= 2.2 which
|
||||
/* HAVE_JPEGTURBO_DUAL_MODE_8_12 is defined for libjpeg-turbo >= 3.0 which
|
||||
* adds a dual-mode 8/12 bit API in the same library.
|
||||
*/
|
||||
|
||||
#if defined(HAVE_JPEGTURBO_DUAL_MODE_8_12)
|
||||
#define JPEG_DUAL_MODE_8_12
|
||||
/* Start by undefining BITS_IN_JSAMPLE which is always set to 8 in libjpeg-turbo
|
||||
* >= 2.2 Cf
|
||||
* >= 3.0 Cf
|
||||
* https://github.com/libjpeg-turbo/libjpeg-turbo/commit/8b9bc4b9635a2a047fb23ebe70c9acd728d3f99b
|
||||
*/
|
||||
#undef BITS_IN_JSAMPLE
|
||||
/* libjpeg-turbo >= 2.2 adds J12xxxx datatypes for the 12-bit mode. */
|
||||
/* libjpeg-turbo >= 3.0 adds J12xxxx datatypes for the 12-bit mode. */
|
||||
#if defined(FROM_TIF_JPEG_12)
|
||||
#define BITS_IN_JSAMPLE 12
|
||||
#define TIFF_JSAMPLE J12SAMPLE
|
||||
|
@ -182,9 +145,20 @@ typedef unsigned char boolean;
|
|||
#define LONGJMP(jbuf, code) longjmp(jbuf, code)
|
||||
#define JMP_BUF jmp_buf
|
||||
|
||||
#ifndef TIFF_jpeg_destination_mgr_defined
|
||||
#define TIFF_jpeg_destination_mgr_defined
|
||||
typedef struct jpeg_destination_mgr jpeg_destination_mgr;
|
||||
#endif
|
||||
|
||||
#ifndef TIFF_jpeg_source_mgr_defined
|
||||
#define TIFF_jpeg_source_mgr_defined
|
||||
typedef struct jpeg_source_mgr jpeg_source_mgr;
|
||||
#endif
|
||||
|
||||
#ifndef TIFF_jpeg_error_mgr_defined
|
||||
#define TIFF_jpeg_error_mgr_defined
|
||||
typedef struct jpeg_error_mgr jpeg_error_mgr;
|
||||
#endif
|
||||
|
||||
/*
|
||||
* State block for each open TIFF file using
|
||||
|
@ -1241,6 +1215,12 @@ int TIFFJPEGIsFullStripRequired(TIFF *tif)
|
|||
* For PC 2, scale down the expected strip/tile size
|
||||
* to match a downsampled component
|
||||
*/
|
||||
if (sp->h_sampling == 0 || sp->v_sampling == 0)
|
||||
{
|
||||
TIFFErrorExtR(tif, module,
|
||||
"JPEG horizontal or vertical sampling is zero");
|
||||
return (0);
|
||||
}
|
||||
segment_width = TIFFhowmany_32(segment_width, sp->h_sampling);
|
||||
segment_height = TIFFhowmany_32(segment_height, sp->v_sampling);
|
||||
}
|
||||
|
@ -1471,7 +1451,10 @@ static int JPEGDecode(TIFF *tif, uint8_t *buf, tmsize_t cc, uint16_t s)
|
|||
sp->src.bytes_in_buffer = (size_t)tif->tif_rawcc;
|
||||
|
||||
if (sp->bytesperline == 0)
|
||||
{
|
||||
memset(buf, 0, (size_t)cc);
|
||||
return 0;
|
||||
}
|
||||
|
||||
nrows = cc / sp->bytesperline;
|
||||
if (cc % sp->bytesperline)
|
||||
|
@ -1492,7 +1475,10 @@ static int JPEGDecode(TIFF *tif, uint8_t *buf, tmsize_t cc, uint16_t s)
|
|||
JSAMPROW bufptr = (JSAMPROW)buf;
|
||||
|
||||
if (TIFFjpeg_read_scanlines(sp, &bufptr, 1) != 1)
|
||||
{
|
||||
memset(buf, 0, (size_t)cc);
|
||||
return (0);
|
||||
}
|
||||
|
||||
++tif->tif_row;
|
||||
buf += sp->bytesperline;
|
||||
|
@ -1526,7 +1512,10 @@ static int JPEGDecode(TIFF *tif, uint8_t *buf, tmsize_t cc, uint16_t s)
|
|||
sp->src.bytes_in_buffer = (size_t)tif->tif_rawcc;
|
||||
|
||||
if (sp->bytesperline == 0)
|
||||
{
|
||||
memset(buf, 0, (size_t)cc);
|
||||
return 0;
|
||||
}
|
||||
|
||||
nrows = cc / sp->bytesperline;
|
||||
if (cc % sp->bytesperline)
|
||||
|
@ -1562,7 +1551,10 @@ static int JPEGDecode(TIFF *tif, uint8_t *buf, tmsize_t cc, uint16_t s)
|
|||
* for 12bit data, which we need to repack.
|
||||
*/
|
||||
if (TIFFjpeg_read_scanlines(sp, &line_work_buf, 1) != 1)
|
||||
{
|
||||
memset(buf, 0, (size_t)cc);
|
||||
return (0);
|
||||
}
|
||||
|
||||
if (sp->cinfo.d.data_precision == 12)
|
||||
{
|
||||
|
@ -2190,6 +2182,12 @@ static int JPEGPreEncode(TIFF *tif, uint16_t s)
|
|||
/* for PC 2, scale down the strip/tile size
|
||||
* to match a downsampled component
|
||||
*/
|
||||
if (sp->h_sampling == 0 || sp->v_sampling == 0)
|
||||
{
|
||||
TIFFErrorExtR(tif, module,
|
||||
"JPEG horizontal or vertical sampling is zero");
|
||||
return (0);
|
||||
}
|
||||
segment_width = TIFFhowmany_32(segment_width, sp->h_sampling);
|
||||
segment_height = TIFFhowmany_32(segment_height, sp->v_sampling);
|
||||
}
|
||||
|
|
|
@ -951,7 +951,8 @@ static
|
|||
int
|
||||
uv_encode(double u, double v, int em) /* encode (u',v') coordinates */
|
||||
{
|
||||
register int vi, ui;
|
||||
unsigned int vi;
|
||||
int ui;
|
||||
|
||||
/* check for NaN */
|
||||
if (u != u || v != v)
|
||||
|
@ -980,8 +981,9 @@ static
|
|||
int
|
||||
uv_decode(double *up, double *vp, int c) /* decode (u',v') index */
|
||||
{
|
||||
int upper, lower;
|
||||
register int ui, vi;
|
||||
unsigned int upper, lower;
|
||||
int ui;
|
||||
unsigned int vi;
|
||||
|
||||
if (c < 0 || c >= UV_NDIVS)
|
||||
return (-1);
|
||||
|
|
|
@ -161,8 +161,8 @@ typedef struct
|
|||
} LZWCodecState;
|
||||
|
||||
#define LZWState(tif) ((LZWBaseState *)(tif)->tif_data)
|
||||
#define DecoderState(tif) ((LZWCodecState *)LZWState(tif))
|
||||
#define EncoderState(tif) ((LZWCodecState *)LZWState(tif))
|
||||
#define LZWDecoderState(tif) ((LZWCodecState *)LZWState(tif))
|
||||
#define LZWEncoderState(tif) ((LZWCodecState *)LZWState(tif))
|
||||
|
||||
static int LZWDecode(TIFF *tif, uint8_t *op0, tmsize_t occ0, uint16_t s);
|
||||
#ifdef LZW_COMPAT
|
||||
|
@ -183,7 +183,7 @@ static int LZWFixupTags(TIFF *tif)
|
|||
static int LZWSetupDecode(TIFF *tif)
|
||||
{
|
||||
static const char module[] = "LZWSetupDecode";
|
||||
LZWCodecState *sp = DecoderState(tif);
|
||||
LZWCodecState *sp = LZWDecoderState(tif);
|
||||
int code;
|
||||
|
||||
if (sp == NULL)
|
||||
|
@ -199,7 +199,7 @@ static int LZWSetupDecode(TIFF *tif)
|
|||
return (0);
|
||||
}
|
||||
|
||||
sp = DecoderState(tif);
|
||||
sp = LZWDecoderState(tif);
|
||||
sp->dec_codetab = NULL;
|
||||
sp->dec_decode = NULL;
|
||||
|
||||
|
@ -245,7 +245,7 @@ static int LZWSetupDecode(TIFF *tif)
|
|||
static int LZWPreDecode(TIFF *tif, uint16_t s)
|
||||
{
|
||||
static const char module[] = "LZWPreDecode";
|
||||
LZWCodecState *sp = DecoderState(tif);
|
||||
LZWCodecState *sp = LZWDecoderState(tif);
|
||||
|
||||
(void)s;
|
||||
assert(sp != NULL);
|
||||
|
@ -329,10 +329,7 @@ static int LZWPreDecode(TIFF *tif, uint16_t s)
|
|||
#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)
|
||||
#if defined(_M_X64)
|
||||
#define GetNextData(nextdata, bp) nextdata = _byteswap_uint64(*(uint64_t *)(bp))
|
||||
#elif defined(__GNUC__)
|
||||
#define GetNextData(nextdata, bp) \
|
||||
|
@ -346,10 +343,7 @@ static int LZWPreDecode(TIFF *tif, uint16_t s)
|
|||
(((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)
|
||||
#if defined(_M_X86)
|
||||
#define GetNextData(nextdata, bp) \
|
||||
nextdata = _byteswap_ulong(*(unsigned long *)(bp))
|
||||
#elif defined(__GNUC__)
|
||||
|
@ -409,7 +403,7 @@ static int LZWPreDecode(TIFF *tif, uint16_t s)
|
|||
static int LZWDecode(TIFF *tif, uint8_t *op0, tmsize_t occ0, uint16_t s)
|
||||
{
|
||||
static const char module[] = "LZWDecode";
|
||||
LZWCodecState *sp = DecoderState(tif);
|
||||
LZWCodecState *sp = LZWDecoderState(tif);
|
||||
uint8_t *op = (uint8_t *)op0;
|
||||
tmsize_t occ = occ0;
|
||||
uint8_t *bp;
|
||||
|
@ -423,6 +417,7 @@ static int LZWDecode(TIFF *tif, uint8_t *op0, tmsize_t occ0, uint16_t s)
|
|||
|
||||
if (sp->read_error)
|
||||
{
|
||||
memset(op, 0, (size_t)occ);
|
||||
TIFFErrorExtR(tif, module,
|
||||
"LZWDecode: Scanline %" PRIu32 " cannot be read due to "
|
||||
"previous error",
|
||||
|
@ -737,6 +732,7 @@ after_loop:
|
|||
|
||||
if (occ > 0)
|
||||
{
|
||||
memset(op, 0, (size_t)occ);
|
||||
TIFFErrorExtR(tif, module,
|
||||
"Not enough data at scanline %" PRIu32 " (short %" PRIu64
|
||||
" bytes)",
|
||||
|
@ -746,12 +742,14 @@ after_loop:
|
|||
return (1);
|
||||
|
||||
no_eoi:
|
||||
memset(op, 0, (size_t)occ);
|
||||
sp->read_error = 1;
|
||||
TIFFErrorExtR(tif, module,
|
||||
"LZWDecode: Strip %" PRIu32 " not terminated with EOI code",
|
||||
tif->tif_curstrip);
|
||||
return 0;
|
||||
error_code:
|
||||
memset(op, 0, (size_t)occ);
|
||||
sp->read_error = 1;
|
||||
TIFFErrorExtR(tif, tif->tif_name, "Using code not yet in table");
|
||||
return 0;
|
||||
|
@ -800,7 +798,7 @@ error_code:
|
|||
static int LZWDecodeCompat(TIFF *tif, uint8_t *op0, tmsize_t occ0, uint16_t s)
|
||||
{
|
||||
static const char module[] = "LZWDecodeCompat";
|
||||
LZWCodecState *sp = DecoderState(tif);
|
||||
LZWCodecState *sp = LZWDecoderState(tif);
|
||||
uint8_t *op = (uint8_t *)op0;
|
||||
tmsize_t occ = occ0;
|
||||
uint8_t *tp;
|
||||
|
@ -1026,7 +1024,7 @@ static int LZWDecodeCompat(TIFF *tif, uint8_t *op0, tmsize_t occ0, uint16_t s)
|
|||
static int LZWSetupEncode(TIFF *tif)
|
||||
{
|
||||
static const char module[] = "LZWSetupEncode";
|
||||
LZWCodecState *sp = EncoderState(tif);
|
||||
LZWCodecState *sp = LZWEncoderState(tif);
|
||||
|
||||
assert(sp != NULL);
|
||||
sp->enc_hashtab = (hash_t *)_TIFFmallocExt(tif, HSIZE * sizeof(hash_t));
|
||||
|
@ -1043,7 +1041,7 @@ static int LZWSetupEncode(TIFF *tif)
|
|||
*/
|
||||
static int LZWPreEncode(TIFF *tif, uint16_t s)
|
||||
{
|
||||
LZWCodecState *sp = EncoderState(tif);
|
||||
LZWCodecState *sp = LZWEncoderState(tif);
|
||||
|
||||
(void)s;
|
||||
assert(sp != NULL);
|
||||
|
@ -1114,7 +1112,7 @@ static int LZWPreEncode(TIFF *tif, uint16_t s)
|
|||
*/
|
||||
static int LZWEncode(TIFF *tif, uint8_t *bp, tmsize_t cc, uint16_t s)
|
||||
{
|
||||
register LZWCodecState *sp = EncoderState(tif);
|
||||
register LZWCodecState *sp = LZWEncoderState(tif);
|
||||
register long fcode;
|
||||
register hash_t *hp;
|
||||
register int h, c;
|
||||
|
@ -1299,7 +1297,7 @@ static int LZWEncode(TIFF *tif, uint8_t *bp, tmsize_t cc, uint16_t s)
|
|||
*/
|
||||
static int LZWPostEncode(TIFF *tif)
|
||||
{
|
||||
register LZWCodecState *sp = EncoderState(tif);
|
||||
register LZWCodecState *sp = LZWEncoderState(tif);
|
||||
uint8_t *op = tif->tif_rawcp;
|
||||
long nextbits = sp->lzw_nextbits;
|
||||
WordType nextdata = sp->lzw_nextdata;
|
||||
|
@ -1381,11 +1379,11 @@ static void LZWCleanup(TIFF *tif)
|
|||
|
||||
assert(tif->tif_data != 0);
|
||||
|
||||
if (DecoderState(tif)->dec_codetab)
|
||||
_TIFFfreeExt(tif, DecoderState(tif)->dec_codetab);
|
||||
if (LZWDecoderState(tif)->dec_codetab)
|
||||
_TIFFfreeExt(tif, LZWDecoderState(tif)->dec_codetab);
|
||||
|
||||
if (EncoderState(tif)->enc_hashtab)
|
||||
_TIFFfreeExt(tif, EncoderState(tif)->enc_hashtab);
|
||||
if (LZWEncoderState(tif)->enc_hashtab)
|
||||
_TIFFfreeExt(tif, LZWEncoderState(tif)->enc_hashtab);
|
||||
|
||||
_TIFFfreeExt(tif, tif->tif_data);
|
||||
tif->tif_data = NULL;
|
||||
|
@ -1404,9 +1402,9 @@ int TIFFInitLZW(TIFF *tif, int scheme)
|
|||
tif->tif_data = (uint8_t *)_TIFFmallocExt(tif, sizeof(LZWCodecState));
|
||||
if (tif->tif_data == NULL)
|
||||
goto bad;
|
||||
DecoderState(tif)->dec_codetab = NULL;
|
||||
DecoderState(tif)->dec_decode = NULL;
|
||||
EncoderState(tif)->enc_hashtab = NULL;
|
||||
LZWDecoderState(tif)->dec_codetab = NULL;
|
||||
LZWDecoderState(tif)->dec_decode = NULL;
|
||||
LZWEncoderState(tif)->enc_hashtab = NULL;
|
||||
LZWState(tif)->rw_mode = tif->tif_mode;
|
||||
|
||||
/*
|
||||
|
|
|
@ -25,7 +25,13 @@
|
|||
/*
|
||||
* TIFF Library.
|
||||
*/
|
||||
|
||||
#ifdef TIFF_DO_NOT_USE_NON_EXT_ALLOC_FUNCTIONS
|
||||
#undef TIFF_DO_NOT_USE_NON_EXT_ALLOC_FUNCTIONS
|
||||
#endif
|
||||
|
||||
#include "tiffiop.h"
|
||||
#include <assert.h>
|
||||
#include <limits.h>
|
||||
|
||||
/*
|
||||
|
@ -81,8 +87,9 @@ TIFFOpenOptions *TIFFOpenOptionsAlloc()
|
|||
void TIFFOpenOptionsFree(TIFFOpenOptions *opts) { _TIFFfree(opts); }
|
||||
|
||||
/** Define a limit in bytes for a single memory allocation done by libtiff.
|
||||
* If max_single_mem_alloc is set to 0, no other limit that the underlying
|
||||
* _TIFFmalloc() will be applied, which is the default.
|
||||
* If max_single_mem_alloc is set to 0, which is the default, no other limit
|
||||
* that the underlying _TIFFmalloc() or
|
||||
* TIFFOpenOptionsSetMaxCumulatedMemAlloc() will be applied.
|
||||
*/
|
||||
void TIFFOpenOptionsSetMaxSingleMemAlloc(TIFFOpenOptions *opts,
|
||||
tmsize_t max_single_mem_alloc)
|
||||
|
@ -90,6 +97,18 @@ void TIFFOpenOptionsSetMaxSingleMemAlloc(TIFFOpenOptions *opts,
|
|||
opts->max_single_mem_alloc = max_single_mem_alloc;
|
||||
}
|
||||
|
||||
/** Define a limit in bytes for the cumulated memory allocations done by libtiff
|
||||
* on a given TIFF handle.
|
||||
* If max_cumulated_mem_alloc is set to 0, which is the default, no other limit
|
||||
* that the underlying _TIFFmalloc() or
|
||||
* TIFFOpenOptionsSetMaxSingleMemAlloc() will be applied.
|
||||
*/
|
||||
void TIFFOpenOptionsSetMaxCumulatedMemAlloc(TIFFOpenOptions *opts,
|
||||
tmsize_t max_cumulated_mem_alloc)
|
||||
{
|
||||
opts->max_cumulated_mem_alloc = max_cumulated_mem_alloc;
|
||||
}
|
||||
|
||||
void TIFFOpenOptionsSetErrorHandlerExtR(TIFFOpenOptions *opts,
|
||||
TIFFErrorHandlerExtR handler,
|
||||
void *errorhandler_user_data)
|
||||
|
@ -117,6 +136,30 @@ static void _TIFFEmitErrorAboveMaxSingleMemAlloc(TIFF *tif,
|
|||
(uint64_t)s, (uint64_t)tif->tif_max_single_mem_alloc);
|
||||
}
|
||||
|
||||
static void _TIFFEmitErrorAboveMaxCumulatedMemAlloc(TIFF *tif,
|
||||
const char *pszFunction,
|
||||
tmsize_t s)
|
||||
{
|
||||
TIFFErrorExtR(tif, pszFunction,
|
||||
"Cumulated memory allocation of %" PRIu64 " + %" PRIu64
|
||||
" bytes is beyond the %" PRIu64
|
||||
" cumulated byte limit defined in open options",
|
||||
(uint64_t)tif->tif_cur_cumulated_mem_alloc, (uint64_t)s,
|
||||
(uint64_t)tif->tif_max_cumulated_mem_alloc);
|
||||
}
|
||||
|
||||
/* When allocating memory, we write at the beginning of the buffer it size.
|
||||
* This allows us to keep track of the total memory allocated when we
|
||||
* malloc/calloc/realloc and free. In theory we need just SIZEOF_SIZE_T bytes
|
||||
* for that, but on x86_64, allocations of more than 16 bytes are aligned on
|
||||
* 16 bytes. Hence using 2 * SIZEOF_SIZE_T.
|
||||
* It is critical that _TIFFmallocExt/_TIFFcallocExt/_TIFFreallocExt are
|
||||
* paired with _TIFFfreeExt.
|
||||
* CMakeLists.txt defines TIFF_DO_NOT_USE_NON_EXT_ALLOC_FUNCTIONS, which in
|
||||
* turn disables the definition of the non Ext version in tiffio.h
|
||||
*/
|
||||
#define LEADING_AREA_TO_STORE_ALLOC_SIZE (2 * SIZEOF_SIZE_T)
|
||||
|
||||
/** malloc() version that takes into account memory-specific open options */
|
||||
void *_TIFFmallocExt(TIFF *tif, tmsize_t s)
|
||||
{
|
||||
|
@ -126,16 +169,32 @@ void *_TIFFmallocExt(TIFF *tif, tmsize_t s)
|
|||
_TIFFEmitErrorAboveMaxSingleMemAlloc(tif, "_TIFFmallocExt", s);
|
||||
return NULL;
|
||||
}
|
||||
if (tif != NULL && tif->tif_max_cumulated_mem_alloc > 0)
|
||||
{
|
||||
if (s > tif->tif_max_cumulated_mem_alloc -
|
||||
tif->tif_cur_cumulated_mem_alloc ||
|
||||
s > TIFF_TMSIZE_T_MAX - LEADING_AREA_TO_STORE_ALLOC_SIZE)
|
||||
{
|
||||
_TIFFEmitErrorAboveMaxCumulatedMemAlloc(tif, "_TIFFmallocExt", s);
|
||||
return NULL;
|
||||
}
|
||||
void *ptr = _TIFFmalloc(LEADING_AREA_TO_STORE_ALLOC_SIZE + s);
|
||||
if (!ptr)
|
||||
return NULL;
|
||||
tif->tif_cur_cumulated_mem_alloc += s;
|
||||
memcpy(ptr, &s, sizeof(s));
|
||||
return (char *)ptr + LEADING_AREA_TO_STORE_ALLOC_SIZE;
|
||||
}
|
||||
return _TIFFmalloc(s);
|
||||
}
|
||||
|
||||
/** calloc() version that takes into account memory-specific open options */
|
||||
void *_TIFFcallocExt(TIFF *tif, tmsize_t nmemb, tmsize_t siz)
|
||||
{
|
||||
if (nmemb <= 0 || siz <= 0 || nmemb > TIFF_TMSIZE_T_MAX / siz)
|
||||
return NULL;
|
||||
if (tif != NULL && tif->tif_max_single_mem_alloc > 0)
|
||||
{
|
||||
if (nmemb <= 0 || siz <= 0 || nmemb > TIFF_TMSIZE_T_MAX / siz)
|
||||
return NULL;
|
||||
if (nmemb * siz > tif->tif_max_single_mem_alloc)
|
||||
{
|
||||
_TIFFEmitErrorAboveMaxSingleMemAlloc(tif, "_TIFFcallocExt",
|
||||
|
@ -143,6 +202,23 @@ void *_TIFFcallocExt(TIFF *tif, tmsize_t nmemb, tmsize_t siz)
|
|||
return NULL;
|
||||
}
|
||||
}
|
||||
if (tif != NULL && tif->tif_max_cumulated_mem_alloc > 0)
|
||||
{
|
||||
const tmsize_t s = nmemb * siz;
|
||||
if (s > tif->tif_max_cumulated_mem_alloc -
|
||||
tif->tif_cur_cumulated_mem_alloc ||
|
||||
s > TIFF_TMSIZE_T_MAX - LEADING_AREA_TO_STORE_ALLOC_SIZE)
|
||||
{
|
||||
_TIFFEmitErrorAboveMaxCumulatedMemAlloc(tif, "_TIFFcallocExt", s);
|
||||
return NULL;
|
||||
}
|
||||
void *ptr = _TIFFcalloc(LEADING_AREA_TO_STORE_ALLOC_SIZE + s, 1);
|
||||
if (!ptr)
|
||||
return NULL;
|
||||
tif->tif_cur_cumulated_mem_alloc += s;
|
||||
memcpy(ptr, &s, sizeof(s));
|
||||
return (char *)ptr + LEADING_AREA_TO_STORE_ALLOC_SIZE;
|
||||
}
|
||||
return _TIFFcalloc(nmemb, siz);
|
||||
}
|
||||
|
||||
|
@ -155,13 +231,49 @@ void *_TIFFreallocExt(TIFF *tif, void *p, tmsize_t s)
|
|||
_TIFFEmitErrorAboveMaxSingleMemAlloc(tif, "_TIFFreallocExt", s);
|
||||
return NULL;
|
||||
}
|
||||
if (tif != NULL && tif->tif_max_cumulated_mem_alloc > 0)
|
||||
{
|
||||
void *oldPtr = p;
|
||||
tmsize_t oldSize = 0;
|
||||
if (p)
|
||||
{
|
||||
oldPtr = (char *)p - LEADING_AREA_TO_STORE_ALLOC_SIZE;
|
||||
memcpy(&oldSize, oldPtr, sizeof(oldSize));
|
||||
assert(oldSize <= tif->tif_cur_cumulated_mem_alloc);
|
||||
}
|
||||
if (s > oldSize &&
|
||||
(s > tif->tif_max_cumulated_mem_alloc -
|
||||
(tif->tif_cur_cumulated_mem_alloc - oldSize) ||
|
||||
s > TIFF_TMSIZE_T_MAX - LEADING_AREA_TO_STORE_ALLOC_SIZE))
|
||||
{
|
||||
_TIFFEmitErrorAboveMaxCumulatedMemAlloc(tif, "_TIFFreallocExt",
|
||||
s - oldSize);
|
||||
return NULL;
|
||||
}
|
||||
void *newPtr =
|
||||
_TIFFrealloc(oldPtr, LEADING_AREA_TO_STORE_ALLOC_SIZE + s);
|
||||
if (newPtr == NULL)
|
||||
return NULL;
|
||||
tif->tif_cur_cumulated_mem_alloc -= oldSize;
|
||||
tif->tif_cur_cumulated_mem_alloc += s;
|
||||
memcpy(newPtr, &s, sizeof(s));
|
||||
return (char *)newPtr + LEADING_AREA_TO_STORE_ALLOC_SIZE;
|
||||
}
|
||||
return _TIFFrealloc(p, s);
|
||||
}
|
||||
|
||||
/** free() version that takes into account memory-specific open options */
|
||||
void _TIFFfreeExt(TIFF *tif, void *p)
|
||||
{
|
||||
(void)tif;
|
||||
if (p != NULL && tif != NULL && tif->tif_max_cumulated_mem_alloc > 0)
|
||||
{
|
||||
void *oldPtr = (char *)p - LEADING_AREA_TO_STORE_ALLOC_SIZE;
|
||||
tmsize_t oldSize;
|
||||
memcpy(&oldSize, oldPtr, sizeof(oldSize));
|
||||
assert(oldSize <= tif->tif_cur_cumulated_mem_alloc);
|
||||
tif->tif_cur_cumulated_mem_alloc -= oldSize;
|
||||
p = oldPtr;
|
||||
}
|
||||
_TIFFfree(p);
|
||||
}
|
||||
|
||||
|
@ -231,6 +343,17 @@ TIFF *TIFFClientOpenExt(const char *name, const char *mode,
|
|||
(uint64_t)opts->max_single_mem_alloc);
|
||||
goto bad2;
|
||||
}
|
||||
if (opts && opts->max_cumulated_mem_alloc > 0 &&
|
||||
size_to_alloc > opts->max_cumulated_mem_alloc)
|
||||
{
|
||||
_TIFFErrorEarly(opts, clientdata, module,
|
||||
"%s: Memory allocation of %" PRIu64
|
||||
" bytes is beyond the %" PRIu64
|
||||
" cumulated byte limit defined in open options",
|
||||
name, (uint64_t)size_to_alloc,
|
||||
(uint64_t)opts->max_cumulated_mem_alloc);
|
||||
goto bad2;
|
||||
}
|
||||
tif = (TIFF *)_TIFFmallocExt(NULL, size_to_alloc);
|
||||
if (tif == NULL)
|
||||
{
|
||||
|
@ -243,6 +366,7 @@ TIFF *TIFFClientOpenExt(const char *name, const char *mode,
|
|||
strcpy(tif->tif_name, name);
|
||||
tif->tif_mode = m & ~(O_CREAT | O_TRUNC);
|
||||
tif->tif_curdir = TIFF_NON_EXISTENT_DIR_NUMBER; /* non-existent directory */
|
||||
tif->tif_curdircount = TIFF_NON_EXISTENT_DIR_NUMBER;
|
||||
tif->tif_curoff = 0;
|
||||
tif->tif_curstrip = (uint32_t)-1; /* invalid strip */
|
||||
tif->tif_row = (uint32_t)-1; /* read/write pre-increment */
|
||||
|
@ -261,6 +385,7 @@ TIFF *TIFFClientOpenExt(const char *name, const char *mode,
|
|||
tif->tif_warnhandler = opts->warnhandler;
|
||||
tif->tif_warnhandler_user_data = opts->warnhandler_user_data;
|
||||
tif->tif_max_single_mem_alloc = opts->max_single_mem_alloc;
|
||||
tif->tif_max_cumulated_mem_alloc = opts->max_cumulated_mem_alloc;
|
||||
}
|
||||
|
||||
if (!readproc || !writeproc || !seekproc || !closeproc || !sizeproc)
|
||||
|
@ -423,9 +548,9 @@ TIFF *TIFFClientOpenExt(const char *name, const char *mode,
|
|||
TIFFErrorExtR(tif, name, "Cannot read TIFF header");
|
||||
goto bad;
|
||||
}
|
||||
/*
|
||||
* Setup header and write.
|
||||
*/
|
||||
/*
|
||||
* Setup header and write.
|
||||
*/
|
||||
#ifdef WORDS_BIGENDIAN
|
||||
tif->tif_header.common.tiff_magic =
|
||||
(tif->tif_flags & TIFF_SWAB) ? TIFF_LITTLEENDIAN : TIFF_BIGENDIAN;
|
||||
|
@ -433,13 +558,17 @@ TIFF *TIFFClientOpenExt(const char *name, const char *mode,
|
|||
tif->tif_header.common.tiff_magic =
|
||||
(tif->tif_flags & TIFF_SWAB) ? TIFF_BIGENDIAN : TIFF_LITTLEENDIAN;
|
||||
#endif
|
||||
TIFFHeaderUnion tif_header_swapped;
|
||||
if (!(tif->tif_flags & TIFF_BIGTIFF))
|
||||
{
|
||||
tif->tif_header.common.tiff_version = TIFF_VERSION_CLASSIC;
|
||||
tif->tif_header.classic.tiff_diroff = 0;
|
||||
if (tif->tif_flags & TIFF_SWAB)
|
||||
TIFFSwabShort(&tif->tif_header.common.tiff_version);
|
||||
tif->tif_header_size = sizeof(TIFFHeaderClassic);
|
||||
/* Swapped copy for writing */
|
||||
_TIFFmemcpy(&tif_header_swapped, &tif->tif_header,
|
||||
sizeof(TIFFHeaderUnion));
|
||||
if (tif->tif_flags & TIFF_SWAB)
|
||||
TIFFSwabShort(&tif_header_swapped.common.tiff_version);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -447,12 +576,15 @@ TIFF *TIFFClientOpenExt(const char *name, const char *mode,
|
|||
tif->tif_header.big.tiff_offsetsize = 8;
|
||||
tif->tif_header.big.tiff_unused = 0;
|
||||
tif->tif_header.big.tiff_diroff = 0;
|
||||
tif->tif_header_size = sizeof(TIFFHeaderBig);
|
||||
/* Swapped copy for writing */
|
||||
_TIFFmemcpy(&tif_header_swapped, &tif->tif_header,
|
||||
sizeof(TIFFHeaderUnion));
|
||||
if (tif->tif_flags & TIFF_SWAB)
|
||||
{
|
||||
TIFFSwabShort(&tif->tif_header.common.tiff_version);
|
||||
TIFFSwabShort(&tif->tif_header.big.tiff_offsetsize);
|
||||
TIFFSwabShort(&tif_header_swapped.common.tiff_version);
|
||||
TIFFSwabShort(&tif_header_swapped.big.tiff_offsetsize);
|
||||
}
|
||||
tif->tif_header_size = sizeof(TIFFHeaderBig);
|
||||
}
|
||||
/*
|
||||
* The doc for "fopen" for some STD_C_LIBs says that if you
|
||||
|
@ -462,26 +594,12 @@ TIFF *TIFFClientOpenExt(const char *name, const char *mode,
|
|||
* on Solaris.
|
||||
*/
|
||||
TIFFSeekFile(tif, 0, SEEK_SET);
|
||||
if (!WriteOK(tif, &tif->tif_header, (tmsize_t)(tif->tif_header_size)))
|
||||
if (!WriteOK(tif, &tif_header_swapped,
|
||||
(tmsize_t)(tif->tif_header_size)))
|
||||
{
|
||||
TIFFErrorExtR(tif, name, "Error writing TIFF header");
|
||||
goto bad;
|
||||
}
|
||||
/*
|
||||
* Setup the byte order handling.
|
||||
*/
|
||||
if (tif->tif_header.common.tiff_magic == TIFF_BIGENDIAN)
|
||||
{
|
||||
#ifndef WORDS_BIGENDIAN
|
||||
tif->tif_flags |= TIFF_SWAB;
|
||||
#endif
|
||||
}
|
||||
else
|
||||
{
|
||||
#ifdef WORDS_BIGENDIAN
|
||||
tif->tif_flags |= TIFF_SWAB;
|
||||
#endif
|
||||
}
|
||||
/*
|
||||
* Setup default directory.
|
||||
*/
|
||||
|
@ -490,10 +608,14 @@ TIFF *TIFFClientOpenExt(const char *name, const char *mode,
|
|||
tif->tif_diroff = 0;
|
||||
tif->tif_lastdiroff = 0;
|
||||
tif->tif_setdirectory_force_absolute = FALSE;
|
||||
/* tif_curdircount = 0 means 'empty file opened for writing, but no IFD
|
||||
* written yet' */
|
||||
tif->tif_curdircount = 0;
|
||||
return (tif);
|
||||
}
|
||||
|
||||
/*
|
||||
* Setup the byte order handling.
|
||||
* Setup the byte order handling according to the opened file for reading.
|
||||
*/
|
||||
if (tif->tif_header.common.tiff_magic != TIFF_BIGENDIAN &&
|
||||
tif->tif_header.common.tiff_magic != TIFF_LITTLEENDIAN
|
||||
|
@ -619,9 +741,17 @@ TIFF *TIFFClientOpenExt(const char *name, const char *mode,
|
|||
* example, it may be broken) and want to proceed to other
|
||||
* directories. I this case we use the TIFF_HEADERONLY flag to open
|
||||
* file and return immediately after reading TIFF header.
|
||||
* However, the pointer to TIFFSetField() and TIFFGetField()
|
||||
* (i.e. tif->tif_tagmethods.vsetfield and
|
||||
* tif->tif_tagmethods.vgetfield) need to be initialized, which is
|
||||
* done in TIFFDefaultDirectory().
|
||||
*/
|
||||
if (tif->tif_flags & TIFF_HEADERONLY)
|
||||
{
|
||||
if (!TIFFDefaultDirectory(tif))
|
||||
goto bad;
|
||||
return (tif);
|
||||
}
|
||||
|
||||
/*
|
||||
* Setup initial directory.
|
||||
|
@ -764,10 +894,7 @@ int 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);
|
||||
}
|
||||
int TIFFIsBigTIFF(TIFF *tif) { return ((tif->tif_flags & TIFF_BIGTIFF) != 0); }
|
||||
|
||||
/*
|
||||
* Return pointer to file read method.
|
||||
|
|
|
@ -300,6 +300,7 @@ static int PackBitsDecode(TIFF *tif, uint8_t *op, tmsize_t occ, uint16_t s)
|
|||
tif->tif_rawcc = cc;
|
||||
if (occ > 0)
|
||||
{
|
||||
memset(op, 0, (size_t)occ);
|
||||
TIFFErrorExtR(tif, module, "Not enough data for scanline %" PRIu32,
|
||||
tif->tif_row);
|
||||
return (0);
|
||||
|
|
|
@ -670,8 +670,8 @@ static int PixarLogMakeTables(TIFF *tif, PixarLogState *sp)
|
|||
return 1;
|
||||
}
|
||||
|
||||
#define DecoderState(tif) ((PixarLogState *)(tif)->tif_data)
|
||||
#define EncoderState(tif) ((PixarLogState *)(tif)->tif_data)
|
||||
#define PixarLogDecoderState(tif) ((PixarLogState *)(tif)->tif_data)
|
||||
#define PixarLogEncoderState(tif) ((PixarLogState *)(tif)->tif_data)
|
||||
|
||||
static int PixarLogEncode(TIFF *tif, uint8_t *bp, tmsize_t cc, uint16_t s);
|
||||
static int PixarLogDecode(TIFF *tif, uint8_t *op, tmsize_t occ, uint16_t s);
|
||||
|
@ -740,7 +740,7 @@ static int PixarLogSetupDecode(TIFF *tif)
|
|||
{
|
||||
static const char module[] = "PixarLogSetupDecode";
|
||||
TIFFDirectory *td = &tif->tif_dir;
|
||||
PixarLogState *sp = DecoderState(tif);
|
||||
PixarLogState *sp = PixarLogDecoderState(tif);
|
||||
tmsize_t tbuf_size;
|
||||
uint32_t strip_height;
|
||||
|
||||
|
@ -813,7 +813,7 @@ static int PixarLogSetupDecode(TIFF *tif)
|
|||
static int PixarLogPreDecode(TIFF *tif, uint16_t s)
|
||||
{
|
||||
static const char module[] = "PixarLogPreDecode";
|
||||
PixarLogState *sp = DecoderState(tif);
|
||||
PixarLogState *sp = PixarLogDecoderState(tif);
|
||||
|
||||
(void)s;
|
||||
assert(sp != NULL);
|
||||
|
@ -835,7 +835,7 @@ static int PixarLogDecode(TIFF *tif, uint8_t *op, tmsize_t occ, uint16_t s)
|
|||
{
|
||||
static const char module[] = "PixarLogDecode";
|
||||
TIFFDirectory *td = &tif->tif_dir;
|
||||
PixarLogState *sp = DecoderState(tif);
|
||||
PixarLogState *sp = PixarLogDecoderState(tif);
|
||||
tmsize_t i;
|
||||
tmsize_t nsamples;
|
||||
int llen;
|
||||
|
@ -859,6 +859,7 @@ static int PixarLogDecode(TIFF *tif, uint8_t *op, tmsize_t occ, uint16_t s)
|
|||
TIFFErrorExtR(tif, module,
|
||||
"%" PRIu16 " bit input not supported in PixarLog",
|
||||
td->td_bitspersample);
|
||||
memset(op, 0, (size_t)occ);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -879,12 +880,14 @@ static int PixarLogDecode(TIFF *tif, uint8_t *op, tmsize_t occ, uint16_t s)
|
|||
if (sp->stream.avail_out != nsamples * sizeof(uint16_t))
|
||||
{
|
||||
TIFFErrorExtR(tif, module, "ZLib cannot deal with buffers this size");
|
||||
memset(op, 0, (size_t)occ);
|
||||
return (0);
|
||||
}
|
||||
/* Check that we will not fill more than what was allocated */
|
||||
if ((tmsize_t)sp->stream.avail_out > sp->tbuf_size)
|
||||
{
|
||||
TIFFErrorExtR(tif, module, "sp->stream.avail_out > sp->tbuf_size");
|
||||
memset(op, 0, (size_t)occ);
|
||||
return (0);
|
||||
}
|
||||
do
|
||||
|
@ -899,12 +902,14 @@ static int PixarLogDecode(TIFF *tif, uint8_t *op, tmsize_t occ, uint16_t s)
|
|||
TIFFErrorExtR(
|
||||
tif, module, "Decoding error at scanline %" PRIu32 ", %s",
|
||||
tif->tif_row, sp->stream.msg ? sp->stream.msg : "(null)");
|
||||
memset(op, 0, (size_t)occ);
|
||||
return (0);
|
||||
}
|
||||
if (state != Z_OK)
|
||||
{
|
||||
TIFFErrorExtR(tif, module, "ZLib error: %s",
|
||||
sp->stream.msg ? sp->stream.msg : "(null)");
|
||||
memset(op, 0, (size_t)occ);
|
||||
return (0);
|
||||
}
|
||||
} while (sp->stream.avail_out > 0);
|
||||
|
@ -916,6 +921,7 @@ static int PixarLogDecode(TIFF *tif, uint8_t *op, tmsize_t occ, uint16_t s)
|
|||
"Not enough data at scanline %" PRIu32
|
||||
" (short %u bytes)",
|
||||
tif->tif_row, sp->stream.avail_out);
|
||||
memset(op, 0, (size_t)occ);
|
||||
return (0);
|
||||
}
|
||||
|
||||
|
@ -977,6 +983,7 @@ static int PixarLogDecode(TIFF *tif, uint8_t *op, tmsize_t occ, uint16_t s)
|
|||
default:
|
||||
TIFFErrorExtR(tif, module, "Unsupported bits/sample: %" PRIu16,
|
||||
td->td_bitspersample);
|
||||
memset(op, 0, (size_t)occ);
|
||||
return (0);
|
||||
}
|
||||
}
|
||||
|
@ -988,7 +995,7 @@ static int PixarLogSetupEncode(TIFF *tif)
|
|||
{
|
||||
static const char module[] = "PixarLogSetupEncode";
|
||||
TIFFDirectory *td = &tif->tif_dir;
|
||||
PixarLogState *sp = EncoderState(tif);
|
||||
PixarLogState *sp = PixarLogEncoderState(tif);
|
||||
tmsize_t tbuf_size;
|
||||
|
||||
assert(sp != NULL);
|
||||
|
@ -1038,7 +1045,7 @@ static int PixarLogSetupEncode(TIFF *tif)
|
|||
static int PixarLogPreEncode(TIFF *tif, uint16_t s)
|
||||
{
|
||||
static const char module[] = "PixarLogPreEncode";
|
||||
PixarLogState *sp = EncoderState(tif);
|
||||
PixarLogState *sp = PixarLogEncoderState(tif);
|
||||
|
||||
(void)s;
|
||||
assert(sp != NULL);
|
||||
|
@ -1294,7 +1301,7 @@ static int PixarLogEncode(TIFF *tif, uint8_t *bp, tmsize_t cc, uint16_t s)
|
|||
{
|
||||
static const char module[] = "PixarLogEncode";
|
||||
TIFFDirectory *td = &tif->tif_dir;
|
||||
PixarLogState *sp = EncoderState(tif);
|
||||
PixarLogState *sp = PixarLogEncoderState(tif);
|
||||
tmsize_t i;
|
||||
tmsize_t n;
|
||||
int llen;
|
||||
|
@ -1401,7 +1408,7 @@ static int PixarLogEncode(TIFF *tif, uint8_t *bp, tmsize_t cc, uint16_t s)
|
|||
static int PixarLogPostEncode(TIFF *tif)
|
||||
{
|
||||
static const char module[] = "PixarLogPostEncode";
|
||||
PixarLogState *sp = EncoderState(tif);
|
||||
PixarLogState *sp = PixarLogEncoderState(tif);
|
||||
int state;
|
||||
|
||||
sp->stream.avail_in = 0;
|
||||
|
|
|
@ -105,8 +105,8 @@ static int TIFFReadAndRealloc(TIFF *tif, tmsize_t size, tmsize_t rawdata_offset,
|
|||
TIFFErrorExtR(tif, module, "Invalid buffer size");
|
||||
return 0;
|
||||
}
|
||||
new_rawdata =
|
||||
(uint8_t *)_TIFFrealloc(tif->tif_rawdata, tif->tif_rawdatasize);
|
||||
new_rawdata = (uint8_t *)_TIFFreallocExt(tif, tif->tif_rawdata,
|
||||
tif->tif_rawdatasize);
|
||||
if (new_rawdata == 0)
|
||||
{
|
||||
TIFFErrorExtR(tif, module,
|
||||
|
@ -464,6 +464,10 @@ int TIFFReadScanline(TIFF *tif, void *buf, uint32_t row, uint16_t sample)
|
|||
if (e)
|
||||
(*tif->tif_postdecode)(tif, (uint8_t *)buf, tif->tif_scanlinesize);
|
||||
}
|
||||
else
|
||||
{
|
||||
memset(buf, 0, (size_t)tif->tif_scanlinesize);
|
||||
}
|
||||
return (e > 0 ? 1 : -1);
|
||||
}
|
||||
|
||||
|
@ -495,6 +499,11 @@ static tmsize_t TIFFReadEncodedStripGetStripSize(TIFF *tif, uint32_t strip,
|
|||
rowsperstrip = td->td_rowsperstrip;
|
||||
if (rowsperstrip > td->td_imagelength)
|
||||
rowsperstrip = td->td_imagelength;
|
||||
if (rowsperstrip == 0)
|
||||
{
|
||||
TIFFErrorExtR(tif, module, "rowsperstrip is zero");
|
||||
return ((tmsize_t)(-1));
|
||||
}
|
||||
stripsperplane =
|
||||
TIFFhowmany_32_maxuint_compat(td->td_imagelength, rowsperstrip);
|
||||
stripinplane = (strip % stripsperplane);
|
||||
|
@ -544,7 +553,10 @@ tmsize_t TIFFReadEncodedStrip(TIFF *tif, uint32_t strip, void *buf,
|
|||
if ((size != (tmsize_t)(-1)) && (size < stripsize))
|
||||
stripsize = size;
|
||||
if (!TIFFFillStrip(tif, strip))
|
||||
{
|
||||
memset(buf, 0, (size_t)stripsize);
|
||||
return ((tmsize_t)(-1));
|
||||
}
|
||||
if ((*tif->tif_decodestrip)(tif, buf, stripsize, plane) <= 0)
|
||||
return ((tmsize_t)(-1));
|
||||
(*tif->tif_postdecode)(tif, buf, stripsize);
|
||||
|
@ -962,9 +974,13 @@ tmsize_t TIFFReadEncodedTile(TIFF *tif, uint32_t tile, void *buf, tmsize_t size)
|
|||
size = tilesize;
|
||||
else if (size > tilesize)
|
||||
size = tilesize;
|
||||
if (TIFFFillTile(tif, tile) &&
|
||||
(*tif->tif_decodetile)(tif, (uint8_t *)buf, size,
|
||||
(uint16_t)(tile / td->td_stripsperimage)))
|
||||
if (!TIFFFillTile(tif, tile))
|
||||
{
|
||||
memset(buf, 0, (size_t)size);
|
||||
return ((tmsize_t)(-1));
|
||||
}
|
||||
else if ((*tif->tif_decodetile)(tif, (uint8_t *)buf, size,
|
||||
(uint16_t)(tile / td->td_stripsperimage)))
|
||||
{
|
||||
(*tif->tif_postdecode)(tif, (uint8_t *)buf, size);
|
||||
return (size);
|
||||
|
@ -1449,6 +1465,11 @@ static int TIFFStartTile(TIFF *tif, uint32_t tile)
|
|||
tif->tif_flags |= TIFF_CODERSETUP;
|
||||
}
|
||||
tif->tif_curtile = tile;
|
||||
if (td->td_tilewidth == 0)
|
||||
{
|
||||
TIFFErrorExtR(tif, module, "Zero tilewidth");
|
||||
return 0;
|
||||
}
|
||||
howmany32 = TIFFhowmany_32(td->td_imagewidth, td->td_tilewidth);
|
||||
if (howmany32 == 0)
|
||||
{
|
||||
|
@ -1545,9 +1566,14 @@ int TIFFReadFromUserBuffer(TIFF *tif, uint32_t strile, void *inbuf,
|
|||
|
||||
if (TIFFIsTiled(tif))
|
||||
{
|
||||
if (!TIFFStartTile(tif, strile) ||
|
||||
!(*tif->tif_decodetile)(tif, (uint8_t *)outbuf, outsize,
|
||||
(uint16_t)(strile / td->td_stripsperimage)))
|
||||
if (!TIFFStartTile(tif, strile))
|
||||
{
|
||||
ret = 0;
|
||||
memset(outbuf, 0, (size_t)outsize);
|
||||
}
|
||||
else if (!(*tif->tif_decodetile)(
|
||||
tif, (uint8_t *)outbuf, outsize,
|
||||
(uint16_t)(strile / td->td_stripsperimage)))
|
||||
{
|
||||
ret = 0;
|
||||
}
|
||||
|
@ -1558,14 +1584,27 @@ int TIFFReadFromUserBuffer(TIFF *tif, uint32_t strile, void *inbuf,
|
|||
uint32_t stripsperplane;
|
||||
if (rowsperstrip > td->td_imagelength)
|
||||
rowsperstrip = td->td_imagelength;
|
||||
stripsperplane =
|
||||
TIFFhowmany_32_maxuint_compat(td->td_imagelength, rowsperstrip);
|
||||
if (!TIFFStartStrip(tif, strile) ||
|
||||
!(*tif->tif_decodestrip)(tif, (uint8_t *)outbuf, outsize,
|
||||
(uint16_t)(strile / stripsperplane)))
|
||||
if (rowsperstrip == 0)
|
||||
{
|
||||
TIFFErrorExtR(tif, module, "rowsperstrip is zero");
|
||||
ret = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
stripsperplane =
|
||||
TIFFhowmany_32_maxuint_compat(td->td_imagelength, rowsperstrip);
|
||||
if (!TIFFStartStrip(tif, strile))
|
||||
{
|
||||
ret = 0;
|
||||
memset(outbuf, 0, (size_t)outsize);
|
||||
}
|
||||
else if (!(*tif->tif_decodestrip)(
|
||||
tif, (uint8_t *)outbuf, outsize,
|
||||
(uint16_t)(strile / stripsperplane)))
|
||||
{
|
||||
ret = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (ret)
|
||||
{
|
||||
|
|
|
@ -38,6 +38,11 @@ uint32_t TIFFComputeStrip(TIFF *tif, uint32_t row, uint16_t sample)
|
|||
TIFFDirectory *td = &tif->tif_dir;
|
||||
uint32_t strip;
|
||||
|
||||
if (td->td_rowsperstrip == 0)
|
||||
{
|
||||
TIFFErrorExtR(tif, module, "Cannot compute strip: RowsPerStrip is zero");
|
||||
return 0;
|
||||
}
|
||||
strip = row / td->td_rowsperstrip;
|
||||
if (td->td_planarconfig == PLANARCONFIG_SEPARATE)
|
||||
{
|
||||
|
@ -61,6 +66,11 @@ uint32_t TIFFNumberOfStrips(TIFF *tif)
|
|||
TIFFDirectory *td = &tif->tif_dir;
|
||||
uint32_t nstrips;
|
||||
|
||||
if (td->td_rowsperstrip == 0)
|
||||
{
|
||||
TIFFWarningExtR(tif, "TIFFNumberOfStrips", "RowsPerStrip is zero");
|
||||
return 0;
|
||||
}
|
||||
nstrips = (td->td_rowsperstrip == (uint32_t)-1
|
||||
? 1
|
||||
: TIFFhowmany_32(td->td_imagelength, td->td_rowsperstrip));
|
||||
|
@ -107,7 +117,8 @@ uint64_t TIFFVStripSize64(TIFF *tif, uint32_t nrows)
|
|||
if ((ycbcrsubsampling[0] != 1 && ycbcrsubsampling[0] != 2 &&
|
||||
ycbcrsubsampling[0] != 4) ||
|
||||
(ycbcrsubsampling[1] != 1 && ycbcrsubsampling[1] != 2 &&
|
||||
ycbcrsubsampling[1] != 4))
|
||||
ycbcrsubsampling[1] != 4) ||
|
||||
(ycbcrsubsampling[0] == 0 || ycbcrsubsampling[1] == 0))
|
||||
{
|
||||
TIFFErrorExtR(tif, module, "Invalid YCbCr subsampling (%dx%d)",
|
||||
ycbcrsubsampling[0], ycbcrsubsampling[1]);
|
||||
|
@ -267,7 +278,8 @@ uint64_t TIFFScanlineSize64(TIFF *tif)
|
|||
if (((ycbcrsubsampling[0] != 1) && (ycbcrsubsampling[0] != 2) &&
|
||||
(ycbcrsubsampling[0] != 4)) ||
|
||||
((ycbcrsubsampling[1] != 1) && (ycbcrsubsampling[1] != 2) &&
|
||||
(ycbcrsubsampling[1] != 4)))
|
||||
(ycbcrsubsampling[1] != 4)) ||
|
||||
((ycbcrsubsampling[0] == 0) || (ycbcrsubsampling[1] == 0)))
|
||||
{
|
||||
TIFFErrorExtR(tif, module, "Invalid YCbCr subsampling");
|
||||
return 0;
|
||||
|
@ -287,7 +299,25 @@ uint64_t TIFFScanlineSize64(TIFF *tif)
|
|||
else
|
||||
{
|
||||
uint64_t scanline_samples;
|
||||
scanline_samples = _TIFFMultiply64(tif, td->td_imagewidth,
|
||||
uint32_t scanline_width = td->td_imagewidth;
|
||||
|
||||
#if 0
|
||||
// Tries to fix https://gitlab.com/libtiff/libtiff/-/merge_requests/564
|
||||
// but causes regression when decoding legit files with tiffcp -c none
|
||||
// Cf https://gitlab.com/libtiff/libtiff/-/merge_requests/644
|
||||
if (td->td_photometric == PHOTOMETRIC_YCBCR)
|
||||
{
|
||||
uint16_t subsampling_hor;
|
||||
uint16_t ignored;
|
||||
TIFFGetFieldDefaulted(tif, TIFFTAG_YCBCRSUBSAMPLING,
|
||||
&subsampling_hor, &ignored);
|
||||
if (subsampling_hor > 1) // roundup width for YCbCr
|
||||
scanline_width =
|
||||
TIFFroundup_32(scanline_width, subsampling_hor);
|
||||
}
|
||||
#endif
|
||||
|
||||
scanline_samples = _TIFFMultiply64(tif, scanline_width,
|
||||
td->td_samplesperpixel, module);
|
||||
scanline_size =
|
||||
TIFFhowmany_64(_TIFFMultiply64(tif, scanline_samples,
|
||||
|
|
|
@ -82,13 +82,14 @@ static int ThunderSetupDecode(TIFF *tif)
|
|||
return (1);
|
||||
}
|
||||
|
||||
static int ThunderDecode(TIFF *tif, uint8_t *op, tmsize_t maxpixels)
|
||||
static int ThunderDecode(TIFF *tif, uint8_t *op0, tmsize_t maxpixels)
|
||||
{
|
||||
static const char module[] = "ThunderDecode";
|
||||
register unsigned char *bp;
|
||||
register tmsize_t cc;
|
||||
unsigned int lastpixel;
|
||||
tmsize_t npixels;
|
||||
uint8_t *op = op0;
|
||||
|
||||
bp = (unsigned char *)tif->tif_rawcp;
|
||||
cc = tif->tif_rawcc;
|
||||
|
@ -107,6 +108,8 @@ static int ThunderDecode(TIFF *tif, uint8_t *op, tmsize_t maxpixels)
|
|||
* Replicate the last pixel n times,
|
||||
* where n is the lower-order 6 bits.
|
||||
*/
|
||||
if (n == 0)
|
||||
break;
|
||||
if (npixels & 1)
|
||||
{
|
||||
op[0] |= lastpixel;
|
||||
|
@ -117,11 +120,10 @@ static int ThunderDecode(TIFF *tif, uint8_t *op, tmsize_t maxpixels)
|
|||
else
|
||||
lastpixel |= lastpixel << 4;
|
||||
npixels += n;
|
||||
if (npixels < maxpixels)
|
||||
{
|
||||
for (; n > 0; n -= 2)
|
||||
*op++ = (uint8_t)lastpixel;
|
||||
}
|
||||
if (npixels > maxpixels)
|
||||
break;
|
||||
for (; n > 0; n -= 2)
|
||||
*op++ = (uint8_t)lastpixel;
|
||||
if (n == -1)
|
||||
*--op &= 0xf0;
|
||||
lastpixel &= 0xf;
|
||||
|
@ -154,6 +156,8 @@ static int ThunderDecode(TIFF *tif, uint8_t *op, tmsize_t maxpixels)
|
|||
tif->tif_rawcc = cc;
|
||||
if (npixels != maxpixels)
|
||||
{
|
||||
uint8_t *op_end = op0 + (maxpixels + 1) / 2;
|
||||
memset(op, 0, (size_t)(op_end - op));
|
||||
TIFFErrorExtR(tif, module,
|
||||
"%s data at scanline %lu (%" PRIu64 " != %" PRIu64 ")",
|
||||
npixels < maxpixels ? "Not enough" : "Too much",
|
||||
|
|
|
@ -27,6 +27,10 @@
|
|||
* Scott Wagner (wagner@itek.com), Itek Graphix, Rochester, NY USA
|
||||
*/
|
||||
|
||||
#ifdef TIFF_DO_NOT_USE_NON_EXT_ALLOC_FUNCTIONS
|
||||
#undef TIFF_DO_NOT_USE_NON_EXT_ALLOC_FUNCTIONS
|
||||
#endif
|
||||
|
||||
#include "tiffiop.h"
|
||||
#include <stdlib.h>
|
||||
|
||||
|
|
|
@ -67,6 +67,8 @@ typedef struct
|
|||
{
|
||||
TIFFPredictorState predict;
|
||||
z_stream stream;
|
||||
int read_error; /* whether a read error has occurred, and which should cause
|
||||
further reads in the same strip/tile to be aborted */
|
||||
int zipquality; /* compression level */
|
||||
int state; /* state flags */
|
||||
int subcodec; /* DEFLATE_SUBCODEC_ZLIB or DEFLATE_SUBCODEC_LIBDEFLATE */
|
||||
|
@ -83,9 +85,9 @@ typedef struct
|
|||
TIFFVSetMethod vsetparent; /* super-class method */
|
||||
} ZIPState;
|
||||
|
||||
#define ZState(tif) ((ZIPState *)(tif)->tif_data)
|
||||
#define DecoderState(tif) ZState(tif)
|
||||
#define EncoderState(tif) ZState(tif)
|
||||
#define GetZIPState(tif) ((ZIPState *)(tif)->tif_data)
|
||||
#define ZIPDecoderState(tif) GetZIPState(tif)
|
||||
#define ZIPEncoderState(tif) GetZIPState(tif)
|
||||
|
||||
static int ZIPEncode(TIFF *tif, uint8_t *bp, tmsize_t cc, uint16_t s);
|
||||
static int ZIPDecode(TIFF *tif, uint8_t *op, tmsize_t occ, uint16_t s);
|
||||
|
@ -99,7 +101,7 @@ static int ZIPFixupTags(TIFF *tif)
|
|||
static int ZIPSetupDecode(TIFF *tif)
|
||||
{
|
||||
static const char module[] = "ZIPSetupDecode";
|
||||
ZIPState *sp = DecoderState(tif);
|
||||
ZIPState *sp = ZIPDecoderState(tif);
|
||||
|
||||
assert(sp != NULL);
|
||||
|
||||
|
@ -131,7 +133,7 @@ static int ZIPSetupDecode(TIFF *tif)
|
|||
*/
|
||||
static int ZIPPreDecode(TIFF *tif, uint16_t s)
|
||||
{
|
||||
ZIPState *sp = DecoderState(tif);
|
||||
ZIPState *sp = ZIPDecoderState(tif);
|
||||
|
||||
(void)s;
|
||||
assert(sp != NULL);
|
||||
|
@ -150,18 +152,33 @@ static int ZIPPreDecode(TIFF *tif, uint16_t s)
|
|||
sp->stream.avail_in = (uint64_t)tif->tif_rawcc < 0xFFFFFFFFU
|
||||
? (uInt)tif->tif_rawcc
|
||||
: 0xFFFFFFFFU;
|
||||
return (inflateReset(&sp->stream) == Z_OK);
|
||||
if (inflateReset(&sp->stream) == Z_OK)
|
||||
{
|
||||
sp->read_error = 0;
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int ZIPDecode(TIFF *tif, uint8_t *op, tmsize_t occ, uint16_t s)
|
||||
{
|
||||
static const char module[] = "ZIPDecode";
|
||||
ZIPState *sp = DecoderState(tif);
|
||||
ZIPState *sp = ZIPDecoderState(tif);
|
||||
|
||||
(void)s;
|
||||
assert(sp != NULL);
|
||||
assert(sp->state == ZSTATE_INIT_DECODE);
|
||||
|
||||
if (sp->read_error)
|
||||
{
|
||||
memset(op, 0, (size_t)occ);
|
||||
TIFFErrorExtR(tif, module,
|
||||
"ZIPDecode: Scanline %" PRIu32 " cannot be read due to "
|
||||
"previous error",
|
||||
tif->tif_row);
|
||||
return 0;
|
||||
}
|
||||
|
||||
#if LIBDEFLATE_SUPPORT
|
||||
if (sp->libdeflate_state == 1)
|
||||
return 0;
|
||||
|
@ -227,8 +244,10 @@ static int ZIPDecode(TIFF *tif, uint8_t *op, tmsize_t occ, uint16_t s)
|
|||
if (res != LIBDEFLATE_SUCCESS &&
|
||||
res != LIBDEFLATE_INSUFFICIENT_SPACE)
|
||||
{
|
||||
memset(op, 0, (size_t)occ);
|
||||
TIFFErrorExtR(tif, module, "Decoding error at scanline %lu",
|
||||
(unsigned long)tif->tif_row);
|
||||
sp->read_error = 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -263,13 +282,17 @@ static int ZIPDecode(TIFF *tif, uint8_t *op, tmsize_t occ, uint16_t s)
|
|||
break;
|
||||
if (state == Z_DATA_ERROR)
|
||||
{
|
||||
memset(sp->stream.next_out, 0, sp->stream.avail_out);
|
||||
TIFFErrorExtR(tif, module, "Decoding error at scanline %lu, %s",
|
||||
(unsigned long)tif->tif_row, SAFE_MSG(sp));
|
||||
sp->read_error = 1;
|
||||
return (0);
|
||||
}
|
||||
if (state != Z_OK)
|
||||
{
|
||||
memset(sp->stream.next_out, 0, sp->stream.avail_out);
|
||||
TIFFErrorExtR(tif, module, "ZLib error: %s", SAFE_MSG(sp));
|
||||
sp->read_error = 1;
|
||||
return (0);
|
||||
}
|
||||
} while (occ > 0);
|
||||
|
@ -279,6 +302,8 @@ static int ZIPDecode(TIFF *tif, uint8_t *op, tmsize_t occ, uint16_t s)
|
|||
"Not enough data at scanline %lu (short %" PRIu64
|
||||
" bytes)",
|
||||
(unsigned long)tif->tif_row, (uint64_t)occ);
|
||||
memset(sp->stream.next_out, 0, sp->stream.avail_out);
|
||||
sp->read_error = 1;
|
||||
return (0);
|
||||
}
|
||||
|
||||
|
@ -290,7 +315,7 @@ static int ZIPDecode(TIFF *tif, uint8_t *op, tmsize_t occ, uint16_t s)
|
|||
static int ZIPSetupEncode(TIFF *tif)
|
||||
{
|
||||
static const char module[] = "ZIPSetupEncode";
|
||||
ZIPState *sp = EncoderState(tif);
|
||||
ZIPState *sp = ZIPEncoderState(tif);
|
||||
int cappedQuality;
|
||||
|
||||
assert(sp != NULL);
|
||||
|
@ -321,7 +346,7 @@ static int ZIPSetupEncode(TIFF *tif)
|
|||
*/
|
||||
static int ZIPPreEncode(TIFF *tif, uint16_t s)
|
||||
{
|
||||
ZIPState *sp = EncoderState(tif);
|
||||
ZIPState *sp = ZIPEncoderState(tif);
|
||||
|
||||
(void)s;
|
||||
assert(sp != NULL);
|
||||
|
@ -348,7 +373,7 @@ static int ZIPPreEncode(TIFF *tif, uint16_t s)
|
|||
static int ZIPEncode(TIFF *tif, uint8_t *bp, tmsize_t cc, uint16_t s)
|
||||
{
|
||||
static const char module[] = "ZIPEncode";
|
||||
ZIPState *sp = EncoderState(tif);
|
||||
ZIPState *sp = ZIPEncoderState(tif);
|
||||
|
||||
assert(sp != NULL);
|
||||
assert(sp->state == ZSTATE_INIT_ENCODE);
|
||||
|
@ -487,7 +512,7 @@ static int ZIPEncode(TIFF *tif, uint8_t *bp, tmsize_t cc, uint16_t s)
|
|||
static int ZIPPostEncode(TIFF *tif)
|
||||
{
|
||||
static const char module[] = "ZIPPostEncode";
|
||||
ZIPState *sp = EncoderState(tif);
|
||||
ZIPState *sp = ZIPEncoderState(tif);
|
||||
int state;
|
||||
|
||||
#if LIBDEFLATE_SUPPORT
|
||||
|
@ -526,7 +551,7 @@ static int ZIPPostEncode(TIFF *tif)
|
|||
|
||||
static void ZIPCleanup(TIFF *tif)
|
||||
{
|
||||
ZIPState *sp = ZState(tif);
|
||||
ZIPState *sp = GetZIPState(tif);
|
||||
|
||||
assert(sp != 0);
|
||||
|
||||
|
@ -562,7 +587,7 @@ static void ZIPCleanup(TIFF *tif)
|
|||
static int ZIPVSetField(TIFF *tif, uint32_t tag, va_list ap)
|
||||
{
|
||||
static const char module[] = "ZIPVSetField";
|
||||
ZIPState *sp = ZState(tif);
|
||||
ZIPState *sp = GetZIPState(tif);
|
||||
|
||||
switch (tag)
|
||||
{
|
||||
|
@ -628,7 +653,7 @@ static int ZIPVSetField(TIFF *tif, uint32_t tag, va_list ap)
|
|||
|
||||
static int ZIPVGetField(TIFF *tif, uint32_t tag, va_list ap)
|
||||
{
|
||||
ZIPState *sp = ZState(tif);
|
||||
ZIPState *sp = GetZIPState(tif);
|
||||
|
||||
switch (tag)
|
||||
{
|
||||
|
@ -680,7 +705,7 @@ int TIFFInitZIP(TIFF *tif, int scheme)
|
|||
tif->tif_data = (uint8_t *)_TIFFcallocExt(tif, sizeof(ZIPState), 1);
|
||||
if (tif->tif_data == NULL)
|
||||
goto bad;
|
||||
sp = ZState(tif);
|
||||
sp = GetZIPState(tif);
|
||||
sp->stream.zalloc = NULL;
|
||||
sp->stream.zfree = NULL;
|
||||
sp->stream.opaque = NULL;
|
||||
|
|
|
@ -77,10 +77,6 @@ typedef tstrile_t ttile_t; /* tile number */
|
|||
typedef tmsize_t tsize_t; /* i/o size in bytes */
|
||||
typedef void *tdata_t; /* image data ref */
|
||||
|
||||
#if !defined(__WIN32__) && (defined(_WIN32) || defined(WIN32))
|
||||
#define __WIN32__
|
||||
#endif
|
||||
|
||||
/*
|
||||
* On windows you should define USE_WIN32_FILEIO if you are using tif_win32.c
|
||||
* or AVOID_WIN32_FILEIO if you are using something else (like tif_unix.c).
|
||||
|
@ -88,7 +84,7 @@ typedef void *tdata_t; /* image data ref */
|
|||
* By default tif_unix.c is assumed.
|
||||
*/
|
||||
|
||||
#if defined(_WINDOWS) || defined(__WIN32__) || defined(_Windows)
|
||||
#if defined(_WIN32)
|
||||
#if !defined(__CYGWIN) && !defined(AVOID_WIN32_FILEIO) && \
|
||||
!defined(USE_WIN32_FILEIO)
|
||||
#define AVOID_WIN32_FILEIO
|
||||
|
@ -98,11 +94,11 @@ typedef void *tdata_t; /* image data ref */
|
|||
#if defined(USE_WIN32_FILEIO)
|
||||
#define VC_EXTRALEAN
|
||||
#include <windows.h>
|
||||
#ifdef __WIN32__
|
||||
#ifdef _WIN32
|
||||
DECLARE_HANDLE(thandle_t); /* Win32 file handle */
|
||||
#else
|
||||
typedef HFILE thandle_t; /* client data handle */
|
||||
#endif /* __WIN32__ */
|
||||
#endif /* _WIN32 */
|
||||
#else
|
||||
typedef void *thandle_t; /* client data handle */
|
||||
#endif /* USE_WIN32_FILEIO */
|
||||
|
@ -311,14 +307,15 @@ extern "C"
|
|||
/*
|
||||
* Auxiliary functions.
|
||||
*/
|
||||
|
||||
#ifndef TIFF_DO_NOT_USE_NON_EXT_ALLOC_FUNCTIONS
|
||||
extern void *_TIFFmalloc(tmsize_t s);
|
||||
extern void *_TIFFcalloc(tmsize_t nmemb, tmsize_t siz);
|
||||
extern void *_TIFFrealloc(void *p, tmsize_t s);
|
||||
extern void _TIFFfree(void *p);
|
||||
#endif
|
||||
extern void _TIFFmemset(void *p, int v, tmsize_t c);
|
||||
extern void _TIFFmemcpy(void *d, const void *s, tmsize_t c);
|
||||
extern int _TIFFmemcmp(const void *p1, const void *p2, tmsize_t c);
|
||||
extern void _TIFFfree(void *p);
|
||||
|
||||
/*
|
||||
** Stuff, related to tag handling and creating custom tags.
|
||||
|
@ -508,6 +505,9 @@ extern int TIFFReadRGBAImageOriented(TIFF *, uint32_t, uint32_t, uint32_t *,
|
|||
TIFFOpenOptionsSetMaxSingleMemAlloc(TIFFOpenOptions *opts,
|
||||
tmsize_t max_single_mem_alloc);
|
||||
extern void
|
||||
TIFFOpenOptionsSetMaxCumulatedMemAlloc(TIFFOpenOptions *opts,
|
||||
tmsize_t max_cumulated_mem_alloc);
|
||||
extern void
|
||||
TIFFOpenOptionsSetErrorHandlerExtR(TIFFOpenOptions *opts,
|
||||
TIFFErrorHandlerExtR handler,
|
||||
void *errorhandler_user_data);
|
||||
|
@ -518,11 +518,11 @@ extern int TIFFReadRGBAImageOriented(TIFF *, uint32_t, uint32_t, uint32_t *,
|
|||
|
||||
extern TIFF *TIFFOpen(const char *, const char *);
|
||||
extern TIFF *TIFFOpenExt(const char *, const char *, TIFFOpenOptions *opts);
|
||||
#ifdef __WIN32__
|
||||
#ifdef _WIN32
|
||||
extern TIFF *TIFFOpenW(const wchar_t *, const char *);
|
||||
extern TIFF *TIFFOpenWExt(const wchar_t *, const char *,
|
||||
TIFFOpenOptions *opts);
|
||||
#endif /* __WIN32__ */
|
||||
#endif /* _WIN32 */
|
||||
extern TIFF *TIFFFdOpen(int, const char *, const char *);
|
||||
extern TIFF *TIFFFdOpenExt(int, const char *, const char *,
|
||||
TIFFOpenOptions *opts);
|
||||
|
|
|
@ -102,6 +102,13 @@ struct TIFFOffsetAndDirNumber
|
|||
};
|
||||
typedef struct TIFFOffsetAndDirNumber TIFFOffsetAndDirNumber;
|
||||
|
||||
typedef union
|
||||
{
|
||||
TIFFHeaderCommon common;
|
||||
TIFFHeaderClassic classic;
|
||||
TIFFHeaderBig big;
|
||||
} TIFFHeaderUnion;
|
||||
|
||||
struct tiff
|
||||
{
|
||||
char *tif_name; /* name of open file */
|
||||
|
@ -153,20 +160,35 @@ struct tiff
|
|||
TIFFDirectory tif_dir; /* internal rep of current directory */
|
||||
TIFFDirectory
|
||||
tif_customdir; /* custom IFDs are separated from the main ones */
|
||||
union
|
||||
{
|
||||
TIFFHeaderCommon common;
|
||||
TIFFHeaderClassic classic;
|
||||
TIFFHeaderBig big;
|
||||
} tif_header;
|
||||
uint16_t tif_header_size; /* file's header block and its length */
|
||||
uint32_t tif_row; /* current scanline */
|
||||
tdir_t tif_curdir; /* current directory (index) */
|
||||
TIFFHeaderUnion tif_header; /* file's header block Classic/BigTIFF union */
|
||||
uint16_t tif_header_size; /* file's header block and its length */
|
||||
uint32_t tif_row; /* current scanline */
|
||||
|
||||
/* There are IFDs in the file and an "active" IFD in memory,
|
||||
* from which fields are "set" and "get".
|
||||
* tif_curdir is set to:
|
||||
* a) TIFF_NON_EXISTENT_DIR_NUMBER if there is no IFD in the file
|
||||
* or the state is unknown,
|
||||
* or the last read (i.e. TIFFFetchDirectory()) failed,
|
||||
* or a custom directory was written.
|
||||
* b) IFD index of last IFD written in the file. In this case the
|
||||
* active IFD is a new (empty) one and tif_diroff is zero.
|
||||
* If writing fails, tif_curdir is not changed.
|
||||
* c) IFD index of IFD read from file into memory (=active IFD),
|
||||
* even if IFD is corrupt and TIFFReadDirectory() returns 0.
|
||||
* Then tif_diroff contains the offset of the IFD in the file.
|
||||
* d) IFD index 0, whenever a custom directory or an unchained SubIFD
|
||||
* was read. */
|
||||
tdir_t tif_curdir; /* current directory (index) */
|
||||
/* tif_curdircount: number of directories (main-IFDs) in file:
|
||||
* - TIFF_NON_EXISTENT_DIR_NUMBER means 'dont know number of IFDs'.
|
||||
* - 0 means 'empty file opened for writing, but no IFD written yet' */
|
||||
tdir_t tif_curdircount;
|
||||
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 */
|
||||
uint64_t tif_dataoff; /* current offset for writing dir (IFD) */
|
||||
/* SubIFD support */
|
||||
uint16_t tif_nsubifd; /* remaining subifds to write */
|
||||
uint64_t tif_subifdoff; /* offset for patching SubIFD link */
|
||||
|
@ -233,7 +255,9 @@ struct tiff
|
|||
void *tif_errorhandler_user_data;
|
||||
TIFFErrorHandlerExtR tif_warnhandler;
|
||||
void *tif_warnhandler_user_data;
|
||||
tmsize_t tif_max_single_mem_alloc; /* in bytes. 0 for unlimited */
|
||||
tmsize_t tif_max_single_mem_alloc; /* in bytes. 0 for unlimited */
|
||||
tmsize_t tif_max_cumulated_mem_alloc; /* in bytes. 0 for unlimited */
|
||||
tmsize_t tif_cur_cumulated_mem_alloc; /* in bytes */
|
||||
};
|
||||
|
||||
struct TIFFOpenOptions
|
||||
|
@ -243,6 +267,7 @@ struct TIFFOpenOptions
|
|||
TIFFErrorHandlerExtR warnhandler; /* may be NULL */
|
||||
void *warnhandler_user_data; /* may be NULL */
|
||||
tmsize_t max_single_mem_alloc; /* in bytes. 0 for unlimited */
|
||||
tmsize_t max_cumulated_mem_alloc; /* in bytes. 0 for unlimited */
|
||||
};
|
||||
|
||||
#define isPseudoTag(t) (t > 0xffff) /* is tag value normal or pseudo */
|
||||
|
@ -331,7 +356,7 @@ struct TIFFOpenOptions
|
|||
#define ftell(stream, offset, whence) ftello(stream, offset, whence)
|
||||
#endif
|
||||
#endif
|
||||
#if defined(__WIN32__) && !(defined(_MSC_VER) && _MSC_VER < 1400) && \
|
||||
#if defined(_WIN32) && \
|
||||
!(defined(__MSVCRT_VERSION__) && __MSVCRT_VERSION__ < 0x800)
|
||||
typedef unsigned int TIFFIOSize_t;
|
||||
#define _TIFF_lseek_f(fildes, offset, whence) \
|
||||
|
@ -437,9 +462,6 @@ extern "C"
|
|||
extern void *_TIFFCheckRealloc(TIFF *, void *, tmsize_t, tmsize_t,
|
||||
const char *);
|
||||
|
||||
extern double _TIFFUInt64ToDouble(uint64_t);
|
||||
extern float _TIFFUInt64ToFloat(uint64_t);
|
||||
|
||||
extern float _TIFFClampDoubleToFloat(double);
|
||||
extern uint32_t _TIFFClampDoubleToUInt32(double);
|
||||
|
||||
|
|
|
@ -8,7 +8,7 @@
|
|||
* Furthermore, configure_file variables of type "@VAR@" are
|
||||
* modified by clang-format and won't be substituted by CMake.
|
||||
*/
|
||||
#define TIFFLIB_VERSION_STR "LIBTIFF, Version 4.6.0\nCopyright (c) 1988-1996 Sam Leffler\nCopyright (c) 1991-1996 Silicon Graphics, Inc."
|
||||
#define TIFFLIB_VERSION_STR "LIBTIFF, Version 4.7.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
|
||||
|
@ -16,13 +16,13 @@
|
|||
* version checking should be done based on the
|
||||
* string returned by TIFFGetVersion.
|
||||
*/
|
||||
#define TIFFLIB_VERSION 20230908
|
||||
#define TIFFLIB_VERSION 20240911
|
||||
|
||||
/* The following defines have been added in 4.5.0 */
|
||||
#define TIFFLIB_MAJOR_VERSION 4
|
||||
#define TIFFLIB_MINOR_VERSION 6
|
||||
#define TIFFLIB_MINOR_VERSION 7
|
||||
#define TIFFLIB_MICRO_VERSION 0
|
||||
#define TIFFLIB_VERSION_STR_MAJ_MIN_MIC "4.6.0"
|
||||
#define TIFFLIB_VERSION_STR_MAJ_MIN_MIC "4.7.0"
|
||||
|
||||
/* Macro added in 4.5.0. Returns TRUE if the current libtiff version is
|
||||
* greater or equal to major.minor.micro
|
||||
|
|
Loading…
Reference in a new issue