Merge pull request #29838 from Xingchen1224:libtiff-4.7.2-upgrade

3rdparty/libtiff: Upgrade libtiff to 4.7.2 - #29838

[Feature Request] Upgrade libtiff to 4.7.2 (https://libtiff.gitlab.io/libtiff/releases/v4.7.2.html)

### Pull Request Readiness Checklist

See details at https://github.com/opencv/opencv/wiki/How_to_contribute#making-a-good-pull-request

- [x] I agree to contribute to the project under Apache 2 License.
- [x] To the best of my knowledge, the proposed patch is not based on a code under GPL or another license that is incompatible with OpenCV
- [x] The PR is proposed to the proper branch
- [ ] There is a reference to the original bug report and related work
- [ ] There is accuracy test, performance test and test data in opencv_extra repository, if applicable
      Patch to opencv_extra has the same branch name.
- [ ] The feature is well documented and sample code can be built with the project CMake
This commit is contained in:
Xingchen
2026-09-03 19:29:33 +08:00
committed by GitHub
parent 1209808c70
commit 5b526645b6
43 changed files with 5352 additions and 1700 deletions

View File

@@ -359,7 +359,7 @@ endif()
set(LIBTIFF_MAJOR_VERSION "4")
set(LIBTIFF_MINOR_VERSION "7")
set(LIBTIFF_MICRO_VERSION "1")
set(LIBTIFF_MICRO_VERSION "2")
set(LIBTIFF_VERSION "${LIBTIFF_MAJOR_VERSION}.${LIBTIFF_MINOR_VERSION}.${LIBTIFF_MICRO_VERSION}")
file(READ "RELEASE-DATE" LIBTIFF_RELEASE_DATE content)

File diff suppressed because it is too large Load Diff

View File

@@ -1 +1 @@
20250911
20260627

View File

@@ -56,6 +56,21 @@ uint64_t _TIFFMultiply64(TIFF *tif, uint64_t first, uint64_t second,
return first * second;
}
uint64_t _TIFFAdd64(TIFF *tif, uint64_t first, uint64_t second,
const char *where)
{
if (first > UINT64_MAX - second)
{
if (tif != NULL && where != NULL)
{
TIFFErrorExtR(tif, where, "Integer overflow in %s", where);
}
return 0;
}
return first + second;
}
tmsize_t _TIFFMultiplySSize(TIFF *tif, tmsize_t first, tmsize_t second,
const char *where)
{
@@ -81,6 +96,30 @@ tmsize_t _TIFFMultiplySSize(TIFF *tif, tmsize_t first, tmsize_t second,
return first * second;
}
tmsize_t _TIFFAddSSize(TIFF *tif, tmsize_t first, tmsize_t second,
const char *where)
{
if (first < 0 || second < 0)
{
if (tif != NULL && where != NULL)
{
TIFFErrorExtR(tif, where,
"Invalid argument to _TIFFAddSSize() in %s", where);
}
return 0;
}
if (first > TIFF_TMSIZE_T_MAX - second)
{
if (tif != NULL && where != NULL)
{
TIFFErrorExtR(tif, where, "Integer overflow in %s", where);
}
return 0;
}
return first + second;
}
tmsize_t _TIFFCastUInt64ToSSize(TIFF *tif, uint64_t val, const char *module)
{
if (val > (uint64_t)TIFF_TMSIZE_T_MAX)
@@ -94,6 +133,55 @@ tmsize_t _TIFFCastUInt64ToSSize(TIFF *tif, uint64_t val, const char *module)
return (tmsize_t)val;
}
uint32_t _TIFFCastUInt64ToUInt32(TIFF *tif, uint64_t val, const char *module)
{
if (val > UINT32_MAX)
{
if (tif != NULL && module != NULL)
{
TIFFErrorExtR(tif, module, "Integer overflow");
}
return 0;
}
return (uint32_t)val;
}
tmsize_t _TIFFComputeRowOffset(TIFF *tif, tmsize_t rowstride, uint32_t row,
const char *where)
{
if (row == 0)
return 0;
return _TIFFMultiplySSize(tif, rowstride, (tmsize_t)row, where);
}
uint64_t _TIFFComputeBitOffset(TIFF *tif, uint32_t col, uint16_t spp,
uint16_t bps, const char *where)
{
uint64_t samples = _TIFFMultiply64(tif, col, spp, where);
if (samples == 0 && col != 0)
return 0;
return _TIFFMultiply64(tif, samples, bps, where);
}
/*
* Returns 0 on overflow or invalid zero-sized row inputs. Callers that
* intentionally allow empty rows should not use this helper directly.
*/
uint64_t _TIFFComputeRowSize64(TIFF *tif, uint32_t width, uint16_t spp,
uint16_t bps, const char *where)
{
uint64_t samples = _TIFFMultiply64(tif, width, spp, where);
uint64_t bits;
if (samples == 0)
return 0;
bits = _TIFFMultiply64(tif, samples, bps, where);
if (bits == 0)
return 0;
return TIFFhowmany8_64(bits);
}
void *_TIFFCheckRealloc(TIFF *tif, void *buffer, tmsize_t nmemb,
tmsize_t elem_size, const char *what)
{
@@ -137,8 +225,8 @@ static int TIFFDefaultTransferFunction(TIFF *tif, TIFFDirectory *td)
if (td->td_bitspersample > 24)
return 0;
n = ((tmsize_t)1) << td->td_bitspersample;
nbytes = n * sizeof(uint16_t);
n = (tmsize_t)(1ULL << td->td_bitspersample);
nbytes = (tmsize_t)((uint64_t)n * sizeof(uint16_t));
tf[0] = (uint16_t *)_TIFFmallocExt(tif, nbytes);
if (tf[0] == NULL)
return 0;
@@ -186,10 +274,10 @@ static int TIFFDefaultRefBlackWhite(TIFF *tif, TIFFDirectory *td)
* YCbCr (Class Y) images must have the ReferenceBlackWhite
* tag set. Fix the broken images, which lacks that tag.
*/
td->td_refblackwhite[0] = 0.0F;
td->td_refblackwhite[0] = 0.0f;
td->td_refblackwhite[1] = td->td_refblackwhite[3] =
td->td_refblackwhite[5] = 255.0F;
td->td_refblackwhite[2] = td->td_refblackwhite[4] = 128.0F;
td->td_refblackwhite[5] = 255.0f;
td->td_refblackwhite[2] = td->td_refblackwhite[4] = 128.0f;
}
else
{
@@ -199,8 +287,11 @@ static int TIFFDefaultRefBlackWhite(TIFF *tif, TIFFDirectory *td)
for (i = 0; i < 3; i++)
{
td->td_refblackwhite[2 * i + 0] = 0;
td->td_refblackwhite[2 * i + 1] =
(float)((1L << td->td_bitspersample) - 1L);
if (td->td_bitspersample < 64)
td->td_refblackwhite[2 * i + 1] =
(float)((1ULL << td->td_bitspersample) - 1ULL);
else
td->td_refblackwhite[2 * i + 1] = (float)UINT64_MAX;
}
}
return 1;
@@ -258,8 +349,8 @@ int TIFFVGetFieldDefaulted(TIFF *tif, uint32_t tag, va_list ap)
* 65535 even if td_bitspersamle is > 16 */
if (td->td_bitspersample <= 16)
{
maxsamplevalue = (1 << td->td_bitspersample) -
1; /* 2**(BitsPerSample) - 1 */
maxsamplevalue = (uint16_t)((1U << td->td_bitspersample) -
1); /* 2**(BitsPerSample) - 1 */
}
else
{
@@ -295,7 +386,11 @@ int TIFFVGetFieldDefaulted(TIFF *tif, uint32_t tag, va_list ap)
}
case TIFFTAG_DOTRANGE:
*va_arg(ap, uint16_t *) = 0;
*va_arg(ap, uint16_t *) = (1 << td->td_bitspersample) - 1;
if (td->td_bitspersample <= 16)
*va_arg(ap, uint16_t *) =
(uint16_t)((1U << td->td_bitspersample) - 1);
else
*va_arg(ap, uint16_t *) = 65535;
return (1);
case TIFFTAG_INKSET:
*va_arg(ap, uint16_t *) = INKSET_CMYK;
@@ -309,14 +404,14 @@ int TIFFVGetFieldDefaulted(TIFF *tif, uint32_t tag, va_list ap)
return (1);
case TIFFTAG_MATTEING:
*va_arg(ap, uint16_t *) =
(td->td_extrasamples == 1 &&
(td->td_extrasamples == 1 && td->td_sampleinfo &&
td->td_sampleinfo[0] == EXTRASAMPLE_ASSOCALPHA);
return (1);
case TIFFTAG_TILEDEPTH:
*va_arg(ap, uint32_t *) = td->td_tiledepth;
return (1);
case TIFFTAG_DATATYPE:
*va_arg(ap, uint16_t *) = td->td_sampleformat - 1;
*va_arg(ap, uint16_t *) = (uint16_t)(td->td_sampleformat - 1);
return (1);
case TIFFTAG_SAMPLEFORMAT:
*va_arg(ap, uint16_t *) = td->td_sampleformat;
@@ -369,6 +464,8 @@ int TIFFVGetFieldDefaulted(TIFF *tif, uint32_t tag, va_list ap)
return (0);
*va_arg(ap, const float **) = td->td_refblackwhite;
return (1);
default:
break;
}
return 0;
}
@@ -390,9 +487,9 @@ int TIFFGetFieldDefaulted(TIFF *tif, uint32_t tag, ...)
float _TIFFClampDoubleToFloat(double val)
{
if (val > FLT_MAX)
if (val > (double)FLT_MAX)
return FLT_MAX;
if (val < -FLT_MAX)
if (val < -(double)FLT_MAX)
return -FLT_MAX;
return (float)val;
}
@@ -401,7 +498,7 @@ uint32_t _TIFFClampDoubleToUInt32(double val)
{
if (val < 0)
return 0;
if (val > 0xFFFFFFFFU || val != val)
if (val > 0xFFFFFFFFU || isnan(val))
return 0xFFFFFFFFU;
return (uint32_t)val;
}

View File

@@ -88,7 +88,7 @@ void TIFFCleanup(TIFF *tif)
*/
TIFFFieldIsAnonymous(fld))
{
_TIFFfreeExt(tif, fld->field_name);
_TIFFfreeExt(tif, (void *)fld->field_name);
_TIFFfreeExt(tif, fld);
}
}
@@ -121,7 +121,7 @@ void TIFFCleanup(TIFF *tif)
}
/************************************************************************/
/* _TIFFCleanupIFDOffsetAndNumberMaps() */
/* _TIFFCleanupIFDOffsetAndNumberMaps() */
/************************************************************************/
void _TIFFCleanupIFDOffsetAndNumberMaps(TIFF *tif)
@@ -139,7 +139,7 @@ void _TIFFCleanupIFDOffsetAndNumberMaps(TIFF *tif)
}
/************************************************************************/
/* TIFFClose() */
/* TIFFClose() */
/************************************************************************/
/**

View File

@@ -55,34 +55,34 @@ void TIFFCIELabToXYZ(TIFFCIELabToRGB *cielab, uint32_t l, int32_t a, int32_t b,
void TIFFCIELab16ToXYZ(TIFFCIELabToRGB *cielab, uint32_t l, int32_t a,
int32_t b, float *X, float *Y, float *Z)
{
float L = (float)l * 100.0F / 65535.0F;
float L = (float)l * 100.0f / 65535.0f;
float cby, tmp;
if (L < 8.856F)
if (L < 8.856f)
{
*Y = (L * cielab->Y0) / 903.292F;
cby = 7.787F * (*Y / cielab->Y0) + 16.0F / 116.0F;
*Y = (L * cielab->Y0) / 903.292f;
cby = 7.787f * (*Y / cielab->Y0) + 16.0f / 116.0f;
}
else
{
cby = (L + 16.0F) / 116.0F;
cby = (L + 16.0f) / 116.0f;
*Y = cielab->Y0 * cby * cby * cby;
}
tmp = (float)a / 256.0F / 500.0F + cby;
if (tmp < 0.2069F)
*X = cielab->X0 * (tmp - 0.13793F) / 7.787F;
tmp = (float)a / 256.0f / 500.0f + cby;
if (tmp < 0.2069f)
*X = cielab->X0 * (tmp - 0.13793f) / 7.787f;
else
*X = cielab->X0 * tmp * tmp * tmp;
tmp = cby - (float)b / 256.0F / 200.0F;
if (tmp < 0.2069F)
*Z = cielab->Z0 * (tmp - 0.13793F) / 7.787F;
tmp = cby - (float)b / 256.0f / 200.0f;
if (tmp < 0.2069f)
*Z = cielab->Z0 * (tmp - 0.13793f) / 7.787f;
else
*Z = cielab->Z0 * tmp * tmp * tmp;
}
#define RINT(R) ((uint32_t)((R) > 0 ? ((R) + 0.5) : ((R)-0.5)))
#define RINT(R) ((uint32_t)((R) > 0 ? ((R) + 0.5f) : ((R) - 0.5f)))
/*
* Convert color value from the XYZ space to RGB.
*/
@@ -143,32 +143,32 @@ int TIFFCIELabToRGBInit(TIFFCIELabToRGB *cielab, const TIFFDisplay *display,
_TIFFmemcpy(&cielab->display, display, sizeof(TIFFDisplay));
/* Red */
dfGamma = 1.0 / cielab->display.d_gammaR;
dfGamma = 1.0 / (double)cielab->display.d_gammaR;
cielab->rstep =
(cielab->display.d_YCR - cielab->display.d_Y0R) / cielab->range;
(cielab->display.d_YCR - cielab->display.d_Y0R) / (float)cielab->range;
for (i = 0; i <= (size_t)cielab->range; i++)
{
cielab->Yr2r[i] = cielab->display.d_Vrwr *
cielab->Yr2r[i] = (float)cielab->display.d_Vrwr *
((float)pow((double)i / cielab->range, dfGamma));
}
/* Green */
dfGamma = 1.0 / cielab->display.d_gammaG;
dfGamma = 1.0 / (double)cielab->display.d_gammaG;
cielab->gstep =
(cielab->display.d_YCR - cielab->display.d_Y0R) / cielab->range;
(cielab->display.d_YCR - cielab->display.d_Y0R) / (float)cielab->range;
for (i = 0; i <= (size_t)cielab->range; i++)
{
cielab->Yg2g[i] = cielab->display.d_Vrwg *
cielab->Yg2g[i] = (float)cielab->display.d_Vrwg *
((float)pow((double)i / cielab->range, dfGamma));
}
/* Blue */
dfGamma = 1.0 / cielab->display.d_gammaB;
dfGamma = 1.0 / (double)cielab->display.d_gammaB;
cielab->bstep =
(cielab->display.d_YCR - cielab->display.d_Y0R) / cielab->range;
(cielab->display.d_YCR - cielab->display.d_Y0R) / (float)cielab->range;
for (i = 0; i <= (size_t)cielab->range; i++)
{
cielab->Yb2b[i] = cielab->display.d_Vrwb *
cielab->Yb2b[i] = (float)cielab->display.d_Vrwb *
((float)pow((double)i / cielab->range, dfGamma));
}
@@ -186,11 +186,11 @@ int TIFFCIELabToRGBInit(TIFFCIELabToRGB *cielab, const TIFFDisplay *display,
* see below for more information on how it works.
*/
#define SHIFT 16
#define FIX(x) ((int32_t)((x) * (1L << SHIFT) + 0.5))
#define FIX(x) ((int32_t)((double)(x) * (1L << SHIFT) + 0.5))
#define ONE_HALF ((int32_t)(1 << (SHIFT - 1)))
#define Code2V(c, RB, RW, CR) \
((((c) - (int32_t)(RB)) * (float)(CR)) / \
(float)(((RW) - (RB) != 0) ? ((RW) - (RB)) : 1))
(((float)((c) - (int32_t)(RB)) * (float)(CR)) / \
((!TIFF_FLOAT_EQ((RW), (RB))) ? ((RW) - (RB)) : 1.0f))
/* !((f)>=(min)) written that way to deal with NaN */
#define CLAMP(f, min, max) \
((!((f) >= (min))) ? (min) : (f) > (max) ? (max) : (f))
@@ -207,12 +207,12 @@ void TIFFYCbCrtoRGB(TIFFYCbCrToRGB *ycbcr, uint32_t Y, int32_t Cb, int32_t Cr,
Cr = CLAMP(Cr, 0, 255);
i = ycbcr->Y_tab[Y] + ycbcr->Cr_r_tab[Cr];
*r = CLAMP(i, 0, 255);
*r = (uint32_t)CLAMP(i, 0, 255);
i = ycbcr->Y_tab[Y] +
(int)((ycbcr->Cb_g_tab[Cb] + ycbcr->Cr_g_tab[Cr]) >> SHIFT);
*g = CLAMP(i, 0, 255);
((ycbcr->Cb_g_tab[Cb] + ycbcr->Cr_g_tab[Cr]) >> SHIFT);
*g = (uint32_t)CLAMP(i, 0, 255);
i = ycbcr->Y_tab[Y] + ycbcr->Cb_b_tab[Cb];
*b = CLAMP(i, 0, 255);
*b = (uint32_t)CLAMP(i, 0, 255);
}
/* Clamp function for sanitization purposes. Normally clamping should not */
@@ -258,8 +258,7 @@ int TIFFYCbCrToRGBInit(TIFFYCbCrToRGB *ycbcr, float *luma, float *refBlackWhite)
#define LumaBlue luma[2]
clamptab =
(TIFFRGBValue *)((uint8_t *)ycbcr +
TIFFroundup_32(sizeof(TIFFYCbCrToRGB), sizeof(long)));
(uint8_t *)ycbcr + TIFFroundup_32(sizeof(TIFFYCbCrToRGB), sizeof(long));
_TIFFmemset(clamptab, 0, 256); /* v < 0 => 0 */
ycbcr->clamptab = (clamptab += 256);
for (i = 0; i < 256; i++)
@@ -273,13 +272,13 @@ int TIFFYCbCrToRGBInit(TIFFYCbCrToRGB *ycbcr, float *luma, float *refBlackWhite)
{
float f1 = 2 - 2 * LumaRed;
int32_t D1 = FIX(CLAMP(f1, 0.0F, 2.0F));
int32_t D1 = FIX(CLAMP(f1, 0.0f, 2.0f));
float f2 = LumaRed * f1 / LumaGreen;
int32_t D2 = -FIX(CLAMP(f2, 0.0F, 2.0F));
int32_t D2 = -FIX(CLAMP(f2, 0.0f, 2.0f));
float f3 = 2 - 2 * LumaBlue;
int32_t D3 = FIX(CLAMP(f3, 0.0F, 2.0F));
int32_t D3 = FIX(CLAMP(f3, 0.0f, 2.0f));
float f4 = LumaBlue * f3 / LumaGreen;
int32_t D4 = -FIX(CLAMP(f4, 0.0F, 2.0F));
int32_t D4 = -FIX(CLAMP(f4, 0.0f, 2.0f));
int x;
#undef LumaBlue
@@ -295,12 +294,12 @@ int TIFFYCbCrToRGBInit(TIFFYCbCrToRGB *ycbcr, float *luma, float *refBlackWhite)
*/
for (i = 0, x = -128; i < 256; i++, x++)
{
int32_t Cr = (int32_t)CLAMPw(Code2V(x, refBlackWhite[4] - 128.0F,
refBlackWhite[5] - 128.0F, 127),
-128.0F * 32, 128.0F * 32);
int32_t Cb = (int32_t)CLAMPw(Code2V(x, refBlackWhite[2] - 128.0F,
refBlackWhite[3] - 128.0F, 127),
-128.0F * 32, 128.0F * 32);
int32_t Cr = (int32_t)CLAMPw(Code2V(x, refBlackWhite[4] - 128.0f,
refBlackWhite[5] - 128.0f, 127),
-128.0f * 32, 128.0f * 32);
int32_t Cb = (int32_t)CLAMPw(Code2V(x, refBlackWhite[2] - 128.0f,
refBlackWhite[3] - 128.0f, 127),
-128.0f * 32, 128.0f * 32);
ycbcr->Cr_r_tab[i] = (int32_t)((D1 * Cr + ONE_HALF) >> SHIFT);
ycbcr->Cb_b_tab[i] = (int32_t)((D3 * Cb + ONE_HALF) >> SHIFT);
@@ -308,7 +307,7 @@ int TIFFYCbCrToRGBInit(TIFFYCbCrToRGB *ycbcr, float *luma, float *refBlackWhite)
ycbcr->Cb_g_tab[i] = D4 * Cb + ONE_HALF;
ycbcr->Y_tab[i] = (int32_t)CLAMPw(
Code2V(x + 128, refBlackWhite[0], refBlackWhite[1], 255),
-128.0F * 32, 128.0F * 32);
-128.0f * 32, 128.0f * 32);
}
}

View File

@@ -139,6 +139,18 @@ static int _TIFFtrue(TIFF *tif)
}
static void _TIFFvoid(TIFF *tif) { (void)tif; }
static uint64_t _TIFFDefaultGetMaxCompressionRatio(TIFF *tif)
{
(void)tif;
return 0; /* unknown */
}
static uint64_t _TIFFGetMaxCompressionRatioOne(TIFF *tif)
{
(void)tif;
return 1; /* no compression */
}
void _TIFFSetDefaultCompressionState(TIFF *tif)
{
tif->tif_fixuptags = _TIFFNoFixupTags;
@@ -160,6 +172,7 @@ void _TIFFSetDefaultCompressionState(TIFF *tif)
tif->tif_cleanup = _TIFFvoid;
tif->tif_defstripsize = _TIFFDefaultStripSize;
tif->tif_deftilesize = _TIFFDefaultTileSize;
tif->tif_getmaxcompressionratio = _TIFFDefaultGetMaxCompressionRatio;
tif->tif_flags &= ~(TIFF_NOBITREV | TIFF_NOREADRAW);
}
@@ -168,6 +181,8 @@ int TIFFSetCompressionScheme(TIFF *tif, int scheme)
const TIFFCodec *c = TIFFFindCODEC((uint16_t)scheme);
_TIFFSetDefaultCompressionState(tif);
if (scheme == COMPRESSION_NONE)
tif->tif_getmaxcompressionratio = _TIFFGetMaxCompressionRatioOne;
/*
* Don't treat an unknown compression scheme as an error.
* This permits applications to open files with data that
@@ -177,6 +192,13 @@ int TIFFSetCompressionScheme(TIFF *tif, int scheme)
return (c ? (*c->init)(tif, scheme) : 1);
}
uint64_t TIFFGetMaxCompressionRatio(TIFF *tif)
{
if (tif->tif_getmaxcompressionratio)
return tif->tif_getmaxcompressionratio(tif);
return 0;
}
/*
* Other compression schemes may be registered. Registered
* schemes can also override the builtin versions provided
@@ -200,7 +222,7 @@ const TIFFCodec *TIFFFindCODEC(uint16_t scheme)
for (c = _TIFFBuiltinCODECS; c->name; c++)
if (c->scheme == scheme)
return (c);
return ((const TIFFCodec *)0);
return NULL;
}
TIFFCodec *TIFFRegisterCODEC(uint16_t scheme, const char *name,
@@ -212,9 +234,11 @@ TIFFCodec *TIFFRegisterCODEC(uint16_t scheme, const char *name,
if (cd != NULL)
{
char *codec_name;
cd->info = (TIFFCodec *)((uint8_t *)cd + sizeof(codec_t));
cd->info->name = (char *)((uint8_t *)cd->info + sizeof(TIFFCodec));
strcpy(cd->info->name, name);
codec_name = (char *)((uint8_t *)cd->info + sizeof(TIFFCodec));
strcpy(codec_name, name);
cd->info->name = codec_name;
cd->info->scheme = scheme;
cd->info->init = init;
cd->next = registeredCODECS;
@@ -247,7 +271,7 @@ void TIFFUnRegisterCODEC(TIFFCodec *c)
}
/************************************************************************/
/* TIFFGetConfisuredCODECs() */
/* TIFFGetConfiguredCODECs() */
/************************************************************************/
/**
@@ -258,7 +282,7 @@ void TIFFUnRegisterCODEC(TIFFCodec *c)
* or NULL if function failed.
*/
TIFFCodec *TIFFGetConfiguredCODECs()
TIFFCodec *TIFFGetConfiguredCODECs(void)
{
int i = 1;
codec_t *cd;
@@ -268,8 +292,8 @@ TIFFCodec *TIFFGetConfiguredCODECs()
for (cd = registeredCODECS; cd; cd = cd->next)
{
new_codecs =
(TIFFCodec *)_TIFFreallocExt(NULL, codecs, i * sizeof(TIFFCodec));
new_codecs = (TIFFCodec *)_TIFFreallocExt(
NULL, codecs, (tmsize_t)((size_t)i * sizeof(TIFFCodec)));
if (!new_codecs)
{
_TIFFfreeExt(NULL, codecs);
@@ -283,21 +307,21 @@ TIFFCodec *TIFFGetConfiguredCODECs()
{
if (TIFFIsCODECConfigured(c->scheme))
{
new_codecs = (TIFFCodec *)_TIFFreallocExt(NULL, codecs,
i * sizeof(TIFFCodec));
new_codecs = (TIFFCodec *)_TIFFreallocExt(
NULL, codecs, (tmsize_t)((size_t)i * sizeof(TIFFCodec)));
if (!new_codecs)
{
_TIFFfreeExt(NULL, codecs);
return NULL;
}
codecs = new_codecs;
_TIFFmemcpy(codecs + i - 1, (const void *)c, sizeof(TIFFCodec));
_TIFFmemcpy(codecs + i - 1, c, sizeof(TIFFCodec));
i++;
}
}
new_codecs =
(TIFFCodec *)_TIFFreallocExt(NULL, codecs, i * sizeof(TIFFCodec));
new_codecs = (TIFFCodec *)_TIFFreallocExt(
NULL, codecs, (tmsize_t)((size_t)i * sizeof(TIFFCodec)));
if (!new_codecs)
{
_TIFFfreeExt(NULL, codecs);

View File

@@ -31,6 +31,7 @@
#include "tiffiop.h"
#include <float.h> /*--: for Rational2Double */
#include <limits.h>
#include <math.h>
/*
* These are used in the backwards compatibility code...
@@ -50,7 +51,8 @@ static void setByteArray(TIFF *tif, void **vpp, const void *vp, size_t nmemb,
}
if (vp)
{
tmsize_t bytes = _TIFFMultiplySSize(NULL, nmemb, elem_size, NULL);
tmsize_t bytes = _TIFFMultiplySSize(NULL, (tmsize_t)nmemb,
(tmsize_t)elem_size, NULL);
if (bytes)
*vpp = (void *)_TIFFmallocExt(tif, bytes);
if (*vpp)
@@ -121,7 +123,8 @@ static void setDoubleArrayOneValue(TIFF *tif, double **vpp, double value,
{
if (*vpp)
_TIFFfreeExt(tif, *vpp);
*vpp = _TIFFmallocExt(tif, nmemb * sizeof(double));
*vpp = (double *)_TIFFmallocExt(tif,
(tmsize_t)nmemb * (tmsize_t)sizeof(double));
if (*vpp)
{
while (nmemb--)
@@ -294,7 +297,7 @@ static int _TIFFVSetField(TIFF *tif, uint32_t tag, va_list ap)
/*
* Setup new compression routine state.
*/
if ((status = TIFFSetCompressionScheme(tif, v)) != 0)
if ((status = TIFFSetCompressionScheme(tif, (int)v)) != 0)
td->td_compression = (uint16_t)v;
else
status = 0;
@@ -402,13 +405,13 @@ static int _TIFFVSetField(TIFF *tif, uint32_t tag, va_list ap)
break;
case TIFFTAG_XRESOLUTION:
dblval = va_arg(ap, double);
if (dblval != dblval || dblval < 0)
if (isnan(dblval) || dblval < 0)
goto badvaluedouble;
td->td_xresolution = _TIFFClampDoubleToFloat(dblval);
break;
case TIFFTAG_YRESOLUTION:
dblval = va_arg(ap, double);
if (dblval != dblval || dblval < 0)
if (isnan(dblval) || dblval < 0)
goto badvaluedouble;
td->td_yresolution = _TIFFClampDoubleToFloat(dblval);
break;
@@ -439,7 +442,12 @@ static int _TIFFVSetField(TIFF *tif, uint32_t tag, va_list ap)
td->td_halftonehints[1] = (uint16_t)va_arg(ap, uint16_vap);
break;
case TIFFTAG_COLORMAP:
v32 = (uint32_t)(1L << td->td_bitspersample);
if (td->td_bitspersample >= 32)
{
v = td->td_bitspersample;
goto badvalue;
}
v32 = 1U << td->td_bitspersample;
_TIFFsetShortArrayExt(tif, &td->td_colormap[0],
va_arg(ap, uint16_t *), v32);
_TIFFsetShortArrayExt(tif, &td->td_colormap[1],
@@ -557,11 +565,17 @@ static int _TIFFVSetField(TIFF *tif, uint32_t tag, va_list ap)
case TIFFTAG_TRANSFERFUNCTION:
{
uint32_t i;
uint32_t count;
if (td->td_bitspersample >= 32)
{
v = td->td_bitspersample;
goto badvalue;
}
count = 1U << td->td_bitspersample;
v = (td->td_samplesperpixel - td->td_extrasamples) > 1 ? 3 : 1;
for (i = 0; i < v; i++)
_TIFFsetShortArrayExt(tif, &td->td_transferfunction[i],
va_arg(ap, uint16_t *),
1U << td->td_bitspersample);
va_arg(ap, uint16_t *), count);
break;
}
case TIFFTAG_REFERENCEBLACKWHITE:
@@ -579,7 +593,7 @@ static int _TIFFVSetField(TIFF *tif, uint32_t tag, va_list ap)
if (ninksinstring > 0)
{
_TIFFsetNString(tif, &td->td_inknames, s, v);
td->td_inknameslen = v;
td->td_inknameslen = (int)v;
/* Set NumberOfInks to the value ninksinstring */
if (TIFFFieldSet(tif, FIELD_NUMBEROFINKS))
{
@@ -725,7 +739,8 @@ static int _TIFFVSetField(TIFF *tif, uint32_t tag, va_list ap)
new_customValues = (TIFFTagValue *)_TIFFreallocExt(
tif, td->td_customValues,
sizeof(TIFFTagValue) * (td->td_customValueCount + 1));
(tmsize_t)(sizeof(TIFFTagValue) *
(size_t)(td->td_customValueCount + 1)));
if (!new_customValues)
{
TIFFErrorExtR(tif, module,
@@ -754,7 +769,7 @@ static int _TIFFVSetField(TIFF *tif, uint32_t tag, va_list ap)
if (tv_size == 0)
{
status = 0;
TIFFErrorExtR(tif, module, "%s: Bad field type %d for \"%s\"",
TIFFErrorExtR(tif, module, "%s: Bad field type %u for \"%s\"",
tif->tif_name, fip->field_type, fip->field_name);
goto end;
}
@@ -784,7 +799,7 @@ static int _TIFFVSetField(TIFF *tif, uint32_t tag, va_list ap)
}
ma = (uint32_t)len;
}
tv->count = ma;
tv->count = (int)ma;
setByteArray(tif, &tv->value, mb, ma, 1);
}
else
@@ -792,9 +807,9 @@ static int _TIFFVSetField(TIFF *tif, uint32_t tag, va_list ap)
if (fip->field_passcount)
{
if (fip->field_writecount == TIFF_VARIABLE2)
tv->count = (uint32_t)va_arg(ap, uint32_t);
tv->count = (int)va_arg(ap, uint32_t);
else
tv->count = (int)va_arg(ap, int);
tv->count = va_arg(ap, int);
}
else if (fip->field_writecount == TIFF_VARIABLE ||
fip->field_writecount == TIFF_VARIABLE2)
@@ -808,7 +823,7 @@ static int _TIFFVSetField(TIFF *tif, uint32_t tag, va_list ap)
{
TIFFWarningExtR(tif, module,
"%s: Null count for \"%s\" (type "
"%d, writecount %d, passcount %d)",
"%u, writecount %d, passcount %d)",
tif->tif_name, fip->field_name,
fip->field_type, fip->field_writecount,
fip->field_passcount);
@@ -845,11 +860,12 @@ static int _TIFFVSetField(TIFF *tif, uint32_t tag, va_list ap)
* 4 or 8 according to fip->set_get_field_type! */
_TIFFmemcpy(tv->value, va_arg(ap, void *),
tv->count * tv_size);
/* Test here for too big values for LONG8, SLONG8 in
/* Test here for too big values for LONG8, IFD8, SLONG8 in
* ClassicTIFF and delete custom field from custom list */
if (!(tif->tif_flags & TIFF_BIGTIFF))
{
if (tv->info->field_type == TIFF_LONG8)
if (tv->info->field_type == TIFF_LONG8 ||
tv->info->field_type == TIFF_IFD8)
{
uint64_t *pui64 = (uint64_t *)tv->value;
for (int i = 0; i < tv->count; i++)
@@ -858,12 +874,15 @@ static int _TIFFVSetField(TIFF *tif, uint32_t tag, va_list ap)
{
TIFFErrorExtR(
tif, module,
"%s: Bad LONG8 value %" PRIu64
"%s: Bad %s value %" PRIu64
" at %d. array position for \"%s\" tag "
"%d in ClassicTIFF. Tag won't be "
"%u in ClassicTIFF. Tag won't be "
"written to file",
tif->tif_name, pui64[i], i,
fip->field_name, tag);
tif->tif_name,
(tv->info->field_type == TIFF_LONG8
? "LONG8"
: "IFD8"),
pui64[i], i, fip->field_name, tag);
goto badvalueifd8long8;
}
}
@@ -880,7 +899,7 @@ static int _TIFFVSetField(TIFF *tif, uint32_t tag, va_list ap)
tif, module,
"%s: Bad SLONG8 value %" PRIi64
" at %d. array position for \"%s\" tag "
"%d in ClassicTIFF. Tag won't be "
"%u in ClassicTIFF. Tag won't be "
"written to file",
tif->tif_name, pi64[i], i,
fip->field_name, tag);
@@ -948,7 +967,7 @@ static int _TIFFVSetField(TIFF *tif, uint32_t tag, va_list ap)
TIFFErrorExtR(
tif, module,
"%s: Bad LONG8 or IFD8 value %" PRIu64
" for \"%s\" tag %d in ClassicTIFF. Tag "
" for \"%s\" tag %u in ClassicTIFF. Tag "
"won't be written to file",
tif->tif_name, v2, fip->field_name, tag);
goto badvalueifd8long8;
@@ -967,7 +986,7 @@ static int _TIFFVSetField(TIFF *tif, uint32_t tag, va_list ap)
TIFFErrorExtR(
tif, module,
"%s: Bad SLONG8 value %" PRIi64
" for \"%s\" tag %d in ClassicTIFF. Tag "
" for \"%s\" tag %u in ClassicTIFF. Tag "
"won't be written to file",
tif->tif_name, v2, fip->field_name, tag);
goto badvalueifd8long8;
@@ -1018,6 +1037,8 @@ static int _TIFFVSetField(TIFF *tif, uint32_t tag, va_list ap)
_TIFFmemcpy(val, &v2, tv_size);
}
break;
case TIFF_NOTYPE:
case TIFF_ASCII:
default:
_TIFFmemset(val, 0, tv_size);
status = 0;
@@ -1345,7 +1366,7 @@ static int _TIFFVGetField(TIFF *tif, uint32_t tag, va_list ap)
break;
case TIFFTAG_MATTEING:
*va_arg(ap, uint16_t *) =
(td->td_extrasamples == 1 &&
(td->td_extrasamples == 1 && td->td_sampleinfo &&
td->td_sampleinfo[0] == EXTRASAMPLE_ASSOCALPHA);
break;
case TIFFTAG_EXTRASAMPLES:
@@ -1376,6 +1397,8 @@ static int _TIFFVGetField(TIFF *tif, uint32_t tag, va_list ap)
case SAMPLEFORMAT_VOID:
*va_arg(ap, uint16_t *) = DATATYPE_VOID;
break;
default:
break;
}
break;
case TIFFTAG_SAMPLEFORMAT:
@@ -1562,6 +1585,8 @@ static int _TIFFVGetField(TIFF *tif, uint32_t tag, va_list ap)
*va_arg(ap, double *) = *(double *)val;
ret_val = 1;
break;
case TIFF_NOTYPE:
case TIFF_ASCII:
default:
ret_val = 0;
break;
@@ -1613,6 +1638,21 @@ int TIFFVGetField(TIFF *tif, uint32_t tag, va_list ap)
} \
}
/*
* Reset tif->tif_dir structure to zero and
* initialize some IFD strile counter and index parameters.
*/
void _TIFFResetTifDirAndInitStrileCounters(TIFFDirectory *td)
{
_TIFFmemset(td, 0, sizeof(*td));
td->td_curstrip = NOSTRIP; /* invalid strip = NOSTRIP */
td->td_row = (uint32_t)-1; /* read/write pre-increment */
td->td_col = (uint32_t)-1; /* read/write pre-increment */
td->td_scanlinesize = 0; /* initialize to zero */
td->td_curtile = NOTILE; /* invalid tile = NOTILE */
td->td_tilesize = (tmsize_t)-1; /* invalidate tilezize */
}
/*
* Release storage associated with a directory.
*/
@@ -1664,6 +1704,7 @@ void TIFFFreeDirectory(TIFF *tif)
tif->tif_dir.td_dirdatasize_Noffsets = 0;
}
tif->tif_dir.td_iswrittentofile = FALSE;
/* Note: tif->tif_dir structure is set to zero in TIFFDefaultDirectory() */
}
#undef CleanupField
@@ -1694,10 +1735,7 @@ int TIFFCreateDirectory(TIFF *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;
}
@@ -1717,15 +1755,12 @@ int TIFFCreateCustomDirectory(TIFF *tif, const TIFFFieldArray *infoarray)
tif->tif_diroff = 0;
tif->tif_nextdiroff = 0;
tif->tif_curoff = 0;
tif->tif_row = (uint32_t)-1;
tif->tif_curstrip = (uint32_t)-1;
/* invalidate directory index */
tif->tif_curdir = TIFF_NON_EXISTENT_DIR_NUMBER;
/* invalidate IFD loop lists */
_TIFFCleanupIFDOffsetAndNumberMaps(tif);
/* To be able to return from SubIFD or custom-IFD to main-IFD */
tif->tif_setdirectory_force_absolute = TRUE;
return 0;
}
@@ -1751,13 +1786,14 @@ int TIFFCreateGPSDirectory(TIFF *tif)
*/
int TIFFDefaultDirectory(TIFF *tif)
{
register TIFFDirectory *td = &tif->tif_dir;
TIFFDirectory *td = &tif->tif_dir;
const TIFFFieldArray *tiffFieldArray;
tiffFieldArray = _TIFFGetFields();
_TIFFSetupFields(tif, tiffFieldArray);
_TIFFmemset(td, 0, sizeof(*td));
/* Reset tif->tif_dir structure to zero and
* initialize some IFD strile counter and index parameters. */
_TIFFResetTifDirAndInitStrileCounters(td);
td->td_fillorder = FILLORDER_MSB2LSB;
td->td_bitspersample = 1;
td->td_threshholding = THRESHHOLD_BILEVEL;
@@ -1860,10 +1896,8 @@ static int TIFFAdvanceDirectory(TIFF *tif, uint64_t *nextdiroff, uint64_t *off,
tmsize_t poffa, poffb, poffc, poffd;
uint16_t dircount;
uint32_t nextdir32;
poffa = (tmsize_t)poff;
poffb = poffa + sizeof(uint16_t);
if (((uint64_t)poffa != poff) || (poffb < poffa) ||
(poffb < (tmsize_t)sizeof(uint16_t)) || (poffb > tif->tif_size))
if (poff > (uint64_t)TIFF_TMSIZE_T_MAX - sizeof(uint16_t) ||
poff > (uint64_t)tif->tif_size - sizeof(uint16_t))
{
TIFFErrorExtR(tif, module,
"%s:%d: %s: Error fetching directory count",
@@ -1871,13 +1905,20 @@ static int TIFFAdvanceDirectory(TIFF *tif, uint64_t *nextdiroff, uint64_t *off,
*nextdiroff = 0;
return (0);
}
poffa = (tmsize_t)poff;
poffb = poffa + (tmsize_t)sizeof(uint16_t);
_TIFFmemcpy(&dircount, tif->tif_base + poffa, sizeof(uint16_t));
if (tif->tif_flags & TIFF_SWAB)
TIFFSwabShort(&dircount);
if (poffb >
TIFF_TMSIZE_T_MAX - dircount * 12 - (tmsize_t)sizeof(uint32_t))
{
TIFFErrorExtR(tif, module, "Error fetching directory link");
return (0);
}
poffc = poffb + dircount * 12;
poffd = poffc + sizeof(uint32_t);
if ((poffc < poffb) || (poffc < dircount * 12) || (poffd < poffc) ||
(poffd < (tmsize_t)sizeof(uint32_t)) || (poffd > tif->tif_size))
poffd = poffc + (tmsize_t)sizeof(uint32_t);
if (poffd > tif->tif_size)
{
TIFFErrorExtR(tif, module, "Error fetching directory link");
return (0);
@@ -1893,7 +1934,6 @@ static int TIFFAdvanceDirectory(TIFF *tif, uint64_t *nextdiroff, uint64_t *off,
{
tmsize_t poffa, poffb, poffc, poffd;
uint64_t dircount64;
uint16_t dircount16;
if (poff > (uint64_t)TIFF_TMSIZE_T_MAX - sizeof(uint64_t))
{
TIFFErrorExtR(tif, module,
@@ -1902,7 +1942,7 @@ static int TIFFAdvanceDirectory(TIFF *tif, uint64_t *nextdiroff, uint64_t *off,
return (0);
}
poffa = (tmsize_t)poff;
poffb = poffa + sizeof(uint64_t);
poffb = poffa + (tmsize_t)sizeof(uint64_t);
if (poffb > tif->tif_size)
{
TIFFErrorExtR(tif, module,
@@ -1919,15 +1959,14 @@ static int TIFFAdvanceDirectory(TIFF *tif, uint64_t *nextdiroff, uint64_t *off,
"Sanity check on directory count failed");
return (0);
}
dircount16 = (uint16_t)dircount64;
if (poffb > TIFF_TMSIZE_T_MAX - (tmsize_t)(dircount16 * 20) -
if (poffb > TIFF_TMSIZE_T_MAX - (tmsize_t)(dircount64 * 20) -
(tmsize_t)sizeof(uint64_t))
{
TIFFErrorExtR(tif, module, "Error fetching directory link");
return (0);
}
poffc = poffb + dircount16 * 20;
poffd = poffc + sizeof(uint64_t);
poffc = poffb + (tmsize_t)(dircount64 * 20);
poffd = poffc + (tmsize_t)sizeof(uint64_t);
if (poffd > tif->tif_size)
{
TIFFErrorExtR(tif, module, "Error fetching directory link");
@@ -1957,9 +1996,9 @@ static int TIFFAdvanceDirectory(TIFF *tif, uint64_t *nextdiroff, uint64_t *off,
if (tif->tif_flags & TIFF_SWAB)
TIFFSwabShort(&dircount);
if (off != NULL)
*off = TIFFSeekFile(tif, dircount * 12, SEEK_CUR);
*off = TIFFSeekFile(tif, dircount * 12U, SEEK_CUR);
else
(void)TIFFSeekFile(tif, dircount * 12, SEEK_CUR);
(void)TIFFSeekFile(tif, dircount * 12U, SEEK_CUR);
if (!ReadOK(tif, &nextdir32, sizeof(uint32_t)))
{
TIFFErrorExtR(tif, module, "%s: Error fetching directory link",
@@ -1973,7 +2012,6 @@ static int TIFFAdvanceDirectory(TIFF *tif, uint64_t *nextdiroff, uint64_t *off,
else
{
uint64_t dircount64;
uint16_t dircount16;
if (!SeekOK(tif, *nextdiroff) ||
!ReadOK(tif, &dircount64, sizeof(uint64_t)))
{
@@ -1991,11 +2029,10 @@ static int TIFFAdvanceDirectory(TIFF *tif, uint64_t *nextdiroff, uint64_t *off,
__FILE__, __LINE__, tif->tif_name);
return (0);
}
dircount16 = (uint16_t)dircount64;
if (off != NULL)
*off = TIFFSeekFile(tif, dircount16 * 20, SEEK_CUR);
*off = TIFFSeekFile(tif, dircount64 * 20, SEEK_CUR);
else
(void)TIFFSeekFile(tif, dircount16 * 20, SEEK_CUR);
(void)TIFFSeekFile(tif, dircount64 * 20, SEEK_CUR);
if (!ReadOK(tif, nextdiroff, sizeof(uint64_t)))
{
TIFFErrorExtR(tif, module, "%s: Error fetching directory link",
@@ -2354,8 +2391,6 @@ int TIFFUnlinkDirectory(TIFF *tif, tdir_t dirn)
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;
tif->tif_curdir = TIFF_NON_EXISTENT_DIR_NUMBER;
if (tif->tif_curdircount > 0)
tif->tif_curdircount--;

View File

@@ -104,6 +104,16 @@ typedef struct
uint16_t td_halftonehints[2];
uint16_t td_extrasamples;
uint16_t *td_sampleinfo;
/* strip support */
uint32_t td_row; /* current scanline */
uint32_t td_curstrip; /* current strip for read/write */
tmsize_t td_scanlinesize; /* # of bytes in a scanline */
#define NOSTRIP ((uint32_t)(-1)) /* undefined state */
/* tiling support */
uint32_t td_col; /* current column (offset by row too) */
uint32_t td_curtile; /* current tile for read/write */
tmsize_t td_tilesize; /* # of bytes in a tile */
#define NOTILE ((uint32_t)(-1)) /* undefined state */
/* even though the name is misleading, td_stripsperimage is the number
* of striles (=strips or tiles) per plane, and td_nstrips the total
* number of striles */
@@ -164,6 +174,8 @@ typedef struct
entries. */
} TIFFDirectory;
extern void _TIFFResetTifDirAndInitStrileCounters(TIFFDirectory *td);
/*
* Field flags used to indicate fields that have been set in a directory, and
* to reference fields when manipulating a directory.
@@ -231,7 +243,7 @@ typedef struct
#define FIELD_LAST (32 * FIELDSET_ITEMS - 1)
#define BITn(n) (((uint32_t)1L) << ((n)&0x1f))
#define BITn(n) (1U << ((n) & 0x1f))
#define BITFIELDn(tif, n) ((tif)->tif_dir.td_fieldsset[(n) / 32])
#define TIFFFieldSet(tif, field) (BITFIELDn(tif, field) & BITn(field))
#define TIFFSetFieldBit(tif, field) (BITFIELDn(tif, field) |= BITn(field))
@@ -340,7 +352,7 @@ extern "C"
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 */
const char *field_name; /* ASCII name */
TIFFFieldArray *field_subfields; /* if field points to child ifds, child
ifd field definition array */
};

View File

@@ -40,17 +40,47 @@
* values accordingly.
*/
/* const object should be initialized */
#ifdef _MSC_VER
/* Forward declarations - definition follows after field arrays.
* Note: In C, we can forward declare static const objects and define them
* later. In C++, we need extern for the declaration, then define without
* extern. Since these are only used within this file via pointers, we use a
* workaround that works in both C and C++: declare as extern here, define as
* static later, but actually we need a different approach for C++
* compatibility.
*
* For C/C++ compatibility, we define a simple struct that holds the pointer
* and initialize it after the arrays are defined.
*/
#ifdef __cplusplus
/* C++ doesn't allow forward declaration of const objects, so we use extern */
extern const TIFFFieldArray tiffFieldArray;
extern const TIFFFieldArray exifFieldArray;
extern const TIFFFieldArray gpsFieldArray;
#else
/* C allows forward declaration of const objects, but C++ doesn't.
* We disable the C++-compat warning for this section since these circular
* dependencies are unavoidable with static initialization. */
#if defined(__GNUC__) && !defined(__clang__)
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wc++-compat"
#elif defined(__clang__)
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wc++-compat"
#elif defined(_MSC_VER)
#pragma warning(push)
#pragma warning(disable : 4132)
#endif
static const TIFFFieldArray tiffFieldArray;
static const TIFFFieldArray exifFieldArray;
static const TIFFFieldArray gpsFieldArray;
#ifdef _MSC_VER
#if defined(__GNUC__) && !defined(__clang__)
#pragma GCC diagnostic pop
#elif defined(__clang__)
#pragma clang diagnostic pop
#elif defined(_MSC_VER)
#pragma warning(pop)
#endif
#endif
/*--: Rational2Double: --
* The Rational2Double upgraded libtiff functionality allows the definition and
* achievement of true double-precision accuracy for TIFF tags of RATIONAL type
@@ -152,9 +182,9 @@ static const TIFFField tiffFields[] = {
/*--: 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 or a 64-bit value and the TIFF_IFD8 type-id into BigTIFF files. */
{TIFFTAG_EXIFIFD, 1, 1, TIFF_IFD8, 0, TIFF_SETGET_IFD8, FIELD_CUSTOM, 1, 0, "EXIFIFDOffset", (TIFFFieldArray *)&exifFieldArray},
{TIFFTAG_EXIFIFD, 1, 1, TIFF_LONG8, 0, TIFF_SETGET_UINT64, FIELD_CUSTOM, 1, 0, "EXIFIFDOffset", (TIFFFieldArray *)&exifFieldArray},
{TIFFTAG_ICCPROFILE, -3, -3, TIFF_UNDEFINED, 0, TIFF_SETGET_C32_UINT8, FIELD_CUSTOM, 1, 1, "ICC Profile", NULL},
{TIFFTAG_GPSIFD, 1, 1, TIFF_IFD8, 0, TIFF_SETGET_IFD8, FIELD_CUSTOM, 1, 0, "GPSIFDOffset", (TIFFFieldArray *)&gpsFieldArray},
{TIFFTAG_GPSIFD, 1, 1, TIFF_LONG8, 0, TIFF_SETGET_UINT64, FIELD_CUSTOM, 1, 0, "GPSIFDOffset", (TIFFFieldArray *)&gpsFieldArray},
{TIFFTAG_FAXRECVPARAMS, 1, 1, TIFF_LONG, 0, TIFF_SETGET_UINT32, FIELD_CUSTOM, TRUE, FALSE, "FaxRecvParams", NULL},
{TIFFTAG_FAXSUBADDRESS, -1, -1, TIFF_ASCII, 0, TIFF_SETGET_ASCII, FIELD_CUSTOM, TRUE, FALSE, "FaxSubAddress", NULL},
{TIFFTAG_FAXRECVTIME, 1, 1, TIFF_LONG, 0, TIFF_SETGET_UINT32, FIELD_CUSTOM, TRUE, FALSE, "FaxRecvTime", NULL},
@@ -479,12 +509,36 @@ static const TIFFField gpsFields[] = {
{GPSTAG_GPSHPOSITIONINGERROR, 1, 1, TIFF_RATIONAL, 0, TIFF_SETGET_DOUBLE, FIELD_CUSTOM, 1, 0, "HorizontalPositioningError", NULL}};
/* clang-format on */ /* was off for better readability of tag comments */
#ifdef __cplusplus
/* In C++, the forward declaration used extern, so definitions must not be
* static */
const TIFFFieldArray tiffFieldArray = {
tfiatImage, 0, TIFFArrayCount(tiffFields), (TIFFField *)tiffFields};
const TIFFFieldArray exifFieldArray = {tfiatExif, 0, TIFFArrayCount(exifFields),
(TIFFField *)exifFields};
const TIFFFieldArray gpsFieldArray = {tfiatGps, 0, TIFFArrayCount(gpsFields),
(TIFFField *)gpsFields};
#else
/* Suppress C++-compat warning for the definitions as well */
#if defined(__GNUC__) && !defined(__clang__)
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wc++-compat"
#elif defined(__clang__)
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wc++-compat"
#endif
static const TIFFFieldArray tiffFieldArray = {
tfiatImage, 0, TIFFArrayCount(tiffFields), (TIFFField *)tiffFields};
static const TIFFFieldArray exifFieldArray = {
tfiatExif, 0, TIFFArrayCount(exifFields), (TIFFField *)exifFields};
static const TIFFFieldArray gpsFieldArray = {
tfiatGps, 0, TIFFArrayCount(gpsFields), (TIFFField *)gpsFields};
#if defined(__GNUC__) && !defined(__clang__)
#pragma GCC diagnostic pop
#elif defined(__clang__)
#pragma clang diagnostic pop
#endif
#endif
/*
* We have our own local lfind() equivalent to avoid subtle differences
@@ -523,7 +577,7 @@ void _TIFFSetupFields(TIFF *tif, const TIFFFieldArray *fieldarray)
{
if (fld->field_bit == FIELD_CUSTOM && TIFFFieldIsAnonymous(fld))
{
_TIFFfreeExt(tif, fld->field_name);
_TIFFfreeExt(tif, (void *)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().
@@ -579,22 +633,26 @@ int _TIFFMergeFields(TIFF *tif, const TIFFField info[], uint32_t n)
tif->tif_foundfield = NULL;
TIFFField **tif_newfields = NULL;
if (tif->tif_fields && tif->tif_nfields > 0)
{
tif->tif_fields = (TIFFField **)_TIFFCheckRealloc(
tif, tif->tif_fields, (tif->tif_nfields + n), sizeof(TIFFField *),
reason);
tif_newfields = (TIFFField **)_TIFFCheckRealloc(
tif, tif->tif_fields, (tmsize_t)tif->tif_nfields + n,
(tmsize_t)sizeof(TIFFField *), reason);
}
else
{
tif->tif_fields =
tif_newfields =
(TIFFField **)_TIFFCheckMalloc(tif, n, sizeof(TIFFField *), reason);
}
if (!tif->tif_fields)
if (!tif_newfields)
{
tif->tif_nfields = 0;
TIFFErrorExtR(tif, module, "Failed to allocate fields array");
return 0;
}
tif->tif_fields = tif_newfields;
/* tp = tif->tif_fields + tif->tif_nfields; */
for (i = 0; i < n; i++)
@@ -612,7 +670,7 @@ int _TIFFMergeFields(TIFF *tif, const TIFFField info[], uint32_t n)
/* Sort the field info by tag number */
qsort(tif->tif_fields, tif->tif_nfields, sizeof(TIFFField *), tagCompare);
return n;
return (int)n;
}
void _TIFFPrintFieldInfo(TIFF *tif, FILE *fd)
@@ -623,7 +681,7 @@ void _TIFFPrintFieldInfo(TIFF *tif, FILE *fd)
for (i = 0; i < tif->tif_nfields; i++)
{
const TIFFField *fip = tif->tif_fields[i];
fprintf(fd, "field[%2d] %5lu, %2d, %2d, %d, %2d, %5s, %5s, %s\n",
fprintf(fd, "field[%2d] %5lu, %2d, %2d, %u, %2d, %5s, %5s, %s\n",
(int)i, (unsigned long)fip->field_tag, fip->field_readcount,
fip->field_writecount, fip->field_type, fip->field_bit,
fip->field_oktochange ? "TRUE" : "FALSE",
@@ -787,6 +845,34 @@ int TIFFFieldSetGetCountSize(const TIFFField *fip)
case TIFF_SETGET_C32_DOUBLE:
case TIFF_SETGET_C32_IFD8:
return 4;
case TIFF_SETGET_UNDEFINED:
case TIFF_SETGET_ASCII:
case TIFF_SETGET_UINT8:
case TIFF_SETGET_SINT8:
case TIFF_SETGET_UINT16:
case TIFF_SETGET_SINT16:
case TIFF_SETGET_UINT32:
case TIFF_SETGET_SINT32:
case TIFF_SETGET_UINT64:
case TIFF_SETGET_SINT64:
case TIFF_SETGET_FLOAT:
case TIFF_SETGET_DOUBLE:
case TIFF_SETGET_IFD8:
case TIFF_SETGET_INT:
case TIFF_SETGET_UINT16_PAIR:
case TIFF_SETGET_C0_ASCII:
case TIFF_SETGET_C0_UINT8:
case TIFF_SETGET_C0_SINT8:
case TIFF_SETGET_C0_UINT16:
case TIFF_SETGET_C0_SINT16:
case TIFF_SETGET_C0_UINT32:
case TIFF_SETGET_C0_SINT32:
case TIFF_SETGET_C0_UINT64:
case TIFF_SETGET_C0_SINT64:
case TIFF_SETGET_C0_FLOAT:
case TIFF_SETGET_C0_DOUBLE:
case TIFF_SETGET_C0_IFD8:
case TIFF_SETGET_OTHER:
default:
return 0;
}
@@ -794,7 +880,8 @@ int TIFFFieldSetGetCountSize(const TIFFField *fip)
const TIFFField *TIFFFindField(TIFF *tif, uint32_t tag, TIFFDataType dt)
{
TIFFField key = {0, 0, 0, TIFF_NOTYPE, 0, 0, 0, 0, 0, NULL, NULL};
TIFFField key = {0, 0, 0, TIFF_NOTYPE, 0, TIFF_SETGET_UNDEFINED,
0, 0, 0, NULL, NULL};
TIFFField *pkey = &key;
const TIFFField **ret;
if (tif->tif_foundfield && tif->tif_foundfield->field_tag == tag &&
@@ -818,7 +905,8 @@ const TIFFField *TIFFFindField(TIFF *tif, uint32_t tag, TIFFDataType dt)
static const TIFFField *_TIFFFindFieldByName(TIFF *tif, const char *field_name,
TIFFDataType dt)
{
TIFFField key = {0, 0, 0, TIFF_NOTYPE, 0, 0, 0, 0, 0, NULL, NULL};
TIFFField key = {0, 0, 0, TIFF_NOTYPE, 0, TIFF_SETGET_UNDEFINED,
0, 0, 0, NULL, NULL};
TIFFField *pkey = &key;
const TIFFField **ret;
if (tif->tif_foundfield &&
@@ -876,7 +964,10 @@ int TIFFFieldReadCount(const TIFFField *fip) { return fip->field_readcount; }
int TIFFFieldWriteCount(const TIFFField *fip) { return fip->field_writecount; }
int TIFFFieldIsAnonymous(const TIFFField *fip) { return fip->field_anonymous; }
int TIFFFieldIsAnonymous(const TIFFField *fip)
{
return (int)fip->field_anonymous;
}
const TIFFField *_TIFFFindOrRegisterField(TIFF *tif, uint32_t tag,
TIFFDataType dt)
@@ -954,6 +1045,7 @@ TIFFField *_TIFFCreateAnonField(TIFF *tif, uint32_t tag,
case TIFF_SLONG8:
fld->set_get_field_type = TIFF_SETGET_C32_SINT64;
break;
case TIFF_NOTYPE:
default:
fld->set_get_field_type = TIFF_SETGET_UNDEFINED;
break;
@@ -961,8 +1053,8 @@ TIFFField *_TIFFCreateAnonField(TIFF *tif, uint32_t tag,
fld->field_bit = FIELD_CUSTOM;
fld->field_oktochange = TRUE;
fld->field_passcount = TRUE;
fld->field_name = (char *)_TIFFmallocExt(tif, 32);
if (fld->field_name == NULL)
char *field_name_buf = (char *)_TIFFmallocExt(tif, 32);
if (field_name_buf == NULL)
{
_TIFFfreeExt(tif, fld);
return NULL;
@@ -975,7 +1067,8 @@ TIFFField *_TIFFCreateAnonField(TIFF *tif, uint32_t tag,
* Update:
* This special sign is replaced by fld->field_anonymous flag.
*/
(void)snprintf(fld->field_name, 32, "Tag %d", (int)tag);
(void)snprintf(field_name_buf, 32, "Tag %d", (int)tag);
fld->field_name = field_name_buf;
return fld;
}
@@ -1025,6 +1118,7 @@ static TIFFSetGetFieldType _TIFFSetGetType(TIFFDataType type, short count,
return TIFF_SETGET_UINT64;
case TIFF_SLONG8:
return TIFF_SETGET_SINT64;
case TIFF_NOTYPE:
default:
return TIFF_SETGET_UNDEFINED;
}
@@ -1062,6 +1156,7 @@ static TIFFSetGetFieldType _TIFFSetGetType(TIFFDataType type, short count,
return TIFF_SETGET_C0_UINT64;
case TIFF_SLONG8:
return TIFF_SETGET_C0_SINT64;
case TIFF_NOTYPE:
default:
return TIFF_SETGET_UNDEFINED;
}
@@ -1099,6 +1194,7 @@ static TIFFSetGetFieldType _TIFFSetGetType(TIFFDataType type, short count,
return TIFF_SETGET_C16_UINT64;
case TIFF_SLONG8:
return TIFF_SETGET_C16_SINT64;
case TIFF_NOTYPE:
default:
return TIFF_SETGET_UNDEFINED;
}
@@ -1136,6 +1232,7 @@ static TIFFSetGetFieldType _TIFFSetGetType(TIFFDataType type, short count,
return TIFF_SETGET_C32_UINT64;
case TIFF_SLONG8:
return TIFF_SETGET_C32_SINT64;
case TIFF_NOTYPE:
default:
return TIFF_SETGET_UNDEFINED;
}
@@ -1152,22 +1249,25 @@ int TIFFMergeFieldInfo(TIFF *tif, const TIFFFieldInfo info[], uint32_t n)
size_t nfields;
uint32_t i;
TIFFFieldArray *tif_newfieldscompat = NULL;
if (tif->tif_nfieldscompat > 0)
{
tif->tif_fieldscompat = (TIFFFieldArray *)_TIFFCheckRealloc(
tif, tif->tif_fieldscompat, tif->tif_nfieldscompat + 1,
sizeof(TIFFFieldArray), reason);
tif_newfieldscompat = (TIFFFieldArray *)_TIFFCheckRealloc(
tif, tif->tif_fieldscompat, (tmsize_t)tif->tif_nfieldscompat + 1,
(tmsize_t)sizeof(TIFFFieldArray), reason);
}
else
{
tif->tif_fieldscompat = (TIFFFieldArray *)_TIFFCheckMalloc(
tif_newfieldscompat = (TIFFFieldArray *)_TIFFCheckMalloc(
tif, 1, sizeof(TIFFFieldArray), reason);
}
if (!tif->tif_fieldscompat)
if (!tif_newfieldscompat)
{
TIFFErrorExtR(tif, module, "Failed to allocate fields array");
return -1;
}
tif->tif_fieldscompat = tif_newfieldscompat;
nfields = tif->tif_nfieldscompat++;
tif->tif_fieldscompat[nfields].type = tfiatOther;
@@ -1309,6 +1409,8 @@ int _TIFFCheckFieldIsValidForCodec(TIFF *tif, ttag_t tag)
case TIFFTAG_JPEGPROC:
case TIFFTAG_JPEGRESTARTINTERVAL:
return 1;
default:
break;
}
break;
case COMPRESSION_CCITTRLE:
@@ -1329,6 +1431,8 @@ int _TIFFCheckFieldIsValidForCodec(TIFF *tif, ttag_t tag)
if (tif->tif_dir.td_compression == COMPRESSION_CCITTFAX4)
return 1;
break;
default:
break;
}
break;
case COMPRESSION_JBIG:
@@ -1359,6 +1463,8 @@ int _TIFFCheckFieldIsValidForCodec(TIFF *tif, ttag_t tag)
if (tag == TIFFTAG_LERC_PARAMETERS)
return 1;
break;
default:
break;
}
return 0;
}

View File

@@ -597,7 +597,7 @@ TIFFReadDirEntrySshort(TIFF *tif, TIFFDirEntry *direntry, int16_t *value)
err = TIFFReadDirEntryCheckRangeSshortShort(m);
if (err != TIFFReadDirEntryErrOk)
return (err);
*value = (uint16_t)m;
*value = (int16_t)m;
return (TIFFReadDirEntryErrOk);
}
case TIFF_SSHORT:
@@ -695,6 +695,7 @@ TIFFReadDirEntryLong(TIFF *tif, TIFFDirEntry *direntry, uint32_t *value)
return (TIFFReadDirEntryErrOk);
}
case TIFF_LONG:
case TIFF_IFD:
TIFFReadDirEntryCheckedLong(tif, direntry, value);
return (TIFFReadDirEntryErrOk);
case TIFF_SLONG:
@@ -708,6 +709,7 @@ TIFFReadDirEntryLong(TIFF *tif, TIFFDirEntry *direntry, uint32_t *value)
return (TIFFReadDirEntryErrOk);
}
case TIFF_LONG8:
case TIFF_IFD8:
{
uint64_t m;
err = TIFFReadDirEntryCheckedLong8(tif, direntry, &m);
@@ -857,6 +859,7 @@ TIFFReadDirEntryLong8(TIFF *tif, TIFFDirEntry *direntry, uint64_t *value)
return (TIFFReadDirEntryErrOk);
}
case TIFF_LONG:
case TIFF_IFD:
{
uint32_t m;
TIFFReadDirEntryCheckedLong(tif, direntry, &m);
@@ -874,6 +877,7 @@ TIFFReadDirEntryLong8(TIFF *tif, TIFFDirEntry *direntry, uint64_t *value)
return (TIFFReadDirEntryErrOk);
}
case TIFF_LONG8:
case TIFF_IFD8:
err = TIFFReadDirEntryCheckedLong8(tif, direntry, value);
return (err);
case TIFF_SLONG8:
@@ -1058,7 +1062,7 @@ TIFFReadDirEntryFloat(TIFF *tif, TIFFDirEntry *direntry, float *value)
err = TIFFReadDirEntryCheckedDouble(tif, direntry, &m);
if (err != TIFFReadDirEntryErrOk)
return (err);
if ((m > FLT_MAX) || (m < -FLT_MAX))
if ((m > (double)FLT_MAX) || (m < -(double)FLT_MAX))
return (TIFFReadDirEntryErrRange);
*value = (float)m;
return (TIFFReadDirEntryErrOk);
@@ -1237,6 +1241,8 @@ static enum TIFFReadDirEntryErr TIFFReadDirEntryDataAndRealloc(TIFF *tif,
*pdest = new_dest;
bytes_read = TIFFReadFile(tif, (char *)*pdest + already_read, to_read);
if (bytes_read < 0)
return TIFFReadDirEntryErrIo;
already_read += bytes_read;
if (bytes_read != to_read)
{
@@ -1260,7 +1266,7 @@ TIFFReadDirEntryArrayWithLimit(TIFF *tif, TIFFDirEntry *direntry,
void *data;
uint64_t target_count64;
int original_datasize_clamped;
typesize = TIFFDataWidth(direntry->tdir_type);
typesize = TIFFDataWidth((TIFFDataType)direntry->tdir_type);
target_count64 =
(direntry->tdir_count > maxcount) ? maxcount : direntry->tdir_count;
@@ -1284,13 +1290,13 @@ TIFFReadDirEntryArrayWithLimit(TIFF *tif, TIFFDirEntry *direntry,
* 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)(MAX_SIZE_TAG_DATA / typesize) < target_count64)
if ((uint64_t)(MAX_SIZE_TAG_DATA / (unsigned int)typesize) < target_count64)
return (TIFFReadDirEntryErrSizesan);
if ((uint64_t)(MAX_SIZE_TAG_DATA / desttypesize) < target_count64)
return (TIFFReadDirEntryErrSizesan);
*count = (uint32_t)target_count64;
datasize = (*count) * typesize;
datasize = (uint32_t)(*count) * (unsigned int)typesize;
assert((tmsize_t)datasize > 0);
if (datasize > 100 * 1024 * 1024)
@@ -1440,6 +1446,8 @@ TIFFReadDirEntryByteArray(TIFF *tif, TIFFDirEntry *direntry, uint8_t **value)
*value = (uint8_t *)origdata;
return (TIFFReadDirEntryErrOk);
}
default:
break;
}
data = (uint8_t *)_TIFFmallocExt(tif, count);
if (data == 0)
@@ -1557,6 +1565,8 @@ TIFFReadDirEntryByteArray(TIFF *tif, TIFFDirEntry *direntry, uint8_t **value)
}
}
break;
default:
break;
}
_TIFFfreeExt(tif, origdata);
if (err != TIFFReadDirEntryErrOk)
@@ -1620,6 +1630,8 @@ TIFFReadDirEntrySbyteArray(TIFF *tif, TIFFDirEntry *direntry, int8_t **value)
case TIFF_SBYTE:
*value = (int8_t *)origdata;
return (TIFFReadDirEntryErrOk);
default:
break;
}
data = (int8_t *)_TIFFmallocExt(tif, count);
if (data == 0)
@@ -1737,6 +1749,8 @@ TIFFReadDirEntrySbyteArray(TIFF *tif, TIFFDirEntry *direntry, int8_t **value)
}
}
break;
default:
break;
}
_TIFFfreeExt(tif, origdata);
if (err != TIFFReadDirEntryErrOk)
@@ -1802,6 +1816,8 @@ TIFFReadDirEntryShortArray(TIFF *tif, TIFFDirEntry *direntry, uint16_t **value)
*value = (uint16_t *)origdata;
return (TIFFReadDirEntryErrOk);
}
default:
break;
}
data = (uint16_t *)_TIFFmallocExt(tif, count * 2);
if (data == 0)
@@ -1910,6 +1926,8 @@ TIFFReadDirEntryShortArray(TIFF *tif, TIFFDirEntry *direntry, uint16_t **value)
}
}
break;
default:
break;
}
_TIFFfreeExt(tif, origdata);
if (err != TIFFReadDirEntryErrOk)
@@ -1975,6 +1993,8 @@ TIFFReadDirEntrySshortArray(TIFF *tif, TIFFDirEntry *direntry, int16_t **value)
if (tif->tif_flags & TIFF_SWAB)
TIFFSwabArrayOfShort((uint16_t *)(*value), count);
return (TIFFReadDirEntryErrOk);
default:
break;
}
data = (int16_t *)_TIFFmallocExt(tif, count * 2);
if (data == 0)
@@ -2078,6 +2098,8 @@ TIFFReadDirEntrySshortArray(TIFF *tif, TIFFDirEntry *direntry, int16_t **value)
}
}
break;
default:
break;
}
_TIFFfreeExt(tif, origdata);
if (err != TIFFReadDirEntryErrOk)
@@ -2106,6 +2128,8 @@ TIFFReadDirEntryLongArray(TIFF *tif, TIFFDirEntry *direntry, uint32_t **value)
case TIFF_SLONG:
case TIFF_LONG8:
case TIFF_SLONG8:
case TIFF_IFD:
case TIFF_IFD8:
break;
default:
return (TIFFReadDirEntryErrType);
@@ -2119,6 +2143,7 @@ TIFFReadDirEntryLongArray(TIFF *tif, TIFFDirEntry *direntry, uint32_t **value)
switch (direntry->tdir_type)
{
case TIFF_LONG:
case TIFF_IFD:
*value = (uint32_t *)origdata;
if (tif->tif_flags & TIFF_SWAB)
TIFFSwabArrayOfLong(*value, count);
@@ -2143,6 +2168,8 @@ TIFFReadDirEntryLongArray(TIFF *tif, TIFFDirEntry *direntry, uint32_t **value)
*value = (uint32_t *)origdata;
return (TIFFReadDirEntryErrOk);
}
default:
break;
}
data = (uint32_t *)_TIFFmallocExt(tif, count * 4);
if (data == 0)
@@ -2213,6 +2240,7 @@ TIFFReadDirEntryLongArray(TIFF *tif, TIFFDirEntry *direntry, uint32_t **value)
}
break;
case TIFF_LONG8:
case TIFF_IFD8:
{
uint64_t *ma;
uint32_t *mb;
@@ -2248,6 +2276,8 @@ TIFFReadDirEntryLongArray(TIFF *tif, TIFFDirEntry *direntry, uint32_t **value)
}
}
break;
default:
break;
}
_TIFFfreeExt(tif, origdata);
if (err != TIFFReadDirEntryErrOk)
@@ -2313,6 +2343,8 @@ TIFFReadDirEntrySlongArray(TIFF *tif, TIFFDirEntry *direntry, int32_t **value)
if (tif->tif_flags & TIFF_SWAB)
TIFFSwabArrayOfLong((uint32_t *)(*value), count);
return (TIFFReadDirEntryErrOk);
default:
break;
}
data = (int32_t *)_TIFFmallocExt(tif, count * 4);
if (data == 0)
@@ -2410,6 +2442,8 @@ TIFFReadDirEntrySlongArray(TIFF *tif, TIFFDirEntry *direntry, int32_t **value)
}
}
break;
default:
break;
}
_TIFFfreeExt(tif, origdata);
if (err != TIFFReadDirEntryErrOk)
@@ -2439,6 +2473,8 @@ TIFFReadDirEntryLong8ArrayWithLimit(TIFF *tif, TIFFDirEntry *direntry,
case TIFF_SLONG:
case TIFF_LONG8:
case TIFF_SLONG8:
case TIFF_IFD:
case TIFF_IFD8:
break;
default:
return (TIFFReadDirEntryErrType);
@@ -2453,6 +2489,7 @@ TIFFReadDirEntryLong8ArrayWithLimit(TIFF *tif, TIFFDirEntry *direntry,
switch (direntry->tdir_type)
{
case TIFF_LONG8:
case TIFF_IFD8:
*value = (uint64_t *)origdata;
if (tif->tif_flags & TIFF_SWAB)
TIFFSwabArrayOfLong8(*value, count);
@@ -2477,6 +2514,8 @@ TIFFReadDirEntryLong8ArrayWithLimit(TIFF *tif, TIFFDirEntry *direntry,
*value = (uint64_t *)origdata;
return (TIFFReadDirEntryErrOk);
}
default:
break;
}
data = (uint64_t *)_TIFFmallocExt(tif, count * 8);
if (data == 0)
@@ -2547,6 +2586,7 @@ TIFFReadDirEntryLong8ArrayWithLimit(TIFF *tif, TIFFDirEntry *direntry,
}
break;
case TIFF_LONG:
case TIFF_IFD:
{
uint32_t *ma;
uint64_t *mb;
@@ -2579,6 +2619,8 @@ TIFFReadDirEntryLong8ArrayWithLimit(TIFF *tif, TIFFDirEntry *direntry,
}
}
break;
default:
break;
}
_TIFFfreeExt(tif, origdata);
if (err != TIFFReadDirEntryErrOk)
@@ -2651,6 +2693,8 @@ TIFFReadDirEntrySlong8Array(TIFF *tif, TIFFDirEntry *direntry, int64_t **value)
if (tif->tif_flags & TIFF_SWAB)
TIFFSwabArrayOfLong8((uint64_t *)(*value), count);
return (TIFFReadDirEntryErrOk);
default:
break;
}
data = (int64_t *)_TIFFmallocExt(tif, count * 8);
if (data == 0)
@@ -2742,6 +2786,8 @@ TIFFReadDirEntrySlong8Array(TIFF *tif, TIFFDirEntry *direntry, int64_t **value)
}
}
break;
default:
break;
}
_TIFFfreeExt(tif, origdata);
*value = data;
@@ -2787,8 +2833,11 @@ TIFFReadDirEntryFloatArray(TIFF *tif, TIFFDirEntry *direntry, float **value)
TIFFCvtIEEEFloatToNative(tif, count, (float *)origdata);
*value = (float *)origdata;
return (TIFFReadDirEntryErrOk);
default:
break;
}
data = (float *)_TIFFmallocExt(tif, count * sizeof(float));
data =
(float *)_TIFFmallocExt(tif, (tmsize_t)((size_t)count * sizeof(float)));
if (data == 0)
{
_TIFFfreeExt(tif, origdata);
@@ -2970,14 +3019,16 @@ TIFFReadDirEntryFloatArray(TIFF *tif, TIFFDirEntry *direntry, float **value)
for (n = 0; n < count; n++)
{
double val = *ma++;
if (val > FLT_MAX)
val = FLT_MAX;
else if (val < -FLT_MAX)
val = -FLT_MAX;
if (val > (double)FLT_MAX)
val = (double)FLT_MAX;
else if (val < -(double)FLT_MAX)
val = -(double)FLT_MAX;
*mb++ = (float)val;
}
}
break;
default:
break;
}
_TIFFfreeExt(tif, origdata);
*value = data;
@@ -3023,8 +3074,11 @@ TIFFReadDirEntryDoubleArray(TIFF *tif, TIFFDirEntry *direntry, double **value)
TIFFCvtIEEEDoubleToNative(tif, count, (double *)origdata);
*value = (double *)origdata;
return (TIFFReadDirEntryErrOk);
default:
break;
}
data = (double *)_TIFFmallocExt(tif, count * sizeof(double));
data = (double *)_TIFFmallocExt(tif,
(tmsize_t)((size_t)count * sizeof(double)));
if (data == 0)
{
_TIFFfreeExt(tif, origdata);
@@ -3207,6 +3261,8 @@ TIFFReadDirEntryDoubleArray(TIFF *tif, TIFFDirEntry *direntry, double **value)
*mb++ = (double)(*ma++);
}
break;
default:
break;
}
_TIFFfreeExt(tif, origdata);
*value = data;
@@ -3244,6 +3300,8 @@ TIFFReadDirEntryIfd8Array(TIFF *tif, TIFFDirEntry *direntry, uint64_t **value)
if (tif->tif_flags & TIFF_SWAB)
TIFFSwabArrayOfLong8(*value, count);
return (TIFFReadDirEntryErrOk);
default:
break;
}
data = (uint64_t *)_TIFFmallocExt(tif, count * 8);
if (data == 0)
@@ -3269,6 +3327,8 @@ TIFFReadDirEntryIfd8Array(TIFF *tif, TIFFDirEntry *direntry, uint64_t **value)
}
}
break;
default:
break;
}
_TIFFfreeExt(tif, origdata);
*value = data;
@@ -3283,13 +3343,42 @@ TIFFReadDirEntryPersampleShort(TIFF *tif, TIFFDirEntry *direntry,
uint16_t *m;
uint16_t *na;
uint16_t nb;
if (direntry->tdir_count < (uint64_t)tif->tif_dir.td_samplesperpixel)
return (TIFFReadDirEntryErrCount);
if (direntry->tdir_count != (uint64_t)tif->tif_dir.td_samplesperpixel)
{
const TIFFField *fip = TIFFFieldWithTag(tif, direntry->tdir_tag);
if (direntry->tdir_count == 0)
{
return TIFFReadDirEntryErrCount;
}
else if (direntry->tdir_count <
(uint64_t)tif->tif_dir.td_samplesperpixel)
{
TIFFWarningExtR(
tif, "TIFFReadDirEntryPersampleShort",
"Tag %s entry count is %" PRIu64
" , whereas it should be SamplesPerPixel=%d. Assuming that "
"missing entries are all at the value of the first one",
fip ? fip->field_name : "unknown tagname", direntry->tdir_count,
tif->tif_dir.td_samplesperpixel);
}
else
{
TIFFWarningExtR(tif, "TIFFReadDirEntryPersampleShort",
"Tag %s entry count is %" PRIu64
" , whereas it should be SamplesPerPixel=%d. "
"Ignoring extra entries",
fip ? fip->field_name : "unknown tagname",
direntry->tdir_count,
tif->tif_dir.td_samplesperpixel);
}
}
err = TIFFReadDirEntryShortArray(tif, direntry, &m);
if (err != TIFFReadDirEntryErrOk || m == NULL)
return (err);
na = m;
nb = tif->tif_dir.td_samplesperpixel;
if (direntry->tdir_count < nb)
nb = (uint16_t)direntry->tdir_count;
*value = *na++;
nb--;
while (nb > 0)
@@ -3908,7 +3997,7 @@ static enum TIFFReadDirEntryErr TIFFReadDirEntryData(TIFF *tif, uint64_t offset,
{
return TIFFReadDirEntryErrIo;
}
mb = ma + size;
mb = (uint64_t)ma + (uint64_t)size;
if (mb > (uint64_t)tif->tif_size)
return (TIFFReadDirEntryErrIo);
_TIFFmemcpy(dest, tif->tif_base + ma, size);
@@ -3955,6 +4044,7 @@ static void TIFFReadDirEntryOutputErr(TIFF *tif, enum TIFFReadDirEntryErr err,
TIFFErrorExtR(tif, module, "Out of memory reading of \"%s\"",
tagname);
break;
case TIFFReadDirEntryErrOk:
default:
assert(0); /* we should never get here */
break;
@@ -4001,6 +4091,7 @@ static void TIFFReadDirEntryOutputErr(TIFF *tif, enum TIFFReadDirEntryErr err,
"Out of memory reading of \"%s\"; tag ignored",
tagname);
break;
case TIFFReadDirEntryErrOk:
default:
assert(0); /* we should never get here */
break;
@@ -4086,7 +4177,8 @@ static int ByteCountLooksBad(TIFF *tif)
*/
static bool EvaluateIFDdatasizeReading(TIFF *tif, TIFFDirEntry *dp)
{
const uint64_t data_width = TIFFDataWidth(dp->tdir_type);
const uint64_t data_width =
(uint64_t)TIFFDataWidth((TIFFDataType)dp->tdir_type);
if (data_width != 0 && dp->tdir_count > UINT64_MAX / data_width)
{
TIFFErrorExtR(tif, "EvaluateIFDdatasizeReading",
@@ -4173,9 +4265,9 @@ static void CalcFinalIFDdatasizeReading(TIFF *tif, uint16_t dircount)
/* Get offset of end of IFD entry space. */
uint64_t IFDendoffset;
if (!(tif->tif_flags & TIFF_BIGTIFF))
IFDendoffset = tif->tif_diroff + 2 + dircount * 12 + 4;
IFDendoffset = tif->tif_diroff + 2 + (uint64_t)dircount * 12 + 4;
else
IFDendoffset = tif->tif_diroff + 8 + dircount * 20 + 8;
IFDendoffset = tif->tif_diroff + 8 + (uint64_t)dircount * 20 + 8;
/* Check which offsets are right behind IFD entries. However, LibTIFF
* increments the writing address for every external data to an even offset.
@@ -4224,9 +4316,9 @@ static void CalcFinalIFDdatasizeReading(TIFF *tif, uint16_t dircount)
/* Finally, add the size of the IFD tag entries themselves. */
if (!(tif->tif_flags & TIFF_BIGTIFF))
tif->tif_dir.td_dirdatasize_read = 2 + dircount * 12 + 4 + size;
tif->tif_dir.td_dirdatasize_read = 2U + dircount * 12U + 4U + size;
else
tif->tif_dir.td_dirdatasize_read = 8 + dircount * 20 + 8 + size;
tif->tif_dir.td_dirdatasize_read = 8U + dircount * 20U + 8U + size;
} /*-- CalcFinalIFDdatasizeReading() --*/
/*
@@ -4298,7 +4390,8 @@ int TIFFReadDirectory(TIFF *tif)
{
TIFFDirEntry *na;
uint16_t nb;
for (na = ma + 1, nb = mb + 1; nb < dircount; na++, nb++)
for (na = ma + 1, nb = (uint16_t)(mb + 1); nb < dircount;
na++, nb++)
{
if (ma->tdir_tag == na->tdir_tag)
{
@@ -4312,7 +4405,15 @@ int TIFFReadDirectory(TIFF *tif)
tif->tif_flags &= ~TIFF_BUF4WRITE; /* reset before new dir */
tif->tif_flags &= ~TIFF_CHOPPEDUPARRAYS;
/* free any old stuff and reinit */
/* When changing directory, in deferred strile loading mode, we must also
* unset the TIFF_LAZYSTRILELOAD_DONE bit if it was initially set,
* to make sure the strile offset/bytecount are read again (when they fit
* in the tag data area).
*/
tif->tif_flags &= ~TIFF_LAZYSTRILELOAD_DONE;
/* Free any old stuff and reinit i/o and other parameters within
* TIFFDefaultDirectory() since we are starting on a new directory. */
TIFFFreeDirectory(tif);
TIFFDefaultDirectory(tif);
@@ -4325,7 +4426,8 @@ int TIFFReadDirectory(TIFF *tif)
* checking. Note: Counter are reset within TIFFFreeDirectory(). */
tif->tif_dir.td_dirdatasize_offsets =
(TIFFEntryOffsetAndLength *)_TIFFmallocExt(
tif, dircount * sizeof(TIFFEntryOffsetAndLength));
tif,
(tmsize_t)((size_t)dircount * sizeof(TIFFEntryOffsetAndLength)));
if (tif->tif_dir.td_dirdatasize_offsets == NULL)
{
TIFFErrorExtR(
@@ -4788,8 +4890,8 @@ int TIFFReadDirectory(TIFF *tif)
(void)TIFFFetchNormalTag(tif, dp, TRUE);
break;
} /* -- switch (dp->tdir_tag) -- */
} /* -- if (!dp->tdir_ignore) */
} /* -- for-loop -- */
} /* -- if (!dp->tdir_ignore) */
} /* -- for-loop -- */
/* Evaluate final IFD data size. */
CalcFinalIFDdatasizeReading(tif, dircount);
@@ -5098,7 +5200,7 @@ int TIFFReadDirectory(TIFF *tif)
tif->tif_dir.td_maxsamplevalue = 0xFFFF;
else
tif->tif_dir.td_maxsamplevalue =
(uint16_t)((1L << tif->tif_dir.td_bitspersample) - 1);
(uint16_t)((1 << tif->tif_dir.td_bitspersample) - 1);
}
#ifdef STRIPBYTECOUNTSORTED_UNUSED
@@ -5164,16 +5266,10 @@ int TIFFReadDirectory(TIFF *tif)
tif->tif_flags &= ~TIFF_DIRTYSTRIP;
/*
* Reinitialize i/o since we are starting on a new directory.
* Reinitialize some further i/o since we are starting on a new directory.
*/
tif->tif_row = (uint32_t)-1;
tif->tif_curstrip = (uint32_t)-1;
tif->tif_col = (uint32_t)-1;
tif->tif_curtile = (uint32_t)-1;
tif->tif_tilesize = (tmsize_t)-1;
tif->tif_scanlinesize = TIFFScanlineSize(tif);
if (!tif->tif_scanlinesize)
tif->tif_dir.td_scanlinesize = TIFFScanlineSize(tif);
if (!tif->tif_dir.td_scanlinesize)
{
TIFFErrorExtR(tif, module, "Cannot handle zero scanline size");
return (0);
@@ -5181,8 +5277,8 @@ int TIFFReadDirectory(TIFF *tif)
if (isTiled(tif))
{
tif->tif_tilesize = TIFFTileSize(tif);
if (!tif->tif_tilesize)
tif->tif_dir.td_tilesize = TIFFTileSize(tif);
if (!tif->tif_dir.td_tilesize)
{
TIFFErrorExtR(tif, module, "Cannot handle zero tile size");
return (0);
@@ -5220,7 +5316,7 @@ static void TIFFReadDirectoryCheckOrder(TIFF *tif, TIFFDirEntry *dir,
"ascending order");
break;
}
m = o->tdir_tag + 1;
m = o->tdir_tag + 1U;
}
}
@@ -5268,7 +5364,7 @@ static void TIFFReadDirectoryFindFieldInfo(TIFF *tif, uint16_t tagid,
break;
mb--;
}
*fii = mb;
*fii = (uint32_t)mb;
}
/*
@@ -5308,7 +5404,8 @@ int TIFFReadCustomDirectory(TIFF *tif, toff_t diroff,
{
TIFFDirEntry *na;
uint16_t nb;
for (na = ma + 1, nb = mb + 1; nb < dircount; na++, nb++)
for (na = ma + 1, nb = (uint16_t)(mb + 1); nb < dircount;
na++, nb++)
{
if (ma->tdir_tag == na->tdir_tag)
{
@@ -5333,7 +5430,8 @@ int TIFFReadCustomDirectory(TIFF *tif, toff_t diroff,
* checking. Note: Counter are reset within TIFFFreeDirectory(). */
tif->tif_dir.td_dirdatasize_offsets =
(TIFFEntryOffsetAndLength *)_TIFFmallocExt(
tif, dircount * sizeof(TIFFEntryOffsetAndLength));
tif,
(tmsize_t)((size_t)dircount * sizeof(TIFFEntryOffsetAndLength)));
if (tif->tif_dir.td_dirdatasize_offsets == NULL)
{
TIFFErrorExtR(
@@ -5515,15 +5613,17 @@ static int EstimateStripByteCounts(TIFF *tif, TIFFDirEntry *dir,
uint64_t space;
uint16_t n;
if (!(tif->tif_flags & TIFF_BIGTIFF))
space = sizeof(TIFFHeaderClassic) + 2 + dircount * 12 + 4;
space = sizeof(TIFFHeaderClassic) + 2 +
(unsigned long)dircount * 12 + 4;
else
space = sizeof(TIFFHeaderBig) + 8 + dircount * 20 + 8;
space =
sizeof(TIFFHeaderBig) + 8 + (unsigned long)dircount * 20 + 8;
/* calculate amount of space used by indirect values */
for (dp = dir, n = dircount; n > 0; n--, dp++)
{
uint32_t typewidth;
uint64_t datasize;
typewidth = TIFFDataWidth((TIFFDataType)dp->tdir_type);
typewidth = (uint32_t)TIFFDataWidth((TIFFDataType)dp->tdir_type);
if (typewidth == 0)
{
TIFFErrorExtR(
@@ -5786,7 +5886,7 @@ int _TIFFCheckDirNumberAndOffset(TIFF *tif, tdir_t dirn, uint64_t diroff)
{
TIFFErrorExtR(tif, "_TIFFCheckDirNumberAndOffset",
"Cannot handle more than %u TIFF directories",
TIFF_MAX_DIR_COUNT);
(unsigned)TIFF_MAX_DIR_COUNT);
return 0;
}
@@ -6048,7 +6148,7 @@ static uint16_t TIFFFetchDirectory(TIFF *tif, uint64_t diroff,
"to read TIFF directory");
if (origdir == NULL)
return 0;
if (!ReadOK(tif, origdir, (tmsize_t)(dircount16 * dirsize)))
if (!ReadOK(tif, origdir, (tmsize_t)dircount16 * dirsize))
{
TIFFErrorExtR(tif, module, "%.100s: Can not read TIFF directory",
tif->tif_name);
@@ -6101,9 +6201,9 @@ static uint16_t TIFFFetchDirectory(TIFF *tif, uint64_t diroff,
*/
if (!(tif->tif_flags & TIFF_BIGTIFF))
{
m = off + sizeof(uint16_t);
if ((m < off) || (m < (tmsize_t)sizeof(uint16_t)) ||
(m > tif->tif_size))
m = (tmsize_t)((uint64_t)off + sizeof(uint16_t));
if ((m < off) || ((uint64_t)m < sizeof(uint16_t)) ||
((uint64_t)m > (uint64_t)tif->tif_size))
{
TIFFErrorExtR(tif, module, "Can not read TIFF directory count");
return 0;
@@ -6112,7 +6212,7 @@ static uint16_t TIFFFetchDirectory(TIFF *tif, uint64_t diroff,
{
_TIFFmemcpy(&dircount16, tif->tif_base + off, sizeof(uint16_t));
}
off += sizeof(uint16_t);
off = (tmsize_t)((uint64_t)off + sizeof(uint16_t));
if (tif->tif_flags & TIFF_SWAB)
TIFFSwabShort(&dircount16);
if (dircount16 > 4096)
@@ -6127,9 +6227,9 @@ static uint16_t TIFFFetchDirectory(TIFF *tif, uint64_t diroff,
else
{
uint64_t dircount64;
m = off + sizeof(uint64_t);
if ((m < off) || (m < (tmsize_t)sizeof(uint64_t)) ||
(m > tif->tif_size))
m = (tmsize_t)((uint64_t)off + sizeof(uint64_t));
if ((m < off) || ((uint64_t)m < sizeof(uint64_t)) ||
((uint64_t)m > (uint64_t)tif->tif_size))
{
TIFFErrorExtR(tif, module, "Can not read TIFF directory count");
return 0;
@@ -6138,7 +6238,7 @@ static uint16_t TIFFFetchDirectory(TIFF *tif, uint64_t diroff,
{
_TIFFmemcpy(&dircount64, tif->tif_base + off, sizeof(uint64_t));
}
off += sizeof(uint64_t);
off = (tmsize_t)((uint64_t)off + sizeof(uint64_t));
if (tif->tif_flags & TIFF_SWAB)
TIFFSwabLong8(&dircount64);
if (dircount64 > 4096)
@@ -6177,7 +6277,7 @@ static uint16_t TIFFFetchDirectory(TIFF *tif, uint64_t diroff,
if (origdir == NULL)
return 0;
m = off + dircount16 * dirsize;
if ((m < off) || (m < (tmsize_t)(dircount16 * dirsize)) ||
if ((m < off) || (m < (tmsize_t)dircount16 * (tmsize_t)dirsize) ||
(m > tif->tif_size))
{
TIFFErrorExtR(tif, module, "Can not read TIFF directory");
@@ -6186,7 +6286,8 @@ static uint16_t TIFFFetchDirectory(TIFF *tif, uint64_t diroff,
}
else
{
_TIFFmemcpy(origdir, tif->tif_base + off, dircount16 * dirsize);
_TIFFmemcpy(origdir, tif->tif_base + off,
(tmsize_t)dircount16 * dirsize);
}
if (nextdiroff)
{
@@ -6194,9 +6295,9 @@ static uint16_t TIFFFetchDirectory(TIFF *tif, uint64_t diroff,
if (!(tif->tif_flags & TIFF_BIGTIFF))
{
uint32_t nextdiroff32;
m = off + sizeof(uint32_t);
if ((m < off) || (m < (tmsize_t)sizeof(uint32_t)) ||
(m > tif->tif_size))
m = (tmsize_t)((uint64_t)off + sizeof(uint32_t));
if ((m < off) || ((uint64_t)m < sizeof(uint32_t)) ||
((uint64_t)m > (uint64_t)tif->tif_size))
nextdiroff32 = 0;
else
_TIFFmemcpy(&nextdiroff32, tif->tif_base + off,
@@ -6207,9 +6308,9 @@ static uint16_t TIFFFetchDirectory(TIFF *tif, uint64_t diroff,
}
else
{
m = off + sizeof(uint64_t);
if ((m < off) || (m < (tmsize_t)sizeof(uint64_t)) ||
(m > tif->tif_size))
m = (tmsize_t)((uint64_t)off + sizeof(uint64_t));
if ((m < off) || ((uint64_t)m < sizeof(uint64_t)) ||
((uint64_t)m > (uint64_t)tif->tif_size))
*nextdiroff = 0;
else
_TIFFmemcpy(nextdiroff, tif->tif_base + off,
@@ -6355,8 +6456,8 @@ static int TIFFFetchNormalTag(TIFF *tif, TIFFDirEntry *dp, int recover)
/* TIFFReadDirEntryArrayWithLimit() ensures this can't be
* larger than MAX_SIZE_TAG_DATA */
assert((uint32_t)dp->tdir_count + 1 == dp->tdir_count + 1);
uint8_t *o =
_TIFFmallocExt(tif, (uint32_t)dp->tdir_count + 1);
uint8_t *o = (uint8_t *)_TIFFmallocExt(
tif, (uint32_t)dp->tdir_count + 1);
if (o == NULL)
{
if (data != NULL)
@@ -6498,7 +6599,7 @@ static int TIFFFetchNormalTag(TIFF *tif, TIFFDirEntry *dp, int recover)
{
if (!EvaluateIFDdatasizeReading(tif, dp))
return 0;
if (!TIFFSetField(tif, dp->tdir_tag, data))
if (!TIFFSetField(tif, dp->tdir_tag, (double)data))
return (0);
}
}
@@ -6910,6 +7011,41 @@ static int TIFFFetchNormalTag(TIFF *tif, TIFFDirEntry *dp, int recover)
}
}
break;
case TIFF_SETGET_C0_IFD8:
{
uint64_t *data;
assert(fip->field_readcount >= 1);
assert(fip->field_passcount == 0);
if (dp->tdir_count != (uint64_t)fip->field_readcount)
{
TIFFWarningExtR(tif, module,
"incorrect count for field \"%s\", expected "
"%d, got %" PRIu64,
fip->field_name, (int)fip->field_readcount,
dp->tdir_count);
return (0);
}
else
{
err = TIFFReadDirEntryIfd8Array(tif, dp, &data);
if (err == TIFFReadDirEntryErrOk)
{
if (!EvaluateIFDdatasizeReading(tif, dp))
{
if (data != 0)
_TIFFfreeExt(tif, data);
return 0;
}
int m;
m = TIFFSetField(tif, dp->tdir_tag, data);
if (data != 0)
_TIFFfreeExt(tif, data);
if (!m)
return (0);
}
}
}
break;
case TIFF_SETGET_C16_ASCII:
{
uint8_t *data;
@@ -6938,8 +7074,8 @@ static int TIFFFetchNormalTag(TIFF *tif, TIFFDirEntry *dp, int recover)
"byte. Forcing it to be null",
fip->field_name);
/* Enlarge buffer and add terminating null. */
uint8_t *o =
_TIFFmallocExt(tif, (uint32_t)dp->tdir_count + 1);
uint8_t *o = (uint8_t *)_TIFFmallocExt(
tif, (uint32_t)dp->tdir_count + 1);
if (o == NULL)
{
if (data != NULL)
@@ -7309,8 +7445,8 @@ static int TIFFFetchNormalTag(TIFF *tif, TIFFDirEntry *dp, int recover)
"in null byte. Forcing it to be null",
fip->field_name);
/* Enlarge buffer and add terminating null. */
uint8_t *o =
_TIFFmallocExt(tif, (uint32_t)dp->tdir_count + 1);
uint8_t *o = (uint8_t *)_TIFFmallocExt(
tif, (uint32_t)dp->tdir_count + 1);
if (o == NULL)
{
if (data != NULL)
@@ -7624,6 +7760,11 @@ static int TIFFFetchNormalTag(TIFF *tif, TIFFDirEntry *dp, int recover)
}
}
break;
case TIFF_SETGET_INT:
case TIFF_SETGET_C0_ASCII:
case TIFF_SETGET_OTHER:
assert(0); /* these should not arrive here */
break;
default:
assert(0); /* we should never get here */
break;
@@ -7700,9 +7841,10 @@ static int TIFFFetchStripThing(TIFF *tif, TIFFDirEntry *dir, uint32_t nstrips,
}
if (dir->tdir_count)
_TIFFmemcpy(resizeddata, data,
(uint32_t)dir->tdir_count * sizeof(uint64_t));
(tmsize_t)((size_t)dir->tdir_count * sizeof(uint64_t)));
_TIFFmemset(resizeddata + (uint32_t)dir->tdir_count, 0,
(nstrips - (uint32_t)dir->tdir_count) * sizeof(uint64_t));
(tmsize_t)((size_t)(nstrips - (uint32_t)dir->tdir_count) *
sizeof(uint64_t)));
_TIFFfreeExt(tif, data);
data = resizeddata;
}
@@ -7866,7 +8008,7 @@ static void allocChoppedUpStripArrays(TIFF *tif, uint32_t nstrips,
*/
static void ChopUpSingleUncompressedStrip(TIFF *tif)
{
register TIFFDirectory *td = &tif->tif_dir;
TIFFDirectory *td = &tif->tif_dir;
uint64_t bytecount;
uint64_t offset;
uint32_t rowblock;
@@ -7881,7 +8023,7 @@ static void ChopUpSingleUncompressedStrip(TIFF *tif)
/* later ( StripOffsets and StripByteCounts improperly filled) . */
if (bytecount == 0 && tif->tif_mode != O_RDONLY)
return;
offset = TIFFGetStrileByteCount(tif, 0);
offset = TIFFGetStrileOffset(tif, 0);
assert(td->td_planarconfig == PLANARCONFIG_CONTIG);
if ((td->td_photometric == PHOTOMETRIC_YCBCR) && (!isUpSampled(tif)))
rowblock = td->td_ycbcrsubsampling[1];
@@ -8032,7 +8174,7 @@ static void TryChopUpUncompressedBigTiff(TIFF *tif)
TIFF_NOSANITIZE_UNSIGNED_INT_OVERFLOW
static uint64_t _TIFFUnsanitizedAddUInt64AndInt(uint64_t a, int b)
{
return a + b;
return a + (uint64_t)b;
}
/* Read the value of [Strip|Tile]Offset or [Strip|Tile]ByteCount around
@@ -8111,7 +8253,7 @@ static int _TIFFPartialReadStripArray(TIFF *tif, TIFFDirEntry *dirent,
panVals[strile] = 0;
return 0;
}
nOffset = nBaseOffset + sizeofval * strile;
nOffset = nBaseOffset + (uint64_t)sizeofval * (uint64_t)strile;
nOffsetStartPage = (nOffset / IO_CACHE_PAGE_SIZE) * IO_CACHE_PAGE_SIZE;
nOffsetEndPage = nOffsetStartPage + IO_CACHE_PAGE_SIZE;
@@ -8119,7 +8261,7 @@ static int _TIFFPartialReadStripArray(TIFF *tif, TIFFDirEntry *dirent,
nOffsetEndPage += IO_CACHE_PAGE_SIZE;
#undef IO_CACHE_PAGE_SIZE
nLastStripOffset = nBaseOffset + arraySize * sizeofval;
nLastStripOffset = nBaseOffset + (uint64_t)arraySize * sizeofval;
if (nLastStripOffset < nOffsetEndPage)
nOffsetEndPage = nLastStripOffset;
if (nOffsetStartPage >= nOffsetEndPage)
@@ -8254,9 +8396,9 @@ static int _TIFFFetchStrileValue(TIFF *tif, uint32_t strile,
}
#endif
offsetArray = (uint64_t *)(_TIFFreallocExt(tif, td->td_stripoffset_p,
nArraySize));
(tmsize_t)nArraySize));
bytecountArray = (uint64_t *)(_TIFFreallocExt(
tif, td->td_stripbytecount_p, nArraySize));
tif, td->td_stripbytecount_p, (tmsize_t)nArraySize));
if (offsetArray)
td->td_stripoffset_p = offsetArray;
if (bytecountArray)
@@ -8290,7 +8432,7 @@ static int _TIFFFetchStrileValue(TIFF *tif, uint32_t strile,
if (~((*parray)[strile]) == 0)
{
if (!_TIFFPartialReadStripArray(tif, dirent, strile, *parray))
if (!_TIFFPartialReadStripArray(tif, dirent, (int)strile, *parray))
{
(*parray)[strile] = 0;
return 0;
@@ -8308,10 +8450,26 @@ static uint64_t _TIFFGetStrileOffsetOrByteCountValue(TIFF *tif, uint32_t strile,
TIFFDirectory *td = &tif->tif_dir;
if (pbErr)
*pbErr = 0;
/* Avoid the "dirent->tdir_count <= 4" code path for one of
* StripOffsets/StripByteCounts, and the other code path for the other one,
* which will lead to inconsistencies and potential out-of-bounds reads.
*/
if ((td->td_stripoffset_entry.tdir_count <= 4) !=
(td->td_stripbytecount_entry.tdir_count <= 4))
{
TIFFErrorExtR(tif, "_TIFFGetStrileOffsetOrByteCountValue",
"Inconsistent directory count between StripOffsets and "
"StripByteCounts");
if (pbErr)
*pbErr = 1;
return 0;
}
if ((tif->tif_flags & TIFF_DEFERSTRILELOAD) &&
!(tif->tif_flags & TIFF_CHOPPEDUPARRAYS))
{
if (!(tif->tif_flags & TIFF_LAZYSTRILELOAD) ||
if (!(tif->tif_flags & TIFF_LAZYSTRILELOAD_ASKED) ||
/* If the values may fit in the toff_long/toff_long8 member */
/* then use _TIFFFillStriles to simplify _TIFFFetchStrileValue */
dirent->tdir_count <= 4)
@@ -8382,7 +8540,7 @@ int _TIFFFillStriles(TIFF *tif) { return _TIFFFillStrilesInternal(tif, 1); }
static int _TIFFFillStrilesInternal(TIFF *tif, int loadStripByteCount)
{
register TIFFDirectory *td = &tif->tif_dir;
TIFFDirectory *td = &tif->tif_dir;
int return_value = 1;
/* Do not do anything if TIFF_DEFERSTRILELOAD is not set */
@@ -8390,7 +8548,8 @@ static int _TIFFFillStrilesInternal(TIFF *tif, int loadStripByteCount)
(tif->tif_flags & TIFF_CHOPPEDUPARRAYS) != 0)
return 1;
if (tif->tif_flags & TIFF_LAZYSTRILELOAD)
if ((tif->tif_flags & TIFF_LAZYSTRILELOAD_ASKED) &&
!(tif->tif_flags & TIFF_LAZYSTRILELOAD_DONE))
{
/* In case of lazy loading, reload completely the arrays */
_TIFFfreeExt(tif, td->td_stripoffset_p);
@@ -8398,7 +8557,7 @@ static int _TIFFFillStrilesInternal(TIFF *tif, int loadStripByteCount)
td->td_stripoffset_p = NULL;
td->td_stripbytecount_p = NULL;
td->td_stripoffsetbyteallocsize = 0;
tif->tif_flags &= ~TIFF_LAZYSTRILELOAD;
tif->tif_flags |= TIFF_LAZYSTRILELOAD_DONE;
}
/* If stripoffset array is already loaded, exit with success */

View File

@@ -365,7 +365,7 @@ static int TIFFRewriteDirectorySec(TIFF *tif, int isimage, int imagedone,
}
if (tif->tif_flags & TIFF_SWAB)
TIFFSwabShort(&dircount);
(void)TIFFSeekFile(tif, nextdir + 2 + dircount * 12, SEEK_SET);
(void)TIFFSeekFile(tif, nextdir + 2 + dircount * 12U, SEEK_SET);
if (!ReadOK(tif, &nextnextdir, 4))
{
TIFFErrorExtR(tif, module, "Error fetching directory link");
@@ -377,7 +377,7 @@ static int TIFFRewriteDirectorySec(TIFF *tif, int isimage, int imagedone,
{
uint32_t m;
m = 0;
(void)TIFFSeekFile(tif, nextdir + 2 + dircount * 12,
(void)TIFFSeekFile(tif, nextdir + 2 + dircount * 12U,
SEEK_SET);
if (!WriteOK(tif, &m, 4))
{
@@ -417,7 +417,6 @@ static int TIFFRewriteDirectorySec(TIFF *tif, int isimage, int imagedone,
while (1)
{
uint64_t dircount64;
uint16_t dircount;
uint64_t nextnextdir;
if (!SeekOK(tif, nextdir) || !ReadOK(tif, &dircount64, 8))
@@ -435,8 +434,8 @@ static int TIFFRewriteDirectorySec(TIFF *tif, int isimage, int imagedone,
"corrupt TIFF");
return (0);
}
dircount = (uint16_t)dircount64;
(void)TIFFSeekFile(tif, nextdir + 8 + dircount * 20, SEEK_SET);
(void)TIFFSeekFile(tif, nextdir + 8 + dircount64 * 20,
SEEK_SET);
if (!ReadOK(tif, &nextnextdir, 8))
{
TIFFErrorExtR(tif, module, "Error fetching directory link");
@@ -448,7 +447,7 @@ static int TIFFRewriteDirectorySec(TIFF *tif, int isimage, int imagedone,
{
uint64_t m;
m = 0;
(void)TIFFSeekFile(tif, nextdir + 8 + dircount * 20,
(void)TIFFSeekFile(tif, nextdir + 8 + dircount64 * 20,
SEEK_SET);
if (!WriteOK(tif, &m, 8))
{
@@ -592,24 +591,24 @@ static int TIFFWriteDirectorySec(TIFF *tif, int isimage, int imagedone,
}
if (TIFFFieldSet(tif, FIELD_RESOLUTION))
{
if (!TIFFWriteDirectoryTagRational(tif, &ndir, dir,
TIFFTAG_XRESOLUTION,
tif->tif_dir.td_xresolution))
if (!TIFFWriteDirectoryTagRational(
tif, &ndir, dir, TIFFTAG_XRESOLUTION,
(double)tif->tif_dir.td_xresolution))
goto bad;
if (!TIFFWriteDirectoryTagRational(tif, &ndir, dir,
TIFFTAG_YRESOLUTION,
tif->tif_dir.td_yresolution))
if (!TIFFWriteDirectoryTagRational(
tif, &ndir, dir, TIFFTAG_YRESOLUTION,
(double)tif->tif_dir.td_yresolution))
goto bad;
}
if (TIFFFieldSet(tif, FIELD_POSITION))
{
if (!TIFFWriteDirectoryTagRational(tif, &ndir, dir,
TIFFTAG_XPOSITION,
tif->tif_dir.td_xposition))
if (!TIFFWriteDirectoryTagRational(
tif, &ndir, dir, TIFFTAG_XPOSITION,
(double)tif->tif_dir.td_xposition))
goto bad;
if (!TIFFWriteDirectoryTagRational(tif, &ndir, dir,
TIFFTAG_YPOSITION,
tif->tif_dir.td_yposition))
if (!TIFFWriteDirectoryTagRational(
tif, &ndir, dir, TIFFTAG_YPOSITION,
(double)tif->tif_dir.td_yposition))
goto bad;
}
if (TIFFFieldSet(tif, FIELD_SUBFILETYPE))
@@ -712,6 +711,14 @@ static int TIFFWriteDirectorySec(TIFF *tif, int isimage, int imagedone,
}
if (TIFFFieldSet(tif, FIELD_STRIPBYTECOUNTS))
{
/* Check td_stripbytecount_p for NULL pointer (bug#749) */
if (tif->tif_dir.td_stripbytecount_p == NULL)
{
TIFFErrorExtR(
tif, module,
"StripByteCount array is not set, pointer is NULL");
goto bad;
}
if (!isTiled(tif))
{
if (!TIFFWriteDirectoryTagLongLong8Array(
@@ -731,6 +738,14 @@ static int TIFFWriteDirectorySec(TIFF *tif, int isimage, int imagedone,
}
if (TIFFFieldSet(tif, FIELD_STRIPOFFSETS))
{
/* Check td_stripoffset_p for NULL pointer (bug#749) */
if (tif->tif_dir.td_stripoffset_p == NULL)
{
TIFFErrorExtR(
tif, module,
"StripByteOffset array is not set, pointer is NULL");
goto bad;
}
if (!isTiled(tif))
{
/* td_stripoffset_p might be NULL in an odd OJPEG case. See
@@ -851,7 +866,8 @@ static int TIFFWriteDirectorySec(TIFF *tif, int isimage, int imagedone,
{
if (!TIFFWriteDirectoryTagAscii(
tif, &ndir, dir, TIFFTAG_INKNAMES,
tif->tif_dir.td_inknameslen, tif->tif_dir.td_inknames))
(uint32_t)tif->tif_dir.td_inknameslen,
tif->tif_dir.td_inknames))
goto bad;
}
if (TIFFFieldSet(tif, FIELD_NUMBEROFINKS))
@@ -932,10 +948,58 @@ static int TIFFWriteDirectorySec(TIFF *tif, int isimage, int imagedone,
TIFFGetField(tif, o->field_tag, &pa, &pb);
if (!TIFFWriteDirectoryTagUndefinedArray(
tif, &ndir, dir, (uint16_t)o->field_tag,
pa, pb))
pa, (uint8_t *)pb))
goto bad;
}
break;
case TIFF_SETGET_UNDEFINED:
case TIFF_SETGET_SINT8:
case TIFF_SETGET_SINT16:
case TIFF_SETGET_SINT32:
case TIFF_SETGET_UINT64:
case TIFF_SETGET_SINT64:
case TIFF_SETGET_FLOAT:
case TIFF_SETGET_DOUBLE:
case TIFF_SETGET_IFD8:
case TIFF_SETGET_INT:
case TIFF_SETGET_UINT16_PAIR:
case TIFF_SETGET_C0_ASCII:
case TIFF_SETGET_C0_UINT8:
case TIFF_SETGET_C0_SINT8:
case TIFF_SETGET_C0_UINT16:
case TIFF_SETGET_C0_SINT16:
case TIFF_SETGET_C0_UINT32:
case TIFF_SETGET_C0_SINT32:
case TIFF_SETGET_C0_UINT64:
case TIFF_SETGET_C0_SINT64:
case TIFF_SETGET_C0_FLOAT:
case TIFF_SETGET_C0_DOUBLE:
case TIFF_SETGET_C0_IFD8:
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_UINT64:
case TIFF_SETGET_C16_SINT64:
case TIFF_SETGET_C16_FLOAT:
case TIFF_SETGET_C16_DOUBLE:
case TIFF_SETGET_C16_IFD8:
case TIFF_SETGET_C32_ASCII:
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_UINT64:
case TIFF_SETGET_C32_SINT64:
case TIFF_SETGET_C32_FLOAT:
case TIFF_SETGET_C32_DOUBLE:
case TIFF_SETGET_C32_IFD8:
case TIFF_SETGET_UINT8:
case TIFF_SETGET_OTHER:
default:
TIFFErrorExtR(
tif, module,
@@ -954,67 +1018,67 @@ static int TIFFWriteDirectorySec(TIFF *tif, int isimage, int imagedone,
{
uint16_t tag =
(uint16_t)tif->tif_dir.td_customValues[m].info->field_tag;
uint32_t count = tif->tif_dir.td_customValues[m].count;
uint32_t count = (uint32_t)tif->tif_dir.td_customValues[m].count;
switch (tif->tif_dir.td_customValues[m].info->field_type)
{
case TIFF_ASCII:
if (!TIFFWriteDirectoryTagAscii(
tif, &ndir, dir, tag, count,
tif->tif_dir.td_customValues[m].value))
(char *)tif->tif_dir.td_customValues[m].value))
goto bad;
break;
case TIFF_UNDEFINED:
if (!TIFFWriteDirectoryTagUndefinedArray(
tif, &ndir, dir, tag, count,
tif->tif_dir.td_customValues[m].value))
(uint8_t *)tif->tif_dir.td_customValues[m].value))
goto bad;
break;
case TIFF_BYTE:
if (!TIFFWriteDirectoryTagByteArray(
tif, &ndir, dir, tag, count,
tif->tif_dir.td_customValues[m].value))
(uint8_t *)tif->tif_dir.td_customValues[m].value))
goto bad;
break;
case TIFF_SBYTE:
if (!TIFFWriteDirectoryTagSbyteArray(
tif, &ndir, dir, tag, count,
tif->tif_dir.td_customValues[m].value))
(int8_t *)tif->tif_dir.td_customValues[m].value))
goto bad;
break;
case TIFF_SHORT:
if (!TIFFWriteDirectoryTagShortArray(
tif, &ndir, dir, tag, count,
tif->tif_dir.td_customValues[m].value))
(uint16_t *)tif->tif_dir.td_customValues[m].value))
goto bad;
break;
case TIFF_SSHORT:
if (!TIFFWriteDirectoryTagSshortArray(
tif, &ndir, dir, tag, count,
tif->tif_dir.td_customValues[m].value))
(int16_t *)tif->tif_dir.td_customValues[m].value))
goto bad;
break;
case TIFF_LONG:
if (!TIFFWriteDirectoryTagLongArray(
tif, &ndir, dir, tag, count,
tif->tif_dir.td_customValues[m].value))
(uint32_t *)tif->tif_dir.td_customValues[m].value))
goto bad;
break;
case TIFF_SLONG:
if (!TIFFWriteDirectoryTagSlongArray(
tif, &ndir, dir, tag, count,
tif->tif_dir.td_customValues[m].value))
(int32_t *)tif->tif_dir.td_customValues[m].value))
goto bad;
break;
case TIFF_LONG8:
if (!TIFFWriteDirectoryTagLong8Array(
tif, &ndir, dir, tag, count,
tif->tif_dir.td_customValues[m].value))
(uint64_t *)tif->tif_dir.td_customValues[m].value))
goto bad;
break;
case TIFF_SLONG8:
if (!TIFFWriteDirectoryTagSlong8Array(
tif, &ndir, dir, tag, count,
tif->tif_dir.td_customValues[m].value))
(int64_t *)tif->tif_dir.td_customValues[m].value))
goto bad;
break;
case TIFF_RATIONAL:
@@ -1029,7 +1093,8 @@ static int TIFFWriteDirectorySec(TIFF *tif, int isimage, int imagedone,
{
if (!TIFFWriteDirectoryTagRationalDoubleArray(
tif, &ndir, dir, tag, count,
tif->tif_dir.td_customValues[m].value))
(double *)tif->tif_dir.td_customValues[m]
.value))
goto bad;
}
else
@@ -1037,7 +1102,7 @@ static int TIFFWriteDirectorySec(TIFF *tif, int isimage, int imagedone,
/*-- default should be tv_size == 4 */
if (!TIFFWriteDirectoryTagRationalArray(
tif, &ndir, dir, tag, count,
tif->tif_dir.td_customValues[m].value))
(float *)tif->tif_dir.td_customValues[m].value))
goto bad;
/*-- ToDo: After Testing, this should be removed and
* tv_size==4 should be set as default. */
@@ -1064,7 +1129,8 @@ static int TIFFWriteDirectorySec(TIFF *tif, int isimage, int imagedone,
{
if (!TIFFWriteDirectoryTagSrationalDoubleArray(
tif, &ndir, dir, tag, count,
tif->tif_dir.td_customValues[m].value))
(double *)tif->tif_dir.td_customValues[m]
.value))
goto bad;
}
else
@@ -1072,7 +1138,7 @@ static int TIFFWriteDirectorySec(TIFF *tif, int isimage, int imagedone,
/*-- default should be tv_size == 4 */
if (!TIFFWriteDirectoryTagSrationalArray(
tif, &ndir, dir, tag, count,
tif->tif_dir.td_customValues[m].value))
(float *)tif->tif_dir.td_customValues[m].value))
goto bad;
/*-- ToDo: After Testing, this should be removed and
* tv_size==4 should be set as default. */
@@ -1090,27 +1156,28 @@ static int TIFFWriteDirectorySec(TIFF *tif, int isimage, int imagedone,
case TIFF_FLOAT:
if (!TIFFWriteDirectoryTagFloatArray(
tif, &ndir, dir, tag, count,
tif->tif_dir.td_customValues[m].value))
(float *)tif->tif_dir.td_customValues[m].value))
goto bad;
break;
case TIFF_DOUBLE:
if (!TIFFWriteDirectoryTagDoubleArray(
tif, &ndir, dir, tag, count,
tif->tif_dir.td_customValues[m].value))
(double *)tif->tif_dir.td_customValues[m].value))
goto bad;
break;
case TIFF_IFD:
if (!TIFFWriteDirectoryTagIfdArray(
tif, &ndir, dir, tag, count,
tif->tif_dir.td_customValues[m].value))
(uint32_t *)tif->tif_dir.td_customValues[m].value))
goto bad;
break;
case TIFF_IFD8:
if (!TIFFWriteDirectoryTagIfdIfd8Array(
tif, &ndir, dir, tag, count,
tif->tif_dir.td_customValues[m].value))
(uint64_t *)tif->tif_dir.td_customValues[m].value))
goto bad;
break;
case TIFF_NOTYPE:
default:
assert(0); /* we should never get here */
break;
@@ -1128,7 +1195,8 @@ static int TIFFWriteDirectorySec(TIFF *tif, int isimage, int imagedone,
tif->tif_dir.td_dirdatasize_write += 8 + ndir * 20 + 8;
/* Setup a new directory within first pass. */
dir = _TIFFmallocExt(tif, ndir * sizeof(TIFFDirEntry));
dir = (TIFFDirEntry *)_TIFFmallocExt(
tif, (tmsize_t)((size_t)ndir * sizeof(TIFFDirEntry)));
if (dir == NULL)
{
TIFFErrorExtR(tif, module, "Out of memory");
@@ -1238,7 +1306,7 @@ static int TIFFWriteDirectorySec(TIFF *tif, int isimage, int imagedone,
uint8_t *n;
uint32_t nTmp;
TIFFDirEntry *o;
n = dirmem;
n = (uint8_t *)dirmem;
*(uint16_t *)n = (uint16_t)ndir;
if (tif->tif_flags & TIFF_SWAB)
TIFFSwabShort((uint16_t *)n);
@@ -1274,7 +1342,7 @@ static int TIFFWriteDirectorySec(TIFF *tif, int isimage, int imagedone,
{
uint8_t *n;
TIFFDirEntry *o;
n = dirmem;
n = (uint8_t *)dirmem;
*(uint64_t *)n = ndir;
if (tif->tif_flags & TIFF_SWAB)
TIFFSwabLong8((uint64_t *)n);
@@ -1405,7 +1473,7 @@ static int8_t TIFFClampDoubleToInt8(double val)
{
if (val > 127)
return 127;
if (val < -128 || val != val)
if (val < -128 || isnan(val))
return -128;
return (int8_t)val;
}
@@ -1414,7 +1482,7 @@ static int16_t TIFFClampDoubleToInt16(double val)
{
if (val > 32767)
return 32767;
if (val < -32768 || val != val)
if (val < -32768 || isnan(val))
return -32768;
return (int16_t)val;
}
@@ -1423,7 +1491,7 @@ static int32_t TIFFClampDoubleToInt32(double val)
{
if (val > 0x7FFFFFFF)
return 0x7FFFFFFF;
if (val < -0x7FFFFFFF - 1 || val != val)
if (val < -0x7FFFFFFF - 1 || isnan(val))
return -0x7FFFFFFF - 1;
return (int32_t)val;
}
@@ -1432,7 +1500,7 @@ static uint8_t TIFFClampDoubleToUInt8(double val)
{
if (val < 0)
return 0;
if (val > 255 || val != val)
if (val > 255 || isnan(val))
return 255;
return (uint8_t)val;
}
@@ -1441,7 +1509,7 @@ static uint16_t TIFFClampDoubleToUInt16(double val)
{
if (val < 0)
return 0;
if (val > 65535 || val != val)
if (val > 65535 || isnan(val))
return 65535;
return (uint16_t)val;
}
@@ -1450,7 +1518,7 @@ static uint32_t TIFFClampDoubleToUInt32(double val)
{
if (val < 0)
return 0;
if (val > 0xFFFFFFFFU || val != val)
if (val > 0xFFFFFFFFU || isnan(val))
return 0xFFFFFFFFU;
return (uint32_t)val;
}
@@ -1464,7 +1532,7 @@ static int TIFFWriteDirectoryTagSampleformatArray(TIFF *tif, uint32_t *ndir,
void *conv;
uint32_t i;
int ok;
conv = _TIFFmallocExt(tif, count * sizeof(double));
conv = _TIFFmallocExt(tif, (tmsize_t)((size_t)count * sizeof(double)));
if (conv == NULL)
{
TIFFErrorExtR(tif, module, "Out of memory");
@@ -1603,7 +1671,9 @@ static int TIFFWriteDirectoryTagShortPerSample(TIFF *tif, uint32_t *ndir,
return (TIFFWriteDirectoryTagCheckedShortArray(
tif, ndir, dir, tag, tif->tif_dir.td_samplesperpixel, NULL));
}
m = _TIFFmallocExt(tif, tif->tif_dir.td_samplesperpixel * sizeof(uint16_t));
m = (uint16_t *)_TIFFmallocExt(
tif,
(tmsize_t)((size_t)tif->tif_dir.td_samplesperpixel * sizeof(uint16_t)));
if (m == NULL)
{
TIFFErrorExtR(tif, module, "Out of memory");
@@ -1664,14 +1734,6 @@ static int TIFFWriteDirectoryTagLong8Array(TIFF *tif, uint32_t *ndir,
uint32_t *q;
int o;
/* is this just a counting pass? */
if (dir == NULL)
{
/* only evaluate IFD data size and inc. ndir */
return (TIFFWriteDirectoryTagCheckedLong8Array(tif, ndir, dir, tag,
count, value));
}
/* We always write Long8 for BigTIFF, no checking needed. */
if (tif->tif_flags & TIFF_BIGTIFF)
return (TIFFWriteDirectoryTagCheckedLong8Array(tif, ndir, dir, tag,
@@ -1681,7 +1743,8 @@ static int TIFFWriteDirectoryTagLong8Array(TIFF *tif, uint32_t *ndir,
** For classic tiff we want to verify everything is in range for long
** and convert to long format.
*/
p = _TIFFmallocExt(tif, count * sizeof(uint32_t));
p = (uint32_t *)_TIFFmallocExt(
tif, (tmsize_t)((size_t)count * sizeof(uint32_t)));
if (p == NULL)
{
TIFFErrorExtR(tif, module, "Out of memory");
@@ -1725,13 +1788,6 @@ static int TIFFWriteDirectoryTagSlong8Array(TIFF *tif, uint32_t *ndir,
int32_t *q;
int o;
/* is this just a counting pass? */
if (dir == NULL)
{
/* only evaluate IFD data size and inc. ndir */
return (TIFFWriteDirectoryTagCheckedSlong8Array(tif, ndir, dir, tag,
count, value));
}
/* We always write SLong8 for BigTIFF, no checking needed. */
if (tif->tif_flags & TIFF_BIGTIFF)
return (TIFFWriteDirectoryTagCheckedSlong8Array(tif, ndir, dir, tag,
@@ -1741,7 +1797,8 @@ static int TIFFWriteDirectoryTagSlong8Array(TIFF *tif, uint32_t *ndir,
** For classic tiff we want to verify everything is in range for signed-long
** and convert to signed-long format.
*/
p = _TIFFmallocExt(tif, count * sizeof(uint32_t));
p = (int32_t *)_TIFFmallocExt(tif,
(tmsize_t)((size_t)count * sizeof(uint32_t)));
if (p == NULL)
{
TIFFErrorExtR(tif, module, "Out of memory");
@@ -1960,7 +2017,8 @@ static int TIFFWriteDirectoryTagLongLong8Array(TIFF *tif, uint32_t *ndir,
** and convert to long format.
*/
uint32_t *p = _TIFFmallocExt(tif, count * sizeof(uint32_t));
uint32_t *p = (uint32_t *)_TIFFmallocExt(
tif, (tmsize_t)((size_t)count * sizeof(uint32_t)));
uint32_t *q;
uint64_t *ma;
uint32_t mb;
@@ -1990,7 +2048,8 @@ static int TIFFWriteDirectoryTagLongLong8Array(TIFF *tif, uint32_t *ndir,
}
else
{
uint16_t *p = _TIFFmallocExt(tif, count * sizeof(uint16_t));
uint16_t *p = (uint16_t *)_TIFFmallocExt(
tif, (tmsize_t)((size_t)count * sizeof(uint16_t)));
uint16_t *q;
uint64_t *ma;
uint32_t mb;
@@ -2050,7 +2109,8 @@ static int TIFFWriteDirectoryTagIfdIfd8Array(TIFF *tif, uint32_t *ndir,
** and convert to long format.
*/
p = _TIFFmallocExt(tif, count * sizeof(uint32_t));
p = (uint32_t *)_TIFFmallocExt(
tif, (tmsize_t)((size_t)count * sizeof(uint32_t)));
if (p == NULL)
{
TIFFErrorExtR(tif, module, "Out of memory");
@@ -2101,26 +2161,45 @@ static int TIFFWriteDirectoryTagColormap(TIFF *tif, uint32_t *ndir,
{
static const char module[] = "TIFFWriteDirectoryTagColormap";
uint32_t m;
uint32_t count;
uint64_t count64;
tmsize_t total_values;
tmsize_t plane_bytes;
uint16_t *n;
int o;
m = (1 << tif->tif_dir.td_bitspersample);
if (tif->tif_dir.td_bitspersample >= 32)
{
TIFFErrorExtR(tif, module, "BitsPerSample too large for Colormap");
return (0);
}
m = 1U << tif->tif_dir.td_bitspersample;
count64 = _TIFFMultiply64(tif, 3U, m, module);
if (count64 == 0)
return (0);
count = _TIFFCastUInt64ToUInt32(tif, count64, module);
total_values = _TIFFCastUInt64ToSSize(tif, count64, module);
plane_bytes = _TIFFCastUInt64ToSSize(
tif, _TIFFMultiply64(tif, m, sizeof(uint16_t), module), module);
if (count == 0 || total_values == 0 || plane_bytes == 0)
return (0);
if (dir == NULL) /* Just evaluate IFD data size and increment ndir. */
{
EvaluateIFDdatasizeWrite(tif, 3 * m, sizeof(uint16_t), ndir);
EvaluateIFDdatasizeWrite(tif, count, sizeof(uint16_t), ndir);
return 1;
}
n = _TIFFmallocExt(tif, 3 * m * sizeof(uint16_t));
n = (uint16_t *)_TIFFCheckMalloc(tif, total_values, sizeof(uint16_t),
module);
if (n == NULL)
{
TIFFErrorExtR(tif, module, "Out of memory");
return (0);
}
_TIFFmemcpy(&n[0], tif->tif_dir.td_colormap[0], m * sizeof(uint16_t));
_TIFFmemcpy(&n[m], tif->tif_dir.td_colormap[1], m * sizeof(uint16_t));
_TIFFmemcpy(&n[2 * m], tif->tif_dir.td_colormap[2], m * sizeof(uint16_t));
_TIFFmemcpy(&n[0], tif->tif_dir.td_colormap[0], plane_bytes);
_TIFFmemcpy(&n[m], tif->tif_dir.td_colormap[1], plane_bytes);
_TIFFmemcpy(&n[2 * m], tif->tif_dir.td_colormap[2], plane_bytes);
o = TIFFWriteDirectoryTagCheckedShortArray(tif, ndir, dir, TIFFTAG_COLORMAP,
3 * m, n);
count, n);
_TIFFfreeExt(tif, n);
return (o);
}
@@ -2130,13 +2209,27 @@ static int TIFFWriteDirectoryTagTransferfunction(TIFF *tif, uint32_t *ndir,
{
static const char module[] = "TIFFWriteDirectoryTagTransferfunction";
uint32_t m;
uint32_t count;
uint64_t count64;
tmsize_t total_values;
tmsize_t plane_bytes;
uint16_t n;
uint16_t *o;
int p;
/* TIFFTAG_TRANSFERFUNCTION expects (1 or 3) pointer to arrays with
* (1 << BitsPerSample) * uint16_t values.
* 2**BitsPerSample uint16_t values.
*/
m = (1 << tif->tif_dir.td_bitspersample);
if (tif->tif_dir.td_bitspersample >= 32)
{
TIFFErrorExtR(tif, module,
"BitsPerSample too large for TransferFunction");
return (0);
}
m = 1U << tif->tif_dir.td_bitspersample;
plane_bytes = _TIFFCastUInt64ToSSize(
tif, _TIFFMultiply64(tif, m, sizeof(uint16_t), module), module);
if (plane_bytes == 0)
return (0);
/* clang-format off */
n = (tif->tif_dir.td_samplesperpixel - tif->tif_dir.td_extrasamples) > 1 ? 3 : 1;
/* clang-format on */
@@ -2161,35 +2254,39 @@ static int TIFFWriteDirectoryTagTransferfunction(TIFF *tif, uint32_t *ndir,
if (n == 3)
{
if (!_TIFFmemcmp(tif->tif_dir.td_transferfunction[0],
tif->tif_dir.td_transferfunction[2],
m * sizeof(uint16_t)) &&
tif->tif_dir.td_transferfunction[2], plane_bytes) &&
!_TIFFmemcmp(tif->tif_dir.td_transferfunction[0],
tif->tif_dir.td_transferfunction[1],
m * sizeof(uint16_t)))
tif->tif_dir.td_transferfunction[1], plane_bytes))
n = 1;
}
count64 = _TIFFMultiply64(tif, n, m, module);
if (count64 == 0)
return (0);
count = _TIFFCastUInt64ToUInt32(tif, count64, module);
total_values = _TIFFCastUInt64ToSSize(tif, count64, module);
if (count == 0 || total_values == 0)
return (0);
if (dir == NULL) /* Just evaluate IFD data size and increment ndir. */
{
EvaluateIFDdatasizeWrite(tif, n * m, 2, ndir);
EvaluateIFDdatasizeWrite(tif, count, 2, ndir);
return 1;
}
o = _TIFFmallocExt(tif, n * m * sizeof(uint16_t));
o = (uint16_t *)_TIFFCheckMalloc(tif, total_values, sizeof(uint16_t),
module);
if (o == NULL)
{
TIFFErrorExtR(tif, module, "Out of memory");
return (0);
}
_TIFFmemcpy(&o[0], tif->tif_dir.td_transferfunction[0],
m * sizeof(uint16_t));
_TIFFmemcpy(&o[0], tif->tif_dir.td_transferfunction[0], plane_bytes);
if (n > 1)
_TIFFmemcpy(&o[m], tif->tif_dir.td_transferfunction[1],
m * sizeof(uint16_t));
_TIFFmemcpy(&o[m], tif->tif_dir.td_transferfunction[1], plane_bytes);
if (n > 2)
_TIFFmemcpy(&o[2 * m], tif->tif_dir.td_transferfunction[2],
m * sizeof(uint16_t));
plane_bytes);
p = TIFFWriteDirectoryTagCheckedShortArray(
tif, ndir, dir, TIFFTAG_TRANSFERFUNCTION, n * m, o);
tif, ndir, dir, TIFFTAG_TRANSFERFUNCTION, count, o);
_TIFFfreeExt(tif, o);
return (p);
}
@@ -2209,7 +2306,9 @@ static int TIFFWriteDirectoryTagSubifd(TIFF *tif, uint32_t *ndir,
uint64_t *pa;
uint32_t *pb;
uint16_t p;
o = _TIFFmallocExt(tif, tif->tif_dir.td_nsubifd * sizeof(uint32_t));
o = (uint32_t *)_TIFFmallocExt(
tif,
(tmsize_t)((size_t)tif->tif_dir.td_nsubifd * sizeof(uint32_t)));
if (o == NULL)
{
TIFFErrorExtR(tif, module, "Out of memory");
@@ -2494,7 +2593,7 @@ static int TIFFWriteDirectoryTagCheckedRational(TIFF *tif, uint32_t *ndir,
TIFFErrorExtR(tif, module, "Negative value is illegal");
return 0;
}
else if (value != value)
else if (isnan(value))
{
TIFFErrorExtR(tif, module, "Not-a-number value is illegal");
return 0;
@@ -2537,7 +2636,8 @@ static int TIFFWriteDirectoryTagCheckedRationalArray(TIFF *tif, uint32_t *ndir,
EvaluateIFDdatasizeWrite(tif, count * 2, sizeof(uint32_t), ndir);
return 1;
}
m = _TIFFmallocExt(tif, count * 2 * sizeof(uint32_t));
m = (uint32_t *)_TIFFCheckMalloc(tif, count, 2 * sizeof(uint32_t),
"for rational array");
if (m == NULL)
{
TIFFErrorExtR(tif, module, "Out of memory");
@@ -2545,7 +2645,7 @@ static int TIFFWriteDirectoryTagCheckedRationalArray(TIFF *tif, uint32_t *ndir,
}
for (na = value, nb = m, nc = 0; nc < count; na++, nb += 2, nc++)
{
DoubleToRational(*na, &nb[0], &nb[1]);
DoubleToRational((double)*na, &nb[0], &nb[1]);
}
if (tif->tif_flags & TIFF_SWAB)
TIFFSwabArrayOfLong(m, count * 2);
@@ -2573,7 +2673,8 @@ static int TIFFWriteDirectoryTagCheckedSrationalArray(TIFF *tif, uint32_t *ndir,
EvaluateIFDdatasizeWrite(tif, count * 2, sizeof(int32_t), ndir);
return 1;
}
m = _TIFFmallocExt(tif, count * 2 * sizeof(int32_t));
m = (int32_t *)_TIFFCheckMalloc(tif, count, 2 * sizeof(int32_t),
"for srational array");
if (m == NULL)
{
TIFFErrorExtR(tif, module, "Out of memory");
@@ -2581,7 +2682,7 @@ static int TIFFWriteDirectoryTagCheckedSrationalArray(TIFF *tif, uint32_t *ndir,
}
for (na = value, nb = m, nc = 0; nc < count; na++, nb += 2, nc++)
{
DoubleToSrational(*na, &nb[0], &nb[1]);
DoubleToSrational((double)*na, &nb[0], &nb[1]);
}
if (tif->tif_flags & TIFF_SWAB)
TIFFSwabArrayOfLong((uint32_t *)m, count * 2);
@@ -2610,7 +2711,8 @@ TIFFWriteDirectoryTagCheckedRationalDoubleArray(TIFF *tif, uint32_t *ndir,
EvaluateIFDdatasizeWrite(tif, count * 2, sizeof(uint32_t), ndir);
return 1;
}
m = _TIFFmallocExt(tif, count * 2 * sizeof(uint32_t));
m = (uint32_t *)_TIFFCheckMalloc(tif, count, 2 * sizeof(uint32_t),
"for rational double array");
if (m == NULL)
{
TIFFErrorExtR(tif, module, "Out of memory");
@@ -2618,7 +2720,7 @@ TIFFWriteDirectoryTagCheckedRationalDoubleArray(TIFF *tif, uint32_t *ndir,
}
for (na = value, nb = m, nc = 0; nc < count; na++, nb += 2, nc++)
{
DoubleToRational(*na, &nb[0], &nb[1]);
DoubleToRational((double)*na, &nb[0], &nb[1]);
}
if (tif->tif_flags & TIFF_SWAB)
TIFFSwabArrayOfLong(m, count * 2);
@@ -2645,7 +2747,8 @@ static int TIFFWriteDirectoryTagCheckedSrationalDoubleArray(
EvaluateIFDdatasizeWrite(tif, count * 2, sizeof(int32_t), ndir);
return 1;
}
m = _TIFFmallocExt(tif, count * 2 * sizeof(int32_t));
m = (int32_t *)_TIFFCheckMalloc(tif, count, 2 * sizeof(int32_t),
"for srational double array");
if (m == NULL)
{
TIFFErrorExtR(tif, module, "Out of memory");
@@ -2653,7 +2756,7 @@ static int TIFFWriteDirectoryTagCheckedSrationalDoubleArray(
}
for (na = value, nb = m, nc = 0; nc < count; na++, nb += 2, nc++)
{
DoubleToSrational(*na, &nb[0], &nb[1]);
DoubleToSrational((double)*na, &nb[0], &nb[1]);
}
if (tif->tif_flags & TIFF_SWAB)
TIFFSwabArrayOfLong((uint32_t *)m, count * 2);
@@ -2744,7 +2847,8 @@ static void ToRationalEuclideanGCD(double value, int blnUseSignedRange,
*the double-value of it reaches an integer number without fractional part.
*/
bigDenom = 1;
while ((value != floor(value)) && (value < fMax) && (bigDenom < nMax))
while ((!TIFF_DOUBLE_EQ(value, floor(value))) && (value < fMax) &&
(bigDenom < nMax))
{
bigDenom <<= 1;
value *= 2;
@@ -2836,7 +2940,7 @@ static void DoubleToRational(double value, uint32_t *num, uint32_t *denom)
return;
}
/*-- Check for easy integer numbers -- */
if (value == (uint32_t)(value))
if (TIFF_DOUBLE_EQ(value, (double)(uint32_t)value))
{
*num = (uint32_t)value;
*denom = 1;
@@ -2911,7 +3015,7 @@ static void DoubleToSrational(double value, int32_t *num, int32_t *denom)
return;
}
/*-- Check for easy numbers -- */
if (value == (int32_t)(value))
if (TIFF_DOUBLE_EQ(value, (double)(int32_t)value))
{
*num = (int32_t)(neg * value);
*denom = 1;
@@ -3231,6 +3335,14 @@ static int TIFFLinkDirectory(TIFF *tif)
uint16_t dircount;
uint32_t nextnextdir;
/* Update IDF loop list and check for IFD loop.
* ndir is IFD ID plus one. */
if (!_TIFFCheckDirNumberAndOffset(tif, ndir - 1, nextdir))
{
TIFFErrorExtR(tif, module, "Error IFD loop detected");
return 0; /* bad offset (IFD looping or more than
TIFF_MAX_DIR_COUNT IFDs) */
}
if (!SeekOK(tif, nextdir) || !ReadOK(tif, &dircount, 2))
{
TIFFErrorExtR(tif, module, "Error fetching directory count");
@@ -3238,7 +3350,7 @@ static int TIFFLinkDirectory(TIFF *tif)
}
if (tif->tif_flags & TIFF_SWAB)
TIFFSwabShort(&dircount);
(void)TIFFSeekFile(tif, nextdir + 2 + dircount * 12, SEEK_SET);
(void)TIFFSeekFile(tif, nextdir + 2 + dircount * 12U, SEEK_SET);
if (!ReadOK(tif, &nextnextdir, 4))
{
TIFFErrorExtR(tif, module, "Error fetching directory link");
@@ -3248,7 +3360,7 @@ static int TIFFLinkDirectory(TIFF *tif)
TIFFSwabLong(&nextnextdir);
if (nextnextdir == 0)
{
(void)TIFFSeekFile(tif, nextdir + 2 + dircount * 12, SEEK_SET);
(void)TIFFSeekFile(tif, nextdir + 2 + dircount * 12U, SEEK_SET);
if (!WriteOK(tif, &m, 4))
{
TIFFErrorExtR(tif, module, "Error writing directory link");
@@ -3306,9 +3418,15 @@ static int TIFFLinkDirectory(TIFF *tif)
while (1)
{
uint64_t dircount64;
uint16_t dircount;
uint64_t nextnextdir;
/* Update IDF loop list and check for IFD loop. */
if (!_TIFFCheckDirNumberAndOffset(tif, ndir - 1, nextdir))
{
TIFFErrorExtR(tif, module, "Error IFD loop detected");
return 0; /* bad offset (IFD looping or more than
TIFF_MAX_DIR_COUNT IFDs) */
}
if (!SeekOK(tif, nextdir) || !ReadOK(tif, &dircount64, 8))
{
TIFFErrorExtR(tif, module, "Error fetching directory count");
@@ -3323,8 +3441,7 @@ static int TIFFLinkDirectory(TIFF *tif)
"likely corrupt TIFF");
return (0);
}
dircount = (uint16_t)dircount64;
(void)TIFFSeekFile(tif, nextdir + 8 + dircount * 20, SEEK_SET);
(void)TIFFSeekFile(tif, nextdir + 8 + dircount64 * 20, SEEK_SET);
if (!ReadOK(tif, &nextnextdir, 8))
{
TIFFErrorExtR(tif, module, "Error fetching directory link");
@@ -3334,7 +3451,8 @@ static int TIFFLinkDirectory(TIFF *tif)
TIFFSwabLong8(&nextnextdir);
if (nextnextdir == 0)
{
(void)TIFFSeekFile(tif, nextdir + 8 + dircount * 20, SEEK_SET);
(void)TIFFSeekFile(tif, nextdir + 8 + dircount64 * 20,
SEEK_SET);
if (!WriteOK(tif, &m, 8))
{
TIFFErrorExtR(tif, module, "Error writing directory link");
@@ -3475,7 +3593,7 @@ int _TIFFRewriteField(TIFF *tif, uint16_t tag, TIFFDataType in_datatype,
if (entry_tag == tag)
break;
read_offset += dirsize;
read_offset += (uint64_t)dirsize;
}
if (entry_tag != tag)
@@ -3584,13 +3702,13 @@ int _TIFFRewriteField(TIFF *tif, uint16_t tag, TIFFDataType in_datatype,
if (in_datatype == TIFF_LONG8 &&
(entry_type == TIFF_SHORT || entry_type == TIFF_LONG ||
entry_type == TIFF_LONG8))
datatype = entry_type;
datatype = (TIFFDataType)entry_type;
else if (in_datatype == TIFF_SLONG8 &&
(entry_type == TIFF_SLONG || entry_type == TIFF_SLONG8))
datatype = entry_type;
datatype = (TIFFDataType)entry_type;
else if (in_datatype == TIFF_IFD8 &&
(entry_type == TIFF_IFD || entry_type == TIFF_IFD8))
datatype = entry_type;
datatype = (TIFFDataType)entry_type;
else
datatype = in_datatype;
}
@@ -3605,7 +3723,8 @@ int _TIFFRewriteField(TIFF *tif, uint16_t tag, TIFFDataType in_datatype,
return 0;
if (datatype == in_datatype)
memcpy(buf_to_write, data, count * TIFFDataWidth(datatype));
memcpy(buf_to_write, data,
(size_t)count * (size_t)TIFFDataWidth(datatype));
else if (datatype == TIFF_SLONG && in_datatype == TIFF_SLONG8)
{
tmsize_t i;
@@ -3698,8 +3817,8 @@ int _TIFFRewriteField(TIFF *tif, uint16_t tag, TIFFDataType in_datatype,
tif->tif_dir.td_stripoffset_entry.tdir_type == 0 &&
tif->tif_dir.td_stripoffset_entry.tdir_offset.toff_long8 == 0)
{
tif->tif_dir.td_stripoffset_entry.tdir_type = datatype;
tif->tif_dir.td_stripoffset_entry.tdir_count = count;
tif->tif_dir.td_stripoffset_entry.tdir_type = (uint16_t)datatype;
tif->tif_dir.td_stripoffset_entry.tdir_count = (uint64_t)count;
}
else if ((tag == TIFFTAG_TILEBYTECOUNTS ||
tag == TIFFTAG_STRIPBYTECOUNTS) &&
@@ -3707,8 +3826,8 @@ int _TIFFRewriteField(TIFF *tif, uint16_t tag, TIFFDataType in_datatype,
tif->tif_dir.td_stripbytecount_entry.tdir_type == 0 &&
tif->tif_dir.td_stripbytecount_entry.tdir_offset.toff_long8 == 0)
{
tif->tif_dir.td_stripbytecount_entry.tdir_type = datatype;
tif->tif_dir.td_stripbytecount_entry.tdir_count = count;
tif->tif_dir.td_stripbytecount_entry.tdir_type = (uint16_t)datatype;
tif->tif_dir.td_stripbytecount_entry.tdir_count = (uint64_t)count;
}
/* -------------------------------------------------------------------- */
@@ -3756,13 +3875,14 @@ int _TIFFRewriteField(TIFF *tif, uint16_t tag, TIFFDataType in_datatype,
if (count * TIFFDataWidth(datatype) == 4)
{
uint32_t value;
memcpy(&value, buf_to_write, count * TIFFDataWidth(datatype));
memcpy(&value, buf_to_write,
(size_t)count * (size_t)TIFFDataWidth(datatype));
entry_offset = value;
}
else
{
memcpy(&entry_offset, buf_to_write,
count * TIFFDataWidth(datatype));
(size_t)count * (size_t)TIFFDataWidth(datatype));
}
}
@@ -3772,7 +3892,7 @@ int _TIFFRewriteField(TIFF *tif, uint16_t tag, TIFFDataType in_datatype,
/* -------------------------------------------------------------------- */
/* Adjust the directory entry. */
/* -------------------------------------------------------------------- */
entry_type = datatype;
entry_type = (uint16_t)datatype;
entry_count = (uint64_t)count;
memcpy(direntry_raw + 2, &entry_type, sizeof(uint16_t));
if (tif->tif_flags & TIFF_SWAB)

View File

@@ -80,7 +80,7 @@ static int DumpModeDecode(TIFF *tif, uint8_t *buf, tmsize_t cc, uint16_t s)
"Not enough data for scanline %" PRIu32
", expected a request for at most %" TIFF_SSIZE_FORMAT
" bytes, got a request for %" TIFF_SSIZE_FORMAT " bytes",
tif->tif_row, tif->tif_rawcc, cc);
tif->tif_dir.td_row, tif->tif_rawcc, cc);
return (0);
}
/*
@@ -99,8 +99,23 @@ static int DumpModeDecode(TIFF *tif, uint8_t *buf, tmsize_t cc, uint16_t s)
*/
static int DumpModeSeek(TIFF *tif, uint32_t nrows)
{
tif->tif_rawcp += nrows * tif->tif_scanlinesize;
tif->tif_rawcc -= nrows * tif->tif_scanlinesize;
tmsize_t seek_size;
if (nrows > 0 &&
tif->tif_dir.td_scanlinesize > (tmsize_t)(TIFF_TMSIZE_T_MAX / nrows))
{
TIFFErrorExtR(tif, "DumpModeSeek",
"Integer overflow computing seek size");
return (0);
}
seek_size = (tmsize_t)nrows * tif->tif_dir.td_scanlinesize;
if (seek_size > tif->tif_rawcc)
{
TIFFErrorExtR(tif, "DumpModeSeek",
"Seek beyond end of raw data buffer");
return (0);
}
tif->tif_rawcp += seek_size;
tif->tif_rawcc -= seek_size;
return (1);
}

View File

@@ -123,7 +123,7 @@ typedef struct
static const char module[] = mod; \
Fax3CodecState *sp = DecoderState(tif); \
int a0; /* reference element */ \
int lastx = sp->b.rowpixels; /* last element in row */ \
int lastx = (int)sp->b.rowpixels; /* last element in row */ \
uint32_t BitAcc; /* bit accumulator */ \
int BitsAvail; /* # valid bits in BitAcc */ \
int RunLength; /* length of current run */ \
@@ -209,61 +209,68 @@ static int Fax3PreDecode(TIFF *tif, uint16_t s)
static void Fax3Unexpected(const char *module, TIFF *tif, uint32_t line,
uint32_t a0)
{
TIFFErrorExtR(tif, module,
"Bad code word at line %" PRIu32 " of %s %" PRIu32
" (x %" PRIu32 ")",
line, isTiled(tif) ? "tile" : "strip",
(isTiled(tif) ? tif->tif_curtile : tif->tif_curstrip), a0);
TIFFErrorExtR(
tif, module,
"Bad code word at line %" PRIu32 " of %s %" PRIu32 " (x %" PRIu32 ")",
line, isTiled(tif) ? "tile" : "strip",
(isTiled(tif) ? tif->tif_dir.td_curtile : tif->tif_dir.td_curstrip),
a0);
}
#define unexpected(table, a0) \
do \
{ \
Fax3Unexpected(module, tif, sp->line, a0); \
Fax3Unexpected(module, tif, (uint32_t)sp->line, (uint32_t)(a0)); \
++sp->unexpectedReachedCount; \
} while (0)
static void Fax3Extension(const char *module, TIFF *tif, uint32_t line,
uint32_t a0)
{
TIFFErrorExtR(tif, module,
"Uncompressed data (not supported) at line %" PRIu32
" of %s %" PRIu32 " (x %" PRIu32 ")",
line, isTiled(tif) ? "tile" : "strip",
(isTiled(tif) ? tif->tif_curtile : tif->tif_curstrip), a0);
TIFFErrorExtR(
tif, module,
"Uncompressed data (not supported) at line %" PRIu32 " of %s %" PRIu32
" (x %" PRIu32 ")",
line, isTiled(tif) ? "tile" : "strip",
(isTiled(tif) ? tif->tif_dir.td_curtile : tif->tif_dir.td_curstrip),
a0);
}
#define extension(a0) Fax3Extension(module, tif, sp->line, a0)
#define extension(a0) \
Fax3Extension(module, tif, (uint32_t)sp->line, (uint32_t)(a0))
static void Fax3BadLength(const char *module, TIFF *tif, uint32_t line,
uint32_t a0, uint32_t lastx)
{
TIFFWarningExtR(tif, module,
"%s at line %" PRIu32 " of %s %" PRIu32 " (got %" PRIu32
", expected %" PRIu32 ")",
a0 < lastx ? "Premature EOL" : "Line length mismatch", line,
isTiled(tif) ? "tile" : "strip",
(isTiled(tif) ? tif->tif_curtile : tif->tif_curstrip), a0,
lastx);
TIFFWarningExtR(
tif, module,
"%s at line %" PRIu32 " of %s %" PRIu32 " (got %" PRIu32
", expected %" PRIu32 ")",
a0 < lastx ? "Premature EOL" : "Line length mismatch", line,
isTiled(tif) ? "tile" : "strip",
(isTiled(tif) ? tif->tif_dir.td_curtile : tif->tif_dir.td_curstrip), a0,
lastx);
}
#define badlength(a0, lastx) \
do \
{ \
Fax3BadLength(module, tif, sp->line, a0, lastx); \
Fax3BadLength(module, tif, (uint32_t)sp->line, (uint32_t)(a0), \
(uint32_t)(lastx)); \
++sp->eolReachedCount; \
} while (0)
static void Fax3PrematureEOF(const char *module, TIFF *tif, uint32_t line,
uint32_t a0)
{
TIFFWarningExtR(tif, module,
"Premature EOF at line %" PRIu32 " of %s %" PRIu32
" (x %" PRIu32 ")",
line, isTiled(tif) ? "tile" : "strip",
(isTiled(tif) ? tif->tif_curtile : tif->tif_curstrip), a0);
TIFFWarningExtR(
tif, module,
"Premature EOF at line %" PRIu32 " of %s %" PRIu32 " (x %" PRIu32 ")",
line, isTiled(tif) ? "tile" : "strip",
(isTiled(tif) ? tif->tif_dir.td_curtile : tif->tif_dir.td_curstrip),
a0);
}
#define prematureEOF(a0) \
do \
{ \
Fax3PrematureEOF(module, tif, sp->line, a0); \
Fax3PrematureEOF(module, tif, (uint32_t)sp->line, (uint32_t)(a0)); \
++sp->eofReachedCount; \
} while (0)
@@ -275,16 +282,15 @@ static void Fax3TryG3WithoutEOL(const char *module, TIFF *tif, uint32_t line,
"Try to decode (read) fax Group 3 data without EOL at line %" PRIu32
" of %s %" PRIu32 " (x %" PRIu32 "). Please check result",
line, isTiled(tif) ? "tile" : "strip",
(isTiled(tif) ? tif->tif_curtile : tif->tif_curstrip), a0);
(isTiled(tif) ? tif->tif_dir.td_curtile : tif->tif_dir.td_curstrip),
a0);
}
#define tryG3WithoutEOL(a0) \
do \
{ \
Fax3TryG3WithoutEOL(module, tif, sp->line, a0); \
Fax3TryG3WithoutEOL(module, tif, (uint32_t)sp->line, (uint32_t)(a0)); \
} while (0)
#define Nop
static int CheckReachedCounters(TIFF *tif, const char *module,
Fax3CodecState *sp)
{
@@ -344,12 +350,12 @@ RETRY_WITHOUT_EOL_1D:
pa = thisrun;
#ifdef FAX3_DEBUG
printf("\nBitAcc=%08" PRIX32 ", BitsAvail = %d\n", BitAcc, BitsAvail);
printf("-------------------- %" PRIu32 "\n", tif->tif_row);
printf("-------------------- %" PRIu32 "\n", tif->tif_dir.td_row);
fflush(stdout);
#endif
SYNC_EOL(EOF1D, RETRY_WITHOUT_EOL_1D);
EXPAND1D(EOF1Da);
(*sp->fill)(buf, thisrun, pa, lastx);
(*sp->fill)(buf, thisrun, pa, (uint32_t)lastx);
buf += sp->b.rowbytes;
occ -= sp->b.rowbytes;
sp->line++;
@@ -357,7 +363,7 @@ RETRY_WITHOUT_EOL_1D:
EOF1D: /* premature EOF */
CLEANUP_RUNS();
EOF1Da: /* premature EOF */
(*sp->fill)(buf, thisrun, pa, lastx);
(*sp->fill)(buf, thisrun, pa, (uint32_t)lastx);
UNCACHE_STATE(tif, sp);
return (-1);
}
@@ -404,16 +410,16 @@ RETRY_WITHOUT_EOL_2D:
ClrBits(1);
#ifdef FAX3_DEBUG
printf(" %s\n-------------------- %" PRIu32 "\n", is1D ? "1D" : "2D",
tif->tif_row);
tif->tif_dir.td_row);
fflush(stdout);
#endif
pb = sp->refruns;
b1 = *pb++;
b1 = (int)*pb++;
if (is1D)
EXPAND1D(EOF2Da);
else
EXPAND2D(EOF2Da);
(*sp->fill)(buf, thisrun, pa, lastx);
(*sp->fill)(buf, thisrun, pa, (uint32_t)lastx);
if (pa < thisrun + sp->nruns)
{
SETVALUE(0); /* imaginary change for reference */
@@ -426,7 +432,7 @@ RETRY_WITHOUT_EOL_2D:
EOF2D: /* premature EOF */
CLEANUP_RUNS();
EOF2Da: /* premature EOF */
(*sp->fill)(buf, thisrun, pa, lastx);
(*sp->fill)(buf, thisrun, pa, (uint32_t)lastx);
UNCACHE_STATE(tif, sp);
return (-1);
}
@@ -479,12 +485,12 @@ void _TIFFFax3fillruns(unsigned char *buf, uint32_t *runs, uint32_t *erun,
{
if (bx)
{ /* align to byte boundary */
*cp++ &= 0xff << (8 - bx);
*cp++ &= (unsigned char)(0xff << (8 - bx));
run -= 8 - bx;
}
if ((n = run >> 3) != 0)
if ((n = (int32_t)(run >> 3)) != 0)
{ /* multiple bytes to fill */
if ((n / sizeof(int64_t)) > 1)
if (((size_t)n / sizeof(int64_t)) > 1)
{
/*
* Align to int64_tword boundary and fill.
@@ -492,8 +498,8 @@ void _TIFFFax3fillruns(unsigned char *buf, uint32_t *runs, uint32_t *erun,
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);
nw = (int32_t)((size_t)n / sizeof(int64_t));
n -= (int32_t)((size_t)nw * sizeof(int64_t));
do
{
*lp++ = 0L;
@@ -504,10 +510,10 @@ void _TIFFFax3fillruns(unsigned char *buf, uint32_t *runs, uint32_t *erun,
run &= 7;
}
if (run)
cp[0] &= 0xff >> run;
cp[0] &= (unsigned char)(0xff >> run);
}
else
cp[0] &= ~(_fillmasks[run] >> bx);
cp[0] &= (unsigned char)~(_fillmasks[run] >> bx);
x += runs[0];
}
run = runs[1];
@@ -521,12 +527,12 @@ void _TIFFFax3fillruns(unsigned char *buf, uint32_t *runs, uint32_t *erun,
{
if (bx)
{ /* align to byte boundary */
*cp++ |= 0xff >> bx;
*cp++ |= (unsigned char)(0xff >> bx);
run -= 8 - bx;
}
if ((n = run >> 3) != 0)
if ((n = (int32_t)(run >> 3)) != 0)
{ /* multiple bytes to fill */
if ((n / sizeof(int64_t)) > 1)
if (((size_t)n / sizeof(int64_t)) > 1)
{
/*
* Align to int64_t boundary and fill.
@@ -534,8 +540,8 @@ void _TIFFFax3fillruns(unsigned char *buf, uint32_t *runs, uint32_t *erun,
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);
nw = (int32_t)((size_t)n / sizeof(int64_t));
n -= (int32_t)((size_t)nw * sizeof(int64_t));
do
{
*lp++ = -1L;
@@ -550,7 +556,7 @@ void _TIFFFax3fillruns(unsigned char *buf, uint32_t *runs, uint32_t *erun,
cp[0] = (unsigned char)((cp[0] | (0xff00 >> run)) & 0xff);
}
else
cp[0] |= _fillmasks[run] >> bx;
cp[0] |= (unsigned char)(_fillmasks[run] >> bx);
x += runs[1];
}
}
@@ -726,12 +732,13 @@ static const int _msbmask[9] = {0x00, 0x01, 0x03, 0x07, 0x0f,
{ \
while (length > bit) \
{ \
data |= bits >> (length - bit); \
data |= (int)((unsigned int)bits >> (length - bit)); \
length -= bit; \
_FlushBits(tif); \
} \
assert(length < 9); \
data |= (bits & _msbmask[length]) << (bit - length); \
data |= (int)(((unsigned int)bits & (unsigned int)_msbmask[length]) \
<< (unsigned int)(bit - length)); \
bit -= length; \
if (bit == 0) \
_FlushBits(tif); \
@@ -745,13 +752,13 @@ static const int _msbmask[9] = {0x00, 0x01, 0x03, 0x07, 0x0f,
static int Fax3PutBits(TIFF *tif, unsigned int bits, unsigned int length)
{
Fax3CodecState *sp = EncoderState(tif);
unsigned int bit = sp->bit;
int data = sp->data;
unsigned int bit = (unsigned int)sp->bit;
int data = (int)sp->data;
_PutBits(tif, bits, length);
sp->data = data;
sp->bit = bit;
sp->data = (uint32_t)data;
sp->bit = (int)bit;
return 1;
}
@@ -782,8 +789,8 @@ static int Fax3PutBits(TIFF *tif, unsigned int bits, unsigned int length)
static int putspan(TIFF *tif, int32_t span, const tableentry *tab)
{
Fax3CodecState *sp = EncoderState(tif);
unsigned int bit = sp->bit;
int data = sp->data;
unsigned int bit = (unsigned int)sp->bit;
int data = (int)sp->data;
unsigned int code, length;
while (span >= 2624)
@@ -816,8 +823,8 @@ static int putspan(TIFF *tif, int32_t span, const tableentry *tab)
#endif
_PutBits(tif, code, length);
sp->data = data;
sp->bit = bit;
sp->data = (uint32_t)data;
sp->bit = (int)bit;
return 1;
}
@@ -831,8 +838,8 @@ static int putspan(TIFF *tif, int32_t span, const tableentry *tab)
static int Fax3PutEOL(TIFF *tif)
{
Fax3CodecState *sp = EncoderState(tif);
unsigned int bit = sp->bit;
int data = sp->data;
unsigned int bit = (unsigned int)sp->bit;
int data = (int)sp->data;
unsigned int code, length, tparm;
if (sp->b.groupoptions & GROUP3OPT_FILLBITS)
@@ -849,7 +856,7 @@ static int Fax3PutEOL(TIFF *tif)
align = sp->bit + (8 - align);
else
align = sp->bit - align;
tparm = align;
tparm = (unsigned int)align;
_PutBits(tif, 0, tparm);
}
}
@@ -862,8 +869,8 @@ static int Fax3PutEOL(TIFF *tif)
}
_PutBits(tif, code, length);
sp->data = data;
sp->bit = bit;
sp->data = (uint32_t)data;
sp->bit = (int)bit;
return 1;
}
@@ -991,10 +998,10 @@ static inline int32_t find0span(unsigned char *bp, int32_t bs, int32_t be)
bp++;
}
lp = (int64_t *)bp;
while ((bits >= (int32_t)(8 * sizeof(int64_t))) && (0 == *lp))
while ((bits >= (int32_t)(size_t)(8 * sizeof(int64_t))) && (0 == *lp))
{
span += 8 * sizeof(int64_t);
bits -= 8 * sizeof(int64_t);
span += (int32_t)(size_t)(8 * sizeof(int64_t));
bits -= (int32_t)(size_t)(8 * sizeof(int64_t));
lp++;
}
bp = (unsigned char *)lp;
@@ -1059,11 +1066,11 @@ static inline int32_t find1span(unsigned char *bp, int32_t bs, int32_t be)
bp++;
}
lp = (int64_t *)bp;
while ((bits >= (int32_t)(8 * sizeof(int64_t))) &&
while ((bits >= (int32_t)(size_t)(8 * sizeof(int64_t))) &&
(~((uint64_t)0) == (uint64_t)*lp))
{
span += 8 * sizeof(int64_t);
bits -= 8 * sizeof(int64_t);
span += (int32_t)(size_t)(8 * sizeof(int64_t));
bits -= (int32_t)(size_t)(8 * sizeof(int64_t));
lp++;
}
bp = (unsigned char *)lp;
@@ -1118,16 +1125,16 @@ static int Fax3Encode1DRow(TIFF *tif, unsigned char *bp, uint32_t bits)
for (;;)
{
span = find0span(bp, bs, bits); /* white span */
span = find0span(bp, (int32_t)bs, (int32_t)bits); /* white span */
if (!putspan(tif, span, TIFFFaxWhiteCodes))
return 0;
bs += span;
bs += (uint32_t)span;
if (bs >= bits)
break;
span = find1span(bp, bs, bits); /* black span */
span = find1span(bp, (int32_t)bs, (int32_t)bits); /* black span */
if (!putspan(tif, span, TIFFFaxBlackCodes))
return 0;
bs += span;
bs += (uint32_t)span;
if (bs >= bits)
break;
}
@@ -1161,15 +1168,20 @@ static const tableentry vcodes[7] = {
static int Fax3Encode2DRow(TIFF *tif, unsigned char *bp, unsigned char *rp,
uint32_t bits)
{
#define PIXEL(buf, ix) ((((buf)[(ix) >> 3]) >> (7 - ((ix)&7))) & 1)
#define PIXEL(buf, ix) ((((buf)[(ix) >> 3]) >> (7 - ((ix) & 7))) & 1)
uint32_t a0 = 0;
uint32_t a1 = (PIXEL(bp, 0) != 0 ? 0 : finddiff(bp, 0, bits, 0));
uint32_t b1 = (PIXEL(rp, 0) != 0 ? 0 : finddiff(rp, 0, bits, 0));
uint32_t a1 = (PIXEL(bp, 0) != 0
? 0
: (uint32_t)finddiff(bp, (int32_t)0, (int32_t)bits, 0));
uint32_t b1 = (PIXEL(rp, 0) != 0
? 0
: (uint32_t)finddiff(rp, (int32_t)0, (int32_t)bits, 0));
uint32_t a2, b2;
for (;;)
{
b2 = finddiff2(rp, b1, bits, PIXEL(rp, b1));
b2 = (uint32_t)finddiff2(rp, (int32_t)b1, (int32_t)bits,
(int32_t)PIXEL(rp, b1));
if (b2 >= a1)
{
/* Naive computation triggers
@@ -1182,21 +1194,22 @@ static int Fax3Encode2DRow(TIFF *tif, unsigned char *bp, unsigned char *rp,
: 0x7FFFFFFF;
if (!(-3 <= d && d <= 3))
{ /* horizontal mode */
a2 = finddiff2(bp, a1, bits, PIXEL(bp, a1));
a2 = (uint32_t)finddiff2(bp, (int32_t)a1, (int32_t)bits,
(int32_t)PIXEL(bp, a1));
if (!putcode(tif, &horizcode))
return 0;
if (a0 + a1 == 0 || PIXEL(bp, a0) == 0)
{
if (!putspan(tif, a1 - a0, TIFFFaxWhiteCodes))
if (!putspan(tif, (int32_t)(a1 - a0), TIFFFaxWhiteCodes))
return 0;
if (!putspan(tif, a2 - a1, TIFFFaxBlackCodes))
if (!putspan(tif, (int32_t)(a2 - a1), TIFFFaxBlackCodes))
return 0;
}
else
{
if (!putspan(tif, a1 - a0, TIFFFaxBlackCodes))
if (!putspan(tif, (int32_t)(a1 - a0), TIFFFaxBlackCodes))
return 0;
if (!putspan(tif, a2 - a1, TIFFFaxWhiteCodes))
if (!putspan(tif, (int32_t)(a2 - a1), TIFFFaxWhiteCodes))
return 0;
}
a0 = a2;
@@ -1216,9 +1229,12 @@ static int Fax3Encode2DRow(TIFF *tif, unsigned char *bp, unsigned char *rp,
}
if (a0 >= bits)
break;
a1 = finddiff(bp, a0, bits, PIXEL(bp, a0));
b1 = finddiff(rp, a0, bits, !PIXEL(bp, a0));
b1 = finddiff(rp, b1, bits, PIXEL(bp, a0));
a1 = (uint32_t)finddiff(bp, (int32_t)a0, (int32_t)bits,
(int32_t)PIXEL(bp, a0));
b1 = (uint32_t)finddiff(rp, (int32_t)a0, (int32_t)bits,
(int32_t)!PIXEL(bp, a0));
b1 = (uint32_t)finddiff(rp, (int32_t)b1, (int32_t)bits,
(int32_t)PIXEL(bp, a0));
}
return (1);
#undef PIXEL
@@ -1487,6 +1503,8 @@ static void Fax3PrintDir(TIFF *tif, FILE *fd, long flags)
case CLEANFAXDATA_UNCLEAN:
fprintf(fd, " uncorrected errors");
break;
default:
break;
}
fprintf(fd, " (%" PRIu16 " = 0x%" PRIx16 ")\n", sp->cleanfaxdata,
sp->cleanfaxdata);
@@ -1500,6 +1518,22 @@ static void Fax3PrintDir(TIFF *tif, FILE *fd, long flags)
(*sp->printdir)(tif, fd, flags);
}
static uint64_t Fax3GetMaxCompressionRatio(TIFF *tif)
{
(void)tif;
/* See README_for_libtiff_developpers.md for raw data used to estimate
* the maximum compression rate. */
/* 1024x1024: 36 */
/* 4096x4096: 100 */
/* 16383x16383: 163 */
/* 65536x65536: 200 */
/* 200000x200000: 208 */
return 250;
}
static int InitCCITTFax3(TIFF *tif)
{
static const char module[] = "InitCCITTFax3";
@@ -1564,6 +1598,7 @@ static int InitCCITTFax3(TIFF *tif)
tif->tif_encodetile = Fax3Encode;
tif->tif_close = Fax3Close;
tif->tif_cleanup = Fax3Cleanup;
tif->tif_getmaxcompressionratio = Fax3GetMaxCompressionRatio;
return (1);
}
@@ -1626,10 +1661,10 @@ static int Fax4Decode(TIFF *tif, uint8_t *buf, tmsize_t occ, uint16_t s)
RunLength = 0;
pa = thisrun = sp->curruns;
pb = sp->refruns;
b1 = *pb++;
b1 = (int)*pb++;
#ifdef FAX3_DEBUG
printf("\nBitAcc=%08" PRIX32 ", BitsAvail = %d\n", BitAcc, BitsAvail);
printf("-------------------- %d\n", tif->tif_row);
printf("-------------------- %d\n", tif->tif_dir.td_row);
fflush(stdout);
#endif
EXPAND2D(EOFG4);
@@ -1643,7 +1678,7 @@ static int Fax4Decode(TIFF *tif, uint8_t *buf, tmsize_t occ, uint16_t s)
occ, lastx);
return -1;
}
(*sp->fill)(buf, thisrun, pa, lastx);
(*sp->fill)(buf, thisrun, pa, (uint32_t)lastx);
SETVALUE(0); /* imaginary change for reference */
SWAP(uint32_t *, sp->curruns, sp->refruns);
buf += sp->b.rowbytes;
@@ -1666,7 +1701,7 @@ static int Fax4Decode(TIFF *tif, uint8_t *buf, tmsize_t occ, uint16_t s)
occ, lastx);
return -1;
}
(*sp->fill)(buf, thisrun, pa, lastx);
(*sp->fill)(buf, thisrun, pa, (uint32_t)lastx);
UNCACHE_STATE(tif, sp);
return (sp->line != start
? 1
@@ -1713,6 +1748,16 @@ static int Fax4PostEncode(TIFF *tif)
return (1);
}
static uint64_t Fax4GetMaxCompressionRatio(TIFF *tif)
{
/* FAX4 can compress up to almost one byte per line, so the compression
* ratio can be up to the tile/strip width.
* See README_for_libtiff_developpers.md for raw data
*/
return isTiled(tif) ? tif->tif_dir.td_tilewidth
: tif->tif_dir.td_imagewidth;
}
int TIFFInitCCITTFax4(TIFF *tif, int scheme)
{
(void)scheme;
@@ -1735,6 +1780,7 @@ int TIFFInitCCITTFax4(TIFF *tif, int scheme)
tif->tif_encodestrip = Fax4Encode;
tif->tif_encodetile = Fax4Encode;
tif->tif_postencode = Fax4PostEncode;
tif->tif_getmaxcompressionratio = Fax4GetMaxCompressionRatio;
/*
* Suppress RTC at the end of each strip.
*/
@@ -1773,11 +1819,11 @@ static int Fax3DecodeRLE(TIFF *tif, uint8_t *buf, tmsize_t occ, uint16_t s)
pa = thisrun;
#ifdef FAX3_DEBUG
printf("\nBitAcc=%08" PRIX32 ", BitsAvail = %d\n", BitAcc, BitsAvail);
printf("-------------------- %" PRIu32 "\n", tif->tif_row);
printf("-------------------- %" PRIu32 "\n", tif->tif_dir.td_row);
fflush(stdout);
#endif
EXPAND1D(EOFRLE);
(*sp->fill)(buf, thisrun, pa, lastx);
(*sp->fill)(buf, thisrun, pa, (uint32_t)lastx);
/*
* Cleanup at the end of the row.
*/
@@ -1798,7 +1844,7 @@ static int Fax3DecodeRLE(TIFF *tif, uint8_t *buf, tmsize_t occ, uint16_t s)
sp->line++;
continue;
EOFRLE: /* premature EOF */
(*sp->fill)(buf, thisrun, pa, lastx);
(*sp->fill)(buf, thisrun, pa, (uint32_t)lastx);
UNCACHE_STATE(tif, sp);
return (-1);
}
@@ -1806,6 +1852,21 @@ static int Fax3DecodeRLE(TIFF *tif, uint8_t *buf, tmsize_t occ, uint16_t s)
return (1);
}
static uint64_t Fax3RLEGetMaxCompressionRatio(TIFF *tif)
{
(void)tif;
/* See README_for_libtiff_developpers.md for raw data used to estimate
* the maximum compression rate. */
/* 1024x1024: 43 */
/* 4096x4096: 128 */
/* 16383x16383: 171 */
/* 65536x65536: 205 */
/* 200000x200000: 211 */
return 250;
}
int TIFFInitCCITTRLE(TIFF *tif, int scheme)
{
(void)scheme;
@@ -1814,6 +1875,7 @@ int TIFFInitCCITTRLE(TIFF *tif, int scheme)
tif->tif_decoderow = Fax3DecodeRLE;
tif->tif_decodestrip = Fax3DecodeRLE;
tif->tif_decodetile = Fax3DecodeRLE;
tif->tif_getmaxcompressionratio = Fax3RLEGetMaxCompressionRatio;
/*
* Suppress RTC+EOLs when encoding and byte-align data.
*/
@@ -1832,6 +1894,7 @@ int TIFFInitCCITTRLEW(TIFF *tif, int scheme)
tif->tif_decoderow = Fax3DecodeRLE;
tif->tif_decodestrip = Fax3DecodeRLE;
tif->tif_decodetile = Fax3DecodeRLE;
tif->tif_getmaxcompressionratio = Fax3RLEGetMaxCompressionRatio;
/*
* Suppress RTC+EOLs when encoding and word-align data.
*/

View File

@@ -267,14 +267,14 @@ static const char *StateNames[] = {
{ \
if (pa >= thisrun + sp->nruns) \
{ \
TIFFErrorExtR(tif, module, "Buffer overflow at line %u of %s %u", \
TIFFErrorExtR(tif, module, "Buffer overflow at line %d of %s %u", \
sp->line, isTiled(tif) ? "tile" : "strip", \
isTiled(tif) ? tif->tif_curtile \
: tif->tif_curstrip); \
isTiled(tif) ? tif->tif_dir.td_curtile \
: tif->tif_dir.td_curstrip); \
return (-1); \
} \
*pa++ = RunLength + (x); \
a0 += (x); \
*pa++ = (uint32_t)((uint32_t)RunLength + (uint32_t)(x)); \
a0 += (int)(uint32_t)(x); \
RunLength = 0; \
} while (0)
#endif
@@ -334,20 +334,20 @@ static const char *StateNames[] = {
{ \
if (RunLength) \
SETVALUE(0); \
if (a0 != lastx) \
if (a0 != (int)lastx) \
{ \
badlength(a0, lastx); \
while (a0 > lastx && pa > thisrun) \
a0 -= *--pa; \
if (a0 < lastx) \
while (a0 > (int)lastx && pa > thisrun) \
a0 -= (int)*--pa; \
if (a0 < (int)lastx) \
{ \
if (a0 < 0) \
a0 = 0; \
if ((pa - thisrun) & 1) \
SETVALUE(0); \
SETVALUE(lastx - a0); \
SETVALUE((uint32_t)((int)lastx - a0)); \
} \
else if (a0 > lastx) \
else if (a0 > (int)lastx) \
{ \
SETVALUE(lastx); \
SETVALUE(0); \
@@ -385,8 +385,9 @@ static const char *StateNames[] = {
goto doneWhite1d; \
case S_MakeUpW: \
case S_MakeUp: \
a0 += TabEnt->Param; \
RunLength += TabEnt->Param; \
a0 = (int)((uint32_t)a0 + TabEnt->Param); \
RunLength = \
(int)((uint32_t)RunLength + TabEnt->Param); \
break; \
default: \
unexpected("WhiteTable", a0); \
@@ -394,7 +395,7 @@ static const char *StateNames[] = {
} \
} \
doneWhite1d: \
if (a0 >= lastx) \
if (a0 >= (int)lastx) \
goto done1d; \
for (;;) \
{ \
@@ -409,8 +410,8 @@ static const char *StateNames[] = {
goto doneBlack1d; \
case S_MakeUpB: \
case S_MakeUp: \
a0 += TabEnt->Param; \
RunLength += TabEnt->Param; \
a0 += (int)TabEnt->Param; \
RunLength += (int)TabEnt->Param; \
break; \
default: \
unexpected("BlackTable", a0); \
@@ -418,7 +419,7 @@ static const char *StateNames[] = {
} \
} \
doneBlack1d: \
if (a0 >= lastx) \
if (a0 >= (int)lastx) \
goto done1d; \
if (*(pa - 1) == 0 && *(pa - 2) == 0) \
pa -= 2; \
@@ -439,17 +440,18 @@ static const char *StateNames[] = {
do \
{ \
if (pa != thisrun) \
while (b1 <= a0 && b1 < lastx) \
while (b1 <= a0 && b1 < (int)lastx) \
{ \
if (pb + 1 >= sp->refruns + sp->nruns) \
{ \
TIFFErrorExtR( \
tif, module, "Buffer overflow at line %u of %s %u", \
sp->line, isTiled(tif) ? "tile" : "strip", \
isTiled(tif) ? tif->tif_curtile : tif->tif_curstrip); \
TIFFErrorExtR(tif, module, \
"Buffer overflow at line %d of %s %u", \
sp->line, isTiled(tif) ? "tile" : "strip", \
isTiled(tif) ? tif->tif_dir.td_curtile \
: tif->tif_dir.td_curstrip); \
return (-1); \
} \
b1 += pb[0] + pb[1]; \
b1 += (int)(pb[0] + pb[1]); \
pb += 2; \
} \
} while (0)
@@ -460,14 +462,15 @@ static const char *StateNames[] = {
#define EXPAND2D(eoflab) \
do \
{ \
while (a0 < lastx) \
while (a0 < (int)lastx) \
{ \
if (pa >= thisrun + sp->nruns) \
{ \
TIFFErrorExtR( \
tif, module, "Buffer overflow at line %u of %s %u", \
sp->line, isTiled(tif) ? "tile" : "strip", \
isTiled(tif) ? tif->tif_curtile : tif->tif_curstrip); \
TIFFErrorExtR(tif, module, \
"Buffer overflow at line %d of %s %u", sp->line, \
isTiled(tif) ? "tile" : "strip", \
isTiled(tif) ? tif->tif_dir.td_curtile \
: tif->tif_dir.td_curstrip); \
return (-1); \
} \
LOOKUP8(7, TIFFFaxMainTable, eof2d); \
@@ -477,18 +480,19 @@ static const char *StateNames[] = {
CHECK_b1; \
if (pb + 1 >= sp->refruns + sp->nruns) \
{ \
TIFFErrorExtR(tif, module, \
"Buffer overflow at line %u of %s %u", \
sp->line, \
isTiled(tif) ? "tile" : "strip", \
isTiled(tif) ? tif->tif_curtile \
: tif->tif_curstrip); \
TIFFErrorExtR( \
tif, module, \
"Buffer overflow at line %d of %s %u", sp->line, \
isTiled(tif) ? "tile" : "strip", \
isTiled(tif) ? tif->tif_dir.td_curtile \
: tif->tif_dir.td_curstrip); \
return (-1); \
} \
b1 += *pb++; \
RunLength += b1 - a0; \
b1 = b1 + (int)*pb++; \
RunLength = \
(int)((uint32_t)RunLength + (uint32_t)(b1 - a0)); \
a0 = b1; \
b1 += *pb++; \
b1 = b1 + (int)*pb++; \
break; \
case S_Horiz: \
if ((pa - thisrun) & 1) \
@@ -503,8 +507,9 @@ static const char *StateNames[] = {
goto doneWhite2da; \
case S_MakeUpB: \
case S_MakeUp: \
a0 += TabEnt->Param; \
RunLength += TabEnt->Param; \
a0 = (int)((uint32_t)a0 + TabEnt->Param); \
RunLength = (int)((uint32_t)RunLength + \
TabEnt->Param); \
break; \
default: \
goto badBlack2d; \
@@ -521,8 +526,9 @@ static const char *StateNames[] = {
goto doneBlack2da; \
case S_MakeUpW: \
case S_MakeUp: \
a0 += TabEnt->Param; \
RunLength += TabEnt->Param; \
a0 = (int)((uint32_t)a0 + TabEnt->Param); \
RunLength = (int)((uint32_t)RunLength + \
TabEnt->Param); \
break; \
default: \
goto badWhite2d; \
@@ -542,8 +548,9 @@ static const char *StateNames[] = {
goto doneWhite2db; \
case S_MakeUpW: \
case S_MakeUp: \
a0 += TabEnt->Param; \
RunLength += TabEnt->Param; \
a0 = (int)((uint32_t)a0 + TabEnt->Param); \
RunLength = (int)((uint32_t)RunLength + \
TabEnt->Param); \
break; \
default: \
goto badWhite2d; \
@@ -560,8 +567,9 @@ static const char *StateNames[] = {
goto doneBlack2db; \
case S_MakeUpB: \
case S_MakeUp: \
a0 += TabEnt->Param; \
RunLength += TabEnt->Param; \
a0 = (int)((uint32_t)a0 + TabEnt->Param); \
RunLength = (int)((uint32_t)RunLength + \
TabEnt->Param); \
break; \
default: \
goto badBlack2d; \
@@ -576,47 +584,47 @@ static const char *StateNames[] = {
SETVALUE(b1 - a0); \
if (pb >= sp->refruns + sp->nruns) \
{ \
TIFFErrorExtR(tif, module, \
"Buffer overflow at line %u of %s %u", \
sp->line, \
isTiled(tif) ? "tile" : "strip", \
isTiled(tif) ? tif->tif_curtile \
: tif->tif_curstrip); \
TIFFErrorExtR( \
tif, module, \
"Buffer overflow at line %d of %s %u", sp->line, \
isTiled(tif) ? "tile" : "strip", \
isTiled(tif) ? tif->tif_dir.td_curtile \
: tif->tif_dir.td_curstrip); \
return (-1); \
} \
b1 += *pb++; \
b1 = b1 + (int)*pb++; \
break; \
case S_VR: \
CHECK_b1; \
SETVALUE(b1 - a0 + TabEnt->Param); \
SETVALUE((int)((uint32_t)(b1 - a0) + TabEnt->Param)); \
if (pb >= sp->refruns + sp->nruns) \
{ \
TIFFErrorExtR(tif, module, \
"Buffer overflow at line %u of %s %u", \
sp->line, \
isTiled(tif) ? "tile" : "strip", \
isTiled(tif) ? tif->tif_curtile \
: tif->tif_curstrip); \
TIFFErrorExtR( \
tif, module, \
"Buffer overflow at line %d of %s %u", sp->line, \
isTiled(tif) ? "tile" : "strip", \
isTiled(tif) ? tif->tif_dir.td_curtile \
: tif->tif_dir.td_curstrip); \
return (-1); \
} \
b1 += *pb++; \
b1 = b1 + (int)*pb++; \
break; \
case S_VL: \
CHECK_b1; \
if (b1 < (int)(a0 + TabEnt->Param)) \
if (b1 < (int)((uint32_t)a0 + TabEnt->Param)) \
{ \
unexpected("VL", a0); \
goto eol2d; \
} \
SETVALUE(b1 - a0 - TabEnt->Param); \
b1 -= *--pb; \
SETVALUE((int)((uint32_t)(b1 - a0) - TabEnt->Param)); \
b1 = b1 - (int)*--pb; \
break; \
case S_Ext: \
*pa++ = lastx - a0; \
*pa++ = (uint32_t)((int)lastx - a0); \
extension(a0); \
goto eol2d; \
case S_EOL: \
*pa++ = lastx - a0; \
*pa++ = (uint32_t)((int)lastx - a0); \
NeedBits8(4, eof2d); \
if (GetBits(4)) \
unexpected("EOL", a0); \

File diff suppressed because it is too large Load Diff

View File

@@ -76,7 +76,7 @@ static const int anPrimes[] = {
100663319, 201326611, 402653189, 805306457, 1610612741};
/************************************************************************/
/* TIFFHashSetHashPointer() */
/* TIFFHashSetHashPointer() */
/************************************************************************/
/**
@@ -93,7 +93,7 @@ static unsigned long TIFFHashSetHashPointer(const void *elt)
}
/************************************************************************/
/* TIFFHashSetEqualPointer() */
/* TIFFHashSetEqualPointer() */
/************************************************************************/
/**
@@ -111,7 +111,7 @@ static bool TIFFHashSetEqualPointer(const void *elt1, const void *elt2)
}
/************************************************************************/
/* TIFFHashSetNew() */
/* TIFFHashSetNew() */
/************************************************************************/
/**
@@ -164,7 +164,7 @@ TIFFHashSet *TIFFHashSetNew(TIFFHashSetHashFunc fnHashFunc,
}
/************************************************************************/
/* TIFFHashSetSize() */
/* TIFFHashSetSize() */
/************************************************************************/
/**
@@ -184,7 +184,7 @@ int TIFFHashSetSize(const TIFFHashSet *set)
}
/************************************************************************/
/* TIFFHashSetGetNewListElt() */
/* TIFFHashSetGetNewListElt() */
/************************************************************************/
static TIFFList *TIFFHashSetGetNewListElt(TIFFHashSet *set)
@@ -202,7 +202,7 @@ static TIFFList *TIFFHashSetGetNewListElt(TIFFHashSet *set)
}
/************************************************************************/
/* TIFFHashSetReturnListElt() */
/* TIFFHashSetReturnListElt() */
/************************************************************************/
static void TIFFHashSetReturnListElt(TIFFHashSet *set, TIFFList *psList)
@@ -220,7 +220,7 @@ static void TIFFHashSetReturnListElt(TIFFHashSet *set, TIFFList *psList)
}
/************************************************************************/
/* TIFFHashSetClearInternal() */
/* TIFFHashSetClearInternal() */
/************************************************************************/
static void TIFFHashSetClearInternal(TIFFHashSet *set, bool bFinalize)
@@ -246,7 +246,7 @@ static void TIFFHashSetClearInternal(TIFFHashSet *set, bool bFinalize)
}
/************************************************************************/
/* TIFFListDestroy() */
/* TIFFListDestroy() */
/************************************************************************/
/**
@@ -270,7 +270,7 @@ static void TIFFListDestroy(TIFFList *psList)
}
/************************************************************************/
/* TIFFHashSetDestroy() */
/* TIFFHashSetDestroy() */
/************************************************************************/
/**
@@ -295,7 +295,7 @@ void TIFFHashSetDestroy(TIFFHashSet *set)
#ifdef notused
/************************************************************************/
/* TIFFHashSetClear() */
/* TIFFHashSetClear() */
/************************************************************************/
/**
@@ -319,7 +319,7 @@ void TIFFHashSetClear(TIFFHashSet *set)
}
/************************************************************************/
/* TIFFHashSetForeach() */
/* TIFFHashSetForeach() */
/************************************************************************/
/**
@@ -360,14 +360,14 @@ void TIFFHashSetForeach(TIFFHashSet *set, TIFFHashSetIterEltFunc fnIterFunc,
#endif
/************************************************************************/
/* TIFFHashSetRehash() */
/* TIFFHashSetRehash() */
/************************************************************************/
static bool TIFFHashSetRehash(TIFFHashSet *set)
{
int nNewAllocatedSize = anPrimes[set->nIndiceAllocatedSize];
TIFFList **newTabList =
(TIFFList **)(calloc(nNewAllocatedSize, sizeof(TIFFList *)));
(TIFFList **)(calloc((size_t)nNewAllocatedSize, sizeof(TIFFList *)));
if (newTabList == NULL)
return false;
#ifdef HASH_DEBUG
@@ -384,7 +384,7 @@ static bool TIFFHashSetRehash(TIFFHashSet *set)
while (cur)
{
const unsigned long nNewHashVal =
set->fnHashFunc(cur->pData) % nNewAllocatedSize;
set->fnHashFunc(cur->pData) % (unsigned long)nNewAllocatedSize;
#ifdef HASH_DEBUG
if (newTabList[nNewHashVal])
set->nCollisions++;
@@ -403,12 +403,13 @@ static bool TIFFHashSetRehash(TIFFHashSet *set)
}
/************************************************************************/
/* TIFFHashSetFindPtr() */
/* TIFFHashSetFindPtr() */
/************************************************************************/
static void **TIFFHashSetFindPtr(TIFFHashSet *set, const void *elt)
{
const unsigned long nHashVal = set->fnHashFunc(elt) % set->nAllocatedSize;
const unsigned long nHashVal =
set->fnHashFunc(elt) % (unsigned long)set->nAllocatedSize;
TIFFList *cur = set->tabList[nHashVal];
while (cur)
{
@@ -464,7 +465,8 @@ bool TIFFHashSetInsert(TIFFHashSet *set, void *elt)
}
}
const unsigned long nHashVal = set->fnHashFunc(elt) % set->nAllocatedSize;
const unsigned long nHashVal =
set->fnHashFunc(elt) % (unsigned long)set->nAllocatedSize;
#ifdef HASH_DEBUG
if (set->tabList[nHashVal])
set->nCollisions++;
@@ -486,7 +488,7 @@ bool TIFFHashSetInsert(TIFFHashSet *set, void *elt)
}
/************************************************************************/
/* TIFFHashSetLookup() */
/* TIFFHashSetLookup() */
/************************************************************************/
/**
@@ -532,7 +534,8 @@ static bool TIFFHashSetRemoveInternal(TIFFHashSet *set, const void *elt,
}
}
int nHashVal = (int)(set->fnHashFunc(elt) % set->nAllocatedSize);
int nHashVal =
(int)(set->fnHashFunc(elt) % (unsigned long)set->nAllocatedSize);
TIFFList *cur = set->tabList[nHashVal];
TIFFList *prev = NULL;
while (cur)
@@ -581,7 +584,7 @@ bool TIFFHashSetRemove(TIFFHashSet *set, const void *elt)
#ifdef notused
/************************************************************************/
/* TIFFHashSetRemoveDeferRehash() */
/* TIFFHashSetRemoveDeferRehash() */
/************************************************************************/
/**

View File

@@ -33,7 +33,14 @@
#include "tiffiop.h"
#ifdef JBIG_SUPPORT
#ifdef __cplusplus
extern "C"
{
#endif
#include "jbig.h"
#ifdef __cplusplus
}
#endif
static int JBIGSetupDecode(TIFF *tif)
{
@@ -100,7 +107,7 @@ static int JBIGDecode(TIFF *tif, uint8_t *buffer, tmsize_t size, uint16_t s)
decodedSize = jbg_dec_getsize(&decoder);
if ((tmsize_t)decodedSize < size)
{
memset(buffer + decodedSize, 0, (size_t)(size - decodedSize));
memset(buffer + decodedSize, 0, (size_t)(size - (tmsize_t)decodedSize));
TIFFWarningExtR(tif, "JBIG",
"Only decoded %lu bytes, whereas %" TIFF_SSIZE_FORMAT
" requested",
@@ -116,7 +123,7 @@ static int JBIGDecode(TIFF *tif, uint8_t *buffer, tmsize_t size, uint16_t s)
return 0;
}
pImage = jbg_dec_getimage(&decoder, 0);
_TIFFmemcpy(buffer, pImage, decodedSize);
_TIFFmemcpy(buffer, pImage, (tmsize_t)decodedSize);
jbg_dec_free(&decoder);
tif->tif_rawcp += tif->tif_rawcc;

View File

@@ -22,9 +22,6 @@
* OF THIS SOFTWARE.
*/
#define WIN32_LEAN_AND_MEAN
#define VC_EXTRALEAN
#include "tiffiop.h"
#include <stdlib.h>
@@ -146,20 +143,9 @@ int TIFFJPEGIsFullStripRequired_12(TIFF *tif);
#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
typedef struct jpeg_destination_mgr tiff_jpeg_destination_mgr;
typedef struct jpeg_source_mgr tiff_jpeg_source_mgr;
typedef struct jpeg_error_mgr tiff_jpeg_error_mgr;
/*
* State block for each open TIFF file using
@@ -174,6 +160,10 @@ typedef struct jpeg_error_mgr jpeg_error_mgr;
* so we can safely cast JPEGState* -> jpeg_xxx_struct*
* and vice versa!
*/
#ifdef _MSC_VER
#pragma warning(push)
#pragma warning(disable : 4324) /* structure padding due to alignment */
#endif
typedef struct
{
union
@@ -184,22 +174,24 @@ typedef struct
} cinfo; /* NB: must be first */
int cinfo_initialized;
jpeg_error_mgr err; /* libjpeg error manager */
JMP_BUF exit_jmpbuf; /* for catching libjpeg failures */
tiff_jpeg_error_mgr err; /* libjpeg error manager */
JMP_BUF exit_jmpbuf; /* for catching libjpeg failures */
struct jpeg_progress_mgr progress;
/*
* The following two members could be a union, but
* they're small enough that it's not worth the effort.
*/
jpeg_destination_mgr dest; /* data dest for compression */
jpeg_source_mgr src; /* data source for decompression */
/* private state */
TIFF *tif; /* back link needed by some code */
uint16_t photometric; /* copy of PhotometricInterpretation */
uint16_t h_sampling; /* luminance sampling factors */
tiff_jpeg_destination_mgr dest; /* data dest for compression */
tiff_jpeg_source_mgr src; /* data source for decompression */
/* private state */
TIFF *tif; /* back link needed by some code */
uint16_t photometric; /* copy of PhotometricInterpretation */
uint16_t h_sampling; /* luminance sampling factors */
uint16_t v_sampling;
tmsize_t bytesperline; /* decompressed bytes per scanline */
uint32_t strile_width;
uint32_t strile_height;
/* pointers to intermediate buffers when processing downsampled data */
TIFF_JSAMPARRAY ds_buffer[MAX_COMPONENTS];
int scancount; /* number of "scanlines" accumulated */
@@ -209,6 +201,9 @@ typedef struct
int encode_raw_error;
} JPEGState;
#ifdef _MSC_VER
#pragma warning(pop)
#endif
#define JState(tif) ((JPEGState *)(tif)->tif_data)
@@ -559,7 +554,7 @@ static boolean tables_empty_output_buffer(j_compress_ptr cinfo)
/* the entire buffer has been filled; enlarge it by 1000 bytes */
newbuf =
_TIFFreallocExt(sp->tif, (void *)sp->otherSettings.jpegtables,
(tmsize_t)(sp->otherSettings.jpegtables_length + 1000));
(tmsize_t)sp->otherSettings.jpegtables_length + 1000);
if (newbuf == NULL)
ERREXIT1(cinfo, JERR_OUT_OF_MEMORY, 100);
sp->dest.next_output_byte =
@@ -912,7 +907,7 @@ JPEGFixupTagsSubsamplingSec(struct JPEGFixupTagsSubsamplingData *data)
return (0);
if (n < 2)
return (0);
n -= 2;
n = (uint16_t)(n - 2);
if (n > 0)
JPEGFixupTagsSubsamplingSkip(data, n);
}
@@ -1016,7 +1011,7 @@ JPEGFixupTagsSubsamplingReadByte(struct JPEGFixupTagsSubsamplingData *data,
assert(m < 0x80000000UL);
if (TIFFReadFile(data->tif, data->buffer, (tmsize_t)m) != (tmsize_t)m)
return (0);
data->buffercurrentbyte = data->buffer;
data->buffercurrentbyte = (uint8_t *)data->buffer;
data->bufferbytesleft = m;
data->fileoffset += m;
data->filebytesleft -= m;
@@ -1037,7 +1032,7 @@ JPEGFixupTagsSubsamplingReadWord(struct JPEGFixupTagsSubsamplingData *data,
return (0);
if (!JPEGFixupTagsSubsamplingReadByte(data, &mb))
return (0);
*result = (ma << 8) | mb;
*result = (uint16_t)((ma << 8) | mb);
return (1);
}
@@ -1159,6 +1154,47 @@ int TIFFJPEGIsFullStripRequired(TIFF *tif)
return ret;
}
static int JPEGComputeStrileWidthHeightBytesPerLine(TIFF *tif, uint16_t s)
{
JPEGState *sp = JState(tif);
TIFFDirectory *td = &tif->tif_dir;
/*
* Check image parameters and set decompression parameters.
*/
if (isTiled(tif))
{
sp->strile_width = td->td_tilewidth;
sp->strile_height = td->td_tilelength;
sp->bytesperline = TIFFTileRowSize(tif);
}
else
{
sp->strile_width = td->td_imagewidth;
sp->strile_height = td->td_imagelength - tif->tif_dir.td_row;
if (sp->strile_height > td->td_rowsperstrip)
sp->strile_height = td->td_rowsperstrip;
sp->bytesperline = TIFFScanlineSize(tif);
}
if (td->td_planarconfig == PLANARCONFIG_SEPARATE && s > 0)
{
/*
* 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, "JPEGComputeStrileWidthHeightBytesPerLine",
"JPEG horizontal or vertical sampling is zero");
return (0);
}
sp->strile_width = TIFFhowmany_32(sp->strile_width, sp->h_sampling);
sp->strile_height = TIFFhowmany_32(sp->strile_height, sp->v_sampling);
}
return 1;
}
/*
* Set up for decoding a strip or tile.
*/
@@ -1167,7 +1203,6 @@ int TIFFJPEGIsFullStripRequired(TIFF *tif)
JPEGState *sp = JState(tif);
TIFFDirectory *td = &tif->tif_dir;
static const char module[] = "JPEGPreDecode";
uint32_t segment_width, segment_height;
int downsampled_output;
int ci;
@@ -1193,52 +1228,24 @@ int TIFFJPEGIsFullStripRequired(TIFF *tif)
return (0);
tif->tif_rawcp = (uint8_t *)sp->src.next_input_byte;
tif->tif_rawcc = sp->src.bytes_in_buffer;
tif->tif_rawcc = (tmsize_t)sp->src.bytes_in_buffer;
/*
* Check image parameters and set decompression parameters.
*/
if (isTiled(tif))
{
segment_width = td->td_tilewidth;
segment_height = td->td_tilelength;
sp->bytesperline = TIFFTileRowSize(tif);
}
else
{
segment_width = td->td_imagewidth;
segment_height = td->td_imagelength - tif->tif_row;
if (segment_height > td->td_rowsperstrip)
segment_height = td->td_rowsperstrip;
sp->bytesperline = TIFFScanlineSize(tif);
}
if (td->td_planarconfig == PLANARCONFIG_SEPARATE && s > 0)
{
/*
* 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);
}
if (sp->cinfo.d.image_width < segment_width ||
sp->cinfo.d.image_height < segment_height)
if (!JPEGComputeStrileWidthHeightBytesPerLine(tif, s))
return 0;
if (sp->cinfo.d.image_width < sp->strile_width ||
sp->cinfo.d.image_height < sp->strile_height)
{
TIFFWarningExtR(tif, module,
"Improper JPEG strip/tile size, "
"expected %" PRIu32 "x%" PRIu32 ", got %ux%u",
segment_width, segment_height, sp->cinfo.d.image_width,
sp->cinfo.d.image_height);
sp->strile_width, sp->strile_height,
sp->cinfo.d.image_width, sp->cinfo.d.image_height);
}
if (sp->cinfo.d.image_width == segment_width &&
sp->cinfo.d.image_height > segment_height &&
tif->tif_row + segment_height == td->td_imagelength && !isTiled(tif))
if (sp->cinfo.d.image_width == sp->strile_width &&
sp->cinfo.d.image_height > sp->strile_height &&
tif->tif_dir.td_row + sp->strile_height == td->td_imagelength &&
!isTiled(tif))
{
/* Some files have a last strip, that should be truncated, */
/* but their JPEG codestream has still the maximum strip */
@@ -1247,11 +1254,11 @@ int TIFFJPEGIsFullStripRequired(TIFF *tif)
TIFFWarningExtR(tif, module,
"JPEG strip size exceeds expected dimensions,"
" expected %" PRIu32 "x%" PRIu32 ", got %ux%u",
segment_width, segment_height, sp->cinfo.d.image_width,
sp->cinfo.d.image_height);
sp->strile_width, sp->strile_height,
sp->cinfo.d.image_width, sp->cinfo.d.image_height);
}
else if (sp->cinfo.d.image_width > segment_width ||
sp->cinfo.d.image_height > segment_height)
else if (sp->cinfo.d.image_width > sp->strile_width ||
sp->cinfo.d.image_height > sp->strile_height)
{
/*
* This case could be dangerous, if the strip or tile size has
@@ -1262,8 +1269,8 @@ int TIFFJPEGIsFullStripRequired(TIFF *tif)
TIFFErrorExtR(tif, module,
"JPEG strip/tile size exceeds expected dimensions,"
" expected %" PRIu32 "x%" PRIu32 ", got %ux%u",
segment_width, segment_height, sp->cinfo.d.image_width,
sp->cinfo.d.image_height);
sp->strile_width, sp->strile_height,
sp->cinfo.d.image_width, sp->cinfo.d.image_height);
return (0);
}
if (sp->cinfo.d.num_components !=
@@ -1282,7 +1289,8 @@ int TIFFJPEGIsFullStripRequired(TIFF *tif)
sp->cinfo.d.data_precision = td->td_bitspersample;
sp->cinfo.d.bits_in_jsample = td->td_bitspersample;
#else
if (sp->cinfo.d.data_precision != td->td_bitspersample)
if (td->td_bitspersample != BITS_IN_JSAMPLE ||
sp->cinfo.d.data_precision != td->td_bitspersample)
{
TIFFErrorExtR(tif, module, "Improper JPEG data precision");
return (0);
@@ -1319,11 +1327,12 @@ int TIFFJPEGIsFullStripRequired(TIFF *tif)
if (compptr->h_samp_factor > 0 && compptr->v_samp_factor > 0)
{
nRequiredMemory +=
(toff_t)(((compptr->width_in_blocks +
compptr->h_samp_factor - 1) /
compptr->h_samp_factor)) *
((compptr->height_in_blocks + compptr->v_samp_factor - 1) /
compptr->v_samp_factor) *
(toff_t)((JDIMENSION)(((int)compptr->width_in_blocks +
compptr->h_samp_factor - 1) /
compptr->h_samp_factor)) *
(JDIMENSION)(((int)compptr->height_in_blocks +
compptr->v_samp_factor - 1) /
compptr->v_samp_factor) *
sizeof(JBLOCK);
}
}
@@ -1439,7 +1448,7 @@ int TIFFJPEGIsFullStripRequired(TIFF *tif)
* Decode a chunk of pixels.
* "Standard" case: returned data is not downsampled.
*/
#if !JPEG_LIB_MK1_OR_12BIT
#if !defined(JPEG_LIB_MK1_OR_12BIT)
static int JPEGDecode(TIFF *tif, uint8_t *buf, tmsize_t cc, uint16_t s)
{
JPEGState *sp = JState(tif);
@@ -1464,7 +1473,18 @@ static int JPEGDecode(TIFF *tif, uint8_t *buf, tmsize_t cc, uint16_t s)
TIFFWarningExtR(tif, tif->tif_name, "fractional scanline not read");
if (nrows > (tmsize_t)sp->cinfo.d.image_height)
{
/* Initialize the output buffer if the JPEG image is smaller than the
* strile height. */
memset(buf, 0, (size_t)cc);
nrows = sp->cinfo.d.image_height;
}
else if (sp->strile_width > sp->cinfo.d.image_width)
{
/* Initialize the output buffer if the JPEG image is smaller than the
* strile width. */
memset(buf, 0, (size_t)cc);
}
/* data is expected to be read in multiples of a scanline */
if (nrows)
@@ -1483,7 +1503,7 @@ static int JPEGDecode(TIFF *tif, uint8_t *buf, tmsize_t cc, uint16_t s)
return (0);
}
++tif->tif_row;
++tif->tif_dir.td_row;
buf += sp->bytesperline;
cc -= sp->bytesperline;
} while (--nrows > 0);
@@ -1491,15 +1511,15 @@ static int JPEGDecode(TIFF *tif, uint8_t *buf, tmsize_t cc, uint16_t s)
/* Update information on consumed data */
tif->tif_rawcp = (uint8_t *)sp->src.next_input_byte;
tif->tif_rawcc = sp->src.bytes_in_buffer;
tif->tif_rawcc = (tmsize_t)sp->src.bytes_in_buffer;
/* Close down the decompressor if we've finished the strip or tile. */
return sp->cinfo.d.output_scanline < sp->cinfo.d.output_height ||
TIFFjpeg_finish_decompress(sp);
}
#endif /* !JPEG_LIB_MK1_OR_12BIT */
#endif /* !defined(JPEG_LIB_MK1_OR_12BIT) */
#if JPEG_LIB_MK1_OR_12BIT
#if defined(JPEG_LIB_MK1_OR_12BIT)
/*ARGSUSED*/ static int JPEGDecode(TIFF *tif, uint8_t *buf, tmsize_t cc,
uint16_t s)
{
@@ -1525,7 +1545,18 @@ static int JPEGDecode(TIFF *tif, uint8_t *buf, tmsize_t cc, uint16_t s)
TIFFWarningExtR(tif, tif->tif_name, "fractional scanline not read");
if (nrows > (tmsize_t)sp->cinfo.d.image_height)
{
/* Initialize the output buffer if the JPEG image is smaller than the
* strile height. */
memset(buf, 0, (size_t)cc);
nrows = sp->cinfo.d.image_height;
}
else if (sp->strile_width > sp->cinfo.d.image_width)
{
/* Initialize the output buffer if the JPEG image is smaller than the
* strile width. */
memset(buf, 0, (size_t)cc);
}
/* data is expected to be read in multiples of a scanline */
if (nrows)
@@ -1539,8 +1570,9 @@ static int JPEGDecode(TIFF *tif, uint8_t *buf, tmsize_t cc, uint16_t s)
if (sp->cinfo.d.data_precision == 12)
{
line_work_buf = (TIFF_JSAMPROW)_TIFFmallocExt(
tif, sizeof(short) * sp->cinfo.d.output_width *
sp->cinfo.d.num_components);
tif, (tmsize_t)((size_t)sizeof(short) *
(size_t)sp->cinfo.d.output_width *
(size_t)sp->cinfo.d.num_components));
}
do
@@ -1556,14 +1588,16 @@ static int JPEGDecode(TIFF *tif, uint8_t *buf, tmsize_t cc, uint16_t s)
if (TIFFjpeg_read_scanlines(sp, &line_work_buf, 1) != 1)
{
memset(buf, 0, (size_t)cc);
_TIFFfreeExt(tif, line_work_buf);
return (0);
}
if (sp->cinfo.d.data_precision == 12)
{
int value_pairs = (sp->cinfo.d.output_width *
sp->cinfo.d.num_components) /
2;
int value_pairs =
(int)((JDIMENSION)sp->cinfo.d.output_width *
(JDIMENSION)sp->cinfo.d.num_components) /
2;
int iPair;
for (iPair = 0; iPair < value_pairs; iPair++)
@@ -1582,18 +1616,19 @@ static int JPEGDecode(TIFF *tif, uint8_t *buf, tmsize_t cc, uint16_t s)
else if (sp->cinfo.d.data_precision == 8)
{
int value_count =
(sp->cinfo.d.output_width * sp->cinfo.d.num_components);
(int)((JDIMENSION)sp->cinfo.d.output_width *
(JDIMENSION)sp->cinfo.d.num_components);
int iValue;
for (iValue = 0; iValue < value_count; iValue++)
{
((unsigned char *)buf)[iValue] =
line_work_buf[iValue] & 0xff;
(unsigned char)(line_work_buf[iValue] & 0xff);
}
}
}
++tif->tif_row;
++tif->tif_dir.td_row;
buf += sp->bytesperline;
cc -= sp->bytesperline;
} while (--nrows > 0);
@@ -1604,13 +1639,13 @@ static int JPEGDecode(TIFF *tif, uint8_t *buf, tmsize_t cc, uint16_t s)
/* Update information on consumed data */
tif->tif_rawcp = (uint8_t *)sp->src.next_input_byte;
tif->tif_rawcc = sp->src.bytes_in_buffer;
tif->tif_rawcc = (tmsize_t)sp->src.bytes_in_buffer;
/* Close down the decompressor if we've finished the strip or tile. */
return sp->cinfo.d.output_scanline < sp->cinfo.d.output_height ||
TIFFjpeg_finish_decompress(sp);
}
#endif /* JPEG_LIB_MK1_OR_12BIT */
#endif /* defined(JPEG_LIB_MK1_OR_12BIT) */
/*ARGSUSED*/ static int DecodeRowError(TIFF *tif, uint8_t *buf, tmsize_t cc,
uint16_t s)
@@ -1644,8 +1679,16 @@ static int JPEGDecode(TIFF *tif, uint8_t *buf, tmsize_t cc, uint16_t s)
/* For last strip, limit number of rows to its truncated height */
/* even if the codestream height is larger (which is not compliant, */
/* but that we tolerate) */
if ((uint32_t)nrows > td->td_imagelength - tif->tif_row && !isTiled(tif))
nrows = td->td_imagelength - tif->tif_row;
if ((uint32_t)nrows > td->td_imagelength - tif->tif_dir.td_row &&
!isTiled(tif))
nrows = td->td_imagelength - tif->tif_dir.td_row;
/* The downsampled-data decode loop below only writes up to the JPEG
* codestream dimensions (and, due to the clump stride, may not cover the
* full caller buffer even for compliant files). Zero the whole buffer so
* no uninitialised heap is ever returned, mirroring the guard JPEGDecode
* received in 65759931ab6e (#826). */
memset(buf, 0, (size_t)cc);
#if defined(JPEG_LIB_MK1_OR_12BIT)
unsigned short *tmpbuf = NULL;
@@ -1660,9 +1703,10 @@ static int JPEGDecode(TIFF *tif, uint8_t *buf, tmsize_t cc, uint16_t s)
int samples_per_clump = sp->samplesperclump;
#if defined(JPEG_LIB_MK1_OR_12BIT)
tmpbuf = _TIFFmallocExt(tif, sizeof(unsigned short) *
sp->cinfo.d.output_width *
sp->cinfo.d.num_components);
tmpbuf = (unsigned short *)_TIFFmallocExt(
tif, (tmsize_t)((size_t)sizeof(unsigned short) *
(size_t)sp->cinfo.d.output_width *
(size_t)sp->cinfo.d.num_components));
if (tmpbuf == NULL)
{
TIFFErrorExtR(tif, "JPEGDecodeRaw", "Out of memory");
@@ -1755,18 +1799,20 @@ static int JPEGDecode(TIFF *tif, uint8_t *buf, tmsize_t cc, uint16_t s)
if (sp->cinfo.d.data_precision == 8)
{
int i = 0;
int len =
sp->cinfo.d.output_width * sp->cinfo.d.num_components;
int len = (int)((JDIMENSION)sp->cinfo.d.output_width *
(JDIMENSION)sp->cinfo.d.num_components);
for (i = 0; i < len; i++)
{
((unsigned char *)buf)[i] = tmpbuf[i] & 0xff;
((unsigned char *)buf)[i] =
(unsigned char)(tmpbuf[i] & 0xff);
}
}
else
{ /* 12-bit */
int value_pairs = (sp->cinfo.d.output_width *
sp->cinfo.d.num_components) /
2;
int value_pairs =
(int)((JDIMENSION)sp->cinfo.d.output_width *
(JDIMENSION)sp->cinfo.d.num_components) /
2;
int iPair;
for (iPair = 0; iPair < value_pairs; iPair++)
{
@@ -1785,7 +1831,7 @@ static int JPEGDecode(TIFF *tif, uint8_t *buf, tmsize_t cc, uint16_t s)
#endif
sp->scancount++;
tif->tif_row += sp->v_sampling;
tif->tif_dir.td_row += sp->v_sampling;
buf += sp->bytesperline;
cc -= sp->bytesperline;
@@ -2024,9 +2070,9 @@ static int JPEGSetupEncode(TIFF *tif)
if (!TIFFGetField(tif, TIFFTAG_REFERENCEBLACKWHITE, &ref))
{
float refbw[6];
long top = 1L << td->td_bitspersample;
uint32_t top = 1U << td->td_bitspersample;
refbw[0] = 0;
refbw[1] = (float)(top - 1L);
refbw[1] = (float)(top - 1);
refbw[2] = (float)(top >> 1);
refbw[3] = refbw[1];
refbw[4] = refbw[2];
@@ -2074,30 +2120,30 @@ static int JPEGSetupEncode(TIFF *tif)
#endif
if (isTiled(tif))
{
if ((td->td_tilelength % (sp->v_sampling * DCTSIZE)) != 0)
if ((td->td_tilelength % ((uint32_t)sp->v_sampling * DCTSIZE)) != 0)
{
TIFFErrorExtR(tif, module,
"JPEG tile height must be multiple of %" PRIu32,
(uint32_t)(sp->v_sampling * DCTSIZE));
(uint32_t)sp->v_sampling * DCTSIZE);
return (0);
}
if ((td->td_tilewidth % (sp->h_sampling * DCTSIZE)) != 0)
if ((td->td_tilewidth % ((uint32_t)sp->h_sampling * DCTSIZE)) != 0)
{
TIFFErrorExtR(tif, module,
"JPEG tile width must be multiple of %" PRIu32,
(uint32_t)(sp->h_sampling * DCTSIZE));
(uint32_t)sp->h_sampling * DCTSIZE);
return (0);
}
}
else
{
if (td->td_rowsperstrip < td->td_imagelength &&
(td->td_rowsperstrip % (sp->v_sampling * DCTSIZE)) != 0)
(td->td_rowsperstrip % ((uint32_t)sp->v_sampling * DCTSIZE)) != 0)
{
TIFFErrorExtR(tif, module,
"RowsPerStrip must be multiple of %" PRIu32
" for JPEG",
(uint32_t)(sp->v_sampling * DCTSIZE));
(uint32_t)sp->v_sampling * DCTSIZE);
return (0);
}
}
@@ -2153,7 +2199,6 @@ static int JPEGPreEncode(TIFF *tif, uint16_t s)
JPEGState *sp = JState(tif);
TIFFDirectory *td = &tif->tif_dir;
static const char module[] = "JPEGPreEncode";
uint32_t segment_width, segment_height;
int downsampled_input;
assert(sp != NULL);
@@ -2164,47 +2209,20 @@ static int JPEGPreEncode(TIFF *tif, uint16_t s)
}
assert(!sp->cinfo.comm.is_decompressor);
/*
* Set encoding parameters for this strip/tile.
*/
if (isTiled(tif))
{
segment_width = td->td_tilewidth;
segment_height = td->td_tilelength;
sp->bytesperline = TIFFTileRowSize(tif);
}
else
{
segment_width = td->td_imagewidth;
segment_height = td->td_imagelength - tif->tif_row;
if (segment_height > td->td_rowsperstrip)
segment_height = td->td_rowsperstrip;
sp->bytesperline = TIFFScanlineSize(tif);
}
if (td->td_planarconfig == PLANARCONFIG_SEPARATE && s > 0)
{
/* 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);
}
if (segment_width > (uint32_t)JPEG_MAX_DIMENSION ||
segment_height > (uint32_t)JPEG_MAX_DIMENSION)
if (!JPEGComputeStrileWidthHeightBytesPerLine(tif, s))
return 0;
if (sp->strile_width > (uint32_t)JPEG_MAX_DIMENSION ||
sp->strile_height > (uint32_t)JPEG_MAX_DIMENSION)
{
TIFFErrorExtR(tif, module,
"Strip/tile too large for JPEG. Maximum dimension is %d",
(int)JPEG_MAX_DIMENSION);
return (0);
}
sp->cinfo.c.image_width = segment_width;
sp->cinfo.c.image_height = segment_height;
sp->cinfo.c.image_width = sp->strile_width;
sp->cinfo.c.image_height = sp->strile_height;
downsampled_input = FALSE;
if (td->td_planarconfig == PLANARCONFIG_CONTIG)
{
@@ -2276,7 +2294,13 @@ static int JPEGPreEncode(TIFF *tif, uint16_t s)
/* an existing file */
suppress_huff_table(sp, 0);
suppress_huff_table(sp, 1);
sp->cinfo.c.optimize_coding = FALSE;
/* We want to keep optimize_coding = TRUE for 12-bit JPEG */
/* See lengthy explanation at
* https://gitlab.com/libtiff/libtiff/-/work_items/773#note_3009836854
*/
if (sp->cinfo.c.data_precision == 8)
sp->cinfo.c.optimize_coding = FALSE;
}
else
sp->cinfo.c.optimize_coding = TRUE;
@@ -2332,13 +2356,15 @@ static int JPEGEncode(TIFF *tif, uint8_t *buf, tmsize_t cc, uint16_t s)
TIFFWarningExtR(tif, tif->tif_name, "fractional scanline discarded");
/* The last strip will be limited to image size */
if (!isTiled(tif) && tif->tif_row + nrows > tif->tif_dir.td_imagelength)
nrows = tif->tif_dir.td_imagelength - tif->tif_row;
if (!isTiled(tif) &&
tif->tif_dir.td_row + nrows > tif->tif_dir.td_imagelength)
nrows = tif->tif_dir.td_imagelength - tif->tif_dir.td_row;
if (sp->cinfo.c.data_precision == 12)
{
line16_count = (int)((sp->bytesperline * 2) / 3);
line16 = (short *)_TIFFmallocExt(tif, sizeof(short) * line16_count);
line16 = (short *)_TIFFmallocExt(
tif, (tmsize_t)(sizeof(short) * (size_t)line16_count));
if (!line16)
{
TIFFErrorExtR(tif, "JPEGEncode", "Failed to allocate memory");
@@ -2363,8 +2389,10 @@ static int JPEGEncode(TIFF *tif, uint8_t *buf, tmsize_t cc, uint16_t s)
unsigned char *in_ptr = ((unsigned char *)buf) + iPair * 3;
TIFF_JSAMPLE *out_ptr = (TIFF_JSAMPLE *)(line16 + iPair * 2);
out_ptr[0] = (in_ptr[0] << 4) | ((in_ptr[1] & 0xf0) >> 4);
out_ptr[1] = ((in_ptr[1] & 0x0f) << 8) | in_ptr[2];
out_ptr[0] = (TIFF_JSAMPLE)((in_ptr[0] << 4) |
((in_ptr[1] & 0xf0) >> 4));
out_ptr[1] =
(TIFF_JSAMPLE)(((in_ptr[1] & 0x0f) << 8) | in_ptr[2]);
}
}
else
@@ -2374,7 +2402,7 @@ static int JPEGEncode(TIFF *tif, uint8_t *buf, tmsize_t cc, uint16_t s)
if (TIFFjpeg_write_scanlines(sp, bufptr, 1) != 1)
return (0);
if (nrows > 0)
tif->tif_row++;
tif->tif_dir.td_row++;
buf += sp->bytesperline;
}
@@ -2443,8 +2471,9 @@ static int JPEGEncodeRaw(TIFF *tif, uint8_t *buf, tmsize_t cc, uint16_t s)
{
int hsamp = compptr->h_samp_factor;
int vsamp = compptr->v_samp_factor;
int padding = (int)(compptr->width_in_blocks * DCTSIZE -
clumps_per_line * hsamp);
int padding =
(int)(compptr->width_in_blocks * DCTSIZE -
(JDIMENSION)clumps_per_line * (JDIMENSION)hsamp);
for (ypos = 0; ypos < vsamp; ypos++)
{
inptr = ((TIFF_JSAMPLE *)buf) + clumpoffset;
@@ -2488,7 +2517,7 @@ static int JPEGEncodeRaw(TIFF *tif, uint8_t *buf, tmsize_t cc, uint16_t s)
}
sp->scancount = 0;
}
tif->tif_row += sp->v_sampling;
tif->tif_dir.td_row += sp->v_sampling;
buf += bytesperclumpline;
nrows -= sp->v_sampling;
}
@@ -2582,10 +2611,11 @@ static void JPEGResetUpsampled(TIFF *tif)
* Must recalculate cached tile size in case sampling state changed.
* Should we really be doing this now if image size isn't set?
*/
if (tif->tif_tilesize > 0)
tif->tif_tilesize = isTiled(tif) ? TIFFTileSize(tif) : (tmsize_t)(-1);
if (tif->tif_scanlinesize > 0)
tif->tif_scanlinesize = TIFFScanlineSize(tif);
if (tif->tif_dir.td_tilesize > 0)
tif->tif_dir.td_tilesize =
isTiled(tif) ? TIFFTileSize(tif) : (tmsize_t)(-1);
if (tif->tif_dir.td_scanlinesize > 0)
tif->tif_dir.td_scanlinesize = TIFFScanlineSize(tif);
}
static int JPEGVSetField(TIFF *tif, uint32_t tag, va_list ap)
@@ -2793,6 +2823,33 @@ static int JPEGInitializeLibJPEG(TIFF *tif, int decompress)
return 1;
}
static uint64_t JPEGGetMaxCompressionRatio(TIFF *tif)
{
/* See README_for_libtiff_developpers.md for raw data used to estimate
* the maximum compression rate. */
const JPEGState *sp = JState(tif);
if ((tif->tif_dir.td_photometric == PHOTOMETRIC_YCBCR) &&
(tif->tif_dir.td_planarconfig == PLANARCONFIG_CONTIG) &&
(tif->tif_dir.td_samplesperpixel == 3))
{
if (sp->h_sampling == 2 && sp->v_sampling == 2)
{
if (tif->tif_dir.td_bitspersample == 12)
return 768;
else
return 512;
}
return 0; /* unknown */
}
if (tif->tif_dir.td_bitspersample == 12)
return 384;
else
return 256;
}
/* Common to tif_jpeg.c and tif_jpeg_12.c */
static void TIFFInitJPEGCommon(TIFF *tif)
{
@@ -2829,6 +2886,7 @@ static void TIFFInitJPEGCommon(TIFF *tif)
tif->tif_encoderow = JPEGEncode;
tif->tif_encodestrip = JPEGEncode;
tif->tif_encodetile = JPEGEncode;
tif->tif_getmaxcompressionratio = JPEGGetMaxCompressionRatio;
tif->tif_cleanup = JPEGCleanup;
tif->tif_defstripsize = JPEGDefaultStripSize;

View File

@@ -33,6 +33,7 @@
#include "Lerc_c_api.h"
#include "zlib.h"
#include <math.h>
#ifdef ZSTD_SUPPORT
#include "zstd.h"
#endif
@@ -188,7 +189,7 @@ static int SetupBuffers(TIFF *tif, LERCState *sp, const char *module)
else
{
sp->segment_width = td->td_imagewidth;
sp->segment_height = td->td_imagelength - tif->tif_row;
sp->segment_height = td->td_imagelength - tif->tif_dir.td_row;
if (sp->segment_height > td->td_rowsperstrip)
sp->segment_height = td->td_rowsperstrip;
}
@@ -242,7 +243,7 @@ static int SetupBuffers(TIFF *tif, LERCState *sp, const char *module)
}
if ((td->td_planarconfig == PLANARCONFIG_CONTIG &&
td->td_extrasamples > 0 &&
td->td_extrasamples > 0 && td->td_sampleinfo &&
td->td_sampleinfo[td->td_extrasamples - 1] == EXTRASAMPLE_UNASSALPHA &&
GetLercDataType(tif) == 1) ||
(td->td_sampleformat == SAMPLEFORMAT_IEEEFP &&
@@ -343,7 +344,7 @@ static int LERCPreDecode(TIFF *tif, uint16_t s)
if (res != LIBDEFLATE_SUCCESS)
{
TIFFErrorExtR(tif, module, "Decoding error at scanline %lu",
(unsigned long)tif->tif_row);
(unsigned long)tif->tif_dir.td_row);
return 0;
}
assert(lerc_data_sizet == (unsigned int)lerc_data_sizet);
@@ -387,7 +388,7 @@ static int LERCPreDecode(TIFF *tif, uint16_t s)
size_t zstd_ret;
zstd_ret = ZSTD_decompress(sp->compressed_buffer, sp->compressed_size,
tif->tif_rawcp, tif->tif_rawcc);
tif->tif_rawcp, (size_t)tif->tif_rawcc);
if (ZSTD_isError(zstd_ret))
{
TIFFErrorExtR(tif, module, "Error in ZSTD_decompress(): %s",
@@ -420,6 +421,7 @@ static int LERCPreDecode(TIFF *tif, uint16_t s)
/* LERC info has dim == samplesperpixel - 1, then there is a LERC */
/* mask. */
if (td->td_planarconfig == PLANARCONFIG_CONTIG && td->td_extrasamples > 0 &&
td->td_sampleinfo &&
td->td_sampleinfo[td->td_extrasamples - 1] == EXTRASAMPLE_UNASSALPHA &&
GetLercDataType(tif) == 1 &&
infoArray[2] == td->td_samplesperpixel - 1U)
@@ -432,7 +434,8 @@ static int LERCPreDecode(TIFF *tif, uint16_t s)
use_mask = 1;
}
ndims = td->td_planarconfig == PLANARCONFIG_CONTIG ? nomask_bands : 1;
ndims =
(int)(td->td_planarconfig == PLANARCONFIG_CONTIG ? nomask_bands : 1);
/* Info returned in infoArray is { version, dataType, nDim/nDepth, nCols,
nRows, nBands, nValidPixels, blobSize,
@@ -440,12 +443,12 @@ static int LERCPreDecode(TIFF *tif, uint16_t s)
if (infoArray[0] != (unsigned)sp->lerc_version)
{
TIFFWarningExtR(tif, module,
"Unexpected version number: %d. Expected: %d",
"Unexpected version number: %u. Expected: %d",
infoArray[0], sp->lerc_version);
}
if (infoArray[1] != (unsigned)lerc_data_type)
{
TIFFErrorExtR(tif, module, "Unexpected dataType: %d. Expected: %d",
TIFFErrorExtR(tif, module, "Unexpected dataType: %u. Expected: %d",
infoArray[1], lerc_data_type);
return 0;
}
@@ -458,7 +461,7 @@ static int LERCPreDecode(TIFF *tif, uint16_t s)
{
if (nFoundDims != 1 && nFoundDims != (unsigned)ndims)
{
TIFFErrorExtR(tif, module, "Unexpected nDim: %d. Expected: 1 or %d",
TIFFErrorExtR(tif, module, "Unexpected nDim: %u. Expected: 1 or %d",
nFoundDims, ndims);
return 0;
}
@@ -467,20 +470,20 @@ static int LERCPreDecode(TIFF *tif, uint16_t s)
#endif
if (nFoundDims != (unsigned)ndims)
{
TIFFErrorExtR(tif, module, "Unexpected nDim: %d. Expected: %d",
TIFFErrorExtR(tif, module, "Unexpected nDim: %u. Expected: %d",
nFoundDims, ndims);
return 0;
}
if (infoArray[3] != sp->segment_width)
{
TIFFErrorExtR(tif, module, "Unexpected nCols: %d. Expected: %du",
TIFFErrorExtR(tif, module, "Unexpected nCols: %u. Expected: %u",
infoArray[3], sp->segment_width);
return 0;
}
if (infoArray[4] != sp->segment_height)
{
TIFFErrorExtR(tif, module, "Unexpected nRows: %d. Expected: %u",
TIFFErrorExtR(tif, module, "Unexpected nRows: %u. Expected: %u",
infoArray[4], sp->segment_height);
return 0;
}
@@ -504,28 +507,28 @@ static int LERCPreDecode(TIFF *tif, uint16_t s)
#endif
if (nFoundBands != td->td_samplesperpixel)
{
TIFFErrorExtR(tif, module, "Unexpected nBands: %d. Expected: %d",
TIFFErrorExtR(tif, module, "Unexpected nBands: %u. Expected: %d",
nFoundBands, td->td_samplesperpixel);
return 0;
}
}
else if (nFoundBands != 1)
{
TIFFErrorExtR(tif, module, "Unexpected nBands: %d. Expected: %d",
TIFFErrorExtR(tif, module, "Unexpected nBands: %u. Expected: %d",
nFoundBands, 1);
return 0;
}
if (infoArray[7] != lerc_data_size)
{
TIFFErrorExtR(tif, module, "Unexpected blobSize: %d. Expected: %u",
TIFFErrorExtR(tif, module, "Unexpected blobSize: %u. Expected: %u",
infoArray[7], lerc_data_size);
return 0;
}
int nRequestedMasks = use_mask ? 1 : 0;
#if LERC_AT_LEAST_VERSION(3, 0, 0)
const int nFoundMasks = infoArray[8];
const int nFoundMasks = (int)infoArray[8];
if (td->td_sampleformat == SAMPLEFORMAT_IEEEFP &&
td->td_planarconfig == PLANARCONFIG_CONTIG &&
td->td_samplesperpixel > 1 && nFoundDims == 1)
@@ -576,21 +579,22 @@ static int LERCPreDecode(TIFF *tif, uint16_t s)
sp->uncompressed_buffer_multiband_alloc = num_bytes_needed;
}
lerc_ret = lerc_decode(lerc_data, lerc_data_size, nRequestedMasks,
sp->mask_buffer, nFoundDims, sp->segment_width,
sp->segment_height, nFoundBands, lerc_data_type,
sp->mask_buffer, (int)nFoundDims,
(int)sp->segment_width, (int)sp->segment_height,
(int)nFoundBands, (unsigned int)lerc_data_type,
sp->uncompressed_buffer_multiband);
}
else
#endif
{
lerc_ret =
lerc_decode(lerc_data, lerc_data_size,
lerc_ret = lerc_decode(
lerc_data, lerc_data_size,
#if LERC_AT_LEAST_VERSION(3, 0, 0)
nRequestedMasks,
nRequestedMasks,
#endif
use_mask ? sp->mask_buffer : NULL, nFoundDims,
sp->segment_width, sp->segment_height, nFoundBands,
lerc_data_type, sp->uncompressed_buffer);
use_mask ? sp->mask_buffer : NULL, (int)nFoundDims,
(int)sp->segment_width, (int)sp->segment_height, (int)nFoundBands,
(unsigned int)lerc_data_type, sp->uncompressed_buffer);
}
if (lerc_ret != 0)
{
@@ -601,17 +605,17 @@ static int LERCPreDecode(TIFF *tif, uint16_t s)
/* Interleave alpha mask with other samples. */
if (use_mask && GetLercDataType(tif) == 1)
{
unsigned src_stride =
(td->td_samplesperpixel - 1) * (td->td_bitspersample / 8);
unsigned src_stride = (unsigned int)((td->td_samplesperpixel - 1) *
(td->td_bitspersample / 8));
unsigned dst_stride =
td->td_samplesperpixel * (td->td_bitspersample / 8);
(unsigned int)(td->td_samplesperpixel * (td->td_bitspersample / 8));
unsigned i = sp->segment_width * sp->segment_height;
/* Operate from end to begin to be able to move in place */
while (i > 0 && i > nomask_bands)
{
i--;
sp->uncompressed_buffer[i * dst_stride + td->td_samplesperpixel -
1] = 255 * sp->mask_buffer[i];
1] = (uint8_t)(255 * sp->mask_buffer[i]);
memcpy(sp->uncompressed_buffer + i * dst_stride,
sp->uncompressed_buffer + i * src_stride, src_stride);
}
@@ -620,7 +624,7 @@ static int LERCPreDecode(TIFF *tif, uint16_t s)
{
i--;
sp->uncompressed_buffer[i * dst_stride + td->td_samplesperpixel -
1] = 255 * sp->mask_buffer[i];
1] = (uint8_t)(255 * sp->mask_buffer[i]);
memmove(sp->uncompressed_buffer + i * dst_stride,
sp->uncompressed_buffer + i * src_stride, src_stride);
}
@@ -649,7 +653,7 @@ static int LERCPreDecode(TIFF *tif, uint16_t s)
}
else
{
const double nan_float64 = nan_float32;
const double nan_float64 = (double)nan_float32;
for (i = 0; i < nb_pixels; i++)
{
if (sp->mask_buffer[i] == 0)
@@ -677,7 +681,7 @@ static int LERCPreDecode(TIFF *tif, uint16_t s)
}
else
{
const double nan_float64 = nan_float32;
const double nan_float64 = (double)nan_float32;
for (i = 0; i < nb_pixels; i++)
{
for (int j = 0; j < td->td_samplesperpixel; j++)
@@ -704,30 +708,32 @@ static int LERCPreDecode(TIFF *tif, uint16_t s)
{
for (int j = 0; j < td->td_samplesperpixel; j++)
{
if (sp->mask_buffer[i + j * nb_pixels] == 0)
if (sp->mask_buffer[i + (unsigned int)j * nb_pixels] ==
0)
((float *)sp->uncompressed_buffer)[k] = nan_float32;
else
((float *)sp->uncompressed_buffer)[k] =
((float *)sp->uncompressed_buffer_multiband)
[i + j * nb_pixels];
[i + (unsigned int)j * nb_pixels];
++k;
}
}
}
else
{
const double nan_float64 = nan_float32;
const double nan_float64 = (double)nan_float32;
for (i = 0; i < nb_pixels; i++)
{
for (int j = 0; j < td->td_samplesperpixel; j++)
{
if (sp->mask_buffer[i + j * nb_pixels] == 0)
if (sp->mask_buffer[i + (unsigned int)j * nb_pixels] ==
0)
((double *)sp->uncompressed_buffer)[k] =
nan_float64;
else
((double *)sp->uncompressed_buffer)[k] =
((double *)sp->uncompressed_buffer_multiband)
[i + j * nb_pixels];
[i + (unsigned int)j * nb_pixels];
++k;
}
}
@@ -766,8 +772,8 @@ static int LERCDecode(TIFF *tif, uint8_t *op, tmsize_t occ, uint16_t s)
return 0;
}
memcpy(op, sp->uncompressed_buffer + sp->uncompressed_offset, occ);
sp->uncompressed_offset += (unsigned)occ;
memcpy(op, sp->uncompressed_buffer + sp->uncompressed_offset, (size_t)occ);
sp->uncompressed_offset += (unsigned int)occ;
return 1;
}
@@ -832,8 +838,8 @@ static int LERCEncode(TIFF *tif, uint8_t *bp, tmsize_t cc, uint16_t s)
return 0;
}
memcpy(sp->uncompressed_buffer + sp->uncompressed_offset, bp, cc);
sp->uncompressed_offset += (unsigned)cc;
memcpy(sp->uncompressed_buffer + sp->uncompressed_offset, bp, (size_t)cc);
sp->uncompressed_offset += (unsigned int)cc;
return 1;
}
@@ -863,13 +869,15 @@ static int LERCPostEncode(TIFF *tif)
/* Extract alpha mask (if containing only 0 and 255 values, */
/* and compact array of regular bands */
if (td->td_planarconfig == PLANARCONFIG_CONTIG && td->td_extrasamples > 0 &&
td->td_sampleinfo &&
td->td_sampleinfo[td->td_extrasamples - 1] == EXTRASAMPLE_UNASSALPHA &&
GetLercDataType(tif) == 1)
{
const unsigned dst_stride =
(td->td_samplesperpixel - 1) * (td->td_bitspersample / 8);
(unsigned int)((td->td_samplesperpixel - 1) *
(td->td_bitspersample / 8));
const unsigned src_stride =
td->td_samplesperpixel * (td->td_bitspersample / 8);
(unsigned int)(td->td_samplesperpixel * (td->td_bitspersample / 8));
unsigned i = 0;
use_mask = 1;
@@ -923,7 +931,7 @@ static int LERCPostEncode(TIFF *tif)
{
const float val = ((float *)sp->uncompressed_buffer)[k];
++k;
if (val != val)
if (isnan(val))
{
++count_nan;
}
@@ -944,7 +952,7 @@ static int LERCPostEncode(TIFF *tif)
for (i = 0; i < nb_pixels; i++)
{
const float val = ((float *)sp->uncompressed_buffer)[i];
if (val != val)
if (isnan(val))
{
use_mask = 1;
break;
@@ -965,7 +973,7 @@ static int LERCPostEncode(TIFF *tif)
const double val =
((double *)sp->uncompressed_buffer)[k];
++k;
if (val != val)
if (isnan(val))
{
++count_nan;
}
@@ -986,7 +994,7 @@ static int LERCPostEncode(TIFF *tif)
for (i = 0; i < nb_pixels; i++)
{
const double val = ((double *)sp->uncompressed_buffer)[i];
if (val != val)
if (isnan(val))
{
use_mask = 1;
break;
@@ -1025,10 +1033,10 @@ static int LERCPostEncode(TIFF *tif)
const float val =
((float *)sp->uncompressed_buffer)[k];
((float *)sp->uncompressed_buffer_multiband)
[i + j * nb_pixels] = val;
[i + (unsigned int)j * nb_pixels] = val;
++k;
sp->mask_buffer[i + j * nb_pixels] =
(val == val) ? 255 : 0;
sp->mask_buffer[i + (unsigned int)j * nb_pixels] =
!isnan(val) ? 255 : 0;
}
}
}
@@ -1041,10 +1049,10 @@ static int LERCPostEncode(TIFF *tif)
const double val =
((double *)sp->uncompressed_buffer)[k];
((double *)sp->uncompressed_buffer_multiband)
[i + j * nb_pixels] = val;
[i + (unsigned int)j * nb_pixels] = val;
++k;
sp->mask_buffer[i + j * nb_pixels] =
(val == val) ? 255 : 0;
sp->mask_buffer[i + (unsigned int)j * nb_pixels] =
!isnan(val) ? 255 : 0;
}
}
}
@@ -1064,7 +1072,7 @@ static int LERCPostEncode(TIFF *tif)
{
const float val =
((float *)sp->uncompressed_buffer)[i * dst_nbands];
sp->mask_buffer[i] = (val == val) ? 255 : 0;
sp->mask_buffer[i] = !isnan(val) ? 255 : 0;
}
}
else
@@ -1073,7 +1081,7 @@ static int LERCPostEncode(TIFF *tif)
{
const double val =
((double *)sp->uncompressed_buffer)[i * dst_nbands];
sp->mask_buffer[i] = (val == val) ? 255 : 0;
sp->mask_buffer[i] = !isnan(val) ? 255 : 0;
}
}
}
@@ -1084,7 +1092,7 @@ static int LERCPostEncode(TIFF *tif)
for (i = 0; i < nb_pixels; i++)
{
const float val = ((float *)sp->uncompressed_buffer)[i];
sp->mask_buffer[i] = (val == val) ? 255 : 0;
sp->mask_buffer[i] = !isnan(val) ? 255 : 0;
}
}
else
@@ -1093,7 +1101,7 @@ static int LERCPostEncode(TIFF *tif)
{
const double val =
((double *)sp->uncompressed_buffer)[i];
sp->mask_buffer[i] = (val == val) ? 255 : 0;
sp->mask_buffer[i] = !isnan(val) ? 255 : 0;
}
}
}
@@ -1104,7 +1112,8 @@ static int LERCPostEncode(TIFF *tif)
#if LERC_AT_LEAST_VERSION(3, 0, 0)
if (mask_count > 1)
{
estimated_compressed_size += nb_pixels * mask_count / 8;
estimated_compressed_size +=
(unsigned int)(nb_pixels * (unsigned int)mask_count / 8);
}
#endif
@@ -1125,8 +1134,9 @@ static int LERCPostEncode(TIFF *tif)
{
lerc_ret = lerc_encodeForVersion(
sp->uncompressed_buffer_multiband, sp->lerc_version,
GetLercDataType(tif), 1, sp->segment_width, sp->segment_height,
dst_nbands, dst_nbands, sp->mask_buffer, sp->maxzerror,
(unsigned int)GetLercDataType(tif), 1, (int)sp->segment_width,
(int)sp->segment_height, (int)dst_nbands, (int)dst_nbands,
sp->mask_buffer, sp->maxzerror,
(unsigned char *)sp->compressed_buffer, sp->compressed_size,
&numBytesWritten);
}
@@ -1134,9 +1144,10 @@ static int LERCPostEncode(TIFF *tif)
#endif
{
lerc_ret = lerc_encodeForVersion(
sp->uncompressed_buffer, sp->lerc_version, GetLercDataType(tif),
td->td_planarconfig == PLANARCONFIG_CONTIG ? dst_nbands : 1,
sp->segment_width, sp->segment_height, 1,
sp->uncompressed_buffer, sp->lerc_version,
(unsigned int)GetLercDataType(tif),
(int)(td->td_planarconfig == PLANARCONFIG_CONTIG ? dst_nbands : 1),
(int)sp->segment_width, (int)sp->segment_height, 1,
#if LERC_AT_LEAST_VERSION(3, 0, 0)
use_mask ? 1 : 0,
#endif
@@ -1179,14 +1190,14 @@ static int LERCPostEncode(TIFF *tif)
return 0;
}
tif->tif_rawcc = libdeflate_zlib_compress(
tif->tif_rawcc = (tmsize_t)libdeflate_zlib_compress(
sp->libdeflate_enc, sp->compressed_buffer, numBytesWritten,
sp->uncompressed_buffer, sp->uncompressed_alloc);
if (tif->tif_rawcc == 0)
{
TIFFErrorExtR(tif, module, "Encoder error at scanline %lu",
(unsigned long)tif->tif_row);
(unsigned long)tif->tif_dir.td_row);
return 0;
}
#else
@@ -1252,7 +1263,7 @@ static int LERCPostEncode(TIFF *tif)
int ret;
uint8_t *tif_rawdata_backup = tif->tif_rawdata;
tif->tif_rawdata = sp->uncompressed_buffer;
tif->tif_rawcc = zstd_ret;
tif->tif_rawcc = (tmsize_t)zstd_ret;
ret = TIFFFlushData1(tif);
tif->tif_rawdata = tif_rawdata_backup;
if (!ret)
@@ -1350,7 +1361,7 @@ static int LERCVSetField(TIFF *tif, uint32_t tag, va_list ap)
{
case TIFFTAG_LERC_PARAMETERS:
{
uint32_t count = va_arg(ap, int);
uint32_t count = (uint32_t)va_arg(ap, int);
int *params = va_arg(ap, int *);
if (count < 2)
{
@@ -1529,6 +1540,13 @@ int TIFFInitLERC(TIFF *tif, int scheme)
#endif
tif->tif_cleanup = LERCCleanup;
/* LERC compression ratio can grow to several millions */
/* eg. 5703725 for Lerc deflate on 16383x16383 array */
/* or 3829644 for regular Lerc */
/* See README_for_libtiff_developpers.md for raw data used to estimate
* the maximum compression rate. */
/* so we don't define tif->tif_getmaxcompressionratio */
/* Default values for codec-specific fields */
TIFFSetField(tif, TIFFTAG_LERC_VERSION, LERC_VERSION_2_4);
TIFFSetField(tif, TIFFTAG_LERC_ADD_COMPRESSION, LERC_ADD_COMPRESSION_NONE);

View File

@@ -212,7 +212,7 @@ static int LogL16Decode(TIFF *tif, uint8_t *op, tmsize_t occ, uint16_t s)
}
tp = (int16_t *)sp->tbuf;
}
_TIFFmemset((void *)tp, 0, npixels * sizeof(tp[0]));
_TIFFmemset((void *)tp, 0, (tmsize_t)((size_t)npixels * sizeof(tp[0])));
bp = (unsigned char *)tif->tif_rawcp;
cc = tif->tif_rawcc;
@@ -235,7 +235,7 @@ static int LogL16Decode(TIFF *tif, uint8_t *op, tmsize_t occ, uint16_t s)
{ /* non-run */
rc = *bp++; /* nul is noop */
while (--cc && rc-- && i < npixels)
tp[i++] |= (int16_t)*bp++ << shft;
tp[i++] |= (int16_t)(*bp++ << shft);
}
}
if (i != npixels)
@@ -243,7 +243,7 @@ static int LogL16Decode(TIFF *tif, uint8_t *op, tmsize_t occ, uint16_t s)
TIFFErrorExtR(tif, module,
"Not enough data at row %" PRIu32
" (short %" TIFF_SSIZE_FORMAT " pixels)",
tif->tif_row, npixels - i);
tif->tif_dir.td_row, npixels - i);
tif->tif_rawcp = (uint8_t *)bp;
tif->tif_rawcc = cc;
return (0);
@@ -290,7 +290,7 @@ static int LogLuvDecode24(TIFF *tif, uint8_t *op, tmsize_t occ, uint16_t s)
cc = tif->tif_rawcc;
for (i = 0; i < npixels && cc >= 3; i++)
{
tp[i] = bp[0] << 16 | bp[1] << 8 | bp[2];
tp[i] = (uint32_t)bp[0] << 16 | (uint32_t)bp[1] << 8 | bp[2];
bp += 3;
cc -= 3;
}
@@ -301,7 +301,7 @@ static int LogLuvDecode24(TIFF *tif, uint8_t *op, tmsize_t occ, uint16_t s)
TIFFErrorExtR(tif, module,
"Not enough data at row %" PRIu32
" (short %" TIFF_SSIZE_FORMAT " pixels)",
tif->tif_row, npixels - i);
tif->tif_dir.td_row, npixels - i);
return (0);
}
(*sp->tfunc)(sp, op, npixels);
@@ -342,7 +342,7 @@ static int LogLuvDecode32(TIFF *tif, uint8_t *op, tmsize_t occ, uint16_t s)
}
tp = (uint32_t *)sp->tbuf;
}
_TIFFmemset((void *)tp, 0, npixels * sizeof(tp[0]));
_TIFFmemset((void *)tp, 0, (tmsize_t)((size_t)npixels * sizeof(tp[0])));
bp = (unsigned char *)tif->tif_rawcp;
cc = tif->tif_rawcc;
@@ -373,7 +373,7 @@ static int LogLuvDecode32(TIFF *tif, uint8_t *op, tmsize_t occ, uint16_t s)
TIFFErrorExtR(tif, module,
"Not enough data at row %" PRIu32
" (short %" TIFF_SSIZE_FORMAT " pixels)",
tif->tif_row, npixels - i);
tif->tif_dir.td_row, npixels - i);
tif->tif_rawcp = (uint8_t *)bp;
tif->tif_rawcc = cc;
return (0);
@@ -767,25 +767,21 @@ static int LogLuvEncodeTile(TIFF *tif, uint8_t *bp, tmsize_t cc, uint16_t s)
#ifndef M_PI
#define M_PI 3.14159265358979323846
#endif
#undef log2 /* Conflict with C'99 function */
#define log2(x) ((1. / M_LN2) * log(x))
#undef exp2 /* Conflict with C'99 function */
#define exp2(x) exp(M_LN2 *(x))
#define TIFF_RAND_MAX 32767
// From POSIX.1-2001 as an example of an implementation of rand()
static uint32_t _TIFFRand()
static uint32_t _TIFFRand(void)
{
static uint32_t nCounter = 0;
if (!nCounter)
nCounter = (uint32_t)(time(NULL) & UINT32_MAX);
++nCounter;
uint32_t nCounterLocal =
(uint32_t)(((uint64_t)(nCounter)*1103515245U + 12345U) & UINT32_MAX);
(uint32_t)(((uint64_t)(nCounter) * 1103515245U + 12345U) & UINT32_MAX);
nCounter = nCounterLocal;
return (nCounterLocal / 65536U) % (TIFF_RAND_MAX + 1);
};
}
static int tiff_itrunc(double x, int m)
{
@@ -797,8 +793,7 @@ static int tiff_itrunc(double x, int m)
#if !LOGLUV_PUBLIC
static
#endif
double
LogL16toY(int p16) /* compute luminance from 16-bit LogL */
double LogL16toY(int p16) /* compute luminance from 16-bit LogL */
{
int Le = p16 & 0x7fff;
double Y;
@@ -812,8 +807,7 @@ static
#if !LOGLUV_PUBLIC
static
#endif
int
LogL16fromY(double Y, int em) /* get 16-bit LogL from Y */
int LogL16fromY(double Y, int em) /* get 16-bit LogL from Y */
{
if (Y >= 1.8371976e19)
return (0x7fff);
@@ -855,20 +849,22 @@ static void L16fromY(LogLuvState *sp, uint8_t *op, tmsize_t n)
float *yp = (float *)op;
while (n-- > 0)
*l16++ = (int16_t)(LogL16fromY(*yp++, sp->encode_meth));
*l16++ = (int16_t)(LogL16fromY((double)*yp++, sp->encode_meth));
}
#if !LOGLUV_PUBLIC
static
#endif
void
XYZtoRGB24(float *xyz, uint8_t *rgb)
void XYZtoRGB24(float *xyz, uint8_t *rgb)
{
double r, g, b;
/* assume CCIR-709 primaries */
r = 2.690 * xyz[0] + -1.276 * xyz[1] + -0.414 * xyz[2];
g = -1.022 * xyz[0] + 1.978 * xyz[1] + 0.044 * xyz[2];
b = 0.061 * xyz[0] + -0.224 * xyz[1] + 1.163 * xyz[2];
r = 2.690 * (double)xyz[0] + -1.276 * (double)xyz[1] +
-0.414 * (double)xyz[2];
g = -1.022 * (double)xyz[0] + 1.978 * (double)xyz[1] +
0.044 * (double)xyz[2];
b = 0.061 * (double)xyz[0] + -0.224 * (double)xyz[1] +
1.163 * (double)xyz[2];
/* assume 2.0 gamma for speed */
/* could use integer sqrt approx., but this is probably faster */
rgb[0] = (uint8_t)((r <= 0.) ? 0 : (r >= 1.) ? 255 : (int)(256. * sqrt(r)));
@@ -879,8 +875,7 @@ static
#if !LOGLUV_PUBLIC
static
#endif
double
LogL10toY(int p10) /* compute luminance from 10-bit LogL */
double LogL10toY(int p10) /* compute luminance from 10-bit LogL */
{
if (p10 == 0)
return (0.);
@@ -890,8 +885,7 @@ static
#if !LOGLUV_PUBLIC
static
#endif
int
LogL10fromY(double Y, int em) /* get 10-bit LogL from Y */
int LogL10fromY(double Y, int em) /* get 10-bit LogL from Y */
{
if (Y >= 15.742)
return (0x3ff);
@@ -903,13 +897,14 @@ static
#define NANGLES 100
#define uv2ang(u, v) \
((NANGLES * .499999999 / M_PI) * atan2((v)-V_NEU, (u)-U_NEU) + .5 * NANGLES)
((NANGLES * .499999999 / M_PI) * atan2((v) - V_NEU, (u) - U_NEU) + \
.5 * NANGLES)
static int oog_encode(double u, double v) /* encode out-of-gamut chroma */
{
static int oog_table[NANGLES];
static int initialized = 0;
register int i;
int i;
if (!initialized)
{ /* set up perimeter table */
@@ -919,13 +914,14 @@ static int oog_encode(double u, double v) /* encode out-of-gamut chroma */
eps[i] = 2.;
for (vi = UV_NVS; vi--;)
{
va = UV_VSTART + (vi + .5) * UV_SQSIZ;
va = (double)UV_VSTART + ((double)vi + .5) * (double)UV_SQSIZ;
ustep = uv_row[vi].nus - 1;
if (vi == UV_NVS - 1 || vi == 0 || ustep <= 0)
ustep = 1;
for (ui = uv_row[vi].nus - 1; ui >= 0; ui -= ustep)
{
ua = uv_row[vi].ustart + (ui + .5) * UV_SQSIZ;
ua = (double)uv_row[vi].ustart +
((double)ui + .5) * (double)UV_SQSIZ;
ang = uv2ang(ua, va);
i = (int)ang;
epsa = fabs(ang - (i + .5));
@@ -963,27 +959,28 @@ static int oog_encode(double u, double v) /* encode out-of-gamut chroma */
#if !LOGLUV_PUBLIC
static
#endif
int
uv_encode(double u, double v, int em) /* encode (u',v') coordinates */
int uv_encode(double u, double v, int em) /* encode (u',v') coordinates */
{
unsigned int vi;
int ui;
/* check for NaN */
if (u != u || v != v)
if (isnan(u) || isnan(v))
{
u = U_NEU;
v = V_NEU;
}
if (v < UV_VSTART)
if ((double)v < (double)UV_VSTART)
return oog_encode(u, v);
vi = tiff_itrunc((v - UV_VSTART) * (1. / UV_SQSIZ), em);
vi = (unsigned int)tiff_itrunc(
((double)v - (double)UV_VSTART) * (1. / (double)UV_SQSIZ), em);
if (vi >= UV_NVS)
return oog_encode(u, v);
if (u < uv_row[vi].ustart)
if ((double)u < (double)uv_row[vi].ustart)
return oog_encode(u, v);
ui = tiff_itrunc((u - uv_row[vi].ustart) * (1. / UV_SQSIZ), em);
ui = tiff_itrunc(
((double)u - (double)uv_row[vi].ustart) * (1. / (double)UV_SQSIZ), em);
if (ui >= uv_row[vi].nus)
return oog_encode(u, v);
@@ -993,8 +990,7 @@ static
#if !LOGLUV_PUBLIC
static
#endif
int
uv_decode(double *up, double *vp, int c) /* decode (u',v') index */
int uv_decode(double *up, double *vp, int c) /* decode (u',v') index */
{
unsigned int upper, lower;
int ui;
@@ -1020,16 +1016,15 @@ static
}
vi = lower;
ui = c - uv_row[vi].ncum;
*up = uv_row[vi].ustart + (ui + .5) * UV_SQSIZ;
*vp = UV_VSTART + (vi + .5) * UV_SQSIZ;
*up = (double)uv_row[vi].ustart + ((double)ui + .5) * (double)UV_SQSIZ;
*vp = (double)UV_VSTART + ((double)vi + .5) * (double)UV_SQSIZ;
return (0);
}
#if !LOGLUV_PUBLIC
static
#endif
void
LogLuv24toXYZ(uint32_t p, float *XYZ)
void LogLuv24toXYZ(uint32_t p, float *XYZ)
{
int Ce;
double L, u, v, s, x, y;
@@ -1059,15 +1054,14 @@ static
#if !LOGLUV_PUBLIC
static
#endif
uint32_t
LogLuv24fromXYZ(float *XYZ, int em)
uint32_t LogLuv24fromXYZ(float *XYZ, int em)
{
int Le, Ce;
double u, v, s;
/* encode luminance */
Le = LogL10fromY(XYZ[1], em);
Le = LogL10fromY((double)XYZ[1], em);
/* encode color */
s = XYZ[0] + 15. * XYZ[1] + 3. * XYZ[2];
s = (double)XYZ[0] + 15. * (double)XYZ[1] + 3. * (double)XYZ[2];
if (!Le || s <= 0.)
{
u = U_NEU;
@@ -1075,14 +1069,14 @@ static
}
else
{
u = 4. * XYZ[0] / s;
v = 9. * XYZ[1] / s;
u = 4. * (double)XYZ[0] / s;
v = 9. * (double)XYZ[1] / s;
}
Ce = uv_encode(u, v, em);
if (Ce < 0) /* never happens */
Ce = uv_encode(U_NEU, V_NEU, SGILOGENCODE_NODITHER);
/* combine encodings */
return (Le << 14 | Ce);
return (uint32_t)Le << 14 | (uint32_t)Ce;
}
static void Luv24toXYZ(LogLuvState *sp, uint8_t *op, tmsize_t n)
@@ -1113,8 +1107,8 @@ static void Luv24toLuv48(LogLuvState *sp, uint8_t *op, tmsize_t n)
u = U_NEU;
v = V_NEU;
}
*luv3++ = (int16_t)(u * (1L << 15));
*luv3++ = (int16_t)(v * (1L << 15));
*luv3++ = (int16_t)(u * (1 << 15));
*luv3++ = (int16_t)(v * (1 << 15));
luv++;
}
}
@@ -1168,7 +1162,7 @@ static void Luv24fromLuv48(LogLuvState *sp, uint8_t *op, tmsize_t n)
sp->encode_meth);
if (Ce < 0) /* never happens */
Ce = uv_encode(U_NEU, V_NEU, SGILOGENCODE_NODITHER);
*luv++ = (uint32_t)Le << 14 | Ce;
*luv++ = (uint32_t)Le << 14 | (uint32_t)Ce;
luv3 += 3;
}
}
@@ -1176,8 +1170,7 @@ static void Luv24fromLuv48(LogLuvState *sp, uint8_t *op, tmsize_t n)
#if !LOGLUV_PUBLIC
static
#endif
void
LogLuv32toXYZ(uint32_t p, float *XYZ)
void LogLuv32toXYZ(uint32_t p, float *XYZ)
{
double L, u, v, s, x, y;
/* decode luminance */
@@ -1202,15 +1195,14 @@ static
#if !LOGLUV_PUBLIC
static
#endif
uint32_t
LogLuv32fromXYZ(float *XYZ, int em)
uint32_t LogLuv32fromXYZ(float *XYZ, int em)
{
unsigned int Le, ue, ve;
double u, v, s;
/* encode luminance */
Le = (unsigned int)LogL16fromY(XYZ[1], em);
Le = (unsigned int)LogL16fromY((double)XYZ[1], em);
/* encode color */
s = XYZ[0] + 15. * XYZ[1] + 3. * XYZ[2];
s = (double)XYZ[0] + 15. * (double)XYZ[1] + 3. * (double)XYZ[2];
if (!Le || s <= 0.)
{
u = U_NEU;
@@ -1218,19 +1210,19 @@ static
}
else
{
u = 4. * XYZ[0] / s;
v = 9. * XYZ[1] / s;
u = 4. * (double)XYZ[0] / s;
v = 9. * (double)XYZ[1] / s;
}
if (u <= 0.)
ue = 0;
else
ue = tiff_itrunc(UVSCALE * u, em);
ue = (unsigned int)tiff_itrunc(UVSCALE * u, em);
if (ue > 255)
ue = 255;
if (v <= 0.)
ve = 0;
else
ve = tiff_itrunc(UVSCALE * v, em);
ve = (unsigned int)tiff_itrunc(UVSCALE * v, em);
if (ve > 255)
ve = 255;
/* combine encodings */
@@ -1261,8 +1253,8 @@ static void Luv32toLuv48(LogLuvState *sp, uint8_t *op, tmsize_t n)
*luv3++ = (int16_t)(*luv >> 16);
u = 1. / UVSCALE * ((*luv >> 8 & 0xff) + .5);
v = 1. / UVSCALE * ((*luv & 0xff) + .5);
*luv3++ = (int16_t)(u * (1L << 15));
*luv3++ = (int16_t)(v * (1L << 15));
*luv3++ = (int16_t)(u * (1 << 15));
*luv3++ = (int16_t)(v * (1 << 15));
luv++;
}
}
@@ -1303,22 +1295,24 @@ static void Luv32fromLuv48(LogLuvState *sp, uint8_t *op, tmsize_t n)
{
while (n-- > 0)
{
*luv++ = (uint32_t)luv3[0] << 16 |
(luv3[1] * (uint32_t)(UVSCALE + .5) >> 7 & 0xff00) |
(luv3[2] * (uint32_t)(UVSCALE + .5) >> 15 & 0xff);
*luv++ =
(uint32_t)luv3[0] << 16 |
((uint32_t)luv3[1] * (uint32_t)(UVSCALE + .5) >> 7 & 0xff00) |
((uint32_t)luv3[2] * (uint32_t)(UVSCALE + .5) >> 15 & 0xff);
luv3 += 3;
}
return;
}
while (n-- > 0)
{
*luv++ =
(uint32_t)luv3[0] << 16 |
(tiff_itrunc(luv3[1] * (UVSCALE / (1 << 15)), sp->encode_meth)
<< 8 &
0xff00) |
(tiff_itrunc(luv3[2] * (UVSCALE / (1 << 15)), sp->encode_meth) &
0xff);
*luv++ = (uint32_t)luv3[0] << 16 |
((uint32_t)tiff_itrunc(luv3[1] * (UVSCALE / (1 << 15)),
sp->encode_meth)
<< 8 &
0xff00) |
((uint32_t)tiff_itrunc(luv3[2] * (UVSCALE / (1 << 15)),
sp->encode_meth) &
0xff);
luv3 += 3;
}
}
@@ -1345,6 +1339,8 @@ static int LogL16GuessDataFmt(TIFFDirectory *td)
case PACK(1, 8, SAMPLEFORMAT_VOID):
case PACK(1, 8, SAMPLEFORMAT_UINT):
return (SGILOGDATAFMT_8BIT);
default:
break;
}
#undef PACK
return (SGILOGDATAFMT_UNKNOWN);
@@ -1399,7 +1395,7 @@ static int LogL16InitState(TIFF *tif)
sp->tbuflen = multiply_ms(td->td_imagewidth, td->td_imagelength);
if (multiply_ms(sp->tbuflen, sizeof(int16_t)) == 0 ||
(sp->tbuf = (uint8_t *)_TIFFmallocExt(
tif, sp->tbuflen * sizeof(int16_t))) == NULL)
tif, (tmsize_t)((size_t)sp->tbuflen * sizeof(int16_t)))) == NULL)
{
TIFFErrorExtR(tif, module, "No space for SGILog translation buffer");
return (0);
@@ -1506,7 +1502,7 @@ static int LogLuvInitState(TIFF *tif)
sp->tbuflen = multiply_ms(td->td_imagewidth, td->td_imagelength);
if (multiply_ms(sp->tbuflen, sizeof(uint32_t)) == 0 ||
(sp->tbuf = (uint8_t *)_TIFFmallocExt(
tif, sp->tbuflen * sizeof(uint32_t))) == NULL)
tif, (tmsize_t)((size_t)sp->tbuflen * sizeof(uint32_t)))) == NULL)
{
TIFFErrorExtR(tif, module, "No space for SGILog translation buffer");
return (0);
@@ -1546,6 +1542,8 @@ static int LogLuvSetupDecode(TIFF *tif)
case SGILOGDATAFMT_8BIT:
sp->tfunc = Luv24toRGB;
break;
default:
break;
}
}
else
@@ -1562,6 +1560,8 @@ static int LogLuvSetupDecode(TIFF *tif)
case SGILOGDATAFMT_8BIT:
sp->tfunc = Luv32toRGB;
break;
default:
break;
}
}
return (1);
@@ -1577,6 +1577,8 @@ static int LogLuvSetupDecode(TIFF *tif)
case SGILOGDATAFMT_8BIT:
sp->tfunc = L16toGry;
break;
default:
break;
}
return (1);
default:
@@ -1755,8 +1757,9 @@ static int LogLuvVSetField(TIFF *tif, uint32_t tag, va_list ap)
/*
* Must recalculate sizes should bits/sample change.
*/
tif->tif_tilesize = isTiled(tif) ? TIFFTileSize(tif) : (tmsize_t)-1;
tif->tif_scanlinesize = TIFFScanlineSize(tif);
tif->tif_dir.td_tilesize =
isTiled(tif) ? TIFFTileSize(tif) : (tmsize_t)-1;
tif->tif_dir.td_scanlinesize = TIFFScanlineSize(tif);
return (1);
case TIFFTAG_SGILOGENCODE:
sp->encode_meth = (int)va_arg(ap, int);

View File

@@ -95,6 +95,17 @@ static const char *LZMAStrerror(lzma_ret ret)
return "no progress is possible (stream is truncated or corrupt)";
case LZMA_PROG_ERROR:
return "programming error";
#if LZMA_VERSION >= 50040000 /* 5.4.0 */
case LZMA_SEEK_NEEDED:
case LZMA_RET_INTERNAL1:
case LZMA_RET_INTERNAL2:
case LZMA_RET_INTERNAL3:
case LZMA_RET_INTERNAL4:
case LZMA_RET_INTERNAL5:
case LZMA_RET_INTERNAL6:
case LZMA_RET_INTERNAL7:
case LZMA_RET_INTERNAL8:
#endif
default:
return "unidentified liblzma error";
}
@@ -179,7 +190,7 @@ static int LZMADecode(TIFF *tif, uint8_t *op, tmsize_t occ, uint16_t s)
TIFFErrorExtR(tif, module,
"LZMADecode: Scanline %" PRIu32 " cannot be read due to "
"previous error",
tif->tif_row);
tif->tif_dir.td_row);
return 0;
}
@@ -231,7 +242,7 @@ static int LZMADecode(TIFF *tif, uint8_t *op, tmsize_t occ, uint16_t s)
{
TIFFErrorExtR(tif, module,
"Decoding error at scanline %" PRIu32 ", %s",
tif->tif_row, LZMAStrerror(ret));
tif->tif_dir.td_row, LZMAStrerror(ret));
break;
}
} while (sp->stream.avail_out > 0);
@@ -242,12 +253,12 @@ static int LZMADecode(TIFF *tif, uint8_t *op, tmsize_t occ, uint16_t s)
TIFFErrorExtR(tif, module,
"Not enough data at scanline %" PRIu32
" (short %" TIFF_SIZE_FORMAT " bytes)",
tif->tif_row, sp->stream.avail_out);
tif->tif_dir.td_row, sp->stream.avail_out);
return 0;
}
tif->tif_rawcp = (uint8_t *)sp->stream.next_in; /* cast away const */
tif->tif_rawcc = sp->stream.avail_in;
tif->tif_rawcc = (tmsize_t)sp->stream.avail_in;
return 1;
}
@@ -326,7 +337,7 @@ static int LZMAEncode(TIFF *tif, uint8_t *bp, tmsize_t cc, uint16_t s)
{
TIFFErrorExtR(tif, module,
"Encoding error at scanline %" PRIu32 ", %s",
tif->tif_row, LZMAStrerror(ret));
tif->tif_dir.td_row, LZMAStrerror(ret));
return 0;
}
if (sp->stream.avail_out == 0)
@@ -365,7 +376,7 @@ static int LZMAPostEncode(TIFF *tif)
if ((tmsize_t)sp->stream.avail_out != tif->tif_rawdatasize)
{
tif->tif_rawcc =
tif->tif_rawdatasize - sp->stream.avail_out;
tif->tif_rawdatasize - (tmsize_t)sp->stream.avail_out;
if (!TIFFFlushData1(tif))
return 0;
sp->stream.next_out = tif->tif_rawdata;
@@ -376,6 +387,27 @@ static int LZMAPostEncode(TIFF *tif)
ZIPPreEncode */
}
break;
case LZMA_NO_CHECK:
case LZMA_UNSUPPORTED_CHECK:
case LZMA_GET_CHECK:
case LZMA_MEM_ERROR:
case LZMA_MEMLIMIT_ERROR:
case LZMA_FORMAT_ERROR:
case LZMA_OPTIONS_ERROR:
case LZMA_DATA_ERROR:
case LZMA_BUF_ERROR:
case LZMA_PROG_ERROR:
#if LZMA_VERSION >= 50040000 /* 5.4.0 */
case LZMA_SEEK_NEEDED:
case LZMA_RET_INTERNAL1:
case LZMA_RET_INTERNAL2:
case LZMA_RET_INTERNAL3:
case LZMA_RET_INTERNAL4:
case LZMA_RET_INTERNAL5:
case LZMA_RET_INTERNAL6:
case LZMA_RET_INTERNAL7:
case LZMA_RET_INTERNAL8:
#endif
default:
TIFFErrorExtR(tif, module, "Liblzma error: %s",
LZMAStrerror(ret));
@@ -416,7 +448,7 @@ static int LZMAVSetField(TIFF *tif, uint32_t tag, va_list ap)
{
case TIFFTAG_LZMAPRESET:
sp->preset = (int)va_arg(ap, int);
lzma_lzma_preset(&sp->opt_lzma, sp->preset);
lzma_lzma_preset(&sp->opt_lzma, (uint32_t)sp->preset);
if (sp->state & LSTATE_INIT_ENCODE)
{
lzma_ret ret =
@@ -454,6 +486,21 @@ static const TIFFField lzmaFields[] = {
FALSE, "LZMA2 Compression Preset", NULL},
};
static uint64_t LZMAGetMaxCompressionRatio(TIFF *tif)
{
(void)tif;
/* See README_for_libtiff_developpers.md for raw data used to estimate
* the maximum compression rate. */
/* 1024x1024: 3800 */
/* 4096x4096: 6534 */
/* 16383x16383: 6846 */
/* 65536x65536: 6874 */
return 7000;
}
int TIFFInitLZMA(TIFF *tif, int scheme)
{
static const char module[] = "TIFFInitLZMA";
@@ -506,7 +553,7 @@ int TIFFInitLZMA(TIFF *tif, int scheme)
sp->filters[0].id = LZMA_FILTER_DELTA;
sp->filters[0].options = &sp->opt_delta;
lzma_lzma_preset(&sp->opt_lzma, sp->preset);
lzma_lzma_preset(&sp->opt_lzma, (uint32_t)sp->preset);
sp->filters[1].id = LZMA_FILTER_LZMA2;
sp->filters[1].options = &sp->opt_lzma;
@@ -529,6 +576,8 @@ int TIFFInitLZMA(TIFF *tif, int scheme)
tif->tif_encodestrip = LZMAEncode;
tif->tif_encodetile = LZMAEncode;
tif->tif_cleanup = LZMACleanup;
tif->tif_getmaxcompressionratio = LZMAGetMaxCompressionRatio;
/*
* Setup predictor setup.
*/

View File

@@ -60,7 +60,7 @@ typedef size_t WordType;
*/
#define LZW_COMPAT /* include backwards compatibility code */
#define MAXCODE(n) ((1L << (n)) - 1)
#define MAXCODE(n) ((1 << (n)) - 1)
/*
* The TIFF spec specifies that encoded bit
* strings range from 9 to 12 bits.
@@ -72,7 +72,7 @@ typedef size_t WordType;
#define CODE_EOI 257 /* end-of-information code */
#define CODE_FIRST 258 /* first free code entry */
#define CODE_MAX MAXCODE(BITS_MAX)
#define HSIZE 9001L /* 91% occupancy */
#define HSIZE 9001 /* 91% occupancy */
#define HSHIFT (13 - 8)
#ifdef LZW_COMPAT
/* NB: +1024 is for compatibility with old files */
@@ -325,7 +325,7 @@ static int LZWPreDecode(TIFF *tif, uint16_t s)
*/
/* Get the next 32 or 64-bit from the input data */
#ifdef WORDS_BIGENDIAN
#if WORDS_BIGENDIAN
#define GetNextData(nextdata, bp) memcpy(&nextdata, bp, sizeof(nextdata))
#elif SIZEOF_WORDTYPE == 8
#if defined(_M_X64)
@@ -372,7 +372,7 @@ static int LZWPreDecode(TIFF *tif, uint16_t s)
nextbits += 8 * SIZEOF_WORDTYPE; \
dec_bitsleft -= 8 * SIZEOF_WORDTYPE; \
code = (WordType)((codetmp | (nextdata >> nextbits)) & \
nbitsmask); \
(WordType)nbitsmask); \
break; \
} \
else \
@@ -396,7 +396,7 @@ static int LZWPreDecode(TIFF *tif, uint16_t s)
} \
} \
} \
code = (WordType)((nextdata >> nextbits) & nbitsmask); \
code = (WordType)((nextdata >> nextbits) & (WordType)nbitsmask); \
} while (0)
static int LZWDecode(TIFF *tif, uint8_t *op0, tmsize_t occ0, uint16_t s)
@@ -420,7 +420,7 @@ static int LZWDecode(TIFF *tif, uint8_t *op0, tmsize_t occ0, uint16_t s)
TIFFErrorExtR(tif, module,
"LZWDecode: Scanline %" PRIu32 " cannot be read due to "
"previous error",
tif->tif_row);
tif->tif_dir.td_row);
return 0;
}
@@ -472,7 +472,8 @@ static int LZWDecode(TIFF *tif, uint8_t *op0, tmsize_t occ0, uint16_t s)
}
bp = (uint8_t *)tif->tif_rawcp;
sp->dec_bitsleft += (((uint64_t)tif->tif_rawcc - sp->old_tif_rawcc) << 3);
sp->dec_bitsleft +=
(((uint64_t)tif->tif_rawcc - (uint64_t)sp->old_tif_rawcc) << 3);
uint64_t dec_bitsleft = sp->dec_bitsleft;
nbits = sp->lzw_nbits;
nextdata = sp->lzw_nextdata;
@@ -493,7 +494,7 @@ begin:
{
WordType code;
GetNextCodeLZW();
codep = dec_codetab + code;
codep = dec_codetab + (unsigned long)code;
if (code >= CODE_FIRST)
goto code_above_or_equal_to_258;
if (code < 256)
@@ -508,7 +509,7 @@ code_below_256:
goto error_code;
free_entp->next = oldcodep;
free_entp->firstchar = oldcodep->firstchar;
free_entp->length = oldcodep->length + 1;
free_entp->length = (uint16_t)(oldcodep->length + 1);
free_entp->value = (uint8_t)code;
free_entp->repeated =
(bool)(oldcodep->repeated & (oldcodep->value == code));
@@ -556,7 +557,7 @@ code_above_or_equal_to_258:
free_entp->next = oldcodep;
free_entp->firstchar = oldcodep->firstchar;
free_entp->length = oldcodep->length + 1;
free_entp->length = (uint16_t)(oldcodep->length + 1);
if (++free_entp > maxcodep)
{
if (++nbits > BITS_MAX) /* should not happen for a conformant encoder */
@@ -673,7 +674,7 @@ code_clear:
free_entp = dec_codetab + CODE_FIRST;
nbits = BITS_MIN;
nbitsmask = MAXCODE(BITS_MIN);
maxcodep = dec_codetab + nbitsmask - 1;
maxcodep = dec_codetab + (unsigned long)nbitsmask - 1;
do
{
GetNextCodeLZW();
@@ -736,7 +737,7 @@ after_loop:
TIFFErrorExtR(tif, module,
"Not enough data at scanline %" PRIu32 " (short %" PRIu64
" bytes)",
tif->tif_row, (uint64_t)occ);
tif->tif_dir.td_row, (uint64_t)occ);
return (0);
}
return (1);
@@ -746,7 +747,7 @@ no_eoi:
sp->read_error = 1;
TIFFErrorExtR(tif, module,
"LZWDecode: Strip %" PRIu32 " not terminated with EOI code",
tif->tif_curstrip);
tif->tif_dir.td_curstrip);
return 0;
error_code:
memset(op, 0, (size_t)occ);
@@ -768,13 +769,13 @@ error_code:
TIFFWarningExtR(_tif, module, \
"LZWDecode: Strip %" PRIu32 \
" not terminated with EOI code", \
_tif->tif_curstrip); \
_tif->tif_dir.td_curstrip); \
_code = CODE_EOI; \
} \
else \
{ \
_get(_sp, _bp, _code); \
dec_bitsleft -= nbits; \
dec_bitsleft -= (uint64_t)nbits; \
} \
}
@@ -790,7 +791,7 @@ error_code:
nextdata |= (unsigned long)*(bp)++ << nextbits; \
nextbits += 8; \
} \
code = (hcode_t)(nextdata & nbitsmask); \
code = (hcode_t)(nextdata & (unsigned long)nbitsmask); \
nextdata >>= nbits; \
nextbits -= nbits; \
}
@@ -858,7 +859,8 @@ static int LZWDecodeCompat(TIFF *tif, uint8_t *op0, tmsize_t occ0, uint16_t s)
bp = (uint8_t *)tif->tif_rawcp;
sp->dec_bitsleft += (((uint64_t)tif->tif_rawcc - sp->old_tif_rawcc) << 3);
sp->dec_bitsleft +=
(((uint64_t)tif->tif_rawcc - (uint64_t)sp->old_tif_rawcc) << 3);
uint64_t dec_bitsleft = sp->dec_bitsleft;
nbits = sp->lzw_nbits;
@@ -893,7 +895,7 @@ static int LZWDecodeCompat(TIFF *tif, uint8_t *op0, tmsize_t occ0, uint16_t s)
TIFFErrorExtR(
tif, tif->tif_name,
"LZWDecode: Corrupted LZW table at scanline %" PRIu32,
tif->tif_row);
tif->tif_dir.td_row);
return (0);
}
*op++ = (uint8_t)code;
@@ -911,7 +913,7 @@ static int LZWDecodeCompat(TIFF *tif, uint8_t *op0, tmsize_t occ0, uint16_t s)
{
TIFFErrorExtR(tif, module,
"Corrupted LZW table at scanline %" PRIu32,
tif->tif_row);
tif->tif_dir.td_row);
return (0);
}
@@ -921,11 +923,11 @@ static int LZWDecodeCompat(TIFF *tif, uint8_t *op0, tmsize_t occ0, uint16_t s)
{
TIFFErrorExtR(tif, module,
"Corrupted LZW table at scanline %" PRIu32,
tif->tif_row);
tif->tif_dir.td_row);
return (0);
}
free_entp->firstchar = free_entp->next->firstchar;
free_entp->length = free_entp->next->length + 1;
free_entp->length = (uint16_t)(free_entp->next->length + 1);
free_entp->value =
(codep < free_entp) ? codep->firstchar : free_entp->firstchar;
if (++free_entp > maxcodep)
@@ -948,7 +950,7 @@ static int LZWDecodeCompat(TIFF *tif, uint8_t *op0, tmsize_t occ0, uint16_t s)
tif, module,
"Wrong length of decoded "
"string: data probably corrupted at scanline %" PRIu32,
tif->tif_row);
tif->tif_dir.td_row);
return (0);
}
if (codep->length > occ)
@@ -1010,7 +1012,7 @@ static int LZWDecodeCompat(TIFF *tif, uint8_t *op0, tmsize_t occ0, uint16_t s)
TIFFErrorExtR(tif, module,
"Not enough data at scanline %" PRIu32 " (short %" PRIu64
" bytes)",
tif->tif_row, (uint64_t)occ);
tif->tif_dir.td_row, (uint64_t)occ);
return (0);
}
return (1);
@@ -1116,10 +1118,10 @@ 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 = LZWEncoderState(tif);
register long fcode;
register hash_t *hp;
register int h, c;
LZWCodecState *sp = LZWEncoderState(tif);
long fcode;
hash_t *hp;
int h, c;
hcode_t ent;
long disp;
tmsize_t incount, outcount, checkpoint;
@@ -1196,7 +1198,7 @@ static int LZWEncode(TIFF *tif, uint8_t *bp, tmsize_t cc, uint16_t s)
* Avoid pointer arithmetic because of
* wraparound problems with segments.
*/
if ((h -= disp) < 0)
if ((h -= (int)disp) < 0)
h += HSIZE;
hp = &sp->enc_hashtab[h];
if (hp->hash == fcode)
@@ -1301,7 +1303,7 @@ static int LZWEncode(TIFF *tif, uint8_t *bp, tmsize_t cc, uint16_t s)
*/
static int LZWPostEncode(TIFF *tif)
{
register LZWCodecState *sp = LZWEncoderState(tif);
LZWCodecState *sp = LZWEncoderState(tif);
uint8_t *op = tif->tif_rawcp;
long nextbits = sp->lzw_nextbits;
WordType nextdata = sp->lzw_nextdata;
@@ -1319,7 +1321,7 @@ static int LZWPostEncode(TIFF *tif)
{
int free_ent = sp->lzw_free_ent;
PutNextCode(op, sp->enc_oldcode);
PutNextCode(op, (WordType)sp->enc_oldcode);
sp->enc_oldcode = (hcode_t)-1;
free_ent++;
@@ -1357,8 +1359,8 @@ static int LZWPostEncode(TIFF *tif)
*/
static void cl_hash(LZWCodecState *sp)
{
register hash_t *hp = &sp->enc_hashtab[HSIZE - 1];
register long i = HSIZE - 8;
hash_t *hp = &sp->enc_hashtab[HSIZE - 1];
long i = HSIZE - 8;
do
{
@@ -1397,6 +1399,21 @@ static void LZWCleanup(TIFF *tif)
_TIFFSetDefaultCompressionState(tif);
}
static uint64_t LZWGetMaxCompressionRatio(TIFF *tif)
{
(void)tif;
/* See README_for_libtiff_developpers.md for raw data used to estimate
* the maximum compression rate. */
/* 1024x1024: 562 */
/* 4096x4096: 1243 */
/* 16383x16383: 1353 */
/* 65536x65536: 1362 */
return 1400;
}
int TIFFInitLZW(TIFF *tif, int scheme)
{
static const char module[] = "TIFFInitLZW";
@@ -1430,6 +1447,7 @@ int TIFFInitLZW(TIFF *tif, int scheme)
tif->tif_encodestrip = LZWEncode;
tif->tif_encodetile = LZWEncode;
#endif
tif->tif_getmaxcompressionratio = LZWGetMaxCompressionRatio;
tif->tif_cleanup = LZWCleanup;
/*
* Setup predictor setup.

View File

@@ -38,21 +38,22 @@
op[0] = (unsigned char)((v) << 6); \
break; \
case 1: \
op[0] |= (v) << 4; \
op[0] |= (unsigned char)((v) << 4); \
break; \
case 2: \
op[0] |= (v) << 2; \
op[0] |= (unsigned char)((v) << 2); \
break; \
case 3: \
*op++ |= (v); \
*op++ |= (unsigned char)(v); \
op_offset++; \
break; \
default: \
break; \
} \
}
#define LITERALROW 0x00
#define LITERALSPAN 0x40
#define WHITE ((1 << 2) - 1)
static int NeXTDecode(TIFF *tif, uint8_t *buf, tmsize_t occ, uint16_t s)
{
@@ -73,7 +74,7 @@ static int NeXTDecode(TIFF *tif, uint8_t *buf, tmsize_t occ, uint16_t s)
bp = (unsigned char *)tif->tif_rawcp;
cc = tif->tif_rawcc;
scanline = tif->tif_scanlinesize;
scanline = tif->tif_dir.td_scanlinesize;
if (occ % scanline)
{
TIFFErrorExtR(tif, module, "Fractional scanlines cannot be read");
@@ -146,7 +147,7 @@ static int NeXTDecode(TIFF *tif, uint8_t *buf, tmsize_t occ, uint16_t s)
{
TIFFErrorExtR(tif, module,
"Invalid data for scanline %" PRIu32,
tif->tif_row);
tif->tif_dir.td_row);
return (0);
}
if (cc == 0)
@@ -163,7 +164,7 @@ static int NeXTDecode(TIFF *tif, uint8_t *buf, tmsize_t occ, uint16_t s)
return (1);
bad:
TIFFErrorExtR(tif, module, "Not enough data for scanline %" PRIu32,
tif->tif_row);
tif->tif_dir.td_row);
return (0);
}

View File

@@ -122,9 +122,6 @@
restarting of LibJpeg decoding session.
*/
#define WIN32_LEAN_AND_MEAN
#define VC_EXTRALEAN
#include "tiffiop.h"
#ifdef OJPEG_SUPPORT
@@ -209,18 +206,12 @@ static const TIFFField ojpegFields[] = {
#include "jerror.h"
#include "jpeglib.h"
#ifndef TIFF_jpeg_source_mgr_defined
#define TIFF_jpeg_source_mgr_defined
typedef struct jpeg_source_mgr jpeg_source_mgr;
#endif
typedef struct jpeg_source_mgr tiff_ojpeg_source_mgr;
#ifndef TIFF_jpeg_error_mgr_defined
#define TIFF_jpeg_error_mgr_defined
typedef struct jpeg_error_mgr jpeg_error_mgr;
#endif
typedef struct jpeg_error_mgr tiff_ojpeg_error_mgr;
typedef struct jpeg_common_struct jpeg_common_struct;
typedef struct jpeg_decompress_struct jpeg_decompress_struct;
typedef struct jpeg_common_struct tiff_ojpeg_common_struct;
typedef struct jpeg_decompress_struct tiff_ojpeg_decompress_struct;
typedef enum
{
@@ -316,9 +307,9 @@ typedef struct
uint32_t write_curstrile;
uint8_t libjpeg_session_active;
uint8_t libjpeg_jpeg_query_style;
jpeg_error_mgr libjpeg_jpeg_error_mgr;
jpeg_decompress_struct libjpeg_jpeg_decompress_struct;
jpeg_source_mgr libjpeg_jpeg_source_mgr;
tiff_ojpeg_error_mgr libjpeg_jpeg_error_mgr;
tiff_ojpeg_decompress_struct libjpeg_jpeg_decompress_struct;
tiff_ojpeg_source_mgr libjpeg_jpeg_source_mgr;
uint8_t subsampling_convert_log;
uint32_t subsampling_convert_ylinelen;
uint32_t subsampling_convert_ylines;
@@ -413,46 +404,51 @@ static void OJPEGWriteStreamEoi(TIFF *tif, void **mem, uint32_t *len);
#ifdef LIBJPEG_ENCAP_EXTERNAL
extern int jpeg_create_decompress_encap(OJPEGState *sp,
jpeg_decompress_struct *cinfo);
extern int jpeg_read_header_encap(OJPEGState *sp, jpeg_decompress_struct *cinfo,
tiff_ojpeg_decompress_struct *cinfo);
extern int jpeg_read_header_encap(OJPEGState *sp,
tiff_ojpeg_decompress_struct *cinfo,
uint8_t require_image);
extern int jpeg_start_decompress_encap(OJPEGState *sp,
jpeg_decompress_struct *cinfo);
tiff_ojpeg_decompress_struct *cinfo);
extern int jpeg_read_scanlines_encap(OJPEGState *sp,
jpeg_decompress_struct *cinfo,
tiff_ojpeg_decompress_struct *cinfo,
void *scanlines, uint32_t max_lines);
extern int jpeg_read_raw_data_encap(OJPEGState *sp,
jpeg_decompress_struct *cinfo, void *data,
uint32_t max_lines);
tiff_ojpeg_decompress_struct *cinfo,
void *data, uint32_t max_lines);
extern void jpeg_encap_unwind(TIFF *tif);
#else
static int jpeg_create_decompress_encap(OJPEGState *sp,
jpeg_decompress_struct *j);
static int jpeg_read_header_encap(OJPEGState *sp, jpeg_decompress_struct *cinfo,
tiff_ojpeg_decompress_struct *j);
static int jpeg_read_header_encap(OJPEGState *sp,
tiff_ojpeg_decompress_struct *cinfo,
uint8_t require_image);
static int jpeg_start_decompress_encap(OJPEGState *sp,
jpeg_decompress_struct *cinfo);
tiff_ojpeg_decompress_struct *cinfo);
static int jpeg_read_scanlines_encap(OJPEGState *sp,
jpeg_decompress_struct *cinfo,
tiff_ojpeg_decompress_struct *cinfo,
void *scanlines, uint32_t max_lines);
static int jpeg_read_raw_data_encap(OJPEGState *sp,
jpeg_decompress_struct *cinfo, void *data,
uint32_t max_lines);
tiff_ojpeg_decompress_struct *cinfo,
void *data, uint32_t max_lines);
static void jpeg_encap_unwind(TIFF *tif);
#endif
static void OJPEGLibjpegJpegErrorMgrOutputMessage(jpeg_common_struct *cinfo);
static void OJPEGLibjpegJpegErrorMgrErrorExit(jpeg_common_struct *cinfo);
static void OJPEGLibjpegJpegSourceMgrInitSource(jpeg_decompress_struct *cinfo);
static boolean
OJPEGLibjpegJpegSourceMgrFillInputBuffer(jpeg_decompress_struct *cinfo);
static void
OJPEGLibjpegJpegSourceMgrSkipInputData(jpeg_decompress_struct *cinfo,
OJPEGLibjpegJpegErrorMgrOutputMessage(tiff_ojpeg_common_struct *cinfo);
static void OJPEGLibjpegJpegErrorMgrErrorExit(tiff_ojpeg_common_struct *cinfo);
static void
OJPEGLibjpegJpegSourceMgrInitSource(tiff_ojpeg_decompress_struct *cinfo);
static boolean
OJPEGLibjpegJpegSourceMgrFillInputBuffer(tiff_ojpeg_decompress_struct *cinfo);
static void
OJPEGLibjpegJpegSourceMgrSkipInputData(tiff_ojpeg_decompress_struct *cinfo,
long num_bytes);
static boolean
OJPEGLibjpegJpegSourceMgrResyncToRestart(jpeg_decompress_struct *cinfo,
OJPEGLibjpegJpegSourceMgrResyncToRestart(tiff_ojpeg_decompress_struct *cinfo,
int desired);
static void OJPEGLibjpegJpegSourceMgrTermSource(jpeg_decompress_struct *cinfo);
static void
OJPEGLibjpegJpegSourceMgrTermSource(tiff_ojpeg_decompress_struct *cinfo);
int TIFFInitOJPEG(TIFF *tif, int scheme)
{
@@ -473,7 +469,7 @@ int TIFFInitOJPEG(TIFF *tif, int scheme)
}
/* state block */
sp = _TIFFmallocExt(tif, sizeof(OJPEGState));
sp = (OJPEGState *)_TIFFmallocExt(tif, sizeof(OJPEGState));
if (sp == NULL)
{
TIFFErrorExtR(tif, module, "No space for OJPEG state block");
@@ -724,9 +720,9 @@ static int OJPEGPreDecode(TIFF *tif, uint16_t s)
return (0);
}
if (isTiled(tif))
m = tif->tif_curtile;
m = tif->tif_dir.td_curtile;
else
m = tif->tif_curstrip;
m = tif->tif_dir.td_curstrip;
if ((sp->writeheader_done != 0) &&
((sp->write_cursample != s) || (sp->write_curstrile > m)))
{
@@ -797,7 +793,7 @@ static int OJPEGPreDecodeSkipRaw(TIFF *tif)
{
if (jpeg_read_raw_data_encap(sp, &(sp->libjpeg_jpeg_decompress_struct),
sp->subsampling_convert_ycbcrimage,
sp->subsampling_ver * 8) == 0)
(uint32_t)sp->subsampling_ver * 8) == 0)
return (0);
m -= sp->subsampling_convert_clines;
}
@@ -805,7 +801,7 @@ static int OJPEGPreDecodeSkipRaw(TIFF *tif)
{
if (jpeg_read_raw_data_encap(sp, &(sp->libjpeg_jpeg_decompress_struct),
sp->subsampling_convert_ycbcrimage,
sp->subsampling_ver * 8) == 0)
(uint32_t)sp->subsampling_ver * 8) == 0)
return (0);
sp->subsampling_convert_state = m;
}
@@ -819,7 +815,7 @@ static int OJPEGPreDecodeSkipScanlines(TIFF *tif)
uint32_t m;
if (sp->skip_buffer == NULL)
{
sp->skip_buffer = _TIFFmallocExt(tif, sp->bytes_per_line);
sp->skip_buffer = (uint8_t *)_TIFFmallocExt(tif, sp->bytes_per_line);
if (sp->skip_buffer == NULL)
{
TIFFErrorExtR(tif, module, "Out of memory");
@@ -910,10 +906,10 @@ static int OJPEGDecodeRaw(TIFF *tif, uint8_t *buf, tmsize_t cc)
{
if (sp->subsampling_convert_state == 0)
{
if (jpeg_read_raw_data_encap(sp,
&(sp->libjpeg_jpeg_decompress_struct),
sp->subsampling_convert_ycbcrimage,
sp->subsampling_ver * 8) == 0)
if (jpeg_read_raw_data_encap(
sp, &(sp->libjpeg_jpeg_decompress_struct),
sp->subsampling_convert_ycbcrimage,
(uint32_t)sp->subsampling_ver * 8) == 0)
{
sp->error_in_raw_data_decoding = 1;
return (0);
@@ -1225,7 +1221,7 @@ static int OJPEGReadHeaderInfo(TIFF *tif)
TIFFErrorExtR(tif, module, "Invalid subsampling values");
return (0);
}
if (sp->strile_length % (sp->subsampling_ver * 8) != 0)
if (sp->strile_length % ((uint32_t)sp->subsampling_ver * 8) != 0)
{
TIFFErrorExtR(tif, module,
"Incompatible vertical subsampling and image "
@@ -1233,9 +1229,11 @@ static int OJPEGReadHeaderInfo(TIFF *tif)
return (0);
}
sp->restart_interval =
(uint16_t)(((sp->strile_width + sp->subsampling_hor * 8 - 1) /
(sp->subsampling_hor * 8)) *
(sp->strile_length / (sp->subsampling_ver * 8)));
(uint16_t)(((sp->strile_width + (uint32_t)sp->subsampling_hor * 8 -
1) /
((uint32_t)sp->subsampling_hor * 8)) *
(sp->strile_length /
((uint32_t)sp->subsampling_ver * 8)));
}
if (OJPEGReadHeaderInfoSec(tif) == 0)
return (0);
@@ -1358,20 +1356,43 @@ static int OJPEGWriteHeaderInfo(TIFF *tif)
/* Check for division by zero. */
if (sp->subsampling_hor == 0 || sp->subsampling_ver == 0)
return (0);
/* Check for potential overflow in subsampling_convert_ylinelen
* computation.
*/
if (sp->strile_width >
UINT32_MAX - ((uint32_t)sp->subsampling_hor * 8 - 1))
return (0);
sp->subsampling_convert_ylinelen =
((sp->strile_width + sp->subsampling_hor * 8 - 1) /
(sp->subsampling_hor * 8) * sp->subsampling_hor * 8);
sp->subsampling_convert_ylines = sp->subsampling_ver * 8;
((sp->strile_width + (uint32_t)sp->subsampling_hor * 8 - 1) /
((uint32_t)sp->subsampling_hor * 8) *
((uint32_t)sp->subsampling_hor * 8));
sp->subsampling_convert_ylines = (uint32_t)sp->subsampling_ver * 8;
sp->subsampling_convert_clinelen =
sp->subsampling_convert_ylinelen / sp->subsampling_hor;
sp->subsampling_convert_clines = 8;
sp->subsampling_convert_ybuflen = sp->subsampling_convert_ylinelen *
sp->subsampling_convert_ylines;
sp->subsampling_convert_cbuflen = sp->subsampling_convert_clinelen *
sp->subsampling_convert_clines;
sp->subsampling_convert_ycbcrbuflen =
sp->subsampling_convert_ybuflen +
2 * sp->subsampling_convert_cbuflen;
/* Check for potential overflow in buffer length computations.
* Use 64-bit intermediates to detect uint32_t overflow in
* ylinelen * ylines, clinelen * clines, and their sum.
*/
{
uint64_t ybuflen64 =
(uint64_t)sp->subsampling_convert_ylinelen *
sp->subsampling_convert_ylines;
uint64_t cbuflen64 =
(uint64_t)sp->subsampling_convert_clinelen *
sp->subsampling_convert_clines;
uint64_t ycbcrbuflen64 = ybuflen64 + 2 * cbuflen64;
if (ybuflen64 > UINT32_MAX || cbuflen64 > UINT32_MAX ||
ycbcrbuflen64 > UINT32_MAX)
{
TIFFErrorExtR(tif, module,
"Integer overflow in OJPEG buffer size");
return (0);
}
sp->subsampling_convert_ybuflen = (uint32_t)ybuflen64;
sp->subsampling_convert_cbuflen = (uint32_t)cbuflen64;
sp->subsampling_convert_ycbcrbuflen = (uint32_t)ycbcrbuflen64;
}
/* The calloc is not normally necessary, except in some edge/broken
* cases */
/* for example for a tiled image of height 1 with a tile height of 1
@@ -1383,8 +1404,8 @@ static int OJPEGWriteHeaderInfo(TIFF *tif)
/* Even if this case is allowed (?), its handling is broken because
* OJPEGPreDecode() should also likely */
/* reset subsampling_convert_state to 0 when changing tile. */
sp->subsampling_convert_ycbcrbuf =
_TIFFcallocExt(tif, 1, sp->subsampling_convert_ycbcrbuflen);
sp->subsampling_convert_ycbcrbuf = (uint8_t *)_TIFFcallocExt(
tif, 1, sp->subsampling_convert_ycbcrbuflen);
if (sp->subsampling_convert_ycbcrbuf == 0)
{
TIFFErrorExtR(tif, module, "Out of memory");
@@ -1398,8 +1419,9 @@ static int OJPEGWriteHeaderInfo(TIFF *tif)
sp->subsampling_convert_ycbcrimagelen =
3 + sp->subsampling_convert_ylines +
2 * sp->subsampling_convert_clines;
sp->subsampling_convert_ycbcrimage = _TIFFmallocExt(
tif, sp->subsampling_convert_ycbcrimagelen * sizeof(uint8_t *));
sp->subsampling_convert_ycbcrimage = (uint8_t **)_TIFFmallocExt(
tif, (tmsize_t)((size_t)sp->subsampling_convert_ycbcrimagelen *
sizeof(uint8_t *)));
if (sp->subsampling_convert_ycbcrimage == 0)
{
TIFFErrorExtR(tif, module, "Out of memory");
@@ -1426,9 +1448,14 @@ static int OJPEGWriteHeaderInfo(TIFF *tif)
((sp->strile_width % sp->subsampling_hor) != 0 ? 1 : 0);
sp->subsampling_convert_state = 0;
sp->error_in_raw_data_decoding = 0;
sp->bytes_per_line =
sp->subsampling_convert_clinelenout *
(sp->subsampling_ver * sp->subsampling_hor + 2);
const uint64_t bpl =
(uint64_t)sp->subsampling_convert_clinelenout *
((uint64_t)sp->subsampling_ver * sp->subsampling_hor + 2);
if (bpl > UINT32_MAX)
return (0);
sp->bytes_per_line = (uint32_t)bpl;
sp->lines_per_strile =
sp->strile_length / sp->subsampling_ver +
((sp->strile_length % sp->subsampling_ver) != 0 ? 1 : 0);
@@ -1478,7 +1505,8 @@ static void OJPEGLibjpegSessionAbort(TIFF *tif)
{
OJPEGState *sp = (OJPEGState *)tif->tif_data;
assert(sp->libjpeg_session_active != 0);
jpeg_destroy((jpeg_common_struct *)(&(sp->libjpeg_jpeg_decompress_struct)));
jpeg_destroy(
(tiff_ojpeg_common_struct *)(&(sp->libjpeg_jpeg_decompress_struct)));
sp->libjpeg_session_active = 0;
}
@@ -1560,7 +1588,7 @@ static int OJPEGReadHeaderInfoSec(TIFF *tif)
return (0);
}
if (n > 2)
OJPEGReadSkip(sp, n - 2);
OJPEGReadSkip(sp, (uint16_t)(n - 2));
break;
case JPEG_MARKER_DRI:
if (OJPEGReadHeaderInfoSecStreamDri(tif) == 0)
@@ -1603,8 +1631,9 @@ static int OJPEGReadHeaderInfoSec(TIFF *tif)
return (0);
sp->sof_marker_id = JPEG_MARKER_SOF0;
for (o = 0; o < sp->samples_per_pixel; o++)
sp->sof_c[o] = o;
sp->sof_hv[0] = ((sp->subsampling_hor << 4) | sp->subsampling_ver);
sp->sof_c[o] = (uint8_t)o;
sp->sof_hv[0] =
(uint8_t)((sp->subsampling_hor << 4) | sp->subsampling_ver);
for (o = 1; o < sp->samples_per_pixel; o++)
sp->sof_hv[o] = 17;
sp->sof_x = sp->strile_width;
@@ -1659,10 +1688,10 @@ static int OJPEGReadHeaderInfoSecStreamDqt(TIFF *tif)
return (0);
}
if (sp->subsamplingcorrect != 0)
OJPEGReadSkip(sp, m - 2);
OJPEGReadSkip(sp, (uint16_t)(m - 2));
else
{
m -= 2;
m = (uint16_t)(m - 2);
do
{
if (m < 65)
@@ -1671,7 +1700,7 @@ static int OJPEGReadHeaderInfoSecStreamDqt(TIFF *tif)
return (0);
}
na = sizeof(uint32_t) + 69;
nb = _TIFFmallocExt(tif, na);
nb = (uint8_t *)_TIFFmallocExt(tif, na);
if (nb == 0)
{
TIFFErrorExtR(tif, module, "Out of memory");
@@ -1697,7 +1726,7 @@ static int OJPEGReadHeaderInfoSecStreamDqt(TIFF *tif)
if (sp->qtable[o] != 0)
_TIFFfreeExt(tif, sp->qtable[o]);
sp->qtable[o] = nb;
m -= 65;
m = (uint16_t)(m - 65);
} while (m > 0);
}
return (1);
@@ -1725,12 +1754,12 @@ static int OJPEGReadHeaderInfoSecStreamDht(TIFF *tif)
}
if (sp->subsamplingcorrect != 0)
{
OJPEGReadSkip(sp, m - 2);
OJPEGReadSkip(sp, (uint16_t)(m - 2));
}
else
{
na = sizeof(uint32_t) + 2 + m;
nb = _TIFFmallocExt(tif, na);
na = (uint32_t)(sizeof(uint32_t) + 2 + m);
nb = (uint8_t *)_TIFFmallocExt(tif, na);
if (nb == 0)
{
TIFFErrorExtR(tif, module, "Out of memory");
@@ -1739,9 +1768,10 @@ static int OJPEGReadHeaderInfoSecStreamDht(TIFF *tif)
*(uint32_t *)nb = na;
nb[sizeof(uint32_t)] = 255;
nb[sizeof(uint32_t) + 1] = JPEG_MARKER_DHT;
nb[sizeof(uint32_t) + 2] = (m >> 8);
nb[sizeof(uint32_t) + 3] = (m & 255);
if (OJPEGReadBlock(sp, m - 2, &nb[sizeof(uint32_t) + 4]) == 0)
nb[sizeof(uint32_t) + 2] = (uint8_t)(m >> 8);
nb[sizeof(uint32_t) + 3] = (uint8_t)(m & 255);
if (OJPEGReadBlock(sp, (uint16_t)(m - 2), &nb[sizeof(uint32_t) + 4]) ==
0)
{
_TIFFfreeExt(tif, nb);
return (0);
@@ -1809,7 +1839,7 @@ static int OJPEGReadHeaderInfoSecStreamSof(TIFF *tif, uint8_t marker_id)
TIFFErrorExtR(tif, module, "Corrupt SOF marker in JPEG data");
return (0);
}
m -= 8;
m = (uint16_t)(m - 8);
if (m % 3 != 0)
{
if (sp->subsamplingcorrect == 0)
@@ -2030,7 +2060,7 @@ static int OJPEGReadHeaderInfoSecTablesQTable(TIFF *tif)
}
}
oa = sizeof(uint32_t) + 69;
ob = _TIFFmallocExt(tif, oa);
ob = (uint8_t *)_TIFFmallocExt(tif, oa);
if (ob == 0)
{
TIFFErrorExtR(tif, module, "Out of memory");
@@ -2098,8 +2128,8 @@ static int OJPEGReadHeaderInfoSecTablesDcTable(TIFF *tif)
q = 0;
for (n = 0; n < 16; n++)
q += o[n];
ra = sizeof(uint32_t) + 21 + q;
rb = _TIFFmallocExt(tif, ra);
ra = (uint32_t)(sizeof(uint32_t) + 21 + q);
rb = (uint8_t *)_TIFFmallocExt(tif, ra);
if (rb == 0)
{
TIFFErrorExtR(tif, module, "Out of memory");
@@ -2122,7 +2152,7 @@ static int OJPEGReadHeaderInfoSecTablesDcTable(TIFF *tif)
if (sp->dctable[m] != 0)
_TIFFfreeExt(tif, sp->dctable[m]);
sp->dctable[m] = rb;
sp->sos_tda[m] = (m << 4);
sp->sos_tda[m] = (uint8_t)(m << 4);
}
else
sp->sos_tda[m] = sp->sos_tda[m - 1];
@@ -2168,8 +2198,8 @@ static int OJPEGReadHeaderInfoSecTablesAcTable(TIFF *tif)
q = 0;
for (n = 0; n < 16; n++)
q += o[n];
ra = sizeof(uint32_t) + 21 + q;
rb = _TIFFmallocExt(tif, ra);
ra = (uint32_t)(sizeof(uint32_t) + 21 + q);
rb = (uint8_t *)_TIFFmallocExt(tif, ra);
if (rb == 0)
{
TIFFErrorExtR(tif, module, "Out of memory");
@@ -2220,7 +2250,7 @@ static int OJPEGReadBufferFill(OJPEGState *sp)
if ((uint64_t)m > sp->in_buffer_file_togo)
m = (uint16_t)sp->in_buffer_file_togo;
n = TIFFReadFile(sp->tif, sp->in_buffer, (tmsize_t)m);
if (n == 0)
if (n <= 0)
return (0);
assert(n > 0);
assert(n <= OJPEG_BUFFER);
@@ -2286,6 +2316,7 @@ static int OJPEGReadBufferFill(OJPEGState *sp)
sp->in_buffer_next_strile++;
}
break;
case osibsEof:
default:
return (0);
}
@@ -2331,7 +2362,7 @@ static int OJPEGReadWord(OJPEGState *sp, uint16_t *word)
uint8_t m;
if (OJPEGReadByte(sp, &m) == 0)
return (0);
*word = (m << 8);
*word = (uint16_t)(m << 8);
if (OJPEGReadByte(sp, &m) == 0)
return (0);
*word |= m;
@@ -2345,7 +2376,7 @@ static int OJPEGReadBlock(OJPEGState *sp, uint16_t len, void *mem)
uint16_t n;
assert(len > 0);
mlen = len;
mmem = mem;
mmem = (uint8_t *)mem;
do
{
if (sp->in_buffer_togo == 0)
@@ -2359,8 +2390,8 @@ static int OJPEGReadBlock(OJPEGState *sp, uint16_t len, void *mem)
n = sp->in_buffer_togo;
_TIFFmemcpy(mmem, sp->in_buffer_cur, n);
sp->in_buffer_cur += n;
sp->in_buffer_togo -= n;
mlen -= n;
sp->in_buffer_togo = (uint16_t)(sp->in_buffer_togo - n);
mlen = (uint16_t)(mlen - n);
mmem += n;
} while (mlen > 0);
return (1);
@@ -2375,8 +2406,8 @@ static void OJPEGReadSkip(OJPEGState *sp, uint16_t len)
if (n > sp->in_buffer_togo)
n = sp->in_buffer_togo;
sp->in_buffer_cur += n;
sp->in_buffer_togo -= n;
m -= n;
sp->in_buffer_togo = (uint16_t)(sp->in_buffer_togo - n);
m = (uint16_t)(m - n);
if (m > 0)
{
assert(sp->in_buffer_togo == 0);
@@ -2462,6 +2493,8 @@ static int OJPEGWriteStream(TIFF *tif, void **mem, uint32_t *len)
case ososEoi:
OJPEGWriteStreamEoi(tif, mem, len);
break;
default:
break;
}
} while (*len == 0);
return (1);
@@ -2475,7 +2508,7 @@ static void OJPEGWriteStreamSoi(TIFF *tif, void **mem, uint32_t *len)
sp->out_buffer[1] = JPEG_MARKER_SOI;
*len = 2;
*mem = (void *)sp->out_buffer;
sp->out_state++;
sp->out_state = (OJPEGStateOutState)(sp->out_state + 1);
}
static void OJPEGWriteStreamQTable(TIFF *tif, uint8_t table_index, void **mem,
@@ -2485,9 +2518,10 @@ static void OJPEGWriteStreamQTable(TIFF *tif, uint8_t table_index, void **mem,
if (sp->qtable[table_index] != 0)
{
*mem = (void *)(sp->qtable[table_index] + sizeof(uint32_t));
*len = *((uint32_t *)sp->qtable[table_index]) - sizeof(uint32_t);
*len = (uint32_t)(*((uint32_t *)sp->qtable[table_index]) -
sizeof(uint32_t));
}
sp->out_state++;
sp->out_state = (OJPEGStateOutState)(sp->out_state + 1);
}
static void OJPEGWriteStreamDcTable(TIFF *tif, uint8_t table_index, void **mem,
@@ -2497,9 +2531,10 @@ static void OJPEGWriteStreamDcTable(TIFF *tif, uint8_t table_index, void **mem,
if (sp->dctable[table_index] != 0)
{
*mem = (void *)(sp->dctable[table_index] + sizeof(uint32_t));
*len = *((uint32_t *)sp->dctable[table_index]) - sizeof(uint32_t);
*len = (uint32_t)(*((uint32_t *)sp->dctable[table_index]) -
sizeof(uint32_t));
}
sp->out_state++;
sp->out_state = (OJPEGStateOutState)(sp->out_state + 1);
}
static void OJPEGWriteStreamAcTable(TIFF *tif, uint8_t table_index, void **mem,
@@ -2509,9 +2544,10 @@ static void OJPEGWriteStreamAcTable(TIFF *tif, uint8_t table_index, void **mem,
if (sp->actable[table_index] != 0)
{
*mem = (void *)(sp->actable[table_index] + sizeof(uint32_t));
*len = *((uint32_t *)sp->actable[table_index]) - sizeof(uint32_t);
*len = (uint32_t)(*((uint32_t *)sp->actable[table_index]) -
sizeof(uint32_t));
}
sp->out_state++;
sp->out_state = (OJPEGStateOutState)(sp->out_state + 1);
}
static void OJPEGWriteStreamDri(TIFF *tif, void **mem, uint32_t *len)
@@ -2524,12 +2560,12 @@ static void OJPEGWriteStreamDri(TIFF *tif, void **mem, uint32_t *len)
sp->out_buffer[1] = JPEG_MARKER_DRI;
sp->out_buffer[2] = 0;
sp->out_buffer[3] = 4;
sp->out_buffer[4] = (sp->restart_interval >> 8);
sp->out_buffer[5] = (sp->restart_interval & 255);
sp->out_buffer[4] = (uint8_t)(sp->restart_interval >> 8);
sp->out_buffer[5] = (uint8_t)(sp->restart_interval & 255);
*len = 6;
*mem = (void *)sp->out_buffer;
}
sp->out_state++;
sp->out_state = (OJPEGStateOutState)(sp->out_state + 1);
}
static void OJPEGWriteStreamSof(TIFF *tif, void **mem, uint32_t *len)
@@ -2542,15 +2578,15 @@ static void OJPEGWriteStreamSof(TIFF *tif, void **mem, uint32_t *len)
sp->out_buffer[1] = sp->sof_marker_id;
/* Lf */
sp->out_buffer[2] = 0;
sp->out_buffer[3] = 8 + sp->samples_per_pixel_per_plane * 3;
sp->out_buffer[3] = (uint8_t)(8 + sp->samples_per_pixel_per_plane * 3);
/* P */
sp->out_buffer[4] = 8;
/* Y */
sp->out_buffer[5] = (uint8_t)(sp->sof_y >> 8);
sp->out_buffer[6] = (sp->sof_y & 255);
sp->out_buffer[6] = (uint8_t)(sp->sof_y & 255);
/* X */
sp->out_buffer[7] = (uint8_t)(sp->sof_x >> 8);
sp->out_buffer[8] = (sp->sof_x & 255);
sp->out_buffer[8] = (uint8_t)(sp->sof_x & 255);
/* Nf */
sp->out_buffer[9] = sp->samples_per_pixel_per_plane;
for (m = 0; m < sp->samples_per_pixel_per_plane; m++)
@@ -2564,9 +2600,9 @@ static void OJPEGWriteStreamSof(TIFF *tif, void **mem, uint32_t *len)
sp->out_buffer[10 + m * 3 + 2] =
sp->sof_tq[sp->plane_sample_offset + m];
}
*len = 10 + sp->samples_per_pixel_per_plane * 3;
*len = 10 + (uint32_t)sp->samples_per_pixel_per_plane * 3;
*mem = (void *)sp->out_buffer;
sp->out_state++;
sp->out_state = (OJPEGStateOutState)(sp->out_state + 1);
}
static void OJPEGWriteStreamSos(TIFF *tif, void **mem, uint32_t *len)
@@ -2579,7 +2615,7 @@ static void OJPEGWriteStreamSos(TIFF *tif, void **mem, uint32_t *len)
sp->out_buffer[1] = JPEG_MARKER_SOS;
/* Ls */
sp->out_buffer[2] = 0;
sp->out_buffer[3] = 6 + sp->samples_per_pixel_per_plane * 2;
sp->out_buffer[3] = (uint8_t)(6 + sp->samples_per_pixel_per_plane * 2);
/* Ns */
sp->out_buffer[4] = sp->samples_per_pixel_per_plane;
for (m = 0; m < sp->samples_per_pixel_per_plane; m++)
@@ -2596,9 +2632,9 @@ static void OJPEGWriteStreamSos(TIFF *tif, void **mem, uint32_t *len)
sp->out_buffer[5 + sp->samples_per_pixel_per_plane * 2 + 1] = 63;
/* Ah and Al */
sp->out_buffer[5 + sp->samples_per_pixel_per_plane * 2 + 2] = 0;
*len = 8 + sp->samples_per_pixel_per_plane * 2;
*len = 8 + (uint32_t)sp->samples_per_pixel_per_plane * 2;
*mem = (void *)sp->out_buffer;
sp->out_state++;
sp->out_state = (OJPEGStateOutState)(sp->out_state + 1);
}
static int OJPEGWriteStreamCompressed(TIFF *tif, void **mem, uint32_t *len)
@@ -2626,6 +2662,8 @@ static int OJPEGWriteStreamCompressed(TIFF *tif, void **mem, uint32_t *len)
case osibsEof:
sp->out_state = ososEoi;
break;
case osibsNotSetYet:
case osibsJpegInterchangeFormat:
default:
break;
}
@@ -2638,7 +2676,7 @@ static void OJPEGWriteStreamRst(TIFF *tif, void **mem, uint32_t *len)
OJPEGState *sp = (OJPEGState *)tif->tif_data;
assert(OJPEG_BUFFER >= 2);
sp->out_buffer[0] = 255;
sp->out_buffer[1] = JPEG_MARKER_RST0 + sp->restart_index;
sp->out_buffer[1] = (uint8_t)(JPEG_MARKER_RST0 + sp->restart_index);
sp->restart_index++;
if (sp->restart_index == 8)
sp->restart_index = 0;
@@ -2659,7 +2697,7 @@ static void OJPEGWriteStreamEoi(TIFF *tif, void **mem, uint32_t *len)
#ifndef LIBJPEG_ENCAP_EXTERNAL
static int jpeg_create_decompress_encap(OJPEGState *sp,
jpeg_decompress_struct *cinfo)
tiff_ojpeg_decompress_struct *cinfo)
{
if (SETJMP(sp->exit_jmpbuf))
return 0;
@@ -2672,7 +2710,8 @@ static int jpeg_create_decompress_encap(OJPEGState *sp,
#endif
#ifndef LIBJPEG_ENCAP_EXTERNAL
static int jpeg_read_header_encap(OJPEGState *sp, jpeg_decompress_struct *cinfo,
static int jpeg_read_header_encap(OJPEGState *sp,
tiff_ojpeg_decompress_struct *cinfo,
uint8_t require_image)
{
if (SETJMP(sp->exit_jmpbuf))
@@ -2687,7 +2726,7 @@ static int jpeg_read_header_encap(OJPEGState *sp, jpeg_decompress_struct *cinfo,
#ifndef LIBJPEG_ENCAP_EXTERNAL
static int jpeg_start_decompress_encap(OJPEGState *sp,
jpeg_decompress_struct *cinfo)
tiff_ojpeg_decompress_struct *cinfo)
{
if (SETJMP(sp->exit_jmpbuf))
return 0;
@@ -2701,14 +2740,14 @@ static int jpeg_start_decompress_encap(OJPEGState *sp,
#ifndef LIBJPEG_ENCAP_EXTERNAL
static int jpeg_read_scanlines_encap(OJPEGState *sp,
jpeg_decompress_struct *cinfo,
tiff_ojpeg_decompress_struct *cinfo,
void *scanlines, uint32_t max_lines)
{
if (SETJMP(sp->exit_jmpbuf))
return 0;
else
{
jpeg_read_scanlines(cinfo, scanlines, max_lines);
jpeg_read_scanlines(cinfo, (JSAMPARRAY)scanlines, max_lines);
return 1;
}
}
@@ -2716,14 +2755,14 @@ static int jpeg_read_scanlines_encap(OJPEGState *sp,
#ifndef LIBJPEG_ENCAP_EXTERNAL
static int jpeg_read_raw_data_encap(OJPEGState *sp,
jpeg_decompress_struct *cinfo, void *data,
uint32_t max_lines)
tiff_ojpeg_decompress_struct *cinfo,
void *data, uint32_t max_lines)
{
if (SETJMP(sp->exit_jmpbuf))
return 0;
else
{
jpeg_read_raw_data(cinfo, data, max_lines);
jpeg_read_raw_data(cinfo, (JSAMPIMAGE)data, max_lines);
return 1;
}
}
@@ -2737,14 +2776,15 @@ static void jpeg_encap_unwind(TIFF *tif)
}
#endif
static void OJPEGLibjpegJpegErrorMgrOutputMessage(jpeg_common_struct *cinfo)
static void
OJPEGLibjpegJpegErrorMgrOutputMessage(tiff_ojpeg_common_struct *cinfo)
{
char buffer[JMSG_LENGTH_MAX];
(*cinfo->err->format_message)(cinfo, buffer);
TIFFWarningExtR(((TIFF *)(cinfo->client_data)), "LibJpeg", "%s", buffer);
}
static void OJPEGLibjpegJpegErrorMgrErrorExit(jpeg_common_struct *cinfo)
static void OJPEGLibjpegJpegErrorMgrErrorExit(tiff_ojpeg_common_struct *cinfo)
{
char buffer[JMSG_LENGTH_MAX];
(*cinfo->err->format_message)(cinfo, buffer);
@@ -2752,13 +2792,14 @@ static void OJPEGLibjpegJpegErrorMgrErrorExit(jpeg_common_struct *cinfo)
jpeg_encap_unwind((TIFF *)(cinfo->client_data));
}
static void OJPEGLibjpegJpegSourceMgrInitSource(jpeg_decompress_struct *cinfo)
static void
OJPEGLibjpegJpegSourceMgrInitSource(tiff_ojpeg_decompress_struct *cinfo)
{
(void)cinfo;
}
static boolean
OJPEGLibjpegJpegSourceMgrFillInputBuffer(jpeg_decompress_struct *cinfo)
OJPEGLibjpegJpegSourceMgrFillInputBuffer(tiff_ojpeg_decompress_struct *cinfo)
{
TIFF *tif = (TIFF *)cinfo->client_data;
OJPEGState *sp = (OJPEGState *)tif->tif_data;
@@ -2770,12 +2811,12 @@ OJPEGLibjpegJpegSourceMgrFillInputBuffer(jpeg_decompress_struct *cinfo)
jpeg_encap_unwind(tif);
}
sp->libjpeg_jpeg_source_mgr.bytes_in_buffer = len;
sp->libjpeg_jpeg_source_mgr.next_input_byte = mem;
sp->libjpeg_jpeg_source_mgr.next_input_byte = (const JOCTET *)mem;
return (1);
}
static void
OJPEGLibjpegJpegSourceMgrSkipInputData(jpeg_decompress_struct *cinfo,
OJPEGLibjpegJpegSourceMgrSkipInputData(tiff_ojpeg_decompress_struct *cinfo,
long num_bytes)
{
TIFF *tif = (TIFF *)cinfo->client_data;
@@ -2789,7 +2830,7 @@ OJPEGLibjpegJpegSourceMgrSkipInputData(jpeg_decompress_struct *cinfo,
#pragma warning(disable : 4702) /* unreachable code */
#endif
static boolean
OJPEGLibjpegJpegSourceMgrResyncToRestart(jpeg_decompress_struct *cinfo,
OJPEGLibjpegJpegSourceMgrResyncToRestart(tiff_ojpeg_decompress_struct *cinfo,
int desired)
{
TIFF *tif = (TIFF *)cinfo->client_data;
@@ -2802,7 +2843,8 @@ OJPEGLibjpegJpegSourceMgrResyncToRestart(jpeg_decompress_struct *cinfo,
#pragma warning(pop)
#endif
static void OJPEGLibjpegJpegSourceMgrTermSource(jpeg_decompress_struct *cinfo)
static void
OJPEGLibjpegJpegSourceMgrTermSource(tiff_ojpeg_decompress_struct *cinfo)
{
(void)cinfo;
}

View File

@@ -77,7 +77,7 @@ int _TIFFgetMode(TIFFOpenOptions *opts, thandle_t clientdata, const char *mode,
return (m);
}
TIFFOpenOptions *TIFFOpenOptionsAlloc()
TIFFOpenOptions *TIFFOpenOptionsAlloc(void)
{
TIFFOpenOptions *opts =
(TIFFOpenOptions *)_TIFFcalloc(1, sizeof(TIFFOpenOptions));
@@ -308,6 +308,7 @@ TIFF *TIFFClientOpenExt(const char *name, const char *mode,
TIFF *tif;
int m;
const char *cp;
tmsize_t size_to_alloc;
/* The following are configuration checks. They should be redundant, but
* should not compile to any actual code in an optimised release build
@@ -330,7 +331,7 @@ TIFF *TIFFClientOpenExt(const char *name, const char *mode,
n.a8[0] = 1;
n.a8[1] = 0;
(void)n;
#ifdef WORDS_BIGENDIAN
#if WORDS_BIGENDIAN
assert(n.a16 == 256);
#else
assert(n.a16 == 1);
@@ -340,7 +341,7 @@ TIFF *TIFFClientOpenExt(const char *name, const char *mode,
m = _TIFFgetMode(opts, clientdata, mode, module);
if (m == -1)
goto bad2;
tmsize_t size_to_alloc = (tmsize_t)(sizeof(TIFF) + strlen(name) + 1);
size_to_alloc = (tmsize_t)(sizeof(TIFF) + strlen(name) + 1);
if (opts && opts->max_single_mem_alloc > 0 &&
size_to_alloc > opts->max_single_mem_alloc)
{
@@ -377,8 +378,6 @@ TIFF *TIFFClientOpenExt(const char *name, const char *mode,
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 */
tif->tif_clientdata = clientdata;
tif->tif_readproc = readproc;
tif->tif_writeproc = writeproc;
@@ -398,6 +397,10 @@ TIFF *TIFFClientOpenExt(const char *name, const char *mode,
tif->tif_warn_about_unknown_tags = opts->warn_about_unknown_tags;
}
/* Reset tif->tif_dir structure to zero and
* initialize some IFD strile counter and index parameters. */
_TIFFResetTifDirAndInitStrileCounters(&tif->tif_dir);
if (!readproc || !writeproc || !seekproc || !closeproc || !sizeproc)
{
TIFFErrorExtR(tif, module,
@@ -480,13 +483,13 @@ TIFF *TIFFClientOpenExt(const char *name, const char *mode,
switch (*cp)
{
case 'b':
#ifndef WORDS_BIGENDIAN
#if !WORDS_BIGENDIAN
if (m & O_CREAT)
tif->tif_flags |= TIFF_SWAB;
#endif
break;
case 'l':
#ifdef WORDS_BIGENDIAN
#if WORDS_BIGENDIAN
if ((m & O_CREAT))
tif->tif_flags |= TIFF_SWAB;
#endif
@@ -536,7 +539,9 @@ TIFF *TIFFClientOpenExt(const char *name, const char *mode,
case 'O':
if (m == O_RDONLY)
tif->tif_flags |=
(TIFF_LAZYSTRILELOAD | TIFF_DEFERSTRILELOAD);
(TIFF_LAZYSTRILELOAD_ASKED | TIFF_DEFERSTRILELOAD);
break;
default:
break;
}
@@ -561,7 +566,7 @@ TIFF *TIFFClientOpenExt(const char *name, const char *mode,
/*
* Setup header and write.
*/
#ifdef WORDS_BIGENDIAN
#if WORDS_BIGENDIAN
tif->tif_header.common.tiff_magic =
(tif->tif_flags & TIFF_SWAB) ? TIFF_LITTLEENDIAN : TIFF_BIGENDIAN;
#else
@@ -654,13 +659,13 @@ TIFF *TIFFClientOpenExt(const char *name, const char *mode,
}
if (tif->tif_header.common.tiff_magic == TIFF_BIGENDIAN)
{
#ifndef WORDS_BIGENDIAN
#if !WORDS_BIGENDIAN
tif->tif_flags |= TIFF_SWAB;
#endif
}
else
{
#ifdef WORDS_BIGENDIAN
#if WORDS_BIGENDIAN
tif->tif_flags |= TIFF_SWAB;
#endif
}
@@ -780,6 +785,8 @@ TIFF *TIFFClientOpenExt(const char *name, const char *mode,
if (!TIFFDefaultDirectory(tif))
goto bad;
return (tif);
default:
break;
}
bad:
tif->tif_mode = O_RDONLY; /* XXX avoid flush */
@@ -861,7 +868,7 @@ int TIFFIsTiled(TIFF *tif) { return (isTiled(tif)); }
/*
* Return current row being read/written.
*/
uint32_t TIFFCurrentRow(TIFF *tif) { return (tif->tif_row); }
uint32_t TIFFCurrentRow(TIFF *tif) { return (tif->tif_dir.td_row); }
/*
* Return index of the current directory.
@@ -871,12 +878,12 @@ tdir_t TIFFCurrentDirectory(TIFF *tif) { return (tif->tif_curdir); }
/*
* Return current strip.
*/
uint32_t TIFFCurrentStrip(TIFF *tif) { return (tif->tif_curstrip); }
uint32_t TIFFCurrentStrip(TIFF *tif) { return (tif->tif_dir.td_curstrip); }
/*
* Return current tile.
*/
uint32_t TIFFCurrentTile(TIFF *tif) { return (tif->tif_curtile); }
uint32_t TIFFCurrentTile(TIFF *tif) { return (tif->tif_dir.td_curtile); }
/*
* Return nonzero if the file has byte-swapped data.

View File

@@ -194,12 +194,17 @@ static int PackBitsEncode(TIFF *tif, uint8_t *buf, tmsize_t cc, uint16_t s)
*/
if (n == 1 && op[-2] == (uint8_t)-1 && *lastliteral < 126)
{
state = (((*lastliteral) += 2) == 127 ? BASE : LITERAL);
state =
(((*lastliteral) = (uint8_t)(*lastliteral + 2)) == 127
? BASE
: LITERAL);
op[-2] = op[-1]; /* replicate */
}
else
state = RUN;
goto again;
default:
break;
}
}
tif->tif_rawcc += (tmsize_t)(op - tif->tif_rawcp);
@@ -306,12 +311,22 @@ static int PackBitsDecode(TIFF *tif, uint8_t *op, tmsize_t occ, uint16_t s)
{
memset(op, 0, (size_t)occ);
TIFFErrorExtR(tif, module, "Not enough data for scanline %" PRIu32,
tif->tif_row);
tif->tif_dir.td_row);
return (0);
}
return (1);
}
static uint64_t PackBitsGetMaxCompressionRatio(TIFF *tif)
{
(void)tif;
/* See README_for_libtiff_developpers.md for raw data used to estimate
* the maximum compression rate. */
return 64;
}
int TIFFInitPackBits(TIFF *tif, int scheme)
{
(void)scheme;
@@ -325,6 +340,8 @@ int TIFFInitPackBits(TIFF *tif, int scheme)
tif->tif_encodestrip = PackBitsEncodeChunk;
tif->tif_encodetile = PackBitsEncodeChunk;
#endif
tif->tif_getmaxcompressionratio = PackBitsGetMaxCompressionRatio;
return (1);
}
#endif /* PACKBITS_SUPPORT */

View File

@@ -117,11 +117,11 @@ static float LogK1, LogK2;
} while (i > 0); \
}
static void horizontalAccumulateF(uint16_t *wp, int n, int stride, float *op,
float *ToLinearF)
static void horizontalAccumulateF(uint16_t *wp, tmsize_t n, int stride,
float *op, float *ToLinearF)
{
register unsigned int cr, cg, cb, ca, mask;
register float t0, t1, t2, t3;
unsigned int cr, cg, cb, ca, mask;
float t0, t1, t2, t3;
if (n >= stride)
{
@@ -180,22 +180,22 @@ static void horizontalAccumulateF(uint16_t *wp, int n, int stride, float *op,
n -= stride;
while (n > 0)
{
REPEAT(stride, wp[stride] += *wp; *op = ToLinearF[*wp & mask];
wp++; op++)
REPEAT(stride, *wp = (uint16_t)(*wp + wp[-stride]);
*op = ToLinearF[*wp & mask]; wp++; op++)
n -= stride;
}
}
}
}
static void horizontalAccumulate12(uint16_t *wp, int n, int stride, int16_t *op,
float *ToLinearF)
static void horizontalAccumulate12(uint16_t *wp, tmsize_t n, int stride,
int16_t *op, float *ToLinearF)
{
register unsigned int cr, cg, cb, ca, mask;
register float t0, t1, t2, t3;
unsigned int cr, cg, cb, ca, mask;
float t0, t1, t2, t3;
#define SCALE12 2048.0F
#define CLAMP12(t) (((t) < 3071) ? (uint16_t)(t) : 3071)
#define SCALE12 2048.0f
#define CLAMP12(t) (((t) < 3071) ? (int16_t)(uint16_t)(t) : (int16_t)3071)
if (n >= stride)
{
@@ -255,19 +255,19 @@ static void horizontalAccumulate12(uint16_t *wp, int n, int stride, int16_t *op,
n -= stride;
while (n > 0)
{
REPEAT(stride, wp[stride] += *wp;
t0 = ToLinearF[wp[stride] & mask] * SCALE12;
*op = CLAMP12(t0); wp++; op++)
REPEAT(stride, *wp = (uint16_t)(*wp + wp[-stride]);
t0 = ToLinearF[*wp & mask] * SCALE12; *op = CLAMP12(t0);
wp++; op++)
n -= stride;
}
}
}
}
static void horizontalAccumulate16(uint16_t *wp, int n, int stride,
static void horizontalAccumulate16(uint16_t *wp, tmsize_t n, int stride,
uint16_t *op, uint16_t *ToLinear16)
{
register unsigned int cr, cg, cb, ca, mask;
unsigned int cr, cg, cb, ca, mask;
if (n >= stride)
{
@@ -312,8 +312,8 @@ static void horizontalAccumulate16(uint16_t *wp, int n, int stride,
n -= stride;
while (n > 0)
{
REPEAT(stride, wp[stride] += *wp; *op = ToLinear16[*wp & mask];
wp++; op++)
REPEAT(stride, *wp = (uint16_t)(*wp + wp[-stride]);
*op = ToLinear16[*wp & mask]; wp++; op++)
n -= stride;
}
}
@@ -324,10 +324,10 @@ static void horizontalAccumulate16(uint16_t *wp, int n, int stride,
* Returns the log encoded 11-bit values with the horizontal
* differencing undone.
*/
static void horizontalAccumulate11(uint16_t *wp, int n, int stride,
static void horizontalAccumulate11(uint16_t *wp, tmsize_t n, int stride,
uint16_t *op)
{
register unsigned int cr, cg, cb, ca, mask;
unsigned int cr, cg, cb, ca, mask;
if (n >= stride)
{
@@ -375,21 +375,22 @@ static void horizontalAccumulate11(uint16_t *wp, int n, int stride,
}
else
{
REPEAT(stride, *op = *wp & mask; wp++; op++)
REPEAT(stride, *op = (uint16_t)(*wp & mask); wp++; op++)
n -= stride;
while (n > 0)
{
REPEAT(stride, wp[stride] += *wp; *op = *wp & mask; wp++; op++)
REPEAT(stride, *wp = (uint16_t)(*wp + wp[-stride]);
*op = (uint16_t)(*wp & mask); wp++; op++)
n -= stride;
}
}
}
}
static void horizontalAccumulate8(uint16_t *wp, int n, int stride,
static void horizontalAccumulate8(uint16_t *wp, tmsize_t n, int stride,
unsigned char *op, unsigned char *ToLinear8)
{
register unsigned int cr, cg, cb, ca, mask;
unsigned int cr, cg, cb, ca, mask;
if (n >= stride)
{
@@ -434,20 +435,20 @@ static void horizontalAccumulate8(uint16_t *wp, int n, int stride,
n -= stride;
while (n > 0)
{
REPEAT(stride, wp[stride] += *wp; *op = ToLinear8[*wp & mask];
wp++; op++)
REPEAT(stride, *wp = (uint16_t)(*wp + wp[-stride]);
*op = ToLinear8[*wp & mask]; wp++; op++)
n -= stride;
}
}
}
}
static void horizontalAccumulate8abgr(uint16_t *wp, int n, int stride,
static void horizontalAccumulate8abgr(uint16_t *wp, tmsize_t n, int stride,
unsigned char *op,
unsigned char *ToLinear8)
{
register unsigned int cr, cg, cb, ca, mask;
register unsigned char t0, t1, t2, t3;
unsigned int cr, cg, cb, ca, mask;
unsigned char t0, t1, t2, t3;
if (n >= stride)
{
@@ -508,8 +509,8 @@ static void horizontalAccumulate8abgr(uint16_t *wp, int n, int stride,
n -= stride;
while (n > 0)
{
REPEAT(stride, wp[stride] += *wp; *op = ToLinear8[*wp & mask];
wp++; op++)
REPEAT(stride, *wp = (uint16_t)(*wp + wp[-stride]);
*op = ToLinear8[*wp & mask]; wp++; op++)
n -= stride;
}
}
@@ -577,7 +578,8 @@ static int PixarLogMakeTables(TIFF *tif, PixarLogState *sp)
LogK1 = (float)(1. / c); /* if (v >= 2) token = k1*log(v*k2) */
LogK2 = (float)(1. / b);
lt2size = (int)(2. / linstep) + 1;
FromLT2 = (uint16_t *)_TIFFmallocExt(tif, lt2size * sizeof(uint16_t));
FromLT2 = (uint16_t *)_TIFFmallocExt(
tif, (tmsize_t)((size_t)lt2size * sizeof(uint16_t)));
From14 = (uint16_t *)_TIFFmallocExt(tif, 16384 * sizeof(uint16_t));
From8 = (uint16_t *)_TIFFmallocExt(tif, 256 * sizeof(uint16_t));
ToLinearF = (float *)_TIFFmallocExt(tif, TSIZEP1 * sizeof(float));
@@ -623,16 +625,17 @@ static int PixarLogMakeTables(TIFF *tif, PixarLogState *sp)
for (i = 0; i < TSIZEP1; i++)
{
v = ToLinearF[i] * 65535.0 + 0.5;
v = (double)ToLinearF[i] * 65535.0 + 0.5;
ToLinear16[i] = (v > 65535.0) ? 65535 : (uint16_t)v;
v = ToLinearF[i] * 255.0 + 0.5;
v = (double)ToLinearF[i] * 255.0 + 0.5;
ToLinear8[i] = (v > 255.0) ? 255 : (unsigned char)v;
}
j = 0;
for (i = 0; i < lt2size; i++)
{
if ((i * linstep) * (i * linstep) > ToLinearF[j] * ToLinearF[j + 1])
if ((i * linstep) * (i * linstep) >
(double)ToLinearF[j] * (double)ToLinearF[j + 1])
j++;
FromLT2[i] = (uint16_t)j;
}
@@ -645,7 +648,8 @@ static int PixarLogMakeTables(TIFF *tif, PixarLogState *sp)
j = 0;
for (i = 0; i < 16384; i++)
{
while ((i / 16383.) * (i / 16383.) > ToLinearF[j] * ToLinearF[j + 1])
while ((i / 16383.) * (i / 16383.) >
(double)ToLinearF[j] * (double)ToLinearF[j + 1])
j++;
From14[i] = (uint16_t)j;
}
@@ -653,7 +657,8 @@ static int PixarLogMakeTables(TIFF *tif, PixarLogState *sp)
j = 0;
for (i = 0; i < 256; i++)
{
while ((i / 255.) * (i / 255.) > ToLinearF[j] * ToLinearF[j + 1])
while ((i / 255.) * (i / 255.) >
(double)ToLinearF[j] * (double)ToLinearF[j + 1])
j++;
From8[i] = (uint16_t)j;
}
@@ -708,6 +713,8 @@ static int PixarLogGuessDataFmt(TIFFDirectory *td)
if (format == SAMPLEFORMAT_VOID || format == SAMPLEFORMAT_UINT)
guess = PIXARLOGDATAFMT_8BIT;
break;
default:
break;
}
return guess;
@@ -769,7 +776,8 @@ static int PixarLogSetupDecode(TIFF *tif)
multiply_ms(multiply_ms(sp->stride, td->td_imagewidth), strip_height),
sizeof(uint16_t));
/* add one more stride in case input ends mid-stride */
tbuf_size = add_ms(tbuf_size, sizeof(uint16_t) * sp->stride);
tbuf_size =
add_ms(tbuf_size, (tmsize_t)(sizeof(uint16_t) * (size_t)sp->stride));
if (tbuf_size == 0)
return (0); /* TODO: this is an error return without error report
through TIFFErrorExt */
@@ -838,18 +846,21 @@ static int PixarLogDecode(TIFF *tif, uint8_t *op, tmsize_t occ, uint16_t s)
PixarLogState *sp = PixarLogDecoderState(tif);
tmsize_t i;
tmsize_t nsamples;
int llen;
tmsize_t llen;
uint16_t *up;
switch (sp->user_datafmt)
{
case PIXARLOGDATAFMT_FLOAT:
nsamples = occ / sizeof(float); /* XXX float == 32 bits */
nsamples = (tmsize_t)((uint64_t)occ /
sizeof(float)); /* XXX float == 32 bits */
break;
case PIXARLOGDATAFMT_16BIT:
case PIXARLOGDATAFMT_12BITPICIO:
case PIXARLOGDATAFMT_11BITLOG:
nsamples = occ / sizeof(uint16_t); /* XXX uint16_t == 16 bits */
nsamples =
(tmsize_t)((uint64_t)occ /
sizeof(uint16_t)); /* XXX uint16_t == 16 bits */
break;
case PIXARLOGDATAFMT_8BIT:
case PIXARLOGDATAFMT_8BITABGR:
@@ -863,7 +874,55 @@ static int PixarLogDecode(TIFF *tif, uint8_t *op, tmsize_t occ, uint16_t s)
return 0;
}
llen = sp->stride * td->td_imagewidth;
llen = (tmsize_t)sp->stride * td->td_imagewidth;
/* Fix: ABGR with stride=3 expands 3 samples to 4 output bytes per pixel */
if (sp->user_datafmt == PIXARLOGDATAFMT_8BITABGR && sp->stride == 3)
{
tmsize_t required = (tmsize_t)td->td_imagewidth * 4;
tmsize_t max_rows;
tmsize_t max_nsamples;
/*
* Ensure at least one expanded output row fits.
*/
if (occ < required)
{
TIFFErrorExtR(tif, module,
"Output buffer too small for PixarLog ABGR data");
memset(op, 0, (size_t)occ);
return (0);
}
/*
* The caller-provided output buffer size must represent a whole
* number of expanded ABGR scanlines.
*/
if (occ % required)
{
TIFFErrorExtR(
tif, module,
"Fractional scanline not supported for PixarLog ABGR data");
memset(op, 0, (size_t)occ);
return (0);
}
/*
* PixarLogDecode() may process multiple rows per call
* (e.g. strip decoding). Limit nsamples so the total
* output written by the loop below never exceeds occ.
*/
max_rows = occ / required;
max_nsamples = max_rows * llen;
if (nsamples > max_nsamples)
{
TIFFErrorExtR(tif, module,
"Output buffer too small for PixarLog ABGR data");
memset(op, 0, (size_t)occ);
return (0);
}
}
(void)s;
assert(sp != NULL);
@@ -876,8 +935,8 @@ static int PixarLogDecode(TIFF *tif, uint8_t *op, tmsize_t occ, uint16_t s)
we need to simplify this code to reflect a ZLib that is likely updated
to deal with 8byte memory sizes, though this code will respond
appropriately even before we simplify it */
sp->stream.avail_out = (uInt)(nsamples * sizeof(uint16_t));
if (sp->stream.avail_out != nsamples * sizeof(uint16_t))
sp->stream.avail_out = (uInt)((unsigned long)nsamples * sizeof(uint16_t));
if (sp->stream.avail_out != (unsigned long)nsamples * sizeof(uint16_t))
{
TIFFErrorExtR(tif, module, "ZLib cannot deal with buffers this size");
memset(op, 0, (size_t)occ);
@@ -899,9 +958,10 @@ static int PixarLogDecode(TIFF *tif, uint8_t *op, tmsize_t occ, uint16_t s)
}
if (state == Z_DATA_ERROR)
{
TIFFErrorExtR(
tif, module, "Decoding error at scanline %" PRIu32 ", %s",
tif->tif_row, sp->stream.msg ? sp->stream.msg : "(null)");
TIFFErrorExtR(tif, module,
"Decoding error at scanline %" PRIu32 ", %s",
tif->tif_dir.td_row,
sp->stream.msg ? sp->stream.msg : "(null)");
memset(op, 0, (size_t)occ);
return (0);
}
@@ -920,7 +980,7 @@ static int PixarLogDecode(TIFF *tif, uint8_t *op, tmsize_t occ, uint16_t s)
TIFFErrorExtR(tif, module,
"Not enough data at scanline %" PRIu32
" (short %u bytes)",
tif->tif_row, sp->stream.avail_out);
tif->tif_dir.td_row, sp->stream.avail_out);
memset(op, 0, (size_t)occ);
return (0);
}
@@ -941,7 +1001,8 @@ static int PixarLogDecode(TIFF *tif, uint8_t *op, tmsize_t occ, uint16_t s)
if (nsamples % llen)
{
TIFFWarningExtR(tif, module,
"stride %d is not a multiple of sample count, "
"stride %" TIFF_SSIZE_FORMAT
" is not a multiple of sample count, "
"%" TIFF_SSIZE_FORMAT ", data truncated.",
llen, nsamples);
nsamples -= nsamples % llen;
@@ -954,31 +1015,37 @@ static int PixarLogDecode(TIFF *tif, uint8_t *op, tmsize_t occ, uint16_t s)
case PIXARLOGDATAFMT_FLOAT:
horizontalAccumulateF(up, llen, sp->stride, (float *)op,
sp->ToLinearF);
op += llen * sizeof(float);
op += (unsigned long)llen * sizeof(float);
break;
case PIXARLOGDATAFMT_16BIT:
horizontalAccumulate16(up, llen, sp->stride, (uint16_t *)op,
sp->ToLinear16);
op += llen * sizeof(uint16_t);
op += (unsigned long)llen * sizeof(uint16_t);
break;
case PIXARLOGDATAFMT_12BITPICIO:
horizontalAccumulate12(up, llen, sp->stride, (int16_t *)op,
sp->ToLinearF);
op += llen * sizeof(int16_t);
op += (unsigned long)llen * sizeof(int16_t);
break;
case PIXARLOGDATAFMT_11BITLOG:
horizontalAccumulate11(up, llen, sp->stride, (uint16_t *)op);
op += llen * sizeof(uint16_t);
op += (unsigned long)llen * sizeof(uint16_t);
break;
case PIXARLOGDATAFMT_8BIT:
horizontalAccumulate8(up, llen, sp->stride, (unsigned char *)op,
sp->ToLinear8);
op += llen * sizeof(unsigned char);
op += (unsigned long)llen * sizeof(unsigned char);
break;
case PIXARLOGDATAFMT_8BITABGR:
horizontalAccumulate8abgr(up, llen, sp->stride,
(unsigned char *)op, sp->ToLinear8);
op += llen * sizeof(unsigned char);
/* For stride == 3 (RGB), horizontalAccumulate8abgr expands to 4
* bytes/pixel (ABGR) */
if (sp->stride == 3)
op += (unsigned long)td->td_imagewidth * 4;
else
op += (unsigned long)llen * sizeof(unsigned char);
break;
default:
TIFFErrorExtR(tif, module, "Unsupported bits/sample: %" PRIu16,
@@ -1063,17 +1130,18 @@ static int PixarLogPreEncode(TIFF *tif, uint16_t s)
return (deflateReset(&sp->stream) == Z_OK);
}
static void horizontalDifferenceF(float *ip, int n, int stride, uint16_t *wp,
uint16_t *FromLT2)
static void horizontalDifferenceF(float *ip, tmsize_t n, int stride,
uint16_t *wp, uint16_t *FromLT2)
{
int32_t r1, g1, b1, a1, r2, g2, b2, a2, mask;
float fltsize = Fltsize;
#define CLAMP(v) \
((v < (float)0.) ? 0 \
: (v < (float)2.) ? FromLT2[(int)(v * fltsize)] \
: (v > (float)24.2) ? 2047 \
: LogK1 * log(v * LogK2) + 0.5)
((v < (float)0.) ? 0 \
: (v < (float)2.) ? FromLT2[(int)(v * fltsize)] \
: (v > (float)24.2) \
? 2047 \
: (double)LogK1 * log((double)v * (double)LogK2) + 0.5)
mask = CODE_MASK;
if (n >= stride)
@@ -1143,10 +1211,10 @@ static void horizontalDifferenceF(float *ip, int n, int stride, uint16_t *wp,
}
}
static void horizontalDifference16(unsigned short *ip, int n, int stride,
static void horizontalDifference16(unsigned short *ip, tmsize_t n, int stride,
unsigned short *wp, uint16_t *From14)
{
register int r1, g1, b1, a1, r2, g2, b2, a2, mask;
int r1, g1, b1, a1, r2, g2, b2, a2, mask;
/* assumption is unsigned pixel values */
#undef CLAMP
@@ -1219,10 +1287,10 @@ static void horizontalDifference16(unsigned short *ip, int n, int stride,
}
}
static void horizontalDifference8(unsigned char *ip, int n, int stride,
static void horizontalDifference8(unsigned char *ip, tmsize_t n, int stride,
unsigned short *wp, uint16_t *From8)
{
register int r1, g1, b1, a1, r2, g2, b2, a2, mask;
int r1, g1, b1, a1, r2, g2, b2, a2, mask;
#undef CLAMP
#define CLAMP(v) (From8[(v)])
@@ -1304,7 +1372,7 @@ static int PixarLogEncode(TIFF *tif, uint8_t *bp, tmsize_t cc, uint16_t s)
PixarLogState *sp = PixarLogEncoderState(tif);
tmsize_t i;
tmsize_t n;
int llen;
tmsize_t llen;
unsigned short *up;
(void)s;
@@ -1312,12 +1380,14 @@ static int PixarLogEncode(TIFF *tif, uint8_t *bp, tmsize_t cc, uint16_t s)
switch (sp->user_datafmt)
{
case PIXARLOGDATAFMT_FLOAT:
n = cc / sizeof(float); /* XXX float == 32 bits */
n = (tmsize_t)((unsigned long)cc /
sizeof(float)); /* XXX float == 32 bits */
break;
case PIXARLOGDATAFMT_16BIT:
case PIXARLOGDATAFMT_12BITPICIO:
case PIXARLOGDATAFMT_11BITLOG:
n = cc / sizeof(uint16_t); /* XXX uint16_t == 16 bits */
n = (tmsize_t)((unsigned long)cc /
sizeof(uint16_t)); /* XXX uint16_t == 16 bits */
break;
case PIXARLOGDATAFMT_8BIT:
case PIXARLOGDATAFMT_8BITABGR:
@@ -1330,7 +1400,7 @@ static int PixarLogEncode(TIFF *tif, uint8_t *bp, tmsize_t cc, uint16_t s)
return 0;
}
llen = sp->stride * td->td_imagewidth;
llen = (tmsize_t)sp->stride * td->td_imagewidth;
/* Check against the number of elements (of size uint16_t) of sp->tbuf */
if (n > ((tmsize_t)td->td_rowsperstrip * llen))
{
@@ -1345,17 +1415,17 @@ static int PixarLogEncode(TIFF *tif, uint8_t *bp, tmsize_t cc, uint16_t s)
case PIXARLOGDATAFMT_FLOAT:
horizontalDifferenceF((float *)bp, llen, sp->stride, up,
sp->FromLT2);
bp += llen * sizeof(float);
bp += (unsigned long)llen * sizeof(float);
break;
case PIXARLOGDATAFMT_16BIT:
horizontalDifference16((uint16_t *)bp, llen, sp->stride, up,
sp->From14);
bp += llen * sizeof(uint16_t);
bp += (unsigned long)llen * sizeof(uint16_t);
break;
case PIXARLOGDATAFMT_8BIT:
horizontalDifference8((unsigned char *)bp, llen, sp->stride, up,
sp->From8);
bp += llen * sizeof(unsigned char);
bp += (unsigned long)llen * sizeof(unsigned char);
break;
default:
TIFFErrorExtR(tif, module,
@@ -1370,8 +1440,8 @@ static int PixarLogEncode(TIFF *tif, uint8_t *bp, tmsize_t cc, uint16_t s)
we need to simplify this code to reflect a ZLib that is likely updated
to deal with 8byte memory sizes, though this code will respond
appropriately even before we simplify it */
sp->stream.avail_in = (uInt)(n * sizeof(uint16_t));
if ((sp->stream.avail_in / sizeof(uint16_t)) != (uInt)n)
sp->stream.avail_in = (uInt)((unsigned long)n * sizeof(uint16_t));
if ((sp->stream.avail_in / sizeof(uint16_t)) != (unsigned long)n)
{
TIFFErrorExtR(tif, module, "ZLib cannot deal with buffers this size");
return (0);
@@ -1562,13 +1632,15 @@ static int PixarLogVSetField(TIFF *tif, uint32_t tag, va_list ap)
TIFFSetField(tif, TIFFTAG_SAMPLEFORMAT,
SAMPLEFORMAT_IEEEFP);
break;
default:
break;
}
/*
* Must recalculate sizes should bits/sample change.
*/
tif->tif_tilesize =
tif->tif_dir.td_tilesize =
isTiled(tif) ? TIFFTileSize(tif) : (tmsize_t)(-1);
tif->tif_scanlinesize = TIFFScanlineSize(tif);
tif->tif_dir.td_scanlinesize = TIFFScanlineSize(tif);
result = 1; /* NB: pseudo tag */
break;
default:
@@ -1601,6 +1673,16 @@ static const TIFFField pixarlogFields[] = {
{TIFFTAG_PIXARLOGQUALITY, 0, 0, TIFF_ANY, 0, TIFF_SETGET_INT, FIELD_PSEUDO,
FALSE, FALSE, "", NULL}};
static uint64_t PixarLogGetMaxCompressionRatio(TIFF *tif)
{
(void)tif;
/* cf https://zlib.net/zlib_tech.html */
const uint64_t MAX_DEFLATE_RATIO = 1032;
/* security margin as I don't understand what this codec does */
return MAX_DEFLATE_RATIO * (uint64_t)4;
}
int TIFFInitPixarLog(TIFF *tif, int scheme)
{
static const char module[] = "TIFFInitPixarLog";
@@ -1648,6 +1730,7 @@ int TIFFInitPixarLog(TIFF *tif, int scheme)
tif->tif_encodetile = PixarLogEncode;
tif->tif_close = PixarLogClose;
tif->tif_cleanup = PixarLogCleanup;
tif->tif_getmaxcompressionratio = PixarLogGetMaxCompressionRatio;
/* Override SetField so we can handle our private pseudo-tag */
sp->vgetparent = tif->tif_tagmethods.vgetfield;

View File

@@ -30,7 +30,7 @@
#include "tif_predict.h"
#include "tiffiop.h"
#if defined(__x86_64__) || defined(_M_X64)
#if defined(__x86_64__) || (defined(_M_X64) && !defined(_M_ARM64EC))
#include <emmintrin.h>
#endif
@@ -151,6 +151,8 @@ static int PredictorSetupDecode(TIFF *tif)
case 64:
sp->decodepfunc = horAcc64;
break;
default:
break;
}
/*
* Override default decoding method with one that does the
@@ -247,6 +249,8 @@ static int PredictorSetupEncode(TIFF *tif)
case 64:
sp->encodepfunc = horDiff64;
break;
default:
break;
}
/*
* Override default encoding method with one that does the
@@ -590,7 +594,7 @@ static int fpAcc(TIFF *tif, uint8_t *cp0, tmsize_t cc)
cp = (uint8_t *)cp0;
count = 0;
#if defined(__x86_64__) || defined(_M_X64)
#if defined(__x86_64__) || (defined(_M_X64) && !defined(_M_ARM64EC))
if (bps == 4)
{
/* Optimization of general case */
@@ -972,7 +976,7 @@ static int PredictorEncodeRow(TIFF *tif, uint8_t *bp, tmsize_t cc, uint16_t s)
(int64_t)cc);
return 0;
}
memcpy(working_copy, bp, cc);
memcpy(working_copy, bp, (size_t)cc);
if (!(*sp->encodepfunc)(tif, working_copy, cc))
{
@@ -1010,7 +1014,7 @@ static int PredictorEncodeTile(TIFF *tif, uint8_t *bp0, tmsize_t cc0,
(int64_t)cc0);
return 0;
}
memcpy(working_copy, bp0, cc0);
memcpy(working_copy, bp0, (size_t)cc0);
bp = working_copy;
rowsize = sp->rowsize;
@@ -1098,8 +1102,10 @@ static void PredictorPrintDir(TIFF *tif, FILE *fd, long flags)
case 3:
fprintf(fd, "floating point predictor ");
break;
default:
break;
}
fprintf(fd, "%d (0x%x)\n", sp->predictor, sp->predictor);
fprintf(fd, "%d (0x%x)\n", sp->predictor, (unsigned)sp->predictor);
}
if (sp->printdir)
(*sp->printdir)(tif, fd, flags);

View File

@@ -118,10 +118,10 @@ static void _TIFFPrintField(FILE *fd, const TIFFField *fip,
if (tv_size == 8)
fprintf(fd, "%lf", ((double *)raw_data)[j]);
else
fprintf(fd, "%f", ((float *)raw_data)[j]);
fprintf(fd, "%f", (double)((float *)raw_data)[j]);
}
else if (fip->field_type == TIFF_FLOAT)
fprintf(fd, "%f", ((float *)raw_data)[j]);
fprintf(fd, "%f", (double)((float *)raw_data)[j]);
else if (fip->field_type == TIFF_LONG8)
fprintf(fd, "%" PRIu64, ((uint64_t *)raw_data)[j]);
else if (fip->field_type == TIFF_SLONG8)
@@ -193,8 +193,9 @@ static int _TIFFPrettyPrintField(TIFF *tif, const TIFFField *fip, FILE *fd,
case TIFFTAG_WHITEPOINT:
if (value_count == 2 && fip->field_type == TIFF_RATIONAL)
{
fprintf(fd, " White Point: %g-%g\n", ((float *)raw_data)[0],
((float *)raw_data)[1]);
fprintf(fd, " White Point: %g-%g\n",
(double)((float *)raw_data)[0],
(double)((float *)raw_data)[1]);
return 1;
}
return 0;
@@ -232,6 +233,9 @@ static int _TIFFPrettyPrintField(TIFF *tif, const TIFFField *fip, FILE *fd,
return 1;
}
return 0;
default:
break;
}
return 0;
@@ -244,8 +248,7 @@ static int _TIFFPrettyPrintField(TIFF *tif, const TIFFField *fip, FILE *fd,
void TIFFPrintDirectory(TIFF *tif, FILE *fd, long flags)
{
TIFFDirectory *td = &tif->tif_dir;
char *sep;
long l, n;
const char *sep;
fprintf(fd, "TIFF Directory at offset 0x%" PRIx64 " (%" PRIu64 ")\n",
tif->tif_diroff, tif->tif_diroff);
@@ -286,8 +289,8 @@ void TIFFPrintDirectory(TIFF *tif, FILE *fd, long flags)
}
if (TIFFFieldSet(tif, FIELD_RESOLUTION))
{
fprintf(fd, " Resolution: %g, %g", td->td_xresolution,
td->td_yresolution);
fprintf(fd, " Resolution: %g, %g", (double)td->td_xresolution,
(double)td->td_yresolution);
if (TIFFFieldSet(tif, FIELD_RESOLUTIONUNIT))
{
switch (td->td_resolutionunit)
@@ -310,7 +313,8 @@ void TIFFPrintDirectory(TIFF *tif, FILE *fd, long flags)
fprintf(fd, "\n");
}
if (TIFFFieldSet(tif, FIELD_POSITION))
fprintf(fd, " Position: %g, %g\n", td->td_xposition, td->td_yposition);
fprintf(fd, " Position: %g, %g\n", (double)td->td_xposition,
(double)td->td_yposition);
if (TIFFFieldSet(tif, FIELD_BITSPERSAMPLE))
fprintf(fd, " Bits/Sample: %" PRIu16 "\n", td->td_bitspersample);
if (TIFFFieldSet(tif, FIELD_SAMPLEFORMAT))
@@ -374,7 +378,8 @@ void TIFFPrintDirectory(TIFF *tif, FILE *fd, long flags)
}
}
}
if (TIFFFieldSet(tif, FIELD_EXTRASAMPLES) && td->td_extrasamples)
if (TIFFFieldSet(tif, FIELD_EXTRASAMPLES) && td->td_extrasamples &&
td->td_sampleinfo)
{
uint16_t i;
fprintf(fd, " Extra Samples: %" PRIu16 "<", td->td_extrasamples);
@@ -412,7 +417,8 @@ void TIFFPrintDirectory(TIFF *tif, FILE *fd, long flags)
i > 0 && cp < td->td_inknames + td->td_inknameslen;
cp = strchr(cp, '\0') + 1, i--)
{
size_t max_chars = td->td_inknameslen - (cp - td->td_inknames);
size_t max_chars =
(size_t)(td->td_inknameslen - (cp - td->td_inknames));
fputs(sep, fd);
_TIFFprintAsciiBounded(fd, cp, max_chars);
sep = ", ";
@@ -548,17 +554,25 @@ void TIFFPrintDirectory(TIFF *tif, FILE *fd, long flags)
if (TIFFFieldSet(tif, FIELD_PAGENUMBER))
fprintf(fd, " Page Number: %" PRIu16 "-%" PRIu16 "\n",
td->td_pagenumber[0], td->td_pagenumber[1]);
if (TIFFFieldSet(tif, FIELD_COLORMAP))
if (TIFFFieldSet(tif, FIELD_COLORMAP) && td->td_colormap[0] &&
td->td_colormap[1] && td->td_colormap[2])
{
fprintf(fd, " Color Map: ");
if (flags & TIFFPRINT_COLORMAP)
{
fprintf(fd, "\n");
n = 1L << td->td_bitspersample;
for (l = 0; l < n; l++)
fprintf(fd, " %5ld: %5" PRIu16 " %5" PRIu16 " %5" PRIu16 "\n",
l, td->td_colormap[0][l], td->td_colormap[1][l],
td->td_colormap[2][l]);
if (td->td_bitspersample >= 64)
fprintf(fd, " (BitsPerSample too large to print safely)\n");
else
{
uint64_t n = 1ULL << td->td_bitspersample;
for (uint64_t l = 0u; l < n; l++)
fprintf(fd,
" %5" PRIu64 ": %5" PRIu16 " %5" PRIu16
" %5" PRIu16 "\n",
l, td->td_colormap[0][l], td->td_colormap[1][l],
td->td_colormap[2][l]);
}
}
else
fprintf(fd, "(present)\n");
@@ -569,26 +583,37 @@ void TIFFPrintDirectory(TIFF *tif, FILE *fd, long flags)
fprintf(fd, " Reference Black/White:\n");
for (i = 0; i < 3; i++)
fprintf(fd, " %2d: %5g %5g\n", i,
td->td_refblackwhite[2 * i + 0],
td->td_refblackwhite[2 * i + 1]);
(double)td->td_refblackwhite[2 * i + 0],
(double)td->td_refblackwhite[2 * i + 1]);
}
if (TIFFFieldSet(tif, FIELD_TRANSFERFUNCTION))
if (TIFFFieldSet(tif, FIELD_TRANSFERFUNCTION) &&
td->td_transferfunction[0] &&
((td->td_samplesperpixel - td->td_extrasamples > 1 &&
td->td_transferfunction[1] && td->td_transferfunction[2]) ||
td->td_samplesperpixel - td->td_extrasamples <= 1))
{
fprintf(fd, " Transfer Function: ");
if (flags & TIFFPRINT_CURVES)
{
fprintf(fd, "\n");
n = 1L << td->td_bitspersample;
for (l = 0; l < n; l++)
if (td->td_bitspersample >= 64)
fprintf(fd, " (BitsPerSample too large to print safely)\n");
else
{
uint16_t i;
fprintf(fd, " %2ld: %5" PRIu16, l,
td->td_transferfunction[0][l]);
for (i = 1;
i < td->td_samplesperpixel - td->td_extrasamples && i < 3;
i++)
fprintf(fd, " %5" PRIu16, td->td_transferfunction[i][l]);
fputc('\n', fd);
uint64_t n = 1ULL << td->td_bitspersample;
for (uint64_t l = 0; l < n; l++)
{
uint16_t i;
fprintf(fd, " %2" PRIu64 ": %5" PRIu16, l,
td->td_transferfunction[0][l]);
for (i = 1;
i < td->td_samplesperpixel - td->td_extrasamples &&
i < 3;
i++)
fprintf(fd, " %5" PRIu16,
td->td_transferfunction[i][l]);
fputc('\n', fd);
}
}
}
else
@@ -655,7 +680,7 @@ void TIFFPrintDirectory(TIFF *tif, FILE *fd, long flags)
else if (fip->field_readcount == TIFF_SPP)
value_count = td->td_samplesperpixel;
else
value_count = fip->field_readcount;
value_count = (uint32_t)fip->field_readcount;
if (fip->field_tag == TIFFTAG_DOTRANGE &&
strcmp(fip->field_name, "DotRange") == 0)
{
@@ -680,7 +705,8 @@ void TIFFPrintDirectory(TIFF *tif, FILE *fd, long flags)
* "set_get_field_type" to determine internal storage size.
*/
int tv_size = TIFFFieldSetGetSize(fip);
raw_data = _TIFFmallocExt(tif, tv_size * value_count);
raw_data = _TIFFCheckMalloc(tif, value_count, tv_size,
"for tag data");
mem_alloc = 1;
if (TIFFGetField(tif, tag, raw_data) != 1)
{
@@ -744,7 +770,7 @@ static void _TIFFprintAsciiBounded(FILE *fd, const char *cp, size_t max_chars)
if (*tp)
fprintf(fd, "\\%c", *tp);
else
fprintf(fd, "\\%03o", *cp & 0xff);
fprintf(fd, "\\%03o", (unsigned int)(*cp & 0xff));
}
}

View File

@@ -27,6 +27,7 @@
* Scanline-oriented Read Support
*/
#include "tiffiop.h"
#include <limits.h>
#include <stdio.h>
int TIFFFillStrip(TIFF *tif, uint32_t strip);
@@ -39,9 +40,6 @@ static tmsize_t TIFFReadRawStrip1(TIFF *tif, uint32_t strip, void *buf,
static tmsize_t TIFFReadRawTile1(TIFF *tif, uint32_t tile, void *buf,
tmsize_t size, const char *module);
#define NOSTRIP ((uint32_t)(-1)) /* undefined state */
#define NOTILE ((uint32_t)(-1)) /* undefined state */
#define INITIAL_THRESHOLD (1024 * 1024)
#define THRESHOLD_MULTIPLIER 10
#define MAX_THRESHOLD \
@@ -99,7 +97,9 @@ static int TIFFReadAndRealloc(TIFF *tif, tmsize_t size, tmsize_t rawdata_offset,
uint8_t *new_rawdata;
assert((tif->tif_flags & TIFF_MYBUFFER) != 0);
tif->tif_rawdatasize = (tmsize_t)TIFFroundup_64(
(uint64_t)already_read + to_read + rawdata_offset, 1024);
(uint64_t)already_read + (uint64_t)to_read +
(uint64_t)rawdata_offset,
1024);
if (tif->tif_rawdatasize == 0)
{
TIFFErrorExtR(tif, module, "Invalid buffer size");
@@ -111,7 +111,7 @@ static int TIFFReadAndRealloc(TIFF *tif, tmsize_t size, tmsize_t rawdata_offset,
{
TIFFErrorExtR(tif, module,
"No space for data buffer at scanline %" PRIu32,
tif->tif_row);
tif->tif_dir.td_row);
_TIFFfreeExt(tif, tif->tif_rawdata);
tif->tif_rawdata = 0;
tif->tif_rawdatasize = 0;
@@ -127,18 +127,22 @@ static int TIFFReadAndRealloc(TIFF *tif, tmsize_t size, tmsize_t rawdata_offset,
bytes_read = TIFFReadFile(
tif, tif->tif_rawdata + rawdata_offset + already_read, to_read);
if (bytes_read < 0)
/* Treat read errors as short reads before updating offsets. */
bytes_read = 0;
already_read += bytes_read;
if (bytes_read != to_read)
{
memset(tif->tif_rawdata + rawdata_offset + already_read, 0,
tif->tif_rawdatasize - rawdata_offset - already_read);
memset(
tif->tif_rawdata + rawdata_offset + already_read, 0,
(size_t)(tif->tif_rawdatasize - rawdata_offset - already_read));
if (is_strip)
{
TIFFErrorExtR(tif, module,
"Read error at scanline %" PRIu32
"; got %" TIFF_SSIZE_FORMAT " bytes, "
"expected %" TIFF_SSIZE_FORMAT,
tif->tif_row, already_read, size);
tif->tif_dir.td_row, already_read, size);
}
else
{
@@ -147,8 +151,8 @@ static int TIFFReadAndRealloc(TIFF *tif, tmsize_t size, tmsize_t rawdata_offset,
", tile %" PRIu32 "; "
"got %" TIFF_SSIZE_FORMAT
" bytes, expected %" TIFF_SSIZE_FORMAT "",
tif->tif_row, tif->tif_col, strip_or_tile,
already_read, size);
tif->tif_dir.td_row, tif->tif_dir.td_col,
strip_or_tile, already_read, size);
}
return 0;
}
@@ -160,7 +164,7 @@ static int TIFFFillStripPartial(TIFF *tif, int strip, tmsize_t read_ahead,
int restart)
{
static const char module[] = "TIFFFillStripPartial";
register TIFFDirectory *td = &tif->tif_dir;
TIFFDirectory *td = &tif->tif_dir;
tmsize_t unused_data;
uint64_t read_offset;
tmsize_t to_read;
@@ -185,7 +189,7 @@ static int TIFFFillStripPartial(TIFF *tif, int strip, tmsize_t read_ahead,
{
assert(restart);
tif->tif_curstrip = NOSTRIP;
tif->tif_dir.td_curstrip = NOSTRIP;
if ((tif->tif_flags & TIFF_MYBUFFER) == 0)
{
TIFFErrorExtR(tif, module,
@@ -214,20 +218,30 @@ static int TIFFFillStripPartial(TIFF *tif, int strip, tmsize_t read_ahead,
if (unused_data > 0)
{
assert((tif->tif_flags & TIFF_BUFFERMMAP) == 0);
memmove(tif->tif_rawdata, tif->tif_rawcp, unused_data);
memmove(tif->tif_rawdata, tif->tif_rawcp, (size_t)unused_data);
}
/*
** Seek to the point in the file where more data should be read.
*/
read_offset = TIFFGetStrileOffset(tif, strip) + tif->tif_rawdataoff +
tif->tif_rawdataloaded;
read_offset = TIFFGetStrileOffset(tif, (uint32_t)strip);
if (read_offset > UINT64_MAX - (uint64_t)tif->tif_rawdataoff ||
read_offset + (uint64_t)tif->tif_rawdataoff >
UINT64_MAX - (uint64_t)tif->tif_rawdataloaded)
{
TIFFErrorExtR(tif, module,
"Seek error at scanline %" PRIu32 ", strip %d",
tif->tif_dir.td_row, strip);
return 0;
}
read_offset +=
(uint64_t)tif->tif_rawdataoff + (uint64_t)tif->tif_rawdataloaded;
if (!SeekOK(tif, read_offset))
{
TIFFErrorExtR(tif, module,
"Seek error at scanline %" PRIu32 ", strip %d",
tif->tif_row, strip);
tif->tif_dir.td_row, strip);
return 0;
}
@@ -238,11 +252,13 @@ static int TIFFFillStripPartial(TIFF *tif, int strip, tmsize_t read_ahead,
to_read = read_ahead_mod - unused_data;
else
to_read = tif->tif_rawdatasize - unused_data;
if ((uint64_t)to_read > TIFFGetStrileByteCount(tif, strip) -
tif->tif_rawdataoff - tif->tif_rawdataloaded)
if ((uint64_t)to_read > TIFFGetStrileByteCount(tif, (uint32_t)strip) -
(uint64_t)tif->tif_rawdataoff -
(uint64_t)tif->tif_rawdataloaded)
{
to_read = (tmsize_t)TIFFGetStrileByteCount(tif, strip) -
tif->tif_rawdataoff - tif->tif_rawdataloaded;
to_read = (tmsize_t)(TIFFGetStrileByteCount(tif, (uint32_t)strip) -
(uint64_t)tif->tif_rawdataoff -
(uint64_t)tif->tif_rawdataloaded);
}
assert((tif->tif_flags & TIFF_BUFFERMMAP) == 0);
@@ -281,16 +297,17 @@ static int TIFFFillStripPartial(TIFF *tif, int strip, tmsize_t read_ahead,
/* For JPEG, if there are multiple scans (can generally be known */
/* with the read_ahead used), we need to read the whole strip */
if (tif->tif_dir.td_compression == COMPRESSION_JPEG &&
(uint64_t)tif->tif_rawcc < TIFFGetStrileByteCount(tif, strip))
(uint64_t)tif->tif_rawcc <
TIFFGetStrileByteCount(tif, (uint32_t)strip))
{
if (TIFFJPEGIsFullStripRequired(tif))
{
return TIFFFillStrip(tif, strip);
return TIFFFillStrip(tif, (uint32_t)strip);
}
}
#endif
return TIFFStartStrip(tif, strip);
return TIFFStartStrip(tif, (uint32_t)strip);
}
else
{
@@ -308,7 +325,7 @@ static int TIFFFillStripPartial(TIFF *tif, int strip, tmsize_t read_ahead,
*/
static int TIFFSeek(TIFF *tif, uint32_t row, uint16_t sample)
{
register TIFFDirectory *td = &tif->tif_dir;
TIFFDirectory *td = &tif->tif_dir;
uint32_t strip;
int whole_strip;
tmsize_t read_ahead = 0;
@@ -323,8 +340,16 @@ static int TIFFSeek(TIFF *tif, uint32_t row, uint16_t sample)
td->td_imagelength);
return (0);
}
if (td->td_rowsperstrip == 0)
{
TIFFErrorExtR(tif, tif->tif_name,
"Cannot compute strip: RowsPerStrip is zero");
return (0);
}
if (td->td_planarconfig == PLANARCONFIG_SEPARATE)
{
uint64_t sample_offset;
uint64_t strip64;
if (sample >= td->td_samplesperpixel)
{
TIFFErrorExtR(tif, tif->tif_name,
@@ -332,16 +357,26 @@ static int TIFFSeek(TIFF *tif, uint32_t row, uint16_t sample)
sample, td->td_samplesperpixel);
return (0);
}
strip = (uint32_t)sample * td->td_stripsperimage +
row / td->td_rowsperstrip;
sample_offset =
_TIFFMultiply64(tif, sample, td->td_stripsperimage, "TIFFSeek");
if (sample_offset == 0 && sample != 0 && td->td_stripsperimage != 0)
return (0);
strip64 = _TIFFAdd64(tif, sample_offset, row / td->td_rowsperstrip,
"TIFFSeek");
if (strip64 == 0 &&
(sample_offset != 0 || (row / td->td_rowsperstrip) != 0))
return (0);
strip = _TIFFCastUInt64ToUInt32(tif, strip64, "TIFFSeek");
if (strip == 0 && strip64 != 0)
return (0);
}
else
strip = row / td->td_rowsperstrip;
/*
* Do we want to treat this strip as one whole chunk or
* read it a few lines at a time?
*/
/*
* Do we want to treat this strip as one whole chunk or
* read it a few lines at a time?
*/
#if defined(CHUNKY_STRIP_READ_SUPPORT)
whole_strip = TIFFGetStrileByteCount(tif, strip) < 10 || isMapped(tif);
if (td->td_compression == COMPRESSION_LERC ||
@@ -359,14 +394,14 @@ static int TIFFSeek(TIFF *tif, uint32_t row, uint16_t sample)
/* is some constant value, for example for JPEG tables */
/* coverity[dead_error_line:SUPPRESS] */
if (tif->tif_scanlinesize < TIFF_TMSIZE_T_MAX / 16 &&
tif->tif_scanlinesize * 16 < TIFF_TMSIZE_T_MAX - 5000)
if (tif->tif_dir.td_scanlinesize < TIFF_TMSIZE_T_MAX / 16 &&
tif->tif_dir.td_scanlinesize * 16 < TIFF_TMSIZE_T_MAX - 5000)
{
read_ahead = tif->tif_scanlinesize * 16 + 5000;
read_ahead = tif->tif_dir.td_scanlinesize * 16 + 5000;
}
else
{
read_ahead = tif->tif_scanlinesize;
read_ahead = tif->tif_dir.td_scanlinesize;
}
}
#else
@@ -377,7 +412,7 @@ static int TIFFSeek(TIFF *tif, uint32_t row, uint16_t sample)
* If we haven't loaded this strip, do so now, possibly
* only reading the first part.
*/
if (strip != tif->tif_curstrip)
if (strip != tif->tif_dir.td_curstrip)
{ /* different strip, refill */
if (whole_strip)
@@ -412,7 +447,7 @@ static int TIFFSeek(TIFF *tif, uint32_t row, uint16_t sample)
}
#endif
if (row < tif->tif_row)
if (row < tif->tif_dir.td_row)
{
/*
* Moving backwards within the same strip: backup
@@ -425,7 +460,7 @@ static int TIFFSeek(TIFF *tif, uint32_t row, uint16_t sample)
if (tif->tif_rawdataoff != 0)
{
if (!TIFFFillStripPartial(tif, strip, read_ahead, 1))
if (!TIFFFillStripPartial(tif, (int)strip, read_ahead, 1))
return 0;
}
else
@@ -435,7 +470,7 @@ static int TIFFSeek(TIFF *tif, uint32_t row, uint16_t sample)
}
}
if (row != tif->tif_row)
if (row != tif->tif_dir.td_row)
{
/*
* Seek forward to the desired row.
@@ -443,9 +478,9 @@ static int TIFFSeek(TIFF *tif, uint32_t row, uint16_t sample)
/* TODO: Will this really work with partial buffers? */
if (!(*tif->tif_seek)(tif, row - tif->tif_row))
if (!(*tif->tif_seek)(tif, row - tif->tif_dir.td_row))
return (0);
tif->tif_row = row;
tif->tif_dir.td_row = row;
}
return (1);
@@ -462,20 +497,21 @@ int TIFFReadScanline(TIFF *tif, void *buf, uint32_t row, uint16_t sample)
/*
* Decompress desired row into user buffer.
*/
e = (*tif->tif_decoderow)(tif, (uint8_t *)buf, tif->tif_scanlinesize,
sample);
e = (*tif->tif_decoderow)(tif, (uint8_t *)buf,
tif->tif_dir.td_scanlinesize, sample);
/* we are now poised at the beginning of the next row */
tif->tif_row = row + 1;
tif->tif_dir.td_row = row + 1;
if (e)
(*tif->tif_postdecode)(tif, (uint8_t *)buf, tif->tif_scanlinesize);
(*tif->tif_postdecode)(tif, (uint8_t *)buf,
tif->tif_dir.td_scanlinesize);
}
else
{
/* See TIFFReadEncodedStrip comment regarding TIFFTAG_FAXFILLFUNC. */
if (buf)
memset(buf, 0, (size_t)tif->tif_scanlinesize);
memset(buf, 0, (size_t)tif->tif_dir.td_scanlinesize);
}
return (e > 0 ? 1 : -1);
}
@@ -553,9 +589,9 @@ tmsize_t TIFFReadEncodedStrip(TIFF *tif, uint32_t strip, void *buf,
if (!isFillOrder(tif, td->td_fillorder) &&
(tif->tif_flags & TIFF_NOBITREV) == 0)
TIFFReverseBits(buf, stripsize);
TIFFReverseBits((uint8_t *)buf, stripsize);
(*tif->tif_postdecode)(tif, buf, stripsize);
(*tif->tif_postdecode)(tif, (uint8_t *)buf, stripsize);
return (stripsize);
}
@@ -569,9 +605,9 @@ tmsize_t TIFFReadEncodedStrip(TIFF *tif, uint32_t strip, void *buf,
memset(buf, 0, (size_t)stripsize);
return ((tmsize_t)(-1));
}
if ((*tif->tif_decodestrip)(tif, buf, stripsize, plane) <= 0)
if ((*tif->tif_decodestrip)(tif, (uint8_t *)buf, stripsize, plane) <= 0)
return ((tmsize_t)(-1));
(*tif->tif_postdecode)(tif, buf, stripsize);
(*tif->tif_postdecode)(tif, (uint8_t *)buf, stripsize);
return (stripsize);
}
@@ -603,17 +639,39 @@ tmsize_t _TIFFReadEncodedStripAndAllocBuffer(TIFF *tif, uint32_t strip,
if (!TIFFFillStrip(tif, strip))
return ((tmsize_t)(-1));
*buf = _TIFFmallocExt(tif, bufsizetoalloc);
/* Sanity checks to avoid excessive memory allocation */
/* Max compression ratio experimentally determined. Might be fragile...
* Only apply this heuristics to situations where the memory allocation
* would be big, to avoid breaking nominal use cases.
*/
if (bufsizetoalloc > 100 * 1024 * 1024)
{
const uint64_t maxCompressionRatio = TIFFGetMaxCompressionRatio(tif);
if (maxCompressionRatio > 0 &&
(uint64_t)tif->tif_rawdatasize <
(uint64_t)this_stripsize / maxCompressionRatio)
{
TIFFErrorExtR(tif, TIFFFileName(tif),
"Likely invalid strip byte count for strip %u. "
"Uncompressed strip size is %" PRIu64 ", "
"compressed one is %" PRIu64,
strip, (uint64_t)this_stripsize,
(uint64_t)tif->tif_rawdatasize);
return ((tmsize_t)(-1));
}
}
*buf = _TIFFcallocExt(tif, 1, bufsizetoalloc);
if (*buf == NULL)
{
TIFFErrorExtR(tif, TIFFFileName(tif), "No space for strip buffer");
return ((tmsize_t)(-1));
}
_TIFFmemset(*buf, 0, bufsizetoalloc);
if ((*tif->tif_decodestrip)(tif, *buf, this_stripsize, plane) <= 0)
if ((*tif->tif_decodestrip)(tif, (uint8_t *)*buf, this_stripsize, plane) <=
0)
return ((tmsize_t)(-1));
(*tif->tif_postdecode)(tif, *buf, this_stripsize);
(*tif->tif_postdecode)(tif, (uint8_t *)*buf, this_stripsize);
return (this_stripsize);
}
@@ -629,7 +687,7 @@ static tmsize_t TIFFReadRawStrip1(TIFF *tif, uint32_t strip, void *buf,
{
TIFFErrorExtR(tif, module,
"Seek error at scanline %" PRIu32 ", strip %" PRIu32,
tif->tif_row, strip);
tif->tif_dir.td_row, strip);
return ((tmsize_t)(-1));
}
cc = TIFFReadFile(tif, buf, size);
@@ -639,7 +697,7 @@ static tmsize_t TIFFReadRawStrip1(TIFF *tif, uint32_t strip, void *buf,
"Read error at scanline %" PRIu32
"; got %" TIFF_SSIZE_FORMAT
" bytes, expected %" TIFF_SSIZE_FORMAT,
tif->tif_row, cc, size);
tif->tif_dir.td_row, cc, size);
return ((tmsize_t)(-1));
}
}
@@ -670,7 +728,7 @@ static tmsize_t TIFFReadRawStrip1(TIFF *tif, uint32_t strip, void *buf,
"Read error at scanline %" PRIu32 ", strip %" PRIu32
"; got %" TIFF_SSIZE_FORMAT
" bytes, expected %" TIFF_SSIZE_FORMAT,
tif->tif_row, strip, n, size);
tif->tif_dir.td_row, strip, n, size);
return ((tmsize_t)(-1));
}
_TIFFmemcpy(buf, tif->tif_base + ma, size);
@@ -691,14 +749,14 @@ static tmsize_t TIFFReadRawStripOrTile2(TIFF *tif, uint32_t strip_or_tile,
{
TIFFErrorExtR(tif, module,
"Seek error at scanline %" PRIu32 ", strip %" PRIu32,
tif->tif_row, strip_or_tile);
tif->tif_dir.td_row, strip_or_tile);
}
else
{
TIFFErrorExtR(tif, module,
"Seek error at row %" PRIu32 ", col %" PRIu32
", tile %" PRIu32,
tif->tif_row, tif->tif_col, strip_or_tile);
TIFFErrorExtR(
tif, module,
"Seek error at row %" PRIu32 ", col %" PRIu32 ", tile %" PRIu32,
tif->tif_dir.td_row, tif->tif_dir.td_col, strip_or_tile);
}
return ((tmsize_t)(-1));
}
@@ -774,22 +832,50 @@ int TIFFFillStrip(TIFF *tif, uint32_t strip)
}
/* To avoid excessive memory allocations: */
/* Byte count should normally not be larger than a number of */
/* times the uncompressed size plus some margin */
if (bytecount > 1024 * 1024)
const tmsize_t stripsize = TIFFStripSize(tif);
if (stripsize > 0)
{
/* 10 and 4096 are just values that could be adjusted. */
/* Hopefully they are safe enough for all codecs */
tmsize_t stripsize = TIFFStripSize(tif);
if (stripsize != 0 && (bytecount - 4096) / 10 > (uint64_t)stripsize)
if (bytecount > 1024 * 1024 &&
(bytecount - 4096) / 10 > (uint64_t)stripsize)
{
/* Byte count should normally not be larger than a number of */
/* times the uncompressed size plus some margin */
/* 10 and 4096 are just values that could be adjusted. */
/* Hopefully they are safe enough for all codecs */
/* What happens next will depend on whether only the bytecount
*/
/* was corrupted to a large value but the strip/tile data is */
/* fine. In that situation most codecs should work fine and */
/* only used part of the tile/strip data. If the strip/tile */
/* data is corrupted too, then codecs will later error out. */
uint64_t newbytecount = (uint64_t)stripsize * 10 + 4096;
TIFFErrorExtR(tif, module,
"Too large strip byte count %" PRIu64
", strip %" PRIu32 ". Limiting to %" PRIu64,
bytecount, strip, newbytecount);
TIFFWarningExtR(tif, module,
"Too large strip byte count %" PRIu64
", strip %" PRIu32 ". Limiting to %" PRIu64,
bytecount, strip, newbytecount);
bytecount = newbytecount;
}
else if (stripsize > 100 * 1024 * 1024)
{
/* Max compression ratio experimentally determined. Might be
* fragile... Only apply this heuristics to situations where the
* memory allocation would be big, to avoid breaking nominal use
* cases.
*/
const uint64_t maxCompressionRatio =
TIFFGetMaxCompressionRatio(tif);
if (maxCompressionRatio > 0 &&
bytecount < (uint64_t)stripsize / maxCompressionRatio)
{
TIFFErrorExtR(
tif, module,
"Likely invalid strip byte count for strip %u. "
"Uncompressed strip size is %" PRIu64 ", "
"compressed one is %" PRIu64,
strip, (uint64_t)stripsize, bytecount);
return 0;
}
}
}
if (isMapped(tif))
@@ -818,10 +904,10 @@ int TIFFFillStrip(TIFF *tif, uint32_t strip)
"Read error on strip %" PRIu32 "; "
"got %" PRIu64 " bytes, expected %" PRIu64,
strip,
NoSanitizeSubUInt64(tif->tif_size,
NoSanitizeSubUInt64((uint64_t)tif->tif_size,
TIFFGetStrileOffset(tif, strip)),
bytecount);
tif->tif_curstrip = NOSTRIP;
tif->tif_dir.td_curstrip = NOSTRIP;
return (0);
}
}
@@ -878,7 +964,7 @@ int TIFFFillStrip(TIFF *tif, uint32_t strip)
}
if (bytecountm > tif->tif_rawdatasize)
{
tif->tif_curstrip = NOSTRIP;
tif->tif_dir.td_curstrip = NOSTRIP;
if ((tif->tif_flags & TIFF_MYBUFFER) == 0)
{
TIFFErrorExtR(
@@ -889,7 +975,7 @@ int TIFFFillStrip(TIFF *tif, uint32_t strip)
}
if (tif->tif_flags & TIFF_BUFFERMMAP)
{
tif->tif_curstrip = NOSTRIP;
tif->tif_dir.td_curstrip = NOSTRIP;
tif->tif_rawdata = NULL;
tif->tif_rawdatasize = 0;
tif->tif_flags &= ~TIFF_BUFFERMMAP;
@@ -954,7 +1040,7 @@ tmsize_t TIFFReadEncodedTile(TIFF *tif, uint32_t tile, void *buf, tmsize_t size)
{
static const char module[] = "TIFFReadEncodedTile";
TIFFDirectory *td = &tif->tif_dir;
tmsize_t tilesize = tif->tif_tilesize;
tmsize_t tilesize = tif->tif_dir.td_tilesize;
if (!TIFFCheckRead(tif, 1))
return ((tmsize_t)(-1));
@@ -976,9 +1062,9 @@ tmsize_t TIFFReadEncodedTile(TIFF *tif, uint32_t tile, void *buf, tmsize_t size)
if (!isFillOrder(tif, td->td_fillorder) &&
(tif->tif_flags & TIFF_NOBITREV) == 0)
TIFFReverseBits(buf, tilesize);
TIFFReverseBits((uint8_t *)buf, tilesize);
(*tif->tif_postdecode)(tif, buf, tilesize);
(*tif->tif_postdecode)(tif, (uint8_t *)buf, tilesize);
return (tilesize);
}
@@ -1032,7 +1118,7 @@ tmsize_t _TIFFReadEncodedTileAndAllocBuffer(TIFF *tif, uint32_t tile,
{
static const char module[] = "_TIFFReadEncodedTileAndAllocBuffer";
TIFFDirectory *td = &tif->tif_dir;
tmsize_t tilesize = tif->tif_tilesize;
tmsize_t tilesize = tif->tif_dir.td_tilesize;
if (*buf != NULL)
{
@@ -1072,25 +1158,22 @@ tmsize_t _TIFFReadEncodedTileAndAllocBuffer(TIFF *tif, uint32_t tile,
* Only apply this heuristics to situations where the memory allocation
* would be big, to avoid breaking nominal use cases.
*/
const int maxCompressionRatio =
td->td_compression == COMPRESSION_ZSTD ? 33000
: td->td_compression == COMPRESSION_JXL
?
/* Evaluated on a 8000x8000 tile */
25000 * (td->td_planarconfig == PLANARCONFIG_CONTIG
? td->td_samplesperpixel
: 1)
: td->td_compression == COMPRESSION_LZMA ? 7000 : 1000;
if (bufsizetoalloc > 100 * 1000 * 1000 &&
tif->tif_rawdatasize < tilesize / maxCompressionRatio)
if (bufsizetoalloc > 100 * 1024 * 1024)
{
TIFFErrorExtR(tif, TIFFFileName(tif),
"Likely invalid tile byte count for tile %u. "
"Uncompressed tile size is %" PRIu64 ", "
"compressed one is %" PRIu64,
tile, (uint64_t)tilesize,
(uint64_t)tif->tif_rawdatasize);
return ((tmsize_t)(-1));
const uint64_t maxCompressionRatio =
TIFFGetMaxCompressionRatio(tif);
if (maxCompressionRatio > 0 &&
(uint64_t)tif->tif_rawdatasize <
(uint64_t)tilesize / maxCompressionRatio)
{
TIFFErrorExtR(tif, TIFFFileName(tif),
"Likely invalid tile byte count for tile %u. "
"Uncompressed tile size is %" PRIu64 ", "
"compressed one is %" PRIu64,
tile, (uint64_t)tilesize,
(uint64_t)tif->tif_rawdatasize);
return ((tmsize_t)(-1));
}
}
}
@@ -1129,7 +1212,7 @@ static tmsize_t TIFFReadRawTile1(TIFF *tif, uint32_t tile, void *buf,
TIFFErrorExtR(tif, module,
"Seek error at row %" PRIu32 ", col %" PRIu32
", tile %" PRIu32,
tif->tif_row, tif->tif_col, tile);
tif->tif_dir.td_row, tif->tif_dir.td_col, tile);
return ((tmsize_t)(-1));
}
cc = TIFFReadFile(tif, buf, size);
@@ -1139,7 +1222,7 @@ static tmsize_t TIFFReadRawTile1(TIFF *tif, uint32_t tile, void *buf,
"Read error at row %" PRIu32 ", col %" PRIu32
"; got %" TIFF_SSIZE_FORMAT
" bytes, expected %" TIFF_SSIZE_FORMAT,
tif->tif_row, tif->tif_col, cc, size);
tif->tif_dir.td_row, tif->tif_dir.td_col, cc, size);
return ((tmsize_t)(-1));
}
}
@@ -1162,7 +1245,8 @@ static tmsize_t TIFFReadRawTile1(TIFF *tif, uint32_t tile, void *buf,
"Read error at row %" PRIu32 ", col %" PRIu32
", tile %" PRIu32 "; got %" TIFF_SSIZE_FORMAT
" bytes, expected %" TIFF_SSIZE_FORMAT,
tif->tif_row, tif->tif_col, tile, n, size);
tif->tif_dir.td_row, tif->tif_dir.td_col, tile, n,
size);
return ((tmsize_t)(-1));
}
_TIFFmemcpy(buf, tif->tif_base + ma, size);
@@ -1229,22 +1313,49 @@ int TIFFFillTile(TIFF *tif, uint32_t tile)
}
/* To avoid excessive memory allocations: */
/* Byte count should normally not be larger than a number of */
/* times the uncompressed size plus some margin */
if (bytecount > 1024 * 1024)
const tmsize_t tilesize = TIFFTileSize(tif);
if (tilesize > 0)
{
/* 10 and 4096 are just values that could be adjusted. */
/* Hopefully they are safe enough for all codecs */
tmsize_t stripsize = TIFFTileSize(tif);
if (stripsize != 0 && (bytecount - 4096) / 10 > (uint64_t)stripsize)
if (bytecount > 1024 * 1024 &&
(bytecount - 4096) / 10 > (uint64_t)tilesize)
{
uint64_t newbytecount = (uint64_t)stripsize * 10 + 4096;
TIFFErrorExtR(tif, module,
"Too large tile byte count %" PRIu64
", tile %" PRIu32 ". Limiting to %" PRIu64,
bytecount, tile, newbytecount);
/* Byte count should normally not be larger than a number of */
/* times the uncompressed size plus some margin */
/* 10 and 4096 are just values that could be adjusted. */
/* Hopefully they are safe enough for all codecs */
/* What happens next will depend on whether only the bytecount
*/
/* was corrupted to a large value but the strip/tile data is */
/* fine. In that situation most codecs should work fine and */
/* only used part of the tile/strip data. If the strip/tile */
/* data is corrupted too, then codecs will later error out. */
uint64_t newbytecount = (uint64_t)tilesize * 10 + 4096;
TIFFWarningExtR(tif, module,
"Too large tile byte count %" PRIu64
", tile %" PRIu32 ". Limiting to %" PRIu64,
bytecount, tile, newbytecount);
bytecount = newbytecount;
}
else if (tilesize > 100 * 1024 * 1024)
{
/* Max compression ratio experimentally determined. Might be
* fragile... Only apply this heuristics to situations where the
* memory allocation would be big, to avoid breaking nominal use
* cases.
*/
const uint64_t maxCompressionRatio =
TIFFGetMaxCompressionRatio(tif);
if (maxCompressionRatio > 0 &&
bytecount < (uint64_t)tilesize / maxCompressionRatio)
{
TIFFErrorExtR(tif, module,
"Likely invalid tile byte count for tile %u. "
"Uncompressed tile size is %" PRIu64 ", "
"compressed one is %" PRIu64,
tile, (uint64_t)tilesize, bytecount);
return 0;
}
}
}
if (isMapped(tif))
@@ -1262,7 +1373,7 @@ int TIFFFillTile(TIFF *tif, uint32_t tile)
TIFFGetStrileOffset(tif, tile) >
(uint64_t)tif->tif_size - bytecount)
{
tif->tif_curtile = NOTILE;
tif->tif_dir.td_curtile = NOTILE;
return (0);
}
}
@@ -1312,7 +1423,7 @@ int TIFFFillTile(TIFF *tif, uint32_t tile)
}
if (bytecountm > tif->tif_rawdatasize)
{
tif->tif_curtile = NOTILE;
tif->tif_dir.td_curtile = NOTILE;
if ((tif->tif_flags & TIFF_MYBUFFER) == 0)
{
TIFFErrorExtR(tif, module,
@@ -1323,7 +1434,7 @@ int TIFFFillTile(TIFF *tif, uint32_t tile)
}
if (tif->tif_flags & TIFF_BUFFERMMAP)
{
tif->tif_curtile = NOTILE;
tif->tif_dir.td_curtile = NOTILE;
tif->tif_rawdata = NULL;
tif->tif_rawdatasize = 0;
tif->tif_flags &= ~TIFF_BUFFERMMAP;
@@ -1410,7 +1521,7 @@ int TIFFReadBufferSetup(TIFF *tif, void *bp, tmsize_t size)
{
TIFFErrorExtR(tif, module,
"No space for data buffer at scanline %" PRIu32,
tif->tif_row);
tif->tif_dir.td_row);
tif->tif_rawdatasize = 0;
return (0);
}
@@ -1431,8 +1542,13 @@ static int TIFFStartStrip(TIFF *tif, uint32_t strip)
return (0);
tif->tif_flags |= TIFF_CODERSETUP;
}
tif->tif_curstrip = strip;
tif->tif_row = (strip % td->td_stripsperimage) * td->td_rowsperstrip;
if (td->td_stripsperimage == 0)
{
TIFFErrorExtR(tif, "TIFFStartStrip", "Zero strips per image");
return 0;
}
tif->tif_dir.td_curstrip = strip;
tif->tif_dir.td_row = (strip % td->td_stripsperimage) * td->td_rowsperstrip;
tif->tif_flags &= ~TIFF_BUF4WRITE;
if (tif->tif_flags & TIFF_NOREADRAW)
@@ -1456,7 +1572,7 @@ static int TIFFStartStrip(TIFF *tif, uint32_t strip)
*/
/* tif_curstrip, we'd call tif_decoderow() on a possibly invalid */
/* codec state. */
tif->tif_curstrip = NOSTRIP;
tif->tif_dir.td_curstrip = NOSTRIP;
return 0;
}
return 1;
@@ -1478,7 +1594,7 @@ static int TIFFStartTile(TIFF *tif, uint32_t tile)
return (0);
tif->tif_flags |= TIFF_CODERSETUP;
}
tif->tif_curtile = tile;
tif->tif_dir.td_curtile = tile;
if (td->td_tilewidth == 0)
{
TIFFErrorExtR(tif, module, "Zero tilewidth");
@@ -1490,14 +1606,14 @@ static int TIFFStartTile(TIFF *tif, uint32_t tile)
TIFFErrorExtR(tif, module, "Zero tiles");
return 0;
}
tif->tif_row = (tile % howmany32) * td->td_tilelength;
tif->tif_dir.td_row = (tile % howmany32) * td->td_tilelength;
howmany32 = TIFFhowmany_32(td->td_imagelength, td->td_tilelength);
if (howmany32 == 0)
{
TIFFErrorExtR(tif, module, "Zero tiles");
return 0;
}
tif->tif_col = (tile % howmany32) * td->td_tilewidth;
tif->tif_dir.td_col = (tile % howmany32) * td->td_tilewidth;
tif->tif_flags &= ~TIFF_BUF4WRITE;
if (tif->tif_flags & TIFF_NOREADRAW)
{
@@ -1568,14 +1684,14 @@ int TIFFReadFromUserBuffer(TIFF *tif, uint32_t strile, void *inbuf,
tif->tif_flags &= ~TIFF_MYBUFFER;
tif->tif_flags |= TIFF_BUFFERMMAP;
tif->tif_rawdatasize = insize;
tif->tif_rawdata = inbuf;
tif->tif_rawdata = (uint8_t *)inbuf;
tif->tif_rawdataoff = 0;
tif->tif_rawdataloaded = insize;
if (!isFillOrder(tif, td->td_fillorder) &&
(tif->tif_flags & TIFF_NOBITREV) == 0)
{
TIFFReverseBits(inbuf, insize);
TIFFReverseBits((uint8_t *)inbuf, insize);
}
if (TIFFIsTiled(tif))
@@ -1632,13 +1748,13 @@ int TIFFReadFromUserBuffer(TIFF *tif, uint32_t strile, void *inbuf,
if (!isFillOrder(tif, td->td_fillorder) &&
(tif->tif_flags & TIFF_NOBITREV) == 0)
{
TIFFReverseBits(inbuf, insize);
TIFFReverseBits((uint8_t *)inbuf, insize);
}
tif->tif_flags = (old_tif_flags & (TIFF_MYBUFFER | TIFF_BUFFERMMAP)) |
(tif->tif_flags & ~(TIFF_MYBUFFER | TIFF_BUFFERMMAP));
tif->tif_rawdatasize = old_rawdatasize;
tif->tif_rawdata = old_rawdata;
tif->tif_rawdata = (uint8_t *)old_rawdata;
tif->tif_rawdataoff = 0;
tif->tif_rawdataloaded = 0;

View File

@@ -47,6 +47,8 @@ uint32_t TIFFComputeStrip(TIFF *tif, uint32_t row, uint16_t sample)
strip = row / td->td_rowsperstrip;
if (td->td_planarconfig == PLANARCONFIG_SEPARATE)
{
uint64_t sample_offset;
uint64_t strip64;
if (sample >= td->td_samplesperpixel)
{
TIFFErrorExtR(tif, module, "%lu: Sample out of range, max %lu",
@@ -54,7 +56,16 @@ uint32_t TIFFComputeStrip(TIFF *tif, uint32_t row, uint16_t sample)
(unsigned long)td->td_samplesperpixel);
return (0);
}
strip += (uint32_t)sample * td->td_stripsperimage;
sample_offset = _TIFFMultiply64(tif, sample, td->td_stripsperimage,
"TIFFComputeStrip");
if (sample_offset == 0 && sample != 0 && td->td_stripsperimage != 0)
return (0);
strip64 = _TIFFAdd64(tif, sample_offset, strip, "TIFFComputeStrip");
if (strip64 == 0 && (sample_offset != 0 || strip != 0))
return (0);
strip = _TIFFCastUInt64ToUInt32(tif, strip64, "TIFFComputeStrip");
if (strip == 0 && strip64 != 0)
return (0);
}
return (strip);
}
@@ -83,14 +94,24 @@ uint32_t TIFFNumberOfStrips(TIFF *tif)
}
/*
* Compute the # bytes in a variable height, row-aligned strip.
* Compute the # bytes in a variable height, row-aligned strip if isStrip is
* TRUE, or in a tile if isStrip is FALSE
*/
uint64_t TIFFVStripSize64(TIFF *tif, uint32_t nrows)
uint64_t _TIFFStrileSize64(TIFF *tif, uint32_t nrows, int isStrip)
{
static const char module[] = "TIFFVStripSize64";
static const char module[] = "_TIFFStrileSize64";
TIFFDirectory *td = &tif->tif_dir;
if (nrows == (uint32_t)(-1))
nrows = td->td_imagelength;
if (isStrip)
{
if (nrows == (uint32_t)(-1))
nrows = td->td_imagelength;
}
else
{
if (td->td_tilelength == 0 || td->td_tilewidth == 0 ||
td->td_tiledepth == 0)
return (0);
}
if ((td->td_planarconfig == PLANARCONFIG_CONTIG) &&
(td->td_photometric == PHOTOMETRIC_YCBCR) && (!isUpSampled(tif)))
{
@@ -125,9 +146,10 @@ uint64_t TIFFVStripSize64(TIFF *tif, uint32_t nrows)
ycbcrsubsampling[0], ycbcrsubsampling[1]);
return 0;
}
samplingblock_samples = ycbcrsubsampling[0] * ycbcrsubsampling[1] + 2;
samplingblocks_hor =
TIFFhowmany_32(td->td_imagewidth, ycbcrsubsampling[0]);
samplingblock_samples =
(uint16_t)(ycbcrsubsampling[0] * ycbcrsubsampling[1] + 2);
const uint32_t width = isStrip ? td->td_imagewidth : td->td_tilewidth;
samplingblocks_hor = TIFFhowmany_32(width, ycbcrsubsampling[0]);
samplingblocks_ver = TIFFhowmany_32(nrows, ycbcrsubsampling[1]);
samplingrow_samples = _TIFFMultiply64(tif, samplingblocks_hor,
samplingblock_samples, module);
@@ -137,8 +159,20 @@ uint64_t TIFFVStripSize64(TIFF *tif, uint32_t nrows)
_TIFFMultiply64(tif, samplingrow_size, samplingblocks_ver, module));
}
else
return (_TIFFMultiply64(tif, nrows, TIFFScanlineSize64(tif), module));
return (_TIFFMultiply64(tif, nrows,
isStrip ? TIFFScanlineSize64(tif)
: TIFFTileRowSize64(tif),
module));
}
/*
* Compute the # bytes in a variable height, row-aligned strip.
*/
uint64_t TIFFVStripSize64(TIFF *tif, uint32_t nrows)
{
return _TIFFStrileSize64(tif, nrows, /* isStrip = */ TRUE);
}
tmsize_t TIFFVStripSize(TIFF *tif, uint32_t nrows)
{
static const char module[] = "TIFFVStripSize";
@@ -286,7 +320,7 @@ uint64_t TIFFScanlineSize64(TIFF *tif)
return 0;
}
samplingblock_samples =
ycbcrsubsampling[0] * ycbcrsubsampling[1] + 2;
(uint16_t)(ycbcrsubsampling[0] * ycbcrsubsampling[1] + 2);
samplingblocks_hor =
TIFFhowmany_32(td->td_imagewidth, ycbcrsubsampling[0]);
samplingrow_samples = _TIFFMultiply64(

View File

@@ -32,7 +32,7 @@
#if defined(DISABLE_CHECK_TIFFSWABMACROS) || !defined(TIFFSwabShort)
void TIFFSwabShort(uint16_t *wp)
{
register unsigned char *cp = (unsigned char *)wp;
unsigned char *cp = (unsigned char *)wp;
unsigned char t;
assert(sizeof(uint16_t) == 2);
t = cp[1];
@@ -44,7 +44,7 @@ void TIFFSwabShort(uint16_t *wp)
#if defined(DISABLE_CHECK_TIFFSWABMACROS) || !defined(TIFFSwabLong)
void TIFFSwabLong(uint32_t *lp)
{
register unsigned char *cp = (unsigned char *)lp;
unsigned char *cp = (unsigned char *)lp;
unsigned char t;
assert(sizeof(uint32_t) == 4);
t = cp[3];
@@ -59,7 +59,7 @@ void TIFFSwabLong(uint32_t *lp)
#if defined(DISABLE_CHECK_TIFFSWABMACROS) || !defined(TIFFSwabLong8)
void TIFFSwabLong8(uint64_t *lp)
{
register unsigned char *cp = (unsigned char *)lp;
unsigned char *cp = (unsigned char *)lp;
unsigned char t;
assert(sizeof(uint64_t) == 8);
t = cp[7];
@@ -78,10 +78,10 @@ void TIFFSwabLong8(uint64_t *lp)
#endif
#if defined(DISABLE_CHECK_TIFFSWABMACROS) || !defined(TIFFSwabArrayOfShort)
void TIFFSwabArrayOfShort(register uint16_t *wp, tmsize_t n)
void TIFFSwabArrayOfShort(uint16_t *wp, tmsize_t n)
{
register unsigned char *cp;
register unsigned char t;
unsigned char *cp;
unsigned char t;
assert(sizeof(uint16_t) == 2);
/* XXX unroll loop some */
while (n-- > 0)
@@ -96,7 +96,7 @@ void TIFFSwabArrayOfShort(register uint16_t *wp, tmsize_t n)
#endif
#if defined(DISABLE_CHECK_TIFFSWABMACROS) || !defined(TIFFSwabArrayOfTriples)
void TIFFSwabArrayOfTriples(register uint8_t *tp, tmsize_t n)
void TIFFSwabArrayOfTriples(uint8_t *tp, tmsize_t n)
{
unsigned char *cp;
unsigned char t;
@@ -114,10 +114,10 @@ void TIFFSwabArrayOfTriples(register uint8_t *tp, tmsize_t n)
#endif
#if defined(DISABLE_CHECK_TIFFSWABMACROS) || !defined(TIFFSwabArrayOfLong)
void TIFFSwabArrayOfLong(register uint32_t *lp, tmsize_t n)
void TIFFSwabArrayOfLong(uint32_t *lp, tmsize_t n)
{
register unsigned char *cp;
register unsigned char t;
unsigned char *cp;
unsigned char t;
assert(sizeof(uint32_t) == 4);
/* XXX unroll loop some */
while (n-- > 0)
@@ -135,10 +135,10 @@ void TIFFSwabArrayOfLong(register uint32_t *lp, tmsize_t n)
#endif
#if defined(DISABLE_CHECK_TIFFSWABMACROS) || !defined(TIFFSwabArrayOfLong8)
void TIFFSwabArrayOfLong8(register uint64_t *lp, tmsize_t n)
void TIFFSwabArrayOfLong8(uint64_t *lp, tmsize_t n)
{
register unsigned char *cp;
register unsigned char t;
unsigned char *cp;
unsigned char t;
assert(sizeof(uint64_t) == 8);
/* XXX unroll loop some */
while (n-- > 0)
@@ -164,7 +164,7 @@ void TIFFSwabArrayOfLong8(register uint64_t *lp, tmsize_t n)
#if defined(DISABLE_CHECK_TIFFSWABMACROS) || !defined(TIFFSwabFloat)
void TIFFSwabFloat(float *fp)
{
register unsigned char *cp = (unsigned char *)fp;
unsigned char *cp = (unsigned char *)fp;
unsigned char t;
assert(sizeof(float) == 4);
t = cp[3];
@@ -177,10 +177,10 @@ void TIFFSwabFloat(float *fp)
#endif
#if defined(DISABLE_CHECK_TIFFSWABMACROS) || !defined(TIFFSwabArrayOfFloat)
void TIFFSwabArrayOfFloat(register float *fp, tmsize_t n)
void TIFFSwabArrayOfFloat(float *fp, tmsize_t n)
{
register unsigned char *cp;
register unsigned char t;
unsigned char *cp;
unsigned char t;
assert(sizeof(float) == 4);
/* XXX unroll loop some */
while (n-- > 0)
@@ -200,7 +200,7 @@ void TIFFSwabArrayOfFloat(register float *fp, tmsize_t n)
#if defined(DISABLE_CHECK_TIFFSWABMACROS) || !defined(TIFFSwabDouble)
void TIFFSwabDouble(double *dp)
{
register unsigned char *cp = (unsigned char *)dp;
unsigned char *cp = (unsigned char *)dp;
unsigned char t;
assert(sizeof(double) == 8);
t = cp[7];
@@ -221,8 +221,8 @@ void TIFFSwabDouble(double *dp)
#if defined(DISABLE_CHECK_TIFFSWABMACROS) || !defined(TIFFSwabArrayOfDouble)
void TIFFSwabArrayOfDouble(double *dp, tmsize_t n)
{
register unsigned char *cp;
register unsigned char t;
unsigned char *cp;
unsigned char t;
assert(sizeof(double) == 8);
/* XXX unroll loop some */
while (n-- > 0)

View File

@@ -41,7 +41,7 @@
* or 3-bit delta values are used, with the deltas packed
* into a single byte.
*/
#define THUNDER_DATA 0x3f /* mask for 6-bit data */
// #define THUNDER_DATA 0x3f /* mask for 6-bit data */
#define THUNDER_CODE 0xc0 /* mask for 2-bit code word */
/* code values */
#define THUNDER_RUN 0x00 /* run of pixels w/ encoded count */
@@ -56,11 +56,11 @@ static const int threebitdeltas[8] = {0, 1, 2, 3, 0, -3, -2, -1};
#define SETPIXEL(op, v) \
{ \
lastpixel = (v)&0xf; \
lastpixel = (v) & 0xf; \
if (npixels < maxpixels) \
{ \
if (npixels++ & 1) \
*op++ |= lastpixel; \
*op++ |= (uint8_t)lastpixel; \
else \
op[0] = (uint8_t)(lastpixel << 4); \
} \
@@ -85,8 +85,8 @@ static int ThunderSetupDecode(TIFF *tif)
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 char *bp;
tmsize_t cc;
unsigned int lastpixel;
tmsize_t npixels;
uint8_t *op = op0;
@@ -112,7 +112,7 @@ static int ThunderDecode(TIFF *tif, uint8_t *op0, tmsize_t maxpixels)
break;
if (npixels & 1)
{
op[0] |= lastpixel;
op[0] |= (uint8_t)lastpixel;
lastpixel = *op++;
npixels++;
n--;
@@ -150,6 +150,8 @@ static int ThunderDecode(TIFF *tif, uint8_t *op0, tmsize_t maxpixels)
case THUNDER_RAW: /* raw data */
SETPIXEL(op, n);
break;
default:
break;
}
}
tif->tif_rawcp = (uint8_t *)bp;
@@ -161,7 +163,7 @@ static int ThunderDecode(TIFF *tif, uint8_t *op0, tmsize_t maxpixels)
TIFFErrorExtR(tif, module,
"%s data at scanline %lu (%" PRIu64 " != %" PRIu64 ")",
npixels < maxpixels ? "Not enough" : "Too much",
(unsigned long)tif->tif_row, (uint64_t)npixels,
(unsigned long)tif->tif_dir.td_row, (uint64_t)npixels,
(uint64_t)maxpixels);
return (0);
}
@@ -175,7 +177,7 @@ static int ThunderDecodeRow(TIFF *tif, uint8_t *buf, tmsize_t occ, uint16_t s)
uint8_t *row = buf;
(void)s;
if (occ % tif->tif_scanlinesize)
if (occ % tif->tif_dir.td_scanlinesize)
{
TIFFErrorExtR(tif, module, "Fractional scanlines cannot be read");
return (0);
@@ -184,8 +186,8 @@ static int ThunderDecodeRow(TIFF *tif, uint8_t *buf, tmsize_t occ, uint16_t s)
{
if (!ThunderDecode(tif, row, tif->tif_dir.td_imagewidth))
return (0);
occ -= tif->tif_scanlinesize;
row += tif->tif_scanlinesize;
occ -= tif->tif_dir.td_scanlinesize;
row += tif->tif_dir.td_scanlinesize;
}
return (1);
}

View File

@@ -54,12 +54,50 @@ uint32_t TIFFComputeTile(TIFF *tif, uint32_t x, uint32_t y, uint32_t z,
uint32_t xpt = TIFFhowmany_32(td->td_imagewidth, dx);
uint32_t ypt = TIFFhowmany_32(td->td_imagelength, dy);
uint32_t zpt = TIFFhowmany_32(td->td_imagedepth, dz);
uint32_t xpt_ypt = _TIFFMultiply32(tif, xpt, ypt, "TIFFComputeTile");
uint32_t xpt_ypt_zpt =
_TIFFMultiply32(tif, xpt_ypt, zpt, "TIFFComputeTile");
uint64_t z_offset;
uint64_t y_offset;
uint64_t tile64;
if ((xpt_ypt == 0 && xpt != 0 && ypt != 0) ||
(xpt_ypt_zpt == 0 && xpt_ypt != 0 && zpt != 0))
return (0);
z_offset = _TIFFMultiply64(tif, xpt_ypt, z / dz, "TIFFComputeTile");
y_offset = _TIFFMultiply64(tif, xpt, y / dy, "TIFFComputeTile");
if ((z_offset == 0 && xpt_ypt != 0 && (z / dz) != 0) ||
(y_offset == 0 && xpt != 0 && (y / dy) != 0))
return (0);
tile64 = _TIFFAdd64(tif, z_offset, y_offset, "TIFFComputeTile");
if (tile64 == 0 && (z_offset != 0 || y_offset != 0))
return (0);
tile64 = _TIFFAdd64(tif, tile64, x / dx, "TIFFComputeTile");
if (tile64 == 0 && (z_offset != 0 || y_offset != 0 || (x / dx) != 0))
return (0);
if (td->td_planarconfig == PLANARCONFIG_SEPARATE)
tile = (xpt * ypt * zpt) * s + (xpt * ypt) * (z / dz) +
xpt * (y / dy) + x / dx;
else
tile = (xpt * ypt) * (z / dz) + xpt * (y / dy) + x / dx;
{
uint64_t sample_offset;
if (s >= td->td_samplesperpixel)
{
TIFFErrorExtR(
tif, "TIFFComputeTile", "%lu: Sample out of range, max %lu",
(unsigned long)s, (unsigned long)td->td_samplesperpixel);
return (0);
}
sample_offset =
_TIFFMultiply64(tif, xpt_ypt_zpt, s, "TIFFComputeTile");
if (sample_offset == 0 && xpt_ypt_zpt != 0 && s != 0)
return (0);
tile64 = _TIFFAdd64(tif, sample_offset, tile64, "TIFFComputeTile");
if (tile64 == 0 && (sample_offset != 0 || z_offset != 0 ||
y_offset != 0 || (x / dx) != 0))
return (0);
}
tile = _TIFFCastUInt64ToUInt32(tif, tile64, "TIFFComputeTile");
if (tile == 0 && tile64 != 0)
return (0);
}
return (tile);
}
@@ -187,54 +225,9 @@ tmsize_t TIFFTileRowSize(TIFF *tif)
*/
uint64_t TIFFVTileSize64(TIFF *tif, uint32_t nrows)
{
static const char module[] = "TIFFVTileSize64";
TIFFDirectory *td = &tif->tif_dir;
if (td->td_tilelength == 0 || td->td_tilewidth == 0 ||
td->td_tiledepth == 0)
return (0);
if ((td->td_planarconfig == PLANARCONFIG_CONTIG) &&
(td->td_photometric == PHOTOMETRIC_YCBCR) &&
(td->td_samplesperpixel == 3) && (!isUpSampled(tif)))
{
/*
* Packed YCbCr data contain one Cb+Cr for every
* HorizontalSampling*VerticalSampling Y values.
* Must also roundup width and height when calculating
* since images that are not a multiple of the
* horizontal/vertical subsampling area include
* YCbCr data for the extended image.
*/
uint16_t ycbcrsubsampling[2];
uint16_t samplingblock_samples;
uint32_t samplingblocks_hor;
uint32_t samplingblocks_ver;
uint64_t samplingrow_samples;
uint64_t samplingrow_size;
TIFFGetFieldDefaulted(tif, TIFFTAG_YCBCRSUBSAMPLING,
ycbcrsubsampling + 0, ycbcrsubsampling + 1);
if ((ycbcrsubsampling[0] != 1 && ycbcrsubsampling[0] != 2 &&
ycbcrsubsampling[0] != 4) ||
(ycbcrsubsampling[1] != 1 && ycbcrsubsampling[1] != 2 &&
ycbcrsubsampling[1] != 4))
{
TIFFErrorExtR(tif, module, "Invalid YCbCr subsampling (%dx%d)",
ycbcrsubsampling[0], ycbcrsubsampling[1]);
return 0;
}
samplingblock_samples = ycbcrsubsampling[0] * ycbcrsubsampling[1] + 2;
samplingblocks_hor =
TIFFhowmany_32(td->td_tilewidth, ycbcrsubsampling[0]);
samplingblocks_ver = TIFFhowmany_32(nrows, ycbcrsubsampling[1]);
samplingrow_samples = _TIFFMultiply64(tif, samplingblocks_hor,
samplingblock_samples, module);
samplingrow_size = TIFFhowmany8_64(_TIFFMultiply64(
tif, samplingrow_samples, td->td_bitspersample, module));
return (
_TIFFMultiply64(tif, samplingrow_size, samplingblocks_ver, module));
}
else
return (_TIFFMultiply64(tif, nrows, TIFFTileRowSize64(tif), module));
return _TIFFStrileSize64(tif, nrows, /* isStrip = */ FALSE);
}
tmsize_t TIFFVTileSize(TIFF *tif, uint32_t nrows)
{
static const char module[] = "TIFFVTileSize";

View File

@@ -77,10 +77,10 @@ static tmsize_t _tiffReadProc(thandle_t fd, void *buf, tmsize_t size)
return (tmsize_t)-1;
}
fdh.h = fd;
for (bytes_read = 0; bytes_read < bytes_total; bytes_read += count)
for (bytes_read = 0; bytes_read < bytes_total; bytes_read += (size_t)count)
{
char *buf_offset = (char *)buf + bytes_read;
size_t io_size = bytes_total - bytes_read;
size_t io_size = (size_t)(bytes_total - bytes_read);
if (io_size > TIFF_IO_MAX)
io_size = TIFF_IO_MAX;
/* Below is an obvious false positive of Coverity Scan */
@@ -108,10 +108,11 @@ static tmsize_t _tiffWriteProc(thandle_t fd, void *buf, tmsize_t size)
return (tmsize_t)-1;
}
fdh.h = fd;
for (bytes_written = 0; bytes_written < bytes_total; bytes_written += count)
for (bytes_written = 0; bytes_written < bytes_total;
bytes_written += (size_t)count)
{
const char *buf_offset = (char *)buf + bytes_written;
size_t io_size = bytes_total - bytes_written;
size_t io_size = (size_t)(bytes_total - bytes_written);
if (io_size > TIFF_IO_MAX)
io_size = TIFF_IO_MAX;
/* Below is an obvious false positive of Coverity Scan */
@@ -174,7 +175,7 @@ static int _tiffMapProc(thandle_t fd, void **pbase, toff_t *psize)
(void *)mmap(0, (size_t)sizem, PROT_READ, MAP_SHARED, fdh.fd, 0);
if (*pbase != (void *)-1)
{
*psize = (tmsize_t)sizem;
*psize = (toff_t)sizem;
return (1);
}
}
@@ -184,7 +185,7 @@ static int _tiffMapProc(thandle_t fd, void **pbase, toff_t *psize)
static void _tiffUnmapProc(thandle_t fd, void *base, toff_t size)
{
(void)fd;
(void)munmap(base, (off_t)size);
(void)munmap(base, (size_t)size);
}
#else /* !HAVE_MMAP */
static int _tiffMapProc(thandle_t fd, void **pbase, toff_t *psize)
@@ -362,7 +363,8 @@ int _TIFFmemcmp(const void *p1, const void *p2, tmsize_t c)
return (memcmp(p1, p2, (size_t)c));
}
static void unixWarningHandler(const char *module, const char *fmt, va_list ap)
static void TIFF_ATTRIBUTE((__format__(__printf__, 2, 0)))
unixWarningHandler(const char *module, const char *fmt, va_list ap)
{
if (module != NULL)
fprintf(stderr, "%s: ", module);
@@ -372,7 +374,8 @@ static void unixWarningHandler(const char *module, const char *fmt, va_list ap)
}
TIFFErrorHandler _TIFFwarningHandler = unixWarningHandler;
static void unixErrorHandler(const char *module, const char *fmt, va_list ap)
static void TIFF_ATTRIBUTE((__format__(__printf__, 2, 0)))
unixErrorHandler(const char *module, const char *fmt, va_list ap)
{
if (module != NULL)
fprintf(stderr, "%s: ", module);

View File

@@ -84,15 +84,16 @@ static int TWebPDatasetWriter(const uint8_t *data, size_t data_size,
if ((tif->tif_rawcc + (tmsize_t)data_size) > tif->tif_rawdatasize)
{
TIFFErrorExtR(
tif, module, "Buffer too small by %" TIFF_SIZE_FORMAT " bytes.",
(size_t)(tif->tif_rawcc + data_size - tif->tif_rawdatasize));
TIFFErrorExtR(tif, module,
"Buffer too small by %" TIFF_SIZE_FORMAT " bytes.",
(size_t)((uint64_t)tif->tif_rawcc + (uint64_t)data_size -
(uint64_t)tif->tif_rawdatasize));
return 0;
}
else
{
_TIFFmemcpy(tif->tif_rawcp, data, data_size);
tif->tif_rawcc += data_size;
_TIFFmemcpy(tif->tif_rawcp, data, (tmsize_t)data_size);
tif->tif_rawcc += (tmsize_t)data_size;
tif->tif_rawcp += data_size;
return 1;
}
@@ -116,7 +117,7 @@ static int TWebPEncode(TIFF *tif, uint8_t *bp, tmsize_t cc, uint16_t s)
return 0;
}
memcpy(sp->pBuffer + sp->buffer_offset, bp, cc);
memcpy(sp->pBuffer + sp->buffer_offset, bp, (size_t)cc);
sp->buffer_offset += (unsigned)cc;
return 1;
@@ -141,7 +142,7 @@ static int TWebPDecode(TIFF *tif, uint8_t *op, tmsize_t occ, uint16_t s)
TIFFErrorExtR(tif, module,
"ZIPDecode: Scanline %" PRIu32 " cannot be read due to "
"previous error",
tif->tif_row);
tif->tif_dir.td_row);
return 0;
}
@@ -158,7 +159,7 @@ static int TWebPDecode(TIFF *tif, uint8_t *op, tmsize_t occ, uint16_t s)
else
{
segment_width = td->td_imagewidth;
segment_height = td->td_imagelength - tif->tif_row;
segment_height = td->td_imagelength - tif->tif_dir.td_row;
if (segment_height > td->td_rowsperstrip)
segment_height = td->td_rowsperstrip;
}
@@ -246,7 +247,7 @@ static int TWebPDecode(TIFF *tif, uint8_t *op, tmsize_t occ, uint16_t s)
sp->pBuffer = NULL;
}
sp->pBuffer = _TIFFmallocExt(tif, buffer_size);
sp->pBuffer = (uint8_t *)_TIFFmallocExt(tif, buffer_size);
if (!sp->pBuffer)
{
TIFFErrorExtR(tif, module, "Cannot allocate buffer");
@@ -262,10 +263,10 @@ static int TWebPDecode(TIFF *tif, uint8_t *op, tmsize_t occ, uint16_t s)
WebPInitDecBuffer(&sp->sDecBuffer);
sp->sDecBuffer.is_external_memory = 1;
sp->sDecBuffer.width = segment_width;
sp->sDecBuffer.height = segment_height;
sp->sDecBuffer.width = (int)segment_width;
sp->sDecBuffer.height = (int)segment_height;
sp->sDecBuffer.u.RGBA.rgba = decode_whole_strile ? op : sp->pBuffer;
sp->sDecBuffer.u.RGBA.stride = segment_width * sp->nSamples;
sp->sDecBuffer.u.RGBA.stride = (int)(segment_width * sp->nSamples);
sp->sDecBuffer.u.RGBA.size = buffer_size;
if (sp->nSamples > 3)
@@ -298,7 +299,7 @@ static int TWebPDecode(TIFF *tif, uint8_t *op, tmsize_t occ, uint16_t s)
return 0;
}
status = WebPIAppend(sp->psDecoder, tif->tif_rawcp, tif->tif_rawcc);
status = WebPIAppend(sp->psDecoder, tif->tif_rawcp, (size_t)tif->tif_rawcc);
if (status != VP8_STATUS_OK && status != VP8_STATUS_SUSPENDED)
{
@@ -345,7 +346,7 @@ static int TWebPDecode(TIFF *tif, uint8_t *op, tmsize_t occ, uint16_t s)
}
else
{
memcpy(op, buf + (sp->last_y * stride), occ);
memcpy(op, buf + (sp->last_y * stride), (size_t)occ);
}
tif->tif_rawcp += tif->tif_rawcc;
@@ -465,7 +466,7 @@ static int TWebPPreDecode(TIFF *tif, uint16_t s)
else
{
segment_width = td->td_imagewidth;
segment_height = td->td_imagelength - tif->tif_row;
segment_height = td->td_imagelength - tif->tif_dir.td_row;
if (segment_height > td->td_rowsperstrip)
segment_height = td->td_rowsperstrip;
}
@@ -601,7 +602,7 @@ static int TWebPPreEncode(TIFF *tif, uint16_t s)
else
{
segment_width = td->td_imagewidth;
segment_height = td->td_imagelength - tif->tif_row;
segment_height = td->td_imagelength - tif->tif_dir.td_row;
if (segment_height > td->td_rowsperstrip)
segment_height = td->td_rowsperstrip;
}
@@ -623,7 +624,7 @@ static int TWebPPreEncode(TIFF *tif, uint16_t s)
sp->pBuffer = NULL;
}
sp->pBuffer = _TIFFmallocExt(tif, sp->buffer_size);
sp->pBuffer = (uint8_t *)_TIFFmallocExt(tif, sp->buffer_size);
if (!sp->pBuffer)
{
TIFFErrorExtR(tif, module, "Cannot allocate buffer");
@@ -631,8 +632,8 @@ static int TWebPPreEncode(TIFF *tif, uint16_t s)
}
sp->buffer_offset = 0;
sp->sPicture.width = segment_width;
sp->sPicture.height = segment_height;
sp->sPicture.width = (int)segment_width;
sp->sPicture.height = (int)segment_height;
sp->sPicture.writer = TWebPDatasetWriter;
sp->sPicture.custom_ptr = tif;
@@ -708,9 +709,11 @@ static int TWebPPostEncode(TIFF *tif)
case VP8_ENC_ERROR_USER_ABORT:
pszErrorMsg = "User interrupted";
break;
case VP8_ENC_OK:
case VP8_ENC_ERROR_LAST:
default:
TIFFErrorExtR(tif, module,
"WebPEncode returned an unknown error code: %d",
"WebPEncode returned an unknown error code: %u",
sp->sPicture.error_code);
pszErrorMsg = "Unknown WebP error type.";
break;
@@ -776,7 +779,7 @@ static int TWebPVSetField(TIFF *tif, uint32_t tag, va_list ap)
{
case TIFFTAG_WEBP_LEVEL:
sp->quality_level = (int)va_arg(ap, int);
if (sp->quality_level <= 0 || sp->quality_level > 100.0f)
if (sp->quality_level <= 0 || sp->quality_level > 100)
{
TIFFWarningExtR(tif, module,
"WEBP_LEVEL should be between 1 and 100");
@@ -844,6 +847,17 @@ static const TIFFField TWebPFields[] = {
FIELD_PSEUDO, TRUE, FALSE, "WEBP exact lossless", NULL},
};
static uint64_t TWebPGetMaxCompressionRatio(TIFF *tif)
{
/* See README_for_libtiff_developpers.md for raw data used to estimate
* the maximum compression rate. */
/* lossy compression: */
/* return (tif->tif_dir.td_samplesperpixel == 4) ? 2199 : 1685; */
/* lossless compression: */
return (tif->tif_dir.td_samplesperpixel == 4) ? 104194 : 78146;
}
int TIFFInitWebP(TIFF *tif, int scheme)
{
static const char module[] = "TIFFInitWebP";
@@ -907,6 +921,7 @@ int TIFFInitWebP(TIFF *tif, int scheme)
tif->tif_encodestrip = TWebPEncode;
tif->tif_encodetile = TWebPEncode;
tif->tif_cleanup = TWebPCleanup;
tif->tif_getmaxcompressionratio = TWebPGetMaxCompressionRatio;
return 1;
bad:

View File

@@ -5,6 +5,7 @@
* 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
* 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
@@ -72,7 +73,7 @@ static tmsize_t _tiffReadProc(thandle_t fd, void *buf, tmsize_t size)
DWORD o;
tmsize_t p;
ma = (uint8_t *)buf;
mb = size;
mb = (uint64_t)size;
p = 0;
while (mb > 0)
{
@@ -101,7 +102,7 @@ static tmsize_t _tiffWriteProc(thandle_t fd, void *buf, tmsize_t size)
DWORD o;
tmsize_t p;
ma = (uint8_t *)buf;
mb = size;
mb = (uint64_t)size;
p = 0;
while (mb > 0)
{
@@ -123,7 +124,7 @@ static uint64_t _tiffSeekProc(thandle_t fd, uint64_t off, int whence)
{
LARGE_INTEGER offli;
DWORD dwMoveMethod;
offli.QuadPart = off;
offli.QuadPart = (LONGLONG)off;
switch (whence)
{
case SEEK_SET:
@@ -140,11 +141,11 @@ static uint64_t _tiffSeekProc(thandle_t fd, uint64_t off, int whence)
break;
}
offli.LowPart =
SetFilePointer(fd, offli.LowPart, &offli.HighPart, dwMoveMethod);
SetFilePointer(fd, (LONG)offli.LowPart, &offli.HighPart, dwMoveMethod);
if ((offli.LowPart == INVALID_SET_FILE_POINTER) &&
(GetLastError() != NO_ERROR))
offli.QuadPart = 0;
return (offli.QuadPart);
return ((uint64_t)offli.QuadPart);
}
static int _tiffCloseProc(thandle_t fd) { return (CloseHandle(fd) ? 0 : -1); }
@@ -153,7 +154,7 @@ static uint64_t _tiffSizeProc(thandle_t fd)
{
LARGE_INTEGER m;
if (GetFileSizeEx(fd, &m))
return (m.QuadPart);
return ((uint64_t)m.QuadPart);
else
return (0);
}
@@ -343,7 +344,7 @@ TIFF *TIFFOpenWExt(const wchar_t *name, const char *mode, TIFFOpenOptions *opts)
NULL);
if (fd == INVALID_HANDLE_VALUE)
{
_TIFFErrorEarly(opts, NULL, module, "%S: Cannot open", name);
_TIFFErrorEarly(opts, NULL, module, "%ls: Cannot open", name);
return ((TIFF *)0);
}

View File

@@ -30,7 +30,7 @@
#include "tiffiop.h"
#include <stdio.h>
#define STRIPINCR 20 /* expansion factor on strip array */
#define NOSTRIP ((uint32_t)(-1)) /* undefined state */
#define WRITECHECKSTRIPS(tif, module) \
(((tif)->tif_flags & TIFF_BEENWRITING) || TIFFWriteCheck((tif), 0, module))
@@ -38,7 +38,7 @@
(((tif)->tif_flags & TIFF_BEENWRITING) || TIFFWriteCheck((tif), 1, module))
#define BUFFERCHECK(tif) \
((((tif)->tif_flags & TIFF_BUFFERSETUP) && tif->tif_rawdata) || \
TIFFWriteBufferSetup((tif), NULL, (tmsize_t)-1))
TIFFWriteBufferSetup((tif), NULL, (tmsize_t)(-1)))
static int TIFFGrowStrips(TIFF *tif, uint32_t delta, const char *module);
static int TIFFAppendToStrip(TIFF *tif, uint32_t strip, uint8_t *data,
@@ -47,7 +47,7 @@ static int TIFFAppendToStrip(TIFF *tif, uint32_t strip, uint8_t *data,
int TIFFWriteScanline(TIFF *tif, void *buf, uint32_t row, uint16_t sample)
{
static const char module[] = "TIFFWriteScanline";
register TIFFDirectory *td;
TIFFDirectory *td;
int status, imagegrew = 0;
uint32_t strip;
@@ -82,8 +82,16 @@ int TIFFWriteScanline(TIFF *tif, void *buf, uint32_t row, uint16_t sample)
/*
* Calculate strip and check for crossings.
*/
if (td->td_rowsperstrip == 0)
{
TIFFErrorExtR(tif, module,
"Cannot compute strip: RowsPerStrip is zero");
return (-1);
}
if (td->td_planarconfig == PLANARCONFIG_SEPARATE)
{
uint64_t sample_offset;
uint64_t strip64;
if (sample >= td->td_samplesperpixel)
{
TIFFErrorExtR(tif, module, "%lu: Sample out of range, max %lu",
@@ -91,7 +99,18 @@ int TIFFWriteScanline(TIFF *tif, void *buf, uint32_t row, uint16_t sample)
(unsigned long)td->td_samplesperpixel);
return (-1);
}
strip = sample * td->td_stripsperimage + row / td->td_rowsperstrip;
sample_offset =
_TIFFMultiply64(tif, sample, td->td_stripsperimage, module);
if (sample_offset == 0 && sample != 0 && td->td_stripsperimage != 0)
return (-1);
strip64 =
_TIFFAdd64(tif, sample_offset, row / td->td_rowsperstrip, module);
if (strip64 == 0 &&
(sample_offset != 0 || (row / td->td_rowsperstrip) != 0))
return (-1);
strip = _TIFFCastUInt64ToUInt32(tif, strip64, module);
if (strip == 0 && strip64 != 0)
return (-1);
}
else
strip = row / td->td_rowsperstrip;
@@ -104,14 +123,14 @@ int TIFFWriteScanline(TIFF *tif, void *buf, uint32_t row, uint16_t sample)
*/
if (strip >= td->td_nstrips && !TIFFGrowStrips(tif, 1, module))
return (-1);
if (strip != tif->tif_curstrip)
if (strip != tif->tif_dir.td_curstrip)
{
/*
* Changing strips -- flush any data present.
*/
if (!TIFFFlushData(tif))
return (-1);
tif->tif_curstrip = strip;
tif->tif_dir.td_curstrip = strip;
/*
* Watch out for a growing image. The value of strips/image
* will initially be 1 (since it can't be deduced until the
@@ -125,7 +144,8 @@ int TIFFWriteScanline(TIFF *tif, void *buf, uint32_t row, uint16_t sample)
TIFFErrorExtR(tif, module, "Zero strips per image");
return (-1);
}
tif->tif_row = (strip % td->td_stripsperimage) * td->td_rowsperstrip;
tif->tif_dir.td_row =
(strip % td->td_stripsperimage) * td->td_rowsperstrip;
if ((tif->tif_flags & TIFF_CODERSETUP) == 0)
{
if (!(*tif->tif_setupencode)(tif))
@@ -148,35 +168,35 @@ int TIFFWriteScanline(TIFF *tif, void *buf, uint32_t row, uint16_t sample)
* beginning of a strip (or that we can randomly
* access the data -- i.e. no encoding).
*/
if (row != tif->tif_row)
if (row != tif->tif_dir.td_row)
{
if (row < tif->tif_row)
if (row < tif->tif_dir.td_row)
{
/*
* Moving backwards within the same strip:
* backup to the start and then decode
* forward (below).
*/
tif->tif_row =
tif->tif_dir.td_row =
(strip % td->td_stripsperimage) * td->td_rowsperstrip;
tif->tif_rawcp = tif->tif_rawdata;
}
/*
* Seek forward to the desired row.
*/
if (!(*tif->tif_seek)(tif, row - tif->tif_row))
if (!(*tif->tif_seek)(tif, row - tif->tif_dir.td_row))
return (-1);
tif->tif_row = row;
tif->tif_dir.td_row = row;
}
/* swab if needed - note that source buffer will be altered */
tif->tif_postdecode(tif, (uint8_t *)buf, tif->tif_scanlinesize);
tif->tif_postdecode(tif, (uint8_t *)buf, tif->tif_dir.td_scanlinesize);
status = (*tif->tif_encoderow)(tif, (uint8_t *)buf, tif->tif_scanlinesize,
sample);
status = (*tif->tif_encoderow)(tif, (uint8_t *)buf,
tif->tif_dir.td_scanlinesize, sample);
/* we are now poised at the beginning of the next row */
tif->tif_row = row + 1;
tif->tif_dir.td_row = row + 1;
return (status);
}
@@ -188,7 +208,21 @@ int TIFFWriteScanline(TIFF *tif, void *buf, uint32_t row, uint16_t sample)
/* time if the new compressed tile is bigger than the older one. (GDAL #4771) */
static int _TIFFReserveLargeEnoughWriteBuffer(TIFF *tif, uint32_t strip_or_tile)
{
static const char module[] = "_TIFFReserveLargeEnoughWriteBuffer";
TIFFDirectory *td = &tif->tif_dir;
if (td->td_stripbytecount_p == NULL)
{
TIFFErrorExtR(tif, module, "Strip bytecount array pointer is NULL");
return 0;
}
if (strip_or_tile == NOSTRIP || strip_or_tile >= td->td_nstrips)
{
TIFFErrorExtR(tif, module, "Strip/tile number not valid");
return 0;
}
if (td->td_stripbytecount_p[strip_or_tile] > 0)
{
/* The +1 is to ensure at least one extra bytes */
@@ -254,7 +288,7 @@ tmsize_t TIFFWriteEncodedStrip(TIFF *tif, uint32_t strip, void *data,
tif->tif_flags |= TIFF_BUF4WRITE;
tif->tif_curstrip = strip;
tif->tif_dir.td_curstrip = strip;
/* this informs TIFFAppendToStrip() we have changed or reset strip */
tif->tif_curoff = 0;
@@ -273,7 +307,7 @@ tmsize_t TIFFWriteEncodedStrip(TIFF *tif, uint32_t strip, void *data,
return ((tmsize_t)-1);
}
tif->tif_row = (strip % td->td_stripsperimage) * td->td_rowsperstrip;
tif->tif_dir.td_row = (strip % td->td_stripsperimage) * td->td_rowsperstrip;
if ((tif->tif_flags & TIFF_CODERSETUP) == 0)
{
if (!(*tif->tif_setupencode)(tif))
@@ -362,9 +396,9 @@ tmsize_t TIFFWriteRawStrip(TIFF *tif, uint32_t strip, void *data, tmsize_t cc)
return ((tmsize_t)-1);
}
if (tif->tif_curstrip != strip)
if (tif->tif_dir.td_curstrip != strip)
{
tif->tif_curstrip = strip;
tif->tif_dir.td_curstrip = strip;
/* this informs TIFFAppendToStrip() we have changed or reset strip */
tif->tif_curoff = 0;
@@ -375,7 +409,7 @@ tmsize_t TIFFWriteRawStrip(TIFF *tif, uint32_t strip, void *data, tmsize_t cc)
TIFFErrorExtR(tif, module, "Zero strips per image");
return ((tmsize_t)-1);
}
tif->tif_row = (strip % td->td_stripsperimage) * td->td_rowsperstrip;
tif->tif_dir.td_row = (strip % td->td_stripsperimage) * td->td_rowsperstrip;
return (TIFFAppendToStrip(tif, strip, (uint8_t *)data, cc) ? cc
: (tmsize_t)-1);
}
@@ -437,7 +471,7 @@ tmsize_t TIFFWriteEncodedTile(TIFF *tif, uint32_t tile, void *data, tmsize_t cc)
tif->tif_flags |= TIFF_BUF4WRITE;
tif->tif_curtile = tile;
tif->tif_dir.td_curtile = tile;
/* this informs TIFFAppendToStrip() we have changed or reset tile */
tif->tif_curoff = 0;
@@ -460,14 +494,14 @@ tmsize_t TIFFWriteEncodedTile(TIFF *tif, uint32_t tile, void *data, tmsize_t cc)
TIFFErrorExtR(tif, module, "Zero tiles");
return ((tmsize_t)(-1));
}
tif->tif_row = (tile % howmany32) * td->td_tilelength;
tif->tif_dir.td_row = (tile % howmany32) * td->td_tilelength;
howmany32 = TIFFhowmany_32(td->td_imagewidth, td->td_tilewidth);
if (howmany32 == 0)
{
TIFFErrorExtR(tif, module, "Zero tiles");
return ((tmsize_t)(-1));
}
tif->tif_col = (tile % howmany32) * td->td_tilewidth;
tif->tif_dir.td_col = (tile % howmany32) * td->td_tilewidth;
if ((tif->tif_flags & TIFF_CODERSETUP) == 0)
{
@@ -482,8 +516,8 @@ tmsize_t TIFFWriteEncodedTile(TIFF *tif, uint32_t tile, void *data, tmsize_t cc)
* done so that callers can pass in some large number
* (e.g. -1) and have the tile size used instead.
*/
if (cc < 1 || cc > tif->tif_tilesize)
cc = tif->tif_tilesize;
if (cc < 1 || cc > tif->tif_dir.td_tilesize)
cc = tif->tif_dir.td_tilesize;
/* shortcut to avoid an extra memcpy() */
if (td->td_compression == COMPRESSION_NONE)
@@ -588,8 +622,10 @@ int TIFFSetupStrips(TIFF *tif)
* Place data at the end-of-file
* (by setting offsets to zero).
*/
_TIFFmemset(td->td_stripoffset_p, 0, td->td_nstrips * sizeof(uint64_t));
_TIFFmemset(td->td_stripbytecount_p, 0, td->td_nstrips * sizeof(uint64_t));
_TIFFmemset(td->td_stripoffset_p, 0,
(tmsize_t)((size_t)td->td_nstrips * sizeof(uint64_t)));
_TIFFmemset(td->td_stripbytecount_p, 0,
(tmsize_t)((size_t)td->td_nstrips * sizeof(uint64_t)));
TIFFSetFieldBit(tif, FIELD_STRIPOFFSETS);
TIFFSetFieldBit(tif, FIELD_STRIPBYTECOUNTS);
return (1);
@@ -644,14 +680,14 @@ int TIFFWriteCheck(TIFF *tif, int tiles, const char *module)
}
if (isTiled(tif))
{
tif->tif_tilesize = TIFFTileSize(tif);
if (tif->tif_tilesize == 0)
tif->tif_dir.td_tilesize = TIFFTileSize(tif);
if (tif->tif_dir.td_tilesize == 0)
return (0);
}
else
tif->tif_tilesize = (tmsize_t)(-1);
tif->tif_scanlinesize = TIFFScanlineSize(tif);
if (tif->tif_scanlinesize == 0)
tif->tif_dir.td_tilesize = (tmsize_t)(-1);
tif->tif_dir.td_scanlinesize = TIFFScanlineSize(tif);
if (tif->tif_dir.td_scanlinesize == 0)
return (0);
tif->tif_flags |= TIFF_BEENWRITING;
@@ -689,7 +725,7 @@ int TIFFWriteBufferSetup(TIFF *tif, void *bp, tmsize_t size)
}
if (size == (tmsize_t)(-1))
{
size = (isTiled(tif) ? tif->tif_tilesize : TIFFStripSize(tif));
size = (isTiled(tif) ? tif->tif_dir.td_tilesize : TIFFStripSize(tif));
/* Adds 10% margin for cases where compression would expand a bit */
if (size < TIFF_TMSIZE_T_MAX - size / 10)
@@ -732,26 +768,31 @@ static int TIFFGrowStrips(TIFF *tif, uint32_t delta, const char *module)
assert(td->td_planarconfig == PLANARCONFIG_CONTIG);
new_stripoffset = (uint64_t *)_TIFFreallocExt(
tif, td->td_stripoffset_p, (td->td_nstrips + delta) * sizeof(uint64_t));
tif, td->td_stripoffset_p,
(tmsize_t)(((size_t)td->td_nstrips + (size_t)delta) *
sizeof(uint64_t)));
/*
* Update td_stripoffset_p immediately so the old pointer is not left
* dangling if the second realloc fails.
*/
if (new_stripoffset)
td->td_stripoffset_p = new_stripoffset;
new_stripbytecount = (uint64_t *)_TIFFreallocExt(
tif, td->td_stripbytecount_p,
(td->td_nstrips + delta) * sizeof(uint64_t));
(tmsize_t)(((size_t)td->td_nstrips + (size_t)delta) *
sizeof(uint64_t)));
if (new_stripbytecount)
td->td_stripbytecount_p = new_stripbytecount;
if (new_stripoffset == NULL || new_stripbytecount == NULL)
{
if (new_stripoffset)
_TIFFfreeExt(tif, new_stripoffset);
if (new_stripbytecount)
_TIFFfreeExt(tif, new_stripbytecount);
td->td_nstrips = 0;
TIFFErrorExtR(tif, module, "No space to expand strip arrays");
return (0);
}
td->td_stripoffset_p = new_stripoffset;
td->td_stripbytecount_p = new_stripbytecount;
_TIFFmemset(td->td_stripoffset_p + td->td_nstrips, 0,
delta * sizeof(uint64_t));
(tmsize_t)((size_t)delta * sizeof(uint64_t)));
_TIFFmemset(td->td_stripbytecount_p + td->td_nstrips, 0,
delta * sizeof(uint64_t));
(tmsize_t)((size_t)delta * sizeof(uint64_t)));
td->td_nstrips += delta;
tif->tif_flags |= TIFF_DIRTYDIRECT;
@@ -769,6 +810,23 @@ static int TIFFAppendToStrip(TIFF *tif, uint32_t strip, uint8_t *data,
uint64_t m;
int64_t old_byte_count = -1;
/* Some security checks */
if (td->td_stripoffset_p == NULL)
{
TIFFErrorExtR(tif, module, "Strip offset array pointer is NULL");
return (0);
}
if (td->td_stripbytecount_p == NULL)
{
TIFFErrorExtR(tif, module, "Strip bytecount array pointer is NULL");
return (0);
}
if (strip == NOSTRIP)
{
TIFFErrorExtR(tif, module, "Strip number not valid (NOSTRIP)");
return (0);
}
if (tif->tif_curoff == 0)
tif->tif_lastvalidoff = 0;
@@ -790,7 +848,7 @@ static int TIFFAppendToStrip(TIFF *tif, uint32_t strip, uint8_t *data,
if (!SeekOK(tif, td->td_stripoffset_p[strip]))
{
TIFFErrorExtR(tif, module, "Seek error at scanline %lu",
(unsigned long)tif->tif_row);
(unsigned long)tif->tif_dir.td_row);
return (0);
}
@@ -812,11 +870,11 @@ static int TIFFAppendToStrip(TIFF *tif, uint32_t strip, uint8_t *data,
/*
* We are starting a fresh strip/tile, so set the size to zero.
*/
old_byte_count = td->td_stripbytecount_p[strip];
old_byte_count = (int64_t)td->td_stripbytecount_p[strip];
td->td_stripbytecount_p[strip] = 0;
}
m = tif->tif_curoff + cc;
m = tif->tif_curoff + (uint64_t)cc;
if (!(tif->tif_flags & TIFF_BIGTIFF))
m = (uint32_t)m;
if ((m < tif->tif_curoff) || (m < (uint64_t)cc))
@@ -850,7 +908,7 @@ static int TIFFAppendToStrip(TIFF *tif, uint32_t strip, uint8_t *data,
offsetRead = td->td_stripoffset_p[strip];
offsetWrite = TIFFSeekFile(tif, 0, SEEK_END);
m = offsetWrite + toCopy + cc;
m = offsetWrite + (uint64_t)toCopy + (uint64_t)cc;
if (!(tif->tif_flags & TIFF_BIGTIFF) && m != (uint32_t)m)
{
TIFFErrorExtR(tif, module, "Maximum TIFF file size exceeded");
@@ -872,13 +930,15 @@ static int TIFFAppendToStrip(TIFF *tif, uint32_t strip, uint8_t *data,
/* Move data written by previous calls to us at end of file */
while (toCopy > 0)
{
tmsize_t chunkSize =
toCopy < (uint64_t)tempSize ? (tmsize_t)toCopy : tempSize;
if (!SeekOK(tif, offsetRead))
{
TIFFErrorExtR(tif, module, "Seek error");
_TIFFfreeExt(tif, temp);
return (0);
}
if (!ReadOK(tif, temp, tempSize))
if (!ReadOK(tif, temp, chunkSize))
{
TIFFErrorExtR(tif, module, "Cannot read");
_TIFFfreeExt(tif, temp);
@@ -890,32 +950,32 @@ static int TIFFAppendToStrip(TIFF *tif, uint32_t strip, uint8_t *data,
_TIFFfreeExt(tif, temp);
return (0);
}
if (!WriteOK(tif, temp, tempSize))
if (!WriteOK(tif, temp, chunkSize))
{
TIFFErrorExtR(tif, module, "Cannot write");
_TIFFfreeExt(tif, temp);
return (0);
}
offsetRead += tempSize;
offsetWrite += tempSize;
td->td_stripbytecount_p[strip] += tempSize;
toCopy -= tempSize;
offsetRead += (uint64_t)chunkSize;
offsetWrite += (uint64_t)chunkSize;
td->td_stripbytecount_p[strip] += (uint64_t)chunkSize;
toCopy -= (uint64_t)chunkSize;
}
_TIFFfreeExt(tif, temp);
/* Append the data of this call */
offsetWrite += cc;
offsetWrite += (uint64_t)cc;
m = offsetWrite;
}
if (!WriteOK(tif, data, cc))
{
TIFFErrorExtR(tif, module, "Write error at scanline %lu",
(unsigned long)tif->tif_row);
(unsigned long)tif->tif_dir.td_row);
return (0);
}
tif->tif_curoff = m;
td->td_stripbytecount_p[strip] += cc;
td->td_stripbytecount_p[strip] += (uint64_t)cc;
if ((int64_t)td->td_stripbytecount_p[strip] != old_byte_count)
tif->tif_flags |= TIFF_DIRTYSTRIP;
@@ -935,9 +995,10 @@ int TIFFFlushData1(TIFF *tif)
if (!isFillOrder(tif, tif->tif_dir.td_fillorder) &&
(tif->tif_flags & TIFF_NOBITREV) == 0)
TIFFReverseBits((uint8_t *)tif->tif_rawdata, tif->tif_rawcc);
if (!TIFFAppendToStrip(
tif, isTiled(tif) ? tif->tif_curtile : tif->tif_curstrip,
tif->tif_rawdata, tif->tif_rawcc))
if (!TIFFAppendToStrip(tif,
isTiled(tif) ? tif->tif_dir.td_curtile
: tif->tif_dir.td_curstrip,
tif->tif_rawdata, tif->tif_rawcc))
{
/* We update those variables even in case of error since there's */
/* code that doesn't really check the return code of this */

View File

@@ -159,7 +159,8 @@ static int ZIPPreDecode(TIFF *tif, uint16_t s)
we need to simplify this code to reflect a ZLib that is likely updated
to deal with 8byte memory sizes, though this code will respond
appropriately even before we simplify it */
sp->stream.avail_in = TIFF_CLAMP_UINT64_TO_INT32_MAX(tif->tif_rawcc);
sp->stream.avail_in =
TIFF_CLAMP_UINT64_TO_INT32_MAX((uint64_t)tif->tif_rawcc);
if (inflateReset(&sp->stream) == Z_OK)
{
sp->read_error = 0;
@@ -183,7 +184,7 @@ static int ZIPDecode(TIFF *tif, uint8_t *op, tmsize_t occ, uint16_t s)
TIFFErrorExtR(tif, module,
"ZIPDecode: Scanline %" PRIu32 " cannot be read due to "
"previous error",
tif->tif_row);
tif->tif_dir.td_row);
return 0;
}
@@ -210,7 +211,7 @@ static int ZIPDecode(TIFF *tif, uint8_t *op, tmsize_t occ, uint16_t s)
}
else
{
uint32_t strip_height = td->td_imagelength - tif->tif_row;
uint32_t strip_height = td->td_imagelength - tif->tif_dir.td_row;
if (strip_height > td->td_rowsperstrip)
strip_height = td->td_rowsperstrip;
if (TIFFVStripSize64(tif, strip_height) != (uint64_t)occ)
@@ -254,7 +255,7 @@ static int ZIPDecode(TIFF *tif, uint8_t *op, tmsize_t occ, uint16_t s)
{
memset(op, 0, (size_t)occ);
TIFFErrorExtR(tif, module, "Decoding error at scanline %lu",
(unsigned long)tif->tif_row);
(unsigned long)tif->tif_dir.td_row);
sp->read_error = 1;
return 0;
}
@@ -275,8 +276,9 @@ static int ZIPDecode(TIFF *tif, uint8_t *op, tmsize_t occ, uint16_t s)
do
{
int state;
uInt avail_in_before = TIFF_CLAMP_UINT64_TO_INT32_MAX(tif->tif_rawcc);
uInt avail_out_before = TIFF_CLAMP_UINT64_TO_INT32_MAX(occ);
uInt avail_in_before =
TIFF_CLAMP_UINT64_TO_INT32_MAX((uint64_t)tif->tif_rawcc);
uInt avail_out_before = TIFF_CLAMP_UINT64_TO_INT32_MAX((uint64_t)occ);
sp->stream.avail_in = avail_in_before;
sp->stream.avail_out = avail_out_before;
state = inflate(&sp->stream, Z_PARTIAL_FLUSH);
@@ -288,7 +290,7 @@ static int ZIPDecode(TIFF *tif, uint8_t *op, tmsize_t occ, uint16_t s)
{
memset(sp->stream.next_out, 0, (size_t)occ);
TIFFErrorExtR(tif, module, "Decoding error at scanline %lu, %s",
(unsigned long)tif->tif_row, SAFE_MSG(sp));
(unsigned long)tif->tif_dir.td_row, SAFE_MSG(sp));
sp->read_error = 1;
return (0);
}
@@ -305,7 +307,7 @@ static int ZIPDecode(TIFF *tif, uint8_t *op, tmsize_t occ, uint16_t s)
TIFFErrorExtR(tif, module,
"Not enough data at scanline %lu (short %" PRIu64
" bytes)",
(unsigned long)tif->tif_row, (uint64_t)occ);
(unsigned long)tif->tif_dir.td_row, (uint64_t)occ);
memset(sp->stream.next_out, 0, (size_t)occ);
sp->read_error = 1;
return (0);
@@ -411,7 +413,7 @@ static int ZIPEncode(TIFF *tif, uint8_t *bp, tmsize_t cc, uint16_t s)
}
else
{
uint32_t strip_height = td->td_imagelength - tif->tif_row;
uint32_t strip_height = td->td_imagelength - tif->tif_dir.td_row;
if (strip_height > td->td_rowsperstrip)
strip_height = td->td_rowsperstrip;
if (TIFFVStripSize64(tif, strip_height) != (uint64_t)cc)
@@ -463,11 +465,11 @@ static int ZIPEncode(TIFF *tif, uint8_t *bp, tmsize_t cc, uint16_t s)
if (nCompressedBytes == 0)
{
TIFFErrorExtR(tif, module, "Encoder error at scanline %lu",
(unsigned long)tif->tif_row);
(unsigned long)tif->tif_dir.td_row);
return 0;
}
tif->tif_rawcc = nCompressedBytes;
tif->tif_rawcc = (tmsize_t)nCompressedBytes;
if (!TIFFFlushData1(tif))
return 0;
@@ -485,7 +487,7 @@ static int ZIPEncode(TIFF *tif, uint8_t *bp, tmsize_t cc, uint16_t s)
appropriately even before we simplify it */
do
{
uInt avail_in_before = TIFF_CLAMP_UINT64_TO_INT32_MAX(cc);
uInt avail_in_before = TIFF_CLAMP_UINT64_TO_INT32_MAX((uint64_t)cc);
sp->stream.avail_in = avail_in_before;
if (deflate(&sp->stream, Z_NO_FLUSH) != Z_OK)
{
@@ -499,7 +501,7 @@ static int ZIPEncode(TIFF *tif, uint8_t *bp, tmsize_t cc, uint16_t s)
return 0;
sp->stream.next_out = tif->tif_rawdata;
sp->stream.avail_out =
TIFF_CLAMP_UINT64_TO_INT32_MAX(tif->tif_rawdatasize);
TIFF_CLAMP_UINT64_TO_INT32_MAX((uint64_t)tif->tif_rawdatasize);
}
cc -= (avail_in_before - sp->stream.avail_in);
} while (cc > 0);
@@ -682,7 +684,7 @@ static const TIFFField zipFields[] = {
static void *TIFF_zalloc(void *opaque, unsigned int items, unsigned int size)
{
static const char module[] = "TIFF_zalloc";
TIFF *tif = opaque;
TIFF *tif = (TIFF *)opaque;
if (items > ~(size_t)0 / size)
{
@@ -698,6 +700,13 @@ static void TIFF_zfree(void *opaque, void *ptr)
_TIFFfreeExt((TIFF *)opaque, ptr);
}
static uint64_t ZIPGetMaxCompressionRatio(TIFF *tif)
{
(void)tif;
/* cf https://zlib.net/zlib_tech.html */
return 1032;
}
int TIFFInitZIP(TIFF *tif, int scheme)
{
static const char module[] = "TIFFInitZIP";
@@ -764,6 +773,7 @@ int TIFFInitZIP(TIFF *tif, int scheme)
tif->tif_encodestrip = ZIPEncode;
tif->tif_encodetile = ZIPEncode;
tif->tif_cleanup = ZIPCleanup;
tif->tif_getmaxcompressionratio = ZIPGetMaxCompressionRatio;
/*
* Setup predictor setup.
*/

View File

@@ -159,13 +159,13 @@ static int ZSTDDecode(TIFF *tif, uint8_t *op, tmsize_t occ, uint16_t s)
memset(op + out_buffer.pos, 0, out_buffer.size - out_buffer.pos);
TIFFErrorExtR(tif, module,
"Not enough data at scanline %lu (short %lu bytes)",
(unsigned long)tif->tif_row,
(unsigned long)tif->tif_dir.td_row,
(unsigned long)((size_t)occ - out_buffer.pos));
return 0;
}
tif->tif_rawcp += in_buffer.pos;
tif->tif_rawcc -= in_buffer.pos;
tif->tif_rawcc -= (tmsize_t)in_buffer.pos;
return 1;
}
@@ -287,7 +287,7 @@ static int ZSTDPostEncode(TIFF *tif)
}
if (sp->out_buffer.pos > 0)
{
tif->tif_rawcc = sp->out_buffer.pos;
tif->tif_rawcc = (tmsize_t)sp->out_buffer.pos;
if (!TIFFFlushData1(tif))
return 0;
sp->out_buffer.dst = tif->tif_rawcp;

View File

@@ -125,13 +125,13 @@ typedef void *thandle_t; /* client data handle */
*/
/* reference white */
#define D65_X0 (95.0470F)
#define D65_Y0 (100.0F)
#define D65_Z0 (108.8827F)
#define D65_X0 (95.0470f)
#define D65_Y0 (100.0f)
#define D65_Z0 (108.8827f)
#define D50_X0 (96.4250F)
#define D50_Y0 (100.0F)
#define D50_Z0 (82.4680F)
#define D50_X0 (96.4250f)
#define D50_Y0 (100.0f)
#define D50_Z0 (82.4680f)
/* Structure for holding information about a display device. */
@@ -254,7 +254,7 @@ struct _TIFFRGBAImage
* Macros for extracting components from the
* packed ABGR form returned by TIFFReadRGBAImage.
*/
#define TIFFGetR(abgr) ((abgr)&0xff)
#define TIFFGetR(abgr) ((abgr) & 0xff)
#define TIFFGetG(abgr) (((abgr) >> 8) & 0xff)
#define TIFFGetB(abgr) (((abgr) >> 16) & 0xff)
#define TIFFGetA(abgr) (((abgr) >> 24) & 0xff)
@@ -269,7 +269,7 @@ struct _TIFFRGBAImage
typedef int (*TIFFInitMethod)(TIFF *, int);
typedef struct
{
char *name;
const char *name;
uint16_t scheme;
TIFFInitMethod init;
} TIFFCodec;
@@ -584,6 +584,7 @@ extern int TIFFReadRGBAImageOriented(TIFF *, uint32_t, uint32_t, uint32_t *,
tmsize_t cc);
extern tmsize_t TIFFWriteRawTile(TIFF *tif, uint32_t tile, void *data,
tmsize_t cc);
extern uint64_t TIFFGetMaxCompressionRatio(TIFF *tif);
extern int TIFFDataWidth(
TIFFDataType); /* table of tag datatype widths within TIFF file. */
extern void TIFFSetWriteOffset(TIFF *tif, toff_t off);
@@ -659,7 +660,7 @@ extern int TIFFReadRGBAImageOriented(TIFF *, uint32_t, uint32_t, uint32_t *,
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 */
const char *field_name; /* ASCII name */
} TIFFFieldInfo;
extern int TIFFMergeFieldInfo(TIFF *, const TIFFFieldInfo[], uint32_t);

View File

@@ -38,6 +38,7 @@
#include <sys/types.h>
#endif
#include <math.h>
#include <string.h>
#ifdef HAVE_ASSERT_H
@@ -94,6 +95,7 @@ typedef int (*TIFFSeekMethod)(TIFF *, uint32_t);
typedef void (*TIFFPostMethod)(TIFF *tif, uint8_t *buf, tmsize_t size);
typedef uint32_t (*TIFFStripMethod)(TIFF *, uint32_t);
typedef void (*TIFFTileMethod)(TIFF *, uint32_t *, uint32_t *);
typedef uint64_t (*TIFFGetMaxCompressionRatioMethod)(TIFF *);
struct TIFFOffsetAndDirNumber
{
@@ -143,13 +145,18 @@ struct tiff
0x800000U /* read buffer (tif_rawdata) points into mmap() memory */
#define TIFF_DEFERSTRILELOAD \
0x1000000U /* defer strip/tile offset/bytecount array loading. */
#define TIFF_LAZYSTRILELOAD \
0x2000000U /* lazy/ondemand loading of strip/tile offset/bytecount values. \
Only used if TIFF_DEFERSTRILELOAD is set and in read-only \
mode */
#define TIFF_LAZYSTRILELOAD_DONE \
0x2000000U /* set when lazy/ondemand loading of strip/tile \
offset/bytecount values has been done. Only used if \
TIFF_DEFERSTRILELOAD is set and in read-only mode */
#define TIFF_CHOPPEDUPARRAYS \
0x4000000U /* set when allocChoppedUpStripArrays() has modified strip \
array */
#define TIFF_LAZYSTRILELOAD_ASKED \
0x8000000U /* set when lazy/ondemand loading of strip/tile \
offset/bytecount values has been requested on opening ('O' \
flag) */
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 */
@@ -162,7 +169,6 @@ struct tiff
tif_customdir; /* custom IFDs are separated from the main ones */
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".
@@ -184,7 +190,6 @@ struct tiff
* - 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() */
@@ -192,10 +197,6 @@ struct tiff
/* SubIFD support */
uint16_t tif_nsubifd; /* remaining subifds to write */
uint64_t tif_subifdoff; /* offset for patching SubIFD link */
/* tiling support */
uint32_t tif_col; /* current column (offset by row too) */
uint32_t tif_curtile; /* current tile for read/write */
tmsize_t tif_tilesize; /* # of bytes in a tile */
/* compression scheme hooks */
int tif_decodestatus;
TIFFBoolMethod tif_fixuptags; /* called in TIFFReadDirectory */
@@ -216,10 +217,10 @@ struct tiff
TIFFVoidMethod tif_cleanup; /* cleanup state routine */
TIFFStripMethod tif_defstripsize; /* calculate/constrain strip size */
TIFFTileMethod tif_deftilesize; /* calculate/constrain tile size */
uint8_t *tif_data; /* compression scheme private data */
/* returns maximum compression ratio for current compression method */
TIFFGetMaxCompressionRatioMethod tif_getmaxcompressionratio;
uint8_t *tif_data; /* compression scheme private data */
/* input/output buffering */
tmsize_t tif_scanlinesize; /* # of bytes in a scanline */
tmsize_t tif_scanlineskew; /* scanline skew for reading strips */
uint8_t *tif_rawdata; /* raw data buffer */
tmsize_t tif_rawdatasize; /* # of bytes in raw data buffer */
tmsize_t tif_rawdataoff; /* rawdata offset within strip */
@@ -295,13 +296,15 @@ struct TIFFOpenOptions
* Default Read/Seek/Write definitions.
*/
#ifndef ReadOK
#define ReadOK(tif, buf, size) (TIFFReadFile((tif), (buf), (size)) == (size))
#define ReadOK(tif, buf, size) \
(TIFFReadFile((tif), (buf), (size)) == (tmsize_t)(size))
#endif
#ifndef SeekOK
#define SeekOK(tif, off) _TIFFSeekOK(tif, off)
#endif
#ifndef WriteOK
#define WriteOK(tif, buf, size) (TIFFWriteFile((tif), (buf), (size)) == (size))
#define WriteOK(tif, buf, size) \
(TIFFWriteFile((tif), (buf), (size)) == (tmsize_t)(size))
#endif
/* NB: the uint32_t casts are to silence certain ANSI-C compilers */
@@ -315,19 +318,19 @@ struct TIFFOpenOptions
(((uint32_t)(x) / (uint32_t)(y)) + \
((((uint32_t)(x) % (uint32_t)(y)) != 0) ? 1 : 0))
#define TIFFhowmany8_32(x) \
(((x)&0x07) ? ((uint32_t)(x) >> 3) + 1 : (uint32_t)(x) >> 3)
#define TIFFroundup_32(x, y) (TIFFhowmany_32(x, y) * (y))
(((x) & 0x07) ? ((uint32_t)(x) >> 3) + 1 : (uint32_t)(x) >> 3)
#define TIFFroundup_32(x, y) ((uint32_t)(TIFFhowmany_32(x, y) * (uint32_t)(y)))
#define TIFFhowmany_64(x, y) \
((((uint64_t)(x)) + (((uint64_t)(y)) - 1)) / ((uint64_t)(y)))
#define TIFFhowmany8_64(x) \
(((x)&0x07) ? ((uint64_t)(x) >> 3) + 1 : (uint64_t)(x) >> 3)
#define TIFFroundup_64(x, y) (TIFFhowmany_64(x, y) * (y))
(((x) & 0x07) ? ((uint64_t)(x) >> 3) + 1 : (uint64_t)(x) >> 3)
#define TIFFroundup_64(x, y) ((uint64_t)(TIFFhowmany_64(x, y) * (uint64_t)(y)))
/* Safe multiply which returns zero if there is an *unsigned* integer overflow.
* This macro is not safe for *signed* integer types */
#define TIFFSafeMultiply(t, v, m) \
((((t)(m) != (t)0) && (((t)(((v) * (m)) / (m))) == (t)(v))) \
? (t)((v) * (m)) \
((((t)(m) != (t)0) && (((t)((((t)(v)) * ((t)(m))) / ((t)(m)))) == (t)(v))) \
? (t)(((t)(v)) * ((t)(m))) \
: (t)0)
#define TIFFmax(A, B) ((A) > (B) ? (A) : (B))
@@ -335,6 +338,10 @@ struct TIFFOpenOptions
#define TIFFArrayCount(a) (sizeof(a) / sizeof((a)[0]))
/* Float/double equality macros that suppress -Wfloat-equal warnings */
#define TIFF_FLOAT_EQ(x, y) (!(fabsf((x) - (y)) > 0.0f))
#define TIFF_DOUBLE_EQ(x, y) (!(fabs((x) - (y)) > 0.0))
/*
Support for large files.
@@ -355,7 +362,7 @@ struct TIFFOpenOptions
*/
#if defined(HAVE_FSEEKO)
#define fseek(stream, offset, whence) fseeko(stream, offset, whence)
#define ftell(stream, offset, whence) ftello(stream, offset, whence)
#define ftell(stream) ftello(stream)
#endif
#endif
#if defined(_WIN32) && \
@@ -459,9 +466,18 @@ extern "C"
extern uint32_t _TIFFMultiply32(TIFF *, uint32_t, uint32_t, const char *);
extern uint64_t _TIFFMultiply64(TIFF *, uint64_t, uint64_t, const char *);
extern uint64_t _TIFFAdd64(TIFF *, uint64_t, uint64_t, const char *);
extern tmsize_t _TIFFMultiplySSize(TIFF *, tmsize_t, tmsize_t,
const char *);
extern tmsize_t _TIFFAddSSize(TIFF *, tmsize_t, tmsize_t, const char *);
extern tmsize_t _TIFFCastUInt64ToSSize(TIFF *, uint64_t, const char *);
extern uint32_t _TIFFCastUInt64ToUInt32(TIFF *, uint64_t, const char *);
extern uint64_t _TIFFComputeRowSize64(TIFF *, uint32_t, uint16_t, uint16_t,
const char *);
extern tmsize_t _TIFFComputeRowOffset(TIFF *, tmsize_t rowstride, uint32_t,
const char *);
extern uint64_t _TIFFComputeBitOffset(TIFF *, uint32_t, uint16_t, uint16_t,
const char *);
extern void *_TIFFCheckMalloc(TIFF *, tmsize_t, tmsize_t, const char *);
extern void *_TIFFCheckRealloc(TIFF *, void *, tmsize_t, tmsize_t,
const char *);
@@ -471,6 +487,8 @@ extern "C"
extern void _TIFFCleanupIFDOffsetAndNumberMaps(TIFF *tif);
extern uint64_t _TIFFStrileSize64(TIFF *tif, uint32_t nrows, int isStrip);
extern tmsize_t _TIFFReadEncodedStripAndAllocBuffer(TIFF *tif,
uint32_t strip,
void **buf,