Upgrade libtiff from 4.7.1 to 4.7.2 Change-Id: I1ba302a3a911b414b99485de73199286dcb1e683 Reviewed-on: https://pdfium-review.googlesource.com/c/pdfium/+/152530 Reviewed-by: Tom Sepez <tsepez@chromium.org> Commit-Queue: Lei Zhang <thestig@chromium.org>
diff --git a/third_party/libtiff/0034-tiff-jpeg-overflow.patch b/third_party/libtiff/0034-tiff-jpeg-overflow.patch deleted file mode 100644 index f03fa94..0000000 --- a/third_party/libtiff/0034-tiff-jpeg-overflow.patch +++ /dev/null
@@ -1,25 +0,0 @@ -commit 0f726d9477a11e15eb67ca349c03907f6cfb82a9 -Author: Mikhail Khachaiants <mkhachaiants@gmail.com> -Date: Mon Dec 1 22:26:34 2025 +0200 - - tif_jpeg: reject mismatched JPEG data precision to avoid write overflow - - Ensure TIFF BitsPerSample matches both BITS_IN_JSAMPLE and the JPEG - header data_precision for JPEG-compressed images. This prevents - under-sized scanline buffers that can lead to write buffer overflows - in jdcolor.c/null_convert when decoding malformed inputs. - -diff --git a/libtiff/tif_jpeg.c b/libtiff/tif_jpeg.c -index aba5f99b..4d6370b5 100644 ---- a/libtiff/tif_jpeg.c -+++ b/libtiff/tif_jpeg.c -@@ -1282,7 +1282,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);
diff --git a/third_party/libtiff/0035-ycbcr-tile-overflow.patch b/third_party/libtiff/0035-ycbcr-tile-overflow.patch deleted file mode 100644 index 7f43f9a..0000000 --- a/third_party/libtiff/0035-ycbcr-tile-overflow.patch +++ /dev/null
@@ -1,48 +0,0 @@ -commit 782a11d6b5b61c6dc21e714950a4af5bf89f023c -Author: Even Rouault <even.rouault@spatialys.com> -Date: Sun Feb 22 23:32:47 2026 +0100 - - TIFFReadRGBAImage(): prevent integer overflow and later heap overflow on images with huge width in YCbCr tile decoding functions - - Fixes https://gitlab.com/libtiff/libtiff/-/issues/787 - -diff --git a/libtiff/tif_getimage.c b/libtiff/tif_getimage.c -index 4543ddda..fa82d091 100644 ---- a/libtiff/tif_getimage.c -+++ b/libtiff/tif_getimage.c -@@ -2224,7 +2224,7 @@ DECLAREContigPutFunc(putcontig8bitYCbCr44tile) - uint32_t *cp1 = cp + w + toskew; - uint32_t *cp2 = cp1 + w + toskew; - uint32_t *cp3 = cp2 + w + toskew; -- int32_t incr = 3 * w + 4 * toskew; -+ const tmsize_t incr = 3 * (tmsize_t)w + 4 * (tmsize_t)toskew; - - (void)y; - /* adjust fromskew */ -@@ -2364,7 +2364,7 @@ DECLAREContigPutFunc(putcontig8bitYCbCr44tile) - DECLAREContigPutFunc(putcontig8bitYCbCr42tile) - { - uint32_t *cp1 = cp + w + toskew; -- int32_t incr = 2 * toskew + w; -+ const tmsize_t incr = 2 * (tmsize_t)toskew + w; - - (void)y; - fromskew = (fromskew / 4) * (4 * 2 + 2); -@@ -2522,7 +2522,7 @@ DECLAREContigPutFunc(putcontig8bitYCbCr41tile) - DECLAREContigPutFunc(putcontig8bitYCbCr22tile) - { - uint32_t *cp2; -- int32_t incr = 2 * toskew + w; -+ const tmsize_t incr = 2 * (tmsize_t)toskew + w; - (void)y; - fromskew = (fromskew / 2) * (2 * 2 + 2); - cp2 = cp + w + toskew; -@@ -2625,7 +2625,7 @@ DECLAREContigPutFunc(putcontig8bitYCbCr21tile) - DECLAREContigPutFunc(putcontig8bitYCbCr12tile) - { - uint32_t *cp2; -- int32_t incr = 2 * toskew + w; -+ const tmsize_t incr = 2 * (tmsize_t)toskew + w; - (void)y; - fromskew = (fromskew / 1) * (1 * 2 + 2); - cp2 = cp + w + toskew;
diff --git a/third_party/libtiff/README.pdfium b/third_party/libtiff/README.pdfium index b275649..17d27a7 100644 --- a/third_party/libtiff/README.pdfium +++ b/third_party/libtiff/README.pdfium
@@ -1,9 +1,9 @@ Name: LibTIFF URL: https://gitlab.com/libtiff/libtiff -Version: 4.7.1 -Revision: 5fe20d0e9aba49a6a350ed533459d1505203838f +Version: 4.7.2 +Revision: d01a94be176f5f6a87f7ee1c0b32e65416aa2b4d Update Mechanism: Manual -CPEPrefix: cpe:/a:libtiff:libtiff:4.7.1 +CPEPrefix: cpe:/a:libtiff:libtiff:4.7.2 Security Critical: yes Shipped: yes License: libtiff @@ -19,5 +19,3 @@ 0028-nstrips-OOM.patch: return error for excess number of tiles/strips. 0031-safe_size_ingtStripContig.patch: return error if the size to read overflow from int32. 0033-avail-out-overflow.patch: signed comparison in PixarLogDecode(). -0034-tiff-jpeg-overflow.patch: reject mismatched JPEG data precision. -0035-ycbcr-tile-overflow.patch: prevent integer overflows in YCbCr tile decoding functions
diff --git a/third_party/libtiff/tif_aux.c b/third_party/libtiff/tif_aux.c index 31b2400..1b2db76 100644 --- a/third_party/libtiff/tif_aux.c +++ b/third_party/libtiff/tif_aux.c
@@ -56,6 +56,21 @@ 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 @@ 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 @@ 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 @@ 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 @@ * 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 @@ 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 @@ * 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 @@ } 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 @@ 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 @@ return (0); *va_arg(ap, const float **) = td->td_refblackwhite; return (1); + default: + break; } return 0; } @@ -390,9 +487,9 @@ 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 @@ { if (val < 0) return 0; - if (val > 0xFFFFFFFFU || val != val) + if (val > 0xFFFFFFFFU || isnan(val)) return 0xFFFFFFFFU; return (uint32_t)val; }
diff --git a/third_party/libtiff/tif_close.c b/third_party/libtiff/tif_close.c index d498010..e60aba7 100644 --- a/third_party/libtiff/tif_close.c +++ b/third_party/libtiff/tif_close.c
@@ -88,7 +88,7 @@ */ TIFFFieldIsAnonymous(fld)) { - _TIFFfreeExt(tif, fld->field_name); + _TIFFfreeExt(tif, (void *)fld->field_name); _TIFFfreeExt(tif, fld); } } @@ -121,7 +121,7 @@ } /************************************************************************/ -/* _TIFFCleanupIFDOffsetAndNumberMaps() */ +/* _TIFFCleanupIFDOffsetAndNumberMaps() */ /************************************************************************/ void _TIFFCleanupIFDOffsetAndNumberMaps(TIFF *tif) @@ -139,7 +139,7 @@ } /************************************************************************/ -/* TIFFClose() */ +/* TIFFClose() */ /************************************************************************/ /**
diff --git a/third_party/libtiff/tif_color.c b/third_party/libtiff/tif_color.c index a52fdac..4a17914 100644 --- a/third_party/libtiff/tif_color.c +++ b/third_party/libtiff/tif_color.c
@@ -55,34 +55,34 @@ 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 @@ _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 @@ * 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 @@ 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 @@ #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 @@ { 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 @@ */ 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 @@ 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); } }
diff --git a/third_party/libtiff/tif_compress.c b/third_party/libtiff/tif_compress.c index c6e17d3..3002083 100644 --- a/third_party/libtiff/tif_compress.c +++ b/third_party/libtiff/tif_compress.c
@@ -139,6 +139,18 @@ } 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 @@ 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 @@ 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 @@ 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 @@ 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 @@ 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 @@ } /************************************************************************/ -/* TIFFGetConfisuredCODECs() */ +/* TIFFGetConfiguredCODECs() */ /************************************************************************/ /** @@ -258,7 +282,7 @@ * or NULL if function failed. */ -TIFFCodec *TIFFGetConfiguredCODECs() +TIFFCodec *TIFFGetConfiguredCODECs(void) { int i = 1; codec_t *cd; @@ -268,8 +292,8 @@ 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 @@ { 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);
diff --git a/third_party/libtiff/tif_dir.c b/third_party/libtiff/tif_dir.c index 7421c73..999a245 100644 --- a/third_party/libtiff/tif_dir.c +++ b/third_party/libtiff/tif_dir.c
@@ -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 @@ } 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 @@ { 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 @@ /* * 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 @@ 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 @@ 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 @@ 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 @@ 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 @@ 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 @@ 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 @@ } ma = (uint32_t)len; } - tv->count = ma; + tv->count = (int)ma; setByteArray(tif, &tv->value, mb, ma, 1); } else @@ -792,9 +807,9 @@ 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 @@ { 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 @@ * 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 @@ { 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 @@ 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 @@ 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 @@ 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 @@ _TIFFmemcpy(val, &v2, tv_size); } break; + case TIFF_NOTYPE: + case TIFF_ASCII: default: _TIFFmemset(val, 0, tv_size); status = 0; @@ -1345,7 +1366,7 @@ 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 @@ case SAMPLEFORMAT_VOID: *va_arg(ap, uint16_t *) = DATATYPE_VOID; break; + default: + break; } break; case TIFFTAG_SAMPLEFORMAT: @@ -1562,6 +1585,8 @@ *va_arg(ap, double *) = *(double *)val; ret_val = 1; break; + case TIFF_NOTYPE: + case TIFF_ASCII: default: ret_val = 0; break; @@ -1614,6 +1639,21 @@ } /* + * 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. */ void TIFFFreeDirectory(TIFF *tif) @@ -1664,6 +1704,7 @@ 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 @@ 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 @@ 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 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 @@ 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 @@ *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 @@ { 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 @@ 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 @@ "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 @@ 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 @@ else { uint64_t dircount64; - uint16_t dircount16; if (!SeekOK(tif, *nextdiroff) || !ReadOK(tif, &dircount64, sizeof(uint64_t))) { @@ -1991,11 +2029,10 @@ __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 @@ 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--;
diff --git a/third_party/libtiff/tif_dir.h b/third_party/libtiff/tif_dir.h index 44270f7..aed9722 100644 --- a/third_party/libtiff/tif_dir.h +++ b/third_party/libtiff/tif_dir.h
@@ -104,6 +104,16 @@ 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 @@ 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 @@ #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 @@ 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 */ };
diff --git a/third_party/libtiff/tif_dirinfo.c b/third_party/libtiff/tif_dirinfo.c index c038497..9218661 100644 --- a/third_party/libtiff/tif_dirinfo.c +++ b/third_party/libtiff/tif_dirinfo.c
@@ -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 @@ /*--: 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 @@ {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 @@ { 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 @@ 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 @@ /* 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 @@ 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 @@ 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 @@ 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 @@ 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 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 @@ 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 @@ 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 @@ * 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 @@ return TIFF_SETGET_UINT64; case TIFF_SLONG8: return TIFF_SETGET_SINT64; + case TIFF_NOTYPE: default: return TIFF_SETGET_UNDEFINED; } @@ -1062,6 +1156,7 @@ 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 @@ 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 @@ 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 @@ 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 @@ case TIFFTAG_JPEGPROC: case TIFFTAG_JPEGRESTARTINTERVAL: return 1; + default: + break; } break; case COMPRESSION_CCITTRLE: @@ -1329,6 +1431,8 @@ if (tif->tif_dir.td_compression == COMPRESSION_CCITTFAX4) return 1; break; + default: + break; } break; case COMPRESSION_JBIG: @@ -1359,6 +1463,8 @@ if (tag == TIFFTAG_LERC_PARAMETERS) return 1; break; + default: + break; } return 0; }
diff --git a/third_party/libtiff/tif_dirread.c b/third_party/libtiff/tif_dirread.c index 88e1bc6..3df651e 100644 --- a/third_party/libtiff/tif_dirread.c +++ b/third_party/libtiff/tif_dirread.c
@@ -597,7 +597,7 @@ 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 @@ return (TIFFReadDirEntryErrOk); } case TIFF_LONG: + case TIFF_IFD: TIFFReadDirEntryCheckedLong(tif, direntry, value); return (TIFFReadDirEntryErrOk); case TIFF_SLONG: @@ -708,6 +709,7 @@ return (TIFFReadDirEntryErrOk); } case TIFF_LONG8: + case TIFF_IFD8: { uint64_t m; err = TIFFReadDirEntryCheckedLong8(tif, direntry, &m); @@ -857,6 +859,7 @@ return (TIFFReadDirEntryErrOk); } case TIFF_LONG: + case TIFF_IFD: { uint32_t m; TIFFReadDirEntryCheckedLong(tif, direntry, &m); @@ -874,6 +877,7 @@ return (TIFFReadDirEntryErrOk); } case TIFF_LONG8: + case TIFF_IFD8: err = TIFFReadDirEntryCheckedLong8(tif, direntry, value); return (err); case TIFF_SLONG8: @@ -1058,7 +1062,7 @@ 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 @@ *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 @@ 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 @@ * 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 @@ *value = (uint8_t *)origdata; return (TIFFReadDirEntryErrOk); } + default: + break; } data = (uint8_t *)_TIFFmallocExt(tif, count); if (data == 0) @@ -1557,6 +1565,8 @@ } } break; + default: + break; } _TIFFfreeExt(tif, origdata); if (err != TIFFReadDirEntryErrOk) @@ -1620,6 +1630,8 @@ case TIFF_SBYTE: *value = (int8_t *)origdata; return (TIFFReadDirEntryErrOk); + default: + break; } data = (int8_t *)_TIFFmallocExt(tif, count); if (data == 0) @@ -1737,6 +1749,8 @@ } } break; + default: + break; } _TIFFfreeExt(tif, origdata); if (err != TIFFReadDirEntryErrOk) @@ -1802,6 +1816,8 @@ *value = (uint16_t *)origdata; return (TIFFReadDirEntryErrOk); } + default: + break; } data = (uint16_t *)_TIFFmallocExt(tif, count * 2); if (data == 0) @@ -1910,6 +1926,8 @@ } } break; + default: + break; } _TIFFfreeExt(tif, origdata); if (err != TIFFReadDirEntryErrOk) @@ -1975,6 +1993,8 @@ 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 @@ } } break; + default: + break; } _TIFFfreeExt(tif, origdata); if (err != TIFFReadDirEntryErrOk) @@ -2106,6 +2128,8 @@ case TIFF_SLONG: case TIFF_LONG8: case TIFF_SLONG8: + case TIFF_IFD: + case TIFF_IFD8: break; default: return (TIFFReadDirEntryErrType); @@ -2119,6 +2143,7 @@ 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 @@ *value = (uint32_t *)origdata; return (TIFFReadDirEntryErrOk); } + default: + break; } data = (uint32_t *)_TIFFmallocExt(tif, count * 4); if (data == 0) @@ -2213,6 +2240,7 @@ } break; case TIFF_LONG8: + case TIFF_IFD8: { uint64_t *ma; uint32_t *mb; @@ -2248,6 +2276,8 @@ } } break; + default: + break; } _TIFFfreeExt(tif, origdata); if (err != TIFFReadDirEntryErrOk) @@ -2313,6 +2343,8 @@ 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 @@ } } break; + default: + break; } _TIFFfreeExt(tif, origdata); if (err != TIFFReadDirEntryErrOk) @@ -2439,6 +2473,8 @@ case TIFF_SLONG: case TIFF_LONG8: case TIFF_SLONG8: + case TIFF_IFD: + case TIFF_IFD8: break; default: return (TIFFReadDirEntryErrType); @@ -2453,6 +2489,7 @@ 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 @@ *value = (uint64_t *)origdata; return (TIFFReadDirEntryErrOk); } + default: + break; } data = (uint64_t *)_TIFFmallocExt(tif, count * 8); if (data == 0) @@ -2547,6 +2586,7 @@ } break; case TIFF_LONG: + case TIFF_IFD: { uint32_t *ma; uint64_t *mb; @@ -2579,6 +2619,8 @@ } } break; + default: + break; } _TIFFfreeExt(tif, origdata); if (err != TIFFReadDirEntryErrOk) @@ -2651,6 +2693,8 @@ 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 @@ } } break; + default: + break; } _TIFFfreeExt(tif, origdata); *value = data; @@ -2787,8 +2833,11 @@ 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 @@ 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 @@ 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 @@ *mb++ = (double)(*ma++); } break; + default: + break; } _TIFFfreeExt(tif, origdata); *value = data; @@ -3244,6 +3300,8 @@ 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 @@ } } break; + default: + break; } _TIFFfreeExt(tif, origdata); *value = data; @@ -3283,13 +3343,42 @@ 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 @@ { 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 @@ 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 @@ "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 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 @@ /* 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 @@ /* 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 @@ { 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 @@ 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 @@ * 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 @@ (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); @@ -5106,7 +5208,7 @@ 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 @@ -5172,16 +5274,10 @@ 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); @@ -5189,8 +5285,8 @@ 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); @@ -5228,7 +5324,7 @@ "ascending order"); break; } - m = o->tdir_tag + 1; + m = o->tdir_tag + 1U; } } @@ -5276,7 +5372,7 @@ break; mb--; } - *fii = mb; + *fii = (uint32_t)mb; } /* @@ -5316,7 +5412,8 @@ { 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) { @@ -5341,7 +5438,8 @@ * 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( @@ -5523,15 +5621,17 @@ 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( @@ -5794,7 +5894,7 @@ { TIFFErrorExtR(tif, "_TIFFCheckDirNumberAndOffset", "Cannot handle more than %u TIFF directories", - TIFF_MAX_DIR_COUNT); + (unsigned)TIFF_MAX_DIR_COUNT); return 0; } @@ -6056,7 +6156,7 @@ "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); @@ -6109,9 +6209,9 @@ */ 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; @@ -6120,7 +6220,7 @@ { _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) @@ -6135,9 +6235,9 @@ 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; @@ -6146,7 +6246,7 @@ { _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) @@ -6185,7 +6285,7 @@ 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"); @@ -6194,7 +6294,8 @@ } else { - _TIFFmemcpy(origdir, tif->tif_base + off, dircount16 * dirsize); + _TIFFmemcpy(origdir, tif->tif_base + off, + (tmsize_t)dircount16 * dirsize); } if (nextdiroff) { @@ -6202,9 +6303,9 @@ 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, @@ -6215,9 +6316,9 @@ } 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, @@ -6363,8 +6464,8 @@ /* 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) @@ -6506,7 +6607,7 @@ { if (!EvaluateIFDdatasizeReading(tif, dp)) return 0; - if (!TIFFSetField(tif, dp->tdir_tag, data)) + if (!TIFFSetField(tif, dp->tdir_tag, (double)data)) return (0); } } @@ -6918,6 +7019,41 @@ } } 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; @@ -6946,8 +7082,8 @@ "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) @@ -7317,8 +7453,8 @@ "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) @@ -7632,6 +7768,11 @@ } } 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; @@ -7708,9 +7849,10 @@ } 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; } @@ -7874,7 +8016,7 @@ */ 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; @@ -7889,7 +8031,7 @@ /* 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]; @@ -8040,7 +8182,7 @@ 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 @@ -8119,7 +8261,7 @@ 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; @@ -8127,7 +8269,7 @@ 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) @@ -8262,9 +8404,9 @@ } #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) @@ -8298,7 +8440,7 @@ if (~((*parray)[strile]) == 0) { - if (!_TIFFPartialReadStripArray(tif, dirent, strile, *parray)) + if (!_TIFFPartialReadStripArray(tif, dirent, (int)strile, *parray)) { (*parray)[strile] = 0; return 0; @@ -8316,10 +8458,26 @@ 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) @@ -8390,7 +8548,7 @@ 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 */ @@ -8398,7 +8556,8 @@ (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); @@ -8406,7 +8565,7 @@ 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 */
diff --git a/third_party/libtiff/tif_dirwrite.c b/third_party/libtiff/tif_dirwrite.c index bc5ada0..5da087e 100644 --- a/third_party/libtiff/tif_dirwrite.c +++ b/third_party/libtiff/tif_dirwrite.c
@@ -365,7 +365,7 @@ } 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 @@ { 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 @@ while (1) { uint64_t dircount64; - uint16_t dircount; uint64_t nextnextdir; if (!SeekOK(tif, nextdir) || !ReadOK(tif, &dircount64, 8)) @@ -435,8 +434,8 @@ "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 @@ { 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 @@ } 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 @@ } 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 @@ } 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 @@ { 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 @@ 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 @@ { 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 @@ { 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 @@ /*-- 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 @@ { 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 @@ /*-- 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 @@ 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 @@ 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 @@ 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 @@ { 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 @@ { 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 @@ { 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 @@ { 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 @@ { 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 @@ { 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 @@ { 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 @@ 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 @@ 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 @@ 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 @@ ** 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 @@ 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 @@ ** 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 @@ ** 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 @@ } 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 @@ ** 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 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 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 @@ 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 @@ 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 @@ 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 @@ 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 @@ } 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 @@ 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 @@ } 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 @@ 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 @@ } 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 @@ 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 @@ } 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 @@ *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 @@ 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 @@ 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 @@ 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 @@ } 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 @@ 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 @@ 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 @@ "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 @@ 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 @@ if (entry_tag == tag) break; - read_offset += dirsize; + read_offset += (uint64_t)dirsize; } if (entry_tag != tag) @@ -3584,13 +3702,13 @@ 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 @@ 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 @@ 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 @@ 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 @@ 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 @@ /* -------------------------------------------------------------------- */ /* 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)
diff --git a/third_party/libtiff/tif_dumpmode.c b/third_party/libtiff/tif_dumpmode.c index 267d5d2..4e3133f 100644 --- a/third_party/libtiff/tif_dumpmode.c +++ b/third_party/libtiff/tif_dumpmode.c
@@ -80,7 +80,7 @@ "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 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); }
diff --git a/third_party/libtiff/tif_fax3.c b/third_party/libtiff/tif_fax3.c index 34e1c78..06b9508 100644 --- a/third_party/libtiff/tif_fax3.c +++ b/third_party/libtiff/tif_fax3.c
@@ -123,7 +123,7 @@ 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 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 @@ "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 @@ 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 @@ 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 @@ 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 @@ 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 @@ { 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 @@ 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 @@ 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 @@ { 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 @@ 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 @@ 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 @@ { \ 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 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 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 @@ #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 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 @@ align = sp->bit + (8 - align); else align = sp->bit - align; - tparm = align; + tparm = (unsigned int)align; _PutBits(tif, 0, tparm); } } @@ -862,8 +869,8 @@ } _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 @@ 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 @@ 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 @@ 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 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 @@ : 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 @@ } 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 @@ case CLEANFAXDATA_UNCLEAN: fprintf(fd, " uncorrected errors"); break; + default: + break; } fprintf(fd, " (%" PRIu16 " = 0x%" PRIx16 ")\n", sp->cleanfaxdata, sp->cleanfaxdata); @@ -1500,6 +1518,22 @@ (*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 @@ tif->tif_encodetile = Fax3Encode; tif->tif_close = Fax3Close; tif->tif_cleanup = Fax3Cleanup; + tif->tif_getmaxcompressionratio = Fax3GetMaxCompressionRatio; return (1); } @@ -1626,10 +1661,10 @@ 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 @@ 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 @@ 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 @@ 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 @@ 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 @@ 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 @@ 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 @@ 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 @@ 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 @@ 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. */
diff --git a/third_party/libtiff/tif_fax3.h b/third_party/libtiff/tif_fax3.h index c3100ce..60d709c 100644 --- a/third_party/libtiff/tif_fax3.h +++ b/third_party/libtiff/tif_fax3.h
@@ -267,14 +267,14 @@ { \ 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 @@ { \ 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 @@ 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 @@ } \ } \ doneWhite1d: \ - if (a0 >= lastx) \ + if (a0 >= (int)lastx) \ goto done1d; \ for (;;) \ { \ @@ -409,8 +410,8 @@ 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 @@ } \ } \ doneBlack1d: \ - if (a0 >= lastx) \ + if (a0 >= (int)lastx) \ goto done1d; \ if (*(pa - 1) == 0 && *(pa - 2) == 0) \ pa -= 2; \ @@ -439,17 +440,18 @@ 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 @@ #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 @@ 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 @@ 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 @@ 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 @@ 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 @@ 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 @@ 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); \
diff --git a/third_party/libtiff/tif_getimage.c b/third_party/libtiff/tif_getimage.c index ee128c0..316284d 100644 --- a/third_party/libtiff/tif_getimage.c +++ b/third_party/libtiff/tif_getimage.c
@@ -29,6 +29,7 @@ */ #include "tiffiop.h" #include <limits.h> +#include <math.h> #include <stdio.h> static int gtTileContig(TIFFRGBAImage *, uint32_t *, uint32_t, uint32_t); @@ -57,21 +58,21 @@ static const TIFFDisplay display_sRGB = { {/* XYZ -> luminance matrix */ - {3.2410F, -1.5374F, -0.4986F}, - {-0.9692F, 1.8760F, 0.0416F}, - {0.0556F, -0.2040F, 1.0570F}}, - 100.0F, - 100.0F, - 100.0F, /* Light o/p for reference white */ + {3.2410f, -1.5374f, -0.4986f}, + {-0.9692f, 1.8760f, 0.0416f}, + {0.0556f, -0.2040f, 1.0570f}}, + 100.0f, + 100.0f, + 100.0f, /* Light o/p for reference white */ 255, 255, 255, /* Pixel values for ref. white */ - 1.0F, - 1.0F, - 1.0F, /* Residual light o/p for black pixel */ - 2.4F, - 2.4F, - 2.4F, /* Gamma values for the three guns */ + 1.0f, + 1.0f, + 1.0f, /* Residual light o/p for black pixel */ + 2.4f, + 2.4f, + 2.4f, /* Gamma values for the three guns */ }; /* @@ -316,7 +317,7 @@ uint16_t compress; int colorchannels; uint16_t *red_orig, *green_orig, *blue_orig; - int n_color; + uint32_t n_color; if (!TIFFRGBAImageOK(tif, emsg)) return 0; @@ -372,6 +373,8 @@ case EXTRASAMPLE_UNASSALPHA: /* data is not pre-multiplied */ img->alpha = sampleinfo[0]; break; + default: + break; } } @@ -421,13 +424,13 @@ } /* copy the colormaps so we can modify them */ - n_color = (1U << img->bitspersample); - img->redcmap = - (uint16_t *)_TIFFmallocExt(tif, sizeof(uint16_t) * n_color); - img->greencmap = - (uint16_t *)_TIFFmallocExt(tif, sizeof(uint16_t) * n_color); - img->bluecmap = - (uint16_t *)_TIFFmallocExt(tif, sizeof(uint16_t) * n_color); + n_color = (uint32_t)(1U << img->bitspersample); + img->redcmap = (uint16_t *)_TIFFmallocExt( + tif, (tmsize_t)(sizeof(uint16_t) * (size_t)n_color)); + img->greencmap = (uint16_t *)_TIFFmallocExt( + tif, (tmsize_t)(sizeof(uint16_t) * (size_t)n_color)); + img->bluecmap = (uint16_t *)_TIFFmallocExt( + tif, (tmsize_t)(sizeof(uint16_t) * (size_t)n_color)); if (!img->redcmap || !img->greencmap || !img->bluecmap) { snprintf(emsg, EMSG_BUF_SIZE, @@ -604,7 +607,7 @@ * Width is checked in img->get() function individually. */ if (0 <= img->row_offset && (uint32_t)img->row_offset < img->height) { - uint32_t hx = img->height - img->row_offset; + uint32_t hx = img->height - (uint32_t)img->row_offset; if (h > hx) { /* Adapt parameters to read only available lines and put image @@ -617,7 +620,7 @@ { TIFFErrorExtR(img->tif, TIFFFileName(img->tif), "Error in TIFFRGBAImageGet: row offset %d exceeds " - "image height %d", + "image height %u", img->row_offset, img->height); return 0; } @@ -751,13 +754,13 @@ if (0 <= img->col_offset && (uint32_t)img->col_offset < img->width) { - wmin = TIFFmin(w, img->width - img->col_offset); + wmin = TIFFmin(w, img->width - (uint32_t)img->col_offset); } else { TIFFErrorExtR(tif, TIFFFileName(tif), "Error in gtTileContig: column offset %d exceeds " - "image width %d", + "image width %u", img->col_offset, img->width); return 0; } @@ -785,7 +788,7 @@ } else { - if (tw > ((int64_t)INT_MAX + w)) + if (tw > ((int64_t)INT_MAX + w) || w > ((int64_t)INT_MAX + tw)) { TIFFErrorExtR(tif, TIFFFileName(tif), "%s", "unsupported tile size (too wide)"); @@ -804,9 +807,9 @@ /* * Leftmost tile is clipped on left side if col_offset > 0. */ - leftmost_fromskew = img->col_offset % tw; - leftmost_tw = tw - leftmost_fromskew; - int64_t skew_i64 = (int64_t)toskew + leftmost_fromskew; + leftmost_fromskew = (int32_t)((uint32_t)img->col_offset % tw); + leftmost_tw = (uint32_t)((int32_t)tw - leftmost_fromskew); + int64_t skew_i64 = (int64_t)toskew + (int64_t)(int32_t)leftmost_fromskew; if (skew_i64 > INT_MAX || skew_i64 < INT_MIN) { TIFFErrorExtR(tif, TIFFFileName(tif), "%s %" PRId64, "Invalid skew", @@ -816,34 +819,36 @@ leftmost_toskew = (int32_t)skew_i64; for (row = 0; ret != 0 && row < h; row += nrow) { - rowstoread = th - (row + img->row_offset) % th; + rowstoread = th - ((uint32_t)row + (uint32_t)img->row_offset) % th; nrow = (row + rowstoread > h ? h - row : rowstoread); fromskew = leftmost_fromskew; this_tw = leftmost_tw; this_toskew = leftmost_toskew; tocol = 0; - col = img->col_offset; + col = (uint32_t)img->col_offset; /* wmin: only write imagewidth if raster is bigger. */ while (tocol < wmin) { if (_TIFFReadTileAndAllocBuffer(tif, (void **)&buf, bufsize, col, - row + img->row_offset, 0, - 0) == (tmsize_t)(-1) && + (uint32_t)row + + (uint32_t)img->row_offset, + 0, 0) == (tmsize_t)(-1) && (buf == NULL || img->stoponerr)) { ret = 0; break; } - pos = ((row + img->row_offset) % th) * TIFFTileRowSize(tif) + + pos = (((uint32_t)row + (uint32_t)img->row_offset) % th) * + TIFFTileRowSize(tif) + ((tmsize_t)fromskew * img->samplesperpixel); if (tocol + this_tw > wmin) { /* * Rightmost tile is clipped on right side. */ - fromskew = tw - (wmin - tocol); - this_tw = tw - fromskew; - this_toskew = toskew + fromskew; + fromskew = (int32_t)(tw - (wmin - tocol)); + this_tw = (uint32_t)((int32_t)tw - fromskew); + this_toskew = (int32_t)(toskew + (int32_t)(uint32_t)fromskew); } tmsize_t roffset = (tmsize_t)y * w + tocol; (*put)(img, raster + roffset, tocol, y, this_tw, nrow, fromskew, @@ -859,7 +864,8 @@ this_toskew = toskew; } - y += ((flip & FLIP_VERTICALLY) ? -(int32_t)nrow : (int32_t)nrow); + y += (uint32_t)((flip & FLIP_VERTICALLY) ? -(int32_t)nrow + : (int32_t)nrow); } _TIFFfreeExt(img->tif, buf); @@ -869,7 +875,7 @@ for (line = 0; line < h; line++) { - uint32_t *left = raster + (line * w); + uint32_t *left = raster + (size_t)line * w; /* Use wmin to only flip horizontally data in place and not complete * raster-row. */ uint32_t *right = left + wmin - 1; @@ -924,13 +930,13 @@ uint32_t wmin; if (0 <= img->col_offset && (uint32_t)img->col_offset < img->width) { - wmin = TIFFmin(w, img->width - img->col_offset); + wmin = TIFFmin(w, img->width - (uint32_t)img->col_offset); } else { TIFFErrorExtR(tif, TIFFFileName(tif), "Error in gtTileSeparate: column offset %d exceeds " - "image width %d", + "image width %u", img->col_offset, img->width); return 0; } @@ -960,7 +966,7 @@ } else { - if (tw > ((int64_t)INT_MAX + w)) + if (tw > ((int64_t)INT_MAX + w) || w > ((int64_t)INT_MAX + tw)) { TIFFErrorExtR(tif, TIFFFileName(tif), "%s", "unsupported tile size (too wide)"); @@ -992,9 +998,9 @@ /* * Leftmost tile is clipped on left side if col_offset > 0. */ - leftmost_fromskew = img->col_offset % tw; - leftmost_tw = tw - leftmost_fromskew; - int64_t skew_i64 = (int64_t)toskew + leftmost_fromskew; + leftmost_fromskew = (int32_t)((uint32_t)img->col_offset % tw); + leftmost_tw = (uint32_t)((int32_t)tw - leftmost_fromskew); + int64_t skew_i64 = (int64_t)toskew + (int64_t)(int32_t)leftmost_fromskew; if (skew_i64 > INT_MAX || skew_i64 < INT_MIN) { TIFFErrorExtR(tif, TIFFFileName(tif), "%s %" PRId64, "Invalid skew", @@ -1004,21 +1010,22 @@ leftmost_toskew = (int32_t)skew_i64; for (row = 0; ret != 0 && row < h; row += nrow) { - rowstoread = th - (row + img->row_offset) % th; + rowstoread = th - ((uint32_t)row + (uint32_t)img->row_offset) % th; nrow = (row + rowstoread > h ? h - row : rowstoread); fromskew = leftmost_fromskew; this_tw = leftmost_tw; this_toskew = leftmost_toskew; tocol = 0; - col = img->col_offset; + col = (uint32_t)img->col_offset; /* wmin: only write imagewidth if raster is bigger. */ while (tocol < wmin) { if (buf == NULL) { - if (_TIFFReadTileAndAllocBuffer(tif, (void **)&buf, bufsize, - col, row + img->row_offset, 0, - 0) == (tmsize_t)(-1) && + if (_TIFFReadTileAndAllocBuffer( + tif, (void **)&buf, bufsize, col, + (uint32_t)((int32_t)row + img->row_offset), 0, + 0) == (tmsize_t)(-1) && (buf == NULL || img->stoponerr)) { ret = 0; @@ -1037,32 +1044,36 @@ pa = (alpha ? (p2 + tilesize) : NULL); } } - else if (TIFFReadTile(tif, p0, col, row + img->row_offset, 0, 0) == - (tmsize_t)(-1) && + else if (TIFFReadTile(tif, p0, col, + (uint32_t)((int32_t)row + img->row_offset), 0, + 0) == (tmsize_t)(-1) && img->stoponerr) { ret = 0; break; } if (colorchannels > 1 && - TIFFReadTile(tif, p1, col, row + img->row_offset, 0, 1) == - (tmsize_t)(-1) && + TIFFReadTile(tif, p1, col, + (uint32_t)((int32_t)row + img->row_offset), 0, + (uint16_t)1) == (tmsize_t)(-1) && img->stoponerr) { ret = 0; break; } if (colorchannels > 1 && - TIFFReadTile(tif, p2, col, row + img->row_offset, 0, 2) == - (tmsize_t)(-1) && + TIFFReadTile(tif, p2, col, + (uint32_t)((int32_t)row + img->row_offset), 0, + (uint16_t)2) == (tmsize_t)(-1) && img->stoponerr) { ret = 0; break; } if (alpha && - TIFFReadTile(tif, pa, col, row + img->row_offset, 0, - colorchannels) == (tmsize_t)(-1) && + TIFFReadTile(tif, pa, col, + (uint32_t)((int32_t)row + img->row_offset), 0, + (uint16_t)colorchannels) == (tmsize_t)(-1) && img->stoponerr) { ret = 0; @@ -1071,16 +1082,17 @@ /* For SEPARATE the pos-offset is per sample and should not be * multiplied by img->samplesperpixel. */ - pos = ((row + img->row_offset) % th) * TIFFTileRowSize(tif) + + pos = (tmsize_t)((uint32_t)((int32_t)row + img->row_offset) % th) * + TIFFTileRowSize(tif) + (tmsize_t)fromskew; if (tocol + this_tw > wmin) { /* * Rightmost tile is clipped on right side. */ - fromskew = tw - (wmin - tocol); - this_tw = tw - fromskew; - this_toskew = toskew + fromskew; + fromskew = (int32_t)(tw - (wmin - tocol)); + this_tw = (uint32_t)((int32_t)tw - fromskew); + this_toskew = (int32_t)(toskew + (int32_t)(uint32_t)fromskew); } tmsize_t roffset = (tmsize_t)y * w + tocol; (*put)(img, raster + roffset, tocol, y, this_tw, nrow, fromskew, @@ -1097,7 +1109,8 @@ this_toskew = toskew; } - y += ((flip & FLIP_VERTICALLY) ? -(int32_t)nrow : (int32_t)nrow); + y += (uint32_t)((flip & FLIP_VERTICALLY) ? -(int32_t)nrow + : (int32_t)nrow); } if (flip & FLIP_HORIZONTALLY) @@ -1106,7 +1119,7 @@ for (line = 0; line < h; line++) { - uint32_t *left = raster + (line * w); + uint32_t *left = raster + (size_t)line * w; /* Use wmin to only flip horizontally data in place and not complete * raster-row. */ uint32_t *right = left + wmin - 1; @@ -1155,13 +1168,13 @@ uint32_t wmin; if (0 <= img->col_offset && (uint32_t)img->col_offset < imagewidth) { - wmin = TIFFmin(w, imagewidth - img->col_offset); + wmin = TIFFmin(w, imagewidth - (uint32_t)img->col_offset); } else { TIFFErrorExtR(tif, TIFFFileName(tif), "Error in gtStripContig: column offset %d exceeds " - "image width %d", + "image width %u", img->col_offset, imagewidth); return 0; } @@ -1201,7 +1214,7 @@ y = 0; /* Skew forward to the end of the raster width of the row currently * copied. */ - toskew = w - wmin; + toskew = (int32_t)(w - wmin); } TIFFGetFieldDefaulted(tif, TIFFTAG_ROWSPERSTRIP, &rowsperstrip); @@ -1212,16 +1225,18 @@ } scanline = TIFFScanlineSize(tif); - fromskew = (w < imagewidth ? imagewidth - w : 0); + fromskew = (int32_t)(w < imagewidth ? imagewidth - w : 0); for (row = 0; row < h; row += nrow) { uint32_t temp; - rowstoread = rowsperstrip - (row + img->row_offset) % rowsperstrip; + rowstoread = rowsperstrip - + (uint32_t)((int32_t)row + img->row_offset) % rowsperstrip; nrow = (row + rowstoread > h ? h - row : rowstoread); nrowsub = nrow; if ((nrowsub % subsamplingver) != 0) nrowsub += subsamplingver - nrowsub % subsamplingver; - temp = (row + img->row_offset) % rowsperstrip + nrowsub; + temp = + (uint32_t)((int32_t)row + img->row_offset) % rowsperstrip + nrowsub; if (scanline > 0 && temp > (size_t)(TIFF_TMSIZE_T_MAX / scanline)) { TIFFErrorExtR(tif, TIFFFileName(tif), @@ -1229,21 +1244,27 @@ return 0; } if (_TIFFReadEncodedStripAndAllocBuffer( - tif, TIFFComputeStrip(tif, row + img->row_offset, 0), + tif, + TIFFComputeStrip(tif, + (uint32_t)((int32_t)row + img->row_offset), 0), (void **)(&buf), maxstripsize, - temp * scanline) == (tmsize_t)(-1) && + (tmsize_t)((size_t)temp * (size_t)scanline)) == + (tmsize_t)(-1) && (buf == NULL || img->stoponerr)) { ret = 0; break; } - pos = ((row + img->row_offset) % rowsperstrip) * scanline + + pos = (tmsize_t)((uint32_t)((int32_t)row + img->row_offset) % + rowsperstrip) * + scanline + ((tmsize_t)img->col_offset * img->samplesperpixel); tmsize_t roffset = (tmsize_t)y * w; (*put)(img, raster + roffset, 0, y, wmin, nrow, fromskew, toskew, buf + pos); - y += ((flip & FLIP_VERTICALLY) ? -(int32_t)nrow : (int32_t)nrow); + y += (uint32_t)((flip & FLIP_VERTICALLY) ? -(int32_t)nrow + : (int32_t)nrow); } if (flip & FLIP_HORIZONTALLY) @@ -1256,7 +1277,7 @@ for (line = 0; line < h; line++) { - uint32_t *left = raster + (line * w); + uint32_t *left = raster + (size_t)line * w; /* Use wmin to only flip horizontally data in place and not complete * raster-row. */ uint32_t *right = left + wmin - 1; @@ -1306,13 +1327,13 @@ uint32_t wmin; if (0 <= img->col_offset && (uint32_t)img->col_offset < imagewidth) { - wmin = TIFFmin(w, imagewidth - img->col_offset); + wmin = TIFFmin(w, imagewidth - (uint32_t)img->col_offset); } else { TIFFErrorExtR(tif, TIFFFileName(tif), "Error in gtStripSeparate: column offset %d exceeds " - "image width %d", + "image width %u", img->col_offset, imagewidth); return 0; } @@ -1343,7 +1364,7 @@ y = 0; /* Skew forward to the end of the raster width of the row currently * written. */ - toskew = w - wmin; + toskew = (int32_t)(w - wmin); } switch (img->photometric) @@ -1367,14 +1388,16 @@ } scanline = TIFFScanlineSize(tif); - fromskew = (w < imagewidth ? imagewidth - w : 0); + fromskew = (int32_t)(w < imagewidth ? imagewidth - w : 0); for (row = 0; row < h; row += nrow) { uint32_t temp; - rowstoread = rowsperstrip - (row + img->row_offset) % rowsperstrip; + rowstoread = + rowsperstrip - + ((uint32_t)((int32_t)row + img->row_offset) % rowsperstrip); nrow = (row + rowstoread > h ? h - row : rowstoread); - offset_row = row + img->row_offset; - temp = (row + img->row_offset) % rowsperstrip + nrow; + offset_row = (uint32_t)((int32_t)row + img->row_offset); + temp = (uint32_t)((int32_t)row + img->row_offset) % rowsperstrip + nrow; if (scanline > 0 && temp > (size_t)(TIFF_TMSIZE_T_MAX / scanline)) { TIFFErrorExtR(tif, TIFFFileName(tif), @@ -1441,12 +1464,15 @@ /* For SEPARATE the pos-offset is per sample and should not be * multiplied by img->samplesperpixel. */ - pos = ((row + img->row_offset) % rowsperstrip) * scanline + + pos = (tmsize_t)((uint32_t)((int32_t)row + img->row_offset) % + rowsperstrip) * + scanline + (tmsize_t)img->col_offset; tmsize_t roffset = (tmsize_t)y * w; (*put)(img, raster + roffset, 0, y, wmin, nrow, fromskew, toskew, p0 + pos, p1 + pos, p2 + pos, (alpha ? (pa + pos) : NULL)); - y += ((flip & FLIP_VERTICALLY) ? -(int32_t)nrow : (int32_t)nrow); + y += (uint32_t)((flip & FLIP_VERTICALLY) ? -(int32_t)nrow + : (int32_t)nrow); } if (flip & FLIP_HORIZONTALLY) @@ -1455,7 +1481,7 @@ for (line = 0; line < h; line++) { - uint32_t *left = raster + (line * w); + uint32_t *left = raster + (size_t)line * w; /* Use wmin to only flip horizontally data in place and not complete * raster-row. */ uint32_t *right = left + wmin - 1; @@ -1511,6 +1537,9 @@ op; /*-fallthrough*/ \ case 1: \ op; \ + break; \ + default: \ + break; \ } #define CASE4(x, op) \ switch (x) \ @@ -1521,6 +1550,9 @@ op; /*-fallthrough*/ \ case 1: \ op; \ + break; \ + default: \ + break; \ } #define NOP @@ -1587,13 +1619,6 @@ #define PACK4(r, g, b, a) \ ((uint32_t)(r) | ((uint32_t)(g) << 8) | ((uint32_t)(b) << 16) | \ ((uint32_t)(a) << 24)) -#define W2B(v) (((v) >> 8) & 0xff) -/* TODO: PACKW should have be made redundant in favor of Bitdepth16To8 LUT */ -#define PACKW(r, g, b) \ - ((uint32_t)W2B(r) | ((uint32_t)W2B(g) << 8) | ((uint32_t)W2B(b) << 16) | A1) -#define PACKW4(r, g, b, a) \ - ((uint32_t)W2B(r) | ((uint32_t)W2B(g) << 8) | ((uint32_t)W2B(b) << 16) | \ - ((uint32_t)W2B(a) << 24)) #define DECLAREContigPutFunc(name) \ static void name(TIFFRGBAImage *img, uint32_t *cp, uint32_t x, uint32_t y, \ @@ -1712,7 +1737,7 @@ { for (x = w; x > 0; --x) { - *cp++ = BWmap[*pp][0] & ((uint32_t) * (pp + 1) << 24 | ~A1); + *cp++ = BWmap[*pp][0] & ((uint32_t)*(pp + 1) << 24 | ~A1); pp += samplesperpixel; } cp += toskew; @@ -1727,6 +1752,9 @@ { int samplesperpixel = img->samplesperpixel; uint32_t **BWmap = img->BWmap; + /* Convert pixel skew to byte skew (16-bit samples) */ + const tmsize_t fromskewLocal = + (tmsize_t)fromskew * (tmsize_t)(2 * samplesperpixel); (void)y; for (; h > 0; --h) @@ -1742,7 +1770,7 @@ wp += samplesperpixel; } cp += toskew; - pp += fromskew; + pp += fromskewLocal; } } @@ -1812,13 +1840,14 @@ (void)x; (void)y; - fromskew *= samplesperpixel; + const tmsize_t fromskewLocal = + (tmsize_t)fromskew * (tmsize_t)samplesperpixel; for (; h > 0; --h) { UNROLL8(w, NOP, *cp++ = PACK(pp[0], pp[1], pp[2]); pp += samplesperpixel); cp += toskew; - pp += fromskew; + pp += fromskewLocal; } } @@ -1832,13 +1861,14 @@ (void)x; (void)y; - fromskew *= samplesperpixel; + const tmsize_t fromskewLocal = + (tmsize_t)fromskew * (tmsize_t)samplesperpixel; for (; h > 0; --h) { UNROLL8(w, NOP, *cp++ = PACK4(pp[0], pp[1], pp[2], pp[3]); pp += samplesperpixel); cp += toskew; - pp += fromskew; + pp += fromskewLocal; } } @@ -1850,7 +1880,8 @@ { int samplesperpixel = img->samplesperpixel; (void)y; - fromskew *= samplesperpixel; + const tmsize_t fromskewLocal = + (tmsize_t)fromskew * (tmsize_t)samplesperpixel; for (; h > 0; --h) { uint32_t r, g, b, a; @@ -1866,7 +1897,7 @@ pp += samplesperpixel; } cp += toskew; - pp += fromskew; + pp += fromskewLocal; } } @@ -1878,7 +1909,8 @@ int samplesperpixel = img->samplesperpixel; uint16_t *wp = (uint16_t *)pp; (void)y; - fromskew *= samplesperpixel; + const tmsize_t fromskewLocal = + (tmsize_t)fromskew * (tmsize_t)samplesperpixel; for (; h > 0; --h) { for (x = w; x > 0; --x) @@ -1888,7 +1920,7 @@ wp += samplesperpixel; } cp += toskew; - wp += fromskew; + wp += fromskewLocal; } } @@ -1901,7 +1933,8 @@ int samplesperpixel = img->samplesperpixel; uint16_t *wp = (uint16_t *)pp; (void)y; - fromskew *= samplesperpixel; + const tmsize_t fromskewLocal = + (tmsize_t)fromskew * (tmsize_t)samplesperpixel; for (; h > 0; --h) { for (x = w; x > 0; --x) @@ -1911,7 +1944,7 @@ wp += samplesperpixel; } cp += toskew; - wp += fromskew; + wp += fromskewLocal; } } @@ -1924,7 +1957,8 @@ int samplesperpixel = img->samplesperpixel; uint16_t *wp = (uint16_t *)pp; (void)y; - fromskew *= samplesperpixel; + const tmsize_t fromskewLocal = + (tmsize_t)fromskew * (tmsize_t)samplesperpixel; for (; h > 0; --h) { uint32_t r, g, b, a; @@ -1940,7 +1974,7 @@ wp += samplesperpixel; } cp += toskew; - wp += fromskew; + wp += fromskewLocal; } } @@ -1956,14 +1990,17 @@ (void)x; (void)y; - fromskew *= samplesperpixel; + const tmsize_t fromskewLocal = + (tmsize_t)fromskew * (tmsize_t)samplesperpixel; for (; h > 0; --h) { - UNROLL8(w, NOP, k = 255 - pp[3]; r = (k * (255 - pp[0])) / 255; - g = (k * (255 - pp[1])) / 255; b = (k * (255 - pp[2])) / 255; + UNROLL8(w, NOP, k = (uint16_t)(255 - pp[3]); + r = (uint16_t)((k * (uint16_t)(255 - pp[0])) / 255); + g = (uint16_t)((k * (uint16_t)(255 - pp[1])) / 255); + b = (uint16_t)((k * (uint16_t)(255 - pp[2])) / 255); *cp++ = PACK(r, g, b); pp += samplesperpixel); cp += toskew; - pp += fromskew; + pp += fromskewLocal; } } @@ -1976,22 +2013,23 @@ { int samplesperpixel = img->samplesperpixel; TIFFRGBValue *Map = img->Map; - uint16_t r, g, b, k; + unsigned int r, g, b, k; (void)y; - fromskew *= samplesperpixel; + const tmsize_t fromskewLocal = + (tmsize_t)fromskew * (tmsize_t)samplesperpixel; for (; h > 0; --h) { for (x = w; x > 0; --x) { - k = 255 - pp[3]; - r = (k * (255 - pp[0])) / 255; - g = (k * (255 - pp[1])) / 255; - b = (k * (255 - pp[2])) / 255; + k = 255U - pp[3]; + r = (k * (255U - pp[0])) / 255U; + g = (k * (255U - pp[1])) / 255U; + b = (k * (255U - pp[2])) / 255U; *cp++ = PACK(Map[r], Map[g], Map[b]); pp += samplesperpixel; } - pp += fromskew; + pp += fromskewLocal; cp += toskew; } } @@ -2044,13 +2082,13 @@ (void)y; for (; h > 0; --h) { - uint32_t rv, gv, bv, kv; + unsigned int rv, gv, bv, kv; for (x = w; x > 0; --x) { - kv = 255 - *a++; - rv = (kv * (255 - *r++)) / 255; - gv = (kv * (255 - *g++)) / 255; - bv = (kv * (255 - *b++)) / 255; + kv = 255U - *a++; + rv = (kv * (255U - *r++)) / 255U; + gv = (kv * (255U - *g++)) / 255U; + bv = (kv * (255U - *b++)) / 255U; *cp++ = PACK4(rv, gv, bv, 255); } SKEW4(r, g, b, a, fromskew); @@ -2162,7 +2200,7 @@ float X, Y, Z; uint32_t r, g, b; (void)y; - fromskew *= 3; + const tmsize_t fromskewLocal = (tmsize_t)fromskew * (tmsize_t)3; for (; h > 0; --h) { for (x = w; x > 0; --x) @@ -2174,7 +2212,7 @@ pp += 3; } cp += toskew; - pp += fromskew; + pp += fromskewLocal; } } @@ -2187,7 +2225,7 @@ uint32_t r, g, b; uint16_t *wp = (uint16_t *)pp; (void)y; - fromskew *= 3; + const tmsize_t fromskewLocal = (tmsize_t)fromskew * (tmsize_t)3; for (; h > 0; --h) { for (x = w; x > 0; --x) @@ -2199,7 +2237,7 @@ wp += 3; } cp += toskew; - wp += fromskew; + wp += fromskewLocal; } } @@ -2210,7 +2248,7 @@ #define YCbCrtoRGB(dst, Y) \ { \ uint32_t r, g, b; \ - TIFFYCbCrtoRGB(img->ycbcr, (Y), Cb, Cr, &r, &g, &b); \ + TIFFYCbCrtoRGB(img->ycbcr, (Y), (int32_t)Cb, (int32_t)Cr, &r, &g, &b); \ dst = PACK(r, g, b); \ } @@ -2226,7 +2264,8 @@ (void)y; /* adjust fromskew */ - fromskew = (fromskew / 4) * (4 * 2 + 2); + const tmsize_t fromskewLocal = + (tmsize_t)(fromskew / 4) * (tmsize_t)(4 * 4 + 2); if ((h & 3) == 0 && (w & 3) == 0) { for (; h >= 4; h -= 4) @@ -2264,7 +2303,7 @@ cp1 += incr; cp2 += incr; cp3 += incr; - pp += fromskew; + pp += fromskewLocal; } } else @@ -2288,7 +2327,7 @@ YCbCrtoRGB(cp1[3], pp[7]); /* FALLTHROUGH */ case 1: YCbCrtoRGB(cp[3], pp[3]); /* FALLTHROUGH */ - } /* FALLTHROUGH */ + } /* FALLTHROUGH */ case 3: switch (h) { @@ -2300,7 +2339,7 @@ YCbCrtoRGB(cp1[2], pp[6]); /* FALLTHROUGH */ case 1: YCbCrtoRGB(cp[2], pp[2]); /* FALLTHROUGH */ - } /* FALLTHROUGH */ + } /* FALLTHROUGH */ case 2: switch (h) { @@ -2312,7 +2351,7 @@ YCbCrtoRGB(cp1[1], pp[5]); /* FALLTHROUGH */ case 1: YCbCrtoRGB(cp[1], pp[1]); /* FALLTHROUGH */ - } /* FALLTHROUGH */ + } /* FALLTHROUGH */ case 1: switch (h) { @@ -2324,7 +2363,7 @@ YCbCrtoRGB(cp1[0], pp[4]); /* FALLTHROUGH */ case 1: YCbCrtoRGB(cp[0], pp[0]); /* FALLTHROUGH */ - } /* FALLTHROUGH */ + } /* FALLTHROUGH */ } if (x < 4) { @@ -2351,7 +2390,7 @@ cp1 += incr; cp2 += incr; cp3 += incr; - pp += fromskew; + pp += fromskewLocal; } } } @@ -2362,10 +2401,11 @@ DECLAREContigPutFunc(putcontig8bitYCbCr42tile) { uint32_t *cp1 = cp + w + toskew; - const tmsize_t incr = 2 * (tmsize_t)toskew + w; + const tmsize_t incr = 2 * (tmsize_t)toskew + (tmsize_t)w; (void)y; - fromskew = (fromskew / 4) * (4 * 2 + 2); + const tmsize_t fromskewLocal = + (tmsize_t)(fromskew / 4) * (tmsize_t)(4 * 2 + 2); if ((w & 3) == 0 && (h & 1) == 0) { for (; h >= 2; h -= 2) @@ -2391,7 +2431,7 @@ } while (--x); cp += incr; cp1 += incr; - pp += fromskew; + pp += fromskewLocal; } } else @@ -2411,7 +2451,7 @@ YCbCrtoRGB(cp1[3], pp[7]); /* FALLTHROUGH */ case 1: YCbCrtoRGB(cp[3], pp[3]); /* FALLTHROUGH */ - } /* FALLTHROUGH */ + } /* FALLTHROUGH */ case 3: switch (h) { @@ -2419,7 +2459,7 @@ YCbCrtoRGB(cp1[2], pp[6]); /* FALLTHROUGH */ case 1: YCbCrtoRGB(cp[2], pp[2]); /* FALLTHROUGH */ - } /* FALLTHROUGH */ + } /* FALLTHROUGH */ case 2: switch (h) { @@ -2427,7 +2467,7 @@ YCbCrtoRGB(cp1[1], pp[5]); /* FALLTHROUGH */ case 1: YCbCrtoRGB(cp[1], pp[1]); /* FALLTHROUGH */ - } /* FALLTHROUGH */ + } /* FALLTHROUGH */ case 1: switch (h) { @@ -2435,7 +2475,7 @@ YCbCrtoRGB(cp1[0], pp[4]); /* FALLTHROUGH */ case 1: YCbCrtoRGB(cp[0], pp[0]); /* FALLTHROUGH */ - } /* FALLTHROUGH */ + } /* FALLTHROUGH */ } if (x < 4) { @@ -2456,7 +2496,7 @@ h -= 2; cp += incr; cp1 += incr; - pp += fromskew; + pp += fromskewLocal; } } } @@ -2467,7 +2507,8 @@ DECLAREContigPutFunc(putcontig8bitYCbCr41tile) { (void)y; - fromskew = (fromskew / 4) * (4 * 1 + 2); + const tmsize_t fromskewLocal = + (tmsize_t)(fromskew / 4) * (tmsize_t)(4 * 1 + 2); do { x = w >> 2; @@ -2501,6 +2542,8 @@ YCbCrtoRGB(cp[0], pp[0]); /*-fallthrough*/ case 0: break; + default: + break; } cp += (w & 3); @@ -2508,7 +2551,7 @@ } cp += toskew; - pp += fromskew; + pp += fromskewLocal; } while (--h); } @@ -2518,9 +2561,10 @@ DECLAREContigPutFunc(putcontig8bitYCbCr22tile) { uint32_t *cp2; - const tmsize_t incr = 2 * (tmsize_t)toskew + w; + const tmsize_t incr = 2 * (tmsize_t)toskew + (tmsize_t)w; (void)y; - fromskew = (fromskew / 2) * (2 * 2 + 2); + const tmsize_t fromskewLocal = + (tmsize_t)(fromskew / 2) * (tmsize_t)(2 * 2 + 2); cp2 = cp + w + toskew; while (h >= 2) { @@ -2550,7 +2594,7 @@ } cp += incr; cp2 += incr; - pp += fromskew; + pp += fromskewLocal; h -= 2; } if (h == 1) @@ -2582,7 +2626,8 @@ DECLAREContigPutFunc(putcontig8bitYCbCr21tile) { (void)y; - fromskew = (fromskew / 2) * (2 * 1 + 2); + const tmsize_t fromskewLocal = + (tmsize_t)(fromskew / 2) * (tmsize_t)(2 * 1 + 2); do { x = w >> 1; @@ -2611,7 +2656,7 @@ } cp += toskew; - pp += fromskew; + pp += fromskewLocal; } while (--h); } @@ -2621,9 +2666,10 @@ DECLAREContigPutFunc(putcontig8bitYCbCr12tile) { uint32_t *cp2; - const tmsize_t incr = 2 * (tmsize_t)toskew + w; + const tmsize_t incr = 2 * (tmsize_t)toskew + (tmsize_t)w; (void)y; - fromskew = (fromskew / 1) * (1 * 2 + 2); + const tmsize_t fromskewLocal = + (tmsize_t)(fromskew / 1) * (tmsize_t)(1 * 2 + 2); cp2 = cp + w + toskew; while (h >= 2) { @@ -2640,7 +2686,7 @@ } while (--x); cp += incr; cp2 += incr; - pp += fromskew; + pp += fromskewLocal; h -= 2; } if (h == 1) @@ -2663,7 +2709,8 @@ DECLAREContigPutFunc(putcontig8bitYCbCr11tile) { (void)y; - fromskew = (fromskew / 1) * (1 * 1 + 2); + const tmsize_t fromskewLocal = + (tmsize_t)(fromskew / 1) * (tmsize_t)(1 * 1 + 2); do { x = w; /* was x = w>>1; patched 2000/09/25 warmerda@home.com */ @@ -2677,7 +2724,7 @@ pp += 3; } while (--x); cp += toskew; - pp += fromskew; + pp += fromskewLocal; } while (--h); } @@ -2736,8 +2783,8 @@ /* Do some validation to avoid later issues. Detect NaN for now */ /* and also if lumaGreen is zero since we divide by it later */ - if (luma[0] != luma[0] || luma[1] != luma[1] || luma[1] == 0.0 || - luma[2] != luma[2]) + if (isnan(luma[0]) || isnan(luma[1]) || TIFF_FLOAT_EQ(luma[1], 0.0f) || + isnan(luma[2])) { TIFFErrorExtR(img->tif, module, "Invalid values for YCbCrCoefficients tag"); @@ -2769,7 +2816,7 @@ float refWhite[3]; TIFFGetFieldDefaulted(img->tif, TIFFTAG_WHITEPOINT, &whitePoint); - if (whitePoint[1] == 0.0f) + if (TIFF_FLOAT_EQ(whitePoint[1], 0.0f)) { TIFFErrorExtR(img->tif, module, "Invalid value for WhitePoint tag."); return NULL; @@ -2787,10 +2834,10 @@ } } - refWhite[1] = 100.0F; + refWhite[1] = 100.0f; refWhite[0] = whitePoint[0] / whitePoint[1] * refWhite[1]; refWhite[2] = - (1.0F - whitePoint[0] - whitePoint[1]) / whitePoint[1] * refWhite[1]; + (1.0f - whitePoint[0] - whitePoint[1]) / whitePoint[1] * refWhite[1]; if (TIFFCIELabToRGBInit(img->cielab, &display_sRGB, refWhite) < 0) { TIFFErrorExtR(img->tif, module, @@ -2826,7 +2873,8 @@ img->BWmap = (uint32_t **)_TIFFmallocExt( img->tif, - 256 * sizeof(uint32_t *) + (256 * nsamples * sizeof(uint32_t))); + (tmsize_t)((size_t)256 * sizeof(uint32_t *) + + ((size_t)256 * (size_t)nsamples * sizeof(uint32_t)))); if (img->BWmap == NULL) { TIFFErrorExtR(img->tif, TIFFFileName(img->tif), @@ -2867,6 +2915,8 @@ case 16: GREY(i); break; + default: + break; } #undef GREY } @@ -2882,14 +2932,14 @@ { int32_t x, range; - range = (int32_t)((1L << img->bitspersample) - 1); + range = (int32_t)((1U << img->bitspersample) - 1U); /* treat 16 bit the same as eight bit */ if (img->bitspersample == 16) - range = (int32_t)255; + range = 255; img->Map = (TIFFRGBValue *)_TIFFmallocExt( - img->tif, (range + 1) * sizeof(TIFFRGBValue)); + img->tif, (tmsize_t)((size_t)(range + 1) * sizeof(TIFFRGBValue))); if (img->Map == NULL) { TIFFErrorExtR(img->tif, TIFFFileName(img->tif), @@ -2972,7 +3022,8 @@ img->PALmap = (uint32_t **)_TIFFmallocExt( img->tif, - 256 * sizeof(uint32_t *) + (256 * nsamples * sizeof(uint32_t))); + (tmsize_t)((size_t)256 * sizeof(uint32_t *) + + ((size_t)256 * (size_t)nsamples * sizeof(uint32_t)))); if (img->PALmap == NULL) { TIFFErrorExtR(img->tif, TIFFFileName(img->tif), @@ -3012,6 +3063,8 @@ case 8: CMAP(i); break; + default: + break; } #undef CMAP } @@ -3054,6 +3107,8 @@ if (img->bitspersample <= 8 && !makecmap(img)) return (0); break; + default: + break; } return (1); } @@ -3102,6 +3157,8 @@ img->put.contig = putRGBcontig16bittile; } break; + default: + break; } break; case PHOTOMETRIC_SEPARATED: @@ -3133,6 +3190,8 @@ case 1: img->put.contig = put1bitcmaptile; break; + default: + break; } } break; @@ -3160,6 +3219,8 @@ case 1: img->put.contig = put1bitbwtile; break; + default: + break; } } break; @@ -3181,6 +3242,19 @@ uint16_t SubsamplingVer; TIFFGetFieldDefaulted(img->tif, TIFFTAG_YCBCRSUBSAMPLING, &SubsamplingHor, &SubsamplingVer); + /* Validate that the image dimensions are compatible with + the subsampling block. All putcontig8bitYCbCrXYtile routines + assume width >= X and height >= Y. */ + if (img->width < SubsamplingHor || + img->height < SubsamplingVer) + { + TIFFErrorExtR(img->tif, TIFFFileName(img->tif), + "YCbCr subsampling (%u,%u) incompatible " + "with image size %ux%u", + SubsamplingHor, SubsamplingVer, + img->width, img->height); + return (0); + } switch ((SubsamplingHor << 4) | SubsamplingVer) { case 0x44: @@ -3204,6 +3278,8 @@ case 0x11: img->put.contig = putcontig8bitYCbCr11tile; break; + default: + break; } } } @@ -3215,6 +3291,9 @@ img->put.contig = initCIELabConversion(img); break; } + break; + default: + break; } return ((img->get != NULL) && (img->put.contig != NULL)); } @@ -3266,6 +3345,8 @@ img->put.separate = putRGBseparate16bittile; } break; + default: + break; } break; case PHOTOMETRIC_SEPARATED: @@ -3290,10 +3371,14 @@ img->put.separate = putseparate8bitYCbCr11tile; break; /* TODO: add other cases here */ + default: + break; } } } break; + default: + break; } return ((img->get != NULL) && (img->put.separate != NULL)); } @@ -3304,7 +3389,7 @@ uint8_t *m; uint16_t na, nv; assert(img->UaToAa == NULL); - img->UaToAa = _TIFFmallocExt(img->tif, 65536); + img->UaToAa = (uint8_t *)_TIFFmallocExt(img->tif, 65536); if (img->UaToAa == NULL) { TIFFErrorExtR(img->tif, module, "Out of memory"); @@ -3325,7 +3410,7 @@ uint8_t *m; uint32_t n; assert(img->Bitdepth16To8 == NULL); - img->Bitdepth16To8 = _TIFFmallocExt(img->tif, 65536); + img->Bitdepth16To8 = (uint8_t *)_TIFFmallocExt(img->tif, 65536); if (img->Bitdepth16To8 == NULL) { TIFFErrorExtR(img->tif, module, "Out of memory"); @@ -3392,7 +3477,7 @@ return (0); } - img.row_offset = row; + img.row_offset = (int)row; img.col_offset = 0; if (row + rowsperstrip > img.height) @@ -3503,8 +3588,8 @@ * Read the chunk of imagery. */ - img.row_offset = row; - img.col_offset = col; + img.row_offset = (int)row; + img.col_offset = (int)col; ok = TIFFRGBAImageGet(&img, raster, read_xsize, read_ysize); @@ -3526,15 +3611,16 @@ memmove(raster + (size_t)(tile_ysize - i_row - 1) * tile_xsize, raster + (size_t)(read_ysize - i_row - 1) * read_xsize, read_xsize * sizeof(uint32_t)); - _TIFFmemset(raster + (size_t)(tile_ysize - i_row - 1) * tile_xsize + - read_xsize, - 0, sizeof(uint32_t) * (tile_xsize - read_xsize)); + _TIFFmemset( + raster + (size_t)(tile_ysize - i_row - 1) * tile_xsize + read_xsize, + 0, + (tmsize_t)(sizeof(uint32_t) * (size_t)(tile_xsize - read_xsize))); } for (i_row = read_ysize; i_row < tile_ysize; i_row++) { _TIFFmemset(raster + (size_t)(tile_ysize - i_row - 1) * tile_xsize, 0, - sizeof(uint32_t) * tile_xsize); + (tmsize_t)(sizeof(uint32_t) * (size_t)tile_xsize)); } return (ok);
diff --git a/third_party/libtiff/tif_hash_set.c b/third_party/libtiff/tif_hash_set.c index 9be488e..aefcaad 100644 --- a/third_party/libtiff/tif_hash_set.c +++ b/third_party/libtiff/tif_hash_set.c
@@ -76,7 +76,7 @@ 100663319, 201326611, 402653189, 805306457, 1610612741}; /************************************************************************/ -/* TIFFHashSetHashPointer() */ +/* TIFFHashSetHashPointer() */ /************************************************************************/ /** @@ -93,7 +93,7 @@ } /************************************************************************/ -/* TIFFHashSetEqualPointer() */ +/* TIFFHashSetEqualPointer() */ /************************************************************************/ /** @@ -111,7 +111,7 @@ } /************************************************************************/ -/* TIFFHashSetNew() */ +/* TIFFHashSetNew() */ /************************************************************************/ /** @@ -164,7 +164,7 @@ } /************************************************************************/ -/* TIFFHashSetSize() */ +/* TIFFHashSetSize() */ /************************************************************************/ /** @@ -184,7 +184,7 @@ } /************************************************************************/ -/* TIFFHashSetGetNewListElt() */ +/* TIFFHashSetGetNewListElt() */ /************************************************************************/ static TIFFList *TIFFHashSetGetNewListElt(TIFFHashSet *set) @@ -202,7 +202,7 @@ } /************************************************************************/ -/* TIFFHashSetReturnListElt() */ +/* TIFFHashSetReturnListElt() */ /************************************************************************/ static void TIFFHashSetReturnListElt(TIFFHashSet *set, TIFFList *psList) @@ -220,7 +220,7 @@ } /************************************************************************/ -/* TIFFHashSetClearInternal() */ +/* TIFFHashSetClearInternal() */ /************************************************************************/ static void TIFFHashSetClearInternal(TIFFHashSet *set, bool bFinalize) @@ -246,7 +246,7 @@ } /************************************************************************/ -/* TIFFListDestroy() */ +/* TIFFListDestroy() */ /************************************************************************/ /** @@ -270,7 +270,7 @@ } /************************************************************************/ -/* TIFFHashSetDestroy() */ +/* TIFFHashSetDestroy() */ /************************************************************************/ /** @@ -295,7 +295,7 @@ #ifdef notused /************************************************************************/ -/* TIFFHashSetClear() */ +/* TIFFHashSetClear() */ /************************************************************************/ /** @@ -319,7 +319,7 @@ } /************************************************************************/ -/* TIFFHashSetForeach() */ +/* TIFFHashSetForeach() */ /************************************************************************/ /** @@ -360,14 +360,14 @@ #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 @@ 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 @@ } /************************************************************************/ -/* 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 @@ } } - 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 @@ } /************************************************************************/ -/* TIFFHashSetLookup() */ +/* TIFFHashSetLookup() */ /************************************************************************/ /** @@ -532,7 +534,8 @@ } } - 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 @@ #ifdef notused /************************************************************************/ -/* TIFFHashSetRemoveDeferRehash() */ +/* TIFFHashSetRemoveDeferRehash() */ /************************************************************************/ /**
diff --git a/third_party/libtiff/tif_jpeg.c b/third_party/libtiff/tif_jpeg.c index a9764f0..1f17d0c 100644 --- a/third_party/libtiff/tif_jpeg.c +++ b/third_party/libtiff/tif_jpeg.c
@@ -22,9 +22,6 @@ * OF THIS SOFTWARE. */ -#define WIN32_LEAN_AND_MEAN -#define VC_EXTRALEAN - #include "tiffiop.h" #include <stdlib.h> @@ -151,20 +148,9 @@ #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 @@ -179,6 +165,10 @@ * 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 @@ -189,22 +179,24 @@ } 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 */ @@ -214,6 +206,9 @@ int encode_raw_error; } JPEGState; +#ifdef _MSC_VER +#pragma warning(pop) +#endif #define JState(tif) ((JPEGState *)(tif)->tif_data) @@ -564,7 +559,7 @@ /* 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 = @@ -917,7 +912,7 @@ return (0); if (n < 2) return (0); - n -= 2; + n = (uint16_t)(n - 2); if (n > 0) JPEGFixupTagsSubsamplingSkip(data, n); } @@ -1021,7 +1016,7 @@ 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; @@ -1042,7 +1037,7 @@ return (0); if (!JPEGFixupTagsSubsamplingReadByte(data, &mb)) return (0); - *result = (ma << 8) | mb; + *result = (uint16_t)((ma << 8) | mb); return (1); } @@ -1164,6 +1159,47 @@ 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. */ @@ -1172,7 +1208,6 @@ 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; @@ -1198,52 +1233,24 @@ 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 */ @@ -1252,11 +1259,11 @@ 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 @@ -1267,8 +1274,8 @@ 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 != @@ -1325,11 +1332,12 @@ 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); } } @@ -1445,7 +1453,7 @@ * 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); @@ -1470,7 +1478,18 @@ 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) @@ -1489,7 +1508,7 @@ return (0); } - ++tif->tif_row; + ++tif->tif_dir.td_row; buf += sp->bytesperline; cc -= sp->bytesperline; } while (--nrows > 0); @@ -1497,15 +1516,15 @@ /* 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) { @@ -1531,7 +1550,18 @@ 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) @@ -1545,8 +1575,9 @@ 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 @@ -1562,14 +1593,16 @@ 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++) @@ -1588,18 +1621,19 @@ 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); @@ -1610,13 +1644,13 @@ /* 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) @@ -1650,8 +1684,16 @@ /* 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; @@ -1666,9 +1708,10 @@ 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"); @@ -1761,18 +1804,20 @@ 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++) { @@ -1791,7 +1836,7 @@ #endif sp->scancount++; - tif->tif_row += sp->v_sampling; + tif->tif_dir.td_row += sp->v_sampling; buf += sp->bytesperline; cc -= sp->bytesperline; @@ -2030,9 +2075,9 @@ 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]; @@ -2080,30 +2125,30 @@ #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); } } @@ -2159,7 +2204,6 @@ 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); @@ -2170,47 +2214,20 @@ } 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) { @@ -2282,7 +2299,13 @@ /* 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; @@ -2338,13 +2361,15 @@ 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"); @@ -2369,8 +2394,10 @@ 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 @@ -2380,7 +2407,7 @@ if (TIFFjpeg_write_scanlines(sp, bufptr, 1) != 1) return (0); if (nrows > 0) - tif->tif_row++; + tif->tif_dir.td_row++; buf += sp->bytesperline; } @@ -2449,8 +2476,9 @@ { 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; @@ -2494,7 +2522,7 @@ } sp->scancount = 0; } - tif->tif_row += sp->v_sampling; + tif->tif_dir.td_row += sp->v_sampling; buf += bytesperclumpline; nrows -= sp->v_sampling; } @@ -2588,10 +2616,11 @@ * 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) @@ -2799,6 +2828,33 @@ 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) { @@ -2835,6 +2891,7 @@ tif->tif_encoderow = JPEGEncode; tif->tif_encodestrip = JPEGEncode; tif->tif_encodetile = JPEGEncode; + tif->tif_getmaxcompressionratio = JPEGGetMaxCompressionRatio; tif->tif_cleanup = JPEGCleanup; tif->tif_defstripsize = JPEGDefaultStripSize;
diff --git a/third_party/libtiff/tif_luv.c b/third_party/libtiff/tif_luv.c index ecc3225..d9bc8fe 100644 --- a/third_party/libtiff/tif_luv.c +++ b/third_party/libtiff/tif_luv.c
@@ -212,7 +212,7 @@ } 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 @@ { /* 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 @@ 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 @@ 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 @@ 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 @@ } 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 @@ 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 @@ #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 @@ #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 @@ #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 @@ 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 @@ #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 @@ #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 @@ #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 @@ 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 @@ #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 @@ #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 @@ } 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 @@ #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 @@ } 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 @@ 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 @@ 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 @@ #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 @@ #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 @@ } 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 @@ *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 @@ { 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 @@ 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 @@ 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 @@ 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 @@ case SGILOGDATAFMT_8BIT: sp->tfunc = Luv24toRGB; break; + default: + break; } } else @@ -1562,6 +1560,8 @@ case SGILOGDATAFMT_8BIT: sp->tfunc = Luv32toRGB; break; + default: + break; } } return (1); @@ -1577,6 +1577,8 @@ case SGILOGDATAFMT_8BIT: sp->tfunc = L16toGry; break; + default: + break; } return (1); default: @@ -1755,8 +1757,9 @@ /* * 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);
diff --git a/third_party/libtiff/tif_lzw.c b/third_party/libtiff/tif_lzw.c index 4bf845b..d9f56a4 100644 --- a/third_party/libtiff/tif_lzw.c +++ b/third_party/libtiff/tif_lzw.c
@@ -60,7 +60,7 @@ */ #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 @@ #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 @@ */ /* 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 @@ nextbits += 8 * SIZEOF_WORDTYPE; \ dec_bitsleft -= 8 * SIZEOF_WORDTYPE; \ code = (WordType)((codetmp | (nextdata >> nextbits)) & \ - nbitsmask); \ + (WordType)nbitsmask); \ break; \ } \ else \ @@ -396,7 +396,7 @@ } \ } \ } \ - 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 @@ 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 @@ } 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 @@ { 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 @@ 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 @@ 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 @@ 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 @@ 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 @@ 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 @@ 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 @@ 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 @@ 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 @@ 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 @@ { TIFFErrorExtR(tif, module, "Corrupted LZW table at scanline %" PRIu32, - tif->tif_row); + tif->tif_dir.td_row); return (0); } @@ -921,11 +923,11 @@ { 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 @@ 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 @@ 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 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 @@ * 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 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 @@ { 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 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 @@ _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 @@ tif->tif_encodestrip = LZWEncode; tif->tif_encodetile = LZWEncode; #endif + tif->tif_getmaxcompressionratio = LZWGetMaxCompressionRatio; tif->tif_cleanup = LZWCleanup; /* * Setup predictor setup.
diff --git a/third_party/libtiff/tif_next.c b/third_party/libtiff/tif_next.c index f000574..04ae474 100644 --- a/third_party/libtiff/tif_next.c +++ b/third_party/libtiff/tif_next.c
@@ -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 @@ 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 @@ { 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 @@ return (1); bad: TIFFErrorExtR(tif, module, "Not enough data for scanline %" PRIu32, - tif->tif_row); + tif->tif_dir.td_row); return (0); }
diff --git a/third_party/libtiff/tif_open.c b/third_party/libtiff/tif_open.c index 565d13c..43cb170 100644 --- a/third_party/libtiff/tif_open.c +++ b/third_party/libtiff/tif_open.c
@@ -77,7 +77,7 @@ return (m); } -TIFFOpenOptions *TIFFOpenOptionsAlloc() +TIFFOpenOptions *TIFFOpenOptionsAlloc(void) { TIFFOpenOptions *opts = (TIFFOpenOptions *)_TIFFcalloc(1, sizeof(TIFFOpenOptions)); @@ -308,6 +308,7 @@ 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 @@ 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 @@ 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 @@ 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 @@ 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 @@ 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 @@ 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 @@ /* * 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 @@ } 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 @@ if (!TIFFDefaultDirectory(tif)) goto bad; return (tif); + default: + break; } bad: tif->tif_mode = O_RDONLY; /* XXX avoid flush */ @@ -861,7 +868,7 @@ /* * 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 @@ /* * 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.
diff --git a/third_party/libtiff/tif_packbits.c b/third_party/libtiff/tif_packbits.c index d7db9b6..13d0f1d 100644 --- a/third_party/libtiff/tif_packbits.c +++ b/third_party/libtiff/tif_packbits.c
@@ -194,12 +194,17 @@ */ 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 @@ { 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 @@ tif->tif_encodestrip = PackBitsEncodeChunk; tif->tif_encodetile = PackBitsEncodeChunk; #endif + tif->tif_getmaxcompressionratio = PackBitsGetMaxCompressionRatio; + return (1); } #endif /* PACKBITS_SUPPORT */
diff --git a/third_party/libtiff/tif_pixarlog.c b/third_party/libtiff/tif_pixarlog.c index 6b0d6f1..7892522 100644 --- a/third_party/libtiff/tif_pixarlog.c +++ b/third_party/libtiff/tif_pixarlog.c
@@ -117,11 +117,11 @@ } 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 @@ 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 @@ 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 @@ 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 @@ * 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 @@ } 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 @@ 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 @@ 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 @@ 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 @@ 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 @@ 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 @@ 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 @@ if (format == SAMPLEFORMAT_VOID || format == SAMPLEFORMAT_UINT) guess = PIXARLOGDATAFMT_8BIT; break; + default: + break; } return guess; @@ -769,7 +776,8 @@ 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 @@ 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 @@ 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 @@ 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 @@ } 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 @@ 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 @@ 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 @@ 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 @@ 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 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 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 @@ PixarLogState *sp = PixarLogEncoderState(tif); tmsize_t i; tmsize_t n; - int llen; + tmsize_t llen; unsigned short *up; (void)s; @@ -1312,12 +1380,14 @@ 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 @@ 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 @@ 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 @@ 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 @@ 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 @@ {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 @@ 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;
diff --git a/third_party/libtiff/tif_predict.c b/third_party/libtiff/tif_predict.c index 7a6fc4a..18b90c2 100644 --- a/third_party/libtiff/tif_predict.c +++ b/third_party/libtiff/tif_predict.c
@@ -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 @@ case 64: sp->decodepfunc = horAcc64; break; + default: + break; } /* * Override default decoding method with one that does the @@ -247,6 +249,8 @@ case 64: sp->encodepfunc = horDiff64; break; + default: + break; } /* * Override default encoding method with one that does the @@ -590,7 +594,7 @@ 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 @@ (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 @@ (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 @@ 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);
diff --git a/third_party/libtiff/tif_print.c b/third_party/libtiff/tif_print.c index addc03a..1ea450d 100644 --- a/third_party/libtiff/tif_print.c +++ b/third_party/libtiff/tif_print.c
@@ -118,10 +118,10 @@ 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 @@ 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 @@ return 1; } return 0; + + default: + break; } return 0; @@ -244,8 +248,7 @@ 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 @@ } 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 @@ 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 @@ } } } - 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 @@ 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 @@ 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 @@ 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 @@ 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 @@ * "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 @@ if (*tp) fprintf(fd, "\\%c", *tp); else - fprintf(fd, "\\%03o", *cp & 0xff); + fprintf(fd, "\\%03o", (unsigned int)(*cp & 0xff)); } }
diff --git a/third_party/libtiff/tif_read.c b/third_party/libtiff/tif_read.c index a2bb304..d1a4e89 100644 --- a/third_party/libtiff/tif_read.c +++ b/third_party/libtiff/tif_read.c
@@ -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 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 @@ 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 @@ { 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 @@ 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 @@ ", 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 @@ 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 @@ { 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 @@ 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 @@ 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 @@ /* 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 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 @@ 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 @@ 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 @@ /* 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 @@ * 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 @@ } #endif - if (row < tif->tif_row) + if (row < tif->tif_dir.td_row) { /* * Moving backwards within the same strip: backup @@ -425,7 +460,7 @@ 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 @@ } } - if (row != tif->tif_row) + if (row != tif->tif_dir.td_row) { /* * Seek forward to the desired row. @@ -443,9 +478,9 @@ /* 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 @@ /* * 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 @@ 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 @@ 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 @@ 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 @@ { 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 @@ "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 @@ "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 @@ { 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 @@ } /* 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 @@ "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 @@ } 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 @@ } 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 @@ { 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 @@ 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 @@ { 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 @@ * 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 @@ 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 @@ "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 @@ "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 @@ } /* 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 @@ 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 @@ } 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 @@ } 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 @@ { 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 @@ 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 @@ */ /* 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 @@ 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 @@ 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 @@ 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 @@ 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;
diff --git a/third_party/libtiff/tif_strip.c b/third_party/libtiff/tif_strip.c index c9ba393..b07bf9f 100644 --- a/third_party/libtiff/tif_strip.c +++ b/third_party/libtiff/tif_strip.c
@@ -47,6 +47,8 @@ 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 @@ (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 @@ } /* - * 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 @@ 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 @@ _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 @@ 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(
diff --git a/third_party/libtiff/tif_swab.c b/third_party/libtiff/tif_swab.c index 827b025..50fe635 100644 --- a/third_party/libtiff/tif_swab.c +++ b/third_party/libtiff/tif_swab.c
@@ -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 @@ #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 @@ #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 @@ #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 @@ #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 @@ #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 @@ #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 @@ #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 @@ #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 @@ #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 @@ #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)
diff --git a/third_party/libtiff/tif_thunder.c b/third_party/libtiff/tif_thunder.c index bac0607..0c688db 100644 --- a/third_party/libtiff/tif_thunder.c +++ b/third_party/libtiff/tif_thunder.c
@@ -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 @@ #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 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 @@ break; if (npixels & 1) { - op[0] |= lastpixel; + op[0] |= (uint8_t)lastpixel; lastpixel = *op++; npixels++; n--; @@ -150,6 +150,8 @@ case THUNDER_RAW: /* raw data */ SETPIXEL(op, n); break; + default: + break; } } tif->tif_rawcp = (uint8_t *)bp; @@ -161,7 +163,7 @@ 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 @@ 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 @@ { 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); }
diff --git a/third_party/libtiff/tif_tile.c b/third_party/libtiff/tif_tile.c index f07032f..f907609 100644 --- a/third_party/libtiff/tif_tile.c +++ b/third_party/libtiff/tif_tile.c
@@ -54,12 +54,50 @@ 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 @@ */ 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";
diff --git a/third_party/libtiff/tif_write.c b/third_party/libtiff/tif_write.c index 3263853..614a8ea 100644 --- a/third_party/libtiff/tif_write.c +++ b/third_party/libtiff/tif_write.c
@@ -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 @@ 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 @@ /* * 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 @@ (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 @@ */ 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 @@ 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 @@ * 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 @@ /* 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 @@ 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 @@ 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 @@ 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 @@ 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 @@ 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 @@ 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 @@ * 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 @@ * 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 @@ } 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 @@ } 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 @@ 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 @@ 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 @@ 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 @@ /* * 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 @@ 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 @@ /* 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 @@ _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 @@ 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 */
diff --git a/third_party/libtiff/tiffio.h b/third_party/libtiff/tiffio.h index f9c206e..bb8fbde 100644 --- a/third_party/libtiff/tiffio.h +++ b/third_party/libtiff/tiffio.h
@@ -125,13 +125,13 @@ */ /* 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 @@ * 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 @@ typedef int (*TIFFInitMethod)(TIFF *, int); typedef struct { - char *name; + const char *name; uint16_t scheme; TIFFInitMethod init; } TIFFCodec; @@ -584,6 +584,7 @@ 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 @@ 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);
diff --git a/third_party/libtiff/tiffiop.h b/third_party/libtiff/tiffiop.h index f00ae32..8df0e84 100644 --- a/third_party/libtiff/tiffiop.h +++ b/third_party/libtiff/tiffiop.h
@@ -38,6 +38,7 @@ #include <sys/types.h> #endif +#include <math.h> #include <string.h> #ifdef HAVE_ASSERT_H @@ -94,6 +95,7 @@ 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 @@ 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 @@ 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 @@ * - 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 @@ /* 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 @@ 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 @@ * 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 @@ (((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 @@ #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 @@ */ #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 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 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,
diff --git a/third_party/libtiff/tiffvers.h b/third_party/libtiff/tiffvers.h index 77ae6b4..2adbbee 100644 --- a/third_party/libtiff/tiffvers.h +++ b/third_party/libtiff/tiffvers.h
@@ -3,7 +3,7 @@ /* clang-format disabled because FindTIFF.cmake is very sensitive to the * formatting of below line being a single line. */ -#define TIFFLIB_VERSION_STR "LIBTIFF, Version 4.7.1\nCopyright (c) 1988-1996 Sam Leffler\nCopyright (c) 1991-1996 Silicon Graphics, Inc." +#define TIFFLIB_VERSION_STR "LIBTIFF, Version 4.7.2\nCopyright (c) 1988-1996 Sam Leffler\nCopyright (c) 1991-1996 Silicon Graphics, Inc." /* * This define can be used in code that requires * compilation-related definitions specific to a @@ -11,12 +11,12 @@ * version checking should be done based on the * string returned by TIFFGetVersion. */ -#define TIFFLIB_VERSION 20250912 +#define TIFFLIB_VERSION 20260627 /* The following defines have been added in 4.5.0 */ #define TIFFLIB_MAJOR_VERSION 4 #define TIFFLIB_MINOR_VERSION 7 -#define TIFFLIB_MICRO_VERSION 1 +#define TIFFLIB_MICRO_VERSION 2 /* Macro added in 4.5.0. Returns TRUE if the current libtiff version is * greater or equal to major.minor.micro