diff --git a/ChangeLog.txt b/ChangeLog.txt index ea38f8d36e0..29cb558c923 100644 --- a/ChangeLog.txt +++ b/ChangeLog.txt @@ -7,6 +7,14 @@ Entries may not always be in chronological/commit order. See license at the end of file. */ +2023-11-12 01:24 UTC+0100 Phil Krylov (phil a t krylov.eu) + * src/3rd/Makefile + - src/3rd/tiff/ + * package/harbour.spec + * README.md + - Removed third-party TIFF library. It's not clear why it was even + included, it's not C90 compatible anymore, and a major pain to maintain. + 2023-11-11 21:41 UTC+0100 Phil Krylov (phil a t krylov.eu) * contrib/hbwin/win_bmp.c ! Fixed dangling pointer access (introduced in commit 64dba82) in diff --git a/README.md b/README.md index a89beae7ac3..0574bed8e59 100644 --- a/README.md +++ b/README.md @@ -495,7 +495,6 @@ the build. Make sure to adjust them to your own directories: HB_WITH_QT=C:\Qt\include (version 4.5.0 or upper is required) HB_WITH_SLANG= (on *nix systems) HB_WITH_SQLITE3=C:\sqlite3 (defaults to locally hosted version if not found) - HB_WITH_TIFF=C:\libtiff (defaults to locally hosted version if not found) HB_WITH_TINYMT=C:\tinymt\tinymt (defaults to locally hosted version) HB_WITH_WATT= (on MS-DOS systems) HB_WITH_X11= (on *nix systems) @@ -1831,8 +1830,6 @@ Supported shells per host platforms: * * HB_WITH_SQLITE3 - sqlite3 [multiplatform, free, open-source] * - * HB_WITH_TIFF - libtiff [multiplatform, free, open-source] - * * HB_WITH_TINYMT - TinyMT (Mersenne Twister) [multiplatform, free, open-source] * * HB_WITH_WATT - Watt-32 (TCP/IP sockets) [dos, free, open-source] diff --git a/package/harbour.spec b/package/harbour.spec index f19edf50960..64c104ff347 100644 --- a/package/harbour.spec +++ b/package/harbour.spec @@ -415,7 +415,6 @@ make install %{?_smp_mflags} rm -f $RPM_BUILD_ROOT/%{_bindir}/{3rdpatch.hb,check.hb,commit.hb,harbour.ucf} rm -f $HB_INSTALL_LIB/libjpeg.a \ $HB_INSTALL_LIB/libpng.a \ - $HB_INSTALL_LIB/libtiff.a \ $HB_INSTALL_LIB/liblibhpdf.a \ $HB_INSTALL_LIB/libsqlite3.a \ $HB_INSTALL_LIB/libexpat.a \ diff --git a/src/3rd/Makefile b/src/3rd/Makefile index 3c1b03e8d63..dc5b6f74671 100644 --- a/src/3rd/Makefile +++ b/src/3rd/Makefile @@ -5,7 +5,6 @@ DIRS := \ png \ jpeg \ pcre \ - tiff \ zlib \ include $(TOP)$(ROOT)config/dir.mk diff --git a/src/3rd/tiff/LICENSE b/src/3rd/tiff/LICENSE deleted file mode 100644 index 55b65673edf..00000000000 --- a/src/3rd/tiff/LICENSE +++ /dev/null @@ -1,23 +0,0 @@ -# LibTIFF license - -Copyright © 1988-1997 Sam Leffler\ -Copyright © 1991-1997 Silicon Graphics, Inc. - -Permission to use, copy, modify, distribute, and sell this software and -its documentation for any purpose is hereby granted without fee, provided -that (i) the above copyright notices and this permission notice appear in -all copies of the software and related documentation, and (ii) the names of -Sam Leffler and Silicon Graphics may not be used in any advertising or -publicity relating to the software without the specific, prior written -permission of Sam Leffler and Silicon Graphics. - -THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, -EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY -WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. - -IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR -ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, -OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, -WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF -LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE -OF THIS SOFTWARE. diff --git a/src/3rd/tiff/Makefile b/src/3rd/tiff/Makefile deleted file mode 100644 index c19edfa4c84..00000000000 --- a/src/3rd/tiff/Makefile +++ /dev/null @@ -1,155 +0,0 @@ -ROOT := ../../../ - -include $(TOP)$(ROOT)config/global.mk - -LIBNAME := tiff - -HB_BUILD_WARN := no -HB_BUILD_MODE := c -HB_BUILD_UNICODE := no - -C_SOURCES := \ - auxtif.c \ - codec.c \ - color.c \ - compress.c \ - dirinfo.c \ - dumpmode.c \ - error.c \ - extensio.c \ - fax3.c \ - fax3sm.c \ - getimage.c \ - hash_set.c \ - jbig.c \ - jpeg.c \ - jpeg_12.c \ - lerc.c \ - luv.c \ - lzma.c \ - lzw.c \ - next.c \ - ojpeg.c \ - packbits.c \ - pixarlog.c \ - predict.c \ - print.c \ - strip.c \ - swab.c \ - thunder.c \ - tile.c \ - version.c \ - warn.c \ - webp.c \ - zstd.c \ - -C_SOURCES += \ - close.c \ - dir.c \ - dirread.c \ - dirwrite.c \ - flush.c \ - open.c \ - read.c \ - write.c \ - -# tif_ojpeg.c \ - -ifeq ($(HB_PLATFORM),win) -# C_SOURCES += win32.c -# HB_CFLAGS += -DUSE_WIN32_FILEIO -else ifeq ($(HB_PLATFORM_UNIX),yes) - C_SOURCES += unix.c - HB_CFLAGS += -DHAVE_FCNTL_H -endif - -ifeq ($(filter $(HB_COMPILER),<>),) - - _DET_DSP_NAME := tiff - _DET_VAR_INC_ := HB_INC_TIFF - _DET_VAR_HAS_ := HB_HAS_TIFF - _DET_FLT_PLAT := - _DET_FLT_COMP := - _DET_INC_DEFP := /usr/include - _DET_INC_LOCL := src/3rd/tiff - _DET_INC_HEAD := /tiff.h - include $(TOP)$(ROOT)config/detfun.mk - - ifneq ($(HB_HAS_TIFF_LOCAL),) - - ifneq ($(HB_HAS_ZLIB),) - HB_CFLAGS += -DZIP_SUPPORT - HB_CFLAGS += $(foreach d,$(HB_HAS_ZLIB),-I$(d)) - endif - - include $(TOP)$(ROOT)config/lib.mk - else - HB_SKIP_REASON := unused - include $(TOP)$(ROOT)config/none.mk - endif -else - HB_SKIP_REASON := compiler not supported - include $(TOP)$(ROOT)config/none.mk -endif - -# ORIGIN https://libtiff.gitlab.io/libtiff/ -# VER 4.6.0 -# URL https://download.osgeo.org/libtiff/tiff-4.6.0.tar.xz -# DIFF tiff.diff -# -# MAP LICENSE.md LICENSE -# MAP libtiff/tif_aux.c auxtif.c -# MAP libtiff/tif_close.c close.c -# MAP libtiff/tif_codec.c codec.c -# MAP libtiff/tif_color.c color.c -# MAP libtiff/tif_compress.c compress.c -# MAP libtiff/tif_dir.c dir.c -# MAP libtiff/tif_dirinfo.c dirinfo.c -# MAP libtiff/tif_dirread.c dirread.c -# MAP libtiff/tif_dirwrite.c dirwrite.c -# MAP libtiff/tif_dumpmode.c dumpmode.c -# MAP libtiff/tif_error.c error.c -# MAP libtiff/tif_extension.c extensio.c -# MAP libtiff/tif_fax3.c fax3.c -# MAP libtiff/tif_fax3sm.c fax3sm.c -# MAP libtiff/tif_flush.c flush.c -# MAP libtiff/tif_getimage.c getimage.c -# MAP libtiff/tif_hash_set.c hash_set.c -# MAP libtiff/tif_jbig.c jbig.c -# MAP libtiff/tif_jpeg.c jpeg.c -# MAP libtiff/tif_jpeg_12.c jpeg_12.c -# MAP libtiff/tif_lerc.c lerc.c -# MAP libtiff/tif_luv.c luv.c -# MAP libtiff/tif_lzma.c lzma.c -# MAP libtiff/tif_lzw.c lzw.c -# MAP libtiff/tif_next.c next.c -# MAP libtiff/tif_ojpeg.c ojpeg.c -# MAP libtiff/tif_open.c open.c -# MAP libtiff/tif_packbits.c packbits.c -# MAP libtiff/tif_pixarlog.c pixarlog.c -# MAP libtiff/tif_predict.c predict.c -# MAP libtiff/tif_print.c print.c -# MAP libtiff/tif_read.c read.c -# MAP libtiff/tif_strip.c strip.c -# MAP libtiff/tif_swab.c swab.c -# MAP libtiff/tif_thunder.c thunder.c -# MAP libtiff/tif_tile.c tile.c -# MAP libtiff/tif_unix.c unix.c -# MAP libtiff/tif_version.c version.c -# MAP libtiff/tif_warning.c warn.c -# MAP libtiff/tif_webp.c webp.c -# MAP libtiff/tif_win32.c win32.c -# MAP libtiff/tif_write.c write.c -# MAP libtiff/tif_zip.c zip.c -# MAP libtiff/tif_zstd.c zstd.c -# MAP libtiff/t4.h t4.h -# MAP libtiff/tiff.h tiff.h -# MAP libtiff/tiffio.h tiffio.h -# MAP libtiff/tiffiop.h tiffiop.h -# MAP libtiff/tiffvers.h tiffvers.h -# MAP libtiff/tif_dir.h dir.h -# MAP libtiff/tif_fax3.h fax3.h -# MAP libtiff/tif_hash_set.h hash_set.h -# MAP libtiff/tif_predict.h predict.h -# MAP libtiff/uvcode.h uvcode.h -# MAP libtiff/tiffconf.h.in tiffconf.h diff --git a/src/3rd/tiff/auxtif.c b/src/3rd/tiff/auxtif.c deleted file mode 100644 index 5f50d1119c2..00000000000 --- a/src/3rd/tiff/auxtif.c +++ /dev/null @@ -1,458 +0,0 @@ -/* - * Copyright (c) 1991-1997 Sam Leffler - * Copyright (c) 1991-1997 Silicon Graphics, Inc. - * - * Permission to use, copy, modify, distribute, and sell this software and - * its documentation for any purpose is hereby granted without fee, provided - * that (i) the above copyright notices and this permission notice appear in - * all copies of the software and related documentation, and (ii) the names of - * Sam Leffler and Silicon Graphics may not be used in any advertising or - * publicity relating to the software without the specific, prior written - * permission of Sam Leffler and Silicon Graphics. - * - * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, - * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY - * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. - * - * IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR - * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, - * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, - * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF - * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE - * OF THIS SOFTWARE. - */ - -/* - * TIFF Library. - * - * Auxiliary Support Routines. - */ -#include "predict.h" -#include "tiffiop.h" -#include -#include - -uint32_t _TIFFMultiply32(TIFF *tif, uint32_t first, uint32_t second, - const char *where) -{ - if (second && first > UINT32_MAX / second) - { - TIFFErrorExtR(tif, where, "Integer overflow in %s", where); - return 0; - } - - return first * second; -} - -uint64_t _TIFFMultiply64(TIFF *tif, uint64_t first, uint64_t second, - const char *where) -{ - if (second && first > UINT64_MAX / second) - { - 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) -{ - if (first <= 0 || second <= 0) - { - if (tif != NULL && where != NULL) - { - TIFFErrorExtR(tif, where, - "Invalid argument to _TIFFMultiplySSize() 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) - { - if (tif != NULL && module != NULL) - { - TIFFErrorExtR(tif, module, "Integer overflow"); - } - return 0; - } - return (tmsize_t)val; -} - -void *_TIFFCheckRealloc(TIFF *tif, void *buffer, tmsize_t nmemb, - tmsize_t elem_size, const char *what) -{ - void *cp = NULL; - tmsize_t count = _TIFFMultiplySSize(tif, nmemb, elem_size, NULL); - /* - * Check for integer overflow. - */ - if (count != 0) - { - cp = _TIFFreallocExt(tif, buffer, count); - } - - if (cp == NULL) - { - TIFFErrorExtR(tif, tif->tif_name, - "Failed to allocate memory for %s " - "(%" TIFF_SSIZE_FORMAT " elements of %" TIFF_SSIZE_FORMAT - " bytes each)", - what, nmemb, elem_size); - } - - return cp; -} - -void *_TIFFCheckMalloc(TIFF *tif, tmsize_t nmemb, tmsize_t elem_size, - const char *what) -{ - return _TIFFCheckRealloc(tif, NULL, nmemb, elem_size, what); -} - -static int TIFFDefaultTransferFunction(TIFF *tif, TIFFDirectory *td) -{ - uint16_t **tf = td->td_transferfunction; - tmsize_t i, n, nbytes; - - tf[0] = tf[1] = tf[2] = 0; - if (td->td_bitspersample >= sizeof(tmsize_t) * 8 - 2) - return 0; - - n = ((tmsize_t)1) << td->td_bitspersample; - nbytes = n * sizeof(uint16_t); - tf[0] = (uint16_t *)_TIFFmallocExt(tif, nbytes); - if (tf[0] == NULL) - return 0; - tf[0][0] = 0; - for (i = 1; i < n; i++) - { - double t = (double)i / ((double)n - 1.); - tf[0][i] = (uint16_t)floor(65535. * pow(t, 2.2) + .5); - } - - if (td->td_samplesperpixel - td->td_extrasamples > 1) - { - tf[1] = (uint16_t *)_TIFFmallocExt(tif, nbytes); - if (tf[1] == NULL) - goto bad; - _TIFFmemcpy(tf[1], tf[0], nbytes); - tf[2] = (uint16_t *)_TIFFmallocExt(tif, nbytes); - if (tf[2] == NULL) - goto bad; - _TIFFmemcpy(tf[2], tf[0], nbytes); - } - return 1; - -bad: - if (tf[0]) - _TIFFfreeExt(tif, tf[0]); - if (tf[1]) - _TIFFfreeExt(tif, tf[1]); - if (tf[2]) - _TIFFfreeExt(tif, tf[2]); - tf[0] = tf[1] = tf[2] = 0; - return 0; -} - -static int TIFFDefaultRefBlackWhite(TIFF *tif, TIFFDirectory *td) -{ - int i; - - td->td_refblackwhite = (float *)_TIFFmallocExt(tif, 6 * sizeof(float)); - if (td->td_refblackwhite == NULL) - return 0; - if (td->td_photometric == PHOTOMETRIC_YCBCR) - { - /* - * 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[1] = td->td_refblackwhite[3] = - td->td_refblackwhite[5] = 255.0F; - td->td_refblackwhite[2] = td->td_refblackwhite[4] = 128.0F; - } - else - { - /* - * Assume RGB (Class R) - */ - 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); - } - } - return 1; -} - -/* - * Like TIFFGetField, but return any default - * value if the tag is not present in the directory. - * - * NB: We use the value in the directory, rather than - * explicit values so that defaults exist only one - * place in the library -- in TIFFDefaultDirectory. - */ -int TIFFVGetFieldDefaulted(TIFF *tif, uint32_t tag, va_list ap) -{ - TIFFDirectory *td = &tif->tif_dir; - - if (TIFFVGetField(tif, tag, ap)) - return (1); - switch (tag) - { - case TIFFTAG_SUBFILETYPE: - *va_arg(ap, uint32_t *) = td->td_subfiletype; - return (1); - case TIFFTAG_BITSPERSAMPLE: - *va_arg(ap, uint16_t *) = td->td_bitspersample; - return (1); - case TIFFTAG_THRESHHOLDING: - *va_arg(ap, uint16_t *) = td->td_threshholding; - return (1); - case TIFFTAG_FILLORDER: - *va_arg(ap, uint16_t *) = td->td_fillorder; - return (1); - case TIFFTAG_ORIENTATION: - *va_arg(ap, uint16_t *) = td->td_orientation; - return (1); - case TIFFTAG_SAMPLESPERPIXEL: - *va_arg(ap, uint16_t *) = td->td_samplesperpixel; - return (1); - case TIFFTAG_ROWSPERSTRIP: - *va_arg(ap, uint32_t *) = td->td_rowsperstrip; - return (1); - case TIFFTAG_MINSAMPLEVALUE: - *va_arg(ap, uint16_t *) = td->td_minsamplevalue; - return (1); - case TIFFTAG_MAXSAMPLEVALUE: - { - uint16_t maxsamplevalue; - /* td_bitspersample=1 is always set in TIFFDefaultDirectory(). - * Therefore, td_maxsamplevalue has to be re-calculated in - * TIFFGetFieldDefaulted(). */ - if (td->td_bitspersample > 0) - { - /* This shift operation into a uint16_t limits the value to - * 65535 even if td_bitspersamle is > 16 */ - if (td->td_bitspersample <= 16) - { - maxsamplevalue = (1 << td->td_bitspersample) - - 1; /* 2**(BitsPerSample) - 1 */ - } - else - { - maxsamplevalue = 65535; - } - } - else - { - maxsamplevalue = 0; - } - *va_arg(ap, uint16_t *) = maxsamplevalue; - return (1); - } - case TIFFTAG_PLANARCONFIG: - *va_arg(ap, uint16_t *) = td->td_planarconfig; - return (1); - case TIFFTAG_RESOLUTIONUNIT: - *va_arg(ap, uint16_t *) = td->td_resolutionunit; - return (1); - case TIFFTAG_PREDICTOR: - { - TIFFPredictorState *sp = (TIFFPredictorState *)tif->tif_data; - if (sp == NULL) - { - TIFFErrorExtR( - tif, tif->tif_name, - "Cannot get \"Predictor\" tag as plugin is not configured"); - *va_arg(ap, uint16_t *) = 0; - return 0; - } - *va_arg(ap, uint16_t *) = (uint16_t)sp->predictor; - return 1; - } - case TIFFTAG_DOTRANGE: - *va_arg(ap, uint16_t *) = 0; - *va_arg(ap, uint16_t *) = (1 << td->td_bitspersample) - 1; - return (1); - case TIFFTAG_INKSET: - *va_arg(ap, uint16_t *) = INKSET_CMYK; - return 1; - case TIFFTAG_NUMBEROFINKS: - *va_arg(ap, uint16_t *) = 4; - return (1); - case TIFFTAG_EXTRASAMPLES: - *va_arg(ap, uint16_t *) = td->td_extrasamples; - *va_arg(ap, const uint16_t **) = td->td_sampleinfo; - return (1); - case TIFFTAG_MATTEING: - *va_arg(ap, uint16_t *) = - (td->td_extrasamples == 1 && - 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; - return (1); - case TIFFTAG_SAMPLEFORMAT: - *va_arg(ap, uint16_t *) = td->td_sampleformat; - return (1); - case TIFFTAG_IMAGEDEPTH: - *va_arg(ap, uint32_t *) = td->td_imagedepth; - return (1); - case TIFFTAG_YCBCRCOEFFICIENTS: - { - /* defaults are from CCIR Recommendation 601-1 */ - static const float ycbcrcoeffs[] = {0.299f, 0.587f, 0.114f}; - *va_arg(ap, const float **) = ycbcrcoeffs; - return 1; - } - case TIFFTAG_YCBCRSUBSAMPLING: - *va_arg(ap, uint16_t *) = td->td_ycbcrsubsampling[0]; - *va_arg(ap, uint16_t *) = td->td_ycbcrsubsampling[1]; - return (1); - case TIFFTAG_YCBCRPOSITIONING: - *va_arg(ap, uint16_t *) = td->td_ycbcrpositioning; - return (1); - case TIFFTAG_WHITEPOINT: - { - /* TIFF 6.0 specification tells that it is no default - value for the WhitePoint, but AdobePhotoshop TIFF - Technical Note tells that it should be CIE D50. */ - static const float whitepoint[] = { - D50_X0 / (D50_X0 + D50_Y0 + D50_Z0), - D50_Y0 / (D50_X0 + D50_Y0 + D50_Z0)}; - *va_arg(ap, const float **) = whitepoint; - return 1; - } - case TIFFTAG_TRANSFERFUNCTION: - if (!td->td_transferfunction[0] && - !TIFFDefaultTransferFunction(tif, td)) - { - TIFFErrorExtR(tif, tif->tif_name, - "No space for \"TransferFunction\" tag"); - return (0); - } - *va_arg(ap, const uint16_t **) = td->td_transferfunction[0]; - if (td->td_samplesperpixel - td->td_extrasamples > 1) - { - *va_arg(ap, const uint16_t **) = td->td_transferfunction[1]; - *va_arg(ap, const uint16_t **) = td->td_transferfunction[2]; - } - return (1); - case TIFFTAG_REFERENCEBLACKWHITE: - if (!td->td_refblackwhite && !TIFFDefaultRefBlackWhite(tif, td)) - return (0); - *va_arg(ap, const float **) = td->td_refblackwhite; - return (1); - } - return 0; -} - -/* - * Like TIFFGetField, but return any default - * value if the tag is not present in the directory. - */ -int TIFFGetFieldDefaulted(TIFF *tif, uint32_t tag, ...) -{ - int ok; - va_list ap; - - va_start(ap, tag); - ok = TIFFVGetFieldDefaulted(tif, tag, ap); - va_end(ap); - return (ok); -} - -struct _Int64Parts -{ - int32_t low, high; -}; - -typedef union -{ - struct _Int64Parts part; - int64_t value; -} _Int64; - -float _TIFFUInt64ToFloat(uint64_t ui64) -{ - _Int64 i; - - i.value = ui64; - if (i.part.high >= 0) - { - return (float)i.value; - } - else - { - long double df; - df = (long double)i.value; - df += 18446744073709551616.0; /* adding 2**64 */ - return (float)df; - } -} - -double _TIFFUInt64ToDouble(uint64_t ui64) -{ - _Int64 i; - - i.value = ui64; - if (i.part.high >= 0) - { - return (double)i.value; - } - else - { - long double df; - df = (long double)i.value; - df += 18446744073709551616.0; /* adding 2**64 */ - return (double)df; - } -} - -float _TIFFClampDoubleToFloat(double val) -{ - if (val > FLT_MAX) - return FLT_MAX; - if (val < -FLT_MAX) - return -FLT_MAX; - return (float)val; -} - -uint32_t _TIFFClampDoubleToUInt32(double val) -{ - if (val < 0) - return 0; - if (val > 0xFFFFFFFFU || val != val) - return 0xFFFFFFFFU; - return (uint32_t)val; -} - -int _TIFFSeekOK(TIFF *tif, toff_t off) -{ - /* Huge offsets, especially -1 / UINT64_MAX, can cause issues */ - /* See http://bugzilla.maptools.org/show_bug.cgi?id=2726 */ - return off <= (~(uint64_t)0) / 2 && TIFFSeekFile(tif, off, SEEK_SET) == off; -} diff --git a/src/3rd/tiff/close.c b/src/3rd/tiff/close.c deleted file mode 100644 index 907d7f139b7..00000000000 --- a/src/3rd/tiff/close.c +++ /dev/null @@ -1,158 +0,0 @@ -/* - * Copyright (c) 1988-1997 Sam Leffler - * Copyright (c) 1991-1997 Silicon Graphics, Inc. - * - * Permission to use, copy, modify, distribute, and sell this software and - * its documentation for any purpose is hereby granted without fee, provided - * that (i) the above copyright notices and this permission notice appear in - * all copies of the software and related documentation, and (ii) the names of - * Sam Leffler and Silicon Graphics may not be used in any advertising or - * publicity relating to the software without the specific, prior written - * permission of Sam Leffler and Silicon Graphics. - * - * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, - * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY - * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. - * - * IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR - * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, - * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, - * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF - * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE - * OF THIS SOFTWARE. - */ - -/* - * TIFF Library. - */ -#include "tiffiop.h" -#include - -/************************************************************************/ -/* TIFFCleanup() */ -/************************************************************************/ - -/** - * Auxiliary function to free the TIFF structure. Given structure will be - * completely freed, so you should save opened file handle and pointer - * to the close procedure in external variables before calling - * _TIFFCleanup(), if you will need these ones to close the file. - * - * @param tif A TIFF pointer. - */ - -void TIFFCleanup(TIFF *tif) -{ - /* - * Flush buffered data and directory (if dirty). - */ - if (tif->tif_mode != O_RDONLY) - TIFFFlush(tif); - (*tif->tif_cleanup)(tif); - TIFFFreeDirectory(tif); - - _TIFFCleanupIFDOffsetAndNumberMaps(tif); - - /* - * Clean up client info links. - */ - while (tif->tif_clientinfo) - { - TIFFClientInfoLink *psLink = tif->tif_clientinfo; - - tif->tif_clientinfo = psLink->next; - _TIFFfreeExt(tif, psLink->name); - _TIFFfreeExt(tif, psLink); - } - - if (tif->tif_rawdata && (tif->tif_flags & TIFF_MYBUFFER)) - _TIFFfreeExt(tif, tif->tif_rawdata); - if (isMapped(tif)) - TIFFUnmapFileContents(tif, tif->tif_base, (toff_t)tif->tif_size); - - /* - * Clean up custom fields. - */ - if (tif->tif_fields && tif->tif_nfields > 0) - { - uint32_t i; - - for (i = 0; i < tif->tif_nfields; i++) - { - TIFFField *fld = tif->tif_fields[i]; - if (fld->field_name != NULL) - { - if (fld->field_bit == FIELD_CUSTOM && - /* caution: tif_fields[i] must not be the beginning of a - * fields-array. Otherwise the following tags are also freed - * with the first free(). - */ - TIFFFieldIsAnonymous(fld)) - { - _TIFFfreeExt(tif, fld->field_name); - _TIFFfreeExt(tif, fld); - } - } - } - - _TIFFfreeExt(tif, tif->tif_fields); - } - - if (tif->tif_nfieldscompat > 0) - { - uint32_t i; - - for (i = 0; i < tif->tif_nfieldscompat; i++) - { - if (tif->tif_fieldscompat[i].allocated_size) - _TIFFfreeExt(tif, tif->tif_fieldscompat[i].fields); - } - _TIFFfreeExt(tif, tif->tif_fieldscompat); - } - - _TIFFfreeExt(NULL, tif); -} - -/************************************************************************/ -/* _TIFFCleanupIFDOffsetAndNumberMaps() */ -/************************************************************************/ - -void _TIFFCleanupIFDOffsetAndNumberMaps(TIFF *tif) -{ - if (tif->tif_map_dir_offset_to_number) - { - TIFFHashSetDestroy(tif->tif_map_dir_offset_to_number); - tif->tif_map_dir_offset_to_number = NULL; - } - if (tif->tif_map_dir_number_to_offset) - { - TIFFHashSetDestroy(tif->tif_map_dir_number_to_offset); - tif->tif_map_dir_number_to_offset = NULL; - } -} - -/************************************************************************/ -/* TIFFClose() */ -/************************************************************************/ - -/** - * Close a previously opened TIFF file. - * - * TIFFClose closes a file that was previously opened with TIFFOpen(). - * Any buffered data are flushed to the file, including the contents of - * the current directory (if modified); and all resources are reclaimed. - * - * @param tif A TIFF pointer. - */ - -void TIFFClose(TIFF *tif) -{ - if (tif != NULL) - { - TIFFCloseProc closeproc = tif->tif_closeproc; - thandle_t fd = tif->tif_clientdata; - - TIFFCleanup(tif); - (void)(*closeproc)(fd); - } -} diff --git a/src/3rd/tiff/codec.c b/src/3rd/tiff/codec.c deleted file mode 100644 index d499b63a584..00000000000 --- a/src/3rd/tiff/codec.c +++ /dev/null @@ -1,163 +0,0 @@ -/* - * Copyright (c) 1988-1997 Sam Leffler - * Copyright (c) 1991-1997 Silicon Graphics, Inc. - * - * Permission to use, copy, modify, distribute, and sell this software and - * its documentation for any purpose is hereby granted without fee, provided - * that (i) the above copyright notices and this permission notice appear in - * all copies of the software and related documentation, and (ii) the names of - * Sam Leffler and Silicon Graphics may not be used in any advertising or - * publicity relating to the software without the specific, prior written - * permission of Sam Leffler and Silicon Graphics. - * - * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, - * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY - * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. - * - * IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR - * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, - * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, - * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF - * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE - * OF THIS SOFTWARE. - */ - -/* - * TIFF Library - * - * Builtin Compression Scheme Configuration Support. - */ -#include "tiffiop.h" - -static int NotConfigured(TIFF *, int); - -#ifndef LZW_SUPPORT -#define TIFFInitLZW NotConfigured -#endif -#ifndef PACKBITS_SUPPORT -#define TIFFInitPackBits NotConfigured -#endif -#ifndef THUNDER_SUPPORT -#define TIFFInitThunderScan NotConfigured -#endif -#ifndef NEXT_SUPPORT -#define TIFFInitNeXT NotConfigured -#endif -#ifndef JPEG_SUPPORT -#define TIFFInitJPEG NotConfigured -#endif -#ifndef OJPEG_SUPPORT -#define TIFFInitOJPEG NotConfigured -#endif -#ifndef CCITT_SUPPORT -#define TIFFInitCCITTRLE NotConfigured -#define TIFFInitCCITTRLEW NotConfigured -#define TIFFInitCCITTFax3 NotConfigured -#define TIFFInitCCITTFax4 NotConfigured -#endif -#ifndef JBIG_SUPPORT -#define TIFFInitJBIG NotConfigured -#endif -#ifndef ZIP_SUPPORT -#define TIFFInitZIP NotConfigured -#endif -#ifndef PIXARLOG_SUPPORT -#define TIFFInitPixarLog NotConfigured -#endif -#ifndef LOGLUV_SUPPORT -#define TIFFInitSGILog NotConfigured -#endif -#ifndef LERC_SUPPORT -#define TIFFInitLERC NotConfigured -#endif -#ifndef LZMA_SUPPORT -#define TIFFInitLZMA NotConfigured -#endif -#ifndef ZSTD_SUPPORT -#define TIFFInitZSTD NotConfigured -#endif -#ifndef WEBP_SUPPORT -#define TIFFInitWebP NotConfigured -#endif - -/* - * Compression schemes statically built into the library. - */ -const TIFFCodec _TIFFBuiltinCODECS[] = { - {"None", COMPRESSION_NONE, TIFFInitDumpMode}, - {"LZW", COMPRESSION_LZW, TIFFInitLZW}, - {"PackBits", COMPRESSION_PACKBITS, TIFFInitPackBits}, - {"ThunderScan", COMPRESSION_THUNDERSCAN, TIFFInitThunderScan}, - {"NeXT", COMPRESSION_NEXT, TIFFInitNeXT}, - {"JPEG", COMPRESSION_JPEG, TIFFInitJPEG}, - {"Old-style JPEG", COMPRESSION_OJPEG, TIFFInitOJPEG}, - {"CCITT RLE", COMPRESSION_CCITTRLE, TIFFInitCCITTRLE}, - {"CCITT RLE/W", COMPRESSION_CCITTRLEW, TIFFInitCCITTRLEW}, - {"CCITT Group 3", COMPRESSION_CCITTFAX3, TIFFInitCCITTFax3}, - {"CCITT Group 4", COMPRESSION_CCITTFAX4, TIFFInitCCITTFax4}, - {"ISO JBIG", COMPRESSION_JBIG, TIFFInitJBIG}, - {"Deflate", COMPRESSION_DEFLATE, TIFFInitZIP}, - {"AdobeDeflate", COMPRESSION_ADOBE_DEFLATE, TIFFInitZIP}, - {"PixarLog", COMPRESSION_PIXARLOG, TIFFInitPixarLog}, - {"SGILog", COMPRESSION_SGILOG, TIFFInitSGILog}, - {"SGILog24", COMPRESSION_SGILOG24, TIFFInitSGILog}, - {"LZMA", COMPRESSION_LZMA, TIFFInitLZMA}, - {"ZSTD", COMPRESSION_ZSTD, TIFFInitZSTD}, - {"WEBP", COMPRESSION_WEBP, TIFFInitWebP}, - {"LERC", COMPRESSION_LERC, TIFFInitLERC}, - {NULL, 0, NULL}}; - -static int _notConfigured(TIFF *tif) -{ - const TIFFCodec *c = TIFFFindCODEC(tif->tif_dir.td_compression); - char compression_code[20]; - - snprintf(compression_code, sizeof(compression_code), "%" PRIu16, - tif->tif_dir.td_compression); - TIFFErrorExtR(tif, tif->tif_name, - "%s compression support is not configured", - c ? c->name : compression_code); - return (0); -} - -static int NotConfigured(TIFF *tif, int scheme) -{ - (void)scheme; - - tif->tif_fixuptags = _notConfigured; - tif->tif_decodestatus = FALSE; - tif->tif_setupdecode = _notConfigured; - tif->tif_encodestatus = FALSE; - tif->tif_setupencode = _notConfigured; - return (1); -} - -/************************************************************************/ -/* TIFFIsCODECConfigured() */ -/************************************************************************/ - -/** - * Check whether we have working codec for the specific coding scheme. - * - * @return returns 1 if the codec is configured and working. Otherwise - * 0 will be returned. - */ - -int TIFFIsCODECConfigured(uint16_t scheme) -{ - const TIFFCodec *codec = TIFFFindCODEC(scheme); - - if (codec == NULL) - { - return 0; - } - if (codec->init == NULL) - { - return 0; - } - if (codec->init != NotConfigured) - { - return 1; - } - return 0; -} diff --git a/src/3rd/tiff/color.c b/src/3rd/tiff/color.c deleted file mode 100644 index 2d7dcac6fe6..00000000000 --- a/src/3rd/tiff/color.c +++ /dev/null @@ -1,322 +0,0 @@ -/* - * Copyright (c) 1988-1997 Sam Leffler - * Copyright (c) 1991-1997 Silicon Graphics, Inc. - * - * Permission to use, copy, modify, distribute, and sell this software and - * its documentation for any purpose is hereby granted without fee, provided - * that (i) the above copyright notices and this permission notice appear in - * all copies of the software and related documentation, and (ii) the names of - * Sam Leffler and Silicon Graphics may not be used in any advertising or - * publicity relating to the software without the specific, prior written - * permission of Sam Leffler and Silicon Graphics. - * - * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, - * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY - * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. - * - * IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR - * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, - * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, - * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF - * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE - * OF THIS SOFTWARE. - */ - -/* - * CIE L*a*b* to CIE XYZ and CIE XYZ to RGB conversion routines are taken - * from the VIPS library (http://www.vips.ecs.soton.ac.uk) with - * the permission of John Cupitt, the VIPS author. - */ - -/* - * TIFF Library. - * - * Color space conversion routines. - */ - -#include "tiffiop.h" -#include - -/* - * Convert color value from the CIE L*a*b* 1976 space to CIE XYZ. - */ -void TIFFCIELabToXYZ(TIFFCIELabToRGB *cielab, uint32_t l, int32_t a, int32_t b, - float *X, float *Y, float *Z) -{ - TIFFCIELab16ToXYZ(cielab, l * 257, a * 256, b * 256, X, Y, Z); -} - -/* - * For CIELab encoded in 16 bits, L is an unsigned integer range [0,65535]. - * The a* and b* components are signed integers range [-32768,32767]. The 16 - * bit chrominance values are encoded as 256 times the 1976 CIE a* and b* - * values - */ -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 cby, tmp; - - if (L < 8.856F) - { - *Y = (L * cielab->Y0) / 903.292F; - cby = 7.787F * (*Y / cielab->Y0) + 16.0F / 116.0F; - } - else - { - 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; - 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; - else - *Z = cielab->Z0 * tmp * tmp * tmp; -} - -#define RINT(R) ((uint32_t)((R) > 0 ? ((R) + 0.5) : ((R)-0.5))) -/* - * Convert color value from the XYZ space to RGB. - */ -void TIFFXYZToRGB(TIFFCIELabToRGB *cielab, float X, float Y, float Z, - uint32_t *r, uint32_t *g, uint32_t *b) -{ - int i; - float Yr, Yg, Yb; - float *matrix = &cielab->display.d_mat[0][0]; - - /* Multiply through the matrix to get luminosity values. */ - Yr = matrix[0] * X + matrix[1] * Y + matrix[2] * Z; - Yg = matrix[3] * X + matrix[4] * Y + matrix[5] * Z; - Yb = matrix[6] * X + matrix[7] * Y + matrix[8] * Z; - - /* Clip input */ - Yr = TIFFmax(Yr, cielab->display.d_Y0R); - Yg = TIFFmax(Yg, cielab->display.d_Y0G); - Yb = TIFFmax(Yb, cielab->display.d_Y0B); - - /* Avoid overflow in case of wrong input values */ - Yr = TIFFmin(Yr, cielab->display.d_YCR); - Yg = TIFFmin(Yg, cielab->display.d_YCG); - Yb = TIFFmin(Yb, cielab->display.d_YCB); - - /* Turn luminosity to colour value. */ - i = (int)((Yr - cielab->display.d_Y0R) / cielab->rstep); - i = TIFFmin(cielab->range, i); - *r = RINT(cielab->Yr2r[i]); - - i = (int)((Yg - cielab->display.d_Y0G) / cielab->gstep); - i = TIFFmin(cielab->range, i); - *g = RINT(cielab->Yg2g[i]); - - i = (int)((Yb - cielab->display.d_Y0B) / cielab->bstep); - i = TIFFmin(cielab->range, i); - *b = RINT(cielab->Yb2b[i]); - - /* Clip output. */ - *r = TIFFmin(*r, cielab->display.d_Vrwr); - *g = TIFFmin(*g, cielab->display.d_Vrwg); - *b = TIFFmin(*b, cielab->display.d_Vrwb); -} -#undef RINT - -/* - * Allocate conversion state structures and make look_up tables for - * the Yr,Yb,Yg <=> r,g,b conversions. - */ -int TIFFCIELabToRGBInit(TIFFCIELabToRGB *cielab, const TIFFDisplay *display, - float *refWhite) -{ - int i; - double dfGamma; - - cielab->range = CIELABTORGB_TABLE_RANGE; - - _TIFFmemcpy(&cielab->display, display, sizeof(TIFFDisplay)); - - /* Red */ - dfGamma = 1.0 / cielab->display.d_gammaR; - cielab->rstep = - (cielab->display.d_YCR - cielab->display.d_Y0R) / cielab->range; - for (i = 0; i <= cielab->range; i++) - { - cielab->Yr2r[i] = cielab->display.d_Vrwr * - ((float)pow((double)i / cielab->range, dfGamma)); - } - - /* Green */ - dfGamma = 1.0 / cielab->display.d_gammaG; - cielab->gstep = - (cielab->display.d_YCR - cielab->display.d_Y0R) / cielab->range; - for (i = 0; i <= cielab->range; i++) - { - cielab->Yg2g[i] = cielab->display.d_Vrwg * - ((float)pow((double)i / cielab->range, dfGamma)); - } - - /* Blue */ - dfGamma = 1.0 / cielab->display.d_gammaB; - cielab->bstep = - (cielab->display.d_YCR - cielab->display.d_Y0R) / cielab->range; - for (i = 0; i <= cielab->range; i++) - { - cielab->Yb2b[i] = cielab->display.d_Vrwb * - ((float)pow((double)i / cielab->range, dfGamma)); - } - - /* Init reference white point */ - cielab->X0 = refWhite[0]; - cielab->Y0 = refWhite[1]; - cielab->Z0 = refWhite[2]; - - return 0; -} - -/* - * Convert color value from the YCbCr space to RGB. - * The colorspace conversion algorithm comes from the IJG v5a code; - * see below for more information on how it works. - */ -#define SHIFT 16 -#define FIX(x) ((int32_t)((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)) -/* !((f)>=(min)) written that way to deal with NaN */ -#define CLAMP(f, min, max) \ - ((!((f) >= (min))) ? (min) : (f) > (max) ? (max) : (f)) -#define HICLAMP(f, max) ((f) > (max) ? (max) : (f)) - -void TIFFYCbCrtoRGB(TIFFYCbCrToRGB *ycbcr, uint32_t Y, int32_t Cb, int32_t Cr, - uint32_t *r, uint32_t *g, uint32_t *b) -{ - int32_t i; - - /* XXX: Only 8-bit YCbCr input supported for now */ - Y = HICLAMP(Y, 255); - Cb = CLAMP(Cb, 0, 255); - Cr = CLAMP(Cr, 0, 255); - - i = ycbcr->Y_tab[Y] + ycbcr->Cr_r_tab[Cr]; - *r = 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); - i = ycbcr->Y_tab[Y] + ycbcr->Cb_b_tab[Cb]; - *b = CLAMP(i, 0, 255); -} - -/* Clamp function for sanitization purposes. Normally clamping should not */ -/* occur for well behaved chroma and refBlackWhite coefficients */ -static float CLAMPw(float v, float vmin, float vmax) -{ - if (v < vmin) - { - /* printf("%f clamped to %f\n", v, vmin); */ - return vmin; - } - if (v > vmax) - { - /* printf("%f clamped to %f\n", v, vmax); */ - return vmax; - } - return v; -} - -/* - * Initialize the YCbCr->RGB conversion tables. The conversion - * is done according to the 6.0 spec: - * - * R = Y + Cr*(2 - 2*LumaRed) - * B = Y + Cb*(2 - 2*LumaBlue) - * G = Y - * - LumaBlue*Cb*(2-2*LumaBlue)/LumaGreen - * - LumaRed*Cr*(2-2*LumaRed)/LumaGreen - * - * To avoid floating point arithmetic the fractional constants that - * come out of the equations are represented as fixed point values - * in the range 0...2^16. We also eliminate multiplications by - * pre-calculating possible values indexed by Cb and Cr (this code - * assumes conversion is being done for 8-bit samples). - */ -int TIFFYCbCrToRGBInit(TIFFYCbCrToRGB *ycbcr, float *luma, float *refBlackWhite) -{ - TIFFRGBValue *clamptab; - int i; - -#define LumaRed luma[0] -#define LumaGreen luma[1] -#define LumaBlue luma[2] - - clamptab = - (TIFFRGBValue *)((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++) - clamptab[i] = (TIFFRGBValue)i; - _TIFFmemset(clamptab + 256, 255, 2 * 256); /* v > 255 => 255 */ - ycbcr->Cr_r_tab = (int *)(clamptab + 3 * 256); - ycbcr->Cb_b_tab = ycbcr->Cr_r_tab + 256; - ycbcr->Cr_g_tab = (int32_t *)(ycbcr->Cb_b_tab + 256); - ycbcr->Cb_g_tab = ycbcr->Cr_g_tab + 256; - ycbcr->Y_tab = ycbcr->Cb_g_tab + 256; - - { - float f1 = 2 - 2 * LumaRed; - 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)); - float f3 = 2 - 2 * LumaBlue; - 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)); - int x; - -#undef LumaBlue -#undef LumaGreen -#undef LumaRed - - /* - * i is the actual input pixel value in the range 0..255 - * Cb and Cr values are in the range -128..127 (actually - * they are in a range defined by the ReferenceBlackWhite - * tag) so there is some range shifting to do here when - * constructing tables indexed by the raw pixel data. - */ - 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); - - ycbcr->Cr_r_tab[i] = (int32_t)((D1 * Cr + ONE_HALF) >> SHIFT); - ycbcr->Cb_b_tab[i] = (int32_t)((D3 * Cb + ONE_HALF) >> SHIFT); - ycbcr->Cr_g_tab[i] = D2 * Cr; - 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); - } - } - - return 0; -} -#undef HICLAMP -#undef CLAMP -#undef Code2V -#undef SHIFT -#undef ONE_HALF -#undef FIX diff --git a/src/3rd/tiff/compress.c b/src/3rd/tiff/compress.c deleted file mode 100644 index c6e17d3e114..00000000000 --- a/src/3rd/tiff/compress.c +++ /dev/null @@ -1,310 +0,0 @@ -/* - * Copyright (c) 1988-1997 Sam Leffler - * Copyright (c) 1991-1997 Silicon Graphics, Inc. - * - * Permission to use, copy, modify, distribute, and sell this software and - * its documentation for any purpose is hereby granted without fee, provided - * that (i) the above copyright notices and this permission notice appear in - * all copies of the software and related documentation, and (ii) the names of - * Sam Leffler and Silicon Graphics may not be used in any advertising or - * publicity relating to the software without the specific, prior written - * permission of Sam Leffler and Silicon Graphics. - * - * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, - * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY - * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. - * - * IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR - * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, - * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, - * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF - * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE - * OF THIS SOFTWARE. - */ - -/* - * TIFF Library - * - * Compression Scheme Configuration Support. - */ -#include "tiffiop.h" - -static int TIFFNoEncode(TIFF *tif, const char *method) -{ - const TIFFCodec *c = TIFFFindCODEC(tif->tif_dir.td_compression); - - if (c) - { - TIFFErrorExtR(tif, tif->tif_name, "%s %s encoding is not implemented", - c->name, method); - } - else - { - TIFFErrorExtR(tif, tif->tif_name, - "Compression scheme %" PRIu16 - " %s encoding is not implemented", - tif->tif_dir.td_compression, method); - } - return (-1); -} - -int _TIFFNoRowEncode(TIFF *tif, uint8_t *pp, tmsize_t cc, uint16_t s) -{ - (void)pp; - (void)cc; - (void)s; - return (TIFFNoEncode(tif, "scanline")); -} - -int _TIFFNoStripEncode(TIFF *tif, uint8_t *pp, tmsize_t cc, uint16_t s) -{ - (void)pp; - (void)cc; - (void)s; - return (TIFFNoEncode(tif, "strip")); -} - -int _TIFFNoTileEncode(TIFF *tif, uint8_t *pp, tmsize_t cc, uint16_t s) -{ - (void)pp; - (void)cc; - (void)s; - return (TIFFNoEncode(tif, "tile")); -} - -static int TIFFNoDecode(TIFF *tif, const char *method) -{ - const TIFFCodec *c = TIFFFindCODEC(tif->tif_dir.td_compression); - - if (c) - TIFFErrorExtR(tif, tif->tif_name, "%s %s decoding is not implemented", - c->name, method); - else - TIFFErrorExtR(tif, tif->tif_name, - "Compression scheme %" PRIu16 - " %s decoding is not implemented", - tif->tif_dir.td_compression, method); - return (0); -} - -static int _TIFFNoFixupTags(TIFF *tif) -{ - (void)tif; - return (1); -} - -int _TIFFNoRowDecode(TIFF *tif, uint8_t *pp, tmsize_t cc, uint16_t s) -{ - (void)pp; - (void)cc; - (void)s; - return (TIFFNoDecode(tif, "scanline")); -} - -int _TIFFNoStripDecode(TIFF *tif, uint8_t *pp, tmsize_t cc, uint16_t s) -{ - (void)pp; - (void)cc; - (void)s; - return (TIFFNoDecode(tif, "strip")); -} - -int _TIFFNoTileDecode(TIFF *tif, uint8_t *pp, tmsize_t cc, uint16_t s) -{ - (void)pp; - (void)cc; - (void)s; - return (TIFFNoDecode(tif, "tile")); -} - -int _TIFFNoSeek(TIFF *tif, uint32_t off) -{ - (void)off; - TIFFErrorExtR(tif, tif->tif_name, - "Compression algorithm does not support random access"); - return (0); -} - -int _TIFFNoPreCode(TIFF *tif, uint16_t s) -{ - (void)tif; - (void)s; - return (1); -} - -static int _TIFFtrue(TIFF *tif) -{ - (void)tif; - return (1); -} -static void _TIFFvoid(TIFF *tif) { (void)tif; } - -void _TIFFSetDefaultCompressionState(TIFF *tif) -{ - tif->tif_fixuptags = _TIFFNoFixupTags; - tif->tif_decodestatus = TRUE; - tif->tif_setupdecode = _TIFFtrue; - tif->tif_predecode = _TIFFNoPreCode; - tif->tif_decoderow = _TIFFNoRowDecode; - tif->tif_decodestrip = _TIFFNoStripDecode; - tif->tif_decodetile = _TIFFNoTileDecode; - tif->tif_encodestatus = TRUE; - tif->tif_setupencode = _TIFFtrue; - tif->tif_preencode = _TIFFNoPreCode; - tif->tif_postencode = _TIFFtrue; - tif->tif_encoderow = _TIFFNoRowEncode; - tif->tif_encodestrip = _TIFFNoStripEncode; - tif->tif_encodetile = _TIFFNoTileEncode; - tif->tif_close = _TIFFvoid; - tif->tif_seek = _TIFFNoSeek; - tif->tif_cleanup = _TIFFvoid; - tif->tif_defstripsize = _TIFFDefaultStripSize; - tif->tif_deftilesize = _TIFFDefaultTileSize; - tif->tif_flags &= ~(TIFF_NOBITREV | TIFF_NOREADRAW); -} - -int TIFFSetCompressionScheme(TIFF *tif, int scheme) -{ - const TIFFCodec *c = TIFFFindCODEC((uint16_t)scheme); - - _TIFFSetDefaultCompressionState(tif); - /* - * Don't treat an unknown compression scheme as an error. - * This permits applications to open files with data that - * the library does not have builtin support for, but which - * may still be meaningful. - */ - return (c ? (*c->init)(tif, scheme) : 1); -} - -/* - * Other compression schemes may be registered. Registered - * schemes can also override the builtin versions provided - * by this library. - */ -typedef struct _codec -{ - struct _codec *next; - TIFFCodec *info; -} codec_t; -static codec_t *registeredCODECS = NULL; - -const TIFFCodec *TIFFFindCODEC(uint16_t scheme) -{ - const TIFFCodec *c; - codec_t *cd; - - for (cd = registeredCODECS; cd; cd = cd->next) - if (cd->info->scheme == scheme) - return ((const TIFFCodec *)cd->info); - for (c = _TIFFBuiltinCODECS; c->name; c++) - if (c->scheme == scheme) - return (c); - return ((const TIFFCodec *)0); -} - -TIFFCodec *TIFFRegisterCODEC(uint16_t scheme, const char *name, - TIFFInitMethod init) -{ - codec_t *cd = (codec_t *)_TIFFmallocExt( - NULL, - (tmsize_t)(sizeof(codec_t) + sizeof(TIFFCodec) + strlen(name) + 1)); - - if (cd != NULL) - { - cd->info = (TIFFCodec *)((uint8_t *)cd + sizeof(codec_t)); - cd->info->name = (char *)((uint8_t *)cd->info + sizeof(TIFFCodec)); - strcpy(cd->info->name, name); - cd->info->scheme = scheme; - cd->info->init = init; - cd->next = registeredCODECS; - registeredCODECS = cd; - } - else - { - TIFFErrorExt(0, "TIFFRegisterCODEC", - "No space to register compression scheme %s", name); - return NULL; - } - return (cd->info); -} - -void TIFFUnRegisterCODEC(TIFFCodec *c) -{ - codec_t *cd; - codec_t **pcd; - - for (pcd = ®isteredCODECS; (cd = *pcd) != NULL; pcd = &cd->next) - if (cd->info == c) - { - *pcd = cd->next; - _TIFFfreeExt(NULL, cd); - return; - } - TIFFErrorExt(0, "TIFFUnRegisterCODEC", - "Cannot remove compression scheme %s; not registered", - c->name); -} - -/************************************************************************/ -/* TIFFGetConfisuredCODECs() */ -/************************************************************************/ - -/** - * Get list of configured codecs, both built-in and registered by user. - * Caller is responsible to free this structure. - * - * @return returns array of TIFFCodec records (the last record should be NULL) - * or NULL if function failed. - */ - -TIFFCodec *TIFFGetConfiguredCODECs() -{ - int i = 1; - codec_t *cd; - const TIFFCodec *c; - TIFFCodec *codecs = NULL; - TIFFCodec *new_codecs; - - for (cd = registeredCODECS; cd; cd = cd->next) - { - new_codecs = - (TIFFCodec *)_TIFFreallocExt(NULL, codecs, i * sizeof(TIFFCodec)); - if (!new_codecs) - { - _TIFFfreeExt(NULL, codecs); - return NULL; - } - codecs = new_codecs; - _TIFFmemcpy(codecs + i - 1, cd->info, sizeof(TIFFCodec)); - i++; - } - for (c = _TIFFBuiltinCODECS; c->name; c++) - { - if (TIFFIsCODECConfigured(c->scheme)) - { - new_codecs = (TIFFCodec *)_TIFFreallocExt(NULL, codecs, - i * sizeof(TIFFCodec)); - if (!new_codecs) - { - _TIFFfreeExt(NULL, codecs); - return NULL; - } - codecs = new_codecs; - _TIFFmemcpy(codecs + i - 1, (const void *)c, sizeof(TIFFCodec)); - i++; - } - } - - new_codecs = - (TIFFCodec *)_TIFFreallocExt(NULL, codecs, i * sizeof(TIFFCodec)); - if (!new_codecs) - { - _TIFFfreeExt(NULL, codecs); - return NULL; - } - codecs = new_codecs; - _TIFFmemset(codecs + i - 1, 0, sizeof(TIFFCodec)); - - return codecs; -} diff --git a/src/3rd/tiff/dir.c b/src/3rd/tiff/dir.c deleted file mode 100644 index 28c967c8dd3..00000000000 --- a/src/3rd/tiff/dir.c +++ /dev/null @@ -1,2311 +0,0 @@ -/* - * Copyright (c) 1988-1997 Sam Leffler - * Copyright (c) 1991-1997 Silicon Graphics, Inc. - * - * Permission to use, copy, modify, distribute, and sell this software and - * its documentation for any purpose is hereby granted without fee, provided - * that (i) the above copyright notices and this permission notice appear in - * all copies of the software and related documentation, and (ii) the names of - * Sam Leffler and Silicon Graphics may not be used in any advertising or - * publicity relating to the software without the specific, prior written - * permission of Sam Leffler and Silicon Graphics. - * - * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, - * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY - * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. - * - * IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR - * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, - * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, - * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF - * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE - * OF THIS SOFTWARE. - */ - -/* - * TIFF Library. - * - * Directory Tag Get & Set Routines. - * (and also some miscellaneous stuff) - */ -#include "tiffiop.h" -#include /*--: for Rational2Double */ -#include - -/* - * These are used in the backwards compatibility code... - */ -#define DATATYPE_VOID 0 /* !untyped data */ -#define DATATYPE_INT 1 /* !signed integer data */ -#define DATATYPE_UINT 2 /* !unsigned integer data */ -#define DATATYPE_IEEEFP 3 /* !IEEE floating point data */ - -static void setByteArray(TIFF *tif, void **vpp, const void *vp, size_t nmemb, - size_t elem_size) -{ - if (*vpp) - { - _TIFFfreeExt(tif, *vpp); - *vpp = 0; - } - if (vp) - { - tmsize_t bytes = _TIFFMultiplySSize(NULL, nmemb, elem_size, NULL); - if (bytes) - *vpp = (void *)_TIFFmallocExt(tif, bytes); - if (*vpp) - _TIFFmemcpy(*vpp, vp, bytes); - } -} -void _TIFFsetByteArray(void **vpp, const void *vp, uint32_t n) -{ - setByteArray(NULL, vpp, vp, n, 1); -} -void _TIFFsetByteArrayExt(TIFF *tif, void **vpp, const void *vp, uint32_t n) -{ - setByteArray(tif, vpp, vp, n, 1); -} - -static void _TIFFsetNString(TIFF *tif, char **cpp, const char *cp, uint32_t n) -{ - setByteArray(tif, (void **)cpp, cp, n, 1); -} - -void _TIFFsetShortArray(uint16_t **wpp, const uint16_t *wp, uint32_t n) -{ - setByteArray(NULL, (void **)wpp, wp, n, sizeof(uint16_t)); -} -void _TIFFsetShortArrayExt(TIFF *tif, uint16_t **wpp, const uint16_t *wp, - uint32_t n) -{ - setByteArray(tif, (void **)wpp, wp, n, sizeof(uint16_t)); -} - -void _TIFFsetLongArray(uint32_t **lpp, const uint32_t *lp, uint32_t n) -{ - setByteArray(NULL, (void **)lpp, lp, n, sizeof(uint32_t)); -} -void _TIFFsetLongArrayExt(TIFF *tif, uint32_t **lpp, const uint32_t *lp, - uint32_t n) -{ - setByteArray(tif, (void **)lpp, lp, n, sizeof(uint32_t)); -} - -static void _TIFFsetLong8Array(TIFF *tif, uint64_t **lpp, const uint64_t *lp, - uint32_t n) -{ - setByteArray(tif, (void **)lpp, lp, n, sizeof(uint64_t)); -} - -void _TIFFsetFloatArray(float **fpp, const float *fp, uint32_t n) -{ - setByteArray(NULL, (void **)fpp, fp, n, sizeof(float)); -} -void _TIFFsetFloatArrayExt(TIFF *tif, float **fpp, const float *fp, uint32_t n) -{ - setByteArray(tif, (void **)fpp, fp, n, sizeof(float)); -} - -void _TIFFsetDoubleArray(double **dpp, const double *dp, uint32_t n) -{ - setByteArray(NULL, (void **)dpp, dp, n, sizeof(double)); -} -void _TIFFsetDoubleArrayExt(TIFF *tif, double **dpp, const double *dp, - uint32_t n) -{ - setByteArray(tif, (void **)dpp, dp, n, sizeof(double)); -} - -static void setDoubleArrayOneValue(TIFF *tif, double **vpp, double value, - size_t nmemb) -{ - if (*vpp) - _TIFFfreeExt(tif, *vpp); - *vpp = _TIFFmallocExt(tif, nmemb * sizeof(double)); - if (*vpp) - { - while (nmemb--) - ((double *)*vpp)[nmemb] = value; - } -} - -/* - * Install extra samples information. - */ -static int setExtraSamples(TIFF *tif, va_list ap, uint32_t *v) -{ -/* XXX: Unassociated alpha data == 999 is a known Corel Draw bug, see below */ -#define EXTRASAMPLE_COREL_UNASSALPHA 999 - - uint16_t *va; - uint32_t i; - TIFFDirectory *td = &tif->tif_dir; - static const char module[] = "setExtraSamples"; - - *v = (uint16_t)va_arg(ap, uint16_vap); - if ((uint16_t)*v > td->td_samplesperpixel) - return 0; - va = va_arg(ap, uint16_t *); - if (*v > 0 && va == NULL) /* typically missing param */ - return 0; - for (i = 0; i < *v; i++) - { - if (va[i] > EXTRASAMPLE_UNASSALPHA) - { - /* - * XXX: Corel Draw is known to produce incorrect - * ExtraSamples tags which must be patched here if we - * want to be able to open some of the damaged TIFF - * files: - */ - if (va[i] == EXTRASAMPLE_COREL_UNASSALPHA) - va[i] = EXTRASAMPLE_UNASSALPHA; - else - return 0; - } - } - - if (td->td_transferfunction[0] != NULL && - (td->td_samplesperpixel - *v > 1) && - !(td->td_samplesperpixel - td->td_extrasamples > 1)) - { - TIFFWarningExtR(tif, module, - "ExtraSamples tag value is changing, " - "but TransferFunction was read with a different value. " - "Canceling it"); - TIFFClrFieldBit(tif, FIELD_TRANSFERFUNCTION); - _TIFFfreeExt(tif, td->td_transferfunction[0]); - td->td_transferfunction[0] = NULL; - } - - td->td_extrasamples = (uint16_t)*v; - _TIFFsetShortArrayExt(tif, &td->td_sampleinfo, va, td->td_extrasamples); - return 1; - -#undef EXTRASAMPLE_COREL_UNASSALPHA -} - -/* - * Count ink names separated by \0. Returns - * zero if the ink names are not as expected. - */ -static uint16_t countInkNamesString(TIFF *tif, uint32_t slen, const char *s) -{ - uint16_t i = 0; - - if (slen > 0) - { - const char *ep = s + slen; - const char *cp = s; - do - { - for (; cp < ep && *cp != '\0'; cp++) - { - } - if (cp >= ep) - goto bad; - cp++; /* skip \0 */ - i++; - } while (cp < ep); - return (i); - } -bad: - TIFFErrorExtR(tif, "TIFFSetField", - "%s: Invalid InkNames value; no NUL at given buffer end " - "location %" PRIu32 ", after %" PRIu16 " ink", - tif->tif_name, slen, i); - return (0); -} - -static int _TIFFVSetField(TIFF *tif, uint32_t tag, va_list ap) -{ - static const char module[] = "_TIFFVSetField"; - - TIFFDirectory *td = &tif->tif_dir; - int status = 1; - uint32_t v32, v; - double dblval; - char *s; - const TIFFField *fip = TIFFFindField(tif, tag, TIFF_ANY); - uint32_t standard_tag = tag; - if (fip == NULL) /* cannot happen since OkToChangeTag() already checks it */ - return 0; - /* - * We want to force the custom code to be used for custom - * fields even if the tag happens to match a well known - * one - important for reinterpreted handling of standard - * tag values in custom directories (i.e. EXIF) - */ - if (fip->field_bit == FIELD_CUSTOM) - { - standard_tag = 0; - } - - switch (standard_tag) - { - case TIFFTAG_SUBFILETYPE: - td->td_subfiletype = (uint32_t)va_arg(ap, uint32_t); - break; - case TIFFTAG_IMAGEWIDTH: - td->td_imagewidth = (uint32_t)va_arg(ap, uint32_t); - break; - case TIFFTAG_IMAGELENGTH: - td->td_imagelength = (uint32_t)va_arg(ap, uint32_t); - break; - case TIFFTAG_BITSPERSAMPLE: - td->td_bitspersample = (uint16_t)va_arg(ap, uint16_vap); - /* - * If the data require post-decoding processing to byte-swap - * samples, set it up here. Note that since tags are required - * to be ordered, compression code can override this behavior - * in the setup method if it wants to roll the post decoding - * work in with its normal work. - */ - if (tif->tif_flags & TIFF_SWAB) - { - if (td->td_bitspersample == 8) - tif->tif_postdecode = _TIFFNoPostDecode; - else if (td->td_bitspersample == 16) - tif->tif_postdecode = _TIFFSwab16BitData; - else if (td->td_bitspersample == 24) - tif->tif_postdecode = _TIFFSwab24BitData; - else if (td->td_bitspersample == 32) - tif->tif_postdecode = _TIFFSwab32BitData; - else if (td->td_bitspersample == 64) - tif->tif_postdecode = _TIFFSwab64BitData; - else if (td->td_bitspersample == 128) /* two 64's */ - tif->tif_postdecode = _TIFFSwab64BitData; - } - break; - case TIFFTAG_COMPRESSION: - v = (uint16_t)va_arg(ap, uint16_vap); - /* - * If we're changing the compression scheme, notify the - * previous module so that it can cleanup any state it's - * setup. - */ - if (TIFFFieldSet(tif, FIELD_COMPRESSION)) - { - if ((uint32_t)td->td_compression == v) - break; - (*tif->tif_cleanup)(tif); - tif->tif_flags &= ~TIFF_CODERSETUP; - } - /* - * Setup new compression routine state. - */ - if ((status = TIFFSetCompressionScheme(tif, v)) != 0) - td->td_compression = (uint16_t)v; - else - status = 0; - break; - case TIFFTAG_PHOTOMETRIC: - td->td_photometric = (uint16_t)va_arg(ap, uint16_vap); - break; - case TIFFTAG_THRESHHOLDING: - td->td_threshholding = (uint16_t)va_arg(ap, uint16_vap); - break; - case TIFFTAG_FILLORDER: - v = (uint16_t)va_arg(ap, uint16_vap); - if (v != FILLORDER_LSB2MSB && v != FILLORDER_MSB2LSB) - goto badvalue; - td->td_fillorder = (uint16_t)v; - break; - case TIFFTAG_ORIENTATION: - v = (uint16_t)va_arg(ap, uint16_vap); - if (v < ORIENTATION_TOPLEFT || ORIENTATION_LEFTBOT < v) - goto badvalue; - else - td->td_orientation = (uint16_t)v; - break; - case TIFFTAG_SAMPLESPERPIXEL: - v = (uint16_t)va_arg(ap, uint16_vap); - if (v == 0) - goto badvalue; - if (v != td->td_samplesperpixel) - { - /* See http://bugzilla.maptools.org/show_bug.cgi?id=2500 */ - if (td->td_sminsamplevalue != NULL) - { - TIFFWarningExtR(tif, module, - "SamplesPerPixel tag value is changing, " - "but SMinSampleValue tag was read with a " - "different value. Canceling it"); - TIFFClrFieldBit(tif, FIELD_SMINSAMPLEVALUE); - _TIFFfreeExt(tif, td->td_sminsamplevalue); - td->td_sminsamplevalue = NULL; - } - if (td->td_smaxsamplevalue != NULL) - { - TIFFWarningExtR(tif, module, - "SamplesPerPixel tag value is changing, " - "but SMaxSampleValue tag was read with a " - "different value. Canceling it"); - TIFFClrFieldBit(tif, FIELD_SMAXSAMPLEVALUE); - _TIFFfreeExt(tif, td->td_smaxsamplevalue); - td->td_smaxsamplevalue = NULL; - } - /* Test if 3 transfer functions instead of just one are now - needed See http://bugzilla.maptools.org/show_bug.cgi?id=2820 - */ - if (td->td_transferfunction[0] != NULL && - (v - td->td_extrasamples > 1) && - !(td->td_samplesperpixel - td->td_extrasamples > 1)) - { - TIFFWarningExtR(tif, module, - "SamplesPerPixel tag value is changing, " - "but TransferFunction was read with a " - "different value. Canceling it"); - TIFFClrFieldBit(tif, FIELD_TRANSFERFUNCTION); - _TIFFfreeExt(tif, td->td_transferfunction[0]); - td->td_transferfunction[0] = NULL; - } - } - td->td_samplesperpixel = (uint16_t)v; - break; - case TIFFTAG_ROWSPERSTRIP: - v32 = (uint32_t)va_arg(ap, uint32_t); - if (v32 == 0) - goto badvalue32; - td->td_rowsperstrip = v32; - if (!TIFFFieldSet(tif, FIELD_TILEDIMENSIONS)) - { - td->td_tilelength = v32; - td->td_tilewidth = td->td_imagewidth; - } - break; - case TIFFTAG_MINSAMPLEVALUE: - td->td_minsamplevalue = (uint16_t)va_arg(ap, uint16_vap); - break; - case TIFFTAG_MAXSAMPLEVALUE: - td->td_maxsamplevalue = (uint16_t)va_arg(ap, uint16_vap); - break; - case TIFFTAG_SMINSAMPLEVALUE: - if (tif->tif_flags & TIFF_PERSAMPLE) - _TIFFsetDoubleArrayExt(tif, &td->td_sminsamplevalue, - va_arg(ap, double *), - td->td_samplesperpixel); - else - setDoubleArrayOneValue(tif, &td->td_sminsamplevalue, - va_arg(ap, double), - td->td_samplesperpixel); - break; - case TIFFTAG_SMAXSAMPLEVALUE: - if (tif->tif_flags & TIFF_PERSAMPLE) - _TIFFsetDoubleArrayExt(tif, &td->td_smaxsamplevalue, - va_arg(ap, double *), - td->td_samplesperpixel); - else - setDoubleArrayOneValue(tif, &td->td_smaxsamplevalue, - va_arg(ap, double), - td->td_samplesperpixel); - break; - case TIFFTAG_XRESOLUTION: - dblval = va_arg(ap, double); - if (dblval != dblval || dblval < 0) - goto badvaluedouble; - td->td_xresolution = _TIFFClampDoubleToFloat(dblval); - break; - case TIFFTAG_YRESOLUTION: - dblval = va_arg(ap, double); - if (dblval != dblval || dblval < 0) - goto badvaluedouble; - td->td_yresolution = _TIFFClampDoubleToFloat(dblval); - break; - case TIFFTAG_PLANARCONFIG: - v = (uint16_t)va_arg(ap, uint16_vap); - if (v != PLANARCONFIG_CONTIG && v != PLANARCONFIG_SEPARATE) - goto badvalue; - td->td_planarconfig = (uint16_t)v; - break; - case TIFFTAG_XPOSITION: - td->td_xposition = _TIFFClampDoubleToFloat(va_arg(ap, double)); - break; - case TIFFTAG_YPOSITION: - td->td_yposition = _TIFFClampDoubleToFloat(va_arg(ap, double)); - break; - case TIFFTAG_RESOLUTIONUNIT: - v = (uint16_t)va_arg(ap, uint16_vap); - if (v < RESUNIT_NONE || RESUNIT_CENTIMETER < v) - goto badvalue; - td->td_resolutionunit = (uint16_t)v; - break; - case TIFFTAG_PAGENUMBER: - td->td_pagenumber[0] = (uint16_t)va_arg(ap, uint16_vap); - td->td_pagenumber[1] = (uint16_t)va_arg(ap, uint16_vap); - break; - case TIFFTAG_HALFTONEHINTS: - td->td_halftonehints[0] = (uint16_t)va_arg(ap, uint16_vap); - td->td_halftonehints[1] = (uint16_t)va_arg(ap, uint16_vap); - break; - case TIFFTAG_COLORMAP: - v32 = (uint32_t)(1L << td->td_bitspersample); - _TIFFsetShortArrayExt(tif, &td->td_colormap[0], - va_arg(ap, uint16_t *), v32); - _TIFFsetShortArrayExt(tif, &td->td_colormap[1], - va_arg(ap, uint16_t *), v32); - _TIFFsetShortArrayExt(tif, &td->td_colormap[2], - va_arg(ap, uint16_t *), v32); - break; - case TIFFTAG_EXTRASAMPLES: - if (!setExtraSamples(tif, ap, &v)) - goto badvalue; - break; - case TIFFTAG_MATTEING: - td->td_extrasamples = (((uint16_t)va_arg(ap, uint16_vap)) != 0); - if (td->td_extrasamples) - { - uint16_t sv = EXTRASAMPLE_ASSOCALPHA; - _TIFFsetShortArrayExt(tif, &td->td_sampleinfo, &sv, 1); - } - break; - case TIFFTAG_TILEWIDTH: - v32 = (uint32_t)va_arg(ap, uint32_t); - if (v32 % 16) - { - if (tif->tif_mode != O_RDONLY) - goto badvalue32; - TIFFWarningExtR( - tif, tif->tif_name, - "Nonstandard tile width %" PRIu32 ", convert file", v32); - } - td->td_tilewidth = v32; - tif->tif_flags |= TIFF_ISTILED; - break; - case TIFFTAG_TILELENGTH: - v32 = (uint32_t)va_arg(ap, uint32_t); - if (v32 % 16) - { - if (tif->tif_mode != O_RDONLY) - goto badvalue32; - TIFFWarningExtR( - tif, tif->tif_name, - "Nonstandard tile length %" PRIu32 ", convert file", v32); - } - td->td_tilelength = v32; - tif->tif_flags |= TIFF_ISTILED; - break; - case TIFFTAG_TILEDEPTH: - v32 = (uint32_t)va_arg(ap, uint32_t); - if (v32 == 0) - goto badvalue32; - td->td_tiledepth = v32; - break; - case TIFFTAG_DATATYPE: - v = (uint16_t)va_arg(ap, uint16_vap); - switch (v) - { - case DATATYPE_VOID: - v = SAMPLEFORMAT_VOID; - break; - case DATATYPE_INT: - v = SAMPLEFORMAT_INT; - break; - case DATATYPE_UINT: - v = SAMPLEFORMAT_UINT; - break; - case DATATYPE_IEEEFP: - v = SAMPLEFORMAT_IEEEFP; - break; - default: - goto badvalue; - } - td->td_sampleformat = (uint16_t)v; - break; - case TIFFTAG_SAMPLEFORMAT: - v = (uint16_t)va_arg(ap, uint16_vap); - if (v < SAMPLEFORMAT_UINT || SAMPLEFORMAT_COMPLEXIEEEFP < v) - goto badvalue; - td->td_sampleformat = (uint16_t)v; - - /* Try to fix up the SWAB function for complex data. */ - if (td->td_sampleformat == SAMPLEFORMAT_COMPLEXINT && - td->td_bitspersample == 32 && - tif->tif_postdecode == _TIFFSwab32BitData) - tif->tif_postdecode = _TIFFSwab16BitData; - else if ((td->td_sampleformat == SAMPLEFORMAT_COMPLEXINT || - td->td_sampleformat == SAMPLEFORMAT_COMPLEXIEEEFP) && - td->td_bitspersample == 64 && - tif->tif_postdecode == _TIFFSwab64BitData) - tif->tif_postdecode = _TIFFSwab32BitData; - break; - case TIFFTAG_IMAGEDEPTH: - td->td_imagedepth = (uint32_t)va_arg(ap, uint32_t); - break; - case TIFFTAG_SUBIFD: - if ((tif->tif_flags & TIFF_INSUBIFD) == 0) - { - td->td_nsubifd = (uint16_t)va_arg(ap, uint16_vap); - _TIFFsetLong8Array(tif, &td->td_subifd, - (uint64_t *)va_arg(ap, uint64_t *), - (uint32_t)td->td_nsubifd); - } - else - { - TIFFErrorExtR(tif, module, "%s: Sorry, cannot nest SubIFDs", - tif->tif_name); - status = 0; - } - break; - case TIFFTAG_YCBCRPOSITIONING: - td->td_ycbcrpositioning = (uint16_t)va_arg(ap, uint16_vap); - break; - case TIFFTAG_YCBCRSUBSAMPLING: - td->td_ycbcrsubsampling[0] = (uint16_t)va_arg(ap, uint16_vap); - td->td_ycbcrsubsampling[1] = (uint16_t)va_arg(ap, uint16_vap); - break; - case TIFFTAG_TRANSFERFUNCTION: - { - uint32_t i; - 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); - break; - } - case TIFFTAG_REFERENCEBLACKWHITE: - /* XXX should check for null range */ - _TIFFsetFloatArrayExt(tif, &td->td_refblackwhite, - va_arg(ap, float *), 6); - break; - case TIFFTAG_INKNAMES: - { - uint16_t ninksinstring; - v = (uint16_t)va_arg(ap, uint16_vap); - s = va_arg(ap, char *); - ninksinstring = countInkNamesString(tif, v, s); - status = ninksinstring > 0; - if (ninksinstring > 0) - { - _TIFFsetNString(tif, &td->td_inknames, s, v); - td->td_inknameslen = v; - /* Set NumberOfInks to the value ninksinstring */ - if (TIFFFieldSet(tif, FIELD_NUMBEROFINKS)) - { - if (td->td_numberofinks != ninksinstring) - { - TIFFErrorExtR( - tif, module, - "Warning %s; Tag %s:\n Value %" PRIu16 - " of NumberOfInks is different from the number of " - "inks %" PRIu16 - ".\n -> NumberOfInks value adapted to %" PRIu16 "", - tif->tif_name, fip->field_name, td->td_numberofinks, - ninksinstring, ninksinstring); - td->td_numberofinks = ninksinstring; - } - } - else - { - td->td_numberofinks = ninksinstring; - TIFFSetFieldBit(tif, FIELD_NUMBEROFINKS); - } - if (TIFFFieldSet(tif, FIELD_SAMPLESPERPIXEL)) - { - if (td->td_numberofinks != td->td_samplesperpixel) - { - TIFFErrorExtR(tif, module, - "Warning %s; Tag %s:\n Value %" PRIu16 - " of NumberOfInks is different from the " - "SamplesPerPixel value %" PRIu16 "", - tif->tif_name, fip->field_name, - td->td_numberofinks, - td->td_samplesperpixel); - } - } - } - } - break; - case TIFFTAG_NUMBEROFINKS: - v = (uint16_t)va_arg(ap, uint16_vap); - /* If InkNames already set also NumberOfInks is set accordingly and - * should be equal */ - if (TIFFFieldSet(tif, FIELD_INKNAMES)) - { - if (v != td->td_numberofinks) - { - TIFFErrorExtR( - tif, module, - "Error %s; Tag %s:\n It is not possible to set the " - "value %" PRIu32 - " for NumberOfInks\n which is different from the " - "number of inks in the InkNames tag (%" PRIu16 ")", - tif->tif_name, fip->field_name, v, td->td_numberofinks); - /* Do not set / overwrite number of inks already set by - * InkNames case accordingly. */ - status = 0; - } - } - else - { - td->td_numberofinks = (uint16_t)v; - if (TIFFFieldSet(tif, FIELD_SAMPLESPERPIXEL)) - { - if (td->td_numberofinks != td->td_samplesperpixel) - { - TIFFErrorExtR(tif, module, - "Warning %s; Tag %s:\n Value %" PRIu32 - " of NumberOfInks is different from the " - "SamplesPerPixel value %" PRIu16 "", - tif->tif_name, fip->field_name, v, - td->td_samplesperpixel); - } - } - } - break; - case TIFFTAG_PERSAMPLE: - v = (uint16_t)va_arg(ap, uint16_vap); - if (v == PERSAMPLE_MULTI) - tif->tif_flags |= TIFF_PERSAMPLE; - else - tif->tif_flags &= ~TIFF_PERSAMPLE; - break; - default: - { - TIFFTagValue *tv; - int tv_size, iCustom; - - /* - * This can happen if multiple images are open with different - * codecs which have private tags. The global tag information - * table may then have tags that are valid for one file but not - * the other. If the client tries to set a tag that is not valid - * for the image's codec then we'll arrive here. This - * happens, for example, when tiffcp is used to convert between - * compression schemes and codec-specific tags are blindly copied. - * - * This also happens when a FIELD_IGNORE tag is written. - */ - if (fip->field_bit == FIELD_IGNORE) - { - TIFFErrorExtR( - tif, module, - "%s: Ignored %stag \"%s\" (not supported by libtiff)", - tif->tif_name, isPseudoTag(tag) ? "pseudo-" : "", - fip->field_name); - status = 0; - break; - } - if (fip->field_bit != FIELD_CUSTOM) - { - TIFFErrorExtR( - tif, module, - "%s: Invalid %stag \"%s\" (not supported by codec)", - tif->tif_name, isPseudoTag(tag) ? "pseudo-" : "", - fip->field_name); - status = 0; - break; - } - - /* - * Find the existing entry for this custom value. - */ - tv = NULL; - for (iCustom = 0; iCustom < td->td_customValueCount; iCustom++) - { - if (td->td_customValues[iCustom].info->field_tag == tag) - { - tv = td->td_customValues + iCustom; - if (tv->value != NULL) - { - _TIFFfreeExt(tif, tv->value); - tv->value = NULL; - } - break; - } - } - - /* - * Grow the custom list if the entry was not found. - */ - if (tv == NULL) - { - TIFFTagValue *new_customValues; - - td->td_customValueCount++; - new_customValues = (TIFFTagValue *)_TIFFreallocExt( - tif, td->td_customValues, - sizeof(TIFFTagValue) * td->td_customValueCount); - if (!new_customValues) - { - TIFFErrorExtR(tif, module, - "%s: Failed to allocate space for list of " - "custom values", - tif->tif_name); - status = 0; - goto end; - } - - td->td_customValues = new_customValues; - - tv = td->td_customValues + (td->td_customValueCount - 1); - tv->info = fip; - tv->value = NULL; - tv->count = 0; - } - - /* - * Set custom value ... save a copy of the custom tag value. - */ - /*--: Rational2Double: For Rationals evaluate "set_field_type" to - * determine internal storage size. */ - tv_size = TIFFFieldSetGetSize(fip); - if (tv_size == 0) - { - status = 0; - TIFFErrorExtR(tif, module, "%s: Bad field type %d for \"%s\"", - tif->tif_name, fip->field_type, fip->field_name); - goto end; - } - - if (fip->field_type == TIFF_ASCII) - { - uint32_t ma; - const char *mb; - if (fip->field_passcount) - { - assert(fip->field_writecount == TIFF_VARIABLE2); - ma = (uint32_t)va_arg(ap, uint32_t); - mb = (const char *)va_arg(ap, const char *); - } - else - { - size_t len; - mb = (const char *)va_arg(ap, const char *); - len = strlen(mb) + 1; - if (len >= 0x80000000U) - { - status = 0; - TIFFErrorExtR(tif, module, - "%s: Too long string value for \"%s\". " - "Maximum supported is 2147483647 bytes", - tif->tif_name, fip->field_name); - goto end; - } - ma = (uint32_t)len; - } - tv->count = ma; - setByteArray(tif, &tv->value, mb, ma, 1); - } - else - { - if (fip->field_passcount) - { - if (fip->field_writecount == TIFF_VARIABLE2) - tv->count = (uint32_t)va_arg(ap, uint32_t); - else - tv->count = (int)va_arg(ap, int); - } - else if (fip->field_writecount == TIFF_VARIABLE || - fip->field_writecount == TIFF_VARIABLE2) - tv->count = 1; - else if (fip->field_writecount == TIFF_SPP) - tv->count = td->td_samplesperpixel; - else - tv->count = fip->field_writecount; - - if (tv->count == 0) - { - status = 0; - TIFFErrorExtR(tif, module, - "%s: Null count for \"%s\" (type " - "%d, writecount %d, passcount %d)", - tif->tif_name, fip->field_name, - fip->field_type, fip->field_writecount, - fip->field_passcount); - goto end; - } - - tv->value = _TIFFCheckMalloc(tif, tv->count, tv_size, - "custom tag binary object"); - if (!tv->value) - { - status = 0; - goto end; - } - - if (fip->field_tag == TIFFTAG_DOTRANGE && - strcmp(fip->field_name, "DotRange") == 0) - { - /* TODO: This is an evil exception and should not have been - handled this way ... likely best if we move it into - the directory structure with an explicit field in - libtiff 4.1 and assign it a FIELD_ value */ - uint16_t v2[2]; - v2[0] = (uint16_t)va_arg(ap, int); - v2[1] = (uint16_t)va_arg(ap, int); - _TIFFmemcpy(tv->value, &v2, 4); - } - - else if (fip->field_passcount || - fip->field_writecount == TIFF_VARIABLE || - fip->field_writecount == TIFF_VARIABLE2 || - fip->field_writecount == TIFF_SPP || tv->count > 1) - { - /*--: Rational2Double: For Rationals tv_size is set above to - * 4 or 8 according to fip->set_field_type! */ - _TIFFmemcpy(tv->value, va_arg(ap, void *), - tv->count * tv_size); - /* Test here for too big values for LONG8, SLONG8 in - * ClassicTIFF and delete custom field from custom list */ - if (!(tif->tif_flags & TIFF_BIGTIFF)) - { - if (tv->info->field_type == TIFF_LONG8) - { - uint64_t *pui64 = (uint64_t *)tv->value; - int i; - for (i = 0; i < tv->count; i++) - { - if (pui64[i] > 0xffffffffu) - { - TIFFErrorExtR( - tif, module, - "%s: Bad LONG8 value %" PRIu64 - " at %d. array position for \"%s\" tag " - "%d in ClassicTIFF. Tag won't be " - "written to file", - tif->tif_name, pui64[i], i, - fip->field_name, tag); - goto badvalueifd8long8; - } - } - } - else if (tv->info->field_type == TIFF_SLONG8) - { - int64_t *pi64 = (int64_t *)tv->value; - int i; - for (i = 0; i < tv->count; i++) - { - if (pi64[i] > 2147483647 || - pi64[i] < (-2147483647 - 1)) - { - TIFFErrorExtR( - tif, module, - "%s: Bad SLONG8 value %" PRIi64 - " at %d. array position for \"%s\" tag " - "%d in ClassicTIFF. Tag won't be " - "written to file", - tif->tif_name, pi64[i], i, - fip->field_name, tag); - goto badvalueifd8long8; - } - } - } - } - } - else - { - char *val = (char *)tv->value; - assert(tv->count == 1); - - switch (fip->field_type) - { - case TIFF_BYTE: - case TIFF_UNDEFINED: - { - uint8_t v2 = (uint8_t)va_arg(ap, int); - _TIFFmemcpy(val, &v2, tv_size); - } - break; - case TIFF_SBYTE: - { - int8_t v2 = (int8_t)va_arg(ap, int); - _TIFFmemcpy(val, &v2, tv_size); - } - break; - case TIFF_SHORT: - { - uint16_t v2 = (uint16_t)va_arg(ap, int); - _TIFFmemcpy(val, &v2, tv_size); - } - break; - case TIFF_SSHORT: - { - int16_t v2 = (int16_t)va_arg(ap, int); - _TIFFmemcpy(val, &v2, tv_size); - } - break; - case TIFF_LONG: - case TIFF_IFD: - { - uint32_t v2 = va_arg(ap, uint32_t); - _TIFFmemcpy(val, &v2, tv_size); - } - break; - case TIFF_SLONG: - { - int32_t v2 = va_arg(ap, int32_t); - _TIFFmemcpy(val, &v2, tv_size); - } - break; - case TIFF_LONG8: - case TIFF_IFD8: - { - uint64_t v2 = va_arg(ap, uint64_t); - _TIFFmemcpy(val, &v2, tv_size); - /* Test here for too big values for ClassicTIFF and - * delete custom field from custom list */ - if (!(tif->tif_flags & TIFF_BIGTIFF) && - (v2 > 0xffffffffu)) - { - TIFFErrorExtR( - tif, module, - "%s: Bad LONG8 or IFD8 value %" PRIu64 - " for \"%s\" tag %d in ClassicTIFF. Tag " - "won't be written to file", - tif->tif_name, v2, fip->field_name, tag); - goto badvalueifd8long8; - } - } - break; - case TIFF_SLONG8: - { - int64_t v2 = va_arg(ap, int64_t); - _TIFFmemcpy(val, &v2, tv_size); - /* Test here for too big values for ClassicTIFF and - * delete custom field from custom list */ - if (!(tif->tif_flags & TIFF_BIGTIFF) && - ((v2 > 2147483647) || (v2 < (-2147483647 - 1)))) - { - TIFFErrorExtR( - tif, module, - "%s: Bad SLONG8 value %" PRIi64 - " for \"%s\" tag %d in ClassicTIFF. Tag " - "won't be written to file", - tif->tif_name, v2, fip->field_name, tag); - goto badvalueifd8long8; - } - } - break; - case TIFF_RATIONAL: - case TIFF_SRATIONAL: - /*-- Rational2Double: For Rationals tv_size is set - * above to 4 or 8 according to fip->set_field_type! - */ - { - if (tv_size == 8) - { - double v2 = va_arg(ap, double); - _TIFFmemcpy(val, &v2, tv_size); - } - else - { - /*-- default should be tv_size == 4 */ - float v3 = (float)va_arg(ap, double); - _TIFFmemcpy(val, &v3, tv_size); - /*-- ToDo: After Testing, this should be - * removed and tv_size==4 should be set as - * default. */ - if (tv_size != 4) - { - TIFFErrorExtR( - tif, module, - "Rational2Double: .set_field_type " - "in not 4 but %d", - tv_size); - } - } - } - break; - case TIFF_FLOAT: - { - float v2 = - _TIFFClampDoubleToFloat(va_arg(ap, double)); - _TIFFmemcpy(val, &v2, tv_size); - } - break; - case TIFF_DOUBLE: - { - double v2 = va_arg(ap, double); - _TIFFmemcpy(val, &v2, tv_size); - } - break; - default: - _TIFFmemset(val, 0, tv_size); - status = 0; - break; - } - } - } - } - } - if (status) - { - const TIFFField *fip2 = TIFFFieldWithTag(tif, tag); - if (fip2) - TIFFSetFieldBit(tif, fip2->field_bit); - tif->tif_flags |= TIFF_DIRTYDIRECT; - } - -end: - va_end(ap); - return (status); -badvalue: -{ - const TIFFField *fip2 = TIFFFieldWithTag(tif, tag); - TIFFErrorExtR(tif, module, "%s: Bad value %" PRIu32 " for \"%s\" tag", - tif->tif_name, v, fip2 ? fip2->field_name : "Unknown"); - va_end(ap); -} - return (0); -badvalue32: -{ - const TIFFField *fip2 = TIFFFieldWithTag(tif, tag); - TIFFErrorExtR(tif, module, "%s: Bad value %" PRIu32 " for \"%s\" tag", - tif->tif_name, v32, fip2 ? fip2->field_name : "Unknown"); - va_end(ap); -} - return (0); -badvaluedouble: -{ - const TIFFField *fip2 = TIFFFieldWithTag(tif, tag); - TIFFErrorExtR(tif, module, "%s: Bad value %f for \"%s\" tag", tif->tif_name, - dblval, fip2 ? fip2->field_name : "Unknown"); - va_end(ap); -} - return (0); -badvalueifd8long8: -{ - /* Error message issued already above. */ - TIFFTagValue *tv2 = NULL; - int iCustom2, iC2; - /* Find the existing entry for this custom value. */ - for (iCustom2 = 0; iCustom2 < td->td_customValueCount; iCustom2++) - { - if (td->td_customValues[iCustom2].info->field_tag == tag) - { - tv2 = td->td_customValues + (iCustom2); - break; - } - } - if (tv2 != NULL) - { - /* Remove custom field from custom list */ - if (tv2->value != NULL) - { - _TIFFfreeExt(tif, tv2->value); - tv2->value = NULL; - } - /* Shorten list and close gap in customValues list. - * Re-allocation of td_customValues not necessary here. */ - td->td_customValueCount--; - for (iC2 = iCustom2; iC2 < td->td_customValueCount; iC2++) - { - td->td_customValues[iC2] = td->td_customValues[iC2 + 1]; - } - } - else - { - assert(0); - } - va_end(ap); -} - return (0); -} /*-- _TIFFVSetField() --*/ - -/* - * Return 1/0 according to whether or not - * it is permissible to set the tag's value. - * Note that we allow ImageLength to be changed - * so that we can append and extend to images. - * Any other tag may not be altered once writing - * has commenced, unless its value has no effect - * on the format of the data that is written. - */ -static int OkToChangeTag(TIFF *tif, uint32_t tag) -{ - const TIFFField *fip = TIFFFindField(tif, tag, TIFF_ANY); - if (!fip) - { /* unknown tag */ - TIFFErrorExtR(tif, "TIFFSetField", "%s: Unknown %stag %" PRIu32, - tif->tif_name, isPseudoTag(tag) ? "pseudo-" : "", tag); - return (0); - } - if (tag != TIFFTAG_IMAGELENGTH && (tif->tif_flags & TIFF_BEENWRITING) && - !fip->field_oktochange) - { - /* - * Consult info table to see if tag can be changed - * after we've started writing. We only allow changes - * to those tags that don't/shouldn't affect the - * compression and/or format of the data. - */ - TIFFErrorExtR(tif, "TIFFSetField", - "%s: Cannot modify tag \"%s\" while writing", - tif->tif_name, fip->field_name); - return (0); - } - return (1); -} - -/* - * Record the value of a field in the - * internal directory structure. The - * field will be written to the file - * when/if the directory structure is - * updated. - */ -int TIFFSetField(TIFF *tif, uint32_t tag, ...) -{ - va_list ap; - int status; - - va_start(ap, tag); - status = TIFFVSetField(tif, tag, ap); - va_end(ap); - return (status); -} - -/* - * Clear the contents of the field in the internal structure. - */ -int TIFFUnsetField(TIFF *tif, uint32_t tag) -{ - const TIFFField *fip = TIFFFieldWithTag(tif, tag); - TIFFDirectory *td = &tif->tif_dir; - - if (!fip) - return 0; - - if (fip->field_bit != FIELD_CUSTOM) - TIFFClrFieldBit(tif, fip->field_bit); - else - { - TIFFTagValue *tv = NULL; - int i; - - for (i = 0; i < td->td_customValueCount; i++) - { - - tv = td->td_customValues + i; - if (tv->info->field_tag == tag) - break; - } - - if (i < td->td_customValueCount) - { - _TIFFfreeExt(tif, tv->value); - for (; i < td->td_customValueCount - 1; i++) - { - td->td_customValues[i] = td->td_customValues[i + 1]; - } - td->td_customValueCount--; - } - } - - tif->tif_flags |= TIFF_DIRTYDIRECT; - - return (1); -} - -/* - * Like TIFFSetField, but taking a varargs - * parameter list. This routine is useful - * for building higher-level interfaces on - * top of the library. - */ -int TIFFVSetField(TIFF *tif, uint32_t tag, va_list ap) -{ - return OkToChangeTag(tif, tag) - ? (*tif->tif_tagmethods.vsetfield)(tif, tag, ap) - : 0; -} - -static int _TIFFVGetField(TIFF *tif, uint32_t tag, va_list ap) -{ - TIFFDirectory *td = &tif->tif_dir; - int ret_val = 1; - uint32_t standard_tag = tag; - const TIFFField *fip = TIFFFindField(tif, tag, TIFF_ANY); - if (fip == NULL) /* cannot happen since TIFFGetField() already checks it */ - return 0; - - /* - * We want to force the custom code to be used for custom - * fields even if the tag happens to match a well known - * one - important for reinterpreted handling of standard - * tag values in custom directories (i.e. EXIF) - */ - if (fip->field_bit == FIELD_CUSTOM) - { - standard_tag = 0; - } - - switch (standard_tag) - { - case TIFFTAG_SUBFILETYPE: - *va_arg(ap, uint32_t *) = td->td_subfiletype; - break; - case TIFFTAG_IMAGEWIDTH: - *va_arg(ap, uint32_t *) = td->td_imagewidth; - break; - case TIFFTAG_IMAGELENGTH: - *va_arg(ap, uint32_t *) = td->td_imagelength; - break; - case TIFFTAG_BITSPERSAMPLE: - *va_arg(ap, uint16_t *) = td->td_bitspersample; - break; - case TIFFTAG_COMPRESSION: - *va_arg(ap, uint16_t *) = td->td_compression; - break; - case TIFFTAG_PHOTOMETRIC: - *va_arg(ap, uint16_t *) = td->td_photometric; - break; - case TIFFTAG_THRESHHOLDING: - *va_arg(ap, uint16_t *) = td->td_threshholding; - break; - case TIFFTAG_FILLORDER: - *va_arg(ap, uint16_t *) = td->td_fillorder; - break; - case TIFFTAG_ORIENTATION: - *va_arg(ap, uint16_t *) = td->td_orientation; - break; - case TIFFTAG_SAMPLESPERPIXEL: - *va_arg(ap, uint16_t *) = td->td_samplesperpixel; - break; - case TIFFTAG_ROWSPERSTRIP: - *va_arg(ap, uint32_t *) = td->td_rowsperstrip; - break; - case TIFFTAG_MINSAMPLEVALUE: - *va_arg(ap, uint16_t *) = td->td_minsamplevalue; - break; - case TIFFTAG_MAXSAMPLEVALUE: - *va_arg(ap, uint16_t *) = td->td_maxsamplevalue; - break; - case TIFFTAG_SMINSAMPLEVALUE: - if (tif->tif_flags & TIFF_PERSAMPLE) - *va_arg(ap, double **) = td->td_sminsamplevalue; - else - { - /* libtiff historically treats this as a single value. */ - uint16_t i; - double v = td->td_sminsamplevalue[0]; - for (i = 1; i < td->td_samplesperpixel; ++i) - if (td->td_sminsamplevalue[i] < v) - v = td->td_sminsamplevalue[i]; - *va_arg(ap, double *) = v; - } - break; - case TIFFTAG_SMAXSAMPLEVALUE: - if (tif->tif_flags & TIFF_PERSAMPLE) - *va_arg(ap, double **) = td->td_smaxsamplevalue; - else - { - /* libtiff historically treats this as a single value. */ - uint16_t i; - double v = td->td_smaxsamplevalue[0]; - for (i = 1; i < td->td_samplesperpixel; ++i) - if (td->td_smaxsamplevalue[i] > v) - v = td->td_smaxsamplevalue[i]; - *va_arg(ap, double *) = v; - } - break; - case TIFFTAG_XRESOLUTION: - *va_arg(ap, float *) = td->td_xresolution; - break; - case TIFFTAG_YRESOLUTION: - *va_arg(ap, float *) = td->td_yresolution; - break; - case TIFFTAG_PLANARCONFIG: - *va_arg(ap, uint16_t *) = td->td_planarconfig; - break; - case TIFFTAG_XPOSITION: - *va_arg(ap, float *) = td->td_xposition; - break; - case TIFFTAG_YPOSITION: - *va_arg(ap, float *) = td->td_yposition; - break; - case TIFFTAG_RESOLUTIONUNIT: - *va_arg(ap, uint16_t *) = td->td_resolutionunit; - break; - case TIFFTAG_PAGENUMBER: - *va_arg(ap, uint16_t *) = td->td_pagenumber[0]; - *va_arg(ap, uint16_t *) = td->td_pagenumber[1]; - break; - case TIFFTAG_HALFTONEHINTS: - *va_arg(ap, uint16_t *) = td->td_halftonehints[0]; - *va_arg(ap, uint16_t *) = td->td_halftonehints[1]; - break; - case TIFFTAG_COLORMAP: - *va_arg(ap, const uint16_t **) = td->td_colormap[0]; - *va_arg(ap, const uint16_t **) = td->td_colormap[1]; - *va_arg(ap, const uint16_t **) = td->td_colormap[2]; - break; - case TIFFTAG_STRIPOFFSETS: - case TIFFTAG_TILEOFFSETS: - _TIFFFillStriles(tif); - *va_arg(ap, const uint64_t **) = td->td_stripoffset_p; - if (td->td_stripoffset_p == NULL) - ret_val = 0; - break; - case TIFFTAG_STRIPBYTECOUNTS: - case TIFFTAG_TILEBYTECOUNTS: - _TIFFFillStriles(tif); - *va_arg(ap, const uint64_t **) = td->td_stripbytecount_p; - if (td->td_stripbytecount_p == NULL) - ret_val = 0; - break; - case TIFFTAG_MATTEING: - *va_arg(ap, uint16_t *) = - (td->td_extrasamples == 1 && - td->td_sampleinfo[0] == EXTRASAMPLE_ASSOCALPHA); - break; - case TIFFTAG_EXTRASAMPLES: - *va_arg(ap, uint16_t *) = td->td_extrasamples; - *va_arg(ap, const uint16_t **) = td->td_sampleinfo; - break; - case TIFFTAG_TILEWIDTH: - *va_arg(ap, uint32_t *) = td->td_tilewidth; - break; - case TIFFTAG_TILELENGTH: - *va_arg(ap, uint32_t *) = td->td_tilelength; - break; - case TIFFTAG_TILEDEPTH: - *va_arg(ap, uint32_t *) = td->td_tiledepth; - break; - case TIFFTAG_DATATYPE: - switch (td->td_sampleformat) - { - case SAMPLEFORMAT_UINT: - *va_arg(ap, uint16_t *) = DATATYPE_UINT; - break; - case SAMPLEFORMAT_INT: - *va_arg(ap, uint16_t *) = DATATYPE_INT; - break; - case SAMPLEFORMAT_IEEEFP: - *va_arg(ap, uint16_t *) = DATATYPE_IEEEFP; - break; - case SAMPLEFORMAT_VOID: - *va_arg(ap, uint16_t *) = DATATYPE_VOID; - break; - } - break; - case TIFFTAG_SAMPLEFORMAT: - *va_arg(ap, uint16_t *) = td->td_sampleformat; - break; - case TIFFTAG_IMAGEDEPTH: - *va_arg(ap, uint32_t *) = td->td_imagedepth; - break; - case TIFFTAG_SUBIFD: - *va_arg(ap, uint16_t *) = td->td_nsubifd; - *va_arg(ap, const uint64_t **) = td->td_subifd; - break; - case TIFFTAG_YCBCRPOSITIONING: - *va_arg(ap, uint16_t *) = td->td_ycbcrpositioning; - break; - case TIFFTAG_YCBCRSUBSAMPLING: - *va_arg(ap, uint16_t *) = td->td_ycbcrsubsampling[0]; - *va_arg(ap, uint16_t *) = td->td_ycbcrsubsampling[1]; - break; - case TIFFTAG_TRANSFERFUNCTION: - *va_arg(ap, const uint16_t **) = td->td_transferfunction[0]; - if (td->td_samplesperpixel - td->td_extrasamples > 1) - { - *va_arg(ap, const uint16_t **) = td->td_transferfunction[1]; - *va_arg(ap, const uint16_t **) = td->td_transferfunction[2]; - } - else - { - *va_arg(ap, const uint16_t **) = NULL; - *va_arg(ap, const uint16_t **) = NULL; - } - break; - case TIFFTAG_REFERENCEBLACKWHITE: - *va_arg(ap, const float **) = td->td_refblackwhite; - break; - case TIFFTAG_INKNAMES: - *va_arg(ap, const char **) = td->td_inknames; - break; - case TIFFTAG_NUMBEROFINKS: - *va_arg(ap, uint16_t *) = td->td_numberofinks; - break; - default: - { - int i; - - /* - * This can happen if multiple images are open - * with different codecs which have private - * tags. The global tag information table may - * then have tags that are valid for one file - * but not the other. If the client tries to - * get a tag that is not valid for the image's - * codec then we'll arrive here. - */ - if (fip->field_bit != FIELD_CUSTOM) - { - TIFFErrorExtR(tif, "_TIFFVGetField", - "%s: Invalid %stag \"%s\" " - "(not supported by codec)", - tif->tif_name, isPseudoTag(tag) ? "pseudo-" : "", - fip->field_name); - ret_val = 0; - break; - } - - /* - * Do we have a custom value? - */ - ret_val = 0; - for (i = 0; i < td->td_customValueCount; i++) - { - TIFFTagValue *tv = td->td_customValues + i; - - if (tv->info->field_tag != tag) - continue; - - if (fip->field_passcount) - { - if (fip->field_readcount == TIFF_VARIABLE2) - *va_arg(ap, uint32_t *) = (uint32_t)tv->count; - else /* Assume TIFF_VARIABLE */ - *va_arg(ap, uint16_t *) = (uint16_t)tv->count; - *va_arg(ap, const void **) = tv->value; - ret_val = 1; - } - else if (fip->field_tag == TIFFTAG_DOTRANGE && - strcmp(fip->field_name, "DotRange") == 0) - { - /* TODO: This is an evil exception and should not have been - handled this way ... likely best if we move it into - the directory structure with an explicit field in - libtiff 4.1 and assign it a FIELD_ value */ - *va_arg(ap, uint16_t *) = ((uint16_t *)tv->value)[0]; - *va_arg(ap, uint16_t *) = ((uint16_t *)tv->value)[1]; - ret_val = 1; - } - else - { - if (fip->field_type == TIFF_ASCII || - fip->field_readcount == TIFF_VARIABLE || - fip->field_readcount == TIFF_VARIABLE2 || - fip->field_readcount == TIFF_SPP || tv->count > 1) - { - *va_arg(ap, void **) = tv->value; - ret_val = 1; - } - else - { - char *val = (char *)tv->value; - assert(tv->count == 1); - switch (fip->field_type) - { - case TIFF_BYTE: - case TIFF_UNDEFINED: - *va_arg(ap, uint8_t *) = *(uint8_t *)val; - ret_val = 1; - break; - case TIFF_SBYTE: - *va_arg(ap, int8_t *) = *(int8_t *)val; - ret_val = 1; - break; - case TIFF_SHORT: - *va_arg(ap, uint16_t *) = *(uint16_t *)val; - ret_val = 1; - break; - case TIFF_SSHORT: - *va_arg(ap, int16_t *) = *(int16_t *)val; - ret_val = 1; - break; - case TIFF_LONG: - case TIFF_IFD: - *va_arg(ap, uint32_t *) = *(uint32_t *)val; - ret_val = 1; - break; - case TIFF_SLONG: - *va_arg(ap, int32_t *) = *(int32_t *)val; - ret_val = 1; - break; - case TIFF_LONG8: - case TIFF_IFD8: - *va_arg(ap, uint64_t *) = *(uint64_t *)val; - ret_val = 1; - break; - case TIFF_SLONG8: - *va_arg(ap, int64_t *) = *(int64_t *)val; - ret_val = 1; - break; - case TIFF_RATIONAL: - case TIFF_SRATIONAL: - { - /*-- Rational2Double: For Rationals evaluate - * "set_field_type" to determine internal - * storage size and return value size. */ - int tv_size = TIFFFieldSetGetSize(fip); - if (tv_size == 8) - { - *va_arg(ap, double *) = *(double *)val; - ret_val = 1; - } - else - { - /*-- default should be tv_size == 4 */ - *va_arg(ap, float *) = *(float *)val; - ret_val = 1; - /*-- ToDo: After Testing, this should be - * removed and tv_size==4 should be set as - * default. */ - if (tv_size != 4) - { - TIFFErrorExtR( - tif, "_TIFFVGetField", - "Rational2Double: .set_field_type " - "in not 4 but %d", - tv_size); - } - } - } - break; - case TIFF_FLOAT: - *va_arg(ap, float *) = *(float *)val; - ret_val = 1; - break; - case TIFF_DOUBLE: - *va_arg(ap, double *) = *(double *)val; - ret_val = 1; - break; - default: - ret_val = 0; - break; - } - } - } - break; - } - } - } - return (ret_val); -} - -/* - * Return the value of a field in the - * internal directory structure. - */ -int TIFFGetField(TIFF *tif, uint32_t tag, ...) -{ - int status; - va_list ap; - - va_start(ap, tag); - status = TIFFVGetField(tif, tag, ap); - va_end(ap); - return (status); -} - -/* - * Like TIFFGetField, but taking a varargs - * parameter list. This routine is useful - * for building higher-level interfaces on - * top of the library. - */ -int TIFFVGetField(TIFF *tif, uint32_t tag, va_list ap) -{ - const TIFFField *fip = TIFFFindField(tif, tag, TIFF_ANY); - return (fip && (isPseudoTag(tag) || TIFFFieldSet(tif, fip->field_bit)) - ? (*tif->tif_tagmethods.vgetfield)(tif, tag, ap) - : 0); -} - -#define CleanupField(member) \ - { \ - if (td->member) \ - { \ - _TIFFfreeExt(tif, td->member); \ - td->member = 0; \ - } \ - } - -/* - * Release storage associated with a directory. - */ -void TIFFFreeDirectory(TIFF *tif) -{ - TIFFDirectory *td = &tif->tif_dir; - int i; - - _TIFFmemset(td->td_fieldsset, 0, sizeof(td->td_fieldsset)); - CleanupField(td_sminsamplevalue); - CleanupField(td_smaxsamplevalue); - CleanupField(td_colormap[0]); - CleanupField(td_colormap[1]); - CleanupField(td_colormap[2]); - CleanupField(td_sampleinfo); - CleanupField(td_subifd); - CleanupField(td_inknames); - CleanupField(td_refblackwhite); - CleanupField(td_transferfunction[0]); - CleanupField(td_transferfunction[1]); - CleanupField(td_transferfunction[2]); - CleanupField(td_stripoffset_p); - CleanupField(td_stripbytecount_p); - td->td_stripoffsetbyteallocsize = 0; - TIFFClrFieldBit(tif, FIELD_YCBCRSUBSAMPLING); - TIFFClrFieldBit(tif, FIELD_YCBCRPOSITIONING); - - /* Cleanup custom tag values */ - for (i = 0; i < td->td_customValueCount; i++) - { - if (td->td_customValues[i].value) - _TIFFfreeExt(tif, td->td_customValues[i].value); - } - - td->td_customValueCount = 0; - CleanupField(td_customValues); - - _TIFFmemset(&(td->td_stripoffset_entry), 0, sizeof(TIFFDirEntry)); - _TIFFmemset(&(td->td_stripbytecount_entry), 0, sizeof(TIFFDirEntry)); -} -#undef CleanupField - -/* - * Client Tag extension support (from Niles Ritter). - */ -static TIFFExtendProc _TIFFextender = (TIFFExtendProc)NULL; - -TIFFExtendProc TIFFSetTagExtender(TIFFExtendProc extender) -{ - TIFFExtendProc prev = _TIFFextender; - _TIFFextender = extender; - return (prev); -} - -/* - * Setup for a new directory. Should we automatically call - * TIFFWriteDirectory() if the current one is dirty? - * - * The newly created directory will not exist on the file till - * TIFFWriteDirectory(), TIFFFlush() or TIFFClose() is called. - */ -int TIFFCreateDirectory(TIFF *tif) -{ - TIFFDefaultDirectory(tif); - tif->tif_diroff = 0; - tif->tif_nextdiroff = 0; - tif->tif_curoff = 0; - tif->tif_row = (uint32_t)-1; - tif->tif_curstrip = (uint32_t)-1; - - return 0; -} - -int TIFFCreateCustomDirectory(TIFF *tif, const TIFFFieldArray *infoarray) -{ - TIFFDefaultDirectory(tif); - - /* - * Reset the field definitions to match the application provided list. - * Hopefully TIFFDefaultDirectory() won't have done anything irreversible - * based on it's assumption this is an image directory. - */ - _TIFFSetupFields(tif, infoarray); - - tif->tif_diroff = 0; - tif->tif_nextdiroff = 0; - tif->tif_curoff = 0; - tif->tif_row = (uint32_t)-1; - tif->tif_curstrip = (uint32_t)-1; - /* invalidate directory index */ - tif->tif_curdir = TIFF_NON_EXISTENT_DIR_NUMBER; - /* invalidate IFD loop lists */ - _TIFFCleanupIFDOffsetAndNumberMaps(tif); - /* To be able to return from SubIFD or custom-IFD to main-IFD */ - tif->tif_setdirectory_force_absolute = TRUE; - - return 0; -} - -int TIFFCreateEXIFDirectory(TIFF *tif) -{ - const TIFFFieldArray *exifFieldArray; - exifFieldArray = _TIFFGetExifFields(); - return TIFFCreateCustomDirectory(tif, exifFieldArray); -} - -/* - * Creates the EXIF GPS custom directory - */ -int TIFFCreateGPSDirectory(TIFF *tif) -{ - const TIFFFieldArray *gpsFieldArray; - gpsFieldArray = _TIFFGetGpsFields(); - return TIFFCreateCustomDirectory(tif, gpsFieldArray); -} - -/* - * Setup a default directory structure. - */ -int TIFFDefaultDirectory(TIFF *tif) -{ - register TIFFDirectory *td = &tif->tif_dir; - const TIFFFieldArray *tiffFieldArray; - - tiffFieldArray = _TIFFGetFields(); - _TIFFSetupFields(tif, tiffFieldArray); - - _TIFFmemset(td, 0, sizeof(*td)); - td->td_fillorder = FILLORDER_MSB2LSB; - td->td_bitspersample = 1; - td->td_threshholding = THRESHHOLD_BILEVEL; - td->td_orientation = ORIENTATION_TOPLEFT; - td->td_samplesperpixel = 1; - td->td_rowsperstrip = (uint32_t)-1; - td->td_tilewidth = 0; - td->td_tilelength = 0; - td->td_tiledepth = 1; -#ifdef STRIPBYTECOUNTSORTED_UNUSED - td->td_stripbytecountsorted = 1; /* Our own arrays always sorted. */ -#endif - td->td_resolutionunit = RESUNIT_INCH; - td->td_sampleformat = SAMPLEFORMAT_UINT; - td->td_imagedepth = 1; - td->td_ycbcrsubsampling[0] = 2; - td->td_ycbcrsubsampling[1] = 2; - td->td_ycbcrpositioning = YCBCRPOSITION_CENTERED; - tif->tif_postdecode = _TIFFNoPostDecode; - tif->tif_foundfield = NULL; - tif->tif_tagmethods.vsetfield = _TIFFVSetField; - tif->tif_tagmethods.vgetfield = _TIFFVGetField; - tif->tif_tagmethods.printdir = NULL; - /* additional default values */ - td->td_planarconfig = PLANARCONFIG_CONTIG; - td->td_compression = COMPRESSION_NONE; - td->td_subfiletype = 0; - td->td_minsamplevalue = 0; - /* td_bitspersample=1 is always set in TIFFDefaultDirectory(). - * Therefore, td_maxsamplevalue has to be re-calculated in - * TIFFGetFieldDefaulted(). */ - td->td_maxsamplevalue = 1; /* Default for td_bitspersample=1 */ - td->td_extrasamples = 0; - td->td_sampleinfo = NULL; - - /* - * Give client code a chance to install their own - * tag extensions & methods, prior to compression overloads, - * but do some prior cleanup first. - * (http://trac.osgeo.org/gdal/ticket/5054) - */ - if (tif->tif_nfieldscompat > 0) - { - uint32_t i; - - for (i = 0; i < tif->tif_nfieldscompat; i++) - { - if (tif->tif_fieldscompat[i].allocated_size) - _TIFFfreeExt(tif, tif->tif_fieldscompat[i].fields); - } - _TIFFfreeExt(tif, tif->tif_fieldscompat); - tif->tif_nfieldscompat = 0; - tif->tif_fieldscompat = NULL; - } - if (_TIFFextender) - (*_TIFFextender)(tif); - (void)TIFFSetField(tif, TIFFTAG_COMPRESSION, COMPRESSION_NONE); - /* - * NB: The directory is marked dirty as a result of setting - * up the default compression scheme. However, this really - * isn't correct -- we want TIFF_DIRTYDIRECT to be set only - * if the user does something. We could just do the setup - * by hand, but it seems better to use the normal mechanism - * (i.e. TIFFSetField). - */ - tif->tif_flags &= ~TIFF_DIRTYDIRECT; - - /* - * As per http://bugzilla.remotesensing.org/show_bug.cgi?id=19 - * we clear the ISTILED flag when setting up a new directory. - * Should we also be clearing stuff like INSUBIFD? - */ - tif->tif_flags &= ~TIFF_ISTILED; - - return (1); -} - -static int TIFFAdvanceDirectory(TIFF *tif, uint64_t *nextdiroff, uint64_t *off, - tdir_t *nextdirnum) -{ - static const char module[] = "TIFFAdvanceDirectory"; - - /* Add this directory to the directory list, if not already in. */ - if (!_TIFFCheckDirNumberAndOffset(tif, *nextdirnum, *nextdiroff)) - { - TIFFErrorExtR(tif, module, - "Starting directory %u at offset 0x%" PRIx64 " (%" PRIu64 - ") might cause an IFD loop", - *nextdirnum, *nextdiroff, *nextdiroff); - *nextdiroff = 0; - *nextdirnum = 0; - return (0); - } - - if (isMapped(tif)) - { - uint64_t poff = *nextdiroff; - if (!(tif->tif_flags & TIFF_BIGTIFF)) - { - 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)) - { - TIFFErrorExtR(tif, module, "Error fetching directory count"); - *nextdiroff = 0; - return (0); - } - _TIFFmemcpy(&dircount, tif->tif_base + poffa, sizeof(uint16_t)); - if (tif->tif_flags & TIFF_SWAB) - TIFFSwabShort(&dircount); - 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)) - { - TIFFErrorExtR(tif, module, "Error fetching directory link"); - return (0); - } - if (off != NULL) - *off = (uint64_t)poffc; - _TIFFmemcpy(&nextdir32, tif->tif_base + poffc, sizeof(uint32_t)); - if (tif->tif_flags & TIFF_SWAB) - TIFFSwabLong(&nextdir32); - *nextdiroff = nextdir32; - } - else - { - 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, "Error fetching directory count"); - return (0); - } - poffa = (tmsize_t)poff; - poffb = poffa + sizeof(uint64_t); - if (poffb > tif->tif_size) - { - TIFFErrorExtR(tif, module, "Error fetching directory count"); - return (0); - } - _TIFFmemcpy(&dircount64, tif->tif_base + poffa, sizeof(uint64_t)); - if (tif->tif_flags & TIFF_SWAB) - TIFFSwabLong8(&dircount64); - if (dircount64 > 0xFFFF) - { - TIFFErrorExtR(tif, module, - "Sanity check on directory count failed"); - return (0); - } - dircount16 = (uint16_t)dircount64; - if (poffb > TIFF_TMSIZE_T_MAX - (tmsize_t)(dircount16 * 20) - - (tmsize_t)sizeof(uint64_t)) - { - TIFFErrorExtR(tif, module, "Error fetching directory link"); - return (0); - } - poffc = poffb + dircount16 * 20; - poffd = poffc + sizeof(uint64_t); - if (poffd > tif->tif_size) - { - TIFFErrorExtR(tif, module, "Error fetching directory link"); - return (0); - } - if (off != NULL) - *off = (uint64_t)poffc; - _TIFFmemcpy(nextdiroff, tif->tif_base + poffc, sizeof(uint64_t)); - if (tif->tif_flags & TIFF_SWAB) - TIFFSwabLong8(nextdiroff); - } - } - else - { - if (!(tif->tif_flags & TIFF_BIGTIFF)) - { - uint16_t dircount; - uint32_t nextdir32; - if (!SeekOK(tif, *nextdiroff) || - !ReadOK(tif, &dircount, sizeof(uint16_t))) - { - TIFFErrorExtR(tif, module, "%s: Error fetching directory count", - tif->tif_name); - return (0); - } - if (tif->tif_flags & TIFF_SWAB) - TIFFSwabShort(&dircount); - if (off != NULL) - *off = TIFFSeekFile(tif, dircount * 12, SEEK_CUR); - else - (void)TIFFSeekFile(tif, dircount * 12, SEEK_CUR); - if (!ReadOK(tif, &nextdir32, sizeof(uint32_t))) - { - TIFFErrorExtR(tif, module, "%s: Error fetching directory link", - tif->tif_name); - return (0); - } - if (tif->tif_flags & TIFF_SWAB) - TIFFSwabLong(&nextdir32); - *nextdiroff = nextdir32; - } - else - { - uint64_t dircount64; - uint16_t dircount16; - if (!SeekOK(tif, *nextdiroff) || - !ReadOK(tif, &dircount64, sizeof(uint64_t))) - { - TIFFErrorExtR(tif, module, "%s: Error fetching directory count", - tif->tif_name); - return (0); - } - if (tif->tif_flags & TIFF_SWAB) - TIFFSwabLong8(&dircount64); - if (dircount64 > 0xFFFF) - { - TIFFErrorExtR(tif, module, "Error fetching directory count"); - return (0); - } - dircount16 = (uint16_t)dircount64; - if (off != NULL) - *off = TIFFSeekFile(tif, dircount16 * 20, SEEK_CUR); - else - (void)TIFFSeekFile(tif, dircount16 * 20, SEEK_CUR); - if (!ReadOK(tif, nextdiroff, sizeof(uint64_t))) - { - TIFFErrorExtR(tif, module, "%s: Error fetching directory link", - tif->tif_name); - return (0); - } - if (tif->tif_flags & TIFF_SWAB) - TIFFSwabLong8(nextdiroff); - } - } - if (*nextdiroff != 0) - { - (*nextdirnum)++; - /* Check next directory for IFD looping and if so, set it as last - * directory. */ - if (!_TIFFCheckDirNumberAndOffset(tif, *nextdirnum, *nextdiroff)) - { - TIFFWarningExtR( - tif, module, - "the next directory %u at offset 0x%" PRIx64 " (%" PRIu64 - ") might be an IFD loop. Treating directory %d as " - "last directory", - *nextdirnum, *nextdiroff, *nextdiroff, (int)(*nextdirnum) - 1); - *nextdiroff = 0; - (*nextdirnum)--; - } - } - return (1); -} - -/* - * Count the number of directories in a file. - */ -tdir_t TIFFNumberOfDirectories(TIFF *tif) -{ - uint64_t nextdiroff; - tdir_t nextdirnum; - tdir_t n; - if (!(tif->tif_flags & TIFF_BIGTIFF)) - nextdiroff = tif->tif_header.classic.tiff_diroff; - else - nextdiroff = tif->tif_header.big.tiff_diroff; - nextdirnum = 0; - n = 0; - while (nextdiroff != 0 && - TIFFAdvanceDirectory(tif, &nextdiroff, NULL, &nextdirnum)) - { - ++n; - } - return (n); -} - -/* - * Set the n-th directory as the current directory. - * NB: Directories are numbered starting at 0. - */ -int TIFFSetDirectory(TIFF *tif, tdir_t dirn) -{ - uint64_t nextdiroff; - tdir_t nextdirnum = 0; - tdir_t n; - - if (tif->tif_setdirectory_force_absolute) - { - /* tif_setdirectory_force_absolute=1 will force parsing the main IFD - * chain from the beginning, thus IFD directory list needs to be cleared - * from possible SubIFD offsets. - */ - _TIFFCleanupIFDOffsetAndNumberMaps(tif); /* invalidate IFD loop lists */ - } - - /* Even faster path, if offset is available within IFD loop hash list. */ - if (!tif->tif_setdirectory_force_absolute && - _TIFFGetOffsetFromDirNumber(tif, dirn, &nextdiroff)) - { - /* Set parameters for following TIFFReadDirectory() below. */ - tif->tif_nextdiroff = nextdiroff; - tif->tif_curdir = dirn; - /* Reset to relative stepping */ - tif->tif_setdirectory_force_absolute = FALSE; - } - else - { - - /* Fast path when we just advance relative to the current directory: - * start at the current dir offset and continue to seek from there. - * Check special cases when relative is not allowed: - * - jump back from SubIFD or custom directory - * - right after TIFFWriteDirectory() jump back to that directory - * using TIFFSetDirectory() */ - const int relative = (dirn >= tif->tif_curdir) && - (tif->tif_diroff != 0) && - !tif->tif_setdirectory_force_absolute; - - if (relative) - { - nextdiroff = tif->tif_diroff; - dirn -= tif->tif_curdir; - nextdirnum = tif->tif_curdir; - } - else if (!(tif->tif_flags & TIFF_BIGTIFF)) - nextdiroff = tif->tif_header.classic.tiff_diroff; - else - nextdiroff = tif->tif_header.big.tiff_diroff; - - /* Reset to relative stepping */ - tif->tif_setdirectory_force_absolute = FALSE; - - for (n = dirn; n > 0 && nextdiroff != 0; n--) - if (!TIFFAdvanceDirectory(tif, &nextdiroff, NULL, &nextdirnum)) - return (0); - /* If the n-th directory could not be reached (does not exist), - * return here without touching anything further. */ - if (nextdiroff == 0 || n > 0) - return (0); - - tif->tif_nextdiroff = nextdiroff; - - /* Set curdir to the actual directory index. */ - if (relative) - tif->tif_curdir += dirn - n; - else - tif->tif_curdir = dirn - n; - } - - /* The -1 decrement is because TIFFReadDirectory will increment - * tif_curdir after successfully reading the directory. */ - if (tif->tif_curdir == 0) - tif->tif_curdir = TIFF_NON_EXISTENT_DIR_NUMBER; - else - tif->tif_curdir--; - return (TIFFReadDirectory(tif)); -} - -/* - * Set the current directory to be the directory - * located at the specified file offset. This interface - * is used mainly to access directories linked with - * the SubIFD tag (e.g. thumbnail images). - */ -int TIFFSetSubDirectory(TIFF *tif, uint64_t diroff) -{ - /* Match nextdiroff and curdir for consistent IFD-loop checking. - * Only with TIFFSetSubDirectory() the IFD list can be corrupted with - * invalid offsets within the main IFD tree. In the case of several subIFDs - * of a main image, there are two possibilities that are not even mutually - * exclusive. a.) The subIFD tag contains an array with all offsets of the - * subIFDs. b.) The SubIFDs are concatenated with their NextIFD parameters. - * (refer to - * https://www.awaresystems.be/imaging/tiff/specification/TIFFPM6.pdf.) - */ - int retval; - uint32_t curdir = 0; - int8_t probablySubIFD = 0; - if (diroff == 0) - { - /* Special case to invalidate the tif_lastdiroff member. */ - tif->tif_curdir = TIFF_NON_EXISTENT_DIR_NUMBER; - } - else - { - if (!_TIFFGetDirNumberFromOffset(tif, diroff, &curdir)) - { - /* Non-existing offsets might point to a SubIFD or invalid IFD.*/ - probablySubIFD = 1; - } - /* -1 because TIFFReadDirectory() will increment tif_curdir. */ - tif->tif_curdir = - curdir == 0 ? TIFF_NON_EXISTENT_DIR_NUMBER : curdir - 1; - } - - tif->tif_nextdiroff = diroff; - retval = TIFFReadDirectory(tif); - /* If failed, curdir was not incremented in TIFFReadDirectory(), so set it - * back, but leave it for diroff==0. */ - if (!retval && diroff != 0) - { - if (tif->tif_curdir == TIFF_NON_EXISTENT_DIR_NUMBER) - tif->tif_curdir = 0; - else - tif->tif_curdir++; - } - if (retval && probablySubIFD) - { - /* Reset IFD list to start new one for SubIFD chain and also start - * SubIFD chain with tif_curdir=0. */ - _TIFFCleanupIFDOffsetAndNumberMaps(tif); /* invalidate IFD loop lists */ - tif->tif_curdir = 0; /* first directory of new chain */ - /* add this offset to new IFD list */ - _TIFFCheckDirNumberAndOffset(tif, tif->tif_curdir, diroff); - /* To be able to return from SubIFD or custom-IFD to main-IFD */ - tif->tif_setdirectory_force_absolute = TRUE; - } - return (retval); -} - -/* - * Return file offset of the current directory. - */ -uint64_t TIFFCurrentDirOffset(TIFF *tif) { return (tif->tif_diroff); } - -/* - * Return an indication of whether or not we are - * at the last directory in the file. - */ -int TIFFLastDirectory(TIFF *tif) { return (tif->tif_nextdiroff == 0); } - -/* - * Unlink the specified directory from the directory chain. - * Note: First directory starts with number dirn=1. - * This is different to TIFFSetDirectory() where the first directory starts with - * zero. - */ -int TIFFUnlinkDirectory(TIFF *tif, tdir_t dirn) -{ - static const char module[] = "TIFFUnlinkDirectory"; - uint64_t nextdir; - tdir_t nextdirnum; - uint64_t off; - tdir_t n; - - if (tif->tif_mode == O_RDONLY) - { - TIFFErrorExtR(tif, module, - "Can not unlink directory in read-only file"); - return (0); - } - if (dirn == 0) - { - TIFFErrorExtR(tif, module, - "For TIFFUnlinkDirectory() first directory starts with " - "number 1 and not 0"); - return (0); - } - /* - * Go to the directory before the one we want - * to unlink and nab the offset of the link - * field we'll need to patch. - */ - if (!(tif->tif_flags & TIFF_BIGTIFF)) - { - nextdir = tif->tif_header.classic.tiff_diroff; - off = 4; - } - else - { - nextdir = tif->tif_header.big.tiff_diroff; - off = 8; - } - nextdirnum = 0; /* First directory is dirn=0 */ - - for (n = dirn - 1; n > 0; n--) - { - if (nextdir == 0) - { - TIFFErrorExtR(tif, module, "Directory %u does not exist", dirn); - return (0); - } - if (!TIFFAdvanceDirectory(tif, &nextdir, &off, &nextdirnum)) - return (0); - } - /* - * Advance to the directory to be unlinked and fetch - * the offset of the directory that follows. - */ - if (!TIFFAdvanceDirectory(tif, &nextdir, NULL, &nextdirnum)) - return (0); - /* - * Go back and patch the link field of the preceding - * directory to point to the offset of the directory - * that follows. - */ - (void)TIFFSeekFile(tif, off, SEEK_SET); - if (!(tif->tif_flags & TIFF_BIGTIFF)) - { - uint32_t nextdir32; - nextdir32 = (uint32_t)nextdir; - assert((uint64_t)nextdir32 == nextdir); - if (tif->tif_flags & TIFF_SWAB) - TIFFSwabLong(&nextdir32); - if (!WriteOK(tif, &nextdir32, sizeof(uint32_t))) - { - TIFFErrorExtR(tif, module, "Error writing directory link"); - return (0); - } - } - else - { - if (tif->tif_flags & TIFF_SWAB) - TIFFSwabLong8(&nextdir); - if (!WriteOK(tif, &nextdir, sizeof(uint64_t))) - { - TIFFErrorExtR(tif, module, "Error writing directory link"); - return (0); - } - } - - /* For dirn=1 (first directory) also update the libtiff internal - * base offset variables. */ - if (dirn == 1) - { - if (!(tif->tif_flags & TIFF_BIGTIFF)) - tif->tif_header.classic.tiff_diroff = (uint32_t)nextdir; - else - tif->tif_header.big.tiff_diroff = nextdir; - } - - /* - * Leave directory state setup safely. We don't have - * facilities for doing inserting and removing directories, - * so it's safest to just invalidate everything. This - * means that the caller can only append to the directory - * chain. - */ - (*tif->tif_cleanup)(tif); - if ((tif->tif_flags & TIFF_MYBUFFER) && tif->tif_rawdata) - { - _TIFFfreeExt(tif, tif->tif_rawdata); - tif->tif_rawdata = NULL; - tif->tif_rawcc = 0; - tif->tif_rawdataoff = 0; - tif->tif_rawdataloaded = 0; - } - tif->tif_flags &= ~(TIFF_BEENWRITING | TIFF_BUFFERSETUP | TIFF_POSTENCODE | - TIFF_BUF4WRITE); - TIFFFreeDirectory(tif); - TIFFDefaultDirectory(tif); - tif->tif_diroff = 0; /* force link on next write */ - tif->tif_nextdiroff = 0; /* next write must be at end */ - tif->tif_lastdiroff = 0; /* will be updated on next link */ - tif->tif_curoff = 0; - tif->tif_row = (uint32_t)-1; - tif->tif_curstrip = (uint32_t)-1; - tif->tif_curdir = TIFF_NON_EXISTENT_DIR_NUMBER; - _TIFFCleanupIFDOffsetAndNumberMaps(tif); /* invalidate IFD loop lists */ - return (1); -} diff --git a/src/3rd/tiff/dir.h b/src/3rd/tiff/dir.h deleted file mode 100644 index 9eaf22f8e62..00000000000 --- a/src/3rd/tiff/dir.h +++ /dev/null @@ -1,340 +0,0 @@ -/* - * Copyright (c) 1988-1997 Sam Leffler - * Copyright (c) 1991-1997 Silicon Graphics, Inc. - * - * Permission to use, copy, modify, distribute, and sell this software and - * its documentation for any purpose is hereby granted without fee, provided - * that (i) the above copyright notices and this permission notice appear in - * all copies of the software and related documentation, and (ii) the names of - * Sam Leffler and Silicon Graphics may not be used in any advertising or - * publicity relating to the software without the specific, prior written - * permission of Sam Leffler and Silicon Graphics. - * - * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, - * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY - * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. - * - * IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR - * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, - * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, - * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF - * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE - * OF THIS SOFTWARE. - */ - -#ifndef _TIFFDIR_ -#define _TIFFDIR_ - -#include "tiff.h" -#include "tiffio.h" - -/* - * ``Library-private'' Directory-related Definitions. - */ - -typedef struct -{ - const TIFFField *info; - int count; - void *value; -} TIFFTagValue; - -/* - * TIFF Image File Directories are comprised of a table of field - * descriptors of the form shown below. The table is sorted in - * ascending order by tag. The values associated with each entry are - * disjoint and may appear anywhere in the file (so long as they are - * placed on a word boundary). - * - * If the value is 4 bytes or less, in ClassicTIFF, or 8 bytes or less in - * BigTIFF, then it is placed in the offset field to save space. If so, - * it is left-justified in the offset field. - */ -typedef struct -{ - uint16_t tdir_tag; /* see below */ - uint16_t tdir_type; /* data type; see below */ - uint64_t tdir_count; /* number of items; length in spec */ - union - { - uint16_t toff_short; - uint32_t toff_long; - uint64_t toff_long8; - } tdir_offset; /* either offset or the data itself if fits */ - uint8_t tdir_ignore; /* flag status to ignore tag when parsing tags in - tif_dirread.c */ -} TIFFDirEntry; - -/* - * Internal format of a TIFF directory entry. - */ -typedef struct -{ -#define FIELDSET_ITEMS 4 - /* bit vector of fields that are set */ - uint32_t td_fieldsset[FIELDSET_ITEMS]; - - uint32_t td_imagewidth, td_imagelength, td_imagedepth; - uint32_t td_tilewidth, td_tilelength, td_tiledepth; - uint32_t td_subfiletype; - uint16_t td_bitspersample; - uint16_t td_sampleformat; - uint16_t td_compression; - uint16_t td_photometric; - uint16_t td_threshholding; - uint16_t td_fillorder; - uint16_t td_orientation; - uint16_t td_samplesperpixel; - uint32_t td_rowsperstrip; - uint16_t td_minsamplevalue, td_maxsamplevalue; - double *td_sminsamplevalue; - double *td_smaxsamplevalue; - float td_xresolution, td_yresolution; - uint16_t td_resolutionunit; - uint16_t td_planarconfig; - float td_xposition, td_yposition; - uint16_t td_pagenumber[2]; - uint16_t *td_colormap[3]; - uint16_t td_halftonehints[2]; - uint16_t td_extrasamples; - uint16_t *td_sampleinfo; - /* 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 */ - uint32_t td_stripsperimage; - uint32_t td_nstrips; /* size of offset & bytecount arrays */ - uint64_t - *td_stripoffset_p; /* should be accessed with TIFFGetStrileOffset */ - uint64_t *td_stripbytecount_p; /* should be accessed with - TIFFGetStrileByteCount */ - uint32_t - td_stripoffsetbyteallocsize; /* number of elements currently allocated - for td_stripoffset/td_stripbytecount. - Only used if TIFF_LAZYSTRILELOAD is set - */ -#ifdef STRIPBYTECOUNTSORTED_UNUSED - int td_stripbytecountsorted; /* is the bytecount array sorted ascending? */ -#endif - TIFFDirEntry td_stripoffset_entry; /* for deferred loading */ - TIFFDirEntry td_stripbytecount_entry; /* for deferred loading */ - uint16_t td_nsubifd; - uint64_t *td_subifd; - /* YCbCr parameters */ - uint16_t td_ycbcrsubsampling[2]; - uint16_t td_ycbcrpositioning; - /* Colorimetry parameters */ - uint16_t *td_transferfunction[3]; - float *td_refblackwhite; - /* CMYK parameters */ - int td_inknameslen; - char *td_inknames; - uint16_t td_numberofinks; /* number of inks in InkNames string */ - - int td_customValueCount; - TIFFTagValue *td_customValues; - - unsigned char - td_deferstrilearraywriting; /* see TIFFDeferStrileArrayWriting() */ -} TIFFDirectory; - -/* - * Field flags used to indicate fields that have been set in a directory, and - * to reference fields when manipulating a directory. - */ - -/* - * FIELD_IGNORE is used to signify tags that are to be processed but otherwise - * ignored. This permits antiquated tags to be quietly read and discarded. - * Note that a bit *is* allocated for ignored tags; this is understood by the - * directory reading logic which uses this fact to avoid special-case handling - */ -#define FIELD_IGNORE 0 - -/* multi-item fields */ -#define FIELD_IMAGEDIMENSIONS 1 -#define FIELD_TILEDIMENSIONS 2 -#define FIELD_RESOLUTION 3 -#define FIELD_POSITION 4 - -/* single-item fields */ -#define FIELD_SUBFILETYPE 5 -#define FIELD_BITSPERSAMPLE 6 -#define FIELD_COMPRESSION 7 -#define FIELD_PHOTOMETRIC 8 -#define FIELD_THRESHHOLDING 9 -#define FIELD_FILLORDER 10 -#define FIELD_ORIENTATION 15 -#define FIELD_SAMPLESPERPIXEL 16 -#define FIELD_ROWSPERSTRIP 17 -#define FIELD_MINSAMPLEVALUE 18 -#define FIELD_MAXSAMPLEVALUE 19 -#define FIELD_PLANARCONFIG 20 -#define FIELD_RESOLUTIONUNIT 22 -#define FIELD_PAGENUMBER 23 -#define FIELD_STRIPBYTECOUNTS 24 -#define FIELD_STRIPOFFSETS 25 -#define FIELD_COLORMAP 26 -#define FIELD_EXTRASAMPLES 31 -#define FIELD_SAMPLEFORMAT 32 -#define FIELD_SMINSAMPLEVALUE 33 -#define FIELD_SMAXSAMPLEVALUE 34 -#define FIELD_IMAGEDEPTH 35 -#define FIELD_TILEDEPTH 36 -#define FIELD_HALFTONEHINTS 37 -#define FIELD_YCBCRSUBSAMPLING 39 -#define FIELD_YCBCRPOSITIONING 40 -#define FIELD_REFBLACKWHITE 41 -#define FIELD_TRANSFERFUNCTION 44 -#define FIELD_INKNAMES 46 -#define FIELD_SUBIFD 49 -#define FIELD_NUMBEROFINKS 50 -/* FIELD_CUSTOM (see tiffio.h) 65 */ -/* end of support for well-known tags; codec-private tags follow */ -#define FIELD_CODEC 66 /* base of codec-private tags */ - -/* - * Pseudo-tags don't normally need field bits since they are not written to an - * output file (by definition). The library also has express logic to always - * query a codec for a pseudo-tag so allocating a field bit for one is a - * waste. If codec wants to promote the notion of a pseudo-tag being ``set'' - * or ``unset'' then it can do using internal state flags without polluting - * the field bit space defined for real tags. - */ -#define FIELD_PSEUDO 0 - -#define FIELD_LAST (32 * FIELDSET_ITEMS - 1) - -#define BITn(n) (((uint32_t)1L) << ((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)) -#define TIFFClrFieldBit(tif, field) (BITFIELDn(tif, field) &= ~BITn(field)) - -#define FieldSet(fields, f) (fields[(f) / 32] & BITn(f)) -#define ResetFieldBit(fields, f) (fields[(f) / 32] &= ~BITn(f)) - -typedef enum -{ - TIFF_SETGET_UNDEFINED = 0, - TIFF_SETGET_ASCII = 1, - TIFF_SETGET_UINT8 = 2, - TIFF_SETGET_SINT8 = 3, - TIFF_SETGET_UINT16 = 4, - TIFF_SETGET_SINT16 = 5, - TIFF_SETGET_UINT32 = 6, - TIFF_SETGET_SINT32 = 7, - TIFF_SETGET_UINT64 = 8, - TIFF_SETGET_SINT64 = 9, - TIFF_SETGET_FLOAT = 10, - TIFF_SETGET_DOUBLE = 11, - TIFF_SETGET_IFD8 = 12, - TIFF_SETGET_INT = 13, - TIFF_SETGET_UINT16_PAIR = 14, - TIFF_SETGET_C0_ASCII = 15, - TIFF_SETGET_C0_UINT8 = 16, - TIFF_SETGET_C0_SINT8 = 17, - TIFF_SETGET_C0_UINT16 = 18, - TIFF_SETGET_C0_SINT16 = 19, - TIFF_SETGET_C0_UINT32 = 20, - TIFF_SETGET_C0_SINT32 = 21, - TIFF_SETGET_C0_UINT64 = 22, - TIFF_SETGET_C0_SINT64 = 23, - TIFF_SETGET_C0_FLOAT = 24, - TIFF_SETGET_C0_DOUBLE = 25, - TIFF_SETGET_C0_IFD8 = 26, - TIFF_SETGET_C16_ASCII = 27, - TIFF_SETGET_C16_UINT8 = 28, - TIFF_SETGET_C16_SINT8 = 29, - TIFF_SETGET_C16_UINT16 = 30, - TIFF_SETGET_C16_SINT16 = 31, - TIFF_SETGET_C16_UINT32 = 32, - TIFF_SETGET_C16_SINT32 = 33, - TIFF_SETGET_C16_UINT64 = 34, - TIFF_SETGET_C16_SINT64 = 35, - TIFF_SETGET_C16_FLOAT = 36, - TIFF_SETGET_C16_DOUBLE = 37, - TIFF_SETGET_C16_IFD8 = 38, - TIFF_SETGET_C32_ASCII = 39, - TIFF_SETGET_C32_UINT8 = 40, - TIFF_SETGET_C32_SINT8 = 41, - TIFF_SETGET_C32_UINT16 = 42, - TIFF_SETGET_C32_SINT16 = 43, - TIFF_SETGET_C32_UINT32 = 44, - TIFF_SETGET_C32_SINT32 = 45, - TIFF_SETGET_C32_UINT64 = 46, - TIFF_SETGET_C32_SINT64 = 47, - TIFF_SETGET_C32_FLOAT = 48, - TIFF_SETGET_C32_DOUBLE = 49, - TIFF_SETGET_C32_IFD8 = 50, - TIFF_SETGET_OTHER = 51 -} TIFFSetGetFieldType; - -#if defined(__cplusplus) -extern "C" -{ -#endif - - extern const TIFFFieldArray *_TIFFGetFields(void); - extern const TIFFFieldArray *_TIFFGetExifFields(void); - extern const TIFFFieldArray *_TIFFGetGpsFields(void); - extern void _TIFFSetupFields(TIFF *tif, const TIFFFieldArray *infoarray); - extern void _TIFFPrintFieldInfo(TIFF *, FILE *); - - extern int _TIFFFillStriles(TIFF *); - - typedef enum - { - tfiatImage, - tfiatExif, - tfiatGps, /* EXIF-GPS fields array type */ - tfiatOther - } TIFFFieldArrayType; - - struct _TIFFFieldArray - { - TIFFFieldArrayType type; /* array type, will be used to determine if IFD - is image and such */ - uint32_t allocated_size; /* 0 if array is constant, other if modified by - future definition extension support */ - uint32_t count; /* number of elements in fields array */ - TIFFField *fields; /* actual field info */ - }; - - struct _TIFFField - { - uint32_t field_tag; /* field's tag */ - short field_readcount; /* read count/TIFF_VARIABLE/TIFF_SPP */ - short field_writecount; /* write count/TIFF_VARIABLE */ - TIFFDataType field_type; /* type of associated data */ - uint32_t - field_anonymous; /* if true, this is a unknown / anonymous tag */ - TIFFSetGetFieldType - set_field_type; /* type to be passed to TIFFSetField */ - TIFFSetGetFieldType - get_field_type; /* type to be passed to TIFFGetField */ - unsigned short field_bit; /* bit in fieldsset bit vector */ - 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 */ - TIFFFieldArray *field_subfields; /* if field points to child ifds, child - ifd field definition array */ - }; - - extern int _TIFFMergeFields(TIFF *, const TIFFField[], uint32_t); - extern const TIFFField *_TIFFFindOrRegisterField(TIFF *, uint32_t, - TIFFDataType); - extern TIFFField *_TIFFCreateAnonField(TIFF *, uint32_t, TIFFDataType); - extern int _TIFFCheckFieldIsValidForCodec(TIFF *tif, ttag_t tag); - extern int _TIFFCheckDirNumberAndOffset(TIFF *tif, tdir_t dirn, - uint64_t diroff); - extern int _TIFFGetDirNumberFromOffset(TIFF *tif, uint64_t diroff, - tdir_t *dirn); - extern int _TIFFGetOffsetFromDirNumber(TIFF *tif, tdir_t dirn, - uint64_t *diroff); - extern int _TIFFRemoveEntryFromDirectoryListByOffset(TIFF *tif, - uint64_t diroff); - -#if defined(__cplusplus) -} -#endif -#endif /* _TIFFDIR_ */ diff --git a/src/3rd/tiff/dirinfo.c b/src/3rd/tiff/dirinfo.c deleted file mode 100644 index 0e705e81e3d..00000000000 --- a/src/3rd/tiff/dirinfo.c +++ /dev/null @@ -1,1351 +0,0 @@ -/* - * Copyright (c) 1988-1997 Sam Leffler - * Copyright (c) 1991-1997 Silicon Graphics, Inc. - * - * Permission to use, copy, modify, distribute, and sell this software and - * its documentation for any purpose is hereby granted without fee, provided - * that (i) the above copyright notices and this permission notice appear in - * all copies of the software and related documentation, and (ii) the names of - * Sam Leffler and Silicon Graphics may not be used in any advertising or - * publicity relating to the software without the specific, prior written - * permission of Sam Leffler and Silicon Graphics. - * - * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, - * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY - * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. - * - * IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR - * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, - * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, - * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF - * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE - * OF THIS SOFTWARE. - */ - -/* - * TIFF Library. - * - * Core Directory Tag Support. - */ -#include "tiffiop.h" -#include - -/* - * NOTE: THIS ARRAY IS ASSUMED TO BE SORTED BY TAG. - * - * NOTE: The second field (field_readcount) and third field (field_writecount) - * sometimes use the values TIFF_VARIABLE (-1), TIFF_VARIABLE2 (-3) - * and TIFF_SPP (-2). The macros should be used but would throw off - * the formatting of the code, so please interpret the -1, -2 and -3 - * values accordingly. - */ - -/* const object should be initialized */ -#ifdef _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 -#pragma warning(pop) -#endif -/*--: Rational2Double: -- - * The Rational2Double upgraded libtiff functionality allows the definition and - * achievement of true double-precision accuracy for TIFF tags of RATIONAL type - * and field_bit=FIELD_CUSTOM using the set_field_type = TIFF_SETGET_DOUBLE. - * Unfortunately, that changes the old implemented interface for TIFFGetField(). - * In order to keep the old TIFFGetField() interface behavior those tags have to - * be redefined with set_field_type = TIFF_SETGET_FLOAT! - * - * Rational custom arrays are already defined as _Cxx_FLOAT, thus can stay. - * - */ - -/* clang-format off */ /* for better readability of tag comments */ -static const TIFFField tiffFields[] = { - {TIFFTAG_SUBFILETYPE, 1, 1, TIFF_LONG, 0, TIFF_SETGET_UINT32, TIFF_SETGET_UNDEFINED, FIELD_SUBFILETYPE, 1, 0, "SubfileType", NULL}, - {TIFFTAG_OSUBFILETYPE, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UNDEFINED, TIFF_SETGET_UNDEFINED, FIELD_IGNORE, 1, 0, "OldSubfileType", NULL}, - {TIFFTAG_IMAGEWIDTH, 1, 1, TIFF_LONG, 0, TIFF_SETGET_UINT32, TIFF_SETGET_UNDEFINED, FIELD_IMAGEDIMENSIONS, 0, 0, "ImageWidth", NULL}, - {TIFFTAG_IMAGELENGTH, 1, 1, TIFF_LONG, 0, TIFF_SETGET_UINT32, TIFF_SETGET_UNDEFINED, FIELD_IMAGEDIMENSIONS, 1, 0, "ImageLength", NULL}, - {TIFFTAG_BITSPERSAMPLE, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, TIFF_SETGET_UNDEFINED, FIELD_BITSPERSAMPLE, 0, 0, "BitsPerSample", NULL}, - {TIFFTAG_COMPRESSION, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, TIFF_SETGET_UNDEFINED, FIELD_COMPRESSION, 0, 0, "Compression", NULL}, - {TIFFTAG_PHOTOMETRIC, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, TIFF_SETGET_UNDEFINED, FIELD_PHOTOMETRIC, 0, 0, "PhotometricInterpretation", NULL}, - {TIFFTAG_THRESHHOLDING, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, TIFF_SETGET_UNDEFINED, FIELD_THRESHHOLDING, 1, 0, "Threshholding", NULL}, - {TIFFTAG_CELLWIDTH, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "CellWidth", NULL}, - {TIFFTAG_CELLLENGTH, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "CellLength", NULL}, - {TIFFTAG_FILLORDER, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, TIFF_SETGET_UNDEFINED, FIELD_FILLORDER, 0, 0, "FillOrder", NULL}, - {TIFFTAG_DOCUMENTNAME, -1, -1, TIFF_ASCII, 0, TIFF_SETGET_ASCII, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "DocumentName", NULL}, - {TIFFTAG_IMAGEDESCRIPTION, -1, -1, TIFF_ASCII, 0, TIFF_SETGET_ASCII, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "ImageDescription", NULL}, - {TIFFTAG_MAKE, -1, -1, TIFF_ASCII, 0, TIFF_SETGET_ASCII, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "Make", NULL}, - {TIFFTAG_MODEL, -1, -1, TIFF_ASCII, 0, TIFF_SETGET_ASCII, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "Model", NULL}, - {TIFFTAG_STRIPOFFSETS, -1, -1, TIFF_LONG8, 0, TIFF_SETGET_UNDEFINED, TIFF_SETGET_UNDEFINED, FIELD_STRIPOFFSETS, 0, 0, "StripOffsets", NULL}, - {TIFFTAG_ORIENTATION, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, TIFF_SETGET_UNDEFINED, FIELD_ORIENTATION, 0, 0, "Orientation", NULL}, - {TIFFTAG_SAMPLESPERPIXEL, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, TIFF_SETGET_UNDEFINED, FIELD_SAMPLESPERPIXEL, 0, 0, "SamplesPerPixel", NULL}, - {TIFFTAG_ROWSPERSTRIP, 1, 1, TIFF_LONG, 0, TIFF_SETGET_UINT32, TIFF_SETGET_UNDEFINED, FIELD_ROWSPERSTRIP, 0, 0, "RowsPerStrip", NULL}, - {TIFFTAG_STRIPBYTECOUNTS, -1, -1, TIFF_LONG8, 0, TIFF_SETGET_UNDEFINED, TIFF_SETGET_UNDEFINED, FIELD_STRIPBYTECOUNTS, 0, 0, "StripByteCounts", NULL}, - {TIFFTAG_MINSAMPLEVALUE, -2, -1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, TIFF_SETGET_UNDEFINED, FIELD_MINSAMPLEVALUE, 1, 0, "MinSampleValue", NULL}, - {TIFFTAG_MAXSAMPLEVALUE, -2, -1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, TIFF_SETGET_UNDEFINED, FIELD_MAXSAMPLEVALUE, 1, 0, "MaxSampleValue", NULL}, - {TIFFTAG_XRESOLUTION, 1, 1, TIFF_RATIONAL, 0, TIFF_SETGET_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_RESOLUTION, 1, 0, "XResolution", NULL}, - {TIFFTAG_YRESOLUTION, 1, 1, TIFF_RATIONAL, 0, TIFF_SETGET_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_RESOLUTION, 1, 0, "YResolution", NULL}, - {TIFFTAG_PLANARCONFIG, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, TIFF_SETGET_UNDEFINED, FIELD_PLANARCONFIG, 0, 0, "PlanarConfiguration", NULL}, - {TIFFTAG_PAGENAME, -1, -1, TIFF_ASCII, 0, TIFF_SETGET_ASCII, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "PageName", NULL}, - {TIFFTAG_XPOSITION, 1, 1, TIFF_RATIONAL, 0, TIFF_SETGET_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_POSITION, 1, 0, "XPosition", NULL}, - {TIFFTAG_YPOSITION, 1, 1, TIFF_RATIONAL, 0, TIFF_SETGET_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_POSITION, 1, 0, "YPosition", NULL}, - {TIFFTAG_FREEOFFSETS, -1, -1, TIFF_LONG8, 0, TIFF_SETGET_UNDEFINED, TIFF_SETGET_UNDEFINED, FIELD_IGNORE, 0, 0, "FreeOffsets", NULL}, - {TIFFTAG_FREEBYTECOUNTS, -1, -1, TIFF_LONG8, 0, TIFF_SETGET_UNDEFINED, TIFF_SETGET_UNDEFINED, FIELD_IGNORE, 0, 0, "FreeByteCounts", NULL}, - {TIFFTAG_GRAYRESPONSEUNIT, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UNDEFINED, TIFF_SETGET_UNDEFINED, FIELD_IGNORE, 1, 0, "GrayResponseUnit", NULL}, - {TIFFTAG_GRAYRESPONSECURVE, -1, -1, TIFF_SHORT, 0, TIFF_SETGET_UNDEFINED, TIFF_SETGET_UNDEFINED, FIELD_IGNORE, 1, 0, "GrayResponseCurve", NULL}, - {TIFFTAG_RESOLUTIONUNIT, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, TIFF_SETGET_UNDEFINED, FIELD_RESOLUTIONUNIT, 1, 0, "ResolutionUnit", NULL}, - {TIFFTAG_PAGENUMBER, 2, 2, TIFF_SHORT, 0, TIFF_SETGET_UINT16_PAIR, TIFF_SETGET_UNDEFINED, FIELD_PAGENUMBER, 1, 0, "PageNumber", NULL}, - {TIFFTAG_COLORRESPONSEUNIT, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UNDEFINED, TIFF_SETGET_UNDEFINED, FIELD_IGNORE, 1, 0, "ColorResponseUnit", NULL}, - {TIFFTAG_TRANSFERFUNCTION, -1, -1, TIFF_SHORT, 0, TIFF_SETGET_OTHER, TIFF_SETGET_UNDEFINED, FIELD_TRANSFERFUNCTION, 1, 0, "TransferFunction", NULL}, - {TIFFTAG_SOFTWARE, -1, -1, TIFF_ASCII, 0, TIFF_SETGET_ASCII, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "Software", NULL}, - {TIFFTAG_DATETIME, 20, 20, TIFF_ASCII, 0, TIFF_SETGET_ASCII, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "DateTime", NULL}, - {TIFFTAG_ARTIST, -1, -1, TIFF_ASCII, 0, TIFF_SETGET_ASCII, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "Artist", NULL}, - {TIFFTAG_HOSTCOMPUTER, -1, -1, TIFF_ASCII, 0, TIFF_SETGET_ASCII, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "HostComputer", NULL}, - {TIFFTAG_WHITEPOINT, 2, 2, TIFF_RATIONAL, 0, TIFF_SETGET_C0_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "WhitePoint", NULL}, - {TIFFTAG_PRIMARYCHROMATICITIES, 6, 6, TIFF_RATIONAL, 0, TIFF_SETGET_C0_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "PrimaryChromaticities", NULL}, - {TIFFTAG_COLORMAP, -1, -1, TIFF_SHORT, 0, TIFF_SETGET_OTHER, TIFF_SETGET_UNDEFINED, FIELD_COLORMAP, 1, 0, "ColorMap", NULL}, - {TIFFTAG_HALFTONEHINTS, 2, 2, TIFF_SHORT, 0, TIFF_SETGET_UINT16_PAIR, TIFF_SETGET_UNDEFINED, FIELD_HALFTONEHINTS, 1, 0, "HalftoneHints", NULL}, - {TIFFTAG_TILEWIDTH, 1, 1, TIFF_LONG, 0, TIFF_SETGET_UINT32, TIFF_SETGET_UNDEFINED, FIELD_TILEDIMENSIONS, 0, 0, "TileWidth", NULL}, - {TIFFTAG_TILELENGTH, 1, 1, TIFF_LONG, 0, TIFF_SETGET_UINT32, TIFF_SETGET_UNDEFINED, FIELD_TILEDIMENSIONS, 0, 0, "TileLength", NULL}, - {TIFFTAG_TILEOFFSETS, -1, 1, TIFF_LONG8, 0, TIFF_SETGET_UNDEFINED, TIFF_SETGET_UNDEFINED, FIELD_STRIPOFFSETS, 0, 0, "TileOffsets", NULL}, - {TIFFTAG_TILEBYTECOUNTS, -1, 1, TIFF_LONG8, 0, TIFF_SETGET_UNDEFINED, TIFF_SETGET_UNDEFINED, FIELD_STRIPBYTECOUNTS, 0, 0, "TileByteCounts", NULL}, - {TIFFTAG_SUBIFD, -1, -1, TIFF_IFD8, 0, TIFF_SETGET_C16_IFD8, TIFF_SETGET_UNDEFINED, FIELD_SUBIFD, 1, 1, "SubIFD", (TIFFFieldArray *)&tiffFieldArray}, - {TIFFTAG_INKSET, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 0, "InkSet", NULL}, - {TIFFTAG_INKNAMES, -1, -1, TIFF_ASCII, 0, TIFF_SETGET_C16_ASCII, TIFF_SETGET_UNDEFINED, FIELD_INKNAMES, 1, 1, "InkNames", NULL}, - {TIFFTAG_NUMBEROFINKS, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, TIFF_SETGET_UNDEFINED, FIELD_NUMBEROFINKS, 1, 0, "NumberOfInks", NULL}, - {TIFFTAG_DOTRANGE, 2, 2, TIFF_SHORT, 0, TIFF_SETGET_UINT16_PAIR, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 0, "DotRange", NULL}, - {TIFFTAG_TARGETPRINTER, -1, -1, TIFF_ASCII, 0, TIFF_SETGET_ASCII, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "TargetPrinter", NULL}, - {TIFFTAG_EXTRASAMPLES, -1, -1, TIFF_SHORT, 0, TIFF_SETGET_C16_UINT16, TIFF_SETGET_UNDEFINED, FIELD_EXTRASAMPLES, 0, 1, "ExtraSamples", NULL}, - {TIFFTAG_SAMPLEFORMAT, -1, -1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, TIFF_SETGET_UNDEFINED, FIELD_SAMPLEFORMAT, 0, 0, "SampleFormat", NULL}, - {TIFFTAG_SMINSAMPLEVALUE, -2, -1, TIFF_ANY, 0, TIFF_SETGET_DOUBLE, TIFF_SETGET_UNDEFINED, FIELD_SMINSAMPLEVALUE, 1, 0, "SMinSampleValue", NULL}, - {TIFFTAG_SMAXSAMPLEVALUE, -2, -1, TIFF_ANY, 0, TIFF_SETGET_DOUBLE, TIFF_SETGET_UNDEFINED, FIELD_SMAXSAMPLEVALUE, 1, 0, "SMaxSampleValue", NULL}, - {TIFFTAG_CLIPPATH, -3, -3, TIFF_BYTE, 0, TIFF_SETGET_C32_UINT8, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 1, "ClipPath", NULL}, - {TIFFTAG_XCLIPPATHUNITS, 1, 1, TIFF_LONG, 0, TIFF_SETGET_UINT32, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 0, "XClipPathUnits", NULL}, - {TIFFTAG_YCLIPPATHUNITS, 1, 1, TIFF_LONG, 0, TIFF_SETGET_UINT32, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 0, "YClipPathUnits", NULL}, - {TIFFTAG_YCBCRCOEFFICIENTS, 3, 3, TIFF_RATIONAL, 0, TIFF_SETGET_C0_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 0, "YCbCrCoefficients", NULL}, - {TIFFTAG_YCBCRSUBSAMPLING, 2, 2, TIFF_SHORT, 0, TIFF_SETGET_UINT16_PAIR, TIFF_SETGET_UNDEFINED, FIELD_YCBCRSUBSAMPLING, 0, 0, "YCbCrSubsampling", NULL}, - {TIFFTAG_YCBCRPOSITIONING, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, TIFF_SETGET_UNDEFINED, FIELD_YCBCRPOSITIONING, 0, 0, "YCbCrPositioning", NULL}, - {TIFFTAG_REFERENCEBLACKWHITE, 6, 6, TIFF_RATIONAL, 0, TIFF_SETGET_C0_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_REFBLACKWHITE, 1, 0, "ReferenceBlackWhite", NULL}, - {TIFFTAG_XMLPACKET, -3, -3, TIFF_BYTE, 0, TIFF_SETGET_C32_UINT8, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 1, "XMLPacket", NULL}, - /* begin SGI tags */ - {TIFFTAG_MATTEING, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, TIFF_SETGET_UNDEFINED, FIELD_EXTRASAMPLES, 0, 0, "Matteing", NULL}, - {TIFFTAG_DATATYPE, -2, -1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, TIFF_SETGET_UNDEFINED, FIELD_SAMPLEFORMAT, 0, 0, "DataType", NULL}, - {TIFFTAG_IMAGEDEPTH, 1, 1, TIFF_LONG, 0, TIFF_SETGET_UINT32, TIFF_SETGET_UNDEFINED, FIELD_IMAGEDEPTH, 0, 0, "ImageDepth", NULL}, - {TIFFTAG_TILEDEPTH, 1, 1, TIFF_LONG, 0, TIFF_SETGET_UINT32, TIFF_SETGET_UNDEFINED, FIELD_TILEDEPTH, 0, 0, "TileDepth", NULL}, - /* end SGI tags */ - /* begin Pixar tags */ - {TIFFTAG_PIXAR_IMAGEFULLWIDTH, 1, 1, TIFF_LONG, 0, TIFF_SETGET_UINT32, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "ImageFullWidth", NULL}, - {TIFFTAG_PIXAR_IMAGEFULLLENGTH, 1, 1, TIFF_LONG, 0, TIFF_SETGET_UINT32, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "ImageFullLength", NULL}, - {TIFFTAG_PIXAR_TEXTUREFORMAT, -1, -1, TIFF_ASCII, 0, TIFF_SETGET_ASCII, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "TextureFormat", NULL}, - {TIFFTAG_PIXAR_WRAPMODES, -1, -1, TIFF_ASCII, 0, TIFF_SETGET_ASCII, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "TextureWrapModes", NULL}, - {TIFFTAG_PIXAR_FOVCOT, 1, 1, TIFF_FLOAT, 0, TIFF_SETGET_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "FieldOfViewCotangent", NULL}, - {TIFFTAG_PIXAR_MATRIX_WORLDTOSCREEN, 16, 16, TIFF_FLOAT, 0, TIFF_SETGET_C0_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "MatrixWorldToScreen", NULL}, - {TIFFTAG_PIXAR_MATRIX_WORLDTOCAMERA, 16, 16, TIFF_FLOAT, 0, TIFF_SETGET_C0_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "MatrixWorldToCamera", NULL}, - {TIFFTAG_COPYRIGHT, -1, -1, TIFF_ASCII, 0, TIFF_SETGET_ASCII, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "Copyright", NULL}, - /* end Pixar tags */ - {TIFFTAG_RICHTIFFIPTC, -3, -3, TIFF_UNDEFINED, 0, TIFF_SETGET_C32_UINT8, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 1, "RichTIFFIPTC", NULL}, - {TIFFTAG_PHOTOSHOP, -3, -3, TIFF_BYTE, 0, TIFF_SETGET_C32_UINT8, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 1, "Photoshop", NULL}, - /*--: EXIFIFD and GPSIFD specified as TIFF_LONG by Aware-Systems and not TIFF_IFD8 as in original LibTiff. However, for IFD-like tags, - * libtiff uses the data type TIFF_IFD8 in tiffFields[]-tag definition combined with a special handling procedure in order to write either - * a 32-bit value and the TIFF_IFD type-id into ClassicTIFF files or a 64-bit value and the TIFF_IFD8 type-id into BigTIFF files. */ - {TIFFTAG_EXIFIFD, 1, 1, TIFF_IFD8, 0, TIFF_SETGET_IFD8, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "EXIFIFDOffset", (TIFFFieldArray *)&exifFieldArray}, - {TIFFTAG_ICCPROFILE, -3, -3, TIFF_UNDEFINED, 0, TIFF_SETGET_C32_UINT8, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 1, "ICC Profile", NULL}, - {TIFFTAG_GPSIFD, 1, 1, TIFF_IFD8, 0, TIFF_SETGET_IFD8, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "GPSIFDOffset", (TIFFFieldArray *)&gpsFieldArray}, - {TIFFTAG_FAXRECVPARAMS, 1, 1, TIFF_LONG, 0, TIFF_SETGET_UINT32, TIFF_SETGET_UINT32, FIELD_CUSTOM, TRUE, FALSE, "FaxRecvParams", NULL}, - {TIFFTAG_FAXSUBADDRESS, -1, -1, TIFF_ASCII, 0, TIFF_SETGET_ASCII, TIFF_SETGET_ASCII, FIELD_CUSTOM, TRUE, FALSE, "FaxSubAddress", NULL}, - {TIFFTAG_FAXRECVTIME, 1, 1, TIFF_LONG, 0, TIFF_SETGET_UINT32, TIFF_SETGET_UINT32, FIELD_CUSTOM, TRUE, FALSE, "FaxRecvTime", NULL}, - {TIFFTAG_FAXDCS, -1, -1, TIFF_ASCII, 0, TIFF_SETGET_ASCII, TIFF_SETGET_ASCII, FIELD_CUSTOM, TRUE, FALSE, "FaxDcs", NULL}, - {TIFFTAG_STONITS, 1, 1, TIFF_DOUBLE, 0, TIFF_SETGET_DOUBLE, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 0, "StoNits", NULL}, - {TIFFTAG_IMAGESOURCEDATA, -3, -3, TIFF_UNDEFINED, 0, TIFF_SETGET_C32_UINT8, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 1, "Adobe Photoshop Document Data Block", NULL}, - {TIFFTAG_INTEROPERABILITYIFD, 1, 1, TIFF_IFD8, 0, TIFF_SETGET_IFD8, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 0, "InteroperabilityIFDOffset", NULL}, - /* begin DNG tags */ - {TIFFTAG_DNGVERSION, 4, 4, TIFF_BYTE, 0, TIFF_SETGET_C0_UINT8, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "DNGVersion", NULL}, - {TIFFTAG_DNGBACKWARDVERSION, 4, 4, TIFF_BYTE, 0, TIFF_SETGET_C0_UINT8, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "DNGBackwardVersion", NULL}, - {TIFFTAG_UNIQUECAMERAMODEL, -1, -1, TIFF_ASCII, 0, TIFF_SETGET_ASCII, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "UniqueCameraModel", NULL}, - {TIFFTAG_LOCALIZEDCAMERAMODEL, -1, -1, TIFF_BYTE, 0, TIFF_SETGET_C16_UINT8, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 1, "LocalizedCameraModel", NULL}, - {TIFFTAG_CFAPLANECOLOR, -1, -1, TIFF_BYTE, 0, TIFF_SETGET_C16_UINT8, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 1, "CFAPlaneColor", NULL}, - {TIFFTAG_CFALAYOUT, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "CFALayout", NULL}, - {TIFFTAG_LINEARIZATIONTABLE, -1, -1, TIFF_SHORT, 0, TIFF_SETGET_C16_UINT16, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 1, "LinearizationTable", NULL}, - {TIFFTAG_BLACKLEVELREPEATDIM, 2, 2, TIFF_SHORT, 0, TIFF_SETGET_C0_UINT16, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "BlackLevelRepeatDim", NULL}, - {TIFFTAG_BLACKLEVEL, -1, -1, TIFF_RATIONAL, 0, TIFF_SETGET_C16_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 1, "BlackLevel", NULL}, - {TIFFTAG_BLACKLEVELDELTAH, -1, -1, TIFF_SRATIONAL, 0, TIFF_SETGET_C16_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 1, "BlackLevelDeltaH", NULL}, - {TIFFTAG_BLACKLEVELDELTAV, -1, -1, TIFF_SRATIONAL, 0, TIFF_SETGET_C16_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 1, "BlackLevelDeltaV", NULL}, - {TIFFTAG_WHITELEVEL, -1, -1, TIFF_LONG, 0, TIFF_SETGET_C16_UINT32, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 1, "WhiteLevel", NULL}, - {TIFFTAG_DEFAULTSCALE, 2, 2, TIFF_RATIONAL, 0, TIFF_SETGET_C0_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "DefaultScale", NULL}, - {TIFFTAG_BESTQUALITYSCALE, 1, 1, TIFF_RATIONAL, 0, TIFF_SETGET_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "BestQualityScale", NULL}, - {TIFFTAG_DEFAULTCROPORIGIN, 2, 2, TIFF_RATIONAL, 0, TIFF_SETGET_C0_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "DefaultCropOrigin", NULL}, - {TIFFTAG_DEFAULTCROPSIZE, 2, 2, TIFF_RATIONAL, 0, TIFF_SETGET_C0_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "DefaultCropSize", NULL}, - {TIFFTAG_COLORMATRIX1, -1, -1, TIFF_SRATIONAL, 0, TIFF_SETGET_C16_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 1, "ColorMatrix1", NULL}, - {TIFFTAG_COLORMATRIX2, -1, -1, TIFF_SRATIONAL, 0, TIFF_SETGET_C16_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 1, "ColorMatrix2", NULL}, - {TIFFTAG_CAMERACALIBRATION1, -1, -1, TIFF_SRATIONAL, 0, TIFF_SETGET_C16_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 1, "CameraCalibration1", NULL}, - {TIFFTAG_CAMERACALIBRATION2, -1, -1, TIFF_SRATIONAL, 0, TIFF_SETGET_C16_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 1, "CameraCalibration2", NULL}, - {TIFFTAG_REDUCTIONMATRIX1, -1, -1, TIFF_SRATIONAL, 0, TIFF_SETGET_C16_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 1, "ReductionMatrix1", NULL}, - {TIFFTAG_REDUCTIONMATRIX2, -1, -1, TIFF_SRATIONAL, 0, TIFF_SETGET_C16_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 1, "ReductionMatrix2", NULL}, - {TIFFTAG_ANALOGBALANCE, -1, -1, TIFF_RATIONAL, 0, TIFF_SETGET_C16_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 1, "AnalogBalance", NULL}, - {TIFFTAG_ASSHOTNEUTRAL, -1, -1, TIFF_RATIONAL, 0, TIFF_SETGET_C16_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 1, "AsShotNeutral", NULL}, - {TIFFTAG_ASSHOTWHITEXY, 2, 2, TIFF_RATIONAL, 0, TIFF_SETGET_C0_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "AsShotWhiteXY", NULL}, - {TIFFTAG_BASELINEEXPOSURE, 1, 1, TIFF_SRATIONAL, 0, TIFF_SETGET_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "BaselineExposure", NULL}, - {TIFFTAG_BASELINENOISE, 1, 1, TIFF_RATIONAL, 0, TIFF_SETGET_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "BaselineNoise", NULL}, - {TIFFTAG_BASELINESHARPNESS, 1, 1, TIFF_RATIONAL, 0, TIFF_SETGET_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "BaselineSharpness", NULL}, - {TIFFTAG_BAYERGREENSPLIT, 1, 1, TIFF_LONG, 0, TIFF_SETGET_UINT32, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "BayerGreenSplit", NULL}, - {TIFFTAG_LINEARRESPONSELIMIT, 1, 1, TIFF_RATIONAL, 0, TIFF_SETGET_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "LinearResponseLimit", NULL}, - {TIFFTAG_CAMERASERIALNUMBER, -1, -1, TIFF_ASCII, 0, TIFF_SETGET_ASCII, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "CameraSerialNumber", NULL}, - {TIFFTAG_LENSINFO, 4, 4, TIFF_RATIONAL, 0, TIFF_SETGET_C0_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "LensInfo", NULL}, - {TIFFTAG_CHROMABLURRADIUS, 1, 1, TIFF_RATIONAL, 0, TIFF_SETGET_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "ChromaBlurRadius", NULL}, - {TIFFTAG_ANTIALIASSTRENGTH, 1, 1, TIFF_RATIONAL, 0, TIFF_SETGET_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "AntiAliasStrength", NULL}, - {TIFFTAG_SHADOWSCALE, 1, 1, TIFF_RATIONAL, 0, TIFF_SETGET_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "ShadowScale", NULL}, - {TIFFTAG_DNGPRIVATEDATA, -1, -1, TIFF_BYTE, 0, TIFF_SETGET_C16_UINT8, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 1, "DNGPrivateData", NULL}, - {TIFFTAG_MAKERNOTESAFETY, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "MakerNoteSafety", NULL}, - {TIFFTAG_CALIBRATIONILLUMINANT1, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "CalibrationIlluminant1", NULL}, - {TIFFTAG_CALIBRATIONILLUMINANT2, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "CalibrationIlluminant2", NULL}, - {TIFFTAG_RAWDATAUNIQUEID, 16, 16, TIFF_BYTE, 0, TIFF_SETGET_C0_UINT8, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "RawDataUniqueID", NULL}, - {TIFFTAG_ORIGINALRAWFILENAME, -1, -1, TIFF_BYTE, 0, TIFF_SETGET_C16_UINT8, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 1, "OriginalRawFileName", NULL}, - {TIFFTAG_ORIGINALRAWFILEDATA, -1, -1, TIFF_UNDEFINED, 0, TIFF_SETGET_C16_UINT8, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 1, "OriginalRawFileData", NULL}, - {TIFFTAG_ACTIVEAREA, 4, 4, TIFF_LONG, 0, TIFF_SETGET_C0_UINT32, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "ActiveArea", NULL}, - {TIFFTAG_MASKEDAREAS, -1, -1, TIFF_LONG, 0, TIFF_SETGET_C16_UINT32, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 1, "MaskedAreas", NULL}, - {TIFFTAG_ASSHOTICCPROFILE, -1, -1, TIFF_UNDEFINED, 0, TIFF_SETGET_C16_UINT8, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 1, "AsShotICCProfile", NULL}, - {TIFFTAG_ASSHOTPREPROFILEMATRIX, -1, -1, TIFF_SRATIONAL, 0, TIFF_SETGET_C16_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 1, "AsShotPreProfileMatrix", NULL}, - {TIFFTAG_CURRENTICCPROFILE, -1, -1, TIFF_UNDEFINED, 0, TIFF_SETGET_C16_UINT8, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 1, "CurrentICCProfile", NULL}, - {TIFFTAG_CURRENTPREPROFILEMATRIX, -1, -1, TIFF_SRATIONAL, 0, TIFF_SETGET_C16_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 1, "CurrentPreProfileMatrix", NULL}, - {TIFFTAG_PERSAMPLE, 0, 0, TIFF_SHORT, 0, TIFF_SETGET_UNDEFINED, TIFF_SETGET_UNDEFINED, FIELD_PSEUDO, TRUE, FALSE, "PerSample", NULL}, -#if 0 - /* TODO: revert above #if 0 for TIFF 4.6.0 */ - - /* begin DNG 1.2.0.0 tags */ - {TIFFTAG_COLORIMETRICREFERENCE, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "ColorimetricReference", NULL}, - {TIFFTAG_CAMERACALIBRATIONSIGNATURE, -1, -1, TIFF_BYTE, 0, TIFF_SETGET_C16_UINT8, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 1, "CameraCalibrationSignature", NULL}, - {TIFFTAG_PROFILECALIBRATIONSIGNATURE, -1, -1, TIFF_BYTE, 0, TIFF_SETGET_C16_UINT8, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 1, "ProfileCalibrationSignature", NULL}, - {TIFFTAG_EXTRACAMERAPROFILES, -1, -1, TIFF_IFD8, 0, TIFF_SETGET_C16_IFD8, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 1, "ExtraCameraProfiles", NULL}, - {TIFFTAG_ASSHOTPROFILENAME, -1, -1, TIFF_BYTE, 0, TIFF_SETGET_C16_UINT8, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 1, "AsShotProfileName", NULL}, - {TIFFTAG_NOISEREDUCTIONAPPLIED, 1, 1, TIFF_RATIONAL, 0, TIFF_SETGET_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "NoiseReductionApplied", NULL}, - {TIFFTAG_PROFILENAME, -1, -1, TIFF_BYTE, 0, TIFF_SETGET_C16_UINT8, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 1, "ProfileName", NULL}, - {TIFFTAG_PROFILEHUESATMAPDIMS, 3, 3, TIFF_LONG, 0, TIFF_SETGET_C0_UINT32, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "ProfileHueSatMapDims", NULL}, - {TIFFTAG_PROFILEHUESATMAPDATA1, -1, -1, TIFF_FLOAT, 0, TIFF_SETGET_C16_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 1, "ProfileHueSatMapData1", NULL}, - {TIFFTAG_PROFILEHUESATMAPDATA2, -1, -1, TIFF_FLOAT, 0, TIFF_SETGET_C16_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 1, "ProfileHueSatMapData2", NULL}, - {TIFFTAG_PROFILETONECURVE, -1, -1, TIFF_FLOAT, 0, TIFF_SETGET_C16_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 1, "ProfileToneCurve", NULL}, - {TIFFTAG_PROFILEEMBEDPOLICY, 1, 1, TIFF_LONG, 0, TIFF_SETGET_UINT32, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "ProfileEmbedPolicy", NULL}, - {TIFFTAG_PROFILECOPYRIGHT, -1, -1, TIFF_BYTE, 0, TIFF_SETGET_C16_UINT8, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 1, "ProfileCopyright", NULL}, - {TIFFTAG_FORWARDMATRIX1, -1, -1, TIFF_SRATIONAL, 0, TIFF_SETGET_C16_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 1, "ForwardMatrix1", NULL}, - {TIFFTAG_FORWARDMATRIX2, -1, -1, TIFF_SRATIONAL, 0, TIFF_SETGET_C16_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 1, "ForwardMatrix2", NULL}, - {TIFFTAG_PREVIEWAPPLICATIONNAME, -1, -1, TIFF_BYTE, 0, TIFF_SETGET_C16_UINT8, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 1, "PreviewApplicationName", NULL}, - {TIFFTAG_PREVIEWAPPLICATIONVERSION, -1, -1, TIFF_BYTE, 0, TIFF_SETGET_C16_UINT8, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 1, "PreviewApplicationVersion", NULL}, - {TIFFTAG_PREVIEWSETTINGSNAME, -1, -1, TIFF_BYTE, 0, TIFF_SETGET_C16_UINT8, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 1, "PreviewSettingsName", NULL}, - {TIFFTAG_PREVIEWSETTINGSDIGEST, 16, 16, TIFF_BYTE, 0, TIFF_SETGET_C0_UINT8, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "PreviewSettingsDigest", NULL}, - {TIFFTAG_PREVIEWCOLORSPACE, 1, 1, TIFF_LONG, 0, TIFF_SETGET_UINT32, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "PreviewColorSpace", NULL}, - {TIFFTAG_PREVIEWDATETIME, -1, -1, TIFF_ASCII, 0, TIFF_SETGET_ASCII, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "PreviewDateTime", NULL}, - {TIFFTAG_RAWIMAGEDIGEST, 16, 16, TIFF_BYTE, 0, TIFF_SETGET_C0_UINT8, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "RawImageDigest", NULL}, - {TIFFTAG_ORIGINALRAWFILEDIGEST, 16, 16, TIFF_BYTE, 0, TIFF_SETGET_C0_UINT8, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "OriginalRawFileDigest", NULL}, - {TIFFTAG_SUBTILEBLOCKSIZE, 2, 2, TIFF_LONG, 0, TIFF_SETGET_C0_UINT32, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "SubTileBlockSize", NULL}, - {TIFFTAG_ROWINTERLEAVEFACTOR, 1, 1, TIFF_LONG, 0, TIFF_SETGET_UINT32, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "RowInterleaveFactor", NULL}, - {TIFFTAG_PROFILELOOKTABLEDIMS, 3, 3, TIFF_LONG, 0, TIFF_SETGET_C0_UINT32, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "ProfileLookTableDims", NULL}, - {TIFFTAG_PROFILELOOKTABLEDATA, -1, -1, TIFF_FLOAT, 0, TIFF_SETGET_C16_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 1, "ProfileLookTableData", NULL}, - /* begin DNG 1.3.0.0 tags */ - {TIFFTAG_OPCODELIST1, -3, -3, TIFF_UNDEFINED, 0, TIFF_SETGET_C32_UINT8, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 1, "OpcodeList1", NULL}, - {TIFFTAG_OPCODELIST2, -3, -3, TIFF_UNDEFINED, 0, TIFF_SETGET_C32_UINT8, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 1, "OpcodeList2", NULL}, - {TIFFTAG_OPCODELIST3, -3, -3, TIFF_UNDEFINED, 0, TIFF_SETGET_C32_UINT8, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 1, "OpcodeList3", NULL}, - {TIFFTAG_NOISEPROFILE, -1, -1, TIFF_DOUBLE, 0, TIFF_SETGET_C16_DOUBLE, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 1, "NoiseProfile", NULL}, - /* begin DNG 1.4.0.0 tags */ - {TIFFTAG_DEFAULTUSERCROP, 4, 4, TIFF_RATIONAL, 0, TIFF_SETGET_C0_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "DefaultUserCrop", NULL}, - {TIFFTAG_DEFAULTBLACKRENDER, 1, 1, TIFF_LONG, 0, TIFF_SETGET_UINT32, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "DefaultBlackRender", NULL}, - {TIFFTAG_BASELINEEXPOSUREOFFSET, 1, 1, TIFF_RATIONAL, 0, TIFF_SETGET_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "BaselineExposureOffset", NULL}, - {TIFFTAG_PROFILELOOKTABLEENCODING, 1, 1, TIFF_LONG, 0, TIFF_SETGET_UINT32, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "ProfileLookTableEncoding", NULL}, - {TIFFTAG_PROFILEHUESATMAPENCODING, 1, 1, TIFF_LONG, 0, TIFF_SETGET_UINT32, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "ProfileHueSatMapEncoding", NULL}, - {TIFFTAG_ORIGINALDEFAULTFINALSIZE, 2, 2, TIFF_LONG, 0, TIFF_SETGET_C0_UINT32, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "OriginalDefaultFinalSize", NULL}, - {TIFFTAG_ORIGINALBESTQUALITYFINALSIZE, 2, 2, TIFF_LONG, 0, TIFF_SETGET_C0_UINT32, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "OriginalBestQualityFinalSize", NULL}, - {TIFFTAG_ORIGINALDEFAULTCROPSIZE, 2, 2, TIFF_RATIONAL, 0, TIFF_SETGET_C0_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "OriginalDefaultCropSize", NULL}, /* could also be rational */ - {TIFFTAG_NEWRAWIMAGEDIGEST, 16, 16, TIFF_BYTE, 0, TIFF_SETGET_C0_UINT8, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "NewRawImageDigest", NULL}, - {TIFFTAG_RAWTOPREVIEWGAIN, 1, 1, TIFF_DOUBLE, 0, TIFF_SETGET_DOUBLE, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "RawToPreviewGain", NULL}, - /* begin DNG 1.5.0.0 tags */ - {TIFFTAG_DEPTHFORMAT, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "DepthFormat", NULL}, - {TIFFTAG_DEPTHNEAR, 1, 1, TIFF_RATIONAL, 0, TIFF_SETGET_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "DepthNear", NULL}, - {TIFFTAG_DEPTHFAR, 1, 1, TIFF_RATIONAL, 0, TIFF_SETGET_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "DepthFar", NULL}, - {TIFFTAG_DEPTHUNITS, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "DepthUnits", NULL}, - {TIFFTAG_DEPTHMEASURETYPE, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "DepthMeasureType", NULL}, - {TIFFTAG_ENHANCEPARAMS, -1, -1, TIFF_ASCII, 0, TIFF_SETGET_ASCII, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "EnhanceParams", NULL}, - /* begin DNG 1.6.0.0 tags */ - {TIFFTAG_PROFILEGAINTABLEMAP, -3, -3, TIFF_UNDEFINED, 0, TIFF_SETGET_C32_UINT8, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 1, "ProfileGainTableMap", NULL}, - {TIFFTAG_SEMANTICNAME, -1, -1, TIFF_ASCII, 0, TIFF_SETGET_ASCII, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "SemanticName", NULL}, - {TIFFTAG_SEMANTICINSTANCEID, -1, -1, TIFF_ASCII, 0, TIFF_SETGET_ASCII, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "SemanticInstanceID", NULL}, - {TIFFTAG_MASKSUBAREA, 4, 4, TIFF_LONG, 0, TIFF_SETGET_C0_UINT32, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "MaskSubArea", NULL}, - {TIFFTAG_RGBTABLES, -3, -3, TIFF_UNDEFINED, 0, TIFF_SETGET_C32_UINT8, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 1, "RGBTables", NULL}, - {TIFFTAG_CALIBRATIONILLUMINANT3, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "CalibrationIlluminant3", NULL}, - {TIFFTAG_COLORMATRIX3, -1, -1, TIFF_SRATIONAL, 0, TIFF_SETGET_C16_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 1, "ColorMatrix3", NULL}, - {TIFFTAG_CAMERACALIBRATION3, -1, -1, TIFF_SRATIONAL, 0, TIFF_SETGET_C16_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 1, "CameraCalibration3", NULL}, - {TIFFTAG_REDUCTIONMATRIX3, -1, -1, TIFF_SRATIONAL, 0, TIFF_SETGET_C16_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 1, "ReductionMatrix3", NULL}, - {TIFFTAG_PROFILEHUESATMAPDATA3, -1, -1, TIFF_FLOAT, 0, TIFF_SETGET_C16_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 1, "ProfileHueSatMapData3", NULL}, - {TIFFTAG_FORWARDMATRIX3, -1, -1, TIFF_SRATIONAL, 0, TIFF_SETGET_C16_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 1, "ForwardMatrix3", NULL}, - {TIFFTAG_ILLUMINANTDATA1, -3, -3, TIFF_UNDEFINED, 0, TIFF_SETGET_C32_UINT8, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 1, "IlluminantData1", NULL}, - {TIFFTAG_ILLUMINANTDATA2, -3, -3, TIFF_UNDEFINED, 0, TIFF_SETGET_C32_UINT8, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 1, "IlluminantData2", NULL}, - {TIFFTAG_ILLUMINANTDATA3, -3, -3, TIFF_UNDEFINED, 0, TIFF_SETGET_C32_UINT8, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 1, "IlluminantData3", NULL}, - /* end DNG tags */ - /* begin TIFF/EP tags */ - {TIFFTAG_EP_CFAREPEATPATTERNDIM, 2, 2, TIFF_SHORT, 0, TIFF_SETGET_C0_UINT16, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "EP CFARepeatPatternDim", NULL}, - {TIFFTAG_EP_CFAPATTERN, -1, -1, TIFF_BYTE, 0, TIFF_SETGET_C16_UINT8, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 1, "EP CFAPattern", NULL}, - /* TIFFTAG_EP_BATTERYLEVEL can be RATIONAL or ASCII. - * LibTiff defines it as ASCII and converts RATIONAL to an ASCII string. */ - {TIFFTAG_EP_BATTERYLEVEL, -1, -1, TIFF_ASCII, 0, TIFF_SETGET_ASCII, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "EP BatteryLevel", NULL}, - {TIFFTAG_EP_INTERLACE, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "EP Interlace", NULL}, - /* TIFFTAG_EP_IPTC_NAA and TIFFTAG_RICHTIFFIPTC share the same tag number (33723) - * LibTIFF type is UNDEFINED or BYTE, but often times incorrectly specified as LONG, because TIFF/EP (ISO/DIS 12234-2) specifies type LONG or ASCII. */ - {TIFFTAG_EP_TIMEZONEOFFSET, -1, -1, TIFF_SSHORT, 0, TIFF_SETGET_C16_UINT16, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 1, "EP TimeZoneOffset", NULL}, - {TIFFTAG_EP_SELFTIMERMODE, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "EP SelfTimerMode", NULL}, - {TIFFTAG_EP_FLASHENERGY, -1, -1, TIFF_RATIONAL, 0, TIFF_SETGET_C16_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 1, "EP FlashEnergy", NULL}, - {TIFFTAG_EP_SPATIALFREQUENCYRESPONSE, -3, -3, TIFF_UNDEFINED, 0, TIFF_SETGET_C32_UINT8, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 1, "EP SpatialFrequencyResponse", NULL}, - {TIFFTAG_EP_NOISE, -3, -3, TIFF_UNDEFINED, 0, TIFF_SETGET_C32_UINT8, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 1, "EP Noise", NULL}, - {TIFFTAG_EP_FOCALPLANEXRESOLUTION, 1, 1, TIFF_RATIONAL, 0, TIFF_SETGET_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "EP FocalPlaneXResolution", NULL}, - {TIFFTAG_EP_FOCALPLANEYRESOLUTION, 1, 1, TIFF_RATIONAL, 0, TIFF_SETGET_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "EP FocalPlaneYResolution", NULL}, - {TIFFTAG_EP_FOCALPLANERESOLUTIONUNIT, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "EP FocalPlaneResolutionUnit", NULL}, - {TIFFTAG_EP_IMAGENUMBER, 1, 1, TIFF_LONG, 0, TIFF_SETGET_UINT32, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "EP ImageNumber", NULL}, /* or SHORT */ - {TIFFTAG_EP_SECURITYCLASSIFICATION, -1, -1, TIFF_ASCII, 0, TIFF_SETGET_ASCII, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "EP SecurityClassification", NULL}, - {TIFFTAG_EP_IMAGEHISTORY, -1, -1, TIFF_ASCII, 0, TIFF_SETGET_ASCII, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "EP ImageHistory", NULL}, - {TIFFTAG_EP_EXPOSUREINDEX, -1, -1, TIFF_RATIONAL, 0, TIFF_SETGET_C16_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 1, "EP ExposureIndex", NULL}, - {TIFFTAG_EP_STANDARDID, 4, 4, TIFF_BYTE, 0, TIFF_SETGET_C0_UINT8, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "EP StandardId", NULL}, - {TIFFTAG_EP_SENSINGMETHOD, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "EP SensingMethod", NULL}, - /* TIFF/EP tags equivalent to EXIF tags, sometimes defined differently. */ - {TIFFTAG_EP_EXPOSURETIME, -1, -1, TIFF_RATIONAL, 0, TIFF_SETGET_C16_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 1, "EP ExposureTime", NULL}, /*N=1 or 2 */ - {TIFFTAG_EP_FNUMBER, -1, -1, TIFF_RATIONAL, 0, TIFF_SETGET_C16_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 1, "EP FNumber", NULL}, - {TIFFTAG_EP_EXPOSUREPROGRAM, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "EP ExposureProgram", NULL}, - {TIFFTAG_EP_SPECTRALSENSITIVITY, -1, -1, TIFF_ASCII, 0, TIFF_SETGET_ASCII, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "EP SpectralSensitivity", NULL}, - {TIFFTAG_EP_ISOSPEEDRATINGS, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "EP ISOSpeedRatings", NULL}, - {TIFFTAG_EP_OECF, -3, -3, TIFF_UNDEFINED, 0, TIFF_SETGET_C32_UINT8, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 1, "EP OptoelectricConversionFactor", NULL}, - {TIFFTAG_EP_DATETIMEORIGINAL, 20, 20, TIFF_ASCII, 0, TIFF_SETGET_ASCII, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "EP DateTimeOriginal", NULL}, - {TIFFTAG_EP_COMPRESSEDBITSPERPIXEL, 1, 1, TIFF_RATIONAL, 0, TIFF_SETGET_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "EP CompressedBitsPerPixel", NULL}, - {TIFFTAG_EP_SHUTTERSPEEDVALUE, 1, 1, TIFF_SRATIONAL, 0, TIFF_SETGET_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "EP ShutterSpeedValue", NULL}, - {TIFFTAG_EP_APERTUREVALUE, 1, 1, TIFF_RATIONAL, 0, TIFF_SETGET_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "EP ApertureValue", NULL}, - {TIFFTAG_EP_BRIGHTNESSVALUE, -1, -1, TIFF_SRATIONAL, 0, TIFF_SETGET_C16_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 1, "EP BrightnessValue", NULL}, - {TIFFTAG_EP_EXPOSUREBIASVALUE, -1, -1, TIFF_SRATIONAL, 0, TIFF_SETGET_C16_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 1, "EP ExposureBiasValue", NULL}, /*N=1 or 2 */ - {TIFFTAG_EP_MAXAPERTUREVALUE, 1, 1, TIFF_RATIONAL, 0, TIFF_SETGET_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "EP MaxApertureValue", NULL}, - {TIFFTAG_EP_SUBJECTDISTANCE, -1, -1, TIFF_SRATIONAL, 0, TIFF_SETGET_C16_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 1, "EP SubjectDistance", NULL}, - {TIFFTAG_EP_METERINGMODE, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "EP MeteringMode", NULL}, - {TIFFTAG_EP_LIGHTSOURCE, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "EP LightSource", NULL}, - {TIFFTAG_EP_FLASH, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "EP Flash", NULL}, - {TIFFTAG_EP_FOCALLENGTH, -1, -1, TIFF_RATIONAL, 0, TIFF_SETGET_C16_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 1, "EP FocalLength", NULL}, - {TIFFTAG_EP_SUBJECTLOCATION, -1, -1, TIFF_SHORT, 0, TIFF_SETGET_C16_UINT16, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 1, "EP SubjectLocation", NULL}, - /* end TIFF/EP tags */ -#endif - /* begin TIFF/FX tags */ - {TIFFTAG_INDEXED, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "Indexed", NULL}, - {TIFFTAG_GLOBALPARAMETERSIFD, 1, 1, TIFF_IFD8, 0, TIFF_SETGET_IFD8, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "GlobalParametersIFD", NULL}, - {TIFFTAG_PROFILETYPE, 1, 1, TIFF_LONG, 0, TIFF_SETGET_UINT32, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "ProfileType", NULL}, - {TIFFTAG_FAXPROFILE, 1, 1, TIFF_BYTE, 0, TIFF_SETGET_UINT8, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "FaxProfile", NULL}, - {TIFFTAG_CODINGMETHODS, 1, 1, TIFF_LONG, 0, TIFF_SETGET_UINT32, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "CodingMethods", NULL}, - {TIFFTAG_VERSIONYEAR, 4, 4, TIFF_BYTE, 0, TIFF_SETGET_C0_UINT8, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "VersionYear", NULL}, - {TIFFTAG_MODENUMBER, 1, 1, TIFF_BYTE, 0, TIFF_SETGET_UINT8, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "ModeNumber", NULL}, - {TIFFTAG_DECODE, -1, -1, TIFF_SRATIONAL, 0, TIFF_SETGET_C16_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 1, "Decode", NULL}, - {TIFFTAG_IMAGEBASECOLOR, -1, -1, TIFF_SHORT, 0, TIFF_SETGET_C16_UINT16, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 1, "ImageBaseColor", NULL}, - {TIFFTAG_T82OPTIONS, 1, 1, TIFF_LONG, 0, TIFF_SETGET_UINT32, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "T82Options", NULL}, - {TIFFTAG_STRIPROWCOUNTS, -1, -1, TIFF_LONG, 0, TIFF_SETGET_C16_UINT32, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 1, "StripRowCounts", NULL}, - {TIFFTAG_IMAGELAYER, 2, 2, TIFF_LONG, 0, TIFF_SETGET_C0_UINT32, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "ImageLayer", NULL}, - /* end TIFF/FX tags */ - /* begin pseudo tags */ -}; - -/* - * EXIF tags (Version 2.31, July 2016 plus version 2.32 May 2019) - */ -static const TIFFField exifFields[] = { - {EXIFTAG_EXPOSURETIME, 1, 1, TIFF_RATIONAL, 0, TIFF_SETGET_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "ExposureTime", NULL}, - {EXIFTAG_FNUMBER, 1, 1, TIFF_RATIONAL, 0, TIFF_SETGET_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "FNumber", NULL}, - {EXIFTAG_EXPOSUREPROGRAM, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "ExposureProgram", NULL}, - {EXIFTAG_SPECTRALSENSITIVITY, -1, -1, TIFF_ASCII, 0, TIFF_SETGET_ASCII, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "SpectralSensitivity", NULL}, - /* After EXIF 2.2.1 ISOSpeedRatings is named PhotographicSensitivity. In addition, while "Count=Any", only 1 count should be used. */ - {EXIFTAG_ISOSPEEDRATINGS, -1, -1, TIFF_SHORT, 0, TIFF_SETGET_C16_UINT16, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 1, "ISOSpeedRatings", NULL}, - {EXIFTAG_OECF, -1, -1, TIFF_UNDEFINED, 0, TIFF_SETGET_C16_UINT8, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 1, "OptoelectricConversionFactor", NULL}, - {EXIFTAG_SENSITIVITYTYPE, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "SensitivityType", NULL}, - {EXIFTAG_STANDARDOUTPUTSENSITIVITY, 1, 1, TIFF_LONG, 0, TIFF_SETGET_UINT32, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "StandardOutputSensitivity", NULL}, - {EXIFTAG_RECOMMENDEDEXPOSUREINDEX, 1, 1, TIFF_LONG, 0, TIFF_SETGET_UINT32, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "RecommendedExposureIndex", NULL}, - {EXIFTAG_ISOSPEED, 1, 1, TIFF_LONG, 0, TIFF_SETGET_UINT32, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "ISOSpeed", NULL}, - {EXIFTAG_ISOSPEEDLATITUDEYYY, 1, 1, TIFF_LONG, 0, TIFF_SETGET_UINT32, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "ISOSpeedLatitudeyyy", NULL}, - {EXIFTAG_ISOSPEEDLATITUDEZZZ, 1, 1, TIFF_LONG, 0, TIFF_SETGET_UINT32, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "ISOSpeedLatitudezzz", NULL}, - {EXIFTAG_EXIFVERSION, 4, 4, TIFF_UNDEFINED, 0, TIFF_SETGET_C0_UINT8, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "ExifVersion", NULL}, - {EXIFTAG_DATETIMEORIGINAL, 20, 20, TIFF_ASCII, 0, TIFF_SETGET_ASCII, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "DateTimeOriginal", NULL}, - {EXIFTAG_DATETIMEDIGITIZED, 20, 20, TIFF_ASCII, 0, TIFF_SETGET_ASCII, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "DateTimeDigitized", NULL}, - {EXIFTAG_OFFSETTIME, 7, 7, TIFF_ASCII, 0, TIFF_SETGET_ASCII, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "OffsetTime", NULL}, - {EXIFTAG_OFFSETTIMEORIGINAL, 7, 7, TIFF_ASCII, 0, TIFF_SETGET_ASCII, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "OffsetTimeOriginal", NULL}, - {EXIFTAG_OFFSETTIMEDIGITIZED, 7, 7, TIFF_ASCII, 0, TIFF_SETGET_ASCII, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "OffsetTimeDigitized", NULL}, - {EXIFTAG_COMPONENTSCONFIGURATION, 4, 4, TIFF_UNDEFINED, 0, TIFF_SETGET_C0_UINT8, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "ComponentsConfiguration", NULL}, - {EXIFTAG_COMPRESSEDBITSPERPIXEL, 1, 1, TIFF_RATIONAL, 0, TIFF_SETGET_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "CompressedBitsPerPixel", NULL}, - {EXIFTAG_SHUTTERSPEEDVALUE, 1, 1, TIFF_SRATIONAL, 0, TIFF_SETGET_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "ShutterSpeedValue", NULL}, - {EXIFTAG_APERTUREVALUE, 1, 1, TIFF_RATIONAL, 0, TIFF_SETGET_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "ApertureValue", NULL}, - {EXIFTAG_BRIGHTNESSVALUE, 1, 1, TIFF_SRATIONAL, 0, TIFF_SETGET_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "BrightnessValue", NULL}, - {EXIFTAG_EXPOSUREBIASVALUE, 1, 1, TIFF_SRATIONAL, 0, TIFF_SETGET_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "ExposureBiasValue", NULL}, - {EXIFTAG_MAXAPERTUREVALUE, 1, 1, TIFF_RATIONAL, 0, TIFF_SETGET_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "MaxApertureValue", NULL}, - /*--: EXIFTAG_SUBJECTDISTANCE: LibTiff returns value of "-1" if numerator equals 4294967295 (0xFFFFFFFF) to indicate infinite distance! - * However, there are two other EXIF tags where numerator indicates a special value and six other cases where the denominator indicates special values, - * which are not treated within LibTiff!! */ - {EXIFTAG_SUBJECTDISTANCE, 1, 1, TIFF_RATIONAL, 0, TIFF_SETGET_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "SubjectDistance", NULL}, - {EXIFTAG_METERINGMODE, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "MeteringMode", NULL}, - {EXIFTAG_LIGHTSOURCE, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "LightSource", NULL}, - {EXIFTAG_FLASH, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "Flash", NULL}, - {EXIFTAG_FOCALLENGTH, 1, 1, TIFF_RATIONAL, 0, TIFF_SETGET_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "FocalLength", NULL}, - {EXIFTAG_SUBJECTAREA, -1, -1, TIFF_SHORT, 0, TIFF_SETGET_C16_UINT16, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 1, "SubjectArea", NULL}, - {EXIFTAG_MAKERNOTE, -1, -1, TIFF_UNDEFINED, 0, TIFF_SETGET_C16_UINT8, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 1, "MakerNote", NULL}, - {EXIFTAG_USERCOMMENT, -1, -1, TIFF_UNDEFINED, 0, TIFF_SETGET_C16_UINT8, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 1, "UserComment", NULL}, - {EXIFTAG_SUBSECTIME, -1, -1, TIFF_ASCII, 0, TIFF_SETGET_ASCII, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "SubSecTime", NULL}, - {EXIFTAG_SUBSECTIMEORIGINAL, -1, -1, TIFF_ASCII, 0, TIFF_SETGET_ASCII, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "SubSecTimeOriginal", NULL}, - {EXIFTAG_SUBSECTIMEDIGITIZED, -1, -1, TIFF_ASCII, 0, TIFF_SETGET_ASCII, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "SubSecTimeDigitized", NULL}, - {EXIFTAG_TEMPERATURE, 1, 1, TIFF_SRATIONAL, 0, TIFF_SETGET_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "Temperature", NULL}, - {EXIFTAG_HUMIDITY, 1, 1, TIFF_RATIONAL, 0, TIFF_SETGET_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "Humidity", NULL}, - {EXIFTAG_PRESSURE, 1, 1, TIFF_RATIONAL, 0, TIFF_SETGET_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "Pressure", NULL}, - {EXIFTAG_WATERDEPTH, 1, 1, TIFF_SRATIONAL, 0, TIFF_SETGET_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "WaterDepth", NULL}, - {EXIFTAG_ACCELERATION, 1, 1, TIFF_RATIONAL, 0, TIFF_SETGET_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "Acceleration", NULL}, - {EXIFTAG_CAMERAELEVATIONANGLE, 1, 1, TIFF_SRATIONAL, 0, TIFF_SETGET_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "CameraElevationAngle", NULL}, - {EXIFTAG_FLASHPIXVERSION, 4, 4, TIFF_UNDEFINED, 0, TIFF_SETGET_C0_UINT8, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "FlashpixVersion", NULL}, - {EXIFTAG_COLORSPACE, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "ColorSpace", NULL}, - {EXIFTAG_PIXELXDIMENSION, 1, 1, TIFF_LONG, 0, TIFF_SETGET_UINT32, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "PixelXDimension", NULL}, - {EXIFTAG_PIXELYDIMENSION, 1, 1, TIFF_LONG, 0, TIFF_SETGET_UINT32, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "PixelYDimension", NULL}, - {EXIFTAG_RELATEDSOUNDFILE, 13, 13, TIFF_ASCII, 0, TIFF_SETGET_ASCII, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "RelatedSoundFile", NULL}, - {EXIFTAG_FLASHENERGY, 1, 1, TIFF_RATIONAL, 0, TIFF_SETGET_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "FlashEnergy", NULL}, - {EXIFTAG_SPATIALFREQUENCYRESPONSE, -1, -1, TIFF_UNDEFINED, 0, TIFF_SETGET_C16_UINT8, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 1, "SpatialFrequencyResponse", NULL}, - {EXIFTAG_FOCALPLANEXRESOLUTION, 1, 1, TIFF_RATIONAL, 0, TIFF_SETGET_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "FocalPlaneXResolution", NULL}, - {EXIFTAG_FOCALPLANEYRESOLUTION, 1, 1, TIFF_RATIONAL, 0, TIFF_SETGET_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "FocalPlaneYResolution", NULL}, - {EXIFTAG_FOCALPLANERESOLUTIONUNIT, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "FocalPlaneResolutionUnit", NULL}, - {EXIFTAG_SUBJECTLOCATION, 2, 2, TIFF_SHORT, 0, TIFF_SETGET_C0_UINT16, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "SubjectLocation", NULL}, - {EXIFTAG_EXPOSUREINDEX, 1, 1, TIFF_RATIONAL, 0, TIFF_SETGET_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "ExposureIndex", NULL}, - {EXIFTAG_SENSINGMETHOD, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "SensingMethod", NULL}, - {EXIFTAG_FILESOURCE, 1, 1, TIFF_UNDEFINED, 0, TIFF_SETGET_UINT8, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "FileSource", NULL}, - {EXIFTAG_SCENETYPE, 1, 1, TIFF_UNDEFINED, 0, TIFF_SETGET_UINT8, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "SceneType", NULL}, - {EXIFTAG_CFAPATTERN, -1, -1, TIFF_UNDEFINED, 0, TIFF_SETGET_C16_UINT8, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 1, "CFAPattern", NULL}, - {EXIFTAG_CUSTOMRENDERED, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "CustomRendered", NULL}, - {EXIFTAG_EXPOSUREMODE, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "ExposureMode", NULL}, - {EXIFTAG_WHITEBALANCE, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "WhiteBalance", NULL}, - {EXIFTAG_DIGITALZOOMRATIO, 1, 1, TIFF_RATIONAL, 0, TIFF_SETGET_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "DigitalZoomRatio", NULL}, - {EXIFTAG_FOCALLENGTHIN35MMFILM, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "FocalLengthIn35mmFilm", NULL}, - {EXIFTAG_SCENECAPTURETYPE, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "SceneCaptureType", NULL}, - {EXIFTAG_GAINCONTROL, 1, 1, TIFF_RATIONAL, 0, TIFF_SETGET_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "GainControl", NULL}, - {EXIFTAG_CONTRAST, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "Contrast", NULL}, - {EXIFTAG_SATURATION, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "Saturation", NULL}, - {EXIFTAG_SHARPNESS, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "Sharpness", NULL}, - {EXIFTAG_DEVICESETTINGDESCRIPTION, -1, -1, TIFF_UNDEFINED, 0, TIFF_SETGET_C16_UINT8, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 1, "DeviceSettingDescription", NULL}, - {EXIFTAG_SUBJECTDISTANCERANGE, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "SubjectDistanceRange", NULL}, - {EXIFTAG_IMAGEUNIQUEID, 33, 33, TIFF_ASCII, 0, TIFF_SETGET_ASCII, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "ImageUniqueID", NULL}, - {EXIFTAG_CAMERAOWNERNAME, -1, -1, TIFF_ASCII, 0, TIFF_SETGET_ASCII, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "CameraOwnerName", NULL}, - {EXIFTAG_BODYSERIALNUMBER, -1, -1, TIFF_ASCII, 0, TIFF_SETGET_ASCII, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "BodySerialNumber", NULL}, - {EXIFTAG_LENSSPECIFICATION, 4, 4, TIFF_RATIONAL, 0, TIFF_SETGET_C0_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "LensSpecification", NULL}, - {EXIFTAG_LENSMAKE, -1, -1, TIFF_ASCII, 0, TIFF_SETGET_ASCII, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "LensMake", NULL}, - {EXIFTAG_LENSMODEL, -1, -1, TIFF_ASCII, 0, TIFF_SETGET_ASCII, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "LensModel", NULL}, - {EXIFTAG_LENSSERIALNUMBER, -1, -1, TIFF_ASCII, 0, TIFF_SETGET_ASCII, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "LensSerialNumber", NULL}, - {EXIFTAG_GAMMA, 1, 1, TIFF_RATIONAL, 0, TIFF_SETGET_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "Gamma", NULL}, - {EXIFTAG_COMPOSITEIMAGE, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "CompositeImage", NULL}, - {EXIFTAG_SOURCEIMAGENUMBEROFCOMPOSITEIMAGE, 2, 2, TIFF_SHORT, 0, TIFF_SETGET_C0_UINT16, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "SourceImageNumberOfCompositeImage", NULL}, - {EXIFTAG_SOURCEEXPOSURETIMESOFCOMPOSITEIMAGE, -1, -1, TIFF_UNDEFINED, 0, TIFF_SETGET_C16_UINT8, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 1, - "SourceExposureTimesOfCompositeImage", NULL}}; -/* - * EXIF-GPS tags (Version 2.31, July 2016; nothing changed for version 2.32 May - * 2019) - */ - -static const TIFFField gpsFields[] = { - /* For the GPS tag definitions in gpsFields[] the standard definition for Rationals is TIFF_SETGET_DOUBLE and TIFF_SETGET_C0_FLOAT. - *-- ATTENTION: After the upgrade with Rational2Double, the GPSTAG values can now be written and also read in double precision! - * In order to achieve double precision for GPS tags: Standard definitions for GPSTAG is kept to TIFF_SETGET_DOUBLE - * and TIFF_SETGET_C0_FLOAT is changed to TIFF_SETGET_C0_DOUBLE. - */ - {GPSTAG_VERSIONID, 4, 4, TIFF_BYTE, 0, TIFF_SETGET_C0_UINT8, TIFF_SETGET_UINT8, FIELD_CUSTOM, 1, 0, "VersionID", NULL}, - {GPSTAG_LATITUDEREF, 2, 2, TIFF_ASCII, 0, TIFF_SETGET_ASCII, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "LatitudeRef", NULL}, - {GPSTAG_LATITUDE, 3, 3, TIFF_RATIONAL, 0, TIFF_SETGET_C0_DOUBLE, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "Latitude", NULL}, - {GPSTAG_LONGITUDEREF, 2, 2, TIFF_ASCII, 0, TIFF_SETGET_ASCII, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "LongitudeRef", NULL}, - {GPSTAG_LONGITUDE, 3, 3, TIFF_RATIONAL, 0, TIFF_SETGET_C0_DOUBLE, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "Longitude", NULL}, - {GPSTAG_ALTITUDEREF, 1, 1, TIFF_BYTE, 0, TIFF_SETGET_UINT8, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "AltitudeRef", NULL}, - {GPSTAG_ALTITUDE, 1, 1, TIFF_RATIONAL, 0, TIFF_SETGET_DOUBLE, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "Altitude", NULL}, - {GPSTAG_TIMESTAMP, 3, 3, TIFF_RATIONAL, 0, TIFF_SETGET_C0_DOUBLE, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "TimeStamp", NULL}, - {GPSTAG_SATELLITES, -1, -1, TIFF_ASCII, 0, TIFF_SETGET_ASCII, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "Satellites", NULL}, - {GPSTAG_STATUS, 2, 2, TIFF_ASCII, 0, TIFF_SETGET_ASCII, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "Status", NULL}, - {GPSTAG_MEASUREMODE, 2, 2, TIFF_ASCII, 0, TIFF_SETGET_ASCII, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "MeasureMode", NULL}, - {GPSTAG_DOP, 1, 1, TIFF_RATIONAL, 0, TIFF_SETGET_DOUBLE, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "DOP", NULL}, - {GPSTAG_SPEEDREF, 2, 2, TIFF_ASCII, 0, TIFF_SETGET_ASCII, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "SpeedRef", NULL}, - {GPSTAG_SPEED, 1, 1, TIFF_RATIONAL, 0, TIFF_SETGET_DOUBLE, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "Speed", NULL}, - {GPSTAG_TRACKREF, 2, 2, TIFF_ASCII, 0, TIFF_SETGET_ASCII, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "TrackRef", NULL}, - {GPSTAG_TRACK, 1, 1, TIFF_RATIONAL, 0, TIFF_SETGET_DOUBLE, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "Track", NULL}, - {GPSTAG_IMGDIRECTIONREF, 2, 2, TIFF_ASCII, 0, TIFF_SETGET_ASCII, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "ImgDirectionRef", NULL}, - {GPSTAG_IMGDIRECTION, 1, 1, TIFF_RATIONAL, 0, TIFF_SETGET_DOUBLE, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "ImgDirection", NULL}, - {GPSTAG_MAPDATUM, -1, -1, TIFF_ASCII, 0, TIFF_SETGET_ASCII, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "MapDatum", NULL}, - {GPSTAG_DESTLATITUDEREF, 2, 2, TIFF_ASCII, 0, TIFF_SETGET_ASCII, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "DestLatitudeRef", NULL}, - {GPSTAG_DESTLATITUDE, 3, 3, TIFF_RATIONAL, 0, TIFF_SETGET_C0_DOUBLE, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "DestLatitude", NULL}, - {GPSTAG_DESTLONGITUDEREF, 2, 2, TIFF_ASCII, 0, TIFF_SETGET_ASCII, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "DestLongitudeRef", NULL}, - {GPSTAG_DESTLONGITUDE, 3, 3, TIFF_RATIONAL, 0, TIFF_SETGET_C0_DOUBLE, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "DestLongitude", NULL}, - {GPSTAG_DESTBEARINGREF, 2, 2, TIFF_ASCII, 0, TIFF_SETGET_ASCII, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "DestBearingRef", NULL}, - {GPSTAG_DESTBEARING, 1, 1, TIFF_RATIONAL, 0, TIFF_SETGET_DOUBLE, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "DestBearing", NULL}, - {GPSTAG_DESTDISTANCEREF, 2, 2, TIFF_ASCII, 0, TIFF_SETGET_ASCII, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "DestDistanceRef", NULL}, - {GPSTAG_DESTDISTANCE, 1, 1, TIFF_RATIONAL, 0, TIFF_SETGET_DOUBLE, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "DestDistance", NULL}, - {GPSTAG_PROCESSINGMETHOD, -1, -1, TIFF_UNDEFINED, 0, TIFF_SETGET_C16_UINT8, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 1, "ProcessingMethod", NULL}, - {GPSTAG_AREAINFORMATION, -1, -1, TIFF_UNDEFINED, 0, TIFF_SETGET_C16_UINT8, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 1, "AreaInformation", NULL}, - {GPSTAG_DATESTAMP, 11, 11, TIFF_ASCII, 0, TIFF_SETGET_ASCII, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "DateStamp", NULL}, - {GPSTAG_DIFFERENTIAL, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "Differential", NULL}, - {GPSTAG_GPSHPOSITIONINGERROR, 1, 1, TIFF_RATIONAL, 0, TIFF_SETGET_DOUBLE, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "HorizontalPositioningError", NULL}}; -/* clang-format on */ /* was off for better readability of tag comments */ - -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}; - -/* - * We have our own local lfind() equivalent to avoid subtle differences - * in types passed to lfind() on different systems. - */ - -static void *td_lfind(const void *key, const void *base, size_t *nmemb, - size_t size, int (*compar)(const void *, const void *)) -{ - char *element, *end; - - end = (char *)base + *nmemb * size; - for (element = (char *)base; element < end; element += size) - if (!compar(key, element)) /* key found */ - return element; - - return NULL; -} - -const TIFFFieldArray *_TIFFGetFields(void) { return (&tiffFieldArray); } - -const TIFFFieldArray *_TIFFGetExifFields(void) { return (&exifFieldArray); } - -const TIFFFieldArray *_TIFFGetGpsFields(void) { return (&gpsFieldArray); } - -void _TIFFSetupFields(TIFF *tif, const TIFFFieldArray *fieldarray) -{ - if (tif->tif_fields && tif->tif_nfields > 0) - { - uint32_t i; - - for (i = 0; i < tif->tif_nfields; i++) - { - TIFFField *fld = tif->tif_fields[i]; - if (fld->field_name != NULL) - { - if (fld->field_bit == FIELD_CUSTOM && TIFFFieldIsAnonymous(fld)) - { - _TIFFfreeExt(tif, 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(). - */ - _TIFFfreeExt(tif, fld); - } - } - } - - _TIFFfreeExt(tif, tif->tif_fields); - tif->tif_fields = NULL; - tif->tif_nfields = 0; - } - if (!_TIFFMergeFields(tif, fieldarray->fields, fieldarray->count)) - { - TIFFErrorExtR(tif, "_TIFFSetupFields", "Setting up field info failed"); - } -} - -static int tagCompare(const void *a, const void *b) -{ - const TIFFField *ta = *(const TIFFField **)a; - const TIFFField *tb = *(const TIFFField **)b; - /* NB: be careful of return values for 16-bit platforms */ - if (ta->field_tag != tb->field_tag) - return (int)ta->field_tag - (int)tb->field_tag; - else - return (ta->field_type == TIFF_ANY) - ? 0 - : ((int)tb->field_type - (int)ta->field_type); -} - -static int tagNameCompare(const void *a, const void *b) -{ - const TIFFField *ta = *(const TIFFField **)a; - const TIFFField *tb = *(const TIFFField **)b; - int ret = strcmp(ta->field_name, tb->field_name); - - if (ret) - return ret; - else - return (ta->field_type == TIFF_ANY) - ? 0 - : ((int)tb->field_type - (int)ta->field_type); -} - -int _TIFFMergeFields(TIFF *tif, const TIFFField info[], uint32_t n) -{ - static const char module[] = "_TIFFMergeFields"; - static const char reason[] = "for fields array"; - /* TIFFField** tp; */ - uint32_t i; - - tif->tif_foundfield = 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); - } - else - { - tif->tif_fields = - (TIFFField **)_TIFFCheckMalloc(tif, n, sizeof(TIFFField *), reason); - } - if (!tif->tif_fields) - { - TIFFErrorExtR(tif, module, "Failed to allocate fields array"); - return 0; - } - - /* tp = tif->tif_fields + tif->tif_nfields; */ - for (i = 0; i < n; i++) - { - const TIFFField *fip = TIFFFindField(tif, info[i].field_tag, TIFF_ANY); - - /* only add definitions that aren't already present */ - if (!fip) - { - tif->tif_fields[tif->tif_nfields] = (TIFFField *)(info + i); - tif->tif_nfields++; - } - } - - /* Sort the field info by tag number */ - qsort(tif->tif_fields, tif->tif_nfields, sizeof(TIFFField *), tagCompare); - - return n; -} - -void _TIFFPrintFieldInfo(TIFF *tif, FILE *fd) -{ - uint32_t i; - - fprintf(fd, "%s: \n", tif->tif_name); - 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", - (int)i, (unsigned long)fip->field_tag, fip->field_readcount, - fip->field_writecount, fip->field_type, fip->field_bit, - fip->field_oktochange ? "TRUE" : "FALSE", - fip->field_passcount ? "TRUE" : "FALSE", fip->field_name); - } -} - -/* - * Return size of TIFFDataType within TIFF-file in bytes - */ -int TIFFDataWidth(TIFFDataType type) -{ - switch (type) - { - case 0: /* nothing */ - case TIFF_BYTE: - case TIFF_ASCII: - case TIFF_SBYTE: - case TIFF_UNDEFINED: - return 1; - case TIFF_SHORT: - case TIFF_SSHORT: - return 2; - case TIFF_LONG: - case TIFF_SLONG: - case TIFF_FLOAT: - case TIFF_IFD: - return 4; - case TIFF_RATIONAL: - case TIFF_SRATIONAL: - case TIFF_DOUBLE: - case TIFF_LONG8: - case TIFF_SLONG8: - case TIFF_IFD8: - return 8; - default: - return 0; /* will return 0 for unknown types */ - } -} - -/* - * Return internal storage size of TIFFSetGetFieldType in bytes. - * TIFFSetField() and TIFFGetField() have to provide the parameter accordingly. - * Replaces internal functions _TIFFDataSize() and _TIFFSetGetFieldSize() - * with now extern available function TIFFFieldSetGetSize(). - */ -int TIFFFieldSetGetSize(const TIFFField *fip) -{ - /* - * TIFFSetField() and TIFFGetField() must provide the parameter accordingly - * to the definition of "set_field_type" of the tag definition in - * dir_info.c. This function returns the data size for that purpose. - * - * Furthermore, this data size is also used for the internal storage, - * even for TIFF_RATIONAL values for FIELD_CUSTOM, which are stored - * internally as 4-byte float, but some of them should be stored internally - * as 8-byte double, depending on the "set_field_type" _FLOAT_ or _DOUBLE_. - */ - if (fip == NULL) - return 0; - - switch (fip->set_field_type) - { - case TIFF_SETGET_UNDEFINED: - case TIFF_SETGET_ASCII: - case TIFF_SETGET_C0_ASCII: - case TIFF_SETGET_C16_ASCII: - case TIFF_SETGET_C32_ASCII: - case TIFF_SETGET_OTHER: - return 1; - case TIFF_SETGET_UINT8: - case TIFF_SETGET_SINT8: - case TIFF_SETGET_C0_UINT8: - case TIFF_SETGET_C0_SINT8: - case TIFF_SETGET_C16_UINT8: - case TIFF_SETGET_C16_SINT8: - case TIFF_SETGET_C32_UINT8: - case TIFF_SETGET_C32_SINT8: - return 1; - case TIFF_SETGET_UINT16: - case TIFF_SETGET_SINT16: - case TIFF_SETGET_C0_UINT16: - case TIFF_SETGET_C0_SINT16: - case TIFF_SETGET_C16_UINT16: - case TIFF_SETGET_C16_SINT16: - case TIFF_SETGET_C32_UINT16: - case TIFF_SETGET_C32_SINT16: - return 2; - case TIFF_SETGET_INT: - case TIFF_SETGET_UINT32: - case TIFF_SETGET_SINT32: - case TIFF_SETGET_FLOAT: - case TIFF_SETGET_UINT16_PAIR: - case TIFF_SETGET_C0_UINT32: - case TIFF_SETGET_C0_SINT32: - case TIFF_SETGET_C0_FLOAT: - case TIFF_SETGET_C16_UINT32: - case TIFF_SETGET_C16_SINT32: - case TIFF_SETGET_C16_FLOAT: - case TIFF_SETGET_C32_UINT32: - case TIFF_SETGET_C32_SINT32: - case TIFF_SETGET_C32_FLOAT: - return 4; - case TIFF_SETGET_UINT64: - case TIFF_SETGET_SINT64: - case TIFF_SETGET_DOUBLE: - case TIFF_SETGET_IFD8: - case TIFF_SETGET_C0_UINT64: - case TIFF_SETGET_C0_SINT64: - case TIFF_SETGET_C0_DOUBLE: - case TIFF_SETGET_C0_IFD8: - case TIFF_SETGET_C16_UINT64: - case TIFF_SETGET_C16_SINT64: - case TIFF_SETGET_C16_DOUBLE: - case TIFF_SETGET_C16_IFD8: - case TIFF_SETGET_C32_UINT64: - case TIFF_SETGET_C32_SINT64: - case TIFF_SETGET_C32_DOUBLE: - case TIFF_SETGET_C32_IFD8: - return 8; - default: - return 0; - } -} /*-- TIFFFieldSetGetSize() --- */ - -/* - * Return size of count parameter of TIFFSetField() and TIFFGetField() - * and also if it is required: 0=none, 2=uint16_t, 4=uint32_t - */ -int TIFFFieldSetGetCountSize(const TIFFField *fip) -{ - if (fip == NULL) - return 0; - - switch (fip->set_field_type) - { - case TIFF_SETGET_C16_ASCII: - case TIFF_SETGET_C16_UINT8: - case TIFF_SETGET_C16_SINT8: - case TIFF_SETGET_C16_UINT16: - case TIFF_SETGET_C16_SINT16: - case TIFF_SETGET_C16_UINT32: - case TIFF_SETGET_C16_SINT32: - case TIFF_SETGET_C16_FLOAT: - case TIFF_SETGET_C16_UINT64: - case TIFF_SETGET_C16_SINT64: - case TIFF_SETGET_C16_DOUBLE: - case TIFF_SETGET_C16_IFD8: - return 2; - case TIFF_SETGET_C32_ASCII: - case TIFF_SETGET_C32_UINT8: - case TIFF_SETGET_C32_SINT8: - case TIFF_SETGET_C32_UINT16: - case TIFF_SETGET_C32_SINT16: - case TIFF_SETGET_C32_UINT32: - case TIFF_SETGET_C32_SINT32: - case TIFF_SETGET_C32_FLOAT: - case TIFF_SETGET_C32_UINT64: - case TIFF_SETGET_C32_SINT64: - case TIFF_SETGET_C32_DOUBLE: - case TIFF_SETGET_C32_IFD8: - return 4; - default: - return 0; - } -} /*-- TIFFFieldSetGetCountSize() --- */ - -const TIFFField *TIFFFindField(TIFF *tif, uint32_t tag, TIFFDataType dt) -{ - TIFFField key = {0, 0, 0, TIFF_NOTYPE, 0, 0, 0, 0, 0, 0, NULL, NULL}; - TIFFField *pkey = &key; - const TIFFField **ret; - if (tif->tif_foundfield && tif->tif_foundfield->field_tag == tag && - (dt == TIFF_ANY || dt == tif->tif_foundfield->field_type)) - return tif->tif_foundfield; - - /* If we are invoked with no field information, then just return. */ - if (!tif->tif_fields) - return NULL; - - /* NB: use sorted search (e.g. binary search) */ - - key.field_tag = tag; - key.field_type = dt; - - ret = (const TIFFField **)bsearch(&pkey, tif->tif_fields, tif->tif_nfields, - sizeof(TIFFField *), tagCompare); - return tif->tif_foundfield = (ret ? *ret : NULL); -} - -static const TIFFField *_TIFFFindFieldByName(TIFF *tif, const char *field_name, - TIFFDataType dt) -{ - TIFFField key = {0, 0, 0, TIFF_NOTYPE, 0, 0, 0, 0, 0, 0, NULL, NULL}; - TIFFField *pkey = &key; - const TIFFField **ret; - if (tif->tif_foundfield && - streq(tif->tif_foundfield->field_name, field_name) && - (dt == TIFF_ANY || dt == tif->tif_foundfield->field_type)) - return (tif->tif_foundfield); - - /* If we are invoked with no field information, then just return. */ - if (!tif->tif_fields) - return NULL; - - /* NB: use linear search since list is sorted by key#, not name */ - - key.field_name = (char *)field_name; - key.field_type = dt; - - ret = - (const TIFFField **)td_lfind(&pkey, tif->tif_fields, &tif->tif_nfields, - sizeof(TIFFField *), tagNameCompare); - - return tif->tif_foundfield = (ret ? *ret : NULL); -} - -const TIFFField *TIFFFieldWithTag(TIFF *tif, uint32_t tag) -{ - const TIFFField *fip = TIFFFindField(tif, tag, TIFF_ANY); - if (!fip) - { - TIFFWarningExtR(tif, "TIFFFieldWithTag", "Warning, unknown tag 0x%x", - (unsigned int)tag); - } - return (fip); -} - -const TIFFField *TIFFFieldWithName(TIFF *tif, const char *field_name) -{ - const TIFFField *fip = _TIFFFindFieldByName(tif, field_name, TIFF_ANY); - if (!fip) - { - TIFFWarningExtR(tif, "TIFFFieldWithName", "Warning, unknown tag %s", - field_name); - } - return (fip); -} - -uint32_t TIFFFieldTag(const TIFFField *fip) { return fip->field_tag; } - -const char *TIFFFieldName(const TIFFField *fip) { return fip->field_name; } - -TIFFDataType TIFFFieldDataType(const TIFFField *fip) { return fip->field_type; } - -int TIFFFieldPassCount(const TIFFField *fip) { return fip->field_passcount; } - -int TIFFFieldReadCount(const TIFFField *fip) { return fip->field_readcount; } - -int TIFFFieldWriteCount(const TIFFField *fip) { return fip->field_writecount; } - -int TIFFFieldIsAnonymous(const TIFFField *fip) { return fip->field_anonymous; } - -const TIFFField *_TIFFFindOrRegisterField(TIFF *tif, uint32_t tag, - TIFFDataType dt) - -{ - const TIFFField *fld; - - fld = TIFFFindField(tif, tag, dt); - if (fld == NULL) - { - fld = _TIFFCreateAnonField(tif, tag, dt); - if (!_TIFFMergeFields(tif, fld, 1)) - return NULL; - } - - return fld; -} - -TIFFField *_TIFFCreateAnonField(TIFF *tif, uint32_t tag, - TIFFDataType field_type) -{ - TIFFField *fld; - (void)tif; - - fld = (TIFFField *)_TIFFmallocExt(tif, sizeof(TIFFField)); - if (fld == NULL) - return NULL; - _TIFFmemset(fld, 0, sizeof(TIFFField)); - - fld->field_tag = tag; - fld->field_readcount = TIFF_VARIABLE2; - fld->field_writecount = TIFF_VARIABLE2; - fld->field_type = field_type; - fld->field_anonymous = - 1; /* indicate that this is an anonymous / unknown tag */ - switch (field_type) - { - case TIFF_BYTE: - case TIFF_UNDEFINED: - fld->set_field_type = TIFF_SETGET_C32_UINT8; - fld->get_field_type = TIFF_SETGET_C32_UINT8; - break; - case TIFF_ASCII: - fld->set_field_type = TIFF_SETGET_C32_ASCII; - fld->get_field_type = TIFF_SETGET_C32_ASCII; - break; - case TIFF_SHORT: - fld->set_field_type = TIFF_SETGET_C32_UINT16; - fld->get_field_type = TIFF_SETGET_C32_UINT16; - break; - case TIFF_LONG: - fld->set_field_type = TIFF_SETGET_C32_UINT32; - fld->get_field_type = TIFF_SETGET_C32_UINT32; - break; - case TIFF_RATIONAL: - case TIFF_SRATIONAL: - case TIFF_FLOAT: - fld->set_field_type = TIFF_SETGET_C32_FLOAT; - fld->get_field_type = TIFF_SETGET_C32_FLOAT; - break; - case TIFF_SBYTE: - fld->set_field_type = TIFF_SETGET_C32_SINT8; - fld->get_field_type = TIFF_SETGET_C32_SINT8; - break; - case TIFF_SSHORT: - fld->set_field_type = TIFF_SETGET_C32_SINT16; - fld->get_field_type = TIFF_SETGET_C32_SINT16; - break; - case TIFF_SLONG: - fld->set_field_type = TIFF_SETGET_C32_SINT32; - fld->get_field_type = TIFF_SETGET_C32_SINT32; - break; - case TIFF_DOUBLE: - fld->set_field_type = TIFF_SETGET_C32_DOUBLE; - fld->get_field_type = TIFF_SETGET_C32_DOUBLE; - break; - case TIFF_IFD: - case TIFF_IFD8: - fld->set_field_type = TIFF_SETGET_C32_IFD8; - fld->get_field_type = TIFF_SETGET_C32_IFD8; - break; - case TIFF_LONG8: - fld->set_field_type = TIFF_SETGET_C32_UINT64; - fld->get_field_type = TIFF_SETGET_C32_UINT64; - break; - case TIFF_SLONG8: - fld->set_field_type = TIFF_SETGET_C32_SINT64; - fld->get_field_type = TIFF_SETGET_C32_SINT64; - break; - default: - fld->set_field_type = TIFF_SETGET_UNDEFINED; - fld->get_field_type = TIFF_SETGET_UNDEFINED; - break; - } - 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) - { - _TIFFfreeExt(tif, fld); - return NULL; - } - fld->field_subfields = NULL; - - /* - * note that this name is a special sign to TIFFClose() and - * _TIFFSetupFields() to free the field - * Update: - * This special sign is replaced by fld->field_anonymous flag. - */ - (void)snprintf(fld->field_name, 32, "Tag %d", (int)tag); - - return fld; -} - -/**************************************************************************** - * O B S O L E T E D I N T E R F A C E S - * - * Don't use this stuff in your applications, it may be removed in the future - * libtiff versions. - ****************************************************************************/ - -static TIFFSetGetFieldType _TIFFSetGetType(TIFFDataType type, short count, - unsigned char passcount) -{ - if (type == TIFF_ASCII && count == TIFF_VARIABLE && passcount == 0) - return TIFF_SETGET_ASCII; - - else if (count == 1 && passcount == 0) - { - switch (type) - { - case TIFF_BYTE: - case TIFF_UNDEFINED: - return TIFF_SETGET_UINT8; - case TIFF_ASCII: - return TIFF_SETGET_ASCII; - case TIFF_SHORT: - return TIFF_SETGET_UINT16; - case TIFF_LONG: - return TIFF_SETGET_UINT32; - case TIFF_RATIONAL: - case TIFF_SRATIONAL: - case TIFF_FLOAT: - return TIFF_SETGET_FLOAT; - case TIFF_SBYTE: - return TIFF_SETGET_SINT8; - case TIFF_SSHORT: - return TIFF_SETGET_SINT16; - case TIFF_SLONG: - return TIFF_SETGET_SINT32; - case TIFF_DOUBLE: - return TIFF_SETGET_DOUBLE; - case TIFF_IFD: - case TIFF_IFD8: - return TIFF_SETGET_IFD8; - case TIFF_LONG8: - return TIFF_SETGET_UINT64; - case TIFF_SLONG8: - return TIFF_SETGET_SINT64; - default: - return TIFF_SETGET_UNDEFINED; - } - } - - else if (count >= 1 && passcount == 0) - { - switch (type) - { - case TIFF_BYTE: - case TIFF_UNDEFINED: - return TIFF_SETGET_C0_UINT8; - case TIFF_ASCII: - return TIFF_SETGET_C0_ASCII; - case TIFF_SHORT: - return TIFF_SETGET_C0_UINT16; - case TIFF_LONG: - return TIFF_SETGET_C0_UINT32; - case TIFF_RATIONAL: - case TIFF_SRATIONAL: - case TIFF_FLOAT: - return TIFF_SETGET_C0_FLOAT; - case TIFF_SBYTE: - return TIFF_SETGET_C0_SINT8; - case TIFF_SSHORT: - return TIFF_SETGET_C0_SINT16; - case TIFF_SLONG: - return TIFF_SETGET_C0_SINT32; - case TIFF_DOUBLE: - return TIFF_SETGET_C0_DOUBLE; - case TIFF_IFD: - case TIFF_IFD8: - return TIFF_SETGET_C0_IFD8; - case TIFF_LONG8: - return TIFF_SETGET_C0_UINT64; - case TIFF_SLONG8: - return TIFF_SETGET_C0_SINT64; - default: - return TIFF_SETGET_UNDEFINED; - } - } - - else if (count == TIFF_VARIABLE && passcount == 1) - { - switch (type) - { - case TIFF_BYTE: - case TIFF_UNDEFINED: - return TIFF_SETGET_C16_UINT8; - case TIFF_ASCII: - return TIFF_SETGET_C16_ASCII; - case TIFF_SHORT: - return TIFF_SETGET_C16_UINT16; - case TIFF_LONG: - return TIFF_SETGET_C16_UINT32; - case TIFF_RATIONAL: - case TIFF_SRATIONAL: - case TIFF_FLOAT: - return TIFF_SETGET_C16_FLOAT; - case TIFF_SBYTE: - return TIFF_SETGET_C16_SINT8; - case TIFF_SSHORT: - return TIFF_SETGET_C16_SINT16; - case TIFF_SLONG: - return TIFF_SETGET_C16_SINT32; - case TIFF_DOUBLE: - return TIFF_SETGET_C16_DOUBLE; - case TIFF_IFD: - case TIFF_IFD8: - return TIFF_SETGET_C16_IFD8; - case TIFF_LONG8: - return TIFF_SETGET_C16_UINT64; - case TIFF_SLONG8: - return TIFF_SETGET_C16_SINT64; - default: - return TIFF_SETGET_UNDEFINED; - } - } - - else if (count == TIFF_VARIABLE2 && passcount == 1) - { - switch (type) - { - case TIFF_BYTE: - case TIFF_UNDEFINED: - return TIFF_SETGET_C32_UINT8; - case TIFF_ASCII: - return TIFF_SETGET_C32_ASCII; - case TIFF_SHORT: - return TIFF_SETGET_C32_UINT16; - case TIFF_LONG: - return TIFF_SETGET_C32_UINT32; - case TIFF_RATIONAL: - case TIFF_SRATIONAL: - case TIFF_FLOAT: - return TIFF_SETGET_C32_FLOAT; - case TIFF_SBYTE: - return TIFF_SETGET_C32_SINT8; - case TIFF_SSHORT: - return TIFF_SETGET_C32_SINT16; - case TIFF_SLONG: - return TIFF_SETGET_C32_SINT32; - case TIFF_DOUBLE: - return TIFF_SETGET_C32_DOUBLE; - case TIFF_IFD: - case TIFF_IFD8: - return TIFF_SETGET_C32_IFD8; - case TIFF_LONG8: - return TIFF_SETGET_C32_UINT64; - case TIFF_SLONG8: - return TIFF_SETGET_C32_SINT64; - default: - return TIFF_SETGET_UNDEFINED; - } - } - - return TIFF_SETGET_UNDEFINED; -} - -int TIFFMergeFieldInfo(TIFF *tif, const TIFFFieldInfo info[], uint32_t n) -{ - static const char module[] = "TIFFMergeFieldInfo"; - static const char reason[] = "for fields array"; - TIFFField *tp; - size_t nfields; - uint32_t i; - - if (tif->tif_nfieldscompat > 0) - { - tif->tif_fieldscompat = (TIFFFieldArray *)_TIFFCheckRealloc( - tif, tif->tif_fieldscompat, tif->tif_nfieldscompat + 1, - sizeof(TIFFFieldArray), reason); - } - else - { - tif->tif_fieldscompat = (TIFFFieldArray *)_TIFFCheckMalloc( - tif, 1, sizeof(TIFFFieldArray), reason); - } - if (!tif->tif_fieldscompat) - { - TIFFErrorExtR(tif, module, "Failed to allocate fields array"); - return -1; - } - nfields = tif->tif_nfieldscompat++; - - tif->tif_fieldscompat[nfields].type = tfiatOther; - tif->tif_fieldscompat[nfields].allocated_size = n; - tif->tif_fieldscompat[nfields].count = n; - tif->tif_fieldscompat[nfields].fields = - (TIFFField *)_TIFFCheckMalloc(tif, n, sizeof(TIFFField), reason); - if (!tif->tif_fieldscompat[nfields].fields) - { - TIFFErrorExtR(tif, module, "Failed to allocate fields array"); - return -1; - } - - tp = tif->tif_fieldscompat[nfields].fields; - for (i = 0; i < n; i++) - { - tp->field_tag = info[i].field_tag; - tp->field_readcount = info[i].field_readcount; - tp->field_writecount = info[i].field_writecount; - tp->field_type = info[i].field_type; - tp->field_anonymous = 0; - tp->set_field_type = - _TIFFSetGetType(info[i].field_type, info[i].field_readcount, - info[i].field_passcount); - tp->get_field_type = - _TIFFSetGetType(info[i].field_type, info[i].field_readcount, - info[i].field_passcount); - tp->field_bit = info[i].field_bit; - tp->field_oktochange = info[i].field_oktochange; - tp->field_passcount = info[i].field_passcount; - if (info[i].field_name == NULL) - { - TIFFErrorExtR(tif, module, - "Field_name of %d.th allocation tag %d is NULL", i, - info[i].field_tag); - return -1; - } - tp->field_name = info[i].field_name; - tp->field_subfields = NULL; - tp++; - } - - if (!_TIFFMergeFields(tif, tif->tif_fieldscompat[nfields].fields, n)) - { - TIFFErrorExtR(tif, module, "Setting up field info failed"); - return -1; - } - - return 0; -} - -int _TIFFCheckFieldIsValidForCodec(TIFF *tif, ttag_t tag) -{ - /* Filter out non-codec specific tags */ - switch (tag) - { - /* Shared tags */ - case TIFFTAG_PREDICTOR: - /* JPEG tags */ - case TIFFTAG_JPEGTABLES: - /* OJPEG tags */ - case TIFFTAG_JPEGIFOFFSET: - case TIFFTAG_JPEGIFBYTECOUNT: - case TIFFTAG_JPEGQTABLES: - case TIFFTAG_JPEGDCTABLES: - case TIFFTAG_JPEGACTABLES: - case TIFFTAG_JPEGPROC: - case TIFFTAG_JPEGRESTARTINTERVAL: - /* CCITT* */ - case TIFFTAG_BADFAXLINES: - case TIFFTAG_CLEANFAXDATA: - case TIFFTAG_CONSECUTIVEBADFAXLINES: - case TIFFTAG_GROUP3OPTIONS: - case TIFFTAG_GROUP4OPTIONS: - /* LERC */ - case TIFFTAG_LERC_PARAMETERS: - break; - default: - return 1; - } - if (!TIFFIsCODECConfigured(tif->tif_dir.td_compression)) - { - return 0; - } - /* Check if codec specific tags are allowed for the current - * compression scheme (codec) */ - switch (tif->tif_dir.td_compression) - { - case COMPRESSION_LZW: - if (tag == TIFFTAG_PREDICTOR) - return 1; - break; - case COMPRESSION_PACKBITS: - /* No codec-specific tags */ - break; - case COMPRESSION_THUNDERSCAN: - /* No codec-specific tags */ - break; - case COMPRESSION_NEXT: - /* No codec-specific tags */ - break; - case COMPRESSION_JPEG: - if (tag == TIFFTAG_JPEGTABLES) - return 1; - break; - case COMPRESSION_OJPEG: - switch (tag) - { - case TIFFTAG_JPEGIFOFFSET: - case TIFFTAG_JPEGIFBYTECOUNT: - case TIFFTAG_JPEGQTABLES: - case TIFFTAG_JPEGDCTABLES: - case TIFFTAG_JPEGACTABLES: - case TIFFTAG_JPEGPROC: - case TIFFTAG_JPEGRESTARTINTERVAL: - return 1; - } - break; - case COMPRESSION_CCITTRLE: - case COMPRESSION_CCITTRLEW: - case COMPRESSION_CCITTFAX3: - case COMPRESSION_CCITTFAX4: - switch (tag) - { - case TIFFTAG_BADFAXLINES: - case TIFFTAG_CLEANFAXDATA: - case TIFFTAG_CONSECUTIVEBADFAXLINES: - return 1; - case TIFFTAG_GROUP3OPTIONS: - if (tif->tif_dir.td_compression == COMPRESSION_CCITTFAX3) - return 1; - break; - case TIFFTAG_GROUP4OPTIONS: - if (tif->tif_dir.td_compression == COMPRESSION_CCITTFAX4) - return 1; - break; - } - break; - case COMPRESSION_JBIG: - /* No codec-specific tags */ - break; - case COMPRESSION_DEFLATE: - case COMPRESSION_ADOBE_DEFLATE: - if (tag == TIFFTAG_PREDICTOR) - return 1; - break; - case COMPRESSION_PIXARLOG: - if (tag == TIFFTAG_PREDICTOR) - return 1; - break; - case COMPRESSION_SGILOG: - case COMPRESSION_SGILOG24: - /* No codec-specific tags */ - break; - case COMPRESSION_LZMA: - if (tag == TIFFTAG_PREDICTOR) - return 1; - break; - case COMPRESSION_ZSTD: - if (tag == TIFFTAG_PREDICTOR) - return 1; - break; - case COMPRESSION_LERC: - if (tag == TIFFTAG_LERC_PARAMETERS) - return 1; - break; - } - return 0; -} diff --git a/src/3rd/tiff/dirread.c b/src/3rd/tiff/dirread.c deleted file mode 100644 index 75344fc575c..00000000000 --- a/src/3rd/tiff/dirread.c +++ /dev/null @@ -1,7908 +0,0 @@ -/* - * Copyright (c) 1988-1997 Sam Leffler - * Copyright (c) 1991-1997 Silicon Graphics, Inc. - * - * Permission to use, copy, modify, distribute, and sell this software and - * its documentation for any purpose is hereby granted without fee, provided - * that (i) the above copyright notices and this permission notice appear in - * all copies of the software and related documentation, and (ii) the names of - * Sam Leffler and Silicon Graphics may not be used in any advertising or - * publicity relating to the software without the specific, prior written - * permission of Sam Leffler and Silicon Graphics. - * - * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, - * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY - * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. - * - * IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR - * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, - * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, - * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF - * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE - * OF THIS SOFTWARE. - */ - -/* - * TIFF Library. - * - * Directory Read Support Routines. - */ - -/* Suggested pending improvements: - * - add a field 'field_info' to the TIFFDirEntry structure, and set that with - * the pointer to the appropriate TIFFField structure early on in - * TIFFReadDirectory, so as to eliminate current possibly repetitive lookup. - */ - -#include "tiffconf.h" -#include "tiffiop.h" -#include -#include -#include -#include - -#define FAILED_FII ((uint32_t)-1) - -#ifdef HAVE_IEEEFP -#define TIFFCvtIEEEFloatToNative(tif, n, fp) -#define TIFFCvtIEEEDoubleToNative(tif, n, dp) -#else -extern void TIFFCvtIEEEFloatToNative(TIFF *, uint32_t, float *); -extern void TIFFCvtIEEEDoubleToNative(TIFF *, uint32_t, double *); -#endif - -enum TIFFReadDirEntryErr -{ - TIFFReadDirEntryErrOk = 0, - TIFFReadDirEntryErrCount = 1, - TIFFReadDirEntryErrType = 2, - TIFFReadDirEntryErrIo = 3, - TIFFReadDirEntryErrRange = 4, - TIFFReadDirEntryErrPsdif = 5, - TIFFReadDirEntryErrSizesan = 6, - TIFFReadDirEntryErrAlloc = 7, -}; - -static enum TIFFReadDirEntryErr -TIFFReadDirEntryByte(TIFF *tif, TIFFDirEntry *direntry, uint8_t *value); -static enum TIFFReadDirEntryErr -TIFFReadDirEntrySbyte(TIFF *tif, TIFFDirEntry *direntry, int8_t *value); -static enum TIFFReadDirEntryErr -TIFFReadDirEntryShort(TIFF *tif, TIFFDirEntry *direntry, uint16_t *value); -static enum TIFFReadDirEntryErr -TIFFReadDirEntrySshort(TIFF *tif, TIFFDirEntry *direntry, int16_t *value); -static enum TIFFReadDirEntryErr -TIFFReadDirEntryLong(TIFF *tif, TIFFDirEntry *direntry, uint32_t *value); -static enum TIFFReadDirEntryErr -TIFFReadDirEntrySlong(TIFF *tif, TIFFDirEntry *direntry, int32_t *value); -static enum TIFFReadDirEntryErr -TIFFReadDirEntryLong8(TIFF *tif, TIFFDirEntry *direntry, uint64_t *value); -static enum TIFFReadDirEntryErr -TIFFReadDirEntrySlong8(TIFF *tif, TIFFDirEntry *direntry, int64_t *value); -static enum TIFFReadDirEntryErr -TIFFReadDirEntryFloat(TIFF *tif, TIFFDirEntry *direntry, float *value); -static enum TIFFReadDirEntryErr -TIFFReadDirEntryDouble(TIFF *tif, TIFFDirEntry *direntry, double *value); -static enum TIFFReadDirEntryErr -TIFFReadDirEntryIfd8(TIFF *tif, TIFFDirEntry *direntry, uint64_t *value); - -static enum TIFFReadDirEntryErr -TIFFReadDirEntryArray(TIFF *tif, TIFFDirEntry *direntry, uint32_t *count, - uint32_t desttypesize, void **value); -static enum TIFFReadDirEntryErr -TIFFReadDirEntryByteArray(TIFF *tif, TIFFDirEntry *direntry, uint8_t **value); -static enum TIFFReadDirEntryErr -TIFFReadDirEntrySbyteArray(TIFF *tif, TIFFDirEntry *direntry, int8_t **value); -static enum TIFFReadDirEntryErr -TIFFReadDirEntryShortArray(TIFF *tif, TIFFDirEntry *direntry, uint16_t **value); -static enum TIFFReadDirEntryErr -TIFFReadDirEntrySshortArray(TIFF *tif, TIFFDirEntry *direntry, int16_t **value); -static enum TIFFReadDirEntryErr -TIFFReadDirEntryLongArray(TIFF *tif, TIFFDirEntry *direntry, uint32_t **value); -static enum TIFFReadDirEntryErr -TIFFReadDirEntrySlongArray(TIFF *tif, TIFFDirEntry *direntry, int32_t **value); -static enum TIFFReadDirEntryErr -TIFFReadDirEntryLong8Array(TIFF *tif, TIFFDirEntry *direntry, uint64_t **value); -static enum TIFFReadDirEntryErr -TIFFReadDirEntrySlong8Array(TIFF *tif, TIFFDirEntry *direntry, int64_t **value); -static enum TIFFReadDirEntryErr -TIFFReadDirEntryFloatArray(TIFF *tif, TIFFDirEntry *direntry, float **value); -static enum TIFFReadDirEntryErr -TIFFReadDirEntryDoubleArray(TIFF *tif, TIFFDirEntry *direntry, double **value); -static enum TIFFReadDirEntryErr -TIFFReadDirEntryIfd8Array(TIFF *tif, TIFFDirEntry *direntry, uint64_t **value); - -static enum TIFFReadDirEntryErr -TIFFReadDirEntryPersampleShort(TIFF *tif, TIFFDirEntry *direntry, - uint16_t *value); - -static void TIFFReadDirEntryCheckedByte(TIFF *tif, TIFFDirEntry *direntry, - uint8_t *value); -static void TIFFReadDirEntryCheckedSbyte(TIFF *tif, TIFFDirEntry *direntry, - int8_t *value); -static void TIFFReadDirEntryCheckedShort(TIFF *tif, TIFFDirEntry *direntry, - uint16_t *value); -static void TIFFReadDirEntryCheckedSshort(TIFF *tif, TIFFDirEntry *direntry, - int16_t *value); -static void TIFFReadDirEntryCheckedLong(TIFF *tif, TIFFDirEntry *direntry, - uint32_t *value); -static void TIFFReadDirEntryCheckedSlong(TIFF *tif, TIFFDirEntry *direntry, - int32_t *value); -static enum TIFFReadDirEntryErr -TIFFReadDirEntryCheckedLong8(TIFF *tif, TIFFDirEntry *direntry, - uint64_t *value); -static enum TIFFReadDirEntryErr -TIFFReadDirEntryCheckedSlong8(TIFF *tif, TIFFDirEntry *direntry, - int64_t *value); -static enum TIFFReadDirEntryErr -TIFFReadDirEntryCheckedRational(TIFF *tif, TIFFDirEntry *direntry, - double *value); -static enum TIFFReadDirEntryErr -TIFFReadDirEntryCheckedSrational(TIFF *tif, TIFFDirEntry *direntry, - double *value); -static void TIFFReadDirEntryCheckedFloat(TIFF *tif, TIFFDirEntry *direntry, - float *value); -static enum TIFFReadDirEntryErr -TIFFReadDirEntryCheckedDouble(TIFF *tif, TIFFDirEntry *direntry, double *value); -#if 0 -static enum TIFFReadDirEntryErr -TIFFReadDirEntryCheckedRationalDirect(TIFF *tif, TIFFDirEntry *direntry, - TIFFRational_t *value); -#endif -static enum TIFFReadDirEntryErr -TIFFReadDirEntryCheckRangeByteSbyte(int8_t value); -static enum TIFFReadDirEntryErr -TIFFReadDirEntryCheckRangeByteShort(uint16_t value); -static enum TIFFReadDirEntryErr -TIFFReadDirEntryCheckRangeByteSshort(int16_t value); -static enum TIFFReadDirEntryErr -TIFFReadDirEntryCheckRangeByteLong(uint32_t value); -static enum TIFFReadDirEntryErr -TIFFReadDirEntryCheckRangeByteSlong(int32_t value); -static enum TIFFReadDirEntryErr -TIFFReadDirEntryCheckRangeByteLong8(uint64_t value); -static enum TIFFReadDirEntryErr -TIFFReadDirEntryCheckRangeByteSlong8(int64_t value); - -static enum TIFFReadDirEntryErr -TIFFReadDirEntryCheckRangeSbyteByte(uint8_t value); -static enum TIFFReadDirEntryErr -TIFFReadDirEntryCheckRangeSbyteShort(uint16_t value); -static enum TIFFReadDirEntryErr -TIFFReadDirEntryCheckRangeSbyteSshort(int16_t value); -static enum TIFFReadDirEntryErr -TIFFReadDirEntryCheckRangeSbyteLong(uint32_t value); -static enum TIFFReadDirEntryErr -TIFFReadDirEntryCheckRangeSbyteSlong(int32_t value); -static enum TIFFReadDirEntryErr -TIFFReadDirEntryCheckRangeSbyteLong8(uint64_t value); -static enum TIFFReadDirEntryErr -TIFFReadDirEntryCheckRangeSbyteSlong8(int64_t value); - -static enum TIFFReadDirEntryErr -TIFFReadDirEntryCheckRangeShortSbyte(int8_t value); -static enum TIFFReadDirEntryErr -TIFFReadDirEntryCheckRangeShortSshort(int16_t value); -static enum TIFFReadDirEntryErr -TIFFReadDirEntryCheckRangeShortLong(uint32_t value); -static enum TIFFReadDirEntryErr -TIFFReadDirEntryCheckRangeShortSlong(int32_t value); -static enum TIFFReadDirEntryErr -TIFFReadDirEntryCheckRangeShortLong8(uint64_t value); -static enum TIFFReadDirEntryErr -TIFFReadDirEntryCheckRangeShortSlong8(int64_t value); - -static enum TIFFReadDirEntryErr -TIFFReadDirEntryCheckRangeSshortShort(uint16_t value); -static enum TIFFReadDirEntryErr -TIFFReadDirEntryCheckRangeSshortLong(uint32_t value); -static enum TIFFReadDirEntryErr -TIFFReadDirEntryCheckRangeSshortSlong(int32_t value); -static enum TIFFReadDirEntryErr -TIFFReadDirEntryCheckRangeSshortLong8(uint64_t value); -static enum TIFFReadDirEntryErr -TIFFReadDirEntryCheckRangeSshortSlong8(int64_t value); - -static enum TIFFReadDirEntryErr -TIFFReadDirEntryCheckRangeLongSbyte(int8_t value); -static enum TIFFReadDirEntryErr -TIFFReadDirEntryCheckRangeLongSshort(int16_t value); -static enum TIFFReadDirEntryErr -TIFFReadDirEntryCheckRangeLongSlong(int32_t value); -static enum TIFFReadDirEntryErr -TIFFReadDirEntryCheckRangeLongLong8(uint64_t value); -static enum TIFFReadDirEntryErr -TIFFReadDirEntryCheckRangeLongSlong8(int64_t value); - -static enum TIFFReadDirEntryErr -TIFFReadDirEntryCheckRangeSlongLong(uint32_t value); -static enum TIFFReadDirEntryErr -TIFFReadDirEntryCheckRangeSlongLong8(uint64_t value); -static enum TIFFReadDirEntryErr -TIFFReadDirEntryCheckRangeSlongSlong8(int64_t value); - -static enum TIFFReadDirEntryErr -TIFFReadDirEntryCheckRangeLong8Sbyte(int8_t value); -static enum TIFFReadDirEntryErr -TIFFReadDirEntryCheckRangeLong8Sshort(int16_t value); -static enum TIFFReadDirEntryErr -TIFFReadDirEntryCheckRangeLong8Slong(int32_t value); -static enum TIFFReadDirEntryErr -TIFFReadDirEntryCheckRangeLong8Slong8(int64_t value); - -static enum TIFFReadDirEntryErr -TIFFReadDirEntryCheckRangeSlong8Long8(uint64_t value); - -static enum TIFFReadDirEntryErr TIFFReadDirEntryData(TIFF *tif, uint64_t offset, - tmsize_t size, void *dest); -static void TIFFReadDirEntryOutputErr(TIFF *tif, enum TIFFReadDirEntryErr err, - const char *module, const char *tagname, - int recover); - -static void TIFFReadDirectoryCheckOrder(TIFF *tif, TIFFDirEntry *dir, - uint16_t dircount); -static TIFFDirEntry *TIFFReadDirectoryFindEntry(TIFF *tif, TIFFDirEntry *dir, - uint16_t dircount, - uint16_t tagid); -static void TIFFReadDirectoryFindFieldInfo(TIFF *tif, uint16_t tagid, - uint32_t *fii); - -static int EstimateStripByteCounts(TIFF *tif, TIFFDirEntry *dir, - uint16_t dircount); -static void MissingRequired(TIFF *, const char *); -static int CheckDirCount(TIFF *, TIFFDirEntry *, uint32_t); -static uint16_t TIFFFetchDirectory(TIFF *tif, uint64_t diroff, - TIFFDirEntry **pdir, uint64_t *nextdiroff); -static int TIFFFetchNormalTag(TIFF *, TIFFDirEntry *, int recover); -static int TIFFFetchStripThing(TIFF *tif, TIFFDirEntry *dir, uint32_t nstrips, - uint64_t **lpp); -static int TIFFFetchSubjectDistance(TIFF *, TIFFDirEntry *); -static void ChopUpSingleUncompressedStrip(TIFF *); -static void TryChopUpUncompressedBigTiff(TIFF *); -static uint64_t TIFFReadUInt64(const uint8_t *value); -static int _TIFFGetMaxColorChannels(uint16_t photometric); - -static int _TIFFFillStrilesInternal(TIFF *tif, int loadStripByteCount); - -typedef union _UInt64Aligned_t -{ - double d; - uint64_t l; - uint32_t i[2]; - uint16_t s[4]; - uint8_t c[8]; -} UInt64Aligned_t; - -/* - Unaligned safe copy of a uint64_t value from an octet array. -*/ -static uint64_t TIFFReadUInt64(const uint8_t *value) -{ - UInt64Aligned_t result; - - result.c[0] = value[0]; - result.c[1] = value[1]; - result.c[2] = value[2]; - result.c[3] = value[3]; - result.c[4] = value[4]; - result.c[5] = value[5]; - result.c[6] = value[6]; - result.c[7] = value[7]; - - return result.l; -} - -static enum TIFFReadDirEntryErr -TIFFReadDirEntryByte(TIFF *tif, TIFFDirEntry *direntry, uint8_t *value) -{ - enum TIFFReadDirEntryErr err; - if (direntry->tdir_count != 1) - return (TIFFReadDirEntryErrCount); - switch (direntry->tdir_type) - { - case TIFF_BYTE: - case TIFF_UNDEFINED: /* Support to read TIFF_UNDEFINED with - field_readcount==1 */ - TIFFReadDirEntryCheckedByte(tif, direntry, value); - return (TIFFReadDirEntryErrOk); - case TIFF_SBYTE: - { - int8_t m; - TIFFReadDirEntryCheckedSbyte(tif, direntry, &m); - err = TIFFReadDirEntryCheckRangeByteSbyte(m); - if (err != TIFFReadDirEntryErrOk) - return (err); - *value = (uint8_t)m; - return (TIFFReadDirEntryErrOk); - } - case TIFF_SHORT: - { - uint16_t m; - TIFFReadDirEntryCheckedShort(tif, direntry, &m); - err = TIFFReadDirEntryCheckRangeByteShort(m); - if (err != TIFFReadDirEntryErrOk) - return (err); - *value = (uint8_t)m; - return (TIFFReadDirEntryErrOk); - } - case TIFF_SSHORT: - { - int16_t m; - TIFFReadDirEntryCheckedSshort(tif, direntry, &m); - err = TIFFReadDirEntryCheckRangeByteSshort(m); - if (err != TIFFReadDirEntryErrOk) - return (err); - *value = (uint8_t)m; - return (TIFFReadDirEntryErrOk); - } - case TIFF_LONG: - { - uint32_t m; - TIFFReadDirEntryCheckedLong(tif, direntry, &m); - err = TIFFReadDirEntryCheckRangeByteLong(m); - if (err != TIFFReadDirEntryErrOk) - return (err); - *value = (uint8_t)m; - return (TIFFReadDirEntryErrOk); - } - case TIFF_SLONG: - { - int32_t m; - TIFFReadDirEntryCheckedSlong(tif, direntry, &m); - err = TIFFReadDirEntryCheckRangeByteSlong(m); - if (err != TIFFReadDirEntryErrOk) - return (err); - *value = (uint8_t)m; - return (TIFFReadDirEntryErrOk); - } - case TIFF_LONG8: - { - uint64_t m; - err = TIFFReadDirEntryCheckedLong8(tif, direntry, &m); - if (err != TIFFReadDirEntryErrOk) - return (err); - err = TIFFReadDirEntryCheckRangeByteLong8(m); - if (err != TIFFReadDirEntryErrOk) - return (err); - *value = (uint8_t)m; - return (TIFFReadDirEntryErrOk); - } - case TIFF_SLONG8: - { - int64_t m; - err = TIFFReadDirEntryCheckedSlong8(tif, direntry, &m); - if (err != TIFFReadDirEntryErrOk) - return (err); - err = TIFFReadDirEntryCheckRangeByteSlong8(m); - if (err != TIFFReadDirEntryErrOk) - return (err); - *value = (uint8_t)m; - return (TIFFReadDirEntryErrOk); - } - default: - return (TIFFReadDirEntryErrType); - } -} - -static enum TIFFReadDirEntryErr -TIFFReadDirEntrySbyte(TIFF *tif, TIFFDirEntry *direntry, int8_t *value) -{ - enum TIFFReadDirEntryErr err; - if (direntry->tdir_count != 1) - return (TIFFReadDirEntryErrCount); - switch (direntry->tdir_type) - { - case TIFF_BYTE: - case TIFF_UNDEFINED: /* Support to read TIFF_UNDEFINED with - field_readcount==1 */ - { - uint8_t m; - TIFFReadDirEntryCheckedByte(tif, direntry, &m); - err = TIFFReadDirEntryCheckRangeSbyteByte(m); - if (err != TIFFReadDirEntryErrOk) - return (err); - *value = (int8_t)m; - return (TIFFReadDirEntryErrOk); - } - case TIFF_SBYTE: - { - TIFFReadDirEntryCheckedSbyte(tif, direntry, value); - return (TIFFReadDirEntryErrOk); - } - case TIFF_SHORT: - { - uint16_t m; - TIFFReadDirEntryCheckedShort(tif, direntry, &m); - err = TIFFReadDirEntryCheckRangeSbyteShort(m); - if (err != TIFFReadDirEntryErrOk) - return (err); - *value = (int8_t)m; - return (TIFFReadDirEntryErrOk); - } - case TIFF_SSHORT: - { - int16_t m; - TIFFReadDirEntryCheckedSshort(tif, direntry, &m); - err = TIFFReadDirEntryCheckRangeSbyteSshort(m); - if (err != TIFFReadDirEntryErrOk) - return (err); - *value = (int8_t)m; - return (TIFFReadDirEntryErrOk); - } - case TIFF_LONG: - { - uint32_t m; - TIFFReadDirEntryCheckedLong(tif, direntry, &m); - err = TIFFReadDirEntryCheckRangeSbyteLong(m); - if (err != TIFFReadDirEntryErrOk) - return (err); - *value = (int8_t)m; - return (TIFFReadDirEntryErrOk); - } - case TIFF_SLONG: - { - int32_t m; - TIFFReadDirEntryCheckedSlong(tif, direntry, &m); - err = TIFFReadDirEntryCheckRangeSbyteSlong(m); - if (err != TIFFReadDirEntryErrOk) - return (err); - *value = (int8_t)m; - return (TIFFReadDirEntryErrOk); - } - case TIFF_LONG8: - { - uint64_t m; - err = TIFFReadDirEntryCheckedLong8(tif, direntry, &m); - if (err != TIFFReadDirEntryErrOk) - return (err); - err = TIFFReadDirEntryCheckRangeSbyteLong8(m); - if (err != TIFFReadDirEntryErrOk) - return (err); - *value = (int8_t)m; - return (TIFFReadDirEntryErrOk); - } - case TIFF_SLONG8: - { - int64_t m; - err = TIFFReadDirEntryCheckedSlong8(tif, direntry, &m); - if (err != TIFFReadDirEntryErrOk) - return (err); - err = TIFFReadDirEntryCheckRangeSbyteSlong8(m); - if (err != TIFFReadDirEntryErrOk) - return (err); - *value = (int8_t)m; - return (TIFFReadDirEntryErrOk); - } - default: - return (TIFFReadDirEntryErrType); - } -} /*-- TIFFReadDirEntrySbyte() --*/ - -static enum TIFFReadDirEntryErr -TIFFReadDirEntryShort(TIFF *tif, TIFFDirEntry *direntry, uint16_t *value) -{ - enum TIFFReadDirEntryErr err; - if (direntry->tdir_count != 1) - return (TIFFReadDirEntryErrCount); - switch (direntry->tdir_type) - { - case TIFF_BYTE: - { - uint8_t m; - TIFFReadDirEntryCheckedByte(tif, direntry, &m); - *value = (uint16_t)m; - return (TIFFReadDirEntryErrOk); - } - case TIFF_SBYTE: - { - int8_t m; - TIFFReadDirEntryCheckedSbyte(tif, direntry, &m); - err = TIFFReadDirEntryCheckRangeShortSbyte(m); - if (err != TIFFReadDirEntryErrOk) - return (err); - *value = (uint16_t)m; - return (TIFFReadDirEntryErrOk); - } - case TIFF_SHORT: - TIFFReadDirEntryCheckedShort(tif, direntry, value); - return (TIFFReadDirEntryErrOk); - case TIFF_SSHORT: - { - int16_t m; - TIFFReadDirEntryCheckedSshort(tif, direntry, &m); - err = TIFFReadDirEntryCheckRangeShortSshort(m); - if (err != TIFFReadDirEntryErrOk) - return (err); - *value = (uint16_t)m; - return (TIFFReadDirEntryErrOk); - } - case TIFF_LONG: - { - uint32_t m; - TIFFReadDirEntryCheckedLong(tif, direntry, &m); - err = TIFFReadDirEntryCheckRangeShortLong(m); - if (err != TIFFReadDirEntryErrOk) - return (err); - *value = (uint16_t)m; - return (TIFFReadDirEntryErrOk); - } - case TIFF_SLONG: - { - int32_t m; - TIFFReadDirEntryCheckedSlong(tif, direntry, &m); - err = TIFFReadDirEntryCheckRangeShortSlong(m); - if (err != TIFFReadDirEntryErrOk) - return (err); - *value = (uint16_t)m; - return (TIFFReadDirEntryErrOk); - } - case TIFF_LONG8: - { - uint64_t m; - err = TIFFReadDirEntryCheckedLong8(tif, direntry, &m); - if (err != TIFFReadDirEntryErrOk) - return (err); - err = TIFFReadDirEntryCheckRangeShortLong8(m); - if (err != TIFFReadDirEntryErrOk) - return (err); - *value = (uint16_t)m; - return (TIFFReadDirEntryErrOk); - } - case TIFF_SLONG8: - { - int64_t m; - err = TIFFReadDirEntryCheckedSlong8(tif, direntry, &m); - if (err != TIFFReadDirEntryErrOk) - return (err); - err = TIFFReadDirEntryCheckRangeShortSlong8(m); - if (err != TIFFReadDirEntryErrOk) - return (err); - *value = (uint16_t)m; - return (TIFFReadDirEntryErrOk); - } - default: - return (TIFFReadDirEntryErrType); - } -} /*-- TIFFReadDirEntryShort() --*/ - -static enum TIFFReadDirEntryErr -TIFFReadDirEntrySshort(TIFF *tif, TIFFDirEntry *direntry, int16_t *value) -{ - enum TIFFReadDirEntryErr err; - if (direntry->tdir_count != 1) - return (TIFFReadDirEntryErrCount); - switch (direntry->tdir_type) - { - case TIFF_BYTE: - { - uint8_t m; - TIFFReadDirEntryCheckedByte(tif, direntry, &m); - *value = (int16_t)m; - return (TIFFReadDirEntryErrOk); - } - case TIFF_SBYTE: - { - int8_t m; - TIFFReadDirEntryCheckedSbyte(tif, direntry, &m); - *value = (int16_t)m; - return (TIFFReadDirEntryErrOk); - } - case TIFF_SHORT: - { - uint16_t m; - TIFFReadDirEntryCheckedShort(tif, direntry, &m); - err = TIFFReadDirEntryCheckRangeSshortShort(m); - if (err != TIFFReadDirEntryErrOk) - return (err); - *value = (uint16_t)m; - return (TIFFReadDirEntryErrOk); - } - case TIFF_SSHORT: - TIFFReadDirEntryCheckedSshort(tif, direntry, value); - return (TIFFReadDirEntryErrOk); - case TIFF_LONG: - { - uint32_t m; - TIFFReadDirEntryCheckedLong(tif, direntry, &m); - err = TIFFReadDirEntryCheckRangeSshortLong(m); - if (err != TIFFReadDirEntryErrOk) - return (err); - *value = (int16_t)m; - return (TIFFReadDirEntryErrOk); - } - case TIFF_SLONG: - { - int32_t m; - TIFFReadDirEntryCheckedSlong(tif, direntry, &m); - err = TIFFReadDirEntryCheckRangeSshortSlong(m); - if (err != TIFFReadDirEntryErrOk) - return (err); - *value = (int16_t)m; - return (TIFFReadDirEntryErrOk); - } - case TIFF_LONG8: - { - uint64_t m; - err = TIFFReadDirEntryCheckedLong8(tif, direntry, &m); - if (err != TIFFReadDirEntryErrOk) - return (err); - err = TIFFReadDirEntryCheckRangeSshortLong8(m); - if (err != TIFFReadDirEntryErrOk) - return (err); - *value = (int16_t)m; - return (TIFFReadDirEntryErrOk); - } - case TIFF_SLONG8: - { - int64_t m; - err = TIFFReadDirEntryCheckedSlong8(tif, direntry, &m); - if (err != TIFFReadDirEntryErrOk) - return (err); - err = TIFFReadDirEntryCheckRangeSshortSlong8(m); - if (err != TIFFReadDirEntryErrOk) - return (err); - *value = (int16_t)m; - return (TIFFReadDirEntryErrOk); - } - default: - return (TIFFReadDirEntryErrType); - } -} /*-- TIFFReadDirEntrySshort() --*/ - -static enum TIFFReadDirEntryErr -TIFFReadDirEntryLong(TIFF *tif, TIFFDirEntry *direntry, uint32_t *value) -{ - enum TIFFReadDirEntryErr err; - if (direntry->tdir_count != 1) - return (TIFFReadDirEntryErrCount); - switch (direntry->tdir_type) - { - case TIFF_BYTE: - { - uint8_t m; - TIFFReadDirEntryCheckedByte(tif, direntry, &m); - *value = (uint32_t)m; - return (TIFFReadDirEntryErrOk); - } - case TIFF_SBYTE: - { - int8_t m; - TIFFReadDirEntryCheckedSbyte(tif, direntry, &m); - err = TIFFReadDirEntryCheckRangeLongSbyte(m); - if (err != TIFFReadDirEntryErrOk) - return (err); - *value = (uint32_t)m; - return (TIFFReadDirEntryErrOk); - } - case TIFF_SHORT: - { - uint16_t m; - TIFFReadDirEntryCheckedShort(tif, direntry, &m); - *value = (uint32_t)m; - return (TIFFReadDirEntryErrOk); - } - case TIFF_SSHORT: - { - int16_t m; - TIFFReadDirEntryCheckedSshort(tif, direntry, &m); - err = TIFFReadDirEntryCheckRangeLongSshort(m); - if (err != TIFFReadDirEntryErrOk) - return (err); - *value = (uint32_t)m; - return (TIFFReadDirEntryErrOk); - } - case TIFF_LONG: - TIFFReadDirEntryCheckedLong(tif, direntry, value); - return (TIFFReadDirEntryErrOk); - case TIFF_SLONG: - { - int32_t m; - TIFFReadDirEntryCheckedSlong(tif, direntry, &m); - err = TIFFReadDirEntryCheckRangeLongSlong(m); - if (err != TIFFReadDirEntryErrOk) - return (err); - *value = (uint32_t)m; - return (TIFFReadDirEntryErrOk); - } - case TIFF_LONG8: - { - uint64_t m; - err = TIFFReadDirEntryCheckedLong8(tif, direntry, &m); - if (err != TIFFReadDirEntryErrOk) - return (err); - err = TIFFReadDirEntryCheckRangeLongLong8(m); - if (err != TIFFReadDirEntryErrOk) - return (err); - *value = (uint32_t)m; - return (TIFFReadDirEntryErrOk); - } - case TIFF_SLONG8: - { - int64_t m; - err = TIFFReadDirEntryCheckedSlong8(tif, direntry, &m); - if (err != TIFFReadDirEntryErrOk) - return (err); - err = TIFFReadDirEntryCheckRangeLongSlong8(m); - if (err != TIFFReadDirEntryErrOk) - return (err); - *value = (uint32_t)m; - return (TIFFReadDirEntryErrOk); - } - default: - return (TIFFReadDirEntryErrType); - } -} /*-- TIFFReadDirEntryLong() --*/ - -static enum TIFFReadDirEntryErr -TIFFReadDirEntrySlong(TIFF *tif, TIFFDirEntry *direntry, int32_t *value) -{ - enum TIFFReadDirEntryErr err; - if (direntry->tdir_count != 1) - return (TIFFReadDirEntryErrCount); - switch (direntry->tdir_type) - { - case TIFF_BYTE: - { - uint8_t m; - TIFFReadDirEntryCheckedByte(tif, direntry, &m); - *value = (int32_t)m; - return (TIFFReadDirEntryErrOk); - } - case TIFF_SBYTE: - { - int8_t m; - TIFFReadDirEntryCheckedSbyte(tif, direntry, &m); - *value = (int32_t)m; - return (TIFFReadDirEntryErrOk); - } - case TIFF_SHORT: - { - uint16_t m; - TIFFReadDirEntryCheckedShort(tif, direntry, &m); - *value = (int32_t)m; - return (TIFFReadDirEntryErrOk); - } - case TIFF_SSHORT: - { - int16_t m; - TIFFReadDirEntryCheckedSshort(tif, direntry, &m); - *value = (int32_t)m; - return (TIFFReadDirEntryErrOk); - } - case TIFF_LONG: - { - uint32_t m; - TIFFReadDirEntryCheckedLong(tif, direntry, &m); - err = TIFFReadDirEntryCheckRangeSlongLong(m); - if (err != TIFFReadDirEntryErrOk) - return (err); - *value = (int32_t)m; - return (TIFFReadDirEntryErrOk); - } - case TIFF_SLONG: - TIFFReadDirEntryCheckedSlong(tif, direntry, value); - return (TIFFReadDirEntryErrOk); - case TIFF_LONG8: - { - uint64_t m; - err = TIFFReadDirEntryCheckedLong8(tif, direntry, &m); - if (err != TIFFReadDirEntryErrOk) - return (err); - err = TIFFReadDirEntryCheckRangeSlongLong8(m); - if (err != TIFFReadDirEntryErrOk) - return (err); - *value = (int32_t)m; - return (TIFFReadDirEntryErrOk); - } - case TIFF_SLONG8: - { - int64_t m; - err = TIFFReadDirEntryCheckedSlong8(tif, direntry, &m); - if (err != TIFFReadDirEntryErrOk) - return (err); - err = TIFFReadDirEntryCheckRangeSlongSlong8(m); - if (err != TIFFReadDirEntryErrOk) - return (err); - *value = (int32_t)m; - return (TIFFReadDirEntryErrOk); - } - default: - return (TIFFReadDirEntryErrType); - } -} /*-- TIFFReadDirEntrySlong() --*/ - -static enum TIFFReadDirEntryErr -TIFFReadDirEntryLong8(TIFF *tif, TIFFDirEntry *direntry, uint64_t *value) -{ - enum TIFFReadDirEntryErr err; - if (direntry->tdir_count != 1) - return (TIFFReadDirEntryErrCount); - switch (direntry->tdir_type) - { - case TIFF_BYTE: - { - uint8_t m; - TIFFReadDirEntryCheckedByte(tif, direntry, &m); - *value = (uint64_t)m; - return (TIFFReadDirEntryErrOk); - } - case TIFF_SBYTE: - { - int8_t m; - TIFFReadDirEntryCheckedSbyte(tif, direntry, &m); - err = TIFFReadDirEntryCheckRangeLong8Sbyte(m); - if (err != TIFFReadDirEntryErrOk) - return (err); - *value = (uint64_t)m; - return (TIFFReadDirEntryErrOk); - } - case TIFF_SHORT: - { - uint16_t m; - TIFFReadDirEntryCheckedShort(tif, direntry, &m); - *value = (uint64_t)m; - return (TIFFReadDirEntryErrOk); - } - case TIFF_SSHORT: - { - int16_t m; - TIFFReadDirEntryCheckedSshort(tif, direntry, &m); - err = TIFFReadDirEntryCheckRangeLong8Sshort(m); - if (err != TIFFReadDirEntryErrOk) - return (err); - *value = (uint64_t)m; - return (TIFFReadDirEntryErrOk); - } - case TIFF_LONG: - { - uint32_t m; - TIFFReadDirEntryCheckedLong(tif, direntry, &m); - *value = (uint64_t)m; - return (TIFFReadDirEntryErrOk); - } - case TIFF_SLONG: - { - int32_t m; - TIFFReadDirEntryCheckedSlong(tif, direntry, &m); - err = TIFFReadDirEntryCheckRangeLong8Slong(m); - if (err != TIFFReadDirEntryErrOk) - return (err); - *value = (uint64_t)m; - return (TIFFReadDirEntryErrOk); - } - case TIFF_LONG8: - err = TIFFReadDirEntryCheckedLong8(tif, direntry, value); - return (err); - case TIFF_SLONG8: - { - int64_t m; - err = TIFFReadDirEntryCheckedSlong8(tif, direntry, &m); - if (err != TIFFReadDirEntryErrOk) - return (err); - err = TIFFReadDirEntryCheckRangeLong8Slong8(m); - if (err != TIFFReadDirEntryErrOk) - return (err); - *value = (uint64_t)m; - return (TIFFReadDirEntryErrOk); - } - default: - return (TIFFReadDirEntryErrType); - } -} /*-- TIFFReadDirEntryLong8() --*/ - -static enum TIFFReadDirEntryErr -TIFFReadDirEntrySlong8(TIFF *tif, TIFFDirEntry *direntry, int64_t *value) -{ - enum TIFFReadDirEntryErr err; - if (direntry->tdir_count != 1) - return (TIFFReadDirEntryErrCount); - switch (direntry->tdir_type) - { - case TIFF_BYTE: - { - uint8_t m; - TIFFReadDirEntryCheckedByte(tif, direntry, &m); - *value = (int64_t)m; - return (TIFFReadDirEntryErrOk); - } - case TIFF_SBYTE: - { - int8_t m; - TIFFReadDirEntryCheckedSbyte(tif, direntry, &m); - *value = (int64_t)m; - return (TIFFReadDirEntryErrOk); - } - case TIFF_SHORT: - { - uint16_t m; - TIFFReadDirEntryCheckedShort(tif, direntry, &m); - *value = (int64_t)m; - return (TIFFReadDirEntryErrOk); - } - case TIFF_SSHORT: - { - int16_t m; - TIFFReadDirEntryCheckedSshort(tif, direntry, &m); - *value = (int64_t)m; - return (TIFFReadDirEntryErrOk); - } - case TIFF_LONG: - { - uint32_t m; - TIFFReadDirEntryCheckedLong(tif, direntry, &m); - *value = (int64_t)m; - return (TIFFReadDirEntryErrOk); - } - case TIFF_SLONG: - { - int32_t m; - TIFFReadDirEntryCheckedSlong(tif, direntry, &m); - *value = (int64_t)m; - return (TIFFReadDirEntryErrOk); - } - case TIFF_LONG8: - { - uint64_t m; - err = TIFFReadDirEntryCheckedLong8(tif, direntry, &m); - if (err != TIFFReadDirEntryErrOk) - return (err); - err = TIFFReadDirEntryCheckRangeSlong8Long8(m); - if (err != TIFFReadDirEntryErrOk) - return (err); - *value = (int64_t)m; - return (TIFFReadDirEntryErrOk); - } - case TIFF_SLONG8: - err = TIFFReadDirEntryCheckedSlong8(tif, direntry, value); - return (err); - default: - return (TIFFReadDirEntryErrType); - } -} /*-- TIFFReadDirEntrySlong8() --*/ - -static enum TIFFReadDirEntryErr -TIFFReadDirEntryFloat(TIFF *tif, TIFFDirEntry *direntry, float *value) -{ - enum TIFFReadDirEntryErr err; - if (direntry->tdir_count != 1) - return (TIFFReadDirEntryErrCount); - switch (direntry->tdir_type) - { - case TIFF_BYTE: - { - uint8_t m; - TIFFReadDirEntryCheckedByte(tif, direntry, &m); - *value = (float)m; - return (TIFFReadDirEntryErrOk); - } - case TIFF_SBYTE: - { - int8_t m; - TIFFReadDirEntryCheckedSbyte(tif, direntry, &m); - *value = (float)m; - return (TIFFReadDirEntryErrOk); - } - case TIFF_SHORT: - { - uint16_t m; - TIFFReadDirEntryCheckedShort(tif, direntry, &m); - *value = (float)m; - return (TIFFReadDirEntryErrOk); - } - case TIFF_SSHORT: - { - int16_t m; - TIFFReadDirEntryCheckedSshort(tif, direntry, &m); - *value = (float)m; - return (TIFFReadDirEntryErrOk); - } - case TIFF_LONG: - { - uint32_t m; - TIFFReadDirEntryCheckedLong(tif, direntry, &m); - *value = (float)m; - return (TIFFReadDirEntryErrOk); - } - case TIFF_SLONG: - { - int32_t m; - TIFFReadDirEntryCheckedSlong(tif, direntry, &m); - *value = (float)m; - return (TIFFReadDirEntryErrOk); - } - case TIFF_LONG8: - { - uint64_t m; - err = TIFFReadDirEntryCheckedLong8(tif, direntry, &m); - if (err != TIFFReadDirEntryErrOk) - return (err); -#if defined(__WIN32__) && (_MSC_VER < 1500) - /* - * XXX: MSVC 6.0 does not support conversion - * of 64-bit integers into floating point - * values. - */ - *value = _TIFFUInt64ToFloat(m); -#else - *value = (float)m; -#endif - return (TIFFReadDirEntryErrOk); - } - case TIFF_SLONG8: - { - int64_t m; - err = TIFFReadDirEntryCheckedSlong8(tif, direntry, &m); - if (err != TIFFReadDirEntryErrOk) - return (err); - *value = (float)m; - return (TIFFReadDirEntryErrOk); - } - case TIFF_RATIONAL: - { - double m; - err = TIFFReadDirEntryCheckedRational(tif, direntry, &m); - if (err != TIFFReadDirEntryErrOk) - return (err); - *value = (float)m; - return (TIFFReadDirEntryErrOk); - } - case TIFF_SRATIONAL: - { - double m; - err = TIFFReadDirEntryCheckedSrational(tif, direntry, &m); - if (err != TIFFReadDirEntryErrOk) - return (err); - *value = (float)m; - return (TIFFReadDirEntryErrOk); - } - case TIFF_FLOAT: - TIFFReadDirEntryCheckedFloat(tif, direntry, value); - return (TIFFReadDirEntryErrOk); - case TIFF_DOUBLE: - { - double m; - err = TIFFReadDirEntryCheckedDouble(tif, direntry, &m); - if (err != TIFFReadDirEntryErrOk) - return (err); - if ((m > FLT_MAX) || (m < -FLT_MAX)) - return (TIFFReadDirEntryErrRange); - *value = (float)m; - return (TIFFReadDirEntryErrOk); - } - default: - return (TIFFReadDirEntryErrType); - } -} - -static enum TIFFReadDirEntryErr -TIFFReadDirEntryDouble(TIFF *tif, TIFFDirEntry *direntry, double *value) -{ - enum TIFFReadDirEntryErr err; - if (direntry->tdir_count != 1) - return (TIFFReadDirEntryErrCount); - switch (direntry->tdir_type) - { - case TIFF_BYTE: - { - uint8_t m; - TIFFReadDirEntryCheckedByte(tif, direntry, &m); - *value = (double)m; - return (TIFFReadDirEntryErrOk); - } - case TIFF_SBYTE: - { - int8_t m; - TIFFReadDirEntryCheckedSbyte(tif, direntry, &m); - *value = (double)m; - return (TIFFReadDirEntryErrOk); - } - case TIFF_SHORT: - { - uint16_t m; - TIFFReadDirEntryCheckedShort(tif, direntry, &m); - *value = (double)m; - return (TIFFReadDirEntryErrOk); - } - case TIFF_SSHORT: - { - int16_t m; - TIFFReadDirEntryCheckedSshort(tif, direntry, &m); - *value = (double)m; - return (TIFFReadDirEntryErrOk); - } - case TIFF_LONG: - { - uint32_t m; - TIFFReadDirEntryCheckedLong(tif, direntry, &m); - *value = (double)m; - return (TIFFReadDirEntryErrOk); - } - case TIFF_SLONG: - { - int32_t m; - TIFFReadDirEntryCheckedSlong(tif, direntry, &m); - *value = (double)m; - return (TIFFReadDirEntryErrOk); - } - case TIFF_LONG8: - { - uint64_t m; - err = TIFFReadDirEntryCheckedLong8(tif, direntry, &m); - if (err != TIFFReadDirEntryErrOk) - return (err); -#if defined(__WIN32__) && (_MSC_VER < 1500) - /* - * XXX: MSVC 6.0 does not support conversion - * of 64-bit integers into floating point - * values. - */ - *value = _TIFFUInt64ToDouble(m); -#else - *value = (double)m; -#endif - return (TIFFReadDirEntryErrOk); - } - case TIFF_SLONG8: - { - int64_t m; - err = TIFFReadDirEntryCheckedSlong8(tif, direntry, &m); - if (err != TIFFReadDirEntryErrOk) - return (err); - *value = (double)m; - return (TIFFReadDirEntryErrOk); - } - case TIFF_RATIONAL: - err = TIFFReadDirEntryCheckedRational(tif, direntry, value); - return (err); - case TIFF_SRATIONAL: - err = TIFFReadDirEntryCheckedSrational(tif, direntry, value); - return (err); - case TIFF_FLOAT: - { - float m; - TIFFReadDirEntryCheckedFloat(tif, direntry, &m); - *value = (double)m; - return (TIFFReadDirEntryErrOk); - } - case TIFF_DOUBLE: - err = TIFFReadDirEntryCheckedDouble(tif, direntry, value); - return (err); - default: - return (TIFFReadDirEntryErrType); - } -} - -static enum TIFFReadDirEntryErr -TIFFReadDirEntryIfd8(TIFF *tif, TIFFDirEntry *direntry, uint64_t *value) -{ - enum TIFFReadDirEntryErr err; - if (direntry->tdir_count != 1) - return (TIFFReadDirEntryErrCount); - switch (direntry->tdir_type) - { - case TIFF_LONG: - case TIFF_IFD: - { - uint32_t m; - TIFFReadDirEntryCheckedLong(tif, direntry, &m); - *value = (uint64_t)m; - return (TIFFReadDirEntryErrOk); - } - case TIFF_LONG8: - case TIFF_IFD8: - err = TIFFReadDirEntryCheckedLong8(tif, direntry, value); - return (err); - default: - return (TIFFReadDirEntryErrType); - } -} - -#define INITIAL_THRESHOLD (1024 * 1024) -#define THRESHOLD_MULTIPLIER 10 -#define MAX_THRESHOLD \ - (THRESHOLD_MULTIPLIER * THRESHOLD_MULTIPLIER * THRESHOLD_MULTIPLIER * \ - INITIAL_THRESHOLD) - -static enum TIFFReadDirEntryErr TIFFReadDirEntryDataAndRealloc(TIFF *tif, - uint64_t offset, - tmsize_t size, - void **pdest) -{ -#if SIZEOF_SIZE_T == 8 - tmsize_t threshold = INITIAL_THRESHOLD; -#endif - tmsize_t already_read = 0; - - assert(!isMapped(tif)); - - if (!SeekOK(tif, offset)) - return (TIFFReadDirEntryErrIo); - - /* On 64 bit processes, read first a maximum of 1 MB, then 10 MB, etc */ - /* so as to avoid allocating too much memory in case the file is too */ - /* short. We could ask for the file size, but this might be */ - /* expensive with some I/O layers (think of reading a gzipped file) */ - /* Restrict to 64 bit processes, so as to avoid reallocs() */ - /* on 32 bit processes where virtual memory is scarce. */ - while (already_read < size) - { - void *new_dest; - tmsize_t bytes_read; - tmsize_t to_read = size - already_read; -#if SIZEOF_SIZE_T == 8 - if (to_read >= threshold && threshold < MAX_THRESHOLD) - { - to_read = threshold; - threshold *= THRESHOLD_MULTIPLIER; - } -#endif - - new_dest = - (uint8_t *)_TIFFreallocExt(tif, *pdest, already_read + to_read); - if (new_dest == NULL) - { - TIFFErrorExtR(tif, tif->tif_name, - "Failed to allocate memory for %s " - "(%" TIFF_SSIZE_FORMAT - " elements of %" TIFF_SSIZE_FORMAT " bytes each)", - "TIFFReadDirEntryArray", (tmsize_t)1, - already_read + to_read); - return TIFFReadDirEntryErrAlloc; - } - *pdest = new_dest; - - bytes_read = TIFFReadFile(tif, (char *)*pdest + already_read, to_read); - already_read += bytes_read; - if (bytes_read != to_read) - { - return TIFFReadDirEntryErrIo; - } - } - return TIFFReadDirEntryErrOk; -} - -/* Caution: if raising that value, make sure int32 / uint32 overflows can't - * occur elsewhere */ -#define MAX_SIZE_TAG_DATA 2147483647U - -static enum TIFFReadDirEntryErr -TIFFReadDirEntryArrayWithLimit(TIFF *tif, TIFFDirEntry *direntry, - uint32_t *count, uint32_t desttypesize, - void **value, uint64_t maxcount) -{ - int typesize; - uint32_t datasize; - void *data; - uint64_t target_count64; - int original_datasize_clamped; - typesize = TIFFDataWidth(direntry->tdir_type); - - target_count64 = - (direntry->tdir_count > maxcount) ? maxcount : direntry->tdir_count; - - if ((target_count64 == 0) || (typesize == 0)) - { - *value = 0; - return (TIFFReadDirEntryErrOk); - } - (void)desttypesize; - - /* We just want to know if the original tag size is more than 4 bytes - * (classic TIFF) or 8 bytes (BigTIFF) - */ - original_datasize_clamped = - ((direntry->tdir_count > 10) ? 10 : (int)direntry->tdir_count) * - typesize; - - /* - * As a sanity check, make sure we have no more than a 2GB tag array - * 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) - return (TIFFReadDirEntryErrSizesan); - if ((uint64_t)(MAX_SIZE_TAG_DATA / desttypesize) < target_count64) - return (TIFFReadDirEntryErrSizesan); - - *count = (uint32_t)target_count64; - datasize = (*count) * typesize; - assert((tmsize_t)datasize > 0); - - if (isMapped(tif) && datasize > (uint64_t)tif->tif_size) - return TIFFReadDirEntryErrIo; - - if (!isMapped(tif) && (((tif->tif_flags & TIFF_BIGTIFF) && datasize > 8) || - (!(tif->tif_flags & TIFF_BIGTIFF) && datasize > 4))) - { - data = NULL; - } - else - { - data = _TIFFCheckMalloc(tif, *count, typesize, "ReadDirEntryArray"); - if (data == 0) - return (TIFFReadDirEntryErrAlloc); - } - if (!(tif->tif_flags & TIFF_BIGTIFF)) - { - /* Only the condition on original_datasize_clamped. The second - * one is implied, but Coverity Scan cannot see it. */ - if (original_datasize_clamped <= 4 && datasize <= 4) - _TIFFmemcpy(data, &direntry->tdir_offset, datasize); - else - { - enum TIFFReadDirEntryErr err; - uint32_t offset = direntry->tdir_offset.toff_long; - if (tif->tif_flags & TIFF_SWAB) - TIFFSwabLong(&offset); - if (isMapped(tif)) - err = TIFFReadDirEntryData(tif, (uint64_t)offset, - (tmsize_t)datasize, data); - else - err = TIFFReadDirEntryDataAndRealloc(tif, (uint64_t)offset, - (tmsize_t)datasize, &data); - if (err != TIFFReadDirEntryErrOk) - { - _TIFFfreeExt(tif, data); - return (err); - } - } - } - else - { - /* See above comment for the Classic TIFF case */ - if (original_datasize_clamped <= 8 && datasize <= 8) - _TIFFmemcpy(data, &direntry->tdir_offset, datasize); - else - { - enum TIFFReadDirEntryErr err; - uint64_t offset = direntry->tdir_offset.toff_long8; - if (tif->tif_flags & TIFF_SWAB) - TIFFSwabLong8(&offset); - if (isMapped(tif)) - err = TIFFReadDirEntryData(tif, (uint64_t)offset, - (tmsize_t)datasize, data); - else - err = TIFFReadDirEntryDataAndRealloc(tif, (uint64_t)offset, - (tmsize_t)datasize, &data); - if (err != TIFFReadDirEntryErrOk) - { - _TIFFfreeExt(tif, data); - return (err); - } - } - } - *value = data; - return (TIFFReadDirEntryErrOk); -} - -static enum TIFFReadDirEntryErr -TIFFReadDirEntryArray(TIFF *tif, TIFFDirEntry *direntry, uint32_t *count, - uint32_t desttypesize, void **value) -{ - return TIFFReadDirEntryArrayWithLimit(tif, direntry, count, desttypesize, - value, ~((uint64_t)0)); -} - -static enum TIFFReadDirEntryErr -TIFFReadDirEntryByteArray(TIFF *tif, TIFFDirEntry *direntry, uint8_t **value) -{ - enum TIFFReadDirEntryErr err; - uint32_t count; - void *origdata; - uint8_t *data; - switch (direntry->tdir_type) - { - case TIFF_ASCII: - case TIFF_UNDEFINED: - case TIFF_BYTE: - case TIFF_SBYTE: - case TIFF_SHORT: - case TIFF_SSHORT: - case TIFF_LONG: - case TIFF_SLONG: - case TIFF_LONG8: - case TIFF_SLONG8: - break; - default: - return (TIFFReadDirEntryErrType); - } - err = TIFFReadDirEntryArray(tif, direntry, &count, 1, &origdata); - if ((err != TIFFReadDirEntryErrOk) || (origdata == 0)) - { - *value = 0; - return (err); - } - switch (direntry->tdir_type) - { - case TIFF_ASCII: - case TIFF_UNDEFINED: - case TIFF_BYTE: - *value = (uint8_t *)origdata; - return (TIFFReadDirEntryErrOk); - case TIFF_SBYTE: - { - int8_t *m; - uint32_t n; - m = (int8_t *)origdata; - for (n = 0; n < count; n++) - { - err = TIFFReadDirEntryCheckRangeByteSbyte(*m); - if (err != TIFFReadDirEntryErrOk) - { - _TIFFfreeExt(tif, origdata); - return (err); - } - m++; - } - *value = (uint8_t *)origdata; - return (TIFFReadDirEntryErrOk); - } - } - data = (uint8_t *)_TIFFmallocExt(tif, count); - if (data == 0) - { - _TIFFfreeExt(tif, origdata); - return (TIFFReadDirEntryErrAlloc); - } - switch (direntry->tdir_type) - { - case TIFF_SHORT: - { - uint16_t *ma; - uint8_t *mb; - uint32_t n; - ma = (uint16_t *)origdata; - mb = data; - for (n = 0; n < count; n++) - { - if (tif->tif_flags & TIFF_SWAB) - TIFFSwabShort(ma); - err = TIFFReadDirEntryCheckRangeByteShort(*ma); - if (err != TIFFReadDirEntryErrOk) - break; - *mb++ = (uint8_t)(*ma++); - } - } - break; - case TIFF_SSHORT: - { - int16_t *ma; - uint8_t *mb; - uint32_t n; - ma = (int16_t *)origdata; - mb = data; - for (n = 0; n < count; n++) - { - if (tif->tif_flags & TIFF_SWAB) - TIFFSwabShort((uint16_t *)ma); - err = TIFFReadDirEntryCheckRangeByteSshort(*ma); - if (err != TIFFReadDirEntryErrOk) - break; - *mb++ = (uint8_t)(*ma++); - } - } - break; - case TIFF_LONG: - { - uint32_t *ma; - uint8_t *mb; - uint32_t n; - ma = (uint32_t *)origdata; - mb = data; - for (n = 0; n < count; n++) - { - if (tif->tif_flags & TIFF_SWAB) - TIFFSwabLong(ma); - err = TIFFReadDirEntryCheckRangeByteLong(*ma); - if (err != TIFFReadDirEntryErrOk) - break; - *mb++ = (uint8_t)(*ma++); - } - } - break; - case TIFF_SLONG: - { - int32_t *ma; - uint8_t *mb; - uint32_t n; - ma = (int32_t *)origdata; - mb = data; - for (n = 0; n < count; n++) - { - if (tif->tif_flags & TIFF_SWAB) - TIFFSwabLong((uint32_t *)ma); - err = TIFFReadDirEntryCheckRangeByteSlong(*ma); - if (err != TIFFReadDirEntryErrOk) - break; - *mb++ = (uint8_t)(*ma++); - } - } - break; - case TIFF_LONG8: - { - uint64_t *ma; - uint8_t *mb; - uint32_t n; - ma = (uint64_t *)origdata; - mb = data; - for (n = 0; n < count; n++) - { - if (tif->tif_flags & TIFF_SWAB) - TIFFSwabLong8(ma); - err = TIFFReadDirEntryCheckRangeByteLong8(*ma); - if (err != TIFFReadDirEntryErrOk) - break; - *mb++ = (uint8_t)(*ma++); - } - } - break; - case TIFF_SLONG8: - { - int64_t *ma; - uint8_t *mb; - uint32_t n; - ma = (int64_t *)origdata; - mb = data; - for (n = 0; n < count; n++) - { - if (tif->tif_flags & TIFF_SWAB) - TIFFSwabLong8((uint64_t *)ma); - err = TIFFReadDirEntryCheckRangeByteSlong8(*ma); - if (err != TIFFReadDirEntryErrOk) - break; - *mb++ = (uint8_t)(*ma++); - } - } - break; - } - _TIFFfreeExt(tif, origdata); - if (err != TIFFReadDirEntryErrOk) - { - _TIFFfreeExt(tif, data); - return (err); - } - *value = data; - return (TIFFReadDirEntryErrOk); -} - -static enum TIFFReadDirEntryErr -TIFFReadDirEntrySbyteArray(TIFF *tif, TIFFDirEntry *direntry, int8_t **value) -{ - enum TIFFReadDirEntryErr err; - uint32_t count; - void *origdata; - int8_t *data; - switch (direntry->tdir_type) - { - case TIFF_UNDEFINED: - case TIFF_BYTE: - case TIFF_SBYTE: - case TIFF_SHORT: - case TIFF_SSHORT: - case TIFF_LONG: - case TIFF_SLONG: - case TIFF_LONG8: - case TIFF_SLONG8: - break; - default: - return (TIFFReadDirEntryErrType); - } - err = TIFFReadDirEntryArray(tif, direntry, &count, 1, &origdata); - if ((err != TIFFReadDirEntryErrOk) || (origdata == 0)) - { - *value = 0; - return (err); - } - switch (direntry->tdir_type) - { - case TIFF_UNDEFINED: - case TIFF_BYTE: - { - uint8_t *m; - uint32_t n; - m = (uint8_t *)origdata; - for (n = 0; n < count; n++) - { - err = TIFFReadDirEntryCheckRangeSbyteByte(*m); - if (err != TIFFReadDirEntryErrOk) - { - _TIFFfreeExt(tif, origdata); - return (err); - } - m++; - } - *value = (int8_t *)origdata; - return (TIFFReadDirEntryErrOk); - } - case TIFF_SBYTE: - *value = (int8_t *)origdata; - return (TIFFReadDirEntryErrOk); - } - data = (int8_t *)_TIFFmallocExt(tif, count); - if (data == 0) - { - _TIFFfreeExt(tif, origdata); - return (TIFFReadDirEntryErrAlloc); - } - switch (direntry->tdir_type) - { - case TIFF_SHORT: - { - uint16_t *ma; - int8_t *mb; - uint32_t n; - ma = (uint16_t *)origdata; - mb = data; - for (n = 0; n < count; n++) - { - if (tif->tif_flags & TIFF_SWAB) - TIFFSwabShort(ma); - err = TIFFReadDirEntryCheckRangeSbyteShort(*ma); - if (err != TIFFReadDirEntryErrOk) - break; - *mb++ = (int8_t)(*ma++); - } - } - break; - case TIFF_SSHORT: - { - int16_t *ma; - int8_t *mb; - uint32_t n; - ma = (int16_t *)origdata; - mb = data; - for (n = 0; n < count; n++) - { - if (tif->tif_flags & TIFF_SWAB) - TIFFSwabShort((uint16_t *)ma); - err = TIFFReadDirEntryCheckRangeSbyteSshort(*ma); - if (err != TIFFReadDirEntryErrOk) - break; - *mb++ = (int8_t)(*ma++); - } - } - break; - case TIFF_LONG: - { - uint32_t *ma; - int8_t *mb; - uint32_t n; - ma = (uint32_t *)origdata; - mb = data; - for (n = 0; n < count; n++) - { - if (tif->tif_flags & TIFF_SWAB) - TIFFSwabLong(ma); - err = TIFFReadDirEntryCheckRangeSbyteLong(*ma); - if (err != TIFFReadDirEntryErrOk) - break; - *mb++ = (int8_t)(*ma++); - } - } - break; - case TIFF_SLONG: - { - int32_t *ma; - int8_t *mb; - uint32_t n; - ma = (int32_t *)origdata; - mb = data; - for (n = 0; n < count; n++) - { - if (tif->tif_flags & TIFF_SWAB) - TIFFSwabLong((uint32_t *)ma); - err = TIFFReadDirEntryCheckRangeSbyteSlong(*ma); - if (err != TIFFReadDirEntryErrOk) - break; - *mb++ = (int8_t)(*ma++); - } - } - break; - case TIFF_LONG8: - { - uint64_t *ma; - int8_t *mb; - uint32_t n; - ma = (uint64_t *)origdata; - mb = data; - for (n = 0; n < count; n++) - { - if (tif->tif_flags & TIFF_SWAB) - TIFFSwabLong8(ma); - err = TIFFReadDirEntryCheckRangeSbyteLong8(*ma); - if (err != TIFFReadDirEntryErrOk) - break; - *mb++ = (int8_t)(*ma++); - } - } - break; - case TIFF_SLONG8: - { - int64_t *ma; - int8_t *mb; - uint32_t n; - ma = (int64_t *)origdata; - mb = data; - for (n = 0; n < count; n++) - { - if (tif->tif_flags & TIFF_SWAB) - TIFFSwabLong8((uint64_t *)ma); - err = TIFFReadDirEntryCheckRangeSbyteSlong8(*ma); - if (err != TIFFReadDirEntryErrOk) - break; - *mb++ = (int8_t)(*ma++); - } - } - break; - } - _TIFFfreeExt(tif, origdata); - if (err != TIFFReadDirEntryErrOk) - { - _TIFFfreeExt(tif, data); - return (err); - } - *value = data; - return (TIFFReadDirEntryErrOk); -} - -static enum TIFFReadDirEntryErr -TIFFReadDirEntryShortArray(TIFF *tif, TIFFDirEntry *direntry, uint16_t **value) -{ - enum TIFFReadDirEntryErr err; - uint32_t count; - void *origdata; - uint16_t *data; - switch (direntry->tdir_type) - { - case TIFF_BYTE: - case TIFF_SBYTE: - case TIFF_SHORT: - case TIFF_SSHORT: - case TIFF_LONG: - case TIFF_SLONG: - case TIFF_LONG8: - case TIFF_SLONG8: - break; - default: - return (TIFFReadDirEntryErrType); - } - err = TIFFReadDirEntryArray(tif, direntry, &count, 2, &origdata); - if ((err != TIFFReadDirEntryErrOk) || (origdata == 0)) - { - *value = 0; - return (err); - } - switch (direntry->tdir_type) - { - case TIFF_SHORT: - *value = (uint16_t *)origdata; - if (tif->tif_flags & TIFF_SWAB) - TIFFSwabArrayOfShort(*value, count); - return (TIFFReadDirEntryErrOk); - case TIFF_SSHORT: - { - int16_t *m; - uint32_t n; - m = (int16_t *)origdata; - for (n = 0; n < count; n++) - { - if (tif->tif_flags & TIFF_SWAB) - TIFFSwabShort((uint16_t *)m); - err = TIFFReadDirEntryCheckRangeShortSshort(*m); - if (err != TIFFReadDirEntryErrOk) - { - _TIFFfreeExt(tif, origdata); - return (err); - } - m++; - } - *value = (uint16_t *)origdata; - return (TIFFReadDirEntryErrOk); - } - } - data = (uint16_t *)_TIFFmallocExt(tif, count * 2); - if (data == 0) - { - _TIFFfreeExt(tif, origdata); - return (TIFFReadDirEntryErrAlloc); - } - switch (direntry->tdir_type) - { - case TIFF_BYTE: - { - uint8_t *ma; - uint16_t *mb; - uint32_t n; - ma = (uint8_t *)origdata; - mb = data; - for (n = 0; n < count; n++) - *mb++ = (uint16_t)(*ma++); - } - break; - case TIFF_SBYTE: - { - int8_t *ma; - uint16_t *mb; - uint32_t n; - ma = (int8_t *)origdata; - mb = data; - for (n = 0; n < count; n++) - { - err = TIFFReadDirEntryCheckRangeShortSbyte(*ma); - if (err != TIFFReadDirEntryErrOk) - break; - *mb++ = (uint16_t)(*ma++); - } - } - break; - case TIFF_LONG: - { - uint32_t *ma; - uint16_t *mb; - uint32_t n; - ma = (uint32_t *)origdata; - mb = data; - for (n = 0; n < count; n++) - { - if (tif->tif_flags & TIFF_SWAB) - TIFFSwabLong(ma); - err = TIFFReadDirEntryCheckRangeShortLong(*ma); - if (err != TIFFReadDirEntryErrOk) - break; - *mb++ = (uint16_t)(*ma++); - } - } - break; - case TIFF_SLONG: - { - int32_t *ma; - uint16_t *mb; - uint32_t n; - ma = (int32_t *)origdata; - mb = data; - for (n = 0; n < count; n++) - { - if (tif->tif_flags & TIFF_SWAB) - TIFFSwabLong((uint32_t *)ma); - err = TIFFReadDirEntryCheckRangeShortSlong(*ma); - if (err != TIFFReadDirEntryErrOk) - break; - *mb++ = (uint16_t)(*ma++); - } - } - break; - case TIFF_LONG8: - { - uint64_t *ma; - uint16_t *mb; - uint32_t n; - ma = (uint64_t *)origdata; - mb = data; - for (n = 0; n < count; n++) - { - if (tif->tif_flags & TIFF_SWAB) - TIFFSwabLong8(ma); - err = TIFFReadDirEntryCheckRangeShortLong8(*ma); - if (err != TIFFReadDirEntryErrOk) - break; - *mb++ = (uint16_t)(*ma++); - } - } - break; - case TIFF_SLONG8: - { - int64_t *ma; - uint16_t *mb; - uint32_t n; - ma = (int64_t *)origdata; - mb = data; - for (n = 0; n < count; n++) - { - if (tif->tif_flags & TIFF_SWAB) - TIFFSwabLong8((uint64_t *)ma); - err = TIFFReadDirEntryCheckRangeShortSlong8(*ma); - if (err != TIFFReadDirEntryErrOk) - break; - *mb++ = (uint16_t)(*ma++); - } - } - break; - } - _TIFFfreeExt(tif, origdata); - if (err != TIFFReadDirEntryErrOk) - { - _TIFFfreeExt(tif, data); - return (err); - } - *value = data; - return (TIFFReadDirEntryErrOk); -} - -static enum TIFFReadDirEntryErr -TIFFReadDirEntrySshortArray(TIFF *tif, TIFFDirEntry *direntry, int16_t **value) -{ - enum TIFFReadDirEntryErr err; - uint32_t count; - void *origdata; - int16_t *data; - switch (direntry->tdir_type) - { - case TIFF_BYTE: - case TIFF_SBYTE: - case TIFF_SHORT: - case TIFF_SSHORT: - case TIFF_LONG: - case TIFF_SLONG: - case TIFF_LONG8: - case TIFF_SLONG8: - break; - default: - return (TIFFReadDirEntryErrType); - } - err = TIFFReadDirEntryArray(tif, direntry, &count, 2, &origdata); - if ((err != TIFFReadDirEntryErrOk) || (origdata == 0)) - { - *value = 0; - return (err); - } - switch (direntry->tdir_type) - { - case TIFF_SHORT: - { - uint16_t *m; - uint32_t n; - m = (uint16_t *)origdata; - for (n = 0; n < count; n++) - { - if (tif->tif_flags & TIFF_SWAB) - TIFFSwabShort(m); - err = TIFFReadDirEntryCheckRangeSshortShort(*m); - if (err != TIFFReadDirEntryErrOk) - { - _TIFFfreeExt(tif, origdata); - return (err); - } - m++; - } - *value = (int16_t *)origdata; - return (TIFFReadDirEntryErrOk); - } - case TIFF_SSHORT: - *value = (int16_t *)origdata; - if (tif->tif_flags & TIFF_SWAB) - TIFFSwabArrayOfShort((uint16_t *)(*value), count); - return (TIFFReadDirEntryErrOk); - } - data = (int16_t *)_TIFFmallocExt(tif, count * 2); - if (data == 0) - { - _TIFFfreeExt(tif, origdata); - return (TIFFReadDirEntryErrAlloc); - } - switch (direntry->tdir_type) - { - case TIFF_BYTE: - { - uint8_t *ma; - int16_t *mb; - uint32_t n; - ma = (uint8_t *)origdata; - mb = data; - for (n = 0; n < count; n++) - *mb++ = (int16_t)(*ma++); - } - break; - case TIFF_SBYTE: - { - int8_t *ma; - int16_t *mb; - uint32_t n; - ma = (int8_t *)origdata; - mb = data; - for (n = 0; n < count; n++) - *mb++ = (int16_t)(*ma++); - } - break; - case TIFF_LONG: - { - uint32_t *ma; - int16_t *mb; - uint32_t n; - ma = (uint32_t *)origdata; - mb = data; - for (n = 0; n < count; n++) - { - if (tif->tif_flags & TIFF_SWAB) - TIFFSwabLong(ma); - err = TIFFReadDirEntryCheckRangeSshortLong(*ma); - if (err != TIFFReadDirEntryErrOk) - break; - *mb++ = (int16_t)(*ma++); - } - } - break; - case TIFF_SLONG: - { - int32_t *ma; - int16_t *mb; - uint32_t n; - ma = (int32_t *)origdata; - mb = data; - for (n = 0; n < count; n++) - { - if (tif->tif_flags & TIFF_SWAB) - TIFFSwabLong((uint32_t *)ma); - err = TIFFReadDirEntryCheckRangeSshortSlong(*ma); - if (err != TIFFReadDirEntryErrOk) - break; - *mb++ = (int16_t)(*ma++); - } - } - break; - case TIFF_LONG8: - { - uint64_t *ma; - int16_t *mb; - uint32_t n; - ma = (uint64_t *)origdata; - mb = data; - for (n = 0; n < count; n++) - { - if (tif->tif_flags & TIFF_SWAB) - TIFFSwabLong8(ma); - err = TIFFReadDirEntryCheckRangeSshortLong8(*ma); - if (err != TIFFReadDirEntryErrOk) - break; - *mb++ = (int16_t)(*ma++); - } - } - break; - case TIFF_SLONG8: - { - int64_t *ma; - int16_t *mb; - uint32_t n; - ma = (int64_t *)origdata; - mb = data; - for (n = 0; n < count; n++) - { - if (tif->tif_flags & TIFF_SWAB) - TIFFSwabLong8((uint64_t *)ma); - err = TIFFReadDirEntryCheckRangeSshortSlong8(*ma); - if (err != TIFFReadDirEntryErrOk) - break; - *mb++ = (int16_t)(*ma++); - } - } - break; - } - _TIFFfreeExt(tif, origdata); - if (err != TIFFReadDirEntryErrOk) - { - _TIFFfreeExt(tif, data); - return (err); - } - *value = data; - return (TIFFReadDirEntryErrOk); -} - -static enum TIFFReadDirEntryErr -TIFFReadDirEntryLongArray(TIFF *tif, TIFFDirEntry *direntry, uint32_t **value) -{ - enum TIFFReadDirEntryErr err; - uint32_t count; - void *origdata; - uint32_t *data; - switch (direntry->tdir_type) - { - case TIFF_BYTE: - case TIFF_SBYTE: - case TIFF_SHORT: - case TIFF_SSHORT: - case TIFF_LONG: - case TIFF_SLONG: - case TIFF_LONG8: - case TIFF_SLONG8: - break; - default: - return (TIFFReadDirEntryErrType); - } - err = TIFFReadDirEntryArray(tif, direntry, &count, 4, &origdata); - if ((err != TIFFReadDirEntryErrOk) || (origdata == 0)) - { - *value = 0; - return (err); - } - switch (direntry->tdir_type) - { - case TIFF_LONG: - *value = (uint32_t *)origdata; - if (tif->tif_flags & TIFF_SWAB) - TIFFSwabArrayOfLong(*value, count); - return (TIFFReadDirEntryErrOk); - case TIFF_SLONG: - { - int32_t *m; - uint32_t n; - m = (int32_t *)origdata; - for (n = 0; n < count; n++) - { - if (tif->tif_flags & TIFF_SWAB) - TIFFSwabLong((uint32_t *)m); - err = TIFFReadDirEntryCheckRangeLongSlong(*m); - if (err != TIFFReadDirEntryErrOk) - { - _TIFFfreeExt(tif, origdata); - return (err); - } - m++; - } - *value = (uint32_t *)origdata; - return (TIFFReadDirEntryErrOk); - } - } - data = (uint32_t *)_TIFFmallocExt(tif, count * 4); - if (data == 0) - { - _TIFFfreeExt(tif, origdata); - return (TIFFReadDirEntryErrAlloc); - } - switch (direntry->tdir_type) - { - case TIFF_BYTE: - { - uint8_t *ma; - uint32_t *mb; - uint32_t n; - ma = (uint8_t *)origdata; - mb = data; - for (n = 0; n < count; n++) - *mb++ = (uint32_t)(*ma++); - } - break; - case TIFF_SBYTE: - { - int8_t *ma; - uint32_t *mb; - uint32_t n; - ma = (int8_t *)origdata; - mb = data; - for (n = 0; n < count; n++) - { - err = TIFFReadDirEntryCheckRangeLongSbyte(*ma); - if (err != TIFFReadDirEntryErrOk) - break; - *mb++ = (uint32_t)(*ma++); - } - } - break; - case TIFF_SHORT: - { - uint16_t *ma; - uint32_t *mb; - uint32_t n; - ma = (uint16_t *)origdata; - mb = data; - for (n = 0; n < count; n++) - { - if (tif->tif_flags & TIFF_SWAB) - TIFFSwabShort(ma); - *mb++ = (uint32_t)(*ma++); - } - } - break; - case TIFF_SSHORT: - { - int16_t *ma; - uint32_t *mb; - uint32_t n; - ma = (int16_t *)origdata; - mb = data; - for (n = 0; n < count; n++) - { - if (tif->tif_flags & TIFF_SWAB) - TIFFSwabShort((uint16_t *)ma); - err = TIFFReadDirEntryCheckRangeLongSshort(*ma); - if (err != TIFFReadDirEntryErrOk) - break; - *mb++ = (uint32_t)(*ma++); - } - } - break; - case TIFF_LONG8: - { - uint64_t *ma; - uint32_t *mb; - uint32_t n; - ma = (uint64_t *)origdata; - mb = data; - for (n = 0; n < count; n++) - { - if (tif->tif_flags & TIFF_SWAB) - TIFFSwabLong8(ma); - err = TIFFReadDirEntryCheckRangeLongLong8(*ma); - if (err != TIFFReadDirEntryErrOk) - break; - *mb++ = (uint32_t)(*ma++); - } - } - break; - case TIFF_SLONG8: - { - int64_t *ma; - uint32_t *mb; - uint32_t n; - ma = (int64_t *)origdata; - mb = data; - for (n = 0; n < count; n++) - { - if (tif->tif_flags & TIFF_SWAB) - TIFFSwabLong8((uint64_t *)ma); - err = TIFFReadDirEntryCheckRangeLongSlong8(*ma); - if (err != TIFFReadDirEntryErrOk) - break; - *mb++ = (uint32_t)(*ma++); - } - } - break; - } - _TIFFfreeExt(tif, origdata); - if (err != TIFFReadDirEntryErrOk) - { - _TIFFfreeExt(tif, data); - return (err); - } - *value = data; - return (TIFFReadDirEntryErrOk); -} - -static enum TIFFReadDirEntryErr -TIFFReadDirEntrySlongArray(TIFF *tif, TIFFDirEntry *direntry, int32_t **value) -{ - enum TIFFReadDirEntryErr err; - uint32_t count; - void *origdata; - int32_t *data; - switch (direntry->tdir_type) - { - case TIFF_BYTE: - case TIFF_SBYTE: - case TIFF_SHORT: - case TIFF_SSHORT: - case TIFF_LONG: - case TIFF_SLONG: - case TIFF_LONG8: - case TIFF_SLONG8: - break; - default: - return (TIFFReadDirEntryErrType); - } - err = TIFFReadDirEntryArray(tif, direntry, &count, 4, &origdata); - if ((err != TIFFReadDirEntryErrOk) || (origdata == 0)) - { - *value = 0; - return (err); - } - switch (direntry->tdir_type) - { - case TIFF_LONG: - { - uint32_t *m; - uint32_t n; - m = (uint32_t *)origdata; - for (n = 0; n < count; n++) - { - if (tif->tif_flags & TIFF_SWAB) - TIFFSwabLong((uint32_t *)m); - err = TIFFReadDirEntryCheckRangeSlongLong(*m); - if (err != TIFFReadDirEntryErrOk) - { - _TIFFfreeExt(tif, origdata); - return (err); - } - m++; - } - *value = (int32_t *)origdata; - return (TIFFReadDirEntryErrOk); - } - case TIFF_SLONG: - *value = (int32_t *)origdata; - if (tif->tif_flags & TIFF_SWAB) - TIFFSwabArrayOfLong((uint32_t *)(*value), count); - return (TIFFReadDirEntryErrOk); - } - data = (int32_t *)_TIFFmallocExt(tif, count * 4); - if (data == 0) - { - _TIFFfreeExt(tif, origdata); - return (TIFFReadDirEntryErrAlloc); - } - switch (direntry->tdir_type) - { - case TIFF_BYTE: - { - uint8_t *ma; - int32_t *mb; - uint32_t n; - ma = (uint8_t *)origdata; - mb = data; - for (n = 0; n < count; n++) - *mb++ = (int32_t)(*ma++); - } - break; - case TIFF_SBYTE: - { - int8_t *ma; - int32_t *mb; - uint32_t n; - ma = (int8_t *)origdata; - mb = data; - for (n = 0; n < count; n++) - *mb++ = (int32_t)(*ma++); - } - break; - case TIFF_SHORT: - { - uint16_t *ma; - int32_t *mb; - uint32_t n; - ma = (uint16_t *)origdata; - mb = data; - for (n = 0; n < count; n++) - { - if (tif->tif_flags & TIFF_SWAB) - TIFFSwabShort(ma); - *mb++ = (int32_t)(*ma++); - } - } - break; - case TIFF_SSHORT: - { - int16_t *ma; - int32_t *mb; - uint32_t n; - ma = (int16_t *)origdata; - mb = data; - for (n = 0; n < count; n++) - { - if (tif->tif_flags & TIFF_SWAB) - TIFFSwabShort((uint16_t *)ma); - *mb++ = (int32_t)(*ma++); - } - } - break; - case TIFF_LONG8: - { - uint64_t *ma; - int32_t *mb; - uint32_t n; - ma = (uint64_t *)origdata; - mb = data; - for (n = 0; n < count; n++) - { - if (tif->tif_flags & TIFF_SWAB) - TIFFSwabLong8(ma); - err = TIFFReadDirEntryCheckRangeSlongLong8(*ma); - if (err != TIFFReadDirEntryErrOk) - break; - *mb++ = (int32_t)(*ma++); - } - } - break; - case TIFF_SLONG8: - { - int64_t *ma; - int32_t *mb; - uint32_t n; - ma = (int64_t *)origdata; - mb = data; - for (n = 0; n < count; n++) - { - if (tif->tif_flags & TIFF_SWAB) - TIFFSwabLong8((uint64_t *)ma); - err = TIFFReadDirEntryCheckRangeSlongSlong8(*ma); - if (err != TIFFReadDirEntryErrOk) - break; - *mb++ = (int32_t)(*ma++); - } - } - break; - } - _TIFFfreeExt(tif, origdata); - if (err != TIFFReadDirEntryErrOk) - { - _TIFFfreeExt(tif, data); - return (err); - } - *value = data; - return (TIFFReadDirEntryErrOk); -} - -static enum TIFFReadDirEntryErr -TIFFReadDirEntryLong8ArrayWithLimit(TIFF *tif, TIFFDirEntry *direntry, - uint64_t **value, uint64_t maxcount) -{ - enum TIFFReadDirEntryErr err; - uint32_t count; - void *origdata; - uint64_t *data; - switch (direntry->tdir_type) - { - case TIFF_BYTE: - case TIFF_SBYTE: - case TIFF_SHORT: - case TIFF_SSHORT: - case TIFF_LONG: - case TIFF_SLONG: - case TIFF_LONG8: - case TIFF_SLONG8: - break; - default: - return (TIFFReadDirEntryErrType); - } - err = TIFFReadDirEntryArrayWithLimit(tif, direntry, &count, 8, &origdata, - maxcount); - if ((err != TIFFReadDirEntryErrOk) || (origdata == 0)) - { - *value = 0; - return (err); - } - switch (direntry->tdir_type) - { - case TIFF_LONG8: - *value = (uint64_t *)origdata; - if (tif->tif_flags & TIFF_SWAB) - TIFFSwabArrayOfLong8(*value, count); - return (TIFFReadDirEntryErrOk); - case TIFF_SLONG8: - { - int64_t *m; - uint32_t n; - m = (int64_t *)origdata; - for (n = 0; n < count; n++) - { - if (tif->tif_flags & TIFF_SWAB) - TIFFSwabLong8((uint64_t *)m); - err = TIFFReadDirEntryCheckRangeLong8Slong8(*m); - if (err != TIFFReadDirEntryErrOk) - { - _TIFFfreeExt(tif, origdata); - return (err); - } - m++; - } - *value = (uint64_t *)origdata; - return (TIFFReadDirEntryErrOk); - } - } - data = (uint64_t *)_TIFFmallocExt(tif, count * 8); - if (data == 0) - { - _TIFFfreeExt(tif, origdata); - return (TIFFReadDirEntryErrAlloc); - } - switch (direntry->tdir_type) - { - case TIFF_BYTE: - { - uint8_t *ma; - uint64_t *mb; - uint32_t n; - ma = (uint8_t *)origdata; - mb = data; - for (n = 0; n < count; n++) - *mb++ = (uint64_t)(*ma++); - } - break; - case TIFF_SBYTE: - { - int8_t *ma; - uint64_t *mb; - uint32_t n; - ma = (int8_t *)origdata; - mb = data; - for (n = 0; n < count; n++) - { - err = TIFFReadDirEntryCheckRangeLong8Sbyte(*ma); - if (err != TIFFReadDirEntryErrOk) - break; - *mb++ = (uint64_t)(*ma++); - } - } - break; - case TIFF_SHORT: - { - uint16_t *ma; - uint64_t *mb; - uint32_t n; - ma = (uint16_t *)origdata; - mb = data; - for (n = 0; n < count; n++) - { - if (tif->tif_flags & TIFF_SWAB) - TIFFSwabShort(ma); - *mb++ = (uint64_t)(*ma++); - } - } - break; - case TIFF_SSHORT: - { - int16_t *ma; - uint64_t *mb; - uint32_t n; - ma = (int16_t *)origdata; - mb = data; - for (n = 0; n < count; n++) - { - if (tif->tif_flags & TIFF_SWAB) - TIFFSwabShort((uint16_t *)ma); - err = TIFFReadDirEntryCheckRangeLong8Sshort(*ma); - if (err != TIFFReadDirEntryErrOk) - break; - *mb++ = (uint64_t)(*ma++); - } - } - break; - case TIFF_LONG: - { - uint32_t *ma; - uint64_t *mb; - uint32_t n; - ma = (uint32_t *)origdata; - mb = data; - for (n = 0; n < count; n++) - { - if (tif->tif_flags & TIFF_SWAB) - TIFFSwabLong(ma); - *mb++ = (uint64_t)(*ma++); - } - } - break; - case TIFF_SLONG: - { - int32_t *ma; - uint64_t *mb; - uint32_t n; - ma = (int32_t *)origdata; - mb = data; - for (n = 0; n < count; n++) - { - if (tif->tif_flags & TIFF_SWAB) - TIFFSwabLong((uint32_t *)ma); - err = TIFFReadDirEntryCheckRangeLong8Slong(*ma); - if (err != TIFFReadDirEntryErrOk) - break; - *mb++ = (uint64_t)(*ma++); - } - } - break; - } - _TIFFfreeExt(tif, origdata); - if (err != TIFFReadDirEntryErrOk) - { - _TIFFfreeExt(tif, data); - return (err); - } - *value = data; - return (TIFFReadDirEntryErrOk); -} - -static enum TIFFReadDirEntryErr -TIFFReadDirEntryLong8Array(TIFF *tif, TIFFDirEntry *direntry, uint64_t **value) -{ - return TIFFReadDirEntryLong8ArrayWithLimit(tif, direntry, value, - ~((uint64_t)0)); -} - -static enum TIFFReadDirEntryErr -TIFFReadDirEntrySlong8Array(TIFF *tif, TIFFDirEntry *direntry, int64_t **value) -{ - enum TIFFReadDirEntryErr err; - uint32_t count; - void *origdata; - int64_t *data; - switch (direntry->tdir_type) - { - case TIFF_BYTE: - case TIFF_SBYTE: - case TIFF_SHORT: - case TIFF_SSHORT: - case TIFF_LONG: - case TIFF_SLONG: - case TIFF_LONG8: - case TIFF_SLONG8: - break; - default: - return (TIFFReadDirEntryErrType); - } - err = TIFFReadDirEntryArray(tif, direntry, &count, 8, &origdata); - if ((err != TIFFReadDirEntryErrOk) || (origdata == 0)) - { - *value = 0; - return (err); - } - switch (direntry->tdir_type) - { - case TIFF_LONG8: - { - uint64_t *m; - uint32_t n; - m = (uint64_t *)origdata; - for (n = 0; n < count; n++) - { - if (tif->tif_flags & TIFF_SWAB) - TIFFSwabLong8(m); - err = TIFFReadDirEntryCheckRangeSlong8Long8(*m); - if (err != TIFFReadDirEntryErrOk) - { - _TIFFfreeExt(tif, origdata); - return (err); - } - m++; - } - *value = (int64_t *)origdata; - return (TIFFReadDirEntryErrOk); - } - case TIFF_SLONG8: - *value = (int64_t *)origdata; - if (tif->tif_flags & TIFF_SWAB) - TIFFSwabArrayOfLong8((uint64_t *)(*value), count); - return (TIFFReadDirEntryErrOk); - } - data = (int64_t *)_TIFFmallocExt(tif, count * 8); - if (data == 0) - { - _TIFFfreeExt(tif, origdata); - return (TIFFReadDirEntryErrAlloc); - } - switch (direntry->tdir_type) - { - case TIFF_BYTE: - { - uint8_t *ma; - int64_t *mb; - uint32_t n; - ma = (uint8_t *)origdata; - mb = data; - for (n = 0; n < count; n++) - *mb++ = (int64_t)(*ma++); - } - break; - case TIFF_SBYTE: - { - int8_t *ma; - int64_t *mb; - uint32_t n; - ma = (int8_t *)origdata; - mb = data; - for (n = 0; n < count; n++) - *mb++ = (int64_t)(*ma++); - } - break; - case TIFF_SHORT: - { - uint16_t *ma; - int64_t *mb; - uint32_t n; - ma = (uint16_t *)origdata; - mb = data; - for (n = 0; n < count; n++) - { - if (tif->tif_flags & TIFF_SWAB) - TIFFSwabShort(ma); - *mb++ = (int64_t)(*ma++); - } - } - break; - case TIFF_SSHORT: - { - int16_t *ma; - int64_t *mb; - uint32_t n; - ma = (int16_t *)origdata; - mb = data; - for (n = 0; n < count; n++) - { - if (tif->tif_flags & TIFF_SWAB) - TIFFSwabShort((uint16_t *)ma); - *mb++ = (int64_t)(*ma++); - } - } - break; - case TIFF_LONG: - { - uint32_t *ma; - int64_t *mb; - uint32_t n; - ma = (uint32_t *)origdata; - mb = data; - for (n = 0; n < count; n++) - { - if (tif->tif_flags & TIFF_SWAB) - TIFFSwabLong(ma); - *mb++ = (int64_t)(*ma++); - } - } - break; - case TIFF_SLONG: - { - int32_t *ma; - int64_t *mb; - uint32_t n; - ma = (int32_t *)origdata; - mb = data; - for (n = 0; n < count; n++) - { - if (tif->tif_flags & TIFF_SWAB) - TIFFSwabLong((uint32_t *)ma); - *mb++ = (int64_t)(*ma++); - } - } - break; - } - _TIFFfreeExt(tif, origdata); - *value = data; - return (TIFFReadDirEntryErrOk); -} - -static enum TIFFReadDirEntryErr -TIFFReadDirEntryFloatArray(TIFF *tif, TIFFDirEntry *direntry, float **value) -{ - enum TIFFReadDirEntryErr err; - uint32_t count; - void *origdata; - float *data; - switch (direntry->tdir_type) - { - case TIFF_BYTE: - case TIFF_SBYTE: - case TIFF_SHORT: - case TIFF_SSHORT: - case TIFF_LONG: - case TIFF_SLONG: - case TIFF_LONG8: - case TIFF_SLONG8: - case TIFF_RATIONAL: - case TIFF_SRATIONAL: - case TIFF_FLOAT: - case TIFF_DOUBLE: - break; - default: - return (TIFFReadDirEntryErrType); - } - err = TIFFReadDirEntryArray(tif, direntry, &count, 4, &origdata); - if ((err != TIFFReadDirEntryErrOk) || (origdata == 0)) - { - *value = 0; - return (err); - } - switch (direntry->tdir_type) - { - case TIFF_FLOAT: - if (tif->tif_flags & TIFF_SWAB) - TIFFSwabArrayOfLong((uint32_t *)origdata, count); - TIFFCvtIEEEFloatToNative(tif, count, (float *)origdata); - *value = (float *)origdata; - return (TIFFReadDirEntryErrOk); - } - data = (float *)_TIFFmallocExt(tif, count * sizeof(float)); - if (data == 0) - { - _TIFFfreeExt(tif, origdata); - return (TIFFReadDirEntryErrAlloc); - } - switch (direntry->tdir_type) - { - case TIFF_BYTE: - { - uint8_t *ma; - float *mb; - uint32_t n; - ma = (uint8_t *)origdata; - mb = data; - for (n = 0; n < count; n++) - *mb++ = (float)(*ma++); - } - break; - case TIFF_SBYTE: - { - int8_t *ma; - float *mb; - uint32_t n; - ma = (int8_t *)origdata; - mb = data; - for (n = 0; n < count; n++) - *mb++ = (float)(*ma++); - } - break; - case TIFF_SHORT: - { - uint16_t *ma; - float *mb; - uint32_t n; - ma = (uint16_t *)origdata; - mb = data; - for (n = 0; n < count; n++) - { - if (tif->tif_flags & TIFF_SWAB) - TIFFSwabShort(ma); - *mb++ = (float)(*ma++); - } - } - break; - case TIFF_SSHORT: - { - int16_t *ma; - float *mb; - uint32_t n; - ma = (int16_t *)origdata; - mb = data; - for (n = 0; n < count; n++) - { - if (tif->tif_flags & TIFF_SWAB) - TIFFSwabShort((uint16_t *)ma); - *mb++ = (float)(*ma++); - } - } - break; - case TIFF_LONG: - { - uint32_t *ma; - float *mb; - uint32_t n; - ma = (uint32_t *)origdata; - mb = data; - for (n = 0; n < count; n++) - { - if (tif->tif_flags & TIFF_SWAB) - TIFFSwabLong(ma); - *mb++ = (float)(*ma++); - } - } - break; - case TIFF_SLONG: - { - int32_t *ma; - float *mb; - uint32_t n; - ma = (int32_t *)origdata; - mb = data; - for (n = 0; n < count; n++) - { - if (tif->tif_flags & TIFF_SWAB) - TIFFSwabLong((uint32_t *)ma); - *mb++ = (float)(*ma++); - } - } - break; - case TIFF_LONG8: - { - uint64_t *ma; - float *mb; - uint32_t n; - ma = (uint64_t *)origdata; - mb = data; - for (n = 0; n < count; n++) - { - if (tif->tif_flags & TIFF_SWAB) - TIFFSwabLong8(ma); -#if defined(__WIN32__) && (_MSC_VER < 1500) - /* - * XXX: MSVC 6.0 does not support - * conversion of 64-bit integers into - * floating point values. - */ - *mb++ = _TIFFUInt64ToFloat(*ma++); -#else - *mb++ = (float)(*ma++); -#endif - } - } - break; - case TIFF_SLONG8: - { - int64_t *ma; - float *mb; - uint32_t n; - ma = (int64_t *)origdata; - mb = data; - for (n = 0; n < count; n++) - { - if (tif->tif_flags & TIFF_SWAB) - TIFFSwabLong8((uint64_t *)ma); - *mb++ = (float)(*ma++); - } - } - break; - case TIFF_RATIONAL: - { - uint32_t *ma; - uint32_t maa; - uint32_t mab; - float *mb; - uint32_t n; - ma = (uint32_t *)origdata; - mb = data; - for (n = 0; n < count; n++) - { - if (tif->tif_flags & TIFF_SWAB) - TIFFSwabLong(ma); - maa = *ma++; - if (tif->tif_flags & TIFF_SWAB) - TIFFSwabLong(ma); - mab = *ma++; - if (mab == 0) - *mb++ = 0.0; - else - *mb++ = (float)maa / (float)mab; - } - } - break; - case TIFF_SRATIONAL: - { - uint32_t *ma; - int32_t maa; - uint32_t mab; - float *mb; - uint32_t n; - ma = (uint32_t *)origdata; - mb = data; - for (n = 0; n < count; n++) - { - if (tif->tif_flags & TIFF_SWAB) - TIFFSwabLong(ma); - maa = *(int32_t *)ma; - ma++; - if (tif->tif_flags & TIFF_SWAB) - TIFFSwabLong(ma); - mab = *ma++; - if (mab == 0) - *mb++ = 0.0; - else - *mb++ = (float)maa / (float)mab; - } - } - break; - case TIFF_DOUBLE: - { - double *ma; - float *mb; - uint32_t n; - if (tif->tif_flags & TIFF_SWAB) - TIFFSwabArrayOfLong8((uint64_t *)origdata, count); - TIFFCvtIEEEDoubleToNative(tif, count, (double *)origdata); - ma = (double *)origdata; - mb = data; - for (n = 0; n < count; n++) - { - double val = *ma++; - if (val > FLT_MAX) - val = FLT_MAX; - else if (val < -FLT_MAX) - val = -FLT_MAX; - *mb++ = (float)val; - } - } - break; - } - _TIFFfreeExt(tif, origdata); - *value = data; - return (TIFFReadDirEntryErrOk); -} - -static enum TIFFReadDirEntryErr -TIFFReadDirEntryDoubleArray(TIFF *tif, TIFFDirEntry *direntry, double **value) -{ - enum TIFFReadDirEntryErr err; - uint32_t count; - void *origdata; - double *data; - switch (direntry->tdir_type) - { - case TIFF_BYTE: - case TIFF_SBYTE: - case TIFF_SHORT: - case TIFF_SSHORT: - case TIFF_LONG: - case TIFF_SLONG: - case TIFF_LONG8: - case TIFF_SLONG8: - case TIFF_RATIONAL: - case TIFF_SRATIONAL: - case TIFF_FLOAT: - case TIFF_DOUBLE: - break; - default: - return (TIFFReadDirEntryErrType); - } - err = TIFFReadDirEntryArray(tif, direntry, &count, 8, &origdata); - if ((err != TIFFReadDirEntryErrOk) || (origdata == 0)) - { - *value = 0; - return (err); - } - switch (direntry->tdir_type) - { - case TIFF_DOUBLE: - if (tif->tif_flags & TIFF_SWAB) - TIFFSwabArrayOfLong8((uint64_t *)origdata, count); - TIFFCvtIEEEDoubleToNative(tif, count, (double *)origdata); - *value = (double *)origdata; - return (TIFFReadDirEntryErrOk); - } - data = (double *)_TIFFmallocExt(tif, count * sizeof(double)); - if (data == 0) - { - _TIFFfreeExt(tif, origdata); - return (TIFFReadDirEntryErrAlloc); - } - switch (direntry->tdir_type) - { - case TIFF_BYTE: - { - uint8_t *ma; - double *mb; - uint32_t n; - ma = (uint8_t *)origdata; - mb = data; - for (n = 0; n < count; n++) - *mb++ = (double)(*ma++); - } - break; - case TIFF_SBYTE: - { - int8_t *ma; - double *mb; - uint32_t n; - ma = (int8_t *)origdata; - mb = data; - for (n = 0; n < count; n++) - *mb++ = (double)(*ma++); - } - break; - case TIFF_SHORT: - { - uint16_t *ma; - double *mb; - uint32_t n; - ma = (uint16_t *)origdata; - mb = data; - for (n = 0; n < count; n++) - { - if (tif->tif_flags & TIFF_SWAB) - TIFFSwabShort(ma); - *mb++ = (double)(*ma++); - } - } - break; - case TIFF_SSHORT: - { - int16_t *ma; - double *mb; - uint32_t n; - ma = (int16_t *)origdata; - mb = data; - for (n = 0; n < count; n++) - { - if (tif->tif_flags & TIFF_SWAB) - TIFFSwabShort((uint16_t *)ma); - *mb++ = (double)(*ma++); - } - } - break; - case TIFF_LONG: - { - uint32_t *ma; - double *mb; - uint32_t n; - ma = (uint32_t *)origdata; - mb = data; - for (n = 0; n < count; n++) - { - if (tif->tif_flags & TIFF_SWAB) - TIFFSwabLong(ma); - *mb++ = (double)(*ma++); - } - } - break; - case TIFF_SLONG: - { - int32_t *ma; - double *mb; - uint32_t n; - ma = (int32_t *)origdata; - mb = data; - for (n = 0; n < count; n++) - { - if (tif->tif_flags & TIFF_SWAB) - TIFFSwabLong((uint32_t *)ma); - *mb++ = (double)(*ma++); - } - } - break; - case TIFF_LONG8: - { - uint64_t *ma; - double *mb; - uint32_t n; - ma = (uint64_t *)origdata; - mb = data; - for (n = 0; n < count; n++) - { - if (tif->tif_flags & TIFF_SWAB) - TIFFSwabLong8(ma); -#if defined(__WIN32__) && (_MSC_VER < 1500) - /* - * XXX: MSVC 6.0 does not support - * conversion of 64-bit integers into - * floating point values. - */ - *mb++ = _TIFFUInt64ToDouble(*ma++); -#else - *mb++ = (double)(*ma++); -#endif - } - } - break; - case TIFF_SLONG8: - { - int64_t *ma; - double *mb; - uint32_t n; - ma = (int64_t *)origdata; - mb = data; - for (n = 0; n < count; n++) - { - if (tif->tif_flags & TIFF_SWAB) - TIFFSwabLong8((uint64_t *)ma); - *mb++ = (double)(*ma++); - } - } - break; - case TIFF_RATIONAL: - { - uint32_t *ma; - uint32_t maa; - uint32_t mab; - double *mb; - uint32_t n; - ma = (uint32_t *)origdata; - mb = data; - for (n = 0; n < count; n++) - { - if (tif->tif_flags & TIFF_SWAB) - TIFFSwabLong(ma); - maa = *ma++; - if (tif->tif_flags & TIFF_SWAB) - TIFFSwabLong(ma); - mab = *ma++; - if (mab == 0) - *mb++ = 0.0; - else - *mb++ = (double)maa / (double)mab; - } - } - break; - case TIFF_SRATIONAL: - { - uint32_t *ma; - int32_t maa; - uint32_t mab; - double *mb; - uint32_t n; - ma = (uint32_t *)origdata; - mb = data; - for (n = 0; n < count; n++) - { - if (tif->tif_flags & TIFF_SWAB) - TIFFSwabLong(ma); - maa = *(int32_t *)ma; - ma++; - if (tif->tif_flags & TIFF_SWAB) - TIFFSwabLong(ma); - mab = *ma++; - if (mab == 0) - *mb++ = 0.0; - else - *mb++ = (double)maa / (double)mab; - } - } - break; - case TIFF_FLOAT: - { - float *ma; - double *mb; - uint32_t n; - if (tif->tif_flags & TIFF_SWAB) - TIFFSwabArrayOfLong((uint32_t *)origdata, count); - TIFFCvtIEEEFloatToNative(tif, count, (float *)origdata); - ma = (float *)origdata; - mb = data; - for (n = 0; n < count; n++) - *mb++ = (double)(*ma++); - } - break; - } - _TIFFfreeExt(tif, origdata); - *value = data; - return (TIFFReadDirEntryErrOk); -} - -static enum TIFFReadDirEntryErr -TIFFReadDirEntryIfd8Array(TIFF *tif, TIFFDirEntry *direntry, uint64_t **value) -{ - enum TIFFReadDirEntryErr err; - uint32_t count; - void *origdata; - uint64_t *data; - switch (direntry->tdir_type) - { - case TIFF_LONG: - case TIFF_LONG8: - case TIFF_IFD: - case TIFF_IFD8: - break; - default: - return (TIFFReadDirEntryErrType); - } - err = TIFFReadDirEntryArray(tif, direntry, &count, 8, &origdata); - if ((err != TIFFReadDirEntryErrOk) || (origdata == 0)) - { - *value = 0; - return (err); - } - switch (direntry->tdir_type) - { - case TIFF_LONG8: - case TIFF_IFD8: - *value = (uint64_t *)origdata; - if (tif->tif_flags & TIFF_SWAB) - TIFFSwabArrayOfLong8(*value, count); - return (TIFFReadDirEntryErrOk); - } - data = (uint64_t *)_TIFFmallocExt(tif, count * 8); - if (data == 0) - { - _TIFFfreeExt(tif, origdata); - return (TIFFReadDirEntryErrAlloc); - } - switch (direntry->tdir_type) - { - case TIFF_LONG: - case TIFF_IFD: - { - uint32_t *ma; - uint64_t *mb; - uint32_t n; - ma = (uint32_t *)origdata; - mb = data; - for (n = 0; n < count; n++) - { - if (tif->tif_flags & TIFF_SWAB) - TIFFSwabLong(ma); - *mb++ = (uint64_t)(*ma++); - } - } - break; - } - _TIFFfreeExt(tif, origdata); - *value = data; - return (TIFFReadDirEntryErrOk); -} - -static enum TIFFReadDirEntryErr -TIFFReadDirEntryPersampleShort(TIFF *tif, TIFFDirEntry *direntry, - uint16_t *value) -{ - enum TIFFReadDirEntryErr err; - uint16_t *m; - uint16_t *na; - uint16_t nb; - if (direntry->tdir_count < (uint64_t)tif->tif_dir.td_samplesperpixel) - return (TIFFReadDirEntryErrCount); - err = TIFFReadDirEntryShortArray(tif, direntry, &m); - if (err != TIFFReadDirEntryErrOk || m == NULL) - return (err); - na = m; - nb = tif->tif_dir.td_samplesperpixel; - *value = *na++; - nb--; - while (nb > 0) - { - if (*na++ != *value) - { - err = TIFFReadDirEntryErrPsdif; - break; - } - nb--; - } - _TIFFfreeExt(tif, m); - return (err); -} - -static void TIFFReadDirEntryCheckedByte(TIFF *tif, TIFFDirEntry *direntry, - uint8_t *value) -{ - (void)tif; - *value = *(uint8_t *)(&direntry->tdir_offset); -} - -static void TIFFReadDirEntryCheckedSbyte(TIFF *tif, TIFFDirEntry *direntry, - int8_t *value) -{ - (void)tif; - *value = *(int8_t *)(&direntry->tdir_offset); -} - -static void TIFFReadDirEntryCheckedShort(TIFF *tif, TIFFDirEntry *direntry, - uint16_t *value) -{ - *value = direntry->tdir_offset.toff_short; - /* *value=*(uint16_t*)(&direntry->tdir_offset); */ - if (tif->tif_flags & TIFF_SWAB) - TIFFSwabShort(value); -} - -static void TIFFReadDirEntryCheckedSshort(TIFF *tif, TIFFDirEntry *direntry, - int16_t *value) -{ - *value = *(int16_t *)(&direntry->tdir_offset); - if (tif->tif_flags & TIFF_SWAB) - TIFFSwabShort((uint16_t *)value); -} - -static void TIFFReadDirEntryCheckedLong(TIFF *tif, TIFFDirEntry *direntry, - uint32_t *value) -{ - *value = *(uint32_t *)(&direntry->tdir_offset); - if (tif->tif_flags & TIFF_SWAB) - TIFFSwabLong(value); -} - -static void TIFFReadDirEntryCheckedSlong(TIFF *tif, TIFFDirEntry *direntry, - int32_t *value) -{ - *value = *(int32_t *)(&direntry->tdir_offset); - if (tif->tif_flags & TIFF_SWAB) - TIFFSwabLong((uint32_t *)value); -} - -static enum TIFFReadDirEntryErr -TIFFReadDirEntryCheckedLong8(TIFF *tif, TIFFDirEntry *direntry, uint64_t *value) -{ - if (!(tif->tif_flags & TIFF_BIGTIFF)) - { - enum TIFFReadDirEntryErr err; - uint32_t offset = direntry->tdir_offset.toff_long; - if (tif->tif_flags & TIFF_SWAB) - TIFFSwabLong(&offset); - err = TIFFReadDirEntryData(tif, offset, 8, value); - if (err != TIFFReadDirEntryErrOk) - return (err); - } - else - *value = direntry->tdir_offset.toff_long8; - if (tif->tif_flags & TIFF_SWAB) - TIFFSwabLong8(value); - return (TIFFReadDirEntryErrOk); -} - -static enum TIFFReadDirEntryErr -TIFFReadDirEntryCheckedSlong8(TIFF *tif, TIFFDirEntry *direntry, int64_t *value) -{ - if (!(tif->tif_flags & TIFF_BIGTIFF)) - { - enum TIFFReadDirEntryErr err; - uint32_t offset = direntry->tdir_offset.toff_long; - if (tif->tif_flags & TIFF_SWAB) - TIFFSwabLong(&offset); - err = TIFFReadDirEntryData(tif, offset, 8, value); - if (err != TIFFReadDirEntryErrOk) - return (err); - } - else - *value = *(int64_t *)(&direntry->tdir_offset); - if (tif->tif_flags & TIFF_SWAB) - TIFFSwabLong8((uint64_t *)value); - return (TIFFReadDirEntryErrOk); -} - -static enum TIFFReadDirEntryErr -TIFFReadDirEntryCheckedRational(TIFF *tif, TIFFDirEntry *direntry, - double *value) -{ - UInt64Aligned_t m; - - assert(sizeof(double) == 8); - assert(sizeof(uint64_t) == 8); - assert(sizeof(uint32_t) == 4); - if (!(tif->tif_flags & TIFF_BIGTIFF)) - { - enum TIFFReadDirEntryErr err; - uint32_t offset = direntry->tdir_offset.toff_long; - if (tif->tif_flags & TIFF_SWAB) - TIFFSwabLong(&offset); - err = TIFFReadDirEntryData(tif, offset, 8, m.i); - if (err != TIFFReadDirEntryErrOk) - return (err); - } - else - m.l = direntry->tdir_offset.toff_long8; - if (tif->tif_flags & TIFF_SWAB) - TIFFSwabArrayOfLong(m.i, 2); - /* Not completely sure what we should do when m.i[1]==0, but some */ - /* sanitizers do not like division by 0.0: */ - /* http://bugzilla.maptools.org/show_bug.cgi?id=2644 */ - if (m.i[0] == 0 || m.i[1] == 0) - *value = 0.0; - else - *value = (double)m.i[0] / (double)m.i[1]; - return (TIFFReadDirEntryErrOk); -} - -static enum TIFFReadDirEntryErr -TIFFReadDirEntryCheckedSrational(TIFF *tif, TIFFDirEntry *direntry, - double *value) -{ - UInt64Aligned_t m; - assert(sizeof(double) == 8); - assert(sizeof(uint64_t) == 8); - assert(sizeof(int32_t) == 4); - assert(sizeof(uint32_t) == 4); - if (!(tif->tif_flags & TIFF_BIGTIFF)) - { - enum TIFFReadDirEntryErr err; - uint32_t offset = direntry->tdir_offset.toff_long; - if (tif->tif_flags & TIFF_SWAB) - TIFFSwabLong(&offset); - err = TIFFReadDirEntryData(tif, offset, 8, m.i); - if (err != TIFFReadDirEntryErrOk) - return (err); - } - else - m.l = direntry->tdir_offset.toff_long8; - if (tif->tif_flags & TIFF_SWAB) - TIFFSwabArrayOfLong(m.i, 2); - /* Not completely sure what we should do when m.i[1]==0, but some */ - /* sanitizers do not like division by 0.0: */ - /* http://bugzilla.maptools.org/show_bug.cgi?id=2644 */ - if ((int32_t)m.i[0] == 0 || m.i[1] == 0) - *value = 0.0; - else - *value = (double)((int32_t)m.i[0]) / (double)m.i[1]; - return (TIFFReadDirEntryErrOk); -} - -#if 0 -static enum TIFFReadDirEntryErr -TIFFReadDirEntryCheckedRationalDirect(TIFF *tif, TIFFDirEntry *direntry, - TIFFRational_t *value) -{ /*--: SetGetRATIONAL_directly:_CustomTag: Read rational (and signed rationals) - directly --*/ - UInt64Aligned_t m; - - assert(sizeof(double) == 8); - assert(sizeof(uint64_t) == 8); - assert(sizeof(uint32_t) == 4); - - if (direntry->tdir_count != 1) - return (TIFFReadDirEntryErrCount); - - if (direntry->tdir_type != TIFF_RATIONAL && - direntry->tdir_type != TIFF_SRATIONAL) - return (TIFFReadDirEntryErrType); - - if (!(tif->tif_flags & TIFF_BIGTIFF)) - { - enum TIFFReadDirEntryErr err; - uint32_t offset = direntry->tdir_offset.toff_long; - if (tif->tif_flags & TIFF_SWAB) - TIFFSwabLong(&offset); - err = TIFFReadDirEntryData(tif, offset, 8, m.i); - if (err != TIFFReadDirEntryErrOk) - return (err); - } - else - { - m.l = direntry->tdir_offset.toff_long8; - } - - if (tif->tif_flags & TIFF_SWAB) - TIFFSwabArrayOfLong(m.i, 2); - - value->uNum = m.i[0]; - value->uDenom = m.i[1]; - return (TIFFReadDirEntryErrOk); -} /*-- TIFFReadDirEntryCheckedRationalDirect() --*/ -#endif - -static void TIFFReadDirEntryCheckedFloat(TIFF *tif, TIFFDirEntry *direntry, - float *value) -{ - union - { - float f; - uint32_t i; - } float_union; - assert(sizeof(float) == 4); - assert(sizeof(uint32_t) == 4); - assert(sizeof(float_union) == 4); - float_union.i = *(uint32_t *)(&direntry->tdir_offset); - *value = float_union.f; - if (tif->tif_flags & TIFF_SWAB) - TIFFSwabLong((uint32_t *)value); -} - -static enum TIFFReadDirEntryErr -TIFFReadDirEntryCheckedDouble(TIFF *tif, TIFFDirEntry *direntry, double *value) -{ - assert(sizeof(double) == 8); - assert(sizeof(uint64_t) == 8); - assert(sizeof(UInt64Aligned_t) == 8); - if (!(tif->tif_flags & TIFF_BIGTIFF)) - { - enum TIFFReadDirEntryErr err; - uint32_t offset = direntry->tdir_offset.toff_long; - if (tif->tif_flags & TIFF_SWAB) - TIFFSwabLong(&offset); - err = TIFFReadDirEntryData(tif, offset, 8, value); - if (err != TIFFReadDirEntryErrOk) - return (err); - } - else - { - UInt64Aligned_t uint64_union; - uint64_union.l = direntry->tdir_offset.toff_long8; - *value = uint64_union.d; - } - if (tif->tif_flags & TIFF_SWAB) - TIFFSwabLong8((uint64_t *)value); - return (TIFFReadDirEntryErrOk); -} - -static enum TIFFReadDirEntryErr -TIFFReadDirEntryCheckRangeByteSbyte(int8_t value) -{ - if (value < 0) - return (TIFFReadDirEntryErrRange); - else - return (TIFFReadDirEntryErrOk); -} - -static enum TIFFReadDirEntryErr -TIFFReadDirEntryCheckRangeByteShort(uint16_t value) -{ - if (value > 0xFF) - return (TIFFReadDirEntryErrRange); - else - return (TIFFReadDirEntryErrOk); -} - -static enum TIFFReadDirEntryErr -TIFFReadDirEntryCheckRangeByteSshort(int16_t value) -{ - if ((value < 0) || (value > 0xFF)) - return (TIFFReadDirEntryErrRange); - else - return (TIFFReadDirEntryErrOk); -} - -static enum TIFFReadDirEntryErr -TIFFReadDirEntryCheckRangeByteLong(uint32_t value) -{ - if (value > 0xFF) - return (TIFFReadDirEntryErrRange); - else - return (TIFFReadDirEntryErrOk); -} - -static enum TIFFReadDirEntryErr -TIFFReadDirEntryCheckRangeByteSlong(int32_t value) -{ - if ((value < 0) || (value > 0xFF)) - return (TIFFReadDirEntryErrRange); - else - return (TIFFReadDirEntryErrOk); -} - -static enum TIFFReadDirEntryErr -TIFFReadDirEntryCheckRangeByteLong8(uint64_t value) -{ - if (value > 0xFF) - return (TIFFReadDirEntryErrRange); - else - return (TIFFReadDirEntryErrOk); -} - -static enum TIFFReadDirEntryErr -TIFFReadDirEntryCheckRangeByteSlong8(int64_t value) -{ - if ((value < 0) || (value > 0xFF)) - return (TIFFReadDirEntryErrRange); - else - return (TIFFReadDirEntryErrOk); -} - -static enum TIFFReadDirEntryErr -TIFFReadDirEntryCheckRangeSbyteByte(uint8_t value) -{ - if (value > 0x7F) - return (TIFFReadDirEntryErrRange); - else - return (TIFFReadDirEntryErrOk); -} - -static enum TIFFReadDirEntryErr -TIFFReadDirEntryCheckRangeSbyteShort(uint16_t value) -{ - if (value > 0x7F) - return (TIFFReadDirEntryErrRange); - else - return (TIFFReadDirEntryErrOk); -} - -static enum TIFFReadDirEntryErr -TIFFReadDirEntryCheckRangeSbyteSshort(int16_t value) -{ - if ((value < -0x80) || (value > 0x7F)) - return (TIFFReadDirEntryErrRange); - else - return (TIFFReadDirEntryErrOk); -} - -static enum TIFFReadDirEntryErr -TIFFReadDirEntryCheckRangeSbyteLong(uint32_t value) -{ - if (value > 0x7F) - return (TIFFReadDirEntryErrRange); - else - return (TIFFReadDirEntryErrOk); -} - -static enum TIFFReadDirEntryErr -TIFFReadDirEntryCheckRangeSbyteSlong(int32_t value) -{ - if ((value < -0x80) || (value > 0x7F)) - return (TIFFReadDirEntryErrRange); - else - return (TIFFReadDirEntryErrOk); -} - -static enum TIFFReadDirEntryErr -TIFFReadDirEntryCheckRangeSbyteLong8(uint64_t value) -{ - if (value > 0x7F) - return (TIFFReadDirEntryErrRange); - else - return (TIFFReadDirEntryErrOk); -} - -static enum TIFFReadDirEntryErr -TIFFReadDirEntryCheckRangeSbyteSlong8(int64_t value) -{ - if ((value < -0x80) || (value > 0x7F)) - return (TIFFReadDirEntryErrRange); - else - return (TIFFReadDirEntryErrOk); -} - -static enum TIFFReadDirEntryErr -TIFFReadDirEntryCheckRangeShortSbyte(int8_t value) -{ - if (value < 0) - return (TIFFReadDirEntryErrRange); - else - return (TIFFReadDirEntryErrOk); -} - -static enum TIFFReadDirEntryErr -TIFFReadDirEntryCheckRangeShortSshort(int16_t value) -{ - if (value < 0) - return (TIFFReadDirEntryErrRange); - else - return (TIFFReadDirEntryErrOk); -} - -static enum TIFFReadDirEntryErr -TIFFReadDirEntryCheckRangeShortLong(uint32_t value) -{ - if (value > 0xFFFF) - return (TIFFReadDirEntryErrRange); - else - return (TIFFReadDirEntryErrOk); -} - -static enum TIFFReadDirEntryErr -TIFFReadDirEntryCheckRangeShortSlong(int32_t value) -{ - if ((value < 0) || (value > 0xFFFF)) - return (TIFFReadDirEntryErrRange); - else - return (TIFFReadDirEntryErrOk); -} - -static enum TIFFReadDirEntryErr -TIFFReadDirEntryCheckRangeShortLong8(uint64_t value) -{ - if (value > 0xFFFF) - return (TIFFReadDirEntryErrRange); - else - return (TIFFReadDirEntryErrOk); -} - -static enum TIFFReadDirEntryErr -TIFFReadDirEntryCheckRangeShortSlong8(int64_t value) -{ - if ((value < 0) || (value > 0xFFFF)) - return (TIFFReadDirEntryErrRange); - else - return (TIFFReadDirEntryErrOk); -} - -static enum TIFFReadDirEntryErr -TIFFReadDirEntryCheckRangeSshortShort(uint16_t value) -{ - if (value > 0x7FFF) - return (TIFFReadDirEntryErrRange); - else - return (TIFFReadDirEntryErrOk); -} - -static enum TIFFReadDirEntryErr -TIFFReadDirEntryCheckRangeSshortLong(uint32_t value) -{ - if (value > 0x7FFF) - return (TIFFReadDirEntryErrRange); - else - return (TIFFReadDirEntryErrOk); -} - -static enum TIFFReadDirEntryErr -TIFFReadDirEntryCheckRangeSshortSlong(int32_t value) -{ - if ((value < -0x8000) || (value > 0x7FFF)) - return (TIFFReadDirEntryErrRange); - else - return (TIFFReadDirEntryErrOk); -} - -static enum TIFFReadDirEntryErr -TIFFReadDirEntryCheckRangeSshortLong8(uint64_t value) -{ - if (value > 0x7FFF) - return (TIFFReadDirEntryErrRange); - else - return (TIFFReadDirEntryErrOk); -} - -static enum TIFFReadDirEntryErr -TIFFReadDirEntryCheckRangeSshortSlong8(int64_t value) -{ - if ((value < -0x8000) || (value > 0x7FFF)) - return (TIFFReadDirEntryErrRange); - else - return (TIFFReadDirEntryErrOk); -} - -static enum TIFFReadDirEntryErr -TIFFReadDirEntryCheckRangeLongSbyte(int8_t value) -{ - if (value < 0) - return (TIFFReadDirEntryErrRange); - else - return (TIFFReadDirEntryErrOk); -} - -static enum TIFFReadDirEntryErr -TIFFReadDirEntryCheckRangeLongSshort(int16_t value) -{ - if (value < 0) - return (TIFFReadDirEntryErrRange); - else - return (TIFFReadDirEntryErrOk); -} - -static enum TIFFReadDirEntryErr -TIFFReadDirEntryCheckRangeLongSlong(int32_t value) -{ - if (value < 0) - return (TIFFReadDirEntryErrRange); - else - return (TIFFReadDirEntryErrOk); -} - -static enum TIFFReadDirEntryErr -TIFFReadDirEntryCheckRangeLongLong8(uint64_t value) -{ - if (value > UINT32_MAX) - return (TIFFReadDirEntryErrRange); - else - return (TIFFReadDirEntryErrOk); -} - -static enum TIFFReadDirEntryErr -TIFFReadDirEntryCheckRangeLongSlong8(int64_t value) -{ - if ((value < 0) || (value > (int64_t)UINT32_MAX)) - return (TIFFReadDirEntryErrRange); - else - return (TIFFReadDirEntryErrOk); -} - -static enum TIFFReadDirEntryErr -TIFFReadDirEntryCheckRangeSlongLong(uint32_t value) -{ - if (value > 0x7FFFFFFFUL) - return (TIFFReadDirEntryErrRange); - else - return (TIFFReadDirEntryErrOk); -} - -/* Check that the 8-byte unsigned value can fit in a 4-byte unsigned range */ -static enum TIFFReadDirEntryErr -TIFFReadDirEntryCheckRangeSlongLong8(uint64_t value) -{ - if (value > 0x7FFFFFFF) - return (TIFFReadDirEntryErrRange); - else - return (TIFFReadDirEntryErrOk); -} - -/* Check that the 8-byte signed value can fit in a 4-byte signed range */ -static enum TIFFReadDirEntryErr -TIFFReadDirEntryCheckRangeSlongSlong8(int64_t value) -{ - if ((value < 0 - ((int64_t)0x7FFFFFFF + 1)) || (value > 0x7FFFFFFF)) - return (TIFFReadDirEntryErrRange); - else - return (TIFFReadDirEntryErrOk); -} - -static enum TIFFReadDirEntryErr -TIFFReadDirEntryCheckRangeLong8Sbyte(int8_t value) -{ - if (value < 0) - return (TIFFReadDirEntryErrRange); - else - return (TIFFReadDirEntryErrOk); -} - -static enum TIFFReadDirEntryErr -TIFFReadDirEntryCheckRangeLong8Sshort(int16_t value) -{ - if (value < 0) - return (TIFFReadDirEntryErrRange); - else - return (TIFFReadDirEntryErrOk); -} - -static enum TIFFReadDirEntryErr -TIFFReadDirEntryCheckRangeLong8Slong(int32_t value) -{ - if (value < 0) - return (TIFFReadDirEntryErrRange); - else - return (TIFFReadDirEntryErrOk); -} - -static enum TIFFReadDirEntryErr -TIFFReadDirEntryCheckRangeLong8Slong8(int64_t value) -{ - if (value < 0) - return (TIFFReadDirEntryErrRange); - else - return (TIFFReadDirEntryErrOk); -} - -static enum TIFFReadDirEntryErr -TIFFReadDirEntryCheckRangeSlong8Long8(uint64_t value) -{ - if (value > INT64_MAX) - return (TIFFReadDirEntryErrRange); - else - return (TIFFReadDirEntryErrOk); -} - -static enum TIFFReadDirEntryErr TIFFReadDirEntryData(TIFF *tif, uint64_t offset, - tmsize_t size, void *dest) -{ - assert(size > 0); - if (!isMapped(tif)) - { - if (!SeekOK(tif, offset)) - return (TIFFReadDirEntryErrIo); - if (!ReadOK(tif, dest, size)) - return (TIFFReadDirEntryErrIo); - } - else - { - size_t ma, mb; - ma = (size_t)offset; - if ((uint64_t)ma != offset || ma > (~(size_t)0) - (size_t)size) - { - return TIFFReadDirEntryErrIo; - } - mb = ma + size; - if (mb > (uint64_t)tif->tif_size) - return (TIFFReadDirEntryErrIo); - _TIFFmemcpy(dest, tif->tif_base + ma, size); - } - return (TIFFReadDirEntryErrOk); -} - -static void TIFFReadDirEntryOutputErr(TIFF *tif, enum TIFFReadDirEntryErr err, - const char *module, const char *tagname, - int recover) -{ - if (!recover) - { - switch (err) - { - case TIFFReadDirEntryErrCount: - TIFFErrorExtR(tif, module, "Incorrect count for \"%s\"", - tagname); - break; - case TIFFReadDirEntryErrType: - TIFFErrorExtR(tif, module, "Incompatible type for \"%s\"", - tagname); - break; - case TIFFReadDirEntryErrIo: - TIFFErrorExtR(tif, module, "IO error during reading of \"%s\"", - tagname); - break; - case TIFFReadDirEntryErrRange: - TIFFErrorExtR(tif, module, "Incorrect value for \"%s\"", - tagname); - break; - case TIFFReadDirEntryErrPsdif: - TIFFErrorExtR( - tif, module, - "Cannot handle different values per sample for \"%s\"", - tagname); - break; - case TIFFReadDirEntryErrSizesan: - TIFFErrorExtR(tif, module, - "Sanity check on size of \"%s\" value failed", - tagname); - break; - case TIFFReadDirEntryErrAlloc: - TIFFErrorExtR(tif, module, "Out of memory reading of \"%s\"", - tagname); - break; - default: - assert(0); /* we should never get here */ - break; - } - } - else - { - switch (err) - { - case TIFFReadDirEntryErrCount: - TIFFWarningExtR(tif, module, - "Incorrect count for \"%s\"; tag ignored", - tagname); - break; - case TIFFReadDirEntryErrType: - TIFFWarningExtR(tif, module, - "Incompatible type for \"%s\"; tag ignored", - tagname); - break; - case TIFFReadDirEntryErrIo: - TIFFWarningExtR( - tif, module, - "IO error during reading of \"%s\"; tag ignored", tagname); - break; - case TIFFReadDirEntryErrRange: - TIFFWarningExtR(tif, module, - "Incorrect value for \"%s\"; tag ignored", - tagname); - break; - case TIFFReadDirEntryErrPsdif: - TIFFWarningExtR(tif, module, - "Cannot handle different values per sample for " - "\"%s\"; tag ignored", - tagname); - break; - case TIFFReadDirEntryErrSizesan: - TIFFWarningExtR( - tif, module, - "Sanity check on size of \"%s\" value failed; tag ignored", - tagname); - break; - case TIFFReadDirEntryErrAlloc: - TIFFWarningExtR(tif, module, - "Out of memory reading of \"%s\"; tag ignored", - tagname); - break; - default: - assert(0); /* we should never get here */ - break; - } - } -} - -/* - * Return the maximum number of color channels specified for a given photometric - * type. 0 is returned if photometric type isn't supported or no default value - * is defined by the specification. - */ -static int _TIFFGetMaxColorChannels(uint16_t photometric) -{ - switch (photometric) - { - case PHOTOMETRIC_PALETTE: - case PHOTOMETRIC_MINISWHITE: - case PHOTOMETRIC_MINISBLACK: - return 1; - case PHOTOMETRIC_YCBCR: - case PHOTOMETRIC_RGB: - case PHOTOMETRIC_CIELAB: - case PHOTOMETRIC_LOGLUV: - case PHOTOMETRIC_ITULAB: - case PHOTOMETRIC_ICCLAB: - return 3; - case PHOTOMETRIC_SEPARATED: - case PHOTOMETRIC_MASK: - return 4; - case PHOTOMETRIC_LOGL: - case PHOTOMETRIC_CFA: - default: - return 0; - } -} - -static int ByteCountLooksBad(TIFF *tif) -{ - /* - * Assume we have wrong StripByteCount value (in case - * of single strip) in following cases: - * - it is equal to zero along with StripOffset; - * - it is larger than file itself (in case of uncompressed - * image); - * - it is smaller than the size of the bytes per row - * multiplied on the number of rows. The last case should - * not be checked in the case of writing new image, - * because we may do not know the exact strip size - * until the whole image will be written and directory - * dumped out. - */ - uint64_t bytecount = TIFFGetStrileByteCount(tif, 0); - uint64_t offset = TIFFGetStrileOffset(tif, 0); - uint64_t filesize; - - if (offset == 0) - return 0; - if (bytecount == 0) - return 1; - if (tif->tif_dir.td_compression != COMPRESSION_NONE) - return 0; - filesize = TIFFGetFileSize(tif); - if (offset <= filesize && bytecount > filesize - offset) - return 1; - if (tif->tif_mode == O_RDONLY) - { - uint64_t scanlinesize = TIFFScanlineSize64(tif); - if (tif->tif_dir.td_imagelength > 0 && - scanlinesize > UINT64_MAX / tif->tif_dir.td_imagelength) - { - return 1; - } - if (bytecount < scanlinesize * tif->tif_dir.td_imagelength) - return 1; - } - return 0; -} - -/* - * Read the next TIFF directory from a file and convert it to the internal - * format. We read directories sequentially. - */ -int TIFFReadDirectory(TIFF *tif) -{ - static const char module[] = "TIFFReadDirectory"; - TIFFDirEntry *dir; - uint16_t dircount; - TIFFDirEntry *dp; - uint16_t di; - const TIFFField *fip; - uint32_t fii = FAILED_FII; - toff_t nextdiroff; - int bitspersample_read = FALSE; - int color_channels; - - if (tif->tif_nextdiroff == 0) - { - /* In this special case, tif_diroff needs also to be set to 0. - * This is behind the last IFD, thus no checking or reading necessary. - */ - tif->tif_diroff = tif->tif_nextdiroff; - return 0; - } - - nextdiroff = tif->tif_nextdiroff; - /* tif_curdir++ and tif_nextdiroff should only be updated after SUCCESSFUL - * reading of the directory. Otherwise, invalid IFD offsets could corrupt - * the IFD list. */ - if (!_TIFFCheckDirNumberAndOffset(tif, - tif->tif_curdir == - TIFF_NON_EXISTENT_DIR_NUMBER - ? 0 - : tif->tif_curdir + 1, - nextdiroff)) - { - return 0; /* bad offset (IFD looping or more than TIFF_MAX_DIR_COUNT - IFDs) */ - } - dircount = TIFFFetchDirectory(tif, nextdiroff, &dir, &tif->tif_nextdiroff); - if (!dircount) - { - TIFFErrorExtR(tif, module, - "Failed to read directory at offset %" PRIu64, - nextdiroff); - return 0; - } - /* Set global values after a valid directory has been fetched. - * tif_diroff is already set to nextdiroff in TIFFFetchDirectory() in the - * beginning. */ - if (tif->tif_curdir == TIFF_NON_EXISTENT_DIR_NUMBER) - tif->tif_curdir = 0; - else - tif->tif_curdir++; - (*tif->tif_cleanup)(tif); /* cleanup any previous compression state */ - - TIFFReadDirectoryCheckOrder(tif, dir, dircount); - - /* - * Mark duplicates of any tag to be ignored (bugzilla 1994) - * to avoid certain pathological problems. - */ - { - TIFFDirEntry *ma; - uint16_t mb; - for (ma = dir, mb = 0; mb < dircount; ma++, mb++) - { - TIFFDirEntry *na; - uint16_t nb; - for (na = ma + 1, nb = mb + 1; nb < dircount; na++, nb++) - { - if (ma->tdir_tag == na->tdir_tag) - { - na->tdir_ignore = TRUE; - } - } - } - } - - tif->tif_flags &= ~TIFF_BEENWRITING; /* reset before new dir */ - tif->tif_flags &= ~TIFF_BUF4WRITE; /* reset before new dir */ - tif->tif_flags &= ~TIFF_CHOPPEDUPARRAYS; - - /* free any old stuff and reinit */ - TIFFFreeDirectory(tif); - TIFFDefaultDirectory(tif); - /* - * Electronic Arts writes gray-scale TIFF files - * without a PlanarConfiguration directory entry. - * Thus we setup a default value here, even though - * the TIFF spec says there is no default value. - * After PlanarConfiguration is preset in TIFFDefaultDirectory() - * the following setting is not needed, but does not harm either. - */ - TIFFSetField(tif, TIFFTAG_PLANARCONFIG, PLANARCONFIG_CONTIG); - /* - * Setup default value and then make a pass over - * the fields to check type and tag information, - * and to extract info required to size data - * structures. A second pass is made afterwards - * to read in everything not taken in the first pass. - * But we must process the Compression tag first - * in order to merge in codec-private tag definitions (otherwise - * we may get complaints about unknown tags). However, the - * Compression tag may be dependent on the SamplesPerPixel - * tag value because older TIFF specs permitted Compression - * to be written as a SamplesPerPixel-count tag entry. - * Thus if we don't first figure out the correct SamplesPerPixel - * tag value then we may end up ignoring the Compression tag - * value because it has an incorrect count value (if the - * true value of SamplesPerPixel is not 1). - */ - dp = - TIFFReadDirectoryFindEntry(tif, dir, dircount, TIFFTAG_SAMPLESPERPIXEL); - if (dp) - { - if (!TIFFFetchNormalTag(tif, dp, 0)) - goto bad; - dp->tdir_ignore = TRUE; - } - dp = TIFFReadDirectoryFindEntry(tif, dir, dircount, TIFFTAG_COMPRESSION); - if (dp) - { - /* - * The 5.0 spec says the Compression tag has one value, while - * earlier specs say it has one value per sample. Because of - * this, we accept the tag if one value is supplied with either - * count. - */ - uint16_t value; - enum TIFFReadDirEntryErr err; - err = TIFFReadDirEntryShort(tif, dp, &value); - if (err == TIFFReadDirEntryErrCount) - err = TIFFReadDirEntryPersampleShort(tif, dp, &value); - if (err != TIFFReadDirEntryErrOk) - { - TIFFReadDirEntryOutputErr(tif, err, module, "Compression", 0); - goto bad; - } - if (!TIFFSetField(tif, TIFFTAG_COMPRESSION, value)) - goto bad; - dp->tdir_ignore = TRUE; - } - else - { - if (!TIFFSetField(tif, TIFFTAG_COMPRESSION, COMPRESSION_NONE)) - goto bad; - } - /* - * First real pass over the directory. - */ - for (di = 0, dp = dir; di < dircount; di++, dp++) - { - if (!dp->tdir_ignore) - { - TIFFReadDirectoryFindFieldInfo(tif, dp->tdir_tag, &fii); - if (fii == FAILED_FII) - { - TIFFWarningExtR(tif, module, - "Unknown field with tag %" PRIu16 " (0x%" PRIx16 - ") encountered", - dp->tdir_tag, dp->tdir_tag); - /* the following knowingly leaks the - anonymous field structure */ - if (!_TIFFMergeFields( - tif, - _TIFFCreateAnonField(tif, dp->tdir_tag, - (TIFFDataType)dp->tdir_type), - 1)) - { - TIFFWarningExtR( - tif, module, - "Registering anonymous field with tag %" PRIu16 - " (0x%" PRIx16 ") failed", - dp->tdir_tag, dp->tdir_tag); - dp->tdir_ignore = TRUE; - } - else - { - TIFFReadDirectoryFindFieldInfo(tif, dp->tdir_tag, &fii); - assert(fii != FAILED_FII); - } - } - } - if (!dp->tdir_ignore) - { - fip = tif->tif_fields[fii]; - if (fip->field_bit == FIELD_IGNORE) - dp->tdir_ignore = TRUE; - else - { - switch (dp->tdir_tag) - { - case TIFFTAG_STRIPOFFSETS: - case TIFFTAG_STRIPBYTECOUNTS: - case TIFFTAG_TILEOFFSETS: - case TIFFTAG_TILEBYTECOUNTS: - TIFFSetFieldBit(tif, fip->field_bit); - break; - case TIFFTAG_IMAGEWIDTH: - case TIFFTAG_IMAGELENGTH: - case TIFFTAG_IMAGEDEPTH: - case TIFFTAG_TILELENGTH: - case TIFFTAG_TILEWIDTH: - case TIFFTAG_TILEDEPTH: - case TIFFTAG_PLANARCONFIG: - case TIFFTAG_ROWSPERSTRIP: - case TIFFTAG_EXTRASAMPLES: - if (!TIFFFetchNormalTag(tif, dp, 0)) - goto bad; - dp->tdir_ignore = TRUE; - break; - default: - if (!_TIFFCheckFieldIsValidForCodec(tif, dp->tdir_tag)) - dp->tdir_ignore = TRUE; - break; - } - } - } - } - /* - * XXX: OJPEG hack. - * If a) compression is OJPEG, b) planarconfig tag says it's separate, - * c) strip offsets/bytecounts tag are both present and - * d) both contain exactly one value, then we consistently find - * that the buggy implementation of the buggy compression scheme - * matches contig planarconfig best. So we 'fix-up' the tag here - */ - if ((tif->tif_dir.td_compression == COMPRESSION_OJPEG) && - (tif->tif_dir.td_planarconfig == PLANARCONFIG_SEPARATE)) - { - if (!_TIFFFillStriles(tif)) - goto bad; - dp = TIFFReadDirectoryFindEntry(tif, dir, dircount, - TIFFTAG_STRIPOFFSETS); - if ((dp != 0) && (dp->tdir_count == 1)) - { - dp = TIFFReadDirectoryFindEntry(tif, dir, dircount, - TIFFTAG_STRIPBYTECOUNTS); - if ((dp != 0) && (dp->tdir_count == 1)) - { - tif->tif_dir.td_planarconfig = PLANARCONFIG_CONTIG; - TIFFWarningExtR(tif, module, - "Planarconfig tag value assumed incorrect, " - "assuming data is contig instead of chunky"); - } - } - } - /* - * Allocate directory structure and setup defaults. - */ - if (!TIFFFieldSet(tif, FIELD_IMAGEDIMENSIONS)) - { - MissingRequired(tif, "ImageLength"); - goto bad; - } - - /* - * Second pass: extract other information. - */ - for (di = 0, dp = dir; di < dircount; di++, dp++) - { - if (!dp->tdir_ignore) - { - switch (dp->tdir_tag) - { - case TIFFTAG_MINSAMPLEVALUE: - case TIFFTAG_MAXSAMPLEVALUE: - case TIFFTAG_BITSPERSAMPLE: - case TIFFTAG_DATATYPE: - case TIFFTAG_SAMPLEFORMAT: - /* - * The MinSampleValue, MaxSampleValue, BitsPerSample - * DataType and SampleFormat tags are supposed to be - * written as one value/sample, but some vendors - * incorrectly write one value only -- so we accept - * that as well (yuck). Other vendors write correct - * value for NumberOfSamples, but incorrect one for - * BitsPerSample and friends, and we will read this - * too. - */ - { - uint16_t value; - enum TIFFReadDirEntryErr err; - err = TIFFReadDirEntryShort(tif, dp, &value); - if (err == TIFFReadDirEntryErrCount) - err = - TIFFReadDirEntryPersampleShort(tif, dp, &value); - if (err != TIFFReadDirEntryErrOk) - { - fip = TIFFFieldWithTag(tif, dp->tdir_tag); - TIFFReadDirEntryOutputErr( - tif, err, module, - fip ? fip->field_name : "unknown tagname", 0); - goto bad; - } - if (!TIFFSetField(tif, dp->tdir_tag, value)) - goto bad; - if (dp->tdir_tag == TIFFTAG_BITSPERSAMPLE) - bitspersample_read = TRUE; - } - break; - case TIFFTAG_SMINSAMPLEVALUE: - case TIFFTAG_SMAXSAMPLEVALUE: - { - - double *data = NULL; - enum TIFFReadDirEntryErr err; - uint32_t saved_flags; - int m; - if (dp->tdir_count != - (uint64_t)tif->tif_dir.td_samplesperpixel) - err = TIFFReadDirEntryErrCount; - else - err = TIFFReadDirEntryDoubleArray(tif, dp, &data); - if (err != TIFFReadDirEntryErrOk) - { - fip = TIFFFieldWithTag(tif, dp->tdir_tag); - TIFFReadDirEntryOutputErr( - tif, err, module, - fip ? fip->field_name : "unknown tagname", 0); - goto bad; - } - saved_flags = tif->tif_flags; - tif->tif_flags |= TIFF_PERSAMPLE; - m = TIFFSetField(tif, dp->tdir_tag, data); - tif->tif_flags = saved_flags; - _TIFFfreeExt(tif, data); - if (!m) - goto bad; - } - break; - case TIFFTAG_STRIPOFFSETS: - case TIFFTAG_TILEOFFSETS: - switch (dp->tdir_type) - { - case TIFF_SHORT: - case TIFF_LONG: - case TIFF_LONG8: - break; - default: - /* Warn except if directory typically created with - * TIFFDeferStrileArrayWriting() */ - if (!(tif->tif_mode == O_RDWR && - dp->tdir_count == 0 && dp->tdir_type == 0 && - dp->tdir_offset.toff_long8 == 0)) - { - fip = TIFFFieldWithTag(tif, dp->tdir_tag); - TIFFWarningExtR( - tif, module, "Invalid data type for tag %s", - fip ? fip->field_name : "unknown tagname"); - } - break; - } - _TIFFmemcpy(&(tif->tif_dir.td_stripoffset_entry), dp, - sizeof(TIFFDirEntry)); - break; - case TIFFTAG_STRIPBYTECOUNTS: - case TIFFTAG_TILEBYTECOUNTS: - switch (dp->tdir_type) - { - case TIFF_SHORT: - case TIFF_LONG: - case TIFF_LONG8: - break; - default: - /* Warn except if directory typically created with - * TIFFDeferStrileArrayWriting() */ - if (!(tif->tif_mode == O_RDWR && - dp->tdir_count == 0 && dp->tdir_type == 0 && - dp->tdir_offset.toff_long8 == 0)) - { - fip = TIFFFieldWithTag(tif, dp->tdir_tag); - TIFFWarningExtR( - tif, module, "Invalid data type for tag %s", - fip ? fip->field_name : "unknown tagname"); - } - break; - } - _TIFFmemcpy(&(tif->tif_dir.td_stripbytecount_entry), dp, - sizeof(TIFFDirEntry)); - break; - case TIFFTAG_COLORMAP: - case TIFFTAG_TRANSFERFUNCTION: - { - enum TIFFReadDirEntryErr err; - uint32_t countpersample; - uint32_t countrequired; - uint32_t incrementpersample; - uint16_t *value = NULL; - /* It would be dangerous to instantiate those tag values */ - /* since if td_bitspersample has not yet been read (due to - */ - /* unordered tags), it could be read afterwards with a */ - /* values greater than the default one (1), which may cause - */ - /* crashes in user code */ - if (!bitspersample_read) - { - fip = TIFFFieldWithTag(tif, dp->tdir_tag); - TIFFWarningExtR( - tif, module, - "Ignoring %s since BitsPerSample tag not found", - fip ? fip->field_name : "unknown tagname"); - continue; - } - /* ColorMap or TransferFunction for high bit */ - /* depths do not make much sense and could be */ - /* used as a denial of service vector */ - if (tif->tif_dir.td_bitspersample > 24) - { - fip = TIFFFieldWithTag(tif, dp->tdir_tag); - TIFFWarningExtR( - tif, module, - "Ignoring %s because BitsPerSample=%" PRIu16 ">24", - fip ? fip->field_name : "unknown tagname", - tif->tif_dir.td_bitspersample); - continue; - } - countpersample = (1U << tif->tif_dir.td_bitspersample); - if ((dp->tdir_tag == TIFFTAG_TRANSFERFUNCTION) && - (dp->tdir_count == (uint64_t)countpersample)) - { - countrequired = countpersample; - incrementpersample = 0; - } - else - { - countrequired = 3 * countpersample; - incrementpersample = countpersample; - } - if (dp->tdir_count != (uint64_t)countrequired) - err = TIFFReadDirEntryErrCount; - else - err = TIFFReadDirEntryShortArray(tif, dp, &value); - if (err != TIFFReadDirEntryErrOk) - { - fip = TIFFFieldWithTag(tif, dp->tdir_tag); - TIFFReadDirEntryOutputErr( - tif, err, module, - fip ? fip->field_name : "unknown tagname", 1); - } - else - { - TIFFSetField(tif, dp->tdir_tag, value, - value + incrementpersample, - value + 2 * incrementpersample); - _TIFFfreeExt(tif, value); - } - } - break; - /* BEGIN REV 4.0 COMPATIBILITY */ - case TIFFTAG_OSUBFILETYPE: - { - uint16_t valueo; - uint32_t value; - if (TIFFReadDirEntryShort(tif, dp, &valueo) == - TIFFReadDirEntryErrOk) - { - switch (valueo) - { - case OFILETYPE_REDUCEDIMAGE: - value = FILETYPE_REDUCEDIMAGE; - break; - case OFILETYPE_PAGE: - value = FILETYPE_PAGE; - break; - default: - value = 0; - break; - } - if (value != 0) - TIFFSetField(tif, TIFFTAG_SUBFILETYPE, value); - } - } - break; - /* END REV 4.0 COMPATIBILITY */ -#if 0 - case TIFFTAG_EP_BATTERYLEVEL: - /* TIFFTAG_EP_BATTERYLEVEL can be RATIONAL or ASCII. - * LibTiff defines it as ASCII and converts RATIONAL to an - * ASCII string. */ - switch (dp->tdir_type) - { - case TIFF_RATIONAL: - { - /* Read rational and convert to ASCII*/ - enum TIFFReadDirEntryErr err; - TIFFRational_t rValue; - err = TIFFReadDirEntryCheckedRationalDirect( - tif, dp, &rValue); - if (err != TIFFReadDirEntryErrOk) - { - fip = TIFFFieldWithTag(tif, dp->tdir_tag); - TIFFReadDirEntryOutputErr( - tif, err, module, - fip ? fip->field_name : "unknown tagname", - 1); - } - else - { - char szAux[32]; - snprintf(szAux, sizeof(szAux) - 1, "%d/%d", - rValue.uNum, rValue.uDenom); - TIFFSetField(tif, dp->tdir_tag, szAux); - } - } - break; - case TIFF_ASCII: - (void)TIFFFetchNormalTag(tif, dp, TRUE); - break; - default: - fip = TIFFFieldWithTag(tif, dp->tdir_tag); - TIFFWarningExtR(tif, module, - "Invalid data type for tag %s. " - "ASCII or RATIONAL expected", - fip ? fip->field_name - : "unknown tagname"); - break; - } - break; -#endif - default: - (void)TIFFFetchNormalTag(tif, dp, TRUE); - break; - } - } /* -- if (!dp->tdir_ignore) */ - } /* -- for-loop -- */ - - /* - * OJPEG hack: - * - If a) compression is OJPEG, and b) photometric tag is missing, - * then we consistently find that photometric should be YCbCr - * - If a) compression is OJPEG, and b) photometric tag says it's RGB, - * then we consistently find that the buggy implementation of the - * buggy compression scheme matches photometric YCbCr instead. - * - If a) compression is OJPEG, and b) bitspersample tag is missing, - * then we consistently find bitspersample should be 8. - * - If a) compression is OJPEG, b) samplesperpixel tag is missing, - * and c) photometric is RGB or YCbCr, then we consistently find - * samplesperpixel should be 3 - * - If a) compression is OJPEG, b) samplesperpixel tag is missing, - * and c) photometric is MINISWHITE or MINISBLACK, then we consistently - * find samplesperpixel should be 3 - */ - if (tif->tif_dir.td_compression == COMPRESSION_OJPEG) - { - if (!TIFFFieldSet(tif, FIELD_PHOTOMETRIC)) - { - TIFFWarningExtR( - tif, module, - "Photometric tag is missing, assuming data is YCbCr"); - if (!TIFFSetField(tif, TIFFTAG_PHOTOMETRIC, PHOTOMETRIC_YCBCR)) - goto bad; - } - else if (tif->tif_dir.td_photometric == PHOTOMETRIC_RGB) - { - tif->tif_dir.td_photometric = PHOTOMETRIC_YCBCR; - TIFFWarningExtR(tif, module, - "Photometric tag value assumed incorrect, " - "assuming data is YCbCr instead of RGB"); - } - if (!TIFFFieldSet(tif, FIELD_BITSPERSAMPLE)) - { - TIFFWarningExtR( - tif, module, - "BitsPerSample tag is missing, assuming 8 bits per sample"); - if (!TIFFSetField(tif, TIFFTAG_BITSPERSAMPLE, 8)) - goto bad; - } - if (!TIFFFieldSet(tif, FIELD_SAMPLESPERPIXEL)) - { - if (tif->tif_dir.td_photometric == PHOTOMETRIC_RGB) - { - TIFFWarningExtR(tif, module, - "SamplesPerPixel tag is missing, " - "assuming correct SamplesPerPixel value is 3"); - if (!TIFFSetField(tif, TIFFTAG_SAMPLESPERPIXEL, 3)) - goto bad; - } - if (tif->tif_dir.td_photometric == PHOTOMETRIC_YCBCR) - { - TIFFWarningExtR(tif, module, - "SamplesPerPixel tag is missing, " - "applying correct SamplesPerPixel value of 3"); - if (!TIFFSetField(tif, TIFFTAG_SAMPLESPERPIXEL, 3)) - goto bad; - } - else if ((tif->tif_dir.td_photometric == PHOTOMETRIC_MINISWHITE) || - (tif->tif_dir.td_photometric == PHOTOMETRIC_MINISBLACK)) - { - /* - * SamplesPerPixel tag is missing, but is not required - * by spec. Assume correct SamplesPerPixel value of 1. - */ - if (!TIFFSetField(tif, TIFFTAG_SAMPLESPERPIXEL, 1)) - goto bad; - } - } - } - - /* - * Setup appropriate structures (by strip or by tile) - * We do that only after the above OJPEG hack which alters SamplesPerPixel - * and thus influences the number of strips in the separate planarconfig. - */ - if (!TIFFFieldSet(tif, FIELD_TILEDIMENSIONS)) - { - tif->tif_dir.td_nstrips = TIFFNumberOfStrips(tif); - tif->tif_dir.td_tilewidth = tif->tif_dir.td_imagewidth; - tif->tif_dir.td_tilelength = tif->tif_dir.td_rowsperstrip; - tif->tif_dir.td_tiledepth = tif->tif_dir.td_imagedepth; - tif->tif_flags &= ~TIFF_ISTILED; - } - else - { - tif->tif_dir.td_nstrips = TIFFNumberOfTiles(tif); - tif->tif_flags |= TIFF_ISTILED; - } - if (!tif->tif_dir.td_nstrips) - { - TIFFErrorExtR(tif, module, "Cannot handle zero number of %s", - isTiled(tif) ? "tiles" : "strips"); - goto bad; - } - tif->tif_dir.td_stripsperimage = tif->tif_dir.td_nstrips; - if (tif->tif_dir.td_planarconfig == PLANARCONFIG_SEPARATE) - tif->tif_dir.td_stripsperimage /= tif->tif_dir.td_samplesperpixel; - if (!TIFFFieldSet(tif, FIELD_STRIPOFFSETS)) - { -#ifdef OJPEG_SUPPORT - if ((tif->tif_dir.td_compression == COMPRESSION_OJPEG) && - (isTiled(tif) == 0) && (tif->tif_dir.td_nstrips == 1)) - { - /* - * XXX: OJPEG hack. - * If a) compression is OJPEG, b) it's not a tiled TIFF, - * and c) the number of strips is 1, - * then we tolerate the absence of stripoffsets tag, - * because, presumably, all required data is in the - * JpegInterchangeFormat stream. - */ - TIFFSetFieldBit(tif, FIELD_STRIPOFFSETS); - } - else -#endif - { - MissingRequired(tif, isTiled(tif) ? "TileOffsets" : "StripOffsets"); - goto bad; - } - } - - if (tif->tif_mode == O_RDWR && - tif->tif_dir.td_stripoffset_entry.tdir_tag != 0 && - tif->tif_dir.td_stripoffset_entry.tdir_count == 0 && - tif->tif_dir.td_stripoffset_entry.tdir_type == 0 && - tif->tif_dir.td_stripoffset_entry.tdir_offset.toff_long8 == 0 && - tif->tif_dir.td_stripbytecount_entry.tdir_tag != 0 && - tif->tif_dir.td_stripbytecount_entry.tdir_count == 0 && - tif->tif_dir.td_stripbytecount_entry.tdir_type == 0 && - tif->tif_dir.td_stripbytecount_entry.tdir_offset.toff_long8 == 0) - { - /* Directory typically created with TIFFDeferStrileArrayWriting() */ - TIFFSetupStrips(tif); - } - else if (!(tif->tif_flags & TIFF_DEFERSTRILELOAD)) - { - if (tif->tif_dir.td_stripoffset_entry.tdir_tag != 0) - { - if (!TIFFFetchStripThing(tif, &(tif->tif_dir.td_stripoffset_entry), - tif->tif_dir.td_nstrips, - &tif->tif_dir.td_stripoffset_p)) - { - goto bad; - } - } - if (tif->tif_dir.td_stripbytecount_entry.tdir_tag != 0) - { - if (!TIFFFetchStripThing( - tif, &(tif->tif_dir.td_stripbytecount_entry), - tif->tif_dir.td_nstrips, &tif->tif_dir.td_stripbytecount_p)) - { - goto bad; - } - } - } - - /* - * Make sure all non-color channels are extrasamples. - * If it's not the case, define them as such. - */ - color_channels = _TIFFGetMaxColorChannels(tif->tif_dir.td_photometric); - if (color_channels && - tif->tif_dir.td_samplesperpixel - tif->tif_dir.td_extrasamples > - color_channels) - { - uint16_t old_extrasamples; - uint16_t *new_sampleinfo; - - TIFFWarningExtR( - tif, module, - "Sum of Photometric type-related " - "color channels and ExtraSamples doesn't match SamplesPerPixel. " - "Defining non-color channels as ExtraSamples."); - - old_extrasamples = tif->tif_dir.td_extrasamples; - tif->tif_dir.td_extrasamples = - (uint16_t)(tif->tif_dir.td_samplesperpixel - color_channels); - - // sampleinfo should contain information relative to these new extra - // samples - new_sampleinfo = (uint16_t *)_TIFFcallocExt( - tif, tif->tif_dir.td_extrasamples, sizeof(uint16_t)); - if (!new_sampleinfo) - { - TIFFErrorExtR(tif, module, - "Failed to allocate memory for " - "temporary new sampleinfo array " - "(%" PRIu16 " 16 bit elements)", - tif->tif_dir.td_extrasamples); - goto bad; - } - - if (old_extrasamples > 0) - memcpy(new_sampleinfo, tif->tif_dir.td_sampleinfo, - old_extrasamples * sizeof(uint16_t)); - _TIFFsetShortArrayExt(tif, &tif->tif_dir.td_sampleinfo, new_sampleinfo, - tif->tif_dir.td_extrasamples); - _TIFFfreeExt(tif, new_sampleinfo); - } - - /* - * Verify Palette image has a Colormap. - */ - if (tif->tif_dir.td_photometric == PHOTOMETRIC_PALETTE && - !TIFFFieldSet(tif, FIELD_COLORMAP)) - { - if (tif->tif_dir.td_bitspersample >= 8 && - tif->tif_dir.td_samplesperpixel == 3) - tif->tif_dir.td_photometric = PHOTOMETRIC_RGB; - else if (tif->tif_dir.td_bitspersample >= 8) - tif->tif_dir.td_photometric = PHOTOMETRIC_MINISBLACK; - else - { - MissingRequired(tif, "Colormap"); - goto bad; - } - } - /* - * OJPEG hack: - * We do no further messing with strip/tile offsets/bytecounts in OJPEG - * TIFFs - */ - if (tif->tif_dir.td_compression != COMPRESSION_OJPEG) - { - /* - * Attempt to deal with a missing StripByteCounts tag. - */ - if (!TIFFFieldSet(tif, FIELD_STRIPBYTECOUNTS)) - { - /* - * Some manufacturers violate the spec by not giving - * the size of the strips. In this case, assume there - * is one uncompressed strip of data. - */ - if ((tif->tif_dir.td_planarconfig == PLANARCONFIG_CONTIG && - tif->tif_dir.td_nstrips > 1) || - (tif->tif_dir.td_planarconfig == PLANARCONFIG_SEPARATE && - tif->tif_dir.td_nstrips != - (uint32_t)tif->tif_dir.td_samplesperpixel)) - { - MissingRequired(tif, "StripByteCounts"); - goto bad; - } - TIFFWarningExtR( - tif, module, - "TIFF directory is missing required " - "\"StripByteCounts\" field, calculating from imagelength"); - if (EstimateStripByteCounts(tif, dir, dircount) < 0) - goto bad; - } - else if (tif->tif_dir.td_nstrips == 1 && - !(tif->tif_flags & TIFF_ISTILED) && ByteCountLooksBad(tif)) - { - /* - * XXX: Plexus (and others) sometimes give a value of - * zero for a tag when they don't know what the - * correct value is! Try and handle the simple case - * of estimating the size of a one strip image. - */ - TIFFWarningExtR(tif, module, - "Bogus \"StripByteCounts\" field, ignoring and " - "calculating from imagelength"); - if (EstimateStripByteCounts(tif, dir, dircount) < 0) - goto bad; - } - else if (!(tif->tif_flags & TIFF_DEFERSTRILELOAD) && - tif->tif_dir.td_planarconfig == PLANARCONFIG_CONTIG && - tif->tif_dir.td_nstrips > 2 && - tif->tif_dir.td_compression == COMPRESSION_NONE && - TIFFGetStrileByteCount(tif, 0) != - TIFFGetStrileByteCount(tif, 1) && - TIFFGetStrileByteCount(tif, 0) != 0 && - TIFFGetStrileByteCount(tif, 1) != 0) - { - /* - * XXX: Some vendors fill StripByteCount array with - * absolutely wrong values (it can be equal to - * StripOffset array, for example). Catch this case - * here. - * - * We avoid this check if deferring strile loading - * as it would always force us to load the strip/tile - * information. - */ - TIFFWarningExtR(tif, module, - "Wrong \"StripByteCounts\" field, ignoring and " - "calculating from imagelength"); - if (EstimateStripByteCounts(tif, dir, dircount) < 0) - goto bad; - } - } - if (dir) - { - _TIFFfreeExt(tif, dir); - dir = NULL; - } - if (!TIFFFieldSet(tif, FIELD_MAXSAMPLEVALUE)) - { - if (tif->tif_dir.td_bitspersample >= 16) - tif->tif_dir.td_maxsamplevalue = 0xFFFF; - else - tif->tif_dir.td_maxsamplevalue = - (uint16_t)((1L << tif->tif_dir.td_bitspersample) - 1); - } - -#ifdef STRIPBYTECOUNTSORTED_UNUSED - /* - * XXX: We can optimize checking for the strip bounds using the sorted - * bytecounts array. See also comments for TIFFAppendToStrip() - * function in tif_write.c. - */ - if (!(tif->tif_flags & TIFF_DEFERSTRILELOAD) && tif->tif_dir.td_nstrips > 1) - { - uint32_t strip; - - tif->tif_dir.td_stripbytecountsorted = 1; - for (strip = 1; strip < tif->tif_dir.td_nstrips; strip++) - { - if (TIFFGetStrileOffset(tif, strip - 1) > - TIFFGetStrileOffset(tif, strip)) - { - tif->tif_dir.td_stripbytecountsorted = 0; - break; - } - } - } -#endif - - /* - * An opportunity for compression mode dependent tag fixup - */ - (*tif->tif_fixuptags)(tif); - - /* - * Some manufacturers make life difficult by writing - * large amounts of uncompressed data as a single strip. - * This is contrary to the recommendations of the spec. - * The following makes an attempt at breaking such images - * into strips closer to the recommended 8k bytes. A - * side effect, however, is that the RowsPerStrip tag - * value may be changed. - */ - if ((tif->tif_dir.td_planarconfig == PLANARCONFIG_CONTIG) && - (tif->tif_dir.td_nstrips == 1) && - (tif->tif_dir.td_compression == COMPRESSION_NONE) && - ((tif->tif_flags & (TIFF_STRIPCHOP | TIFF_ISTILED)) == TIFF_STRIPCHOP)) - { - ChopUpSingleUncompressedStrip(tif); - } - - /* There are also uncompressed striped files with strips larger than */ - /* 2 GB, which make them unfriendly with a lot of code. If possible, */ - /* try to expose smaller "virtual" strips. */ - if (tif->tif_dir.td_planarconfig == PLANARCONFIG_CONTIG && - tif->tif_dir.td_compression == COMPRESSION_NONE && - (tif->tif_flags & (TIFF_STRIPCHOP | TIFF_ISTILED)) == TIFF_STRIPCHOP && - TIFFStripSize64(tif) > 0x7FFFFFFFUL) - { - TryChopUpUncompressedBigTiff(tif); - } - - /* - * Clear the dirty directory flag. - */ - tif->tif_flags &= ~TIFF_DIRTYDIRECT; - tif->tif_flags &= ~TIFF_DIRTYSTRIP; - - /* - * Reinitialize 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) - { - TIFFErrorExtR(tif, module, "Cannot handle zero scanline size"); - return (0); - } - - if (isTiled(tif)) - { - tif->tif_tilesize = TIFFTileSize(tif); - if (!tif->tif_tilesize) - { - TIFFErrorExtR(tif, module, "Cannot handle zero tile size"); - return (0); - } - } - else - { - if (!TIFFStripSize(tif)) - { - TIFFErrorExtR(tif, module, "Cannot handle zero strip size"); - return (0); - } - } - return (1); -bad: - if (dir) - _TIFFfreeExt(tif, dir); - return (0); -} - -static void TIFFReadDirectoryCheckOrder(TIFF *tif, TIFFDirEntry *dir, - uint16_t dircount) -{ - static const char module[] = "TIFFReadDirectoryCheckOrder"; - uint32_t m; - uint16_t n; - TIFFDirEntry *o; - m = 0; - for (n = 0, o = dir; n < dircount; n++, o++) - { - if (o->tdir_tag < m) - { - TIFFWarningExtR(tif, module, - "Invalid TIFF directory; tags are not sorted in " - "ascending order"); - break; - } - m = o->tdir_tag + 1; - } -} - -static TIFFDirEntry *TIFFReadDirectoryFindEntry(TIFF *tif, TIFFDirEntry *dir, - uint16_t dircount, - uint16_t tagid) -{ - TIFFDirEntry *m; - uint16_t n; - (void)tif; - for (m = dir, n = 0; n < dircount; m++, n++) - { - if (m->tdir_tag == tagid) - return (m); - } - return (0); -} - -static void TIFFReadDirectoryFindFieldInfo(TIFF *tif, uint16_t tagid, - uint32_t *fii) -{ - int32_t ma, mb, mc; - ma = -1; - mc = (int32_t)tif->tif_nfields; - while (1) - { - if (ma + 1 == mc) - { - *fii = FAILED_FII; - return; - } - mb = (ma + mc) / 2; - if (tif->tif_fields[mb]->field_tag == (uint32_t)tagid) - break; - if (tif->tif_fields[mb]->field_tag < (uint32_t)tagid) - ma = mb; - else - mc = mb; - } - while (1) - { - if (mb == 0) - break; - if (tif->tif_fields[mb - 1]->field_tag != (uint32_t)tagid) - break; - mb--; - } - *fii = mb; -} - -/* - * Read custom directory from the arbitrary offset. - * The code is very similar to TIFFReadDirectory(). - */ -int TIFFReadCustomDirectory(TIFF *tif, toff_t diroff, - const TIFFFieldArray *infoarray) -{ - static const char module[] = "TIFFReadCustomDirectory"; - TIFFDirEntry *dir; - uint16_t dircount; - TIFFDirEntry *dp; - uint16_t di; - const TIFFField *fip; - uint32_t fii; - (*tif->tif_cleanup)(tif); /* cleanup any previous compression state */ - _TIFFSetupFields(tif, infoarray); - dircount = TIFFFetchDirectory(tif, diroff, &dir, NULL); - if (!dircount) - { - TIFFErrorExtR(tif, module, - "Failed to read custom directory at offset %" PRIu64, - diroff); - return 0; - } - TIFFFreeDirectory(tif); - _TIFFmemset(&tif->tif_dir, 0, sizeof(TIFFDirectory)); - TIFFReadDirectoryCheckOrder(tif, dir, dircount); - for (di = 0, dp = dir; di < dircount; di++, dp++) - { - TIFFReadDirectoryFindFieldInfo(tif, dp->tdir_tag, &fii); - if (fii == FAILED_FII) - { - TIFFWarningExtR(tif, module, - "Unknown field with tag %" PRIu16 " (0x%" PRIx16 - ") encountered", - dp->tdir_tag, dp->tdir_tag); - if (!_TIFFMergeFields( - tif, - _TIFFCreateAnonField(tif, dp->tdir_tag, - (TIFFDataType)dp->tdir_type), - 1)) - { - TIFFWarningExtR(tif, module, - "Registering anonymous field with tag %" PRIu16 - " (0x%" PRIx16 ") failed", - dp->tdir_tag, dp->tdir_tag); - dp->tdir_ignore = TRUE; - } - else - { - TIFFReadDirectoryFindFieldInfo(tif, dp->tdir_tag, &fii); - assert(fii != FAILED_FII); - } - } - if (!dp->tdir_ignore) - { - fip = tif->tif_fields[fii]; - if (fip->field_bit == FIELD_IGNORE) - dp->tdir_ignore = TRUE; - else - { - /* check data type */ - while ((fip->field_type != TIFF_ANY) && - (fip->field_type != dp->tdir_type)) - { - fii++; - if ((fii == tif->tif_nfields) || - (tif->tif_fields[fii]->field_tag != - (uint32_t)dp->tdir_tag)) - { - fii = 0xFFFF; - break; - } - fip = tif->tif_fields[fii]; - } - if (fii == 0xFFFF) - { - TIFFWarningExtR(tif, module, - "Wrong data type %" PRIu16 - " for \"%s\"; tag ignored", - dp->tdir_type, fip->field_name); - dp->tdir_ignore = TRUE; - } - else - { - /* check count if known in advance */ - if ((fip->field_readcount != TIFF_VARIABLE) && - (fip->field_readcount != TIFF_VARIABLE2)) - { - uint32_t expected; - if (fip->field_readcount == TIFF_SPP) - expected = - (uint32_t)tif->tif_dir.td_samplesperpixel; - else - expected = (uint32_t)fip->field_readcount; - if (!CheckDirCount(tif, dp, expected)) - dp->tdir_ignore = TRUE; - } - } - } - if (!dp->tdir_ignore) - { - switch (dp->tdir_tag) - { - case EXIFTAG_SUBJECTDISTANCE: - if (!TIFFFieldIsAnonymous(fip)) - { - /* should only be called on a Exif directory */ - /* when exifFields[] is active */ - (void)TIFFFetchSubjectDistance(tif, dp); - } - else - { - (void)TIFFFetchNormalTag(tif, dp, TRUE); - } - break; - default: - (void)TIFFFetchNormalTag(tif, dp, TRUE); - break; - } - } /*-- if (!dp->tdir_ignore) */ - } - } - /* To be able to return from SubIFD or custom-IFD to main-IFD */ - tif->tif_setdirectory_force_absolute = TRUE; - if (dir) - _TIFFfreeExt(tif, dir); - return 1; -} - -/* - * EXIF is important special case of custom IFD, so we have a special - * function to read it. - */ -int TIFFReadEXIFDirectory(TIFF *tif, toff_t diroff) -{ - const TIFFFieldArray *exifFieldArray; - exifFieldArray = _TIFFGetExifFields(); - return TIFFReadCustomDirectory(tif, diroff, exifFieldArray); -} - -/* - *--: EXIF-GPS custom directory reading as another special case of custom IFD. - */ -int TIFFReadGPSDirectory(TIFF *tif, toff_t diroff) -{ - const TIFFFieldArray *gpsFieldArray; - gpsFieldArray = _TIFFGetGpsFields(); - return TIFFReadCustomDirectory(tif, diroff, gpsFieldArray); -} - -static int EstimateStripByteCounts(TIFF *tif, TIFFDirEntry *dir, - uint16_t dircount) -{ - static const char module[] = "EstimateStripByteCounts"; - - TIFFDirEntry *dp; - TIFFDirectory *td = &tif->tif_dir; - uint32_t strip; - - /* Do not try to load stripbytecount as we will compute it */ - if (!_TIFFFillStrilesInternal(tif, 0)) - return -1; - - if (td->td_stripbytecount_p) - _TIFFfreeExt(tif, td->td_stripbytecount_p); - td->td_stripbytecount_p = (uint64_t *)_TIFFCheckMalloc( - tif, td->td_nstrips, sizeof(uint64_t), "for \"StripByteCounts\" array"); - if (td->td_stripbytecount_p == NULL) - return -1; - - if (td->td_compression != COMPRESSION_NONE) - { - uint64_t space; - uint64_t filesize; - uint16_t n; - filesize = TIFFGetFileSize(tif); - if (!(tif->tif_flags & TIFF_BIGTIFF)) - space = sizeof(TIFFHeaderClassic) + 2 + dircount * 12 + 4; - else - space = sizeof(TIFFHeaderBig) + 8 + 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); - if (typewidth == 0) - { - TIFFErrorExtR( - tif, module, - "Cannot determine size of unknown tag type %" PRIu16, - dp->tdir_type); - return -1; - } - if (dp->tdir_count > UINT64_MAX / typewidth) - return -1; - datasize = (uint64_t)typewidth * dp->tdir_count; - if (!(tif->tif_flags & TIFF_BIGTIFF)) - { - if (datasize <= 4) - datasize = 0; - } - else - { - if (datasize <= 8) - datasize = 0; - } - if (space > UINT64_MAX - datasize) - return -1; - space += datasize; - } - if (filesize < space) - /* we should perhaps return in error ? */ - space = filesize; - else - space = filesize - space; - if (td->td_planarconfig == PLANARCONFIG_SEPARATE) - space /= td->td_samplesperpixel; - for (strip = 0; strip < td->td_nstrips; strip++) - td->td_stripbytecount_p[strip] = space; - /* - * This gross hack handles the case were the offset to - * the last strip is past the place where we think the strip - * should begin. Since a strip of data must be contiguous, - * it's safe to assume that we've overestimated the amount - * of data in the strip and trim this number back accordingly. - */ - strip--; - if (td->td_stripoffset_p[strip] > - UINT64_MAX - td->td_stripbytecount_p[strip]) - return -1; - if (td->td_stripoffset_p[strip] + td->td_stripbytecount_p[strip] > - filesize) - { - if (td->td_stripoffset_p[strip] >= filesize) - { - /* Not sure what we should in that case... */ - td->td_stripbytecount_p[strip] = 0; - } - else - { - td->td_stripbytecount_p[strip] = - filesize - td->td_stripoffset_p[strip]; - } - } - } - else if (isTiled(tif)) - { - uint64_t bytespertile = TIFFTileSize64(tif); - - for (strip = 0; strip < td->td_nstrips; strip++) - td->td_stripbytecount_p[strip] = bytespertile; - } - else - { - uint64_t rowbytes = TIFFScanlineSize64(tif); - uint32_t rowsperstrip = td->td_imagelength / td->td_stripsperimage; - for (strip = 0; strip < td->td_nstrips; strip++) - { - if (rowbytes > 0 && rowsperstrip > UINT64_MAX / rowbytes) - return -1; - td->td_stripbytecount_p[strip] = rowbytes * rowsperstrip; - } - } - TIFFSetFieldBit(tif, FIELD_STRIPBYTECOUNTS); - if (!TIFFFieldSet(tif, FIELD_ROWSPERSTRIP)) - td->td_rowsperstrip = td->td_imagelength; - return 1; -} - -static void MissingRequired(TIFF *tif, const char *tagname) -{ - static const char module[] = "MissingRequired"; - - TIFFErrorExtR(tif, module, - "TIFF directory is missing required \"%s\" field", tagname); -} - -static unsigned long hashFuncOffsetToNumber(const void *elt) -{ - const TIFFOffsetAndDirNumber *offsetAndDirNumber = - (const TIFFOffsetAndDirNumber *)elt; - const uint32_t hash = (uint32_t)(offsetAndDirNumber->offset >> 32) ^ - ((uint32_t)offsetAndDirNumber->offset & 0xFFFFFFFFU); - return hash; -} - -static bool equalFuncOffsetToNumber(const void *elt1, const void *elt2) -{ - const TIFFOffsetAndDirNumber *offsetAndDirNumber1 = - (const TIFFOffsetAndDirNumber *)elt1; - const TIFFOffsetAndDirNumber *offsetAndDirNumber2 = - (const TIFFOffsetAndDirNumber *)elt2; - return offsetAndDirNumber1->offset == offsetAndDirNumber2->offset; -} - -static unsigned long hashFuncNumberToOffset(const void *elt) -{ - const TIFFOffsetAndDirNumber *offsetAndDirNumber = - (const TIFFOffsetAndDirNumber *)elt; - return offsetAndDirNumber->dirNumber; -} - -static bool equalFuncNumberToOffset(const void *elt1, const void *elt2) -{ - const TIFFOffsetAndDirNumber *offsetAndDirNumber1 = - (const TIFFOffsetAndDirNumber *)elt1; - const TIFFOffsetAndDirNumber *offsetAndDirNumber2 = - (const TIFFOffsetAndDirNumber *)elt2; - return offsetAndDirNumber1->dirNumber == offsetAndDirNumber2->dirNumber; -} - -/* - * Check the directory number and offset against the list of already seen - * directory numbers and offsets. This is a trick to prevent IFD looping. - * The one can create TIFF file with looped directory pointers. We will - * maintain a list of already seen directories and check every IFD offset - * and its IFD number against that list. However, the offset of an IFD number - * can change - e.g. when writing updates to file. - * Returns 1 if all is ok; 0 if last directory or IFD loop is encountered, - * or an error has occurred. - */ -int _TIFFCheckDirNumberAndOffset(TIFF *tif, tdir_t dirn, uint64_t diroff) -{ - TIFFOffsetAndDirNumber entry; - TIFFOffsetAndDirNumber *foundEntry; - - if (diroff == 0) /* no more directories */ - return 0; - - if (tif->tif_map_dir_offset_to_number == NULL) - { - tif->tif_map_dir_offset_to_number = TIFFHashSetNew( - hashFuncOffsetToNumber, equalFuncOffsetToNumber, free); - if (tif->tif_map_dir_offset_to_number == NULL) - { - TIFFErrorExtR(tif, "_TIFFCheckDirNumberAndOffset", - "Not enough memory"); - return 1; - } - } - - if (tif->tif_map_dir_number_to_offset == NULL) - { - /* No free callback for this map, as it shares the same items as - * tif->tif_map_dir_offset_to_number. */ - tif->tif_map_dir_number_to_offset = TIFFHashSetNew( - hashFuncNumberToOffset, equalFuncNumberToOffset, NULL); - if (tif->tif_map_dir_number_to_offset == NULL) - { - TIFFErrorExtR(tif, "_TIFFCheckDirNumberAndOffset", - "Not enough memory"); - return 1; - } - } - - /* Check if offset is already in the list: - * - yes: check, if offset is at the same IFD number - if not, it is an IFD - * loop - * - no: add to list or update offset at that IFD number - */ - entry.offset = diroff; - entry.dirNumber = dirn; - - foundEntry = - (TIFFOffsetAndDirNumber *)TIFFHashSetLookup( - tif->tif_map_dir_offset_to_number, &entry); - if (foundEntry) - { - if (foundEntry->dirNumber == dirn) - { - return 1; - } - else - { - TIFFWarningExtR(tif, "_TIFFCheckDirNumberAndOffset", - "TIFF directory %d has IFD looping to directory %u " - "at offset 0x%" PRIx64 " (%" PRIu64 ")", - (int)dirn - 1, foundEntry->dirNumber, diroff, - diroff); - return 0; - } - } - - /* Check if offset of an IFD has been changed and update offset of that IFD - * number. */ - foundEntry = (TIFFOffsetAndDirNumber *)TIFFHashSetLookup( - tif->tif_map_dir_number_to_offset, &entry); - if (foundEntry) - { - if (foundEntry->offset != diroff) - { - TIFFOffsetAndDirNumber entryOld; - TIFFOffsetAndDirNumber *foundEntryOld; - entryOld.offset = foundEntry->offset; - entryOld.dirNumber = dirn; - /* We must remove first from tif_map_dir_number_to_offset as the */ - /* entry is owned (and thus freed) by */ - /* tif_map_dir_offset_to_number */ - foundEntryOld = - (TIFFOffsetAndDirNumber *)TIFFHashSetLookup( - tif->tif_map_dir_number_to_offset, &entryOld); - if (foundEntryOld) - { - TIFFHashSetRemove(tif->tif_map_dir_number_to_offset, - foundEntryOld); - } - foundEntryOld = (TIFFOffsetAndDirNumber *)TIFFHashSetLookup( - tif->tif_map_dir_offset_to_number, &entryOld); - if (foundEntryOld) - { - TIFFHashSetRemove(tif->tif_map_dir_offset_to_number, - foundEntryOld); - } - - { - TIFFOffsetAndDirNumber *entryPtr = (TIFFOffsetAndDirNumber *)malloc( - sizeof(TIFFOffsetAndDirNumber)); - if (entryPtr == NULL) - { - return 0; - } - - /* Add IFD offset and dirn to IFD directory list */ - *entryPtr = entry; - - if (!TIFFHashSetInsert(tif->tif_map_dir_offset_to_number, entryPtr)) - { - TIFFErrorExtR( - tif, "_TIFFCheckDirNumberAndOffset", - "Insertion in tif_map_dir_offset_to_number failed"); - return 0; - } - if (!TIFFHashSetInsert(tif->tif_map_dir_number_to_offset, entryPtr)) - { - TIFFErrorExtR( - tif, "_TIFFCheckDirNumberAndOffset", - "Insertion in tif_map_dir_number_to_offset failed"); - return 0; - } - } - } - return 1; - } - - /* Arbitrary (hopefully big enough) limit */ - if (TIFFHashSetSize(tif->tif_map_dir_offset_to_number) >= - TIFF_MAX_DIR_COUNT) - { - TIFFErrorExtR(tif, "_TIFFCheckDirNumberAndOffset", - "Cannot handle more than %u TIFF directories", - TIFF_MAX_DIR_COUNT); - return 0; - } - - { - TIFFOffsetAndDirNumber *entryPtr = - (TIFFOffsetAndDirNumber *)malloc(sizeof(TIFFOffsetAndDirNumber)); - if (entryPtr == NULL) - { - TIFFErrorExtR(tif, "_TIFFCheckDirNumberAndOffset", - "malloc(sizeof(TIFFOffsetAndDirNumber)) failed"); - return 0; - } - - /* Add IFD offset and dirn to IFD directory list */ - *entryPtr = entry; - - if (!TIFFHashSetInsert(tif->tif_map_dir_offset_to_number, entryPtr)) - { - TIFFErrorExtR(tif, "_TIFFCheckDirNumberAndOffset", - "Insertion in tif_map_dir_offset_to_number failed"); - return 0; - } - if (!TIFFHashSetInsert(tif->tif_map_dir_number_to_offset, entryPtr)) - { - TIFFErrorExtR(tif, "_TIFFCheckDirNumberAndOffset", - "Insertion in tif_map_dir_number_to_offset failed"); - return 0; - } - } - - return 1; -} /* --- _TIFFCheckDirNumberAndOffset() ---*/ - -/* - * Retrieve the matching IFD directory number of a given IFD offset - * from the list of directories already seen. - * Returns 1 if the offset was in the list and the directory number - * can be returned. - * Otherwise returns 0 or if an error occurred. - */ -int _TIFFGetDirNumberFromOffset(TIFF *tif, uint64_t diroff, tdir_t *dirn) -{ - TIFFOffsetAndDirNumber entry; - TIFFOffsetAndDirNumber *foundEntry; - if (diroff == 0) /* no more directories */ - return 0; - - /* Check if offset is already in the list and return matching directory - * number. Otherwise update IFD list using TIFFNumberOfDirectories() and - * search again in IFD list. - */ - if (tif->tif_map_dir_offset_to_number == NULL) - return 0; - entry.offset = diroff; - entry.dirNumber = 0; /* not used */ - - foundEntry = - (TIFFOffsetAndDirNumber *)TIFFHashSetLookup( - tif->tif_map_dir_offset_to_number, &entry); - if (foundEntry) - { - *dirn = foundEntry->dirNumber; - return 1; - } - - /* This updates the directory list for all main-IFDs in the file. */ - TIFFNumberOfDirectories(tif); - - foundEntry = (TIFFOffsetAndDirNumber *)TIFFHashSetLookup( - tif->tif_map_dir_offset_to_number, &entry); - if (foundEntry) - { - *dirn = foundEntry->dirNumber; - return 1; - } - - return 0; -} /*--- _TIFFGetDirNumberFromOffset() ---*/ - -/* - * Retrieve the matching IFD directory offset of a given IFD number - * from the list of directories already seen. - * Returns 1 if the offset was in the list of already seen IFDs and the - * directory offset can be returned. The directory list is not updated. - * Otherwise returns 0 or if an error occurred. - */ -int _TIFFGetOffsetFromDirNumber(TIFF *tif, tdir_t dirn, uint64_t *diroff) -{ - - TIFFOffsetAndDirNumber entry; - TIFFOffsetAndDirNumber *foundEntry; - if (tif->tif_map_dir_number_to_offset == NULL) - return 0; - entry.offset = 0; /* not used */ - entry.dirNumber = dirn; - - foundEntry = - (TIFFOffsetAndDirNumber *)TIFFHashSetLookup( - tif->tif_map_dir_number_to_offset, &entry); - if (foundEntry) - { - *diroff = foundEntry->offset; - return 1; - } - - return 0; -} /*--- _TIFFGetOffsetFromDirNumber() ---*/ - -/* - * Remove an entry from the directory list of already seen directories - * by directory offset. - * If an entry is to be removed from the list, it is also okay if the entry - * is not in the list or the list does not exist. - */ -int _TIFFRemoveEntryFromDirectoryListByOffset(TIFF *tif, uint64_t diroff) -{ - TIFFOffsetAndDirNumber entryOld; - TIFFOffsetAndDirNumber *foundEntryOldOff; - if (tif->tif_map_dir_offset_to_number == NULL) - return 1; - - entryOld.offset = diroff; - entryOld.dirNumber = 0; - /* We must remove first from tif_map_dir_number_to_offset as the - * entry is owned (and thus freed) by tif_map_dir_offset_to_number. - * However, we need firstly to find the directory number from offset. */ - - foundEntryOldOff = - (TIFFOffsetAndDirNumber *)TIFFHashSetLookup( - tif->tif_map_dir_offset_to_number, &entryOld); - if (foundEntryOldOff) - { - entryOld.dirNumber = foundEntryOldOff->dirNumber; - if (tif->tif_map_dir_number_to_offset != NULL) - { - TIFFOffsetAndDirNumber *foundEntryOldDir = - (TIFFOffsetAndDirNumber *)TIFFHashSetLookup( - tif->tif_map_dir_number_to_offset, &entryOld); - if (foundEntryOldDir) - { - TIFFHashSetRemove(tif->tif_map_dir_number_to_offset, - foundEntryOldDir); - TIFFHashSetRemove(tif->tif_map_dir_offset_to_number, - foundEntryOldOff); - return 1; - } - } - else - { - TIFFErrorExtR(tif, "_TIFFRemoveEntryFromDirectoryListByOffset", - "Unexpectedly tif_map_dir_number_to_offset is " - "missing but tif_map_dir_offset_to_number exists."); - return 0; - } - } - return 1; -} /*--- _TIFFRemoveEntryFromDirectoryListByOffset() ---*/ - -/* - * Check the count field of a directory entry against a known value. The - * caller is expected to skip/ignore the tag if there is a mismatch. - */ -static int CheckDirCount(TIFF *tif, TIFFDirEntry *dir, uint32_t count) -{ - if ((uint64_t)count > dir->tdir_count) - { - const TIFFField *fip = TIFFFieldWithTag(tif, dir->tdir_tag); - TIFFWarningExtR(tif, tif->tif_name, - "incorrect count for field \"%s\" (%" PRIu64 - ", expecting %" PRIu32 "); tag ignored", - fip ? fip->field_name : "unknown tagname", - dir->tdir_count, count); - return (0); - } - else if ((uint64_t)count < dir->tdir_count) - { - const TIFFField *fip = TIFFFieldWithTag(tif, dir->tdir_tag); - TIFFWarningExtR(tif, tif->tif_name, - "incorrect count for field \"%s\" (%" PRIu64 - ", expecting %" PRIu32 "); tag trimmed", - fip ? fip->field_name : "unknown tagname", - dir->tdir_count, count); - dir->tdir_count = count; - return (1); - } - return (1); -} - -/* - * Read IFD structure from the specified offset. If the pointer to - * nextdiroff variable has been specified, read it too. Function returns a - * number of fields in the directory or 0 if failed. - */ -static uint16_t TIFFFetchDirectory(TIFF *tif, uint64_t diroff, - TIFFDirEntry **pdir, uint64_t *nextdiroff) -{ - static const char module[] = "TIFFFetchDirectory"; - - void *origdir; - uint16_t dircount16; - uint32_t dirsize; - TIFFDirEntry *dir; - uint8_t *ma; - TIFFDirEntry *mb; - uint16_t n; - - assert(pdir); - - tif->tif_diroff = diroff; - if (nextdiroff) - *nextdiroff = 0; - if (!isMapped(tif)) - { - if (!SeekOK(tif, tif->tif_diroff)) - { - TIFFErrorExtR(tif, module, - "%s: Seek error accessing TIFF directory", - tif->tif_name); - return 0; - } - if (!(tif->tif_flags & TIFF_BIGTIFF)) - { - if (!ReadOK(tif, &dircount16, sizeof(uint16_t))) - { - TIFFErrorExtR(tif, module, - "%s: Can not read TIFF directory count", - tif->tif_name); - return 0; - } - if (tif->tif_flags & TIFF_SWAB) - TIFFSwabShort(&dircount16); - if (dircount16 > 4096) - { - TIFFErrorExtR(tif, module, - "Sanity check on directory count failed, this is " - "probably not a valid IFD offset"); - return 0; - } - dirsize = 12; - } - else - { - uint64_t dircount64; - if (!ReadOK(tif, &dircount64, sizeof(uint64_t))) - { - TIFFErrorExtR(tif, module, - "%s: Can not read TIFF directory count", - tif->tif_name); - return 0; - } - if (tif->tif_flags & TIFF_SWAB) - TIFFSwabLong8(&dircount64); - if (dircount64 > 4096) - { - TIFFErrorExtR(tif, module, - "Sanity check on directory count failed, this is " - "probably not a valid IFD offset"); - return 0; - } - dircount16 = (uint16_t)dircount64; - dirsize = 20; - } - origdir = _TIFFCheckMalloc(tif, dircount16, dirsize, - "to read TIFF directory"); - if (origdir == NULL) - return 0; - if (!ReadOK(tif, origdir, (tmsize_t)(dircount16 * dirsize))) - { - TIFFErrorExtR(tif, module, "%.100s: Can not read TIFF directory", - tif->tif_name); - _TIFFfreeExt(tif, origdir); - return 0; - } - /* - * Read offset to next directory for sequential scans if - * needed. - */ - if (nextdiroff) - { - if (!(tif->tif_flags & TIFF_BIGTIFF)) - { - uint32_t nextdiroff32; - if (!ReadOK(tif, &nextdiroff32, sizeof(uint32_t))) - nextdiroff32 = 0; - if (tif->tif_flags & TIFF_SWAB) - TIFFSwabLong(&nextdiroff32); - *nextdiroff = nextdiroff32; - } - else - { - if (!ReadOK(tif, nextdiroff, sizeof(uint64_t))) - *nextdiroff = 0; - if (tif->tif_flags & TIFF_SWAB) - TIFFSwabLong8(nextdiroff); - } - } - } - else - { - tmsize_t m; - tmsize_t off; - if (tif->tif_diroff > (uint64_t)INT64_MAX) - { - TIFFErrorExtR(tif, module, "Can not read TIFF directory count"); - return (0); - } - off = (tmsize_t)tif->tif_diroff; - - /* - * Check for integer overflow when validating the dir_off, - * otherwise a very high offset may cause an OOB read and - * crash the client. Make two comparisons instead of - * - * off + sizeof(uint16_t) > tif->tif_size - * - * to avoid overflow. - */ - if (!(tif->tif_flags & TIFF_BIGTIFF)) - { - m = off + sizeof(uint16_t); - if ((m < off) || (m < (tmsize_t)sizeof(uint16_t)) || - (m > tif->tif_size)) - { - TIFFErrorExtR(tif, module, "Can not read TIFF directory count"); - return 0; - } - else - { - _TIFFmemcpy(&dircount16, tif->tif_base + off, sizeof(uint16_t)); - } - off += sizeof(uint16_t); - if (tif->tif_flags & TIFF_SWAB) - TIFFSwabShort(&dircount16); - if (dircount16 > 4096) - { - TIFFErrorExtR(tif, module, - "Sanity check on directory count failed, this is " - "probably not a valid IFD offset"); - return 0; - } - dirsize = 12; - } - else - { - uint64_t dircount64; - m = off + sizeof(uint64_t); - if ((m < off) || (m < (tmsize_t)sizeof(uint64_t)) || - (m > tif->tif_size)) - { - TIFFErrorExtR(tif, module, "Can not read TIFF directory count"); - return 0; - } - else - { - _TIFFmemcpy(&dircount64, tif->tif_base + off, sizeof(uint64_t)); - } - off += sizeof(uint64_t); - if (tif->tif_flags & TIFF_SWAB) - TIFFSwabLong8(&dircount64); - if (dircount64 > 4096) - { - TIFFErrorExtR(tif, module, - "Sanity check on directory count failed, this is " - "probably not a valid IFD offset"); - return 0; - } - dircount16 = (uint16_t)dircount64; - dirsize = 20; - } - if (dircount16 == 0) - { - TIFFErrorExtR(tif, module, - "Sanity check on directory count failed, zero tag " - "directories not supported"); - return 0; - } - origdir = _TIFFCheckMalloc(tif, dircount16, dirsize, - "to read TIFF directory"); - if (origdir == NULL) - return 0; - m = off + dircount16 * dirsize; - if ((m < off) || (m < (tmsize_t)(dircount16 * dirsize)) || - (m > tif->tif_size)) - { - TIFFErrorExtR(tif, module, "Can not read TIFF directory"); - _TIFFfreeExt(tif, origdir); - return 0; - } - else - { - _TIFFmemcpy(origdir, tif->tif_base + off, dircount16 * dirsize); - } - if (nextdiroff) - { - off += dircount16 * dirsize; - 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)) - nextdiroff32 = 0; - else - _TIFFmemcpy(&nextdiroff32, tif->tif_base + off, - sizeof(uint32_t)); - if (tif->tif_flags & TIFF_SWAB) - TIFFSwabLong(&nextdiroff32); - *nextdiroff = nextdiroff32; - } - else - { - m = off + sizeof(uint64_t); - if ((m < off) || (m < (tmsize_t)sizeof(uint64_t)) || - (m > tif->tif_size)) - *nextdiroff = 0; - else - _TIFFmemcpy(nextdiroff, tif->tif_base + off, - sizeof(uint64_t)); - if (tif->tif_flags & TIFF_SWAB) - TIFFSwabLong8(nextdiroff); - } - } - } - dir = (TIFFDirEntry *)_TIFFCheckMalloc( - tif, dircount16, sizeof(TIFFDirEntry), "to read TIFF directory"); - if (dir == 0) - { - _TIFFfreeExt(tif, origdir); - return 0; - } - ma = (uint8_t *)origdir; - mb = dir; - for (n = 0; n < dircount16; n++) - { - mb->tdir_ignore = FALSE; - if (tif->tif_flags & TIFF_SWAB) - TIFFSwabShort((uint16_t *)ma); - mb->tdir_tag = *(uint16_t *)ma; - ma += sizeof(uint16_t); - if (tif->tif_flags & TIFF_SWAB) - TIFFSwabShort((uint16_t *)ma); - mb->tdir_type = *(uint16_t *)ma; - ma += sizeof(uint16_t); - if (!(tif->tif_flags & TIFF_BIGTIFF)) - { - if (tif->tif_flags & TIFF_SWAB) - TIFFSwabLong((uint32_t *)ma); - mb->tdir_count = (uint64_t)(*(uint32_t *)ma); - ma += sizeof(uint32_t); - mb->tdir_offset.toff_long8 = 0; - *(uint32_t *)(&mb->tdir_offset) = *(uint32_t *)ma; - ma += sizeof(uint32_t); - } - else - { - if (tif->tif_flags & TIFF_SWAB) - TIFFSwabLong8((uint64_t *)ma); - mb->tdir_count = TIFFReadUInt64(ma); - ma += sizeof(uint64_t); - mb->tdir_offset.toff_long8 = TIFFReadUInt64(ma); - ma += sizeof(uint64_t); - } - mb++; - } - _TIFFfreeExt(tif, origdir); - *pdir = dir; - return dircount16; -} - -/* - * Fetch a tag that is not handled by special case code. - */ -static int TIFFFetchNormalTag(TIFF *tif, TIFFDirEntry *dp, int recover) -{ - static const char module[] = "TIFFFetchNormalTag"; - enum TIFFReadDirEntryErr err; - uint32_t fii; - const TIFFField *fip = NULL; - TIFFReadDirectoryFindFieldInfo(tif, dp->tdir_tag, &fii); - if (fii == FAILED_FII) - { - TIFFErrorExtR(tif, "TIFFFetchNormalTag", - "No definition found for tag %" PRIu16, dp->tdir_tag); - return 0; - } - fip = tif->tif_fields[fii]; - assert(fip != NULL); /* should not happen */ - assert(fip->set_field_type != - TIFF_SETGET_OTHER); /* if so, we shouldn't arrive here but deal with - this in specialized code */ - assert(fip->set_field_type != - TIFF_SETGET_INT); /* if so, we shouldn't arrive here as this is only - the case for pseudo-tags */ - err = TIFFReadDirEntryErrOk; - switch (fip->set_field_type) - { - case TIFF_SETGET_UNDEFINED: - TIFFErrorExtR( - tif, "TIFFFetchNormalTag", - "Defined set_field_type of custom tag %u (%s) is " - "TIFF_SETGET_UNDEFINED and thus tag is not read from file", - fip->field_tag, fip->field_name); - break; - case TIFF_SETGET_ASCII: - { - uint8_t *data; - assert(fip->field_passcount == 0); - err = TIFFReadDirEntryByteArray(tif, dp, &data); - if (err == TIFFReadDirEntryErrOk) - { - size_t mb = 0; - int n; - if (data != NULL) - { - if (dp->tdir_count > 0 && data[dp->tdir_count - 1] == 0) - { - /* optimization: if data is known to be 0 terminated, we - * can use strlen() */ - mb = strlen((const char *)data); - } - else - { - /* general case. equivalent to non-portable */ - /* mb = strnlen((const char*)data, - * (uint32_t)dp->tdir_count); */ - uint8_t *ma = data; - while (mb < (uint32_t)dp->tdir_count) - { - if (*ma == 0) - break; - ma++; - mb++; - } - } - } - if (mb + 1 < (uint32_t)dp->tdir_count) - TIFFWarningExtR( - tif, module, - "ASCII value for tag \"%s\" contains null byte in " - "value; value incorrectly truncated during reading due " - "to implementation limitations", - fip->field_name); - else if (mb + 1 > (uint32_t)dp->tdir_count) - { - uint8_t *o; - TIFFWarningExtR( - tif, module, - "ASCII value for tag \"%s\" does not end in null byte", - fip->field_name); - /* TIFFReadDirEntryArrayWithLimit() ensures this can't be - * larger than MAX_SIZE_TAG_DATA */ - assert((uint32_t)dp->tdir_count + 1 == dp->tdir_count + 1); - o = _TIFFmallocExt(tif, (uint32_t)dp->tdir_count + 1); - if (o == NULL) - { - if (data != NULL) - _TIFFfreeExt(tif, data); - return (0); - } - if (dp->tdir_count > 0) - { - _TIFFmemcpy(o, data, (uint32_t)dp->tdir_count); - } - o[(uint32_t)dp->tdir_count] = 0; - if (data != 0) - _TIFFfreeExt(tif, data); - data = o; - } - n = TIFFSetField(tif, dp->tdir_tag, data); - if (data != 0) - _TIFFfreeExt(tif, data); - if (!n) - return (0); - } - } - break; - case TIFF_SETGET_UINT8: - { - uint8_t data = 0; - assert(fip->field_readcount == 1); - assert(fip->field_passcount == 0); - err = TIFFReadDirEntryByte(tif, dp, &data); - if (err == TIFFReadDirEntryErrOk) - { - if (!TIFFSetField(tif, dp->tdir_tag, data)) - return (0); - } - } - break; - case TIFF_SETGET_SINT8: - { - int8_t data = 0; - assert(fip->field_readcount == 1); - assert(fip->field_passcount == 0); - err = TIFFReadDirEntrySbyte(tif, dp, &data); - if (err == TIFFReadDirEntryErrOk) - { - if (!TIFFSetField(tif, dp->tdir_tag, data)) - return (0); - } - } - break; - case TIFF_SETGET_UINT16: - { - uint16_t data; - assert(fip->field_readcount == 1); - assert(fip->field_passcount == 0); - err = TIFFReadDirEntryShort(tif, dp, &data); - if (err == TIFFReadDirEntryErrOk) - { - if (!TIFFSetField(tif, dp->tdir_tag, data)) - return (0); - } - } - break; - case TIFF_SETGET_SINT16: - { - int16_t data; - assert(fip->field_readcount == 1); - assert(fip->field_passcount == 0); - err = TIFFReadDirEntrySshort(tif, dp, &data); - if (err == TIFFReadDirEntryErrOk) - { - if (!TIFFSetField(tif, dp->tdir_tag, data)) - return (0); - } - } - break; - case TIFF_SETGET_UINT32: - { - uint32_t data; - assert(fip->field_readcount == 1); - assert(fip->field_passcount == 0); - err = TIFFReadDirEntryLong(tif, dp, &data); - if (err == TIFFReadDirEntryErrOk) - { - if (!TIFFSetField(tif, dp->tdir_tag, data)) - return (0); - } - } - break; - case TIFF_SETGET_SINT32: - { - int32_t data; - assert(fip->field_readcount == 1); - assert(fip->field_passcount == 0); - err = TIFFReadDirEntrySlong(tif, dp, &data); - if (err == TIFFReadDirEntryErrOk) - { - if (!TIFFSetField(tif, dp->tdir_tag, data)) - return (0); - } - } - break; - case TIFF_SETGET_UINT64: - { - uint64_t data; - assert(fip->field_readcount == 1); - assert(fip->field_passcount == 0); - err = TIFFReadDirEntryLong8(tif, dp, &data); - if (err == TIFFReadDirEntryErrOk) - { - if (!TIFFSetField(tif, dp->tdir_tag, data)) - return (0); - } - } - break; - case TIFF_SETGET_SINT64: - { - int64_t data; - assert(fip->field_readcount == 1); - assert(fip->field_passcount == 0); - err = TIFFReadDirEntrySlong8(tif, dp, &data); - if (err == TIFFReadDirEntryErrOk) - { - if (!TIFFSetField(tif, dp->tdir_tag, data)) - return (0); - } - } - break; - case TIFF_SETGET_FLOAT: - { - float data; - assert(fip->field_readcount == 1); - assert(fip->field_passcount == 0); - err = TIFFReadDirEntryFloat(tif, dp, &data); - if (err == TIFFReadDirEntryErrOk) - { - if (!TIFFSetField(tif, dp->tdir_tag, data)) - return (0); - } - } - break; - case TIFF_SETGET_DOUBLE: - { - double data; - assert(fip->field_readcount == 1); - assert(fip->field_passcount == 0); - err = TIFFReadDirEntryDouble(tif, dp, &data); - if (err == TIFFReadDirEntryErrOk) - { - if (!TIFFSetField(tif, dp->tdir_tag, data)) - return (0); - } - } - break; - case TIFF_SETGET_IFD8: - { - uint64_t data; - assert(fip->field_readcount == 1); - assert(fip->field_passcount == 0); - err = TIFFReadDirEntryIfd8(tif, dp, &data); - if (err == TIFFReadDirEntryErrOk) - { - if (!TIFFSetField(tif, dp->tdir_tag, data)) - return (0); - } - } - break; - case TIFF_SETGET_UINT16_PAIR: - { - uint16_t *data; - assert(fip->field_readcount == 2); - assert(fip->field_passcount == 0); - if (dp->tdir_count != 2) - { - TIFFWarningExtR(tif, module, - "incorrect count for field \"%s\", expected 2, " - "got %" PRIu64, - fip->field_name, dp->tdir_count); - return (0); - } - err = TIFFReadDirEntryShortArray(tif, dp, &data); - if (err == TIFFReadDirEntryErrOk) - { - int m; - assert(data); /* avoid CLang static Analyzer false positive */ - m = TIFFSetField(tif, dp->tdir_tag, data[0], data[1]); - _TIFFfreeExt(tif, data); - if (!m) - return (0); - } - } - break; - case TIFF_SETGET_C0_UINT8: - { - uint8_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 = TIFFReadDirEntryByteArray(tif, dp, &data); - if (err == TIFFReadDirEntryErrOk) - { - int m; - m = TIFFSetField(tif, dp->tdir_tag, data); - if (data != 0) - _TIFFfreeExt(tif, data); - if (!m) - return (0); - } - } - } - break; - case TIFF_SETGET_C0_SINT8: - { - int8_t *data; - assert(fip->field_readcount >= 1); - assert(fip->field_passcount == 0); - if (dp->tdir_count != (uint64_t)fip->field_readcount) - { - 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 = TIFFReadDirEntrySbyteArray(tif, dp, &data); - if (err == TIFFReadDirEntryErrOk) - { - int m; - m = TIFFSetField(tif, dp->tdir_tag, data); - if (data != 0) - _TIFFfreeExt(tif, data); - if (!m) - return (0); - } - } - } - break; - case TIFF_SETGET_C0_UINT16: - { - uint16_t *data; - assert(fip->field_readcount >= 1); - assert(fip->field_passcount == 0); - if (dp->tdir_count != (uint64_t)fip->field_readcount) - { - 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 = TIFFReadDirEntryShortArray(tif, dp, &data); - if (err == TIFFReadDirEntryErrOk) - { - int m; - m = TIFFSetField(tif, dp->tdir_tag, data); - if (data != 0) - _TIFFfreeExt(tif, data); - if (!m) - return (0); - } - } - } - break; - case TIFF_SETGET_C0_SINT16: - { - int16_t *data; - assert(fip->field_readcount >= 1); - assert(fip->field_passcount == 0); - if (dp->tdir_count != (uint64_t)fip->field_readcount) - { - 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 = TIFFReadDirEntrySshortArray(tif, dp, &data); - if (err == TIFFReadDirEntryErrOk) - { - int m; - m = TIFFSetField(tif, dp->tdir_tag, data); - if (data != 0) - _TIFFfreeExt(tif, data); - if (!m) - return (0); - } - } - } - break; - case TIFF_SETGET_C0_UINT32: - { - uint32_t *data; - assert(fip->field_readcount >= 1); - assert(fip->field_passcount == 0); - if (dp->tdir_count != (uint64_t)fip->field_readcount) - { - 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 = TIFFReadDirEntryLongArray(tif, dp, &data); - if (err == TIFFReadDirEntryErrOk) - { - int m; - m = TIFFSetField(tif, dp->tdir_tag, data); - if (data != 0) - _TIFFfreeExt(tif, data); - if (!m) - return (0); - } - } - } - break; - case TIFF_SETGET_C0_SINT32: - { - int32_t *data; - assert(fip->field_readcount >= 1); - assert(fip->field_passcount == 0); - if (dp->tdir_count != (uint64_t)fip->field_readcount) - { - 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 = TIFFReadDirEntrySlongArray(tif, dp, &data); - if (err == TIFFReadDirEntryErrOk) - { - int m; - m = TIFFSetField(tif, dp->tdir_tag, data); - if (data != 0) - _TIFFfreeExt(tif, data); - if (!m) - return (0); - } - } - } - break; - case TIFF_SETGET_C0_UINT64: - { - uint64_t *data; - assert(fip->field_readcount >= 1); - assert(fip->field_passcount == 0); - if (dp->tdir_count != (uint64_t)fip->field_readcount) - { - 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 = TIFFReadDirEntryLong8Array(tif, dp, &data); - if (err == TIFFReadDirEntryErrOk) - { - int m; - m = TIFFSetField(tif, dp->tdir_tag, data); - if (data != 0) - _TIFFfreeExt(tif, data); - if (!m) - return (0); - } - } - } - break; - case TIFF_SETGET_C0_SINT64: - { - int64_t *data; - assert(fip->field_readcount >= 1); - assert(fip->field_passcount == 0); - if (dp->tdir_count != (uint64_t)fip->field_readcount) - { - 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 = TIFFReadDirEntrySlong8Array(tif, dp, &data); - if (err == TIFFReadDirEntryErrOk) - { - int m; - m = TIFFSetField(tif, dp->tdir_tag, data); - if (data != 0) - _TIFFfreeExt(tif, data); - if (!m) - return (0); - } - } - } - break; - case TIFF_SETGET_C0_FLOAT: - { - float *data; - assert(fip->field_readcount >= 1); - assert(fip->field_passcount == 0); - if (dp->tdir_count != (uint64_t)fip->field_readcount) - { - 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 = TIFFReadDirEntryFloatArray(tif, dp, &data); - if (err == TIFFReadDirEntryErrOk) - { - int m; - m = TIFFSetField(tif, dp->tdir_tag, data); - if (data != 0) - _TIFFfreeExt(tif, data); - if (!m) - return (0); - } - } - } - break; - /*--: Rational2Double: Extend for Double Arrays and Rational-Arrays read - * into Double-Arrays. */ - case TIFF_SETGET_C0_DOUBLE: - { - double *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 = TIFFReadDirEntryDoubleArray(tif, dp, &data); - if (err == TIFFReadDirEntryErrOk) - { - 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; - assert(fip->field_readcount == TIFF_VARIABLE); - assert(fip->field_passcount == 1); - if (dp->tdir_count > 0xFFFF) - err = TIFFReadDirEntryErrCount; - else - { - err = TIFFReadDirEntryByteArray(tif, dp, &data); - if (err == TIFFReadDirEntryErrOk) - { - int m; - if (data != 0 && dp->tdir_count > 0 && - data[dp->tdir_count - 1] != '\0') - { - TIFFWarningExtR( - tif, module, - "ASCII value for tag \"%s\" does not end in null " - "byte. Forcing it to be null", - fip->field_name); - data[dp->tdir_count - 1] = '\0'; - } - m = TIFFSetField(tif, dp->tdir_tag, - (uint16_t)(dp->tdir_count), data); - if (data != 0) - _TIFFfreeExt(tif, data); - if (!m) - return (0); - } - } - } - break; - case TIFF_SETGET_C16_UINT8: - { - uint8_t *data; - assert(fip->field_readcount == TIFF_VARIABLE); - assert(fip->field_passcount == 1); - if (dp->tdir_count > 0xFFFF) - err = TIFFReadDirEntryErrCount; - else - { - err = TIFFReadDirEntryByteArray(tif, dp, &data); - if (err == TIFFReadDirEntryErrOk) - { - int m; - m = TIFFSetField(tif, dp->tdir_tag, - (uint16_t)(dp->tdir_count), data); - if (data != 0) - _TIFFfreeExt(tif, data); - if (!m) - return (0); - } - } - } - break; - case TIFF_SETGET_C16_SINT8: - { - int8_t *data; - assert(fip->field_readcount == TIFF_VARIABLE); - assert(fip->field_passcount == 1); - if (dp->tdir_count > 0xFFFF) - err = TIFFReadDirEntryErrCount; - else - { - err = TIFFReadDirEntrySbyteArray(tif, dp, &data); - if (err == TIFFReadDirEntryErrOk) - { - int m; - m = TIFFSetField(tif, dp->tdir_tag, - (uint16_t)(dp->tdir_count), data); - if (data != 0) - _TIFFfreeExt(tif, data); - if (!m) - return (0); - } - } - } - break; - case TIFF_SETGET_C16_UINT16: - { - uint16_t *data; - assert(fip->field_readcount == TIFF_VARIABLE); - assert(fip->field_passcount == 1); - if (dp->tdir_count > 0xFFFF) - err = TIFFReadDirEntryErrCount; - else - { - err = TIFFReadDirEntryShortArray(tif, dp, &data); - if (err == TIFFReadDirEntryErrOk) - { - int m; - m = TIFFSetField(tif, dp->tdir_tag, - (uint16_t)(dp->tdir_count), data); - if (data != 0) - _TIFFfreeExt(tif, data); - if (!m) - return (0); - } - } - } - break; - case TIFF_SETGET_C16_SINT16: - { - int16_t *data; - assert(fip->field_readcount == TIFF_VARIABLE); - assert(fip->field_passcount == 1); - if (dp->tdir_count > 0xFFFF) - err = TIFFReadDirEntryErrCount; - else - { - err = TIFFReadDirEntrySshortArray(tif, dp, &data); - if (err == TIFFReadDirEntryErrOk) - { - int m; - m = TIFFSetField(tif, dp->tdir_tag, - (uint16_t)(dp->tdir_count), data); - if (data != 0) - _TIFFfreeExt(tif, data); - if (!m) - return (0); - } - } - } - break; - case TIFF_SETGET_C16_UINT32: - { - uint32_t *data; - assert(fip->field_readcount == TIFF_VARIABLE); - assert(fip->field_passcount == 1); - if (dp->tdir_count > 0xFFFF) - err = TIFFReadDirEntryErrCount; - else - { - err = TIFFReadDirEntryLongArray(tif, dp, &data); - if (err == TIFFReadDirEntryErrOk) - { - int m; - m = TIFFSetField(tif, dp->tdir_tag, - (uint16_t)(dp->tdir_count), data); - if (data != 0) - _TIFFfreeExt(tif, data); - if (!m) - return (0); - } - } - } - break; - case TIFF_SETGET_C16_SINT32: - { - int32_t *data; - assert(fip->field_readcount == TIFF_VARIABLE); - assert(fip->field_passcount == 1); - if (dp->tdir_count > 0xFFFF) - err = TIFFReadDirEntryErrCount; - else - { - err = TIFFReadDirEntrySlongArray(tif, dp, &data); - if (err == TIFFReadDirEntryErrOk) - { - int m; - m = TIFFSetField(tif, dp->tdir_tag, - (uint16_t)(dp->tdir_count), data); - if (data != 0) - _TIFFfreeExt(tif, data); - if (!m) - return (0); - } - } - } - break; - case TIFF_SETGET_C16_UINT64: - { - uint64_t *data; - assert(fip->field_readcount == TIFF_VARIABLE); - assert(fip->field_passcount == 1); - if (dp->tdir_count > 0xFFFF) - err = TIFFReadDirEntryErrCount; - else - { - err = TIFFReadDirEntryLong8Array(tif, dp, &data); - if (err == TIFFReadDirEntryErrOk) - { - int m; - m = TIFFSetField(tif, dp->tdir_tag, - (uint16_t)(dp->tdir_count), data); - if (data != 0) - _TIFFfreeExt(tif, data); - if (!m) - return (0); - } - } - } - break; - case TIFF_SETGET_C16_SINT64: - { - int64_t *data; - assert(fip->field_readcount == TIFF_VARIABLE); - assert(fip->field_passcount == 1); - if (dp->tdir_count > 0xFFFF) - err = TIFFReadDirEntryErrCount; - else - { - err = TIFFReadDirEntrySlong8Array(tif, dp, &data); - if (err == TIFFReadDirEntryErrOk) - { - int m; - m = TIFFSetField(tif, dp->tdir_tag, - (uint16_t)(dp->tdir_count), data); - if (data != 0) - _TIFFfreeExt(tif, data); - if (!m) - return (0); - } - } - } - break; - case TIFF_SETGET_C16_FLOAT: - { - float *data; - assert(fip->field_readcount == TIFF_VARIABLE); - assert(fip->field_passcount == 1); - if (dp->tdir_count > 0xFFFF) - err = TIFFReadDirEntryErrCount; - else - { - err = TIFFReadDirEntryFloatArray(tif, dp, &data); - if (err == TIFFReadDirEntryErrOk) - { - int m; - m = TIFFSetField(tif, dp->tdir_tag, - (uint16_t)(dp->tdir_count), data); - if (data != 0) - _TIFFfreeExt(tif, data); - if (!m) - return (0); - } - } - } - break; - case TIFF_SETGET_C16_DOUBLE: - { - double *data; - assert(fip->field_readcount == TIFF_VARIABLE); - assert(fip->field_passcount == 1); - if (dp->tdir_count > 0xFFFF) - err = TIFFReadDirEntryErrCount; - else - { - err = TIFFReadDirEntryDoubleArray(tif, dp, &data); - if (err == TIFFReadDirEntryErrOk) - { - int m; - m = TIFFSetField(tif, dp->tdir_tag, - (uint16_t)(dp->tdir_count), data); - if (data != 0) - _TIFFfreeExt(tif, data); - if (!m) - return (0); - } - } - } - break; - case TIFF_SETGET_C16_IFD8: - { - uint64_t *data; - assert(fip->field_readcount == TIFF_VARIABLE); - assert(fip->field_passcount == 1); - if (dp->tdir_count > 0xFFFF) - err = TIFFReadDirEntryErrCount; - else - { - err = TIFFReadDirEntryIfd8Array(tif, dp, &data); - if (err == TIFFReadDirEntryErrOk) - { - int m; - m = TIFFSetField(tif, dp->tdir_tag, - (uint16_t)(dp->tdir_count), data); - if (data != 0) - _TIFFfreeExt(tif, data); - if (!m) - return (0); - } - } - } - break; - case TIFF_SETGET_C32_ASCII: - { - uint8_t *data; - assert(fip->field_readcount == TIFF_VARIABLE2); - assert(fip->field_passcount == 1); - err = TIFFReadDirEntryByteArray(tif, dp, &data); - if (err == TIFFReadDirEntryErrOk) - { - int m; - if (data != 0 && dp->tdir_count > 0 && - data[dp->tdir_count - 1] != '\0') - { - TIFFWarningExtR(tif, module, - "ASCII value for tag \"%s\" does not end " - "in null byte. Forcing it to be null", - fip->field_name); - data[dp->tdir_count - 1] = '\0'; - } - m = TIFFSetField(tif, dp->tdir_tag, (uint32_t)(dp->tdir_count), - data); - if (data != 0) - _TIFFfreeExt(tif, data); - if (!m) - return (0); - } - } - break; - case TIFF_SETGET_C32_UINT8: - { - uint8_t *data; - uint32_t count = 0; - assert(fip->field_readcount == TIFF_VARIABLE2); - assert(fip->field_passcount == 1); - if (fip->field_tag == TIFFTAG_RICHTIFFIPTC && - dp->tdir_type == TIFF_LONG) - { - /* Adobe's software (wrongly) writes RichTIFFIPTC tag with - * data type LONG instead of UNDEFINED. Work around this - * frequently found issue */ - void *origdata; - err = TIFFReadDirEntryArray(tif, dp, &count, 4, &origdata); - if ((err != TIFFReadDirEntryErrOk) || (origdata == 0)) - { - data = NULL; - } - else - { - if (tif->tif_flags & TIFF_SWAB) - TIFFSwabArrayOfLong((uint32_t *)origdata, count); - data = (uint8_t *)origdata; - count = (uint32_t)(count * 4); - } - } - else - { - err = TIFFReadDirEntryByteArray(tif, dp, &data); - count = (uint32_t)(dp->tdir_count); - } - if (err == TIFFReadDirEntryErrOk) - { - int m; - m = TIFFSetField(tif, dp->tdir_tag, count, data); - if (data != 0) - _TIFFfreeExt(tif, data); - if (!m) - return (0); - } - } - break; - case TIFF_SETGET_C32_SINT8: - { - int8_t *data = NULL; - assert(fip->field_readcount == TIFF_VARIABLE2); - assert(fip->field_passcount == 1); - err = TIFFReadDirEntrySbyteArray(tif, dp, &data); - if (err == TIFFReadDirEntryErrOk) - { - int m; - m = TIFFSetField(tif, dp->tdir_tag, (uint32_t)(dp->tdir_count), - data); - if (data != 0) - _TIFFfreeExt(tif, data); - if (!m) - return (0); - } - } - break; - case TIFF_SETGET_C32_UINT16: - { - uint16_t *data; - assert(fip->field_readcount == TIFF_VARIABLE2); - assert(fip->field_passcount == 1); - err = TIFFReadDirEntryShortArray(tif, dp, &data); - if (err == TIFFReadDirEntryErrOk) - { - int m; - m = TIFFSetField(tif, dp->tdir_tag, (uint32_t)(dp->tdir_count), - data); - if (data != 0) - _TIFFfreeExt(tif, data); - if (!m) - return (0); - } - } - break; - case TIFF_SETGET_C32_SINT16: - { - int16_t *data = NULL; - assert(fip->field_readcount == TIFF_VARIABLE2); - assert(fip->field_passcount == 1); - err = TIFFReadDirEntrySshortArray(tif, dp, &data); - if (err == TIFFReadDirEntryErrOk) - { - int m; - m = TIFFSetField(tif, dp->tdir_tag, (uint32_t)(dp->tdir_count), - data); - if (data != 0) - _TIFFfreeExt(tif, data); - if (!m) - return (0); - } - } - break; - case TIFF_SETGET_C32_UINT32: - { - uint32_t *data; - assert(fip->field_readcount == TIFF_VARIABLE2); - assert(fip->field_passcount == 1); - err = TIFFReadDirEntryLongArray(tif, dp, &data); - if (err == TIFFReadDirEntryErrOk) - { - int m; - m = TIFFSetField(tif, dp->tdir_tag, (uint32_t)(dp->tdir_count), - data); - if (data != 0) - _TIFFfreeExt(tif, data); - if (!m) - return (0); - } - } - break; - case TIFF_SETGET_C32_SINT32: - { - int32_t *data = NULL; - assert(fip->field_readcount == TIFF_VARIABLE2); - assert(fip->field_passcount == 1); - err = TIFFReadDirEntrySlongArray(tif, dp, &data); - if (err == TIFFReadDirEntryErrOk) - { - int m; - m = TIFFSetField(tif, dp->tdir_tag, (uint32_t)(dp->tdir_count), - data); - if (data != 0) - _TIFFfreeExt(tif, data); - if (!m) - return (0); - } - } - break; - case TIFF_SETGET_C32_UINT64: - { - uint64_t *data; - assert(fip->field_readcount == TIFF_VARIABLE2); - assert(fip->field_passcount == 1); - err = TIFFReadDirEntryLong8Array(tif, dp, &data); - if (err == TIFFReadDirEntryErrOk) - { - int m; - m = TIFFSetField(tif, dp->tdir_tag, (uint32_t)(dp->tdir_count), - data); - if (data != 0) - _TIFFfreeExt(tif, data); - if (!m) - return (0); - } - } - break; - case TIFF_SETGET_C32_SINT64: - { - int64_t *data = NULL; - assert(fip->field_readcount == TIFF_VARIABLE2); - assert(fip->field_passcount == 1); - err = TIFFReadDirEntrySlong8Array(tif, dp, &data); - if (err == TIFFReadDirEntryErrOk) - { - int m; - m = TIFFSetField(tif, dp->tdir_tag, (uint32_t)(dp->tdir_count), - data); - if (data != 0) - _TIFFfreeExt(tif, data); - if (!m) - return (0); - } - } - break; - case TIFF_SETGET_C32_FLOAT: - { - float *data; - assert(fip->field_readcount == TIFF_VARIABLE2); - assert(fip->field_passcount == 1); - err = TIFFReadDirEntryFloatArray(tif, dp, &data); - if (err == TIFFReadDirEntryErrOk) - { - int m; - m = TIFFSetField(tif, dp->tdir_tag, (uint32_t)(dp->tdir_count), - data); - if (data != 0) - _TIFFfreeExt(tif, data); - if (!m) - return (0); - } - } - break; - case TIFF_SETGET_C32_DOUBLE: - { - double *data; - assert(fip->field_readcount == TIFF_VARIABLE2); - assert(fip->field_passcount == 1); - err = TIFFReadDirEntryDoubleArray(tif, dp, &data); - if (err == TIFFReadDirEntryErrOk) - { - int m; - m = TIFFSetField(tif, dp->tdir_tag, (uint32_t)(dp->tdir_count), - data); - if (data != 0) - _TIFFfreeExt(tif, data); - if (!m) - return (0); - } - } - break; - case TIFF_SETGET_C32_IFD8: - { - uint64_t *data; - assert(fip->field_readcount == TIFF_VARIABLE2); - assert(fip->field_passcount == 1); - err = TIFFReadDirEntryIfd8Array(tif, dp, &data); - if (err == TIFFReadDirEntryErrOk) - { - int m; - m = TIFFSetField(tif, dp->tdir_tag, (uint32_t)(dp->tdir_count), - data); - if (data != 0) - _TIFFfreeExt(tif, data); - if (!m) - return (0); - } - } - break; - default: - assert(0); /* we should never get here */ - break; - } - if (err != TIFFReadDirEntryErrOk) - { - TIFFReadDirEntryOutputErr(tif, err, module, fip->field_name, recover); - return (0); - } - return (1); -} - -/* - * Fetch a set of offsets or lengths. - * While this routine says "strips", in fact it's also used for tiles. - */ -static int TIFFFetchStripThing(TIFF *tif, TIFFDirEntry *dir, uint32_t nstrips, - uint64_t **lpp) -{ - static const char module[] = "TIFFFetchStripThing"; - enum TIFFReadDirEntryErr err; - uint64_t *data; - err = TIFFReadDirEntryLong8ArrayWithLimit(tif, dir, &data, nstrips); - if (err != TIFFReadDirEntryErrOk) - { - const TIFFField *fip = TIFFFieldWithTag(tif, dir->tdir_tag); - TIFFReadDirEntryOutputErr(tif, err, module, - fip ? fip->field_name : "unknown tagname", 0); - return (0); - } - if (dir->tdir_count < (uint64_t)nstrips) - { - uint64_t *resizeddata; - const TIFFField *fip = TIFFFieldWithTag(tif, dir->tdir_tag); - const char *pszMax = getenv("LIBTIFF_STRILE_ARRAY_MAX_RESIZE_COUNT"); - uint32_t max_nstrips = 1000000; - if (pszMax) - max_nstrips = (uint32_t)atoi(pszMax); - TIFFReadDirEntryOutputErr(tif, TIFFReadDirEntryErrCount, module, - fip ? fip->field_name : "unknown tagname", - (nstrips <= max_nstrips)); - - if (nstrips > max_nstrips) - { - _TIFFfreeExt(tif, data); - return (0); - } - - resizeddata = (uint64_t *)_TIFFCheckMalloc( - tif, nstrips, sizeof(uint64_t), "for strip array"); - if (resizeddata == 0) - { - _TIFFfreeExt(tif, data); - return (0); - } - if (dir->tdir_count) - _TIFFmemcpy(resizeddata, data, - (uint32_t)dir->tdir_count * sizeof(uint64_t)); - _TIFFmemset(resizeddata + (uint32_t)dir->tdir_count, 0, - (nstrips - (uint32_t)dir->tdir_count) * sizeof(uint64_t)); - _TIFFfreeExt(tif, data); - data = resizeddata; - } - *lpp = data; - return (1); -} - -/* - * Fetch and set the SubjectDistance EXIF tag. - */ -static int TIFFFetchSubjectDistance(TIFF *tif, TIFFDirEntry *dir) -{ - static const char module[] = "TIFFFetchSubjectDistance"; - enum TIFFReadDirEntryErr err; - UInt64Aligned_t m; - m.l = 0; - assert(sizeof(double) == 8); - assert(sizeof(uint64_t) == 8); - assert(sizeof(uint32_t) == 4); - if (dir->tdir_count != 1) - err = TIFFReadDirEntryErrCount; - else if (dir->tdir_type != TIFF_RATIONAL) - err = TIFFReadDirEntryErrType; - else - { - if (!(tif->tif_flags & TIFF_BIGTIFF)) - { - uint32_t offset; - offset = *(uint32_t *)(&dir->tdir_offset); - if (tif->tif_flags & TIFF_SWAB) - TIFFSwabLong(&offset); - err = TIFFReadDirEntryData(tif, offset, 8, m.i); - } - else - { - m.l = dir->tdir_offset.toff_long8; - err = TIFFReadDirEntryErrOk; - } - } - if (err == TIFFReadDirEntryErrOk) - { - double n; - if (tif->tif_flags & TIFF_SWAB) - TIFFSwabArrayOfLong(m.i, 2); - if (m.i[0] == 0) - n = 0.0; - else if (m.i[0] == 0xFFFFFFFF || m.i[1] == 0) - /* - * XXX: Numerator 0xFFFFFFFF means that we have infinite - * distance. Indicate that with a negative floating point - * SubjectDistance value. - */ - n = -1.0; - else - n = (double)m.i[0] / (double)m.i[1]; - return (TIFFSetField(tif, dir->tdir_tag, n)); - } - else - { - TIFFReadDirEntryOutputErr(tif, err, module, "SubjectDistance", TRUE); - return (0); - } -} - -static void allocChoppedUpStripArrays(TIFF *tif, uint32_t nstrips, - uint64_t stripbytes, - uint32_t rowsperstrip) -{ - TIFFDirectory *td = &tif->tif_dir; - uint64_t bytecount; - uint64_t offset; - uint64_t last_offset; - uint64_t last_bytecount; - uint32_t i; - uint64_t *newcounts; - uint64_t *newoffsets; - - offset = TIFFGetStrileOffset(tif, 0); - last_offset = TIFFGetStrileOffset(tif, td->td_nstrips - 1); - last_bytecount = TIFFGetStrileByteCount(tif, td->td_nstrips - 1); - if (last_offset > UINT64_MAX - last_bytecount || - last_offset + last_bytecount < offset) - { - return; - } - bytecount = last_offset + last_bytecount - offset; - - newcounts = - (uint64_t *)_TIFFCheckMalloc(tif, nstrips, sizeof(uint64_t), - "for chopped \"StripByteCounts\" array"); - newoffsets = (uint64_t *)_TIFFCheckMalloc( - tif, nstrips, sizeof(uint64_t), "for chopped \"StripOffsets\" array"); - if (newcounts == NULL || newoffsets == NULL) - { - /* - * Unable to allocate new strip information, give up and use - * the original one strip information. - */ - if (newcounts != NULL) - _TIFFfreeExt(tif, newcounts); - if (newoffsets != NULL) - _TIFFfreeExt(tif, newoffsets); - return; - } - - /* - * Fill the strip information arrays with new bytecounts and offsets - * that reflect the broken-up format. - */ - for (i = 0; i < nstrips; i++) - { - if (stripbytes > bytecount) - stripbytes = bytecount; - newcounts[i] = stripbytes; - newoffsets[i] = stripbytes ? offset : 0; - offset += stripbytes; - bytecount -= stripbytes; - } - - /* - * Replace old single strip info with multi-strip info. - */ - td->td_stripsperimage = td->td_nstrips = nstrips; - TIFFSetField(tif, TIFFTAG_ROWSPERSTRIP, rowsperstrip); - - _TIFFfreeExt(tif, td->td_stripbytecount_p); - _TIFFfreeExt(tif, td->td_stripoffset_p); - td->td_stripbytecount_p = newcounts; - td->td_stripoffset_p = newoffsets; -#ifdef STRIPBYTECOUNTSORTED_UNUSED - td->td_stripbytecountsorted = 1; -#endif - tif->tif_flags |= TIFF_CHOPPEDUPARRAYS; -} - -/* - * Replace a single strip (tile) of uncompressed data by multiple strips - * (tiles), each approximately STRIP_SIZE_DEFAULT bytes. This is useful for - * dealing with large images or for dealing with machines with a limited - * amount memory. - */ -static void ChopUpSingleUncompressedStrip(TIFF *tif) -{ - register TIFFDirectory *td = &tif->tif_dir; - uint64_t bytecount; - uint64_t offset; - uint32_t rowblock; - uint64_t rowblockbytes; - uint64_t stripbytes; - uint32_t nstrips; - uint32_t rowsperstrip; - - bytecount = TIFFGetStrileByteCount(tif, 0); - /* On a newly created file, just re-opened to be filled, we */ - /* don't want strip chop to trigger as it is going to cause issues */ - /* later ( StripOffsets and StripByteCounts improperly filled) . */ - if (bytecount == 0 && tif->tif_mode != O_RDONLY) - return; - offset = TIFFGetStrileByteCount(tif, 0); - assert(td->td_planarconfig == PLANARCONFIG_CONTIG); - if ((td->td_photometric == PHOTOMETRIC_YCBCR) && (!isUpSampled(tif))) - rowblock = td->td_ycbcrsubsampling[1]; - else - rowblock = 1; - rowblockbytes = TIFFVTileSize64(tif, rowblock); - /* - * Make the rows hold at least one scanline, but fill specified amount - * of data if possible. - */ - if (rowblockbytes > STRIP_SIZE_DEFAULT) - { - stripbytes = rowblockbytes; - rowsperstrip = rowblock; - } - else if (rowblockbytes > 0) - { - uint32_t rowblocksperstrip; - rowblocksperstrip = (uint32_t)(STRIP_SIZE_DEFAULT / rowblockbytes); - rowsperstrip = rowblocksperstrip * rowblock; - stripbytes = rowblocksperstrip * rowblockbytes; - } - else - return; - - /* - * never increase the number of rows per strip - */ - if (rowsperstrip >= td->td_rowsperstrip) - return; - nstrips = TIFFhowmany_32(td->td_imagelength, rowsperstrip); - if (nstrips == 0) - return; - - /* If we are going to allocate a lot of memory, make sure that the */ - /* file is as big as needed */ - if (tif->tif_mode == O_RDONLY && nstrips > 1000000 && - (offset >= TIFFGetFileSize(tif) || - stripbytes > (TIFFGetFileSize(tif) - offset) / (nstrips - 1))) - { - return; - } - - allocChoppedUpStripArrays(tif, nstrips, stripbytes, rowsperstrip); -} - -/* - * Replace a file with contiguous strips > 2 GB of uncompressed data by - * multiple smaller strips. This is useful for - * dealing with large images or for dealing with machines with a limited - * amount memory. - */ -static void TryChopUpUncompressedBigTiff(TIFF *tif) -{ - TIFFDirectory *td = &tif->tif_dir; - uint32_t rowblock; - uint64_t rowblockbytes; - uint32_t i; - uint64_t stripsize; - uint32_t rowblocksperstrip; - uint32_t rowsperstrip; - uint64_t stripbytes; - uint32_t nstrips; - - stripsize = TIFFStripSize64(tif); - - assert(tif->tif_dir.td_planarconfig == PLANARCONFIG_CONTIG); - assert(tif->tif_dir.td_compression == COMPRESSION_NONE); - assert((tif->tif_flags & (TIFF_STRIPCHOP | TIFF_ISTILED)) == - TIFF_STRIPCHOP); - assert(stripsize > 0x7FFFFFFFUL); - - /* On a newly created file, just re-opened to be filled, we */ - /* don't want strip chop to trigger as it is going to cause issues */ - /* later ( StripOffsets and StripByteCounts improperly filled) . */ - if (TIFFGetStrileByteCount(tif, 0) == 0 && tif->tif_mode != O_RDONLY) - return; - - if ((td->td_photometric == PHOTOMETRIC_YCBCR) && (!isUpSampled(tif))) - rowblock = td->td_ycbcrsubsampling[1]; - else - rowblock = 1; - rowblockbytes = TIFFVStripSize64(tif, rowblock); - if (rowblockbytes == 0 || rowblockbytes > 0x7FFFFFFFUL) - { - /* In case of file with gigantic width */ - return; - } - - /* Check that the strips are contiguous and of the expected size */ - for (i = 0; i < td->td_nstrips; i++) - { - if (i == td->td_nstrips - 1) - { - if (TIFFGetStrileByteCount(tif, i) < - TIFFVStripSize64(tif, - td->td_imagelength - i * td->td_rowsperstrip)) - { - return; - } - } - else - { - if (TIFFGetStrileByteCount(tif, i) != stripsize) - { - return; - } - if (i > 0 && TIFFGetStrileOffset(tif, i) != - TIFFGetStrileOffset(tif, i - 1) + - TIFFGetStrileByteCount(tif, i - 1)) - { - return; - } - } - } - - /* Aim for 512 MB strips (that will still be manageable by 32 bit builds */ - rowblocksperstrip = (uint32_t)(512 * 1024 * 1024 / rowblockbytes); - if (rowblocksperstrip == 0) - rowblocksperstrip = 1; - rowsperstrip = rowblocksperstrip * rowblock; - stripbytes = rowblocksperstrip * rowblockbytes; - assert(stripbytes <= 0x7FFFFFFFUL); - - nstrips = TIFFhowmany_32(td->td_imagelength, rowsperstrip); - if (nstrips == 0) - return; - - /* If we are going to allocate a lot of memory, make sure that the */ - /* file is as big as needed */ - if (tif->tif_mode == O_RDONLY && nstrips > 1000000) - { - uint64_t last_offset = TIFFGetStrileOffset(tif, td->td_nstrips - 1); - uint64_t filesize = TIFFGetFileSize(tif); - uint64_t last_bytecount = - TIFFGetStrileByteCount(tif, td->td_nstrips - 1); - if (last_offset > filesize || last_bytecount > filesize - last_offset) - { - return; - } - } - - allocChoppedUpStripArrays(tif, nstrips, stripbytes, rowsperstrip); -} - -TIFF_NOSANITIZE_UNSIGNED_INT_OVERFLOW -static uint64_t _TIFFUnsanitizedAddUInt64AndInt(uint64_t a, int b) -{ - return a + b; -} - -/* Read the value of [Strip|Tile]Offset or [Strip|Tile]ByteCount around - * strip/tile of number strile. Also fetch the neighbouring values using a - * 4096 byte page size. - */ -static int _TIFFPartialReadStripArray(TIFF *tif, TIFFDirEntry *dirent, - int strile, uint64_t *panVals) -{ - static const char module[] = "_TIFFPartialReadStripArray"; -#define IO_CACHE_PAGE_SIZE 4096 - - size_t sizeofval; - const int bSwab = (tif->tif_flags & TIFF_SWAB) != 0; - int sizeofvalint; - uint64_t nBaseOffset; - uint64_t nOffset; - uint64_t nOffsetStartPage; - uint64_t nOffsetEndPage; - tmsize_t nToRead; - tmsize_t nRead; - uint64_t nLastStripOffset; - int iStartBefore; - int i; - const uint32_t arraySize = tif->tif_dir.td_stripoffsetbyteallocsize; - unsigned char buffer[2 * IO_CACHE_PAGE_SIZE]; - - assert(dirent->tdir_count > 4); - - if (dirent->tdir_type == TIFF_SHORT) - { - sizeofval = sizeof(uint16_t); - } - else if (dirent->tdir_type == TIFF_LONG) - { - sizeofval = sizeof(uint32_t); - } - else if (dirent->tdir_type == TIFF_LONG8) - { - sizeofval = sizeof(uint64_t); - } - else if (dirent->tdir_type == TIFF_SLONG8) - { - /* Non conformant but used by some images as in */ - /* https://github.com/OSGeo/gdal/issues/2165 */ - sizeofval = sizeof(int64_t); - } - else - { - TIFFErrorExtR(tif, module, - "Invalid type for [Strip|Tile][Offset/ByteCount] tag"); - panVals[strile] = 0; - return 0; - } - sizeofvalint = (int)(sizeofval); - - if (tif->tif_flags & TIFF_BIGTIFF) - { - uint64_t offset = dirent->tdir_offset.toff_long8; - if (bSwab) - TIFFSwabLong8(&offset); - nBaseOffset = offset; - } - else - { - uint32_t offset = dirent->tdir_offset.toff_long; - if (bSwab) - TIFFSwabLong(&offset); - nBaseOffset = offset; - } - /* To avoid later unsigned integer overflows */ - if (nBaseOffset > (uint64_t)INT64_MAX) - { - TIFFErrorExtR(tif, module, "Cannot read offset/size for strile %d", - strile); - panVals[strile] = 0; - return 0; - } - nOffset = nBaseOffset + sizeofval * strile; - nOffsetStartPage = (nOffset / IO_CACHE_PAGE_SIZE) * IO_CACHE_PAGE_SIZE; - nOffsetEndPage = nOffsetStartPage + IO_CACHE_PAGE_SIZE; - - if (nOffset + sizeofval > nOffsetEndPage) - nOffsetEndPage += IO_CACHE_PAGE_SIZE; -#undef IO_CACHE_PAGE_SIZE - - nLastStripOffset = nBaseOffset + arraySize * sizeofval; - if (nLastStripOffset < nOffsetEndPage) - nOffsetEndPage = nLastStripOffset; - if (nOffsetStartPage >= nOffsetEndPage) - { - TIFFErrorExtR(tif, module, "Cannot read offset/size for strile %d", - strile); - panVals[strile] = 0; - return 0; - } - if (!SeekOK(tif, nOffsetStartPage)) - { - panVals[strile] = 0; - return 0; - } - - nToRead = (tmsize_t)(nOffsetEndPage - nOffsetStartPage); - nRead = TIFFReadFile(tif, buffer, nToRead); - if (nRead < nToRead) - { - TIFFErrorExtR(tif, module, - "Cannot read offset/size for strile around ~%d", strile); - return 0; - } - iStartBefore = -(int)((nOffset - nOffsetStartPage) / sizeofval); - if (strile + iStartBefore < 0) - iStartBefore = -strile; - for (i = iStartBefore; - (uint32_t)(strile + i) < arraySize && - _TIFFUnsanitizedAddUInt64AndInt(nOffset, (i + 1) * sizeofvalint) <= - nOffsetEndPage; - ++i) - { - if (dirent->tdir_type == TIFF_SHORT) - { - uint16_t val; - memcpy(&val, - buffer + (nOffset - nOffsetStartPage) + i * sizeofvalint, - sizeof(val)); - if (bSwab) - TIFFSwabShort(&val); - panVals[strile + i] = val; - } - else if (dirent->tdir_type == TIFF_LONG) - { - uint32_t val; - memcpy(&val, - buffer + (nOffset - nOffsetStartPage) + i * sizeofvalint, - sizeof(val)); - if (bSwab) - TIFFSwabLong(&val); - panVals[strile + i] = val; - } - else if (dirent->tdir_type == TIFF_LONG8) - { - uint64_t val; - memcpy(&val, - buffer + (nOffset - nOffsetStartPage) + i * sizeofvalint, - sizeof(val)); - if (bSwab) - TIFFSwabLong8(&val); - panVals[strile + i] = val; - } - else /* if( dirent->tdir_type == TIFF_SLONG8 ) */ - { - /* Non conformant data type */ - int64_t val; - memcpy(&val, - buffer + (nOffset - nOffsetStartPage) + i * sizeofvalint, - sizeof(val)); - if (bSwab) - TIFFSwabLong8((uint64_t *)&val); - panVals[strile + i] = (uint64_t)val; - } - } - return 1; -} - -static int _TIFFFetchStrileValue(TIFF *tif, uint32_t strile, - TIFFDirEntry *dirent, uint64_t **parray) -{ - static const char module[] = "_TIFFFetchStrileValue"; - TIFFDirectory *td = &tif->tif_dir; - if (strile >= dirent->tdir_count) - { - return 0; - } - if (strile >= td->td_stripoffsetbyteallocsize) - { - uint32_t nStripArrayAllocBefore = td->td_stripoffsetbyteallocsize; - uint32_t nStripArrayAllocNew; - uint64_t nArraySize64; - size_t nArraySize; - uint64_t *offsetArray; - uint64_t *bytecountArray; - - if (strile > 1000000) - { - uint64_t filesize = TIFFGetFileSize(tif); - /* Avoid excessive memory allocation attempt */ - /* For such a big blockid we need at least a TIFF_LONG per strile */ - /* for the offset array. */ - if (strile > filesize / sizeof(uint32_t)) - { - TIFFErrorExtR(tif, module, "File too short"); - return 0; - } - } - - if (td->td_stripoffsetbyteallocsize == 0 && - td->td_nstrips < 1024 * 1024) - { - nStripArrayAllocNew = td->td_nstrips; - } - else - { -#define TIFF_MAX(a, b) (((a) > (b)) ? (a) : (b)) -#define TIFF_MIN(a, b) (((a) < (b)) ? (a) : (b)) - nStripArrayAllocNew = TIFF_MAX(strile + 1, 1024U * 512U); - if (nStripArrayAllocNew < 0xFFFFFFFFU / 2) - nStripArrayAllocNew *= 2; - nStripArrayAllocNew = TIFF_MIN(nStripArrayAllocNew, td->td_nstrips); - } - assert(strile < nStripArrayAllocNew); - nArraySize64 = (uint64_t)sizeof(uint64_t) * nStripArrayAllocNew; - nArraySize = (size_t)(nArraySize64); -#if SIZEOF_SIZE_T == 4 - if (nArraySize != nArraySize64) - { - TIFFErrorExtR(tif, module, - "Cannot allocate strip offset and bytecount arrays"); - return 0; - } -#endif - offsetArray = (uint64_t *)(_TIFFreallocExt(tif, td->td_stripoffset_p, - nArraySize)); - bytecountArray = (uint64_t *)(_TIFFreallocExt( - tif, td->td_stripbytecount_p, nArraySize)); - if (offsetArray) - td->td_stripoffset_p = offsetArray; - if (bytecountArray) - td->td_stripbytecount_p = bytecountArray; - if (offsetArray && bytecountArray) - { - td->td_stripoffsetbyteallocsize = nStripArrayAllocNew; - /* Initialize new entries to ~0 / -1 */ - /* coverity[overrun-buffer-arg] */ - memset(td->td_stripoffset_p + nStripArrayAllocBefore, 0xFF, - (td->td_stripoffsetbyteallocsize - nStripArrayAllocBefore) * - sizeof(uint64_t)); - /* coverity[overrun-buffer-arg] */ - memset(td->td_stripbytecount_p + nStripArrayAllocBefore, 0xFF, - (td->td_stripoffsetbyteallocsize - nStripArrayAllocBefore) * - sizeof(uint64_t)); - } - else - { - TIFFErrorExtR(tif, module, - "Cannot allocate strip offset and bytecount arrays"); - _TIFFfreeExt(tif, td->td_stripoffset_p); - td->td_stripoffset_p = NULL; - _TIFFfreeExt(tif, td->td_stripbytecount_p); - td->td_stripbytecount_p = NULL; - td->td_stripoffsetbyteallocsize = 0; - } - } - if (*parray == NULL || strile >= td->td_stripoffsetbyteallocsize) - return 0; - - if (~((*parray)[strile]) == 0) - { - if (!_TIFFPartialReadStripArray(tif, dirent, strile, *parray)) - { - (*parray)[strile] = 0; - return 0; - } - } - - return 1; -} - -static uint64_t _TIFFGetStrileOffsetOrByteCountValue(TIFF *tif, uint32_t strile, - TIFFDirEntry *dirent, - uint64_t **parray, - int *pbErr) -{ - TIFFDirectory *td = &tif->tif_dir; - if (pbErr) - *pbErr = 0; - if ((tif->tif_flags & TIFF_DEFERSTRILELOAD) && - !(tif->tif_flags & TIFF_CHOPPEDUPARRAYS)) - { - if (!(tif->tif_flags & TIFF_LAZYSTRILELOAD) || - /* If the values may fit in the toff_long/toff_long8 member */ - /* then use _TIFFFillStriles to simplify _TIFFFetchStrileValue */ - dirent->tdir_count <= 4) - { - if (!_TIFFFillStriles(tif)) - { - if (pbErr) - *pbErr = 1; - /* Do not return, as we want this function to always */ - /* return the same value if called several times with */ - /* the same arguments */ - } - } - else - { - if (!_TIFFFetchStrileValue(tif, strile, dirent, parray)) - { - if (pbErr) - *pbErr = 1; - return 0; - } - } - } - if (*parray == NULL || strile >= td->td_nstrips) - { - if (pbErr) - *pbErr = 1; - return 0; - } - return (*parray)[strile]; -} - -/* Return the value of the TileOffsets/StripOffsets array for the specified - * tile/strile */ -uint64_t TIFFGetStrileOffset(TIFF *tif, uint32_t strile) -{ - return TIFFGetStrileOffsetWithErr(tif, strile, NULL); -} - -/* Return the value of the TileOffsets/StripOffsets array for the specified - * tile/strile */ -uint64_t TIFFGetStrileOffsetWithErr(TIFF *tif, uint32_t strile, int *pbErr) -{ - TIFFDirectory *td = &tif->tif_dir; - return _TIFFGetStrileOffsetOrByteCountValue(tif, strile, - &(td->td_stripoffset_entry), - &(td->td_stripoffset_p), pbErr); -} - -/* Return the value of the TileByteCounts/StripByteCounts array for the - * specified tile/strile */ -uint64_t TIFFGetStrileByteCount(TIFF *tif, uint32_t strile) -{ - return TIFFGetStrileByteCountWithErr(tif, strile, NULL); -} - -/* Return the value of the TileByteCounts/StripByteCounts array for the - * specified tile/strile */ -uint64_t TIFFGetStrileByteCountWithErr(TIFF *tif, uint32_t strile, int *pbErr) -{ - TIFFDirectory *td = &tif->tif_dir; - return _TIFFGetStrileOffsetOrByteCountValue( - tif, strile, &(td->td_stripbytecount_entry), &(td->td_stripbytecount_p), - pbErr); -} - -int _TIFFFillStriles(TIFF *tif) { return _TIFFFillStrilesInternal(tif, 1); } - -static int _TIFFFillStrilesInternal(TIFF *tif, int loadStripByteCount) -{ - register TIFFDirectory *td = &tif->tif_dir; - int return_value = 1; - - /* Do not do anything if TIFF_DEFERSTRILELOAD is not set */ - if (!(tif->tif_flags & TIFF_DEFERSTRILELOAD) || - (tif->tif_flags & TIFF_CHOPPEDUPARRAYS) != 0) - return 1; - - if (tif->tif_flags & TIFF_LAZYSTRILELOAD) - { - /* In case of lazy loading, reload completely the arrays */ - _TIFFfreeExt(tif, td->td_stripoffset_p); - _TIFFfreeExt(tif, td->td_stripbytecount_p); - td->td_stripoffset_p = NULL; - td->td_stripbytecount_p = NULL; - td->td_stripoffsetbyteallocsize = 0; - tif->tif_flags &= ~TIFF_LAZYSTRILELOAD; - } - - /* If stripoffset array is already loaded, exit with success */ - if (td->td_stripoffset_p != NULL) - return 1; - - /* If tdir_count was canceled, then we already got there, but in error */ - if (td->td_stripoffset_entry.tdir_count == 0) - return 0; - - if (!TIFFFetchStripThing(tif, &(td->td_stripoffset_entry), td->td_nstrips, - &td->td_stripoffset_p)) - { - return_value = 0; - } - - if (loadStripByteCount && - !TIFFFetchStripThing(tif, &(td->td_stripbytecount_entry), - td->td_nstrips, &td->td_stripbytecount_p)) - { - return_value = 0; - } - - _TIFFmemset(&(td->td_stripoffset_entry), 0, sizeof(TIFFDirEntry)); - _TIFFmemset(&(td->td_stripbytecount_entry), 0, sizeof(TIFFDirEntry)); - -#ifdef STRIPBYTECOUNTSORTED_UNUSED - if (tif->tif_dir.td_nstrips > 1 && return_value == 1) - { - uint32_t strip; - - tif->tif_dir.td_stripbytecountsorted = 1; - for (strip = 1; strip < tif->tif_dir.td_nstrips; strip++) - { - if (tif->tif_dir.td_stripoffset_p[strip - 1] > - tif->tif_dir.td_stripoffset_p[strip]) - { - tif->tif_dir.td_stripbytecountsorted = 0; - break; - } - } - } -#endif - - return return_value; -} diff --git a/src/3rd/tiff/dirwrite.c b/src/3rd/tiff/dirwrite.c deleted file mode 100644 index d75d2229495..00000000000 --- a/src/3rd/tiff/dirwrite.c +++ /dev/null @@ -1,3622 +0,0 @@ -/* - * Copyright (c) 1988-1997 Sam Leffler - * Copyright (c) 1991-1997 Silicon Graphics, Inc. - * - * Permission to use, copy, modify, distribute, and sell this software and - * its documentation for any purpose is hereby granted without fee, provided - * that (i) the above copyright notices and this permission notice appear in - * all copies of the software and related documentation, and (ii) the names of - * Sam Leffler and Silicon Graphics may not be used in any advertising or - * publicity relating to the software without the specific, prior written - * permission of Sam Leffler and Silicon Graphics. - * - * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, - * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY - * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. - * - * IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR - * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, - * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, - * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF - * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE - * OF THIS SOFTWARE. - */ - -/* - * TIFF Library. - * - * Directory Write Support Routines. - */ -#include "tiffiop.h" -#include /*--: for Rational2Double */ -#include /*--: for Rational2Double */ - -#ifdef HAVE_IEEEFP -#define TIFFCvtNativeToIEEEFloat(tif, n, fp) -#define TIFFCvtNativeToIEEEDouble(tif, n, dp) -#else -extern void TIFFCvtNativeToIEEEFloat(TIFF *tif, uint32_t n, float *fp); -extern void TIFFCvtNativeToIEEEDouble(TIFF *tif, uint32_t n, double *dp); -#endif - -static int TIFFWriteDirectorySec(TIFF *tif, int isimage, int imagedone, - uint64_t *pdiroff); - -static int TIFFWriteDirectoryTagSampleformatArray(TIFF *tif, uint32_t *ndir, - TIFFDirEntry *dir, - uint16_t tag, uint32_t count, - double *value); - -static int TIFFWriteDirectoryTagAscii(TIFF *tif, uint32_t *ndir, - TIFFDirEntry *dir, uint16_t tag, - uint32_t count, char *value); -static int TIFFWriteDirectoryTagUndefinedArray(TIFF *tif, uint32_t *ndir, - TIFFDirEntry *dir, uint16_t tag, - uint32_t count, uint8_t *value); -static int TIFFWriteDirectoryTagByteArray(TIFF *tif, uint32_t *ndir, - TIFFDirEntry *dir, uint16_t tag, - uint32_t count, uint8_t *value); -static int TIFFWriteDirectoryTagSbyteArray(TIFF *tif, uint32_t *ndir, - TIFFDirEntry *dir, uint16_t tag, - uint32_t count, int8_t *value); -static int TIFFWriteDirectoryTagShort(TIFF *tif, uint32_t *ndir, - TIFFDirEntry *dir, uint16_t tag, - uint16_t value); -static int TIFFWriteDirectoryTagShortArray(TIFF *tif, uint32_t *ndir, - TIFFDirEntry *dir, uint16_t tag, - uint32_t count, uint16_t *value); -static int TIFFWriteDirectoryTagShortPerSample(TIFF *tif, uint32_t *ndir, - TIFFDirEntry *dir, uint16_t tag, - uint16_t value); -static int TIFFWriteDirectoryTagSshortArray(TIFF *tif, uint32_t *ndir, - TIFFDirEntry *dir, uint16_t tag, - uint32_t count, int16_t *value); -static int TIFFWriteDirectoryTagLong(TIFF *tif, uint32_t *ndir, - TIFFDirEntry *dir, uint16_t tag, - uint32_t value); -static int TIFFWriteDirectoryTagLongArray(TIFF *tif, uint32_t *ndir, - TIFFDirEntry *dir, uint16_t tag, - uint32_t count, uint32_t *value); -static int TIFFWriteDirectoryTagSlongArray(TIFF *tif, uint32_t *ndir, - TIFFDirEntry *dir, uint16_t tag, - uint32_t count, int32_t *value); -static int TIFFWriteDirectoryTagLong8Array(TIFF *tif, uint32_t *ndir, - TIFFDirEntry *dir, uint16_t tag, - uint32_t count, uint64_t *value); -static int TIFFWriteDirectoryTagSlong8Array(TIFF *tif, uint32_t *ndir, - TIFFDirEntry *dir, uint16_t tag, - uint32_t count, int64_t *value); -static int TIFFWriteDirectoryTagRational(TIFF *tif, uint32_t *ndir, - TIFFDirEntry *dir, uint16_t tag, - double value); -static int TIFFWriteDirectoryTagRationalArray(TIFF *tif, uint32_t *ndir, - TIFFDirEntry *dir, uint16_t tag, - uint32_t count, float *value); -static int TIFFWriteDirectoryTagSrationalArray(TIFF *tif, uint32_t *ndir, - TIFFDirEntry *dir, uint16_t tag, - uint32_t count, float *value); -static int TIFFWriteDirectoryTagFloatArray(TIFF *tif, uint32_t *ndir, - TIFFDirEntry *dir, uint16_t tag, - uint32_t count, float *value); -static int TIFFWriteDirectoryTagDoubleArray(TIFF *tif, uint32_t *ndir, - TIFFDirEntry *dir, uint16_t tag, - uint32_t count, double *value); -static int TIFFWriteDirectoryTagIfdArray(TIFF *tif, uint32_t *ndir, - TIFFDirEntry *dir, uint16_t tag, - uint32_t count, uint32_t *value); -static int TIFFWriteDirectoryTagShortLong(TIFF *tif, uint32_t *ndir, - TIFFDirEntry *dir, uint16_t tag, - uint32_t value); -static int TIFFWriteDirectoryTagLongLong8Array(TIFF *tif, uint32_t *ndir, - TIFFDirEntry *dir, uint16_t tag, - uint32_t count, uint64_t *value); -static int TIFFWriteDirectoryTagIfdIfd8Array(TIFF *tif, uint32_t *ndir, - TIFFDirEntry *dir, uint16_t tag, - uint32_t count, uint64_t *value); -static int TIFFWriteDirectoryTagColormap(TIFF *tif, uint32_t *ndir, - TIFFDirEntry *dir); -static int TIFFWriteDirectoryTagTransferfunction(TIFF *tif, uint32_t *ndir, - TIFFDirEntry *dir); -static int TIFFWriteDirectoryTagSubifd(TIFF *tif, uint32_t *ndir, - TIFFDirEntry *dir); - -static int TIFFWriteDirectoryTagCheckedAscii(TIFF *tif, uint32_t *ndir, - TIFFDirEntry *dir, uint16_t tag, - uint32_t count, char *value); -static int TIFFWriteDirectoryTagCheckedUndefinedArray(TIFF *tif, uint32_t *ndir, - TIFFDirEntry *dir, - uint16_t tag, - uint32_t count, - uint8_t *value); -static int TIFFWriteDirectoryTagCheckedByteArray(TIFF *tif, uint32_t *ndir, - TIFFDirEntry *dir, - uint16_t tag, uint32_t count, - uint8_t *value); -static int TIFFWriteDirectoryTagCheckedSbyteArray(TIFF *tif, uint32_t *ndir, - TIFFDirEntry *dir, - uint16_t tag, uint32_t count, - int8_t *value); -static int TIFFWriteDirectoryTagCheckedShort(TIFF *tif, uint32_t *ndir, - TIFFDirEntry *dir, uint16_t tag, - uint16_t value); -static int TIFFWriteDirectoryTagCheckedShortArray(TIFF *tif, uint32_t *ndir, - TIFFDirEntry *dir, - uint16_t tag, uint32_t count, - uint16_t *value); -static int TIFFWriteDirectoryTagCheckedSshortArray(TIFF *tif, uint32_t *ndir, - TIFFDirEntry *dir, - uint16_t tag, uint32_t count, - int16_t *value); -static int TIFFWriteDirectoryTagCheckedLong(TIFF *tif, uint32_t *ndir, - TIFFDirEntry *dir, uint16_t tag, - uint32_t value); -static int TIFFWriteDirectoryTagCheckedLongArray(TIFF *tif, uint32_t *ndir, - TIFFDirEntry *dir, - uint16_t tag, uint32_t count, - uint32_t *value); -static int TIFFWriteDirectoryTagCheckedSlongArray(TIFF *tif, uint32_t *ndir, - TIFFDirEntry *dir, - uint16_t tag, uint32_t count, - int32_t *value); -static int TIFFWriteDirectoryTagCheckedLong8Array(TIFF *tif, uint32_t *ndir, - TIFFDirEntry *dir, - uint16_t tag, uint32_t count, - uint64_t *value); -static int TIFFWriteDirectoryTagCheckedSlong8Array(TIFF *tif, uint32_t *ndir, - TIFFDirEntry *dir, - uint16_t tag, uint32_t count, - int64_t *value); -static int TIFFWriteDirectoryTagCheckedRational(TIFF *tif, uint32_t *ndir, - TIFFDirEntry *dir, uint16_t tag, - double value); -static int TIFFWriteDirectoryTagCheckedRationalArray(TIFF *tif, uint32_t *ndir, - TIFFDirEntry *dir, - uint16_t tag, - uint32_t count, - float *value); -static int TIFFWriteDirectoryTagCheckedSrationalArray(TIFF *tif, uint32_t *ndir, - TIFFDirEntry *dir, - uint16_t tag, - uint32_t count, - float *value); - -/*--: Rational2Double: New functions to support true double-precision for custom - * rational tag types. */ -static int TIFFWriteDirectoryTagRationalDoubleArray(TIFF *tif, uint32_t *ndir, - TIFFDirEntry *dir, - uint16_t tag, - uint32_t count, - double *value); -static int TIFFWriteDirectoryTagSrationalDoubleArray(TIFF *tif, uint32_t *ndir, - TIFFDirEntry *dir, - uint16_t tag, - uint32_t count, - double *value); -static int -TIFFWriteDirectoryTagCheckedRationalDoubleArray(TIFF *tif, uint32_t *ndir, - TIFFDirEntry *dir, uint16_t tag, - uint32_t count, double *value); -static int TIFFWriteDirectoryTagCheckedSrationalDoubleArray( - TIFF *tif, uint32_t *ndir, TIFFDirEntry *dir, uint16_t tag, uint32_t count, - double *value); -static void DoubleToRational(double value, uint32_t *num, uint32_t *denom); -static void DoubleToSrational(double value, int32_t *num, int32_t *denom); - -static int TIFFWriteDirectoryTagCheckedFloatArray(TIFF *tif, uint32_t *ndir, - TIFFDirEntry *dir, - uint16_t tag, uint32_t count, - float *value); -static int TIFFWriteDirectoryTagCheckedDoubleArray(TIFF *tif, uint32_t *ndir, - TIFFDirEntry *dir, - uint16_t tag, uint32_t count, - double *value); -static int TIFFWriteDirectoryTagCheckedIfdArray(TIFF *tif, uint32_t *ndir, - TIFFDirEntry *dir, uint16_t tag, - uint32_t count, - uint32_t *value); -static int TIFFWriteDirectoryTagCheckedIfd8Array(TIFF *tif, uint32_t *ndir, - TIFFDirEntry *dir, - uint16_t tag, uint32_t count, - uint64_t *value); - -static int TIFFWriteDirectoryTagData(TIFF *tif, uint32_t *ndir, - TIFFDirEntry *dir, uint16_t tag, - uint16_t datatype, uint32_t count, - uint32_t datalength, void *data); - -static int TIFFLinkDirectory(TIFF *); - -/* - * Write the contents of the current directory - * to the specified file. This routine doesn't - * handle overwriting a directory with auxiliary - * storage that's been changed. - */ -int TIFFWriteDirectory(TIFF *tif) -{ - return TIFFWriteDirectorySec(tif, TRUE, TRUE, NULL); -} - -/* - * This is an advanced writing function that must be used in a particular - * sequence, and generally together with TIFFForceStrileArrayWriting(), - * to make its intended effect. Its aim is to modify the location - * where the [Strip/Tile][Offsets/ByteCounts] arrays are located in the file. - * More precisely, when TIFFWriteCheck() will be called, the tag entries for - * those arrays will be written with type = count = offset = 0 as a temporary - * value. - * - * Its effect is only valid for the current directory, and before - * TIFFWriteDirectory() is first called, and will be reset when - * changing directory. - * - * The typical sequence of calls is: - * TIFFOpen() - * [ TIFFCreateDirectory(tif) ] - * Set fields with calls to TIFFSetField(tif, ...) - * TIFFDeferStrileArrayWriting(tif) - * TIFFWriteCheck(tif, ...) - * TIFFWriteDirectory(tif) - * ... potentially create other directories and come back to the above directory - * TIFFForceStrileArrayWriting(tif): emit the arrays at the end of file - * - * Returns 1 in case of success, 0 otherwise. - */ -int TIFFDeferStrileArrayWriting(TIFF *tif) -{ - static const char module[] = "TIFFDeferStrileArrayWriting"; - if (tif->tif_mode == O_RDONLY) - { - TIFFErrorExtR(tif, tif->tif_name, "File opened in read-only mode"); - return 0; - } - if (tif->tif_diroff != 0) - { - TIFFErrorExtR(tif, module, "Directory has already been written"); - return 0; - } - - tif->tif_dir.td_deferstrilearraywriting = TRUE; - return 1; -} - -/* - * Similar to TIFFWriteDirectory(), writes the directory out - * but leaves all data structures in memory so that it can be - * written again. This will make a partially written TIFF file - * readable before it is successfully completed/closed. - */ -int TIFFCheckpointDirectory(TIFF *tif) -{ - int rc; - /* Setup the strips arrays, if they haven't already been. */ - if (tif->tif_dir.td_stripoffset_p == NULL) - (void)TIFFSetupStrips(tif); - rc = TIFFWriteDirectorySec(tif, TRUE, FALSE, NULL); - (void)TIFFSetWriteOffset(tif, TIFFSeekFile(tif, 0, SEEK_END)); - return rc; -} - -int TIFFWriteCustomDirectory(TIFF *tif, uint64_t *pdiroff) -{ - return TIFFWriteDirectorySec(tif, FALSE, FALSE, pdiroff); -} - -/* - * Similar to TIFFWriteDirectory(), but if the directory has already - * been written once, it is relocated to the end of the file, in case it - * has changed in size. Note that this will result in the loss of the - * previously used directory space. - */ -int TIFFRewriteDirectory(TIFF *tif) -{ - static const char module[] = "TIFFRewriteDirectory"; - uint64_t torewritediroff; - - /* We don't need to do anything special if it hasn't been written. */ - if (tif->tif_diroff == 0) - return TIFFWriteDirectory(tif); - - /* - * Find and zero the pointer to this directory, so that TIFFLinkDirectory - * will cause it to be added after this directories current pre-link. - */ - torewritediroff = tif->tif_diroff; - - if (!(tif->tif_flags & TIFF_BIGTIFF)) - { - if (tif->tif_header.classic.tiff_diroff == tif->tif_diroff) - { - tif->tif_header.classic.tiff_diroff = 0; - tif->tif_diroff = 0; - - TIFFSeekFile(tif, 4, SEEK_SET); - if (!WriteOK(tif, &(tif->tif_header.classic.tiff_diroff), 4)) - { - TIFFErrorExtR(tif, tif->tif_name, "Error updating TIFF header"); - return (0); - } - } - else if (tif->tif_diroff > 0xFFFFFFFFU) - { - TIFFErrorExtR(tif, module, - "tif->tif_diroff exceeds 32 bit range allowed for " - "Classic TIFF"); - return (0); - } - else - { - uint32_t nextdir; - nextdir = tif->tif_header.classic.tiff_diroff; - while (1) - { - uint16_t dircount; - uint32_t nextnextdir; - - if (!SeekOK(tif, nextdir) || !ReadOK(tif, &dircount, 2)) - { - TIFFErrorExtR(tif, module, - "Error fetching directory count"); - return (0); - } - if (tif->tif_flags & TIFF_SWAB) - TIFFSwabShort(&dircount); - (void)TIFFSeekFile(tif, nextdir + 2 + dircount * 12, SEEK_SET); - if (!ReadOK(tif, &nextnextdir, 4)) - { - TIFFErrorExtR(tif, module, "Error fetching directory link"); - return (0); - } - if (tif->tif_flags & TIFF_SWAB) - TIFFSwabLong(&nextnextdir); - if (nextnextdir == tif->tif_diroff) - { - uint32_t m; - m = 0; - (void)TIFFSeekFile(tif, nextdir + 2 + dircount * 12, - SEEK_SET); - if (!WriteOK(tif, &m, 4)) - { - TIFFErrorExtR(tif, module, - "Error writing directory link"); - return (0); - } - tif->tif_diroff = 0; - /* Force a full-traversal to reach the zeroed pointer */ - tif->tif_lastdiroff = 0; - break; - } - nextdir = nextnextdir; - } - } - /* Remove skipped offset from IFD loop directory list. */ - _TIFFRemoveEntryFromDirectoryListByOffset(tif, torewritediroff); - } - else - { - if (tif->tif_header.big.tiff_diroff == tif->tif_diroff) - { - tif->tif_header.big.tiff_diroff = 0; - tif->tif_diroff = 0; - - TIFFSeekFile(tif, 8, SEEK_SET); - if (!WriteOK(tif, &(tif->tif_header.big.tiff_diroff), 8)) - { - TIFFErrorExtR(tif, tif->tif_name, "Error updating TIFF header"); - return (0); - } - } - else - { - uint64_t nextdir; - nextdir = tif->tif_header.big.tiff_diroff; - while (1) - { - uint64_t dircount64; - uint16_t dircount; - uint64_t nextnextdir; - - if (!SeekOK(tif, nextdir) || !ReadOK(tif, &dircount64, 8)) - { - TIFFErrorExtR(tif, module, - "Error fetching directory count"); - return (0); - } - if (tif->tif_flags & TIFF_SWAB) - TIFFSwabLong8(&dircount64); - if (dircount64 > 0xFFFF) - { - TIFFErrorExtR(tif, module, - "Sanity check on tag count failed, likely " - "corrupt TIFF"); - return (0); - } - dircount = (uint16_t)dircount64; - (void)TIFFSeekFile(tif, nextdir + 8 + dircount * 20, SEEK_SET); - if (!ReadOK(tif, &nextnextdir, 8)) - { - TIFFErrorExtR(tif, module, "Error fetching directory link"); - return (0); - } - if (tif->tif_flags & TIFF_SWAB) - TIFFSwabLong8(&nextnextdir); - if (nextnextdir == tif->tif_diroff) - { - uint64_t m; - m = 0; - (void)TIFFSeekFile(tif, nextdir + 8 + dircount * 20, - SEEK_SET); - if (!WriteOK(tif, &m, 8)) - { - TIFFErrorExtR(tif, module, - "Error writing directory link"); - return (0); - } - tif->tif_diroff = 0; - /* Force a full-traversal to reach the zeroed pointer */ - tif->tif_lastdiroff = 0; - break; - } - nextdir = nextnextdir; - } - } - /* Remove skipped offset from IFD loop directory list. */ - _TIFFRemoveEntryFromDirectoryListByOffset(tif, torewritediroff); - } - - /* - * Now use TIFFWriteDirectory() normally. - */ - - return TIFFWriteDirectory(tif); -} - -static int TIFFWriteDirectorySec(TIFF *tif, int isimage, int imagedone, - uint64_t *pdiroff) -{ - static const char module[] = "TIFFWriteDirectorySec"; - uint32_t ndir; - TIFFDirEntry *dir; - uint32_t dirsize; - void *dirmem; - uint32_t m; - if (tif->tif_mode == O_RDONLY) - return (1); - - _TIFFFillStriles(tif); - - /* - * Clear write state so that subsequent images with - * different characteristics get the right buffers - * setup for them. - */ - if (imagedone) - { - if (tif->tif_flags & TIFF_POSTENCODE) - { - tif->tif_flags &= ~TIFF_POSTENCODE; - if (!(*tif->tif_postencode)(tif)) - { - TIFFErrorExtR(tif, module, - "Error post-encoding before directory write"); - return (0); - } - } - (*tif->tif_close)(tif); /* shutdown encoder */ - /* - * Flush any data that might have been written - * by the compression close+cleanup routines. But - * be careful not to write stuff if we didn't add data - * in the previous steps as the "rawcc" data may well be - * a previously read tile/strip in mixed read/write mode. - */ - if (tif->tif_rawcc > 0 && (tif->tif_flags & TIFF_BEENWRITING) != 0) - { - if (!TIFFFlushData1(tif)) - { - TIFFErrorExtR(tif, module, - "Error flushing data before directory write"); - return (0); - } - } - if ((tif->tif_flags & TIFF_MYBUFFER) && tif->tif_rawdata) - { - _TIFFfreeExt(tif, tif->tif_rawdata); - tif->tif_rawdata = NULL; - tif->tif_rawcc = 0; - tif->tif_rawdatasize = 0; - tif->tif_rawdataoff = 0; - tif->tif_rawdataloaded = 0; - } - tif->tif_flags &= ~(TIFF_BEENWRITING | TIFF_BUFFERSETUP); - } - - if (TIFFFieldSet(tif, FIELD_COMPRESSION) && - (tif->tif_dir.td_compression == COMPRESSION_DEFLATE)) - { - TIFFWarningExtR(tif, module, - "Creating TIFF with legacy Deflate codec identifier, " - "COMPRESSION_ADOBE_DEFLATE is more widely supported"); - } - dir = NULL; - dirmem = NULL; - dirsize = 0; - while (1) - { - ndir = 0; - if (isimage) - { - if (TIFFFieldSet(tif, FIELD_IMAGEDIMENSIONS)) - { - if (!TIFFWriteDirectoryTagShortLong(tif, &ndir, dir, - TIFFTAG_IMAGEWIDTH, - tif->tif_dir.td_imagewidth)) - goto bad; - if (!TIFFWriteDirectoryTagShortLong( - tif, &ndir, dir, TIFFTAG_IMAGELENGTH, - tif->tif_dir.td_imagelength)) - goto bad; - } - if (TIFFFieldSet(tif, FIELD_TILEDIMENSIONS)) - { - if (!TIFFWriteDirectoryTagShortLong(tif, &ndir, dir, - TIFFTAG_TILEWIDTH, - tif->tif_dir.td_tilewidth)) - goto bad; - if (!TIFFWriteDirectoryTagShortLong(tif, &ndir, dir, - TIFFTAG_TILELENGTH, - tif->tif_dir.td_tilelength)) - goto bad; - } - if (TIFFFieldSet(tif, FIELD_RESOLUTION)) - { - if (!TIFFWriteDirectoryTagRational(tif, &ndir, dir, - TIFFTAG_XRESOLUTION, - tif->tif_dir.td_xresolution)) - goto bad; - if (!TIFFWriteDirectoryTagRational(tif, &ndir, dir, - TIFFTAG_YRESOLUTION, - tif->tif_dir.td_yresolution)) - goto bad; - } - if (TIFFFieldSet(tif, FIELD_POSITION)) - { - if (!TIFFWriteDirectoryTagRational(tif, &ndir, dir, - TIFFTAG_XPOSITION, - tif->tif_dir.td_xposition)) - goto bad; - if (!TIFFWriteDirectoryTagRational(tif, &ndir, dir, - TIFFTAG_YPOSITION, - tif->tif_dir.td_yposition)) - goto bad; - } - if (TIFFFieldSet(tif, FIELD_SUBFILETYPE)) - { - if (!TIFFWriteDirectoryTagLong(tif, &ndir, dir, - TIFFTAG_SUBFILETYPE, - tif->tif_dir.td_subfiletype)) - goto bad; - } - if (TIFFFieldSet(tif, FIELD_BITSPERSAMPLE)) - { - if (!TIFFWriteDirectoryTagShortPerSample( - tif, &ndir, dir, TIFFTAG_BITSPERSAMPLE, - tif->tif_dir.td_bitspersample)) - goto bad; - } - if (TIFFFieldSet(tif, FIELD_COMPRESSION)) - { - if (!TIFFWriteDirectoryTagShort(tif, &ndir, dir, - TIFFTAG_COMPRESSION, - tif->tif_dir.td_compression)) - goto bad; - } - if (TIFFFieldSet(tif, FIELD_PHOTOMETRIC)) - { - if (!TIFFWriteDirectoryTagShort(tif, &ndir, dir, - TIFFTAG_PHOTOMETRIC, - tif->tif_dir.td_photometric)) - goto bad; - } - if (TIFFFieldSet(tif, FIELD_THRESHHOLDING)) - { - if (!TIFFWriteDirectoryTagShort(tif, &ndir, dir, - TIFFTAG_THRESHHOLDING, - tif->tif_dir.td_threshholding)) - goto bad; - } - if (TIFFFieldSet(tif, FIELD_FILLORDER)) - { - if (!TIFFWriteDirectoryTagShort(tif, &ndir, dir, - TIFFTAG_FILLORDER, - tif->tif_dir.td_fillorder)) - goto bad; - } - if (TIFFFieldSet(tif, FIELD_ORIENTATION)) - { - if (!TIFFWriteDirectoryTagShort(tif, &ndir, dir, - TIFFTAG_ORIENTATION, - tif->tif_dir.td_orientation)) - goto bad; - } - if (TIFFFieldSet(tif, FIELD_SAMPLESPERPIXEL)) - { - if (!TIFFWriteDirectoryTagShort( - tif, &ndir, dir, TIFFTAG_SAMPLESPERPIXEL, - tif->tif_dir.td_samplesperpixel)) - goto bad; - } - if (TIFFFieldSet(tif, FIELD_ROWSPERSTRIP)) - { - if (!TIFFWriteDirectoryTagShortLong( - tif, &ndir, dir, TIFFTAG_ROWSPERSTRIP, - tif->tif_dir.td_rowsperstrip)) - goto bad; - } - if (TIFFFieldSet(tif, FIELD_MINSAMPLEVALUE)) - { - if (!TIFFWriteDirectoryTagShortPerSample( - tif, &ndir, dir, TIFFTAG_MINSAMPLEVALUE, - tif->tif_dir.td_minsamplevalue)) - goto bad; - } - if (TIFFFieldSet(tif, FIELD_MAXSAMPLEVALUE)) - { - if (!TIFFWriteDirectoryTagShortPerSample( - tif, &ndir, dir, TIFFTAG_MAXSAMPLEVALUE, - tif->tif_dir.td_maxsamplevalue)) - goto bad; - } - if (TIFFFieldSet(tif, FIELD_PLANARCONFIG)) - { - if (!TIFFWriteDirectoryTagShort(tif, &ndir, dir, - TIFFTAG_PLANARCONFIG, - tif->tif_dir.td_planarconfig)) - goto bad; - } - if (TIFFFieldSet(tif, FIELD_RESOLUTIONUNIT)) - { - if (!TIFFWriteDirectoryTagShort(tif, &ndir, dir, - TIFFTAG_RESOLUTIONUNIT, - tif->tif_dir.td_resolutionunit)) - goto bad; - } - if (TIFFFieldSet(tif, FIELD_PAGENUMBER)) - { - if (!TIFFWriteDirectoryTagShortArray( - tif, &ndir, dir, TIFFTAG_PAGENUMBER, 2, - &tif->tif_dir.td_pagenumber[0])) - goto bad; - } - if (TIFFFieldSet(tif, FIELD_STRIPBYTECOUNTS)) - { - if (!isTiled(tif)) - { - if (!TIFFWriteDirectoryTagLongLong8Array( - tif, &ndir, dir, TIFFTAG_STRIPBYTECOUNTS, - tif->tif_dir.td_nstrips, - tif->tif_dir.td_stripbytecount_p)) - goto bad; - } - else - { - if (!TIFFWriteDirectoryTagLongLong8Array( - tif, &ndir, dir, TIFFTAG_TILEBYTECOUNTS, - tif->tif_dir.td_nstrips, - tif->tif_dir.td_stripbytecount_p)) - goto bad; - } - } - if (TIFFFieldSet(tif, FIELD_STRIPOFFSETS)) - { - if (!isTiled(tif)) - { - /* td_stripoffset_p might be NULL in an odd OJPEG case. See - * tif_dirread.c around line 3634. - * XXX: OJPEG hack. - * If a) compression is OJPEG, b) it's not a tiled TIFF, - * and c) the number of strips is 1, - * then we tolerate the absence of stripoffsets tag, - * because, presumably, all required data is in the - * JpegInterchangeFormat stream. - * We can get here when using tiffset on such a file. - * See http://bugzilla.maptools.org/show_bug.cgi?id=2500 - */ - if (tif->tif_dir.td_stripoffset_p != NULL && - !TIFFWriteDirectoryTagLongLong8Array( - tif, &ndir, dir, TIFFTAG_STRIPOFFSETS, - tif->tif_dir.td_nstrips, - tif->tif_dir.td_stripoffset_p)) - goto bad; - } - else - { - if (!TIFFWriteDirectoryTagLongLong8Array( - tif, &ndir, dir, TIFFTAG_TILEOFFSETS, - tif->tif_dir.td_nstrips, - tif->tif_dir.td_stripoffset_p)) - goto bad; - } - } - if (TIFFFieldSet(tif, FIELD_COLORMAP)) - { - if (!TIFFWriteDirectoryTagColormap(tif, &ndir, dir)) - goto bad; - } - if (TIFFFieldSet(tif, FIELD_EXTRASAMPLES)) - { - if (tif->tif_dir.td_extrasamples) - { - uint16_t na; - uint16_t *nb; - TIFFGetFieldDefaulted(tif, TIFFTAG_EXTRASAMPLES, &na, &nb); - if (!TIFFWriteDirectoryTagShortArray( - tif, &ndir, dir, TIFFTAG_EXTRASAMPLES, na, nb)) - goto bad; - } - } - if (TIFFFieldSet(tif, FIELD_SAMPLEFORMAT)) - { - if (!TIFFWriteDirectoryTagShortPerSample( - tif, &ndir, dir, TIFFTAG_SAMPLEFORMAT, - tif->tif_dir.td_sampleformat)) - goto bad; - } - if (TIFFFieldSet(tif, FIELD_SMINSAMPLEVALUE)) - { - if (!TIFFWriteDirectoryTagSampleformatArray( - tif, &ndir, dir, TIFFTAG_SMINSAMPLEVALUE, - tif->tif_dir.td_samplesperpixel, - tif->tif_dir.td_sminsamplevalue)) - goto bad; - } - if (TIFFFieldSet(tif, FIELD_SMAXSAMPLEVALUE)) - { - if (!TIFFWriteDirectoryTagSampleformatArray( - tif, &ndir, dir, TIFFTAG_SMAXSAMPLEVALUE, - tif->tif_dir.td_samplesperpixel, - tif->tif_dir.td_smaxsamplevalue)) - goto bad; - } - if (TIFFFieldSet(tif, FIELD_IMAGEDEPTH)) - { - if (!TIFFWriteDirectoryTagLong(tif, &ndir, dir, - TIFFTAG_IMAGEDEPTH, - tif->tif_dir.td_imagedepth)) - goto bad; - } - if (TIFFFieldSet(tif, FIELD_TILEDEPTH)) - { - if (!TIFFWriteDirectoryTagLong(tif, &ndir, dir, - TIFFTAG_TILEDEPTH, - tif->tif_dir.td_tiledepth)) - goto bad; - } - if (TIFFFieldSet(tif, FIELD_HALFTONEHINTS)) - { - if (!TIFFWriteDirectoryTagShortArray( - tif, &ndir, dir, TIFFTAG_HALFTONEHINTS, 2, - &tif->tif_dir.td_halftonehints[0])) - goto bad; - } - if (TIFFFieldSet(tif, FIELD_YCBCRSUBSAMPLING)) - { - if (!TIFFWriteDirectoryTagShortArray( - tif, &ndir, dir, TIFFTAG_YCBCRSUBSAMPLING, 2, - &tif->tif_dir.td_ycbcrsubsampling[0])) - goto bad; - } - if (TIFFFieldSet(tif, FIELD_YCBCRPOSITIONING)) - { - if (!TIFFWriteDirectoryTagShort( - tif, &ndir, dir, TIFFTAG_YCBCRPOSITIONING, - tif->tif_dir.td_ycbcrpositioning)) - goto bad; - } - if (TIFFFieldSet(tif, FIELD_REFBLACKWHITE)) - { - if (!TIFFWriteDirectoryTagRationalArray( - tif, &ndir, dir, TIFFTAG_REFERENCEBLACKWHITE, 6, - tif->tif_dir.td_refblackwhite)) - goto bad; - } - if (TIFFFieldSet(tif, FIELD_TRANSFERFUNCTION)) - { - if (!TIFFWriteDirectoryTagTransferfunction(tif, &ndir, dir)) - goto bad; - } - if (TIFFFieldSet(tif, FIELD_INKNAMES)) - { - if (!TIFFWriteDirectoryTagAscii( - tif, &ndir, dir, TIFFTAG_INKNAMES, - tif->tif_dir.td_inknameslen, tif->tif_dir.td_inknames)) - goto bad; - } - if (TIFFFieldSet(tif, FIELD_NUMBEROFINKS)) - { - if (!TIFFWriteDirectoryTagShort(tif, &ndir, dir, - TIFFTAG_NUMBEROFINKS, - tif->tif_dir.td_numberofinks)) - goto bad; - } - if (TIFFFieldSet(tif, FIELD_SUBIFD)) - { - if (!TIFFWriteDirectoryTagSubifd(tif, &ndir, dir)) - goto bad; - } - { - uint32_t n; - for (n = 0; n < tif->tif_nfields; n++) - { - const TIFFField *o; - o = tif->tif_fields[n]; - if ((o->field_bit >= FIELD_CODEC) && - (TIFFFieldSet(tif, o->field_bit))) - { - switch (o->get_field_type) - { - case TIFF_SETGET_ASCII: - { - uint32_t pa; - char *pb; - assert(o->field_type == TIFF_ASCII); - assert(o->field_readcount == TIFF_VARIABLE); - assert(o->field_passcount == 0); - TIFFGetField(tif, o->field_tag, &pb); - pa = (uint32_t)(strlen(pb)); - if (!TIFFWriteDirectoryTagAscii( - tif, &ndir, dir, (uint16_t)o->field_tag, - pa, pb)) - goto bad; - } - break; - case TIFF_SETGET_UINT16: - { - uint16_t p; - assert(o->field_type == TIFF_SHORT); - assert(o->field_readcount == 1); - assert(o->field_passcount == 0); - TIFFGetField(tif, o->field_tag, &p); - if (!TIFFWriteDirectoryTagShort( - tif, &ndir, dir, (uint16_t)o->field_tag, - p)) - goto bad; - } - break; - case TIFF_SETGET_UINT32: - { - uint32_t p; - assert(o->field_type == TIFF_LONG); - assert(o->field_readcount == 1); - assert(o->field_passcount == 0); - TIFFGetField(tif, o->field_tag, &p); - if (!TIFFWriteDirectoryTagLong( - tif, &ndir, dir, (uint16_t)o->field_tag, - p)) - goto bad; - } - break; - case TIFF_SETGET_C32_UINT8: - { - uint32_t pa; - void *pb; - assert(o->field_type == TIFF_UNDEFINED); - assert(o->field_readcount == TIFF_VARIABLE2); - assert(o->field_passcount == 1); - TIFFGetField(tif, o->field_tag, &pa, &pb); - if (!TIFFWriteDirectoryTagUndefinedArray( - tif, &ndir, dir, (uint16_t)o->field_tag, - pa, pb)) - goto bad; - } - break; - default: - TIFFErrorExtR( - tif, module, - "Cannot write tag %" PRIu32 " (%s)", - TIFFFieldTag(o), - o->field_name ? o->field_name : "unknown"); - goto bad; - } - } - } - } - } - for (m = 0; m < (uint32_t)(tif->tif_dir.td_customValueCount); m++) - { - uint16_t tag = - (uint16_t)tif->tif_dir.td_customValues[m].info->field_tag; - uint32_t count = 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)) - goto bad; - break; - case TIFF_UNDEFINED: - if (!TIFFWriteDirectoryTagUndefinedArray( - tif, &ndir, dir, tag, count, - 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)) - goto bad; - break; - case TIFF_SBYTE: - if (!TIFFWriteDirectoryTagSbyteArray( - tif, &ndir, dir, tag, count, - 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)) - goto bad; - break; - case TIFF_SSHORT: - if (!TIFFWriteDirectoryTagSshortArray( - tif, &ndir, dir, tag, count, - 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)) - goto bad; - break; - case TIFF_SLONG: - if (!TIFFWriteDirectoryTagSlongArray( - tif, &ndir, dir, tag, count, - 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)) - goto bad; - break; - case TIFF_SLONG8: - if (!TIFFWriteDirectoryTagSlong8Array( - tif, &ndir, dir, tag, count, - tif->tif_dir.td_customValues[m].value)) - goto bad; - break; - case TIFF_RATIONAL: - { - /*-- Rational2Double: For Rationals evaluate - * "set_field_type" to determine internal storage size. */ - int tv_size; - tv_size = TIFFFieldSetGetSize( - tif->tif_dir.td_customValues[m].info); - if (tv_size == 8) - { - if (!TIFFWriteDirectoryTagRationalDoubleArray( - tif, &ndir, dir, tag, count, - tif->tif_dir.td_customValues[m].value)) - goto bad; - } - else - { - /*-- default should be tv_size == 4 */ - if (!TIFFWriteDirectoryTagRationalArray( - tif, &ndir, dir, tag, count, - 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. */ - if (tv_size != 4) - { - TIFFErrorExtR(tif, - "TIFFLib: _TIFFWriteDirectorySec()", - "Rational2Double: .set_field_type is " - "not 4 but %d", - tv_size); - } - } - } - break; - case TIFF_SRATIONAL: - { - /*-- Rational2Double: For Rationals evaluate - * "set_field_type" to determine internal storage size. */ - int tv_size; - tv_size = TIFFFieldSetGetSize( - tif->tif_dir.td_customValues[m].info); - if (tv_size == 8) - { - if (!TIFFWriteDirectoryTagSrationalDoubleArray( - tif, &ndir, dir, tag, count, - tif->tif_dir.td_customValues[m].value)) - goto bad; - } - else - { - /*-- default should be tv_size == 4 */ - if (!TIFFWriteDirectoryTagSrationalArray( - tif, &ndir, dir, tag, count, - 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. */ - if (tv_size != 4) - { - TIFFErrorExtR(tif, - "TIFFLib: _TIFFWriteDirectorySec()", - "Rational2Double: .set_field_type is " - "not 4 but %d", - tv_size); - } - } - } - break; - case TIFF_FLOAT: - if (!TIFFWriteDirectoryTagFloatArray( - tif, &ndir, dir, tag, count, - 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)) - goto bad; - break; - case TIFF_IFD: - if (!TIFFWriteDirectoryTagIfdArray( - tif, &ndir, dir, tag, count, - 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)) - goto bad; - break; - default: - assert(0); /* we should never get here */ - break; - } - } - if (dir != NULL) - break; - dir = _TIFFmallocExt(tif, ndir * sizeof(TIFFDirEntry)); - if (dir == NULL) - { - TIFFErrorExtR(tif, module, "Out of memory"); - goto bad; - } - if (isimage) - { - if ((tif->tif_diroff == 0) && (!TIFFLinkDirectory(tif))) - goto bad; - } - else - tif->tif_diroff = - (TIFFSeekFile(tif, 0, SEEK_END) + 1) & (~((toff_t)1)); - if (pdiroff != NULL) - *pdiroff = tif->tif_diroff; - if (!(tif->tif_flags & TIFF_BIGTIFF)) - dirsize = 2 + ndir * 12 + 4; - else - dirsize = 8 + ndir * 20 + 8; - tif->tif_dataoff = tif->tif_diroff + dirsize; - if (!(tif->tif_flags & TIFF_BIGTIFF)) - tif->tif_dataoff = (uint32_t)tif->tif_dataoff; - if ((tif->tif_dataoff < tif->tif_diroff) || - (tif->tif_dataoff < (uint64_t)dirsize)) - { - TIFFErrorExtR(tif, module, "Maximum TIFF file size exceeded"); - goto bad; - } - if (tif->tif_dataoff & 1) - tif->tif_dataoff++; - if (isimage) - { - if (tif->tif_curdir == TIFF_NON_EXISTENT_DIR_NUMBER) - tif->tif_curdir = 0; - else - tif->tif_curdir++; - } - } - if (isimage) - { - if (TIFFFieldSet(tif, FIELD_SUBIFD) && (tif->tif_subifdoff == 0)) - { - uint32_t na; - TIFFDirEntry *nb; - for (na = 0, nb = dir;; na++, nb++) - { - if (na == ndir) - { - TIFFErrorExtR(tif, module, "Cannot find SubIFD tag"); - goto bad; - } - if (nb->tdir_tag == TIFFTAG_SUBIFD) - break; - } - if (!(tif->tif_flags & TIFF_BIGTIFF)) - tif->tif_subifdoff = tif->tif_diroff + 2 + na * 12 + 8; - else - tif->tif_subifdoff = tif->tif_diroff + 8 + na * 20 + 12; - } - } - dirmem = _TIFFmallocExt(tif, dirsize); - if (dirmem == NULL) - { - TIFFErrorExtR(tif, module, "Out of memory"); - goto bad; - } - if (!(tif->tif_flags & TIFF_BIGTIFF)) - { - uint8_t *n; - uint32_t nTmp; - TIFFDirEntry *o; - n = dirmem; - *(uint16_t *)n = (uint16_t)ndir; - if (tif->tif_flags & TIFF_SWAB) - TIFFSwabShort((uint16_t *)n); - n += 2; - o = dir; - for (m = 0; m < ndir; m++) - { - *(uint16_t *)n = o->tdir_tag; - if (tif->tif_flags & TIFF_SWAB) - TIFFSwabShort((uint16_t *)n); - n += 2; - *(uint16_t *)n = o->tdir_type; - if (tif->tif_flags & TIFF_SWAB) - TIFFSwabShort((uint16_t *)n); - n += 2; - nTmp = (uint32_t)o->tdir_count; - _TIFFmemcpy(n, &nTmp, 4); - if (tif->tif_flags & TIFF_SWAB) - TIFFSwabLong((uint32_t *)n); - n += 4; - /* This is correct. The data has been */ - /* swabbed previously in TIFFWriteDirectoryTagData */ - _TIFFmemcpy(n, &o->tdir_offset, 4); - n += 4; - o++; - } - nTmp = (uint32_t)tif->tif_nextdiroff; - if (tif->tif_flags & TIFF_SWAB) - TIFFSwabLong(&nTmp); - _TIFFmemcpy(n, &nTmp, 4); - } - else - { - uint8_t *n; - TIFFDirEntry *o; - n = dirmem; - *(uint64_t *)n = ndir; - if (tif->tif_flags & TIFF_SWAB) - TIFFSwabLong8((uint64_t *)n); - n += 8; - o = dir; - for (m = 0; m < ndir; m++) - { - *(uint16_t *)n = o->tdir_tag; - if (tif->tif_flags & TIFF_SWAB) - TIFFSwabShort((uint16_t *)n); - n += 2; - *(uint16_t *)n = o->tdir_type; - if (tif->tif_flags & TIFF_SWAB) - TIFFSwabShort((uint16_t *)n); - n += 2; - _TIFFmemcpy(n, &o->tdir_count, 8); - if (tif->tif_flags & TIFF_SWAB) - TIFFSwabLong8((uint64_t *)n); - n += 8; - _TIFFmemcpy(n, &o->tdir_offset, 8); - n += 8; - o++; - } - _TIFFmemcpy(n, &tif->tif_nextdiroff, 8); - if (tif->tif_flags & TIFF_SWAB) - TIFFSwabLong8((uint64_t *)n); - } - _TIFFfreeExt(tif, dir); - dir = NULL; - if (!SeekOK(tif, tif->tif_diroff)) - { - TIFFErrorExtR(tif, module, "IO error writing directory"); - goto bad; - } - if (!WriteOK(tif, dirmem, (tmsize_t)dirsize)) - { - TIFFErrorExtR(tif, module, "IO error writing directory"); - goto bad; - } - _TIFFfreeExt(tif, dirmem); - if (imagedone) - { - TIFFFreeDirectory(tif); - tif->tif_flags &= ~TIFF_DIRTYDIRECT; - tif->tif_flags &= ~TIFF_DIRTYSTRIP; - (*tif->tif_cleanup)(tif); - /* - * Reset directory-related state for subsequent - * directories. - */ - TIFFCreateDirectory(tif); - } - return (1); -bad: - if (dir != NULL) - _TIFFfreeExt(tif, dir); - if (dirmem != NULL) - _TIFFfreeExt(tif, dirmem); - return (0); -} - -static int8_t TIFFClampDoubleToInt8(double val) -{ - if (val > 127) - return 127; - if (val < -128 || val != val) - return -128; - return (int8_t)val; -} - -static int16_t TIFFClampDoubleToInt16(double val) -{ - if (val > 32767) - return 32767; - if (val < -32768 || val != val) - return -32768; - return (int16_t)val; -} - -static int32_t TIFFClampDoubleToInt32(double val) -{ - if (val > 0x7FFFFFFF) - return 0x7FFFFFFF; - if (val < -0x7FFFFFFF - 1 || val != val) - return -0x7FFFFFFF - 1; - return (int32_t)val; -} - -static uint8_t TIFFClampDoubleToUInt8(double val) -{ - if (val < 0) - return 0; - if (val > 255 || val != val) - return 255; - return (uint8_t)val; -} - -static uint16_t TIFFClampDoubleToUInt16(double val) -{ - if (val < 0) - return 0; - if (val > 65535 || val != val) - return 65535; - return (uint16_t)val; -} - -static uint32_t TIFFClampDoubleToUInt32(double val) -{ - if (val < 0) - return 0; - if (val > 0xFFFFFFFFU || val != val) - return 0xFFFFFFFFU; - return (uint32_t)val; -} - -static int TIFFWriteDirectoryTagSampleformatArray(TIFF *tif, uint32_t *ndir, - TIFFDirEntry *dir, - uint16_t tag, uint32_t count, - double *value) -{ - static const char module[] = "TIFFWriteDirectoryTagSampleformatArray"; - void *conv; - uint32_t i; - int ok; - conv = _TIFFmallocExt(tif, count * sizeof(double)); - if (conv == NULL) - { - TIFFErrorExtR(tif, module, "Out of memory"); - return (0); - } - - switch (tif->tif_dir.td_sampleformat) - { - case SAMPLEFORMAT_IEEEFP: - if (tif->tif_dir.td_bitspersample <= 32) - { - for (i = 0; i < count; ++i) - ((float *)conv)[i] = _TIFFClampDoubleToFloat(value[i]); - ok = TIFFWriteDirectoryTagFloatArray(tif, ndir, dir, tag, count, - (float *)conv); - } - else - { - ok = TIFFWriteDirectoryTagDoubleArray(tif, ndir, dir, tag, - count, value); - } - break; - case SAMPLEFORMAT_INT: - if (tif->tif_dir.td_bitspersample <= 8) - { - for (i = 0; i < count; ++i) - ((int8_t *)conv)[i] = TIFFClampDoubleToInt8(value[i]); - ok = TIFFWriteDirectoryTagSbyteArray(tif, ndir, dir, tag, count, - (int8_t *)conv); - } - else if (tif->tif_dir.td_bitspersample <= 16) - { - for (i = 0; i < count; ++i) - ((int16_t *)conv)[i] = TIFFClampDoubleToInt16(value[i]); - ok = TIFFWriteDirectoryTagSshortArray(tif, ndir, dir, tag, - count, (int16_t *)conv); - } - else - { - for (i = 0; i < count; ++i) - ((int32_t *)conv)[i] = TIFFClampDoubleToInt32(value[i]); - ok = TIFFWriteDirectoryTagSlongArray(tif, ndir, dir, tag, count, - (int32_t *)conv); - } - break; - case SAMPLEFORMAT_UINT: - if (tif->tif_dir.td_bitspersample <= 8) - { - for (i = 0; i < count; ++i) - ((uint8_t *)conv)[i] = TIFFClampDoubleToUInt8(value[i]); - ok = TIFFWriteDirectoryTagByteArray(tif, ndir, dir, tag, count, - (uint8_t *)conv); - } - else if (tif->tif_dir.td_bitspersample <= 16) - { - for (i = 0; i < count; ++i) - ((uint16_t *)conv)[i] = TIFFClampDoubleToUInt16(value[i]); - ok = TIFFWriteDirectoryTagShortArray(tif, ndir, dir, tag, count, - (uint16_t *)conv); - } - else - { - for (i = 0; i < count; ++i) - ((uint32_t *)conv)[i] = TIFFClampDoubleToUInt32(value[i]); - ok = TIFFWriteDirectoryTagLongArray(tif, ndir, dir, tag, count, - (uint32_t *)conv); - } - break; - default: - ok = 0; - } - - _TIFFfreeExt(tif, conv); - return (ok); -} - -static int TIFFWriteDirectoryTagAscii(TIFF *tif, uint32_t *ndir, - TIFFDirEntry *dir, uint16_t tag, - uint32_t count, char *value) -{ - if (dir == NULL) - { - (*ndir)++; - return (1); - } - return ( - TIFFWriteDirectoryTagCheckedAscii(tif, ndir, dir, tag, count, value)); -} - -static int TIFFWriteDirectoryTagUndefinedArray(TIFF *tif, uint32_t *ndir, - TIFFDirEntry *dir, uint16_t tag, - uint32_t count, uint8_t *value) -{ - if (dir == NULL) - { - (*ndir)++; - return (1); - } - return (TIFFWriteDirectoryTagCheckedUndefinedArray(tif, ndir, dir, tag, - count, value)); -} - -static int TIFFWriteDirectoryTagByteArray(TIFF *tif, uint32_t *ndir, - TIFFDirEntry *dir, uint16_t tag, - uint32_t count, uint8_t *value) -{ - if (dir == NULL) - { - (*ndir)++; - return (1); - } - return (TIFFWriteDirectoryTagCheckedByteArray(tif, ndir, dir, tag, count, - value)); -} - -static int TIFFWriteDirectoryTagSbyteArray(TIFF *tif, uint32_t *ndir, - TIFFDirEntry *dir, uint16_t tag, - uint32_t count, int8_t *value) -{ - if (dir == NULL) - { - (*ndir)++; - return (1); - } - return (TIFFWriteDirectoryTagCheckedSbyteArray(tif, ndir, dir, tag, count, - value)); -} - -static int TIFFWriteDirectoryTagShort(TIFF *tif, uint32_t *ndir, - TIFFDirEntry *dir, uint16_t tag, - uint16_t value) -{ - if (dir == NULL) - { - (*ndir)++; - return (1); - } - return (TIFFWriteDirectoryTagCheckedShort(tif, ndir, dir, tag, value)); -} - -static int TIFFWriteDirectoryTagShortArray(TIFF *tif, uint32_t *ndir, - TIFFDirEntry *dir, uint16_t tag, - uint32_t count, uint16_t *value) -{ - if (dir == NULL) - { - (*ndir)++; - return (1); - } - return (TIFFWriteDirectoryTagCheckedShortArray(tif, ndir, dir, tag, count, - value)); -} - -static int TIFFWriteDirectoryTagShortPerSample(TIFF *tif, uint32_t *ndir, - TIFFDirEntry *dir, uint16_t tag, - uint16_t value) -{ - static const char module[] = "TIFFWriteDirectoryTagShortPerSample"; - uint16_t *m; - uint16_t *na; - uint16_t nb; - int o; - if (dir == NULL) - { - (*ndir)++; - return (1); - } - m = _TIFFmallocExt(tif, tif->tif_dir.td_samplesperpixel * sizeof(uint16_t)); - if (m == NULL) - { - TIFFErrorExtR(tif, module, "Out of memory"); - return (0); - } - for (na = m, nb = 0; nb < tif->tif_dir.td_samplesperpixel; na++, nb++) - *na = value; - o = TIFFWriteDirectoryTagCheckedShortArray( - tif, ndir, dir, tag, tif->tif_dir.td_samplesperpixel, m); - _TIFFfreeExt(tif, m); - return (o); -} - -static int TIFFWriteDirectoryTagSshortArray(TIFF *tif, uint32_t *ndir, - TIFFDirEntry *dir, uint16_t tag, - uint32_t count, int16_t *value) -{ - if (dir == NULL) - { - (*ndir)++; - return (1); - } - return (TIFFWriteDirectoryTagCheckedSshortArray(tif, ndir, dir, tag, count, - value)); -} - -static int TIFFWriteDirectoryTagLong(TIFF *tif, uint32_t *ndir, - TIFFDirEntry *dir, uint16_t tag, - uint32_t value) -{ - if (dir == NULL) - { - (*ndir)++; - return (1); - } - return (TIFFWriteDirectoryTagCheckedLong(tif, ndir, dir, tag, value)); -} - -static int TIFFWriteDirectoryTagLongArray(TIFF *tif, uint32_t *ndir, - TIFFDirEntry *dir, uint16_t tag, - uint32_t count, uint32_t *value) -{ - if (dir == NULL) - { - (*ndir)++; - return (1); - } - return (TIFFWriteDirectoryTagCheckedLongArray(tif, ndir, dir, tag, count, - value)); -} - -static int TIFFWriteDirectoryTagSlongArray(TIFF *tif, uint32_t *ndir, - TIFFDirEntry *dir, uint16_t tag, - uint32_t count, int32_t *value) -{ - if (dir == NULL) - { - (*ndir)++; - return (1); - } - return (TIFFWriteDirectoryTagCheckedSlongArray(tif, ndir, dir, tag, count, - value)); -} - -/************************************************************************/ -/* TIFFWriteDirectoryTagLong8Array() */ -/* */ -/* Write either Long8 or Long array depending on file type. */ -/************************************************************************/ -static int TIFFWriteDirectoryTagLong8Array(TIFF *tif, uint32_t *ndir, - TIFFDirEntry *dir, uint16_t tag, - uint32_t count, uint64_t *value) -{ - static const char module[] = "TIFFWriteDirectoryTagLong8Array"; - uint64_t *ma; - uint32_t mb; - uint32_t *p; - uint32_t *q; - int o; - - /* is this just a counting pass? */ - if (dir == NULL) - { - (*ndir)++; - return (1); - } - - /* We always write Long8 for BigTIFF, no checking needed. */ - if (tif->tif_flags & TIFF_BIGTIFF) - return (TIFFWriteDirectoryTagCheckedLong8Array(tif, ndir, dir, tag, - count, value)); - - /* - ** 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)); - if (p == NULL) - { - TIFFErrorExtR(tif, module, "Out of memory"); - return (0); - } - - for (q = p, ma = value, mb = 0; mb < count; ma++, mb++, q++) - { - if (*ma > 0xFFFFFFFF) - { - TIFFErrorExtR(tif, module, - "Attempt to write unsigned long value %" PRIu64 - " larger than 0xFFFFFFFF for tag %d in Classic TIFF " - "file. TIFF file writing aborted", - *ma, tag); - _TIFFfreeExt(tif, p); - return (0); - } - *q = (uint32_t)(*ma); - } - - o = TIFFWriteDirectoryTagCheckedLongArray(tif, ndir, dir, tag, count, p); - _TIFFfreeExt(tif, p); - - return (o); -} - -/************************************************************************/ -/* TIFFWriteDirectoryTagSlong8Array() */ -/* */ -/* Write either SLong8 or SLong array depending on file type. */ -/************************************************************************/ -static int TIFFWriteDirectoryTagSlong8Array(TIFF *tif, uint32_t *ndir, - TIFFDirEntry *dir, uint16_t tag, - uint32_t count, int64_t *value) -{ - static const char module[] = "TIFFWriteDirectoryTagSlong8Array"; - int64_t *ma; - uint32_t mb; - int32_t *p; - int32_t *q; - int o; - - /* is this just a counting pass? */ - if (dir == NULL) - { - (*ndir)++; - return (1); - } - /* We always write SLong8 for BigTIFF, no checking needed. */ - if (tif->tif_flags & TIFF_BIGTIFF) - return (TIFFWriteDirectoryTagCheckedSlong8Array(tif, ndir, dir, tag, - count, value)); - - /* - ** 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)); - if (p == NULL) - { - TIFFErrorExtR(tif, module, "Out of memory"); - return (0); - } - - for (q = p, ma = value, mb = 0; mb < count; ma++, mb++, q++) - { - if (*ma > (2147483647)) - { - TIFFErrorExtR(tif, module, - "Attempt to write signed long value %" PRIi64 - " larger than 0x7FFFFFFF (2147483647) for tag %d in " - "Classic TIFF file. TIFF writing to file aborted", - *ma, tag); - _TIFFfreeExt(tif, p); - return (0); - } - else if (*ma < (-2147483647 - 1)) - { - TIFFErrorExtR(tif, module, - "Attempt to write signed long value %" PRIi64 - " smaller than 0x80000000 (-2147483648) for tag %d " - "in Classic TIFF file. TIFF writing to file aborted", - *ma, tag); - _TIFFfreeExt(tif, p); - return (0); - } - *q = (int32_t)(*ma); - } - - o = TIFFWriteDirectoryTagCheckedSlongArray(tif, ndir, dir, tag, count, p); - _TIFFfreeExt(tif, p); - - return (o); -} - -static int TIFFWriteDirectoryTagRational(TIFF *tif, uint32_t *ndir, - TIFFDirEntry *dir, uint16_t tag, - double value) -{ - if (dir == NULL) - { - (*ndir)++; - return (1); - } - return (TIFFWriteDirectoryTagCheckedRational(tif, ndir, dir, tag, value)); -} - -static int TIFFWriteDirectoryTagRationalArray(TIFF *tif, uint32_t *ndir, - TIFFDirEntry *dir, uint16_t tag, - uint32_t count, float *value) -{ - if (dir == NULL) - { - (*ndir)++; - return (1); - } - return (TIFFWriteDirectoryTagCheckedRationalArray(tif, ndir, dir, tag, - count, value)); -} - -static int TIFFWriteDirectoryTagSrationalArray(TIFF *tif, uint32_t *ndir, - TIFFDirEntry *dir, uint16_t tag, - uint32_t count, float *value) -{ - if (dir == NULL) - { - (*ndir)++; - return (1); - } - return (TIFFWriteDirectoryTagCheckedSrationalArray(tif, ndir, dir, tag, - count, value)); -} - -/*-- Rational2Double: additional write functions */ -static int TIFFWriteDirectoryTagRationalDoubleArray(TIFF *tif, uint32_t *ndir, - TIFFDirEntry *dir, - uint16_t tag, - uint32_t count, - double *value) -{ - if (dir == NULL) - { - (*ndir)++; - return (1); - } - return (TIFFWriteDirectoryTagCheckedRationalDoubleArray(tif, ndir, dir, tag, - count, value)); -} - -static int TIFFWriteDirectoryTagSrationalDoubleArray(TIFF *tif, uint32_t *ndir, - TIFFDirEntry *dir, - uint16_t tag, - uint32_t count, - double *value) -{ - if (dir == NULL) - { - (*ndir)++; - return (1); - } - return (TIFFWriteDirectoryTagCheckedSrationalDoubleArray( - tif, ndir, dir, tag, count, value)); -} - -static int TIFFWriteDirectoryTagFloatArray(TIFF *tif, uint32_t *ndir, - TIFFDirEntry *dir, uint16_t tag, - uint32_t count, float *value) -{ - if (dir == NULL) - { - (*ndir)++; - return (1); - } - return (TIFFWriteDirectoryTagCheckedFloatArray(tif, ndir, dir, tag, count, - value)); -} - -static int TIFFWriteDirectoryTagDoubleArray(TIFF *tif, uint32_t *ndir, - TIFFDirEntry *dir, uint16_t tag, - uint32_t count, double *value) -{ - if (dir == NULL) - { - (*ndir)++; - return (1); - } - return (TIFFWriteDirectoryTagCheckedDoubleArray(tif, ndir, dir, tag, count, - value)); -} - -static int TIFFWriteDirectoryTagIfdArray(TIFF *tif, uint32_t *ndir, - TIFFDirEntry *dir, uint16_t tag, - uint32_t count, uint32_t *value) -{ - if (dir == NULL) - { - (*ndir)++; - return (1); - } - return (TIFFWriteDirectoryTagCheckedIfdArray(tif, ndir, dir, tag, count, - value)); -} - -static int TIFFWriteDirectoryTagShortLong(TIFF *tif, uint32_t *ndir, - TIFFDirEntry *dir, uint16_t tag, - uint32_t value) -{ - if (dir == NULL) - { - (*ndir)++; - return (1); - } - if (value <= 0xFFFF) - return (TIFFWriteDirectoryTagCheckedShort(tif, ndir, dir, tag, - (uint16_t)value)); - else - return (TIFFWriteDirectoryTagCheckedLong(tif, ndir, dir, tag, value)); -} - -static int _WriteAsType(TIFF *tif, uint64_t strile_size, - uint64_t uncompressed_threshold) -{ - const uint16_t compression = tif->tif_dir.td_compression; - if (compression == COMPRESSION_NONE) - { - return strile_size > uncompressed_threshold; - } - else if (compression == COMPRESSION_JPEG || - compression == COMPRESSION_LZW || - compression == COMPRESSION_ADOBE_DEFLATE || - compression == COMPRESSION_DEFLATE || - compression == COMPRESSION_LZMA || - compression == COMPRESSION_LERC || - compression == COMPRESSION_ZSTD || - compression == COMPRESSION_WEBP || compression == COMPRESSION_JXL) - { - /* For a few select compression types, we assume that in the worst */ - /* case the compressed size will be 10 times the uncompressed size */ - /* This is overly pessismistic ! */ - return strile_size >= uncompressed_threshold / 10; - } - return 1; -} - -static int WriteAsLong8(TIFF *tif, uint64_t strile_size) -{ - return _WriteAsType(tif, strile_size, 0xFFFFFFFFU); -} - -static int WriteAsLong4(TIFF *tif, uint64_t strile_size) -{ - return _WriteAsType(tif, strile_size, 0xFFFFU); -} - -/************************************************************************/ -/* TIFFWriteDirectoryTagLongLong8Array() */ -/* */ -/* Write out LONG8 array and write a SHORT/LONG/LONG8 depending */ -/* on strile size and Classic/BigTIFF mode. */ -/************************************************************************/ - -static int TIFFWriteDirectoryTagLongLong8Array(TIFF *tif, uint32_t *ndir, - TIFFDirEntry *dir, uint16_t tag, - uint32_t count, uint64_t *value) -{ - static const char module[] = "TIFFWriteDirectoryTagLongLong8Array"; - int o; - int write_aslong4; - - /* is this just a counting pass? */ - if (dir == NULL) - { - (*ndir)++; - return (1); - } - - if (tif->tif_dir.td_deferstrilearraywriting) - { - return TIFFWriteDirectoryTagData(tif, ndir, dir, tag, TIFF_NOTYPE, 0, 0, - NULL); - } - - if (tif->tif_flags & TIFF_BIGTIFF) - { - int write_aslong8 = 1; - /* In the case of ByteCounts array, we may be able to write them on */ - /* LONG if the strip/tilesize is not too big. */ - /* Also do that for count > 1 in the case someone would want to create - */ - /* a single-strip file with a growing height, in which case using */ - /* LONG8 will be safer. */ - if (count > 1 && tag == TIFFTAG_STRIPBYTECOUNTS) - { - write_aslong8 = WriteAsLong8(tif, TIFFStripSize64(tif)); - } - else if (count > 1 && tag == TIFFTAG_TILEBYTECOUNTS) - { - write_aslong8 = WriteAsLong8(tif, TIFFTileSize64(tif)); - } - if (write_aslong8) - { - return TIFFWriteDirectoryTagCheckedLong8Array(tif, ndir, dir, tag, - count, value); - } - } - - write_aslong4 = 1; - if (count > 1 && tag == TIFFTAG_STRIPBYTECOUNTS) - { - write_aslong4 = WriteAsLong4(tif, TIFFStripSize64(tif)); - } - else if (count > 1 && tag == TIFFTAG_TILEBYTECOUNTS) - { - write_aslong4 = WriteAsLong4(tif, TIFFTileSize64(tif)); - } - if (write_aslong4) - { - /* - ** For classic tiff we want to verify everything is in range for LONG - ** and convert to long format. - */ - - uint32_t *p = _TIFFmallocExt(tif, count * sizeof(uint32_t)); - uint32_t *q; - uint64_t *ma; - uint32_t mb; - - if (p == NULL) - { - TIFFErrorExtR(tif, module, "Out of memory"); - return (0); - } - - for (q = p, ma = value, mb = 0; mb < count; ma++, mb++, q++) - { - if (*ma > 0xFFFFFFFF) - { - TIFFErrorExtR(tif, module, - "Attempt to write value larger than 0xFFFFFFFF " - "in LONG array."); - _TIFFfreeExt(tif, p); - return (0); - } - *q = (uint32_t)(*ma); - } - - o = TIFFWriteDirectoryTagCheckedLongArray(tif, ndir, dir, tag, count, - p); - _TIFFfreeExt(tif, p); - } - else - { - uint16_t *p = _TIFFmallocExt(tif, count * sizeof(uint16_t)); - uint16_t *q; - uint64_t *ma; - uint32_t mb; - - if (p == NULL) - { - TIFFErrorExtR(tif, module, "Out of memory"); - return (0); - } - - for (q = p, ma = value, mb = 0; mb < count; ma++, mb++, q++) - { - if (*ma > 0xFFFF) - { - /* Should not happen normally given the check we did before */ - TIFFErrorExtR(tif, module, - "Attempt to write value larger than 0xFFFF in " - "SHORT array."); - _TIFFfreeExt(tif, p); - return (0); - } - *q = (uint16_t)(*ma); - } - - o = TIFFWriteDirectoryTagCheckedShortArray(tif, ndir, dir, tag, count, - p); - _TIFFfreeExt(tif, p); - } - - return (o); -} - -/************************************************************************/ -/* TIFFWriteDirectoryTagIfdIfd8Array() */ -/* */ -/* Write either IFD8 or IFD array depending on file type. */ -/************************************************************************/ - -static int TIFFWriteDirectoryTagIfdIfd8Array(TIFF *tif, uint32_t *ndir, - TIFFDirEntry *dir, uint16_t tag, - uint32_t count, uint64_t *value) -{ - static const char module[] = "TIFFWriteDirectoryTagIfdIfd8Array"; - uint64_t *ma; - uint32_t mb; - uint32_t *p; - uint32_t *q; - int o; - - /* is this just a counting pass? */ - if (dir == NULL) - { - (*ndir)++; - return (1); - } - - /* We always write IFD8 for BigTIFF, no checking needed. */ - if (tif->tif_flags & TIFF_BIGTIFF) - return TIFFWriteDirectoryTagCheckedIfd8Array(tif, ndir, dir, tag, count, - value); - - /* - ** For classic tiff we want to verify everything is in range for IFD - ** and convert to long format. - */ - - p = _TIFFmallocExt(tif, count * sizeof(uint32_t)); - if (p == NULL) - { - TIFFErrorExtR(tif, module, "Out of memory"); - return (0); - } - - for (q = p, ma = value, mb = 0; mb < count; ma++, mb++, q++) - { - if (*ma > 0xFFFFFFFF) - { - TIFFErrorExtR(tif, module, - "Attempt to write value larger than 0xFFFFFFFF in " - "Classic TIFF file."); - _TIFFfreeExt(tif, p); - return (0); - } - *q = (uint32_t)(*ma); - } - - o = TIFFWriteDirectoryTagCheckedIfdArray(tif, ndir, dir, tag, count, p); - _TIFFfreeExt(tif, p); - - return (o); -} - -static int TIFFWriteDirectoryTagColormap(TIFF *tif, uint32_t *ndir, - TIFFDirEntry *dir) -{ - static const char module[] = "TIFFWriteDirectoryTagColormap"; - uint32_t m; - uint16_t *n; - int o; - if (dir == NULL) - { - (*ndir)++; - return (1); - } - m = (1 << tif->tif_dir.td_bitspersample); - n = _TIFFmallocExt(tif, 3 * m * sizeof(uint16_t)); - 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)); - o = TIFFWriteDirectoryTagCheckedShortArray(tif, ndir, dir, TIFFTAG_COLORMAP, - 3 * m, n); - _TIFFfreeExt(tif, n); - return (o); -} - -static int TIFFWriteDirectoryTagTransferfunction(TIFF *tif, uint32_t *ndir, - TIFFDirEntry *dir) -{ - static const char module[] = "TIFFWriteDirectoryTagTransferfunction"; - uint32_t m; - uint16_t n; - uint16_t *o; - int p; - int i; - if (dir == NULL) - { - (*ndir)++; - return (1); - } - /* TIFFTAG_TRANSFERFUNCTION expects (1 or 3) pointer to arrays with - * (1 << BitsPerSample) * uint16_t values. - */ - m = (1 << tif->tif_dir.td_bitspersample); - /* clang-format off */ - n = (tif->tif_dir.td_samplesperpixel - tif->tif_dir.td_extrasamples) > 1 ? 3 : 1; - /* clang-format on */ - - /* Check for proper number of transferfunctions */ - for (i = 0; i < n; i++) - { - if (tif->tif_dir.td_transferfunction[i] == NULL) - { - TIFFWarningExtR( - tif, module, - "Too few TransferFunctions provided. Tag not written to file"); - return (1); /* Not an error; only tag is not written. */ - } - } - /* - * Check if the table can be written as a single column, - * or if it must be written as 3 columns. Note that we - * write a 3-column tag if there are 2 samples/pixel and - * a single column of data won't suffice--hmm. - */ - if (n == 3) - { - if (!_TIFFmemcmp(tif->tif_dir.td_transferfunction[0], - tif->tif_dir.td_transferfunction[2], - m * sizeof(uint16_t)) && - !_TIFFmemcmp(tif->tif_dir.td_transferfunction[0], - tif->tif_dir.td_transferfunction[1], - m * sizeof(uint16_t))) - n = 1; - } - o = _TIFFmallocExt(tif, n * m * sizeof(uint16_t)); - if (o == NULL) - { - TIFFErrorExtR(tif, module, "Out of memory"); - return (0); - } - _TIFFmemcpy(&o[0], tif->tif_dir.td_transferfunction[0], - m * sizeof(uint16_t)); - if (n > 1) - _TIFFmemcpy(&o[m], tif->tif_dir.td_transferfunction[1], - m * sizeof(uint16_t)); - if (n > 2) - _TIFFmemcpy(&o[2 * m], tif->tif_dir.td_transferfunction[2], - m * sizeof(uint16_t)); - p = TIFFWriteDirectoryTagCheckedShortArray( - tif, ndir, dir, TIFFTAG_TRANSFERFUNCTION, n * m, o); - _TIFFfreeExt(tif, o); - return (p); -} - -static int TIFFWriteDirectoryTagSubifd(TIFF *tif, uint32_t *ndir, - TIFFDirEntry *dir) -{ - static const char module[] = "TIFFWriteDirectoryTagSubifd"; - uint64_t m; - int n; - if (tif->tif_dir.td_nsubifd == 0) - return (1); - if (dir == NULL) - { - (*ndir)++; - return (1); - } - m = tif->tif_dataoff; - if (!(tif->tif_flags & TIFF_BIGTIFF)) - { - uint32_t *o; - uint64_t *pa; - uint32_t *pb; - uint16_t p; - o = _TIFFmallocExt(tif, tif->tif_dir.td_nsubifd * sizeof(uint32_t)); - if (o == NULL) - { - TIFFErrorExtR(tif, module, "Out of memory"); - return (0); - } - pa = tif->tif_dir.td_subifd; - pb = o; - for (p = 0; p < tif->tif_dir.td_nsubifd; p++) - { - assert(pa != 0); - - /* Could happen if an classicTIFF has a SubIFD of type LONG8 (which - * is illegal) */ - if (*pa > 0xFFFFFFFFUL) - { - TIFFErrorExtR(tif, module, "Illegal value for SubIFD tag"); - _TIFFfreeExt(tif, o); - return (0); - } - *pb++ = (uint32_t)(*pa++); - } - n = TIFFWriteDirectoryTagCheckedIfdArray(tif, ndir, dir, TIFFTAG_SUBIFD, - tif->tif_dir.td_nsubifd, o); - _TIFFfreeExt(tif, o); - } - else - n = TIFFWriteDirectoryTagCheckedIfd8Array( - tif, ndir, dir, TIFFTAG_SUBIFD, tif->tif_dir.td_nsubifd, - tif->tif_dir.td_subifd); - if (!n) - return (0); - /* - * Total hack: if this directory includes a SubIFD - * tag then force the next directories to be - * written as ``sub directories'' of this one. This - * is used to write things like thumbnails and - * image masks that one wants to keep out of the - * normal directory linkage access mechanism. - */ - tif->tif_flags |= TIFF_INSUBIFD; - tif->tif_nsubifd = tif->tif_dir.td_nsubifd; - if (tif->tif_dir.td_nsubifd == 1) - tif->tif_subifdoff = 0; - else - tif->tif_subifdoff = m; - return (1); -} - -static int TIFFWriteDirectoryTagCheckedAscii(TIFF *tif, uint32_t *ndir, - TIFFDirEntry *dir, uint16_t tag, - uint32_t count, char *value) -{ - assert(sizeof(char) == 1); - return (TIFFWriteDirectoryTagData(tif, ndir, dir, tag, TIFF_ASCII, count, - count, value)); -} - -static int TIFFWriteDirectoryTagCheckedUndefinedArray(TIFF *tif, uint32_t *ndir, - TIFFDirEntry *dir, - uint16_t tag, - uint32_t count, - uint8_t *value) -{ - assert(sizeof(uint8_t) == 1); - return (TIFFWriteDirectoryTagData(tif, ndir, dir, tag, TIFF_UNDEFINED, - count, count, value)); -} - -static int TIFFWriteDirectoryTagCheckedByteArray(TIFF *tif, uint32_t *ndir, - TIFFDirEntry *dir, - uint16_t tag, uint32_t count, - uint8_t *value) -{ - assert(sizeof(uint8_t) == 1); - return (TIFFWriteDirectoryTagData(tif, ndir, dir, tag, TIFF_BYTE, count, - count, value)); -} - -static int TIFFWriteDirectoryTagCheckedSbyteArray(TIFF *tif, uint32_t *ndir, - TIFFDirEntry *dir, - uint16_t tag, uint32_t count, - int8_t *value) -{ - assert(sizeof(int8_t) == 1); - return (TIFFWriteDirectoryTagData(tif, ndir, dir, tag, TIFF_SBYTE, count, - count, value)); -} - -static int TIFFWriteDirectoryTagCheckedShort(TIFF *tif, uint32_t *ndir, - TIFFDirEntry *dir, uint16_t tag, - uint16_t value) -{ - uint16_t m; - assert(sizeof(uint16_t) == 2); - m = value; - if (tif->tif_flags & TIFF_SWAB) - TIFFSwabShort(&m); - return ( - TIFFWriteDirectoryTagData(tif, ndir, dir, tag, TIFF_SHORT, 1, 2, &m)); -} - -static int TIFFWriteDirectoryTagCheckedShortArray(TIFF *tif, uint32_t *ndir, - TIFFDirEntry *dir, - uint16_t tag, uint32_t count, - uint16_t *value) -{ - assert(count < 0x80000000); - assert(sizeof(uint16_t) == 2); - if (tif->tif_flags & TIFF_SWAB) - TIFFSwabArrayOfShort(value, count); - return (TIFFWriteDirectoryTagData(tif, ndir, dir, tag, TIFF_SHORT, count, - count * 2, value)); -} - -static int TIFFWriteDirectoryTagCheckedSshortArray(TIFF *tif, uint32_t *ndir, - TIFFDirEntry *dir, - uint16_t tag, uint32_t count, - int16_t *value) -{ - assert(count < 0x80000000); - assert(sizeof(int16_t) == 2); - if (tif->tif_flags & TIFF_SWAB) - TIFFSwabArrayOfShort((uint16_t *)value, count); - return (TIFFWriteDirectoryTagData(tif, ndir, dir, tag, TIFF_SSHORT, count, - count * 2, value)); -} - -static int TIFFWriteDirectoryTagCheckedLong(TIFF *tif, uint32_t *ndir, - TIFFDirEntry *dir, uint16_t tag, - uint32_t value) -{ - uint32_t m; - assert(sizeof(uint32_t) == 4); - m = value; - if (tif->tif_flags & TIFF_SWAB) - TIFFSwabLong(&m); - return ( - TIFFWriteDirectoryTagData(tif, ndir, dir, tag, TIFF_LONG, 1, 4, &m)); -} - -static int TIFFWriteDirectoryTagCheckedLongArray(TIFF *tif, uint32_t *ndir, - TIFFDirEntry *dir, - uint16_t tag, uint32_t count, - uint32_t *value) -{ - assert(count < 0x40000000); - assert(sizeof(uint32_t) == 4); - if (tif->tif_flags & TIFF_SWAB) - TIFFSwabArrayOfLong(value, count); - return (TIFFWriteDirectoryTagData(tif, ndir, dir, tag, TIFF_LONG, count, - count * 4, value)); -} - -static int TIFFWriteDirectoryTagCheckedSlongArray(TIFF *tif, uint32_t *ndir, - TIFFDirEntry *dir, - uint16_t tag, uint32_t count, - int32_t *value) -{ - assert(count < 0x40000000); - assert(sizeof(int32_t) == 4); - if (tif->tif_flags & TIFF_SWAB) - TIFFSwabArrayOfLong((uint32_t *)value, count); - return (TIFFWriteDirectoryTagData(tif, ndir, dir, tag, TIFF_SLONG, count, - count * 4, value)); -} - -static int TIFFWriteDirectoryTagCheckedLong8Array(TIFF *tif, uint32_t *ndir, - TIFFDirEntry *dir, - uint16_t tag, uint32_t count, - uint64_t *value) -{ - assert(count < 0x20000000); - assert(sizeof(uint64_t) == 8); - if (!(tif->tif_flags & TIFF_BIGTIFF)) - { - TIFFErrorExtR(tif, "TIFFWriteDirectoryTagCheckedLong8Array", - "LONG8 not allowed for ClassicTIFF"); - return (0); - } - if (tif->tif_flags & TIFF_SWAB) - TIFFSwabArrayOfLong8(value, count); - return (TIFFWriteDirectoryTagData(tif, ndir, dir, tag, TIFF_LONG8, count, - count * 8, value)); -} - -static int TIFFWriteDirectoryTagCheckedSlong8Array(TIFF *tif, uint32_t *ndir, - TIFFDirEntry *dir, - uint16_t tag, uint32_t count, - int64_t *value) -{ - assert(count < 0x20000000); - assert(sizeof(int64_t) == 8); - if (!(tif->tif_flags & TIFF_BIGTIFF)) - { - TIFFErrorExtR(tif, "TIFFWriteDirectoryTagCheckedSlong8Array", - "SLONG8 not allowed for ClassicTIFF"); - return (0); - } - if (tif->tif_flags & TIFF_SWAB) - TIFFSwabArrayOfLong8((uint64_t *)value, count); - return (TIFFWriteDirectoryTagData(tif, ndir, dir, tag, TIFF_SLONG8, count, - count * 8, value)); -} - -static int TIFFWriteDirectoryTagCheckedRational(TIFF *tif, uint32_t *ndir, - TIFFDirEntry *dir, uint16_t tag, - double value) -{ - static const char module[] = "TIFFWriteDirectoryTagCheckedRational"; - uint32_t m[2]; - assert(sizeof(uint32_t) == 4); - if (value < 0) - { - TIFFErrorExtR(tif, module, "Negative value is illegal"); - return 0; - } - else if (value != value) - { - TIFFErrorExtR(tif, module, "Not-a-number value is illegal"); - return 0; - } - /*--Rational2Double: New function also used for non-custom rational tags. - * However, could be omitted here, because - * TIFFWriteDirectoryTagCheckedRational() is not used by code for custom - * tags, only by code for named-tiff-tags like FIELD_RESOLUTION and - * FIELD_POSITION */ - else - { - DoubleToRational(value, &m[0], &m[1]); - } - - if (tif->tif_flags & TIFF_SWAB) - { - TIFFSwabLong(&m[0]); - TIFFSwabLong(&m[1]); - } - return (TIFFWriteDirectoryTagData(tif, ndir, dir, tag, TIFF_RATIONAL, 1, 8, - &m[0])); -} - -static int TIFFWriteDirectoryTagCheckedRationalArray(TIFF *tif, uint32_t *ndir, - TIFFDirEntry *dir, - uint16_t tag, - uint32_t count, - float *value) -{ - static const char module[] = "TIFFWriteDirectoryTagCheckedRationalArray"; - uint32_t *m; - float *na; - uint32_t *nb; - uint32_t nc; - int o; - assert(sizeof(uint32_t) == 4); - m = _TIFFmallocExt(tif, count * 2 * sizeof(uint32_t)); - if (m == NULL) - { - TIFFErrorExtR(tif, module, "Out of memory"); - return (0); - } - for (na = value, nb = m, nc = 0; nc < count; na++, nb += 2, nc++) - { - DoubleToRational(*na, &nb[0], &nb[1]); - } - if (tif->tif_flags & TIFF_SWAB) - TIFFSwabArrayOfLong(m, count * 2); - o = TIFFWriteDirectoryTagData(tif, ndir, dir, tag, TIFF_RATIONAL, count, - count * 8, &m[0]); - _TIFFfreeExt(tif, m); - return (o); -} - -static int TIFFWriteDirectoryTagCheckedSrationalArray(TIFF *tif, uint32_t *ndir, - TIFFDirEntry *dir, - uint16_t tag, - uint32_t count, - float *value) -{ - static const char module[] = "TIFFWriteDirectoryTagCheckedSrationalArray"; - int32_t *m; - float *na; - int32_t *nb; - uint32_t nc; - int o; - assert(sizeof(int32_t) == 4); - m = _TIFFmallocExt(tif, count * 2 * sizeof(int32_t)); - if (m == NULL) - { - TIFFErrorExtR(tif, module, "Out of memory"); - return (0); - } - for (na = value, nb = m, nc = 0; nc < count; na++, nb += 2, nc++) - { - DoubleToSrational(*na, &nb[0], &nb[1]); - } - if (tif->tif_flags & TIFF_SWAB) - TIFFSwabArrayOfLong((uint32_t *)m, count * 2); - o = TIFFWriteDirectoryTagData(tif, ndir, dir, tag, TIFF_SRATIONAL, count, - count * 8, &m[0]); - _TIFFfreeExt(tif, m); - return (o); -} - -/*-- Rational2Double: additional write functions for double arrays */ -static int -TIFFWriteDirectoryTagCheckedRationalDoubleArray(TIFF *tif, uint32_t *ndir, - TIFFDirEntry *dir, uint16_t tag, - uint32_t count, double *value) -{ - static const char module[] = - "TIFFWriteDirectoryTagCheckedRationalDoubleArray"; - uint32_t *m; - double *na; - uint32_t *nb; - uint32_t nc; - int o; - assert(sizeof(uint32_t) == 4); - m = _TIFFmallocExt(tif, count * 2 * sizeof(uint32_t)); - if (m == NULL) - { - TIFFErrorExtR(tif, module, "Out of memory"); - return (0); - } - for (na = value, nb = m, nc = 0; nc < count; na++, nb += 2, nc++) - { - DoubleToRational(*na, &nb[0], &nb[1]); - } - if (tif->tif_flags & TIFF_SWAB) - TIFFSwabArrayOfLong(m, count * 2); - o = TIFFWriteDirectoryTagData(tif, ndir, dir, tag, TIFF_RATIONAL, count, - count * 8, &m[0]); - _TIFFfreeExt(tif, m); - return (o); -} /*-- TIFFWriteDirectoryTagCheckedRationalDoubleArray() ------- */ - -static int TIFFWriteDirectoryTagCheckedSrationalDoubleArray( - TIFF *tif, uint32_t *ndir, TIFFDirEntry *dir, uint16_t tag, uint32_t count, - double *value) -{ - static const char module[] = - "TIFFWriteDirectoryTagCheckedSrationalDoubleArray"; - int32_t *m; - double *na; - int32_t *nb; - uint32_t nc; - int o; - assert(sizeof(int32_t) == 4); - m = _TIFFmallocExt(tif, count * 2 * sizeof(int32_t)); - if (m == NULL) - { - TIFFErrorExtR(tif, module, "Out of memory"); - return (0); - } - for (na = value, nb = m, nc = 0; nc < count; na++, nb += 2, nc++) - { - DoubleToSrational(*na, &nb[0], &nb[1]); - } - if (tif->tif_flags & TIFF_SWAB) - TIFFSwabArrayOfLong((uint32_t *)m, count * 2); - o = TIFFWriteDirectoryTagData(tif, ndir, dir, tag, TIFF_SRATIONAL, count, - count * 8, &m[0]); - _TIFFfreeExt(tif, m); - return (o); -} /*--- TIFFWriteDirectoryTagCheckedSrationalDoubleArray() -------- */ - -/** ----- Rational2Double: Double To Rational Conversion ----------------------------------------------------------- -* There is a mathematical theorem to convert real numbers into a rational -(integer fraction) number. -* This is called "continuous fraction" which uses the Euclidean algorithm to -find the greatest common divisor (GCD). -* (ref. e.g. https://de.wikipedia.org/wiki/Kettenbruch or -https://en.wikipedia.org/wiki/Continued_fraction -* https://en.wikipedia.org/wiki/Euclidean_algorithm) -* The following functions implement the -* - ToRationalEuclideanGCD() auxiliary function which mainly -implements euclidean GCD -* - DoubleToRational() conversion function for un-signed -rationals -* - DoubleToSrational() conversion function for signed rationals -------------------------------------------------------------------------------------------------------------------*/ - -/**---- ToRationalEuclideanGCD() ----------------------------------------- -* Calculates the rational fractional of a double input value -* using the Euclidean algorithm to find the greatest common divisor (GCD) -------------------------------------------------------------------------*/ -static void ToRationalEuclideanGCD(double value, int blnUseSignedRange, - int blnUseSmallRange, uint64_t *ullNum, - uint64_t *ullDenom) -{ - /* Internally, the integer variables can be bigger than the external ones, - * as long as the result will fit into the external variable size. - */ - uint64_t numSum[3] = {0, 1, 0}, denomSum[3] = {1, 0, 0}; - uint64_t aux, bigNum, bigDenom; - uint64_t returnLimit; - int i; - uint64_t nMax; - double fMax; - unsigned long maxDenom; - /*-- nMax and fMax defines the initial accuracy of the starting fractional, - * or better, the highest used integer numbers used within the starting - * fractional (bigNum/bigDenom). There are two approaches, which can - * accidentally lead to different accuracies just depending on the value. - * Therefore, blnUseSmallRange steers this behavior. - * For long long nMax = ((9223372036854775807-1)/2); for long nMax = - * ((2147483647-1)/2); - */ - if (blnUseSmallRange) - { - nMax = (uint64_t)((2147483647 - 1) / 2); /* for ULONG range */ - } - else - { - nMax = ((HB_ULL( 9223372036854775807 ) - 1) / 2); /* for ULLONG range */ - } - fMax = (double)nMax; - - /*-- For the Euclidean GCD define the denominator range, so that it stays - * within size of unsigned long variables. maxDenom should be LONG_MAX for - * negative values and ULONG_MAX for positive ones. Also the final returned - * value of ullNum and ullDenom is limited according to signed- or - * unsigned-range. - */ - if (blnUseSignedRange) - { - maxDenom = 2147483647UL; /*LONG_MAX = 0x7FFFFFFFUL*/ - returnLimit = maxDenom; - } - else - { - maxDenom = 0xFFFFFFFFUL; /*ULONG_MAX = 0xFFFFFFFFUL*/ - returnLimit = maxDenom; - } - - /*-- First generate a rational fraction (bigNum/bigDenom) which represents - *the value as a rational number with the highest accuracy. Therefore, - *uint64_t (uint64_t) is needed. This rational fraction is then reduced - *using the Euclidean algorithm to find the greatest common divisor (GCD). - * bigNum = big numinator of value without fraction (or cut residual - *fraction) bigDenom = big denominator of value - *-- Break-criteria so that uint64_t cast to "bigNum" introduces no error - *and bigDenom has no overflow, and stop with enlargement of fraction when - *the double-value of it reaches an integer number without fractional part. - */ - bigDenom = 1; - while ((value != floor(value)) && (value < fMax) && (bigDenom < nMax)) - { - bigDenom <<= 1; - value *= 2; - } - bigNum = (uint64_t)value; - - /*-- Start Euclidean algorithm to find the greatest common divisor (GCD) -- - */ -#define MAX_ITERATIONS 64 - for (i = 0; i < MAX_ITERATIONS; i++) - { - uint64_t val; - /* if bigDenom is not zero, calculate integer part of fraction. */ - if (bigDenom == 0) - { - break; - } - val = bigNum / bigDenom; - - /* Set bigDenom to reminder of bigNum/bigDenom and bigNum to previous - * denominator bigDenom. */ - aux = bigNum; - bigNum = bigDenom; - bigDenom = aux % bigDenom; - - /* calculate next denominator and check for its given maximum */ - aux = val; - if (denomSum[1] * val + denomSum[0] >= maxDenom) - { - aux = (maxDenom - denomSum[0]) / denomSum[1]; - if (aux * 2 >= val || denomSum[1] >= maxDenom) - i = (MAX_ITERATIONS + - 1); /* exit but execute rest of for-loop */ - else - break; - } - /* calculate next numerator to numSum2 and save previous one to numSum0; - * numSum1 just copy of numSum2. */ - numSum[2] = aux * numSum[1] + numSum[0]; - numSum[0] = numSum[1]; - numSum[1] = numSum[2]; - /* calculate next denominator to denomSum2 and save previous one to - * denomSum0; denomSum1 just copy of denomSum2. */ - denomSum[2] = aux * denomSum[1] + denomSum[0]; - denomSum[0] = denomSum[1]; - denomSum[1] = denomSum[2]; - } - - /*-- Check and adapt for final variable size and return values; reduces - * internal accuracy; denominator is kept in ULONG-range with maxDenom -- */ - while (numSum[1] > returnLimit || denomSum[1] > returnLimit) - { - numSum[1] = numSum[1] / 2; - denomSum[1] = denomSum[1] / 2; - } - - /* return values */ - *ullNum = numSum[1]; - *ullDenom = denomSum[1]; - -} /*-- ToRationalEuclideanGCD() -------------- */ - -/**---- DoubleToRational() ----------------------------------------------- -* Calculates the rational fractional of a double input value -* for UN-SIGNED rationals, -* using the Euclidean algorithm to find the greatest common divisor (GCD) -------------------------------------------------------------------------*/ -static void DoubleToRational(double value, uint32_t *num, uint32_t *denom) -{ - /*---- UN-SIGNED RATIONAL ---- */ - double dblDiff, dblDiff2; - uint64_t ullNum, ullDenom, ullNum2, ullDenom2; - - /*-- Check for negative values. If so it is an error. */ - /* Test written that way to catch NaN */ - if (!(value >= 0)) - { - *num = *denom = 0; - TIFFErrorExt(0, "TIFFLib: DoubleToRational()", - " Negative Value for Unsigned Rational given."); - return; - } - - /*-- Check for too big numbers (> ULONG_MAX) -- */ - if (value > 0xFFFFFFFFUL) - { - *num = 0xFFFFFFFFU; - *denom = 0; - return; - } - /*-- Check for easy integer numbers -- */ - if (value == (uint32_t)(value)) - { - *num = (uint32_t)value; - *denom = 1; - return; - } - /*-- Check for too small numbers for "unsigned long" type rationals -- */ - if (value < 1.0 / (double)0xFFFFFFFFUL) - { - *num = 0; - *denom = 0xFFFFFFFFU; - return; - } - - /*-- There are two approaches using the Euclidean algorithm, - * which can accidentally lead to different accuracies just depending on - * the value. Try both and define which one was better. - */ - ToRationalEuclideanGCD(value, FALSE, FALSE, &ullNum, &ullDenom); - ToRationalEuclideanGCD(value, FALSE, TRUE, &ullNum2, &ullDenom2); - /*-- Double-Check, that returned values fit into ULONG :*/ - if (ullNum > 0xFFFFFFFFUL || ullDenom > 0xFFFFFFFFUL || - ullNum2 > 0xFFFFFFFFUL || ullDenom2 > 0xFFFFFFFFUL) - { - TIFFErrorExt(0, "TIFFLib: DoubleToRational()", - " Num or Denom exceeds ULONG: val=%14.6f, num=%12" PRIu64 - ", denom=%12" PRIu64 " | num2=%12" PRIu64 - ", denom2=%12" PRIu64 "", - value, ullNum, ullDenom, ullNum2, ullDenom2); - assert(0); - } - - /* Check, which one has higher accuracy and take that. */ - dblDiff = fabs(value - ((double)ullNum / (double)ullDenom)); - dblDiff2 = fabs(value - ((double)ullNum2 / (double)ullDenom2)); - if (dblDiff < dblDiff2) - { - *num = (uint32_t)ullNum; - *denom = (uint32_t)ullDenom; - } - else - { - *num = (uint32_t)ullNum2; - *denom = (uint32_t)ullDenom2; - } -} /*-- DoubleToRational() -------------- */ - -/**---- DoubleToSrational() ----------------------------------------------- -* Calculates the rational fractional of a double input value -* for SIGNED rationals, -* using the Euclidean algorithm to find the greatest common divisor (GCD) -------------------------------------------------------------------------*/ -static void DoubleToSrational(double value, int32_t *num, int32_t *denom) -{ - /*---- SIGNED RATIONAL ----*/ - int neg = 1; - double dblDiff, dblDiff2; - uint64_t ullNum, ullDenom, ullNum2, ullDenom2; - - /*-- Check for negative values and use then the positive one for internal - * calculations, but take the sign into account before returning. */ - if (value < 0) - { - neg = -1; - value = -value; - } - - /*-- Check for too big numbers (> LONG_MAX) -- */ - if (value > 0x7FFFFFFFL) - { - *num = 0x7FFFFFFFL; - *denom = 0; - return; - } - /*-- Check for easy numbers -- */ - if (value == (int32_t)(value)) - { - *num = (int32_t)(neg * value); - *denom = 1; - return; - } - /*-- Check for too small numbers for "long" type rationals -- */ - if (value < 1.0 / (double)0x7FFFFFFFL) - { - *num = 0; - *denom = 0x7FFFFFFFL; - return; - } - - /*-- There are two approaches using the Euclidean algorithm, - * which can accidentally lead to different accuracies just depending on - * the value. Try both and define which one was better. Furthermore, set - * behavior of ToRationalEuclideanGCD() to the range of signed-long. - */ - ToRationalEuclideanGCD(value, TRUE, FALSE, &ullNum, &ullDenom); - ToRationalEuclideanGCD(value, TRUE, TRUE, &ullNum2, &ullDenom2); - /*-- Double-Check, that returned values fit into LONG :*/ - if (ullNum > 0x7FFFFFFFL || ullDenom > 0x7FFFFFFFL || - ullNum2 > 0x7FFFFFFFL || ullDenom2 > 0x7FFFFFFFL) - { - TIFFErrorExt(0, "TIFFLib: DoubleToSrational()", - " Num or Denom exceeds LONG: val=%14.6f, num=%12" PRIu64 - ", denom=%12" PRIu64 " | num2=%12" PRIu64 - ", denom2=%12" PRIu64 "", - neg * value, ullNum, ullDenom, ullNum2, ullDenom2); - assert(0); - } - - /* Check, which one has higher accuracy and take that. */ - dblDiff = fabs(value - ((double)ullNum / (double)ullDenom)); - dblDiff2 = fabs(value - ((double)ullNum2 / (double)ullDenom2)); - if (dblDiff < dblDiff2) - { - *num = (int32_t)(neg * (long)ullNum); - *denom = (int32_t)ullDenom; - } - else - { - *num = (int32_t)(neg * (long)ullNum2); - *denom = (int32_t)ullDenom2; - } -} /*-- DoubleToSrational() --------------*/ - -static int TIFFWriteDirectoryTagCheckedFloatArray(TIFF *tif, uint32_t *ndir, - TIFFDirEntry *dir, - uint16_t tag, uint32_t count, - float *value) -{ - assert(count < 0x40000000); - assert(sizeof(float) == 4); - TIFFCvtNativeToIEEEFloat(tif, count, value); - if (tif->tif_flags & TIFF_SWAB) - TIFFSwabArrayOfFloat(value, count); - return (TIFFWriteDirectoryTagData(tif, ndir, dir, tag, TIFF_FLOAT, count, - count * 4, value)); -} - -static int TIFFWriteDirectoryTagCheckedDoubleArray(TIFF *tif, uint32_t *ndir, - TIFFDirEntry *dir, - uint16_t tag, uint32_t count, - double *value) -{ - assert(count < 0x20000000); - assert(sizeof(double) == 8); - TIFFCvtNativeToIEEEDouble(tif, count, value); - if (tif->tif_flags & TIFF_SWAB) - TIFFSwabArrayOfDouble(value, count); - return (TIFFWriteDirectoryTagData(tif, ndir, dir, tag, TIFF_DOUBLE, count, - count * 8, value)); -} - -static int TIFFWriteDirectoryTagCheckedIfdArray(TIFF *tif, uint32_t *ndir, - TIFFDirEntry *dir, uint16_t tag, - uint32_t count, uint32_t *value) -{ - assert(count < 0x40000000); - assert(sizeof(uint32_t) == 4); - if (tif->tif_flags & TIFF_SWAB) - TIFFSwabArrayOfLong(value, count); - return (TIFFWriteDirectoryTagData(tif, ndir, dir, tag, TIFF_IFD, count, - count * 4, value)); -} - -static int TIFFWriteDirectoryTagCheckedIfd8Array(TIFF *tif, uint32_t *ndir, - TIFFDirEntry *dir, - uint16_t tag, uint32_t count, - uint64_t *value) -{ - assert(count < 0x20000000); - assert(sizeof(uint64_t) == 8); - assert(tif->tif_flags & TIFF_BIGTIFF); - if (tif->tif_flags & TIFF_SWAB) - TIFFSwabArrayOfLong8(value, count); - return (TIFFWriteDirectoryTagData(tif, ndir, dir, tag, TIFF_IFD8, count, - count * 8, value)); -} - -static int TIFFWriteDirectoryTagData(TIFF *tif, uint32_t *ndir, - TIFFDirEntry *dir, uint16_t tag, - uint16_t datatype, uint32_t count, - uint32_t datalength, void *data) -{ - static const char module[] = "TIFFWriteDirectoryTagData"; - uint32_t m; - m = 0; - while (m < (*ndir)) - { - assert(dir[m].tdir_tag != tag); - if (dir[m].tdir_tag > tag) - break; - m++; - } - if (m < (*ndir)) - { - uint32_t n; - for (n = *ndir; n > m; n--) - dir[n] = dir[n - 1]; - } - dir[m].tdir_tag = tag; - dir[m].tdir_type = datatype; - dir[m].tdir_count = count; - dir[m].tdir_offset.toff_long8 = 0; - if (datalength <= ((tif->tif_flags & TIFF_BIGTIFF) ? 0x8U : 0x4U)) - { - if (data && datalength) - { - _TIFFmemcpy(&dir[m].tdir_offset, data, datalength); - } - } - else - { - uint64_t na, nb; - na = tif->tif_dataoff; - nb = na + datalength; - if (!(tif->tif_flags & TIFF_BIGTIFF)) - nb = (uint32_t)nb; - if ((nb < na) || (nb < datalength)) - { - TIFFErrorExtR(tif, module, "Maximum TIFF file size exceeded"); - return (0); - } - if (!SeekOK(tif, na)) - { - TIFFErrorExtR(tif, module, "IO error writing tag data"); - return (0); - } - if (datalength >= 0x80000000UL) - { - TIFFErrorExtR(tif, module, - "libtiff does not allow writing more than 2147483647 " - "bytes in a tag"); - return (0); - } - if (!WriteOK(tif, data, (tmsize_t)datalength)) - { - TIFFErrorExtR(tif, module, "IO error writing tag data"); - return (0); - } - tif->tif_dataoff = nb; - if (tif->tif_dataoff & 1) - tif->tif_dataoff++; - if (!(tif->tif_flags & TIFF_BIGTIFF)) - { - uint32_t o; - o = (uint32_t)na; - if (tif->tif_flags & TIFF_SWAB) - TIFFSwabLong(&o); - _TIFFmemcpy(&dir[m].tdir_offset, &o, 4); - } - else - { - dir[m].tdir_offset.toff_long8 = na; - if (tif->tif_flags & TIFF_SWAB) - TIFFSwabLong8(&dir[m].tdir_offset.toff_long8); - } - } - (*ndir)++; - return (1); -} - -/* - * Link the current directory into the directory chain for the file. - */ -static int TIFFLinkDirectory(TIFF *tif) -{ - static const char module[] = "TIFFLinkDirectory"; - - tif->tif_diroff = (TIFFSeekFile(tif, 0, SEEK_END) + 1) & (~((toff_t)1)); - - /* - * Handle SubIFDs - */ - if (tif->tif_flags & TIFF_INSUBIFD) - { - if (!(tif->tif_flags & TIFF_BIGTIFF)) - { - uint32_t m; - m = (uint32_t)tif->tif_diroff; - if (tif->tif_flags & TIFF_SWAB) - TIFFSwabLong(&m); - (void)TIFFSeekFile(tif, tif->tif_subifdoff, SEEK_SET); - if (!WriteOK(tif, &m, 4)) - { - TIFFErrorExtR(tif, module, - "Error writing SubIFD directory link"); - return (0); - } - /* - * Advance to the next SubIFD or, if this is - * the last one configured, revert back to the - * normal directory linkage. - */ - if (--tif->tif_nsubifd) - tif->tif_subifdoff += 4; - else - tif->tif_flags &= ~TIFF_INSUBIFD; - return (1); - } - else - { - uint64_t m; - m = tif->tif_diroff; - if (tif->tif_flags & TIFF_SWAB) - TIFFSwabLong8(&m); - (void)TIFFSeekFile(tif, tif->tif_subifdoff, SEEK_SET); - if (!WriteOK(tif, &m, 8)) - { - TIFFErrorExtR(tif, module, - "Error writing SubIFD directory link"); - return (0); - } - /* - * Advance to the next SubIFD or, if this is - * the last one configured, revert back to the - * normal directory linkage. - */ - if (--tif->tif_nsubifd) - tif->tif_subifdoff += 8; - else - tif->tif_flags &= ~TIFF_INSUBIFD; - return (1); - } - } - - if (!(tif->tif_flags & TIFF_BIGTIFF)) - { - uint32_t m; - uint32_t nextdir; - m = (uint32_t)(tif->tif_diroff); - if (tif->tif_flags & TIFF_SWAB) - TIFFSwabLong(&m); - if (tif->tif_header.classic.tiff_diroff == 0) - { - /* - * First directory, overwrite offset in header. - */ - tif->tif_header.classic.tiff_diroff = (uint32_t)tif->tif_diroff; - tif->tif_lastdiroff = tif->tif_diroff; - (void)TIFFSeekFile(tif, 4, SEEK_SET); - if (!WriteOK(tif, &m, 4)) - { - TIFFErrorExtR(tif, tif->tif_name, "Error writing TIFF header"); - return (0); - } - return (1); - } - /* - * Not the first directory, search to the last and append. - */ - if (tif->tif_lastdiroff != 0) - { - nextdir = (uint32_t)tif->tif_lastdiroff; - } - else - { - nextdir = tif->tif_header.classic.tiff_diroff; - } - - while (1) - { - uint16_t dircount; - uint32_t nextnextdir; - - if (!SeekOK(tif, nextdir) || !ReadOK(tif, &dircount, 2)) - { - TIFFErrorExtR(tif, module, "Error fetching directory count"); - return (0); - } - if (tif->tif_flags & TIFF_SWAB) - TIFFSwabShort(&dircount); - (void)TIFFSeekFile(tif, nextdir + 2 + dircount * 12, SEEK_SET); - if (!ReadOK(tif, &nextnextdir, 4)) - { - TIFFErrorExtR(tif, module, "Error fetching directory link"); - return (0); - } - if (tif->tif_flags & TIFF_SWAB) - TIFFSwabLong(&nextnextdir); - if (nextnextdir == 0) - { - (void)TIFFSeekFile(tif, nextdir + 2 + dircount * 12, SEEK_SET); - if (!WriteOK(tif, &m, 4)) - { - TIFFErrorExtR(tif, module, "Error writing directory link"); - return (0); - } - tif->tif_lastdiroff = tif->tif_diroff; - break; - } - nextdir = nextnextdir; - } - } - else - { - uint64_t m; - uint64_t nextdir; - m = tif->tif_diroff; - if (tif->tif_flags & TIFF_SWAB) - TIFFSwabLong8(&m); - if (tif->tif_header.big.tiff_diroff == 0) - { - /* - * First directory, overwrite offset in header. - */ - tif->tif_header.big.tiff_diroff = tif->tif_diroff; - tif->tif_lastdiroff = tif->tif_diroff; - (void)TIFFSeekFile(tif, 8, SEEK_SET); - if (!WriteOK(tif, &m, 8)) - { - TIFFErrorExtR(tif, tif->tif_name, "Error writing TIFF header"); - return (0); - } - return (1); - } - /* - * Not the first directory, search to the last and append. - */ - if (tif->tif_lastdiroff != 0) - { - nextdir = tif->tif_lastdiroff; - } - else - { - nextdir = tif->tif_header.big.tiff_diroff; - } - while (1) - { - uint64_t dircount64; - uint16_t dircount; - uint64_t nextnextdir; - - if (!SeekOK(tif, nextdir) || !ReadOK(tif, &dircount64, 8)) - { - TIFFErrorExtR(tif, module, "Error fetching directory count"); - return (0); - } - if (tif->tif_flags & TIFF_SWAB) - TIFFSwabLong8(&dircount64); - if (dircount64 > 0xFFFF) - { - TIFFErrorExtR( - tif, module, - "Sanity check on tag count failed, likely corrupt TIFF"); - return (0); - } - dircount = (uint16_t)dircount64; - (void)TIFFSeekFile(tif, nextdir + 8 + dircount * 20, SEEK_SET); - if (!ReadOK(tif, &nextnextdir, 8)) - { - TIFFErrorExtR(tif, module, "Error fetching directory link"); - return (0); - } - if (tif->tif_flags & TIFF_SWAB) - TIFFSwabLong8(&nextnextdir); - if (nextnextdir == 0) - { - (void)TIFFSeekFile(tif, nextdir + 8 + dircount * 20, SEEK_SET); - if (!WriteOK(tif, &m, 8)) - { - TIFFErrorExtR(tif, module, "Error writing directory link"); - return (0); - } - tif->tif_lastdiroff = tif->tif_diroff; - break; - } - nextdir = nextnextdir; - } - } - return (1); -} - -/************************************************************************/ -/* TIFFRewriteField() */ -/* */ -/* Rewrite a field in the directory on disk without regard to */ -/* updating the TIFF directory structure in memory. Currently */ -/* only supported for field that already exist in the on-disk */ -/* directory. Mainly used for updating stripoffset / */ -/* stripbytecount values after the directory is already on */ -/* disk. */ -/* */ -/* Returns zero on failure, and one on success. */ -/************************************************************************/ - -int _TIFFRewriteField(TIFF *tif, uint16_t tag, TIFFDataType in_datatype, - tmsize_t count, void *data) -{ - static const char module[] = "TIFFResetField"; - /* const TIFFField* fip = NULL; */ - uint16_t dircount; - tmsize_t dirsize; - uint8_t direntry_raw[20]; - uint16_t entry_tag = 0; - uint16_t entry_type = 0; - uint64_t entry_count = 0; - uint64_t entry_offset = 0; - int value_in_entry = 0; - uint64_t read_offset; - uint8_t *buf_to_write = NULL; - TIFFDataType datatype; - - /* -------------------------------------------------------------------- */ - /* Find field definition. */ - /* -------------------------------------------------------------------- */ - /*fip =*/TIFFFindField(tif, tag, TIFF_ANY); - - /* -------------------------------------------------------------------- */ - /* Do some checking this is a straight forward case. */ - /* -------------------------------------------------------------------- */ - if (isMapped(tif)) - { - TIFFErrorExtR( - tif, module, - "Memory mapped files not currently supported for this operation."); - return 0; - } - - if (tif->tif_diroff == 0) - { - TIFFErrorExtR( - tif, module, - "Attempt to reset field on directory not already on disk."); - return 0; - } - - /* -------------------------------------------------------------------- */ - /* Read the directory entry count. */ - /* -------------------------------------------------------------------- */ - if (!SeekOK(tif, tif->tif_diroff)) - { - TIFFErrorExtR(tif, module, "%s: Seek error accessing TIFF directory", - tif->tif_name); - return 0; - } - - read_offset = tif->tif_diroff; - - if (!(tif->tif_flags & TIFF_BIGTIFF)) - { - if (!ReadOK(tif, &dircount, sizeof(uint16_t))) - { - TIFFErrorExtR(tif, module, "%s: Can not read TIFF directory count", - tif->tif_name); - return 0; - } - if (tif->tif_flags & TIFF_SWAB) - TIFFSwabShort(&dircount); - dirsize = 12; - read_offset += 2; - } - else - { - uint64_t dircount64; - if (!ReadOK(tif, &dircount64, sizeof(uint64_t))) - { - TIFFErrorExtR(tif, module, "%s: Can not read TIFF directory count", - tif->tif_name); - return 0; - } - if (tif->tif_flags & TIFF_SWAB) - TIFFSwabLong8(&dircount64); - dircount = (uint16_t)dircount64; - dirsize = 20; - read_offset += 8; - } - - /* -------------------------------------------------------------------- */ - /* Read through directory to find target tag. */ - /* -------------------------------------------------------------------- */ - while (dircount > 0) - { - if (!ReadOK(tif, direntry_raw, dirsize)) - { - TIFFErrorExtR(tif, module, "%s: Can not read TIFF directory entry.", - tif->tif_name); - return 0; - } - - memcpy(&entry_tag, direntry_raw + 0, sizeof(uint16_t)); - if (tif->tif_flags & TIFF_SWAB) - TIFFSwabShort(&entry_tag); - - if (entry_tag == tag) - break; - - read_offset += dirsize; - } - - if (entry_tag != tag) - { - TIFFErrorExtR(tif, module, "%s: Could not find tag %" PRIu16 ".", - tif->tif_name, tag); - return 0; - } - - /* -------------------------------------------------------------------- */ - /* Extract the type, count and offset for this entry. */ - /* -------------------------------------------------------------------- */ - memcpy(&entry_type, direntry_raw + 2, sizeof(uint16_t)); - if (tif->tif_flags & TIFF_SWAB) - TIFFSwabShort(&entry_type); - - if (!(tif->tif_flags & TIFF_BIGTIFF)) - { - uint32_t value; - - memcpy(&value, direntry_raw + 4, sizeof(uint32_t)); - if (tif->tif_flags & TIFF_SWAB) - TIFFSwabLong(&value); - entry_count = value; - - memcpy(&value, direntry_raw + 8, sizeof(uint32_t)); - if (tif->tif_flags & TIFF_SWAB) - TIFFSwabLong(&value); - entry_offset = value; - } - else - { - memcpy(&entry_count, direntry_raw + 4, sizeof(uint64_t)); - if (tif->tif_flags & TIFF_SWAB) - TIFFSwabLong8(&entry_count); - - memcpy(&entry_offset, direntry_raw + 12, sizeof(uint64_t)); - if (tif->tif_flags & TIFF_SWAB) - TIFFSwabLong8(&entry_offset); - } - - /* -------------------------------------------------------------------- */ - /* When a dummy tag was written due to TIFFDeferStrileArrayWriting() */ - /* -------------------------------------------------------------------- */ - if (entry_offset == 0 && entry_count == 0 && entry_type == 0) - { - if (tag == TIFFTAG_TILEOFFSETS || tag == TIFFTAG_STRIPOFFSETS) - { - entry_type = - (tif->tif_flags & TIFF_BIGTIFF) ? TIFF_LONG8 : TIFF_LONG; - } - else - { - int write_aslong8 = 1; - if (count > 1 && tag == TIFFTAG_STRIPBYTECOUNTS) - { - write_aslong8 = WriteAsLong8(tif, TIFFStripSize64(tif)); - } - else if (count > 1 && tag == TIFFTAG_TILEBYTECOUNTS) - { - write_aslong8 = WriteAsLong8(tif, TIFFTileSize64(tif)); - } - if (write_aslong8) - { - entry_type = TIFF_LONG8; - } - else - { - int write_aslong4 = 1; - if (count > 1 && tag == TIFFTAG_STRIPBYTECOUNTS) - { - write_aslong4 = WriteAsLong4(tif, TIFFStripSize64(tif)); - } - else if (count > 1 && tag == TIFFTAG_TILEBYTECOUNTS) - { - write_aslong4 = WriteAsLong4(tif, TIFFTileSize64(tif)); - } - if (write_aslong4) - { - entry_type = TIFF_LONG; - } - else - { - entry_type = TIFF_SHORT; - } - } - } - } - - /* -------------------------------------------------------------------- */ - /* What data type do we want to write this as? */ - /* -------------------------------------------------------------------- */ - if (TIFFDataWidth(in_datatype) == 8 && !(tif->tif_flags & TIFF_BIGTIFF)) - { - if (in_datatype == TIFF_LONG8) - datatype = entry_type == TIFF_SHORT ? TIFF_SHORT : TIFF_LONG; - else if (in_datatype == TIFF_SLONG8) - datatype = TIFF_SLONG; - else if (in_datatype == TIFF_IFD8) - datatype = TIFF_IFD; - else - datatype = in_datatype; - } - else - { - if (in_datatype == TIFF_LONG8 && - (entry_type == TIFF_SHORT || entry_type == TIFF_LONG || - entry_type == TIFF_LONG8)) - datatype = entry_type; - else if (in_datatype == TIFF_SLONG8 && - (entry_type == TIFF_SLONG || entry_type == TIFF_SLONG8)) - datatype = entry_type; - else if (in_datatype == TIFF_IFD8 && - (entry_type == TIFF_IFD || entry_type == TIFF_IFD8)) - datatype = entry_type; - else - datatype = in_datatype; - } - - /* -------------------------------------------------------------------- */ - /* Prepare buffer of actual data to write. This includes */ - /* swabbing as needed. */ - /* -------------------------------------------------------------------- */ - buf_to_write = (uint8_t *)_TIFFCheckMalloc( - tif, count, TIFFDataWidth(datatype), "for field buffer."); - if (!buf_to_write) - return 0; - - if (datatype == in_datatype) - memcpy(buf_to_write, data, count * TIFFDataWidth(datatype)); - else if (datatype == TIFF_SLONG && in_datatype == TIFF_SLONG8) - { - tmsize_t i; - - for (i = 0; i < count; i++) - { - ((int32_t *)buf_to_write)[i] = (int32_t)((int64_t *)data)[i]; - if ((int64_t)((int32_t *)buf_to_write)[i] != ((int64_t *)data)[i]) - { - _TIFFfreeExt(tif, buf_to_write); - TIFFErrorExtR(tif, module, - "Value exceeds 32bit range of output type."); - return 0; - } - } - } - else if ((datatype == TIFF_LONG && in_datatype == TIFF_LONG8) || - (datatype == TIFF_IFD && in_datatype == TIFF_IFD8)) - { - tmsize_t i; - - for (i = 0; i < count; i++) - { - ((uint32_t *)buf_to_write)[i] = (uint32_t)((uint64_t *)data)[i]; - if ((uint64_t)((uint32_t *)buf_to_write)[i] != - ((uint64_t *)data)[i]) - { - _TIFFfreeExt(tif, buf_to_write); - TIFFErrorExtR(tif, module, - "Value exceeds 32bit range of output type."); - return 0; - } - } - } - else if (datatype == TIFF_SHORT && in_datatype == TIFF_LONG8) - { - tmsize_t i; - - for (i = 0; i < count; i++) - { - ((uint16_t *)buf_to_write)[i] = (uint16_t)((uint64_t *)data)[i]; - if ((uint64_t)((uint16_t *)buf_to_write)[i] != - ((uint64_t *)data)[i]) - { - _TIFFfreeExt(tif, buf_to_write); - TIFFErrorExtR(tif, module, - "Value exceeds 16bit range of output type."); - return 0; - } - } - } - else - { - TIFFErrorExtR(tif, module, "Unhandled type conversion."); - return 0; - } - - if (TIFFDataWidth(datatype) > 1 && (tif->tif_flags & TIFF_SWAB)) - { - if (TIFFDataWidth(datatype) == 2) - TIFFSwabArrayOfShort((uint16_t *)buf_to_write, count); - else if (TIFFDataWidth(datatype) == 4) - TIFFSwabArrayOfLong((uint32_t *)buf_to_write, count); - else if (TIFFDataWidth(datatype) == 8) - TIFFSwabArrayOfLong8((uint64_t *)buf_to_write, count); - } - - /* -------------------------------------------------------------------- */ - /* Is this a value that fits into the directory entry? */ - /* -------------------------------------------------------------------- */ - if (!(tif->tif_flags & TIFF_BIGTIFF)) - { - if (TIFFDataWidth(datatype) * count <= 4) - { - entry_offset = read_offset + 8; - value_in_entry = 1; - } - } - else - { - if (TIFFDataWidth(datatype) * count <= 8) - { - entry_offset = read_offset + 12; - value_in_entry = 1; - } - } - - if ((tag == TIFFTAG_TILEOFFSETS || tag == TIFFTAG_STRIPOFFSETS) && - tif->tif_dir.td_stripoffset_entry.tdir_count == 0 && - tif->tif_dir.td_stripoffset_entry.tdir_type == 0 && - tif->tif_dir.td_stripoffset_entry.tdir_offset.toff_long8 == 0) - { - tif->tif_dir.td_stripoffset_entry.tdir_type = datatype; - tif->tif_dir.td_stripoffset_entry.tdir_count = count; - } - else if ((tag == TIFFTAG_TILEBYTECOUNTS || - tag == TIFFTAG_STRIPBYTECOUNTS) && - tif->tif_dir.td_stripbytecount_entry.tdir_count == 0 && - tif->tif_dir.td_stripbytecount_entry.tdir_type == 0 && - tif->tif_dir.td_stripbytecount_entry.tdir_offset.toff_long8 == 0) - { - tif->tif_dir.td_stripbytecount_entry.tdir_type = datatype; - tif->tif_dir.td_stripbytecount_entry.tdir_count = count; - } - - /* -------------------------------------------------------------------- */ - /* If the tag type, and count match, then we just write it out */ - /* over the old values without altering the directory entry at */ - /* all. */ - /* -------------------------------------------------------------------- */ - if (entry_count == (uint64_t)count && entry_type == (uint16_t)datatype) - { - if (!SeekOK(tif, entry_offset)) - { - _TIFFfreeExt(tif, buf_to_write); - TIFFErrorExtR(tif, module, - "%s: Seek error accessing TIFF directory", - tif->tif_name); - return 0; - } - if (!WriteOK(tif, buf_to_write, count * TIFFDataWidth(datatype))) - { - _TIFFfreeExt(tif, buf_to_write); - TIFFErrorExtR(tif, module, "Error writing directory link"); - return (0); - } - - _TIFFfreeExt(tif, buf_to_write); - return 1; - } - - /* -------------------------------------------------------------------- */ - /* Otherwise, we write the new tag data at the end of the file. */ - /* -------------------------------------------------------------------- */ - if (!value_in_entry) - { - entry_offset = TIFFSeekFile(tif, 0, SEEK_END); - - if (!WriteOK(tif, buf_to_write, count * TIFFDataWidth(datatype))) - { - _TIFFfreeExt(tif, buf_to_write); - TIFFErrorExtR(tif, module, "Error writing directory link"); - return (0); - } - } - else - { - if (count * TIFFDataWidth(datatype) == 4) - { - uint32_t value; - memcpy(&value, buf_to_write, count * TIFFDataWidth(datatype)); - entry_offset = value; - } - else - { - memcpy(&entry_offset, buf_to_write, - count * TIFFDataWidth(datatype)); - } - } - - _TIFFfreeExt(tif, buf_to_write); - buf_to_write = 0; - - /* -------------------------------------------------------------------- */ - /* Adjust the directory entry. */ - /* -------------------------------------------------------------------- */ - entry_type = datatype; - entry_count = (uint64_t)count; - memcpy(direntry_raw + 2, &entry_type, sizeof(uint16_t)); - if (tif->tif_flags & TIFF_SWAB) - TIFFSwabShort((uint16_t *)(direntry_raw + 2)); - - if (!(tif->tif_flags & TIFF_BIGTIFF)) - { - uint32_t value; - - value = (uint32_t)entry_count; - memcpy(direntry_raw + 4, &value, sizeof(uint32_t)); - if (tif->tif_flags & TIFF_SWAB) - TIFFSwabLong((uint32_t *)(direntry_raw + 4)); - - value = (uint32_t)entry_offset; - memcpy(direntry_raw + 8, &value, sizeof(uint32_t)); - if (tif->tif_flags & TIFF_SWAB) - TIFFSwabLong((uint32_t *)(direntry_raw + 8)); - } - else - { - memcpy(direntry_raw + 4, &entry_count, sizeof(uint64_t)); - if (tif->tif_flags & TIFF_SWAB) - TIFFSwabLong8((uint64_t *)(direntry_raw + 4)); - - memcpy(direntry_raw + 12, &entry_offset, sizeof(uint64_t)); - if (tif->tif_flags & TIFF_SWAB) - TIFFSwabLong8((uint64_t *)(direntry_raw + 12)); - } - - /* -------------------------------------------------------------------- */ - /* Write the directory entry out to disk. */ - /* -------------------------------------------------------------------- */ - if (!SeekOK(tif, read_offset)) - { - TIFFErrorExtR(tif, module, "%s: Seek error accessing TIFF directory", - tif->tif_name); - return 0; - } - - if (!WriteOK(tif, direntry_raw, dirsize)) - { - TIFFErrorExtR(tif, module, "%s: Can not write TIFF directory entry.", - tif->tif_name); - return 0; - } - - return 1; -} diff --git a/src/3rd/tiff/dumpmode.c b/src/3rd/tiff/dumpmode.c deleted file mode 100644 index 267d5d2d7a5..00000000000 --- a/src/3rd/tiff/dumpmode.c +++ /dev/null @@ -1,122 +0,0 @@ -/* - * Copyright (c) 1988-1997 Sam Leffler - * Copyright (c) 1991-1997 Silicon Graphics, Inc. - * - * Permission to use, copy, modify, distribute, and sell this software and - * its documentation for any purpose is hereby granted without fee, provided - * that (i) the above copyright notices and this permission notice appear in - * all copies of the software and related documentation, and (ii) the names of - * Sam Leffler and Silicon Graphics may not be used in any advertising or - * publicity relating to the software without the specific, prior written - * permission of Sam Leffler and Silicon Graphics. - * - * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, - * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY - * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. - * - * IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR - * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, - * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, - * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF - * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE - * OF THIS SOFTWARE. - */ - -/* - * TIFF Library. - * - * "Null" Compression Algorithm Support. - */ -#include "tiffiop.h" - -static int DumpFixupTags(TIFF *tif) -{ - (void)tif; - return (1); -} - -/* - * Encode a hunk of pixels. - */ -static int DumpModeEncode(TIFF *tif, uint8_t *pp, tmsize_t cc, uint16_t s) -{ - (void)s; - while (cc > 0) - { - tmsize_t n; - - n = cc; - if (tif->tif_rawcc + n > tif->tif_rawdatasize) - n = tif->tif_rawdatasize - tif->tif_rawcc; - - assert(n > 0); - - /* - * Avoid copy if client has setup raw - * data buffer to avoid extra copy. - */ - if (tif->tif_rawcp != pp) - _TIFFmemcpy(tif->tif_rawcp, pp, n); - tif->tif_rawcp += n; - tif->tif_rawcc += n; - pp += n; - cc -= n; - if (tif->tif_rawcc >= tif->tif_rawdatasize && !TIFFFlushData1(tif)) - return (0); - } - return (1); -} - -/* - * Decode a hunk of pixels. - */ -static int DumpModeDecode(TIFF *tif, uint8_t *buf, tmsize_t cc, uint16_t s) -{ - static const char module[] = "DumpModeDecode"; - (void)s; - if (tif->tif_rawcc < cc) - { - TIFFErrorExtR(tif, module, - "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); - return (0); - } - /* - * Avoid copy if client has setup raw - * data buffer to avoid extra copy. - */ - if (tif->tif_rawcp != buf) - _TIFFmemcpy(buf, tif->tif_rawcp, cc); - tif->tif_rawcp += cc; - tif->tif_rawcc -= cc; - return (1); -} - -/* - * Seek forwards nrows in the current strip. - */ -static int DumpModeSeek(TIFF *tif, uint32_t nrows) -{ - tif->tif_rawcp += nrows * tif->tif_scanlinesize; - tif->tif_rawcc -= nrows * tif->tif_scanlinesize; - return (1); -} - -/* - * Initialize dump mode. - */ -int TIFFInitDumpMode(TIFF *tif, int scheme) -{ - (void)scheme; - tif->tif_fixuptags = DumpFixupTags; - tif->tif_decoderow = DumpModeDecode; - tif->tif_decodestrip = DumpModeDecode; - tif->tif_decodetile = DumpModeDecode; - tif->tif_encoderow = DumpModeEncode; - tif->tif_encodestrip = DumpModeEncode; - tif->tif_encodetile = DumpModeEncode; - tif->tif_seek = DumpModeSeek; - return (1); -} diff --git a/src/3rd/tiff/error.c b/src/3rd/tiff/error.c deleted file mode 100644 index c3ca8493da1..00000000000 --- a/src/3rd/tiff/error.c +++ /dev/null @@ -1,134 +0,0 @@ -/* - * Copyright (c) 1988-1997 Sam Leffler - * Copyright (c) 1991-1997 Silicon Graphics, Inc. - * - * Permission to use, copy, modify, distribute, and sell this software and - * its documentation for any purpose is hereby granted without fee, provided - * that (i) the above copyright notices and this permission notice appear in - * all copies of the software and related documentation, and (ii) the names of - * Sam Leffler and Silicon Graphics may not be used in any advertising or - * publicity relating to the software without the specific, prior written - * permission of Sam Leffler and Silicon Graphics. - * - * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, - * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY - * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. - * - * IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR - * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, - * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, - * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF - * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE - * OF THIS SOFTWARE. - */ - -/* - * TIFF Library. - */ -#include "tiffiop.h" - -TIFFErrorHandlerExt _TIFFerrorHandlerExt = NULL; - -TIFFErrorHandler TIFFSetErrorHandler(TIFFErrorHandler handler) -{ - TIFFErrorHandler prev = _TIFFerrorHandler; - _TIFFerrorHandler = handler; - return (prev); -} - -TIFFErrorHandlerExt TIFFSetErrorHandlerExt(TIFFErrorHandlerExt handler) -{ - TIFFErrorHandlerExt prev = _TIFFerrorHandlerExt; - _TIFFerrorHandlerExt = handler; - return (prev); -} - -void TIFFError(const char *module, const char *fmt, ...) -{ - va_list ap; - if (_TIFFerrorHandler) - { - va_start(ap, fmt); - (*_TIFFerrorHandler)(module, fmt, ap); - va_end(ap); - } - if (_TIFFerrorHandlerExt) - { - va_start(ap, fmt); - (*_TIFFerrorHandlerExt)(0, module, fmt, ap); - va_end(ap); - } -} - -void TIFFErrorExt(thandle_t fd, const char *module, const char *fmt, ...) -{ - va_list ap; - if (_TIFFerrorHandler) - { - va_start(ap, fmt); - (*_TIFFerrorHandler)(module, fmt, ap); - va_end(ap); - } - if (_TIFFerrorHandlerExt) - { - va_start(ap, fmt); - (*_TIFFerrorHandlerExt)(fd, module, fmt, ap); - va_end(ap); - } -} - -void _TIFFErrorEarly(TIFFOpenOptions *opts, thandle_t clientdata, - const char *module, const char *fmt, ...) -{ - va_list ap; - if (opts && opts->errorhandler) - { - int stop; - va_start(ap, fmt); - stop = opts->errorhandler(NULL, opts->errorhandler_user_data, - module, fmt, ap); - va_end(ap); - if (stop) - return; - } - if (_TIFFerrorHandler) - { - va_start(ap, fmt); - (*_TIFFerrorHandler)(module, fmt, ap); - va_end(ap); - } - if (_TIFFerrorHandlerExt) - { - va_start(ap, fmt); - (*_TIFFerrorHandlerExt)(clientdata, module, fmt, ap); - va_end(ap); - } -} - -void TIFFErrorExtR(TIFF *tif, const char *module, const char *fmt, ...) -{ - va_list ap; - if (tif && tif->tif_errorhandler) - { - int stop; - va_start(ap, fmt); - stop = (*tif->tif_errorhandler)( - tif, tif->tif_errorhandler_user_data, module, fmt, ap); - va_end(ap); - if (stop) - return; - } - if (_TIFFerrorHandler) - { - va_start(ap, fmt); - (*_TIFFerrorHandler)(module, fmt, ap); - va_end(ap); - } - if (_TIFFerrorHandlerExt) - { - va_start(ap, fmt); - (*_TIFFerrorHandlerExt)(tif ? tif->tif_clientdata : (thandle_t)0, module, fmt, - ap); - va_end(ap); - } -} diff --git a/src/3rd/tiff/extensio.c b/src/3rd/tiff/extensio.c deleted file mode 100644 index 1a09e987a5b..00000000000 --- a/src/3rd/tiff/extensio.c +++ /dev/null @@ -1,110 +0,0 @@ -/* - * Copyright (c) 1988-1997 Sam Leffler - * Copyright (c) 1991-1997 Silicon Graphics, Inc. - * - * Permission to use, copy, modify, distribute, and sell this software and - * its documentation for any purpose is hereby granted without fee, provided - * that (i) the above copyright notices and this permission notice appear in - * all copies of the software and related documentation, and (ii) the names of - * Sam Leffler and Silicon Graphics may not be used in any advertising or - * publicity relating to the software without the specific, prior written - * permission of Sam Leffler and Silicon Graphics. - * - * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, - * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY - * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. - * - * IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR - * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, - * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, - * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF - * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE - * OF THIS SOFTWARE. - */ - -/* - * TIFF Library. - * - * Various routines support external extension of the tag set, and other - * application extension capabilities. - */ - -#include "tiffiop.h" - -int TIFFGetTagListCount(TIFF *tif) - -{ - TIFFDirectory *td = &tif->tif_dir; - - return td->td_customValueCount; -} - -uint32_t TIFFGetTagListEntry(TIFF *tif, int tag_index) - -{ - TIFFDirectory *td = &tif->tif_dir; - - if (tag_index < 0 || tag_index >= td->td_customValueCount) - return (uint32_t)(-1); - else - return td->td_customValues[tag_index].info->field_tag; -} - -/* -** This provides read/write access to the TIFFTagMethods within the TIFF -** structure to application code without giving access to the private -** TIFF structure. -*/ -TIFFTagMethods *TIFFAccessTagMethods(TIFF *tif) - -{ - return &(tif->tif_tagmethods); -} - -void *TIFFGetClientInfo(TIFF *tif, const char *name) - -{ - TIFFClientInfoLink *psLink = tif->tif_clientinfo; - - while (psLink != NULL && strcmp(psLink->name, name) != 0) - psLink = psLink->next; - - if (psLink != NULL) - return psLink->data; - else - return NULL; -} - -void TIFFSetClientInfo(TIFF *tif, void *data, const char *name) - -{ - TIFFClientInfoLink *psLink = tif->tif_clientinfo; - - /* - ** Do we have an existing link with this name? If so, just - ** set it. - */ - while (psLink != NULL && strcmp(psLink->name, name) != 0) - psLink = psLink->next; - - if (psLink != NULL) - { - psLink->data = data; - return; - } - - /* - ** Create a new link. - */ - - psLink = - (TIFFClientInfoLink *)_TIFFmallocExt(tif, sizeof(TIFFClientInfoLink)); - assert(psLink != NULL); - psLink->next = tif->tif_clientinfo; - psLink->name = (char *)_TIFFmallocExt(tif, (tmsize_t)(strlen(name) + 1)); - assert(psLink->name != NULL); - strcpy(psLink->name, name); - psLink->data = data; - - tif->tif_clientinfo = psLink; -} diff --git a/src/3rd/tiff/fax3.c b/src/3rd/tiff/fax3.c deleted file mode 100644 index e6d0c1aec1d..00000000000 --- a/src/3rd/tiff/fax3.c +++ /dev/null @@ -1,1735 +0,0 @@ -/* - * Copyright (c) 1990-1997 Sam Leffler - * Copyright (c) 1991-1997 Silicon Graphics, Inc. - * - * Permission to use, copy, modify, distribute, and sell this software and - * its documentation for any purpose is hereby granted without fee, provided - * that (i) the above copyright notices and this permission notice appear in - * all copies of the software and related documentation, and (ii) the names of - * Sam Leffler and Silicon Graphics may not be used in any advertising or - * publicity relating to the software without the specific, prior written - * permission of Sam Leffler and Silicon Graphics. - * - * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, - * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY - * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. - * - * IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR - * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, - * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, - * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF - * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE - * OF THIS SOFTWARE. - */ - -#include "tiffiop.h" -#ifdef CCITT_SUPPORT -/* - * TIFF Library. - * - * CCITT Group 3 (T.4) and Group 4 (T.6) Compression Support. - * - * This file contains support for decoding and encoding TIFF - * compression algorithms 2, 3, 4, and 32771. - * - * Decoder support is derived, with permission, from the code - * in Frank Cringle's viewfax program; - * Copyright (C) 1990, 1995 Frank D. Cringle. - */ -#include "fax3.h" -#define G3CODES -#include "t4.h" -#include - -/* - * Compression+decompression state blocks are - * derived from this ``base state'' block. - */ -typedef struct -{ - int rw_mode; /* O_RDONLY for decode, else encode */ - int mode; /* operating mode */ - tmsize_t rowbytes; /* bytes in a decoded scanline */ - uint32_t rowpixels; /* pixels in a scanline */ - - uint16_t cleanfaxdata; /* CleanFaxData tag */ - uint32_t badfaxrun; /* BadFaxRun tag */ - uint32_t badfaxlines; /* BadFaxLines tag */ - uint32_t groupoptions; /* Group 3/4 options tag */ - - TIFFVGetMethod vgetparent; /* super-class method */ - TIFFVSetMethod vsetparent; /* super-class method */ - TIFFPrintMethod printdir; /* super-class method */ -} Fax3BaseState; -#define Fax3State(tif) ((Fax3BaseState *)(tif)->tif_data) - -typedef enum -{ - G3_1D, - G3_2D -} Ttag; -typedef struct -{ - Fax3BaseState b; - - /* Decoder state info */ - const unsigned char *bitmap; /* bit reversal table */ - uint32_t data; /* current i/o byte/word */ - int bit; /* current i/o bit in byte */ - int EOLcnt; /* count of EOL codes recognized */ - TIFFFaxFillFunc fill; /* fill routine */ - uint32_t *runs; /* b&w runs for current/previous row */ - uint32_t nruns; /* size of the refruns / curruns arrays */ - uint32_t *refruns; /* runs for reference line */ - uint32_t *curruns; /* runs for current line */ - - /* Encoder state info */ - Ttag tag; /* encoding state */ - unsigned char *refline; /* reference line for 2d decoding */ - int k; /* #rows left that can be 2d encoded */ - int maxk; /* max #rows that can be 2d encoded */ - - int line; -} Fax3CodecState; -#define DecoderState(tif) ((Fax3CodecState *)Fax3State(tif)) -#define EncoderState(tif) ((Fax3CodecState *)Fax3State(tif)) - -#define is2DEncoding(sp) (sp->b.groupoptions & GROUP3OPT_2DENCODING) -#define isAligned(p, t) ((((size_t)(p)) & (sizeof(t) - 1)) == 0) - -/* - * Group 3 and Group 4 Decoding. - */ - -/* - * These macros glue the TIFF library state to - * the state expected by Frank's decoder. - */ -#define DECLARE_STATE(tif, sp, mod) \ - static const char module[] = mod; \ - Fax3CodecState *sp = DecoderState(tif); \ - int a0; /* reference element */ \ - int lastx = sp->b.rowpixels; /* last element in row */ \ - uint32_t BitAcc; /* bit accumulator */ \ - int BitsAvail; /* # valid bits in BitAcc */ \ - int RunLength; /* length of current run */ \ - unsigned char *cp; /* next byte of input data */ \ - unsigned char *ep; /* end of input data */ \ - uint32_t *pa; /* place to stuff next run */ \ - uint32_t *thisrun; /* current row's run array */ \ - int EOLcnt; /* # EOL codes recognized */ \ - const unsigned char *bitmap = sp->bitmap; /* input data bit reverser */ \ - const TIFFFaxTabEnt *TabEnt -#define DECLARE_STATE_2D(tif, sp, mod) \ - DECLARE_STATE(tif, sp, mod); \ - int b1; /* next change on prev line */ \ - uint32_t \ - *pb /* next run in reference line */ /* \ - * Load any state that may be \ - * changed during decoding. \ - */ -#define CACHE_STATE(tif, sp) \ - do \ - { \ - BitAcc = sp->data; \ - BitsAvail = sp->bit; \ - EOLcnt = sp->EOLcnt; \ - cp = (unsigned char *)tif->tif_rawcp; \ - ep = cp + tif->tif_rawcc; \ - } while (0) -/* - * Save state possibly changed during decoding. - */ -#define UNCACHE_STATE(tif, sp) \ - do \ - { \ - sp->bit = BitsAvail; \ - sp->data = BitAcc; \ - sp->EOLcnt = EOLcnt; \ - tif->tif_rawcc -= (tmsize_t)((uint8_t *)cp - tif->tif_rawcp); \ - tif->tif_rawcp = (uint8_t *)cp; \ - } while (0) - -/* - * Setup state for decoding a strip. - */ -static int Fax3PreDecode(TIFF *tif, uint16_t s) -{ - Fax3CodecState *sp = DecoderState(tif); - - (void)s; - assert(sp != NULL); - sp->bit = 0; /* force initial read */ - sp->data = 0; - sp->EOLcnt = 0; /* force initial scan for EOL */ - /* - * Decoder assumes lsb-to-msb bit order. Note that we select - * this here rather than in Fax3SetupState so that viewers can - * hold the image open, fiddle with the FillOrder tag value, - * and then re-decode the image. Otherwise they'd need to close - * and open the image to get the state reset. - */ - sp->bitmap = - TIFFGetBitRevTable(tif->tif_dir.td_fillorder != FILLORDER_LSB2MSB); - sp->curruns = sp->runs; - if (sp->refruns) - { /* init reference line to white */ - sp->refruns = sp->runs + sp->nruns; - sp->refruns[0] = (uint32_t)sp->b.rowpixels; - sp->refruns[1] = 0; - } - sp->line = 0; - return (1); -} - -/* - * Routine for handling various errors/conditions. - * Note how they are "glued into the decoder" by - * overriding the definitions used by the decoder. - */ - -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); -} -#define unexpected(table, a0) Fax3Unexpected(module, tif, sp->line, a0) - -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); -} -#define extension(a0) Fax3Extension(module, tif, sp->line, 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); -} -#define badlength(a0, lastx) Fax3BadLength(module, tif, sp->line, a0, lastx) - -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); -} -#define prematureEOF(a0) Fax3PrematureEOF(module, tif, sp->line, a0) - -#define Nop - -/** - * Decode the requested amount of G3 1D-encoded data. - * @param buf destination buffer - * @param occ available bytes in destination buffer - * @param s number of planes (ignored) - * @returns 1 for success, -1 in case of error - */ -static int Fax3Decode1D(TIFF *tif, uint8_t *buf, tmsize_t occ, uint16_t s) -{ - DECLARE_STATE(tif, sp, "Fax3Decode1D"); - (void)s; - if (occ % sp->b.rowbytes) - { - TIFFErrorExtR(tif, module, "Fractional scanlines cannot be read"); - return (-1); - } - CACHE_STATE(tif, sp); - thisrun = sp->curruns; - while (occ > 0) - { - a0 = 0; - RunLength = 0; - pa = thisrun; -#ifdef FAX3_DEBUG - printf("\nBitAcc=%08" PRIX32 ", BitsAvail = %d\n", BitAcc, BitsAvail); - printf("-------------------- %" PRIu32 "\n", tif->tif_row); - fflush(stdout); -#endif - SYNC_EOL(EOF1D); - EXPAND1D(EOF1Da); - (*sp->fill)(buf, thisrun, pa, lastx); - buf += sp->b.rowbytes; - occ -= sp->b.rowbytes; - sp->line++; - continue; - EOF1D: /* premature EOF */ - CLEANUP_RUNS(); - EOF1Da: /* premature EOF */ - (*sp->fill)(buf, thisrun, pa, lastx); - UNCACHE_STATE(tif, sp); - return (-1); - } - UNCACHE_STATE(tif, sp); - return (1); -} - -#define SWAP(t, a, b) \ - { \ - t x; \ - x = (a); \ - (a) = (b); \ - (b) = x; \ - } -/* - * Decode the requested amount of G3 2D-encoded data. - */ -static int Fax3Decode2D(TIFF *tif, uint8_t *buf, tmsize_t occ, uint16_t s) -{ - DECLARE_STATE_2D(tif, sp, "Fax3Decode2D"); - int is1D; /* current line is 1d/2d-encoded */ - (void)s; - if (occ % sp->b.rowbytes) - { - TIFFErrorExtR(tif, module, "Fractional scanlines cannot be read"); - return (-1); - } - CACHE_STATE(tif, sp); - while (occ > 0) - { - a0 = 0; - RunLength = 0; - pa = thisrun = sp->curruns; -#ifdef FAX3_DEBUG - printf("\nBitAcc=%08" PRIX32 ", BitsAvail = %d EOLcnt = %d", BitAcc, - BitsAvail, EOLcnt); -#endif - SYNC_EOL(EOF2D); - NeedBits8(1, EOF2D); - is1D = GetBits(1); /* 1D/2D-encoding tag bit */ - ClrBits(1); -#ifdef FAX3_DEBUG - printf(" %s\n-------------------- %" PRIu32 "\n", is1D ? "1D" : "2D", - tif->tif_row); - fflush(stdout); -#endif - pb = sp->refruns; - b1 = *pb++; - if (is1D) - EXPAND1D(EOF2Da); - else - EXPAND2D(EOF2Da); - (*sp->fill)(buf, thisrun, pa, lastx); - if (pa < thisrun + sp->nruns) - { - SETVALUE(0); /* imaginary change for reference */ - } - SWAP(uint32_t *, sp->curruns, sp->refruns); - buf += sp->b.rowbytes; - occ -= sp->b.rowbytes; - sp->line++; - continue; - EOF2D: /* premature EOF */ - CLEANUP_RUNS(); - EOF2Da: /* premature EOF */ - (*sp->fill)(buf, thisrun, pa, lastx); - UNCACHE_STATE(tif, sp); - return (-1); - } - UNCACHE_STATE(tif, sp); - return (1); -} -#undef SWAP - -#define FILL(n, cp) \ - for (int32_t ifill = 0; ifill < (n); ++ifill) \ - { \ - (cp)[ifill] = 0xff; \ - } \ - (cp) += (n); - -#define ZERO(n, cp) \ - for (int32_t izero = 0; izero < (n); ++izero) \ - { \ - (cp)[izero] = 0; \ - } \ - (cp) += (n); - -/* - * Bit-fill a row according to the white/black - * runs generated during G3/G4 decoding. - */ -void _TIFFFax3fillruns(unsigned char *buf, uint32_t *runs, uint32_t *erun, - uint32_t lastx) -{ - static const unsigned char _fillmasks[] = {0x00, 0x80, 0xc0, 0xe0, 0xf0, - 0xf8, 0xfc, 0xfe, 0xff}; - unsigned char *cp; - uint32_t x, bx, run; - int32_t n, nw; - int64_t *lp; - - if ((erun - runs) & 1) - *erun++ = 0; - x = 0; - for (; runs < erun; runs += 2) - { - run = runs[0]; - if (x + run > lastx || run > lastx) - run = runs[0] = (uint32_t)(lastx - x); - if (run) - { - cp = buf + (x >> 3); - bx = x & 7; - if (run > 8 - bx) - { - if (bx) - { /* align to byte boundary */ - *cp++ &= 0xff << (8 - bx); - run -= 8 - bx; - } - if ((n = run >> 3) != 0) - { /* multiple bytes to fill */ - if ((n / sizeof(int64_t)) > 1) - { - /* - * Align to int64_tword boundary and fill. - */ - for (; n && !isAligned(cp, int64_t); n--) - *cp++ = 0x00; - lp = (int64_t *)cp; - nw = (int32_t)(n / sizeof(int64_t)); - n -= nw * sizeof(int64_t); - do - { - *lp++ = 0L; - } while (--nw); - cp = (unsigned char *)lp; - } - ZERO(n, cp); - run &= 7; - } - if (run) - cp[0] &= 0xff >> run; - } - else - cp[0] &= ~(_fillmasks[run] >> bx); - x += runs[0]; - } - run = runs[1]; - if (x + run > lastx || run > lastx) - run = runs[1] = lastx - x; - if (run) - { - cp = buf + (x >> 3); - bx = x & 7; - if (run > 8 - bx) - { - if (bx) - { /* align to byte boundary */ - *cp++ |= 0xff >> bx; - run -= 8 - bx; - } - if ((n = run >> 3) != 0) - { /* multiple bytes to fill */ - if ((n / sizeof(int64_t)) > 1) - { - /* - * Align to int64_t boundary and fill. - */ - for (; n && !isAligned(cp, int64_t); n--) - *cp++ = 0xff; - lp = (int64_t *)cp; - nw = (int32_t)(n / sizeof(int64_t)); - n -= nw * sizeof(int64_t); - do - { - *lp++ = -1L; - } while (--nw); - cp = (unsigned char *)lp; - } - FILL(n, cp); - run &= 7; - } - /* Explicit 0xff masking to make icc -check=conversions happy */ - if (run) - cp[0] = (unsigned char)((cp[0] | (0xff00 >> run)) & 0xff); - } - else - cp[0] |= _fillmasks[run] >> bx; - x += runs[1]; - } - } - assert(x == lastx); -} -#undef ZERO -#undef FILL - -static int Fax3FixupTags(TIFF *tif) -{ - (void)tif; - return (1); -} - -/* - * Setup G3/G4-related compression/decompression state - * before data is processed. This routine is called once - * per image -- it sets up different state based on whether - * or not decoding or encoding is being done and whether - * 1D- or 2D-encoded data is involved. - */ -static int Fax3SetupState(TIFF *tif) -{ - static const char module[] = "Fax3SetupState"; - TIFFDirectory *td = &tif->tif_dir; - Fax3BaseState *sp = Fax3State(tif); - int needsRefLine; - Fax3CodecState *dsp = (Fax3CodecState *)Fax3State(tif); - tmsize_t rowbytes; - uint32_t rowpixels; - - if (td->td_bitspersample != 1) - { - TIFFErrorExtR(tif, module, - "Bits/sample must be 1 for Group 3/4 encoding/decoding"); - return (0); - } - /* - * Calculate the scanline/tile widths. - */ - if (isTiled(tif)) - { - rowbytes = TIFFTileRowSize(tif); - rowpixels = td->td_tilewidth; - } - else - { - rowbytes = TIFFScanlineSize(tif); - rowpixels = td->td_imagewidth; - } - if ((int64_t)rowbytes < ((int64_t)rowpixels + 7) / 8) - { - TIFFErrorExtR(tif, module, - "Inconsistent number of bytes per row : rowbytes=%" PRId64 - " rowpixels=%" PRIu32, - (int64_t)rowbytes, rowpixels); - return (0); - } - sp->rowbytes = rowbytes; - sp->rowpixels = rowpixels; - /* - * Allocate any additional space required for decoding/encoding. - */ - needsRefLine = ((sp->groupoptions & GROUP3OPT_2DENCODING) || - td->td_compression == COMPRESSION_CCITTFAX4); - - /* - Assure that allocation computations do not overflow. - - TIFFroundup and TIFFSafeMultiply return zero on integer overflow - */ - dsp->runs = (uint32_t *)NULL; - dsp->nruns = TIFFroundup_32(rowpixels + 1, 32); - if (needsRefLine) - { - dsp->nruns = TIFFSafeMultiply(uint32_t, dsp->nruns, 2); - } - if ((dsp->nruns == 0) || (TIFFSafeMultiply(uint32_t, dsp->nruns, 2) == 0)) - { - TIFFErrorExtR(tif, tif->tif_name, - "Row pixels integer overflow (rowpixels %" PRIu32 ")", - rowpixels); - return (0); - } - dsp->runs = (uint32_t *)_TIFFCheckMalloc( - tif, TIFFSafeMultiply(uint32_t, dsp->nruns, 2), sizeof(uint32_t), - "for Group 3/4 run arrays"); - if (dsp->runs == NULL) - return (0); - memset(dsp->runs, 0, - TIFFSafeMultiply(uint32_t, dsp->nruns, 2) * sizeof(uint32_t)); - dsp->curruns = dsp->runs; - if (needsRefLine) - dsp->refruns = dsp->runs + dsp->nruns; - else - dsp->refruns = NULL; - if (td->td_compression == COMPRESSION_CCITTFAX3 && is2DEncoding(dsp)) - { /* NB: default is 1D routine */ - tif->tif_decoderow = Fax3Decode2D; - tif->tif_decodestrip = Fax3Decode2D; - tif->tif_decodetile = Fax3Decode2D; - } - - if (needsRefLine) - { /* 2d encoding */ - Fax3CodecState *esp = EncoderState(tif); - /* - * 2d encoding requires a scanline - * buffer for the ``reference line''; the - * scanline against which delta encoding - * is referenced. The reference line must - * be initialized to be ``white'' (done elsewhere). - */ - esp->refline = (unsigned char *)_TIFFmallocExt(tif, rowbytes); - if (esp->refline == NULL) - { - TIFFErrorExtR(tif, module, "No space for Group 3/4 reference line"); - return (0); - } - } - else /* 1d encoding */ - EncoderState(tif)->refline = NULL; - - return (1); -} - -/* - * CCITT Group 3 FAX Encoding. - */ - -#define Fax3FlushBits(tif, sp) \ - { \ - if ((tif)->tif_rawcc >= (tif)->tif_rawdatasize) \ - { \ - if (!TIFFFlushData1(tif)) \ - return 0; \ - } \ - *(tif)->tif_rawcp++ = (uint8_t)(sp)->data; \ - (tif)->tif_rawcc++; \ - (sp)->data = 0, (sp)->bit = 8; \ - } -#define _FlushBits(tif) \ - { \ - if ((tif)->tif_rawcc >= (tif)->tif_rawdatasize) \ - { \ - if (!TIFFFlushData1(tif)) \ - return 0; \ - } \ - *(tif)->tif_rawcp++ = (uint8_t)data; \ - (tif)->tif_rawcc++; \ - data = 0, bit = 8; \ - } -static const int _msbmask[9] = {0x00, 0x01, 0x03, 0x07, 0x0f, - 0x1f, 0x3f, 0x7f, 0xff}; -#define _PutBits(tif, bits, length) \ - { \ - while (length > bit) \ - { \ - data |= bits >> (length - bit); \ - length -= bit; \ - _FlushBits(tif); \ - } \ - assert(length < 9); \ - data |= (bits & _msbmask[length]) << (bit - length); \ - bit -= length; \ - if (bit == 0) \ - _FlushBits(tif); \ - } - -/* - * Write a variable-length bit-value to - * the output stream. Values are - * assumed to be at most 16 bits. - */ -static int Fax3PutBits(TIFF *tif, unsigned int bits, unsigned int length) -{ - Fax3CodecState *sp = EncoderState(tif); - unsigned int bit = sp->bit; - int data = sp->data; - - _PutBits(tif, bits, length); - - sp->data = data; - sp->bit = bit; - return 1; -} - -/* - * Write a code to the output stream. - */ -#define putcode(tif, te) Fax3PutBits(tif, (te)->code, (te)->length) - -#ifdef FAX3_DEBUG -#define DEBUG_COLOR(w) (tab == TIFFFaxWhiteCodes ? w "W" : w "B") -#define DEBUG_PRINT(what, len) \ - { \ - int t; \ - printf("%08" PRIX32 "/%-2d: %s%5d\t", data, bit, DEBUG_COLOR(what), \ - len); \ - for (t = length - 1; t >= 0; t--) \ - putchar(code & (1 << t) ? '1' : '0'); \ - putchar('\n'); \ - } -#endif - -/* - * Write the sequence of codes that describes - * the specified span of zero's or one's. The - * appropriate table that holds the make-up and - * terminating codes is supplied. - */ -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 code, length; - - while (span >= 2624) - { - const tableentry *te = &tab[63 + (2560 >> 6)]; - code = te->code; - length = te->length; -#ifdef FAX3_DEBUG - DEBUG_PRINT("MakeUp", te->runlen); -#endif - _PutBits(tif, code, length); - span -= te->runlen; - } - if (span >= 64) - { - const tableentry *te = &tab[63 + (span >> 6)]; - assert(te->runlen == 64 * (span >> 6)); - code = te->code; - length = te->length; -#ifdef FAX3_DEBUG - DEBUG_PRINT("MakeUp", te->runlen); -#endif - _PutBits(tif, code, length); - span -= te->runlen; - } - code = tab[span].code; - length = tab[span].length; -#ifdef FAX3_DEBUG - DEBUG_PRINT(" Term", tab[span].runlen); -#endif - _PutBits(tif, code, length); - - sp->data = data; - sp->bit = bit; - - return 1; -} - -/* - * Write an EOL code to the output stream. The zero-fill - * logic for byte-aligning encoded scanlines is handled - * here. We also handle writing the tag bit for the next - * scanline when doing 2d encoding. - */ -static int Fax3PutEOL(TIFF *tif) -{ - Fax3CodecState *sp = EncoderState(tif); - unsigned int bit = sp->bit; - int data = sp->data; - unsigned int code, length, tparm; - - if (sp->b.groupoptions & GROUP3OPT_FILLBITS) - { - /* - * Force bit alignment so EOL will terminate on - * a byte boundary. That is, force the bit alignment - * to 16-12 = 4 before putting out the EOL code. - */ - int align = 8 - 4; - if (align != sp->bit) - { - if (align > sp->bit) - align = sp->bit + (8 - align); - else - align = sp->bit - align; - tparm = align; - _PutBits(tif, 0, tparm); - } - } - code = EOL; - length = 12; - if (is2DEncoding(sp)) - { - code = (code << 1) | (sp->tag == G3_1D); - length++; - } - _PutBits(tif, code, length); - - sp->data = data; - sp->bit = bit; - - return 1; -} - -/* - * Reset encoding state at the start of a strip. - */ -static int Fax3PreEncode(TIFF *tif, uint16_t s) -{ - Fax3CodecState *sp = EncoderState(tif); - - (void)s; - assert(sp != NULL); - sp->bit = 8; - sp->data = 0; - sp->tag = G3_1D; - /* - * This is necessary for Group 4; otherwise it isn't - * needed because the first scanline of each strip ends - * up being copied into the refline. - */ - if (sp->refline) - _TIFFmemset(sp->refline, 0x00, sp->b.rowbytes); - if (is2DEncoding(sp)) - { - float res = tif->tif_dir.td_yresolution; - /* - * The CCITT spec says that when doing 2d encoding, you - * should only do it on K consecutive scanlines, where K - * depends on the resolution of the image being encoded - * (2 for <= 200 lpi, 4 for > 200 lpi). Since the directory - * code initializes td_yresolution to 0, this code will - * select a K of 2 unless the YResolution tag is set - * appropriately. (Note also that we fudge a little here - * and use 150 lpi to avoid problems with units conversion.) - */ - if (tif->tif_dir.td_resolutionunit == RESUNIT_CENTIMETER) - res *= 2.54f; /* convert to inches */ - sp->maxk = (res > 150 ? 4 : 2); - sp->k = sp->maxk - 1; - } - else - sp->k = sp->maxk = 0; - sp->line = 0; - return (1); -} - -static const unsigned char zeroruns[256] = { - 8, 7, 6, 6, 5, 5, 5, 5, 4, 4, 4, 4, 4, 4, 4, 4, /* 0x00 - 0x0f */ - 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, /* 0x10 - 0x1f */ - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, /* 0x20 - 0x2f */ - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, /* 0x30 - 0x3f */ - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 0x40 - 0x4f */ - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 0x50 - 0x5f */ - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 0x60 - 0x6f */ - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 0x70 - 0x7f */ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x80 - 0x8f */ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x90 - 0x9f */ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0xa0 - 0xaf */ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0xb0 - 0xbf */ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0xc0 - 0xcf */ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0xd0 - 0xdf */ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0xe0 - 0xef */ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0xf0 - 0xff */ -}; -static const unsigned char oneruns[256] = { - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x00 - 0x0f */ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x10 - 0x1f */ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x20 - 0x2f */ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x30 - 0x3f */ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x40 - 0x4f */ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x50 - 0x5f */ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x60 - 0x6f */ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x70 - 0x7f */ - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 0x80 - 0x8f */ - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 0x90 - 0x9f */ - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 0xa0 - 0xaf */ - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 0xb0 - 0xbf */ - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, /* 0xc0 - 0xcf */ - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, /* 0xd0 - 0xdf */ - 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, /* 0xe0 - 0xef */ - 4, 4, 4, 4, 4, 4, 4, 4, 5, 5, 5, 5, 6, 6, 7, 8, /* 0xf0 - 0xff */ -}; - -/* - * Find a span of ones or zeros using the supplied - * table. The ``base'' of the bit string is supplied - * along with the start+end bit indices. - */ -static inline int32_t find0span(unsigned char *bp, int32_t bs, int32_t be) -{ - int32_t bits = be - bs; - int32_t n, span; - - bp += bs >> 3; - /* - * Check partial byte on lhs. - */ - if (bits > 0 && (n = (bs & 7)) != 0) - { - span = zeroruns[(*bp << n) & 0xff]; - if (span > 8 - n) /* table value too generous */ - span = 8 - n; - if (span > bits) /* constrain span to bit range */ - span = bits; - if (n + span < 8) /* doesn't extend to edge of byte */ - return (span); - bits -= span; - bp++; - } - else - span = 0; - if (bits >= (int32_t)(2 * 8 * sizeof(int64_t))) - { - int64_t *lp; - /* - * Align to int64_t boundary and check int64_t words. - */ - while (!isAligned(bp, int64_t)) - { - if (*bp != 0x00) - return (span + zeroruns[*bp]); - span += 8; - bits -= 8; - bp++; - } - lp = (int64_t *)bp; - while ((bits >= (int32_t)(8 * sizeof(int64_t))) && (0 == *lp)) - { - span += 8 * sizeof(int64_t); - bits -= 8 * sizeof(int64_t); - lp++; - } - bp = (unsigned char *)lp; - } - /* - * Scan full bytes for all 0's. - */ - while (bits >= 8) - { - if (*bp != 0x00) /* end of run */ - return (span + zeroruns[*bp]); - span += 8; - bits -= 8; - bp++; - } - /* - * Check partial byte on rhs. - */ - if (bits > 0) - { - n = zeroruns[*bp]; - span += (n > bits ? bits : n); - } - return (span); -} - -static inline int32_t find1span(unsigned char *bp, int32_t bs, int32_t be) -{ - int32_t bits = be - bs; - int32_t n, span; - - bp += bs >> 3; - /* - * Check partial byte on lhs. - */ - if (bits > 0 && (n = (bs & 7)) != 0) - { - span = oneruns[(*bp << n) & 0xff]; - if (span > 8 - n) /* table value too generous */ - span = 8 - n; - if (span > bits) /* constrain span to bit range */ - span = bits; - if (n + span < 8) /* doesn't extend to edge of byte */ - return (span); - bits -= span; - bp++; - } - else - span = 0; - if (bits >= (int32_t)(2 * 8 * sizeof(int64_t))) - { - int64_t *lp; - /* - * Align to int64_t boundary and check int64_t words. - */ - while (!isAligned(bp, int64_t)) - { - if (*bp != 0xff) - return (span + oneruns[*bp]); - span += 8; - bits -= 8; - bp++; - } - lp = (int64_t *)bp; - while ((bits >= (int32_t)(8 * sizeof(int64_t))) && - (~((uint64_t)0) == (uint64_t)*lp)) - { - span += 8 * sizeof(int64_t); - bits -= 8 * sizeof(int64_t); - lp++; - } - bp = (unsigned char *)lp; - } - /* - * Scan full bytes for all 1's. - */ - while (bits >= 8) - { - if (*bp != 0xff) /* end of run */ - return (span + oneruns[*bp]); - span += 8; - bits -= 8; - bp++; - } - /* - * Check partial byte on rhs. - */ - if (bits > 0) - { - n = oneruns[*bp]; - span += (n > bits ? bits : n); - } - return (span); -} - -/* - * Return the offset of the next bit in the range - * [bs..be] that is different from the specified - * color. The end, be, is returned if no such bit - * exists. - */ -#define finddiff(_cp, _bs, _be, _color) \ - (_bs + (_color ? find1span(_cp, _bs, _be) : find0span(_cp, _bs, _be))) -/* - * Like finddiff, but also check the starting bit - * against the end in case start > end. - */ -#define finddiff2(_cp, _bs, _be, _color) \ - (_bs < _be ? finddiff(_cp, _bs, _be, _color) : _be) - -/* - * 1d-encode a row of pixels. The encoding is - * a sequence of all-white or all-black spans - * of pixels encoded with Huffman codes. - */ -static int Fax3Encode1DRow(TIFF *tif, unsigned char *bp, uint32_t bits) -{ - Fax3CodecState *sp = EncoderState(tif); - int32_t span; - uint32_t bs = 0; - - for (;;) - { - span = find0span(bp, bs, bits); /* white span */ - if (!putspan(tif, span, TIFFFaxWhiteCodes)) - return 0; - bs += span; - if (bs >= bits) - break; - span = find1span(bp, bs, bits); /* black span */ - if (!putspan(tif, span, TIFFFaxBlackCodes)) - return 0; - bs += span; - if (bs >= bits) - break; - } - if (sp->b.mode & (FAXMODE_BYTEALIGN | FAXMODE_WORDALIGN)) - { - if (sp->bit != 8) /* byte-align */ - Fax3FlushBits(tif, sp); - if ((sp->b.mode & FAXMODE_WORDALIGN) && - !isAligned(tif->tif_rawcp, uint16_t)) - Fax3FlushBits(tif, sp); - } - return (1); -} - -static const tableentry horizcode = {3, 0x1, 0}; /* 001 */ -static const tableentry passcode = {4, 0x1, 0}; /* 0001 */ -static const tableentry vcodes[7] = { - {7, 0x03, 0}, /* 0000 011 */ - {6, 0x03, 0}, /* 0000 11 */ - {3, 0x03, 0}, /* 011 */ - {1, 0x1, 0}, /* 1 */ - {3, 0x2, 0}, /* 010 */ - {6, 0x02, 0}, /* 0000 10 */ - {7, 0x02, 0} /* 0000 010 */ -}; - -/* - * 2d-encode a row of pixels. Consult the CCITT - * documentation for the algorithm. - */ -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) - 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 a2, b2; - - for (;;) - { - b2 = finddiff2(rp, b1, bits, PIXEL(rp, b1)); - if (b2 >= a1) - { - /* Naive computation triggers - * -fsanitize=undefined,unsigned-integer-overflow */ - /* although it is correct unless the difference between both is < 31 - * bit */ - /* int32_t d = b1 - a1; */ - int32_t d = (b1 >= a1 && b1 - a1 <= 3U) ? (int32_t)(b1 - a1) - : (b1 < a1 && a1 - b1 <= 3U) ? -(int32_t)(a1 - b1) - : 0x7FFFFFFF; - if (!(-3 <= d && d <= 3)) - { /* horizontal mode */ - a2 = finddiff2(bp, a1, bits, PIXEL(bp, a1)); - if (!putcode(tif, &horizcode)) - return 0; - if (a0 + a1 == 0 || PIXEL(bp, a0) == 0) - { - if (!putspan(tif, a1 - a0, TIFFFaxWhiteCodes)) - return 0; - if (!putspan(tif, a2 - a1, TIFFFaxBlackCodes)) - return 0; - } - else - { - if (!putspan(tif, a1 - a0, TIFFFaxBlackCodes)) - return 0; - if (!putspan(tif, a2 - a1, TIFFFaxWhiteCodes)) - return 0; - } - a0 = a2; - } - else - { /* vertical mode */ - if (!putcode(tif, &vcodes[d + 3])) - return 0; - a0 = a1; - } - } - else - { /* pass mode */ - if (!putcode(tif, &passcode)) - return 0; - a0 = b2; - } - 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)); - } - return (1); -#undef PIXEL -} - -/* - * Encode a buffer of pixels. - */ -static int Fax3Encode(TIFF *tif, uint8_t *bp, tmsize_t cc, uint16_t s) -{ - static const char module[] = "Fax3Encode"; - Fax3CodecState *sp = EncoderState(tif); - (void)s; - if (cc % sp->b.rowbytes) - { - TIFFErrorExtR(tif, module, "Fractional scanlines cannot be written"); - return (0); - } - while (cc > 0) - { - if ((sp->b.mode & FAXMODE_NOEOL) == 0) - { - if (!Fax3PutEOL(tif)) - return 0; - } - if (is2DEncoding(sp)) - { - if (sp->tag == G3_1D) - { - if (!Fax3Encode1DRow(tif, bp, sp->b.rowpixels)) - return (0); - sp->tag = G3_2D; - } - else - { - if (!Fax3Encode2DRow(tif, bp, sp->refline, sp->b.rowpixels)) - return (0); - sp->k--; - } - if (sp->k == 0) - { - sp->tag = G3_1D; - sp->k = sp->maxk - 1; - } - else - _TIFFmemcpy(sp->refline, bp, sp->b.rowbytes); - } - else - { - if (!Fax3Encode1DRow(tif, bp, sp->b.rowpixels)) - return (0); - } - bp += sp->b.rowbytes; - cc -= sp->b.rowbytes; - } - return (1); -} - -static int Fax3PostEncode(TIFF *tif) -{ - Fax3CodecState *sp = EncoderState(tif); - - if (sp->bit != 8) - Fax3FlushBits(tif, sp); - return (1); -} - -static int _Fax3Close(TIFF *tif) -{ - if ((Fax3State(tif)->mode & FAXMODE_NORTC) == 0 && tif->tif_rawcp) - { - Fax3CodecState *sp = EncoderState(tif); - unsigned int code = EOL; - unsigned int length = 12; - int i; - - if (is2DEncoding(sp)) - { - code = (code << 1) | (sp->tag == G3_1D); - length++; - } - for (i = 0; i < 6; i++) - Fax3PutBits(tif, code, length); - Fax3FlushBits(tif, sp); - } - return 1; -} - -static void Fax3Close(TIFF *tif) { _Fax3Close(tif); } - -static void Fax3Cleanup(TIFF *tif) -{ - Fax3CodecState *sp = DecoderState(tif); - - assert(sp != 0); - - tif->tif_tagmethods.vgetfield = sp->b.vgetparent; - tif->tif_tagmethods.vsetfield = sp->b.vsetparent; - tif->tif_tagmethods.printdir = sp->b.printdir; - - if (sp->runs) - _TIFFfreeExt(tif, sp->runs); - if (sp->refline) - _TIFFfreeExt(tif, sp->refline); - - _TIFFfreeExt(tif, tif->tif_data); - tif->tif_data = NULL; - - _TIFFSetDefaultCompressionState(tif); -} - -#define FIELD_BADFAXLINES (FIELD_CODEC + 0) -#define FIELD_CLEANFAXDATA (FIELD_CODEC + 1) -#define FIELD_BADFAXRUN (FIELD_CODEC + 2) - -#define FIELD_OPTIONS (FIELD_CODEC + 7) - -static const TIFFField faxFields[] = { - {TIFFTAG_FAXMODE, 0, 0, TIFF_ANY, 0, TIFF_SETGET_INT, TIFF_SETGET_UNDEFINED, - FIELD_PSEUDO, FALSE, FALSE, "FaxMode", NULL}, - {TIFFTAG_FAXFILLFUNC, 0, 0, TIFF_ANY, 0, TIFF_SETGET_OTHER, - TIFF_SETGET_UNDEFINED, FIELD_PSEUDO, FALSE, FALSE, "FaxFillFunc", NULL}, - {TIFFTAG_BADFAXLINES, 1, 1, TIFF_LONG, 0, TIFF_SETGET_UINT32, - TIFF_SETGET_UINT32, FIELD_BADFAXLINES, TRUE, FALSE, "BadFaxLines", NULL}, - {TIFFTAG_CLEANFAXDATA, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, - TIFF_SETGET_UINT16, FIELD_CLEANFAXDATA, TRUE, FALSE, "CleanFaxData", NULL}, - {TIFFTAG_CONSECUTIVEBADFAXLINES, 1, 1, TIFF_LONG, 0, TIFF_SETGET_UINT32, - TIFF_SETGET_UINT32, FIELD_BADFAXRUN, TRUE, FALSE, "ConsecutiveBadFaxLines", - NULL}}; -static const TIFFField fax3Fields[] = { - {TIFFTAG_GROUP3OPTIONS, 1, 1, TIFF_LONG, 0, TIFF_SETGET_UINT32, - TIFF_SETGET_UINT32, FIELD_OPTIONS, FALSE, FALSE, "Group3Options", NULL}, -}; -static const TIFFField fax4Fields[] = { - {TIFFTAG_GROUP4OPTIONS, 1, 1, TIFF_LONG, 0, TIFF_SETGET_UINT32, - TIFF_SETGET_UINT32, FIELD_OPTIONS, FALSE, FALSE, "Group4Options", NULL}, -}; - -static int Fax3VSetField(TIFF *tif, uint32_t tag, va_list ap) -{ - Fax3BaseState *sp = Fax3State(tif); - const TIFFField *fip; - - assert(sp != 0); - assert(sp->vsetparent != 0); - - switch (tag) - { - case TIFFTAG_FAXMODE: - sp->mode = (int)va_arg(ap, int); - return 1; /* NB: pseudo tag */ - case TIFFTAG_FAXFILLFUNC: - DecoderState(tif)->fill = va_arg(ap, TIFFFaxFillFunc); - return 1; /* NB: pseudo tag */ - case TIFFTAG_GROUP3OPTIONS: - /* XXX: avoid reading options if compression mismatches. */ - if (tif->tif_dir.td_compression == COMPRESSION_CCITTFAX3) - sp->groupoptions = (uint32_t)va_arg(ap, uint32_t); - break; - case TIFFTAG_GROUP4OPTIONS: - /* XXX: avoid reading options if compression mismatches. */ - if (tif->tif_dir.td_compression == COMPRESSION_CCITTFAX4) - sp->groupoptions = (uint32_t)va_arg(ap, uint32_t); - break; - case TIFFTAG_BADFAXLINES: - sp->badfaxlines = (uint32_t)va_arg(ap, uint32_t); - break; - case TIFFTAG_CLEANFAXDATA: - sp->cleanfaxdata = (uint16_t)va_arg(ap, uint16_vap); - break; - case TIFFTAG_CONSECUTIVEBADFAXLINES: - sp->badfaxrun = (uint32_t)va_arg(ap, uint32_t); - break; - default: - return (*sp->vsetparent)(tif, tag, ap); - } - - if ((fip = TIFFFieldWithTag(tif, tag)) != NULL) - TIFFSetFieldBit(tif, fip->field_bit); - else - return 0; - - tif->tif_flags |= TIFF_DIRTYDIRECT; - return 1; -} - -static int Fax3VGetField(TIFF *tif, uint32_t tag, va_list ap) -{ - Fax3BaseState *sp = Fax3State(tif); - - assert(sp != 0); - - switch (tag) - { - case TIFFTAG_FAXMODE: - *va_arg(ap, int *) = sp->mode; - break; - case TIFFTAG_FAXFILLFUNC: - *va_arg(ap, TIFFFaxFillFunc *) = DecoderState(tif)->fill; - break; - case TIFFTAG_GROUP3OPTIONS: - case TIFFTAG_GROUP4OPTIONS: - *va_arg(ap, uint32_t *) = sp->groupoptions; - break; - case TIFFTAG_BADFAXLINES: - *va_arg(ap, uint32_t *) = sp->badfaxlines; - break; - case TIFFTAG_CLEANFAXDATA: - *va_arg(ap, uint16_t *) = sp->cleanfaxdata; - break; - case TIFFTAG_CONSECUTIVEBADFAXLINES: - *va_arg(ap, uint32_t *) = sp->badfaxrun; - break; - default: - return (*sp->vgetparent)(tif, tag, ap); - } - return (1); -} - -static void Fax3PrintDir(TIFF *tif, FILE *fd, long flags) -{ - Fax3BaseState *sp = Fax3State(tif); - - assert(sp != 0); - - (void)flags; - if (TIFFFieldSet(tif, FIELD_OPTIONS)) - { - const char *sep = " "; - if (tif->tif_dir.td_compression == COMPRESSION_CCITTFAX4) - { - fprintf(fd, " Group 4 Options:"); - if (sp->groupoptions & GROUP4OPT_UNCOMPRESSED) - fprintf(fd, "%suncompressed data", sep); - } - else - { - - fprintf(fd, " Group 3 Options:"); - if (sp->groupoptions & GROUP3OPT_2DENCODING) - { - fprintf(fd, "%s2-d encoding", sep); - sep = "+"; - } - if (sp->groupoptions & GROUP3OPT_FILLBITS) - { - fprintf(fd, "%sEOL padding", sep); - sep = "+"; - } - if (sp->groupoptions & GROUP3OPT_UNCOMPRESSED) - fprintf(fd, "%suncompressed data", sep); - } - fprintf(fd, " (%" PRIu32 " = 0x%" PRIx32 ")\n", sp->groupoptions, - sp->groupoptions); - } - if (TIFFFieldSet(tif, FIELD_CLEANFAXDATA)) - { - fprintf(fd, " Fax Data:"); - switch (sp->cleanfaxdata) - { - case CLEANFAXDATA_CLEAN: - fprintf(fd, " clean"); - break; - case CLEANFAXDATA_REGENERATED: - fprintf(fd, " receiver regenerated"); - break; - case CLEANFAXDATA_UNCLEAN: - fprintf(fd, " uncorrected errors"); - break; - } - fprintf(fd, " (%" PRIu16 " = 0x%" PRIx16 ")\n", sp->cleanfaxdata, - sp->cleanfaxdata); - } - if (TIFFFieldSet(tif, FIELD_BADFAXLINES)) - fprintf(fd, " Bad Fax Lines: %" PRIu32 "\n", sp->badfaxlines); - if (TIFFFieldSet(tif, FIELD_BADFAXRUN)) - fprintf(fd, " Consecutive Bad Fax Lines: %" PRIu32 "\n", - sp->badfaxrun); - if (sp->printdir) - (*sp->printdir)(tif, fd, flags); -} - -static int InitCCITTFax3(TIFF *tif) -{ - static const char module[] = "InitCCITTFax3"; - Fax3BaseState *sp; - - /* - * Merge codec-specific tag information. - */ - if (!_TIFFMergeFields(tif, faxFields, TIFFArrayCount(faxFields))) - { - TIFFErrorExtR(tif, "InitCCITTFax3", - "Merging common CCITT Fax codec-specific tags failed"); - return 0; - } - - /* - * Allocate state block so tag methods have storage to record values. - */ - tif->tif_data = (uint8_t *)_TIFFmallocExt(tif, sizeof(Fax3CodecState)); - - if (tif->tif_data == NULL) - { - TIFFErrorExtR(tif, module, "No space for state block"); - return (0); - } - _TIFFmemset(tif->tif_data, 0, sizeof(Fax3CodecState)); - - sp = Fax3State(tif); - sp->rw_mode = tif->tif_mode; - - /* - * Override parent get/set field methods. - */ - sp->vgetparent = tif->tif_tagmethods.vgetfield; - tif->tif_tagmethods.vgetfield = Fax3VGetField; /* hook for codec tags */ - sp->vsetparent = tif->tif_tagmethods.vsetfield; - tif->tif_tagmethods.vsetfield = Fax3VSetField; /* hook for codec tags */ - sp->printdir = tif->tif_tagmethods.printdir; - tif->tif_tagmethods.printdir = Fax3PrintDir; /* hook for codec tags */ - sp->groupoptions = 0; - - if (sp->rw_mode == O_RDONLY) /* FIXME: improve for in place update */ - tif->tif_flags |= TIFF_NOBITREV; /* decoder does bit reversal */ - DecoderState(tif)->runs = NULL; - TIFFSetField(tif, TIFFTAG_FAXFILLFUNC, _TIFFFax3fillruns); - EncoderState(tif)->refline = NULL; - - /* - * Install codec methods. - */ - tif->tif_fixuptags = Fax3FixupTags; - tif->tif_setupdecode = Fax3SetupState; - tif->tif_predecode = Fax3PreDecode; - tif->tif_decoderow = Fax3Decode1D; - tif->tif_decodestrip = Fax3Decode1D; - tif->tif_decodetile = Fax3Decode1D; - tif->tif_setupencode = Fax3SetupState; - tif->tif_preencode = Fax3PreEncode; - tif->tif_postencode = Fax3PostEncode; - tif->tif_encoderow = Fax3Encode; - tif->tif_encodestrip = Fax3Encode; - tif->tif_encodetile = Fax3Encode; - tif->tif_close = Fax3Close; - tif->tif_cleanup = Fax3Cleanup; - - return (1); -} - -int TIFFInitCCITTFax3(TIFF *tif, int scheme) -{ - (void)scheme; - if (InitCCITTFax3(tif)) - { - /* - * Merge codec-specific tag information. - */ - if (!_TIFFMergeFields(tif, fax3Fields, TIFFArrayCount(fax3Fields))) - { - TIFFErrorExtR(tif, "TIFFInitCCITTFax3", - "Merging CCITT Fax 3 codec-specific tags failed"); - return 0; - } - - /* - * The default format is Class/F-style w/o RTC. - */ - return TIFFSetField(tif, TIFFTAG_FAXMODE, FAXMODE_CLASSF); - } - else - return 01; -} - -/* - * CCITT Group 4 (T.6) Facsimile-compatible - * Compression Scheme Support. - */ - -#define SWAP(t, a, b) \ - { \ - t x; \ - x = (a); \ - (a) = (b); \ - (b) = x; \ - } -/* - * Decode the requested amount of G4-encoded data. - */ -static int Fax4Decode(TIFF *tif, uint8_t *buf, tmsize_t occ, uint16_t s) -{ - DECLARE_STATE_2D(tif, sp, "Fax4Decode"); - (void)s; - if (occ % sp->b.rowbytes) - { - TIFFErrorExtR(tif, module, "Fractional scanlines cannot be read"); - return (-1); - } - CACHE_STATE(tif, sp); - while (occ > 0) - { - a0 = 0; - RunLength = 0; - pa = thisrun = sp->curruns; - pb = sp->refruns; - b1 = *pb++; -#ifdef FAX3_DEBUG - printf("\nBitAcc=%08" PRIX32 ", BitsAvail = %d\n", BitAcc, BitsAvail); - printf("-------------------- %d\n", tif->tif_row); - fflush(stdout); -#endif - EXPAND2D(EOFG4); - if (EOLcnt) - goto EOFG4; - if (((lastx + 7) >> 3) > (int)occ) /* check for buffer overrun */ - { - TIFFErrorExtR(tif, module, - "Buffer overrun detected : %" TIFF_SSIZE_FORMAT - " bytes available, %d bits needed", - occ, lastx); - return -1; - } - (*sp->fill)(buf, thisrun, pa, lastx); - SETVALUE(0); /* imaginary change for reference */ - SWAP(uint32_t *, sp->curruns, sp->refruns); - buf += sp->b.rowbytes; - occ -= sp->b.rowbytes; - sp->line++; - continue; - EOFG4: - NeedBits16(13, BADG4); - BADG4: -#ifdef FAX3_DEBUG - if (GetBits(13) != 0x1001) - fputs("Bad EOFB\n", stderr); -#endif - ClrBits(13); - if (((lastx + 7) >> 3) > (int)occ) /* check for buffer overrun */ - { - TIFFErrorExtR(tif, module, - "Buffer overrun detected : %" TIFF_SSIZE_FORMAT - " bytes available, %d bits needed", - occ, lastx); - return -1; - } - (*sp->fill)(buf, thisrun, pa, lastx); - UNCACHE_STATE(tif, sp); - return (sp->line ? 1 : -1); /* don't error on badly-terminated strips */ - } - UNCACHE_STATE(tif, sp); - return (1); -} -#undef SWAP - -/* - * Encode the requested amount of data. - */ -static int Fax4Encode(TIFF *tif, uint8_t *bp, tmsize_t cc, uint16_t s) -{ - static const char module[] = "Fax4Encode"; - Fax3CodecState *sp = EncoderState(tif); - (void)s; - if (cc % sp->b.rowbytes) - { - TIFFErrorExtR(tif, module, "Fractional scanlines cannot be written"); - return (0); - } - while (cc > 0) - { - if (!Fax3Encode2DRow(tif, bp, sp->refline, sp->b.rowpixels)) - return (0); - _TIFFmemcpy(sp->refline, bp, sp->b.rowbytes); - bp += sp->b.rowbytes; - cc -= sp->b.rowbytes; - } - return (1); -} - -static int Fax4PostEncode(TIFF *tif) -{ - Fax3CodecState *sp = EncoderState(tif); - - /* terminate strip w/ EOFB */ - Fax3PutBits(tif, EOL, 12); - Fax3PutBits(tif, EOL, 12); - if (sp->bit != 8) - Fax3FlushBits(tif, sp); - return (1); -} - -int TIFFInitCCITTFax4(TIFF *tif, int scheme) -{ - (void)scheme; - if (InitCCITTFax3(tif)) - { /* reuse G3 support */ - /* - * Merge codec-specific tag information. - */ - if (!_TIFFMergeFields(tif, fax4Fields, TIFFArrayCount(fax4Fields))) - { - TIFFErrorExtR(tif, "TIFFInitCCITTFax4", - "Merging CCITT Fax 4 codec-specific tags failed"); - return 0; - } - - tif->tif_decoderow = Fax4Decode; - tif->tif_decodestrip = Fax4Decode; - tif->tif_decodetile = Fax4Decode; - tif->tif_encoderow = Fax4Encode; - tif->tif_encodestrip = Fax4Encode; - tif->tif_encodetile = Fax4Encode; - tif->tif_postencode = Fax4PostEncode; - /* - * Suppress RTC at the end of each strip. - */ - return TIFFSetField(tif, TIFFTAG_FAXMODE, FAXMODE_NORTC); - } - else - return (0); -} - -/* - * CCITT Group 3 1-D Modified Huffman RLE Compression Support. - * (Compression algorithms 2 and 32771) - */ - -/* - * Decode the requested amount of RLE-encoded data. - */ -static int Fax3DecodeRLE(TIFF *tif, uint8_t *buf, tmsize_t occ, uint16_t s) -{ - DECLARE_STATE(tif, sp, "Fax3DecodeRLE"); - int mode = sp->b.mode; - (void)s; - if (occ % sp->b.rowbytes) - { - TIFFErrorExtR(tif, module, "Fractional scanlines cannot be read"); - return (-1); - } - CACHE_STATE(tif, sp); - thisrun = sp->curruns; - while (occ > 0) - { - a0 = 0; - RunLength = 0; - pa = thisrun; -#ifdef FAX3_DEBUG - printf("\nBitAcc=%08" PRIX32 ", BitsAvail = %d\n", BitAcc, BitsAvail); - printf("-------------------- %" PRIu32 "\n", tif->tif_row); - fflush(stdout); -#endif - EXPAND1D(EOFRLE); - (*sp->fill)(buf, thisrun, pa, lastx); - /* - * Cleanup at the end of the row. - */ - if (mode & FAXMODE_BYTEALIGN) - { - int n = BitsAvail - (BitsAvail & ~7); - ClrBits(n); - } - else if (mode & FAXMODE_WORDALIGN) - { - int n = BitsAvail - (BitsAvail & ~15); - ClrBits(n); - if (BitsAvail == 0 && !isAligned(cp, uint16_t)) - cp++; - } - buf += sp->b.rowbytes; - occ -= sp->b.rowbytes; - sp->line++; - continue; - EOFRLE: /* premature EOF */ - (*sp->fill)(buf, thisrun, pa, lastx); - UNCACHE_STATE(tif, sp); - return (-1); - } - UNCACHE_STATE(tif, sp); - return (1); -} - -int TIFFInitCCITTRLE(TIFF *tif, int scheme) -{ - (void)scheme; - if (InitCCITTFax3(tif)) - { /* reuse G3 support */ - tif->tif_decoderow = Fax3DecodeRLE; - tif->tif_decodestrip = Fax3DecodeRLE; - tif->tif_decodetile = Fax3DecodeRLE; - /* - * Suppress RTC+EOLs when encoding and byte-align data. - */ - return TIFFSetField(tif, TIFFTAG_FAXMODE, - FAXMODE_NORTC | FAXMODE_NOEOL | FAXMODE_BYTEALIGN); - } - else - return (0); -} - -int TIFFInitCCITTRLEW(TIFF *tif, int scheme) -{ - (void)scheme; - if (InitCCITTFax3(tif)) - { /* reuse G3 support */ - tif->tif_decoderow = Fax3DecodeRLE; - tif->tif_decodestrip = Fax3DecodeRLE; - tif->tif_decodetile = Fax3DecodeRLE; - /* - * Suppress RTC+EOLs when encoding and word-align data. - */ - return TIFFSetField(tif, TIFFTAG_FAXMODE, - FAXMODE_NORTC | FAXMODE_NOEOL | FAXMODE_WORDALIGN); - } - else - return (0); -} -#endif /* CCITT_SUPPORT */ diff --git a/src/3rd/tiff/fax3.h b/src/3rd/tiff/fax3.h deleted file mode 100644 index e095009bba4..00000000000 --- a/src/3rd/tiff/fax3.h +++ /dev/null @@ -1,648 +0,0 @@ -/* - * Copyright (c) 1990-1997 Sam Leffler - * Copyright (c) 1991-1997 Silicon Graphics, Inc. - * - * Permission to use, copy, modify, distribute, and sell this software and - * its documentation for any purpose is hereby granted without fee, provided - * that (i) the above copyright notices and this permission notice appear in - * all copies of the software and related documentation, and (ii) the names of - * Sam Leffler and Silicon Graphics may not be used in any advertising or - * publicity relating to the software without the specific, prior written - * permission of Sam Leffler and Silicon Graphics. - * - * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, - * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY - * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. - * - * IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR - * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, - * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, - * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF - * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE - * OF THIS SOFTWARE. - */ - -#ifndef _FAX3_ -#define _FAX3_ -/* - * TIFF Library. - * - * CCITT Group 3 (T.4) and Group 4 (T.6) Decompression Support. - * - * Decoder support is derived, with permission, from the code - * in Frank Cringle's viewfax program; - * Copyright (C) 1990, 1995 Frank D. Cringle. - */ -#include "tiff.h" - -/* - * To override the default routine used to image decoded - * spans one can use the pseudo tag TIFFTAG_FAXFILLFUNC. - * The routine must have the type signature given below; - * for example: - * - * fillruns(unsigned char* buf, uint32_t* runs, uint32_t* erun, uint32_t lastx) - * - * where buf is place to set the bits, runs is the array of b&w run - * lengths (white then black), erun is the last run in the array, and - * lastx is the width of the row in pixels. Fill routines can assume - * the run array has room for at least lastx runs and can overwrite - * data in the run array as needed (e.g. to append zero runs to bring - * the count up to a nice multiple). - */ -typedef void (*TIFFFaxFillFunc)(unsigned char *, uint32_t *, uint32_t *, - uint32_t); - -/* - * The default run filler; made external for other decoders. - */ -#if defined(__cplusplus) -extern "C" -{ -#endif - extern void _TIFFFax3fillruns(unsigned char *, uint32_t *, uint32_t *, - uint32_t); -#if defined(__cplusplus) -} -#endif - -/* finite state machine codes */ -#define S_Null 0 -#define S_Pass 1 -#define S_Horiz 2 -#define S_V0 3 -#define S_VR 4 -#define S_VL 5 -#define S_Ext 6 -#define S_TermW 7 -#define S_TermB 8 -#define S_MakeUpW 9 -#define S_MakeUpB 10 -#define S_MakeUp 11 -#define S_EOL 12 - -/* WARNING: do not change the layout of this structure as the HylaFAX software - */ -/* really depends on it. See http://bugzilla.maptools.org/show_bug.cgi?id=2636 - */ -typedef struct -{ /* state table entry */ - unsigned char State; /* see above */ - unsigned char Width; /* width of code in bits */ - uint32_t Param; /* unsigned 32-bit run length in bits (holds on 16 bit - actually, but cannot be changed. See above warning) */ -} TIFFFaxTabEnt; - -extern const TIFFFaxTabEnt TIFFFaxMainTable[]; -extern const TIFFFaxTabEnt TIFFFaxWhiteTable[]; -extern const TIFFFaxTabEnt TIFFFaxBlackTable[]; - -/* - * The following macros define the majority of the G3/G4 decoder - * algorithm using the state tables defined elsewhere. To build - * a decoder you need some setup code and some glue code. Note - * that you may also need/want to change the way the NeedBits* - * macros get input data if, for example, you know the data to be - * decoded is properly aligned and oriented (doing so before running - * the decoder can be a big performance win). - * - * Consult the decoder in the TIFF library for an idea of what you - * need to define and setup to make use of these definitions. - * - * NB: to enable a debugging version of these macros define FAX3_DEBUG - * before including this file. Trace output goes to stdout. - */ - -#ifndef EndOfData -#define EndOfData() (cp >= ep) -#endif -/* - * Need <=8 or <=16 bits of input data. Unlike viewfax we - * cannot use/assume a word-aligned, properly bit swizzled - * input data set because data may come from an arbitrarily - * aligned, read-only source such as a memory-mapped file. - * Note also that the viewfax decoder does not check for - * running off the end of the input data buffer. This is - * possible for G3-encoded data because it prescans the input - * data to count EOL markers, but can cause problems for G4 - * data. In any event, we don't prescan and must watch for - * running out of data since we can't permit the library to - * scan past the end of the input data buffer. - * - * Finally, note that we must handle remaindered data at the end - * of a strip specially. The coder asks for a fixed number of - * bits when scanning for the next code. This may be more bits - * than are actually present in the data stream. If we appear - * to run out of data but still have some number of valid bits - * remaining then we makeup the requested amount with zeros and - * return successfully. If the returned data is incorrect then - * we should be called again and get a premature EOF error; - * otherwise we should get the right answer. - */ -#ifndef NeedBits8 -#define NeedBits8(n, eoflab) \ - do \ - { \ - if (BitsAvail < (n)) \ - { \ - if (EndOfData()) \ - { \ - if (BitsAvail == 0) /* no valid bits */ \ - goto eoflab; \ - BitsAvail = (n); /* pad with zeros */ \ - } \ - else \ - { \ - BitAcc |= ((uint32_t)bitmap[*cp++]) << BitsAvail; \ - BitsAvail += 8; \ - } \ - } \ - } while (0) -#endif -#ifndef NeedBits16 -#define NeedBits16(n, eoflab) \ - do \ - { \ - if (BitsAvail < (n)) \ - { \ - if (EndOfData()) \ - { \ - if (BitsAvail == 0) /* no valid bits */ \ - goto eoflab; \ - BitsAvail = (n); /* pad with zeros */ \ - } \ - else \ - { \ - BitAcc |= ((uint32_t)bitmap[*cp++]) << BitsAvail; \ - if ((BitsAvail += 8) < (n)) \ - { \ - if (EndOfData()) \ - { \ - /* NB: we know BitsAvail is non-zero here */ \ - BitsAvail = (n); /* pad with zeros */ \ - } \ - else \ - { \ - BitAcc |= ((uint32_t)bitmap[*cp++]) << BitsAvail; \ - BitsAvail += 8; \ - } \ - } \ - } \ - } \ - } while (0) -#endif -#define GetBits(n) (BitAcc & ((1 << (n)) - 1)) -#define ClrBits(n) \ - do \ - { \ - BitsAvail -= (n); \ - BitAcc >>= (n); \ - } while (0) - -#ifdef FAX3_DEBUG -static const char *StateNames[] = { - "Null ", "Pass ", "Horiz ", "V0 ", "VR ", "VL ", "Ext ", - "TermW ", "TermB ", "MakeUpW", "MakeUpB", "MakeUp ", "EOL ", -}; -#define DEBUG_SHOW putchar(BitAcc & (1 << t) ? '1' : '0') -#define LOOKUP8(wid, tab, eoflab) \ - do \ - { \ - int t; \ - NeedBits8(wid, eoflab); \ - TabEnt = tab + GetBits(wid); \ - printf("%08lX/%d: %s%5d\t", (long)BitAcc, BitsAvail, \ - StateNames[TabEnt->State], TabEnt->Param); \ - for (t = 0; t < TabEnt->Width; t++) \ - DEBUG_SHOW; \ - putchar('\n'); \ - fflush(stdout); \ - ClrBits(TabEnt->Width); \ - } while (0) -#define LOOKUP16(wid, tab, eoflab) \ - do \ - { \ - int t; \ - NeedBits16(wid, eoflab); \ - TabEnt = tab + GetBits(wid); \ - printf("%08lX/%d: %s%5d\t", (long)BitAcc, BitsAvail, \ - StateNames[TabEnt->State], TabEnt->Param); \ - for (t = 0; t < TabEnt->Width; t++) \ - DEBUG_SHOW; \ - putchar('\n'); \ - fflush(stdout); \ - ClrBits(TabEnt->Width); \ - } while (0) - -#define SETVALUE(x) \ - do \ - { \ - *pa++ = RunLength + (x); \ - printf("SETVALUE: %d\t%d\n", RunLength + (x), a0); \ - a0 += x; \ - RunLength = 0; \ - } while (0) -#else -#define LOOKUP8(wid, tab, eoflab) \ - do \ - { \ - NeedBits8(wid, eoflab); \ - TabEnt = tab + GetBits(wid); \ - ClrBits(TabEnt->Width); \ - } while (0) -#define LOOKUP16(wid, tab, eoflab) \ - do \ - { \ - NeedBits16(wid, eoflab); \ - TabEnt = tab + GetBits(wid); \ - ClrBits(TabEnt->Width); \ - } while (0) - -/* - * Append a run to the run length array for the - * current row and reset decoding state. - */ -#define SETVALUE(x) \ - do \ - { \ - 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); \ - return (-1); \ - } \ - *pa++ = RunLength + (x); \ - a0 += (x); \ - RunLength = 0; \ - } while (0) -#endif - -/* - * Synchronize input decoding at the start of each - * row by scanning for an EOL (if appropriate) and - * skipping any trash data that might be present - * after a decoding error. Note that the decoding - * done elsewhere that recognizes an EOL only consumes - * 11 consecutive zero bits. This means that if EOLcnt - * is non-zero then we still need to scan for the final flag - * bit that is part of the EOL code. - */ -#define SYNC_EOL(eoflab) \ - do \ - { \ - if (EOLcnt == 0) \ - { \ - for (;;) \ - { \ - NeedBits16(11, eoflab); \ - if (GetBits(11) == 0) \ - break; \ - ClrBits(1); \ - } \ - } \ - for (;;) \ - { \ - NeedBits8(8, eoflab); \ - if (GetBits(8)) \ - break; \ - ClrBits(8); \ - } \ - while (GetBits(1) == 0) \ - ClrBits(1); \ - ClrBits(1); /* EOL bit */ \ - EOLcnt = 0; /* reset EOL counter/flag */ \ - } while (0) - -/* - * Cleanup the array of runs after decoding a row. - * We adjust final runs to insure the user buffer is not - * overwritten and/or undecoded area is white filled. - */ -#define CLEANUP_RUNS() \ - do \ - { \ - if (RunLength) \ - SETVALUE(0); \ - if (a0 != lastx) \ - { \ - badlength(a0, lastx); \ - while (a0 > lastx && pa > thisrun) \ - a0 -= *--pa; \ - if (a0 < lastx) \ - { \ - if (a0 < 0) \ - a0 = 0; \ - if ((pa - thisrun) & 1) \ - SETVALUE(0); \ - SETVALUE(lastx - a0); \ - } \ - else if (a0 > lastx) \ - { \ - SETVALUE(lastx); \ - SETVALUE(0); \ - } \ - } \ - } while (0) - -/* - * Decode a line of 1D-encoded data. - * - * The line expanders are written as macros so that they can be reused - * but still have direct access to the local variables of the "calling" - * function. - * - * Note that unlike the original version we have to explicitly test for - * a0 >= lastx after each black/white run is decoded. This is because - * the original code depended on the input data being zero-padded to - * insure the decoder recognized an EOL before running out of data. - */ -#define EXPAND1D(eoflab) \ - do \ - { \ - for (;;) \ - { \ - for (;;) \ - { \ - LOOKUP16(12, TIFFFaxWhiteTable, eof1d); \ - switch (TabEnt->State) \ - { \ - case S_EOL: \ - EOLcnt = 1; \ - goto done1d; \ - case S_TermW: \ - SETVALUE(TabEnt->Param); \ - goto doneWhite1d; \ - case S_MakeUpW: \ - case S_MakeUp: \ - a0 += TabEnt->Param; \ - RunLength += TabEnt->Param; \ - break; \ - default: \ - unexpected("WhiteTable", a0); \ - goto done1d; \ - } \ - } \ - doneWhite1d: \ - if (a0 >= lastx) \ - goto done1d; \ - for (;;) \ - { \ - LOOKUP16(13, TIFFFaxBlackTable, eof1d); \ - switch (TabEnt->State) \ - { \ - case S_EOL: \ - EOLcnt = 1; \ - goto done1d; \ - case S_TermB: \ - SETVALUE(TabEnt->Param); \ - goto doneBlack1d; \ - case S_MakeUpB: \ - case S_MakeUp: \ - a0 += TabEnt->Param; \ - RunLength += TabEnt->Param; \ - break; \ - default: \ - unexpected("BlackTable", a0); \ - goto done1d; \ - } \ - } \ - doneBlack1d: \ - if (a0 >= lastx) \ - goto done1d; \ - if (*(pa - 1) == 0 && *(pa - 2) == 0) \ - pa -= 2; \ - } \ - eof1d: \ - prematureEOF(a0); \ - CLEANUP_RUNS(); \ - goto eoflab; \ - done1d: \ - CLEANUP_RUNS(); \ - } while (0) - -/* - * Update the value of b1 using the array - * of runs for the reference line. - */ -#define CHECK_b1 \ - do \ - { \ - if (pa != thisrun) \ - while (b1 <= a0 && b1 < 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); \ - return (-1); \ - } \ - b1 += pb[0] + pb[1]; \ - pb += 2; \ - } \ - } while (0) - -/* - * Expand a row of 2D-encoded data. - */ -#define EXPAND2D(eoflab) \ - do \ - { \ - while (a0 < 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); \ - return (-1); \ - } \ - LOOKUP8(7, TIFFFaxMainTable, eof2d); \ - switch (TabEnt->State) \ - { \ - case S_Pass: \ - 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); \ - return (-1); \ - } \ - b1 += *pb++; \ - RunLength += b1 - a0; \ - a0 = b1; \ - b1 += *pb++; \ - break; \ - case S_Horiz: \ - if ((pa - thisrun) & 1) \ - { \ - for (;;) \ - { /* black first */ \ - LOOKUP16(13, TIFFFaxBlackTable, eof2d); \ - switch (TabEnt->State) \ - { \ - case S_TermB: \ - SETVALUE(TabEnt->Param); \ - goto doneWhite2da; \ - case S_MakeUpB: \ - case S_MakeUp: \ - a0 += TabEnt->Param; \ - RunLength += TabEnt->Param; \ - break; \ - default: \ - goto badBlack2d; \ - } \ - } \ - doneWhite2da:; \ - for (;;) \ - { /* then white */ \ - LOOKUP16(12, TIFFFaxWhiteTable, eof2d); \ - switch (TabEnt->State) \ - { \ - case S_TermW: \ - SETVALUE(TabEnt->Param); \ - goto doneBlack2da; \ - case S_MakeUpW: \ - case S_MakeUp: \ - a0 += TabEnt->Param; \ - RunLength += TabEnt->Param; \ - break; \ - default: \ - goto badWhite2d; \ - } \ - } \ - doneBlack2da:; \ - } \ - else \ - { \ - for (;;) \ - { /* white first */ \ - LOOKUP16(12, TIFFFaxWhiteTable, eof2d); \ - switch (TabEnt->State) \ - { \ - case S_TermW: \ - SETVALUE(TabEnt->Param); \ - goto doneWhite2db; \ - case S_MakeUpW: \ - case S_MakeUp: \ - a0 += TabEnt->Param; \ - RunLength += TabEnt->Param; \ - break; \ - default: \ - goto badWhite2d; \ - } \ - } \ - doneWhite2db:; \ - for (;;) \ - { /* then black */ \ - LOOKUP16(13, TIFFFaxBlackTable, eof2d); \ - switch (TabEnt->State) \ - { \ - case S_TermB: \ - SETVALUE(TabEnt->Param); \ - goto doneBlack2db; \ - case S_MakeUpB: \ - case S_MakeUp: \ - a0 += TabEnt->Param; \ - RunLength += TabEnt->Param; \ - break; \ - default: \ - goto badBlack2d; \ - } \ - } \ - doneBlack2db:; \ - } \ - CHECK_b1; \ - break; \ - case S_V0: \ - CHECK_b1; \ - 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); \ - return (-1); \ - } \ - b1 += *pb++; \ - break; \ - case S_VR: \ - CHECK_b1; \ - SETVALUE(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); \ - return (-1); \ - } \ - b1 += *pb++; \ - break; \ - case S_VL: \ - CHECK_b1; \ - if (b1 < (int)(a0 + TabEnt->Param)) \ - { \ - unexpected("VL", a0); \ - goto eol2d; \ - } \ - SETVALUE(b1 - a0 - TabEnt->Param); \ - b1 -= *--pb; \ - break; \ - case S_Ext: \ - *pa++ = lastx - a0; \ - extension(a0); \ - goto eol2d; \ - case S_EOL: \ - *pa++ = lastx - a0; \ - NeedBits8(4, eof2d); \ - if (GetBits(4)) \ - unexpected("EOL", a0); \ - ClrBits(4); \ - EOLcnt = 1; \ - goto eol2d; \ - default: \ - badMain2d: \ - unexpected("MainTable", a0); \ - goto eol2d; \ - badBlack2d: \ - unexpected("BlackTable", a0); \ - goto eol2d; \ - badWhite2d: \ - unexpected("WhiteTable", a0); \ - goto eol2d; \ - eof2d: \ - prematureEOF(a0); \ - CLEANUP_RUNS(); \ - goto eoflab; \ - } \ - } \ - if (RunLength) \ - { \ - if (RunLength + a0 < lastx) \ - { \ - /* expect a final V0 */ \ - NeedBits8(1, eof2d); \ - if (!GetBits(1)) \ - goto badMain2d; \ - ClrBits(1); \ - } \ - SETVALUE(0); \ - } \ - eol2d: \ - CLEANUP_RUNS(); \ - } while (0) -#endif /* _FAX3_ */ diff --git a/src/3rd/tiff/fax3sm.c b/src/3rd/tiff/fax3sm.c deleted file mode 100644 index 1f2cddc6536..00000000000 --- a/src/3rd/tiff/fax3sm.c +++ /dev/null @@ -1,1261 +0,0 @@ -/* WARNING, this file was automatically generated by the - mkg3states program */ -#include -#include "tiff.h" -#include "fax3.h" - const TIFFFaxTabEnt TIFFFaxMainTable[128] = { -{12,7,0},{3,1,0},{5,3,1},{3,1,0},{2,3,0},{3,1,0},{4,3,1},{3,1,0},{1,4,0},{3,1,0}, -{5,3,1},{3,1,0},{2,3,0},{3,1,0},{4,3,1},{3,1,0},{5,6,2},{3,1,0},{5,3,1},{3,1,0}, -{2,3,0},{3,1,0},{4,3,1},{3,1,0},{1,4,0},{3,1,0},{5,3,1},{3,1,0},{2,3,0},{3,1,0}, -{4,3,1},{3,1,0},{5,7,3},{3,1,0},{5,3,1},{3,1,0},{2,3,0},{3,1,0},{4,3,1},{3,1,0}, -{1,4,0},{3,1,0},{5,3,1},{3,1,0},{2,3,0},{3,1,0},{4,3,1},{3,1,0},{4,6,2},{3,1,0}, -{5,3,1},{3,1,0},{2,3,0},{3,1,0},{4,3,1},{3,1,0},{1,4,0},{3,1,0},{5,3,1},{3,1,0}, -{2,3,0},{3,1,0},{4,3,1},{3,1,0},{6,7,0},{3,1,0},{5,3,1},{3,1,0},{2,3,0},{3,1,0}, -{4,3,1},{3,1,0},{1,4,0},{3,1,0},{5,3,1},{3,1,0},{2,3,0},{3,1,0},{4,3,1},{3,1,0}, -{5,6,2},{3,1,0},{5,3,1},{3,1,0},{2,3,0},{3,1,0},{4,3,1},{3,1,0},{1,4,0},{3,1,0}, -{5,3,1},{3,1,0},{2,3,0},{3,1,0},{4,3,1},{3,1,0},{4,7,3},{3,1,0},{5,3,1},{3,1,0}, -{2,3,0},{3,1,0},{4,3,1},{3,1,0},{1,4,0},{3,1,0},{5,3,1},{3,1,0},{2,3,0},{3,1,0}, -{4,3,1},{3,1,0},{4,6,2},{3,1,0},{5,3,1},{3,1,0},{2,3,0},{3,1,0},{4,3,1},{3,1,0}, -{1,4,0},{3,1,0},{5,3,1},{3,1,0},{2,3,0},{3,1,0},{4,3,1},{3,1,0} -}; - const TIFFFaxTabEnt TIFFFaxWhiteTable[4096] = { -{12,11,0},{7,4,3},{7,5,11},{7,4,5},{7,6,12},{7,5,9},{9,6,1664},{7,4,6},{7,7,20},{9,5,128}, -{7,7,24},{7,6,14},{7,7,28},{7,4,4},{7,4,2},{7,4,7},{7,7,23},{7,4,3},{7,7,27},{7,4,5}, -{7,8,39},{7,6,16},{9,8,576},{7,4,6},{7,7,19},{7,5,8},{7,8,55},{9,5,64},{7,5,10},{7,4,4}, -{7,4,2},{7,4,7},{7,8,45},{7,4,3},{7,5,11},{7,4,5},{7,8,53},{7,5,9},{9,8,448},{7,4,6}, -{7,8,35},{9,5,128},{7,8,51},{7,6,15},{7,8,63},{7,4,4},{7,4,2},{7,4,7},{7,6,13},{7,4,3}, -{9,9,1472},{7,4,5},{7,8,43},{7,6,17},{9,9,1216},{7,4,6},{7,6,1},{7,5,8},{9,6,192},{9,5,64}, -{7,5,10},{7,4,4},{7,4,2},{7,4,7},{7,8,29},{7,4,3},{7,5,11},{7,4,5},{7,6,12},{7,5,9}, -{9,6,1664},{7,4,6},{7,8,33},{9,5,128},{7,8,49},{7,6,14},{7,8,61},{7,4,4},{7,4,2},{7,4,7}, -{7,8,47},{7,4,3},{7,8,59},{7,4,5},{7,8,41},{7,6,16},{9,9,960},{7,4,6},{7,8,31},{7,5,8}, -{7,8,57},{9,5,64},{7,5,10},{7,4,4},{7,4,2},{7,4,7},{7,7,22},{7,4,3},{7,5,11},{7,4,5}, -{7,7,26},{7,5,9},{9,9,704},{7,4,6},{7,8,37},{9,5,128},{7,7,25},{7,6,15},{9,8,320},{7,4,4}, -{7,4,2},{7,4,7},{7,6,13},{7,4,3},{7,7,18},{7,4,5},{7,7,21},{7,6,17},{9,7,256},{7,4,6}, -{7,6,1},{7,5,8},{9,6,192},{9,5,64},{7,5,10},{7,4,4},{7,4,2},{7,4,7},{11,11,1792},{7,4,3}, -{7,5,11},{7,4,5},{7,6,12},{7,5,9},{9,6,1664},{7,4,6},{7,7,20},{9,5,128},{7,7,24},{7,6,14}, -{7,7,28},{7,4,4},{7,4,2},{7,4,7},{7,7,23},{7,4,3},{7,7,27},{7,4,5},{7,8,40},{7,6,16}, -{9,9,832},{7,4,6},{7,7,19},{7,5,8},{7,8,56},{9,5,64},{7,5,10},{7,4,4},{7,4,2},{7,4,7}, -{7,8,46},{7,4,3},{7,5,11},{7,4,5},{7,8,54},{7,5,9},{9,8,512},{7,4,6},{7,8,36},{9,5,128}, -{7,8,52},{7,6,15},{7,8,0},{7,4,4},{7,4,2},{7,4,7},{7,6,13},{7,4,3},{9,9,1600},{7,4,5}, -{7,8,44},{7,6,17},{9,9,1344},{7,4,6},{7,6,1},{7,5,8},{9,6,192},{9,5,64},{7,5,10},{7,4,4}, -{7,4,2},{7,4,7},{7,8,30},{7,4,3},{7,5,11},{7,4,5},{7,6,12},{7,5,9},{9,6,1664},{7,4,6}, -{7,8,34},{9,5,128},{7,8,50},{7,6,14},{7,8,62},{7,4,4},{7,4,2},{7,4,7},{7,8,48},{7,4,3}, -{7,8,60},{7,4,5},{7,8,42},{7,6,16},{9,9,1088},{7,4,6},{7,8,32},{7,5,8},{7,8,58},{9,5,64}, -{7,5,10},{7,4,4},{7,4,2},{7,4,7},{7,7,22},{7,4,3},{7,5,11},{7,4,5},{7,7,26},{7,5,9}, -{9,8,640},{7,4,6},{7,8,38},{9,5,128},{7,7,25},{7,6,15},{9,8,384},{7,4,4},{7,4,2},{7,4,7}, -{7,6,13},{7,4,3},{7,7,18},{7,4,5},{7,7,21},{7,6,17},{9,7,256},{7,4,6},{7,6,1},{7,5,8}, -{9,6,192},{9,5,64},{7,5,10},{7,4,4},{7,4,2},{7,4,7},{0,0,0},{7,4,3},{7,5,11},{7,4,5}, -{7,6,12},{7,5,9},{9,6,1664},{7,4,6},{7,7,20},{9,5,128},{7,7,24},{7,6,14},{7,7,28},{7,4,4}, -{7,4,2},{7,4,7},{7,7,23},{7,4,3},{7,7,27},{7,4,5},{7,8,39},{7,6,16},{9,8,576},{7,4,6}, -{7,7,19},{7,5,8},{7,8,55},{9,5,64},{7,5,10},{7,4,4},{7,4,2},{7,4,7},{7,8,45},{7,4,3}, -{7,5,11},{7,4,5},{7,8,53},{7,5,9},{9,8,448},{7,4,6},{7,8,35},{9,5,128},{7,8,51},{7,6,15}, -{7,8,63},{7,4,4},{7,4,2},{7,4,7},{7,6,13},{7,4,3},{9,9,1536},{7,4,5},{7,8,43},{7,6,17}, -{9,9,1280},{7,4,6},{7,6,1},{7,5,8},{9,6,192},{9,5,64},{7,5,10},{7,4,4},{7,4,2},{7,4,7}, -{7,8,29},{7,4,3},{7,5,11},{7,4,5},{7,6,12},{7,5,9},{9,6,1664},{7,4,6},{7,8,33},{9,5,128}, -{7,8,49},{7,6,14},{7,8,61},{7,4,4},{7,4,2},{7,4,7},{7,8,47},{7,4,3},{7,8,59},{7,4,5}, -{7,8,41},{7,6,16},{9,9,1024},{7,4,6},{7,8,31},{7,5,8},{7,8,57},{9,5,64},{7,5,10},{7,4,4}, -{7,4,2},{7,4,7},{7,7,22},{7,4,3},{7,5,11},{7,4,5},{7,7,26},{7,5,9},{9,9,768},{7,4,6}, -{7,8,37},{9,5,128},{7,7,25},{7,6,15},{9,8,320},{7,4,4},{7,4,2},{7,4,7},{7,6,13},{7,4,3}, -{7,7,18},{7,4,5},{7,7,21},{7,6,17},{9,7,256},{7,4,6},{7,6,1},{7,5,8},{9,6,192},{9,5,64}, -{7,5,10},{7,4,4},{7,4,2},{7,4,7},{11,11,1856},{7,4,3},{7,5,11},{7,4,5},{7,6,12},{7,5,9}, -{9,6,1664},{7,4,6},{7,7,20},{9,5,128},{7,7,24},{7,6,14},{7,7,28},{7,4,4},{7,4,2},{7,4,7}, -{7,7,23},{7,4,3},{7,7,27},{7,4,5},{7,8,40},{7,6,16},{9,9,896},{7,4,6},{7,7,19},{7,5,8}, -{7,8,56},{9,5,64},{7,5,10},{7,4,4},{7,4,2},{7,4,7},{7,8,46},{7,4,3},{7,5,11},{7,4,5}, -{7,8,54},{7,5,9},{9,8,512},{7,4,6},{7,8,36},{9,5,128},{7,8,52},{7,6,15},{7,8,0},{7,4,4}, -{7,4,2},{7,4,7},{7,6,13},{7,4,3},{9,9,1728},{7,4,5},{7,8,44},{7,6,17},{9,9,1408},{7,4,6}, -{7,6,1},{7,5,8},{9,6,192},{9,5,64},{7,5,10},{7,4,4},{7,4,2},{7,4,7},{7,8,30},{7,4,3}, -{7,5,11},{7,4,5},{7,6,12},{7,5,9},{9,6,1664},{7,4,6},{7,8,34},{9,5,128},{7,8,50},{7,6,14}, -{7,8,62},{7,4,4},{7,4,2},{7,4,7},{7,8,48},{7,4,3},{7,8,60},{7,4,5},{7,8,42},{7,6,16}, -{9,9,1152},{7,4,6},{7,8,32},{7,5,8},{7,8,58},{9,5,64},{7,5,10},{7,4,4},{7,4,2},{7,4,7}, -{7,7,22},{7,4,3},{7,5,11},{7,4,5},{7,7,26},{7,5,9},{9,8,640},{7,4,6},{7,8,38},{9,5,128}, -{7,7,25},{7,6,15},{9,8,384},{7,4,4},{7,4,2},{7,4,7},{7,6,13},{7,4,3},{7,7,18},{7,4,5}, -{7,7,21},{7,6,17},{9,7,256},{7,4,6},{7,6,1},{7,5,8},{9,6,192},{9,5,64},{7,5,10},{7,4,4}, -{7,4,2},{7,4,7},{0,0,0},{7,4,3},{7,5,11},{7,4,5},{7,6,12},{7,5,9},{9,6,1664},{7,4,6}, -{7,7,20},{9,5,128},{7,7,24},{7,6,14},{7,7,28},{7,4,4},{7,4,2},{7,4,7},{7,7,23},{7,4,3}, -{7,7,27},{7,4,5},{7,8,39},{7,6,16},{9,8,576},{7,4,6},{7,7,19},{7,5,8},{7,8,55},{9,5,64}, -{7,5,10},{7,4,4},{7,4,2},{7,4,7},{7,8,45},{7,4,3},{7,5,11},{7,4,5},{7,8,53},{7,5,9}, -{9,8,448},{7,4,6},{7,8,35},{9,5,128},{7,8,51},{7,6,15},{7,8,63},{7,4,4},{7,4,2},{7,4,7}, -{7,6,13},{7,4,3},{9,9,1472},{7,4,5},{7,8,43},{7,6,17},{9,9,1216},{7,4,6},{7,6,1},{7,5,8}, -{9,6,192},{9,5,64},{7,5,10},{7,4,4},{7,4,2},{7,4,7},{7,8,29},{7,4,3},{7,5,11},{7,4,5}, -{7,6,12},{7,5,9},{9,6,1664},{7,4,6},{7,8,33},{9,5,128},{7,8,49},{7,6,14},{7,8,61},{7,4,4}, -{7,4,2},{7,4,7},{7,8,47},{7,4,3},{7,8,59},{7,4,5},{7,8,41},{7,6,16},{9,9,960},{7,4,6}, -{7,8,31},{7,5,8},{7,8,57},{9,5,64},{7,5,10},{7,4,4},{7,4,2},{7,4,7},{7,7,22},{7,4,3}, -{7,5,11},{7,4,5},{7,7,26},{7,5,9},{9,9,704},{7,4,6},{7,8,37},{9,5,128},{7,7,25},{7,6,15}, -{9,8,320},{7,4,4},{7,4,2},{7,4,7},{7,6,13},{7,4,3},{7,7,18},{7,4,5},{7,7,21},{7,6,17}, -{9,7,256},{7,4,6},{7,6,1},{7,5,8},{9,6,192},{9,5,64},{7,5,10},{7,4,4},{7,4,2},{7,4,7}, -{11,12,2112},{7,4,3},{7,5,11},{7,4,5},{7,6,12},{7,5,9},{9,6,1664},{7,4,6},{7,7,20},{9,5,128}, -{7,7,24},{7,6,14},{7,7,28},{7,4,4},{7,4,2},{7,4,7},{7,7,23},{7,4,3},{7,7,27},{7,4,5}, -{7,8,40},{7,6,16},{9,9,832},{7,4,6},{7,7,19},{7,5,8},{7,8,56},{9,5,64},{7,5,10},{7,4,4}, -{7,4,2},{7,4,7},{7,8,46},{7,4,3},{7,5,11},{7,4,5},{7,8,54},{7,5,9},{9,8,512},{7,4,6}, -{7,8,36},{9,5,128},{7,8,52},{7,6,15},{7,8,0},{7,4,4},{7,4,2},{7,4,7},{7,6,13},{7,4,3}, -{9,9,1600},{7,4,5},{7,8,44},{7,6,17},{9,9,1344},{7,4,6},{7,6,1},{7,5,8},{9,6,192},{9,5,64}, -{7,5,10},{7,4,4},{7,4,2},{7,4,7},{7,8,30},{7,4,3},{7,5,11},{7,4,5},{7,6,12},{7,5,9}, -{9,6,1664},{7,4,6},{7,8,34},{9,5,128},{7,8,50},{7,6,14},{7,8,62},{7,4,4},{7,4,2},{7,4,7}, -{7,8,48},{7,4,3},{7,8,60},{7,4,5},{7,8,42},{7,6,16},{9,9,1088},{7,4,6},{7,8,32},{7,5,8}, -{7,8,58},{9,5,64},{7,5,10},{7,4,4},{7,4,2},{7,4,7},{7,7,22},{7,4,3},{7,5,11},{7,4,5}, -{7,7,26},{7,5,9},{9,8,640},{7,4,6},{7,8,38},{9,5,128},{7,7,25},{7,6,15},{9,8,384},{7,4,4}, -{7,4,2},{7,4,7},{7,6,13},{7,4,3},{7,7,18},{7,4,5},{7,7,21},{7,6,17},{9,7,256},{7,4,6}, -{7,6,1},{7,5,8},{9,6,192},{9,5,64},{7,5,10},{7,4,4},{7,4,2},{7,4,7},{0,0,0},{7,4,3}, -{7,5,11},{7,4,5},{7,6,12},{7,5,9},{9,6,1664},{7,4,6},{7,7,20},{9,5,128},{7,7,24},{7,6,14}, -{7,7,28},{7,4,4},{7,4,2},{7,4,7},{7,7,23},{7,4,3},{7,7,27},{7,4,5},{7,8,39},{7,6,16}, -{9,8,576},{7,4,6},{7,7,19},{7,5,8},{7,8,55},{9,5,64},{7,5,10},{7,4,4},{7,4,2},{7,4,7}, -{7,8,45},{7,4,3},{7,5,11},{7,4,5},{7,8,53},{7,5,9},{9,8,448},{7,4,6},{7,8,35},{9,5,128}, -{7,8,51},{7,6,15},{7,8,63},{7,4,4},{7,4,2},{7,4,7},{7,6,13},{7,4,3},{9,9,1536},{7,4,5}, -{7,8,43},{7,6,17},{9,9,1280},{7,4,6},{7,6,1},{7,5,8},{9,6,192},{9,5,64},{7,5,10},{7,4,4}, -{7,4,2},{7,4,7},{7,8,29},{7,4,3},{7,5,11},{7,4,5},{7,6,12},{7,5,9},{9,6,1664},{7,4,6}, -{7,8,33},{9,5,128},{7,8,49},{7,6,14},{7,8,61},{7,4,4},{7,4,2},{7,4,7},{7,8,47},{7,4,3}, -{7,8,59},{7,4,5},{7,8,41},{7,6,16},{9,9,1024},{7,4,6},{7,8,31},{7,5,8},{7,8,57},{9,5,64}, -{7,5,10},{7,4,4},{7,4,2},{7,4,7},{7,7,22},{7,4,3},{7,5,11},{7,4,5},{7,7,26},{7,5,9}, -{9,9,768},{7,4,6},{7,8,37},{9,5,128},{7,7,25},{7,6,15},{9,8,320},{7,4,4},{7,4,2},{7,4,7}, -{7,6,13},{7,4,3},{7,7,18},{7,4,5},{7,7,21},{7,6,17},{9,7,256},{7,4,6},{7,6,1},{7,5,8}, -{9,6,192},{9,5,64},{7,5,10},{7,4,4},{7,4,2},{7,4,7},{11,12,2368},{7,4,3},{7,5,11},{7,4,5}, -{7,6,12},{7,5,9},{9,6,1664},{7,4,6},{7,7,20},{9,5,128},{7,7,24},{7,6,14},{7,7,28},{7,4,4}, -{7,4,2},{7,4,7},{7,7,23},{7,4,3},{7,7,27},{7,4,5},{7,8,40},{7,6,16},{9,9,896},{7,4,6}, -{7,7,19},{7,5,8},{7,8,56},{9,5,64},{7,5,10},{7,4,4},{7,4,2},{7,4,7},{7,8,46},{7,4,3}, -{7,5,11},{7,4,5},{7,8,54},{7,5,9},{9,8,512},{7,4,6},{7,8,36},{9,5,128},{7,8,52},{7,6,15}, -{7,8,0},{7,4,4},{7,4,2},{7,4,7},{7,6,13},{7,4,3},{9,9,1728},{7,4,5},{7,8,44},{7,6,17}, -{9,9,1408},{7,4,6},{7,6,1},{7,5,8},{9,6,192},{9,5,64},{7,5,10},{7,4,4},{7,4,2},{7,4,7}, -{7,8,30},{7,4,3},{7,5,11},{7,4,5},{7,6,12},{7,5,9},{9,6,1664},{7,4,6},{7,8,34},{9,5,128}, -{7,8,50},{7,6,14},{7,8,62},{7,4,4},{7,4,2},{7,4,7},{7,8,48},{7,4,3},{7,8,60},{7,4,5}, -{7,8,42},{7,6,16},{9,9,1152},{7,4,6},{7,8,32},{7,5,8},{7,8,58},{9,5,64},{7,5,10},{7,4,4}, -{7,4,2},{7,4,7},{7,7,22},{7,4,3},{7,5,11},{7,4,5},{7,7,26},{7,5,9},{9,8,640},{7,4,6}, -{7,8,38},{9,5,128},{7,7,25},{7,6,15},{9,8,384},{7,4,4},{7,4,2},{7,4,7},{7,6,13},{7,4,3}, -{7,7,18},{7,4,5},{7,7,21},{7,6,17},{9,7,256},{7,4,6},{7,6,1},{7,5,8},{9,6,192},{9,5,64}, -{7,5,10},{7,4,4},{7,4,2},{7,4,7},{0,0,0},{7,4,3},{7,5,11},{7,4,5},{7,6,12},{7,5,9}, -{9,6,1664},{7,4,6},{7,7,20},{9,5,128},{7,7,24},{7,6,14},{7,7,28},{7,4,4},{7,4,2},{7,4,7}, -{7,7,23},{7,4,3},{7,7,27},{7,4,5},{7,8,39},{7,6,16},{9,8,576},{7,4,6},{7,7,19},{7,5,8}, -{7,8,55},{9,5,64},{7,5,10},{7,4,4},{7,4,2},{7,4,7},{7,8,45},{7,4,3},{7,5,11},{7,4,5}, -{7,8,53},{7,5,9},{9,8,448},{7,4,6},{7,8,35},{9,5,128},{7,8,51},{7,6,15},{7,8,63},{7,4,4}, -{7,4,2},{7,4,7},{7,6,13},{7,4,3},{9,9,1472},{7,4,5},{7,8,43},{7,6,17},{9,9,1216},{7,4,6}, -{7,6,1},{7,5,8},{9,6,192},{9,5,64},{7,5,10},{7,4,4},{7,4,2},{7,4,7},{7,8,29},{7,4,3}, -{7,5,11},{7,4,5},{7,6,12},{7,5,9},{9,6,1664},{7,4,6},{7,8,33},{9,5,128},{7,8,49},{7,6,14}, -{7,8,61},{7,4,4},{7,4,2},{7,4,7},{7,8,47},{7,4,3},{7,8,59},{7,4,5},{7,8,41},{7,6,16}, -{9,9,960},{7,4,6},{7,8,31},{7,5,8},{7,8,57},{9,5,64},{7,5,10},{7,4,4},{7,4,2},{7,4,7}, -{7,7,22},{7,4,3},{7,5,11},{7,4,5},{7,7,26},{7,5,9},{9,9,704},{7,4,6},{7,8,37},{9,5,128}, -{7,7,25},{7,6,15},{9,8,320},{7,4,4},{7,4,2},{7,4,7},{7,6,13},{7,4,3},{7,7,18},{7,4,5}, -{7,7,21},{7,6,17},{9,7,256},{7,4,6},{7,6,1},{7,5,8},{9,6,192},{9,5,64},{7,5,10},{7,4,4}, -{7,4,2},{7,4,7},{11,12,1984},{7,4,3},{7,5,11},{7,4,5},{7,6,12},{7,5,9},{9,6,1664},{7,4,6}, -{7,7,20},{9,5,128},{7,7,24},{7,6,14},{7,7,28},{7,4,4},{7,4,2},{7,4,7},{7,7,23},{7,4,3}, -{7,7,27},{7,4,5},{7,8,40},{7,6,16},{9,9,832},{7,4,6},{7,7,19},{7,5,8},{7,8,56},{9,5,64}, -{7,5,10},{7,4,4},{7,4,2},{7,4,7},{7,8,46},{7,4,3},{7,5,11},{7,4,5},{7,8,54},{7,5,9}, -{9,8,512},{7,4,6},{7,8,36},{9,5,128},{7,8,52},{7,6,15},{7,8,0},{7,4,4},{7,4,2},{7,4,7}, -{7,6,13},{7,4,3},{9,9,1600},{7,4,5},{7,8,44},{7,6,17},{9,9,1344},{7,4,6},{7,6,1},{7,5,8}, -{9,6,192},{9,5,64},{7,5,10},{7,4,4},{7,4,2},{7,4,7},{7,8,30},{7,4,3},{7,5,11},{7,4,5}, -{7,6,12},{7,5,9},{9,6,1664},{7,4,6},{7,8,34},{9,5,128},{7,8,50},{7,6,14},{7,8,62},{7,4,4}, -{7,4,2},{7,4,7},{7,8,48},{7,4,3},{7,8,60},{7,4,5},{7,8,42},{7,6,16},{9,9,1088},{7,4,6}, -{7,8,32},{7,5,8},{7,8,58},{9,5,64},{7,5,10},{7,4,4},{7,4,2},{7,4,7},{7,7,22},{7,4,3}, -{7,5,11},{7,4,5},{7,7,26},{7,5,9},{9,8,640},{7,4,6},{7,8,38},{9,5,128},{7,7,25},{7,6,15}, -{9,8,384},{7,4,4},{7,4,2},{7,4,7},{7,6,13},{7,4,3},{7,7,18},{7,4,5},{7,7,21},{7,6,17}, -{9,7,256},{7,4,6},{7,6,1},{7,5,8},{9,6,192},{9,5,64},{7,5,10},{7,4,4},{7,4,2},{7,4,7}, -{0,0,0},{7,4,3},{7,5,11},{7,4,5},{7,6,12},{7,5,9},{9,6,1664},{7,4,6},{7,7,20},{9,5,128}, -{7,7,24},{7,6,14},{7,7,28},{7,4,4},{7,4,2},{7,4,7},{7,7,23},{7,4,3},{7,7,27},{7,4,5}, -{7,8,39},{7,6,16},{9,8,576},{7,4,6},{7,7,19},{7,5,8},{7,8,55},{9,5,64},{7,5,10},{7,4,4}, -{7,4,2},{7,4,7},{7,8,45},{7,4,3},{7,5,11},{7,4,5},{7,8,53},{7,5,9},{9,8,448},{7,4,6}, -{7,8,35},{9,5,128},{7,8,51},{7,6,15},{7,8,63},{7,4,4},{7,4,2},{7,4,7},{7,6,13},{7,4,3}, -{9,9,1536},{7,4,5},{7,8,43},{7,6,17},{9,9,1280},{7,4,6},{7,6,1},{7,5,8},{9,6,192},{9,5,64}, -{7,5,10},{7,4,4},{7,4,2},{7,4,7},{7,8,29},{7,4,3},{7,5,11},{7,4,5},{7,6,12},{7,5,9}, -{9,6,1664},{7,4,6},{7,8,33},{9,5,128},{7,8,49},{7,6,14},{7,8,61},{7,4,4},{7,4,2},{7,4,7}, -{7,8,47},{7,4,3},{7,8,59},{7,4,5},{7,8,41},{7,6,16},{9,9,1024},{7,4,6},{7,8,31},{7,5,8}, -{7,8,57},{9,5,64},{7,5,10},{7,4,4},{7,4,2},{7,4,7},{7,7,22},{7,4,3},{7,5,11},{7,4,5}, -{7,7,26},{7,5,9},{9,9,768},{7,4,6},{7,8,37},{9,5,128},{7,7,25},{7,6,15},{9,8,320},{7,4,4}, -{7,4,2},{7,4,7},{7,6,13},{7,4,3},{7,7,18},{7,4,5},{7,7,21},{7,6,17},{9,7,256},{7,4,6}, -{7,6,1},{7,5,8},{9,6,192},{9,5,64},{7,5,10},{7,4,4},{7,4,2},{7,4,7},{11,11,1920},{7,4,3}, -{7,5,11},{7,4,5},{7,6,12},{7,5,9},{9,6,1664},{7,4,6},{7,7,20},{9,5,128},{7,7,24},{7,6,14}, -{7,7,28},{7,4,4},{7,4,2},{7,4,7},{7,7,23},{7,4,3},{7,7,27},{7,4,5},{7,8,40},{7,6,16}, -{9,9,896},{7,4,6},{7,7,19},{7,5,8},{7,8,56},{9,5,64},{7,5,10},{7,4,4},{7,4,2},{7,4,7}, -{7,8,46},{7,4,3},{7,5,11},{7,4,5},{7,8,54},{7,5,9},{9,8,512},{7,4,6},{7,8,36},{9,5,128}, -{7,8,52},{7,6,15},{7,8,0},{7,4,4},{7,4,2},{7,4,7},{7,6,13},{7,4,3},{9,9,1728},{7,4,5}, -{7,8,44},{7,6,17},{9,9,1408},{7,4,6},{7,6,1},{7,5,8},{9,6,192},{9,5,64},{7,5,10},{7,4,4}, -{7,4,2},{7,4,7},{7,8,30},{7,4,3},{7,5,11},{7,4,5},{7,6,12},{7,5,9},{9,6,1664},{7,4,6}, -{7,8,34},{9,5,128},{7,8,50},{7,6,14},{7,8,62},{7,4,4},{7,4,2},{7,4,7},{7,8,48},{7,4,3}, -{7,8,60},{7,4,5},{7,8,42},{7,6,16},{9,9,1152},{7,4,6},{7,8,32},{7,5,8},{7,8,58},{9,5,64}, -{7,5,10},{7,4,4},{7,4,2},{7,4,7},{7,7,22},{7,4,3},{7,5,11},{7,4,5},{7,7,26},{7,5,9}, -{9,8,640},{7,4,6},{7,8,38},{9,5,128},{7,7,25},{7,6,15},{9,8,384},{7,4,4},{7,4,2},{7,4,7}, -{7,6,13},{7,4,3},{7,7,18},{7,4,5},{7,7,21},{7,6,17},{9,7,256},{7,4,6},{7,6,1},{7,5,8}, -{9,6,192},{9,5,64},{7,5,10},{7,4,4},{7,4,2},{7,4,7},{0,0,0},{7,4,3},{7,5,11},{7,4,5}, -{7,6,12},{7,5,9},{9,6,1664},{7,4,6},{7,7,20},{9,5,128},{7,7,24},{7,6,14},{7,7,28},{7,4,4}, -{7,4,2},{7,4,7},{7,7,23},{7,4,3},{7,7,27},{7,4,5},{7,8,39},{7,6,16},{9,8,576},{7,4,6}, -{7,7,19},{7,5,8},{7,8,55},{9,5,64},{7,5,10},{7,4,4},{7,4,2},{7,4,7},{7,8,45},{7,4,3}, -{7,5,11},{7,4,5},{7,8,53},{7,5,9},{9,8,448},{7,4,6},{7,8,35},{9,5,128},{7,8,51},{7,6,15}, -{7,8,63},{7,4,4},{7,4,2},{7,4,7},{7,6,13},{7,4,3},{9,9,1472},{7,4,5},{7,8,43},{7,6,17}, -{9,9,1216},{7,4,6},{7,6,1},{7,5,8},{9,6,192},{9,5,64},{7,5,10},{7,4,4},{7,4,2},{7,4,7}, -{7,8,29},{7,4,3},{7,5,11},{7,4,5},{7,6,12},{7,5,9},{9,6,1664},{7,4,6},{7,8,33},{9,5,128}, -{7,8,49},{7,6,14},{7,8,61},{7,4,4},{7,4,2},{7,4,7},{7,8,47},{7,4,3},{7,8,59},{7,4,5}, -{7,8,41},{7,6,16},{9,9,960},{7,4,6},{7,8,31},{7,5,8},{7,8,57},{9,5,64},{7,5,10},{7,4,4}, -{7,4,2},{7,4,7},{7,7,22},{7,4,3},{7,5,11},{7,4,5},{7,7,26},{7,5,9},{9,9,704},{7,4,6}, -{7,8,37},{9,5,128},{7,7,25},{7,6,15},{9,8,320},{7,4,4},{7,4,2},{7,4,7},{7,6,13},{7,4,3}, -{7,7,18},{7,4,5},{7,7,21},{7,6,17},{9,7,256},{7,4,6},{7,6,1},{7,5,8},{9,6,192},{9,5,64}, -{7,5,10},{7,4,4},{7,4,2},{7,4,7},{11,12,2240},{7,4,3},{7,5,11},{7,4,5},{7,6,12},{7,5,9}, -{9,6,1664},{7,4,6},{7,7,20},{9,5,128},{7,7,24},{7,6,14},{7,7,28},{7,4,4},{7,4,2},{7,4,7}, -{7,7,23},{7,4,3},{7,7,27},{7,4,5},{7,8,40},{7,6,16},{9,9,832},{7,4,6},{7,7,19},{7,5,8}, -{7,8,56},{9,5,64},{7,5,10},{7,4,4},{7,4,2},{7,4,7},{7,8,46},{7,4,3},{7,5,11},{7,4,5}, -{7,8,54},{7,5,9},{9,8,512},{7,4,6},{7,8,36},{9,5,128},{7,8,52},{7,6,15},{7,8,0},{7,4,4}, -{7,4,2},{7,4,7},{7,6,13},{7,4,3},{9,9,1600},{7,4,5},{7,8,44},{7,6,17},{9,9,1344},{7,4,6}, -{7,6,1},{7,5,8},{9,6,192},{9,5,64},{7,5,10},{7,4,4},{7,4,2},{7,4,7},{7,8,30},{7,4,3}, -{7,5,11},{7,4,5},{7,6,12},{7,5,9},{9,6,1664},{7,4,6},{7,8,34},{9,5,128},{7,8,50},{7,6,14}, -{7,8,62},{7,4,4},{7,4,2},{7,4,7},{7,8,48},{7,4,3},{7,8,60},{7,4,5},{7,8,42},{7,6,16}, -{9,9,1088},{7,4,6},{7,8,32},{7,5,8},{7,8,58},{9,5,64},{7,5,10},{7,4,4},{7,4,2},{7,4,7}, -{7,7,22},{7,4,3},{7,5,11},{7,4,5},{7,7,26},{7,5,9},{9,8,640},{7,4,6},{7,8,38},{9,5,128}, -{7,7,25},{7,6,15},{9,8,384},{7,4,4},{7,4,2},{7,4,7},{7,6,13},{7,4,3},{7,7,18},{7,4,5}, -{7,7,21},{7,6,17},{9,7,256},{7,4,6},{7,6,1},{7,5,8},{9,6,192},{9,5,64},{7,5,10},{7,4,4}, -{7,4,2},{7,4,7},{0,0,0},{7,4,3},{7,5,11},{7,4,5},{7,6,12},{7,5,9},{9,6,1664},{7,4,6}, -{7,7,20},{9,5,128},{7,7,24},{7,6,14},{7,7,28},{7,4,4},{7,4,2},{7,4,7},{7,7,23},{7,4,3}, -{7,7,27},{7,4,5},{7,8,39},{7,6,16},{9,8,576},{7,4,6},{7,7,19},{7,5,8},{7,8,55},{9,5,64}, -{7,5,10},{7,4,4},{7,4,2},{7,4,7},{7,8,45},{7,4,3},{7,5,11},{7,4,5},{7,8,53},{7,5,9}, -{9,8,448},{7,4,6},{7,8,35},{9,5,128},{7,8,51},{7,6,15},{7,8,63},{7,4,4},{7,4,2},{7,4,7}, -{7,6,13},{7,4,3},{9,9,1536},{7,4,5},{7,8,43},{7,6,17},{9,9,1280},{7,4,6},{7,6,1},{7,5,8}, -{9,6,192},{9,5,64},{7,5,10},{7,4,4},{7,4,2},{7,4,7},{7,8,29},{7,4,3},{7,5,11},{7,4,5}, -{7,6,12},{7,5,9},{9,6,1664},{7,4,6},{7,8,33},{9,5,128},{7,8,49},{7,6,14},{7,8,61},{7,4,4}, -{7,4,2},{7,4,7},{7,8,47},{7,4,3},{7,8,59},{7,4,5},{7,8,41},{7,6,16},{9,9,1024},{7,4,6}, -{7,8,31},{7,5,8},{7,8,57},{9,5,64},{7,5,10},{7,4,4},{7,4,2},{7,4,7},{7,7,22},{7,4,3}, -{7,5,11},{7,4,5},{7,7,26},{7,5,9},{9,9,768},{7,4,6},{7,8,37},{9,5,128},{7,7,25},{7,6,15}, -{9,8,320},{7,4,4},{7,4,2},{7,4,7},{7,6,13},{7,4,3},{7,7,18},{7,4,5},{7,7,21},{7,6,17}, -{9,7,256},{7,4,6},{7,6,1},{7,5,8},{9,6,192},{9,5,64},{7,5,10},{7,4,4},{7,4,2},{7,4,7}, -{11,12,2496},{7,4,3},{7,5,11},{7,4,5},{7,6,12},{7,5,9},{9,6,1664},{7,4,6},{7,7,20},{9,5,128}, -{7,7,24},{7,6,14},{7,7,28},{7,4,4},{7,4,2},{7,4,7},{7,7,23},{7,4,3},{7,7,27},{7,4,5}, -{7,8,40},{7,6,16},{9,9,896},{7,4,6},{7,7,19},{7,5,8},{7,8,56},{9,5,64},{7,5,10},{7,4,4}, -{7,4,2},{7,4,7},{7,8,46},{7,4,3},{7,5,11},{7,4,5},{7,8,54},{7,5,9},{9,8,512},{7,4,6}, -{7,8,36},{9,5,128},{7,8,52},{7,6,15},{7,8,0},{7,4,4},{7,4,2},{7,4,7},{7,6,13},{7,4,3}, -{9,9,1728},{7,4,5},{7,8,44},{7,6,17},{9,9,1408},{7,4,6},{7,6,1},{7,5,8},{9,6,192},{9,5,64}, -{7,5,10},{7,4,4},{7,4,2},{7,4,7},{7,8,30},{7,4,3},{7,5,11},{7,4,5},{7,6,12},{7,5,9}, -{9,6,1664},{7,4,6},{7,8,34},{9,5,128},{7,8,50},{7,6,14},{7,8,62},{7,4,4},{7,4,2},{7,4,7}, -{7,8,48},{7,4,3},{7,8,60},{7,4,5},{7,8,42},{7,6,16},{9,9,1152},{7,4,6},{7,8,32},{7,5,8}, -{7,8,58},{9,5,64},{7,5,10},{7,4,4},{7,4,2},{7,4,7},{7,7,22},{7,4,3},{7,5,11},{7,4,5}, -{7,7,26},{7,5,9},{9,8,640},{7,4,6},{7,8,38},{9,5,128},{7,7,25},{7,6,15},{9,8,384},{7,4,4}, -{7,4,2},{7,4,7},{7,6,13},{7,4,3},{7,7,18},{7,4,5},{7,7,21},{7,6,17},{9,7,256},{7,4,6}, -{7,6,1},{7,5,8},{9,6,192},{9,5,64},{7,5,10},{7,4,4},{7,4,2},{7,4,7},{12,11,0},{7,4,3}, -{7,5,11},{7,4,5},{7,6,12},{7,5,9},{9,6,1664},{7,4,6},{7,7,20},{9,5,128},{7,7,24},{7,6,14}, -{7,7,28},{7,4,4},{7,4,2},{7,4,7},{7,7,23},{7,4,3},{7,7,27},{7,4,5},{7,8,39},{7,6,16}, -{9,8,576},{7,4,6},{7,7,19},{7,5,8},{7,8,55},{9,5,64},{7,5,10},{7,4,4},{7,4,2},{7,4,7}, -{7,8,45},{7,4,3},{7,5,11},{7,4,5},{7,8,53},{7,5,9},{9,8,448},{7,4,6},{7,8,35},{9,5,128}, -{7,8,51},{7,6,15},{7,8,63},{7,4,4},{7,4,2},{7,4,7},{7,6,13},{7,4,3},{9,9,1472},{7,4,5}, -{7,8,43},{7,6,17},{9,9,1216},{7,4,6},{7,6,1},{7,5,8},{9,6,192},{9,5,64},{7,5,10},{7,4,4}, -{7,4,2},{7,4,7},{7,8,29},{7,4,3},{7,5,11},{7,4,5},{7,6,12},{7,5,9},{9,6,1664},{7,4,6}, -{7,8,33},{9,5,128},{7,8,49},{7,6,14},{7,8,61},{7,4,4},{7,4,2},{7,4,7},{7,8,47},{7,4,3}, -{7,8,59},{7,4,5},{7,8,41},{7,6,16},{9,9,960},{7,4,6},{7,8,31},{7,5,8},{7,8,57},{9,5,64}, -{7,5,10},{7,4,4},{7,4,2},{7,4,7},{7,7,22},{7,4,3},{7,5,11},{7,4,5},{7,7,26},{7,5,9}, -{9,9,704},{7,4,6},{7,8,37},{9,5,128},{7,7,25},{7,6,15},{9,8,320},{7,4,4},{7,4,2},{7,4,7}, -{7,6,13},{7,4,3},{7,7,18},{7,4,5},{7,7,21},{7,6,17},{9,7,256},{7,4,6},{7,6,1},{7,5,8}, -{9,6,192},{9,5,64},{7,5,10},{7,4,4},{7,4,2},{7,4,7},{11,11,1792},{7,4,3},{7,5,11},{7,4,5}, -{7,6,12},{7,5,9},{9,6,1664},{7,4,6},{7,7,20},{9,5,128},{7,7,24},{7,6,14},{7,7,28},{7,4,4}, -{7,4,2},{7,4,7},{7,7,23},{7,4,3},{7,7,27},{7,4,5},{7,8,40},{7,6,16},{9,9,832},{7,4,6}, -{7,7,19},{7,5,8},{7,8,56},{9,5,64},{7,5,10},{7,4,4},{7,4,2},{7,4,7},{7,8,46},{7,4,3}, -{7,5,11},{7,4,5},{7,8,54},{7,5,9},{9,8,512},{7,4,6},{7,8,36},{9,5,128},{7,8,52},{7,6,15}, -{7,8,0},{7,4,4},{7,4,2},{7,4,7},{7,6,13},{7,4,3},{9,9,1600},{7,4,5},{7,8,44},{7,6,17}, -{9,9,1344},{7,4,6},{7,6,1},{7,5,8},{9,6,192},{9,5,64},{7,5,10},{7,4,4},{7,4,2},{7,4,7}, -{7,8,30},{7,4,3},{7,5,11},{7,4,5},{7,6,12},{7,5,9},{9,6,1664},{7,4,6},{7,8,34},{9,5,128}, -{7,8,50},{7,6,14},{7,8,62},{7,4,4},{7,4,2},{7,4,7},{7,8,48},{7,4,3},{7,8,60},{7,4,5}, -{7,8,42},{7,6,16},{9,9,1088},{7,4,6},{7,8,32},{7,5,8},{7,8,58},{9,5,64},{7,5,10},{7,4,4}, -{7,4,2},{7,4,7},{7,7,22},{7,4,3},{7,5,11},{7,4,5},{7,7,26},{7,5,9},{9,8,640},{7,4,6}, -{7,8,38},{9,5,128},{7,7,25},{7,6,15},{9,8,384},{7,4,4},{7,4,2},{7,4,7},{7,6,13},{7,4,3}, -{7,7,18},{7,4,5},{7,7,21},{7,6,17},{9,7,256},{7,4,6},{7,6,1},{7,5,8},{9,6,192},{9,5,64}, -{7,5,10},{7,4,4},{7,4,2},{7,4,7},{0,0,0},{7,4,3},{7,5,11},{7,4,5},{7,6,12},{7,5,9}, -{9,6,1664},{7,4,6},{7,7,20},{9,5,128},{7,7,24},{7,6,14},{7,7,28},{7,4,4},{7,4,2},{7,4,7}, -{7,7,23},{7,4,3},{7,7,27},{7,4,5},{7,8,39},{7,6,16},{9,8,576},{7,4,6},{7,7,19},{7,5,8}, -{7,8,55},{9,5,64},{7,5,10},{7,4,4},{7,4,2},{7,4,7},{7,8,45},{7,4,3},{7,5,11},{7,4,5}, -{7,8,53},{7,5,9},{9,8,448},{7,4,6},{7,8,35},{9,5,128},{7,8,51},{7,6,15},{7,8,63},{7,4,4}, -{7,4,2},{7,4,7},{7,6,13},{7,4,3},{9,9,1536},{7,4,5},{7,8,43},{7,6,17},{9,9,1280},{7,4,6}, -{7,6,1},{7,5,8},{9,6,192},{9,5,64},{7,5,10},{7,4,4},{7,4,2},{7,4,7},{7,8,29},{7,4,3}, -{7,5,11},{7,4,5},{7,6,12},{7,5,9},{9,6,1664},{7,4,6},{7,8,33},{9,5,128},{7,8,49},{7,6,14}, -{7,8,61},{7,4,4},{7,4,2},{7,4,7},{7,8,47},{7,4,3},{7,8,59},{7,4,5},{7,8,41},{7,6,16}, -{9,9,1024},{7,4,6},{7,8,31},{7,5,8},{7,8,57},{9,5,64},{7,5,10},{7,4,4},{7,4,2},{7,4,7}, -{7,7,22},{7,4,3},{7,5,11},{7,4,5},{7,7,26},{7,5,9},{9,9,768},{7,4,6},{7,8,37},{9,5,128}, -{7,7,25},{7,6,15},{9,8,320},{7,4,4},{7,4,2},{7,4,7},{7,6,13},{7,4,3},{7,7,18},{7,4,5}, -{7,7,21},{7,6,17},{9,7,256},{7,4,6},{7,6,1},{7,5,8},{9,6,192},{9,5,64},{7,5,10},{7,4,4}, -{7,4,2},{7,4,7},{11,11,1856},{7,4,3},{7,5,11},{7,4,5},{7,6,12},{7,5,9},{9,6,1664},{7,4,6}, -{7,7,20},{9,5,128},{7,7,24},{7,6,14},{7,7,28},{7,4,4},{7,4,2},{7,4,7},{7,7,23},{7,4,3}, -{7,7,27},{7,4,5},{7,8,40},{7,6,16},{9,9,896},{7,4,6},{7,7,19},{7,5,8},{7,8,56},{9,5,64}, -{7,5,10},{7,4,4},{7,4,2},{7,4,7},{7,8,46},{7,4,3},{7,5,11},{7,4,5},{7,8,54},{7,5,9}, -{9,8,512},{7,4,6},{7,8,36},{9,5,128},{7,8,52},{7,6,15},{7,8,0},{7,4,4},{7,4,2},{7,4,7}, -{7,6,13},{7,4,3},{9,9,1728},{7,4,5},{7,8,44},{7,6,17},{9,9,1408},{7,4,6},{7,6,1},{7,5,8}, -{9,6,192},{9,5,64},{7,5,10},{7,4,4},{7,4,2},{7,4,7},{7,8,30},{7,4,3},{7,5,11},{7,4,5}, -{7,6,12},{7,5,9},{9,6,1664},{7,4,6},{7,8,34},{9,5,128},{7,8,50},{7,6,14},{7,8,62},{7,4,4}, -{7,4,2},{7,4,7},{7,8,48},{7,4,3},{7,8,60},{7,4,5},{7,8,42},{7,6,16},{9,9,1152},{7,4,6}, -{7,8,32},{7,5,8},{7,8,58},{9,5,64},{7,5,10},{7,4,4},{7,4,2},{7,4,7},{7,7,22},{7,4,3}, -{7,5,11},{7,4,5},{7,7,26},{7,5,9},{9,8,640},{7,4,6},{7,8,38},{9,5,128},{7,7,25},{7,6,15}, -{9,8,384},{7,4,4},{7,4,2},{7,4,7},{7,6,13},{7,4,3},{7,7,18},{7,4,5},{7,7,21},{7,6,17}, -{9,7,256},{7,4,6},{7,6,1},{7,5,8},{9,6,192},{9,5,64},{7,5,10},{7,4,4},{7,4,2},{7,4,7}, -{0,0,0},{7,4,3},{7,5,11},{7,4,5},{7,6,12},{7,5,9},{9,6,1664},{7,4,6},{7,7,20},{9,5,128}, -{7,7,24},{7,6,14},{7,7,28},{7,4,4},{7,4,2},{7,4,7},{7,7,23},{7,4,3},{7,7,27},{7,4,5}, -{7,8,39},{7,6,16},{9,8,576},{7,4,6},{7,7,19},{7,5,8},{7,8,55},{9,5,64},{7,5,10},{7,4,4}, -{7,4,2},{7,4,7},{7,8,45},{7,4,3},{7,5,11},{7,4,5},{7,8,53},{7,5,9},{9,8,448},{7,4,6}, -{7,8,35},{9,5,128},{7,8,51},{7,6,15},{7,8,63},{7,4,4},{7,4,2},{7,4,7},{7,6,13},{7,4,3}, -{9,9,1472},{7,4,5},{7,8,43},{7,6,17},{9,9,1216},{7,4,6},{7,6,1},{7,5,8},{9,6,192},{9,5,64}, -{7,5,10},{7,4,4},{7,4,2},{7,4,7},{7,8,29},{7,4,3},{7,5,11},{7,4,5},{7,6,12},{7,5,9}, -{9,6,1664},{7,4,6},{7,8,33},{9,5,128},{7,8,49},{7,6,14},{7,8,61},{7,4,4},{7,4,2},{7,4,7}, -{7,8,47},{7,4,3},{7,8,59},{7,4,5},{7,8,41},{7,6,16},{9,9,960},{7,4,6},{7,8,31},{7,5,8}, -{7,8,57},{9,5,64},{7,5,10},{7,4,4},{7,4,2},{7,4,7},{7,7,22},{7,4,3},{7,5,11},{7,4,5}, -{7,7,26},{7,5,9},{9,9,704},{7,4,6},{7,8,37},{9,5,128},{7,7,25},{7,6,15},{9,8,320},{7,4,4}, -{7,4,2},{7,4,7},{7,6,13},{7,4,3},{7,7,18},{7,4,5},{7,7,21},{7,6,17},{9,7,256},{7,4,6}, -{7,6,1},{7,5,8},{9,6,192},{9,5,64},{7,5,10},{7,4,4},{7,4,2},{7,4,7},{11,12,2176},{7,4,3}, -{7,5,11},{7,4,5},{7,6,12},{7,5,9},{9,6,1664},{7,4,6},{7,7,20},{9,5,128},{7,7,24},{7,6,14}, -{7,7,28},{7,4,4},{7,4,2},{7,4,7},{7,7,23},{7,4,3},{7,7,27},{7,4,5},{7,8,40},{7,6,16}, -{9,9,832},{7,4,6},{7,7,19},{7,5,8},{7,8,56},{9,5,64},{7,5,10},{7,4,4},{7,4,2},{7,4,7}, -{7,8,46},{7,4,3},{7,5,11},{7,4,5},{7,8,54},{7,5,9},{9,8,512},{7,4,6},{7,8,36},{9,5,128}, -{7,8,52},{7,6,15},{7,8,0},{7,4,4},{7,4,2},{7,4,7},{7,6,13},{7,4,3},{9,9,1600},{7,4,5}, -{7,8,44},{7,6,17},{9,9,1344},{7,4,6},{7,6,1},{7,5,8},{9,6,192},{9,5,64},{7,5,10},{7,4,4}, -{7,4,2},{7,4,7},{7,8,30},{7,4,3},{7,5,11},{7,4,5},{7,6,12},{7,5,9},{9,6,1664},{7,4,6}, -{7,8,34},{9,5,128},{7,8,50},{7,6,14},{7,8,62},{7,4,4},{7,4,2},{7,4,7},{7,8,48},{7,4,3}, -{7,8,60},{7,4,5},{7,8,42},{7,6,16},{9,9,1088},{7,4,6},{7,8,32},{7,5,8},{7,8,58},{9,5,64}, -{7,5,10},{7,4,4},{7,4,2},{7,4,7},{7,7,22},{7,4,3},{7,5,11},{7,4,5},{7,7,26},{7,5,9}, -{9,8,640},{7,4,6},{7,8,38},{9,5,128},{7,7,25},{7,6,15},{9,8,384},{7,4,4},{7,4,2},{7,4,7}, -{7,6,13},{7,4,3},{7,7,18},{7,4,5},{7,7,21},{7,6,17},{9,7,256},{7,4,6},{7,6,1},{7,5,8}, -{9,6,192},{9,5,64},{7,5,10},{7,4,4},{7,4,2},{7,4,7},{0,0,0},{7,4,3},{7,5,11},{7,4,5}, -{7,6,12},{7,5,9},{9,6,1664},{7,4,6},{7,7,20},{9,5,128},{7,7,24},{7,6,14},{7,7,28},{7,4,4}, -{7,4,2},{7,4,7},{7,7,23},{7,4,3},{7,7,27},{7,4,5},{7,8,39},{7,6,16},{9,8,576},{7,4,6}, -{7,7,19},{7,5,8},{7,8,55},{9,5,64},{7,5,10},{7,4,4},{7,4,2},{7,4,7},{7,8,45},{7,4,3}, -{7,5,11},{7,4,5},{7,8,53},{7,5,9},{9,8,448},{7,4,6},{7,8,35},{9,5,128},{7,8,51},{7,6,15}, -{7,8,63},{7,4,4},{7,4,2},{7,4,7},{7,6,13},{7,4,3},{9,9,1536},{7,4,5},{7,8,43},{7,6,17}, -{9,9,1280},{7,4,6},{7,6,1},{7,5,8},{9,6,192},{9,5,64},{7,5,10},{7,4,4},{7,4,2},{7,4,7}, -{7,8,29},{7,4,3},{7,5,11},{7,4,5},{7,6,12},{7,5,9},{9,6,1664},{7,4,6},{7,8,33},{9,5,128}, -{7,8,49},{7,6,14},{7,8,61},{7,4,4},{7,4,2},{7,4,7},{7,8,47},{7,4,3},{7,8,59},{7,4,5}, -{7,8,41},{7,6,16},{9,9,1024},{7,4,6},{7,8,31},{7,5,8},{7,8,57},{9,5,64},{7,5,10},{7,4,4}, -{7,4,2},{7,4,7},{7,7,22},{7,4,3},{7,5,11},{7,4,5},{7,7,26},{7,5,9},{9,9,768},{7,4,6}, -{7,8,37},{9,5,128},{7,7,25},{7,6,15},{9,8,320},{7,4,4},{7,4,2},{7,4,7},{7,6,13},{7,4,3}, -{7,7,18},{7,4,5},{7,7,21},{7,6,17},{9,7,256},{7,4,6},{7,6,1},{7,5,8},{9,6,192},{9,5,64}, -{7,5,10},{7,4,4},{7,4,2},{7,4,7},{11,12,2432},{7,4,3},{7,5,11},{7,4,5},{7,6,12},{7,5,9}, -{9,6,1664},{7,4,6},{7,7,20},{9,5,128},{7,7,24},{7,6,14},{7,7,28},{7,4,4},{7,4,2},{7,4,7}, -{7,7,23},{7,4,3},{7,7,27},{7,4,5},{7,8,40},{7,6,16},{9,9,896},{7,4,6},{7,7,19},{7,5,8}, -{7,8,56},{9,5,64},{7,5,10},{7,4,4},{7,4,2},{7,4,7},{7,8,46},{7,4,3},{7,5,11},{7,4,5}, -{7,8,54},{7,5,9},{9,8,512},{7,4,6},{7,8,36},{9,5,128},{7,8,52},{7,6,15},{7,8,0},{7,4,4}, -{7,4,2},{7,4,7},{7,6,13},{7,4,3},{9,9,1728},{7,4,5},{7,8,44},{7,6,17},{9,9,1408},{7,4,6}, -{7,6,1},{7,5,8},{9,6,192},{9,5,64},{7,5,10},{7,4,4},{7,4,2},{7,4,7},{7,8,30},{7,4,3}, -{7,5,11},{7,4,5},{7,6,12},{7,5,9},{9,6,1664},{7,4,6},{7,8,34},{9,5,128},{7,8,50},{7,6,14}, -{7,8,62},{7,4,4},{7,4,2},{7,4,7},{7,8,48},{7,4,3},{7,8,60},{7,4,5},{7,8,42},{7,6,16}, -{9,9,1152},{7,4,6},{7,8,32},{7,5,8},{7,8,58},{9,5,64},{7,5,10},{7,4,4},{7,4,2},{7,4,7}, -{7,7,22},{7,4,3},{7,5,11},{7,4,5},{7,7,26},{7,5,9},{9,8,640},{7,4,6},{7,8,38},{9,5,128}, -{7,7,25},{7,6,15},{9,8,384},{7,4,4},{7,4,2},{7,4,7},{7,6,13},{7,4,3},{7,7,18},{7,4,5}, -{7,7,21},{7,6,17},{9,7,256},{7,4,6},{7,6,1},{7,5,8},{9,6,192},{9,5,64},{7,5,10},{7,4,4}, -{7,4,2},{7,4,7},{0,0,0},{7,4,3},{7,5,11},{7,4,5},{7,6,12},{7,5,9},{9,6,1664},{7,4,6}, -{7,7,20},{9,5,128},{7,7,24},{7,6,14},{7,7,28},{7,4,4},{7,4,2},{7,4,7},{7,7,23},{7,4,3}, -{7,7,27},{7,4,5},{7,8,39},{7,6,16},{9,8,576},{7,4,6},{7,7,19},{7,5,8},{7,8,55},{9,5,64}, -{7,5,10},{7,4,4},{7,4,2},{7,4,7},{7,8,45},{7,4,3},{7,5,11},{7,4,5},{7,8,53},{7,5,9}, -{9,8,448},{7,4,6},{7,8,35},{9,5,128},{7,8,51},{7,6,15},{7,8,63},{7,4,4},{7,4,2},{7,4,7}, -{7,6,13},{7,4,3},{9,9,1472},{7,4,5},{7,8,43},{7,6,17},{9,9,1216},{7,4,6},{7,6,1},{7,5,8}, -{9,6,192},{9,5,64},{7,5,10},{7,4,4},{7,4,2},{7,4,7},{7,8,29},{7,4,3},{7,5,11},{7,4,5}, -{7,6,12},{7,5,9},{9,6,1664},{7,4,6},{7,8,33},{9,5,128},{7,8,49},{7,6,14},{7,8,61},{7,4,4}, -{7,4,2},{7,4,7},{7,8,47},{7,4,3},{7,8,59},{7,4,5},{7,8,41},{7,6,16},{9,9,960},{7,4,6}, -{7,8,31},{7,5,8},{7,8,57},{9,5,64},{7,5,10},{7,4,4},{7,4,2},{7,4,7},{7,7,22},{7,4,3}, -{7,5,11},{7,4,5},{7,7,26},{7,5,9},{9,9,704},{7,4,6},{7,8,37},{9,5,128},{7,7,25},{7,6,15}, -{9,8,320},{7,4,4},{7,4,2},{7,4,7},{7,6,13},{7,4,3},{7,7,18},{7,4,5},{7,7,21},{7,6,17}, -{9,7,256},{7,4,6},{7,6,1},{7,5,8},{9,6,192},{9,5,64},{7,5,10},{7,4,4},{7,4,2},{7,4,7}, -{11,12,2048},{7,4,3},{7,5,11},{7,4,5},{7,6,12},{7,5,9},{9,6,1664},{7,4,6},{7,7,20},{9,5,128}, -{7,7,24},{7,6,14},{7,7,28},{7,4,4},{7,4,2},{7,4,7},{7,7,23},{7,4,3},{7,7,27},{7,4,5}, -{7,8,40},{7,6,16},{9,9,832},{7,4,6},{7,7,19},{7,5,8},{7,8,56},{9,5,64},{7,5,10},{7,4,4}, -{7,4,2},{7,4,7},{7,8,46},{7,4,3},{7,5,11},{7,4,5},{7,8,54},{7,5,9},{9,8,512},{7,4,6}, -{7,8,36},{9,5,128},{7,8,52},{7,6,15},{7,8,0},{7,4,4},{7,4,2},{7,4,7},{7,6,13},{7,4,3}, -{9,9,1600},{7,4,5},{7,8,44},{7,6,17},{9,9,1344},{7,4,6},{7,6,1},{7,5,8},{9,6,192},{9,5,64}, -{7,5,10},{7,4,4},{7,4,2},{7,4,7},{7,8,30},{7,4,3},{7,5,11},{7,4,5},{7,6,12},{7,5,9}, -{9,6,1664},{7,4,6},{7,8,34},{9,5,128},{7,8,50},{7,6,14},{7,8,62},{7,4,4},{7,4,2},{7,4,7}, -{7,8,48},{7,4,3},{7,8,60},{7,4,5},{7,8,42},{7,6,16},{9,9,1088},{7,4,6},{7,8,32},{7,5,8}, -{7,8,58},{9,5,64},{7,5,10},{7,4,4},{7,4,2},{7,4,7},{7,7,22},{7,4,3},{7,5,11},{7,4,5}, -{7,7,26},{7,5,9},{9,8,640},{7,4,6},{7,8,38},{9,5,128},{7,7,25},{7,6,15},{9,8,384},{7,4,4}, -{7,4,2},{7,4,7},{7,6,13},{7,4,3},{7,7,18},{7,4,5},{7,7,21},{7,6,17},{9,7,256},{7,4,6}, -{7,6,1},{7,5,8},{9,6,192},{9,5,64},{7,5,10},{7,4,4},{7,4,2},{7,4,7},{0,0,0},{7,4,3}, -{7,5,11},{7,4,5},{7,6,12},{7,5,9},{9,6,1664},{7,4,6},{7,7,20},{9,5,128},{7,7,24},{7,6,14}, -{7,7,28},{7,4,4},{7,4,2},{7,4,7},{7,7,23},{7,4,3},{7,7,27},{7,4,5},{7,8,39},{7,6,16}, -{9,8,576},{7,4,6},{7,7,19},{7,5,8},{7,8,55},{9,5,64},{7,5,10},{7,4,4},{7,4,2},{7,4,7}, -{7,8,45},{7,4,3},{7,5,11},{7,4,5},{7,8,53},{7,5,9},{9,8,448},{7,4,6},{7,8,35},{9,5,128}, -{7,8,51},{7,6,15},{7,8,63},{7,4,4},{7,4,2},{7,4,7},{7,6,13},{7,4,3},{9,9,1536},{7,4,5}, -{7,8,43},{7,6,17},{9,9,1280},{7,4,6},{7,6,1},{7,5,8},{9,6,192},{9,5,64},{7,5,10},{7,4,4}, -{7,4,2},{7,4,7},{7,8,29},{7,4,3},{7,5,11},{7,4,5},{7,6,12},{7,5,9},{9,6,1664},{7,4,6}, -{7,8,33},{9,5,128},{7,8,49},{7,6,14},{7,8,61},{7,4,4},{7,4,2},{7,4,7},{7,8,47},{7,4,3}, -{7,8,59},{7,4,5},{7,8,41},{7,6,16},{9,9,1024},{7,4,6},{7,8,31},{7,5,8},{7,8,57},{9,5,64}, -{7,5,10},{7,4,4},{7,4,2},{7,4,7},{7,7,22},{7,4,3},{7,5,11},{7,4,5},{7,7,26},{7,5,9}, -{9,9,768},{7,4,6},{7,8,37},{9,5,128},{7,7,25},{7,6,15},{9,8,320},{7,4,4},{7,4,2},{7,4,7}, -{7,6,13},{7,4,3},{7,7,18},{7,4,5},{7,7,21},{7,6,17},{9,7,256},{7,4,6},{7,6,1},{7,5,8}, -{9,6,192},{9,5,64},{7,5,10},{7,4,4},{7,4,2},{7,4,7},{11,11,1920},{7,4,3},{7,5,11},{7,4,5}, -{7,6,12},{7,5,9},{9,6,1664},{7,4,6},{7,7,20},{9,5,128},{7,7,24},{7,6,14},{7,7,28},{7,4,4}, -{7,4,2},{7,4,7},{7,7,23},{7,4,3},{7,7,27},{7,4,5},{7,8,40},{7,6,16},{9,9,896},{7,4,6}, -{7,7,19},{7,5,8},{7,8,56},{9,5,64},{7,5,10},{7,4,4},{7,4,2},{7,4,7},{7,8,46},{7,4,3}, -{7,5,11},{7,4,5},{7,8,54},{7,5,9},{9,8,512},{7,4,6},{7,8,36},{9,5,128},{7,8,52},{7,6,15}, -{7,8,0},{7,4,4},{7,4,2},{7,4,7},{7,6,13},{7,4,3},{9,9,1728},{7,4,5},{7,8,44},{7,6,17}, -{9,9,1408},{7,4,6},{7,6,1},{7,5,8},{9,6,192},{9,5,64},{7,5,10},{7,4,4},{7,4,2},{7,4,7}, -{7,8,30},{7,4,3},{7,5,11},{7,4,5},{7,6,12},{7,5,9},{9,6,1664},{7,4,6},{7,8,34},{9,5,128}, -{7,8,50},{7,6,14},{7,8,62},{7,4,4},{7,4,2},{7,4,7},{7,8,48},{7,4,3},{7,8,60},{7,4,5}, -{7,8,42},{7,6,16},{9,9,1152},{7,4,6},{7,8,32},{7,5,8},{7,8,58},{9,5,64},{7,5,10},{7,4,4}, -{7,4,2},{7,4,7},{7,7,22},{7,4,3},{7,5,11},{7,4,5},{7,7,26},{7,5,9},{9,8,640},{7,4,6}, -{7,8,38},{9,5,128},{7,7,25},{7,6,15},{9,8,384},{7,4,4},{7,4,2},{7,4,7},{7,6,13},{7,4,3}, -{7,7,18},{7,4,5},{7,7,21},{7,6,17},{9,7,256},{7,4,6},{7,6,1},{7,5,8},{9,6,192},{9,5,64}, -{7,5,10},{7,4,4},{7,4,2},{7,4,7},{0,0,0},{7,4,3},{7,5,11},{7,4,5},{7,6,12},{7,5,9}, -{9,6,1664},{7,4,6},{7,7,20},{9,5,128},{7,7,24},{7,6,14},{7,7,28},{7,4,4},{7,4,2},{7,4,7}, -{7,7,23},{7,4,3},{7,7,27},{7,4,5},{7,8,39},{7,6,16},{9,8,576},{7,4,6},{7,7,19},{7,5,8}, -{7,8,55},{9,5,64},{7,5,10},{7,4,4},{7,4,2},{7,4,7},{7,8,45},{7,4,3},{7,5,11},{7,4,5}, -{7,8,53},{7,5,9},{9,8,448},{7,4,6},{7,8,35},{9,5,128},{7,8,51},{7,6,15},{7,8,63},{7,4,4}, -{7,4,2},{7,4,7},{7,6,13},{7,4,3},{9,9,1472},{7,4,5},{7,8,43},{7,6,17},{9,9,1216},{7,4,6}, -{7,6,1},{7,5,8},{9,6,192},{9,5,64},{7,5,10},{7,4,4},{7,4,2},{7,4,7},{7,8,29},{7,4,3}, -{7,5,11},{7,4,5},{7,6,12},{7,5,9},{9,6,1664},{7,4,6},{7,8,33},{9,5,128},{7,8,49},{7,6,14}, -{7,8,61},{7,4,4},{7,4,2},{7,4,7},{7,8,47},{7,4,3},{7,8,59},{7,4,5},{7,8,41},{7,6,16}, -{9,9,960},{7,4,6},{7,8,31},{7,5,8},{7,8,57},{9,5,64},{7,5,10},{7,4,4},{7,4,2},{7,4,7}, -{7,7,22},{7,4,3},{7,5,11},{7,4,5},{7,7,26},{7,5,9},{9,9,704},{7,4,6},{7,8,37},{9,5,128}, -{7,7,25},{7,6,15},{9,8,320},{7,4,4},{7,4,2},{7,4,7},{7,6,13},{7,4,3},{7,7,18},{7,4,5}, -{7,7,21},{7,6,17},{9,7,256},{7,4,6},{7,6,1},{7,5,8},{9,6,192},{9,5,64},{7,5,10},{7,4,4}, -{7,4,2},{7,4,7},{11,12,2304},{7,4,3},{7,5,11},{7,4,5},{7,6,12},{7,5,9},{9,6,1664},{7,4,6}, -{7,7,20},{9,5,128},{7,7,24},{7,6,14},{7,7,28},{7,4,4},{7,4,2},{7,4,7},{7,7,23},{7,4,3}, -{7,7,27},{7,4,5},{7,8,40},{7,6,16},{9,9,832},{7,4,6},{7,7,19},{7,5,8},{7,8,56},{9,5,64}, -{7,5,10},{7,4,4},{7,4,2},{7,4,7},{7,8,46},{7,4,3},{7,5,11},{7,4,5},{7,8,54},{7,5,9}, -{9,8,512},{7,4,6},{7,8,36},{9,5,128},{7,8,52},{7,6,15},{7,8,0},{7,4,4},{7,4,2},{7,4,7}, -{7,6,13},{7,4,3},{9,9,1600},{7,4,5},{7,8,44},{7,6,17},{9,9,1344},{7,4,6},{7,6,1},{7,5,8}, -{9,6,192},{9,5,64},{7,5,10},{7,4,4},{7,4,2},{7,4,7},{7,8,30},{7,4,3},{7,5,11},{7,4,5}, -{7,6,12},{7,5,9},{9,6,1664},{7,4,6},{7,8,34},{9,5,128},{7,8,50},{7,6,14},{7,8,62},{7,4,4}, -{7,4,2},{7,4,7},{7,8,48},{7,4,3},{7,8,60},{7,4,5},{7,8,42},{7,6,16},{9,9,1088},{7,4,6}, -{7,8,32},{7,5,8},{7,8,58},{9,5,64},{7,5,10},{7,4,4},{7,4,2},{7,4,7},{7,7,22},{7,4,3}, -{7,5,11},{7,4,5},{7,7,26},{7,5,9},{9,8,640},{7,4,6},{7,8,38},{9,5,128},{7,7,25},{7,6,15}, -{9,8,384},{7,4,4},{7,4,2},{7,4,7},{7,6,13},{7,4,3},{7,7,18},{7,4,5},{7,7,21},{7,6,17}, -{9,7,256},{7,4,6},{7,6,1},{7,5,8},{9,6,192},{9,5,64},{7,5,10},{7,4,4},{7,4,2},{7,4,7}, -{0,0,0},{7,4,3},{7,5,11},{7,4,5},{7,6,12},{7,5,9},{9,6,1664},{7,4,6},{7,7,20},{9,5,128}, -{7,7,24},{7,6,14},{7,7,28},{7,4,4},{7,4,2},{7,4,7},{7,7,23},{7,4,3},{7,7,27},{7,4,5}, -{7,8,39},{7,6,16},{9,8,576},{7,4,6},{7,7,19},{7,5,8},{7,8,55},{9,5,64},{7,5,10},{7,4,4}, -{7,4,2},{7,4,7},{7,8,45},{7,4,3},{7,5,11},{7,4,5},{7,8,53},{7,5,9},{9,8,448},{7,4,6}, -{7,8,35},{9,5,128},{7,8,51},{7,6,15},{7,8,63},{7,4,4},{7,4,2},{7,4,7},{7,6,13},{7,4,3}, -{9,9,1536},{7,4,5},{7,8,43},{7,6,17},{9,9,1280},{7,4,6},{7,6,1},{7,5,8},{9,6,192},{9,5,64}, -{7,5,10},{7,4,4},{7,4,2},{7,4,7},{7,8,29},{7,4,3},{7,5,11},{7,4,5},{7,6,12},{7,5,9}, -{9,6,1664},{7,4,6},{7,8,33},{9,5,128},{7,8,49},{7,6,14},{7,8,61},{7,4,4},{7,4,2},{7,4,7}, -{7,8,47},{7,4,3},{7,8,59},{7,4,5},{7,8,41},{7,6,16},{9,9,1024},{7,4,6},{7,8,31},{7,5,8}, -{7,8,57},{9,5,64},{7,5,10},{7,4,4},{7,4,2},{7,4,7},{7,7,22},{7,4,3},{7,5,11},{7,4,5}, -{7,7,26},{7,5,9},{9,9,768},{7,4,6},{7,8,37},{9,5,128},{7,7,25},{7,6,15},{9,8,320},{7,4,4}, -{7,4,2},{7,4,7},{7,6,13},{7,4,3},{7,7,18},{7,4,5},{7,7,21},{7,6,17},{9,7,256},{7,4,6}, -{7,6,1},{7,5,8},{9,6,192},{9,5,64},{7,5,10},{7,4,4},{7,4,2},{7,4,7},{11,12,2560},{7,4,3}, -{7,5,11},{7,4,5},{7,6,12},{7,5,9},{9,6,1664},{7,4,6},{7,7,20},{9,5,128},{7,7,24},{7,6,14}, -{7,7,28},{7,4,4},{7,4,2},{7,4,7},{7,7,23},{7,4,3},{7,7,27},{7,4,5},{7,8,40},{7,6,16}, -{9,9,896},{7,4,6},{7,7,19},{7,5,8},{7,8,56},{9,5,64},{7,5,10},{7,4,4},{7,4,2},{7,4,7}, -{7,8,46},{7,4,3},{7,5,11},{7,4,5},{7,8,54},{7,5,9},{9,8,512},{7,4,6},{7,8,36},{9,5,128}, -{7,8,52},{7,6,15},{7,8,0},{7,4,4},{7,4,2},{7,4,7},{7,6,13},{7,4,3},{9,9,1728},{7,4,5}, -{7,8,44},{7,6,17},{9,9,1408},{7,4,6},{7,6,1},{7,5,8},{9,6,192},{9,5,64},{7,5,10},{7,4,4}, -{7,4,2},{7,4,7},{7,8,30},{7,4,3},{7,5,11},{7,4,5},{7,6,12},{7,5,9},{9,6,1664},{7,4,6}, -{7,8,34},{9,5,128},{7,8,50},{7,6,14},{7,8,62},{7,4,4},{7,4,2},{7,4,7},{7,8,48},{7,4,3}, -{7,8,60},{7,4,5},{7,8,42},{7,6,16},{9,9,1152},{7,4,6},{7,8,32},{7,5,8},{7,8,58},{9,5,64}, -{7,5,10},{7,4,4},{7,4,2},{7,4,7},{7,7,22},{7,4,3},{7,5,11},{7,4,5},{7,7,26},{7,5,9}, -{9,8,640},{7,4,6},{7,8,38},{9,5,128},{7,7,25},{7,6,15},{9,8,384},{7,4,4},{7,4,2},{7,4,7}, -{7,6,13},{7,4,3},{7,7,18},{7,4,5},{7,7,21},{7,6,17},{9,7,256},{7,4,6},{7,6,1},{7,5,8}, -{9,6,192},{9,5,64},{7,5,10},{7,4,4},{7,4,2},{7,4,7} -}; - const TIFFFaxTabEnt TIFFFaxBlackTable[8192] = { -{12,11,0},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,9},{8,2,3}, -{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,10},{8,2,3},{8,3,1},{8,2,2}, -{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3}, -{8,3,4},{8,2,2},{8,8,13},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2}, -{8,6,8},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,9,15},{8,2,3}, -{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2}, -{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,10,18},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3}, -{8,3,4},{8,2,2},{8,6,9},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2}, -{8,7,11},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3}, -{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,10,17},{8,2,3},{8,3,1},{8,2,2}, -{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,8},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3}, -{8,3,4},{8,2,2},{8,7,12},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2}, -{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{11,11,1792},{8,2,3}, -{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,9},{8,2,3},{8,3,1},{8,2,2}, -{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,10},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3}, -{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2}, -{8,11,23},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,8},{8,2,3}, -{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,11,20},{8,2,3},{8,3,1},{8,2,2}, -{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3}, -{8,3,4},{8,2,2},{8,11,25},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2}, -{8,6,9},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,11},{8,2,3}, -{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2}, -{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,8,14},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3}, -{8,3,4},{8,2,2},{8,6,8},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2}, -{8,7,12},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3}, -{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{0,0,0},{8,2,3},{8,3,1},{8,2,2}, -{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,9},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3}, -{8,3,4},{8,2,2},{8,7,10},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2}, -{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,8,13},{8,2,3}, -{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,8},{8,2,3},{8,3,1},{8,2,2}, -{8,4,5},{8,2,3},{8,3,4},{8,2,2},{10,12,128},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3}, -{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2}, -{8,12,56},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,9},{8,2,3}, -{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,11},{8,2,3},{8,3,1},{8,2,2}, -{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3}, -{8,3,4},{8,2,2},{8,12,30},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2}, -{8,6,8},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,12},{8,2,3}, -{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2}, -{8,4,5},{8,2,3},{8,3,4},{8,2,2},{11,11,1856},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3}, -{8,3,4},{8,2,2},{8,6,9},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2}, -{8,7,10},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3}, -{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,12,57},{8,2,3},{8,3,1},{8,2,2}, -{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,8},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3}, -{8,3,4},{8,2,2},{8,11,21},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2}, -{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,12,54},{8,2,3}, -{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,9},{8,2,3},{8,3,1},{8,2,2}, -{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,11},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3}, -{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2}, -{8,8,14},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,8},{8,2,3}, -{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,12},{8,2,3},{8,3,1},{8,2,2}, -{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3}, -{8,3,4},{8,2,2},{0,0,0},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2}, -{8,6,9},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,10},{8,2,3}, -{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2}, -{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,8,13},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3}, -{8,3,4},{8,2,2},{8,6,8},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2}, -{8,9,15},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3}, -{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,12,52},{8,2,3},{8,3,1},{8,2,2}, -{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,9},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3}, -{8,3,4},{8,2,2},{8,7,11},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2}, -{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,12,48},{8,2,3}, -{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,8},{8,2,3},{8,3,1},{8,2,2}, -{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,12},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3}, -{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2}, -{11,12,2112},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,9},{8,2,3}, -{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,10},{8,2,3},{8,3,1},{8,2,2}, -{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3}, -{8,3,4},{8,2,2},{8,12,44},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2}, -{8,6,8},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,12,36},{8,2,3}, -{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2}, -{8,4,5},{8,2,3},{8,3,4},{8,2,2},{10,12,384},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3}, -{8,3,4},{8,2,2},{8,6,9},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2}, -{8,7,11},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3}, -{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,8,14},{8,2,3},{8,3,1},{8,2,2}, -{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,8},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3}, -{8,3,4},{8,2,2},{8,7,12},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2}, -{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{0,0,0},{8,2,3}, -{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,9},{8,2,3},{8,3,1},{8,2,2}, -{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,10},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3}, -{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2}, -{8,8,13},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,8},{8,2,3}, -{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,12,28},{8,2,3},{8,3,1},{8,2,2}, -{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3}, -{8,3,4},{8,2,2},{8,12,60},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2}, -{8,6,9},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,11},{8,2,3}, -{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2}, -{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,12,40},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3}, -{8,3,4},{8,2,2},{8,6,8},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2}, -{8,7,12},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3}, -{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{11,12,2368},{8,2,3},{8,3,1},{8,2,2}, -{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,9},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3}, -{8,3,4},{8,2,2},{8,7,10},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2}, -{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,10,16},{8,2,3}, -{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,8},{8,2,3},{8,3,1},{8,2,2}, -{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,10,0},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3}, -{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2}, -{10,10,64},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,9},{8,2,3}, -{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,11},{8,2,3},{8,3,1},{8,2,2}, -{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3}, -{8,3,4},{8,2,2},{8,8,14},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2}, -{8,6,8},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,12},{8,2,3}, -{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2}, -{8,4,5},{8,2,3},{8,3,4},{8,2,2},{0,0,0},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3}, -{8,3,4},{8,2,2},{8,6,9},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2}, -{8,7,10},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3}, -{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,8,13},{8,2,3},{8,3,1},{8,2,2}, -{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,8},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3}, -{8,3,4},{8,2,2},{8,9,15},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2}, -{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,10,18},{8,2,3}, -{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,9},{8,2,3},{8,3,1},{8,2,2}, -{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,11},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3}, -{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2}, -{8,10,17},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,8},{8,2,3}, -{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,12},{8,2,3},{8,3,1},{8,2,2}, -{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3}, -{8,3,4},{8,2,2},{11,12,1984},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2}, -{8,6,9},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,10},{8,2,3}, -{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2}, -{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,12,50},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3}, -{8,3,4},{8,2,2},{8,6,8},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2}, -{8,12,34},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3}, -{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{10,13,1664},{8,2,3},{8,3,1},{8,2,2}, -{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,9},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3}, -{8,3,4},{8,2,2},{8,7,11},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2}, -{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,8,14},{8,2,3}, -{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,8},{8,2,3},{8,3,1},{8,2,2}, -{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,12},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3}, -{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2}, -{0,0,0},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,9},{8,2,3}, -{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,10},{8,2,3},{8,3,1},{8,2,2}, -{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3}, -{8,3,4},{8,2,2},{8,8,13},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2}, -{8,6,8},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,12,26},{8,2,3}, -{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2}, -{8,4,5},{8,2,3},{8,3,4},{8,2,2},{10,13,1408},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3}, -{8,3,4},{8,2,2},{8,6,9},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2}, -{8,7,11},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3}, -{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,12,32},{8,2,3},{8,3,1},{8,2,2}, -{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,8},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3}, -{8,3,4},{8,2,2},{8,7,12},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2}, -{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{11,11,1920},{8,2,3}, -{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,9},{8,2,3},{8,3,1},{8,2,2}, -{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,10},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3}, -{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2}, -{8,12,61},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,8},{8,2,3}, -{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,12,42},{8,2,3},{8,3,1},{8,2,2}, -{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3}, -{8,3,4},{8,2,2},{10,13,1024},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2}, -{8,6,9},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,11},{8,2,3}, -{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2}, -{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,8,14},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3}, -{8,3,4},{8,2,2},{8,6,8},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2}, -{8,7,12},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3}, -{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{0,0,0},{8,2,3},{8,3,1},{8,2,2}, -{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,9},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3}, -{8,3,4},{8,2,2},{8,7,10},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2}, -{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,8,13},{8,2,3}, -{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,8},{8,2,3},{8,3,1},{8,2,2}, -{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,9,15},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3}, -{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2}, -{10,13,768},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,9},{8,2,3}, -{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,11},{8,2,3},{8,3,1},{8,2,2}, -{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3}, -{8,3,4},{8,2,2},{8,12,62},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2}, -{8,6,8},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,12},{8,2,3}, -{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2}, -{8,4,5},{8,2,3},{8,3,4},{8,2,2},{11,12,2240},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3}, -{8,3,4},{8,2,2},{8,6,9},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2}, -{8,7,10},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3}, -{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,12,46},{8,2,3},{8,3,1},{8,2,2}, -{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,8},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3}, -{8,3,4},{8,2,2},{8,12,38},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2}, -{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{10,13,512},{8,2,3}, -{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,9},{8,2,3},{8,3,1},{8,2,2}, -{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,11},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3}, -{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2}, -{8,8,14},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,8},{8,2,3}, -{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,12},{8,2,3},{8,3,1},{8,2,2}, -{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3}, -{8,3,4},{8,2,2},{0,0,0},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2}, -{8,6,9},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,10},{8,2,3}, -{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2}, -{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,8,13},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3}, -{8,3,4},{8,2,2},{8,6,8},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2}, -{8,11,19},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3}, -{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,11,24},{8,2,3},{8,3,1},{8,2,2}, -{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,9},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3}, -{8,3,4},{8,2,2},{8,7,11},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2}, -{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,11,22},{8,2,3}, -{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,8},{8,2,3},{8,3,1},{8,2,2}, -{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,12},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3}, -{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2}, -{11,12,2496},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,9},{8,2,3}, -{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,10},{8,2,3},{8,3,1},{8,2,2}, -{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3}, -{8,3,4},{8,2,2},{8,10,16},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2}, -{8,6,8},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,10,0},{8,2,3}, -{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2}, -{8,4,5},{8,2,3},{8,3,4},{8,2,2},{10,10,64},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3}, -{8,3,4},{8,2,2},{8,6,9},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2}, -{8,7,11},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3}, -{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,8,14},{8,2,3},{8,3,1},{8,2,2}, -{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,8},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3}, -{8,3,4},{8,2,2},{8,7,12},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2}, -{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{12,11,0},{8,2,3}, -{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,9},{8,2,3},{8,3,1},{8,2,2}, -{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,10},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3}, -{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2}, -{8,8,13},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,8},{8,2,3}, -{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,9,15},{8,2,3},{8,3,1},{8,2,2}, -{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3}, -{8,3,4},{8,2,2},{8,10,18},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2}, -{8,6,9},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,11},{8,2,3}, -{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2}, -{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,10,17},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3}, -{8,3,4},{8,2,2},{8,6,8},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2}, -{8,7,12},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3}, -{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{11,11,1792},{8,2,3},{8,3,1},{8,2,2}, -{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,9},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3}, -{8,3,4},{8,2,2},{8,7,10},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2}, -{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,11,23},{8,2,3}, -{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,8},{8,2,3},{8,3,1},{8,2,2}, -{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,11,20},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3}, -{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2}, -{8,11,25},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,9},{8,2,3}, -{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,11},{8,2,3},{8,3,1},{8,2,2}, -{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3}, -{8,3,4},{8,2,2},{8,8,14},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2}, -{8,6,8},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,12},{8,2,3}, -{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2}, -{8,4,5},{8,2,3},{8,3,4},{8,2,2},{0,0,0},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3}, -{8,3,4},{8,2,2},{8,6,9},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2}, -{8,7,10},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3}, -{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,8,13},{8,2,3},{8,3,1},{8,2,2}, -{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,8},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3}, -{8,3,4},{8,2,2},{10,12,192},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2}, -{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{10,13,1280},{8,2,3}, -{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,9},{8,2,3},{8,3,1},{8,2,2}, -{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,11},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3}, -{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2}, -{8,12,31},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,8},{8,2,3}, -{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,12},{8,2,3},{8,3,1},{8,2,2}, -{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3}, -{8,3,4},{8,2,2},{11,11,1856},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2}, -{8,6,9},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,10},{8,2,3}, -{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2}, -{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,12,58},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3}, -{8,3,4},{8,2,2},{8,6,8},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2}, -{8,11,21},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3}, -{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{10,13,896},{8,2,3},{8,3,1},{8,2,2}, -{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,9},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3}, -{8,3,4},{8,2,2},{8,7,11},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2}, -{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,8,14},{8,2,3}, -{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,8},{8,2,3},{8,3,1},{8,2,2}, -{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,12},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3}, -{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2}, -{0,0,0},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,9},{8,2,3}, -{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,10},{8,2,3},{8,3,1},{8,2,2}, -{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3}, -{8,3,4},{8,2,2},{8,8,13},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2}, -{8,6,8},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,9,15},{8,2,3}, -{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2}, -{8,4,5},{8,2,3},{8,3,4},{8,2,2},{10,13,640},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3}, -{8,3,4},{8,2,2},{8,6,9},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2}, -{8,7,11},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3}, -{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,12,49},{8,2,3},{8,3,1},{8,2,2}, -{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,8},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3}, -{8,3,4},{8,2,2},{8,7,12},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2}, -{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{11,12,2176},{8,2,3}, -{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,9},{8,2,3},{8,3,1},{8,2,2}, -{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,10},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3}, -{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2}, -{8,12,45},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,8},{8,2,3}, -{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,12,37},{8,2,3},{8,3,1},{8,2,2}, -{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3}, -{8,3,4},{8,2,2},{10,12,448},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2}, -{8,6,9},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,11},{8,2,3}, -{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2}, -{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,8,14},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3}, -{8,3,4},{8,2,2},{8,6,8},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2}, -{8,7,12},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3}, -{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{0,0,0},{8,2,3},{8,3,1},{8,2,2}, -{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,9},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3}, -{8,3,4},{8,2,2},{8,7,10},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2}, -{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,8,13},{8,2,3}, -{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,8},{8,2,3},{8,3,1},{8,2,2}, -{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,12,29},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3}, -{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2}, -{10,13,1536},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,9},{8,2,3}, -{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,11},{8,2,3},{8,3,1},{8,2,2}, -{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3}, -{8,3,4},{8,2,2},{8,12,41},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2}, -{8,6,8},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,12},{8,2,3}, -{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2}, -{8,4,5},{8,2,3},{8,3,4},{8,2,2},{11,12,2432},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3}, -{8,3,4},{8,2,2},{8,6,9},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2}, -{8,7,10},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3}, -{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,10,16},{8,2,3},{8,3,1},{8,2,2}, -{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,8},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3}, -{8,3,4},{8,2,2},{8,10,0},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2}, -{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{10,10,64},{8,2,3}, -{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,9},{8,2,3},{8,3,1},{8,2,2}, -{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,11},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3}, -{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2}, -{8,8,14},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,8},{8,2,3}, -{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,12},{8,2,3},{8,3,1},{8,2,2}, -{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3}, -{8,3,4},{8,2,2},{0,0,0},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2}, -{8,6,9},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,10},{8,2,3}, -{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2}, -{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,8,13},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3}, -{8,3,4},{8,2,2},{8,6,8},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2}, -{8,9,15},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3}, -{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,10,18},{8,2,3},{8,3,1},{8,2,2}, -{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,9},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3}, -{8,3,4},{8,2,2},{8,7,11},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2}, -{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,10,17},{8,2,3}, -{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,8},{8,2,3},{8,3,1},{8,2,2}, -{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,12},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3}, -{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2}, -{11,12,2048},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,9},{8,2,3}, -{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,10},{8,2,3},{8,3,1},{8,2,2}, -{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3}, -{8,3,4},{8,2,2},{8,12,51},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2}, -{8,6,8},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,12,35},{8,2,3}, -{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2}, -{8,4,5},{8,2,3},{8,3,4},{8,2,2},{10,12,320},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3}, -{8,3,4},{8,2,2},{8,6,9},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2}, -{8,7,11},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3}, -{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,8,14},{8,2,3},{8,3,1},{8,2,2}, -{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,8},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3}, -{8,3,4},{8,2,2},{8,7,12},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2}, -{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{0,0,0},{8,2,3}, -{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,9},{8,2,3},{8,3,1},{8,2,2}, -{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,10},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3}, -{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2}, -{8,8,13},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,8},{8,2,3}, -{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,12,27},{8,2,3},{8,3,1},{8,2,2}, -{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3}, -{8,3,4},{8,2,2},{8,12,59},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2}, -{8,6,9},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,11},{8,2,3}, -{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2}, -{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,12,33},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3}, -{8,3,4},{8,2,2},{8,6,8},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2}, -{8,7,12},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3}, -{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{11,11,1920},{8,2,3},{8,3,1},{8,2,2}, -{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,9},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3}, -{8,3,4},{8,2,2},{8,7,10},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2}, -{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{10,12,256},{8,2,3}, -{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,8},{8,2,3},{8,3,1},{8,2,2}, -{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,12,43},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3}, -{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2}, -{10,13,1152},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,9},{8,2,3}, -{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,11},{8,2,3},{8,3,1},{8,2,2}, -{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3}, -{8,3,4},{8,2,2},{8,8,14},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2}, -{8,6,8},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,12},{8,2,3}, -{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2}, -{8,4,5},{8,2,3},{8,3,4},{8,2,2},{0,0,0},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3}, -{8,3,4},{8,2,2},{8,6,9},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2}, -{8,7,10},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3}, -{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,8,13},{8,2,3},{8,3,1},{8,2,2}, -{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,8},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3}, -{8,3,4},{8,2,2},{8,9,15},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2}, -{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,12,55},{8,2,3}, -{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,9},{8,2,3},{8,3,1},{8,2,2}, -{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,11},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3}, -{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2}, -{8,12,63},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,8},{8,2,3}, -{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,12},{8,2,3},{8,3,1},{8,2,2}, -{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3}, -{8,3,4},{8,2,2},{11,12,2304},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2}, -{8,6,9},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,10},{8,2,3}, -{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2}, -{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,12,47},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3}, -{8,3,4},{8,2,2},{8,6,8},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2}, -{8,12,39},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3}, -{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,12,53},{8,2,3},{8,3,1},{8,2,2}, -{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,9},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3}, -{8,3,4},{8,2,2},{8,7,11},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2}, -{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,8,14},{8,2,3}, -{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,8},{8,2,3},{8,3,1},{8,2,2}, -{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,12},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3}, -{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2}, -{0,0,0},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,9},{8,2,3}, -{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,10},{8,2,3},{8,3,1},{8,2,2}, -{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3}, -{8,3,4},{8,2,2},{8,8,13},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2}, -{8,6,8},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,11,19},{8,2,3}, -{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2}, -{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,11,24},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3}, -{8,3,4},{8,2,2},{8,6,9},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2}, -{8,7,11},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3}, -{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,11,22},{8,2,3},{8,3,1},{8,2,2}, -{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,8},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3}, -{8,3,4},{8,2,2},{8,7,12},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2}, -{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{11,12,2560},{8,2,3}, -{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,9},{8,2,3},{8,3,1},{8,2,2}, -{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,10},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3}, -{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2}, -{8,10,16},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,8},{8,2,3}, -{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,10,0},{8,2,3},{8,3,1},{8,2,2}, -{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3}, -{8,3,4},{8,2,2},{10,10,64},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2}, -{8,6,9},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,11},{8,2,3}, -{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2}, -{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,8,14},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3}, -{8,3,4},{8,2,2},{8,6,8},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2}, -{8,7,12},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3}, -{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{12,11,0},{8,2,3},{8,3,1},{8,2,2}, -{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,9},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3}, -{8,3,4},{8,2,2},{8,7,10},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2}, -{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,8,13},{8,2,3}, -{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,8},{8,2,3},{8,3,1},{8,2,2}, -{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,9,15},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3}, -{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2}, -{8,10,18},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,9},{8,2,3}, -{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,11},{8,2,3},{8,3,1},{8,2,2}, -{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3}, -{8,3,4},{8,2,2},{8,10,17},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2}, -{8,6,8},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,12},{8,2,3}, -{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2}, -{8,4,5},{8,2,3},{8,3,4},{8,2,2},{11,11,1792},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3}, -{8,3,4},{8,2,2},{8,6,9},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2}, -{8,7,10},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3}, -{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,11,23},{8,2,3},{8,3,1},{8,2,2}, -{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,8},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3}, -{8,3,4},{8,2,2},{8,11,20},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2}, -{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,11,25},{8,2,3}, -{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,9},{8,2,3},{8,3,1},{8,2,2}, -{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,11},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3}, -{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2}, -{8,8,14},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,8},{8,2,3}, -{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,12},{8,2,3},{8,3,1},{8,2,2}, -{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3}, -{8,3,4},{8,2,2},{0,0,0},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2}, -{8,6,9},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,10},{8,2,3}, -{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2}, -{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,8,13},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3}, -{8,3,4},{8,2,2},{8,6,8},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2}, -{10,12,128},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3}, -{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,12,56},{8,2,3},{8,3,1},{8,2,2}, -{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,9},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3}, -{8,3,4},{8,2,2},{8,7,11},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2}, -{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,12,30},{8,2,3}, -{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,8},{8,2,3},{8,3,1},{8,2,2}, -{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,12},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3}, -{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2}, -{11,11,1856},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,9},{8,2,3}, -{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,10},{8,2,3},{8,3,1},{8,2,2}, -{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3}, -{8,3,4},{8,2,2},{8,12,57},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2}, -{8,6,8},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,11,21},{8,2,3}, -{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2}, -{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,12,54},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3}, -{8,3,4},{8,2,2},{8,6,9},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2}, -{8,7,11},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3}, -{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,8,14},{8,2,3},{8,3,1},{8,2,2}, -{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,8},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3}, -{8,3,4},{8,2,2},{8,7,12},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2}, -{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{0,0,0},{8,2,3}, -{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,9},{8,2,3},{8,3,1},{8,2,2}, -{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,10},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3}, -{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2}, -{8,8,13},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,8},{8,2,3}, -{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,9,15},{8,2,3},{8,3,1},{8,2,2}, -{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3}, -{8,3,4},{8,2,2},{8,12,52},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2}, -{8,6,9},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,11},{8,2,3}, -{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2}, -{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,12,48},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3}, -{8,3,4},{8,2,2},{8,6,8},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2}, -{8,7,12},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3}, -{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{11,12,2112},{8,2,3},{8,3,1},{8,2,2}, -{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,9},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3}, -{8,3,4},{8,2,2},{8,7,10},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2}, -{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,12,44},{8,2,3}, -{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,8},{8,2,3},{8,3,1},{8,2,2}, -{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,12,36},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3}, -{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2}, -{10,12,384},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,9},{8,2,3}, -{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,11},{8,2,3},{8,3,1},{8,2,2}, -{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3}, -{8,3,4},{8,2,2},{8,8,14},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2}, -{8,6,8},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,12},{8,2,3}, -{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2}, -{8,4,5},{8,2,3},{8,3,4},{8,2,2},{0,0,0},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3}, -{8,3,4},{8,2,2},{8,6,9},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2}, -{8,7,10},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3}, -{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,8,13},{8,2,3},{8,3,1},{8,2,2}, -{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,8},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3}, -{8,3,4},{8,2,2},{8,12,28},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2}, -{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,12,60},{8,2,3}, -{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,9},{8,2,3},{8,3,1},{8,2,2}, -{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,11},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3}, -{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2}, -{8,12,40},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,8},{8,2,3}, -{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,12},{8,2,3},{8,3,1},{8,2,2}, -{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3}, -{8,3,4},{8,2,2},{11,12,2368},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2}, -{8,6,9},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,10},{8,2,3}, -{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2}, -{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,10,16},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3}, -{8,3,4},{8,2,2},{8,6,8},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2}, -{8,10,0},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3}, -{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{10,10,64},{8,2,3},{8,3,1},{8,2,2}, -{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,9},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3}, -{8,3,4},{8,2,2},{8,7,11},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2}, -{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,8,14},{8,2,3}, -{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,8},{8,2,3},{8,3,1},{8,2,2}, -{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,12},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3}, -{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2}, -{0,0,0},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,9},{8,2,3}, -{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,10},{8,2,3},{8,3,1},{8,2,2}, -{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3}, -{8,3,4},{8,2,2},{8,8,13},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2}, -{8,6,8},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,9,15},{8,2,3}, -{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2}, -{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,10,18},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3}, -{8,3,4},{8,2,2},{8,6,9},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2}, -{8,7,11},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3}, -{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,10,17},{8,2,3},{8,3,1},{8,2,2}, -{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,8},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3}, -{8,3,4},{8,2,2},{8,7,12},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2}, -{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{11,12,1984},{8,2,3}, -{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,9},{8,2,3},{8,3,1},{8,2,2}, -{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,10},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3}, -{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2}, -{8,12,50},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,8},{8,2,3}, -{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,12,34},{8,2,3},{8,3,1},{8,2,2}, -{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3}, -{8,3,4},{8,2,2},{10,13,1728},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2}, -{8,6,9},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,11},{8,2,3}, -{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2}, -{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,8,14},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3}, -{8,3,4},{8,2,2},{8,6,8},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2}, -{8,7,12},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3}, -{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{0,0,0},{8,2,3},{8,3,1},{8,2,2}, -{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,9},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3}, -{8,3,4},{8,2,2},{8,7,10},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2}, -{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,8,13},{8,2,3}, -{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,8},{8,2,3},{8,3,1},{8,2,2}, -{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,12,26},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3}, -{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2}, -{10,13,1472},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,9},{8,2,3}, -{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,11},{8,2,3},{8,3,1},{8,2,2}, -{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3}, -{8,3,4},{8,2,2},{8,12,32},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2}, -{8,6,8},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,12},{8,2,3}, -{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2}, -{8,4,5},{8,2,3},{8,3,4},{8,2,2},{11,11,1920},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3}, -{8,3,4},{8,2,2},{8,6,9},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2}, -{8,7,10},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3}, -{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,12,61},{8,2,3},{8,3,1},{8,2,2}, -{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,8},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3}, -{8,3,4},{8,2,2},{8,12,42},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2}, -{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{10,13,1088},{8,2,3}, -{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,9},{8,2,3},{8,3,1},{8,2,2}, -{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,11},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3}, -{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2}, -{8,8,14},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,8},{8,2,3}, -{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,12},{8,2,3},{8,3,1},{8,2,2}, -{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3}, -{8,3,4},{8,2,2},{0,0,0},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2}, -{8,6,9},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,10},{8,2,3}, -{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2}, -{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,8,13},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3}, -{8,3,4},{8,2,2},{8,6,8},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2}, -{8,9,15},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3}, -{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{10,13,832},{8,2,3},{8,3,1},{8,2,2}, -{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,9},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3}, -{8,3,4},{8,2,2},{8,7,11},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2}, -{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,12,62},{8,2,3}, -{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,8},{8,2,3},{8,3,1},{8,2,2}, -{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,12},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3}, -{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2}, -{11,12,2240},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,9},{8,2,3}, -{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,10},{8,2,3},{8,3,1},{8,2,2}, -{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3}, -{8,3,4},{8,2,2},{8,12,46},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2}, -{8,6,8},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,12,38},{8,2,3}, -{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2}, -{8,4,5},{8,2,3},{8,3,4},{8,2,2},{10,13,576},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3}, -{8,3,4},{8,2,2},{8,6,9},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2}, -{8,7,11},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3}, -{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,8,14},{8,2,3},{8,3,1},{8,2,2}, -{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,8},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3}, -{8,3,4},{8,2,2},{8,7,12},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2}, -{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{0,0,0},{8,2,3}, -{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,9},{8,2,3},{8,3,1},{8,2,2}, -{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,10},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3}, -{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2}, -{8,8,13},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,8},{8,2,3}, -{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,11,19},{8,2,3},{8,3,1},{8,2,2}, -{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3}, -{8,3,4},{8,2,2},{8,11,24},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2}, -{8,6,9},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,11},{8,2,3}, -{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2}, -{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,11,22},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3}, -{8,3,4},{8,2,2},{8,6,8},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2}, -{8,7,12},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3}, -{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{11,12,2496},{8,2,3},{8,3,1},{8,2,2}, -{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,9},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3}, -{8,3,4},{8,2,2},{8,7,10},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2}, -{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,10,16},{8,2,3}, -{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,8},{8,2,3},{8,3,1},{8,2,2}, -{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,10,0},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3}, -{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2}, -{10,10,64},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,9},{8,2,3}, -{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,11},{8,2,3},{8,3,1},{8,2,2}, -{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3}, -{8,3,4},{8,2,2},{8,8,14},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2}, -{8,6,8},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,12},{8,2,3}, -{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2}, -{8,4,5},{8,2,3},{8,3,4},{8,2,2},{12,11,0},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3}, -{8,3,4},{8,2,2},{8,6,9},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2}, -{8,7,10},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3}, -{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,8,13},{8,2,3},{8,3,1},{8,2,2}, -{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,8},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3}, -{8,3,4},{8,2,2},{8,9,15},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2}, -{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,10,18},{8,2,3}, -{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,9},{8,2,3},{8,3,1},{8,2,2}, -{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,11},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3}, -{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2}, -{8,10,17},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,8},{8,2,3}, -{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,12},{8,2,3},{8,3,1},{8,2,2}, -{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3}, -{8,3,4},{8,2,2},{11,11,1792},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2}, -{8,6,9},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,10},{8,2,3}, -{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2}, -{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,11,23},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3}, -{8,3,4},{8,2,2},{8,6,8},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2}, -{8,11,20},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3}, -{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,11,25},{8,2,3},{8,3,1},{8,2,2}, -{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,9},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3}, -{8,3,4},{8,2,2},{8,7,11},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2}, -{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,8,14},{8,2,3}, -{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,8},{8,2,3},{8,3,1},{8,2,2}, -{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,12},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3}, -{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2}, -{0,0,0},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,9},{8,2,3}, -{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,10},{8,2,3},{8,3,1},{8,2,2}, -{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3}, -{8,3,4},{8,2,2},{8,8,13},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2}, -{8,6,8},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{10,12,192},{8,2,3}, -{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2}, -{8,4,5},{8,2,3},{8,3,4},{8,2,2},{10,13,1344},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3}, -{8,3,4},{8,2,2},{8,6,9},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2}, -{8,7,11},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3}, -{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,12,31},{8,2,3},{8,3,1},{8,2,2}, -{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,8},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3}, -{8,3,4},{8,2,2},{8,7,12},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2}, -{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{11,11,1856},{8,2,3}, -{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,9},{8,2,3},{8,3,1},{8,2,2}, -{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,10},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3}, -{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2}, -{8,12,58},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,8},{8,2,3}, -{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,11,21},{8,2,3},{8,3,1},{8,2,2}, -{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3}, -{8,3,4},{8,2,2},{10,13,960},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2}, -{8,6,9},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,11},{8,2,3}, -{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2}, -{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,8,14},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3}, -{8,3,4},{8,2,2},{8,6,8},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2}, -{8,7,12},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3}, -{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{0,0,0},{8,2,3},{8,3,1},{8,2,2}, -{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,9},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3}, -{8,3,4},{8,2,2},{8,7,10},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2}, -{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,8,13},{8,2,3}, -{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,8},{8,2,3},{8,3,1},{8,2,2}, -{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,9,15},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3}, -{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2}, -{10,13,704},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,9},{8,2,3}, -{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,11},{8,2,3},{8,3,1},{8,2,2}, -{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3}, -{8,3,4},{8,2,2},{8,12,49},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2}, -{8,6,8},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,12},{8,2,3}, -{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2}, -{8,4,5},{8,2,3},{8,3,4},{8,2,2},{11,12,2176},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3}, -{8,3,4},{8,2,2},{8,6,9},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2}, -{8,7,10},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3}, -{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,12,45},{8,2,3},{8,3,1},{8,2,2}, -{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,8},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3}, -{8,3,4},{8,2,2},{8,12,37},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2}, -{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{10,12,448},{8,2,3}, -{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,9},{8,2,3},{8,3,1},{8,2,2}, -{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,11},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3}, -{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2}, -{8,8,14},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,8},{8,2,3}, -{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,12},{8,2,3},{8,3,1},{8,2,2}, -{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3}, -{8,3,4},{8,2,2},{0,0,0},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2}, -{8,6,9},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,10},{8,2,3}, -{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2}, -{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,8,13},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3}, -{8,3,4},{8,2,2},{8,6,8},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2}, -{8,12,29},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3}, -{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{10,13,1600},{8,2,3},{8,3,1},{8,2,2}, -{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,9},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3}, -{8,3,4},{8,2,2},{8,7,11},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2}, -{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,12,41},{8,2,3}, -{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,8},{8,2,3},{8,3,1},{8,2,2}, -{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,12},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3}, -{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2}, -{11,12,2432},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,9},{8,2,3}, -{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,10},{8,2,3},{8,3,1},{8,2,2}, -{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3}, -{8,3,4},{8,2,2},{8,10,16},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2}, -{8,6,8},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,10,0},{8,2,3}, -{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2}, -{8,4,5},{8,2,3},{8,3,4},{8,2,2},{10,10,64},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3}, -{8,3,4},{8,2,2},{8,6,9},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2}, -{8,7,11},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3}, -{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,8,14},{8,2,3},{8,3,1},{8,2,2}, -{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,8},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3}, -{8,3,4},{8,2,2},{8,7,12},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2}, -{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{0,0,0},{8,2,3}, -{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,9},{8,2,3},{8,3,1},{8,2,2}, -{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,10},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3}, -{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2}, -{8,8,13},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,8},{8,2,3}, -{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,9,15},{8,2,3},{8,3,1},{8,2,2}, -{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3}, -{8,3,4},{8,2,2},{8,10,18},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2}, -{8,6,9},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,11},{8,2,3}, -{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2}, -{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,10,17},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3}, -{8,3,4},{8,2,2},{8,6,8},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2}, -{8,7,12},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3}, -{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{11,12,2048},{8,2,3},{8,3,1},{8,2,2}, -{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,9},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3}, -{8,3,4},{8,2,2},{8,7,10},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2}, -{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,12,51},{8,2,3}, -{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,8},{8,2,3},{8,3,1},{8,2,2}, -{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,12,35},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3}, -{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2}, -{10,12,320},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,9},{8,2,3}, -{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,11},{8,2,3},{8,3,1},{8,2,2}, -{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3}, -{8,3,4},{8,2,2},{8,8,14},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2}, -{8,6,8},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,12},{8,2,3}, -{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2}, -{8,4,5},{8,2,3},{8,3,4},{8,2,2},{0,0,0},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3}, -{8,3,4},{8,2,2},{8,6,9},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2}, -{8,7,10},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3}, -{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,8,13},{8,2,3},{8,3,1},{8,2,2}, -{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,8},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3}, -{8,3,4},{8,2,2},{8,12,27},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2}, -{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,12,59},{8,2,3}, -{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,9},{8,2,3},{8,3,1},{8,2,2}, -{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,11},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3}, -{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2}, -{8,12,33},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,8},{8,2,3}, -{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,12},{8,2,3},{8,3,1},{8,2,2}, -{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3}, -{8,3,4},{8,2,2},{11,11,1920},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2}, -{8,6,9},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,10},{8,2,3}, -{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2}, -{8,4,5},{8,2,3},{8,3,4},{8,2,2},{10,12,256},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3}, -{8,3,4},{8,2,2},{8,6,8},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2}, -{8,12,43},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3}, -{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{10,13,1216},{8,2,3},{8,3,1},{8,2,2}, -{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,9},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3}, -{8,3,4},{8,2,2},{8,7,11},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2}, -{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,8,14},{8,2,3}, -{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,8},{8,2,3},{8,3,1},{8,2,2}, -{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,12},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3}, -{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2}, -{0,0,0},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,9},{8,2,3}, -{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,10},{8,2,3},{8,3,1},{8,2,2}, -{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3}, -{8,3,4},{8,2,2},{8,8,13},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2}, -{8,6,8},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,9,15},{8,2,3}, -{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2}, -{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,12,55},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3}, -{8,3,4},{8,2,2},{8,6,9},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2}, -{8,7,11},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3}, -{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,12,63},{8,2,3},{8,3,1},{8,2,2}, -{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,8},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3}, -{8,3,4},{8,2,2},{8,7,12},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2}, -{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{11,12,2304},{8,2,3}, -{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,9},{8,2,3},{8,3,1},{8,2,2}, -{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,10},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3}, -{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2}, -{8,12,47},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,8},{8,2,3}, -{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,12,39},{8,2,3},{8,3,1},{8,2,2}, -{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3}, -{8,3,4},{8,2,2},{8,12,53},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2}, -{8,6,9},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,11},{8,2,3}, -{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2}, -{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,8,14},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3}, -{8,3,4},{8,2,2},{8,6,8},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2}, -{8,7,12},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3}, -{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{0,0,0},{8,2,3},{8,3,1},{8,2,2}, -{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,9},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3}, -{8,3,4},{8,2,2},{8,7,10},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2}, -{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,8,13},{8,2,3}, -{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,8},{8,2,3},{8,3,1},{8,2,2}, -{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,11,19},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3}, -{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2}, -{8,11,24},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,9},{8,2,3}, -{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,11},{8,2,3},{8,3,1},{8,2,2}, -{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3}, -{8,3,4},{8,2,2},{8,11,22},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2}, -{8,6,8},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,12},{8,2,3}, -{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2}, -{8,4,5},{8,2,3},{8,3,4},{8,2,2},{11,12,2560},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3}, -{8,3,4},{8,2,2},{8,6,9},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2}, -{8,7,10},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3}, -{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,10,16},{8,2,3},{8,3,1},{8,2,2}, -{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,8},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3}, -{8,3,4},{8,2,2},{8,10,0},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2}, -{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{10,10,64},{8,2,3}, -{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,9},{8,2,3},{8,3,1},{8,2,2}, -{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,11},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3}, -{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2}, -{8,8,14},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,8},{8,2,3}, -{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,12},{8,2,3},{8,3,1},{8,2,2}, -{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3}, -{8,3,4},{8,2,2} -}; -/* - * Local Variables: - * mode: c - * c-basic-offset: 8 - * fill-column: 78 - * End: - */ diff --git a/src/3rd/tiff/flush.c b/src/3rd/tiff/flush.c deleted file mode 100644 index ff9c1e247a3..00000000000 --- a/src/3rd/tiff/flush.c +++ /dev/null @@ -1,157 +0,0 @@ -/* - * Copyright (c) 1988-1997 Sam Leffler - * Copyright (c) 1991-1997 Silicon Graphics, Inc. - * - * Permission to use, copy, modify, distribute, and sell this software and - * its documentation for any purpose is hereby granted without fee, provided - * that (i) the above copyright notices and this permission notice appear in - * all copies of the software and related documentation, and (ii) the names of - * Sam Leffler and Silicon Graphics may not be used in any advertising or - * publicity relating to the software without the specific, prior written - * permission of Sam Leffler and Silicon Graphics. - * - * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, - * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY - * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. - * - * IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR - * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, - * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, - * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF - * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE - * OF THIS SOFTWARE. - */ - -/* - * TIFF Library. - */ -#include "tiffiop.h" - -int TIFFFlush(TIFF *tif) -{ - if (tif->tif_mode == O_RDONLY) - return 1; - - if (!TIFFFlushData(tif)) - return (0); - - /* In update (r+) mode we try to detect the case where - only the strip/tile map has been altered, and we try to - rewrite only that portion of the directory without - making any other changes */ - - if ((tif->tif_flags & TIFF_DIRTYSTRIP) && - !(tif->tif_flags & TIFF_DIRTYDIRECT) && tif->tif_mode == O_RDWR) - { - if (TIFFForceStrileArrayWriting(tif)) - return 1; - } - - if ((tif->tif_flags & (TIFF_DIRTYDIRECT | TIFF_DIRTYSTRIP)) && - !TIFFRewriteDirectory(tif)) - return (0); - - return (1); -} - -/* - * This is an advanced writing function that must be used in a particular - * sequence, and together with TIFFDeferStrileArrayWriting(), - * to make its intended effect. Its aim is to force the writing of - * the [Strip/Tile][Offsets/ByteCounts] arrays at the end of the file, when - * they have not yet been rewritten. - * - * The typical sequence of calls is: - * TIFFOpen() - * [ TIFFCreateDirectory(tif) ] - * Set fields with calls to TIFFSetField(tif, ...) - * TIFFDeferStrileArrayWriting(tif) - * TIFFWriteCheck(tif, ...) - * TIFFWriteDirectory(tif) - * ... potentially create other directories and come back to the above directory - * TIFFForceStrileArrayWriting(tif) - * - * Returns 1 in case of success, 0 otherwise. - */ -int TIFFForceStrileArrayWriting(TIFF *tif) -{ - static const char module[] = "TIFFForceStrileArrayWriting"; - const int isTiled = TIFFIsTiled(tif); - - if (tif->tif_mode == O_RDONLY) - { - TIFFErrorExtR(tif, tif->tif_name, "File opened in read-only mode"); - return 0; - } - if (tif->tif_diroff == 0) - { - TIFFErrorExtR(tif, module, "Directory has not yet been written"); - return 0; - } - if ((tif->tif_flags & TIFF_DIRTYDIRECT) != 0) - { - TIFFErrorExtR(tif, module, - "Directory has changes other than the strile arrays. " - "TIFFRewriteDirectory() should be called instead"); - return 0; - } - - if (!(tif->tif_flags & TIFF_DIRTYSTRIP)) - { - if (!(tif->tif_dir.td_stripoffset_entry.tdir_tag != 0 && - tif->tif_dir.td_stripoffset_entry.tdir_count == 0 && - tif->tif_dir.td_stripoffset_entry.tdir_type == 0 && - tif->tif_dir.td_stripoffset_entry.tdir_offset.toff_long8 == 0 && - tif->tif_dir.td_stripbytecount_entry.tdir_tag != 0 && - tif->tif_dir.td_stripbytecount_entry.tdir_count == 0 && - tif->tif_dir.td_stripbytecount_entry.tdir_type == 0 && - tif->tif_dir.td_stripbytecount_entry.tdir_offset.toff_long8 == 0)) - { - TIFFErrorExtR(tif, module, - "Function not called together with " - "TIFFDeferStrileArrayWriting()"); - return 0; - } - - if (tif->tif_dir.td_stripoffset_p == NULL && !TIFFSetupStrips(tif)) - return 0; - } - - if (_TIFFRewriteField(tif, - isTiled ? TIFFTAG_TILEOFFSETS : TIFFTAG_STRIPOFFSETS, - TIFF_LONG8, tif->tif_dir.td_nstrips, - tif->tif_dir.td_stripoffset_p) && - _TIFFRewriteField( - tif, isTiled ? TIFFTAG_TILEBYTECOUNTS : TIFFTAG_STRIPBYTECOUNTS, - TIFF_LONG8, tif->tif_dir.td_nstrips, - tif->tif_dir.td_stripbytecount_p)) - { - tif->tif_flags &= ~TIFF_DIRTYSTRIP; - tif->tif_flags &= ~TIFF_BEENWRITING; - return 1; - } - - return 0; -} - -/* - * Flush buffered data to the file. - * - * Frank Warmerdam'2000: I modified this to return 1 if TIFF_BEENWRITING - * is not set, so that TIFFFlush() will proceed to write out the directory. - * The documentation says returning 1 is an error indicator, but not having - * been writing isn't exactly a an error. Hopefully this doesn't cause - * problems for other people. - */ -int TIFFFlushData(TIFF *tif) -{ - if ((tif->tif_flags & TIFF_BEENWRITING) == 0) - return (1); - if (tif->tif_flags & TIFF_POSTENCODE) - { - tif->tif_flags &= ~TIFF_POSTENCODE; - if (!(*tif->tif_postencode)(tif)) - return (0); - } - return (TIFFFlushData1(tif)); -} diff --git a/src/3rd/tiff/getimage.c b/src/3rd/tiff/getimage.c deleted file mode 100644 index 3d04b02a97f..00000000000 --- a/src/3rd/tiff/getimage.c +++ /dev/null @@ -1,3368 +0,0 @@ -/* - * Copyright (c) 1991-1997 Sam Leffler - * Copyright (c) 1991-1997 Silicon Graphics, Inc. - * - * Permission to use, copy, modify, distribute, and sell this software and - * its documentation for any purpose is hereby granted without fee, provided - * that (i) the above copyright notices and this permission notice appear in - * all copies of the software and related documentation, and (ii) the names of - * Sam Leffler and Silicon Graphics may not be used in any advertising or - * publicity relating to the software without the specific, prior written - * permission of Sam Leffler and Silicon Graphics. - * - * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, - * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY - * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. - * - * IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR - * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, - * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, - * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF - * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE - * OF THIS SOFTWARE. - */ - -/* - * TIFF Library - * - * Read and return a packed RGBA image. - */ -#include "tiffiop.h" -#include -#include - -static int gtTileContig(TIFFRGBAImage *, uint32_t *, uint32_t, uint32_t); -static int gtTileSeparate(TIFFRGBAImage *, uint32_t *, uint32_t, uint32_t); -static int gtStripContig(TIFFRGBAImage *, uint32_t *, uint32_t, uint32_t); -static int gtStripSeparate(TIFFRGBAImage *, uint32_t *, uint32_t, uint32_t); -static int PickContigCase(TIFFRGBAImage *); -static int PickSeparateCase(TIFFRGBAImage *); - -static int BuildMapUaToAa(TIFFRGBAImage *img); -static int BuildMapBitdepth16To8(TIFFRGBAImage *img); - -static const char photoTag[] = "PhotometricInterpretation"; - -/* - * Helper constants used in Orientation tag handling - */ -#define FLIP_VERTICALLY 0x01 -#define FLIP_HORIZONTALLY 0x02 - -#define EMSG_BUF_SIZE 1024 - -/* - * Color conversion constants. We will define display types here. - */ - -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 */ - 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 */ -}; - -/* - * Check the image to see if TIFFReadRGBAImage can deal with it. - * 1/0 is returned according to whether or not the image can - * be handled. If 0 is returned, emsg contains the reason - * why it is being rejected. - */ -int TIFFRGBAImageOK(TIFF *tif, char emsg[EMSG_BUF_SIZE]) -{ - TIFFDirectory *td = &tif->tif_dir; - uint16_t photometric; - int colorchannels; - - if (!tif->tif_decodestatus) - { - snprintf(emsg, EMSG_BUF_SIZE, - "Sorry, requested compression method is not configured"); - return (0); - } - switch (td->td_bitspersample) - { - case 1: - case 2: - case 4: - case 8: - case 16: - break; - default: - snprintf(emsg, EMSG_BUF_SIZE, - "Sorry, can not handle images with %" PRIu16 - "-bit samples", - td->td_bitspersample); - return (0); - } - if (td->td_sampleformat == SAMPLEFORMAT_IEEEFP) - { - snprintf( - emsg, EMSG_BUF_SIZE, - "Sorry, can not handle images with IEEE floating-point samples"); - return (0); - } - colorchannels = td->td_samplesperpixel - td->td_extrasamples; - if (!TIFFGetField(tif, TIFFTAG_PHOTOMETRIC, &photometric)) - { - switch (colorchannels) - { - case 1: - photometric = PHOTOMETRIC_MINISBLACK; - break; - case 3: - photometric = PHOTOMETRIC_RGB; - break; - default: - snprintf(emsg, EMSG_BUF_SIZE, "Missing needed %s tag", - photoTag); - return (0); - } - } - switch (photometric) - { - case PHOTOMETRIC_MINISWHITE: - case PHOTOMETRIC_MINISBLACK: - case PHOTOMETRIC_PALETTE: - if (td->td_planarconfig == PLANARCONFIG_CONTIG && - td->td_samplesperpixel != 1 && td->td_bitspersample < 8) - { - snprintf( - emsg, EMSG_BUF_SIZE, - "Sorry, can not handle contiguous data with %s=%" PRIu16 - ", " - "and %s=%" PRIu16 " and Bits/Sample=%" PRIu16 "", - photoTag, photometric, "Samples/pixel", - td->td_samplesperpixel, td->td_bitspersample); - return (0); - } - /* - * We should likely validate that any extra samples are either - * to be ignored, or are alpha, and if alpha we should try to use - * them. But for now we won't bother with this. - */ - break; - case PHOTOMETRIC_YCBCR: - /* - * TODO: if at all meaningful and useful, make more complete - * support check here, or better still, refactor to let supporting - * code decide whether there is support and what meaningful - * error to return - */ - break; - case PHOTOMETRIC_RGB: - if (colorchannels < 3) - { - snprintf(emsg, EMSG_BUF_SIZE, - "Sorry, can not handle RGB image with %s=%d", - "Color channels", colorchannels); - return (0); - } - break; - case PHOTOMETRIC_SEPARATED: - { - uint16_t inkset; - TIFFGetFieldDefaulted(tif, TIFFTAG_INKSET, &inkset); - if (inkset != INKSET_CMYK) - { - snprintf(emsg, EMSG_BUF_SIZE, - "Sorry, can not handle separated image with %s=%d", - "InkSet", inkset); - return 0; - } - if (td->td_samplesperpixel < 4) - { - snprintf( - emsg, EMSG_BUF_SIZE, - "Sorry, can not handle separated image with %s=%" PRIu16, - "Samples/pixel", td->td_samplesperpixel); - return 0; - } - break; - } - case PHOTOMETRIC_LOGL: - if (td->td_compression != COMPRESSION_SGILOG) - { - snprintf(emsg, EMSG_BUF_SIZE, - "Sorry, LogL data must have %s=%d", "Compression", - COMPRESSION_SGILOG); - return (0); - } - break; - case PHOTOMETRIC_LOGLUV: - if (td->td_compression != COMPRESSION_SGILOG && - td->td_compression != COMPRESSION_SGILOG24) - { - snprintf(emsg, EMSG_BUF_SIZE, - "Sorry, LogLuv data must have %s=%d or %d", - "Compression", COMPRESSION_SGILOG, - COMPRESSION_SGILOG24); - return (0); - } - if (td->td_planarconfig != PLANARCONFIG_CONTIG) - { - snprintf(emsg, EMSG_BUF_SIZE, - "Sorry, can not handle LogLuv images with %s=%" PRIu16, - "Planarconfiguration", td->td_planarconfig); - return (0); - } - if (td->td_samplesperpixel != 3 || colorchannels != 3) - { - snprintf(emsg, EMSG_BUF_SIZE, - "Sorry, can not handle image with %s=%" PRIu16 - ", %s=%d", - "Samples/pixel", td->td_samplesperpixel, - "colorchannels", colorchannels); - return 0; - } - break; - case PHOTOMETRIC_CIELAB: - if (td->td_samplesperpixel != 3 || colorchannels != 3 || - (td->td_bitspersample != 8 && td->td_bitspersample != 16)) - { - snprintf(emsg, EMSG_BUF_SIZE, - "Sorry, can not handle image with %s=%" PRIu16 - ", %s=%d and %s=%" PRIu16, - "Samples/pixel", td->td_samplesperpixel, - "colorchannels", colorchannels, "Bits/sample", - td->td_bitspersample); - return 0; - } - break; - default: - snprintf(emsg, EMSG_BUF_SIZE, - "Sorry, can not handle image with %s=%" PRIu16, photoTag, - photometric); - return (0); - } - return (1); -} - -void TIFFRGBAImageEnd(TIFFRGBAImage *img) -{ - if (img->Map) - { - _TIFFfreeExt(img->tif, img->Map); - img->Map = NULL; - } - if (img->BWmap) - { - _TIFFfreeExt(img->tif, img->BWmap); - img->BWmap = NULL; - } - if (img->PALmap) - { - _TIFFfreeExt(img->tif, img->PALmap); - img->PALmap = NULL; - } - if (img->ycbcr) - { - _TIFFfreeExt(img->tif, img->ycbcr); - img->ycbcr = NULL; - } - if (img->cielab) - { - _TIFFfreeExt(img->tif, img->cielab); - img->cielab = NULL; - } - if (img->UaToAa) - { - _TIFFfreeExt(img->tif, img->UaToAa); - img->UaToAa = NULL; - } - if (img->Bitdepth16To8) - { - _TIFFfreeExt(img->tif, img->Bitdepth16To8); - img->Bitdepth16To8 = NULL; - } - - if (img->redcmap) - { - _TIFFfreeExt(img->tif, img->redcmap); - _TIFFfreeExt(img->tif, img->greencmap); - _TIFFfreeExt(img->tif, img->bluecmap); - img->redcmap = img->greencmap = img->bluecmap = NULL; - } -} - -static int isCCITTCompression(TIFF *tif) -{ - uint16_t compress; - TIFFGetField(tif, TIFFTAG_COMPRESSION, &compress); - return (compress == COMPRESSION_CCITTFAX3 || - compress == COMPRESSION_CCITTFAX4 || - compress == COMPRESSION_CCITTRLE || - compress == COMPRESSION_CCITTRLEW); -} - -int TIFFRGBAImageBegin(TIFFRGBAImage *img, TIFF *tif, int stop, - char emsg[EMSG_BUF_SIZE]) -{ - uint16_t *sampleinfo; - uint16_t extrasamples; - uint16_t planarconfig; - uint16_t compress; - int colorchannels; - uint16_t *red_orig, *green_orig, *blue_orig; - int n_color; - - if (!TIFFRGBAImageOK(tif, emsg)) - return 0; - - /* Initialize to normal values */ - img->row_offset = 0; - img->col_offset = 0; - img->redcmap = NULL; - img->greencmap = NULL; - img->bluecmap = NULL; - img->Map = NULL; - img->BWmap = NULL; - img->PALmap = NULL; - img->ycbcr = NULL; - img->cielab = NULL; - img->UaToAa = NULL; - img->Bitdepth16To8 = NULL; - img->req_orientation = ORIENTATION_BOTLEFT; /* It is the default */ - - img->tif = tif; - img->stoponerr = stop; - TIFFGetFieldDefaulted(tif, TIFFTAG_BITSPERSAMPLE, &img->bitspersample); - switch (img->bitspersample) - { - case 1: - case 2: - case 4: - case 8: - case 16: - break; - default: - snprintf(emsg, EMSG_BUF_SIZE, - "Sorry, can not handle images with %" PRIu16 - "-bit samples", - img->bitspersample); - goto fail_return; - } - img->alpha = 0; - TIFFGetFieldDefaulted(tif, TIFFTAG_SAMPLESPERPIXEL, &img->samplesperpixel); - TIFFGetFieldDefaulted(tif, TIFFTAG_EXTRASAMPLES, &extrasamples, - &sampleinfo); - if (extrasamples >= 1) - { - switch (sampleinfo[0]) - { - case EXTRASAMPLE_UNSPECIFIED: /* Workaround for some images without - */ - if (img->samplesperpixel > - 3) /* correct info about alpha channel */ - img->alpha = EXTRASAMPLE_ASSOCALPHA; - break; - case EXTRASAMPLE_ASSOCALPHA: /* data is pre-multiplied */ - case EXTRASAMPLE_UNASSALPHA: /* data is not pre-multiplied */ - img->alpha = sampleinfo[0]; - break; - } - } - -#ifdef DEFAULT_EXTRASAMPLE_AS_ALPHA - if (!TIFFGetField(tif, TIFFTAG_PHOTOMETRIC, &img->photometric)) - img->photometric = PHOTOMETRIC_MINISWHITE; - - if (extrasamples == 0 && img->samplesperpixel == 4 && - img->photometric == PHOTOMETRIC_RGB) - { - img->alpha = EXTRASAMPLE_ASSOCALPHA; - extrasamples = 1; - } -#endif - - colorchannels = img->samplesperpixel - extrasamples; - TIFFGetFieldDefaulted(tif, TIFFTAG_COMPRESSION, &compress); - TIFFGetFieldDefaulted(tif, TIFFTAG_PLANARCONFIG, &planarconfig); - if (!TIFFGetField(tif, TIFFTAG_PHOTOMETRIC, &img->photometric)) - { - switch (colorchannels) - { - case 1: - if (isCCITTCompression(tif)) - img->photometric = PHOTOMETRIC_MINISWHITE; - else - img->photometric = PHOTOMETRIC_MINISBLACK; - break; - case 3: - img->photometric = PHOTOMETRIC_RGB; - break; - default: - snprintf(emsg, EMSG_BUF_SIZE, "Missing needed %s tag", - photoTag); - goto fail_return; - } - } - switch (img->photometric) - { - case PHOTOMETRIC_PALETTE: - if (!TIFFGetField(tif, TIFFTAG_COLORMAP, &red_orig, &green_orig, - &blue_orig)) - { - snprintf(emsg, EMSG_BUF_SIZE, - "Missing required \"Colormap\" tag"); - goto fail_return; - } - - /* 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); - if (!img->redcmap || !img->greencmap || !img->bluecmap) - { - snprintf(emsg, EMSG_BUF_SIZE, - "Out of memory for colormap copy"); - goto fail_return; - } - - _TIFFmemcpy(img->redcmap, red_orig, n_color * 2); - _TIFFmemcpy(img->greencmap, green_orig, n_color * 2); - _TIFFmemcpy(img->bluecmap, blue_orig, n_color * 2); - - /* fall through... */ - case PHOTOMETRIC_MINISWHITE: - case PHOTOMETRIC_MINISBLACK: - if (planarconfig == PLANARCONFIG_CONTIG && - img->samplesperpixel != 1 && img->bitspersample < 8) - { - snprintf( - emsg, EMSG_BUF_SIZE, - "Sorry, can not handle contiguous data with %s=%" PRIu16 - ", " - "and %s=%" PRIu16 " and Bits/Sample=%" PRIu16, - photoTag, img->photometric, "Samples/pixel", - img->samplesperpixel, img->bitspersample); - goto fail_return; - } - break; - case PHOTOMETRIC_YCBCR: - /* It would probably be nice to have a reality check here. */ - if (planarconfig == PLANARCONFIG_CONTIG) - /* can rely on libjpeg to convert to RGB */ - /* XXX should restore current state on exit */ - switch (compress) - { - case COMPRESSION_JPEG: - /* - * TODO: when complete tests verify complete - * desubsampling and YCbCr handling, remove use of - * TIFFTAG_JPEGCOLORMODE in favor of tif_getimage.c - * native handling - */ - TIFFSetField(tif, TIFFTAG_JPEGCOLORMODE, - JPEGCOLORMODE_RGB); - img->photometric = PHOTOMETRIC_RGB; - break; - default: - /* do nothing */; - break; - } - /* - * TODO: if at all meaningful and useful, make more complete - * support check here, or better still, refactor to let supporting - * code decide whether there is support and what meaningful - * error to return - */ - break; - case PHOTOMETRIC_RGB: - if (colorchannels < 3) - { - snprintf(emsg, EMSG_BUF_SIZE, - "Sorry, can not handle RGB image with %s=%d", - "Color channels", colorchannels); - goto fail_return; - } - break; - case PHOTOMETRIC_SEPARATED: - { - uint16_t inkset; - TIFFGetFieldDefaulted(tif, TIFFTAG_INKSET, &inkset); - if (inkset != INKSET_CMYK) - { - snprintf( - emsg, EMSG_BUF_SIZE, - "Sorry, can not handle separated image with %s=%" PRIu16, - "InkSet", inkset); - goto fail_return; - } - if (img->samplesperpixel < 4) - { - snprintf( - emsg, EMSG_BUF_SIZE, - "Sorry, can not handle separated image with %s=%" PRIu16, - "Samples/pixel", img->samplesperpixel); - goto fail_return; - } - } - break; - case PHOTOMETRIC_LOGL: - if (compress != COMPRESSION_SGILOG) - { - snprintf(emsg, EMSG_BUF_SIZE, - "Sorry, LogL data must have %s=%d", "Compression", - COMPRESSION_SGILOG); - goto fail_return; - } - TIFFSetField(tif, TIFFTAG_SGILOGDATAFMT, SGILOGDATAFMT_8BIT); - img->photometric = PHOTOMETRIC_MINISBLACK; /* little white lie */ - img->bitspersample = 8; - break; - case PHOTOMETRIC_LOGLUV: - if (compress != COMPRESSION_SGILOG && - compress != COMPRESSION_SGILOG24) - { - snprintf(emsg, EMSG_BUF_SIZE, - "Sorry, LogLuv data must have %s=%d or %d", - "Compression", COMPRESSION_SGILOG, - COMPRESSION_SGILOG24); - goto fail_return; - } - if (planarconfig != PLANARCONFIG_CONTIG) - { - snprintf(emsg, EMSG_BUF_SIZE, - "Sorry, can not handle LogLuv images with %s=%" PRIu16, - "Planarconfiguration", planarconfig); - return (0); - } - TIFFSetField(tif, TIFFTAG_SGILOGDATAFMT, SGILOGDATAFMT_8BIT); - img->photometric = PHOTOMETRIC_RGB; /* little white lie */ - img->bitspersample = 8; - break; - case PHOTOMETRIC_CIELAB: - break; - default: - snprintf(emsg, EMSG_BUF_SIZE, - "Sorry, can not handle image with %s=%" PRIu16, photoTag, - img->photometric); - goto fail_return; - } - TIFFGetField(tif, TIFFTAG_IMAGEWIDTH, &img->width); - TIFFGetField(tif, TIFFTAG_IMAGELENGTH, &img->height); - TIFFGetFieldDefaulted(tif, TIFFTAG_ORIENTATION, &img->orientation); - img->isContig = - !(planarconfig == PLANARCONFIG_SEPARATE && img->samplesperpixel > 1); - if (img->isContig) - { - if (!PickContigCase(img)) - { - snprintf(emsg, EMSG_BUF_SIZE, "Sorry, can not handle image"); - goto fail_return; - } - } - else - { - if (!PickSeparateCase(img)) - { - snprintf(emsg, EMSG_BUF_SIZE, "Sorry, can not handle image"); - goto fail_return; - } - } - return 1; - -fail_return: - TIFFRGBAImageEnd(img); - return 0; -} - -int TIFFRGBAImageGet(TIFFRGBAImage *img, uint32_t *raster, uint32_t w, - uint32_t h) -{ - if (img->get == NULL) - { - TIFFErrorExtR(img->tif, TIFFFileName(img->tif), - "No \"get\" routine setup"); - return (0); - } - if (img->put.any == NULL) - { - TIFFErrorExtR( - img->tif, TIFFFileName(img->tif), - "No \"put\" routine setupl; probably can not handle image format"); - return (0); - } - return (*img->get)(img, raster, w, h); -} - -/* - * Read the specified image into an ABGR-format rastertaking in account - * specified orientation. - */ -int TIFFReadRGBAImageOriented(TIFF *tif, uint32_t rwidth, uint32_t rheight, - uint32_t *raster, int orientation, int stop) -{ - char emsg[EMSG_BUF_SIZE] = ""; - TIFFRGBAImage img; - int ok; - - if (TIFFRGBAImageOK(tif, emsg) && TIFFRGBAImageBegin(&img, tif, stop, emsg)) - { - img.req_orientation = (uint16_t)orientation; - /* XXX verify rwidth and rheight against width and height */ - ok = TIFFRGBAImageGet(&img, raster + (rheight - img.height) * rwidth, - rwidth, img.height); - TIFFRGBAImageEnd(&img); - } - else - { - TIFFErrorExtR(tif, TIFFFileName(tif), "%s", emsg); - ok = 0; - } - return (ok); -} - -/* - * Read the specified image into an ABGR-format raster. Use bottom left - * origin for raster by default. - */ -int TIFFReadRGBAImage(TIFF *tif, uint32_t rwidth, uint32_t rheight, - uint32_t *raster, int stop) -{ - return TIFFReadRGBAImageOriented(tif, rwidth, rheight, raster, - ORIENTATION_BOTLEFT, stop); -} - -static int setorientation(TIFFRGBAImage *img) -{ - switch (img->orientation) - { - case ORIENTATION_TOPLEFT: - case ORIENTATION_LEFTTOP: - if (img->req_orientation == ORIENTATION_TOPRIGHT || - img->req_orientation == ORIENTATION_RIGHTTOP) - return FLIP_HORIZONTALLY; - else if (img->req_orientation == ORIENTATION_BOTRIGHT || - img->req_orientation == ORIENTATION_RIGHTBOT) - return FLIP_HORIZONTALLY | FLIP_VERTICALLY; - else if (img->req_orientation == ORIENTATION_BOTLEFT || - img->req_orientation == ORIENTATION_LEFTBOT) - return FLIP_VERTICALLY; - else - return 0; - case ORIENTATION_TOPRIGHT: - case ORIENTATION_RIGHTTOP: - if (img->req_orientation == ORIENTATION_TOPLEFT || - img->req_orientation == ORIENTATION_LEFTTOP) - return FLIP_HORIZONTALLY; - else if (img->req_orientation == ORIENTATION_BOTRIGHT || - img->req_orientation == ORIENTATION_RIGHTBOT) - return FLIP_VERTICALLY; - else if (img->req_orientation == ORIENTATION_BOTLEFT || - img->req_orientation == ORIENTATION_LEFTBOT) - return FLIP_HORIZONTALLY | FLIP_VERTICALLY; - else - return 0; - case ORIENTATION_BOTRIGHT: - case ORIENTATION_RIGHTBOT: - if (img->req_orientation == ORIENTATION_TOPLEFT || - img->req_orientation == ORIENTATION_LEFTTOP) - return FLIP_HORIZONTALLY | FLIP_VERTICALLY; - else if (img->req_orientation == ORIENTATION_TOPRIGHT || - img->req_orientation == ORIENTATION_RIGHTTOP) - return FLIP_VERTICALLY; - else if (img->req_orientation == ORIENTATION_BOTLEFT || - img->req_orientation == ORIENTATION_LEFTBOT) - return FLIP_HORIZONTALLY; - else - return 0; - case ORIENTATION_BOTLEFT: - case ORIENTATION_LEFTBOT: - if (img->req_orientation == ORIENTATION_TOPLEFT || - img->req_orientation == ORIENTATION_LEFTTOP) - return FLIP_VERTICALLY; - else if (img->req_orientation == ORIENTATION_TOPRIGHT || - img->req_orientation == ORIENTATION_RIGHTTOP) - return FLIP_HORIZONTALLY | FLIP_VERTICALLY; - else if (img->req_orientation == ORIENTATION_BOTRIGHT || - img->req_orientation == ORIENTATION_RIGHTBOT) - return FLIP_HORIZONTALLY; - else - return 0; - default: /* NOTREACHED */ - return 0; - } -} - -/* - * Get an tile-organized image that has - * PlanarConfiguration contiguous if SamplesPerPixel > 1 - * or - * SamplesPerPixel == 1 - */ -static int gtTileContig(TIFFRGBAImage *img, uint32_t *raster, uint32_t w, - uint32_t h) -{ - TIFF *tif = img->tif; - tileContigRoutine put = img->put.contig; - uint32_t col, row, y, rowstoread; - tmsize_t pos; - uint32_t tw, th; - unsigned char *buf = NULL; - int32_t fromskew, toskew; - uint32_t nrow; - int ret = 1, flip; - uint32_t this_tw, tocol; - int32_t this_toskew, leftmost_toskew; - int32_t leftmost_fromskew; - uint32_t leftmost_tw; - tmsize_t bufsize; - - bufsize = TIFFTileSize(tif); - if (bufsize == 0) - { - TIFFErrorExtR(tif, TIFFFileName(tif), "%s", "No space for tile buffer"); - return (0); - } - - TIFFGetField(tif, TIFFTAG_TILEWIDTH, &tw); - TIFFGetField(tif, TIFFTAG_TILELENGTH, &th); - - flip = setorientation(img); - if (flip & FLIP_VERTICALLY) - { - if ((tw + w) > INT_MAX) - { - TIFFErrorExtR(tif, TIFFFileName(tif), "%s", - "unsupported tile size (too wide)"); - return (0); - } - y = h - 1; - toskew = -(int32_t)(tw + w); - } - else - { - if (tw > (INT_MAX + w)) - { - TIFFErrorExtR(tif, TIFFFileName(tif), "%s", - "unsupported tile size (too wide)"); - return (0); - } - y = 0; - toskew = -(int32_t)(tw - w); - } - - /* - * Leftmost tile is clipped on left side if col_offset > 0. - */ - leftmost_fromskew = img->col_offset % tw; - leftmost_tw = tw - leftmost_fromskew; - leftmost_toskew = toskew + leftmost_fromskew; - for (row = 0; ret != 0 && row < h; row += nrow) - { - rowstoread = th - (row + 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; - while (tocol < w) - { - if (_TIFFReadTileAndAllocBuffer(tif, (void **)&buf, bufsize, col, - row + img->row_offset, 0, - 0) == (tmsize_t)(-1) && - (buf == NULL || img->stoponerr)) - { - ret = 0; - break; - } - pos = ((row + img->row_offset) % th) * TIFFTileRowSize(tif) + - ((tmsize_t)fromskew * img->samplesperpixel); - if (tocol + this_tw > w) - { - /* - * Rightmost tile is clipped on right side. - */ - fromskew = tw - (w - tocol); - this_tw = tw - fromskew; - this_toskew = toskew + fromskew; - } - { - tmsize_t roffset = (tmsize_t)y * w + tocol; - (*put)(img, raster + roffset, tocol, y, this_tw, nrow, fromskew, - this_toskew, buf + pos); - } - tocol += this_tw; - col += this_tw; - /* - * After the leftmost tile, tiles are no longer clipped on left - * side. - */ - fromskew = 0; - this_tw = tw; - this_toskew = toskew; - } - - y += ((flip & FLIP_VERTICALLY) ? -(int32_t)nrow : (int32_t)nrow); - } - _TIFFfreeExt(img->tif, buf); - - if (flip & FLIP_HORIZONTALLY) - { - uint32_t line; - - for (line = 0; line < h; line++) - { - uint32_t *left = raster + (line * w); - uint32_t *right = left + w - 1; - - while (left < right) - { - uint32_t temp = *left; - *left = *right; - *right = temp; - left++; - right--; - } - } - } - - return (ret); -} - -/* - * Get an tile-organized image that has - * SamplesPerPixel > 1 - * PlanarConfiguration separated - * We assume that all such images are RGB. - */ -static int gtTileSeparate(TIFFRGBAImage *img, uint32_t *raster, uint32_t w, - uint32_t h) -{ - TIFF *tif = img->tif; - tileSeparateRoutine put = img->put.separate; - uint32_t col, row, y, rowstoread; - tmsize_t pos; - uint32_t tw, th; - unsigned char *buf = NULL; - unsigned char *p0 = NULL; - unsigned char *p1 = NULL; - unsigned char *p2 = NULL; - unsigned char *pa = NULL; - tmsize_t tilesize; - tmsize_t bufsize; - int32_t fromskew, toskew; - int alpha = img->alpha; - uint32_t nrow; - int ret = 1, flip; - uint16_t colorchannels; - uint32_t this_tw, tocol; - int32_t this_toskew, leftmost_toskew; - int32_t leftmost_fromskew; - uint32_t leftmost_tw; - - tilesize = TIFFTileSize(tif); - bufsize = - _TIFFMultiplySSize(tif, alpha ? 4 : 3, tilesize, "gtTileSeparate"); - if (bufsize == 0) - { - return (0); - } - - TIFFGetField(tif, TIFFTAG_TILEWIDTH, &tw); - TIFFGetField(tif, TIFFTAG_TILELENGTH, &th); - - flip = setorientation(img); - if (flip & FLIP_VERTICALLY) - { - if ((tw + w) > INT_MAX) - { - TIFFErrorExtR(tif, TIFFFileName(tif), "%s", - "unsupported tile size (too wide)"); - return (0); - } - y = h - 1; - toskew = -(int32_t)(tw + w); - } - else - { - if (tw > (INT_MAX + w)) - { - TIFFErrorExtR(tif, TIFFFileName(tif), "%s", - "unsupported tile size (too wide)"); - return (0); - } - y = 0; - toskew = -(int32_t)(tw - w); - } - - switch (img->photometric) - { - case PHOTOMETRIC_MINISWHITE: - case PHOTOMETRIC_MINISBLACK: - case PHOTOMETRIC_PALETTE: - colorchannels = 1; - break; - - default: - colorchannels = 3; - break; - } - - /* - * Leftmost tile is clipped on left side if col_offset > 0. - */ - leftmost_fromskew = img->col_offset % tw; - leftmost_tw = tw - leftmost_fromskew; - leftmost_toskew = toskew + leftmost_fromskew; - for (row = 0; ret != 0 && row < h; row += nrow) - { - rowstoread = th - (row + 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; - while (tocol < w) - { - if (buf == NULL) - { - if (_TIFFReadTileAndAllocBuffer(tif, (void **)&buf, bufsize, - col, row + img->row_offset, 0, - 0) == (tmsize_t)(-1) && - (buf == NULL || img->stoponerr)) - { - ret = 0; - break; - } - p0 = buf; - if (colorchannels == 1) - { - p2 = p1 = p0; - pa = (alpha ? (p0 + 3 * tilesize) : NULL); - } - else - { - p1 = p0 + tilesize; - p2 = p1 + tilesize; - pa = (alpha ? (p2 + tilesize) : NULL); - } - } - else if (TIFFReadTile(tif, p0, col, 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) && - img->stoponerr) - { - ret = 0; - break; - } - if (colorchannels > 1 && - TIFFReadTile(tif, p2, col, row + img->row_offset, 0, 2) == - (tmsize_t)(-1) && - img->stoponerr) - { - ret = 0; - break; - } - if (alpha && - TIFFReadTile(tif, pa, col, row + img->row_offset, 0, - colorchannels) == (tmsize_t)(-1) && - img->stoponerr) - { - ret = 0; - break; - } - - pos = ((row + img->row_offset) % th) * TIFFTileRowSize(tif) + - ((tmsize_t)fromskew * img->samplesperpixel); - if (tocol + this_tw > w) - { - /* - * Rightmost tile is clipped on right side. - */ - fromskew = tw - (w - tocol); - this_tw = tw - fromskew; - this_toskew = toskew + fromskew; - } - { - tmsize_t roffset = (tmsize_t)y * w + tocol; - (*put)(img, raster + roffset, tocol, y, this_tw, nrow, fromskew, - this_toskew, p0 + pos, p1 + pos, p2 + pos, - (alpha ? (pa + pos) : NULL)); - } - tocol += this_tw; - col += this_tw; - /* - * After the leftmost tile, tiles are no longer clipped on left - * side. - */ - fromskew = 0; - this_tw = tw; - this_toskew = toskew; - } - - y += ((flip & FLIP_VERTICALLY) ? -(int32_t)nrow : (int32_t)nrow); - } - - if (flip & FLIP_HORIZONTALLY) - { - uint32_t line; - - for (line = 0; line < h; line++) - { - uint32_t *left = raster + (line * w); - uint32_t *right = left + w - 1; - - while (left < right) - { - uint32_t temp = *left; - *left = *right; - *right = temp; - left++; - right--; - } - } - } - - _TIFFfreeExt(img->tif, buf); - return (ret); -} - -/* - * Get a strip-organized image that has - * PlanarConfiguration contiguous if SamplesPerPixel > 1 - * or - * SamplesPerPixel == 1 - */ -static int gtStripContig(TIFFRGBAImage *img, uint32_t *raster, uint32_t w, - uint32_t h) -{ - TIFF *tif = img->tif; - tileContigRoutine put = img->put.contig; - uint32_t row, y, nrow, nrowsub, rowstoread; - tmsize_t pos; - unsigned char *buf = NULL; - uint32_t rowsperstrip; - uint16_t subsamplinghor, subsamplingver; - uint32_t imagewidth = img->width; - tmsize_t scanline; - int32_t fromskew, toskew; - int ret = 1, flip; - tmsize_t maxstripsize; - - TIFFGetFieldDefaulted(tif, TIFFTAG_YCBCRSUBSAMPLING, &subsamplinghor, - &subsamplingver); - if (subsamplingver == 0) - { - TIFFErrorExtR(tif, TIFFFileName(tif), - "Invalid vertical YCbCr subsampling"); - return (0); - } - - maxstripsize = TIFFStripSize(tif); - - flip = setorientation(img); - if (flip & FLIP_VERTICALLY) - { - if (w > INT_MAX) - { - TIFFErrorExtR(tif, TIFFFileName(tif), "Width overflow"); - return (0); - } - y = h - 1; - toskew = -(int32_t)(w + w); - } - else - { - y = 0; - toskew = -(int32_t)(w - w); - } - - TIFFGetFieldDefaulted(tif, TIFFTAG_ROWSPERSTRIP, &rowsperstrip); - - scanline = TIFFScanlineSize(tif); - fromskew = (w < imagewidth ? imagewidth - w : 0); - for (row = 0; row < h; row += nrow) - { - uint32_t temp; - rowstoread = rowsperstrip - (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; - if (scanline > 0 && temp > (size_t)(TIFF_TMSIZE_T_MAX / scanline)) - { - TIFFErrorExtR(tif, TIFFFileName(tif), - "Integer overflow in gtStripContig"); - return 0; - } - if (_TIFFReadEncodedStripAndAllocBuffer( - tif, TIFFComputeStrip(tif, row + img->row_offset, 0), - (void **)(&buf), maxstripsize, - temp * scanline) == (tmsize_t)(-1) && - (buf == NULL || img->stoponerr)) - { - ret = 0; - break; - } - - pos = ((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, w, nrow, fromskew, toskew, - buf + pos); - } - y += ((flip & FLIP_VERTICALLY) ? -(int32_t)nrow : (int32_t)nrow); - } - - if (flip & FLIP_HORIZONTALLY) - { - uint32_t line; - - for (line = 0; line < h; line++) - { - uint32_t *left = raster + (line * w); - uint32_t *right = left + w - 1; - - while (left < right) - { - uint32_t temp = *left; - *left = *right; - *right = temp; - left++; - right--; - } - } - } - - _TIFFfreeExt(img->tif, buf); - return (ret); -} - -/* - * Get a strip-organized image with - * SamplesPerPixel > 1 - * PlanarConfiguration separated - * We assume that all such images are RGB. - */ -static int gtStripSeparate(TIFFRGBAImage *img, uint32_t *raster, uint32_t w, - uint32_t h) -{ - TIFF *tif = img->tif; - tileSeparateRoutine put = img->put.separate; - unsigned char *buf = NULL; - unsigned char *p0 = NULL, *p1 = NULL, *p2 = NULL, *pa = NULL; - uint32_t row, y, nrow, rowstoread; - tmsize_t pos; - tmsize_t scanline; - uint32_t rowsperstrip, offset_row; - uint32_t imagewidth = img->width; - tmsize_t stripsize; - tmsize_t bufsize; - int32_t fromskew, toskew; - int alpha = img->alpha; - int ret = 1, flip; - uint16_t colorchannels; - - stripsize = TIFFStripSize(tif); - bufsize = - _TIFFMultiplySSize(tif, alpha ? 4 : 3, stripsize, "gtStripSeparate"); - if (bufsize == 0) - { - return (0); - } - - flip = setorientation(img); - if (flip & FLIP_VERTICALLY) - { - if (w > INT_MAX) - { - TIFFErrorExtR(tif, TIFFFileName(tif), "Width overflow"); - return (0); - } - y = h - 1; - toskew = -(int32_t)(w + w); - } - else - { - y = 0; - toskew = -(int32_t)(w - w); - } - - switch (img->photometric) - { - case PHOTOMETRIC_MINISWHITE: - case PHOTOMETRIC_MINISBLACK: - case PHOTOMETRIC_PALETTE: - colorchannels = 1; - break; - - default: - colorchannels = 3; - break; - } - - TIFFGetFieldDefaulted(tif, TIFFTAG_ROWSPERSTRIP, &rowsperstrip); - scanline = TIFFScanlineSize(tif); - fromskew = (w < imagewidth ? imagewidth - w : 0); - for (row = 0; row < h; row += nrow) - { - uint32_t temp; - rowstoread = rowsperstrip - (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; - if (scanline > 0 && temp > (size_t)(TIFF_TMSIZE_T_MAX / scanline)) - { - TIFFErrorExtR(tif, TIFFFileName(tif), - "Integer overflow in gtStripSeparate"); - return 0; - } - if (buf == NULL) - { - if (_TIFFReadEncodedStripAndAllocBuffer( - tif, TIFFComputeStrip(tif, offset_row, 0), (void **)&buf, - bufsize, temp * scanline) == (tmsize_t)(-1) && - (buf == NULL || img->stoponerr)) - { - ret = 0; - break; - } - p0 = buf; - if (colorchannels == 1) - { - p2 = p1 = p0; - pa = (alpha ? (p0 + 3 * stripsize) : NULL); - } - else - { - p1 = p0 + stripsize; - p2 = p1 + stripsize; - pa = (alpha ? (p2 + stripsize) : NULL); - } - } - else if (TIFFReadEncodedStrip(tif, TIFFComputeStrip(tif, offset_row, 0), - p0, temp * scanline) == (tmsize_t)(-1) && - img->stoponerr) - { - ret = 0; - break; - } - if (colorchannels > 1 && - TIFFReadEncodedStrip(tif, TIFFComputeStrip(tif, offset_row, 1), p1, - temp * scanline) == (tmsize_t)(-1) && - img->stoponerr) - { - ret = 0; - break; - } - if (colorchannels > 1 && - TIFFReadEncodedStrip(tif, TIFFComputeStrip(tif, offset_row, 2), p2, - temp * scanline) == (tmsize_t)(-1) && - img->stoponerr) - { - ret = 0; - break; - } - if (alpha) - { - if (TIFFReadEncodedStrip( - tif, TIFFComputeStrip(tif, offset_row, colorchannels), pa, - temp * scanline) == (tmsize_t)(-1) && - img->stoponerr) - { - ret = 0; - break; - } - } - - pos = ((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, w, nrow, fromskew, toskew, p0 + pos, - p1 + pos, p2 + pos, (alpha ? (pa + pos) : NULL)); - } - y += ((flip & FLIP_VERTICALLY) ? -(int32_t)nrow : (int32_t)nrow); - } - - if (flip & FLIP_HORIZONTALLY) - { - uint32_t line; - - for (line = 0; line < h; line++) - { - uint32_t *left = raster + (line * w); - uint32_t *right = left + w - 1; - - while (left < right) - { - uint32_t temp = *left; - *left = *right; - *right = temp; - left++; - right--; - } - } - } - - _TIFFfreeExt(img->tif, buf); - return (ret); -} - -/* - * The following routines move decoded data returned - * from the TIFF library into rasters filled with packed - * ABGR pixels (i.e. suitable for passing to lrecwrite.) - * - * The routines have been created according to the most - * important cases and optimized. PickContigCase and - * PickSeparateCase analyze the parameters and select - * the appropriate "get" and "put" routine to use. - */ -#define REPEAT8(op) \ - REPEAT4(op); \ - REPEAT4(op) -#define REPEAT4(op) \ - REPEAT2(op); \ - REPEAT2(op) -#define REPEAT2(op) \ - op; \ - op -#define CASE8(x, op) \ - switch (x) \ - { \ - case 7: \ - op; /*-fallthrough*/ \ - case 6: \ - op; /*-fallthrough*/ \ - case 5: \ - op; /*-fallthrough*/ \ - case 4: \ - op; /*-fallthrough*/ \ - case 3: \ - op; /*-fallthrough*/ \ - case 2: \ - op; /*-fallthrough*/ \ - case 1: \ - op; \ - } -#define CASE4(x, op) \ - switch (x) \ - { \ - case 3: \ - op; /*-fallthrough*/ \ - case 2: \ - op; /*-fallthrough*/ \ - case 1: \ - op; \ - } -#define NOP - -#define UNROLL8(w, op1, op2) \ - { \ - uint32_t _x; \ - for (_x = w; _x >= 8; _x -= 8) \ - { \ - op1; \ - REPEAT8(op2); \ - } \ - if (_x > 0) \ - { \ - op1; \ - CASE8(_x, op2); \ - } \ - } -#define UNROLL4(w, op1, op2) \ - { \ - uint32_t _x; \ - for (_x = w; _x >= 4; _x -= 4) \ - { \ - op1; \ - REPEAT4(op2); \ - } \ - if (_x > 0) \ - { \ - op1; \ - CASE4(_x, op2); \ - } \ - } -#define UNROLL2(w, op1, op2) \ - { \ - uint32_t _x; \ - for (_x = w; _x >= 2; _x -= 2) \ - { \ - op1; \ - REPEAT2(op2); \ - } \ - if (_x) \ - { \ - op1; \ - op2; \ - } \ - } - -#define SKEW(r, g, b, skew) \ - { \ - r += skew; \ - g += skew; \ - b += skew; \ - } -#define SKEW4(r, g, b, a, skew) \ - { \ - r += skew; \ - g += skew; \ - b += skew; \ - a += skew; \ - } - -#define A1 (((uint32_t)0xffL) << 24) -#define PACK(r, g, b) \ - ((uint32_t)(r) | ((uint32_t)(g) << 8) | ((uint32_t)(b) << 16) | A1) -#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, \ - uint32_t w, uint32_t h, int32_t fromskew, int32_t toskew, \ - unsigned char *pp) - -/* - * 8-bit palette => colormap/RGB - */ -DECLAREContigPutFunc(put8bitcmaptile) -{ - uint32_t **PALmap = img->PALmap; - int samplesperpixel = img->samplesperpixel; - - (void)y; - for (; h > 0; --h) - { - for (x = w; x > 0; --x) - { - *cp++ = PALmap[*pp][0]; - pp += samplesperpixel; - } - cp += toskew; - pp += fromskew; - } -} - -/* - * 4-bit palette => colormap/RGB - */ -DECLAREContigPutFunc(put4bitcmaptile) -{ - uint32_t **PALmap = img->PALmap; - - (void)x; - (void)y; - fromskew /= 2; - for (; h > 0; --h) - { - uint32_t *bw; - UNROLL2(w, bw = PALmap[*pp++], *cp++ = *bw++); - cp += toskew; - pp += fromskew; - } -} - -/* - * 2-bit palette => colormap/RGB - */ -DECLAREContigPutFunc(put2bitcmaptile) -{ - uint32_t **PALmap = img->PALmap; - - (void)x; - (void)y; - fromskew /= 4; - for (; h > 0; --h) - { - uint32_t *bw; - UNROLL4(w, bw = PALmap[*pp++], *cp++ = *bw++); - cp += toskew; - pp += fromskew; - } -} - -/* - * 1-bit palette => colormap/RGB - */ -DECLAREContigPutFunc(put1bitcmaptile) -{ - uint32_t **PALmap = img->PALmap; - - (void)x; - (void)y; - fromskew /= 8; - for (; h > 0; --h) - { - uint32_t *bw; - UNROLL8(w, bw = PALmap[*pp++], *cp++ = *bw++); - cp += toskew; - pp += fromskew; - } -} - -/* - * 8-bit greyscale => colormap/RGB - */ -DECLAREContigPutFunc(putgreytile) -{ - int samplesperpixel = img->samplesperpixel; - uint32_t **BWmap = img->BWmap; - - (void)y; - for (; h > 0; --h) - { - for (x = w; x > 0; --x) - { - *cp++ = BWmap[*pp][0]; - pp += samplesperpixel; - } - cp += toskew; - pp += fromskew; - } -} - -/* - * 8-bit greyscale with associated alpha => colormap/RGBA - */ -DECLAREContigPutFunc(putagreytile) -{ - int samplesperpixel = img->samplesperpixel; - uint32_t **BWmap = img->BWmap; - - (void)y; - for (; h > 0; --h) - { - for (x = w; x > 0; --x) - { - *cp++ = BWmap[*pp][0] & ((uint32_t) * (pp + 1) << 24 | ~A1); - pp += samplesperpixel; - } - cp += toskew; - pp += fromskew; - } -} - -/* - * 16-bit greyscale => colormap/RGB - */ -DECLAREContigPutFunc(put16bitbwtile) -{ - int samplesperpixel = img->samplesperpixel; - uint32_t **BWmap = img->BWmap; - - (void)y; - for (; h > 0; --h) - { - uint16_t *wp = (uint16_t *)pp; - - for (x = w; x > 0; --x) - { - /* use high order byte of 16bit value */ - - *cp++ = BWmap[*wp >> 8][0]; - pp += 2 * samplesperpixel; - wp += samplesperpixel; - } - cp += toskew; - pp += fromskew; - } -} - -/* - * 1-bit bilevel => colormap/RGB - */ -DECLAREContigPutFunc(put1bitbwtile) -{ - uint32_t **BWmap = img->BWmap; - - (void)x; - (void)y; - fromskew /= 8; - for (; h > 0; --h) - { - uint32_t *bw; - UNROLL8(w, bw = BWmap[*pp++], *cp++ = *bw++); - cp += toskew; - pp += fromskew; - } -} - -/* - * 2-bit greyscale => colormap/RGB - */ -DECLAREContigPutFunc(put2bitbwtile) -{ - uint32_t **BWmap = img->BWmap; - - (void)x; - (void)y; - fromskew /= 4; - for (; h > 0; --h) - { - uint32_t *bw; - UNROLL4(w, bw = BWmap[*pp++], *cp++ = *bw++); - cp += toskew; - pp += fromskew; - } -} - -/* - * 4-bit greyscale => colormap/RGB - */ -DECLAREContigPutFunc(put4bitbwtile) -{ - uint32_t **BWmap = img->BWmap; - - (void)x; - (void)y; - fromskew /= 2; - for (; h > 0; --h) - { - uint32_t *bw; - UNROLL2(w, bw = BWmap[*pp++], *cp++ = *bw++); - cp += toskew; - pp += fromskew; - } -} - -/* - * 8-bit packed samples, no Map => RGB - */ -DECLAREContigPutFunc(putRGBcontig8bittile) -{ - int samplesperpixel = img->samplesperpixel; - - (void)x; - (void)y; - fromskew *= samplesperpixel; - for (; h > 0; --h) - { - UNROLL8(w, NOP, *cp++ = PACK(pp[0], pp[1], pp[2]); - pp += samplesperpixel); - cp += toskew; - pp += fromskew; - } -} - -/* - * 8-bit packed samples => RGBA w/ associated alpha - * (known to have Map == NULL) - */ -DECLAREContigPutFunc(putRGBAAcontig8bittile) -{ - int samplesperpixel = img->samplesperpixel; - - (void)x; - (void)y; - fromskew *= samplesperpixel; - for (; h > 0; --h) - { - UNROLL8(w, NOP, *cp++ = PACK4(pp[0], pp[1], pp[2], pp[3]); - pp += samplesperpixel); - cp += toskew; - pp += fromskew; - } -} - -/* - * 8-bit packed samples => RGBA w/ unassociated alpha - * (known to have Map == NULL) - */ -DECLAREContigPutFunc(putRGBUAcontig8bittile) -{ - int samplesperpixel = img->samplesperpixel; - (void)y; - fromskew *= samplesperpixel; - for (; h > 0; --h) - { - uint32_t r, g, b, a; - uint8_t *m; - for (x = w; x > 0; --x) - { - a = pp[3]; - m = img->UaToAa + ((size_t)a << 8); - r = m[pp[0]]; - g = m[pp[1]]; - b = m[pp[2]]; - *cp++ = PACK4(r, g, b, a); - pp += samplesperpixel; - } - cp += toskew; - pp += fromskew; - } -} - -/* - * 16-bit packed samples => RGB - */ -DECLAREContigPutFunc(putRGBcontig16bittile) -{ - int samplesperpixel = img->samplesperpixel; - uint16_t *wp = (uint16_t *)pp; - (void)y; - fromskew *= samplesperpixel; - for (; h > 0; --h) - { - for (x = w; x > 0; --x) - { - *cp++ = PACK(img->Bitdepth16To8[wp[0]], img->Bitdepth16To8[wp[1]], - img->Bitdepth16To8[wp[2]]); - wp += samplesperpixel; - } - cp += toskew; - wp += fromskew; - } -} - -/* - * 16-bit packed samples => RGBA w/ associated alpha - * (known to have Map == NULL) - */ -DECLAREContigPutFunc(putRGBAAcontig16bittile) -{ - int samplesperpixel = img->samplesperpixel; - uint16_t *wp = (uint16_t *)pp; - (void)y; - fromskew *= samplesperpixel; - for (; h > 0; --h) - { - for (x = w; x > 0; --x) - { - *cp++ = PACK4(img->Bitdepth16To8[wp[0]], img->Bitdepth16To8[wp[1]], - img->Bitdepth16To8[wp[2]], img->Bitdepth16To8[wp[3]]); - wp += samplesperpixel; - } - cp += toskew; - wp += fromskew; - } -} - -/* - * 16-bit packed samples => RGBA w/ unassociated alpha - * (known to have Map == NULL) - */ -DECLAREContigPutFunc(putRGBUAcontig16bittile) -{ - int samplesperpixel = img->samplesperpixel; - uint16_t *wp = (uint16_t *)pp; - (void)y; - fromskew *= samplesperpixel; - for (; h > 0; --h) - { - uint32_t r, g, b, a; - uint8_t *m; - for (x = w; x > 0; --x) - { - a = img->Bitdepth16To8[wp[3]]; - m = img->UaToAa + ((size_t)a << 8); - r = m[img->Bitdepth16To8[wp[0]]]; - g = m[img->Bitdepth16To8[wp[1]]]; - b = m[img->Bitdepth16To8[wp[2]]]; - *cp++ = PACK4(r, g, b, a); - wp += samplesperpixel; - } - cp += toskew; - wp += fromskew; - } -} - -/* - * 8-bit packed CMYK samples w/o Map => RGB - * - * NB: The conversion of CMYK->RGB is *very* crude. - */ -DECLAREContigPutFunc(putRGBcontig8bitCMYKtile) -{ - int samplesperpixel = img->samplesperpixel; - uint16_t r, g, b, k; - - (void)x; - (void)y; - fromskew *= 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; - *cp++ = PACK(r, g, b); pp += samplesperpixel); - cp += toskew; - pp += fromskew; - } -} - -/* - * 8-bit packed CMYK samples w/Map => RGB - * - * NB: The conversion of CMYK->RGB is *very* crude. - */ -DECLAREContigPutFunc(putRGBcontig8bitCMYKMaptile) -{ - int samplesperpixel = img->samplesperpixel; - TIFFRGBValue *Map = img->Map; - uint16_t r, g, b, k; - - (void)y; - fromskew *= 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; - *cp++ = PACK(Map[r], Map[g], Map[b]); - pp += samplesperpixel; - } - pp += fromskew; - cp += toskew; - } -} - -#define DECLARESepPutFunc(name) \ - static void name(TIFFRGBAImage *img, uint32_t *cp, uint32_t x, uint32_t y, \ - uint32_t w, uint32_t h, int32_t fromskew, int32_t toskew, \ - unsigned char *r, unsigned char *g, unsigned char *b, \ - unsigned char *a) - -/* - * 8-bit unpacked samples => RGB - */ -DECLARESepPutFunc(putRGBseparate8bittile) -{ - (void)img; - (void)x; - (void)y; - (void)a; - for (; h > 0; --h) - { - UNROLL8(w, NOP, *cp++ = PACK(*r++, *g++, *b++)); - SKEW(r, g, b, fromskew); - cp += toskew; - } -} - -/* - * 8-bit unpacked samples => RGBA w/ associated alpha - */ -DECLARESepPutFunc(putRGBAAseparate8bittile) -{ - (void)img; - (void)x; - (void)y; - for (; h > 0; --h) - { - UNROLL8(w, NOP, *cp++ = PACK4(*r++, *g++, *b++, *a++)); - SKEW4(r, g, b, a, fromskew); - cp += toskew; - } -} - -/* - * 8-bit unpacked CMYK samples => RGBA - */ -DECLARESepPutFunc(putCMYKseparate8bittile) -{ - (void)img; - (void)y; - for (; h > 0; --h) - { - uint32_t 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; - *cp++ = PACK4(rv, gv, bv, 255); - } - SKEW4(r, g, b, a, fromskew); - cp += toskew; - } -} - -/* - * 8-bit unpacked samples => RGBA w/ unassociated alpha - */ -DECLARESepPutFunc(putRGBUAseparate8bittile) -{ - (void)img; - (void)y; - for (; h > 0; --h) - { - uint32_t rv, gv, bv, av; - uint8_t *m; - for (x = w; x > 0; --x) - { - av = *a++; - m = img->UaToAa + ((size_t)av << 8); - rv = m[*r++]; - gv = m[*g++]; - bv = m[*b++]; - *cp++ = PACK4(rv, gv, bv, av); - } - SKEW4(r, g, b, a, fromskew); - cp += toskew; - } -} - -/* - * 16-bit unpacked samples => RGB - */ -DECLARESepPutFunc(putRGBseparate16bittile) -{ - uint16_t *wr = (uint16_t *)r; - uint16_t *wg = (uint16_t *)g; - uint16_t *wb = (uint16_t *)b; - (void)img; - (void)y; - (void)a; - for (; h > 0; --h) - { - for (x = 0; x < w; x++) - *cp++ = PACK(img->Bitdepth16To8[*wr++], img->Bitdepth16To8[*wg++], - img->Bitdepth16To8[*wb++]); - SKEW(wr, wg, wb, fromskew); - cp += toskew; - } -} - -/* - * 16-bit unpacked samples => RGBA w/ associated alpha - */ -DECLARESepPutFunc(putRGBAAseparate16bittile) -{ - uint16_t *wr = (uint16_t *)r; - uint16_t *wg = (uint16_t *)g; - uint16_t *wb = (uint16_t *)b; - uint16_t *wa = (uint16_t *)a; - (void)img; - (void)y; - for (; h > 0; --h) - { - for (x = 0; x < w; x++) - *cp++ = PACK4(img->Bitdepth16To8[*wr++], img->Bitdepth16To8[*wg++], - img->Bitdepth16To8[*wb++], img->Bitdepth16To8[*wa++]); - SKEW4(wr, wg, wb, wa, fromskew); - cp += toskew; - } -} - -/* - * 16-bit unpacked samples => RGBA w/ unassociated alpha - */ -DECLARESepPutFunc(putRGBUAseparate16bittile) -{ - uint16_t *wr = (uint16_t *)r; - uint16_t *wg = (uint16_t *)g; - uint16_t *wb = (uint16_t *)b; - uint16_t *wa = (uint16_t *)a; - (void)img; - (void)y; - for (; h > 0; --h) - { - uint32_t r2, g2, b2, a2; - uint8_t *m; - for (x = w; x > 0; --x) - { - a2 = img->Bitdepth16To8[*wa++]; - m = img->UaToAa + ((size_t)a2 << 8); - r2 = m[img->Bitdepth16To8[*wr++]]; - g2 = m[img->Bitdepth16To8[*wg++]]; - b2 = m[img->Bitdepth16To8[*wb++]]; - *cp++ = PACK4(r2, g2, b2, a2); - } - SKEW4(wr, wg, wb, wa, fromskew); - cp += toskew; - } -} - -/* - * 8-bit packed CIE L*a*b 1976 samples => RGB - */ -DECLAREContigPutFunc(putcontig8bitCIELab8) -{ - float X, Y, Z; - uint32_t r, g, b; - (void)y; - fromskew *= 3; - for (; h > 0; --h) - { - for (x = w; x > 0; --x) - { - TIFFCIELabToXYZ(img->cielab, (unsigned char)pp[0], - (signed char)pp[1], (signed char)pp[2], &X, &Y, &Z); - TIFFXYZToRGB(img->cielab, X, Y, Z, &r, &g, &b); - *cp++ = PACK(r, g, b); - pp += 3; - } - cp += toskew; - pp += fromskew; - } -} - -/* - * 16-bit packed CIE L*a*b 1976 samples => RGB - */ -DECLAREContigPutFunc(putcontig8bitCIELab16) -{ - float X, Y, Z; - uint32_t r, g, b; - uint16_t *wp = (uint16_t *)pp; - (void)y; - fromskew *= 3; - for (; h > 0; --h) - { - for (x = w; x > 0; --x) - { - TIFFCIELab16ToXYZ(img->cielab, (uint16_t)wp[0], (int16_t)wp[1], - (int16_t)wp[2], &X, &Y, &Z); - TIFFXYZToRGB(img->cielab, X, Y, Z, &r, &g, &b); - *cp++ = PACK(r, g, b); - wp += 3; - } - cp += toskew; - wp += fromskew; - } -} - -/* - * YCbCr -> RGB conversion and packing routines. - */ - -#define YCbCrtoRGB(dst, Y) \ - { \ - uint32_t r, g, b; \ - TIFFYCbCrtoRGB(img->ycbcr, (Y), Cb, Cr, &r, &g, &b); \ - dst = PACK(r, g, b); \ - } - -/* - * 8-bit packed YCbCr samples w/ 4,4 subsampling => RGB - */ -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; - - (void)y; - /* adjust fromskew */ - fromskew = (fromskew / 4) * (4 * 2 + 2); - if ((h & 3) == 0 && (w & 3) == 0) - { - for (; h >= 4; h -= 4) - { - x = w >> 2; - do - { - int32_t Cb = pp[16]; - int32_t Cr = pp[17]; - - YCbCrtoRGB(cp[0], pp[0]); - YCbCrtoRGB(cp[1], pp[1]); - YCbCrtoRGB(cp[2], pp[2]); - YCbCrtoRGB(cp[3], pp[3]); - YCbCrtoRGB(cp1[0], pp[4]); - YCbCrtoRGB(cp1[1], pp[5]); - YCbCrtoRGB(cp1[2], pp[6]); - YCbCrtoRGB(cp1[3], pp[7]); - YCbCrtoRGB(cp2[0], pp[8]); - YCbCrtoRGB(cp2[1], pp[9]); - YCbCrtoRGB(cp2[2], pp[10]); - YCbCrtoRGB(cp2[3], pp[11]); - YCbCrtoRGB(cp3[0], pp[12]); - YCbCrtoRGB(cp3[1], pp[13]); - YCbCrtoRGB(cp3[2], pp[14]); - YCbCrtoRGB(cp3[3], pp[15]); - - cp += 4; - cp1 += 4; - cp2 += 4; - cp3 += 4; - pp += 18; - } while (--x); - cp += incr; - cp1 += incr; - cp2 += incr; - cp3 += incr; - pp += fromskew; - } - } - else - { - while (h > 0) - { - for (x = w; x > 0;) - { - int32_t Cb = pp[16]; - int32_t Cr = pp[17]; - switch (x) - { - default: - switch (h) - { - default: - YCbCrtoRGB(cp3[3], pp[15]); /* FALLTHROUGH */ - case 3: - YCbCrtoRGB(cp2[3], pp[11]); /* FALLTHROUGH */ - case 2: - YCbCrtoRGB(cp1[3], pp[7]); /* FALLTHROUGH */ - case 1: - YCbCrtoRGB(cp[3], pp[3]); /* FALLTHROUGH */ - } /* FALLTHROUGH */ - case 3: - switch (h) - { - default: - YCbCrtoRGB(cp3[2], pp[14]); /* FALLTHROUGH */ - case 3: - YCbCrtoRGB(cp2[2], pp[10]); /* FALLTHROUGH */ - case 2: - YCbCrtoRGB(cp1[2], pp[6]); /* FALLTHROUGH */ - case 1: - YCbCrtoRGB(cp[2], pp[2]); /* FALLTHROUGH */ - } /* FALLTHROUGH */ - case 2: - switch (h) - { - default: - YCbCrtoRGB(cp3[1], pp[13]); /* FALLTHROUGH */ - case 3: - YCbCrtoRGB(cp2[1], pp[9]); /* FALLTHROUGH */ - case 2: - YCbCrtoRGB(cp1[1], pp[5]); /* FALLTHROUGH */ - case 1: - YCbCrtoRGB(cp[1], pp[1]); /* FALLTHROUGH */ - } /* FALLTHROUGH */ - case 1: - switch (h) - { - default: - YCbCrtoRGB(cp3[0], pp[12]); /* FALLTHROUGH */ - case 3: - YCbCrtoRGB(cp2[0], pp[8]); /* FALLTHROUGH */ - case 2: - YCbCrtoRGB(cp1[0], pp[4]); /* FALLTHROUGH */ - case 1: - YCbCrtoRGB(cp[0], pp[0]); /* FALLTHROUGH */ - } /* FALLTHROUGH */ - } - if (x < 4) - { - cp += x; - cp1 += x; - cp2 += x; - cp3 += x; - x = 0; - } - else - { - cp += 4; - cp1 += 4; - cp2 += 4; - cp3 += 4; - x -= 4; - } - pp += 18; - } - if (h <= 4) - break; - h -= 4; - cp += incr; - cp1 += incr; - cp2 += incr; - cp3 += incr; - pp += fromskew; - } - } -} - -/* - * 8-bit packed YCbCr samples w/ 4,2 subsampling => RGB - */ -DECLAREContigPutFunc(putcontig8bitYCbCr42tile) -{ - uint32_t *cp1 = cp + w + toskew; - int32_t incr = 2 * toskew + w; - - (void)y; - fromskew = (fromskew / 4) * (4 * 2 + 2); - if ((w & 3) == 0 && (h & 1) == 0) - { - for (; h >= 2; h -= 2) - { - x = w >> 2; - do - { - int32_t Cb = pp[8]; - int32_t Cr = pp[9]; - - YCbCrtoRGB(cp[0], pp[0]); - YCbCrtoRGB(cp[1], pp[1]); - YCbCrtoRGB(cp[2], pp[2]); - YCbCrtoRGB(cp[3], pp[3]); - YCbCrtoRGB(cp1[0], pp[4]); - YCbCrtoRGB(cp1[1], pp[5]); - YCbCrtoRGB(cp1[2], pp[6]); - YCbCrtoRGB(cp1[3], pp[7]); - - cp += 4; - cp1 += 4; - pp += 10; - } while (--x); - cp += incr; - cp1 += incr; - pp += fromskew; - } - } - else - { - while (h > 0) - { - for (x = w; x > 0;) - { - int32_t Cb = pp[8]; - int32_t Cr = pp[9]; - switch (x) - { - default: - switch (h) - { - default: - YCbCrtoRGB(cp1[3], pp[7]); /* FALLTHROUGH */ - case 1: - YCbCrtoRGB(cp[3], pp[3]); /* FALLTHROUGH */ - } /* FALLTHROUGH */ - case 3: - switch (h) - { - default: - YCbCrtoRGB(cp1[2], pp[6]); /* FALLTHROUGH */ - case 1: - YCbCrtoRGB(cp[2], pp[2]); /* FALLTHROUGH */ - } /* FALLTHROUGH */ - case 2: - switch (h) - { - default: - YCbCrtoRGB(cp1[1], pp[5]); /* FALLTHROUGH */ - case 1: - YCbCrtoRGB(cp[1], pp[1]); /* FALLTHROUGH */ - } /* FALLTHROUGH */ - case 1: - switch (h) - { - default: - YCbCrtoRGB(cp1[0], pp[4]); /* FALLTHROUGH */ - case 1: - YCbCrtoRGB(cp[0], pp[0]); /* FALLTHROUGH */ - } /* FALLTHROUGH */ - } - if (x < 4) - { - cp += x; - cp1 += x; - x = 0; - } - else - { - cp += 4; - cp1 += 4; - x -= 4; - } - pp += 10; - } - if (h <= 2) - break; - h -= 2; - cp += incr; - cp1 += incr; - pp += fromskew; - } - } -} - -/* - * 8-bit packed YCbCr samples w/ 4,1 subsampling => RGB - */ -DECLAREContigPutFunc(putcontig8bitYCbCr41tile) -{ - (void)y; - fromskew = (fromskew / 4) * (4 * 1 + 2); - do - { - x = w >> 2; - while (x > 0) - { - int32_t Cb = pp[4]; - int32_t Cr = pp[5]; - - YCbCrtoRGB(cp[0], pp[0]); - YCbCrtoRGB(cp[1], pp[1]); - YCbCrtoRGB(cp[2], pp[2]); - YCbCrtoRGB(cp[3], pp[3]); - - cp += 4; - pp += 6; - x--; - } - - if ((w & 3) != 0) - { - int32_t Cb = pp[4]; - int32_t Cr = pp[5]; - - switch ((w & 3)) - { - case 3: - YCbCrtoRGB(cp[2], pp[2]); /*-fallthrough*/ - case 2: - YCbCrtoRGB(cp[1], pp[1]); /*-fallthrough*/ - case 1: - YCbCrtoRGB(cp[0], pp[0]); /*-fallthrough*/ - case 0: - break; - } - - cp += (w & 3); - pp += 6; - } - - cp += toskew; - pp += fromskew; - } while (--h); -} - -/* - * 8-bit packed YCbCr samples w/ 2,2 subsampling => RGB - */ -DECLAREContigPutFunc(putcontig8bitYCbCr22tile) -{ - uint32_t *cp2; - int32_t incr = 2 * toskew + w; - (void)y; - fromskew = (fromskew / 2) * (2 * 2 + 2); - cp2 = cp + w + toskew; - while (h >= 2) - { - x = w; - while (x >= 2) - { - uint32_t Cb = pp[4]; - uint32_t Cr = pp[5]; - YCbCrtoRGB(cp[0], pp[0]); - YCbCrtoRGB(cp[1], pp[1]); - YCbCrtoRGB(cp2[0], pp[2]); - YCbCrtoRGB(cp2[1], pp[3]); - cp += 2; - cp2 += 2; - pp += 6; - x -= 2; - } - if (x == 1) - { - uint32_t Cb = pp[4]; - uint32_t Cr = pp[5]; - YCbCrtoRGB(cp[0], pp[0]); - YCbCrtoRGB(cp2[0], pp[2]); - cp++; - cp2++; - pp += 6; - } - cp += incr; - cp2 += incr; - pp += fromskew; - h -= 2; - } - if (h == 1) - { - x = w; - while (x >= 2) - { - uint32_t Cb = pp[4]; - uint32_t Cr = pp[5]; - YCbCrtoRGB(cp[0], pp[0]); - YCbCrtoRGB(cp[1], pp[1]); - cp += 2; - cp2 += 2; - pp += 6; - x -= 2; - } - if (x == 1) - { - uint32_t Cb = pp[4]; - uint32_t Cr = pp[5]; - YCbCrtoRGB(cp[0], pp[0]); - } - } -} - -/* - * 8-bit packed YCbCr samples w/ 2,1 subsampling => RGB - */ -DECLAREContigPutFunc(putcontig8bitYCbCr21tile) -{ - (void)y; - fromskew = (fromskew / 2) * (2 * 1 + 2); - do - { - x = w >> 1; - while (x > 0) - { - int32_t Cb = pp[2]; - int32_t Cr = pp[3]; - - YCbCrtoRGB(cp[0], pp[0]); - YCbCrtoRGB(cp[1], pp[1]); - - cp += 2; - pp += 4; - x--; - } - - if ((w & 1) != 0) - { - int32_t Cb = pp[2]; - int32_t Cr = pp[3]; - - YCbCrtoRGB(cp[0], pp[0]); - - cp += 1; - pp += 4; - } - - cp += toskew; - pp += fromskew; - } while (--h); -} - -/* - * 8-bit packed YCbCr samples w/ 1,2 subsampling => RGB - */ -DECLAREContigPutFunc(putcontig8bitYCbCr12tile) -{ - uint32_t *cp2; - int32_t incr = 2 * toskew + w; - (void)y; - fromskew = (fromskew / 1) * (1 * 2 + 2); - cp2 = cp + w + toskew; - while (h >= 2) - { - x = w; - do - { - uint32_t Cb = pp[2]; - uint32_t Cr = pp[3]; - YCbCrtoRGB(cp[0], pp[0]); - YCbCrtoRGB(cp2[0], pp[1]); - cp++; - cp2++; - pp += 4; - } while (--x); - cp += incr; - cp2 += incr; - pp += fromskew; - h -= 2; - } - if (h == 1) - { - x = w; - do - { - uint32_t Cb = pp[2]; - uint32_t Cr = pp[3]; - YCbCrtoRGB(cp[0], pp[0]); - cp++; - pp += 4; - } while (--x); - } -} - -/* - * 8-bit packed YCbCr samples w/ no subsampling => RGB - */ -DECLAREContigPutFunc(putcontig8bitYCbCr11tile) -{ - (void)y; - fromskew = (fromskew / 1) * (1 * 1 + 2); - do - { - x = w; /* was x = w>>1; patched 2000/09/25 warmerda@home.com */ - do - { - int32_t Cb = pp[1]; - int32_t Cr = pp[2]; - - YCbCrtoRGB(*cp++, pp[0]); - - pp += 3; - } while (--x); - cp += toskew; - pp += fromskew; - } while (--h); -} - -/* - * 8-bit packed YCbCr samples w/ no subsampling => RGB - */ -DECLARESepPutFunc(putseparate8bitYCbCr11tile) -{ - (void)y; - (void)a; - /* TODO: naming of input vars is still off, change obfuscating declaration - * inside define, or resolve obfuscation */ - for (; h > 0; --h) - { - x = w; - do - { - uint32_t dr, dg, db; - TIFFYCbCrtoRGB(img->ycbcr, *r++, *g++, *b++, &dr, &dg, &db); - *cp++ = PACK(dr, dg, db); - } while (--x); - SKEW(r, g, b, fromskew); - cp += toskew; - } -} -#undef YCbCrtoRGB - -static int isInRefBlackWhiteRange(float f) -{ - return f > (float)(-0x7FFFFFFF + 128) && f < (float)0x7FFFFFFF; -} - -static int initYCbCrConversion(TIFFRGBAImage *img) -{ - static const char module[] = "initYCbCrConversion"; - - float *luma, *refBlackWhite; - - if (img->ycbcr == NULL) - { - img->ycbcr = (TIFFYCbCrToRGB *)_TIFFmallocExt( - img->tif, TIFFroundup_32(sizeof(TIFFYCbCrToRGB), sizeof(long)) + - 4 * 256 * sizeof(TIFFRGBValue) + - 2 * 256 * sizeof(int) + 3 * 256 * sizeof(int32_t)); - if (img->ycbcr == NULL) - { - TIFFErrorExtR(img->tif, module, - "No space for YCbCr->RGB conversion state"); - return (0); - } - } - - TIFFGetFieldDefaulted(img->tif, TIFFTAG_YCBCRCOEFFICIENTS, &luma); - TIFFGetFieldDefaulted(img->tif, TIFFTAG_REFERENCEBLACKWHITE, - &refBlackWhite); - - /* 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]) - { - TIFFErrorExtR(img->tif, module, - "Invalid values for YCbCrCoefficients tag"); - return (0); - } - - if (!isInRefBlackWhiteRange(refBlackWhite[0]) || - !isInRefBlackWhiteRange(refBlackWhite[1]) || - !isInRefBlackWhiteRange(refBlackWhite[2]) || - !isInRefBlackWhiteRange(refBlackWhite[3]) || - !isInRefBlackWhiteRange(refBlackWhite[4]) || - !isInRefBlackWhiteRange(refBlackWhite[5])) - { - TIFFErrorExtR(img->tif, module, - "Invalid values for ReferenceBlackWhite tag"); - return (0); - } - - if (TIFFYCbCrToRGBInit(img->ycbcr, luma, refBlackWhite) < 0) - return (0); - return (1); -} - -static tileContigRoutine initCIELabConversion(TIFFRGBAImage *img) -{ - static const char module[] = "initCIELabConversion"; - - float *whitePoint; - float refWhite[3]; - - TIFFGetFieldDefaulted(img->tif, TIFFTAG_WHITEPOINT, &whitePoint); - if (whitePoint[1] == 0.0f) - { - TIFFErrorExtR(img->tif, module, "Invalid value for WhitePoint tag."); - return NULL; - } - - if (!img->cielab) - { - img->cielab = (TIFFCIELabToRGB *)_TIFFmallocExt( - img->tif, sizeof(TIFFCIELabToRGB)); - if (!img->cielab) - { - TIFFErrorExtR(img->tif, module, - "No space for CIE L*a*b*->RGB conversion state."); - return NULL; - } - } - - refWhite[1] = 100.0F; - refWhite[0] = whitePoint[0] / whitePoint[1] * refWhite[1]; - refWhite[2] = - (1.0F - whitePoint[0] - whitePoint[1]) / whitePoint[1] * refWhite[1]; - if (TIFFCIELabToRGBInit(img->cielab, &display_sRGB, refWhite) < 0) - { - TIFFErrorExtR(img->tif, module, - "Failed to initialize CIE L*a*b*->RGB conversion state."); - _TIFFfreeExt(img->tif, img->cielab); - return NULL; - } - - if (img->bitspersample == 8) - return putcontig8bitCIELab8; - else if (img->bitspersample == 16) - return putcontig8bitCIELab16; - return NULL; -} - -/* - * Greyscale images with less than 8 bits/sample are handled - * with a table to avoid lots of shifts and masks. The table - * is setup so that put*bwtile (below) can retrieve 8/bitspersample - * pixel values simply by indexing into the table with one - * number. - */ -static int makebwmap(TIFFRGBAImage *img) -{ - TIFFRGBValue *Map = img->Map; - int bitspersample = img->bitspersample; - int nsamples = 8 / bitspersample; - int i; - uint32_t *p; - - if (nsamples == 0) - nsamples = 1; - - img->BWmap = (uint32_t **)_TIFFmallocExt( - img->tif, - 256 * sizeof(uint32_t *) + (256 * nsamples * sizeof(uint32_t))); - if (img->BWmap == NULL) - { - TIFFErrorExtR(img->tif, TIFFFileName(img->tif), - "No space for B&W mapping table"); - return (0); - } - p = (uint32_t *)(img->BWmap + 256); - for (i = 0; i < 256; i++) - { - TIFFRGBValue c; - img->BWmap[i] = p; - switch (bitspersample) - { -#define GREY(x) \ - c = Map[x]; \ - *p++ = PACK(c, c, c); - case 1: - GREY(i >> 7); - GREY((i >> 6) & 1); - GREY((i >> 5) & 1); - GREY((i >> 4) & 1); - GREY((i >> 3) & 1); - GREY((i >> 2) & 1); - GREY((i >> 1) & 1); - GREY(i & 1); - break; - case 2: - GREY(i >> 6); - GREY((i >> 4) & 3); - GREY((i >> 2) & 3); - GREY(i & 3); - break; - case 4: - GREY(i >> 4); - GREY(i & 0xf); - break; - case 8: - case 16: - GREY(i); - break; - } -#undef GREY - } - return (1); -} - -/* - * Construct a mapping table to convert from the range - * of the data samples to [0,255] --for display. This - * process also handles inverting B&W images when needed. - */ -static int setupMap(TIFFRGBAImage *img) -{ - int32_t x, range; - - range = (int32_t)((1L << img->bitspersample) - 1); - - /* treat 16 bit the same as eight bit */ - if (img->bitspersample == 16) - range = (int32_t)255; - - img->Map = (TIFFRGBValue *)_TIFFmallocExt( - img->tif, (range + 1) * sizeof(TIFFRGBValue)); - if (img->Map == NULL) - { - TIFFErrorExtR(img->tif, TIFFFileName(img->tif), - "No space for photometric conversion table"); - return (0); - } - if (img->photometric == PHOTOMETRIC_MINISWHITE) - { - for (x = 0; x <= range; x++) - img->Map[x] = (TIFFRGBValue)(((range - x) * 255) / range); - } - else - { - for (x = 0; x <= range; x++) - img->Map[x] = (TIFFRGBValue)((x * 255) / range); - } - if (img->bitspersample <= 16 && - (img->photometric == PHOTOMETRIC_MINISBLACK || - img->photometric == PHOTOMETRIC_MINISWHITE)) - { - /* - * Use photometric mapping table to construct - * unpacking tables for samples <= 8 bits. - */ - if (!makebwmap(img)) - return (0); - /* no longer need Map, free it */ - _TIFFfreeExt(img->tif, img->Map); - img->Map = NULL; - } - return (1); -} - -static int checkcmap(TIFFRGBAImage *img) -{ - uint16_t *r = img->redcmap; - uint16_t *g = img->greencmap; - uint16_t *b = img->bluecmap; - long n = 1L << img->bitspersample; - - while (n-- > 0) - if (*r++ >= 256 || *g++ >= 256 || *b++ >= 256) - return (16); - return (8); -} - -static void cvtcmap(TIFFRGBAImage *img) -{ - uint16_t *r = img->redcmap; - uint16_t *g = img->greencmap; - uint16_t *b = img->bluecmap; - long i; - - for (i = (1L << img->bitspersample) - 1; i >= 0; i--) - { -#define CVT(x) ((uint16_t)((x) >> 8)) - r[i] = CVT(r[i]); - g[i] = CVT(g[i]); - b[i] = CVT(b[i]); -#undef CVT - } -} - -/* - * Palette images with <= 8 bits/sample are handled - * with a table to avoid lots of shifts and masks. The table - * is setup so that put*cmaptile (below) can retrieve 8/bitspersample - * pixel values simply by indexing into the table with one - * number. - */ -static int makecmap(TIFFRGBAImage *img) -{ - int bitspersample = img->bitspersample; - int nsamples = 8 / bitspersample; - uint16_t *r = img->redcmap; - uint16_t *g = img->greencmap; - uint16_t *b = img->bluecmap; - uint32_t *p; - int i; - - img->PALmap = (uint32_t **)_TIFFmallocExt( - img->tif, - 256 * sizeof(uint32_t *) + (256 * nsamples * sizeof(uint32_t))); - if (img->PALmap == NULL) - { - TIFFErrorExtR(img->tif, TIFFFileName(img->tif), - "No space for Palette mapping table"); - return (0); - } - p = (uint32_t *)(img->PALmap + 256); - for (i = 0; i < 256; i++) - { - TIFFRGBValue c; - img->PALmap[i] = p; -#define CMAP(x) \ - c = (TIFFRGBValue)x; \ - *p++ = PACK(r[c] & 0xff, g[c] & 0xff, b[c] & 0xff); - switch (bitspersample) - { - case 1: - CMAP(i >> 7); - CMAP((i >> 6) & 1); - CMAP((i >> 5) & 1); - CMAP((i >> 4) & 1); - CMAP((i >> 3) & 1); - CMAP((i >> 2) & 1); - CMAP((i >> 1) & 1); - CMAP(i & 1); - break; - case 2: - CMAP(i >> 6); - CMAP((i >> 4) & 3); - CMAP((i >> 2) & 3); - CMAP(i & 3); - break; - case 4: - CMAP(i >> 4); - CMAP(i & 0xf); - break; - case 8: - CMAP(i); - break; - } -#undef CMAP - } - return (1); -} - -/* - * Construct any mapping table used - * by the associated put routine. - */ -static int buildMap(TIFFRGBAImage *img) -{ - switch (img->photometric) - { - case PHOTOMETRIC_RGB: - case PHOTOMETRIC_YCBCR: - case PHOTOMETRIC_SEPARATED: - if (img->bitspersample == 8) - break; - /* fall through... */ - case PHOTOMETRIC_MINISBLACK: - case PHOTOMETRIC_MINISWHITE: - if (!setupMap(img)) - return (0); - break; - case PHOTOMETRIC_PALETTE: - /* - * Convert 16-bit colormap to 8-bit (unless it looks - * like an old-style 8-bit colormap). - */ - if (checkcmap(img) == 16) - cvtcmap(img); - else - TIFFWarningExtR(img->tif, TIFFFileName(img->tif), - "Assuming 8-bit colormap"); - /* - * Use mapping table and colormap to construct - * unpacking tables for samples < 8 bits. - */ - if (img->bitspersample <= 8 && !makecmap(img)) - return (0); - break; - } - return (1); -} - -/* - * Select the appropriate conversion routine for packed data. - */ -static int PickContigCase(TIFFRGBAImage *img) -{ - img->get = TIFFIsTiled(img->tif) ? gtTileContig : gtStripContig; - img->put.contig = NULL; - switch (img->photometric) - { - case PHOTOMETRIC_RGB: - switch (img->bitspersample) - { - case 8: - if (img->alpha == EXTRASAMPLE_ASSOCALPHA && - img->samplesperpixel >= 4) - img->put.contig = putRGBAAcontig8bittile; - else if (img->alpha == EXTRASAMPLE_UNASSALPHA && - img->samplesperpixel >= 4) - { - if (BuildMapUaToAa(img)) - img->put.contig = putRGBUAcontig8bittile; - } - else if (img->samplesperpixel >= 3) - img->put.contig = putRGBcontig8bittile; - break; - case 16: - if (img->alpha == EXTRASAMPLE_ASSOCALPHA && - img->samplesperpixel >= 4) - { - if (BuildMapBitdepth16To8(img)) - img->put.contig = putRGBAAcontig16bittile; - } - else if (img->alpha == EXTRASAMPLE_UNASSALPHA && - img->samplesperpixel >= 4) - { - if (BuildMapBitdepth16To8(img) && BuildMapUaToAa(img)) - img->put.contig = putRGBUAcontig16bittile; - } - else if (img->samplesperpixel >= 3) - { - if (BuildMapBitdepth16To8(img)) - img->put.contig = putRGBcontig16bittile; - } - break; - } - break; - case PHOTOMETRIC_SEPARATED: - if (img->samplesperpixel >= 4 && buildMap(img)) - { - if (img->bitspersample == 8) - { - if (!img->Map) - img->put.contig = putRGBcontig8bitCMYKtile; - else - img->put.contig = putRGBcontig8bitCMYKMaptile; - } - } - break; - case PHOTOMETRIC_PALETTE: - if (buildMap(img)) - { - switch (img->bitspersample) - { - case 8: - img->put.contig = put8bitcmaptile; - break; - case 4: - img->put.contig = put4bitcmaptile; - break; - case 2: - img->put.contig = put2bitcmaptile; - break; - case 1: - img->put.contig = put1bitcmaptile; - break; - } - } - break; - case PHOTOMETRIC_MINISWHITE: - case PHOTOMETRIC_MINISBLACK: - if (buildMap(img)) - { - switch (img->bitspersample) - { - case 16: - img->put.contig = put16bitbwtile; - break; - case 8: - if (img->alpha && img->samplesperpixel == 2) - img->put.contig = putagreytile; - else - img->put.contig = putgreytile; - break; - case 4: - img->put.contig = put4bitbwtile; - break; - case 2: - img->put.contig = put2bitbwtile; - break; - case 1: - img->put.contig = put1bitbwtile; - break; - } - } - break; - case PHOTOMETRIC_YCBCR: - if ((img->bitspersample == 8) && (img->samplesperpixel == 3)) - { - if (initYCbCrConversion(img) != 0) - { - /* - * The 6.0 spec says that subsampling must be - * one of 1, 2, or 4, and that vertical subsampling - * must always be <= horizontal subsampling; so - * there are only a few possibilities and we just - * enumerate the cases. - * Joris: added support for the [1,2] case, nonetheless, to - * accommodate some OJPEG files - */ - uint16_t SubsamplingHor; - uint16_t SubsamplingVer; - TIFFGetFieldDefaulted(img->tif, TIFFTAG_YCBCRSUBSAMPLING, - &SubsamplingHor, &SubsamplingVer); - switch ((SubsamplingHor << 4) | SubsamplingVer) - { - case 0x44: - img->put.contig = putcontig8bitYCbCr44tile; - break; - case 0x42: - img->put.contig = putcontig8bitYCbCr42tile; - break; - case 0x41: - img->put.contig = putcontig8bitYCbCr41tile; - break; - case 0x22: - img->put.contig = putcontig8bitYCbCr22tile; - break; - case 0x21: - img->put.contig = putcontig8bitYCbCr21tile; - break; - case 0x12: - img->put.contig = putcontig8bitYCbCr12tile; - break; - case 0x11: - img->put.contig = putcontig8bitYCbCr11tile; - break; - } - } - } - break; - case PHOTOMETRIC_CIELAB: - if (img->samplesperpixel == 3 && buildMap(img)) - { - if (img->bitspersample == 8 || img->bitspersample == 16) - img->put.contig = initCIELabConversion(img); - break; - } - } - return ((img->get != NULL) && (img->put.contig != NULL)); -} - -/* - * Select the appropriate conversion routine for unpacked data. - * - * NB: we assume that unpacked single channel data is directed - * to the "packed routines. - */ -static int PickSeparateCase(TIFFRGBAImage *img) -{ - img->get = TIFFIsTiled(img->tif) ? gtTileSeparate : gtStripSeparate; - img->put.separate = NULL; - switch (img->photometric) - { - case PHOTOMETRIC_MINISWHITE: - case PHOTOMETRIC_MINISBLACK: - /* greyscale images processed pretty much as RGB by gtTileSeparate - */ - case PHOTOMETRIC_RGB: - switch (img->bitspersample) - { - case 8: - if (img->alpha == EXTRASAMPLE_ASSOCALPHA) - img->put.separate = putRGBAAseparate8bittile; - else if (img->alpha == EXTRASAMPLE_UNASSALPHA) - { - if (BuildMapUaToAa(img)) - img->put.separate = putRGBUAseparate8bittile; - } - else - img->put.separate = putRGBseparate8bittile; - break; - case 16: - if (img->alpha == EXTRASAMPLE_ASSOCALPHA) - { - if (BuildMapBitdepth16To8(img)) - img->put.separate = putRGBAAseparate16bittile; - } - else if (img->alpha == EXTRASAMPLE_UNASSALPHA) - { - if (BuildMapBitdepth16To8(img) && BuildMapUaToAa(img)) - img->put.separate = putRGBUAseparate16bittile; - } - else - { - if (BuildMapBitdepth16To8(img)) - img->put.separate = putRGBseparate16bittile; - } - break; - } - break; - case PHOTOMETRIC_SEPARATED: - if (img->bitspersample == 8 && img->samplesperpixel == 4) - { - img->alpha = - 1; // Not alpha, but seems like the only way to get 4th band - img->put.separate = putCMYKseparate8bittile; - } - break; - case PHOTOMETRIC_YCBCR: - if ((img->bitspersample == 8) && (img->samplesperpixel == 3)) - { - if (initYCbCrConversion(img) != 0) - { - uint16_t hs, vs; - TIFFGetFieldDefaulted(img->tif, TIFFTAG_YCBCRSUBSAMPLING, - &hs, &vs); - switch ((hs << 4) | vs) - { - case 0x11: - img->put.separate = putseparate8bitYCbCr11tile; - break; - /* TODO: add other cases here */ - } - } - } - break; - } - return ((img->get != NULL) && (img->put.separate != NULL)); -} - -static int BuildMapUaToAa(TIFFRGBAImage *img) -{ - static const char module[] = "BuildMapUaToAa"; - uint8_t *m; - uint16_t na, nv; - assert(img->UaToAa == NULL); - img->UaToAa = _TIFFmallocExt(img->tif, 65536); - if (img->UaToAa == NULL) - { - TIFFErrorExtR(img->tif, module, "Out of memory"); - return (0); - } - m = img->UaToAa; - for (na = 0; na < 256; na++) - { - for (nv = 0; nv < 256; nv++) - *m++ = (uint8_t)((nv * na + 127) / 255); - } - return (1); -} - -static int BuildMapBitdepth16To8(TIFFRGBAImage *img) -{ - static const char module[] = "BuildMapBitdepth16To8"; - uint8_t *m; - uint32_t n; - assert(img->Bitdepth16To8 == NULL); - img->Bitdepth16To8 = _TIFFmallocExt(img->tif, 65536); - if (img->Bitdepth16To8 == NULL) - { - TIFFErrorExtR(img->tif, module, "Out of memory"); - return (0); - } - m = img->Bitdepth16To8; - for (n = 0; n < 65536; n++) - *m++ = (uint8_t)((n + 128) / 257); - return (1); -} - -/* - * Read a whole strip off data from the file, and convert to RGBA form. - * If this is the last strip, then it will only contain the portion of - * the strip that is actually within the image space. The result is - * organized in bottom to top form. - */ - -int TIFFReadRGBAStrip(TIFF *tif, uint32_t row, uint32_t *raster) - -{ - return TIFFReadRGBAStripExt(tif, row, raster, 0); -} - -int TIFFReadRGBAStripExt(TIFF *tif, uint32_t row, uint32_t *raster, - int stop_on_error) - -{ - char emsg[EMSG_BUF_SIZE] = ""; - TIFFRGBAImage img; - int ok; - uint32_t rowsperstrip, rows_to_read; - - if (TIFFIsTiled(tif)) - { - TIFFErrorExtR(tif, TIFFFileName(tif), - "Can't use TIFFReadRGBAStrip() with tiled file."); - return (0); - } - - TIFFGetFieldDefaulted(tif, TIFFTAG_ROWSPERSTRIP, &rowsperstrip); - if ((row % rowsperstrip) != 0) - { - TIFFErrorExtR( - tif, TIFFFileName(tif), - "Row passed to TIFFReadRGBAStrip() must be first in a strip."); - return (0); - } - - if (TIFFRGBAImageOK(tif, emsg) && - TIFFRGBAImageBegin(&img, tif, stop_on_error, emsg)) - { - - img.row_offset = row; - img.col_offset = 0; - - if (row + rowsperstrip > img.height) - rows_to_read = img.height - row; - else - rows_to_read = rowsperstrip; - - ok = TIFFRGBAImageGet(&img, raster, img.width, rows_to_read); - - TIFFRGBAImageEnd(&img); - } - else - { - TIFFErrorExtR(tif, TIFFFileName(tif), "%s", emsg); - ok = 0; - } - - return (ok); -} - -/* - * Read a whole tile off data from the file, and convert to RGBA form. - * The returned RGBA data is organized from bottom to top of tile, - * and may include zeroed areas if the tile extends off the image. - */ - -int TIFFReadRGBATile(TIFF *tif, uint32_t col, uint32_t row, uint32_t *raster) - -{ - return TIFFReadRGBATileExt(tif, col, row, raster, 0); -} - -int TIFFReadRGBATileExt(TIFF *tif, uint32_t col, uint32_t row, uint32_t *raster, - int stop_on_error) -{ - char emsg[EMSG_BUF_SIZE] = ""; - TIFFRGBAImage img; - int ok; - uint32_t tile_xsize, tile_ysize; - uint32_t read_xsize, read_ysize; - uint32_t i_row; - - /* - * Verify that our request is legal - on a tile file, and on a - * tile boundary. - */ - - if (!TIFFIsTiled(tif)) - { - TIFFErrorExtR(tif, TIFFFileName(tif), - "Can't use TIFFReadRGBATile() with striped file."); - return (0); - } - - TIFFGetFieldDefaulted(tif, TIFFTAG_TILEWIDTH, &tile_xsize); - TIFFGetFieldDefaulted(tif, TIFFTAG_TILELENGTH, &tile_ysize); - if ((col % tile_xsize) != 0 || (row % tile_ysize) != 0) - { - TIFFErrorExtR(tif, TIFFFileName(tif), - "Row/col passed to TIFFReadRGBATile() must be top" - "left corner of a tile."); - return (0); - } - - /* - * Setup the RGBA reader. - */ - - if (!TIFFRGBAImageOK(tif, emsg) || - !TIFFRGBAImageBegin(&img, tif, stop_on_error, emsg)) - { - TIFFErrorExtR(tif, TIFFFileName(tif), "%s", emsg); - return (0); - } - - /* - * The TIFFRGBAImageGet() function doesn't allow us to get off the - * edge of the image, even to fill an otherwise valid tile. So we - * figure out how much we can read, and fix up the tile buffer to - * a full tile configuration afterwards. - */ - - if (row + tile_ysize > img.height) - read_ysize = img.height - row; - else - read_ysize = tile_ysize; - - if (col + tile_xsize > img.width) - read_xsize = img.width - col; - else - read_xsize = tile_xsize; - - /* - * Read the chunk of imagery. - */ - - img.row_offset = row; - img.col_offset = col; - - ok = TIFFRGBAImageGet(&img, raster, read_xsize, read_ysize); - - TIFFRGBAImageEnd(&img); - - /* - * If our read was incomplete we will need to fix up the tile by - * shifting the data around as if a full tile of data is being returned. - * - * This is all the more complicated because the image is organized in - * bottom to top format. - */ - - if (read_xsize == tile_xsize && read_ysize == tile_ysize) - return (ok); - - for (i_row = 0; i_row < read_ysize; i_row++) - { - 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)); - } - - 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); - } - - return (ok); -} diff --git a/src/3rd/tiff/hash_set.c b/src/3rd/tiff/hash_set.c deleted file mode 100644 index 2f024fd9704..00000000000 --- a/src/3rd/tiff/hash_set.c +++ /dev/null @@ -1,614 +0,0 @@ -/********************************************************************** - * - * Name: tif_hash_set.c - * Purpose: Hash set functions. - * Author: Even Rouault, - * - ********************************************************************** - * Copyright (c) 2008-2009, Even Rouault - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included - * in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. - ****************************************************************************/ - -#include "tiffconf.h" - -#include "hash_set.h" - -#include -#include -#include -#include -#include - -/** List element structure. */ -typedef struct _TIFFList TIFFList; - -/** List element structure. */ -struct _TIFFList -{ - /*! Pointer to the data object. Should be allocated and freed by the - * caller. - * */ - void *pData; - /*! Pointer to the next element in list. NULL, if current element is the - * last one. - */ - struct _TIFFList *psNext; -}; - -struct _TIFFHashSet -{ - TIFFHashSetHashFunc fnHashFunc; - TIFFHashSetEqualFunc fnEqualFunc; - TIFFHashSetFreeEltFunc fnFreeEltFunc; - TIFFList **tabList; - int nSize; - int nIndiceAllocatedSize; - int nAllocatedSize; - TIFFList *psRecyclingList; - int nRecyclingListSize; - bool bRehash; -#ifdef HASH_DEBUG - int nCollisions; -#endif -}; - -static const int anPrimes[] = { - 53, 97, 193, 389, 769, 1543, 3079, - 6151, 12289, 24593, 49157, 98317, 196613, 393241, - 786433, 1572869, 3145739, 6291469, 12582917, 25165843, 50331653, - 100663319, 201326611, 402653189, 805306457, 1610612741}; - -/************************************************************************/ -/* TIFFHashSetHashPointer() */ -/************************************************************************/ - -/** - * Hash function for an arbitrary pointer - * - * @param elt the arbitrary pointer to hash - * - * @return the hash value of the pointer - */ - -static unsigned long TIFFHashSetHashPointer(const void *elt) -{ - return (unsigned long)(uintptr_t)((void *)(elt)); -} - -/************************************************************************/ -/* TIFFHashSetEqualPointer() */ -/************************************************************************/ - -/** - * Equality function for arbitrary pointers - * - * @param elt1 the first arbitrary pointer to compare - * @param elt2 the second arbitrary pointer to compare - * - * @return true if the pointers are equal - */ - -static bool TIFFHashSetEqualPointer(const void *elt1, const void *elt2) -{ - return elt1 == elt2; -} - -/************************************************************************/ -/* TIFFHashSetNew() */ -/************************************************************************/ - -/** - * Creates a new hash set - * - * The hash function must return a hash value for the elements to insert. - * If fnHashFunc is NULL, TIFFHashSetHashPointer will be used. - * - * The equal function must return if two elements are equal. - * If fnEqualFunc is NULL, TIFFHashSetEqualPointer will be used. - * - * The free function is used to free elements inserted in the hash set, - * when the hash set is destroyed, when elements are removed or replaced. - * If fnFreeEltFunc is NULL, elements inserted into the hash set will not be - * freed. - * - * @param fnHashFunc hash function. May be NULL. - * @param fnEqualFunc equal function. May be NULL. - * @param fnFreeEltFunc element free function. May be NULL. - * - * @return a new hash set - */ - -TIFFHashSet *TIFFHashSetNew(TIFFHashSetHashFunc fnHashFunc, - TIFFHashSetEqualFunc fnEqualFunc, - TIFFHashSetFreeEltFunc fnFreeEltFunc) -{ - TIFFHashSet *set = (TIFFHashSet *)malloc(sizeof(TIFFHashSet)); - if (set == NULL) - return NULL; - set->fnHashFunc = fnHashFunc ? fnHashFunc : TIFFHashSetHashPointer; - set->fnEqualFunc = fnEqualFunc ? fnEqualFunc : TIFFHashSetEqualPointer; - set->fnFreeEltFunc = fnFreeEltFunc; - set->nSize = 0; - set->tabList = (TIFFList **)(calloc(sizeof(TIFFList *), 53)); - if (set->tabList == NULL) - { - free(set); - return NULL; - } - set->nIndiceAllocatedSize = 0; - set->nAllocatedSize = 53; - set->psRecyclingList = NULL; - set->nRecyclingListSize = 0; - set->bRehash = false; -#ifdef HASH_DEBUG - set->nCollisions = 0; -#endif - return set; -} - -/************************************************************************/ -/* TIFFHashSetSize() */ -/************************************************************************/ - -/** - * Returns the number of elements inserted in the hash set - * - * Note: this is not the internal size of the hash set - * - * @param set the hash set - * - * @return the number of elements in the hash set - */ - -int TIFFHashSetSize(const TIFFHashSet *set) -{ - assert(set != NULL); - return set->nSize; -} - -/************************************************************************/ -/* TIFFHashSetGetNewListElt() */ -/************************************************************************/ - -static TIFFList *TIFFHashSetGetNewListElt(TIFFHashSet *set) -{ - if (set->psRecyclingList) - { - TIFFList *psRet = set->psRecyclingList; - psRet->pData = NULL; - set->nRecyclingListSize--; - set->psRecyclingList = psRet->psNext; - return psRet; - } - - return (TIFFList *)malloc(sizeof(TIFFList)); -} - -/************************************************************************/ -/* TIFFHashSetReturnListElt() */ -/************************************************************************/ - -static void TIFFHashSetReturnListElt(TIFFHashSet *set, TIFFList *psList) -{ - if (set->nRecyclingListSize < 128) - { - psList->psNext = set->psRecyclingList; - set->psRecyclingList = psList; - set->nRecyclingListSize++; - } - else - { - free(psList); - } -} - -/************************************************************************/ -/* TIFFHashSetClearInternal() */ -/************************************************************************/ - -static void TIFFHashSetClearInternal(TIFFHashSet *set, bool bFinalize) -{ - int i; - assert(set != NULL); - for (i = 0; i < set->nAllocatedSize; i++) - { - TIFFList *cur = set->tabList[i]; - while (cur) - { - TIFFList *psNext; - if (set->fnFreeEltFunc) - set->fnFreeEltFunc(cur->pData); - psNext = cur->psNext; - if (bFinalize) - free(cur); - else - TIFFHashSetReturnListElt(set, cur); - cur = psNext; - } - set->tabList[i] = NULL; - } - set->bRehash = false; -} - -/************************************************************************/ -/* TIFFListDestroy() */ -/************************************************************************/ - -/** - * Destroy a list. Caller responsible for freeing data objects contained in - * list elements. - * - * @param psList pointer to list head. - * - */ - -static void TIFFListDestroy(TIFFList *psList) -{ - TIFFList *psCurrent = psList; - - while (psCurrent) - { - TIFFList *const psNext = psCurrent->psNext; - free(psCurrent); - psCurrent = psNext; - } -} - -/************************************************************************/ -/* TIFFHashSetDestroy() */ -/************************************************************************/ - -/** - * Destroys an allocated hash set. - * - * This function also frees the elements if a free function was - * provided at the creation of the hash set. - * - * @param set the hash set - */ - -void TIFFHashSetDestroy(TIFFHashSet *set) -{ - if (set) - { - TIFFHashSetClearInternal(set, true); - free(set->tabList); - TIFFListDestroy(set->psRecyclingList); - free(set); - } -} - -#ifdef notused -/************************************************************************/ -/* TIFFHashSetClear() */ -/************************************************************************/ - -/** - * Clear all elements from a hash set. - * - * This function also frees the elements if a free function was - * provided at the creation of the hash set. - * - * @param set the hash set - */ - -void TIFFHashSetClear(TIFFHashSet *set) -{ - TIFFHashSetClearInternal(set, false); - set->nIndiceAllocatedSize = 0; - set->nAllocatedSize = 53; -#ifdef HASH_DEBUG - set->nCollisions = 0; -#endif - set->nSize = 0; -} - -/************************************************************************/ -/* TIFFHashSetForeach() */ -/************************************************************************/ - -/** - * Walk through the hash set and runs the provided function on all the - * elements - * - * This function is provided the user_data argument of TIFFHashSetForeach. - * It must return true to go on the walk through the hash set, or FALSE to - * make it stop. - * - * Note : the structure of the hash set must *NOT* be modified during the - * walk. - * - * @param set the hash set. - * @param fnIterFunc the function called on each element. - * @param user_data the user data provided to the function. - */ - -void TIFFHashSetForeach(TIFFHashSet *set, TIFFHashSetIterEltFunc fnIterFunc, - void *user_data) -{ - assert(set != NULL); - if (!fnIterFunc) - return; - - for (int i = 0; i < set->nAllocatedSize; i++) - { - TIFFList *cur = set->tabList[i]; - while (cur) - { - if (!fnIterFunc(cur->pData, user_data)) - return; - - cur = cur->psNext; - } - } -} -#endif - -/************************************************************************/ -/* TIFFHashSetRehash() */ -/************************************************************************/ - -static bool TIFFHashSetRehash(TIFFHashSet *set) -{ - int nNewAllocatedSize = anPrimes[set->nIndiceAllocatedSize]; - TIFFList **newTabList = - (TIFFList **)(calloc(sizeof(TIFFList *), nNewAllocatedSize)); - int i; - if (newTabList == NULL) - return false; -#ifdef HASH_DEBUG - TIFFDebug("TIFFHASH", - "hashSet=%p, nSize=%d, nCollisions=%d, " - "fCollisionRate=%.02f", - set, set->nSize, set->nCollisions, - set->nCollisions * 100.0 / set->nSize); - set->nCollisions = 0; -#endif - for (i = 0; i < set->nAllocatedSize; i++) - { - TIFFList *cur = set->tabList[i]; - while (cur) - { - const unsigned long nNewHashVal = - set->fnHashFunc(cur->pData) % nNewAllocatedSize; -#ifdef HASH_DEBUG - if (newTabList[nNewHashVal]) - set->nCollisions++; -#endif - TIFFList *psNext = cur->psNext; - cur->psNext = newTabList[nNewHashVal]; - newTabList[nNewHashVal] = cur; - cur = psNext; - } - } - free(set->tabList); - set->tabList = newTabList; - set->nAllocatedSize = nNewAllocatedSize; - set->bRehash = false; - return true; -} - -/************************************************************************/ -/* TIFFHashSetFindPtr() */ -/************************************************************************/ - -static void **TIFFHashSetFindPtr(TIFFHashSet *set, const void *elt) -{ - const unsigned long nHashVal = set->fnHashFunc(elt) % set->nAllocatedSize; - TIFFList *cur = set->tabList[nHashVal]; - while (cur) - { - if (set->fnEqualFunc(cur->pData, elt)) - return &cur->pData; - cur = cur->psNext; - } - return NULL; -} - -/************************************************************************/ -/* TIFFHashSetInsert() */ -/************************************************************************/ - -/** - * Inserts an element into a hash set. - * - * If the element was already inserted in the hash set, the previous - * element is replaced by the new element. If a free function was provided, - * it is used to free the previously inserted element - * - * @param set the hash set - * @param elt the new element to insert in the hash set - * - * @return true if success. If false is returned, elt has not been inserted, - * but TIFFHashSetInsert() will have run the free function if provided. - */ - -bool TIFFHashSetInsert(TIFFHashSet *set, void *elt) -{ - void **pElt; - assert(set != NULL); - pElt = TIFFHashSetFindPtr(set, elt); - if (pElt) - { - if (set->fnFreeEltFunc) - set->fnFreeEltFunc(*pElt); - - *pElt = elt; - return true; - } - - if (set->nSize >= 2 * set->nAllocatedSize / 3 || - (set->bRehash && set->nIndiceAllocatedSize > 0 && - set->nSize <= set->nAllocatedSize / 2)) - { - set->nIndiceAllocatedSize++; - if (!TIFFHashSetRehash(set)) - { - set->nIndiceAllocatedSize--; - if (set->fnFreeEltFunc) - set->fnFreeEltFunc(elt); - return false; - } - } - - { - const unsigned long nHashVal = set->fnHashFunc(elt) % set->nAllocatedSize; -#ifdef HASH_DEBUG - if (set->tabList[nHashVal]) - set->nCollisions++; -#endif - - { - TIFFList *new_elt = TIFFHashSetGetNewListElt(set); - if (new_elt == NULL) - { - if (set->fnFreeEltFunc) - set->fnFreeEltFunc(elt); - return false; - } - new_elt->pData = elt; - new_elt->psNext = set->tabList[nHashVal]; - set->tabList[nHashVal] = new_elt; - set->nSize++; - } - } - - return true; -} - -/************************************************************************/ -/* TIFFHashSetLookup() */ -/************************************************************************/ - -/** - * Returns the element found in the hash set corresponding to the element to - * look up The element must not be modified. - * - * @param set the hash set - * @param elt the element to look up in the hash set - * - * @return the element found in the hash set or NULL - */ - -void *TIFFHashSetLookup(TIFFHashSet *set, const void *elt) -{ - void **pElt; - assert(set != NULL); - pElt = TIFFHashSetFindPtr(set, elt); - if (pElt) - return *pElt; - - return NULL; -} - -/************************************************************************/ -/* TIFFHashSetRemoveInternal() */ -/************************************************************************/ - -static bool TIFFHashSetRemoveInternal(TIFFHashSet *set, const void *elt, - bool bDeferRehash) -{ - assert(set != NULL); - if (set->nIndiceAllocatedSize > 0 && set->nSize <= set->nAllocatedSize / 2) - { - set->nIndiceAllocatedSize--; - if (bDeferRehash) - set->bRehash = true; - else - { - if (!TIFFHashSetRehash(set)) - { - set->nIndiceAllocatedSize++; - return false; - } - } - } - - { - int nHashVal = (int)(set->fnHashFunc(elt) % set->nAllocatedSize); - TIFFList *cur = set->tabList[nHashVal]; - TIFFList *prev = NULL; - while (cur) - { - if (set->fnEqualFunc(cur->pData, elt)) - { - if (prev) - prev->psNext = cur->psNext; - else - set->tabList[nHashVal] = cur->psNext; - - if (set->fnFreeEltFunc) - set->fnFreeEltFunc(cur->pData); - - TIFFHashSetReturnListElt(set, cur); -#ifdef HASH_DEBUG - if (set->tabList[nHashVal]) - set->nCollisions--; -#endif - set->nSize--; - return true; - } - prev = cur; - cur = cur->psNext; - } - } - return false; -} - -/************************************************************************/ -/* TIFFHashSetRemove() */ -/************************************************************************/ - -/** - * Removes an element from a hash set - * - * @param set the hash set - * @param elt the new element to remove from the hash set - * - * @return true if the element was in the hash set - */ - -bool TIFFHashSetRemove(TIFFHashSet *set, const void *elt) -{ - return TIFFHashSetRemoveInternal(set, elt, false); -} - -#ifdef notused -/************************************************************************/ -/* TIFFHashSetRemoveDeferRehash() */ -/************************************************************************/ - -/** - * Removes an element from a hash set. - * - * This will defer potential rehashing of the set to later calls to - * TIFFHashSetInsert() or TIFFHashSetRemove(). - * - * @param set the hash set - * @param elt the new element to remove from the hash set - * - * @return true if the element was in the hash set - */ - -bool TIFFHashSetRemoveDeferRehash(TIFFHashSet *set, const void *elt) -{ - return TIFFHashSetRemoveInternal(set, elt, true); -} -#endif diff --git a/src/3rd/tiff/hash_set.h b/src/3rd/tiff/hash_set.h deleted file mode 100644 index f60e2c675e5..00000000000 --- a/src/3rd/tiff/hash_set.h +++ /dev/null @@ -1,100 +0,0 @@ -/********************************************************************** - * $Id$ - * - * Name: tif_hash_set.h - * Project: TIFF - Common Portability Library - * Purpose: Hash set functions. - * Author: Even Rouault, - * - ********************************************************************** - * Copyright (c) 2008-2009, Even Rouault - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included - * in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. - ****************************************************************************/ - -#ifndef TIFF_HASH_SET_H_INCLUDED -#define TIFF_HASH_SET_H_INCLUDED - -#include - -/** - * \file tif_hash_set.h - * - * Hash set implementation. - * - * An hash set is a data structure that holds elements that are unique - * according to a comparison function. Operations on the hash set, such as - * insertion, removal or lookup, are supposed to be fast if an efficient - * "hash" function is provided. - */ - -#ifdef __cplusplus -extern "C" -{ -#endif - - /* Types */ - - /** Opaque type for a hash set */ - typedef struct _TIFFHashSet TIFFHashSet; - - /** TIFFHashSetHashFunc */ - typedef unsigned long (*TIFFHashSetHashFunc)(const void *elt); - - /** TIFFHashSetEqualFunc */ - typedef bool (*TIFFHashSetEqualFunc)(const void *elt1, const void *elt2); - - /** TIFFHashSetFreeEltFunc */ - typedef void (*TIFFHashSetFreeEltFunc)(void *elt); - - /* Functions */ - - TIFFHashSet *TIFFHashSetNew(TIFFHashSetHashFunc fnHashFunc, - TIFFHashSetEqualFunc fnEqualFunc, - TIFFHashSetFreeEltFunc fnFreeEltFunc); - - void TIFFHashSetDestroy(TIFFHashSet *set); - - int TIFFHashSetSize(const TIFFHashSet *set); - -#ifdef notused - void TIFFHashSetClear(TIFFHashSet *set); - - /** TIFFHashSetIterEltFunc */ - typedef int (*TIFFHashSetIterEltFunc)(void *elt, void *user_data); - - void TIFFHashSetForeach(TIFFHashSet *set, TIFFHashSetIterEltFunc fnIterFunc, - void *user_data); -#endif - - bool TIFFHashSetInsert(TIFFHashSet *set, void *elt); - - void *TIFFHashSetLookup(TIFFHashSet *set, const void *elt); - - bool TIFFHashSetRemove(TIFFHashSet *set, const void *elt); - -#ifdef notused - bool TIFFHashSetRemoveDeferRehash(TIFFHashSet *set, const void *elt); -#endif - -#ifdef __cplusplus -} -#endif - -#endif /* TIFF_HASH_SET_H_INCLUDED */ diff --git a/src/3rd/tiff/jbig.c b/src/3rd/tiff/jbig.c deleted file mode 100644 index 7e455ad1ce1..00000000000 --- a/src/3rd/tiff/jbig.c +++ /dev/null @@ -1,231 +0,0 @@ -/* - * Copyright (c) 1988-1997 Sam Leffler - * Copyright (c) 1991-1997 Silicon Graphics, Inc. - * - * Permission to use, copy, modify, distribute, and sell this software and - * its documentation for any purpose is hereby granted without fee, provided - * that (i) the above copyright notices and this permission notice appear in - * all copies of the software and related documentation, and (ii) the names of - * Sam Leffler and Silicon Graphics may not be used in any advertising or - * publicity relating to the software without the specific, prior written - * permission of Sam Leffler and Silicon Graphics. - * - * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, - * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY - * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. - * - * IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR - * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, - * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, - * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF - * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE - * OF THIS SOFTWARE. - */ - -/* - * TIFF Library. - * - * JBIG Compression Algorithm Support. - * Contributed by Lee Howard - * - */ - -#include "tiffiop.h" - -#ifdef JBIG_SUPPORT -#include "jbig.h" - -static int JBIGSetupDecode(TIFF *tif) -{ - if (TIFFNumberOfStrips(tif) != 1) - { - TIFFErrorExtR(tif, "JBIG", - "Multistrip images not supported in decoder"); - return 0; - } - - return 1; -} - -static int JBIGDecode(TIFF *tif, uint8_t *buffer, tmsize_t size, uint16_t s) -{ - struct jbg_dec_state decoder; - int decodeStatus = 0; - unsigned char *pImage = NULL; - unsigned long decodedSize; - (void)s; - - if (isFillOrder(tif, tif->tif_dir.td_fillorder)) - { - TIFFReverseBits(tif->tif_rawcp, tif->tif_rawcc); - } - - jbg_dec_init(&decoder); - -#if defined(HAVE_JBG_NEWLEN) - jbg_newlen(tif->tif_rawcp, (size_t)tif->tif_rawcc); - /* - * I do not check the return status of jbg_newlen because even if this - * function fails it does not necessarily mean that decoding the image - * will fail. It is generally only needed for received fax images - * that do not contain the actual length of the image in the BIE - * header. I do not log when an error occurs because that will cause - * problems when converting JBIG encoded TIFF's to - * PostScript. As long as the actual image length is contained in the - * BIE header jbg_dec_in should succeed. - */ -#endif /* HAVE_JBG_NEWLEN */ - - decodeStatus = jbg_dec_in(&decoder, (unsigned char *)tif->tif_rawcp, - (size_t)tif->tif_rawcc, NULL); - if (JBG_EOK != decodeStatus) - { - /* - * XXX: JBG_EN constant was defined in pre-2.0 releases of the - * JBIG-KIT. Since the 2.0 the error reporting functions were - * changed. We will handle both cases here. - */ - TIFFErrorExtR(tif, "JBIG", "Error (%d) decoding: %s", decodeStatus, -#if defined(JBG_EN) - jbg_strerror(decodeStatus, JBG_EN) -#else - jbg_strerror(decodeStatus) -#endif - ); - jbg_dec_free(&decoder); - return 0; - } - - decodedSize = jbg_dec_getsize(&decoder); - if ((tmsize_t)decodedSize < size) - { - TIFFWarningExtR(tif, "JBIG", - "Only decoded %lu bytes, whereas %" TIFF_SSIZE_FORMAT - " requested", - decodedSize, size); - } - else if ((tmsize_t)decodedSize > size) - { - TIFFErrorExtR(tif, "JBIG", - "Decoded %lu bytes, whereas %" TIFF_SSIZE_FORMAT - " were requested", - decodedSize, size); - jbg_dec_free(&decoder); - return 0; - } - pImage = jbg_dec_getimage(&decoder, 0); - _TIFFmemcpy(buffer, pImage, decodedSize); - jbg_dec_free(&decoder); - - tif->tif_rawcp += tif->tif_rawcc; - tif->tif_rawcc = 0; - - return 1; -} - -static int JBIGSetupEncode(TIFF *tif) -{ - if (TIFFNumberOfStrips(tif) != 1) - { - TIFFErrorExtR(tif, "JBIG", - "Multistrip images not supported in encoder"); - return 0; - } - - return 1; -} - -static int JBIGCopyEncodedData(TIFF *tif, unsigned char *pp, size_t cc, - uint16_t s) -{ - (void)s; - while (cc > 0) - { - tmsize_t n = (tmsize_t)cc; - - if (tif->tif_rawcc + n > tif->tif_rawdatasize) - { - n = tif->tif_rawdatasize - tif->tif_rawcc; - } - - assert(n > 0); - _TIFFmemcpy(tif->tif_rawcp, pp, n); - tif->tif_rawcp += n; - tif->tif_rawcc += n; - pp += n; - cc -= (size_t)n; - if (tif->tif_rawcc >= tif->tif_rawdatasize && !TIFFFlushData1(tif)) - { - return (-1); - } - } - - return (1); -} - -static void JBIGOutputBie(unsigned char *buffer, size_t len, void *userData) -{ - TIFF *tif = (TIFF *)userData; - - if (isFillOrder(tif, tif->tif_dir.td_fillorder)) - { - TIFFReverseBits(buffer, (tmsize_t)len); - } - - JBIGCopyEncodedData(tif, buffer, len, 0); -} - -static int JBIGEncode(TIFF *tif, uint8_t *buffer, tmsize_t size, uint16_t s) -{ - TIFFDirectory *dir = &tif->tif_dir; - struct jbg_enc_state encoder; - - (void)size, (void)s; - - jbg_enc_init(&encoder, dir->td_imagewidth, dir->td_imagelength, 1, &buffer, - JBIGOutputBie, tif); - /* - * jbg_enc_out does the "real" encoding. As data is encoded, - * JBIGOutputBie is called, which writes the data to the directory. - */ - jbg_enc_out(&encoder); - jbg_enc_free(&encoder); - - return 1; -} - -int TIFFInitJBIG(TIFF *tif, int scheme) -{ - (void)scheme; - assert(scheme == COMPRESSION_JBIG); - - /* - * These flags are set so the JBIG Codec can control when to reverse - * bits and when not to and to allow the jbig decoder and bit reverser - * to write to memory when necessary. - */ - tif->tif_flags |= TIFF_NOBITREV; - tif->tif_flags &= ~TIFF_MAPPED; - /* We may have read from a previous IFD and thus set TIFF_BUFFERMMAP and - * cleared TIFF_MYBUFFER. It is necessary to restore them to their initial - * value to be consistent with the state of a non-memory mapped file. - */ - if (tif->tif_flags & TIFF_BUFFERMMAP) - { - tif->tif_rawdata = NULL; - tif->tif_rawdatasize = 0; - tif->tif_flags &= ~TIFF_BUFFERMMAP; - tif->tif_flags |= TIFF_MYBUFFER; - } - - /* Setup the function pointers for encode, decode, and cleanup. */ - tif->tif_setupdecode = JBIGSetupDecode; - tif->tif_decodestrip = JBIGDecode; - - tif->tif_setupencode = JBIGSetupEncode; - tif->tif_encodestrip = JBIGEncode; - - return 1; -} - -#endif /* JBIG_SUPPORT */ diff --git a/src/3rd/tiff/jpeg.c b/src/3rd/tiff/jpeg.c deleted file mode 100644 index 250144f2112..00000000000 --- a/src/3rd/tiff/jpeg.c +++ /dev/null @@ -1,2900 +0,0 @@ -/* - * Copyright (c) 1994-1997 Sam Leffler - * Copyright (c) 1994-1997 Silicon Graphics, Inc. - * - * Permission to use, copy, modify, distribute, and sell this software and - * its documentation for any purpose is hereby granted without fee, provided - * that (i) the above copyright notices and this permission notice appear in - * all copies of the software and related documentation, and (ii) the names of - * Sam Leffler and Silicon Graphics may not be used in any advertising or - * publicity relating to the software without the specific, prior written - * permission of Sam Leffler and Silicon Graphics. - * - * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, - * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY - * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. - * - * IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR - * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, - * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, - * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF - * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE - * OF THIS SOFTWARE. - */ - -#define WIN32_LEAN_AND_MEAN -#define VC_EXTRALEAN - -#include "tiffiop.h" -#include - -#ifdef JPEG_SUPPORT - -/* - * TIFF Library - * - * JPEG Compression support per TIFF Technical Note #2 - * (*not* per the original TIFF 6.0 spec). - * - * This file is simply an interface to the libjpeg library written by - * the Independent JPEG Group. You need release 5 or later of the IJG - * code, which you can find on the Internet at ftp.uu.net:/graphics/jpeg/. - * - * Contributed by Tom Lane . - */ -#include - -/* Settings that are independent of libjpeg ABI. Used when reinitializing the */ -/* JPEGState from libjpegs 8 bit to libjpeg 12 bits, which have potentially */ -/* different ABI */ -typedef struct -{ - TIFFVGetMethod vgetparent; /* super-class method */ - TIFFVSetMethod vsetparent; /* super-class method */ - TIFFPrintMethod printdir; /* super-class method */ - TIFFStripMethod defsparent; /* super-class method */ - TIFFTileMethod deftparent; /* super-class method */ - - /* pseudo-tag fields */ - void *jpegtables; /* JPEGTables tag value, or NULL */ - uint32_t jpegtables_length; /* number of bytes in same */ - int jpegquality; /* Compression quality level */ - int jpegcolormode; /* Auto RGB<=>YCbCr convert? */ - int jpegtablesmode; /* What to put in JPEGTables */ - - int ycbcrsampling_fetched; - int max_allowed_scan_number; - int has_warned_about_progressive_mode; -} JPEGOtherSettings; - -int TIFFFillStrip(TIFF *tif, uint32_t strip); -int TIFFFillTile(TIFF *tif, uint32_t tile); -int TIFFReInitJPEG_12(TIFF *tif, const JPEGOtherSettings *otherSettings, - int scheme, int is_encode); -int TIFFJPEGIsFullStripRequired_12(TIFF *tif); - -/* We undefine FAR to avoid conflict with JPEG definition */ - -#ifdef FAR -#undef FAR -#endif - -/* - Libjpeg's jmorecfg.h defines INT16 and INT32, but only if XMD_H is - not defined. Unfortunately, the MinGW and Borland compilers include - a typedef for INT32, which causes a conflict. MSVC does not include - a conflicting typedef given the headers which are included. -*/ -#if defined(__BORLANDC__) || defined(__MINGW32__) -#define XMD_H 1 -#endif - -/* - The windows RPCNDR.H file defines boolean, but defines it with the - unsigned char size. You should compile JPEG library using appropriate - definitions in jconfig.h header, but many users compile library in wrong - way. That causes errors of the following type: - - "JPEGLib: JPEG parameter struct mismatch: library thinks size is 432, - caller expects 464" - - For such users we will fix the problem here. See install.doc file from - the JPEG library distribution for details. -*/ - -/* Define "boolean" as unsigned char, not int, per Windows custom. */ -#if defined(__WIN32__) && !defined(__MINGW32__) -#ifndef __RPCNDR_H__ /* don't conflict if rpcndr.h already read */ -typedef unsigned char boolean; -#endif -#define HAVE_BOOLEAN /* prevent jmorecfg.h from redefining it */ -#endif - -#include "jerror.h" -#include "jpeglib.h" - -/* Do optional compile-time version check */ -#if defined(EXPECTED_JPEG_LIB_VERSION) && !defined(LIBJPEG_12_PATH) -#if EXPECTED_JPEG_LIB_VERSION != JPEG_LIB_VERSION -#error EXPECTED_JPEG_LIB_VERSION != JPEG_LIB_VERSION -#endif -#endif - -/* - * Do we want to do special processing suitable for when JSAMPLE is a - * 16bit value? - */ - -/* HAVE_JPEGTURBO_DUAL_MODE_8_12 is defined for libjpeg-turbo >= 2.2 which - * adds a dual-mode 8/12 bit API in the same library. - */ - -#if defined(HAVE_JPEGTURBO_DUAL_MODE_8_12) -#define JPEG_DUAL_MODE_8_12 -/* Start by undefining BITS_IN_JSAMPLE which is always set to 8 in libjpeg-turbo - * >= 2.2 Cf - * https://github.com/libjpeg-turbo/libjpeg-turbo/commit/8b9bc4b9635a2a047fb23ebe70c9acd728d3f99b - */ -#undef BITS_IN_JSAMPLE -/* libjpeg-turbo >= 2.2 adds J12xxxx datatypes for the 12-bit mode. */ -#if defined(FROM_TIF_JPEG_12) -#define BITS_IN_JSAMPLE 12 -#define TIFF_JSAMPLE J12SAMPLE -#define TIFF_JSAMPARRAY J12SAMPARRAY -#define TIFF_JSAMPIMAGE J12SAMPIMAGE -#define TIFF_JSAMPROW J12SAMPROW -#else -#define BITS_IN_JSAMPLE 8 -#define TIFF_JSAMPLE JSAMPLE -#define TIFF_JSAMPARRAY JSAMPARRAY -#define TIFF_JSAMPIMAGE JSAMPIMAGE -#define TIFF_JSAMPROW JSAMPROW -#endif -#else -#define TIFF_JSAMPLE JSAMPLE -#define TIFF_JSAMPARRAY JSAMPARRAY -#define TIFF_JSAMPIMAGE JSAMPIMAGE -#define TIFF_JSAMPROW JSAMPROW -#endif - -#if defined(JPEG_LIB_MK1) -#define JPEG_LIB_MK1_OR_12BIT 1 -#elif BITS_IN_JSAMPLE == 12 -#define JPEG_LIB_MK1_OR_12BIT 1 -#endif - -/* - * We are using width_in_blocks which is supposed to be private to - * libjpeg. Unfortunately, the libjpeg delivered with Cygwin has - * renamed this member to width_in_data_units. Since the header has - * also renamed a define, use that unique define name in order to - * detect the problem header and adjust to suit. - */ -#if defined(D_MAX_DATA_UNITS_IN_MCU) -#define width_in_blocks width_in_data_units -#endif - -/* - * On some machines it may be worthwhile to use _setjmp or sigsetjmp - * in place of plain setjmp. These macros will make it easier. - */ -#define SETJMP(jbuf) setjmp(jbuf) -#define LONGJMP(jbuf, code) longjmp(jbuf, code) -#define JMP_BUF jmp_buf - -typedef struct jpeg_destination_mgr jpeg_destination_mgr; -typedef struct jpeg_source_mgr jpeg_source_mgr; -typedef struct jpeg_error_mgr jpeg_error_mgr; - -/* - * State block for each open TIFF file using - * libjpeg to do JPEG compression/decompression. - * - * libjpeg's visible state is either a jpeg_compress_struct - * or jpeg_decompress_struct depending on which way we - * are going. comm can be used to refer to the fields - * which are common to both. - * - * NB: cinfo is required to be the first member of JPEGState, - * so we can safely cast JPEGState* -> jpeg_xxx_struct* - * and vice versa! - */ -typedef struct -{ - union - { - struct jpeg_compress_struct c; - struct jpeg_decompress_struct d; - struct jpeg_common_struct comm; - } cinfo; /* NB: must be first */ - int cinfo_initialized; - - 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 */ - uint16_t v_sampling; - tmsize_t bytesperline; /* decompressed bytes per scanline */ - /* pointers to intermediate buffers when processing downsampled data */ - TIFF_JSAMPARRAY ds_buffer[MAX_COMPONENTS]; - int scancount; /* number of "scanlines" accumulated */ - int samplesperclump; - - JPEGOtherSettings otherSettings; -} JPEGState; - -#define JState(tif) ((JPEGState *)(tif)->tif_data) - -static int JPEGDecode(TIFF *tif, uint8_t *buf, tmsize_t cc, uint16_t s); -static int JPEGDecodeRaw(TIFF *tif, uint8_t *buf, tmsize_t cc, uint16_t s); -static int JPEGEncode(TIFF *tif, uint8_t *buf, tmsize_t cc, uint16_t s); -static int JPEGEncodeRaw(TIFF *tif, uint8_t *buf, tmsize_t cc, uint16_t s); -static int JPEGInitializeLibJPEG(TIFF *tif, int decode); -static int DecodeRowError(TIFF *tif, uint8_t *buf, tmsize_t cc, uint16_t s); - -#define FIELD_JPEGTABLES (FIELD_CODEC + 0) - -static const TIFFField jpegFields[] = { - {TIFFTAG_JPEGTABLES, -3, -3, TIFF_UNDEFINED, 0, TIFF_SETGET_C32_UINT8, - TIFF_SETGET_C32_UINT8, FIELD_JPEGTABLES, FALSE, TRUE, "JPEGTables", NULL}, - {TIFFTAG_JPEGQUALITY, 0, 0, TIFF_ANY, 0, TIFF_SETGET_INT, - TIFF_SETGET_UNDEFINED, FIELD_PSEUDO, TRUE, FALSE, "", NULL}, - {TIFFTAG_JPEGCOLORMODE, 0, 0, TIFF_ANY, 0, TIFF_SETGET_INT, - TIFF_SETGET_UNDEFINED, FIELD_PSEUDO, FALSE, FALSE, "", NULL}, - {TIFFTAG_JPEGTABLESMODE, 0, 0, TIFF_ANY, 0, TIFF_SETGET_INT, - TIFF_SETGET_UNDEFINED, FIELD_PSEUDO, FALSE, FALSE, "", NULL}}; - -/* - * libjpeg interface layer. - * - * We use setjmp/longjmp to return control to libtiff - * when a fatal error is encountered within the JPEG - * library. We also direct libjpeg error and warning - * messages through the appropriate libtiff handlers. - */ - -/* - * Error handling routines (these replace corresponding - * IJG routines from jerror.c). These are used for both - * compression and decompression. - */ -static void TIFFjpeg_error_exit(j_common_ptr cinfo) -{ - JPEGState *sp = (JPEGState *)cinfo; /* NB: cinfo assumed first */ - char buffer[JMSG_LENGTH_MAX]; - - (*cinfo->err->format_message)(cinfo, buffer); - TIFFErrorExtR(sp->tif, "JPEGLib", "%s", - buffer); /* display the error message */ - jpeg_abort(cinfo); /* clean up libjpeg state */ - LONGJMP(sp->exit_jmpbuf, 1); /* return to libtiff caller */ -} - -/* - * This routine is invoked only for warning messages, - * since error_exit does its own thing and trace_level - * is never set > 0. - */ -static void TIFFjpeg_output_message(j_common_ptr cinfo) -{ - char buffer[JMSG_LENGTH_MAX]; - - (*cinfo->err->format_message)(cinfo, buffer); - TIFFWarningExtR(((JPEGState *)cinfo)->tif, "JPEGLib", "%s", buffer); -} - -/* Avoid the risk of denial-of-service on crafted JPEGs with an insane */ -/* number of scans. */ -/* See - * http://www.libjpeg-turbo.org/pmwiki/uploads/About/TwoIssueswiththeJPEGStandard.pdf - */ -static void TIFFjpeg_progress_monitor(j_common_ptr cinfo) -{ - JPEGState *sp = (JPEGState *)cinfo; /* NB: cinfo assumed first */ - if (cinfo->is_decompressor) - { - const int scan_no = ((j_decompress_ptr)cinfo)->input_scan_number; - if (scan_no >= sp->otherSettings.max_allowed_scan_number) - { - TIFFErrorExtR( - ((JPEGState *)cinfo)->tif, "TIFFjpeg_progress_monitor", - "Scan number %d exceeds maximum scans (%d). This limit " - "can be raised through the " - "LIBTIFF_JPEG_MAX_ALLOWED_SCAN_NUMBER " - "environment variable.", - scan_no, sp->otherSettings.max_allowed_scan_number); - - jpeg_abort(cinfo); /* clean up libjpeg state */ - LONGJMP(sp->exit_jmpbuf, 1); /* return to libtiff caller */ - } - } -} - -/* - * Interface routines. This layer of routines exists - * primarily to limit side-effects from using setjmp. - * Also, normal/error returns are converted into return - * values per libtiff practice. - */ -#define CALLJPEG(sp, fail, op) (SETJMP((sp)->exit_jmpbuf) ? (fail) : (op)) -#define CALLVJPEG(sp, op) CALLJPEG(sp, 0, ((op), 1)) - -static int TIFFjpeg_create_compress(JPEGState *sp) -{ - /* initialize JPEG error handling */ - sp->cinfo.c.err = jpeg_std_error(&sp->err); - sp->err.error_exit = TIFFjpeg_error_exit; - sp->err.output_message = TIFFjpeg_output_message; - - /* set client_data to avoid UMR warning from tools like Purify */ - sp->cinfo.c.client_data = NULL; - - return CALLVJPEG(sp, jpeg_create_compress(&sp->cinfo.c)); -} - -static int TIFFjpeg_create_decompress(JPEGState *sp) -{ - /* initialize JPEG error handling */ - sp->cinfo.d.err = jpeg_std_error(&sp->err); - sp->err.error_exit = TIFFjpeg_error_exit; - sp->err.output_message = TIFFjpeg_output_message; - - /* set client_data to avoid UMR warning from tools like Purify */ - sp->cinfo.d.client_data = NULL; - - return CALLVJPEG(sp, jpeg_create_decompress(&sp->cinfo.d)); -} - -static int TIFFjpeg_set_defaults(JPEGState *sp) -{ - return CALLVJPEG(sp, jpeg_set_defaults(&sp->cinfo.c)); -} - -static int TIFFjpeg_set_colorspace(JPEGState *sp, J_COLOR_SPACE colorspace) -{ - return CALLVJPEG(sp, jpeg_set_colorspace(&sp->cinfo.c, colorspace)); -} - -static int TIFFjpeg_set_quality(JPEGState *sp, int quality, - boolean force_baseline) -{ - return CALLVJPEG(sp, - jpeg_set_quality(&sp->cinfo.c, quality, force_baseline)); -} - -static int TIFFjpeg_suppress_tables(JPEGState *sp, boolean suppress) -{ - return CALLVJPEG(sp, jpeg_suppress_tables(&sp->cinfo.c, suppress)); -} - -static int TIFFjpeg_start_compress(JPEGState *sp, boolean write_all_tables) -{ - return CALLVJPEG(sp, jpeg_start_compress(&sp->cinfo.c, write_all_tables)); -} - -static int TIFFjpeg_write_scanlines(JPEGState *sp, TIFF_JSAMPARRAY scanlines, - int num_lines) -{ -#if defined(HAVE_JPEGTURBO_DUAL_MODE_8_12) && BITS_IN_JSAMPLE == 12 - return CALLJPEG(sp, -1, - (int)jpeg12_write_scanlines(&sp->cinfo.c, scanlines, - (JDIMENSION)num_lines)); -#else - return CALLJPEG(sp, -1, - (int)jpeg_write_scanlines(&sp->cinfo.c, scanlines, - (JDIMENSION)num_lines)); -#endif -} - -static int TIFFjpeg_write_raw_data(JPEGState *sp, TIFF_JSAMPIMAGE data, - int num_lines) -{ -#if defined(HAVE_JPEGTURBO_DUAL_MODE_8_12) && BITS_IN_JSAMPLE == 12 - return CALLJPEG( - sp, -1, - (int)jpeg12_write_raw_data(&sp->cinfo.c, data, (JDIMENSION)num_lines)); -#else - return CALLJPEG( - sp, -1, - (int)jpeg_write_raw_data(&sp->cinfo.c, data, (JDIMENSION)num_lines)); -#endif -} - -static int TIFFjpeg_finish_compress(JPEGState *sp) -{ - return CALLVJPEG(sp, jpeg_finish_compress(&sp->cinfo.c)); -} - -static int TIFFjpeg_write_tables(JPEGState *sp) -{ - return CALLVJPEG(sp, jpeg_write_tables(&sp->cinfo.c)); -} - -static int TIFFjpeg_read_header(JPEGState *sp, boolean require_image) -{ - return CALLJPEG(sp, -1, jpeg_read_header(&sp->cinfo.d, require_image)); -} - -static int TIFFjpeg_has_multiple_scans(JPEGState *sp) -{ - return CALLJPEG(sp, 0, jpeg_has_multiple_scans(&sp->cinfo.d)); -} - -static int TIFFjpeg_start_decompress(JPEGState *sp) -{ - const char *sz_max_allowed_scan_number; - /* progress monitor */ - sp->cinfo.d.progress = &sp->progress; - sp->progress.progress_monitor = TIFFjpeg_progress_monitor; - sp->otherSettings.max_allowed_scan_number = 100; - sz_max_allowed_scan_number = getenv("LIBTIFF_JPEG_MAX_ALLOWED_SCAN_NUMBER"); - if (sz_max_allowed_scan_number) - sp->otherSettings.max_allowed_scan_number = - atoi(sz_max_allowed_scan_number); - - return CALLVJPEG(sp, jpeg_start_decompress(&sp->cinfo.d)); -} - -static int TIFFjpeg_read_scanlines(JPEGState *sp, TIFF_JSAMPARRAY scanlines, - int max_lines) -{ -#if defined(HAVE_JPEGTURBO_DUAL_MODE_8_12) && BITS_IN_JSAMPLE == 12 - return CALLJPEG(sp, -1, - (int)jpeg12_read_scanlines(&sp->cinfo.d, scanlines, - (JDIMENSION)max_lines)); -#else - return CALLJPEG(sp, -1, - (int)jpeg_read_scanlines(&sp->cinfo.d, scanlines, - (JDIMENSION)max_lines)); -#endif -} - -static int TIFFjpeg_read_raw_data(JPEGState *sp, TIFF_JSAMPIMAGE data, - int max_lines) -{ -#if defined(HAVE_JPEGTURBO_DUAL_MODE_8_12) && BITS_IN_JSAMPLE == 12 - return CALLJPEG( - sp, -1, - (int)jpeg12_read_raw_data(&sp->cinfo.d, data, (JDIMENSION)max_lines)); -#else - return CALLJPEG( - sp, -1, - (int)jpeg_read_raw_data(&sp->cinfo.d, data, (JDIMENSION)max_lines)); -#endif -} - -static int TIFFjpeg_finish_decompress(JPEGState *sp) -{ - return CALLJPEG(sp, -1, (int)jpeg_finish_decompress(&sp->cinfo.d)); -} - -static int TIFFjpeg_abort(JPEGState *sp) -{ - return CALLVJPEG(sp, jpeg_abort(&sp->cinfo.comm)); -} - -static int TIFFjpeg_destroy(JPEGState *sp) -{ - return CALLVJPEG(sp, jpeg_destroy(&sp->cinfo.comm)); -} - -static JSAMPARRAY TIFFjpeg_alloc_sarray(JPEGState *sp, int pool_id, - JDIMENSION samplesperrow, - JDIMENSION numrows) -{ - return CALLJPEG(sp, (JSAMPARRAY)NULL, - (*sp->cinfo.comm.mem->alloc_sarray)( - &sp->cinfo.comm, pool_id, samplesperrow, numrows)); -} - -/* - * JPEG library destination data manager. - * These routines direct compressed data from libjpeg into the - * libtiff output buffer. - */ - -static void std_init_destination(j_compress_ptr cinfo) -{ - JPEGState *sp = (JPEGState *)cinfo; - TIFF *tif = sp->tif; - - sp->dest.next_output_byte = (JOCTET *)tif->tif_rawdata; - sp->dest.free_in_buffer = (size_t)tif->tif_rawdatasize; -} - -static boolean std_empty_output_buffer(j_compress_ptr cinfo) -{ - JPEGState *sp = (JPEGState *)cinfo; - TIFF *tif = sp->tif; - - /* the entire buffer has been filled */ - tif->tif_rawcc = tif->tif_rawdatasize; - -#ifdef IPPJ_HUFF - /* - * The Intel IPP performance library does not necessarily fill up - * the whole output buffer on each pass, so only dump out the parts - * that have been filled. - * http://trac.osgeo.org/gdal/wiki/JpegIPP - */ - if (sp->dest.free_in_buffer >= 0) - { - tif->tif_rawcc = tif->tif_rawdatasize - sp->dest.free_in_buffer; - } -#endif - - if (!TIFFFlushData1(tif)) - return FALSE; - sp->dest.next_output_byte = (JOCTET *)tif->tif_rawdata; - sp->dest.free_in_buffer = (size_t)tif->tif_rawdatasize; - - return (TRUE); -} - -static void std_term_destination(j_compress_ptr cinfo) -{ - JPEGState *sp = (JPEGState *)cinfo; - TIFF *tif = sp->tif; - - tif->tif_rawcp = (uint8_t *)sp->dest.next_output_byte; - tif->tif_rawcc = tif->tif_rawdatasize - (tmsize_t)sp->dest.free_in_buffer; - /* NB: libtiff does the final buffer flush */ -} - -static void TIFFjpeg_data_dest(JPEGState *sp, TIFF *tif) -{ - (void)tif; - sp->cinfo.c.dest = &sp->dest; - sp->dest.init_destination = std_init_destination; - sp->dest.empty_output_buffer = std_empty_output_buffer; - sp->dest.term_destination = std_term_destination; -} - -/* - * Alternate destination manager for outputting to JPEGTables field. - */ - -static void tables_init_destination(j_compress_ptr cinfo) -{ - JPEGState *sp = (JPEGState *)cinfo; - - /* while building, otherSettings.jpegtables_length is allocated buffer size - */ - sp->dest.next_output_byte = (JOCTET *)sp->otherSettings.jpegtables; - sp->dest.free_in_buffer = (size_t)sp->otherSettings.jpegtables_length; -} - -static boolean tables_empty_output_buffer(j_compress_ptr cinfo) -{ - JPEGState *sp = (JPEGState *)cinfo; - void *newbuf; - - /* 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)); - if (newbuf == NULL) - ERREXIT1(cinfo, JERR_OUT_OF_MEMORY, 100); - sp->dest.next_output_byte = - (JOCTET *)newbuf + sp->otherSettings.jpegtables_length; - sp->dest.free_in_buffer = (size_t)1000; - sp->otherSettings.jpegtables = newbuf; - sp->otherSettings.jpegtables_length += 1000; - return (TRUE); -} - -static void tables_term_destination(j_compress_ptr cinfo) -{ - JPEGState *sp = (JPEGState *)cinfo; - - /* set tables length to number of bytes actually emitted */ - sp->otherSettings.jpegtables_length -= (uint32_t)sp->dest.free_in_buffer; -} - -static int TIFFjpeg_tables_dest(JPEGState *sp, TIFF *tif) -{ - (void)tif; - /* - * Allocate a working buffer for building tables. - * Initial size is 1000 bytes, which is usually adequate. - */ - if (sp->otherSettings.jpegtables) - _TIFFfreeExt(tif, sp->otherSettings.jpegtables); - sp->otherSettings.jpegtables_length = 1000; - sp->otherSettings.jpegtables = (void *)_TIFFmallocExt( - tif, (tmsize_t)sp->otherSettings.jpegtables_length); - if (sp->otherSettings.jpegtables == NULL) - { - sp->otherSettings.jpegtables_length = 0; - TIFFErrorExtR(sp->tif, "TIFFjpeg_tables_dest", - "No space for JPEGTables"); - return (0); - } - sp->cinfo.c.dest = &sp->dest; - sp->dest.init_destination = tables_init_destination; - sp->dest.empty_output_buffer = tables_empty_output_buffer; - sp->dest.term_destination = tables_term_destination; - return (1); -} - -/* - * JPEG library source data manager. - * These routines supply compressed data to libjpeg. - */ - -static void std_init_source(j_decompress_ptr cinfo) -{ - JPEGState *sp = (JPEGState *)cinfo; - TIFF *tif = sp->tif; - - sp->src.next_input_byte = (const JOCTET *)tif->tif_rawdata; - sp->src.bytes_in_buffer = (size_t)tif->tif_rawcc; -} - -static boolean std_fill_input_buffer(j_decompress_ptr cinfo) -{ - JPEGState *sp = (JPEGState *)cinfo; - static const JOCTET dummy_EOI[2] = {0xFF, JPEG_EOI}; - -#ifdef IPPJ_HUFF - /* - * The Intel IPP performance library does not necessarily read the whole - * input buffer in one pass, so it is possible to get here with data - * yet to read. - * - * We just return without doing anything, until the entire buffer has - * been read. - * http://trac.osgeo.org/gdal/wiki/JpegIPP - */ - if (sp->src.bytes_in_buffer > 0) - { - return (TRUE); - } -#endif - - /* - * Normally the whole strip/tile is read and so we don't need to do - * a fill. In the case of CHUNKY_STRIP_READ_SUPPORT we might not have - * all the data, but the rawdata is refreshed between scanlines and - * we push this into the io machinery in JPEGDecode(). - * http://trac.osgeo.org/gdal/ticket/3894 - */ - - WARNMS(cinfo, JWRN_JPEG_EOF); - /* insert a fake EOI marker */ - sp->src.next_input_byte = dummy_EOI; - sp->src.bytes_in_buffer = 2; - return (TRUE); -} - -static void std_skip_input_data(j_decompress_ptr cinfo, long num_bytes) -{ - JPEGState *sp = (JPEGState *)cinfo; - - if (num_bytes > 0) - { - if ((size_t)num_bytes > sp->src.bytes_in_buffer) - { - /* oops, buffer overrun */ - (void)std_fill_input_buffer(cinfo); - } - else - { - sp->src.next_input_byte += (size_t)num_bytes; - sp->src.bytes_in_buffer -= (size_t)num_bytes; - } - } -} - -static void std_term_source(j_decompress_ptr cinfo) -{ - /* No work necessary here */ - (void)cinfo; -} - -static void TIFFjpeg_data_src(JPEGState *sp) -{ - sp->cinfo.d.src = &sp->src; - sp->src.init_source = std_init_source; - sp->src.fill_input_buffer = std_fill_input_buffer; - sp->src.skip_input_data = std_skip_input_data; - sp->src.resync_to_restart = jpeg_resync_to_restart; - sp->src.term_source = std_term_source; - sp->src.bytes_in_buffer = 0; /* for safety */ - sp->src.next_input_byte = NULL; -} - -/* - * Alternate source manager for reading from JPEGTables. - * We can share all the code except for the init routine. - */ - -static void tables_init_source(j_decompress_ptr cinfo) -{ - JPEGState *sp = (JPEGState *)cinfo; - - sp->src.next_input_byte = (const JOCTET *)sp->otherSettings.jpegtables; - sp->src.bytes_in_buffer = (size_t)sp->otherSettings.jpegtables_length; -} - -static void TIFFjpeg_tables_src(JPEGState *sp) -{ - TIFFjpeg_data_src(sp); - sp->src.init_source = tables_init_source; -} - -/* - * Allocate downsampled-data buffers needed for downsampled I/O. - * We use values computed in jpeg_start_compress or jpeg_start_decompress. - * We use libjpeg's allocator so that buffers will be released automatically - * when done with strip/tile. - * This is also a handy place to compute samplesperclump, bytesperline. - */ -static int alloc_downsampled_buffers(TIFF *tif, jpeg_component_info *comp_info, - int num_components) -{ - JPEGState *sp = JState(tif); - int ci; - jpeg_component_info *compptr; - TIFF_JSAMPARRAY buf; - int samples_per_clump = 0; - - for (ci = 0, compptr = comp_info; ci < num_components; ci++, compptr++) - { - samples_per_clump += compptr->h_samp_factor * compptr->v_samp_factor; - buf = (TIFF_JSAMPARRAY)TIFFjpeg_alloc_sarray( - sp, JPOOL_IMAGE, compptr->width_in_blocks * DCTSIZE, - (JDIMENSION)(compptr->v_samp_factor * DCTSIZE)); - if (buf == NULL) - return (0); - sp->ds_buffer[ci] = buf; - } - sp->samplesperclump = samples_per_clump; - return (1); -} - -/* - * JPEG Decoding. - */ - -#ifdef CHECK_JPEG_YCBCR_SUBSAMPLING - -#define JPEG_MARKER_SOF0 0xC0 -#define JPEG_MARKER_SOF1 0xC1 -#define JPEG_MARKER_SOF2 0xC2 -#define JPEG_MARKER_SOF9 0xC9 -#define JPEG_MARKER_SOF10 0xCA -#define JPEG_MARKER_DHT 0xC4 -#define JPEG_MARKER_SOI 0xD8 -#define JPEG_MARKER_SOS 0xDA -#define JPEG_MARKER_DQT 0xDB -#define JPEG_MARKER_DRI 0xDD -#define JPEG_MARKER_APP0 0xE0 -#define JPEG_MARKER_COM 0xFE -struct JPEGFixupTagsSubsamplingData -{ - TIFF *tif; - void *buffer; - uint32_t buffersize; - uint8_t *buffercurrentbyte; - uint32_t bufferbytesleft; - uint64_t fileoffset; - uint64_t filebytesleft; - uint8_t filepositioned; -}; -static void JPEGFixupTagsSubsampling(TIFF *tif); -static int -JPEGFixupTagsSubsamplingSec(struct JPEGFixupTagsSubsamplingData *data); -static int -JPEGFixupTagsSubsamplingReadByte(struct JPEGFixupTagsSubsamplingData *data, - uint8_t *result); -static int -JPEGFixupTagsSubsamplingReadWord(struct JPEGFixupTagsSubsamplingData *data, - uint16_t *result); -static void -JPEGFixupTagsSubsamplingSkip(struct JPEGFixupTagsSubsamplingData *data, - uint16_t skiplength); - -#endif - -static int JPEGFixupTags(TIFF *tif) -{ -#ifdef CHECK_JPEG_YCBCR_SUBSAMPLING - 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) && - !sp->otherSettings.ycbcrsampling_fetched) - JPEGFixupTagsSubsampling(tif); -#endif - - return (1); -} - -#ifdef CHECK_JPEG_YCBCR_SUBSAMPLING - -static void JPEGFixupTagsSubsampling(TIFF *tif) -{ - /* - * Some JPEG-in-TIFF produces do not emit the YCBCRSUBSAMPLING values in - * the TIFF tags, but still use non-default (2,2) values within the jpeg - * data stream itself. In order for TIFF applications to work properly - * - for instance to get the strip buffer size right - it is imperative - * that the subsampling be available before we start reading the image - * data normally. This function will attempt to analyze the first strip in - * order to get the sampling values from the jpeg data stream. - * - * Note that JPEGPreDeocode() will produce a fairly loud warning when the - * discovered sampling does not match the default sampling (2,2) or whatever - * was actually in the tiff tags. - * - * See the bug in bugzilla for details: - * - * http://bugzilla.remotesensing.org/show_bug.cgi?id=168 - * - * Frank Warmerdam, July 2002 - * Joris Van Damme, May 2007 - */ - static const char module[] = "JPEGFixupTagsSubsampling"; - struct JPEGFixupTagsSubsamplingData m; - uint64_t fileoffset = TIFFGetStrileOffset(tif, 0); - - if (fileoffset == 0) - { - /* Do not even try to check if the first strip/tile does not - yet exist, as occurs when GDAL has created a new NULL file - for instance. */ - return; - } - - m.tif = tif; - m.buffersize = 2048; - m.buffer = _TIFFmallocExt(tif, m.buffersize); - if (m.buffer == NULL) - { - TIFFWarningExtR(tif, module, - "Unable to allocate memory for auto-correcting of " - "subsampling values; auto-correcting skipped"); - return; - } - m.buffercurrentbyte = NULL; - m.bufferbytesleft = 0; - m.fileoffset = fileoffset; - m.filepositioned = 0; - m.filebytesleft = TIFFGetStrileByteCount(tif, 0); - if (!JPEGFixupTagsSubsamplingSec(&m)) - TIFFWarningExtR( - tif, module, - "Unable to auto-correct subsampling values, likely corrupt JPEG " - "compressed data in first strip/tile; auto-correcting skipped"); - _TIFFfreeExt(tif, m.buffer); -} - -static int -JPEGFixupTagsSubsamplingSec(struct JPEGFixupTagsSubsamplingData *data) -{ - static const char module[] = "JPEGFixupTagsSubsamplingSec"; - uint8_t m; - while (1) - { - while (1) - { - if (!JPEGFixupTagsSubsamplingReadByte(data, &m)) - return (0); - if (m == 255) - break; - } - while (1) - { - if (!JPEGFixupTagsSubsamplingReadByte(data, &m)) - return (0); - if (m != 255) - break; - } - switch (m) - { - case JPEG_MARKER_SOI: - /* this type of marker has no data and should be skipped */ - break; - case JPEG_MARKER_COM: - case JPEG_MARKER_APP0: - case JPEG_MARKER_APP0 + 1: - case JPEG_MARKER_APP0 + 2: - case JPEG_MARKER_APP0 + 3: - case JPEG_MARKER_APP0 + 4: - case JPEG_MARKER_APP0 + 5: - case JPEG_MARKER_APP0 + 6: - case JPEG_MARKER_APP0 + 7: - case JPEG_MARKER_APP0 + 8: - case JPEG_MARKER_APP0 + 9: - case JPEG_MARKER_APP0 + 10: - case JPEG_MARKER_APP0 + 11: - case JPEG_MARKER_APP0 + 12: - case JPEG_MARKER_APP0 + 13: - case JPEG_MARKER_APP0 + 14: - case JPEG_MARKER_APP0 + 15: - case JPEG_MARKER_DQT: - case JPEG_MARKER_SOS: - case JPEG_MARKER_DHT: - case JPEG_MARKER_DRI: - /* this type of marker has data, but it has no use to us and - * should be skipped */ - { - uint16_t n; - if (!JPEGFixupTagsSubsamplingReadWord(data, &n)) - return (0); - if (n < 2) - return (0); - n -= 2; - if (n > 0) - JPEGFixupTagsSubsamplingSkip(data, n); - } - break; - case JPEG_MARKER_SOF0: /* Baseline sequential Huffman */ - case JPEG_MARKER_SOF1: /* Extended sequential Huffman */ - case JPEG_MARKER_SOF2: /* Progressive Huffman: normally not allowed - by TechNote, but that doesn't hurt - supporting it */ - case JPEG_MARKER_SOF9: /* Extended sequential arithmetic */ - case JPEG_MARKER_SOF10: /* Progressive arithmetic: normally not - allowed by TechNote, but that doesn't - hurt supporting it */ - /* this marker contains the subsampling factors we're scanning - * for */ - { - uint16_t n; - uint16_t o; - uint8_t p; - uint8_t ph, pv; - if (!JPEGFixupTagsSubsamplingReadWord(data, &n)) - return (0); - if (n != 8 + data->tif->tif_dir.td_samplesperpixel * 3) - return (0); - JPEGFixupTagsSubsamplingSkip(data, 7); - if (!JPEGFixupTagsSubsamplingReadByte(data, &p)) - return (0); - ph = (p >> 4); - pv = (p & 15); - JPEGFixupTagsSubsamplingSkip(data, 1); - for (o = 1; o < data->tif->tif_dir.td_samplesperpixel; o++) - { - JPEGFixupTagsSubsamplingSkip(data, 1); - if (!JPEGFixupTagsSubsamplingReadByte(data, &p)) - return (0); - if (p != 0x11) - { - TIFFWarningExtR(data->tif, module, - "Subsampling values inside JPEG " - "compressed data " - "have no TIFF equivalent, " - "auto-correction of TIFF " - "subsampling values failed"); - return (1); - } - JPEGFixupTagsSubsamplingSkip(data, 1); - } - if (((ph != 1) && (ph != 2) && (ph != 4)) || - ((pv != 1) && (pv != 2) && (pv != 4))) - { - TIFFWarningExtR(data->tif, module, - "Subsampling values inside JPEG " - "compressed data have no TIFF " - "equivalent, auto-correction of TIFF " - "subsampling values failed"); - return (1); - } - if ((ph != data->tif->tif_dir.td_ycbcrsubsampling[0]) || - (pv != data->tif->tif_dir.td_ycbcrsubsampling[1])) - { - TIFFWarningExtR( - data->tif, module, - "Auto-corrected former TIFF subsampling values " - "[%" PRIu16 ",%" PRIu16 - "] to match subsampling values inside JPEG " - "compressed data [%" PRIu8 ",%" PRIu8 "]", - data->tif->tif_dir.td_ycbcrsubsampling[0], - data->tif->tif_dir.td_ycbcrsubsampling[1], ph, pv); - data->tif->tif_dir.td_ycbcrsubsampling[0] = ph; - data->tif->tif_dir.td_ycbcrsubsampling[1] = pv; - } - } - return (1); - default: - return (0); - } - } -} - -static int -JPEGFixupTagsSubsamplingReadByte(struct JPEGFixupTagsSubsamplingData *data, - uint8_t *result) -{ - if (data->bufferbytesleft == 0) - { - uint32_t m; - if (data->filebytesleft == 0) - return (0); - if (!data->filepositioned) - { - if (TIFFSeekFile(data->tif, data->fileoffset, SEEK_SET) == - (toff_t)-1) - { - return 0; - } - data->filepositioned = 1; - } - m = data->buffersize; - if ((uint64_t)m > data->filebytesleft) - m = (uint32_t)data->filebytesleft; - assert(m < 0x80000000UL); - if (TIFFReadFile(data->tif, data->buffer, (tmsize_t)m) != (tmsize_t)m) - return (0); - data->buffercurrentbyte = data->buffer; - data->bufferbytesleft = m; - data->fileoffset += m; - data->filebytesleft -= m; - } - *result = *data->buffercurrentbyte; - data->buffercurrentbyte++; - data->bufferbytesleft--; - return (1); -} - -static int -JPEGFixupTagsSubsamplingReadWord(struct JPEGFixupTagsSubsamplingData *data, - uint16_t *result) -{ - uint8_t ma; - uint8_t mb; - if (!JPEGFixupTagsSubsamplingReadByte(data, &ma)) - return (0); - if (!JPEGFixupTagsSubsamplingReadByte(data, &mb)) - return (0); - *result = (ma << 8) | mb; - return (1); -} - -static void -JPEGFixupTagsSubsamplingSkip(struct JPEGFixupTagsSubsamplingData *data, - uint16_t skiplength) -{ - if ((uint32_t)skiplength <= data->bufferbytesleft) - { - data->buffercurrentbyte += skiplength; - data->bufferbytesleft -= skiplength; - } - else - { - uint16_t m; - m = (uint16_t)(skiplength - data->bufferbytesleft); - if (m <= data->filebytesleft) - { - data->bufferbytesleft = 0; - data->fileoffset += m; - data->filebytesleft -= m; - data->filepositioned = 0; - } - else - { - data->bufferbytesleft = 0; - data->filebytesleft = 0; - } - } -} - -#endif - -static int JPEGSetupDecode(TIFF *tif) -{ - JPEGState *sp = JState(tif); - TIFFDirectory *td = &tif->tif_dir; - -#if defined(JPEG_DUAL_MODE_8_12) && !defined(FROM_TIF_JPEG_12) - if (tif->tif_dir.td_bitspersample == 12) - { - /* We pass a pointer to a copy of otherSettings, since */ - /* TIFFReInitJPEG_12() will clear sp */ - JPEGOtherSettings savedOtherSettings = sp->otherSettings; - return TIFFReInitJPEG_12(tif, &savedOtherSettings, COMPRESSION_JPEG, 0); - } -#endif - - JPEGInitializeLibJPEG(tif, TRUE); - - assert(sp != NULL); - assert(sp->cinfo.comm.is_decompressor); - - /* Read JPEGTables if it is present */ - if (TIFFFieldSet(tif, FIELD_JPEGTABLES)) - { - TIFFjpeg_tables_src(sp); - if (TIFFjpeg_read_header(sp, FALSE) != JPEG_HEADER_TABLES_ONLY) - { - TIFFErrorExtR(tif, "JPEGSetupDecode", "Bogus JPEGTables field"); - return (0); - } - } - - /* Grab parameters that are same for all strips/tiles */ - sp->photometric = td->td_photometric; - switch (sp->photometric) - { - case PHOTOMETRIC_YCBCR: - sp->h_sampling = td->td_ycbcrsubsampling[0]; - sp->v_sampling = td->td_ycbcrsubsampling[1]; - break; - default: - /* TIFF 6.0 forbids subsampling of all other color spaces */ - sp->h_sampling = 1; - sp->v_sampling = 1; - break; - } - - /* Set up for reading normal data */ - TIFFjpeg_data_src(sp); - tif->tif_postdecode = _TIFFNoPostDecode; /* override byte swapping */ - return (1); -} - -/* Returns 1 if the full strip should be read, even when doing scanline per */ -/* scanline decoding. This happens when the JPEG stream uses multiple scans. */ -/* Currently only called in CHUNKY_STRIP_READ_SUPPORT mode through */ -/* scanline interface. */ -/* Only reads tif->tif_dir.td_bitspersample, tif->tif_rawdata and */ -/* tif->tif_rawcc members. */ -/* Can be called independently of the usual setup/predecode/decode states */ -int TIFFJPEGIsFullStripRequired(TIFF *tif) -{ - int ret; - JPEGState state; - -#if defined(JPEG_DUAL_MODE_8_12) && !defined(FROM_TIF_JPEG_12) - if (tif->tif_dir.td_bitspersample == 12) - return TIFFJPEGIsFullStripRequired_12(tif); -#endif - - memset(&state, 0, sizeof(JPEGState)); - state.tif = tif; - - TIFFjpeg_create_decompress(&state); - - TIFFjpeg_data_src(&state); - - if (TIFFjpeg_read_header(&state, TRUE) != JPEG_HEADER_OK) - { - TIFFjpeg_destroy(&state); - return (0); - } - ret = TIFFjpeg_has_multiple_scans(&state); - - TIFFjpeg_destroy(&state); - - return ret; -} - -/* - * Set up for decoding a strip or tile. - */ -/*ARGSUSED*/ static int JPEGPreDecode(TIFF *tif, uint16_t s) -{ - 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; - - assert(sp != NULL); - - if (sp->cinfo.comm.is_decompressor == 0) - { - tif->tif_setupdecode(tif); - } - - assert(sp->cinfo.comm.is_decompressor); - /* - * Reset decoder state from any previous strip/tile, - * in case application didn't read the whole strip. - */ - if (!TIFFjpeg_abort(sp)) - return (0); - /* - * Read the header for this strip/tile. - */ - - if (TIFFjpeg_read_header(sp, TRUE) != JPEG_HEADER_OK) - return (0); - - tif->tif_rawcp = (uint8_t *)sp->src.next_input_byte; - tif->tif_rawcc = 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 - */ - 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) - { - 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); - } - 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)) - { - /* Some files have a last strip, that should be truncated, */ - /* but their JPEG codestream has still the maximum strip */ - /* height. Warn about this as this is non compliant, but */ - /* we can safely recover from that. */ - 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); - } - else if (sp->cinfo.d.image_width > segment_width || - sp->cinfo.d.image_height > segment_height) - { - /* - * This case could be dangerous, if the strip or tile size has - * been reported as less than the amount of data jpeg will - * return, some potential security issues arise. Catch this - * case and error out. - */ - 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); - return (0); - } - if (sp->cinfo.d.num_components != - (td->td_planarconfig == PLANARCONFIG_CONTIG ? td->td_samplesperpixel - : 1)) - { - TIFFErrorExtR(tif, module, "Improper JPEG component count"); - return (0); - } -#ifdef JPEG_LIB_MK1 - if (12 != td->td_bitspersample && 8 != td->td_bitspersample) - { - TIFFErrorExtR(tif, module, "Improper JPEG data precision"); - return (0); - } - 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) - { - TIFFErrorExtR(tif, module, "Improper JPEG data precision"); - return (0); - } -#endif - - if (sp->cinfo.d.progressive_mode && - !sp->otherSettings.has_warned_about_progressive_mode) - { - TIFFWarningExtR(tif, module, - "The JPEG strip/tile is encoded with progressive mode, " - "which is normally not legal for JPEG-in-TIFF.\n" - "libtiff should be able to decode it, but it might " - "cause compatibility issues with other readers"); - sp->otherSettings.has_warned_about_progressive_mode = TRUE; - } - - /* In some cases, libjpeg needs to allocate a lot of memory */ - /* http://www.libjpeg-turbo.org/pmwiki/uploads/About/TwoIssueswiththeJPEGStandard.pdf - */ - if (TIFFjpeg_has_multiple_scans(sp)) - { - /* In this case libjpeg will need to allocate memory or backing */ - /* store for all coefficients */ - /* See call to jinit_d_coef_controller() from master_selection() */ - /* in libjpeg */ - - /* 1 MB for regular libjpeg usage */ - toff_t nRequiredMemory = 1024 * 1024; - - for (ci = 0; ci < sp->cinfo.d.num_components; ci++) - { - const jpeg_component_info *compptr = &(sp->cinfo.d.comp_info[ci]); - 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) * - sizeof(JBLOCK); - } - } - - if (sp->cinfo.d.mem->max_memory_to_use > 0 && - nRequiredMemory > (toff_t)(sp->cinfo.d.mem->max_memory_to_use) && - getenv("LIBTIFF_ALLOW_LARGE_LIBJPEG_MEM_ALLOC") == NULL) - { - TIFFErrorExtR( - tif, module, - "Reading this image would require libjpeg to allocate " - "at least %" PRIu64 " bytes. " - "This is disabled since above the %ld threshold. " - "You may override this restriction by defining the " - "LIBTIFF_ALLOW_LARGE_LIBJPEG_MEM_ALLOC environment variable, " - "or setting the JPEGMEM environment variable to a value " - "greater " - "or equal to '%" PRIu64 "M'", - nRequiredMemory, sp->cinfo.d.mem->max_memory_to_use, - (nRequiredMemory + 1000000u - 1u) / 1000000u); - return 0; - } - } - - if (td->td_planarconfig == PLANARCONFIG_CONTIG) - { - /* Component 0 should have expected sampling factors */ - if (sp->cinfo.d.comp_info[0].h_samp_factor != sp->h_sampling || - sp->cinfo.d.comp_info[0].v_samp_factor != sp->v_sampling) - { - TIFFErrorExtR(tif, module, - "Improper JPEG sampling factors %d,%d\n" - "Apparently should be %" PRIu16 ",%" PRIu16 ".", - sp->cinfo.d.comp_info[0].h_samp_factor, - sp->cinfo.d.comp_info[0].v_samp_factor, - sp->h_sampling, sp->v_sampling); - return (0); - } - /* Rest should have sampling factors 1,1 */ - for (ci = 1; ci < sp->cinfo.d.num_components; ci++) - { - if (sp->cinfo.d.comp_info[ci].h_samp_factor != 1 || - sp->cinfo.d.comp_info[ci].v_samp_factor != 1) - { - TIFFErrorExtR(tif, module, "Improper JPEG sampling factors"); - return (0); - } - } - } - else - { - /* PC 2's single component should have sampling factors 1,1 */ - if (sp->cinfo.d.comp_info[0].h_samp_factor != 1 || - sp->cinfo.d.comp_info[0].v_samp_factor != 1) - { - TIFFErrorExtR(tif, module, "Improper JPEG sampling factors"); - return (0); - } - } - downsampled_output = FALSE; - if (td->td_planarconfig == PLANARCONFIG_CONTIG && - sp->photometric == PHOTOMETRIC_YCBCR && - sp->otherSettings.jpegcolormode == JPEGCOLORMODE_RGB) - { - /* Convert YCbCr to RGB */ - sp->cinfo.d.jpeg_color_space = JCS_YCbCr; - sp->cinfo.d.out_color_space = JCS_RGB; - } - else - { - /* Suppress colorspace handling */ - sp->cinfo.d.jpeg_color_space = JCS_UNKNOWN; - sp->cinfo.d.out_color_space = JCS_UNKNOWN; - if (td->td_planarconfig == PLANARCONFIG_CONTIG && - (sp->h_sampling != 1 || sp->v_sampling != 1)) - downsampled_output = TRUE; - /* XXX what about up-sampling? */ - } - if (downsampled_output) - { - /* Need to use raw-data interface to libjpeg */ - sp->cinfo.d.raw_data_out = TRUE; -#if JPEG_LIB_VERSION >= 70 - sp->cinfo.d.do_fancy_upsampling = FALSE; -#endif /* JPEG_LIB_VERSION >= 70 */ - tif->tif_decoderow = DecodeRowError; - tif->tif_decodestrip = JPEGDecodeRaw; - tif->tif_decodetile = JPEGDecodeRaw; - } - else - { - /* Use normal interface to libjpeg */ - sp->cinfo.d.raw_data_out = FALSE; - tif->tif_decoderow = JPEGDecode; - tif->tif_decodestrip = JPEGDecode; - tif->tif_decodetile = JPEGDecode; - } - /* Start JPEG decompressor */ - if (!TIFFjpeg_start_decompress(sp)) - return (0); - /* Allocate downsampled-data buffers if needed */ - if (downsampled_output) - { - if (!alloc_downsampled_buffers(tif, sp->cinfo.d.comp_info, - sp->cinfo.d.num_components)) - return (0); - sp->scancount = DCTSIZE; /* mark buffer empty */ - } - return (1); -} - -/* - * Decode a chunk of pixels. - * "Standard" case: returned data is not downsampled. - */ -#if !JPEG_LIB_MK1_OR_12BIT -static int JPEGDecode(TIFF *tif, uint8_t *buf, tmsize_t cc, uint16_t s) -{ - JPEGState *sp = JState(tif); - tmsize_t nrows; - (void)s; - - /* - ** Update available information, buffer may have been refilled - ** between decode requests - */ - sp->src.next_input_byte = (const JOCTET *)tif->tif_rawcp; - sp->src.bytes_in_buffer = (size_t)tif->tif_rawcc; - - if (sp->bytesperline == 0) - return 0; - - nrows = cc / sp->bytesperline; - if (cc % sp->bytesperline) - TIFFWarningExtR(tif, tif->tif_name, "fractional scanline not read"); - - if (nrows > (tmsize_t)sp->cinfo.d.image_height) - nrows = sp->cinfo.d.image_height; - - /* data is expected to be read in multiples of a scanline */ - if (nrows) - { - do - { - /* - * In the libjpeg6b-9a 8bit case. We read directly into - * the TIFF buffer. - */ - JSAMPROW bufptr = (JSAMPROW)buf; - - if (TIFFjpeg_read_scanlines(sp, &bufptr, 1) != 1) - return (0); - - ++tif->tif_row; - buf += sp->bytesperline; - cc -= sp->bytesperline; - } while (--nrows > 0); - } - - /* Update information on consumed data */ - tif->tif_rawcp = (uint8_t *)sp->src.next_input_byte; - tif->tif_rawcc = 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 */ - -#if JPEG_LIB_MK1_OR_12BIT -/*ARGSUSED*/ static int JPEGDecode(TIFF *tif, uint8_t *buf, tmsize_t cc, - uint16_t s) -{ - JPEGState *sp = JState(tif); - tmsize_t nrows; - (void)s; - - /* - ** Update available information, buffer may have been refilled - ** between decode requests - */ - sp->src.next_input_byte = (const JOCTET *)tif->tif_rawcp; - sp->src.bytes_in_buffer = (size_t)tif->tif_rawcc; - - if (sp->bytesperline == 0) - return 0; - - nrows = cc / sp->bytesperline; - if (cc % sp->bytesperline) - TIFFWarningExtR(tif, tif->tif_name, "fractional scanline not read"); - - if (nrows > (tmsize_t)sp->cinfo.d.image_height) - nrows = sp->cinfo.d.image_height; - - /* data is expected to be read in multiples of a scanline */ - if (nrows) - { - TIFF_JSAMPROW line_work_buf = NULL; - - /* - * For 6B, only use temporary buffer for 12 bit imagery. - * For Mk1 always use it. - */ - 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); - } - - do - { - if (line_work_buf != NULL) - { - /* - * In the MK1 case, we always read into a 16bit - * buffer, and then pack down to 12bit or 8bit. - * In 6B case we only read into 16 bit buffer - * for 12bit data, which we need to repack. - */ - if (TIFFjpeg_read_scanlines(sp, &line_work_buf, 1) != 1) - return (0); - - if (sp->cinfo.d.data_precision == 12) - { - int value_pairs = (sp->cinfo.d.output_width * - sp->cinfo.d.num_components) / - 2; - int iPair; - - for (iPair = 0; iPair < value_pairs; iPair++) - { - unsigned char *out_ptr = - ((unsigned char *)buf) + iPair * 3; - TIFF_JSAMPLE *in_ptr = line_work_buf + iPair * 2; - - out_ptr[0] = (unsigned char)((in_ptr[0] & 0xff0) >> 4); - out_ptr[1] = - (unsigned char)(((in_ptr[0] & 0xf) << 4) | - ((in_ptr[1] & 0xf00) >> 8)); - out_ptr[2] = (unsigned char)(((in_ptr[1] & 0xff) >> 0)); - } - } - else if (sp->cinfo.d.data_precision == 8) - { - int value_count = - (sp->cinfo.d.output_width * sp->cinfo.d.num_components); - int iValue; - - for (iValue = 0; iValue < value_count; iValue++) - { - ((unsigned char *)buf)[iValue] = - line_work_buf[iValue] & 0xff; - } - } - } - - ++tif->tif_row; - buf += sp->bytesperline; - cc -= sp->bytesperline; - } while (--nrows > 0); - - if (line_work_buf != NULL) - _TIFFfreeExt(tif, line_work_buf); - } - - /* Update information on consumed data */ - tif->tif_rawcp = (uint8_t *)sp->src.next_input_byte; - tif->tif_rawcc = 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 */ - -/*ARGSUSED*/ static int DecodeRowError(TIFF *tif, uint8_t *buf, tmsize_t cc, - uint16_t s) - -{ - (void)buf; - (void)cc; - (void)s; - - TIFFErrorExtR( - tif, "TIFFReadScanline", - "scanline oriented access is not supported for downsampled JPEG " - "compressed images, consider enabling TIFFTAG_JPEGCOLORMODE as " - "JPEGCOLORMODE_RGB."); - return 0; -} - -/* - * Decode a chunk of pixels. - * Returned data is downsampled per sampling factors. - */ -/*ARGSUSED*/ static int JPEGDecodeRaw(TIFF *tif, uint8_t *buf, tmsize_t cc, - uint16_t s) -{ - JPEGState *sp = JState(tif); - tmsize_t nrows; - TIFFDirectory *td = &tif->tif_dir; - (void)s; - - nrows = sp->cinfo.d.image_height; - /* 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 defined(JPEG_LIB_MK1_OR_12BIT) - unsigned short *tmpbuf = NULL; -#endif - - /* data is expected to be read in multiples of a scanline */ - if (nrows != 0) - { - - /* Cb,Cr both have sampling factors 1, so this is correct */ - JDIMENSION clumps_per_line = sp->cinfo.d.comp_info[1].downsampled_width; - 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); - if (tmpbuf == NULL) - { - TIFFErrorExtR(tif, "JPEGDecodeRaw", "Out of memory"); - return 0; - } -#endif - - do - { - jpeg_component_info *compptr; - int ci, clumpoffset; - - if (cc < sp->bytesperline) - { - TIFFErrorExtR( - tif, "JPEGDecodeRaw", - "application buffer not large enough for all data."); - goto error; - } - - /* Reload downsampled-data buffer if needed */ - if (sp->scancount >= DCTSIZE) - { - int n = sp->cinfo.d.max_v_samp_factor * DCTSIZE; - if (TIFFjpeg_read_raw_data(sp, sp->ds_buffer, n) != n) - goto error; - sp->scancount = 0; - } - /* - * Fastest way to unseparate data is to make one pass - * over the scanline for each row of each component. - */ - clumpoffset = 0; /* first sample in clump */ - for (ci = 0, compptr = sp->cinfo.d.comp_info; - ci < sp->cinfo.d.num_components; ci++, compptr++) - { - int hsamp = compptr->h_samp_factor; - int vsamp = compptr->v_samp_factor; - int ypos; - - for (ypos = 0; ypos < vsamp; ypos++) - { - TIFF_JSAMPLE *inptr = - sp->ds_buffer[ci][sp->scancount * vsamp + ypos]; - JDIMENSION nclump; -#if defined(JPEG_LIB_MK1_OR_12BIT) - TIFF_JSAMPLE *outptr = (TIFF_JSAMPLE *)tmpbuf + clumpoffset; -#else - TIFF_JSAMPLE *outptr = (TIFF_JSAMPLE *)buf + clumpoffset; - if (cc < (tmsize_t)(clumpoffset + - (tmsize_t)samples_per_clump * - (clumps_per_line - 1) + - hsamp)) - { - TIFFErrorExtR( - tif, "JPEGDecodeRaw", - "application buffer not large enough for all data, " - "possible subsampling issue"); - goto error; - } -#endif - - if (hsamp == 1) - { - /* fast path for at least Cb and Cr */ - for (nclump = clumps_per_line; nclump-- > 0;) - { - outptr[0] = *inptr++; - outptr += samples_per_clump; - } - } - else - { - int xpos; - - /* general case */ - for (nclump = clumps_per_line; nclump-- > 0;) - { - for (xpos = 0; xpos < hsamp; xpos++) - outptr[xpos] = *inptr++; - outptr += samples_per_clump; - } - } - clumpoffset += hsamp; - } - } - -#if defined(JPEG_LIB_MK1_OR_12BIT) - { - if (sp->cinfo.d.data_precision == 8) - { - int i = 0; - int len = - sp->cinfo.d.output_width * sp->cinfo.d.num_components; - for (i = 0; i < len; i++) - { - ((unsigned char *)buf)[i] = tmpbuf[i] & 0xff; - } - } - else - { /* 12-bit */ - int value_pairs = (sp->cinfo.d.output_width * - sp->cinfo.d.num_components) / - 2; - int iPair; - for (iPair = 0; iPair < value_pairs; iPair++) - { - unsigned char *out_ptr = - ((unsigned char *)buf) + iPair * 3; - JSAMPLE *in_ptr = (JSAMPLE *)(tmpbuf + iPair * 2); - out_ptr[0] = (unsigned char)((in_ptr[0] & 0xff0) >> 4); - out_ptr[1] = - (unsigned char)(((in_ptr[0] & 0xf) << 4) | - ((in_ptr[1] & 0xf00) >> 8)); - out_ptr[2] = (unsigned char)(((in_ptr[1] & 0xff) >> 0)); - } - } - } -#endif - - sp->scancount++; - tif->tif_row += sp->v_sampling; - - buf += sp->bytesperline; - cc -= sp->bytesperline; - - nrows -= sp->v_sampling; - } while (nrows > 0); - -#if defined(JPEG_LIB_MK1_OR_12BIT) - _TIFFfreeExt(tif, tmpbuf); -#endif - } - - /* Close down the decompressor if done. */ - return sp->cinfo.d.output_scanline < sp->cinfo.d.output_height || - TIFFjpeg_finish_decompress(sp); - -error: -#if defined(JPEG_LIB_MK1_OR_12BIT) - _TIFFfreeExt(tif, tmpbuf); -#endif - return 0; -} - -/* - * JPEG Encoding. - */ - -static void unsuppress_quant_table(JPEGState *sp, int tblno) -{ - JQUANT_TBL *qtbl; - - if ((qtbl = sp->cinfo.c.quant_tbl_ptrs[tblno]) != NULL) - qtbl->sent_table = FALSE; -} - -static void suppress_quant_table(JPEGState *sp, int tblno) -{ - JQUANT_TBL *qtbl; - - if ((qtbl = sp->cinfo.c.quant_tbl_ptrs[tblno]) != NULL) - qtbl->sent_table = TRUE; -} - -static void unsuppress_huff_table(JPEGState *sp, int tblno) -{ - JHUFF_TBL *htbl; - - if ((htbl = sp->cinfo.c.dc_huff_tbl_ptrs[tblno]) != NULL) - htbl->sent_table = FALSE; - if ((htbl = sp->cinfo.c.ac_huff_tbl_ptrs[tblno]) != NULL) - htbl->sent_table = FALSE; -} - -static void suppress_huff_table(JPEGState *sp, int tblno) -{ - JHUFF_TBL *htbl; - - if ((htbl = sp->cinfo.c.dc_huff_tbl_ptrs[tblno]) != NULL) - htbl->sent_table = TRUE; - if ((htbl = sp->cinfo.c.ac_huff_tbl_ptrs[tblno]) != NULL) - htbl->sent_table = TRUE; -} - -static int prepare_JPEGTables(TIFF *tif) -{ - JPEGState *sp = JState(tif); - - /* Initialize quant tables for current quality setting */ - if (!TIFFjpeg_set_quality(sp, sp->otherSettings.jpegquality, FALSE)) - return (0); - /* Mark only the tables we want for output */ - /* NB: chrominance tables are currently used only with YCbCr */ - if (!TIFFjpeg_suppress_tables(sp, TRUE)) - return (0); - if (sp->otherSettings.jpegtablesmode & JPEGTABLESMODE_QUANT) - { - unsuppress_quant_table(sp, 0); - if (sp->photometric == PHOTOMETRIC_YCBCR) - unsuppress_quant_table(sp, 1); - } - if (sp->otherSettings.jpegtablesmode & JPEGTABLESMODE_HUFF) - { - unsuppress_huff_table(sp, 0); - if (sp->photometric == PHOTOMETRIC_YCBCR) - unsuppress_huff_table(sp, 1); - } - /* Direct libjpeg output into otherSettings.jpegtables */ - if (!TIFFjpeg_tables_dest(sp, tif)) - return (0); - /* Emit tables-only datastream */ - if (!TIFFjpeg_write_tables(sp)) - return (0); - - return (1); -} - -#if defined(JPEG_LIB_VERSION_MAJOR) && \ - (JPEG_LIB_VERSION_MAJOR > 9 || \ - (JPEG_LIB_VERSION_MAJOR == 9 && JPEG_LIB_VERSION_MINOR >= 4)) -/* This is a modified version of std_huff_tables() from jcparam.c - * in libjpeg-9d because it no longer initializes default Huffman - * tables in jpeg_set_defaults(). */ -static void TIFF_std_huff_tables(j_compress_ptr cinfo) -{ - - if (cinfo->dc_huff_tbl_ptrs[0] == NULL) - { - (void)jpeg_std_huff_table((j_common_ptr)cinfo, TRUE, 0); - } - if (cinfo->ac_huff_tbl_ptrs[0] == NULL) - { - (void)jpeg_std_huff_table((j_common_ptr)cinfo, FALSE, 0); - } - if (cinfo->dc_huff_tbl_ptrs[1] == NULL) - { - (void)jpeg_std_huff_table((j_common_ptr)cinfo, TRUE, 1); - } - if (cinfo->ac_huff_tbl_ptrs[1] == NULL) - { - (void)jpeg_std_huff_table((j_common_ptr)cinfo, FALSE, 1); - } -} -#endif - -static int JPEGSetupEncode(TIFF *tif) -{ - JPEGState *sp = JState(tif); - TIFFDirectory *td = &tif->tif_dir; - static const char module[] = "JPEGSetupEncode"; - -#if defined(JPEG_DUAL_MODE_8_12) && !defined(FROM_TIF_JPEG_12) - if (tif->tif_dir.td_bitspersample == 12) - { - /* We pass a pointer to a copy of otherSettings, since */ - /* TIFFReInitJPEG_12() will clear sp */ - JPEGOtherSettings savedOtherSettings = sp->otherSettings; - return TIFFReInitJPEG_12(tif, &savedOtherSettings, COMPRESSION_JPEG, 1); - } -#endif - - JPEGInitializeLibJPEG(tif, FALSE); - - assert(sp != NULL); - assert(!sp->cinfo.comm.is_decompressor); - - sp->photometric = td->td_photometric; - - /* - * Initialize all JPEG parameters to default values. - * Note that jpeg_set_defaults needs legal values for - * in_color_space and input_components. - */ - if (td->td_planarconfig == PLANARCONFIG_CONTIG) - { - sp->cinfo.c.input_components = td->td_samplesperpixel; - if (sp->photometric == PHOTOMETRIC_YCBCR) - { - if (sp->otherSettings.jpegcolormode == JPEGCOLORMODE_RGB) - { - sp->cinfo.c.in_color_space = JCS_RGB; - } - else - { - sp->cinfo.c.in_color_space = JCS_YCbCr; - } - } - else - { - if ((td->td_photometric == PHOTOMETRIC_MINISWHITE || - td->td_photometric == PHOTOMETRIC_MINISBLACK) && - td->td_samplesperpixel == 1) - sp->cinfo.c.in_color_space = JCS_GRAYSCALE; - else if (td->td_photometric == PHOTOMETRIC_RGB && - td->td_samplesperpixel == 3) - sp->cinfo.c.in_color_space = JCS_RGB; - else if (td->td_photometric == PHOTOMETRIC_SEPARATED && - td->td_samplesperpixel == 4) - sp->cinfo.c.in_color_space = JCS_CMYK; - else - sp->cinfo.c.in_color_space = JCS_UNKNOWN; - } - } - else - { - sp->cinfo.c.input_components = 1; - sp->cinfo.c.in_color_space = JCS_UNKNOWN; - } - if (!TIFFjpeg_set_defaults(sp)) - return (0); - - /* mozjpeg by default enables progressive JPEG, which is illegal in - * JPEG-in-TIFF */ - /* So explicitly disable it. */ - if (sp->cinfo.c.num_scans != 0 && - (sp->otherSettings.jpegtablesmode & JPEGTABLESMODE_HUFF) != 0) - { - /* it has been found that mozjpeg could create corrupt strips/tiles */ - /* in non optimize_coding mode. */ - TIFFWarningExtR( - tif, module, - "mozjpeg library likely detected. Disable emission of " - "Huffman tables in JpegTables tag, and use optimize_coding " - "to avoid potential issues"); - sp->otherSettings.jpegtablesmode &= ~JPEGTABLESMODE_HUFF; - } - sp->cinfo.c.num_scans = 0; - sp->cinfo.c.scan_info = NULL; - - /* Set per-file parameters */ - switch (sp->photometric) - { - case PHOTOMETRIC_YCBCR: - sp->h_sampling = td->td_ycbcrsubsampling[0]; - sp->v_sampling = td->td_ycbcrsubsampling[1]; - if (sp->h_sampling == 0 || sp->v_sampling == 0) - { - TIFFErrorExtR(tif, module, - "Invalig horizontal/vertical sampling value"); - return (0); - } - if (td->td_bitspersample > 16) - { - TIFFErrorExtR(tif, module, - "BitsPerSample %" PRIu16 " not allowed for JPEG", - td->td_bitspersample); - return (0); - } - - /* - * A ReferenceBlackWhite field *must* be present since the - * default value is inappropriate for YCbCr. Fill in the - * proper value if application didn't set it. - */ - { - float *ref; - if (!TIFFGetField(tif, TIFFTAG_REFERENCEBLACKWHITE, &ref)) - { - float refbw[6]; - long top = 1L << td->td_bitspersample; - refbw[0] = 0; - refbw[1] = (float)(top - 1L); - refbw[2] = (float)(top >> 1); - refbw[3] = refbw[1]; - refbw[4] = refbw[2]; - refbw[5] = refbw[1]; - TIFFSetField(tif, TIFFTAG_REFERENCEBLACKWHITE, refbw); - } - } - break; - case PHOTOMETRIC_PALETTE: /* disallowed by Tech Note */ - case PHOTOMETRIC_MASK: - TIFFErrorExtR(tif, module, - "PhotometricInterpretation %" PRIu16 - " not allowed for JPEG", - sp->photometric); - return (0); - default: - /* TIFF 6.0 forbids subsampling of all other color spaces */ - sp->h_sampling = 1; - sp->v_sampling = 1; - break; - } - - /* Verify miscellaneous parameters */ - - /* - * This would need work if libtiff ever supports different - * depths for different components, or if libjpeg ever supports - * run-time selection of depth. Neither is imminent. - */ -#ifdef JPEG_LIB_MK1 - /* BITS_IN_JSAMPLE now permits 8 and 12 --- dgilbert */ - if (td->td_bitspersample != 8 && td->td_bitspersample != 12) -#else - if (td->td_bitspersample != BITS_IN_JSAMPLE) -#endif - { - TIFFErrorExtR(tif, module, - "BitsPerSample %" PRIu16 " not allowed for JPEG", - td->td_bitspersample); - return (0); - } - sp->cinfo.c.data_precision = td->td_bitspersample; -#ifdef JPEG_LIB_MK1 - sp->cinfo.c.bits_in_jsample = td->td_bitspersample; -#endif - if (isTiled(tif)) - { - if ((td->td_tilelength % (sp->v_sampling * DCTSIZE)) != 0) - { - TIFFErrorExtR(tif, module, - "JPEG tile height must be multiple of %" PRIu32, - (uint32_t)(sp->v_sampling * DCTSIZE)); - return (0); - } - if ((td->td_tilewidth % (sp->h_sampling * DCTSIZE)) != 0) - { - TIFFErrorExtR(tif, module, - "JPEG tile width must be multiple of %" PRIu32, - (uint32_t)(sp->h_sampling * DCTSIZE)); - return (0); - } - } - else - { - if (td->td_rowsperstrip < td->td_imagelength && - (td->td_rowsperstrip % (sp->v_sampling * DCTSIZE)) != 0) - { - TIFFErrorExtR(tif, module, - "RowsPerStrip must be multiple of %" PRIu32 - " for JPEG", - (uint32_t)(sp->v_sampling * DCTSIZE)); - return (0); - } - } - - /* Create a JPEGTables field if appropriate */ - if (sp->otherSettings.jpegtablesmode & - (JPEGTABLESMODE_QUANT | JPEGTABLESMODE_HUFF)) - { - if (sp->otherSettings.jpegtables == NULL || - memcmp(sp->otherSettings.jpegtables, "\0\0\0\0\0\0\0\0\0", 8) == 0) - { -#if defined(JPEG_LIB_VERSION_MAJOR) && \ - (JPEG_LIB_VERSION_MAJOR > 9 || \ - (JPEG_LIB_VERSION_MAJOR == 9 && JPEG_LIB_VERSION_MINOR >= 4)) - if ((sp->otherSettings.jpegtablesmode & JPEGTABLESMODE_HUFF) != 0 && - (sp->cinfo.c.dc_huff_tbl_ptrs[0] == NULL || - sp->cinfo.c.dc_huff_tbl_ptrs[1] == NULL || - sp->cinfo.c.ac_huff_tbl_ptrs[0] == NULL || - sp->cinfo.c.ac_huff_tbl_ptrs[1] == NULL)) - { - /* libjpeg-9d no longer initializes default Huffman tables in */ - /* jpeg_set_defaults() */ - TIFF_std_huff_tables(&sp->cinfo.c); - } -#endif - - if (!prepare_JPEGTables(tif)) - return (0); - /* Mark the field present */ - /* Can't use TIFFSetField since BEENWRITING is already set! */ - tif->tif_flags |= TIFF_DIRTYDIRECT; - TIFFSetFieldBit(tif, FIELD_JPEGTABLES); - } - } - else - { - /* We do not support application-supplied JPEGTables, */ - /* so mark the field not present */ - TIFFClrFieldBit(tif, FIELD_JPEGTABLES); - } - - /* Direct libjpeg output to libtiff's output buffer */ - TIFFjpeg_data_dest(sp, tif); - - return (1); -} - -/* - * Set encoding state at the start of a strip or tile. - */ -static int JPEGPreEncode(TIFF *tif, uint16_t s) -{ - JPEGState *sp = JState(tif); - TIFFDirectory *td = &tif->tif_dir; - static const char module[] = "JPEGPreEncode"; - uint32_t segment_width, segment_height; - int downsampled_input; - - assert(sp != NULL); - - if (sp->cinfo.comm.is_decompressor == 1) - { - tif->tif_setupencode(tif); - } - - 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 - */ - segment_width = TIFFhowmany_32(segment_width, sp->h_sampling); - segment_height = TIFFhowmany_32(segment_height, sp->v_sampling); - } - if (segment_width > 65535 || segment_height > 65535) - { - TIFFErrorExtR(tif, module, "Strip/tile too large for JPEG"); - return (0); - } - sp->cinfo.c.image_width = segment_width; - sp->cinfo.c.image_height = segment_height; - downsampled_input = FALSE; - if (td->td_planarconfig == PLANARCONFIG_CONTIG) - { - sp->cinfo.c.input_components = td->td_samplesperpixel; - if (sp->photometric == PHOTOMETRIC_YCBCR) - { - if (sp->otherSettings.jpegcolormode != JPEGCOLORMODE_RGB) - { - if (sp->h_sampling != 1 || sp->v_sampling != 1) - downsampled_input = TRUE; - } - if (!TIFFjpeg_set_colorspace(sp, JCS_YCbCr)) - return (0); - /* - * Set Y sampling factors; - * we assume jpeg_set_colorspace() set the rest to 1 - */ - sp->cinfo.c.comp_info[0].h_samp_factor = sp->h_sampling; - sp->cinfo.c.comp_info[0].v_samp_factor = sp->v_sampling; - } - else - { - if (!TIFFjpeg_set_colorspace(sp, sp->cinfo.c.in_color_space)) - return (0); - /* jpeg_set_colorspace set all sampling factors to 1 */ - } - } - else - { - if (!TIFFjpeg_set_colorspace(sp, JCS_UNKNOWN)) - return (0); - sp->cinfo.c.comp_info[0].component_id = s; - /* jpeg_set_colorspace() set sampling factors to 1 */ - if (sp->photometric == PHOTOMETRIC_YCBCR && s > 0) - { - sp->cinfo.c.comp_info[0].quant_tbl_no = 1; - sp->cinfo.c.comp_info[0].dc_tbl_no = 1; - sp->cinfo.c.comp_info[0].ac_tbl_no = 1; - } - } - /* ensure libjpeg won't write any extraneous markers */ - sp->cinfo.c.write_JFIF_header = FALSE; - sp->cinfo.c.write_Adobe_marker = FALSE; - /* set up table handling correctly */ - /* calling TIFFjpeg_set_quality() causes quantization tables to be flagged - */ - /* as being to be emitted, which we don't want in the JPEGTABLESMODE_QUANT - */ - /* mode, so we must manually suppress them. However TIFFjpeg_set_quality() - */ - /* should really be called when dealing with files with directories with */ - /* mixed qualities. see http://trac.osgeo.org/gdal/ticket/3539 */ - if (!TIFFjpeg_set_quality(sp, sp->otherSettings.jpegquality, FALSE)) - return (0); - if (sp->otherSettings.jpegtablesmode & JPEGTABLESMODE_QUANT) - { - suppress_quant_table(sp, 0); - suppress_quant_table(sp, 1); - } - else - { - unsuppress_quant_table(sp, 0); - unsuppress_quant_table(sp, 1); - } - if (sp->otherSettings.jpegtablesmode & JPEGTABLESMODE_HUFF) - { - /* Explicit suppression is only needed if we did not go through the */ - /* prepare_JPEGTables() code path, which may be the case if updating */ - /* an existing file */ - suppress_huff_table(sp, 0); - suppress_huff_table(sp, 1); - sp->cinfo.c.optimize_coding = FALSE; - } - else - sp->cinfo.c.optimize_coding = TRUE; - if (downsampled_input) - { - /* Need to use raw-data interface to libjpeg */ - sp->cinfo.c.raw_data_in = TRUE; - tif->tif_encoderow = JPEGEncodeRaw; - tif->tif_encodestrip = JPEGEncodeRaw; - tif->tif_encodetile = JPEGEncodeRaw; - } - else - { - /* Use normal interface to libjpeg */ - sp->cinfo.c.raw_data_in = FALSE; - tif->tif_encoderow = JPEGEncode; - tif->tif_encodestrip = JPEGEncode; - tif->tif_encodetile = JPEGEncode; - } - /* Start JPEG compressor */ - if (!TIFFjpeg_start_compress(sp, FALSE)) - return (0); - /* Allocate downsampled-data buffers if needed */ - if (downsampled_input) - { - if (!alloc_downsampled_buffers(tif, sp->cinfo.c.comp_info, - sp->cinfo.c.num_components)) - return (0); - } - sp->scancount = 0; - - return (1); -} - -/* - * Encode a chunk of pixels. - * "Standard" case: incoming data is not downsampled. - */ -static int JPEGEncode(TIFF *tif, uint8_t *buf, tmsize_t cc, uint16_t s) -{ - JPEGState *sp = JState(tif); - tmsize_t nrows; - TIFF_JSAMPROW bufptr[1]; - short *line16 = NULL; - int line16_count = 0; - - (void)s; - assert(sp != NULL); - /* data is expected to be supplied in multiples of a scanline */ - nrows = cc / sp->bytesperline; - if (cc % sp->bytesperline) - 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 (sp->cinfo.c.data_precision == 12) - { - line16_count = (int)((sp->bytesperline * 2) / 3); - line16 = (short *)_TIFFmallocExt(tif, sizeof(short) * line16_count); - if (!line16) - { - TIFFErrorExtR(tif, "JPEGEncode", "Failed to allocate memory"); - - return 0; - } - } - - while (nrows-- > 0) - { - - if (sp->cinfo.c.data_precision == 12) - { - - int value_pairs = line16_count / 2; - int iPair; - - bufptr[0] = (TIFF_JSAMPROW)line16; - - for (iPair = 0; iPair < value_pairs; iPair++) - { - 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]; - } - } - else - { - bufptr[0] = (TIFF_JSAMPROW)buf; - } - if (TIFFjpeg_write_scanlines(sp, bufptr, 1) != 1) - return (0); - if (nrows > 0) - tif->tif_row++; - buf += sp->bytesperline; - } - - if (sp->cinfo.c.data_precision == 12) - { - _TIFFfreeExt(tif, line16); - } - - return (1); -} - -/* - * Encode a chunk of pixels. - * Incoming data is expected to be downsampled per sampling factors. - */ -static int JPEGEncodeRaw(TIFF *tif, uint8_t *buf, tmsize_t cc, uint16_t s) -{ - JPEGState *sp = JState(tif); - TIFF_JSAMPLE *inptr; - TIFF_JSAMPLE *outptr; - tmsize_t nrows; - JDIMENSION clumps_per_line, nclump; - int clumpoffset, ci, xpos, ypos; - jpeg_component_info *compptr; - int samples_per_clump = sp->samplesperclump; - tmsize_t bytesperclumpline; - - (void)s; - assert(sp != NULL); - /* data is expected to be supplied in multiples of a clumpline */ - /* a clumpline is equivalent to v_sampling desubsampled scanlines */ - /* TODO: the following calculation of bytesperclumpline, should substitute - * calculation of sp->bytesperline, except that it is per v_sampling lines - */ - bytesperclumpline = - ((((tmsize_t)sp->cinfo.c.image_width + sp->h_sampling - 1) / - sp->h_sampling) * - ((tmsize_t)sp->h_sampling * sp->v_sampling + 2) * - sp->cinfo.c.data_precision + - 7) / - 8; - - nrows = (cc / bytesperclumpline) * sp->v_sampling; - if (cc % bytesperclumpline) - TIFFWarningExtR(tif, tif->tif_name, "fractional scanline discarded"); - - /* Cb,Cr both have sampling factors 1, so this is correct */ - clumps_per_line = sp->cinfo.c.comp_info[1].downsampled_width; - - while (nrows > 0) - { - /* - * Fastest way to separate the data is to make one pass - * over the scanline for each row of each component. - */ - clumpoffset = 0; /* first sample in clump */ - for (ci = 0, compptr = sp->cinfo.c.comp_info; - ci < sp->cinfo.c.num_components; ci++, compptr++) - { - int hsamp = compptr->h_samp_factor; - int vsamp = compptr->v_samp_factor; - int padding = (int)(compptr->width_in_blocks * DCTSIZE - - clumps_per_line * hsamp); - for (ypos = 0; ypos < vsamp; ypos++) - { - inptr = ((TIFF_JSAMPLE *)buf) + clumpoffset; - outptr = sp->ds_buffer[ci][sp->scancount * vsamp + ypos]; - if (hsamp == 1) - { - /* fast path for at least Cb and Cr */ - for (nclump = clumps_per_line; nclump-- > 0;) - { - *outptr++ = inptr[0]; - inptr += samples_per_clump; - } - } - else - { - /* general case */ - for (nclump = clumps_per_line; nclump-- > 0;) - { - for (xpos = 0; xpos < hsamp; xpos++) - *outptr++ = inptr[xpos]; - inptr += samples_per_clump; - } - } - /* pad each scanline as needed */ - for (xpos = 0; xpos < padding; xpos++) - { - *outptr = outptr[-1]; - outptr++; - } - clumpoffset += hsamp; - } - } - sp->scancount++; - if (sp->scancount >= DCTSIZE) - { - int n = sp->cinfo.c.max_v_samp_factor * DCTSIZE; - if (TIFFjpeg_write_raw_data(sp, sp->ds_buffer, n) != n) - return (0); - sp->scancount = 0; - } - tif->tif_row += sp->v_sampling; - buf += bytesperclumpline; - nrows -= sp->v_sampling; - } - return (1); -} - -/* - * Finish up at the end of a strip or tile. - */ -static int JPEGPostEncode(TIFF *tif) -{ - JPEGState *sp = JState(tif); - - if (sp->scancount > 0) - { - /* - * Need to emit a partial bufferload of downsampled data. - * Pad the data vertically. - */ - int ci, ypos, n; - jpeg_component_info *compptr; - - for (ci = 0, compptr = sp->cinfo.c.comp_info; - ci < sp->cinfo.c.num_components; ci++, compptr++) - { - int vsamp = compptr->v_samp_factor; - tmsize_t row_width = - compptr->width_in_blocks * DCTSIZE * sizeof(JSAMPLE); - for (ypos = sp->scancount * vsamp; ypos < DCTSIZE * vsamp; ypos++) - { - _TIFFmemcpy((void *)sp->ds_buffer[ci][ypos], - (void *)sp->ds_buffer[ci][ypos - 1], row_width); - } - } - n = sp->cinfo.c.max_v_samp_factor * DCTSIZE; - if (TIFFjpeg_write_raw_data(sp, sp->ds_buffer, n) != n) - return (0); - } - - return (TIFFjpeg_finish_compress(JState(tif))); -} - -static void JPEGCleanup(TIFF *tif) -{ - JPEGState *sp = JState(tif); - - assert(sp != 0); - - tif->tif_tagmethods.vgetfield = sp->otherSettings.vgetparent; - tif->tif_tagmethods.vsetfield = sp->otherSettings.vsetparent; - tif->tif_tagmethods.printdir = sp->otherSettings.printdir; - if (sp->cinfo_initialized) - TIFFjpeg_destroy(sp); /* release libjpeg resources */ - if (sp->otherSettings.jpegtables) /* tag value */ - _TIFFfreeExt(tif, sp->otherSettings.jpegtables); - _TIFFfreeExt(tif, tif->tif_data); /* release local state */ - tif->tif_data = NULL; - - _TIFFSetDefaultCompressionState(tif); -} - -static void JPEGResetUpsampled(TIFF *tif) -{ - JPEGState *sp = JState(tif); - TIFFDirectory *td = &tif->tif_dir; - - /* - * Mark whether returned data is up-sampled or not so TIFFStripSize - * and TIFFTileSize return values that reflect the true amount of - * data. - */ - tif->tif_flags &= ~TIFF_UPSAMPLED; - if (td->td_planarconfig == PLANARCONFIG_CONTIG) - { - if (td->td_photometric == PHOTOMETRIC_YCBCR && - sp->otherSettings.jpegcolormode == JPEGCOLORMODE_RGB) - { - tif->tif_flags |= TIFF_UPSAMPLED; - } - else - { -#ifdef notdef - if (td->td_ycbcrsubsampling[0] != 1 || - td->td_ycbcrsubsampling[1] != 1) - ; /* XXX what about up-sampling? */ -#endif - } - } - - /* - * 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); -} - -static int JPEGVSetField(TIFF *tif, uint32_t tag, va_list ap) -{ - JPEGState *sp = JState(tif); - const TIFFField *fip; - uint32_t v32; - - assert(sp != NULL); - - switch (tag) - { - case TIFFTAG_JPEGTABLES: - v32 = (uint32_t)va_arg(ap, uint32_t); - if (v32 == 0) - { - /* XXX */ - return (0); - } - _TIFFsetByteArrayExt(tif, &sp->otherSettings.jpegtables, - va_arg(ap, void *), v32); - sp->otherSettings.jpegtables_length = v32; - TIFFSetFieldBit(tif, FIELD_JPEGTABLES); - break; - case TIFFTAG_JPEGQUALITY: - sp->otherSettings.jpegquality = (int)va_arg(ap, int); - return (1); /* pseudo tag */ - case TIFFTAG_JPEGCOLORMODE: - sp->otherSettings.jpegcolormode = (int)va_arg(ap, int); - JPEGResetUpsampled(tif); - return (1); /* pseudo tag */ - case TIFFTAG_PHOTOMETRIC: - { - int ret_value = (*sp->otherSettings.vsetparent)(tif, tag, ap); - JPEGResetUpsampled(tif); - return ret_value; - } - case TIFFTAG_JPEGTABLESMODE: - sp->otherSettings.jpegtablesmode = (int)va_arg(ap, int); - return (1); /* pseudo tag */ - case TIFFTAG_YCBCRSUBSAMPLING: - /* mark the fact that we have a real ycbcrsubsampling! */ - sp->otherSettings.ycbcrsampling_fetched = 1; - /* should we be recomputing upsampling info here? */ - return (*sp->otherSettings.vsetparent)(tif, tag, ap); - default: - return (*sp->otherSettings.vsetparent)(tif, tag, ap); - } - - if ((fip = TIFFFieldWithTag(tif, tag)) != NULL) - { - TIFFSetFieldBit(tif, fip->field_bit); - } - else - { - return (0); - } - - tif->tif_flags |= TIFF_DIRTYDIRECT; - return (1); -} - -static int JPEGVGetField(TIFF *tif, uint32_t tag, va_list ap) -{ - JPEGState *sp = JState(tif); - - assert(sp != NULL); - - switch (tag) - { - case TIFFTAG_JPEGTABLES: - *va_arg(ap, uint32_t *) = sp->otherSettings.jpegtables_length; - *va_arg(ap, const void **) = sp->otherSettings.jpegtables; - break; - case TIFFTAG_JPEGQUALITY: - *va_arg(ap, int *) = sp->otherSettings.jpegquality; - break; - case TIFFTAG_JPEGCOLORMODE: - *va_arg(ap, int *) = sp->otherSettings.jpegcolormode; - break; - case TIFFTAG_JPEGTABLESMODE: - *va_arg(ap, int *) = sp->otherSettings.jpegtablesmode; - break; - default: - return (*sp->otherSettings.vgetparent)(tif, tag, ap); - } - return (1); -} - -static void JPEGPrintDir(TIFF *tif, FILE *fd, long flags) -{ - JPEGState *sp = JState(tif); - - assert(sp != NULL); - (void)flags; - - if (sp != NULL) - { - if (TIFFFieldSet(tif, FIELD_JPEGTABLES)) - fprintf(fd, " JPEG Tables: (%" PRIu32 " bytes)\n", - sp->otherSettings.jpegtables_length); - if (sp->otherSettings.printdir) - (*sp->otherSettings.printdir)(tif, fd, flags); - } -} - -static uint32_t JPEGDefaultStripSize(TIFF *tif, uint32_t s) -{ - JPEGState *sp = JState(tif); - TIFFDirectory *td = &tif->tif_dir; - - s = (*sp->otherSettings.defsparent)(tif, s); - if (s < td->td_imagelength) - s = TIFFroundup_32(s, td->td_ycbcrsubsampling[1] * DCTSIZE); - return (s); -} - -static void JPEGDefaultTileSize(TIFF *tif, uint32_t *tw, uint32_t *th) -{ - JPEGState *sp = JState(tif); - TIFFDirectory *td = &tif->tif_dir; - - (*sp->otherSettings.deftparent)(tif, tw, th); - *tw = TIFFroundup_32(*tw, td->td_ycbcrsubsampling[0] * DCTSIZE); - *th = TIFFroundup_32(*th, td->td_ycbcrsubsampling[1] * DCTSIZE); -} - -/* - * The JPEG library initialized used to be done in TIFFInitJPEG(), but - * now that we allow a TIFF file to be opened in update mode it is necessary - * to have some way of deciding whether compression or decompression is - * desired other than looking at tif->tif_mode. We accomplish this by - * examining {TILE/STRIP}BYTECOUNTS to see if there is a non-zero entry. - * If so, we assume decompression is desired. - * - * This is tricky, because TIFFInitJPEG() is called while the directory is - * being read, and generally speaking the BYTECOUNTS tag won't have been read - * at that point. So we try to defer jpeg library initialization till we - * do have that tag ... basically any access that might require the compressor - * or decompressor that occurs after the reading of the directory. - * - * In an ideal world compressors or decompressors would be setup - * at the point where a single tile or strip was accessed (for read or write) - * so that stuff like update of missing tiles, or replacement of tiles could - * be done. However, we aren't trying to crack that nut just yet ... - * - * NFW, Feb 3rd, 2003. - */ - -static int JPEGInitializeLibJPEG(TIFF *tif, int decompress) -{ - JPEGState *sp = JState(tif); - - if (sp->cinfo_initialized) - { - if (!decompress && sp->cinfo.comm.is_decompressor) - TIFFjpeg_destroy(sp); - else if (decompress && !sp->cinfo.comm.is_decompressor) - TIFFjpeg_destroy(sp); - else - return 1; - - sp->cinfo_initialized = 0; - } - - /* - * Initialize libjpeg. - */ - if (decompress) - { - if (!TIFFjpeg_create_decompress(sp)) - return (0); - } - else - { - if (!TIFFjpeg_create_compress(sp)) - return (0); -#ifndef TIFF_JPEG_MAX_MEMORY_TO_USE -#define TIFF_JPEG_MAX_MEMORY_TO_USE (10 * 1024 * 1024) -#endif - /* libjpeg turbo 1.5.2 honours max_memory_to_use, but has no backing */ - /* store implementation, so better not set max_memory_to_use ourselves. - */ - /* See https://github.com/libjpeg-turbo/libjpeg-turbo/issues/162 */ - if (sp->cinfo.c.mem->max_memory_to_use > 0) - { - /* This is to address bug related in ticket GDAL #1795. */ - if (getenv("JPEGMEM") == NULL) - { - /* Increase the max memory usable. This helps when creating - * files */ - /* with "big" tile, without using libjpeg temporary files. */ - /* For example a 512x512 tile with 3 bands */ - /* requires 1.5 MB which is above libjpeg 1MB default */ - if (sp->cinfo.c.mem->max_memory_to_use < - TIFF_JPEG_MAX_MEMORY_TO_USE) - sp->cinfo.c.mem->max_memory_to_use = - TIFF_JPEG_MAX_MEMORY_TO_USE; - } - } - } - - sp->cinfo_initialized = TRUE; - - return 1; -} - -/* Common to tif_jpeg.c and tif_jpeg_12.c */ -static void TIFFInitJPEGCommon(TIFF *tif) -{ - JPEGState *sp; - - sp = JState(tif); - sp->tif = tif; /* back link */ - - /* Default values for codec-specific fields */ - sp->otherSettings.jpegtables = NULL; - sp->otherSettings.jpegtables_length = 0; - sp->otherSettings.jpegquality = 75; /* Default IJG quality */ - sp->otherSettings.jpegcolormode = JPEGCOLORMODE_RAW; - sp->otherSettings.jpegtablesmode = - JPEGTABLESMODE_QUANT | JPEGTABLESMODE_HUFF; - sp->otherSettings.ycbcrsampling_fetched = 0; - - tif->tif_tagmethods.vgetfield = JPEGVGetField; /* hook for codec tags */ - tif->tif_tagmethods.vsetfield = JPEGVSetField; /* hook for codec tags */ - tif->tif_tagmethods.printdir = JPEGPrintDir; /* hook for codec tags */ - - /* - * Install codec methods. - */ - tif->tif_fixuptags = JPEGFixupTags; - tif->tif_setupdecode = JPEGSetupDecode; - tif->tif_predecode = JPEGPreDecode; - tif->tif_decoderow = JPEGDecode; - tif->tif_decodestrip = JPEGDecode; - tif->tif_decodetile = JPEGDecode; - tif->tif_setupencode = JPEGSetupEncode; - tif->tif_preencode = JPEGPreEncode; - tif->tif_postencode = JPEGPostEncode; - tif->tif_encoderow = JPEGEncode; - tif->tif_encodestrip = JPEGEncode; - tif->tif_encodetile = JPEGEncode; - tif->tif_cleanup = JPEGCleanup; - - tif->tif_defstripsize = JPEGDefaultStripSize; - tif->tif_deftilesize = JPEGDefaultTileSize; - tif->tif_flags |= TIFF_NOBITREV; /* no bit reversal, please */ - sp->cinfo_initialized = FALSE; -} - -int TIFFInitJPEG(TIFF *tif, int scheme) -{ - JPEGState *sp; - - (void)scheme; - assert(scheme == COMPRESSION_JPEG); - - /* - * Merge codec-specific tag information. - */ - if (!_TIFFMergeFields(tif, jpegFields, TIFFArrayCount(jpegFields))) - { - TIFFErrorExtR(tif, "TIFFInitJPEG", - "Merging JPEG codec-specific tags failed"); - return 0; - } - - /* - * Allocate state block so tag methods have storage to record values. - */ - tif->tif_data = (uint8_t *)_TIFFmallocExt(tif, sizeof(JPEGState)); - - if (tif->tif_data == NULL) - { - TIFFErrorExtR(tif, "TIFFInitJPEG", "No space for JPEG state block"); - return 0; - } - _TIFFmemset(tif->tif_data, 0, sizeof(JPEGState)); - - sp = JState(tif); - /* - * Override parent get/set field methods. - */ - sp->otherSettings.vgetparent = tif->tif_tagmethods.vgetfield; - sp->otherSettings.vsetparent = tif->tif_tagmethods.vsetfield; - sp->otherSettings.printdir = tif->tif_tagmethods.printdir; - - sp->otherSettings.defsparent = tif->tif_defstripsize; - sp->otherSettings.deftparent = tif->tif_deftilesize; - - TIFFInitJPEGCommon(tif); - - /* - ** Create a JPEGTables field if no directory has yet been created. - ** We do this just to ensure that sufficient space is reserved for - ** the JPEGTables field. It will be properly created the right - ** size later. - */ - if (tif->tif_diroff == 0) - { -#define SIZE_OF_JPEGTABLES 2000 - /* - The following line assumes incorrectly that all JPEG-in-TIFF files will - have a JPEGTABLES tag generated and causes null-filled JPEGTABLES tags - to be written when the JPEG data is placed with TIFFWriteRawStrip. The - field bit should be set, anyway, later when actual JPEGTABLES header is - generated, so removing it here hopefully is harmless. - TIFFSetFieldBit(tif, FIELD_JPEGTABLES); - */ - sp->otherSettings.jpegtables_length = SIZE_OF_JPEGTABLES; - sp->otherSettings.jpegtables = - (void *)_TIFFmallocExt(tif, sp->otherSettings.jpegtables_length); - if (sp->otherSettings.jpegtables) - { - _TIFFmemset(sp->otherSettings.jpegtables, 0, SIZE_OF_JPEGTABLES); - } - else - { - TIFFErrorExtR(tif, "TIFFInitJPEG", - "Failed to allocate memory for JPEG tables"); - return 0; - } -#undef SIZE_OF_JPEGTABLES - } - return 1; -} -#endif /* JPEG_SUPPORT */ diff --git a/src/3rd/tiff/jpeg_12.c b/src/3rd/tiff/jpeg_12.c deleted file mode 100644 index 6b7d5b35763..00000000000 --- a/src/3rd/tiff/jpeg_12.c +++ /dev/null @@ -1,63 +0,0 @@ - -#include "tiffiop.h" - -#if defined(HAVE_JPEGTURBO_DUAL_MODE_8_12) -#define JPEG_DUAL_MODE_8_12 -#endif - -#if defined(JPEG_DUAL_MODE_8_12) - -#define FROM_TIF_JPEG_12 - -#ifdef TIFFInitJPEG -#undef TIFFInitJPEG -#endif -#define TIFFInitJPEG TIFFInitJPEG_12 - -#ifdef TIFFJPEGIsFullStripRequired -#undef TIFFJPEGIsFullStripRequired -#endif -#define TIFFJPEGIsFullStripRequired TIFFJPEGIsFullStripRequired_12 - -int TIFFInitJPEG_12(TIFF *tif, int scheme); - -#if !defined(HAVE_JPEGTURBO_DUAL_MODE_8_12) -#include LIBJPEG_12_PATH -#endif - -#include "jpeg.c" - -int TIFFReInitJPEG_12(TIFF *tif, const JPEGOtherSettings *otherSettings, - int scheme, int is_encode) -{ - JPEGState *sp; - uint8_t *new_tif_data; - - (void)scheme; - assert(scheme == COMPRESSION_JPEG); - - new_tif_data = - (uint8_t *)_TIFFreallocExt(tif, tif->tif_data, sizeof(JPEGState)); - - if (new_tif_data == NULL) - { - TIFFErrorExtR(tif, "TIFFReInitJPEG_12", - "No space for JPEG state block"); - return 0; - } - - tif->tif_data = new_tif_data; - _TIFFmemset(tif->tif_data, 0, sizeof(JPEGState)); - - TIFFInitJPEGCommon(tif); - - sp = JState(tif); - sp->otherSettings = *otherSettings; - - if (is_encode) - return JPEGSetupEncode(tif); - else - return JPEGSetupDecode(tif); -} - -#endif /* defined(JPEG_DUAL_MODE_8_12) */ diff --git a/src/3rd/tiff/lerc.c b/src/3rd/tiff/lerc.c deleted file mode 100644 index 4f357a6011a..00000000000 --- a/src/3rd/tiff/lerc.c +++ /dev/null @@ -1,1206 +0,0 @@ -/* - * Copyright (c) 2018, Even Rouault - * Author: - * - * Permission to use, copy, modify, distribute, and sell this software and - * its documentation for any purpose is hereby granted without fee, provided - * that (i) the above copyright notices and this permission notice appear in - * all copies of the software and related documentation, and (ii) the names of - * Sam Leffler and Silicon Graphics may not be used in any advertising or - * publicity relating to the software without the specific, prior written - * permission of Sam Leffler and Silicon Graphics. - * - * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, - * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY - * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. - * - * IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR - * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, - * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, - * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF - * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE - * OF THIS SOFTWARE. - */ - -#include "tiffiop.h" -#ifdef LERC_SUPPORT -/* - * TIFF Library. - * - * LERC Compression Support - * - */ - -#include "Lerc_c_api.h" -#include "zlib.h" -#ifdef ZSTD_SUPPORT -#include "zstd.h" -#endif - -#if LIBDEFLATE_SUPPORT -#include "libdeflate.h" -#endif -#define LIBDEFLATE_MAX_COMPRESSION_LEVEL 12 - -#include - -#define LSTATE_INIT_DECODE 0x01 -#define LSTATE_INIT_ENCODE 0x02 - -#ifndef LERC_AT_LEAST_VERSION -#define LERC_AT_LEAST_VERSION(maj, min, patch) 0 -#endif - -/* - * State block for each open TIFF file using LERC compression/decompression. - */ -typedef struct -{ - double maxzerror; /* max z error */ - int lerc_version; - int additional_compression; - int zstd_compress_level; /* zstd */ - int zipquality; /* deflate */ - int state; /* state flags */ - - uint32_t segment_width; - uint32_t segment_height; - - unsigned int uncompressed_size; - unsigned int uncompressed_alloc; - uint8_t *uncompressed_buffer; - unsigned int uncompressed_offset; - - unsigned int mask_size; - uint8_t *mask_buffer; - - unsigned int compressed_size; - void *compressed_buffer; - -#if LIBDEFLATE_SUPPORT - struct libdeflate_decompressor *libdeflate_dec; - struct libdeflate_compressor *libdeflate_enc; -#endif - - TIFFVGetMethod vgetparent; /* super-class method */ - TIFFVSetMethod vsetparent; /* super-class method */ -} LERCState; - -#define LState(tif) ((LERCState *)(tif)->tif_data) -#define DecoderState(tif) LState(tif) -#define EncoderState(tif) LState(tif) - -static int LERCEncode(TIFF *tif, uint8_t *bp, tmsize_t cc, uint16_t s); -static int LERCDecode(TIFF *tif, uint8_t *op, tmsize_t occ, uint16_t s); - -static int LERCFixupTags(TIFF *tif) -{ - (void)tif; - return 1; -} - -static int LERCSetupDecode(TIFF *tif) -{ - LERCState *sp = DecoderState(tif); - - assert(sp != NULL); - - /* if we were last encoding, terminate this mode */ - if (sp->state & LSTATE_INIT_ENCODE) - { - sp->state = 0; - } - - sp->state |= LSTATE_INIT_DECODE; - return 1; -} - -static int GetLercDataType(TIFF *tif) -{ - TIFFDirectory *td = &tif->tif_dir; - static const char module[] = "GetLercDataType"; - - if (td->td_sampleformat == SAMPLEFORMAT_INT && td->td_bitspersample == 8) - { - return 0; - } - - if (td->td_sampleformat == SAMPLEFORMAT_UINT && td->td_bitspersample == 8) - { - return 1; - } - - if (td->td_sampleformat == SAMPLEFORMAT_INT && td->td_bitspersample == 16) - { - return 2; - } - - if (td->td_sampleformat == SAMPLEFORMAT_UINT && td->td_bitspersample == 16) - { - return 3; - } - - if (td->td_sampleformat == SAMPLEFORMAT_INT && td->td_bitspersample == 32) - { - return 4; - } - - if (td->td_sampleformat == SAMPLEFORMAT_UINT && td->td_bitspersample == 32) - { - return 5; - } - - if (td->td_sampleformat == SAMPLEFORMAT_IEEEFP && - td->td_bitspersample == 32) - { - return 6; - } - - if (td->td_sampleformat == SAMPLEFORMAT_IEEEFP && - td->td_bitspersample == 64) - { - return 7; - } - - TIFFErrorExtR( - tif, module, - "Unsupported combination of SampleFormat and td_bitspersample"); - return -1; -} - -static int SetupUncompressedBuffer(TIFF *tif, LERCState *sp, const char *module) -{ - TIFFDirectory *td = &tif->tif_dir; - uint64_t new_size_64; - uint64_t new_alloc_64; - unsigned int new_size; - unsigned int new_alloc; - - sp->uncompressed_offset = 0; - - if (isTiled(tif)) - { - sp->segment_width = td->td_tilewidth; - sp->segment_height = td->td_tilelength; - } - else - { - sp->segment_width = td->td_imagewidth; - sp->segment_height = td->td_imagelength - tif->tif_row; - if (sp->segment_height > td->td_rowsperstrip) - sp->segment_height = td->td_rowsperstrip; - } - - new_size_64 = (uint64_t)sp->segment_width * sp->segment_height * - (td->td_bitspersample / 8); - if (td->td_planarconfig == PLANARCONFIG_CONTIG) - { - new_size_64 *= td->td_samplesperpixel; - } - - new_size = (unsigned int)new_size_64; - sp->uncompressed_size = new_size; - - /* add some margin as we are going to use it also to store deflate/zstd - * compressed data */ - new_alloc_64 = 100 + new_size_64 + new_size_64 / 3; -#ifdef ZSTD_SUPPORT - { - size_t zstd_max = ZSTD_compressBound((size_t)new_size_64); - if (new_alloc_64 < zstd_max) - { - new_alloc_64 = zstd_max; - } - } -#endif - new_alloc = (unsigned int)new_alloc_64; - if (new_alloc != new_alloc_64) - { - TIFFErrorExtR(tif, module, "Too large uncompressed strip/tile"); - _TIFFfreeExt(tif, sp->uncompressed_buffer); - sp->uncompressed_buffer = 0; - sp->uncompressed_alloc = 0; - return 0; - } - - if (sp->uncompressed_alloc < new_alloc) - { - _TIFFfreeExt(tif, sp->uncompressed_buffer); - sp->uncompressed_buffer = _TIFFmallocExt(tif, new_alloc); - if (!sp->uncompressed_buffer) - { - TIFFErrorExtR(tif, module, "Cannot allocate buffer"); - _TIFFfreeExt(tif, sp->uncompressed_buffer); - sp->uncompressed_buffer = 0; - sp->uncompressed_alloc = 0; - return 0; - } - sp->uncompressed_alloc = new_alloc; - } - - if ((td->td_planarconfig == PLANARCONFIG_CONTIG && - td->td_extrasamples > 0 && - td->td_sampleinfo[td->td_extrasamples - 1] == EXTRASAMPLE_UNASSALPHA && - GetLercDataType(tif) == 1) || - (td->td_sampleformat == SAMPLEFORMAT_IEEEFP && - (td->td_planarconfig == PLANARCONFIG_SEPARATE || - td->td_samplesperpixel == 1) && - (td->td_bitspersample == 32 || td->td_bitspersample == 64))) - { - unsigned int mask_size = sp->segment_width * sp->segment_height; - if (sp->mask_size < mask_size) - { - void *mask_buffer = - _TIFFreallocExt(tif, sp->mask_buffer, mask_size); - if (mask_buffer == NULL) - { - TIFFErrorExtR(tif, module, "Cannot allocate buffer"); - sp->mask_size = 0; - _TIFFfreeExt(tif, sp->uncompressed_buffer); - sp->uncompressed_buffer = 0; - sp->uncompressed_alloc = 0; - return 0; - } - sp->mask_buffer = (uint8_t *)mask_buffer; - sp->mask_size = mask_size; - } - } - - return 1; -} - -/* - * Setup state for decoding a strip. - */ -static int LERCPreDecode(TIFF *tif, uint16_t s) -{ - static const char module[] = "LERCPreDecode"; - lerc_status lerc_ret; - TIFFDirectory *td = &tif->tif_dir; - LERCState *sp = DecoderState(tif); - int lerc_data_type; - unsigned int infoArray[8]; - unsigned nomask_bands = td->td_samplesperpixel; - int ndims; - int use_mask = 0; - uint8_t *lerc_data = tif->tif_rawcp; - unsigned int lerc_data_size = (unsigned int)tif->tif_rawcc; - - (void)s; - assert(sp != NULL); - if (sp->state != LSTATE_INIT_DECODE) - tif->tif_setupdecode(tif); - - lerc_data_type = GetLercDataType(tif); - if (lerc_data_type < 0) - return 0; - - if (!SetupUncompressedBuffer(tif, sp, module)) - return 0; - - if (sp->additional_compression != LERC_ADD_COMPRESSION_NONE) - { - if (sp->compressed_size < sp->uncompressed_alloc) - { - _TIFFfreeExt(tif, sp->compressed_buffer); - sp->compressed_buffer = _TIFFmallocExt(tif, sp->uncompressed_alloc); - if (!sp->compressed_buffer) - { - sp->compressed_size = 0; - return 0; - } - sp->compressed_size = sp->uncompressed_alloc; - } - } - - if (sp->additional_compression == LERC_ADD_COMPRESSION_DEFLATE) - { -#if LIBDEFLATE_SUPPORT - enum libdeflate_result res; - size_t lerc_data_sizet = 0; - if (sp->libdeflate_dec == NULL) - { - sp->libdeflate_dec = libdeflate_alloc_decompressor(); - if (sp->libdeflate_dec == NULL) - { - TIFFErrorExtR(tif, module, "Cannot allocate decompressor"); - return 0; - } - } - - res = libdeflate_zlib_decompress( - sp->libdeflate_dec, tif->tif_rawcp, (size_t)tif->tif_rawcc, - sp->compressed_buffer, sp->compressed_size, &lerc_data_sizet); - if (res != LIBDEFLATE_SUCCESS) - { - TIFFErrorExtR(tif, module, "Decoding error at scanline %lu", - (unsigned long)tif->tif_row); - return 0; - } - assert(lerc_data_sizet == (unsigned int)lerc_data_sizet); - lerc_data = sp->compressed_buffer; - lerc_data_size = (unsigned int)lerc_data_sizet; -#else - z_stream strm; - int zlib_ret; - - memset(&strm, 0, sizeof(strm)); - strm.zalloc = NULL; - strm.zfree = NULL; - strm.opaque = NULL; - zlib_ret = inflateInit(&strm); - if (zlib_ret != Z_OK) - { - TIFFErrorExtR(tif, module, "inflateInit() failed"); - inflateEnd(&strm); - return 0; - } - - strm.avail_in = (uInt)tif->tif_rawcc; - strm.next_in = tif->tif_rawcp; - strm.avail_out = sp->compressed_size; - strm.next_out = sp->compressed_buffer; - zlib_ret = inflate(&strm, Z_FINISH); - if (zlib_ret != Z_STREAM_END && zlib_ret != Z_OK) - { - TIFFErrorExtR(tif, module, "inflate() failed"); - inflateEnd(&strm); - return 0; - } - lerc_data = sp->compressed_buffer; - lerc_data_size = sp->compressed_size - strm.avail_out; - inflateEnd(&strm); -#endif - } - else if (sp->additional_compression == LERC_ADD_COMPRESSION_ZSTD) - { -#ifdef ZSTD_SUPPORT - size_t zstd_ret; - - zstd_ret = ZSTD_decompress(sp->compressed_buffer, sp->compressed_size, - tif->tif_rawcp, tif->tif_rawcc); - if (ZSTD_isError(zstd_ret)) - { - TIFFErrorExtR(tif, module, "Error in ZSTD_decompress(): %s", - ZSTD_getErrorName(zstd_ret)); - return 0; - } - - lerc_data = sp->compressed_buffer; - lerc_data_size = (unsigned int)zstd_ret; -#else - TIFFErrorExtR(tif, module, "ZSTD support missing"); - return 0; -#endif - } - else if (sp->additional_compression != LERC_ADD_COMPRESSION_NONE) - { - TIFFErrorExtR(tif, module, "Unhandled additional compression"); - return 0; - } - - lerc_ret = - lerc_getBlobInfo(lerc_data, lerc_data_size, infoArray, NULL, 8, 0); - if (lerc_ret != 0) - { - TIFFErrorExtR(tif, module, "lerc_getBlobInfo() failed"); - return 0; - } - - /* If the configuration is compatible of a LERC mask, and that the */ - /* LERC info has dim == samplesperpixel - 1, then there is a LERC */ - /* mask. */ - if (td->td_planarconfig == PLANARCONFIG_CONTIG && td->td_extrasamples > 0 && - td->td_sampleinfo[td->td_extrasamples - 1] == EXTRASAMPLE_UNASSALPHA && - GetLercDataType(tif) == 1 && - infoArray[2] == td->td_samplesperpixel - 1U) - { - use_mask = 1; - nomask_bands--; - } - else if (td->td_sampleformat == SAMPLEFORMAT_IEEEFP && - (td->td_planarconfig == PLANARCONFIG_SEPARATE || - td->td_samplesperpixel == 1) && - (td->td_bitspersample == 32 || td->td_bitspersample == 64)) - { - use_mask = 1; - } - - ndims = td->td_planarconfig == PLANARCONFIG_CONTIG ? nomask_bands : 1; - - /* Info returned in infoArray is { version, dataType, nDim, nCols, - nRows, nBands, nValidPixels, blobSize } */ - if (infoArray[0] != (unsigned)sp->lerc_version) - { - TIFFWarningExtR(tif, module, - "Unexpected version number: %d. Expected: %d", - infoArray[0], sp->lerc_version); - } - if (infoArray[1] != (unsigned)lerc_data_type) - { - TIFFErrorExtR(tif, module, "Unexpected dataType: %d. Expected: %d", - infoArray[1], lerc_data_type); - return 0; - } - if (infoArray[2] != (unsigned)ndims) - { - TIFFErrorExtR(tif, module, "Unexpected nDim: %d. Expected: %d", - infoArray[2], ndims); - return 0; - } - if (infoArray[3] != sp->segment_width) - { - TIFFErrorExtR(tif, module, "Unexpected nCols: %d. Expected: %du", - infoArray[3], sp->segment_width); - return 0; - } - if (infoArray[4] != sp->segment_height) - { - TIFFErrorExtR(tif, module, "Unexpected nRows: %d. Expected: %u", - infoArray[4], sp->segment_height); - return 0; - } - if (infoArray[5] != 1) - { - TIFFErrorExtR(tif, module, "Unexpected nBands: %d. Expected: %d", - infoArray[5], 1); - return 0; - } - if (infoArray[7] != lerc_data_size) - { - TIFFErrorExtR(tif, module, "Unexpected blobSize: %d. Expected: %u", - infoArray[7], lerc_data_size); - return 0; - } - - lerc_ret = lerc_decode(lerc_data, lerc_data_size, -#if LERC_AT_LEAST_VERSION(3, 0, 0) - use_mask ? 1 : 0, -#endif - use_mask ? sp->mask_buffer : NULL, ndims, - sp->segment_width, sp->segment_height, 1, - lerc_data_type, sp->uncompressed_buffer); - if (lerc_ret != 0) - { - TIFFErrorExtR(tif, module, "lerc_decode() failed"); - return 0; - } - - /* Interleave alpha mask with other samples. */ - if (use_mask && GetLercDataType(tif) == 1) - { - unsigned src_stride = - (td->td_samplesperpixel - 1) * (td->td_bitspersample / 8); - unsigned dst_stride = - td->td_samplesperpixel * (td->td_bitspersample / 8); - unsigned i = sp->segment_width * sp->segment_height; - /* Operate from end to begin to be able to move in place */ - while (i > 0 && i > nomask_bands) - { - i--; - sp->uncompressed_buffer[i * dst_stride + td->td_samplesperpixel - - 1] = 255 * sp->mask_buffer[i]; - memcpy(sp->uncompressed_buffer + i * dst_stride, - sp->uncompressed_buffer + i * src_stride, src_stride); - } - /* First pixels must use memmove due to overlapping areas */ - while (i > 0) - { - i--; - sp->uncompressed_buffer[i * dst_stride + td->td_samplesperpixel - - 1] = 255 * sp->mask_buffer[i]; - memmove(sp->uncompressed_buffer + i * dst_stride, - sp->uncompressed_buffer + i * src_stride, src_stride); - } - } - else if (use_mask && td->td_sampleformat == SAMPLEFORMAT_IEEEFP) - { - const unsigned nb_pixels = sp->segment_width * sp->segment_height; - unsigned i; -#if WORDS_BIGENDIAN - const unsigned char nan_bytes[] = {0x7f, 0xc0, 0, 0}; -#else - const unsigned char nan_bytes[] = {0, 0, 0xc0, 0x7f}; -#endif - float nan_float32; - memcpy(&nan_float32, nan_bytes, 4); - - if (td->td_bitspersample == 32) - { - for (i = 0; i < nb_pixels; i++) - { - if (sp->mask_buffer[i] == 0) - ((float *)sp->uncompressed_buffer)[i] = nan_float32; - } - } - else - { - const double nan_float64 = nan_float32; - for (i = 0; i < nb_pixels; i++) - { - if (sp->mask_buffer[i] == 0) - ((double *)sp->uncompressed_buffer)[i] = nan_float64; - } - } - } - - return 1; -} - -/* - * Decode a strip, tile or scanline. - */ -static int LERCDecode(TIFF *tif, uint8_t *op, tmsize_t occ, uint16_t s) -{ - static const char module[] = "LERCDecode"; - LERCState *sp = DecoderState(tif); - - (void)s; - assert(sp != NULL); - assert(sp->state == LSTATE_INIT_DECODE); - - if (sp->uncompressed_buffer == 0) - { - TIFFErrorExtR(tif, module, "Uncompressed buffer not allocated"); - return 0; - } - - if ((uint64_t)sp->uncompressed_offset + (uint64_t)occ > - sp->uncompressed_size) - { - TIFFErrorExtR(tif, module, "Too many bytes read"); - return 0; - } - - memcpy(op, sp->uncompressed_buffer + sp->uncompressed_offset, occ); - sp->uncompressed_offset += (unsigned)occ; - - return 1; -} - -static int LERCSetupEncode(TIFF *tif) -{ - LERCState *sp = EncoderState(tif); - - assert(sp != NULL); - if (sp->state & LSTATE_INIT_DECODE) - { - sp->state = 0; - } - - sp->state |= LSTATE_INIT_ENCODE; - - return 1; -} - -/* - * Reset encoding state at the start of a strip. - */ -static int LERCPreEncode(TIFF *tif, uint16_t s) -{ - static const char module[] = "LERCPreEncode"; - LERCState *sp = EncoderState(tif); - int lerc_data_type; - - (void)s; - assert(sp != NULL); - if (sp->state != LSTATE_INIT_ENCODE) - tif->tif_setupencode(tif); - - lerc_data_type = GetLercDataType(tif); - if (lerc_data_type < 0) - return 0; - - if (!SetupUncompressedBuffer(tif, sp, module)) - return 0; - - return 1; -} - -/* - * Encode a chunk of pixels. - */ -static int LERCEncode(TIFF *tif, uint8_t *bp, tmsize_t cc, uint16_t s) -{ - static const char module[] = "LERCEncode"; - LERCState *sp = EncoderState(tif); - - (void)s; - assert(sp != NULL); - assert(sp->state == LSTATE_INIT_ENCODE); - - if ((uint64_t)sp->uncompressed_offset + (uint64_t)cc > - sp->uncompressed_size) - { - TIFFErrorExtR(tif, module, "Too many bytes written"); - return 0; - } - - memcpy(sp->uncompressed_buffer + sp->uncompressed_offset, bp, cc); - sp->uncompressed_offset += (unsigned)cc; - - return 1; -} - -/* - * Finish off an encoded strip by flushing it. - */ -static int LERCPostEncode(TIFF *tif) -{ - lerc_status lerc_ret; - static const char module[] = "LERCPostEncode"; - LERCState *sp = EncoderState(tif); - unsigned int numBytes = 0; - unsigned int numBytesWritten = 0; - TIFFDirectory *td = &tif->tif_dir; - int use_mask = 0; - unsigned dst_nbands = td->td_samplesperpixel; - - if (sp->uncompressed_offset != sp->uncompressed_size) - { - TIFFErrorExtR(tif, module, "Unexpected number of bytes in the buffer"); - return 0; - } - - /* Extract alpha mask (if containing only 0 and 255 values, */ - /* and compact array of regular bands */ - if (td->td_planarconfig == PLANARCONFIG_CONTIG && td->td_extrasamples > 0 && - td->td_sampleinfo[td->td_extrasamples - 1] == EXTRASAMPLE_UNASSALPHA && - GetLercDataType(tif) == 1) - { - const unsigned dst_stride = - (td->td_samplesperpixel - 1) * (td->td_bitspersample / 8); - const unsigned src_stride = - td->td_samplesperpixel * (td->td_bitspersample / 8); - unsigned i = 0; - const unsigned nb_pixels = sp->segment_width * sp->segment_height; - - use_mask = 1; - for (i = 0; i < nb_pixels; i++) - { - int v = sp->uncompressed_buffer[i * src_stride + - td->td_samplesperpixel - 1]; - if (v != 0 && v != 255) - { - use_mask = 0; - break; - } - } - - if (use_mask) - { - dst_nbands--; - /* First pixels must use memmove due to overlapping areas */ - for (i = 0; i < dst_nbands && i < nb_pixels; i++) - { - memmove(sp->uncompressed_buffer + i * dst_stride, - sp->uncompressed_buffer + i * src_stride, dst_stride); - sp->mask_buffer[i] = - sp->uncompressed_buffer[i * src_stride + - td->td_samplesperpixel - 1]; - } - for (; i < nb_pixels; i++) - { - memcpy(sp->uncompressed_buffer + i * dst_stride, - sp->uncompressed_buffer + i * src_stride, dst_stride); - sp->mask_buffer[i] = - sp->uncompressed_buffer[i * src_stride + - td->td_samplesperpixel - 1]; - } - } - } - else if (td->td_sampleformat == SAMPLEFORMAT_IEEEFP && - (td->td_planarconfig == PLANARCONFIG_SEPARATE || - dst_nbands == 1) && - (td->td_bitspersample == 32 || td->td_bitspersample == 64)) - { - /* Check for NaN values */ - unsigned i; - const unsigned nb_pixels = sp->segment_width * sp->segment_height; - if (td->td_bitspersample == 32) - { - for (i = 0; i < nb_pixels; i++) - { - const float val = ((float *)sp->uncompressed_buffer)[i]; - if (val != val) - { - use_mask = 1; - break; - } - } - } - else - { - for (i = 0; i < nb_pixels; i++) - { - const double val = ((double *)sp->uncompressed_buffer)[i]; - if (val != val) - { - use_mask = 1; - break; - } - } - } - - if (use_mask) - { - if (td->td_bitspersample == 32) - { - for (i = 0; i < nb_pixels; i++) - { - const float val = ((float *)sp->uncompressed_buffer)[i]; - sp->mask_buffer[i] = (val == val) ? 255 : 0; - } - } - else - { - for (i = 0; i < nb_pixels; i++) - { - const double val = ((double *)sp->uncompressed_buffer)[i]; - sp->mask_buffer[i] = (val == val) ? 255 : 0; - } - } - } - } - -#if 0 - lerc_ret = lerc_computeCompressedSize( - sp->uncompressed_buffer, - sp->lerc_version, - GetLercDataType(tif), - td->td_planarconfig == PLANARCONFIG_CONTIG ? - dst_nbands : 1, - sp->segment_width, - sp->segment_height, - 1, - use_mask ? sp->mask_buffer : NULL, - sp->maxzerror, - &numBytes); - if( lerc_ret != 0 ) - { - TIFFErrorExtR(tif, module, - "lerc_computeCompressedSize() failed"); - return 0; - } -#else - numBytes = sp->uncompressed_alloc; -#endif - - if (sp->compressed_size < numBytes) - { - _TIFFfreeExt(tif, sp->compressed_buffer); - sp->compressed_buffer = _TIFFmallocExt(tif, numBytes); - if (!sp->compressed_buffer) - { - sp->compressed_size = 0; - return 0; - } - sp->compressed_size = numBytes; - } - - lerc_ret = lerc_encodeForVersion( - sp->uncompressed_buffer, sp->lerc_version, GetLercDataType(tif), - td->td_planarconfig == PLANARCONFIG_CONTIG ? dst_nbands : 1, - sp->segment_width, sp->segment_height, 1, -#if LERC_AT_LEAST_VERSION(3, 0, 0) - use_mask ? 1 : 0, -#endif - use_mask ? sp->mask_buffer : NULL, sp->maxzerror, sp->compressed_buffer, - sp->compressed_size, &numBytesWritten); - if (lerc_ret != 0) - { - TIFFErrorExtR(tif, module, "lerc_encode() failed"); - return 0; - } - assert(numBytesWritten < numBytes); - - if (sp->additional_compression == LERC_ADD_COMPRESSION_DEFLATE) - { -#if LIBDEFLATE_SUPPORT - if (sp->libdeflate_enc == NULL) - { - /* To get results as good as zlib, we ask for an extra */ - /* level of compression */ - sp->libdeflate_enc = libdeflate_alloc_compressor( - sp->zipquality == Z_DEFAULT_COMPRESSION ? 7 - : sp->zipquality >= 6 && sp->zipquality <= 9 - ? sp->zipquality + 1 - : sp->zipquality); - if (sp->libdeflate_enc == NULL) - { - TIFFErrorExtR(tif, module, "Cannot allocate compressor"); - return 0; - } - } - - /* Should not happen normally */ - if (libdeflate_zlib_compress_bound( - sp->libdeflate_enc, numBytesWritten) > sp->uncompressed_alloc) - { - TIFFErrorExtR(tif, module, - "Output buffer for libdeflate too small"); - return 0; - } - - tif->tif_rawcc = libdeflate_zlib_compress( - sp->libdeflate_enc, sp->compressed_buffer, numBytesWritten, - sp->uncompressed_buffer, sp->uncompressed_alloc); - - if (tif->tif_rawcc == 0) - { - TIFFErrorExtR(tif, module, "Encoder error at scanline %lu", - (unsigned long)tif->tif_row); - return 0; - } -#else - z_stream strm; - int zlib_ret; - int cappedQuality = sp->zipquality; - if (cappedQuality > Z_BEST_COMPRESSION) - cappedQuality = Z_BEST_COMPRESSION; - - memset(&strm, 0, sizeof(strm)); - strm.zalloc = NULL; - strm.zfree = NULL; - strm.opaque = NULL; - zlib_ret = deflateInit(&strm, cappedQuality); - if (zlib_ret != Z_OK) - { - TIFFErrorExtR(tif, module, "deflateInit() failed"); - return 0; - } - - strm.avail_in = numBytesWritten; - strm.next_in = sp->compressed_buffer; - strm.avail_out = sp->uncompressed_alloc; - strm.next_out = sp->uncompressed_buffer; - zlib_ret = deflate(&strm, Z_FINISH); - if (zlib_ret == Z_STREAM_END) - { - tif->tif_rawcc = sp->uncompressed_alloc - strm.avail_out; - } - deflateEnd(&strm); - if (zlib_ret != Z_STREAM_END) - { - TIFFErrorExtR(tif, module, "deflate() failed"); - return 0; - } -#endif - { - int ret; - uint8_t *tif_rawdata_backup = tif->tif_rawdata; - tif->tif_rawdata = sp->uncompressed_buffer; - ret = TIFFFlushData1(tif); - tif->tif_rawdata = tif_rawdata_backup; - if (!ret) - { - return 0; - } - } - } - else if (sp->additional_compression == LERC_ADD_COMPRESSION_ZSTD) - { -#ifdef ZSTD_SUPPORT - size_t zstd_ret = ZSTD_compress( - sp->uncompressed_buffer, sp->uncompressed_alloc, - sp->compressed_buffer, numBytesWritten, sp->zstd_compress_level); - if (ZSTD_isError(zstd_ret)) - { - TIFFErrorExtR(tif, module, "Error in ZSTD_compress(): %s", - ZSTD_getErrorName(zstd_ret)); - return 0; - } - - { - int ret; - uint8_t *tif_rawdata_backup = tif->tif_rawdata; - tif->tif_rawdata = sp->uncompressed_buffer; - tif->tif_rawcc = zstd_ret; - ret = TIFFFlushData1(tif); - tif->tif_rawdata = tif_rawdata_backup; - if (!ret) - { - return 0; - } - } -#else - TIFFErrorExtR(tif, module, "ZSTD support missing"); - return 0; -#endif - } - else if (sp->additional_compression != LERC_ADD_COMPRESSION_NONE) - { - TIFFErrorExtR(tif, module, "Unhandled additional compression"); - return 0; - } - else - { - int ret; - uint8_t *tif_rawdata_backup = tif->tif_rawdata; - tif->tif_rawdata = sp->compressed_buffer; - tif->tif_rawcc = numBytesWritten; - ret = TIFFFlushData1(tif); - tif->tif_rawdata = tif_rawdata_backup; - if (!ret) - return 0; - } - - return 1; -} - -static void LERCCleanup(TIFF *tif) -{ - LERCState *sp = LState(tif); - - assert(sp != 0); - - tif->tif_tagmethods.vgetfield = sp->vgetparent; - tif->tif_tagmethods.vsetfield = sp->vsetparent; - - _TIFFfreeExt(tif, sp->uncompressed_buffer); - _TIFFfreeExt(tif, sp->compressed_buffer); - _TIFFfreeExt(tif, sp->mask_buffer); - -#if LIBDEFLATE_SUPPORT - if (sp->libdeflate_dec) - libdeflate_free_decompressor(sp->libdeflate_dec); - if (sp->libdeflate_enc) - libdeflate_free_compressor(sp->libdeflate_enc); -#endif - - _TIFFfreeExt(tif, sp); - tif->tif_data = NULL; - - _TIFFSetDefaultCompressionState(tif); -} - -static const TIFFField LERCFields[] = { - {TIFFTAG_LERC_PARAMETERS, TIFF_VARIABLE2, TIFF_VARIABLE2, TIFF_LONG, 0, - TIFF_SETGET_C32_UINT32, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, FALSE, TRUE, - "LercParameters", NULL}, - {TIFFTAG_LERC_MAXZERROR, 0, 0, TIFF_ANY, 0, TIFF_SETGET_DOUBLE, - TIFF_SETGET_UNDEFINED, FIELD_PSEUDO, TRUE, FALSE, "LercMaximumError", - NULL}, - {TIFFTAG_LERC_VERSION, 0, 0, TIFF_ANY, 0, TIFF_SETGET_UINT32, - TIFF_SETGET_UNDEFINED, FIELD_PSEUDO, FALSE, FALSE, "LercVersion", NULL}, - {TIFFTAG_LERC_ADD_COMPRESSION, 0, 0, TIFF_ANY, 0, TIFF_SETGET_UINT32, - TIFF_SETGET_UNDEFINED, FIELD_PSEUDO, FALSE, FALSE, - "LercAdditionalCompression", NULL}, - {TIFFTAG_ZSTD_LEVEL, 0, 0, TIFF_ANY, 0, TIFF_SETGET_INT, - TIFF_SETGET_UNDEFINED, FIELD_PSEUDO, TRUE, FALSE, - "ZSTD zstd_compress_level", NULL}, - {TIFFTAG_ZIPQUALITY, 0, 0, TIFF_ANY, 0, TIFF_SETGET_INT, - TIFF_SETGET_UNDEFINED, FIELD_PSEUDO, TRUE, FALSE, "", NULL}, -}; - -static int LERCVSetFieldBase(TIFF *tif, uint32_t tag, ...) -{ - LERCState *sp = LState(tif); - int ret; - va_list ap; - va_start(ap, tag); - ret = (*sp->vsetparent)(tif, tag, ap); - va_end(ap); - return ret; -} - -static int LERCVSetField(TIFF *tif, uint32_t tag, va_list ap) -{ - static const char module[] = "LERCVSetField"; - LERCState *sp = LState(tif); - - switch (tag) - { - case TIFFTAG_LERC_PARAMETERS: - { - uint32_t count = va_arg(ap, int); - int *params = va_arg(ap, int *); - if (count < 2) - { - TIFFErrorExtR(tif, module, - "Invalid count for LercParameters: %u", count); - return 0; - } - sp->lerc_version = params[0]; - sp->additional_compression = params[1]; - return LERCVSetFieldBase(tif, TIFFTAG_LERC_PARAMETERS, count, - params); - } - case TIFFTAG_LERC_MAXZERROR: - sp->maxzerror = va_arg(ap, double); - return 1; - case TIFFTAG_LERC_VERSION: - { - int params[2] = {0, 0}; - int version = va_arg(ap, int); - if (version != LERC_VERSION_2_4) - { - TIFFErrorExtR(tif, module, "Invalid value for LercVersion: %d", - version); - return 0; - } - sp->lerc_version = version; - params[0] = sp->lerc_version; - params[1] = sp->additional_compression; - return LERCVSetFieldBase(tif, TIFFTAG_LERC_PARAMETERS, 2, params); - } - case TIFFTAG_LERC_ADD_COMPRESSION: - { - int params[2] = {0, 0}; - int additional_compression = va_arg(ap, int); -#ifndef ZSTD_SUPPORT - if (additional_compression == LERC_ADD_COMPRESSION_ZSTD) - { - TIFFErrorExtR(tif, module, - "LERC_ZSTD requested, but ZSTD not available"); - return 0; - } -#endif - if (additional_compression != LERC_ADD_COMPRESSION_NONE && - additional_compression != LERC_ADD_COMPRESSION_DEFLATE && - additional_compression != LERC_ADD_COMPRESSION_ZSTD) - { - TIFFErrorExtR(tif, module, - "Invalid value for LercAdditionalCompression: %d", - additional_compression); - return 0; - } - sp->additional_compression = additional_compression; - params[0] = sp->lerc_version; - params[1] = sp->additional_compression; - return LERCVSetFieldBase(tif, TIFFTAG_LERC_PARAMETERS, 2, params); - } -#ifdef ZSTD_SUPPORT - case TIFFTAG_ZSTD_LEVEL: - { - sp->zstd_compress_level = (int)va_arg(ap, int); - if (sp->zstd_compress_level <= 0 || - sp->zstd_compress_level > ZSTD_maxCLevel()) - { - TIFFWarningExtR(tif, module, - "ZSTD_LEVEL should be between 1 and %d", - ZSTD_maxCLevel()); - } - return 1; - } -#endif - case TIFFTAG_ZIPQUALITY: - { - sp->zipquality = (int)va_arg(ap, int); - if (sp->zipquality < Z_DEFAULT_COMPRESSION || - sp->zipquality > LIBDEFLATE_MAX_COMPRESSION_LEVEL) - { - TIFFErrorExtR( - tif, module, - "Invalid ZipQuality value. Should be in [-1,%d] range", - LIBDEFLATE_MAX_COMPRESSION_LEVEL); - return 0; - } - -#if LIBDEFLATE_SUPPORT - if (sp->libdeflate_enc) - { - libdeflate_free_compressor(sp->libdeflate_enc); - sp->libdeflate_enc = NULL; - } -#endif - - return (1); - } - default: - return (*sp->vsetparent)(tif, tag, ap); - } - /*NOTREACHED*/ -} - -static int LERCVGetField(TIFF *tif, uint32_t tag, va_list ap) -{ - LERCState *sp = LState(tif); - - switch (tag) - { - case TIFFTAG_LERC_MAXZERROR: - *va_arg(ap, double *) = sp->maxzerror; - break; - case TIFFTAG_LERC_VERSION: - *va_arg(ap, int *) = sp->lerc_version; - break; - case TIFFTAG_LERC_ADD_COMPRESSION: - *va_arg(ap, int *) = sp->additional_compression; - break; - case TIFFTAG_ZSTD_LEVEL: - *va_arg(ap, int *) = sp->zstd_compress_level; - break; - case TIFFTAG_ZIPQUALITY: - *va_arg(ap, int *) = sp->zipquality; - break; - default: - return (*sp->vgetparent)(tif, tag, ap); - } - return 1; -} - -int TIFFInitLERC(TIFF *tif, int scheme) -{ - static const char module[] = "TIFFInitLERC"; - LERCState *sp; - - (void)scheme; - assert(scheme == COMPRESSION_LERC); - - /* - * Merge codec-specific tag information. - */ - if (!_TIFFMergeFields(tif, LERCFields, TIFFArrayCount(LERCFields))) - { - TIFFErrorExtR(tif, module, "Merging LERC codec-specific tags failed"); - return 0; - } - - /* - * Allocate state block so tag methods have storage to record values. - */ - tif->tif_data = (uint8_t *)_TIFFcallocExt(tif, 1, sizeof(LERCState)); - if (tif->tif_data == NULL) - goto bad; - sp = LState(tif); - - /* - * Override parent get/set field methods. - */ - sp->vgetparent = tif->tif_tagmethods.vgetfield; - tif->tif_tagmethods.vgetfield = LERCVGetField; /* hook for codec tags */ - sp->vsetparent = tif->tif_tagmethods.vsetfield; - tif->tif_tagmethods.vsetfield = LERCVSetField; /* hook for codec tags */ - - /* - * Install codec methods. - */ - tif->tif_fixuptags = LERCFixupTags; - tif->tif_setupdecode = LERCSetupDecode; - tif->tif_predecode = LERCPreDecode; - tif->tif_decoderow = LERCDecode; - tif->tif_decodestrip = LERCDecode; - tif->tif_decodetile = LERCDecode; - tif->tif_setupencode = LERCSetupEncode; - tif->tif_preencode = LERCPreEncode; - tif->tif_postencode = LERCPostEncode; - tif->tif_encoderow = LERCEncode; - tif->tif_encodestrip = LERCEncode; - tif->tif_encodetile = LERCEncode; - tif->tif_cleanup = LERCCleanup; - - /* Default values for codec-specific fields */ - TIFFSetField(tif, TIFFTAG_LERC_VERSION, LERC_VERSION_2_4); - TIFFSetField(tif, TIFFTAG_LERC_ADD_COMPRESSION, LERC_ADD_COMPRESSION_NONE); - sp->maxzerror = 0.0; - sp->zstd_compress_level = 9; /* default comp. level */ - sp->zipquality = Z_DEFAULT_COMPRESSION; /* default comp. level */ - sp->state = 0; - - return 1; -bad: - TIFFErrorExtR(tif, module, "No space for LERC state block"); - return 0; -} -#endif /* LERC_SUPPORT */ diff --git a/src/3rd/tiff/luv.c b/src/3rd/tiff/luv.c deleted file mode 100644 index 021756d5d6d..00000000000 --- a/src/3rd/tiff/luv.c +++ /dev/null @@ -1,1838 +0,0 @@ -/* - * Copyright (c) 1997 Greg Ward Larson - * Copyright (c) 1997 Silicon Graphics, Inc. - * - * Permission to use, copy, modify, distribute, and sell this software and - * its documentation for any purpose is hereby granted without fee, provided - * that (i) the above copyright notices and this permission notice appear in - * all copies of the software and related documentation, and (ii) the names of - * Sam Leffler, Greg Larson and Silicon Graphics may not be used in any - * advertising or publicity relating to the software without the specific, - * prior written permission of Sam Leffler, Greg Larson and Silicon Graphics. - * - * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, - * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY - * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. - * - * IN NO EVENT SHALL SAM LEFFLER, GREG LARSON OR SILICON GRAPHICS BE LIABLE - * FOR ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, - * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, - * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF - * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE - * OF THIS SOFTWARE. - */ - -#include "tiffiop.h" -#ifdef LOGLUV_SUPPORT - -/* - * TIFF Library. - * LogLuv compression support for high dynamic range images. - * - * Contributed by Greg Larson. - * - * LogLuv image support uses the TIFF library to store 16 or 10-bit - * log luminance values with 8 bits each of u and v or a 14-bit index. - * - * The codec can take as input and produce as output 32-bit IEEE float values - * as well as 16-bit integer values. A 16-bit luminance is interpreted - * as a sign bit followed by a 15-bit integer that is converted - * to and from a linear magnitude using the transformation: - * - * L = 2^( (Le+.5)/256 - 64 ) # real from 15-bit - * - * Le = floor( 256*(log2(L) + 64) ) # 15-bit from real - * - * The actual conversion to world luminance units in candelas per sq. meter - * requires an additional multiplier, which is stored in the TIFFTAG_STONITS. - * This value is usually set such that a reasonable exposure comes from - * clamping decoded luminances above 1 to 1 in the displayed image. - * - * The 16-bit values for u and v may be converted to real values by dividing - * each by 32768. (This allows for negative values, which aren't useful as - * far as we know, but are left in case of future improvements in human - * color vision.) - * - * Conversion from (u,v), which is actually the CIE (u',v') system for - * you color scientists, is accomplished by the following transformation: - * - * u = 4*x / (-2*x + 12*y + 3) - * v = 9*y / (-2*x + 12*y + 3) - * - * x = 9*u / (6*u - 16*v + 12) - * y = 4*v / (6*u - 16*v + 12) - * - * This process is greatly simplified by passing 32-bit IEEE floats - * for each of three CIE XYZ coordinates. The codec then takes care - * of conversion to and from LogLuv, though the application is still - * responsible for interpreting the TIFFTAG_STONITS calibration factor. - * - * By definition, a CIE XYZ vector of [1 1 1] corresponds to a neutral white - * point of (x,y)=(1/3,1/3). However, most color systems assume some other - * white point, such as D65, and an absolute color conversion to XYZ then - * to another color space with a different white point may introduce an - * unwanted color cast to the image. It is often desirable, therefore, to - * perform a white point conversion that maps the input white to [1 1 1] - * in XYZ, then record the original white point using the TIFFTAG_WHITEPOINT - * tag value. A decoder that demands absolute color calibration may use - * this white point tag to get back the original colors, but usually it - * will be ignored and the new white point will be used instead that - * matches the output color space. - * - * Pixel information is compressed into one of two basic encodings, depending - * on the setting of the compression tag, which is one of COMPRESSION_SGILOG - * or COMPRESSION_SGILOG24. For COMPRESSION_SGILOG, greyscale data is - * stored as: - * - * 1 15 - * |-+---------------| - * - * COMPRESSION_SGILOG color data is stored as: - * - * 1 15 8 8 - * |-+---------------|--------+--------| - * S Le ue ve - * - * For the 24-bit COMPRESSION_SGILOG24 color format, the data is stored as: - * - * 10 14 - * |----------|--------------| - * Le' Ce - * - * There is no sign bit in the 24-bit case, and the (u,v) chromaticity is - * encoded as an index for optimal color resolution. The 10 log bits are - * defined by the following conversions: - * - * L = 2^((Le'+.5)/64 - 12) # real from 10-bit - * - * Le' = floor( 64*(log2(L) + 12) ) # 10-bit from real - * - * The 10 bits of the smaller format may be converted into the 15 bits of - * the larger format by multiplying by 4 and adding 13314. Obviously, - * a smaller range of magnitudes is covered (about 5 orders of magnitude - * instead of 38), and the lack of a sign bit means that negative luminances - * are not allowed. (Well, they aren't allowed in the real world, either, - * but they are useful for certain types of image processing.) - * - * The desired user format is controlled by the setting the internal - * pseudo tag TIFFTAG_SGILOGDATAFMT to one of: - * SGILOGDATAFMT_FLOAT = IEEE 32-bit float XYZ values - * SGILOGDATAFMT_16BIT = 16-bit integer encodings of logL, u and v - * Raw data i/o is also possible using: - * SGILOGDATAFMT_RAW = 32-bit unsigned integer with encoded pixel - * In addition, the following decoding is provided for ease of display: - * SGILOGDATAFMT_8BIT = 8-bit default RGB gamma-corrected values - * - * For grayscale images, we provide the following data formats: - * SGILOGDATAFMT_FLOAT = IEEE 32-bit float Y values - * SGILOGDATAFMT_16BIT = 16-bit integer w/ encoded luminance - * SGILOGDATAFMT_8BIT = 8-bit gray monitor values - * - * Note that the COMPRESSION_SGILOG applies a simple run-length encoding - * scheme by separating the logL, u and v bytes for each row and applying - * a PackBits type of compression. Since the 24-bit encoding is not - * adaptive, the 32-bit color format takes less space in many cases. - * - * Further control is provided over the conversion from higher-resolution - * formats to final encoded values through the pseudo tag - * TIFFTAG_SGILOGENCODE: - * SGILOGENCODE_NODITHER = do not dither encoded values - * SGILOGENCODE_RANDITHER = apply random dithering during encoding - * - * The default value of this tag is SGILOGENCODE_NODITHER for - * COMPRESSION_SGILOG to maximize run-length encoding and - * SGILOGENCODE_RANDITHER for COMPRESSION_SGILOG24 to turn - * quantization errors into noise. - */ - -#include -#include -#include - -/* - * State block for each open TIFF - * file using LogLuv compression/decompression. - */ -typedef struct logLuvState LogLuvState; - -struct logLuvState -{ - int encoder_state; /* 1 if encoder correctly initialized */ - int user_datafmt; /* user data format */ - int encode_meth; /* encoding method */ - int pixel_size; /* bytes per pixel */ - - uint8_t *tbuf; /* translation buffer */ - tmsize_t tbuflen; /* buffer length */ - void (*tfunc)(LogLuvState *, uint8_t *, tmsize_t); - - TIFFVSetMethod vgetparent; /* super-class method */ - TIFFVSetMethod vsetparent; /* super-class method */ -}; - -#define DecoderState(tif) ((LogLuvState *)(tif)->tif_data) -#define EncoderState(tif) ((LogLuvState *)(tif)->tif_data) - -#define SGILOGDATAFMT_UNKNOWN -1 - -#define MINRUN 4 /* minimum run length */ - -/* - * Decode a string of 16-bit gray pixels. - */ -static int LogL16Decode(TIFF *tif, uint8_t *op, tmsize_t occ, uint16_t s) -{ - static const char module[] = "LogL16Decode"; - LogLuvState *sp = DecoderState(tif); - int shft; - tmsize_t i; - tmsize_t npixels; - unsigned char *bp; - int16_t *tp; - int16_t b; - tmsize_t cc; - int rc; - - (void)s; - assert(s == 0); - assert(sp != NULL); - - npixels = occ / sp->pixel_size; - - if (sp->user_datafmt == SGILOGDATAFMT_16BIT) - tp = (int16_t *)op; - else - { - if (sp->tbuflen < npixels) - { - TIFFErrorExtR(tif, module, "Translation buffer too short"); - return (0); - } - tp = (int16_t *)sp->tbuf; - } - _TIFFmemset((void *)tp, 0, npixels * sizeof(tp[0])); - - bp = (unsigned char *)tif->tif_rawcp; - cc = tif->tif_rawcc; - /* get each byte string */ - for (shft = 8; shft >= 0; shft -= 8) - { - for (i = 0; i < npixels && cc > 0;) - { - if (*bp >= 128) - { /* run */ - if (cc < 2) - break; - rc = *bp++ + (2 - 128); - b = (int16_t)(*bp++ << shft); - cc -= 2; - while (rc-- && i < npixels) - tp[i++] |= b; - } - else - { /* non-run */ - rc = *bp++; /* nul is noop */ - while (--cc && rc-- && i < npixels) - tp[i++] |= (int16_t)*bp++ << shft; - } - } - if (i != npixels) - { - TIFFErrorExtR(tif, module, - "Not enough data at row %" PRIu32 - " (short %" TIFF_SSIZE_FORMAT " pixels)", - tif->tif_row, npixels - i); - tif->tif_rawcp = (uint8_t *)bp; - tif->tif_rawcc = cc; - return (0); - } - } - (*sp->tfunc)(sp, op, npixels); - tif->tif_rawcp = (uint8_t *)bp; - tif->tif_rawcc = cc; - return (1); -} - -/* - * Decode a string of 24-bit pixels. - */ -static int LogLuvDecode24(TIFF *tif, uint8_t *op, tmsize_t occ, uint16_t s) -{ - static const char module[] = "LogLuvDecode24"; - LogLuvState *sp = DecoderState(tif); - tmsize_t cc; - tmsize_t i; - tmsize_t npixels; - unsigned char *bp; - uint32_t *tp; - - (void)s; - assert(s == 0); - assert(sp != NULL); - - npixels = occ / sp->pixel_size; - - if (sp->user_datafmt == SGILOGDATAFMT_RAW) - tp = (uint32_t *)op; - else - { - if (sp->tbuflen < npixels) - { - TIFFErrorExtR(tif, module, "Translation buffer too short"); - return (0); - } - tp = (uint32_t *)sp->tbuf; - } - /* copy to array of uint32_t */ - bp = (unsigned char *)tif->tif_rawcp; - cc = tif->tif_rawcc; - for (i = 0; i < npixels && cc >= 3; i++) - { - tp[i] = bp[0] << 16 | bp[1] << 8 | bp[2]; - bp += 3; - cc -= 3; - } - tif->tif_rawcp = (uint8_t *)bp; - tif->tif_rawcc = cc; - if (i != npixels) - { - TIFFErrorExtR(tif, module, - "Not enough data at row %" PRIu32 - " (short %" TIFF_SSIZE_FORMAT " pixels)", - tif->tif_row, npixels - i); - return (0); - } - (*sp->tfunc)(sp, op, npixels); - return (1); -} - -/* - * Decode a string of 32-bit pixels. - */ -static int LogLuvDecode32(TIFF *tif, uint8_t *op, tmsize_t occ, uint16_t s) -{ - static const char module[] = "LogLuvDecode32"; - LogLuvState *sp; - int shft; - tmsize_t i; - tmsize_t npixels; - unsigned char *bp; - uint32_t *tp; - uint32_t b; - tmsize_t cc; - int rc; - - (void)s; - assert(s == 0); - sp = DecoderState(tif); - assert(sp != NULL); - - npixels = occ / sp->pixel_size; - - if (sp->user_datafmt == SGILOGDATAFMT_RAW) - tp = (uint32_t *)op; - else - { - if (sp->tbuflen < npixels) - { - TIFFErrorExtR(tif, module, "Translation buffer too short"); - return (0); - } - tp = (uint32_t *)sp->tbuf; - } - _TIFFmemset((void *)tp, 0, npixels * sizeof(tp[0])); - - bp = (unsigned char *)tif->tif_rawcp; - cc = tif->tif_rawcc; - /* get each byte string */ - for (shft = 24; shft >= 0; shft -= 8) - { - for (i = 0; i < npixels && cc > 0;) - { - if (*bp >= 128) - { /* run */ - if (cc < 2) - break; - rc = *bp++ + (2 - 128); - b = (uint32_t)*bp++ << shft; - cc -= 2; - while (rc-- && i < npixels) - tp[i++] |= b; - } - else - { /* non-run */ - rc = *bp++; /* nul is noop */ - while (--cc && rc-- && i < npixels) - tp[i++] |= (uint32_t)*bp++ << shft; - } - } - if (i != npixels) - { - TIFFErrorExtR(tif, module, - "Not enough data at row %" PRIu32 - " (short %" TIFF_SSIZE_FORMAT " pixels)", - tif->tif_row, npixels - i); - tif->tif_rawcp = (uint8_t *)bp; - tif->tif_rawcc = cc; - return (0); - } - } - (*sp->tfunc)(sp, op, npixels); - tif->tif_rawcp = (uint8_t *)bp; - tif->tif_rawcc = cc; - return (1); -} - -/* - * Decode a strip of pixels. We break it into rows to - * maintain synchrony with the encode algorithm, which - * is row by row. - */ -static int LogLuvDecodeStrip(TIFF *tif, uint8_t *bp, tmsize_t cc, uint16_t s) -{ - tmsize_t rowlen = TIFFScanlineSize(tif); - - if (rowlen == 0) - return 0; - - assert(cc % rowlen == 0); - while (cc && (*tif->tif_decoderow)(tif, bp, rowlen, s)) - { - bp += rowlen; - cc -= rowlen; - } - return (cc == 0); -} - -/* - * Decode a tile of pixels. We break it into rows to - * maintain synchrony with the encode algorithm, which - * is row by row. - */ -static int LogLuvDecodeTile(TIFF *tif, uint8_t *bp, tmsize_t cc, uint16_t s) -{ - tmsize_t rowlen = TIFFTileRowSize(tif); - - if (rowlen == 0) - return 0; - - assert(cc % rowlen == 0); - while (cc && (*tif->tif_decoderow)(tif, bp, rowlen, s)) - { - bp += rowlen; - cc -= rowlen; - } - return (cc == 0); -} - -/* - * Encode a row of 16-bit pixels. - */ -static int LogL16Encode(TIFF *tif, uint8_t *bp, tmsize_t cc, uint16_t s) -{ - static const char module[] = "LogL16Encode"; - LogLuvState *sp = EncoderState(tif); - int shft; - tmsize_t i; - tmsize_t j; - tmsize_t npixels; - uint8_t *op; - int16_t *tp; - int16_t b; - tmsize_t occ; - int rc = 0, mask; - tmsize_t beg; - - (void)s; - assert(s == 0); - assert(sp != NULL); - npixels = cc / sp->pixel_size; - - if (sp->user_datafmt == SGILOGDATAFMT_16BIT) - tp = (int16_t *)bp; - else - { - tp = (int16_t *)sp->tbuf; - if (sp->tbuflen < npixels) - { - TIFFErrorExtR(tif, module, "Translation buffer too short"); - return (0); - } - (*sp->tfunc)(sp, bp, npixels); - } - /* compress each byte string */ - op = tif->tif_rawcp; - occ = tif->tif_rawdatasize - tif->tif_rawcc; - for (shft = 8; shft >= 0; shft -= 8) - { - for (i = 0; i < npixels; i += rc) - { - if (occ < 4) - { - tif->tif_rawcp = op; - tif->tif_rawcc = tif->tif_rawdatasize - occ; - if (!TIFFFlushData1(tif)) - return (0); - op = tif->tif_rawcp; - occ = tif->tif_rawdatasize - tif->tif_rawcc; - } - mask = 0xff << shft; /* find next run */ - for (beg = i; beg < npixels; beg += rc) - { - b = (int16_t)(tp[beg] & mask); - rc = 1; - while (rc < 127 + 2 && beg + rc < npixels && - (tp[beg + rc] & mask) == b) - rc++; - if (rc >= MINRUN) - break; /* long enough */ - } - if (beg - i > 1 && beg - i < MINRUN) - { - b = (int16_t)(tp[i] & mask); /*check short run */ - j = i + 1; - while ((tp[j++] & mask) == b) - if (j == beg) - { - *op++ = (uint8_t)(128 - 2 + j - i); - *op++ = (uint8_t)(b >> shft); - occ -= 2; - i = beg; - break; - } - } - while (i < beg) - { /* write out non-run */ - if ((j = beg - i) > 127) - j = 127; - if (occ < j + 3) - { - tif->tif_rawcp = op; - tif->tif_rawcc = tif->tif_rawdatasize - occ; - if (!TIFFFlushData1(tif)) - return (0); - op = tif->tif_rawcp; - occ = tif->tif_rawdatasize - tif->tif_rawcc; - } - *op++ = (uint8_t)j; - occ--; - while (j--) - { - *op++ = (uint8_t)(tp[i++] >> shft & 0xff); - occ--; - } - } - if (rc >= MINRUN) - { /* write out run */ - *op++ = (uint8_t)(128 - 2 + rc); - *op++ = (uint8_t)(tp[beg] >> shft & 0xff); - occ -= 2; - } - else - rc = 0; - } - } - tif->tif_rawcp = op; - tif->tif_rawcc = tif->tif_rawdatasize - occ; - - return (1); -} - -/* - * Encode a row of 24-bit pixels. - */ -static int LogLuvEncode24(TIFF *tif, uint8_t *bp, tmsize_t cc, uint16_t s) -{ - static const char module[] = "LogLuvEncode24"; - LogLuvState *sp = EncoderState(tif); - tmsize_t i; - tmsize_t npixels; - tmsize_t occ; - uint8_t *op; - uint32_t *tp; - - (void)s; - assert(s == 0); - assert(sp != NULL); - npixels = cc / sp->pixel_size; - - if (sp->user_datafmt == SGILOGDATAFMT_RAW) - tp = (uint32_t *)bp; - else - { - tp = (uint32_t *)sp->tbuf; - if (sp->tbuflen < npixels) - { - TIFFErrorExtR(tif, module, "Translation buffer too short"); - return (0); - } - (*sp->tfunc)(sp, bp, npixels); - } - /* write out encoded pixels */ - op = tif->tif_rawcp; - occ = tif->tif_rawdatasize - tif->tif_rawcc; - for (i = npixels; i--;) - { - if (occ < 3) - { - tif->tif_rawcp = op; - tif->tif_rawcc = tif->tif_rawdatasize - occ; - if (!TIFFFlushData1(tif)) - return (0); - op = tif->tif_rawcp; - occ = tif->tif_rawdatasize - tif->tif_rawcc; - } - *op++ = (uint8_t)(*tp >> 16); - *op++ = (uint8_t)(*tp >> 8 & 0xff); - *op++ = (uint8_t)(*tp++ & 0xff); - occ -= 3; - } - tif->tif_rawcp = op; - tif->tif_rawcc = tif->tif_rawdatasize - occ; - - return (1); -} - -/* - * Encode a row of 32-bit pixels. - */ -static int LogLuvEncode32(TIFF *tif, uint8_t *bp, tmsize_t cc, uint16_t s) -{ - static const char module[] = "LogLuvEncode32"; - LogLuvState *sp = EncoderState(tif); - int shft; - tmsize_t i; - tmsize_t j; - tmsize_t npixels; - uint8_t *op; - uint32_t *tp; - uint32_t b; - tmsize_t occ; - int rc = 0; - tmsize_t beg; - - (void)s; - assert(s == 0); - assert(sp != NULL); - - npixels = cc / sp->pixel_size; - - if (sp->user_datafmt == SGILOGDATAFMT_RAW) - tp = (uint32_t *)bp; - else - { - tp = (uint32_t *)sp->tbuf; - if (sp->tbuflen < npixels) - { - TIFFErrorExtR(tif, module, "Translation buffer too short"); - return (0); - } - (*sp->tfunc)(sp, bp, npixels); - } - /* compress each byte string */ - op = tif->tif_rawcp; - occ = tif->tif_rawdatasize - tif->tif_rawcc; - for (shft = 24; shft >= 0; shft -= 8) - { - const uint32_t mask = 0xffU << shft; /* find next run */ - for (i = 0; i < npixels; i += rc) - { - if (occ < 4) - { - tif->tif_rawcp = op; - tif->tif_rawcc = tif->tif_rawdatasize - occ; - if (!TIFFFlushData1(tif)) - return (0); - op = tif->tif_rawcp; - occ = tif->tif_rawdatasize - tif->tif_rawcc; - } - for (beg = i; beg < npixels; beg += rc) - { - b = tp[beg] & mask; - rc = 1; - while (rc < 127 + 2 && beg + rc < npixels && - (tp[beg + rc] & mask) == b) - rc++; - if (rc >= MINRUN) - break; /* long enough */ - } - if (beg - i > 1 && beg - i < MINRUN) - { - b = tp[i] & mask; /* check short run */ - j = i + 1; - while ((tp[j++] & mask) == b) - if (j == beg) - { - *op++ = (uint8_t)(128 - 2 + j - i); - *op++ = (uint8_t)(b >> shft); - occ -= 2; - i = beg; - break; - } - } - while (i < beg) - { /* write out non-run */ - if ((j = beg - i) > 127) - j = 127; - if (occ < j + 3) - { - tif->tif_rawcp = op; - tif->tif_rawcc = tif->tif_rawdatasize - occ; - if (!TIFFFlushData1(tif)) - return (0); - op = tif->tif_rawcp; - occ = tif->tif_rawdatasize - tif->tif_rawcc; - } - *op++ = (uint8_t)j; - occ--; - while (j--) - { - *op++ = (uint8_t)(tp[i++] >> shft & 0xff); - occ--; - } - } - if (rc >= MINRUN) - { /* write out run */ - *op++ = (uint8_t)(128 - 2 + rc); - *op++ = (uint8_t)(tp[beg] >> shft & 0xff); - occ -= 2; - } - else - rc = 0; - } - } - tif->tif_rawcp = op; - tif->tif_rawcc = tif->tif_rawdatasize - occ; - - return (1); -} - -/* - * Encode a strip of pixels. We break it into rows to - * avoid encoding runs across row boundaries. - */ -static int LogLuvEncodeStrip(TIFF *tif, uint8_t *bp, tmsize_t cc, uint16_t s) -{ - tmsize_t rowlen = TIFFScanlineSize(tif); - - if (rowlen == 0) - return 0; - - assert(cc % rowlen == 0); - while (cc && (*tif->tif_encoderow)(tif, bp, rowlen, s) == 1) - { - bp += rowlen; - cc -= rowlen; - } - return (cc == 0); -} - -/* - * Encode a tile of pixels. We break it into rows to - * avoid encoding runs across row boundaries. - */ -static int LogLuvEncodeTile(TIFF *tif, uint8_t *bp, tmsize_t cc, uint16_t s) -{ - tmsize_t rowlen = TIFFTileRowSize(tif); - - if (rowlen == 0) - return 0; - - assert(cc % rowlen == 0); - while (cc && (*tif->tif_encoderow)(tif, bp, rowlen, s) == 1) - { - bp += rowlen; - cc -= rowlen; - } - return (cc == 0); -} - -/* - * Encode/Decode functions for converting to and from user formats. - */ - -#include "uvcode.h" - -#ifndef UVSCALE -#define U_NEU 0.210526316 -#define V_NEU 0.473684211 -#define UVSCALE 410. -#endif - -#ifndef M_LN2 -#define M_LN2 0.69314718055994530942 -#endif -#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)) - -static int tiff_itrunc(double x, int m) -{ - if (m == SGILOGENCODE_NODITHER) - return (int)x; - /* Silence CoverityScan warning about bad crypto function */ - /* coverity[dont_call] */ - return (int)(x + rand() * (1. / RAND_MAX) - .5); -} - -#if !LOGLUV_PUBLIC -static -#endif - double - LogL16toY(int p16) /* compute luminance from 16-bit LogL */ -{ - int Le = p16 & 0x7fff; - double Y; - - if (!Le) - return (0.); - Y = exp(M_LN2 / 256. * (Le + .5) - M_LN2 * 64.); - return (!(p16 & 0x8000) ? Y : -Y); -} - -#if !LOGLUV_PUBLIC -static -#endif - int - LogL16fromY(double Y, int em) /* get 16-bit LogL from Y */ -{ - if (Y >= 1.8371976e19) - return (0x7fff); - if (Y <= -1.8371976e19) - return (0xffff); - if (Y > 5.4136769e-20) - return tiff_itrunc(256. * (log2(Y) + 64.), em); - if (Y < -5.4136769e-20) - return (~0x7fff | tiff_itrunc(256. * (log2(-Y) + 64.), em)); - return (0); -} - -static void L16toY(LogLuvState *sp, uint8_t *op, tmsize_t n) -{ - int16_t *l16 = (int16_t *)sp->tbuf; - float *yp = (float *)op; - - while (n-- > 0) - *yp++ = (float)LogL16toY(*l16++); -} - -static void L16toGry(LogLuvState *sp, uint8_t *op, tmsize_t n) -{ - int16_t *l16 = (int16_t *)sp->tbuf; - uint8_t *gp = (uint8_t *)op; - - while (n-- > 0) - { - double Y = LogL16toY(*l16++); - *gp++ = (uint8_t)((Y <= 0.) ? 0 - : (Y >= 1.) ? 255 - : (int)(256. * sqrt(Y))); - } -} - -static void L16fromY(LogLuvState *sp, uint8_t *op, tmsize_t n) -{ - int16_t *l16 = (int16_t *)sp->tbuf; - float *yp = (float *)op; - - while (n-- > 0) - *l16++ = (int16_t)(LogL16fromY(*yp++, sp->encode_meth)); -} - -#if !LOGLUV_PUBLIC -static -#endif - 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]; - /* 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))); - rgb[1] = (uint8_t)((g <= 0.) ? 0 : (g >= 1.) ? 255 : (int)(256. * sqrt(g))); - rgb[2] = (uint8_t)((b <= 0.) ? 0 : (b >= 1.) ? 255 : (int)(256. * sqrt(b))); -} - -#if !LOGLUV_PUBLIC -static -#endif - double - LogL10toY(int p10) /* compute luminance from 10-bit LogL */ -{ - if (p10 == 0) - return (0.); - return (exp(M_LN2 / 64. * (p10 + .5) - M_LN2 * 12.)); -} - -#if !LOGLUV_PUBLIC -static -#endif - int - LogL10fromY(double Y, int em) /* get 10-bit LogL from Y */ -{ - if (Y >= 15.742) - return (0x3ff); - else if (Y <= .00024283) - return (0); - else - return tiff_itrunc(64. * (log2(Y) + 12.), em); -} - -#define NANGLES 100 -#define uv2ang(u, v) \ - ((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; - - if (!initialized) - { /* set up perimeter table */ - double eps[NANGLES], ua, va, ang, epsa; - int ui, vi, ustep; - for (i = NANGLES; i--;) - eps[i] = 2.; - for (vi = UV_NVS; vi--;) - { - va = UV_VSTART + (vi + .5) * 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; - ang = uv2ang(ua, va); - i = (int)ang; - epsa = fabs(ang - (i + .5)); - if (epsa < eps[i]) - { - oog_table[i] = uv_row[vi].ncum + ui; - eps[i] = epsa; - } - } - } - for (i = NANGLES; i--;) /* fill any holes */ - if (eps[i] > 1.5) - { - int i1, i2; - for (i1 = 1; i1 < NANGLES / 2; i1++) - if (eps[(i + i1) % NANGLES] < 1.5) - break; - for (i2 = 1; i2 < NANGLES / 2; i2++) - if (eps[(i + NANGLES - i2) % NANGLES] < 1.5) - break; - if (i1 < i2) - oog_table[i] = oog_table[(i + i1) % NANGLES]; - else - oog_table[i] = oog_table[(i + NANGLES - i2) % NANGLES]; - } - initialized = 1; - } - i = (int)uv2ang(u, v); /* look up hue angle */ - return (oog_table[i]); -} - -#undef uv2ang -#undef NANGLES - -#if !LOGLUV_PUBLIC -static -#endif - int - uv_encode(double u, double v, int em) /* encode (u',v') coordinates */ -{ - register int vi, ui; - - /* check for NaN */ - if (u != u || v != v) - { - u = U_NEU; - v = V_NEU; - } - - if (v < UV_VSTART) - return oog_encode(u, v); - vi = tiff_itrunc((v - UV_VSTART) * (1. / UV_SQSIZ), em); - if (vi >= UV_NVS) - return oog_encode(u, v); - if (u < uv_row[vi].ustart) - return oog_encode(u, v); - ui = tiff_itrunc((u - uv_row[vi].ustart) * (1. / UV_SQSIZ), em); - if (ui >= uv_row[vi].nus) - return oog_encode(u, v); - - return (uv_row[vi].ncum + ui); -} - -#if !LOGLUV_PUBLIC -static -#endif - int - uv_decode(double *up, double *vp, int c) /* decode (u',v') index */ -{ - int upper, lower; - register int ui, vi; - - if (c < 0 || c >= UV_NDIVS) - return (-1); - lower = 0; /* binary search */ - upper = UV_NVS; - while (upper - lower > 1) - { - vi = (lower + upper) >> 1; - ui = c - uv_row[vi].ncum; - if (ui > 0) - lower = vi; - else if (ui < 0) - upper = vi; - else - { - lower = vi; - break; - } - } - vi = lower; - ui = c - uv_row[vi].ncum; - *up = uv_row[vi].ustart + (ui + .5) * UV_SQSIZ; - *vp = UV_VSTART + (vi + .5) * UV_SQSIZ; - return (0); -} - -#if !LOGLUV_PUBLIC -static -#endif - void - LogLuv24toXYZ(uint32_t p, float *XYZ) -{ - int Ce; - double L, u, v, s, x, y; - /* decode luminance */ - L = LogL10toY(p >> 14 & 0x3ff); - if (L <= 0.) - { - XYZ[0] = XYZ[1] = XYZ[2] = 0.; - return; - } - /* decode color */ - Ce = p & 0x3fff; - if (uv_decode(&u, &v, Ce) < 0) - { - u = U_NEU; - v = V_NEU; - } - s = 1. / (6. * u - 16. * v + 12.); - x = 9. * u * s; - y = 4. * v * s; - /* convert to XYZ */ - XYZ[0] = (float)(x / y * L); - XYZ[1] = (float)L; - XYZ[2] = (float)((1. - x - y) / y * L); -} - -#if !LOGLUV_PUBLIC -static -#endif - uint32_t - LogLuv24fromXYZ(float *XYZ, int em) -{ - int Le, Ce; - double u, v, s; - /* encode luminance */ - Le = LogL10fromY(XYZ[1], em); - /* encode color */ - s = XYZ[0] + 15. * XYZ[1] + 3. * XYZ[2]; - if (!Le || s <= 0.) - { - u = U_NEU; - v = V_NEU; - } - else - { - u = 4. * XYZ[0] / s; - v = 9. * 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); -} - -static void Luv24toXYZ(LogLuvState *sp, uint8_t *op, tmsize_t n) -{ - uint32_t *luv = (uint32_t *)sp->tbuf; - float *xyz = (float *)op; - - while (n-- > 0) - { - LogLuv24toXYZ(*luv, xyz); - xyz += 3; - luv++; - } -} - -static void Luv24toLuv48(LogLuvState *sp, uint8_t *op, tmsize_t n) -{ - uint32_t *luv = (uint32_t *)sp->tbuf; - int16_t *luv3 = (int16_t *)op; - - while (n-- > 0) - { - double u, v; - - *luv3++ = (int16_t)((*luv >> 12 & 0xffd) + 13314); - if (uv_decode(&u, &v, *luv & 0x3fff) < 0) - { - u = U_NEU; - v = V_NEU; - } - *luv3++ = (int16_t)(u * (1L << 15)); - *luv3++ = (int16_t)(v * (1L << 15)); - luv++; - } -} - -static void Luv24toRGB(LogLuvState *sp, uint8_t *op, tmsize_t n) -{ - uint32_t *luv = (uint32_t *)sp->tbuf; - uint8_t *rgb = (uint8_t *)op; - - while (n-- > 0) - { - float xyz[3]; - - LogLuv24toXYZ(*luv++, xyz); - XYZtoRGB24(xyz, rgb); - rgb += 3; - } -} - -static void Luv24fromXYZ(LogLuvState *sp, uint8_t *op, tmsize_t n) -{ - uint32_t *luv = (uint32_t *)sp->tbuf; - float *xyz = (float *)op; - - while (n-- > 0) - { - *luv++ = LogLuv24fromXYZ(xyz, sp->encode_meth); - xyz += 3; - } -} - -static void Luv24fromLuv48(LogLuvState *sp, uint8_t *op, tmsize_t n) -{ - uint32_t *luv = (uint32_t *)sp->tbuf; - int16_t *luv3 = (int16_t *)op; - - while (n-- > 0) - { - int Le, Ce; - - if (luv3[0] <= 0) - Le = 0; - else if (luv3[0] >= (1 << 12) + 3314) - Le = (1 << 10) - 1; - else if (sp->encode_meth == SGILOGENCODE_NODITHER) - Le = (luv3[0] - 3314) >> 2; - else - Le = tiff_itrunc(.25 * (luv3[0] - 3314.), sp->encode_meth); - - Ce = uv_encode((luv3[1] + .5) / (1 << 15), (luv3[2] + .5) / (1 << 15), - sp->encode_meth); - if (Ce < 0) /* never happens */ - Ce = uv_encode(U_NEU, V_NEU, SGILOGENCODE_NODITHER); - *luv++ = (uint32_t)Le << 14 | Ce; - luv3 += 3; - } -} - -#if !LOGLUV_PUBLIC -static -#endif - void - LogLuv32toXYZ(uint32_t p, float *XYZ) -{ - double L, u, v, s, x, y; - /* decode luminance */ - L = LogL16toY((int)p >> 16); - if (L <= 0.) - { - XYZ[0] = XYZ[1] = XYZ[2] = 0.; - return; - } - /* decode color */ - u = 1. / UVSCALE * ((p >> 8 & 0xff) + .5); - v = 1. / UVSCALE * ((p & 0xff) + .5); - s = 1. / (6. * u - 16. * v + 12.); - x = 9. * u * s; - y = 4. * v * s; - /* convert to XYZ */ - XYZ[0] = (float)(x / y * L); - XYZ[1] = (float)L; - XYZ[2] = (float)((1. - x - y) / y * L); -} - -#if !LOGLUV_PUBLIC -static -#endif - 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); - /* encode color */ - s = XYZ[0] + 15. * XYZ[1] + 3. * XYZ[2]; - if (!Le || s <= 0.) - { - u = U_NEU; - v = V_NEU; - } - else - { - u = 4. * XYZ[0] / s; - v = 9. * XYZ[1] / s; - } - if (u <= 0.) - ue = 0; - else - ue = tiff_itrunc(UVSCALE * u, em); - if (ue > 255) - ue = 255; - if (v <= 0.) - ve = 0; - else - ve = tiff_itrunc(UVSCALE * v, em); - if (ve > 255) - ve = 255; - /* combine encodings */ - return (Le << 16 | ue << 8 | ve); -} - -static void Luv32toXYZ(LogLuvState *sp, uint8_t *op, tmsize_t n) -{ - uint32_t *luv = (uint32_t *)sp->tbuf; - float *xyz = (float *)op; - - while (n-- > 0) - { - LogLuv32toXYZ(*luv++, xyz); - xyz += 3; - } -} - -static void Luv32toLuv48(LogLuvState *sp, uint8_t *op, tmsize_t n) -{ - uint32_t *luv = (uint32_t *)sp->tbuf; - int16_t *luv3 = (int16_t *)op; - - while (n-- > 0) - { - double u, v; - - *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)); - luv++; - } -} - -static void Luv32toRGB(LogLuvState *sp, uint8_t *op, tmsize_t n) -{ - uint32_t *luv = (uint32_t *)sp->tbuf; - uint8_t *rgb = (uint8_t *)op; - - while (n-- > 0) - { - float xyz[3]; - - LogLuv32toXYZ(*luv++, xyz); - XYZtoRGB24(xyz, rgb); - rgb += 3; - } -} - -static void Luv32fromXYZ(LogLuvState *sp, uint8_t *op, tmsize_t n) -{ - uint32_t *luv = (uint32_t *)sp->tbuf; - float *xyz = (float *)op; - - while (n-- > 0) - { - *luv++ = LogLuv32fromXYZ(xyz, sp->encode_meth); - xyz += 3; - } -} - -static void Luv32fromLuv48(LogLuvState *sp, uint8_t *op, tmsize_t n) -{ - uint32_t *luv = (uint32_t *)sp->tbuf; - int16_t *luv3 = (int16_t *)op; - - if (sp->encode_meth == SGILOGENCODE_NODITHER) - { - 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); - 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); - luv3 += 3; - } -} - -static void _logLuvNop(LogLuvState *sp, uint8_t *op, tmsize_t n) -{ - (void)sp; - (void)op; - (void)n; -} - -static int LogL16GuessDataFmt(TIFFDirectory *td) -{ -#define PACK(s, b, f) (((b) << 6) | ((s) << 3) | (f)) - switch ( - PACK(td->td_samplesperpixel, td->td_bitspersample, td->td_sampleformat)) - { - case PACK(1, 32, SAMPLEFORMAT_IEEEFP): - return (SGILOGDATAFMT_FLOAT); - case PACK(1, 16, SAMPLEFORMAT_VOID): - case PACK(1, 16, SAMPLEFORMAT_INT): - case PACK(1, 16, SAMPLEFORMAT_UINT): - return (SGILOGDATAFMT_16BIT); - case PACK(1, 8, SAMPLEFORMAT_VOID): - case PACK(1, 8, SAMPLEFORMAT_UINT): - return (SGILOGDATAFMT_8BIT); - } -#undef PACK - return (SGILOGDATAFMT_UNKNOWN); -} - -static tmsize_t multiply_ms(tmsize_t m1, tmsize_t m2) -{ - return _TIFFMultiplySSize(NULL, m1, m2, NULL); -} - -static int LogL16InitState(TIFF *tif) -{ - static const char module[] = "LogL16InitState"; - TIFFDirectory *td = &tif->tif_dir; - LogLuvState *sp = DecoderState(tif); - - assert(sp != NULL); - assert(td->td_photometric == PHOTOMETRIC_LOGL); - - if (td->td_samplesperpixel != 1) - { - TIFFErrorExtR(tif, module, - "Sorry, can not handle LogL image with %s=%" PRIu16, - "Samples/pixel", td->td_samplesperpixel); - return 0; - } - - /* for some reason, we can't do this in TIFFInitLogL16 */ - if (sp->user_datafmt == SGILOGDATAFMT_UNKNOWN) - sp->user_datafmt = LogL16GuessDataFmt(td); - switch (sp->user_datafmt) - { - case SGILOGDATAFMT_FLOAT: - sp->pixel_size = sizeof(float); - break; - case SGILOGDATAFMT_16BIT: - sp->pixel_size = sizeof(int16_t); - break; - case SGILOGDATAFMT_8BIT: - sp->pixel_size = sizeof(uint8_t); - break; - default: - TIFFErrorExtR(tif, module, - "No support for converting user data format to LogL"); - return (0); - } - if (isTiled(tif)) - sp->tbuflen = multiply_ms(td->td_tilewidth, td->td_tilelength); - else if (td->td_rowsperstrip < td->td_imagelength) - sp->tbuflen = multiply_ms(td->td_imagewidth, td->td_rowsperstrip); - else - 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) - { - TIFFErrorExtR(tif, module, "No space for SGILog translation buffer"); - return (0); - } - return (1); -} - -static int LogLuvGuessDataFmt(TIFFDirectory *td) -{ - int guess; - - /* - * If the user didn't tell us their datafmt, - * take our best guess from the bitspersample. - */ -#define PACK(a, b) (((a) << 3) | (b)) - switch (PACK(td->td_bitspersample, td->td_sampleformat)) - { - case PACK(32, SAMPLEFORMAT_IEEEFP): - guess = SGILOGDATAFMT_FLOAT; - break; - case PACK(32, SAMPLEFORMAT_VOID): - case PACK(32, SAMPLEFORMAT_UINT): - case PACK(32, SAMPLEFORMAT_INT): - guess = SGILOGDATAFMT_RAW; - break; - case PACK(16, SAMPLEFORMAT_VOID): - case PACK(16, SAMPLEFORMAT_INT): - case PACK(16, SAMPLEFORMAT_UINT): - guess = SGILOGDATAFMT_16BIT; - break; - case PACK(8, SAMPLEFORMAT_VOID): - case PACK(8, SAMPLEFORMAT_UINT): - guess = SGILOGDATAFMT_8BIT; - break; - default: - guess = SGILOGDATAFMT_UNKNOWN; - break; -#undef PACK - } - /* - * Double-check samples per pixel. - */ - switch (td->td_samplesperpixel) - { - case 1: - if (guess != SGILOGDATAFMT_RAW) - guess = SGILOGDATAFMT_UNKNOWN; - break; - case 3: - if (guess == SGILOGDATAFMT_RAW) - guess = SGILOGDATAFMT_UNKNOWN; - break; - default: - guess = SGILOGDATAFMT_UNKNOWN; - break; - } - return (guess); -} - -static int LogLuvInitState(TIFF *tif) -{ - static const char module[] = "LogLuvInitState"; - TIFFDirectory *td = &tif->tif_dir; - LogLuvState *sp = DecoderState(tif); - - assert(sp != NULL); - assert(td->td_photometric == PHOTOMETRIC_LOGLUV); - - /* for some reason, we can't do this in TIFFInitLogLuv */ - if (td->td_planarconfig != PLANARCONFIG_CONTIG) - { - TIFFErrorExtR(tif, module, - "SGILog compression cannot handle non-contiguous data"); - return (0); - } - if (sp->user_datafmt == SGILOGDATAFMT_UNKNOWN) - sp->user_datafmt = LogLuvGuessDataFmt(td); - switch (sp->user_datafmt) - { - case SGILOGDATAFMT_FLOAT: - sp->pixel_size = 3 * sizeof(float); - break; - case SGILOGDATAFMT_16BIT: - sp->pixel_size = 3 * sizeof(int16_t); - break; - case SGILOGDATAFMT_RAW: - sp->pixel_size = sizeof(uint32_t); - break; - case SGILOGDATAFMT_8BIT: - sp->pixel_size = 3 * sizeof(uint8_t); - break; - default: - TIFFErrorExtR( - tif, module, - "No support for converting user data format to LogLuv"); - return (0); - } - if (isTiled(tif)) - sp->tbuflen = multiply_ms(td->td_tilewidth, td->td_tilelength); - else if (td->td_rowsperstrip < td->td_imagelength) - sp->tbuflen = multiply_ms(td->td_imagewidth, td->td_rowsperstrip); - else - 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) - { - TIFFErrorExtR(tif, module, "No space for SGILog translation buffer"); - return (0); - } - return (1); -} - -static int LogLuvFixupTags(TIFF *tif) -{ - (void)tif; - return (1); -} - -static int LogLuvSetupDecode(TIFF *tif) -{ - static const char module[] = "LogLuvSetupDecode"; - LogLuvState *sp = DecoderState(tif); - TIFFDirectory *td = &tif->tif_dir; - - tif->tif_postdecode = _TIFFNoPostDecode; - switch (td->td_photometric) - { - case PHOTOMETRIC_LOGLUV: - if (!LogLuvInitState(tif)) - break; - if (td->td_compression == COMPRESSION_SGILOG24) - { - tif->tif_decoderow = LogLuvDecode24; - switch (sp->user_datafmt) - { - case SGILOGDATAFMT_FLOAT: - sp->tfunc = Luv24toXYZ; - break; - case SGILOGDATAFMT_16BIT: - sp->tfunc = Luv24toLuv48; - break; - case SGILOGDATAFMT_8BIT: - sp->tfunc = Luv24toRGB; - break; - } - } - else - { - tif->tif_decoderow = LogLuvDecode32; - switch (sp->user_datafmt) - { - case SGILOGDATAFMT_FLOAT: - sp->tfunc = Luv32toXYZ; - break; - case SGILOGDATAFMT_16BIT: - sp->tfunc = Luv32toLuv48; - break; - case SGILOGDATAFMT_8BIT: - sp->tfunc = Luv32toRGB; - break; - } - } - return (1); - case PHOTOMETRIC_LOGL: - if (!LogL16InitState(tif)) - break; - tif->tif_decoderow = LogL16Decode; - switch (sp->user_datafmt) - { - case SGILOGDATAFMT_FLOAT: - sp->tfunc = L16toY; - break; - case SGILOGDATAFMT_8BIT: - sp->tfunc = L16toGry; - break; - } - return (1); - default: - TIFFErrorExtR(tif, module, - "Inappropriate photometric interpretation %" PRIu16 - " for SGILog compression; %s", - td->td_photometric, "must be either LogLUV or LogL"); - break; - } - return (0); -} - -static int LogLuvSetupEncode(TIFF *tif) -{ - static const char module[] = "LogLuvSetupEncode"; - LogLuvState *sp = EncoderState(tif); - TIFFDirectory *td = &tif->tif_dir; - - switch (td->td_photometric) - { - case PHOTOMETRIC_LOGLUV: - if (!LogLuvInitState(tif)) - return (0); - if (td->td_compression == COMPRESSION_SGILOG24) - { - tif->tif_encoderow = LogLuvEncode24; - switch (sp->user_datafmt) - { - case SGILOGDATAFMT_FLOAT: - sp->tfunc = Luv24fromXYZ; - break; - case SGILOGDATAFMT_16BIT: - sp->tfunc = Luv24fromLuv48; - break; - case SGILOGDATAFMT_RAW: - break; - default: - goto notsupported; - } - } - else - { - tif->tif_encoderow = LogLuvEncode32; - switch (sp->user_datafmt) - { - case SGILOGDATAFMT_FLOAT: - sp->tfunc = Luv32fromXYZ; - break; - case SGILOGDATAFMT_16BIT: - sp->tfunc = Luv32fromLuv48; - break; - case SGILOGDATAFMT_RAW: - break; - default: - goto notsupported; - } - } - break; - case PHOTOMETRIC_LOGL: - if (!LogL16InitState(tif)) - return (0); - tif->tif_encoderow = LogL16Encode; - switch (sp->user_datafmt) - { - case SGILOGDATAFMT_FLOAT: - sp->tfunc = L16fromY; - break; - case SGILOGDATAFMT_16BIT: - break; - default: - goto notsupported; - } - break; - default: - TIFFErrorExtR(tif, module, - "Inappropriate photometric interpretation %" PRIu16 - " for SGILog compression; %s", - td->td_photometric, "must be either LogLUV or LogL"); - return (0); - } - sp->encoder_state = 1; - return (1); -notsupported: - TIFFErrorExtR(tif, module, - "SGILog compression supported only for %s, or raw data", - td->td_photometric == PHOTOMETRIC_LOGL ? "Y, L" : "XYZ, Luv"); - return (0); -} - -static void LogLuvClose(TIFF *tif) -{ - LogLuvState *sp = (LogLuvState *)tif->tif_data; - TIFFDirectory *td = &tif->tif_dir; - - assert(sp != 0); - /* - * For consistency, we always want to write out the same - * bitspersample and sampleformat for our TIFF file, - * regardless of the data format being used by the application. - * Since this routine is called after tags have been set but - * before they have been recorded in the file, we reset them here. - * Note: this is really a nasty approach. See PixarLogClose - */ - if (sp->encoder_state) - { - /* See PixarLogClose. Might avoid issues with tags whose size depends - * on those below, but not completely sure this is enough. */ - td->td_samplesperpixel = - (td->td_photometric == PHOTOMETRIC_LOGL) ? 1 : 3; - td->td_bitspersample = 16; - td->td_sampleformat = SAMPLEFORMAT_INT; - } -} - -static void LogLuvCleanup(TIFF *tif) -{ - LogLuvState *sp = (LogLuvState *)tif->tif_data; - - assert(sp != 0); - - tif->tif_tagmethods.vgetfield = sp->vgetparent; - tif->tif_tagmethods.vsetfield = sp->vsetparent; - - if (sp->tbuf) - _TIFFfreeExt(tif, sp->tbuf); - _TIFFfreeExt(tif, sp); - tif->tif_data = NULL; - - _TIFFSetDefaultCompressionState(tif); -} - -static int LogLuvVSetField(TIFF *tif, uint32_t tag, va_list ap) -{ - static const char module[] = "LogLuvVSetField"; - LogLuvState *sp = DecoderState(tif); - int bps, fmt; - - switch (tag) - { - case TIFFTAG_SGILOGDATAFMT: - sp->user_datafmt = (int)va_arg(ap, int); - /* - * Tweak the TIFF header so that the rest of libtiff knows what - * size of data will be passed between app and library, and - * assume that the app knows what it is doing and is not - * confused by these header manipulations... - */ - switch (sp->user_datafmt) - { - case SGILOGDATAFMT_FLOAT: - bps = 32; - fmt = SAMPLEFORMAT_IEEEFP; - break; - case SGILOGDATAFMT_16BIT: - bps = 16; - fmt = SAMPLEFORMAT_INT; - break; - case SGILOGDATAFMT_RAW: - bps = 32; - fmt = SAMPLEFORMAT_UINT; - TIFFSetField(tif, TIFFTAG_SAMPLESPERPIXEL, 1); - break; - case SGILOGDATAFMT_8BIT: - bps = 8; - fmt = SAMPLEFORMAT_UINT; - break; - default: - TIFFErrorExtR( - tif, tif->tif_name, - "Unknown data format %d for LogLuv compression", - sp->user_datafmt); - return (0); - } - TIFFSetField(tif, TIFFTAG_BITSPERSAMPLE, bps); - TIFFSetField(tif, TIFFTAG_SAMPLEFORMAT, fmt); - /* - * Must recalculate sizes should bits/sample change. - */ - tif->tif_tilesize = isTiled(tif) ? TIFFTileSize(tif) : (tmsize_t)-1; - tif->tif_scanlinesize = TIFFScanlineSize(tif); - return (1); - case TIFFTAG_SGILOGENCODE: - sp->encode_meth = (int)va_arg(ap, int); - if (sp->encode_meth != SGILOGENCODE_NODITHER && - sp->encode_meth != SGILOGENCODE_RANDITHER) - { - TIFFErrorExtR(tif, module, - "Unknown encoding %d for LogLuv compression", - sp->encode_meth); - return (0); - } - return (1); - default: - return (*sp->vsetparent)(tif, tag, ap); - } -} - -static int LogLuvVGetField(TIFF *tif, uint32_t tag, va_list ap) -{ - LogLuvState *sp = (LogLuvState *)tif->tif_data; - - switch (tag) - { - case TIFFTAG_SGILOGDATAFMT: - *va_arg(ap, int *) = sp->user_datafmt; - return (1); - default: - return (*sp->vgetparent)(tif, tag, ap); - } -} - -static const TIFFField LogLuvFields[] = { - {TIFFTAG_SGILOGDATAFMT, 0, 0, TIFF_SHORT, 0, TIFF_SETGET_INT, - TIFF_SETGET_UNDEFINED, FIELD_PSEUDO, TRUE, FALSE, "SGILogDataFmt", NULL}, - {TIFFTAG_SGILOGENCODE, 0, 0, TIFF_SHORT, 0, TIFF_SETGET_INT, - TIFF_SETGET_UNDEFINED, FIELD_PSEUDO, TRUE, FALSE, "SGILogEncode", NULL}}; - -int TIFFInitSGILog(TIFF *tif, int scheme) -{ - static const char module[] = "TIFFInitSGILog"; - LogLuvState *sp; - - assert(scheme == COMPRESSION_SGILOG24 || scheme == COMPRESSION_SGILOG); - - /* - * Merge codec-specific tag information. - */ - if (!_TIFFMergeFields(tif, LogLuvFields, TIFFArrayCount(LogLuvFields))) - { - TIFFErrorExtR(tif, module, "Merging SGILog codec-specific tags failed"); - return 0; - } - - /* - * Allocate state block so tag methods have storage to record values. - */ - tif->tif_data = (uint8_t *)_TIFFmallocExt(tif, sizeof(LogLuvState)); - if (tif->tif_data == NULL) - goto bad; - sp = (LogLuvState *)tif->tif_data; - _TIFFmemset((void *)sp, 0, sizeof(*sp)); - sp->user_datafmt = SGILOGDATAFMT_UNKNOWN; - sp->encode_meth = (scheme == COMPRESSION_SGILOG24) ? SGILOGENCODE_RANDITHER - : SGILOGENCODE_NODITHER; - sp->tfunc = _logLuvNop; - - /* - * Install codec methods. - * NB: tif_decoderow & tif_encoderow are filled - * in at setup time. - */ - tif->tif_fixuptags = LogLuvFixupTags; - tif->tif_setupdecode = LogLuvSetupDecode; - tif->tif_decodestrip = LogLuvDecodeStrip; - tif->tif_decodetile = LogLuvDecodeTile; - tif->tif_setupencode = LogLuvSetupEncode; - tif->tif_encodestrip = LogLuvEncodeStrip; - tif->tif_encodetile = LogLuvEncodeTile; - tif->tif_close = LogLuvClose; - tif->tif_cleanup = LogLuvCleanup; - - /* - * Override parent get/set field methods. - */ - sp->vgetparent = tif->tif_tagmethods.vgetfield; - tif->tif_tagmethods.vgetfield = LogLuvVGetField; /* hook for codec tags */ - sp->vsetparent = tif->tif_tagmethods.vsetfield; - tif->tif_tagmethods.vsetfield = LogLuvVSetField; /* hook for codec tags */ - - return (1); -bad: - TIFFErrorExtR(tif, module, "%s: No space for LogLuv state block", - tif->tif_name); - return (0); -} -#endif /* LOGLUV_SUPPORT */ diff --git a/src/3rd/tiff/lzma.c b/src/3rd/tiff/lzma.c deleted file mode 100644 index 70230799381..00000000000 --- a/src/3rd/tiff/lzma.c +++ /dev/null @@ -1,520 +0,0 @@ -/* - * Copyright (c) 2010, Andrey Kiselev - * - * Permission to use, copy, modify, distribute, and sell this software and - * its documentation for any purpose is hereby granted without fee, provided - * that (i) the above copyright notices and this permission notice appear in - * all copies of the software and related documentation, and (ii) the names of - * Sam Leffler and Silicon Graphics may not be used in any advertising or - * publicity relating to the software without the specific, prior written - * permission of Sam Leffler and Silicon Graphics. - * - * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, - * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY - * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. - * - * IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR - * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, - * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, - * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF - * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE - * OF THIS SOFTWARE. - */ - -#include "tiffiop.h" -#ifdef LZMA_SUPPORT -/* - * TIFF Library. - * - * LZMA2 Compression Support - * - * You need an LZMA2 SDK to link with. See http://tukaani.org/xz/ for details. - * - * The codec is derived from ZLIB codec (tif_zip.c). - */ - -#include "lzma.h" -#include "predict.h" - -#include - -/* - * State block for each open TIFF file using LZMA2 compression/decompression. - */ -typedef struct -{ - TIFFPredictorState predict; - lzma_stream stream; - lzma_filter filters[LZMA_FILTERS_MAX + 1]; - lzma_options_delta opt_delta; /* delta filter options */ - lzma_options_lzma opt_lzma; /* LZMA2 filter options */ - int preset; /* compression level */ - lzma_check check; /* type of the integrity check */ - int state; /* state flags */ -#define LSTATE_INIT_DECODE 0x01 -#define LSTATE_INIT_ENCODE 0x02 - - TIFFVGetMethod vgetparent; /* super-class method */ - TIFFVSetMethod vsetparent; /* super-class method */ -} LZMAState; - -#define LState(tif) ((LZMAState *)(tif)->tif_data) -#define DecoderState(tif) LState(tif) -#define EncoderState(tif) LState(tif) - -static int LZMAEncode(TIFF *tif, uint8_t *bp, tmsize_t cc, uint16_t s); -static int LZMADecode(TIFF *tif, uint8_t *op, tmsize_t occ, uint16_t s); - -static const char *LZMAStrerror(lzma_ret ret) -{ - switch (ret) - { - case LZMA_OK: - return "operation completed successfully"; - case LZMA_STREAM_END: - return "end of stream was reached"; - case LZMA_NO_CHECK: - return "input stream has no integrity check"; - case LZMA_UNSUPPORTED_CHECK: - return "cannot calculate the integrity check"; - case LZMA_GET_CHECK: - return "integrity check type is now available"; - case LZMA_MEM_ERROR: - return "cannot allocate memory"; - case LZMA_MEMLIMIT_ERROR: - return "memory usage limit was reached"; - case LZMA_FORMAT_ERROR: - return "file format not recognized"; - case LZMA_OPTIONS_ERROR: - return "invalid or unsupported options"; - case LZMA_DATA_ERROR: - return "data is corrupt"; - case LZMA_BUF_ERROR: - return "no progress is possible (stream is truncated or corrupt)"; - case LZMA_PROG_ERROR: - return "programming error"; - default: - return "unidentified liblzma error"; - } -} - -static int LZMAFixupTags(TIFF *tif) -{ - (void)tif; - return 1; -} - -static int LZMASetupDecode(TIFF *tif) -{ - LZMAState *sp = DecoderState(tif); - - assert(sp != NULL); - - /* if we were last encoding, terminate this mode */ - if (sp->state & LSTATE_INIT_ENCODE) - { - lzma_end(&sp->stream); - sp->state = 0; - } - - sp->state |= LSTATE_INIT_DECODE; - return 1; -} - -/* - * Setup state for decoding a strip. - */ -static int LZMAPreDecode(TIFF *tif, uint16_t s) -{ - static const char module[] = "LZMAPreDecode"; - LZMAState *sp = DecoderState(tif); - lzma_ret ret; - - (void)s; - assert(sp != NULL); - - if ((sp->state & LSTATE_INIT_DECODE) == 0) - tif->tif_setupdecode(tif); - - sp->stream.next_in = tif->tif_rawdata; - sp->stream.avail_in = (size_t)tif->tif_rawcc; - if ((tmsize_t)sp->stream.avail_in != tif->tif_rawcc) - { - TIFFErrorExtR(tif, module, - "Liblzma cannot deal with buffers this size"); - return 0; - } - - /* - * Disable memory limit when decoding. UINT64_MAX is a flag to disable - * the limit, we are passing (uint64_t)-1 which should be the same. - */ - ret = lzma_stream_decoder(&sp->stream, (uint64_t)-1, 0); - if (ret != LZMA_OK) - { - TIFFErrorExtR(tif, module, "Error initializing the stream decoder, %s", - LZMAStrerror(ret)); - return 0; - } - return 1; -} - -static int LZMADecode(TIFF *tif, uint8_t *op, tmsize_t occ, uint16_t s) -{ - static const char module[] = "LZMADecode"; - LZMAState *sp = DecoderState(tif); - - (void)s; - assert(sp != NULL); - assert(sp->state == LSTATE_INIT_DECODE); - - sp->stream.next_in = tif->tif_rawcp; - sp->stream.avail_in = (size_t)tif->tif_rawcc; - - sp->stream.next_out = op; - sp->stream.avail_out = (size_t)occ; - if ((tmsize_t)sp->stream.avail_out != occ) - { - TIFFErrorExtR(tif, module, - "Liblzma cannot deal with buffers this size"); - return 0; - } - - do - { - /* - * Save the current stream state to properly recover from the - * decoding errors later. - */ - const uint8_t *next_in = sp->stream.next_in; - size_t avail_in = sp->stream.avail_in; - - lzma_ret ret = lzma_code(&sp->stream, LZMA_RUN); - if (ret == LZMA_STREAM_END) - break; - if (ret == LZMA_MEMLIMIT_ERROR) - { - lzma_ret r = - lzma_stream_decoder(&sp->stream, lzma_memusage(&sp->stream), 0); - if (r != LZMA_OK) - { - TIFFErrorExtR(tif, module, - "Error initializing the stream decoder, %s", - LZMAStrerror(r)); - break; - } - sp->stream.next_in = next_in; - sp->stream.avail_in = avail_in; - continue; - } - if (ret != LZMA_OK) - { - TIFFErrorExtR(tif, module, - "Decoding error at scanline %" PRIu32 ", %s", - tif->tif_row, LZMAStrerror(ret)); - break; - } - } while (sp->stream.avail_out > 0); - if (sp->stream.avail_out != 0) - { - TIFFErrorExtR(tif, module, - "Not enough data at scanline %" PRIu32 - " (short %" TIFF_SIZE_FORMAT " bytes)", - tif->tif_row, sp->stream.avail_out); - return 0; - } - - tif->tif_rawcp = (uint8_t *)sp->stream.next_in; /* cast away const */ - tif->tif_rawcc = sp->stream.avail_in; - - return 1; -} - -static int LZMASetupEncode(TIFF *tif) -{ - LZMAState *sp = EncoderState(tif); - - assert(sp != NULL); - if (sp->state & LSTATE_INIT_DECODE) - { - lzma_end(&sp->stream); - sp->state = 0; - } - - sp->state |= LSTATE_INIT_ENCODE; - return 1; -} - -/* - * Reset encoding state at the start of a strip. - */ -static int LZMAPreEncode(TIFF *tif, uint16_t s) -{ - static const char module[] = "LZMAPreEncode"; - LZMAState *sp = EncoderState(tif); - lzma_ret ret; - - (void)s; - assert(sp != NULL); - if (sp->state != LSTATE_INIT_ENCODE) - tif->tif_setupencode(tif); - - sp->stream.next_out = tif->tif_rawdata; - sp->stream.avail_out = (size_t)tif->tif_rawdatasize; - if ((tmsize_t)sp->stream.avail_out != tif->tif_rawdatasize) - { - TIFFErrorExtR(tif, module, - "Liblzma cannot deal with buffers this size"); - return 0; - } - ret = lzma_stream_encoder(&sp->stream, sp->filters, sp->check); - if (ret != LZMA_OK) - { - TIFFErrorExtR(tif, module, "Error in lzma_stream_encoder(): %s", - LZMAStrerror(ret)); - return 0; - } - return 1; -} - -/* - * Encode a chunk of pixels. - */ -static int LZMAEncode(TIFF *tif, uint8_t *bp, tmsize_t cc, uint16_t s) -{ - static const char module[] = "LZMAEncode"; - LZMAState *sp = EncoderState(tif); - - assert(sp != NULL); - assert(sp->state == LSTATE_INIT_ENCODE); - - (void)s; - sp->stream.next_in = bp; - sp->stream.avail_in = (size_t)cc; - if ((tmsize_t)sp->stream.avail_in != cc) - { - TIFFErrorExtR(tif, module, - "Liblzma cannot deal with buffers this size"); - return 0; - } - do - { - lzma_ret ret = lzma_code(&sp->stream, LZMA_RUN); - if (ret != LZMA_OK) - { - TIFFErrorExtR(tif, module, - "Encoding error at scanline %" PRIu32 ", %s", - tif->tif_row, LZMAStrerror(ret)); - return 0; - } - if (sp->stream.avail_out == 0) - { - tif->tif_rawcc = tif->tif_rawdatasize; - if (!TIFFFlushData1(tif)) - return 0; - sp->stream.next_out = tif->tif_rawdata; - sp->stream.avail_out = - (size_t) - tif->tif_rawdatasize; /* this is a safe typecast, as check - is made already in LZMAPreEncode */ - } - } while (sp->stream.avail_in > 0); - return 1; -} - -/* - * Finish off an encoded strip by flushing the last - * string and tacking on an End Of Information code. - */ -static int LZMAPostEncode(TIFF *tif) -{ - static const char module[] = "LZMAPostEncode"; - LZMAState *sp = EncoderState(tif); - lzma_ret ret; - - sp->stream.avail_in = 0; - do - { - ret = lzma_code(&sp->stream, LZMA_FINISH); - switch (ret) - { - case LZMA_STREAM_END: - case LZMA_OK: - if ((tmsize_t)sp->stream.avail_out != tif->tif_rawdatasize) - { - tif->tif_rawcc = - tif->tif_rawdatasize - sp->stream.avail_out; - if (!TIFFFlushData1(tif)) - return 0; - sp->stream.next_out = tif->tif_rawdata; - sp->stream.avail_out = - (size_t) - tif->tif_rawdatasize; /* this is a safe typecast, as - check is made already in - ZIPPreEncode */ - } - break; - default: - TIFFErrorExtR(tif, module, "Liblzma error: %s", - LZMAStrerror(ret)); - return 0; - } - } while (ret != LZMA_STREAM_END); - return 1; -} - -static void LZMACleanup(TIFF *tif) -{ - LZMAState *sp = LState(tif); - - assert(sp != 0); - - (void)TIFFPredictorCleanup(tif); - - tif->tif_tagmethods.vgetfield = sp->vgetparent; - tif->tif_tagmethods.vsetfield = sp->vsetparent; - - if (sp->state) - { - lzma_end(&sp->stream); - sp->state = 0; - } - _TIFFfreeExt(tif, sp); - tif->tif_data = NULL; - - _TIFFSetDefaultCompressionState(tif); -} - -static int LZMAVSetField(TIFF *tif, uint32_t tag, va_list ap) -{ - static const char module[] = "LZMAVSetField"; - LZMAState *sp = LState(tif); - - switch (tag) - { - case TIFFTAG_LZMAPRESET: - sp->preset = (int)va_arg(ap, int); - lzma_lzma_preset(&sp->opt_lzma, sp->preset); - if (sp->state & LSTATE_INIT_ENCODE) - { - lzma_ret ret = - lzma_stream_encoder(&sp->stream, sp->filters, sp->check); - if (ret != LZMA_OK) - { - TIFFErrorExtR(tif, module, "Liblzma error: %s", - LZMAStrerror(ret)); - } - } - return 1; - default: - return (*sp->vsetparent)(tif, tag, ap); - } - /*NOTREACHED*/ -} - -static int LZMAVGetField(TIFF *tif, uint32_t tag, va_list ap) -{ - LZMAState *sp = LState(tif); - - switch (tag) - { - case TIFFTAG_LZMAPRESET: - *va_arg(ap, int *) = sp->preset; - break; - default: - return (*sp->vgetparent)(tif, tag, ap); - } - return 1; -} - -static const TIFFField lzmaFields[] = { - {TIFFTAG_LZMAPRESET, 0, 0, TIFF_ANY, 0, TIFF_SETGET_INT, - TIFF_SETGET_UNDEFINED, FIELD_PSEUDO, TRUE, FALSE, - "LZMA2 Compression Preset", NULL}, -}; - -int TIFFInitLZMA(TIFF *tif, int scheme) -{ - static const char module[] = "TIFFInitLZMA"; - LZMAState *sp; - lzma_stream tmp_stream = LZMA_STREAM_INIT; - - (void)scheme; - assert(scheme == COMPRESSION_LZMA); - - /* - * Merge codec-specific tag information. - */ - if (!_TIFFMergeFields(tif, lzmaFields, TIFFArrayCount(lzmaFields))) - { - TIFFErrorExtR(tif, module, "Merging LZMA2 codec-specific tags failed"); - return 0; - } - - /* - * Allocate state block so tag methods have storage to record values. - */ - tif->tif_data = (uint8_t *)_TIFFmallocExt(tif, sizeof(LZMAState)); - if (tif->tif_data == NULL) - goto bad; - sp = LState(tif); - memcpy(&sp->stream, &tmp_stream, sizeof(lzma_stream)); - - /* - * Override parent get/set field methods. - */ - sp->vgetparent = tif->tif_tagmethods.vgetfield; - tif->tif_tagmethods.vgetfield = LZMAVGetField; /* hook for codec tags */ - sp->vsetparent = tif->tif_tagmethods.vsetfield; - tif->tif_tagmethods.vsetfield = LZMAVSetField; /* hook for codec tags */ - - /* Default values for codec-specific fields */ - sp->preset = LZMA_PRESET_DEFAULT; /* default comp. level */ - sp->check = LZMA_CHECK_NONE; - sp->state = 0; - - /* Data filters. So far we are using delta and LZMA2 filters only. */ - sp->opt_delta.type = LZMA_DELTA_TYPE_BYTE; - /* - * The sample size in bytes seems to be reasonable distance for delta - * filter. - */ - sp->opt_delta.dist = (tif->tif_dir.td_bitspersample % 8) - ? 1 - : tif->tif_dir.td_bitspersample / 8; - sp->filters[0].id = LZMA_FILTER_DELTA; - sp->filters[0].options = &sp->opt_delta; - - lzma_lzma_preset(&sp->opt_lzma, sp->preset); - sp->filters[1].id = LZMA_FILTER_LZMA2; - sp->filters[1].options = &sp->opt_lzma; - - sp->filters[2].id = LZMA_VLI_UNKNOWN; - sp->filters[2].options = NULL; - - /* - * Install codec methods. - */ - tif->tif_fixuptags = LZMAFixupTags; - tif->tif_setupdecode = LZMASetupDecode; - tif->tif_predecode = LZMAPreDecode; - tif->tif_decoderow = LZMADecode; - tif->tif_decodestrip = LZMADecode; - tif->tif_decodetile = LZMADecode; - tif->tif_setupencode = LZMASetupEncode; - tif->tif_preencode = LZMAPreEncode; - tif->tif_postencode = LZMAPostEncode; - tif->tif_encoderow = LZMAEncode; - tif->tif_encodestrip = LZMAEncode; - tif->tif_encodetile = LZMAEncode; - tif->tif_cleanup = LZMACleanup; - /* - * Setup predictor setup. - */ - (void)TIFFPredictorInit(tif); - return 1; -bad: - TIFFErrorExtR(tif, module, "No space for LZMA2 state block"); - return 0; -} -#endif /* LZMA_SUPPORT */ diff --git a/src/3rd/tiff/lzw.c b/src/3rd/tiff/lzw.c deleted file mode 100644 index 7234b8e9226..00000000000 --- a/src/3rd/tiff/lzw.c +++ /dev/null @@ -1,1458 +0,0 @@ -/* - * Copyright (c) 1988-1997 Sam Leffler - * Copyright (c) 1991-1997 Silicon Graphics, Inc. - * Copyright (c) 2022 Even Rouault - * - * Permission to use, copy, modify, distribute, and sell this software and - * its documentation for any purpose is hereby granted without fee, provided - * that (i) the above copyright notices and this permission notice appear in - * all copies of the software and related documentation, and (ii) the names of - * Sam Leffler and Silicon Graphics may not be used in any advertising or - * publicity relating to the software without the specific, prior written - * permission of Sam Leffler and Silicon Graphics. - * - * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, - * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY - * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. - * - * IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR - * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, - * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, - * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF - * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE - * OF THIS SOFTWARE. - */ - -#include "tiffiop.h" -#ifdef LZW_SUPPORT -/* - * TIFF Library. - * Rev 5.0 Lempel-Ziv & Welch Compression Support - * - * This code is derived from the compress program whose code is - * derived from software contributed to Berkeley by James A. Woods, - * derived from original work by Spencer Thomas and Joseph Orost. - * - * The original Berkeley copyright notice appears below in its entirety. - */ -#include "predict.h" - -#include -#include -#include - -/* Select the plausible largest natural integer type for the architecture */ -#define SIZEOF_WORDTYPE SIZEOF_SIZE_T -typedef size_t WordType; - -/* - * NB: The 5.0 spec describes a different algorithm than Aldus - * implements. Specifically, Aldus does code length transitions - * one code earlier than should be done (for real LZW). - * Earlier versions of this library implemented the correct - * LZW algorithm, but emitted codes in a bit order opposite - * to the TIFF spec. Thus, to maintain compatibility w/ Aldus - * we interpret MSB-LSB ordered codes to be images written w/ - * old versions of this library, but otherwise adhere to the - * Aldus "off by one" algorithm. - * - * Future revisions to the TIFF spec are expected to "clarify this issue". - */ -#define LZW_COMPAT /* include backwards compatibility code */ - -#define MAXCODE(n) ((1L << (n)) - 1) -/* - * The TIFF spec specifies that encoded bit - * strings range from 9 to 12 bits. - */ -#define BITS_MIN 9 /* start with 9 bits */ -#define BITS_MAX 12 /* max of 12 bit strings */ -/* predefined codes */ -#define CODE_CLEAR 256 /* code to clear string table */ -#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 HSHIFT (13 - 8) -#ifdef LZW_COMPAT -/* NB: +1024 is for compatibility with old files */ -#define CSIZE (MAXCODE(BITS_MAX) + 1024L) -#else -#define CSIZE (MAXCODE(BITS_MAX) + 1L) -#endif - -/* - * State block for each open TIFF file using LZW - * compression/decompression. Note that the predictor - * state block must be first in this data structure. - */ -typedef struct -{ - TIFFPredictorState predict; /* predictor super class */ - - unsigned short nbits; /* # of bits/code */ - unsigned short maxcode; /* maximum code for lzw_nbits */ - unsigned short free_ent; /* next free entry in hash table */ - WordType nextdata; /* next bits of i/o */ - long nextbits; /* # of valid bits in lzw_nextdata */ - - int rw_mode; /* preserve rw_mode from init */ -} LZWBaseState; - -#define lzw_nbits base.nbits -#define lzw_maxcode base.maxcode -#define lzw_free_ent base.free_ent -#define lzw_nextdata base.nextdata -#define lzw_nextbits base.nextbits - -/* - * Encoding-specific state. - */ -typedef uint16_t hcode_t; /* codes fit in 16 bits */ -typedef struct -{ - long hash; - hcode_t code; -} hash_t; - -/* - * Decoding-specific state. - */ -typedef struct code_ent -{ - struct code_ent *next; - unsigned short length; /* string len, including this token */ - /* firstchar should be placed immediately before value in this structure */ - unsigned char firstchar; /* first token of string */ - unsigned char value; /* data value */ - bool repeated; -} code_t; - -typedef int (*decodeFunc)(TIFF *, uint8_t *, tmsize_t, uint16_t); - -typedef struct -{ - LZWBaseState base; - - /* Decoding specific data */ - long dec_nbitsmask; /* lzw_nbits 1 bits, right adjusted */ - tmsize_t dec_restart; /* restart count */ - uint64_t dec_bitsleft; /* available bits in raw data */ - tmsize_t old_tif_rawcc; /* value of tif_rawcc at the end of the previous - TIFLZWDecode() call */ - decodeFunc dec_decode; /* regular or backwards compatible */ - code_t *dec_codep; /* current recognized code */ - code_t *dec_oldcodep; /* previously recognized code */ - code_t *dec_free_entp; /* next free entry */ - code_t *dec_maxcodep; /* max available entry */ - code_t *dec_codetab; /* kept separate for small machines */ - int read_error; /* whether a read error has occurred, and which should cause - further reads in the same strip/tile to be aborted */ - - /* Encoding specific data */ - int enc_oldcode; /* last code encountered */ - tmsize_t enc_checkpoint; /* point at which to clear table */ -#define CHECK_GAP 10000 /* enc_ratio check interval */ - tmsize_t enc_ratio; /* current compression ratio */ - tmsize_t enc_incount; /* (input) data bytes encoded */ - tmsize_t enc_outcount; /* encoded (output) bytes */ - uint8_t *enc_rawlimit; /* bound on tif_rawdata buffer */ - hash_t *enc_hashtab; /* kept separate for small machines */ -} LZWCodecState; - -#define LZWState(tif) ((LZWBaseState *)(tif)->tif_data) -#define DecoderState(tif) ((LZWCodecState *)LZWState(tif)) -#define EncoderState(tif) ((LZWCodecState *)LZWState(tif)) - -static int LZWDecode(TIFF *tif, uint8_t *op0, tmsize_t occ0, uint16_t s); -#ifdef LZW_COMPAT -static int LZWDecodeCompat(TIFF *tif, uint8_t *op0, tmsize_t occ0, uint16_t s); -#endif -static void cl_hash(LZWCodecState *); - -/* - * LZW Decoder. - */ - -static int LZWFixupTags(TIFF *tif) -{ - (void)tif; - return (1); -} - -static int LZWSetupDecode(TIFF *tif) -{ - static const char module[] = "LZWSetupDecode"; - LZWCodecState *sp = DecoderState(tif); - int code; - - if (sp == NULL) - { - /* - * Allocate state block so tag methods have storage to record - * values. - */ - tif->tif_data = (uint8_t *)_TIFFmallocExt(tif, sizeof(LZWCodecState)); - if (tif->tif_data == NULL) - { - TIFFErrorExtR(tif, module, "No space for LZW state block"); - return (0); - } - - sp = DecoderState(tif); - sp->dec_codetab = NULL; - sp->dec_decode = NULL; - - /* - * Setup predictor setup. - */ - (void)TIFFPredictorInit(tif); - } - - if (sp->dec_codetab == NULL) - { - sp->dec_codetab = (code_t *)_TIFFmallocExt(tif, CSIZE * sizeof(code_t)); - if (sp->dec_codetab == NULL) - { - TIFFErrorExtR(tif, module, "No space for LZW code table"); - return (0); - } - /* - * Pre-load the table. - */ - code = 255; - do - { - sp->dec_codetab[code].firstchar = (unsigned char)code; - sp->dec_codetab[code].value = (unsigned char)code; - sp->dec_codetab[code].repeated = true; - sp->dec_codetab[code].length = 1; - sp->dec_codetab[code].next = NULL; - } while (code--); - /* - * Zero-out the unused entries */ - /* Silence false positive */ - /* coverity[overrun-buffer-arg] */ - memset(&sp->dec_codetab[CODE_CLEAR], 0, - (CODE_FIRST - CODE_CLEAR) * sizeof(code_t)); - } - return (1); -} - -/* - * Setup state for decoding a strip. - */ -static int LZWPreDecode(TIFF *tif, uint16_t s) -{ - static const char module[] = "LZWPreDecode"; - LZWCodecState *sp = DecoderState(tif); - - (void)s; - assert(sp != NULL); - if (sp->dec_codetab == NULL) - { - tif->tif_setupdecode(tif); - if (sp->dec_codetab == NULL) - return (0); - } - - /* - * Check for old bit-reversed codes. - */ - if (tif->tif_rawcc >= 2 && tif->tif_rawdata[0] == 0 && - (tif->tif_rawdata[1] & 0x1)) - { -#ifdef LZW_COMPAT - if (!sp->dec_decode) - { - TIFFWarningExtR(tif, module, "Old-style LZW codes, convert file"); - /* - * Override default decoding methods with - * ones that deal with the old coding. - * Otherwise the predictor versions set - * above will call the compatibility routines - * through the dec_decode method. - */ - tif->tif_decoderow = LZWDecodeCompat; - tif->tif_decodestrip = LZWDecodeCompat; - tif->tif_decodetile = LZWDecodeCompat; - /* - * If doing horizontal differencing, must - * re-setup the predictor logic since we - * switched the basic decoder methods... - */ - (*tif->tif_setupdecode)(tif); - sp->dec_decode = LZWDecodeCompat; - } - sp->lzw_maxcode = MAXCODE(BITS_MIN); -#else /* !LZW_COMPAT */ - if (!sp->dec_decode) - { - TIFFErrorExtR(tif, module, "Old-style LZW codes not supported"); - sp->dec_decode = LZWDecode; - } - return (0); -#endif /* !LZW_COMPAT */ - } - else - { - sp->lzw_maxcode = MAXCODE(BITS_MIN) - 1; - sp->dec_decode = LZWDecode; - } - sp->lzw_nbits = BITS_MIN; - sp->lzw_nextbits = 0; - sp->lzw_nextdata = 0; - - sp->dec_restart = 0; - sp->dec_nbitsmask = MAXCODE(BITS_MIN); - sp->dec_bitsleft = 0; - sp->old_tif_rawcc = 0; - sp->dec_free_entp = sp->dec_codetab - 1; // + CODE_FIRST; - /* - * Zero entries that are not yet filled in. We do - * this to guard against bogus input data that causes - * us to index into undefined entries. If you can - * come up with a way to safely bounds-check input codes - * while decoding then you can remove this operation. - */ - sp->dec_oldcodep = &sp->dec_codetab[0]; - sp->dec_maxcodep = &sp->dec_codetab[sp->dec_nbitsmask - 1]; - sp->read_error = 0; - return (1); -} - -/* - * Decode a "hunk of data". - */ - -/* Get the next 32 or 64-bit from the input data */ -#ifdef WORDS_BIGENDIAN -#define GetNextData(nextdata, bp) memcpy(&nextdata, bp, sizeof(nextdata)) -#elif SIZEOF_WORDTYPE == 8 -#if defined(__GNUC__) && defined(__x86_64__) -#define GetNextData(nextdata, bp) \ - nextdata = __builtin_bswap64(*(uint64_t *)(bp)) -#elif defined(_M_X64) -#define GetNextData(nextdata, bp) nextdata = _byteswap_uint64(*(uint64_t *)(bp)) -#elif defined(__GNUC__) -#define GetNextData(nextdata, bp) \ - memcpy(&nextdata, bp, sizeof(nextdata)); \ - nextdata = __builtin_bswap64(nextdata) -#else -#define GetNextData(nextdata, bp) \ - nextdata = (((uint64_t)bp[0]) << 56) | (((uint64_t)bp[1]) << 48) | \ - (((uint64_t)bp[2]) << 40) | (((uint64_t)bp[3]) << 32) | \ - (((uint64_t)bp[4]) << 24) | (((uint64_t)bp[5]) << 16) | \ - (((uint64_t)bp[6]) << 8) | (((uint64_t)bp[7])) -#endif -#elif SIZEOF_WORDTYPE == 4 -#if defined(__GNUC__) && defined(__i386__) -#define GetNextData(nextdata, bp) \ - nextdata = __builtin_bswap32(*(uint32_t *)(bp)) -#elif defined(_M_X86) -#define GetNextData(nextdata, bp) \ - nextdata = _byteswap_ulong(*(unsigned long *)(bp)) -#elif defined(__GNUC__) -#define GetNextData(nextdata, bp) \ - memcpy(&nextdata, bp, sizeof(nextdata)); \ - nextdata = __builtin_bswap32(nextdata) -#else -#define GetNextData(nextdata, bp) \ - nextdata = (((uint32_t)bp[0]) << 24) | (((uint32_t)bp[1]) << 16) | \ - (((uint32_t)bp[2]) << 8) | (((uint32_t)bp[3])) -#endif -#else -#error "Unhandled SIZEOF_WORDTYPE" -#endif - -#define GetNextCodeLZW() \ - do \ - { \ - nextbits -= nbits; \ - if (nextbits < 0) \ - { \ - if (dec_bitsleft >= 8 * SIZEOF_WORDTYPE) \ - { \ - unsigned codetmp = (unsigned)(nextdata << (-nextbits)); \ - GetNextData(nextdata, bp); \ - bp += SIZEOF_WORDTYPE; \ - nextbits += 8 * SIZEOF_WORDTYPE; \ - dec_bitsleft -= 8 * SIZEOF_WORDTYPE; \ - code = (WordType)((codetmp | (nextdata >> nextbits)) & \ - nbitsmask); \ - break; \ - } \ - else \ - { \ - if (dec_bitsleft < 8) \ - { \ - goto no_eoi; \ - } \ - nextdata = (nextdata << 8) | *(bp)++; \ - nextbits += 8; \ - dec_bitsleft -= 8; \ - if (nextbits < 0) \ - { \ - if (dec_bitsleft < 8) \ - { \ - goto no_eoi; \ - } \ - nextdata = (nextdata << 8) | *(bp)++; \ - nextbits += 8; \ - dec_bitsleft -= 8; \ - } \ - } \ - } \ - code = (WordType)((nextdata >> nextbits) & nbitsmask); \ - } while (0) - -static int LZWDecode(TIFF *tif, uint8_t *op0, tmsize_t occ0, uint16_t s) -{ - static const char module[] = "LZWDecode"; - LZWCodecState *sp = DecoderState(tif); - uint8_t *op = (uint8_t *)op0; - tmsize_t occ = occ0; - uint8_t *bp; - long nbits, nextbits, nbitsmask; - WordType nextdata; - code_t *free_entp, *maxcodep, *oldcodep; - - (void)s; - assert(sp != NULL); - assert(sp->dec_codetab != NULL); - - if (sp->read_error) - { - TIFFErrorExtR(tif, module, - "LZWDecode: Scanline %" PRIu32 " cannot be read due to " - "previous error", - tif->tif_row); - return 0; - } - - /* - * Restart interrupted output operation. - */ - if (sp->dec_restart) - { - tmsize_t residue; - - code_t *codep = sp->dec_codep; - residue = codep->length - sp->dec_restart; - if (residue > occ) - { - /* - * Residue from previous decode is sufficient - * to satisfy decode request. Skip to the - * start of the decoded string, place decoded - * values in the output buffer, and return. - */ - sp->dec_restart += occ; - do - { - codep = codep->next; - } while (--residue > occ && codep); - if (codep) - { - uint8_t *tp = op + occ; - do - { - *--tp = codep->value; - codep = codep->next; - } while (--occ && codep); - } - return (1); - } - /* - * Residue satisfies only part of the decode request. - */ - op += residue; - occ -= residue; - uint8_t *tp = op; - do - { - *--tp = codep->value; - codep = codep->next; - } while (--residue && codep); - sp->dec_restart = 0; - } - - bp = (uint8_t *)tif->tif_rawcp; - sp->dec_bitsleft += (((uint64_t)tif->tif_rawcc - sp->old_tif_rawcc) << 3); - uint64_t dec_bitsleft = sp->dec_bitsleft; - nbits = sp->lzw_nbits; - nextdata = sp->lzw_nextdata; - nextbits = sp->lzw_nextbits; - nbitsmask = sp->dec_nbitsmask; - oldcodep = sp->dec_oldcodep; - free_entp = sp->dec_free_entp; - maxcodep = sp->dec_maxcodep; - code_t *const dec_codetab = sp->dec_codetab; - code_t *codep; - - if (occ == 0) - { - goto after_loop; - } - -begin: -{ - WordType code; - GetNextCodeLZW(); - codep = dec_codetab + code; - if (code >= CODE_FIRST) - goto code_above_or_equal_to_258; - if (code < 256) - goto code_below_256; - if (code == CODE_EOI) - goto after_loop; - goto code_clear; - -code_below_256: -{ - if (codep > free_entp) - goto error_code; - free_entp->next = oldcodep; - free_entp->firstchar = oldcodep->firstchar; - free_entp->length = oldcodep->length + 1; - free_entp->value = (uint8_t)code; - free_entp->repeated = - (bool)(oldcodep->repeated & (oldcodep->value == code)); - if (++free_entp > maxcodep) - { - if (++nbits > BITS_MAX) /* should not happen for a conformant encoder */ - nbits = BITS_MAX; - nbitsmask = MAXCODE(nbits); - maxcodep = dec_codetab + nbitsmask - 1; - if (free_entp >= &dec_codetab[CSIZE]) - { - /* At that point, the next valid states are either EOI or a */ - /* CODE_CLEAR. If a regular code is read, at the next */ - /* attempt at registering a new entry, we will error out */ - /* due to setting free_entp before any valid code */ - free_entp = dec_codetab - 1; - } - } - oldcodep = codep; - *op++ = (uint8_t)code; - occ--; - if (occ == 0) - goto after_loop; - goto begin; -} - -code_above_or_equal_to_258: -{ - /* - * Add the new entry to the code table. - */ - - if (codep >= free_entp) - { - if (codep != free_entp) - goto error_code; - free_entp->value = oldcodep->firstchar; - } - else - { - free_entp->value = codep->firstchar; - } - free_entp->repeated = - (bool)(oldcodep->repeated & (oldcodep->value == free_entp->value)); - free_entp->next = oldcodep; - - free_entp->firstchar = oldcodep->firstchar; - free_entp->length = oldcodep->length + 1; - if (++free_entp > maxcodep) - { - if (++nbits > BITS_MAX) /* should not happen for a conformant encoder */ - nbits = BITS_MAX; - nbitsmask = MAXCODE(nbits); - maxcodep = dec_codetab + nbitsmask - 1; - if (free_entp >= &dec_codetab[CSIZE]) - { - /* At that point, the next valid states are either EOI or a */ - /* CODE_CLEAR. If a regular code is read, at the next */ - /* attempt at registering a new entry, we will error out */ - /* due to setting free_entp before any valid code */ - free_entp = dec_codetab - 1; - } - } - oldcodep = codep; - - /* - * Code maps to a string, copy string - * value to output (written in reverse). - */ - /* tiny bit faster on x86_64 to store in unsigned short than int */ - unsigned short len = codep->length; - - if (len < 3) /* equivalent to len == 2 given all other conditions */ - { - if (occ <= 2) - { - if (occ == 2) - { - memcpy(op, &(codep->firstchar), 2); - op += 2; - occ -= 2; - goto after_loop; - } - goto too_short_buffer; - } - - memcpy(op, &(codep->firstchar), 2); - op += 2; - occ -= 2; - goto begin; /* we can save the comparison occ > 0 */ - } - - if (len == 3) - { - if (occ <= 3) - { - if (occ == 3) - { - op[0] = codep->firstchar; - op[1] = codep->next->value; - op[2] = codep->value; - op += 3; - occ -= 3; - goto after_loop; - } - goto too_short_buffer; - } - - op[0] = codep->firstchar; - op[1] = codep->next->value; - op[2] = codep->value; - op += 3; - occ -= 3; - goto begin; /* we can save the comparison occ > 0 */ - } - - if (len > occ) - { - goto too_short_buffer; - } - - if (codep->repeated) - { - memset(op, codep->value, len); - op += len; - occ -= len; - if (occ == 0) - goto after_loop; - goto begin; - } - - uint8_t *tp = op + len; - - assert(len >= 4); - - *--tp = codep->value; - codep = codep->next; - *--tp = codep->value; - codep = codep->next; - *--tp = codep->value; - codep = codep->next; - *--tp = codep->value; - if (tp > op) - { - do - { - codep = codep->next; - *--tp = codep->value; - } while (tp > op); - } - - assert(occ >= len); - op += len; - occ -= len; - if (occ == 0) - goto after_loop; - goto begin; -} - -code_clear: -{ - free_entp = dec_codetab + CODE_FIRST; - nbits = BITS_MIN; - nbitsmask = MAXCODE(BITS_MIN); - maxcodep = dec_codetab + nbitsmask - 1; - do - { - GetNextCodeLZW(); - } while (code == CODE_CLEAR); /* consecutive CODE_CLEAR codes */ - if (code == CODE_EOI) - goto after_loop; - if (code > CODE_EOI) - { - goto error_code; - } - *op++ = (uint8_t)code; - occ--; - oldcodep = dec_codetab + code; - if (occ == 0) - goto after_loop; - goto begin; -} -} - -too_short_buffer: -{ - /* - * String is too long for decode buffer, - * locate portion that will fit, copy to - * the decode buffer, and setup restart - * logic for the next decoding call. - */ - sp->dec_codep = codep; - do - { - codep = codep->next; - } while (codep->length > occ); - - sp->dec_restart = occ; - uint8_t *tp = op + occ; - do - { - *--tp = codep->value; - codep = codep->next; - } while (--occ); -} - -after_loop: - tif->tif_rawcc -= (tmsize_t)((uint8_t *)bp - tif->tif_rawcp); - tif->tif_rawcp = (uint8_t *)bp; - sp->old_tif_rawcc = tif->tif_rawcc; - sp->dec_bitsleft = dec_bitsleft; - sp->lzw_nbits = (unsigned short)nbits; - sp->lzw_nextdata = nextdata; - sp->lzw_nextbits = nextbits; - sp->dec_nbitsmask = nbitsmask; - sp->dec_oldcodep = oldcodep; - sp->dec_free_entp = free_entp; - sp->dec_maxcodep = maxcodep; - - if (occ > 0) - { - TIFFErrorExtR(tif, module, - "Not enough data at scanline %" PRIu32 " (short %" PRIu64 - " bytes)", - tif->tif_row, (uint64_t)occ); - return (0); - } - return (1); - -no_eoi: - sp->read_error = 1; - TIFFErrorExtR(tif, module, - "LZWDecode: Strip %" PRIu32 " not terminated with EOI code", - tif->tif_curstrip); - return 0; -error_code: - sp->read_error = 1; - TIFFErrorExtR(tif, tif->tif_name, "Using code not yet in table"); - return 0; -} - -#ifdef LZW_COMPAT - -/* - * This check shouldn't be necessary because each - * strip is suppose to be terminated with CODE_EOI. - */ -#define NextCode(_tif, _sp, _bp, _code, _get, dec_bitsleft) \ - { \ - if (dec_bitsleft < (uint64_t)nbits) \ - { \ - TIFFWarningExtR(_tif, module, \ - "LZWDecode: Strip %" PRIu32 \ - " not terminated with EOI code", \ - _tif->tif_curstrip); \ - _code = CODE_EOI; \ - } \ - else \ - { \ - _get(_sp, _bp, _code); \ - dec_bitsleft -= nbits; \ - } \ - } - -/* - * Decode a "hunk of data" for old images. - */ -#define GetNextCodeCompat(sp, bp, code) \ - { \ - nextdata |= (unsigned long)*(bp)++ << nextbits; \ - nextbits += 8; \ - if (nextbits < nbits) \ - { \ - nextdata |= (unsigned long)*(bp)++ << nextbits; \ - nextbits += 8; \ - } \ - code = (hcode_t)(nextdata & nbitsmask); \ - nextdata >>= nbits; \ - nextbits -= nbits; \ - } - -static int LZWDecodeCompat(TIFF *tif, uint8_t *op0, tmsize_t occ0, uint16_t s) -{ - static const char module[] = "LZWDecodeCompat"; - LZWCodecState *sp = DecoderState(tif); - uint8_t *op = (uint8_t *)op0; - tmsize_t occ = occ0; - uint8_t *tp; - uint8_t *bp; - int code, nbits; - int len; - long nextbits, nbitsmask; - WordType nextdata; - code_t *codep, *free_entp, *maxcodep, *oldcodep; - - (void)s; - assert(sp != NULL); - - /* - * Restart interrupted output operation. - */ - if (sp->dec_restart) - { - tmsize_t residue; - - codep = sp->dec_codep; - residue = codep->length - sp->dec_restart; - if (residue > occ) - { - /* - * Residue from previous decode is sufficient - * to satisfy decode request. Skip to the - * start of the decoded string, place decoded - * values in the output buffer, and return. - */ - sp->dec_restart += occ; - do - { - codep = codep->next; - } while (--residue > occ); - tp = op + occ; - do - { - *--tp = codep->value; - codep = codep->next; - } while (--occ); - return (1); - } - /* - * Residue satisfies only part of the decode request. - */ - op += residue; - occ -= residue; - tp = op; - do - { - *--tp = codep->value; - codep = codep->next; - } while (--residue); - sp->dec_restart = 0; - } - - bp = (uint8_t *)tif->tif_rawcp; - - sp->dec_bitsleft += (((uint64_t)tif->tif_rawcc - sp->old_tif_rawcc) << 3); - uint64_t dec_bitsleft = sp->dec_bitsleft; - - nbits = sp->lzw_nbits; - nextdata = sp->lzw_nextdata; - nextbits = sp->lzw_nextbits; - nbitsmask = sp->dec_nbitsmask; - oldcodep = sp->dec_oldcodep; - free_entp = sp->dec_free_entp; - maxcodep = sp->dec_maxcodep; - - while (occ > 0) - { - NextCode(tif, sp, bp, code, GetNextCodeCompat, dec_bitsleft); - if (code == CODE_EOI) - break; - if (code == CODE_CLEAR) - { - do - { - free_entp = sp->dec_codetab + CODE_FIRST; - _TIFFmemset(free_entp, 0, - (CSIZE - CODE_FIRST) * sizeof(code_t)); - nbits = BITS_MIN; - nbitsmask = MAXCODE(BITS_MIN); - maxcodep = sp->dec_codetab + nbitsmask; - NextCode(tif, sp, bp, code, GetNextCodeCompat, dec_bitsleft); - } while (code == CODE_CLEAR); /* consecutive CODE_CLEAR codes */ - if (code == CODE_EOI) - break; - if (code > CODE_CLEAR) - { - TIFFErrorExtR( - tif, tif->tif_name, - "LZWDecode: Corrupted LZW table at scanline %" PRIu32, - tif->tif_row); - return (0); - } - *op++ = (uint8_t)code; - occ--; - oldcodep = sp->dec_codetab + code; - continue; - } - codep = sp->dec_codetab + code; - - /* - * Add the new entry to the code table. - */ - if (free_entp < &sp->dec_codetab[0] || - free_entp >= &sp->dec_codetab[CSIZE]) - { - TIFFErrorExtR(tif, module, - "Corrupted LZW table at scanline %" PRIu32, - tif->tif_row); - return (0); - } - - free_entp->next = oldcodep; - if (free_entp->next < &sp->dec_codetab[0] || - free_entp->next >= &sp->dec_codetab[CSIZE]) - { - TIFFErrorExtR(tif, module, - "Corrupted LZW table at scanline %" PRIu32, - tif->tif_row); - return (0); - } - free_entp->firstchar = free_entp->next->firstchar; - free_entp->length = free_entp->next->length + 1; - free_entp->value = - (codep < free_entp) ? codep->firstchar : free_entp->firstchar; - if (++free_entp > maxcodep) - { - if (++nbits > BITS_MAX) /* should not happen */ - nbits = BITS_MAX; - nbitsmask = MAXCODE(nbits); - maxcodep = sp->dec_codetab + nbitsmask; - } - oldcodep = codep; - if (code >= 256) - { - /* - * Code maps to a string, copy string - * value to output (written in reverse). - */ - if (codep->length == 0) - { - TIFFErrorExtR( - tif, module, - "Wrong length of decoded " - "string: data probably corrupted at scanline %" PRIu32, - tif->tif_row); - return (0); - } - if (codep->length > occ) - { - /* - * String is too long for decode buffer, - * locate portion that will fit, copy to - * the decode buffer, and setup restart - * logic for the next decoding call. - */ - sp->dec_codep = codep; - do - { - codep = codep->next; - } while (codep->length > occ); - sp->dec_restart = occ; - tp = op + occ; - do - { - *--tp = codep->value; - codep = codep->next; - } while (--occ); - break; - } - len = codep->length; - tp = op + len; - do - { - *--tp = codep->value; - codep = codep->next; - } while (codep && tp > op); - assert(occ >= len); - op += len; - occ -= len; - } - else - { - *op++ = (uint8_t)code; - occ--; - } - } - - tif->tif_rawcc -= (tmsize_t)((uint8_t *)bp - tif->tif_rawcp); - tif->tif_rawcp = (uint8_t *)bp; - - sp->old_tif_rawcc = tif->tif_rawcc; - sp->dec_bitsleft = dec_bitsleft; - - sp->lzw_nbits = (unsigned short)nbits; - sp->lzw_nextdata = nextdata; - sp->lzw_nextbits = nextbits; - sp->dec_nbitsmask = nbitsmask; - sp->dec_oldcodep = oldcodep; - sp->dec_free_entp = free_entp; - sp->dec_maxcodep = maxcodep; - - if (occ > 0) - { - TIFFErrorExtR(tif, module, - "Not enough data at scanline %" PRIu32 " (short %" PRIu64 - " bytes)", - tif->tif_row, (uint64_t)occ); - return (0); - } - return (1); -} -#endif /* LZW_COMPAT */ - -/* - * LZW Encoding. - */ - -static int LZWSetupEncode(TIFF *tif) -{ - static const char module[] = "LZWSetupEncode"; - LZWCodecState *sp = EncoderState(tif); - - assert(sp != NULL); - sp->enc_hashtab = (hash_t *)_TIFFmallocExt(tif, HSIZE * sizeof(hash_t)); - if (sp->enc_hashtab == NULL) - { - TIFFErrorExtR(tif, module, "No space for LZW hash table"); - return (0); - } - return (1); -} - -/* - * Reset encoding state at the start of a strip. - */ -static int LZWPreEncode(TIFF *tif, uint16_t s) -{ - LZWCodecState *sp = EncoderState(tif); - - (void)s; - assert(sp != NULL); - - if (sp->enc_hashtab == NULL) - { - tif->tif_setupencode(tif); - } - - sp->lzw_nbits = BITS_MIN; - sp->lzw_maxcode = MAXCODE(BITS_MIN); - sp->lzw_free_ent = CODE_FIRST; - sp->lzw_nextbits = 0; - sp->lzw_nextdata = 0; - sp->enc_checkpoint = CHECK_GAP; - sp->enc_ratio = 0; - sp->enc_incount = 0; - sp->enc_outcount = 0; - /* - * The 4 here insures there is space for 2 max-sized - * codes in LZWEncode and LZWPostDecode. - */ - sp->enc_rawlimit = tif->tif_rawdata + tif->tif_rawdatasize - 1 - 4; - cl_hash(sp); /* clear hash table */ - sp->enc_oldcode = (hcode_t)-1; /* generates CODE_CLEAR in LZWEncode */ - return (1); -} - -#define CALCRATIO(sp, rat) \ - { \ - if (incount > 0x007fffff) \ - { /* NB: shift will overflow */ \ - rat = outcount >> 8; \ - rat = (rat == 0 ? 0x7fffffff : incount / rat); \ - } \ - else \ - rat = (incount << 8) / outcount; \ - } - -/* Explicit 0xff masking to make icc -check=conversions happy */ -#define PutNextCode(op, c) \ - { \ - nextdata = (nextdata << nbits) | c; \ - nextbits += nbits; \ - *op++ = (unsigned char)((nextdata >> (nextbits - 8)) & 0xff); \ - nextbits -= 8; \ - if (nextbits >= 8) \ - { \ - *op++ = (unsigned char)((nextdata >> (nextbits - 8)) & 0xff); \ - nextbits -= 8; \ - } \ - outcount += nbits; \ - } - -/* - * Encode a chunk of pixels. - * - * Uses an open addressing double hashing (no chaining) on the - * prefix code/next character combination. We do a variant of - * Knuth's algorithm D (vol. 3, sec. 6.4) along with G. Knott's - * relatively-prime secondary probe. Here, the modular division - * first probe is gives way to a faster exclusive-or manipulation. - * Also do block compression with an adaptive reset, whereby the - * code table is cleared when the compression ratio decreases, - * but after the table fills. The variable-length output codes - * are re-sized at this point, and a CODE_CLEAR is generated - * for the decoder. - */ -static int LZWEncode(TIFF *tif, uint8_t *bp, tmsize_t cc, uint16_t s) -{ - register LZWCodecState *sp = EncoderState(tif); - register long fcode; - register hash_t *hp; - register int h, c; - hcode_t ent; - long disp; - tmsize_t incount, outcount, checkpoint; - WordType nextdata; - long nextbits; - int free_ent, maxcode, nbits; - uint8_t *op; - uint8_t *limit; - - (void)s; - if (sp == NULL) - return (0); - - assert(sp->enc_hashtab != NULL); - - /* - * Load local state. - */ - incount = sp->enc_incount; - outcount = sp->enc_outcount; - checkpoint = sp->enc_checkpoint; - nextdata = sp->lzw_nextdata; - nextbits = sp->lzw_nextbits; - free_ent = sp->lzw_free_ent; - maxcode = sp->lzw_maxcode; - nbits = sp->lzw_nbits; - op = tif->tif_rawcp; - limit = sp->enc_rawlimit; - ent = (hcode_t)sp->enc_oldcode; - - if (ent == (hcode_t)-1 && cc > 0) - { - /* - * NB: This is safe because it can only happen - * at the start of a strip where we know there - * is space in the data buffer. - */ - PutNextCode(op, CODE_CLEAR); - ent = *bp++; - cc--; - incount++; - } - while (cc > 0) - { - c = *bp++; - cc--; - incount++; - fcode = ((long)c << BITS_MAX) + ent; - h = (c << HSHIFT) ^ ent; /* xor hashing */ -#ifdef _WINDOWS - /* - * Check hash index for an overflow. - */ - if (h >= HSIZE) - h -= HSIZE; -#endif - hp = &sp->enc_hashtab[h]; - if (hp->hash == fcode) - { - ent = hp->code; - continue; - } - if (hp->hash >= 0) - { - /* - * Primary hash failed, check secondary hash. - */ - disp = HSIZE - h; - if (h == 0) - disp = 1; - do - { - /* - * Avoid pointer arithmetic because of - * wraparound problems with segments. - */ - if ((h -= disp) < 0) - h += HSIZE; - hp = &sp->enc_hashtab[h]; - if (hp->hash == fcode) - { - ent = hp->code; - goto hit; - } - } while (hp->hash >= 0); - } - /* - * New entry, emit code and add to table. - */ - /* - * Verify there is space in the buffer for the code - * and any potential Clear code that might be emitted - * below. The value of limit is setup so that there - * are at least 4 bytes free--room for 2 codes. - */ - if (op > limit) - { - tif->tif_rawcc = (tmsize_t)(op - tif->tif_rawdata); - if (!TIFFFlushData1(tif)) - return 0; - op = tif->tif_rawdata; - } - PutNextCode(op, ent); - ent = (hcode_t)c; - hp->code = (hcode_t)(free_ent++); - hp->hash = fcode; - if (free_ent == CODE_MAX - 1) - { - /* table is full, emit clear code and reset */ - cl_hash(sp); - sp->enc_ratio = 0; - incount = 0; - outcount = 0; - free_ent = CODE_FIRST; - PutNextCode(op, CODE_CLEAR); - nbits = BITS_MIN; - maxcode = MAXCODE(BITS_MIN); - } - else - { - /* - * If the next entry is going to be too big for - * the code size, then increase it, if possible. - */ - if (free_ent > maxcode) - { - nbits++; - assert(nbits <= BITS_MAX); - maxcode = (int)MAXCODE(nbits); - } - else if (incount >= checkpoint) - { - tmsize_t rat; - /* - * Check compression ratio and, if things seem - * to be slipping, clear the hash table and - * reset state. The compression ratio is a - * 24+8-bit fractional number. - */ - checkpoint = incount + CHECK_GAP; - CALCRATIO(sp, rat); - if (rat <= sp->enc_ratio) - { - cl_hash(sp); - sp->enc_ratio = 0; - incount = 0; - outcount = 0; - free_ent = CODE_FIRST; - PutNextCode(op, CODE_CLEAR); - nbits = BITS_MIN; - maxcode = MAXCODE(BITS_MIN); - } - else - sp->enc_ratio = rat; - } - } - hit:; - } - - /* - * Restore global state. - */ - sp->enc_incount = incount; - sp->enc_outcount = outcount; - sp->enc_checkpoint = checkpoint; - sp->enc_oldcode = ent; - sp->lzw_nextdata = nextdata; - sp->lzw_nextbits = nextbits; - sp->lzw_free_ent = (unsigned short)free_ent; - sp->lzw_maxcode = (unsigned short)maxcode; - sp->lzw_nbits = (unsigned short)nbits; - tif->tif_rawcp = op; - return (1); -} - -/* - * Finish off an encoded strip by flushing the last - * string and tacking on an End Of Information code. - */ -static int LZWPostEncode(TIFF *tif) -{ - register LZWCodecState *sp = EncoderState(tif); - uint8_t *op = tif->tif_rawcp; - long nextbits = sp->lzw_nextbits; - WordType nextdata = sp->lzw_nextdata; - tmsize_t outcount = sp->enc_outcount; - int nbits = sp->lzw_nbits; - - if (op > sp->enc_rawlimit) - { - tif->tif_rawcc = (tmsize_t)(op - tif->tif_rawdata); - if (!TIFFFlushData1(tif)) - return 0; - op = tif->tif_rawdata; - } - if (sp->enc_oldcode != (hcode_t)-1) - { - int free_ent = sp->lzw_free_ent; - - PutNextCode(op, sp->enc_oldcode); - sp->enc_oldcode = (hcode_t)-1; - free_ent++; - - if (free_ent == CODE_MAX - 1) - { - /* table is full, emit clear code and reset */ - outcount = 0; - PutNextCode(op, CODE_CLEAR); - nbits = BITS_MIN; - } - else - { - /* - * If the next entry is going to be too big for - * the code size, then increase it, if possible. - */ - if (free_ent > sp->lzw_maxcode) - { - nbits++; - assert(nbits <= BITS_MAX); - } - } - } - PutNextCode(op, CODE_EOI); - /* Explicit 0xff masking to make icc -check=conversions happy */ - if (nextbits > 0) - *op++ = (unsigned char)((nextdata << (8 - nextbits)) & 0xff); - tif->tif_rawcc = (tmsize_t)(op - tif->tif_rawdata); - (void)outcount; - return (1); -} - -/* - * Reset encoding hash table. - */ -static void cl_hash(LZWCodecState *sp) -{ - register hash_t *hp = &sp->enc_hashtab[HSIZE - 1]; - register long i = HSIZE - 8; - - do - { - i -= 8; - hp[-7].hash = -1; - hp[-6].hash = -1; - hp[-5].hash = -1; - hp[-4].hash = -1; - hp[-3].hash = -1; - hp[-2].hash = -1; - hp[-1].hash = -1; - hp[0].hash = -1; - hp -= 8; - } while (i >= 0); - for (i += 8; i > 0; i--, hp--) - hp->hash = -1; -} - -static void LZWCleanup(TIFF *tif) -{ - (void)TIFFPredictorCleanup(tif); - - assert(tif->tif_data != 0); - - if (DecoderState(tif)->dec_codetab) - _TIFFfreeExt(tif, DecoderState(tif)->dec_codetab); - - if (EncoderState(tif)->enc_hashtab) - _TIFFfreeExt(tif, EncoderState(tif)->enc_hashtab); - - _TIFFfreeExt(tif, tif->tif_data); - tif->tif_data = NULL; - - _TIFFSetDefaultCompressionState(tif); -} - -int TIFFInitLZW(TIFF *tif, int scheme) -{ - static const char module[] = "TIFFInitLZW"; - (void)scheme; - assert(scheme == COMPRESSION_LZW); - /* - * Allocate state block so tag methods have storage to record values. - */ - tif->tif_data = (uint8_t *)_TIFFmallocExt(tif, sizeof(LZWCodecState)); - if (tif->tif_data == NULL) - goto bad; - DecoderState(tif)->dec_codetab = NULL; - DecoderState(tif)->dec_decode = NULL; - EncoderState(tif)->enc_hashtab = NULL; - LZWState(tif)->rw_mode = tif->tif_mode; - - /* - * Install codec methods. - */ - tif->tif_fixuptags = LZWFixupTags; - tif->tif_setupdecode = LZWSetupDecode; - tif->tif_predecode = LZWPreDecode; - tif->tif_decoderow = LZWDecode; - tif->tif_decodestrip = LZWDecode; - tif->tif_decodetile = LZWDecode; - tif->tif_setupencode = LZWSetupEncode; - tif->tif_preencode = LZWPreEncode; - tif->tif_postencode = LZWPostEncode; - tif->tif_encoderow = LZWEncode; - tif->tif_encodestrip = LZWEncode; - tif->tif_encodetile = LZWEncode; - tif->tif_cleanup = LZWCleanup; - /* - * Setup predictor setup. - */ - (void)TIFFPredictorInit(tif); - return (1); -bad: - TIFFErrorExtR(tif, module, "No space for LZW state block"); - return (0); -} - -/* - * Copyright (c) 1985, 1986 The Regents of the University of California. - * All rights reserved. - * - * This code is derived from software contributed to Berkeley by - * James A. Woods, derived from original work by Spencer Thomas - * and Joseph Orost. - * - * Redistribution and use in source and binary forms are permitted - * provided that the above copyright notice and this paragraph are - * duplicated in all such forms and that any documentation, - * advertising materials, and other materials related to such - * distribution and use acknowledge that the software was developed - * by the University of California, Berkeley. The name of the - * University may not be used to endorse or promote products derived - * from this software without specific prior written permission. - * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. - */ -#endif /* LZW_SUPPORT */ diff --git a/src/3rd/tiff/next.c b/src/3rd/tiff/next.c deleted file mode 100644 index f000574ee74..00000000000 --- a/src/3rd/tiff/next.c +++ /dev/null @@ -1,194 +0,0 @@ -/* - * Copyright (c) 1988-1997 Sam Leffler - * Copyright (c) 1991-1997 Silicon Graphics, Inc. - * - * Permission to use, copy, modify, distribute, and sell this software and - * its documentation for any purpose is hereby granted without fee, provided - * that (i) the above copyright notices and this permission notice appear in - * all copies of the software and related documentation, and (ii) the names of - * Sam Leffler and Silicon Graphics may not be used in any advertising or - * publicity relating to the software without the specific, prior written - * permission of Sam Leffler and Silicon Graphics. - * - * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, - * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY - * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. - * - * IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR - * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, - * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, - * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF - * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE - * OF THIS SOFTWARE. - */ - -#include "tiffiop.h" -#ifdef NEXT_SUPPORT -/* - * TIFF Library. - * - * NeXT 2-bit Grey Scale Compression Algorithm Support - */ - -#define SETPIXEL(op, v) \ - { \ - switch (npixels++ & 3) \ - { \ - case 0: \ - op[0] = (unsigned char)((v) << 6); \ - break; \ - case 1: \ - op[0] |= (v) << 4; \ - break; \ - case 2: \ - op[0] |= (v) << 2; \ - break; \ - case 3: \ - *op++ |= (v); \ - op_offset++; \ - 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) -{ - static const char module[] = "NeXTDecode"; - unsigned char *bp, *op; - tmsize_t cc; - uint8_t *row; - tmsize_t scanline, n; - - (void)s; - /* - * Each scanline is assumed to start off as all - * white (we assume a PhotometricInterpretation - * of ``min-is-black''). - */ - for (op = (unsigned char *)buf, cc = occ; cc-- > 0;) - *op++ = 0xff; - - bp = (unsigned char *)tif->tif_rawcp; - cc = tif->tif_rawcc; - scanline = tif->tif_scanlinesize; - if (occ % scanline) - { - TIFFErrorExtR(tif, module, "Fractional scanlines cannot be read"); - return (0); - } - for (row = buf; cc > 0 && occ > 0; occ -= scanline, row += scanline) - { - n = *bp++; - cc--; - switch (n) - { - case LITERALROW: - /* - * The entire scanline is given as literal values. - */ - if (cc < scanline) - goto bad; - _TIFFmemcpy(row, bp, scanline); - bp += scanline; - cc -= scanline; - break; - case LITERALSPAN: - { - tmsize_t off; - /* - * The scanline has a literal span that begins at some - * offset. - */ - if (cc < 4) - goto bad; - off = (bp[0] * 256) + bp[1]; - n = (bp[2] * 256) + bp[3]; - if (cc < 4 + n || off + n > scanline) - goto bad; - _TIFFmemcpy(row + off, bp + 4, n); - bp += 4 + n; - cc -= 4 + n; - break; - } - default: - { - uint32_t npixels = 0, grey; - tmsize_t op_offset = 0; - uint32_t imagewidth = tif->tif_dir.td_imagewidth; - if (isTiled(tif)) - imagewidth = tif->tif_dir.td_tilewidth; - - /* - * The scanline is composed of a sequence of constant - * color ``runs''. We shift into ``run mode'' and - * interpret bytes as codes of the form - * until we've filled the scanline. - */ - op = row; - for (;;) - { - grey = (uint32_t)((n >> 6) & 0x3); - n &= 0x3f; - /* - * Ensure the run does not exceed the scanline - * bounds, potentially resulting in a security - * issue. - */ - while (n-- > 0 && npixels < imagewidth && - op_offset < scanline) - SETPIXEL(op, grey); - if (npixels >= imagewidth) - break; - if (op_offset >= scanline) - { - TIFFErrorExtR(tif, module, - "Invalid data for scanline %" PRIu32, - tif->tif_row); - return (0); - } - if (cc == 0) - goto bad; - n = *bp++; - cc--; - } - break; - } - } - } - tif->tif_rawcp = (uint8_t *)bp; - tif->tif_rawcc = cc; - return (1); -bad: - TIFFErrorExtR(tif, module, "Not enough data for scanline %" PRIu32, - tif->tif_row); - return (0); -} - -static int NeXTPreDecode(TIFF *tif, uint16_t s) -{ - static const char module[] = "NeXTPreDecode"; - TIFFDirectory *td = &tif->tif_dir; - (void)s; - - if (td->td_bitspersample != 2) - { - TIFFErrorExtR(tif, module, "Unsupported BitsPerSample = %" PRIu16, - td->td_bitspersample); - return (0); - } - return (1); -} - -int TIFFInitNeXT(TIFF *tif, int scheme) -{ - (void)scheme; - tif->tif_predecode = NeXTPreDecode; - tif->tif_decoderow = NeXTDecode; - tif->tif_decodestrip = NeXTDecode; - tif->tif_decodetile = NeXTDecode; - return (1); -} -#endif /* NEXT_SUPPORT */ diff --git a/src/3rd/tiff/ojpeg.c b/src/3rd/tiff/ojpeg.c deleted file mode 100644 index ea572091e50..00000000000 --- a/src/3rd/tiff/ojpeg.c +++ /dev/null @@ -1,2815 +0,0 @@ -/* WARNING: The type of JPEG encapsulation defined by the TIFF Version 6.0 - specification is now totally obsolete and deprecated for new applications and - images. This file was was created solely in order to read unconverted images - still present on some users' computer systems. It will never be extended - to write such files. Writing new-style JPEG compressed TIFFs is implemented - in tif_jpeg.c. - - The code is carefully crafted to robustly read all gathered JPEG-in-TIFF - testfiles, and anticipate as much as possible all other... But still, it may - fail on some. If you encounter problems, please report them on the TIFF - mailing list and/or to Joris Van Damme . - - Please read the file called "TIFF Technical Note #2" if you need to be - convinced this compression scheme is bad and breaks TIFF. That document - is linked to from the LibTiff site - and from AWare Systems' TIFF section - . It is also absorbed - in Adobe's specification supplements, marked "draft" up to this day, but - supported by the TIFF community. - - This file interfaces with Release 6B of the JPEG Library written by the - Independent JPEG Group. Previous versions of this file required a hack inside - the LibJpeg library. This version no longer requires that. Remember to - remove the hack if you update from the old version. - - Copyright (c) Joris Van Damme - Copyright (c) AWare Systems - - The licence agreement for this file is the same as the rest of the LibTiff - library. - - IN NO EVENT SHALL JORIS VAN DAMME OR AWARE SYSTEMS BE LIABLE FOR - ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, - OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, - WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF - LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE - OF THIS SOFTWARE. - - Joris Van Damme and/or AWare Systems may be available for custom - development. If you like what you see, and need anything similar or related, - contact . -*/ - -/* What is what, and what is not? - - This decoder starts with an input stream, that is essentially the - JpegInterchangeFormat stream, if any, followed by the strile data, if any. - This stream is read in OJPEGReadByte and related functions. - - It analyzes the start of this stream, until it encounters non-marker data, - i.e. compressed image data. Some of the header markers it sees have no actual - content, like the SOI marker, and APP/COM markers that really shouldn't even - be there. Some other markers do have content, and the valuable bits and - pieces of information in these markers are saved, checking all to verify that - the stream is more or less within expected bounds. This happens inside the - OJPEGReadHeaderInfoSecStreamXxx functions. - - Some OJPEG imagery contains no valid JPEG header markers. This situation is - picked up on if we've seen no SOF marker when we're at the start of the - compressed image data. In this case, the tables are read from JpegXxxTables - tags, and the other bits and pieces of information is initialized to its most - basic value. This is implemented in the OJPEGReadHeaderInfoSecTablesXxx - functions. - - When this is complete, a good and valid JPEG header can be assembled, and - this is passed through to LibJpeg. When that's done, the remainder of the - input stream, i.e. the compressed image data, can be passed through - unchanged. This is done in OJPEGWriteStream functions. - - LibTiff rightly expects to know the subsampling values before decompression. - Just like in new-style JPEG-in-TIFF, though, or even more so, actually, the - YCbCrsubsampling tag is notoriously unreliable. To correct these tag values - with the ones inside the JPEG stream, the first part of the input stream is - pre-scanned in OJPEGSubsamplingCorrect, making no note of any other data, - reporting no warnings or errors, up to the point where either these values - are read, or it's clear they aren't there. This means that some of the data - is read twice, but we feel speed in correcting these values is important - enough to warrant this sacrifice. Although there is currently no define or - other configuration mechanism to disable this behavior, the actual header - scanning is build to robustly respond with error report if it should - encounter an uncorrected mismatch of subsampling values. See - OJPEGReadHeaderInfoSecStreamSof. - - The restart interval and restart markers are the most tricky part... The - restart interval can be specified in a tag. It can also be set inside the - input JPEG stream. It can be used inside the input JPEG stream. If reading - from strile data, we've consistently discovered the need to insert restart - markers in between the different striles, as is also probably the most likely - interpretation of the original TIFF 6.0 specification. With all this setting - of interval, and actual use of markers that is not predictable at the time of - valid JPEG header assembly, the restart thing may turn out the Achilles heel - of this implementation. Fortunately, most OJPEG writer vendors succeed in - reading back what they write, which may be the reason why we've been able to - discover ways that seem to work. - - Some special provision is made for planarconfig separate OJPEG files. These - seem to consistently contain header info, a SOS marker, a plane, SOS marker, - plane, SOS, and plane. This may or may not be a valid JPEG configuration, we - don't know and don't care. We want LibTiff to be able to access the planes - individually, without huge buffering inside LibJpeg, anyway. So we compose - headers to feed to LibJpeg, in this case, that allow us to pass a single - plane such that LibJpeg sees a valid single-channel JPEG stream. Locating - subsequent SOS markers, and thus subsequent planes, is done inside - OJPEGReadSecondarySos. - - The benefit of the scheme is... that it works, basically. We know of no other - that does. It works without checking software tag, or otherwise going about - things in an OJPEG flavor specific manner. Instead, it is a single scheme, - that covers the cases with and without JpegInterchangeFormat, with and - without striles, with part of the header in JpegInterchangeFormat and - remainder in first strile, etc. It is forgiving and robust, may likely work - with OJPEG flavors we've not seen yet, and makes most out of the data. - - Another nice side-effect is that a complete JPEG single valid stream is build - if planarconfig is not separate (vast majority). We may one day use that to - build converters to JPEG, and/or to new-style JPEG compression inside TIFF. - - A disadvantage is the lack of random access to the individual striles. This - is the reason for much of the complicated restart-and-position stuff inside - OJPEGPreDecode. Applications would do well accessing all striles in order, as - this will result in a single sequential scan of the input stream, and no - restarting of LibJpeg decoding session. -*/ - -#define WIN32_LEAN_AND_MEAN -#define VC_EXTRALEAN - -#include "tiffiop.h" -#ifdef OJPEG_SUPPORT - -/* Configuration defines here are: - * JPEG_ENCAP_EXTERNAL: The normal way to call libjpeg, uses longjump. In some - * environments, like eg LibTiffDelphi, this is not possible. For this reason, - * the actual calls to libjpeg, with longjump stuff, are encapsulated in - * dedicated functions. When JPEG_ENCAP_EXTERNAL is defined, these encapsulating - * functions are declared external to this unit, and can be defined elsewhere to - * use stuff other then longjump. The default mode, without JPEG_ENCAP_EXTERNAL, - * implements the call encapsulators here, internally, with normal longjump. - * SETJMP, LONGJMP, JMP_BUF: On some machines/environments a longjump equivalent - * is conveniently available, but still it may be worthwhile to use _setjmp or - * sigsetjmp in place of plain setjmp. These macros will make it easier. It is - * useless to fiddle with these if you define JPEG_ENCAP_EXTERNAL. OJPEG_BUFFER: - * Define the size of the desired buffer here. Should be small enough so as to - * guarantee instant processing, optimal streaming and optimal use of processor - * cache, but also big enough so as to not result in significant call overhead. - * It should be at least a few bytes to accommodate some structures (this is - * verified in asserts), but it would not be sensible to make it this small - * anyway, and it should be at most 64K since it is indexed with uint16_t. We - * recommend 2K. EGYPTIANWALK: You could also define EGYPTIANWALK here, but it - * is not used anywhere and has absolutely no effect. That is why most people - * insist the EGYPTIANWALK is a bit silly. - */ - -/* define LIBJPEG_ENCAP_EXTERNAL */ -#define SETJMP(jbuf) setjmp(jbuf) -#define LONGJMP(jbuf, code) longjmp(jbuf, code) -#define JMP_BUF jmp_buf -#define OJPEG_BUFFER 2048 -/* define EGYPTIANWALK */ - -#define JPEG_MARKER_SOF0 0xC0 -#define JPEG_MARKER_SOF1 0xC1 -#define JPEG_MARKER_SOF3 0xC3 -#define JPEG_MARKER_DHT 0xC4 -#define JPEG_MARKER_RST0 0XD0 -#define JPEG_MARKER_SOI 0xD8 -#define JPEG_MARKER_EOI 0xD9 -#define JPEG_MARKER_SOS 0xDA -#define JPEG_MARKER_DQT 0xDB -#define JPEG_MARKER_DRI 0xDD -#define JPEG_MARKER_APP0 0xE0 -#define JPEG_MARKER_COM 0xFE - -#define FIELD_OJPEG_JPEGINTERCHANGEFORMAT (FIELD_CODEC + 0) -#define FIELD_OJPEG_JPEGINTERCHANGEFORMATLENGTH (FIELD_CODEC + 1) -#define FIELD_OJPEG_JPEGQTABLES (FIELD_CODEC + 2) -#define FIELD_OJPEG_JPEGDCTABLES (FIELD_CODEC + 3) -#define FIELD_OJPEG_JPEGACTABLES (FIELD_CODEC + 4) -#define FIELD_OJPEG_JPEGPROC (FIELD_CODEC + 5) -#define FIELD_OJPEG_JPEGRESTARTINTERVAL (FIELD_CODEC + 6) - -static const TIFFField ojpegFields[] = { - {TIFFTAG_JPEGIFOFFSET, 1, 1, TIFF_LONG8, 0, TIFF_SETGET_UINT64, - TIFF_SETGET_UNDEFINED, FIELD_OJPEG_JPEGINTERCHANGEFORMAT, TRUE, FALSE, - "JpegInterchangeFormat", NULL}, - {TIFFTAG_JPEGIFBYTECOUNT, 1, 1, TIFF_LONG8, 0, TIFF_SETGET_UINT64, - TIFF_SETGET_UNDEFINED, FIELD_OJPEG_JPEGINTERCHANGEFORMATLENGTH, TRUE, - FALSE, "JpegInterchangeFormatLength", NULL}, - {TIFFTAG_JPEGQTABLES, TIFF_VARIABLE2, TIFF_VARIABLE2, TIFF_LONG8, 0, - TIFF_SETGET_C32_UINT64, TIFF_SETGET_UNDEFINED, FIELD_OJPEG_JPEGQTABLES, - FALSE, TRUE, "JpegQTables", NULL}, - {TIFFTAG_JPEGDCTABLES, TIFF_VARIABLE2, TIFF_VARIABLE2, TIFF_LONG8, 0, - TIFF_SETGET_C32_UINT64, TIFF_SETGET_UNDEFINED, FIELD_OJPEG_JPEGDCTABLES, - FALSE, TRUE, "JpegDcTables", NULL}, - {TIFFTAG_JPEGACTABLES, TIFF_VARIABLE2, TIFF_VARIABLE2, TIFF_LONG8, 0, - TIFF_SETGET_C32_UINT64, TIFF_SETGET_UNDEFINED, FIELD_OJPEG_JPEGACTABLES, - FALSE, TRUE, "JpegAcTables", NULL}, - {TIFFTAG_JPEGPROC, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, - TIFF_SETGET_UNDEFINED, FIELD_OJPEG_JPEGPROC, FALSE, FALSE, "JpegProc", - NULL}, - {TIFFTAG_JPEGRESTARTINTERVAL, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, - TIFF_SETGET_UNDEFINED, FIELD_OJPEG_JPEGRESTARTINTERVAL, FALSE, FALSE, - "JpegRestartInterval", NULL}, -}; - -#ifndef LIBJPEG_ENCAP_EXTERNAL -#include -#endif - -/* We undefine FAR to avoid conflict with JPEG definition */ - -#ifdef FAR -#undef FAR -#endif - -/* - Libjpeg's jmorecfg.h defines INT16 and INT32, but only if XMD_H is - not defined. Unfortunately, the MinGW and Borland compilers include - a typedef for INT32, which causes a conflict. MSVC does not include - a conflicting typedef given the headers which are included. -*/ -#if defined(__BORLANDC__) || defined(__MINGW32__) -#define XMD_H 1 -#endif - -/* Define "boolean" as unsigned char, not int, per Windows custom. */ -#if defined(__WIN32__) && !defined(__MINGW32__) -#ifndef __RPCNDR_H__ /* don't conflict if rpcndr.h already read */ -typedef unsigned char boolean; -#endif -#define HAVE_BOOLEAN /* prevent jmorecfg.h from redefining it */ -#endif - -#include "jerror.h" -#include "jpeglib.h" - -typedef struct jpeg_error_mgr jpeg_error_mgr; -typedef struct jpeg_common_struct jpeg_common_struct; -typedef struct jpeg_decompress_struct jpeg_decompress_struct; -typedef struct jpeg_source_mgr jpeg_source_mgr; - -typedef enum -{ - osibsNotSetYet, - osibsJpegInterchangeFormat, - osibsStrile, - osibsEof -} OJPEGStateInBufferSource; - -typedef enum -{ - ososSoi, - ososQTable0, - ososQTable1, - ososQTable2, - ososQTable3, - ososDcTable0, - ososDcTable1, - ososDcTable2, - ososDcTable3, - ososAcTable0, - ososAcTable1, - ososAcTable2, - ososAcTable3, - ososDri, - ososSof, - ososSos, - ososCompressed, - ososRst, - ososEoi -} OJPEGStateOutState; - -typedef struct -{ - TIFF *tif; - int decoder_ok; - int error_in_raw_data_decoding; -#ifndef LIBJPEG_ENCAP_EXTERNAL - JMP_BUF exit_jmpbuf; -#endif - TIFFVGetMethod vgetparent; - TIFFVSetMethod vsetparent; - TIFFPrintMethod printdir; - uint64_t file_size; - uint32_t image_width; - uint32_t image_length; - uint32_t strile_width; - uint32_t strile_length; - uint32_t strile_length_total; - uint8_t samples_per_pixel; - uint8_t plane_sample_offset; - uint8_t samples_per_pixel_per_plane; - uint64_t jpeg_interchange_format; - uint64_t jpeg_interchange_format_length; - uint8_t jpeg_proc; - uint8_t subsamplingcorrect; - uint8_t subsamplingcorrect_done; - uint8_t subsampling_tag; - uint8_t subsampling_hor; - uint8_t subsampling_ver; - uint8_t subsampling_force_desubsampling_inside_decompression; - uint8_t qtable_offset_count; - uint8_t dctable_offset_count; - uint8_t actable_offset_count; - uint64_t qtable_offset[3]; - uint64_t dctable_offset[3]; - uint64_t actable_offset[3]; - uint8_t *qtable[4]; - uint8_t *dctable[4]; - uint8_t *actable[4]; - uint16_t restart_interval; - uint8_t restart_index; - uint8_t sof_log; - uint8_t sof_marker_id; - uint32_t sof_x; - uint32_t sof_y; - uint8_t sof_c[3]; - uint8_t sof_hv[3]; - uint8_t sof_tq[3]; - uint8_t sos_cs[3]; - uint8_t sos_tda[3]; - struct - { - uint8_t log; - OJPEGStateInBufferSource in_buffer_source; - uint32_t in_buffer_next_strile; - uint64_t in_buffer_file_pos; - uint64_t in_buffer_file_togo; - } sos_end[3]; - uint8_t readheader_done; - uint8_t writeheader_done; - uint16_t write_cursample; - uint32_t write_curstrile; - uint8_t libjpeg_session_active; - uint8_t libjpeg_jpeg_query_style; - jpeg_error_mgr libjpeg_jpeg_error_mgr; - jpeg_decompress_struct libjpeg_jpeg_decompress_struct; - jpeg_source_mgr libjpeg_jpeg_source_mgr; - uint8_t subsampling_convert_log; - uint32_t subsampling_convert_ylinelen; - uint32_t subsampling_convert_ylines; - uint32_t subsampling_convert_clinelen; - uint32_t subsampling_convert_clines; - uint32_t subsampling_convert_ybuflen; - uint32_t subsampling_convert_cbuflen; - uint32_t subsampling_convert_ycbcrbuflen; - uint8_t *subsampling_convert_ycbcrbuf; - uint8_t *subsampling_convert_ybuf; - uint8_t *subsampling_convert_cbbuf; - uint8_t *subsampling_convert_crbuf; - uint32_t subsampling_convert_ycbcrimagelen; - uint8_t **subsampling_convert_ycbcrimage; - uint32_t subsampling_convert_clinelenout; - uint32_t subsampling_convert_state; - uint32_t bytes_per_line; /* if the codec outputs subsampled data, a 'line' - in bytes_per_line */ - uint32_t lines_per_strile; /* and lines_per_strile means subsampling_ver - desubsampled rows */ - OJPEGStateInBufferSource in_buffer_source; - uint32_t in_buffer_next_strile; - uint32_t in_buffer_strile_count; - uint64_t in_buffer_file_pos; - uint8_t in_buffer_file_pos_log; - uint64_t in_buffer_file_togo; - uint16_t in_buffer_togo; - uint8_t *in_buffer_cur; - uint8_t in_buffer[OJPEG_BUFFER]; - OJPEGStateOutState out_state; - uint8_t out_buffer[OJPEG_BUFFER]; - uint8_t *skip_buffer; -} OJPEGState; - -static int OJPEGVGetField(TIFF *tif, uint32_t tag, va_list ap); -static int OJPEGVSetField(TIFF *tif, uint32_t tag, va_list ap); -static void OJPEGPrintDir(TIFF *tif, FILE *fd, long flags); - -static int OJPEGFixupTags(TIFF *tif); -static int OJPEGSetupDecode(TIFF *tif); -static int OJPEGPreDecode(TIFF *tif, uint16_t s); -static int OJPEGPreDecodeSkipRaw(TIFF *tif); -static int OJPEGPreDecodeSkipScanlines(TIFF *tif); -static int OJPEGDecode(TIFF *tif, uint8_t *buf, tmsize_t cc, uint16_t s); -static int OJPEGDecodeRaw(TIFF *tif, uint8_t *buf, tmsize_t cc); -static int OJPEGDecodeScanlines(TIFF *tif, uint8_t *buf, tmsize_t cc); -static void OJPEGPostDecode(TIFF *tif, uint8_t *buf, tmsize_t cc); -static int OJPEGSetupEncode(TIFF *tif); -static int OJPEGPreEncode(TIFF *tif, uint16_t s); -static int OJPEGEncode(TIFF *tif, uint8_t *buf, tmsize_t cc, uint16_t s); -static int OJPEGPostEncode(TIFF *tif); -static void OJPEGCleanup(TIFF *tif); - -static void OJPEGSubsamplingCorrect(TIFF *tif); -static int OJPEGReadHeaderInfo(TIFF *tif); -static int OJPEGReadSecondarySos(TIFF *tif, uint16_t s); -static int OJPEGWriteHeaderInfo(TIFF *tif); -static void OJPEGLibjpegSessionAbort(TIFF *tif); - -static int OJPEGReadHeaderInfoSec(TIFF *tif); -static int OJPEGReadHeaderInfoSecStreamDri(TIFF *tif); -static int OJPEGReadHeaderInfoSecStreamDqt(TIFF *tif); -static int OJPEGReadHeaderInfoSecStreamDht(TIFF *tif); -static int OJPEGReadHeaderInfoSecStreamSof(TIFF *tif, uint8_t marker_id); -static int OJPEGReadHeaderInfoSecStreamSos(TIFF *tif); -static int OJPEGReadHeaderInfoSecTablesQTable(TIFF *tif); -static int OJPEGReadHeaderInfoSecTablesDcTable(TIFF *tif); -static int OJPEGReadHeaderInfoSecTablesAcTable(TIFF *tif); - -static int OJPEGReadBufferFill(OJPEGState *sp); -static int OJPEGReadByte(OJPEGState *sp, uint8_t *byte); -static int OJPEGReadBytePeek(OJPEGState *sp, uint8_t *byte); -static void OJPEGReadByteAdvance(OJPEGState *sp); -static int OJPEGReadWord(OJPEGState *sp, uint16_t *word); -static int OJPEGReadBlock(OJPEGState *sp, uint16_t len, void *mem); -static void OJPEGReadSkip(OJPEGState *sp, uint16_t len); - -static int OJPEGWriteStream(TIFF *tif, void **mem, uint32_t *len); -static void OJPEGWriteStreamSoi(TIFF *tif, void **mem, uint32_t *len); -static void OJPEGWriteStreamQTable(TIFF *tif, uint8_t table_index, void **mem, - uint32_t *len); -static void OJPEGWriteStreamDcTable(TIFF *tif, uint8_t table_index, void **mem, - uint32_t *len); -static void OJPEGWriteStreamAcTable(TIFF *tif, uint8_t table_index, void **mem, - uint32_t *len); -static void OJPEGWriteStreamDri(TIFF *tif, void **mem, uint32_t *len); -static void OJPEGWriteStreamSof(TIFF *tif, void **mem, uint32_t *len); -static void OJPEGWriteStreamSos(TIFF *tif, void **mem, uint32_t *len); -static int OJPEGWriteStreamCompressed(TIFF *tif, void **mem, uint32_t *len); -static void OJPEGWriteStreamRst(TIFF *tif, void **mem, uint32_t *len); -static void OJPEGWriteStreamEoi(TIFF *tif, void **mem, uint32_t *len); - -#ifdef LIBJPEG_ENCAP_EXTERNAL -extern int jpeg_create_decompress_encap(OJPEGState *sp, - jpeg_decompress_struct *cinfo); -extern int jpeg_read_header_encap(OJPEGState *sp, jpeg_decompress_struct *cinfo, - uint8_t require_image); -extern int jpeg_start_decompress_encap(OJPEGState *sp, - jpeg_decompress_struct *cinfo); -extern int jpeg_read_scanlines_encap(OJPEGState *sp, - jpeg_decompress_struct *cinfo, - void *scanlines, uint32_t max_lines); -extern int jpeg_read_raw_data_encap(OJPEGState *sp, - jpeg_decompress_struct *cinfo, void *data, - uint32_t max_lines); -extern void jpeg_encap_unwind(TIFF *tif); -#else -static int jpeg_create_decompress_encap(OJPEGState *sp, - jpeg_decompress_struct *j); -static int jpeg_read_header_encap(OJPEGState *sp, jpeg_decompress_struct *cinfo, - uint8_t require_image); -static int jpeg_start_decompress_encap(OJPEGState *sp, - jpeg_decompress_struct *cinfo); -static int jpeg_read_scanlines_encap(OJPEGState *sp, - jpeg_decompress_struct *cinfo, - void *scanlines, uint32_t max_lines); -static int jpeg_read_raw_data_encap(OJPEGState *sp, - jpeg_decompress_struct *cinfo, void *data, - uint32_t max_lines); -static void jpeg_encap_unwind(TIFF *tif); -#endif - -static void OJPEGLibjpegJpegErrorMgrOutputMessage(jpeg_common_struct *cinfo); -static void OJPEGLibjpegJpegErrorMgrErrorExit(jpeg_common_struct *cinfo); -static void OJPEGLibjpegJpegSourceMgrInitSource(jpeg_decompress_struct *cinfo); -static boolean -OJPEGLibjpegJpegSourceMgrFillInputBuffer(jpeg_decompress_struct *cinfo); -static void -OJPEGLibjpegJpegSourceMgrSkipInputData(jpeg_decompress_struct *cinfo, - long num_bytes); -static boolean -OJPEGLibjpegJpegSourceMgrResyncToRestart(jpeg_decompress_struct *cinfo, - int desired); -static void OJPEGLibjpegJpegSourceMgrTermSource(jpeg_decompress_struct *cinfo); - -int TIFFInitOJPEG(TIFF *tif, int scheme) -{ - static const char module[] = "TIFFInitOJPEG"; - OJPEGState *sp; - - (void)scheme; - assert(scheme == COMPRESSION_OJPEG); - - /* - * Merge codec-specific tag information. - */ - if (!_TIFFMergeFields(tif, ojpegFields, TIFFArrayCount(ojpegFields))) - { - TIFFErrorExtR(tif, module, - "Merging Old JPEG codec-specific tags failed"); - return 0; - } - - /* state block */ - sp = _TIFFmallocExt(tif, sizeof(OJPEGState)); - if (sp == NULL) - { - TIFFErrorExtR(tif, module, "No space for OJPEG state block"); - return (0); - } - _TIFFmemset(sp, 0, sizeof(OJPEGState)); - sp->tif = tif; - sp->jpeg_proc = 1; - sp->subsampling_hor = 2; - sp->subsampling_ver = 2; - TIFFSetField(tif, TIFFTAG_YCBCRSUBSAMPLING, 2, 2); - /* tif codec methods */ - tif->tif_fixuptags = OJPEGFixupTags; - tif->tif_setupdecode = OJPEGSetupDecode; - tif->tif_predecode = OJPEGPreDecode; - tif->tif_postdecode = OJPEGPostDecode; - tif->tif_decoderow = OJPEGDecode; - tif->tif_decodestrip = OJPEGDecode; - tif->tif_decodetile = OJPEGDecode; - tif->tif_setupencode = OJPEGSetupEncode; - tif->tif_preencode = OJPEGPreEncode; - tif->tif_postencode = OJPEGPostEncode; - tif->tif_encoderow = OJPEGEncode; - tif->tif_encodestrip = OJPEGEncode; - tif->tif_encodetile = OJPEGEncode; - tif->tif_cleanup = OJPEGCleanup; - tif->tif_data = (uint8_t *)sp; - /* tif tag methods */ - sp->vgetparent = tif->tif_tagmethods.vgetfield; - tif->tif_tagmethods.vgetfield = OJPEGVGetField; - sp->vsetparent = tif->tif_tagmethods.vsetfield; - tif->tif_tagmethods.vsetfield = OJPEGVSetField; - sp->printdir = tif->tif_tagmethods.printdir; - tif->tif_tagmethods.printdir = OJPEGPrintDir; - /* Some OJPEG files don't have strip or tile offsets or bytecounts tags. - Some others do, but have totally meaningless or corrupt values - in these tags. In these cases, the JpegInterchangeFormat stream is - reliable. In any case, this decoder reads the compressed data itself, - from the most reliable locations, and we need to notify encapsulating - LibTiff not to read raw strips or tiles for us. */ - tif->tif_flags |= TIFF_NOREADRAW; - return (1); -} - -static int OJPEGVGetField(TIFF *tif, uint32_t tag, va_list ap) -{ - OJPEGState *sp = (OJPEGState *)tif->tif_data; - switch (tag) - { - case TIFFTAG_JPEGIFOFFSET: - *va_arg(ap, uint64_t *) = (uint64_t)sp->jpeg_interchange_format; - break; - case TIFFTAG_JPEGIFBYTECOUNT: - *va_arg(ap, uint64_t *) = - (uint64_t)sp->jpeg_interchange_format_length; - break; - case TIFFTAG_YCBCRSUBSAMPLING: - if (sp->subsamplingcorrect_done == 0) - OJPEGSubsamplingCorrect(tif); - *va_arg(ap, uint16_t *) = (uint16_t)sp->subsampling_hor; - *va_arg(ap, uint16_t *) = (uint16_t)sp->subsampling_ver; - break; - case TIFFTAG_JPEGQTABLES: - *va_arg(ap, uint32_t *) = (uint32_t)sp->qtable_offset_count; - *va_arg(ap, const void **) = (const void *)sp->qtable_offset; - break; - case TIFFTAG_JPEGDCTABLES: - *va_arg(ap, uint32_t *) = (uint32_t)sp->dctable_offset_count; - *va_arg(ap, const void **) = (const void *)sp->dctable_offset; - break; - case TIFFTAG_JPEGACTABLES: - *va_arg(ap, uint32_t *) = (uint32_t)sp->actable_offset_count; - *va_arg(ap, const void **) = (const void *)sp->actable_offset; - break; - case TIFFTAG_JPEGPROC: - *va_arg(ap, uint16_t *) = (uint16_t)sp->jpeg_proc; - break; - case TIFFTAG_JPEGRESTARTINTERVAL: - *va_arg(ap, uint16_t *) = sp->restart_interval; - break; - default: - return (*sp->vgetparent)(tif, tag, ap); - } - return (1); -} - -static int OJPEGVSetField(TIFF *tif, uint32_t tag, va_list ap) -{ - static const char module[] = "OJPEGVSetField"; - OJPEGState *sp = (OJPEGState *)tif->tif_data; - uint32_t ma; - uint64_t *mb; - uint32_t n; - const TIFFField *fip; - - switch (tag) - { - case TIFFTAG_JPEGIFOFFSET: - sp->jpeg_interchange_format = (uint64_t)va_arg(ap, uint64_t); - break; - case TIFFTAG_JPEGIFBYTECOUNT: - sp->jpeg_interchange_format_length = (uint64_t)va_arg(ap, uint64_t); - break; - case TIFFTAG_YCBCRSUBSAMPLING: - sp->subsampling_tag = 1; - sp->subsampling_hor = (uint8_t)va_arg(ap, uint16_vap); - sp->subsampling_ver = (uint8_t)va_arg(ap, uint16_vap); - tif->tif_dir.td_ycbcrsubsampling[0] = sp->subsampling_hor; - tif->tif_dir.td_ycbcrsubsampling[1] = sp->subsampling_ver; - break; - case TIFFTAG_JPEGQTABLES: - ma = (uint32_t)va_arg(ap, uint32_t); - if (ma != 0) - { - if (ma > 3) - { - TIFFErrorExtR(tif, module, - "JpegQTables tag has incorrect count"); - return (0); - } - sp->qtable_offset_count = (uint8_t)ma; - mb = (uint64_t *)va_arg(ap, uint64_t *); - for (n = 0; n < ma; n++) - sp->qtable_offset[n] = mb[n]; - } - break; - case TIFFTAG_JPEGDCTABLES: - ma = (uint32_t)va_arg(ap, uint32_t); - if (ma != 0) - { - if (ma > 3) - { - TIFFErrorExtR(tif, module, - "JpegDcTables tag has incorrect count"); - return (0); - } - sp->dctable_offset_count = (uint8_t)ma; - mb = (uint64_t *)va_arg(ap, uint64_t *); - for (n = 0; n < ma; n++) - sp->dctable_offset[n] = mb[n]; - } - break; - case TIFFTAG_JPEGACTABLES: - ma = (uint32_t)va_arg(ap, uint32_t); - if (ma != 0) - { - if (ma > 3) - { - TIFFErrorExtR(tif, module, - "JpegAcTables tag has incorrect count"); - return (0); - } - sp->actable_offset_count = (uint8_t)ma; - mb = (uint64_t *)va_arg(ap, uint64_t *); - for (n = 0; n < ma; n++) - sp->actable_offset[n] = mb[n]; - } - break; - case TIFFTAG_JPEGPROC: - sp->jpeg_proc = (uint8_t)va_arg(ap, uint16_vap); - break; - case TIFFTAG_JPEGRESTARTINTERVAL: - sp->restart_interval = (uint16_t)va_arg(ap, uint16_vap); - break; - default: - return (*sp->vsetparent)(tif, tag, ap); - } - fip = TIFFFieldWithTag(tif, tag); - if (fip == NULL) /* shouldn't happen */ - return (0); - TIFFSetFieldBit(tif, fip->field_bit); - tif->tif_flags |= TIFF_DIRTYDIRECT; - return (1); -} - -static void OJPEGPrintDir(TIFF *tif, FILE *fd, long flags) -{ - OJPEGState *sp = (OJPEGState *)tif->tif_data; - uint8_t m; - (void)flags; - assert(sp != NULL); - if (TIFFFieldSet(tif, FIELD_OJPEG_JPEGINTERCHANGEFORMAT)) - fprintf(fd, " JpegInterchangeFormat: %" PRIu64 "\n", - (uint64_t)sp->jpeg_interchange_format); - if (TIFFFieldSet(tif, FIELD_OJPEG_JPEGINTERCHANGEFORMATLENGTH)) - fprintf(fd, " JpegInterchangeFormatLength: %" PRIu64 "\n", - (uint64_t)sp->jpeg_interchange_format_length); - if (TIFFFieldSet(tif, FIELD_OJPEG_JPEGQTABLES)) - { - fprintf(fd, " JpegQTables:"); - for (m = 0; m < sp->qtable_offset_count; m++) - fprintf(fd, " %" PRIu64, (uint64_t)sp->qtable_offset[m]); - fprintf(fd, "\n"); - } - if (TIFFFieldSet(tif, FIELD_OJPEG_JPEGDCTABLES)) - { - fprintf(fd, " JpegDcTables:"); - for (m = 0; m < sp->dctable_offset_count; m++) - fprintf(fd, " %" PRIu64, (uint64_t)sp->dctable_offset[m]); - fprintf(fd, "\n"); - } - if (TIFFFieldSet(tif, FIELD_OJPEG_JPEGACTABLES)) - { - fprintf(fd, " JpegAcTables:"); - for (m = 0; m < sp->actable_offset_count; m++) - fprintf(fd, " %" PRIu64, (uint64_t)sp->actable_offset[m]); - fprintf(fd, "\n"); - } - if (TIFFFieldSet(tif, FIELD_OJPEG_JPEGPROC)) - fprintf(fd, " JpegProc: %" PRIu8 "\n", sp->jpeg_proc); - if (TIFFFieldSet(tif, FIELD_OJPEG_JPEGRESTARTINTERVAL)) - fprintf(fd, " JpegRestartInterval: %" PRIu16 "\n", - sp->restart_interval); - if (sp->printdir) - (*sp->printdir)(tif, fd, flags); -} - -static int OJPEGFixupTags(TIFF *tif) -{ - (void)tif; - return (1); -} - -static int OJPEGSetupDecode(TIFF *tif) -{ - static const char module[] = "OJPEGSetupDecode"; - TIFFWarningExtR(tif, module, - "Deprecated and troublesome old-style JPEG compression " - "mode, please convert to new-style JPEG compression and " - "notify vendor of writing software"); - return (1); -} - -static int OJPEGPreDecode(TIFF *tif, uint16_t s) -{ - OJPEGState *sp = (OJPEGState *)tif->tif_data; - uint32_t m; - if (sp->subsamplingcorrect_done == 0) - OJPEGSubsamplingCorrect(tif); - if (sp->readheader_done == 0) - { - if (OJPEGReadHeaderInfo(tif) == 0) - return (0); - } - if (sp->sos_end[s].log == 0) - { - if (OJPEGReadSecondarySos(tif, s) == 0) - return (0); - } - if (isTiled(tif)) - m = tif->tif_curtile; - else - m = tif->tif_curstrip; - if ((sp->writeheader_done != 0) && - ((sp->write_cursample != s) || (sp->write_curstrile > m))) - { - if (sp->libjpeg_session_active != 0) - OJPEGLibjpegSessionAbort(tif); - sp->writeheader_done = 0; - } - if (sp->writeheader_done == 0) - { - sp->plane_sample_offset = (uint8_t)s; - sp->write_cursample = s; - sp->write_curstrile = s * tif->tif_dir.td_stripsperimage; - if ((sp->in_buffer_file_pos_log == 0) || - (sp->in_buffer_file_pos - sp->in_buffer_togo != - sp->sos_end[s].in_buffer_file_pos)) - { - sp->in_buffer_source = sp->sos_end[s].in_buffer_source; - sp->in_buffer_next_strile = sp->sos_end[s].in_buffer_next_strile; - sp->in_buffer_file_pos = sp->sos_end[s].in_buffer_file_pos; - sp->in_buffer_file_pos_log = 0; - sp->in_buffer_file_togo = sp->sos_end[s].in_buffer_file_togo; - sp->in_buffer_togo = 0; - sp->in_buffer_cur = 0; - } - if (OJPEGWriteHeaderInfo(tif) == 0) - return (0); - } - while (sp->write_curstrile < m) - { - if (sp->libjpeg_jpeg_query_style == 0) - { - if (OJPEGPreDecodeSkipRaw(tif) == 0) - return (0); - } - else - { - if (OJPEGPreDecodeSkipScanlines(tif) == 0) - return (0); - } - sp->write_curstrile++; - } - sp->decoder_ok = 1; - return (1); -} - -static int OJPEGPreDecodeSkipRaw(TIFF *tif) -{ - OJPEGState *sp = (OJPEGState *)tif->tif_data; - uint32_t m; - m = sp->lines_per_strile; - if (sp->subsampling_convert_state != 0) - { - if (sp->subsampling_convert_clines - sp->subsampling_convert_state >= m) - { - sp->subsampling_convert_state += m; - if (sp->subsampling_convert_state == sp->subsampling_convert_clines) - sp->subsampling_convert_state = 0; - return (1); - } - m -= sp->subsampling_convert_clines - sp->subsampling_convert_state; - sp->subsampling_convert_state = 0; - sp->error_in_raw_data_decoding = 0; - } - while (m >= sp->subsampling_convert_clines) - { - if (jpeg_read_raw_data_encap(sp, &(sp->libjpeg_jpeg_decompress_struct), - sp->subsampling_convert_ycbcrimage, - sp->subsampling_ver * 8) == 0) - return (0); - m -= sp->subsampling_convert_clines; - } - if (m > 0) - { - if (jpeg_read_raw_data_encap(sp, &(sp->libjpeg_jpeg_decompress_struct), - sp->subsampling_convert_ycbcrimage, - sp->subsampling_ver * 8) == 0) - return (0); - sp->subsampling_convert_state = m; - } - return (1); -} - -static int OJPEGPreDecodeSkipScanlines(TIFF *tif) -{ - static const char module[] = "OJPEGPreDecodeSkipScanlines"; - OJPEGState *sp = (OJPEGState *)tif->tif_data; - uint32_t m; - if (sp->skip_buffer == NULL) - { - sp->skip_buffer = _TIFFmallocExt(tif, sp->bytes_per_line); - if (sp->skip_buffer == NULL) - { - TIFFErrorExtR(tif, module, "Out of memory"); - return (0); - } - } - for (m = 0; m < sp->lines_per_strile; m++) - { - if (jpeg_read_scanlines_encap(sp, &(sp->libjpeg_jpeg_decompress_struct), - &sp->skip_buffer, 1) == 0) - return (0); - } - return (1); -} - -static int OJPEGDecode(TIFF *tif, uint8_t *buf, tmsize_t cc, uint16_t s) -{ - static const char module[] = "OJPEGDecode"; - OJPEGState *sp = (OJPEGState *)tif->tif_data; - (void)s; - if (!sp->decoder_ok) - { - TIFFErrorExtR(tif, module, - "Cannot decode: decoder not correctly initialized"); - return 0; - } - if (sp->libjpeg_session_active == 0) - { - /* This should normally not happen, except that it does when */ - /* using TIFFReadScanline() which calls OJPEGPostDecode() for */ - /* each scanline, which assumes that a whole strile was read */ - /* and may thus incorrectly consider it has read the whole image, - * causing */ - /* OJPEGLibjpegSessionAbort() to be called prematurely. */ - /* Triggered by https://gitlab.com/libtiff/libtiff/-/issues/337 */ - TIFFErrorExtR(tif, module, - "Cannot decode: libjpeg_session_active == 0"); - return 0; - } - if (sp->error_in_raw_data_decoding) - { - return 0; - } - if (sp->libjpeg_jpeg_query_style == 0) - { - if (OJPEGDecodeRaw(tif, buf, cc) == 0) - return (0); - } - else - { - if (OJPEGDecodeScanlines(tif, buf, cc) == 0) - return (0); - } - return (1); -} - -static int OJPEGDecodeRaw(TIFF *tif, uint8_t *buf, tmsize_t cc) -{ - static const char module[] = "OJPEGDecodeRaw"; - OJPEGState *sp = (OJPEGState *)tif->tif_data; - uint8_t *m; - tmsize_t n; - uint8_t *oy; - uint8_t *ocb; - uint8_t *ocr; - uint8_t *p; - uint32_t q; - uint8_t *r; - uint8_t sx, sy; - if (cc % sp->bytes_per_line != 0) - { - TIFFErrorExtR(tif, module, "Fractional scanline not read"); - return (0); - } - assert(cc > 0); - m = buf; - n = cc; - do - { - if (sp->subsampling_convert_state == 0) - { - if (jpeg_read_raw_data_encap(sp, - &(sp->libjpeg_jpeg_decompress_struct), - sp->subsampling_convert_ycbcrimage, - sp->subsampling_ver * 8) == 0) - { - sp->error_in_raw_data_decoding = 1; - return (0); - } - } - oy = sp->subsampling_convert_ybuf + - sp->subsampling_convert_state * sp->subsampling_ver * - sp->subsampling_convert_ylinelen; - ocb = sp->subsampling_convert_cbbuf + - sp->subsampling_convert_state * sp->subsampling_convert_clinelen; - ocr = sp->subsampling_convert_crbuf + - sp->subsampling_convert_state * sp->subsampling_convert_clinelen; - p = m; - for (q = 0; q < sp->subsampling_convert_clinelenout; q++) - { - r = oy; - for (sy = 0; sy < sp->subsampling_ver; sy++) - { - for (sx = 0; sx < sp->subsampling_hor; sx++) - *p++ = *r++; - r += sp->subsampling_convert_ylinelen - sp->subsampling_hor; - } - oy += sp->subsampling_hor; - *p++ = *ocb++; - *p++ = *ocr++; - } - sp->subsampling_convert_state++; - if (sp->subsampling_convert_state == sp->subsampling_convert_clines) - sp->subsampling_convert_state = 0; - m += sp->bytes_per_line; - n -= sp->bytes_per_line; - } while (n > 0); - return (1); -} - -static int OJPEGDecodeScanlines(TIFF *tif, uint8_t *buf, tmsize_t cc) -{ - static const char module[] = "OJPEGDecodeScanlines"; - OJPEGState *sp = (OJPEGState *)tif->tif_data; - uint8_t *m; - tmsize_t n; - if (cc % sp->bytes_per_line != 0) - { - TIFFErrorExtR(tif, module, "Fractional scanline not read"); - return (0); - } - assert(cc > 0); - m = buf; - n = cc; - do - { - if (jpeg_read_scanlines_encap(sp, &(sp->libjpeg_jpeg_decompress_struct), - &m, 1) == 0) - return (0); - m += sp->bytes_per_line; - n -= sp->bytes_per_line; - } while (n > 0); - return (1); -} - -static void OJPEGPostDecode(TIFF *tif, uint8_t *buf, tmsize_t cc) -{ - OJPEGState *sp = (OJPEGState *)tif->tif_data; - (void)buf; - (void)cc; - /* This function somehow incorrectly assumes that a whole strile was read, - */ - /* which is not true when TIFFReadScanline() is called, */ - /* and may thus incorrectly consider it has read the whole image, causing */ - /* OJPEGLibjpegSessionAbort() to be called prematurely. */ - /* So this logic should be fixed to take into account cc, or disable */ - /* the scan line reading interface. */ - /* Triggered by https://gitlab.com/libtiff/libtiff/-/issues/337 */ - sp->write_curstrile++; - if (sp->write_curstrile % tif->tif_dir.td_stripsperimage == 0) - { - assert(sp->libjpeg_session_active != 0); - OJPEGLibjpegSessionAbort(tif); - sp->writeheader_done = 0; - } -} - -static int OJPEGSetupEncode(TIFF *tif) -{ - static const char module[] = "OJPEGSetupEncode"; - TIFFErrorExtR( - tif, module, - "OJPEG encoding not supported; use new-style JPEG compression instead"); - return (0); -} - -static int OJPEGPreEncode(TIFF *tif, uint16_t s) -{ - static const char module[] = "OJPEGPreEncode"; - (void)s; - TIFFErrorExtR( - tif, module, - "OJPEG encoding not supported; use new-style JPEG compression instead"); - return (0); -} - -static int OJPEGEncode(TIFF *tif, uint8_t *buf, tmsize_t cc, uint16_t s) -{ - static const char module[] = "OJPEGEncode"; - (void)buf; - (void)cc; - (void)s; - TIFFErrorExtR( - tif, module, - "OJPEG encoding not supported; use new-style JPEG compression instead"); - return (0); -} - -static int OJPEGPostEncode(TIFF *tif) -{ - static const char module[] = "OJPEGPostEncode"; - TIFFErrorExtR( - tif, module, - "OJPEG encoding not supported; use new-style JPEG compression instead"); - return (0); -} - -static void OJPEGCleanup(TIFF *tif) -{ - OJPEGState *sp = (OJPEGState *)tif->tif_data; - if (sp != 0) - { - tif->tif_tagmethods.vgetfield = sp->vgetparent; - tif->tif_tagmethods.vsetfield = sp->vsetparent; - tif->tif_tagmethods.printdir = sp->printdir; - if (sp->qtable[0] != 0) - _TIFFfreeExt(tif, sp->qtable[0]); - if (sp->qtable[1] != 0) - _TIFFfreeExt(tif, sp->qtable[1]); - if (sp->qtable[2] != 0) - _TIFFfreeExt(tif, sp->qtable[2]); - if (sp->qtable[3] != 0) - _TIFFfreeExt(tif, sp->qtable[3]); - if (sp->dctable[0] != 0) - _TIFFfreeExt(tif, sp->dctable[0]); - if (sp->dctable[1] != 0) - _TIFFfreeExt(tif, sp->dctable[1]); - if (sp->dctable[2] != 0) - _TIFFfreeExt(tif, sp->dctable[2]); - if (sp->dctable[3] != 0) - _TIFFfreeExt(tif, sp->dctable[3]); - if (sp->actable[0] != 0) - _TIFFfreeExt(tif, sp->actable[0]); - if (sp->actable[1] != 0) - _TIFFfreeExt(tif, sp->actable[1]); - if (sp->actable[2] != 0) - _TIFFfreeExt(tif, sp->actable[2]); - if (sp->actable[3] != 0) - _TIFFfreeExt(tif, sp->actable[3]); - if (sp->libjpeg_session_active != 0) - OJPEGLibjpegSessionAbort(tif); - if (sp->subsampling_convert_ycbcrbuf != 0) - _TIFFfreeExt(tif, sp->subsampling_convert_ycbcrbuf); - if (sp->subsampling_convert_ycbcrimage != 0) - _TIFFfreeExt(tif, sp->subsampling_convert_ycbcrimage); - if (sp->skip_buffer != 0) - _TIFFfreeExt(tif, sp->skip_buffer); - _TIFFfreeExt(tif, sp); - tif->tif_data = NULL; - _TIFFSetDefaultCompressionState(tif); - } -} - -static void OJPEGSubsamplingCorrect(TIFF *tif) -{ - static const char module[] = "OJPEGSubsamplingCorrect"; - OJPEGState *sp = (OJPEGState *)tif->tif_data; - uint8_t mh; - uint8_t mv; - - assert(sp->subsamplingcorrect_done == 0); - if ((tif->tif_dir.td_samplesperpixel != 3) || - ((tif->tif_dir.td_photometric != PHOTOMETRIC_YCBCR) && - (tif->tif_dir.td_photometric != PHOTOMETRIC_ITULAB))) - { - if (sp->subsampling_tag != 0) - TIFFWarningExtR(tif, module, - "Subsampling tag not appropriate for this " - "Photometric and/or SamplesPerPixel"); - sp->subsampling_hor = 1; - sp->subsampling_ver = 1; - sp->subsampling_force_desubsampling_inside_decompression = 0; - } - else - { - sp->subsamplingcorrect_done = 1; - mh = sp->subsampling_hor; - mv = sp->subsampling_ver; - sp->subsamplingcorrect = 1; - OJPEGReadHeaderInfoSec(tif); - if (sp->subsampling_force_desubsampling_inside_decompression != 0) - { - sp->subsampling_hor = 1; - sp->subsampling_ver = 1; - } - sp->subsamplingcorrect = 0; - if (((sp->subsampling_hor != mh) || (sp->subsampling_ver != mv)) && - (sp->subsampling_force_desubsampling_inside_decompression == 0)) - { - if (sp->subsampling_tag == 0) - TIFFWarningExtR( - tif, module, - "Subsampling tag is not set, yet subsampling inside JPEG " - "data [%" PRIu8 ",%" PRIu8 - "] does not match default values [2,2]; assuming " - "subsampling inside JPEG data is correct", - sp->subsampling_hor, sp->subsampling_ver); - else - TIFFWarningExtR( - tif, module, - "Subsampling inside JPEG data [%" PRIu8 ",%" PRIu8 - "] does not match subsampling tag values [%" PRIu8 - ",%" PRIu8 - "]; assuming subsampling inside JPEG data is correct", - sp->subsampling_hor, sp->subsampling_ver, mh, mv); - } - if (sp->subsampling_force_desubsampling_inside_decompression != 0) - { - if (sp->subsampling_tag == 0) - TIFFWarningExtR( - tif, module, - "Subsampling tag is not set, yet subsampling inside JPEG " - "data does not match default values [2,2] (nor any other " - "values allowed in TIFF); assuming subsampling inside JPEG " - "data is correct and desubsampling inside JPEG " - "decompression"); - else - TIFFWarningExtR( - tif, module, - "Subsampling inside JPEG data does not match subsampling " - "tag values [%" PRIu8 ",%" PRIu8 - "] (nor any other values allowed in TIFF); assuming " - "subsampling inside JPEG data is correct and desubsampling " - "inside JPEG decompression", - mh, mv); - } - if (sp->subsampling_force_desubsampling_inside_decompression == 0) - { - if (sp->subsampling_hor < sp->subsampling_ver) - TIFFWarningExtR(tif, module, - "Subsampling values [%" PRIu8 ",%" PRIu8 - "] are not allowed in TIFF", - sp->subsampling_hor, sp->subsampling_ver); - } - } - sp->subsamplingcorrect_done = 1; -} - -static int OJPEGReadHeaderInfo(TIFF *tif) -{ - static const char module[] = "OJPEGReadHeaderInfo"; - OJPEGState *sp = (OJPEGState *)tif->tif_data; - assert(sp->readheader_done == 0); - sp->image_width = tif->tif_dir.td_imagewidth; - sp->image_length = tif->tif_dir.td_imagelength; - if (isTiled(tif)) - { - sp->strile_width = tif->tif_dir.td_tilewidth; - sp->strile_length = tif->tif_dir.td_tilelength; - sp->strile_length_total = - ((sp->image_length + sp->strile_length - 1) / sp->strile_length) * - sp->strile_length; - } - else - { - sp->strile_width = sp->image_width; - sp->strile_length = tif->tif_dir.td_rowsperstrip; - if (sp->strile_length == (uint32_t)-1) - sp->strile_length = sp->image_length; - sp->strile_length_total = sp->image_length; - } - if (tif->tif_dir.td_samplesperpixel == 1) - { - sp->samples_per_pixel = 1; - sp->plane_sample_offset = 0; - sp->samples_per_pixel_per_plane = sp->samples_per_pixel; - sp->subsampling_hor = 1; - sp->subsampling_ver = 1; - } - else - { - if (tif->tif_dir.td_samplesperpixel != 3) - { - TIFFErrorExtR(tif, module, - "SamplesPerPixel %" PRIu8 - " not supported for this compression scheme", - sp->samples_per_pixel); - return (0); - } - sp->samples_per_pixel = 3; - sp->plane_sample_offset = 0; - if (tif->tif_dir.td_planarconfig == PLANARCONFIG_CONTIG) - sp->samples_per_pixel_per_plane = 3; - else - sp->samples_per_pixel_per_plane = 1; - } - if (sp->strile_length < sp->image_length) - { - if (((sp->subsampling_hor != 1) && (sp->subsampling_hor != 2) && - (sp->subsampling_hor != 4)) || - ((sp->subsampling_ver != 1) && (sp->subsampling_ver != 2) && - (sp->subsampling_ver != 4))) - { - TIFFErrorExtR(tif, module, "Invalid subsampling values"); - return (0); - } - if (sp->strile_length % (sp->subsampling_ver * 8) != 0) - { - TIFFErrorExtR(tif, module, - "Incompatible vertical subsampling and image " - "strip/tile length"); - return (0); - } - sp->restart_interval = - (uint16_t)(((sp->strile_width + sp->subsampling_hor * 8 - 1) / - (sp->subsampling_hor * 8)) * - (sp->strile_length / (sp->subsampling_ver * 8))); - } - if (OJPEGReadHeaderInfoSec(tif) == 0) - return (0); - sp->sos_end[0].log = 1; - sp->sos_end[0].in_buffer_source = sp->in_buffer_source; - sp->sos_end[0].in_buffer_next_strile = sp->in_buffer_next_strile; - sp->sos_end[0].in_buffer_file_pos = - sp->in_buffer_file_pos - sp->in_buffer_togo; - sp->sos_end[0].in_buffer_file_togo = - sp->in_buffer_file_togo + sp->in_buffer_togo; - sp->readheader_done = 1; - return (1); -} - -static int OJPEGReadSecondarySos(TIFF *tif, uint16_t s) -{ - OJPEGState *sp = (OJPEGState *)tif->tif_data; - uint8_t m; - assert(s > 0); - assert(s < 3); - assert(sp->sos_end[0].log != 0); - assert(sp->sos_end[s].log == 0); - sp->plane_sample_offset = (uint8_t)(s - 1); - while (sp->sos_end[sp->plane_sample_offset].log == 0) - sp->plane_sample_offset--; - sp->in_buffer_source = - sp->sos_end[sp->plane_sample_offset].in_buffer_source; - sp->in_buffer_next_strile = - sp->sos_end[sp->plane_sample_offset].in_buffer_next_strile; - sp->in_buffer_file_pos = - sp->sos_end[sp->plane_sample_offset].in_buffer_file_pos; - sp->in_buffer_file_pos_log = 0; - sp->in_buffer_file_togo = - sp->sos_end[sp->plane_sample_offset].in_buffer_file_togo; - sp->in_buffer_togo = 0; - sp->in_buffer_cur = 0; - while (sp->plane_sample_offset < s) - { - do - { - if (OJPEGReadByte(sp, &m) == 0) - return (0); - if (m == 255) - { - do - { - if (OJPEGReadByte(sp, &m) == 0) - return (0); - if (m != 255) - break; - } while (1); - if (m == JPEG_MARKER_SOS) - break; - } - } while (1); - sp->plane_sample_offset++; - if (OJPEGReadHeaderInfoSecStreamSos(tif) == 0) - return (0); - sp->sos_end[sp->plane_sample_offset].log = 1; - sp->sos_end[sp->plane_sample_offset].in_buffer_source = - sp->in_buffer_source; - sp->sos_end[sp->plane_sample_offset].in_buffer_next_strile = - sp->in_buffer_next_strile; - sp->sos_end[sp->plane_sample_offset].in_buffer_file_pos = - sp->in_buffer_file_pos - sp->in_buffer_togo; - sp->sos_end[sp->plane_sample_offset].in_buffer_file_togo = - sp->in_buffer_file_togo + sp->in_buffer_togo; - } - return (1); -} - -static int OJPEGWriteHeaderInfo(TIFF *tif) -{ - static const char module[] = "OJPEGWriteHeaderInfo"; - OJPEGState *sp = (OJPEGState *)tif->tif_data; - uint8_t **m; - uint32_t n; - /* if a previous attempt failed, don't try again */ - if (sp->libjpeg_session_active != 0) - return 0; - sp->out_state = ososSoi; - sp->restart_index = 0; - jpeg_std_error(&(sp->libjpeg_jpeg_error_mgr)); - sp->libjpeg_jpeg_error_mgr.output_message = - OJPEGLibjpegJpegErrorMgrOutputMessage; - sp->libjpeg_jpeg_error_mgr.error_exit = OJPEGLibjpegJpegErrorMgrErrorExit; - sp->libjpeg_jpeg_decompress_struct.err = &(sp->libjpeg_jpeg_error_mgr); - sp->libjpeg_jpeg_decompress_struct.client_data = (void *)tif; - if (jpeg_create_decompress_encap( - sp, &(sp->libjpeg_jpeg_decompress_struct)) == 0) - return (0); - sp->libjpeg_session_active = 1; - sp->libjpeg_jpeg_source_mgr.bytes_in_buffer = 0; - sp->libjpeg_jpeg_source_mgr.init_source = - OJPEGLibjpegJpegSourceMgrInitSource; - sp->libjpeg_jpeg_source_mgr.fill_input_buffer = - OJPEGLibjpegJpegSourceMgrFillInputBuffer; - sp->libjpeg_jpeg_source_mgr.skip_input_data = - OJPEGLibjpegJpegSourceMgrSkipInputData; - sp->libjpeg_jpeg_source_mgr.resync_to_restart = - OJPEGLibjpegJpegSourceMgrResyncToRestart; - sp->libjpeg_jpeg_source_mgr.term_source = - OJPEGLibjpegJpegSourceMgrTermSource; - sp->libjpeg_jpeg_decompress_struct.src = &(sp->libjpeg_jpeg_source_mgr); - if (jpeg_read_header_encap(sp, &(sp->libjpeg_jpeg_decompress_struct), 1) == - 0) - return (0); - if ((sp->subsampling_force_desubsampling_inside_decompression == 0) && - (sp->samples_per_pixel_per_plane > 1)) - { - sp->libjpeg_jpeg_decompress_struct.raw_data_out = 1; -#if JPEG_LIB_VERSION >= 70 - sp->libjpeg_jpeg_decompress_struct.do_fancy_upsampling = FALSE; -#endif - sp->libjpeg_jpeg_query_style = 0; - if (sp->subsampling_convert_log == 0) - { - assert(sp->subsampling_convert_ycbcrbuf == 0); - assert(sp->subsampling_convert_ycbcrimage == 0); - /* Check for division by zero. */ - if (sp->subsampling_hor == 0 || sp->subsampling_ver == 0) - return (0); - sp->subsampling_convert_ylinelen = - ((sp->strile_width + sp->subsampling_hor * 8 - 1) / - (sp->subsampling_hor * 8) * sp->subsampling_hor * 8); - sp->subsampling_convert_ylines = sp->subsampling_ver * 8; - sp->subsampling_convert_clinelen = - sp->subsampling_convert_ylinelen / sp->subsampling_hor; - sp->subsampling_convert_clines = 8; - sp->subsampling_convert_ybuflen = sp->subsampling_convert_ylinelen * - sp->subsampling_convert_ylines; - sp->subsampling_convert_cbuflen = sp->subsampling_convert_clinelen * - sp->subsampling_convert_clines; - sp->subsampling_convert_ycbcrbuflen = - sp->subsampling_convert_ybuflen + - 2 * sp->subsampling_convert_cbuflen; - /* The calloc is not normally necessary, except in some edge/broken - * cases */ - /* for example for a tiled image of height 1 with a tile height of 1 - * and subsampling_hor=subsampling_ver=2 */ - /* In that case, libjpeg will only fill the 8 first lines of the 16 - * lines */ - /* See https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=16844 - */ - /* Even if this case is allowed (?), its handling is broken because - * OJPEGPreDecode() should also likely */ - /* reset subsampling_convert_state to 0 when changing tile. */ - sp->subsampling_convert_ycbcrbuf = - _TIFFcallocExt(tif, 1, sp->subsampling_convert_ycbcrbuflen); - if (sp->subsampling_convert_ycbcrbuf == 0) - { - TIFFErrorExtR(tif, module, "Out of memory"); - return (0); - } - sp->subsampling_convert_ybuf = sp->subsampling_convert_ycbcrbuf; - sp->subsampling_convert_cbbuf = - sp->subsampling_convert_ybuf + sp->subsampling_convert_ybuflen; - sp->subsampling_convert_crbuf = - sp->subsampling_convert_cbbuf + sp->subsampling_convert_cbuflen; - sp->subsampling_convert_ycbcrimagelen = - 3 + sp->subsampling_convert_ylines + - 2 * sp->subsampling_convert_clines; - sp->subsampling_convert_ycbcrimage = _TIFFmallocExt( - tif, sp->subsampling_convert_ycbcrimagelen * sizeof(uint8_t *)); - if (sp->subsampling_convert_ycbcrimage == 0) - { - TIFFErrorExtR(tif, module, "Out of memory"); - return (0); - } - m = sp->subsampling_convert_ycbcrimage; - *m++ = (uint8_t *)(sp->subsampling_convert_ycbcrimage + 3); - *m++ = (uint8_t *)(sp->subsampling_convert_ycbcrimage + 3 + - sp->subsampling_convert_ylines); - *m++ = (uint8_t *)(sp->subsampling_convert_ycbcrimage + 3 + - sp->subsampling_convert_ylines + - sp->subsampling_convert_clines); - for (n = 0; n < sp->subsampling_convert_ylines; n++) - *m++ = sp->subsampling_convert_ybuf + - n * sp->subsampling_convert_ylinelen; - for (n = 0; n < sp->subsampling_convert_clines; n++) - *m++ = sp->subsampling_convert_cbbuf + - n * sp->subsampling_convert_clinelen; - for (n = 0; n < sp->subsampling_convert_clines; n++) - *m++ = sp->subsampling_convert_crbuf + - n * sp->subsampling_convert_clinelen; - sp->subsampling_convert_clinelenout = - sp->strile_width / sp->subsampling_hor + - ((sp->strile_width % sp->subsampling_hor) != 0 ? 1 : 0); - sp->subsampling_convert_state = 0; - sp->error_in_raw_data_decoding = 0; - sp->bytes_per_line = - sp->subsampling_convert_clinelenout * - (sp->subsampling_ver * sp->subsampling_hor + 2); - sp->lines_per_strile = - sp->strile_length / sp->subsampling_ver + - ((sp->strile_length % sp->subsampling_ver) != 0 ? 1 : 0); - sp->subsampling_convert_log = 1; - } - } - else - { - sp->libjpeg_jpeg_decompress_struct.jpeg_color_space = JCS_UNKNOWN; - sp->libjpeg_jpeg_decompress_struct.out_color_space = JCS_UNKNOWN; - sp->libjpeg_jpeg_query_style = 1; - sp->bytes_per_line = sp->samples_per_pixel_per_plane * sp->strile_width; - sp->lines_per_strile = sp->strile_length; - } - if (jpeg_start_decompress_encap(sp, - &(sp->libjpeg_jpeg_decompress_struct)) == 0) - return (0); - if (sp->libjpeg_jpeg_decompress_struct.image_width != sp->strile_width) - { - TIFFErrorExtR(tif, module, - "jpeg_start_decompress() returned image_width = %u, " - "expected %" PRIu32, - sp->libjpeg_jpeg_decompress_struct.image_width, - sp->strile_width); - return 0; - } - if (sp->libjpeg_jpeg_decompress_struct.max_h_samp_factor != - sp->subsampling_hor || - sp->libjpeg_jpeg_decompress_struct.max_v_samp_factor != - sp->subsampling_ver) - { - TIFFErrorExtR(tif, module, - "jpeg_start_decompress() returned max_h_samp_factor = %d " - "and max_v_samp_factor = %d, expected %" PRIu8 - " and %" PRIu8, - sp->libjpeg_jpeg_decompress_struct.max_h_samp_factor, - sp->libjpeg_jpeg_decompress_struct.max_v_samp_factor, - sp->subsampling_hor, sp->subsampling_ver); - return 0; - } - - sp->writeheader_done = 1; - return (1); -} - -static void OJPEGLibjpegSessionAbort(TIFF *tif) -{ - OJPEGState *sp = (OJPEGState *)tif->tif_data; - assert(sp->libjpeg_session_active != 0); - jpeg_destroy((jpeg_common_struct *)(&(sp->libjpeg_jpeg_decompress_struct))); - sp->libjpeg_session_active = 0; -} - -static int OJPEGReadHeaderInfoSec(TIFF *tif) -{ - static const char module[] = "OJPEGReadHeaderInfoSec"; - OJPEGState *sp = (OJPEGState *)tif->tif_data; - uint8_t m; - uint16_t n; - uint8_t o; - if (sp->file_size == 0) - sp->file_size = TIFFGetFileSize(tif); - if (sp->jpeg_interchange_format != 0) - { - if (sp->jpeg_interchange_format >= sp->file_size) - { - sp->jpeg_interchange_format = 0; - sp->jpeg_interchange_format_length = 0; - } - else - { - if ((sp->jpeg_interchange_format_length == 0) || - (sp->jpeg_interchange_format > - UINT64_MAX - sp->jpeg_interchange_format_length) || - (sp->jpeg_interchange_format + - sp->jpeg_interchange_format_length > - sp->file_size)) - sp->jpeg_interchange_format_length = - sp->file_size - sp->jpeg_interchange_format; - } - } - sp->in_buffer_source = osibsNotSetYet; - sp->in_buffer_next_strile = 0; - sp->in_buffer_strile_count = tif->tif_dir.td_nstrips; - sp->in_buffer_file_togo = 0; - sp->in_buffer_togo = 0; - do - { - if (OJPEGReadBytePeek(sp, &m) == 0) - return (0); - if (m != 255) - break; - OJPEGReadByteAdvance(sp); - do - { - if (OJPEGReadByte(sp, &m) == 0) - return (0); - } while (m == 255); - switch (m) - { - case JPEG_MARKER_SOI: - /* this type of marker has no data, and should be skipped */ - break; - case JPEG_MARKER_COM: - case JPEG_MARKER_APP0: - case JPEG_MARKER_APP0 + 1: - case JPEG_MARKER_APP0 + 2: - case JPEG_MARKER_APP0 + 3: - case JPEG_MARKER_APP0 + 4: - case JPEG_MARKER_APP0 + 5: - case JPEG_MARKER_APP0 + 6: - case JPEG_MARKER_APP0 + 7: - case JPEG_MARKER_APP0 + 8: - case JPEG_MARKER_APP0 + 9: - case JPEG_MARKER_APP0 + 10: - case JPEG_MARKER_APP0 + 11: - case JPEG_MARKER_APP0 + 12: - case JPEG_MARKER_APP0 + 13: - case JPEG_MARKER_APP0 + 14: - case JPEG_MARKER_APP0 + 15: - /* this type of marker has data, but it has no use to us (and no - * place here) and should be skipped */ - if (OJPEGReadWord(sp, &n) == 0) - return (0); - if (n < 2) - { - if (sp->subsamplingcorrect == 0) - TIFFErrorExtR(tif, module, "Corrupt JPEG data"); - return (0); - } - if (n > 2) - OJPEGReadSkip(sp, n - 2); - break; - case JPEG_MARKER_DRI: - if (OJPEGReadHeaderInfoSecStreamDri(tif) == 0) - return (0); - break; - case JPEG_MARKER_DQT: - if (OJPEGReadHeaderInfoSecStreamDqt(tif) == 0) - return (0); - break; - case JPEG_MARKER_DHT: - if (OJPEGReadHeaderInfoSecStreamDht(tif) == 0) - return (0); - break; - case JPEG_MARKER_SOF0: - case JPEG_MARKER_SOF1: - case JPEG_MARKER_SOF3: - if (OJPEGReadHeaderInfoSecStreamSof(tif, m) == 0) - return (0); - if (sp->subsamplingcorrect != 0) - return (1); - break; - case JPEG_MARKER_SOS: - if (sp->subsamplingcorrect != 0) - return (1); - assert(sp->plane_sample_offset == 0); - if (OJPEGReadHeaderInfoSecStreamSos(tif) == 0) - return (0); - break; - default: - TIFFErrorExtR(tif, module, - "Unknown marker type %" PRIu8 " in JPEG data", m); - return (0); - } - } while (m != JPEG_MARKER_SOS); - if (sp->subsamplingcorrect) - return (1); - if (sp->sof_log == 0) - { - if (OJPEGReadHeaderInfoSecTablesQTable(tif) == 0) - return (0); - sp->sof_marker_id = JPEG_MARKER_SOF0; - for (o = 0; o < sp->samples_per_pixel; o++) - sp->sof_c[o] = o; - sp->sof_hv[0] = ((sp->subsampling_hor << 4) | sp->subsampling_ver); - for (o = 1; o < sp->samples_per_pixel; o++) - sp->sof_hv[o] = 17; - sp->sof_x = sp->strile_width; - sp->sof_y = sp->strile_length_total; - sp->sof_log = 1; - if (OJPEGReadHeaderInfoSecTablesDcTable(tif) == 0) - return (0); - if (OJPEGReadHeaderInfoSecTablesAcTable(tif) == 0) - return (0); - for (o = 1; o < sp->samples_per_pixel; o++) - sp->sos_cs[o] = o; - } - return (1); -} - -static int OJPEGReadHeaderInfoSecStreamDri(TIFF *tif) -{ - /* This could easily cause trouble in some cases... but no such cases have - occurred so far */ - static const char module[] = "OJPEGReadHeaderInfoSecStreamDri"; - OJPEGState *sp = (OJPEGState *)tif->tif_data; - uint16_t m; - if (OJPEGReadWord(sp, &m) == 0) - return (0); - if (m != 4) - { - TIFFErrorExtR(tif, module, "Corrupt DRI marker in JPEG data"); - return (0); - } - if (OJPEGReadWord(sp, &m) == 0) - return (0); - sp->restart_interval = m; - return (1); -} - -static int OJPEGReadHeaderInfoSecStreamDqt(TIFF *tif) -{ - /* this is a table marker, and it is to be saved as a whole for exact - * pushing on the jpeg stream later on */ - static const char module[] = "OJPEGReadHeaderInfoSecStreamDqt"; - OJPEGState *sp = (OJPEGState *)tif->tif_data; - uint16_t m; - uint32_t na; - uint8_t *nb; - uint8_t o; - if (OJPEGReadWord(sp, &m) == 0) - return (0); - if (m <= 2) - { - if (sp->subsamplingcorrect == 0) - TIFFErrorExtR(tif, module, "Corrupt DQT marker in JPEG data"); - return (0); - } - if (sp->subsamplingcorrect != 0) - OJPEGReadSkip(sp, m - 2); - else - { - m -= 2; - do - { - if (m < 65) - { - TIFFErrorExtR(tif, module, "Corrupt DQT marker in JPEG data"); - return (0); - } - na = sizeof(uint32_t) + 69; - nb = _TIFFmallocExt(tif, na); - if (nb == 0) - { - TIFFErrorExtR(tif, module, "Out of memory"); - return (0); - } - *(uint32_t *)nb = na; - nb[sizeof(uint32_t)] = 255; - nb[sizeof(uint32_t) + 1] = JPEG_MARKER_DQT; - nb[sizeof(uint32_t) + 2] = 0; - nb[sizeof(uint32_t) + 3] = 67; - if (OJPEGReadBlock(sp, 65, &nb[sizeof(uint32_t) + 4]) == 0) - { - _TIFFfreeExt(tif, nb); - return (0); - } - o = nb[sizeof(uint32_t) + 4] & 15; - if (3 < o) - { - TIFFErrorExtR(tif, module, "Corrupt DQT marker in JPEG data"); - _TIFFfreeExt(tif, nb); - return (0); - } - if (sp->qtable[o] != 0) - _TIFFfreeExt(tif, sp->qtable[o]); - sp->qtable[o] = nb; - m -= 65; - } while (m > 0); - } - return (1); -} - -static int OJPEGReadHeaderInfoSecStreamDht(TIFF *tif) -{ - /* this is a table marker, and it is to be saved as a whole for exact - * pushing on the jpeg stream later on */ - /* TODO: the following assumes there is only one table in this marker... but - * i'm not quite sure that assumption is guaranteed correct */ - static const char module[] = "OJPEGReadHeaderInfoSecStreamDht"; - OJPEGState *sp = (OJPEGState *)tif->tif_data; - uint16_t m; - uint32_t na; - uint8_t *nb; - uint8_t o; - if (OJPEGReadWord(sp, &m) == 0) - return (0); - if (m <= 2) - { - if (sp->subsamplingcorrect == 0) - TIFFErrorExtR(tif, module, "Corrupt DHT marker in JPEG data"); - return (0); - } - if (sp->subsamplingcorrect != 0) - { - OJPEGReadSkip(sp, m - 2); - } - else - { - na = sizeof(uint32_t) + 2 + m; - nb = _TIFFmallocExt(tif, na); - if (nb == 0) - { - TIFFErrorExtR(tif, module, "Out of memory"); - return (0); - } - *(uint32_t *)nb = na; - nb[sizeof(uint32_t)] = 255; - nb[sizeof(uint32_t) + 1] = JPEG_MARKER_DHT; - nb[sizeof(uint32_t) + 2] = (m >> 8); - nb[sizeof(uint32_t) + 3] = (m & 255); - if (OJPEGReadBlock(sp, m - 2, &nb[sizeof(uint32_t) + 4]) == 0) - { - _TIFFfreeExt(tif, nb); - return (0); - } - o = nb[sizeof(uint32_t) + 4]; - if ((o & 240) == 0) - { - if (3 < o) - { - TIFFErrorExtR(tif, module, "Corrupt DHT marker in JPEG data"); - _TIFFfreeExt(tif, nb); - return (0); - } - if (sp->dctable[o] != 0) - _TIFFfreeExt(tif, sp->dctable[o]); - sp->dctable[o] = nb; - } - else - { - if ((o & 240) != 16) - { - TIFFErrorExtR(tif, module, "Corrupt DHT marker in JPEG data"); - _TIFFfreeExt(tif, nb); - return (0); - } - o &= 15; - if (3 < o) - { - TIFFErrorExtR(tif, module, "Corrupt DHT marker in JPEG data"); - _TIFFfreeExt(tif, nb); - return (0); - } - if (sp->actable[o] != 0) - _TIFFfreeExt(tif, sp->actable[o]); - sp->actable[o] = nb; - } - } - return (1); -} - -static int OJPEGReadHeaderInfoSecStreamSof(TIFF *tif, uint8_t marker_id) -{ - /* this marker needs to be checked, and part of its data needs to be saved - * for regeneration later on */ - static const char module[] = "OJPEGReadHeaderInfoSecStreamSof"; - OJPEGState *sp = (OJPEGState *)tif->tif_data; - uint16_t m; - uint16_t n; - uint8_t o; - uint16_t p; - uint16_t q; - if (sp->sof_log != 0) - { - TIFFErrorExtR(tif, module, "Corrupt JPEG data"); - return (0); - } - if (sp->subsamplingcorrect == 0) - sp->sof_marker_id = marker_id; - /* Lf: data length */ - if (OJPEGReadWord(sp, &m) == 0) - return (0); - if (m < 11) - { - if (sp->subsamplingcorrect == 0) - TIFFErrorExtR(tif, module, "Corrupt SOF marker in JPEG data"); - return (0); - } - m -= 8; - if (m % 3 != 0) - { - if (sp->subsamplingcorrect == 0) - TIFFErrorExtR(tif, module, "Corrupt SOF marker in JPEG data"); - return (0); - } - n = m / 3; - if (sp->subsamplingcorrect == 0) - { - if (n != sp->samples_per_pixel) - { - TIFFErrorExtR( - tif, module, - "JPEG compressed data indicates unexpected number of samples"); - return (0); - } - } - /* P: Sample precision */ - if (OJPEGReadByte(sp, &o) == 0) - return (0); - if (o != 8) - { - if (sp->subsamplingcorrect == 0) - TIFFErrorExtR(tif, module, - "JPEG compressed data indicates unexpected number of " - "bits per sample"); - return (0); - } - /* Y: Number of lines, X: Number of samples per line */ - if (sp->subsamplingcorrect) - OJPEGReadSkip(sp, 4); - else - { - /* Y: Number of lines */ - if (OJPEGReadWord(sp, &p) == 0) - return (0); - if (((uint32_t)p < sp->image_length) && - ((uint32_t)p < sp->strile_length_total)) - { - TIFFErrorExtR(tif, module, - "JPEG compressed data indicates unexpected height"); - return (0); - } - sp->sof_y = p; - /* X: Number of samples per line */ - if (OJPEGReadWord(sp, &p) == 0) - return (0); - if (((uint32_t)p < sp->image_width) && ((uint32_t)p < sp->strile_width)) - { - TIFFErrorExtR(tif, module, - "JPEG compressed data indicates unexpected width"); - return (0); - } - if ((uint32_t)p > sp->strile_width) - { - TIFFErrorExtR(tif, module, - "JPEG compressed data image width exceeds expected " - "image width"); - return (0); - } - sp->sof_x = p; - } - /* Nf: Number of image components in frame */ - if (OJPEGReadByte(sp, &o) == 0) - return (0); - if (o != n) - { - if (sp->subsamplingcorrect == 0) - TIFFErrorExtR(tif, module, "Corrupt SOF marker in JPEG data"); - return (0); - } - /* per component stuff */ - /* TODO: double-check that flow implies that n cannot be as big as to make - * us overflow sof_c, sof_hv and sof_tq arrays */ - for (q = 0; q < n; q++) - { - /* C: Component identifier */ - if (OJPEGReadByte(sp, &o) == 0) - return (0); - if (sp->subsamplingcorrect == 0) - sp->sof_c[q] = o; - /* H: Horizontal sampling factor, and V: Vertical sampling factor */ - if (OJPEGReadByte(sp, &o) == 0) - return (0); - if (sp->subsamplingcorrect != 0) - { - if (q == 0) - { - sp->subsampling_hor = (o >> 4); - sp->subsampling_ver = (o & 15); - if (((sp->subsampling_hor != 1) && (sp->subsampling_hor != 2) && - (sp->subsampling_hor != 4)) || - ((sp->subsampling_ver != 1) && (sp->subsampling_ver != 2) && - (sp->subsampling_ver != 4))) - sp->subsampling_force_desubsampling_inside_decompression = - 1; - } - else - { - if (o != 17) - sp->subsampling_force_desubsampling_inside_decompression = - 1; - } - } - else - { - sp->sof_hv[q] = o; - if (sp->subsampling_force_desubsampling_inside_decompression == 0) - { - if (q == 0) - { - if (o != ((sp->subsampling_hor << 4) | sp->subsampling_ver)) - { - TIFFErrorExtR(tif, module, - "JPEG compressed data indicates " - "unexpected subsampling values"); - return (0); - } - } - else - { - if (o != 17) - { - TIFFErrorExtR(tif, module, - "JPEG compressed data indicates " - "unexpected subsampling values"); - return (0); - } - } - } - } - /* Tq: Quantization table destination selector */ - if (OJPEGReadByte(sp, &o) == 0) - return (0); - if (sp->subsamplingcorrect == 0) - sp->sof_tq[q] = o; - } - if (sp->subsamplingcorrect == 0) - sp->sof_log = 1; - return (1); -} - -static int OJPEGReadHeaderInfoSecStreamSos(TIFF *tif) -{ - /* this marker needs to be checked, and part of its data needs to be saved - * for regeneration later on */ - static const char module[] = "OJPEGReadHeaderInfoSecStreamSos"; - OJPEGState *sp = (OJPEGState *)tif->tif_data; - uint16_t m; - uint8_t n; - uint8_t o; - assert(sp->subsamplingcorrect == 0); - if (sp->sof_log == 0) - { - TIFFErrorExtR(tif, module, "Corrupt SOS marker in JPEG data"); - return (0); - } - /* Ls */ - if (OJPEGReadWord(sp, &m) == 0) - return (0); - if (m != 6 + sp->samples_per_pixel_per_plane * 2) - { - TIFFErrorExtR(tif, module, "Corrupt SOS marker in JPEG data"); - return (0); - } - /* Ns */ - if (OJPEGReadByte(sp, &n) == 0) - return (0); - if (n != sp->samples_per_pixel_per_plane) - { - TIFFErrorExtR(tif, module, "Corrupt SOS marker in JPEG data"); - return (0); - } - /* Cs, Td, and Ta */ - for (o = 0; o < sp->samples_per_pixel_per_plane; o++) - { - /* Cs */ - if (OJPEGReadByte(sp, &n) == 0) - return (0); - sp->sos_cs[sp->plane_sample_offset + o] = n; - /* Td and Ta */ - if (OJPEGReadByte(sp, &n) == 0) - return (0); - sp->sos_tda[sp->plane_sample_offset + o] = n; - } - /* skip Ss, Se, Ah, en Al -> no check, as per Tom Lane recommendation, as - * per LibJpeg source */ - OJPEGReadSkip(sp, 3); - return (1); -} - -static int OJPEGReadHeaderInfoSecTablesQTable(TIFF *tif) -{ - static const char module[] = "OJPEGReadHeaderInfoSecTablesQTable"; - OJPEGState *sp = (OJPEGState *)tif->tif_data; - uint8_t m; - uint8_t n; - uint32_t oa; - uint8_t *ob; - uint32_t p; - if (sp->qtable_offset[0] == 0) - { - TIFFErrorExtR(tif, module, "Missing JPEG tables"); - return (0); - } - sp->in_buffer_file_pos_log = 0; - for (m = 0; m < sp->samples_per_pixel; m++) - { - if ((sp->qtable_offset[m] != 0) && - ((m == 0) || (sp->qtable_offset[m] != sp->qtable_offset[m - 1]))) - { - for (n = 0; n < m - 1; n++) - { - if (sp->qtable_offset[m] == sp->qtable_offset[n]) - { - TIFFErrorExtR(tif, module, "Corrupt JpegQTables tag value"); - return (0); - } - } - oa = sizeof(uint32_t) + 69; - ob = _TIFFmallocExt(tif, oa); - if (ob == 0) - { - TIFFErrorExtR(tif, module, "Out of memory"); - return (0); - } - *(uint32_t *)ob = oa; - ob[sizeof(uint32_t)] = 255; - ob[sizeof(uint32_t) + 1] = JPEG_MARKER_DQT; - ob[sizeof(uint32_t) + 2] = 0; - ob[sizeof(uint32_t) + 3] = 67; - ob[sizeof(uint32_t) + 4] = m; - TIFFSeekFile(tif, sp->qtable_offset[m], SEEK_SET); - p = (uint32_t)TIFFReadFile(tif, &ob[sizeof(uint32_t) + 5], 64); - if (p != 64) - { - _TIFFfreeExt(tif, ob); - return (0); - } - if (sp->qtable[m] != 0) - _TIFFfreeExt(tif, sp->qtable[m]); - sp->qtable[m] = ob; - sp->sof_tq[m] = m; - } - else - sp->sof_tq[m] = sp->sof_tq[m - 1]; - } - return (1); -} - -static int OJPEGReadHeaderInfoSecTablesDcTable(TIFF *tif) -{ - static const char module[] = "OJPEGReadHeaderInfoSecTablesDcTable"; - OJPEGState *sp = (OJPEGState *)tif->tif_data; - uint8_t m; - uint8_t n; - uint8_t o[16]; - uint32_t p; - uint32_t q; - uint32_t ra; - uint8_t *rb; - if (sp->dctable_offset[0] == 0) - { - TIFFErrorExtR(tif, module, "Missing JPEG tables"); - return (0); - } - sp->in_buffer_file_pos_log = 0; - for (m = 0; m < sp->samples_per_pixel; m++) - { - if ((sp->dctable_offset[m] != 0) && - ((m == 0) || (sp->dctable_offset[m] != sp->dctable_offset[m - 1]))) - { - for (n = 0; n < m - 1; n++) - { - if (sp->dctable_offset[m] == sp->dctable_offset[n]) - { - TIFFErrorExtR(tif, module, - "Corrupt JpegDcTables tag value"); - return (0); - } - } - TIFFSeekFile(tif, sp->dctable_offset[m], SEEK_SET); - p = (uint32_t)TIFFReadFile(tif, o, 16); - if (p != 16) - return (0); - q = 0; - for (n = 0; n < 16; n++) - q += o[n]; - ra = sizeof(uint32_t) + 21 + q; - rb = _TIFFmallocExt(tif, ra); - if (rb == 0) - { - TIFFErrorExtR(tif, module, "Out of memory"); - return (0); - } - *(uint32_t *)rb = ra; - rb[sizeof(uint32_t)] = 255; - rb[sizeof(uint32_t) + 1] = JPEG_MARKER_DHT; - rb[sizeof(uint32_t) + 2] = (uint8_t)((19 + q) >> 8); - rb[sizeof(uint32_t) + 3] = ((19 + q) & 255); - rb[sizeof(uint32_t) + 4] = m; - for (n = 0; n < 16; n++) - rb[sizeof(uint32_t) + 5 + n] = o[n]; - p = (uint32_t)TIFFReadFile(tif, &(rb[sizeof(uint32_t) + 21]), q); - if (p != q) - { - _TIFFfreeExt(tif, rb); - return (0); - } - if (sp->dctable[m] != 0) - _TIFFfreeExt(tif, sp->dctable[m]); - sp->dctable[m] = rb; - sp->sos_tda[m] = (m << 4); - } - else - sp->sos_tda[m] = sp->sos_tda[m - 1]; - } - return (1); -} - -static int OJPEGReadHeaderInfoSecTablesAcTable(TIFF *tif) -{ - static const char module[] = "OJPEGReadHeaderInfoSecTablesAcTable"; - OJPEGState *sp = (OJPEGState *)tif->tif_data; - uint8_t m; - uint8_t n; - uint8_t o[16]; - uint32_t p; - uint32_t q; - uint32_t ra; - uint8_t *rb; - if (sp->actable_offset[0] == 0) - { - TIFFErrorExtR(tif, module, "Missing JPEG tables"); - return (0); - } - sp->in_buffer_file_pos_log = 0; - for (m = 0; m < sp->samples_per_pixel; m++) - { - if ((sp->actable_offset[m] != 0) && - ((m == 0) || (sp->actable_offset[m] != sp->actable_offset[m - 1]))) - { - for (n = 0; n < m - 1; n++) - { - if (sp->actable_offset[m] == sp->actable_offset[n]) - { - TIFFErrorExtR(tif, module, - "Corrupt JpegAcTables tag value"); - return (0); - } - } - TIFFSeekFile(tif, sp->actable_offset[m], SEEK_SET); - p = (uint32_t)TIFFReadFile(tif, o, 16); - if (p != 16) - return (0); - q = 0; - for (n = 0; n < 16; n++) - q += o[n]; - ra = sizeof(uint32_t) + 21 + q; - rb = _TIFFmallocExt(tif, ra); - if (rb == 0) - { - TIFFErrorExtR(tif, module, "Out of memory"); - return (0); - } - *(uint32_t *)rb = ra; - rb[sizeof(uint32_t)] = 255; - rb[sizeof(uint32_t) + 1] = JPEG_MARKER_DHT; - rb[sizeof(uint32_t) + 2] = (uint8_t)((19 + q) >> 8); - rb[sizeof(uint32_t) + 3] = ((19 + q) & 255); - rb[sizeof(uint32_t) + 4] = (16 | m); - for (n = 0; n < 16; n++) - rb[sizeof(uint32_t) + 5 + n] = o[n]; - p = (uint32_t)TIFFReadFile(tif, &(rb[sizeof(uint32_t) + 21]), q); - if (p != q) - { - _TIFFfreeExt(tif, rb); - return (0); - } - if (sp->actable[m] != 0) - _TIFFfreeExt(tif, sp->actable[m]); - sp->actable[m] = rb; - sp->sos_tda[m] = (sp->sos_tda[m] | m); - } - else - sp->sos_tda[m] = (sp->sos_tda[m] | (sp->sos_tda[m - 1] & 15)); - } - return (1); -} - -static int OJPEGReadBufferFill(OJPEGState *sp) -{ - uint16_t m; - tmsize_t n; - /* TODO: double-check: when subsamplingcorrect is set, no call to - * TIFFErrorExt or TIFFWarningExt should be made in any other case, seek or - * read errors should be passed through */ - do - { - if (sp->in_buffer_file_togo != 0) - { - if (sp->in_buffer_file_pos_log == 0) - { - TIFFSeekFile(sp->tif, sp->in_buffer_file_pos, SEEK_SET); - sp->in_buffer_file_pos_log = 1; - } - m = OJPEG_BUFFER; - if ((uint64_t)m > sp->in_buffer_file_togo) - m = (uint16_t)sp->in_buffer_file_togo; - n = TIFFReadFile(sp->tif, sp->in_buffer, (tmsize_t)m); - if (n == 0) - return (0); - assert(n > 0); - assert(n <= OJPEG_BUFFER); - assert(n < 65536); - assert((uint64_t)n <= sp->in_buffer_file_togo); - m = (uint16_t)n; - sp->in_buffer_togo = m; - sp->in_buffer_cur = sp->in_buffer; - sp->in_buffer_file_togo -= m; - sp->in_buffer_file_pos += m; - break; - } - sp->in_buffer_file_pos_log = 0; - switch (sp->in_buffer_source) - { - case osibsNotSetYet: - if (sp->jpeg_interchange_format != 0) - { - sp->in_buffer_file_pos = sp->jpeg_interchange_format; - sp->in_buffer_file_togo = - sp->jpeg_interchange_format_length; - } - sp->in_buffer_source = osibsJpegInterchangeFormat; - break; - case osibsJpegInterchangeFormat: - sp->in_buffer_source = osibsStrile; - break; - case osibsStrile: - if (sp->in_buffer_next_strile == sp->in_buffer_strile_count) - sp->in_buffer_source = osibsEof; - else - { - int err = 0; - sp->in_buffer_file_pos = TIFFGetStrileOffsetWithErr( - sp->tif, sp->in_buffer_next_strile, &err); - if (err) - return 0; - if (sp->in_buffer_file_pos != 0) - { - uint64_t bytecount = TIFFGetStrileByteCountWithErr( - sp->tif, sp->in_buffer_next_strile, &err); - if (err) - return 0; - if (sp->in_buffer_file_pos >= sp->file_size) - sp->in_buffer_file_pos = 0; - else if (bytecount == 0) - sp->in_buffer_file_togo = - sp->file_size - sp->in_buffer_file_pos; - else - { - sp->in_buffer_file_togo = bytecount; - if (sp->in_buffer_file_togo == 0) - sp->in_buffer_file_pos = 0; - else if (sp->in_buffer_file_pos > - UINT64_MAX - sp->in_buffer_file_togo || - sp->in_buffer_file_pos + - sp->in_buffer_file_togo > - sp->file_size) - sp->in_buffer_file_togo = - sp->file_size - sp->in_buffer_file_pos; - } - } - sp->in_buffer_next_strile++; - } - break; - default: - return (0); - } - } while (1); - return (1); -} - -static int OJPEGReadByte(OJPEGState *sp, uint8_t *byte) -{ - if (sp->in_buffer_togo == 0) - { - if (OJPEGReadBufferFill(sp) == 0) - return (0); - assert(sp->in_buffer_togo > 0); - } - *byte = *(sp->in_buffer_cur); - sp->in_buffer_cur++; - sp->in_buffer_togo--; - return (1); -} - -static int OJPEGReadBytePeek(OJPEGState *sp, uint8_t *byte) -{ - if (sp->in_buffer_togo == 0) - { - if (OJPEGReadBufferFill(sp) == 0) - return (0); - assert(sp->in_buffer_togo > 0); - } - *byte = *(sp->in_buffer_cur); - return (1); -} - -static void OJPEGReadByteAdvance(OJPEGState *sp) -{ - assert(sp->in_buffer_togo > 0); - sp->in_buffer_cur++; - sp->in_buffer_togo--; -} - -static int OJPEGReadWord(OJPEGState *sp, uint16_t *word) -{ - uint8_t m; - if (OJPEGReadByte(sp, &m) == 0) - return (0); - *word = (m << 8); - if (OJPEGReadByte(sp, &m) == 0) - return (0); - *word |= m; - return (1); -} - -static int OJPEGReadBlock(OJPEGState *sp, uint16_t len, void *mem) -{ - uint16_t mlen; - uint8_t *mmem; - uint16_t n; - assert(len > 0); - mlen = len; - mmem = mem; - do - { - if (sp->in_buffer_togo == 0) - { - if (OJPEGReadBufferFill(sp) == 0) - return (0); - assert(sp->in_buffer_togo > 0); - } - n = mlen; - if (n > sp->in_buffer_togo) - n = sp->in_buffer_togo; - _TIFFmemcpy(mmem, sp->in_buffer_cur, n); - sp->in_buffer_cur += n; - sp->in_buffer_togo -= n; - mlen -= n; - mmem += n; - } while (mlen > 0); - return (1); -} - -static void OJPEGReadSkip(OJPEGState *sp, uint16_t len) -{ - uint16_t m; - uint16_t n; - m = len; - n = m; - if (n > sp->in_buffer_togo) - n = sp->in_buffer_togo; - sp->in_buffer_cur += n; - sp->in_buffer_togo -= n; - m -= n; - if (m > 0) - { - assert(sp->in_buffer_togo == 0); - n = m; - if ((uint64_t)n > sp->in_buffer_file_togo) - n = (uint16_t)sp->in_buffer_file_togo; - sp->in_buffer_file_pos += n; - sp->in_buffer_file_togo -= n; - sp->in_buffer_file_pos_log = 0; - /* we don't skip past jpeginterchangeformat/strile block... - * if that is asked from us, we're dealing with totally bazurk - * data anyway, and we've not seen this happening on any - * testfile, so we might as well likely cause some other - * meaningless error to be passed at some later time - */ - } -} - -static int OJPEGWriteStream(TIFF *tif, void **mem, uint32_t *len) -{ - OJPEGState *sp = (OJPEGState *)tif->tif_data; - *len = 0; - do - { - assert(sp->out_state <= ososEoi); - switch (sp->out_state) - { - case ososSoi: - OJPEGWriteStreamSoi(tif, mem, len); - break; - case ososQTable0: - OJPEGWriteStreamQTable(tif, 0, mem, len); - break; - case ososQTable1: - OJPEGWriteStreamQTable(tif, 1, mem, len); - break; - case ososQTable2: - OJPEGWriteStreamQTable(tif, 2, mem, len); - break; - case ososQTable3: - OJPEGWriteStreamQTable(tif, 3, mem, len); - break; - case ososDcTable0: - OJPEGWriteStreamDcTable(tif, 0, mem, len); - break; - case ososDcTable1: - OJPEGWriteStreamDcTable(tif, 1, mem, len); - break; - case ososDcTable2: - OJPEGWriteStreamDcTable(tif, 2, mem, len); - break; - case ososDcTable3: - OJPEGWriteStreamDcTable(tif, 3, mem, len); - break; - case ososAcTable0: - OJPEGWriteStreamAcTable(tif, 0, mem, len); - break; - case ososAcTable1: - OJPEGWriteStreamAcTable(tif, 1, mem, len); - break; - case ososAcTable2: - OJPEGWriteStreamAcTable(tif, 2, mem, len); - break; - case ososAcTable3: - OJPEGWriteStreamAcTable(tif, 3, mem, len); - break; - case ososDri: - OJPEGWriteStreamDri(tif, mem, len); - break; - case ososSof: - OJPEGWriteStreamSof(tif, mem, len); - break; - case ososSos: - OJPEGWriteStreamSos(tif, mem, len); - break; - case ososCompressed: - if (OJPEGWriteStreamCompressed(tif, mem, len) == 0) - return (0); - break; - case ososRst: - OJPEGWriteStreamRst(tif, mem, len); - break; - case ososEoi: - OJPEGWriteStreamEoi(tif, mem, len); - break; - } - } while (*len == 0); - return (1); -} - -static void OJPEGWriteStreamSoi(TIFF *tif, void **mem, uint32_t *len) -{ - OJPEGState *sp = (OJPEGState *)tif->tif_data; - assert(OJPEG_BUFFER >= 2); - sp->out_buffer[0] = 255; - sp->out_buffer[1] = JPEG_MARKER_SOI; - *len = 2; - *mem = (void *)sp->out_buffer; - sp->out_state++; -} - -static void OJPEGWriteStreamQTable(TIFF *tif, uint8_t table_index, void **mem, - uint32_t *len) -{ - OJPEGState *sp = (OJPEGState *)tif->tif_data; - if (sp->qtable[table_index] != 0) - { - *mem = (void *)(sp->qtable[table_index] + sizeof(uint32_t)); - *len = *((uint32_t *)sp->qtable[table_index]) - sizeof(uint32_t); - } - sp->out_state++; -} - -static void OJPEGWriteStreamDcTable(TIFF *tif, uint8_t table_index, void **mem, - uint32_t *len) -{ - OJPEGState *sp = (OJPEGState *)tif->tif_data; - if (sp->dctable[table_index] != 0) - { - *mem = (void *)(sp->dctable[table_index] + sizeof(uint32_t)); - *len = *((uint32_t *)sp->dctable[table_index]) - sizeof(uint32_t); - } - sp->out_state++; -} - -static void OJPEGWriteStreamAcTable(TIFF *tif, uint8_t table_index, void **mem, - uint32_t *len) -{ - OJPEGState *sp = (OJPEGState *)tif->tif_data; - if (sp->actable[table_index] != 0) - { - *mem = (void *)(sp->actable[table_index] + sizeof(uint32_t)); - *len = *((uint32_t *)sp->actable[table_index]) - sizeof(uint32_t); - } - sp->out_state++; -} - -static void OJPEGWriteStreamDri(TIFF *tif, void **mem, uint32_t *len) -{ - OJPEGState *sp = (OJPEGState *)tif->tif_data; - assert(OJPEG_BUFFER >= 6); - if (sp->restart_interval != 0) - { - sp->out_buffer[0] = 255; - sp->out_buffer[1] = JPEG_MARKER_DRI; - sp->out_buffer[2] = 0; - sp->out_buffer[3] = 4; - sp->out_buffer[4] = (sp->restart_interval >> 8); - sp->out_buffer[5] = (sp->restart_interval & 255); - *len = 6; - *mem = (void *)sp->out_buffer; - } - sp->out_state++; -} - -static void OJPEGWriteStreamSof(TIFF *tif, void **mem, uint32_t *len) -{ - OJPEGState *sp = (OJPEGState *)tif->tif_data; - uint8_t m; - assert(OJPEG_BUFFER >= 2 + 8 + sp->samples_per_pixel_per_plane * 3); - assert(255 >= 8 + sp->samples_per_pixel_per_plane * 3); - sp->out_buffer[0] = 255; - sp->out_buffer[1] = sp->sof_marker_id; - /* Lf */ - sp->out_buffer[2] = 0; - sp->out_buffer[3] = 8 + sp->samples_per_pixel_per_plane * 3; - /* P */ - sp->out_buffer[4] = 8; - /* Y */ - sp->out_buffer[5] = (uint8_t)(sp->sof_y >> 8); - sp->out_buffer[6] = (sp->sof_y & 255); - /* X */ - sp->out_buffer[7] = (uint8_t)(sp->sof_x >> 8); - sp->out_buffer[8] = (sp->sof_x & 255); - /* Nf */ - sp->out_buffer[9] = sp->samples_per_pixel_per_plane; - for (m = 0; m < sp->samples_per_pixel_per_plane; m++) - { - /* C */ - sp->out_buffer[10 + m * 3] = sp->sof_c[sp->plane_sample_offset + m]; - /* H and V */ - sp->out_buffer[10 + m * 3 + 1] = - sp->sof_hv[sp->plane_sample_offset + m]; - /* Tq */ - sp->out_buffer[10 + m * 3 + 2] = - sp->sof_tq[sp->plane_sample_offset + m]; - } - *len = 10 + sp->samples_per_pixel_per_plane * 3; - *mem = (void *)sp->out_buffer; - sp->out_state++; -} - -static void OJPEGWriteStreamSos(TIFF *tif, void **mem, uint32_t *len) -{ - OJPEGState *sp = (OJPEGState *)tif->tif_data; - uint8_t m; - assert(OJPEG_BUFFER >= 2 + 6 + sp->samples_per_pixel_per_plane * 2); - assert(255 >= 6 + sp->samples_per_pixel_per_plane * 2); - sp->out_buffer[0] = 255; - sp->out_buffer[1] = JPEG_MARKER_SOS; - /* Ls */ - sp->out_buffer[2] = 0; - sp->out_buffer[3] = 6 + sp->samples_per_pixel_per_plane * 2; - /* Ns */ - sp->out_buffer[4] = sp->samples_per_pixel_per_plane; - for (m = 0; m < sp->samples_per_pixel_per_plane; m++) - { - /* Cs */ - sp->out_buffer[5 + m * 2] = sp->sos_cs[sp->plane_sample_offset + m]; - /* Td and Ta */ - sp->out_buffer[5 + m * 2 + 1] = - sp->sos_tda[sp->plane_sample_offset + m]; - } - /* Ss */ - sp->out_buffer[5 + sp->samples_per_pixel_per_plane * 2] = 0; - /* Se */ - sp->out_buffer[5 + sp->samples_per_pixel_per_plane * 2 + 1] = 63; - /* Ah and Al */ - sp->out_buffer[5 + sp->samples_per_pixel_per_plane * 2 + 2] = 0; - *len = 8 + sp->samples_per_pixel_per_plane * 2; - *mem = (void *)sp->out_buffer; - sp->out_state++; -} - -static int OJPEGWriteStreamCompressed(TIFF *tif, void **mem, uint32_t *len) -{ - OJPEGState *sp = (OJPEGState *)tif->tif_data; - if (sp->in_buffer_togo == 0) - { - if (OJPEGReadBufferFill(sp) == 0) - return (0); - assert(sp->in_buffer_togo > 0); - } - *len = sp->in_buffer_togo; - *mem = (void *)sp->in_buffer_cur; - sp->in_buffer_togo = 0; - if (sp->in_buffer_file_togo == 0) - { - switch (sp->in_buffer_source) - { - case osibsStrile: - if (sp->in_buffer_next_strile < sp->in_buffer_strile_count) - sp->out_state = ososRst; - else - sp->out_state = ososEoi; - break; - case osibsEof: - sp->out_state = ososEoi; - break; - default: - break; - } - } - return (1); -} - -static void OJPEGWriteStreamRst(TIFF *tif, void **mem, uint32_t *len) -{ - OJPEGState *sp = (OJPEGState *)tif->tif_data; - assert(OJPEG_BUFFER >= 2); - sp->out_buffer[0] = 255; - sp->out_buffer[1] = JPEG_MARKER_RST0 + sp->restart_index; - sp->restart_index++; - if (sp->restart_index == 8) - sp->restart_index = 0; - *len = 2; - *mem = (void *)sp->out_buffer; - sp->out_state = ososCompressed; -} - -static void OJPEGWriteStreamEoi(TIFF *tif, void **mem, uint32_t *len) -{ - OJPEGState *sp = (OJPEGState *)tif->tif_data; - assert(OJPEG_BUFFER >= 2); - sp->out_buffer[0] = 255; - sp->out_buffer[1] = JPEG_MARKER_EOI; - *len = 2; - *mem = (void *)sp->out_buffer; -} - -#ifndef LIBJPEG_ENCAP_EXTERNAL -static int jpeg_create_decompress_encap(OJPEGState *sp, - jpeg_decompress_struct *cinfo) -{ - if (SETJMP(sp->exit_jmpbuf)) - return 0; - else - { - jpeg_create_decompress(cinfo); - return 1; - } -} -#endif - -#ifndef LIBJPEG_ENCAP_EXTERNAL -static int jpeg_read_header_encap(OJPEGState *sp, jpeg_decompress_struct *cinfo, - uint8_t require_image) -{ - if (SETJMP(sp->exit_jmpbuf)) - return 0; - else - { - jpeg_read_header(cinfo, require_image); - return 1; - } -} -#endif - -#ifndef LIBJPEG_ENCAP_EXTERNAL -static int jpeg_start_decompress_encap(OJPEGState *sp, - jpeg_decompress_struct *cinfo) -{ - if (SETJMP(sp->exit_jmpbuf)) - return 0; - else - { - jpeg_start_decompress(cinfo); - return 1; - } -} -#endif - -#ifndef LIBJPEG_ENCAP_EXTERNAL -static int jpeg_read_scanlines_encap(OJPEGState *sp, - jpeg_decompress_struct *cinfo, - void *scanlines, uint32_t max_lines) -{ - if (SETJMP(sp->exit_jmpbuf)) - return 0; - else - { - jpeg_read_scanlines(cinfo, scanlines, max_lines); - return 1; - } -} -#endif - -#ifndef LIBJPEG_ENCAP_EXTERNAL -static int jpeg_read_raw_data_encap(OJPEGState *sp, - jpeg_decompress_struct *cinfo, void *data, - uint32_t max_lines) -{ - if (SETJMP(sp->exit_jmpbuf)) - return 0; - else - { - jpeg_read_raw_data(cinfo, data, max_lines); - return 1; - } -} -#endif - -#ifndef LIBJPEG_ENCAP_EXTERNAL -static void jpeg_encap_unwind(TIFF *tif) -{ - OJPEGState *sp = (OJPEGState *)tif->tif_data; - LONGJMP(sp->exit_jmpbuf, 1); -} -#endif - -static void OJPEGLibjpegJpegErrorMgrOutputMessage(jpeg_common_struct *cinfo) -{ - char buffer[JMSG_LENGTH_MAX]; - (*cinfo->err->format_message)(cinfo, buffer); - TIFFWarningExtR(((TIFF *)(cinfo->client_data)), "LibJpeg", "%s", buffer); -} - -static void OJPEGLibjpegJpegErrorMgrErrorExit(jpeg_common_struct *cinfo) -{ - char buffer[JMSG_LENGTH_MAX]; - (*cinfo->err->format_message)(cinfo, buffer); - TIFFErrorExtR(((TIFF *)(cinfo->client_data)), "LibJpeg", "%s", buffer); - jpeg_encap_unwind((TIFF *)(cinfo->client_data)); -} - -static void OJPEGLibjpegJpegSourceMgrInitSource(jpeg_decompress_struct *cinfo) -{ - (void)cinfo; -} - -static boolean -OJPEGLibjpegJpegSourceMgrFillInputBuffer(jpeg_decompress_struct *cinfo) -{ - TIFF *tif = (TIFF *)cinfo->client_data; - OJPEGState *sp = (OJPEGState *)tif->tif_data; - void *mem = 0; - uint32_t len = 0U; - if (OJPEGWriteStream(tif, &mem, &len) == 0) - { - TIFFErrorExtR(tif, "LibJpeg", "Premature end of JPEG data"); - jpeg_encap_unwind(tif); - } - sp->libjpeg_jpeg_source_mgr.bytes_in_buffer = len; - sp->libjpeg_jpeg_source_mgr.next_input_byte = mem; - return (1); -} - -static void -OJPEGLibjpegJpegSourceMgrSkipInputData(jpeg_decompress_struct *cinfo, - long num_bytes) -{ - TIFF *tif = (TIFF *)cinfo->client_data; - (void)num_bytes; - TIFFErrorExtR(tif, "LibJpeg", "Unexpected error"); - jpeg_encap_unwind(tif); -} - -#ifdef _MSC_VER -#pragma warning(push) -#pragma warning(disable : 4702) /* unreachable code */ -#endif -static boolean -OJPEGLibjpegJpegSourceMgrResyncToRestart(jpeg_decompress_struct *cinfo, - int desired) -{ - TIFF *tif = (TIFF *)cinfo->client_data; - (void)desired; - TIFFErrorExtR(tif, "LibJpeg", "Unexpected error"); - jpeg_encap_unwind(tif); - return (0); -} -#ifdef _MSC_VER -#pragma warning(pop) -#endif - -static void OJPEGLibjpegJpegSourceMgrTermSource(jpeg_decompress_struct *cinfo) -{ - (void)cinfo; -} - -#endif diff --git a/src/3rd/tiff/open.c b/src/3rd/tiff/open.c deleted file mode 100644 index ca884c0728f..00000000000 --- a/src/3rd/tiff/open.c +++ /dev/null @@ -1,810 +0,0 @@ -/* - * Copyright (c) 1988-1997 Sam Leffler - * Copyright (c) 1991-1997 Silicon Graphics, Inc. - * - * Permission to use, copy, modify, distribute, and sell this software and - * its documentation for any purpose is hereby granted without fee, provided - * that (i) the above copyright notices and this permission notice appear in - * all copies of the software and related documentation, and (ii) the names of - * Sam Leffler and Silicon Graphics may not be used in any advertising or - * publicity relating to the software without the specific, prior written - * permission of Sam Leffler and Silicon Graphics. - * - * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, - * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY - * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. - * - * IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR - * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, - * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, - * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF - * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE - * OF THIS SOFTWARE. - */ - -/* - * TIFF Library. - */ -#include "tiffiop.h" -#include - -/* - * Dummy functions to fill the omitted client procedures. - */ -static int _tiffDummyMapProc(thandle_t fd, void **pbase, toff_t *psize) -{ - (void)fd; - (void)pbase; - (void)psize; - return (0); -} - -static void _tiffDummyUnmapProc(thandle_t fd, void *base, toff_t size) -{ - (void)fd; - (void)base; - (void)size; -} - -int _TIFFgetMode(TIFFOpenOptions *opts, thandle_t clientdata, const char *mode, - const char *module) -{ - int m = -1; - - switch (mode[0]) - { - case 'r': - m = O_RDONLY; - if (mode[1] == '+') - m = O_RDWR; - break; - case 'w': - case 'a': - m = O_RDWR | O_CREAT; - if (mode[0] == 'w') - m |= O_TRUNC; - break; - default: - _TIFFErrorEarly(opts, clientdata, module, "\"%s\": Bad mode", mode); - break; - } - return (m); -} - -TIFFOpenOptions *TIFFOpenOptionsAlloc() -{ - TIFFOpenOptions *opts = - (TIFFOpenOptions *)_TIFFcalloc(1, sizeof(TIFFOpenOptions)); - return opts; -} - -void TIFFOpenOptionsFree(TIFFOpenOptions *opts) { _TIFFfree(opts); } - -/** Define a limit in bytes for a single memory allocation done by libtiff. - * If max_single_mem_alloc is set to 0, no other limit that the underlying - * _TIFFmalloc() will be applied, which is the default. - */ -void TIFFOpenOptionsSetMaxSingleMemAlloc(TIFFOpenOptions *opts, - tmsize_t max_single_mem_alloc) -{ - opts->max_single_mem_alloc = max_single_mem_alloc; -} - -void TIFFOpenOptionsSetErrorHandlerExtR(TIFFOpenOptions *opts, - TIFFErrorHandlerExtR handler, - void *errorhandler_user_data) -{ - opts->errorhandler = handler; - opts->errorhandler_user_data = errorhandler_user_data; -} - -void TIFFOpenOptionsSetWarningHandlerExtR(TIFFOpenOptions *opts, - TIFFErrorHandlerExtR handler, - void *warnhandler_user_data) -{ - opts->warnhandler = handler; - opts->warnhandler_user_data = warnhandler_user_data; -} - -static void _TIFFEmitErrorAboveMaxSingleMemAlloc(TIFF *tif, - const char *pszFunction, - tmsize_t s) -{ - TIFFErrorExtR(tif, pszFunction, - "Memory allocation of %" PRIu64 - " bytes is beyond the %" PRIu64 - " byte limit defined in open options", - (uint64_t)s, (uint64_t)tif->tif_max_single_mem_alloc); -} - -/** malloc() version that takes into account memory-specific open options */ -void *_TIFFmallocExt(TIFF *tif, tmsize_t s) -{ - if (tif != NULL && tif->tif_max_single_mem_alloc > 0 && - s > tif->tif_max_single_mem_alloc) - { - _TIFFEmitErrorAboveMaxSingleMemAlloc(tif, "_TIFFmallocExt", s); - return NULL; - } - return _TIFFmalloc(s); -} - -/** calloc() version that takes into account memory-specific open options */ -void *_TIFFcallocExt(TIFF *tif, tmsize_t nmemb, tmsize_t siz) -{ - if (tif != NULL && tif->tif_max_single_mem_alloc > 0) - { - if (nmemb <= 0 || siz <= 0 || nmemb > TIFF_TMSIZE_T_MAX / siz) - return NULL; - if (nmemb * siz > tif->tif_max_single_mem_alloc) - { - _TIFFEmitErrorAboveMaxSingleMemAlloc(tif, "_TIFFcallocExt", - nmemb * siz); - return NULL; - } - } - return _TIFFcalloc(nmemb, siz); -} - -/** realloc() version that takes into account memory-specific open options */ -void *_TIFFreallocExt(TIFF *tif, void *p, tmsize_t s) -{ - if (tif != NULL && tif->tif_max_single_mem_alloc > 0 && - s > tif->tif_max_single_mem_alloc) - { - _TIFFEmitErrorAboveMaxSingleMemAlloc(tif, "_TIFFreallocExt", s); - return NULL; - } - return _TIFFrealloc(p, s); -} - -/** free() version that takes into account memory-specific open options */ -void _TIFFfreeExt(TIFF *tif, void *p) -{ - (void)tif; - _TIFFfree(p); -} - -TIFF *TIFFClientOpen(const char *name, const char *mode, thandle_t clientdata, - TIFFReadWriteProc readproc, TIFFReadWriteProc writeproc, - TIFFSeekProc seekproc, TIFFCloseProc closeproc, - TIFFSizeProc sizeproc, TIFFMapFileProc mapproc, - TIFFUnmapFileProc unmapproc) -{ - return TIFFClientOpenExt(name, mode, clientdata, readproc, writeproc, - seekproc, closeproc, sizeproc, mapproc, unmapproc, - NULL); -} - -TIFF *TIFFClientOpenExt(const char *name, const char *mode, - thandle_t clientdata, TIFFReadWriteProc readproc, - TIFFReadWriteProc writeproc, TIFFSeekProc seekproc, - TIFFCloseProc closeproc, TIFFSizeProc sizeproc, - TIFFMapFileProc mapproc, TIFFUnmapFileProc unmapproc, - TIFFOpenOptions *opts) -{ - static const char module[] = "TIFFClientOpenExt"; - TIFF *tif; - int m; - const char *cp; - - /* The following are configuration checks. They should be redundant, but - * should not compile to any actual code in an optimised release build - * anyway. If any of them fail, (makefile-based or other) configuration is - * not correct */ - assert(sizeof(uint8_t) == 1); - assert(sizeof(int8_t) == 1); - assert(sizeof(uint16_t) == 2); - assert(sizeof(int16_t) == 2); - assert(sizeof(uint32_t) == 4); - assert(sizeof(int32_t) == 4); - assert(sizeof(uint64_t) == 8); - assert(sizeof(int64_t) == 8); - { - union - { - uint8_t a8[2]; - uint16_t a16; - } n; - n.a8[0] = 1; - n.a8[1] = 0; - (void)n; -#ifdef WORDS_BIGENDIAN - assert(n.a16 == 256); -#else - assert(n.a16 == 1); -#endif - } - - m = _TIFFgetMode(opts, clientdata, mode, module); - if (m == -1) - goto bad2; - { - tmsize_t 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) - { - _TIFFErrorEarly(opts, clientdata, module, - "%s: Memory allocation of %" PRIu64 - " bytes is beyond the %" PRIu64 - " byte limit defined in open options", - name, (uint64_t)size_to_alloc, - (uint64_t)opts->max_single_mem_alloc); - goto bad2; - } - tif = (TIFF *)_TIFFmallocExt(NULL, size_to_alloc); - } - if (tif == NULL) - { - _TIFFErrorEarly(opts, clientdata, module, - "%s: Out of memory (TIFF structure)", name); - goto bad2; - } - _TIFFmemset(tif, 0, sizeof(*tif)); - tif->tif_name = (char *)tif + sizeof(TIFF); - strcpy(tif->tif_name, name); - tif->tif_mode = m & ~(O_CREAT | O_TRUNC); - tif->tif_curdir = TIFF_NON_EXISTENT_DIR_NUMBER; /* non-existent directory */ - tif->tif_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; - tif->tif_seekproc = seekproc; - tif->tif_closeproc = closeproc; - tif->tif_sizeproc = sizeproc; - tif->tif_mapproc = mapproc ? mapproc : _tiffDummyMapProc; - tif->tif_unmapproc = unmapproc ? unmapproc : _tiffDummyUnmapProc; - if (opts) - { - tif->tif_errorhandler = opts->errorhandler; - tif->tif_errorhandler_user_data = opts->errorhandler_user_data; - tif->tif_warnhandler = opts->warnhandler; - tif->tif_warnhandler_user_data = opts->warnhandler_user_data; - tif->tif_max_single_mem_alloc = opts->max_single_mem_alloc; - } - - if (!readproc || !writeproc || !seekproc || !closeproc || !sizeproc) - { - TIFFErrorExtR(tif, module, - "One of the client procedures is NULL pointer."); - _TIFFfreeExt(NULL, tif); - goto bad2; - } - - _TIFFSetDefaultCompressionState(tif); /* setup default state */ - /* - * Default is to return data MSB2LSB and enable the - * use of memory-mapped files and strip chopping when - * a file is opened read-only. - */ - tif->tif_flags = FILLORDER_MSB2LSB; - if (m == O_RDONLY) - tif->tif_flags |= TIFF_MAPPED; - -#ifdef STRIPCHOP_DEFAULT - if (m == O_RDONLY || m == O_RDWR) - tif->tif_flags |= STRIPCHOP_DEFAULT; -#endif - - /* - * Process library-specific flags in the open mode string. - * The following flags may be used to control intrinsic library - * behavior that may or may not be desirable (usually for - * compatibility with some application that claims to support - * TIFF but only supports some brain dead idea of what the - * vendor thinks TIFF is): - * - * 'l' use little-endian byte order for creating a file - * 'b' use big-endian byte order for creating a file - * 'L' read/write information using LSB2MSB bit order - * 'B' read/write information using MSB2LSB bit order - * 'H' read/write information using host bit order - * 'M' enable use of memory-mapped files when supported - * 'm' disable use of memory-mapped files - * 'C' enable strip chopping support when reading - * 'c' disable strip chopping support - * 'h' read TIFF header only, do not load the first IFD - * '4' ClassicTIFF for creating a file (default) - * '8' BigTIFF for creating a file - * 'D' enable use of deferred strip/tile offset/bytecount array loading. - * 'O' on-demand loading of values instead of whole array loading (implies - * D) - * - * The use of the 'l' and 'b' flags is strongly discouraged. - * These flags are provided solely because numerous vendors, - * typically on the PC, do not correctly support TIFF; they - * only support the Intel little-endian byte order. This - * support is not configured by default because it supports - * the violation of the TIFF spec that says that readers *MUST* - * support both byte orders. It is strongly recommended that - * you not use this feature except to deal with busted apps - * that write invalid TIFF. And even in those cases you should - * bang on the vendors to fix their software. - * - * The 'L', 'B', and 'H' flags are intended for applications - * that can optimize operations on data by using a particular - * bit order. By default the library returns data in MSB2LSB - * bit order for compatibility with older versions of this - * library. Returning data in the bit order of the native CPU - * makes the most sense but also requires applications to check - * the value of the FillOrder tag; something they probably do - * not do right now. - * - * The 'M' and 'm' flags are provided because some virtual memory - * systems exhibit poor behavior when large images are mapped. - * These options permit clients to control the use of memory-mapped - * files on a per-file basis. - * - * The 'C' and 'c' flags are provided because the library support - * for chopping up large strips into multiple smaller strips is not - * application-transparent and as such can cause problems. The 'c' - * option permits applications that only want to look at the tags, - * for example, to get the unadulterated TIFF tag information. - */ - for (cp = mode; *cp; cp++) - switch (*cp) - { - case 'b': -#ifndef WORDS_BIGENDIAN - if (m & O_CREAT) - tif->tif_flags |= TIFF_SWAB; -#endif - break; - case 'l': -#ifdef WORDS_BIGENDIAN - if ((m & O_CREAT)) - tif->tif_flags |= TIFF_SWAB; -#endif - break; - case 'B': - tif->tif_flags = - (tif->tif_flags & ~TIFF_FILLORDER) | FILLORDER_MSB2LSB; - break; - case 'L': - tif->tif_flags = - (tif->tif_flags & ~TIFF_FILLORDER) | FILLORDER_LSB2MSB; - break; - case 'H': - TIFFWarningExtR(tif, name, - "H(ost) mode is deprecated. Since " - "libtiff 4.5.1, it is an alias of 'B' / " - "FILLORDER_MSB2LSB."); - tif->tif_flags = - (tif->tif_flags & ~TIFF_FILLORDER) | FILLORDER_MSB2LSB; - break; - case 'M': - if (m == O_RDONLY) - tif->tif_flags |= TIFF_MAPPED; - break; - case 'm': - if (m == O_RDONLY) - tif->tif_flags &= ~TIFF_MAPPED; - break; - case 'C': - if (m == O_RDONLY) - tif->tif_flags |= TIFF_STRIPCHOP; - break; - case 'c': - if (m == O_RDONLY) - tif->tif_flags &= ~TIFF_STRIPCHOP; - break; - case 'h': - tif->tif_flags |= TIFF_HEADERONLY; - break; - case '8': - if (m & O_CREAT) - tif->tif_flags |= TIFF_BIGTIFF; - break; - case 'D': - tif->tif_flags |= TIFF_DEFERSTRILELOAD; - break; - case 'O': - if (m == O_RDONLY) - tif->tif_flags |= - (TIFF_LAZYSTRILELOAD | TIFF_DEFERSTRILELOAD); - break; - } - -#ifdef DEFER_STRILE_LOAD - /* Compatibility with old DEFER_STRILE_LOAD compilation flag */ - /* Probably unneeded, since to the best of my knowledge (E. Rouault) */ - /* GDAL was the only user of this, and will now use the new 'D' flag */ - tif->tif_flags |= TIFF_DEFERSTRILELOAD; -#endif - - /* - * Read in TIFF header. - */ - if ((m & O_TRUNC) || - !ReadOK(tif, &tif->tif_header, sizeof(TIFFHeaderClassic))) - { - if (tif->tif_mode == O_RDONLY) - { - TIFFErrorExtR(tif, name, "Cannot read TIFF header"); - goto bad; - } -/* - * Setup header and write. - */ -#ifdef WORDS_BIGENDIAN - tif->tif_header.common.tiff_magic = - (tif->tif_flags & TIFF_SWAB) ? TIFF_LITTLEENDIAN : TIFF_BIGENDIAN; -#else - tif->tif_header.common.tiff_magic = - (tif->tif_flags & TIFF_SWAB) ? TIFF_BIGENDIAN : TIFF_LITTLEENDIAN; -#endif - if (!(tif->tif_flags & TIFF_BIGTIFF)) - { - tif->tif_header.common.tiff_version = TIFF_VERSION_CLASSIC; - tif->tif_header.classic.tiff_diroff = 0; - if (tif->tif_flags & TIFF_SWAB) - TIFFSwabShort(&tif->tif_header.common.tiff_version); - tif->tif_header_size = sizeof(TIFFHeaderClassic); - } - else - { - tif->tif_header.common.tiff_version = TIFF_VERSION_BIG; - tif->tif_header.big.tiff_offsetsize = 8; - tif->tif_header.big.tiff_unused = 0; - tif->tif_header.big.tiff_diroff = 0; - if (tif->tif_flags & TIFF_SWAB) - { - TIFFSwabShort(&tif->tif_header.common.tiff_version); - TIFFSwabShort(&tif->tif_header.big.tiff_offsetsize); - } - tif->tif_header_size = sizeof(TIFFHeaderBig); - } - /* - * The doc for "fopen" for some STD_C_LIBs says that if you - * open a file for modify ("+"), then you must fseek (or - * fflush?) between any freads and fwrites. This is not - * necessary on most systems, but has been shown to be needed - * on Solaris. - */ - TIFFSeekFile(tif, 0, SEEK_SET); - if (!WriteOK(tif, &tif->tif_header, (tmsize_t)(tif->tif_header_size))) - { - TIFFErrorExtR(tif, name, "Error writing TIFF header"); - goto bad; - } - /* - * Setup the byte order handling. - */ - if (tif->tif_header.common.tiff_magic == TIFF_BIGENDIAN) - { -#ifndef WORDS_BIGENDIAN - tif->tif_flags |= TIFF_SWAB; -#endif - } - else - { -#ifdef WORDS_BIGENDIAN - tif->tif_flags |= TIFF_SWAB; -#endif - } - /* - * Setup default directory. - */ - if (!TIFFDefaultDirectory(tif)) - goto bad; - tif->tif_diroff = 0; - tif->tif_lastdiroff = 0; - tif->tif_setdirectory_force_absolute = FALSE; - return (tif); - } - /* - * Setup the byte order handling. - */ - if (tif->tif_header.common.tiff_magic != TIFF_BIGENDIAN && - tif->tif_header.common.tiff_magic != TIFF_LITTLEENDIAN -#if MDI_SUPPORT - && -#if HOST_BIGENDIAN - tif->tif_header.common.tiff_magic != MDI_BIGENDIAN -#else - tif->tif_header.common.tiff_magic != MDI_LITTLEENDIAN -#endif - ) - { - TIFFErrorExtR(tif, name, - "Not a TIFF or MDI file, bad magic number %" PRIu16 - " (0x%" PRIx16 ")", -#else - ) - { - TIFFErrorExtR(tif, name, - "Not a TIFF file, bad magic number %" PRIu16 - " (0x%" PRIx16 ")", -#endif - tif->tif_header.common.tiff_magic, - tif->tif_header.common.tiff_magic); - goto bad; - } - if (tif->tif_header.common.tiff_magic == TIFF_BIGENDIAN) - { -#ifndef WORDS_BIGENDIAN - tif->tif_flags |= TIFF_SWAB; -#endif - } - else - { -#ifdef WORDS_BIGENDIAN - tif->tif_flags |= TIFF_SWAB; -#endif - } - if (tif->tif_flags & TIFF_SWAB) - TIFFSwabShort(&tif->tif_header.common.tiff_version); - if ((tif->tif_header.common.tiff_version != TIFF_VERSION_CLASSIC) && - (tif->tif_header.common.tiff_version != TIFF_VERSION_BIG)) - { - TIFFErrorExtR(tif, name, - "Not a TIFF file, bad version number %" PRIu16 - " (0x%" PRIx16 ")", - tif->tif_header.common.tiff_version, - tif->tif_header.common.tiff_version); - goto bad; - } - if (tif->tif_header.common.tiff_version == TIFF_VERSION_CLASSIC) - { - if (tif->tif_flags & TIFF_SWAB) - TIFFSwabLong(&tif->tif_header.classic.tiff_diroff); - tif->tif_header_size = sizeof(TIFFHeaderClassic); - } - else - { - if (!ReadOK(tif, - ((uint8_t *)(&tif->tif_header) + sizeof(TIFFHeaderClassic)), - (sizeof(TIFFHeaderBig) - sizeof(TIFFHeaderClassic)))) - { - TIFFErrorExtR(tif, name, "Cannot read TIFF header"); - goto bad; - } - if (tif->tif_flags & TIFF_SWAB) - { - TIFFSwabShort(&tif->tif_header.big.tiff_offsetsize); - TIFFSwabLong8(&tif->tif_header.big.tiff_diroff); - } - if (tif->tif_header.big.tiff_offsetsize != 8) - { - TIFFErrorExtR(tif, name, - "Not a TIFF file, bad BigTIFF offsetsize %" PRIu16 - " (0x%" PRIx16 ")", - tif->tif_header.big.tiff_offsetsize, - tif->tif_header.big.tiff_offsetsize); - goto bad; - } - if (tif->tif_header.big.tiff_unused != 0) - { - TIFFErrorExtR(tif, name, - "Not a TIFF file, bad BigTIFF unused %" PRIu16 - " (0x%" PRIx16 ")", - tif->tif_header.big.tiff_unused, - tif->tif_header.big.tiff_unused); - goto bad; - } - tif->tif_header_size = sizeof(TIFFHeaderBig); - tif->tif_flags |= TIFF_BIGTIFF; - } - tif->tif_flags |= TIFF_MYBUFFER; - tif->tif_rawcp = tif->tif_rawdata = 0; - tif->tif_rawdatasize = 0; - tif->tif_rawdataoff = 0; - tif->tif_rawdataloaded = 0; - - switch (mode[0]) - { - case 'r': - if (!(tif->tif_flags & TIFF_BIGTIFF)) - tif->tif_nextdiroff = tif->tif_header.classic.tiff_diroff; - else - tif->tif_nextdiroff = tif->tif_header.big.tiff_diroff; - /* - * Try to use a memory-mapped file if the client - * has not explicitly suppressed usage with the - * 'm' flag in the open mode (see above). - */ - if (tif->tif_flags & TIFF_MAPPED) - { - toff_t n; - if (TIFFMapFileContents(tif, (void **)(&tif->tif_base), &n)) - { - tif->tif_size = (tmsize_t)n; - assert((toff_t)tif->tif_size == n); - } - else - tif->tif_flags &= ~TIFF_MAPPED; - } - /* - * Sometimes we do not want to read the first directory (for - * example, it may be broken) and want to proceed to other - * directories. I this case we use the TIFF_HEADERONLY flag to open - * file and return immediately after reading TIFF header. - */ - if (tif->tif_flags & TIFF_HEADERONLY) - return (tif); - - /* - * Setup initial directory. - */ - if (TIFFReadDirectory(tif)) - { - return (tif); - } - break; - case 'a': - /* - * New directories are automatically append - * to the end of the directory chain when they - * are written out (see TIFFWriteDirectory). - */ - if (!TIFFDefaultDirectory(tif)) - goto bad; - return (tif); - } -bad: - tif->tif_mode = O_RDONLY; /* XXX avoid flush */ - TIFFCleanup(tif); -bad2: - return ((TIFF *)0); -} - -/* - * Query functions to access private data. - */ - -/* - * Return open file's name. - */ -const char *TIFFFileName(TIFF *tif) { return (tif->tif_name); } - -/* - * Set the file name. - */ -const char *TIFFSetFileName(TIFF *tif, const char *name) -{ - const char *old_name = tif->tif_name; - tif->tif_name = (char *)name; - return (old_name); -} - -/* - * Return open file's I/O descriptor. - */ -int TIFFFileno(TIFF *tif) { return (tif->tif_fd); } - -/* - * Set open file's I/O descriptor, and return previous value. - */ -int TIFFSetFileno(TIFF *tif, int fd) -{ - int old_fd = tif->tif_fd; - tif->tif_fd = fd; - return old_fd; -} - -/* - * Return open file's clientdata. - */ -thandle_t TIFFClientdata(TIFF *tif) { return (tif->tif_clientdata); } - -/* - * Set open file's clientdata, and return previous value. - */ -thandle_t TIFFSetClientdata(TIFF *tif, thandle_t newvalue) -{ - thandle_t m = tif->tif_clientdata; - tif->tif_clientdata = newvalue; - return m; -} - -/* - * Return read/write mode. - */ -int TIFFGetMode(TIFF *tif) { return (tif->tif_mode); } - -/* - * Return read/write mode. - */ -int TIFFSetMode(TIFF *tif, int mode) -{ - int old_mode = tif->tif_mode; - tif->tif_mode = mode; - return (old_mode); -} - -/* - * Return nonzero if file is organized in - * tiles; zero if organized as strips. - */ -int TIFFIsTiled(TIFF *tif) { return (isTiled(tif)); } - -/* - * Return current row being read/written. - */ -uint32_t TIFFCurrentRow(TIFF *tif) { return (tif->tif_row); } - -/* - * Return index of the current directory. - */ -tdir_t TIFFCurrentDirectory(TIFF *tif) { return (tif->tif_curdir); } - -/* - * Return current strip. - */ -uint32_t TIFFCurrentStrip(TIFF *tif) { return (tif->tif_curstrip); } - -/* - * Return current tile. - */ -uint32_t TIFFCurrentTile(TIFF *tif) { return (tif->tif_curtile); } - -/* - * Return nonzero if the file has byte-swapped data. - */ -int TIFFIsByteSwapped(TIFF *tif) { return ((tif->tif_flags & TIFF_SWAB) != 0); } - -/* - * Return nonzero if the data is returned up-sampled. - */ -int TIFFIsUpSampled(TIFF *tif) { return (isUpSampled(tif)); } - -/* - * Return nonzero if the data is returned in MSB-to-LSB bit order. - */ -int TIFFIsMSB2LSB(TIFF *tif) { return (isFillOrder(tif, FILLORDER_MSB2LSB)); } - -/* - * Return nonzero if given file was written in big-endian order. - */ -int TIFFIsBigEndian(TIFF *tif) -{ - return (tif->tif_header.common.tiff_magic == TIFF_BIGENDIAN); -} - -/* - * Return nonzero if given file is BigTIFF style. - */ -int TIFFIsBigTIFF(TIFF *tif) -{ - return (tif->tif_header.common.tiff_version == TIFF_VERSION_BIG); -} - -/* - * Return pointer to file read method. - */ -TIFFReadWriteProc TIFFGetReadProc(TIFF *tif) { return (tif->tif_readproc); } - -/* - * Return pointer to file write method. - */ -TIFFReadWriteProc TIFFGetWriteProc(TIFF *tif) { return (tif->tif_writeproc); } - -/* - * Return pointer to file seek method. - */ -TIFFSeekProc TIFFGetSeekProc(TIFF *tif) { return (tif->tif_seekproc); } - -/* - * Return pointer to file close method. - */ -TIFFCloseProc TIFFGetCloseProc(TIFF *tif) { return (tif->tif_closeproc); } - -/* - * Return pointer to file size requesting method. - */ -TIFFSizeProc TIFFGetSizeProc(TIFF *tif) { return (tif->tif_sizeproc); } - -/* - * Return pointer to memory mapping method. - */ -TIFFMapFileProc TIFFGetMapFileProc(TIFF *tif) { return (tif->tif_mapproc); } - -/* - * Return pointer to memory unmapping method. - */ -TIFFUnmapFileProc TIFFGetUnmapFileProc(TIFF *tif) -{ - return (tif->tif_unmapproc); -} diff --git a/src/3rd/tiff/packbits.c b/src/3rd/tiff/packbits.c deleted file mode 100644 index 62849f8f3c1..00000000000 --- a/src/3rd/tiff/packbits.c +++ /dev/null @@ -1,323 +0,0 @@ -/* - * Copyright (c) 1988-1997 Sam Leffler - * Copyright (c) 1991-1997 Silicon Graphics, Inc. - * - * Permission to use, copy, modify, distribute, and sell this software and - * its documentation for any purpose is hereby granted without fee, provided - * that (i) the above copyright notices and this permission notice appear in - * all copies of the software and related documentation, and (ii) the names of - * Sam Leffler and Silicon Graphics may not be used in any advertising or - * publicity relating to the software without the specific, prior written - * permission of Sam Leffler and Silicon Graphics. - * - * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, - * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY - * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. - * - * IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR - * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, - * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, - * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF - * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE - * OF THIS SOFTWARE. - */ - -#include "tiffiop.h" -#ifdef PACKBITS_SUPPORT -/* - * TIFF Library. - * - * PackBits Compression Algorithm Support - */ -#include - -static int PackBitsPreEncode(TIFF *tif, uint16_t s) -{ - (void)s; - - tif->tif_data = (uint8_t *)_TIFFmallocExt(tif, sizeof(tmsize_t)); - if (tif->tif_data == NULL) - return (0); - /* - * Calculate the scanline/tile-width size in bytes. - */ - if (isTiled(tif)) - *(tmsize_t *)tif->tif_data = TIFFTileRowSize(tif); - else - *(tmsize_t *)tif->tif_data = TIFFScanlineSize(tif); - return (1); -} - -static int PackBitsPostEncode(TIFF *tif) -{ - if (tif->tif_data) - _TIFFfreeExt(tif, tif->tif_data); - return (1); -} - -/* - * Encode a run of pixels. - */ -static int PackBitsEncode(TIFF *tif, uint8_t *buf, tmsize_t cc, uint16_t s) -{ - unsigned char *bp = (unsigned char *)buf; - uint8_t *op; - uint8_t *ep; - uint8_t *lastliteral; - long n, slop; - int b; - enum - { - BASE, - LITERAL, - RUN, - LITERAL_RUN - } state; - - (void)s; - op = tif->tif_rawcp; - ep = tif->tif_rawdata + tif->tif_rawdatasize; - state = BASE; - lastliteral = 0; - while (cc > 0) - { - /* - * Find the longest string of identical bytes. - */ - b = *bp++; - cc--; - n = 1; - for (; cc > 0 && b == *bp; cc--, bp++) - n++; - again: - if (op + 2 >= ep) - { /* insure space for new data */ - /* - * Be careful about writing the last - * literal. Must write up to that point - * and then copy the remainder to the - * front of the buffer. - */ - if (state == LITERAL || state == LITERAL_RUN) - { - slop = (long)(op - lastliteral); - tif->tif_rawcc += (tmsize_t)(lastliteral - tif->tif_rawcp); - if (!TIFFFlushData1(tif)) - return (0); - op = tif->tif_rawcp; - while (slop-- > 0) - *op++ = *lastliteral++; - lastliteral = tif->tif_rawcp; - } - else - { - tif->tif_rawcc += (tmsize_t)(op - tif->tif_rawcp); - if (!TIFFFlushData1(tif)) - return (0); - op = tif->tif_rawcp; - } - } - switch (state) - { - case BASE: /* initial state, set run/literal */ - if (n > 1) - { - state = RUN; - if (n > 128) - { - *op++ = (uint8_t)-127; - *op++ = (uint8_t)b; - n -= 128; - goto again; - } - *op++ = (uint8_t)(-(n - 1)); - *op++ = (uint8_t)b; - } - else - { - lastliteral = op; - *op++ = 0; - *op++ = (uint8_t)b; - state = LITERAL; - } - break; - case LITERAL: /* last object was literal string */ - if (n > 1) - { - state = LITERAL_RUN; - if (n > 128) - { - *op++ = (uint8_t)-127; - *op++ = (uint8_t)b; - n -= 128; - goto again; - } - *op++ = (uint8_t)(-(n - 1)); /* encode run */ - *op++ = (uint8_t)b; - } - else - { /* extend literal */ - if (++(*lastliteral) == 127) - state = BASE; - *op++ = (uint8_t)b; - } - break; - case RUN: /* last object was run */ - if (n > 1) - { - if (n > 128) - { - *op++ = (uint8_t)-127; - *op++ = (uint8_t)b; - n -= 128; - goto again; - } - *op++ = (uint8_t)(-(n - 1)); - *op++ = (uint8_t)b; - } - else - { - lastliteral = op; - *op++ = 0; - *op++ = (uint8_t)b; - state = LITERAL; - } - break; - case LITERAL_RUN: /* literal followed by a run */ - /* - * Check to see if previous run should - * be converted to a literal, in which - * case we convert literal-run-literal - * to a single literal. - */ - if (n == 1 && op[-2] == (uint8_t)-1 && *lastliteral < 126) - { - state = (((*lastliteral) += 2) == 127 ? BASE : LITERAL); - op[-2] = op[-1]; /* replicate */ - } - else - state = RUN; - goto again; - } - } - tif->tif_rawcc += (tmsize_t)(op - tif->tif_rawcp); - tif->tif_rawcp = op; - return (1); -} - -/* - * Encode a rectangular chunk of pixels. We break it up - * into row-sized pieces to insure that encoded runs do - * not span rows. Otherwise, there can be problems with - * the decoder if data is read, for example, by scanlines - * when it was encoded by strips. - */ -static int PackBitsEncodeChunk(TIFF *tif, uint8_t *bp, tmsize_t cc, uint16_t s) -{ - tmsize_t rowsize = *(tmsize_t *)tif->tif_data; - - while (cc > 0) - { - tmsize_t chunk = rowsize; - - if (cc < chunk) - chunk = cc; - - if (PackBitsEncode(tif, bp, chunk, s) < 0) - return (-1); - bp += chunk; - cc -= chunk; - } - return (1); -} - -static int PackBitsDecode(TIFF *tif, uint8_t *op, tmsize_t occ, uint16_t s) -{ - static const char module[] = "PackBitsDecode"; - int8_t *bp; - tmsize_t cc; - long n; - int b; - - (void)s; - bp = (int8_t *)tif->tif_rawcp; - cc = tif->tif_rawcc; - while (cc > 0 && occ > 0) - { - n = (long)*bp++; - cc--; - if (n < 0) - { /* replicate next byte -n+1 times */ - if (n == -128) /* nop */ - continue; - n = -n + 1; - if (occ < (tmsize_t)n) - { - TIFFWarningExtR(tif, module, - "Discarding %" TIFF_SSIZE_FORMAT - " bytes to avoid buffer overrun", - (tmsize_t)n - occ); - n = (long)occ; - } - if (cc == 0) - { - TIFFWarningExtR( - tif, module, - "Terminating PackBitsDecode due to lack of data."); - break; - } - occ -= n; - b = *bp++; - cc--; - while (n-- > 0) - *op++ = (uint8_t)b; - } - else - { /* copy next n+1 bytes literally */ - if (occ < (tmsize_t)(n + 1)) - { - TIFFWarningExtR(tif, module, - "Discarding %" TIFF_SSIZE_FORMAT - " bytes to avoid buffer overrun", - (tmsize_t)n - occ + 1); - n = (long)occ - 1; - } - if (cc < (tmsize_t)(n + 1)) - { - TIFFWarningExtR( - tif, module, - "Terminating PackBitsDecode due to lack of data."); - break; - } - _TIFFmemcpy(op, bp, ++n); - op += n; - occ -= n; - bp += n; - cc -= n; - } - } - tif->tif_rawcp = (uint8_t *)bp; - tif->tif_rawcc = cc; - if (occ > 0) - { - TIFFErrorExtR(tif, module, "Not enough data for scanline %" PRIu32, - tif->tif_row); - return (0); - } - return (1); -} - -int TIFFInitPackBits(TIFF *tif, int scheme) -{ - (void)scheme; - tif->tif_decoderow = PackBitsDecode; - tif->tif_decodestrip = PackBitsDecode; - tif->tif_decodetile = PackBitsDecode; - tif->tif_preencode = PackBitsPreEncode; - tif->tif_postencode = PackBitsPostEncode; - tif->tif_encoderow = PackBitsEncode; - tif->tif_encodestrip = PackBitsEncodeChunk; - tif->tif_encodetile = PackBitsEncodeChunk; - return (1); -} -#endif /* PACKBITS_SUPPORT */ diff --git a/src/3rd/tiff/pixarlog.c b/src/3rd/tiff/pixarlog.c deleted file mode 100644 index 5049866bbfc..00000000000 --- a/src/3rd/tiff/pixarlog.c +++ /dev/null @@ -1,1670 +0,0 @@ -/* - * Copyright (c) 1996-1997 Sam Leffler - * Copyright (c) 1996 Pixar - * - * Permission to use, copy, modify, distribute, and sell this software and - * its documentation for any purpose is hereby granted without fee, provided - * that (i) the above copyright notices and this permission notice appear in - * all copies of the software and related documentation, and (ii) the names of - * Pixar, Sam Leffler and Silicon Graphics may not be used in any advertising or - * publicity relating to the software without the specific, prior written - * permission of Pixar, Sam Leffler and Silicon Graphics. - * - * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, - * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY - * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. - * - * IN NO EVENT SHALL PIXAR, SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR - * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, - * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, - * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF - * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE - * OF THIS SOFTWARE. - */ - -#include "tiffiop.h" -#ifdef PIXARLOG_SUPPORT - -/* - * TIFF Library. - * PixarLog Compression Support - * - * Contributed by Dan McCoy. - * - * PixarLog film support uses the TIFF library to store companded - * 11 bit values into a tiff file, which are compressed using the - * zip compressor. - * - * The codec can take as input and produce as output 32-bit IEEE float values - * as well as 16-bit or 8-bit unsigned integer values. - * - * On writing any of the above are converted into the internal - * 11-bit log format. In the case of 8 and 16 bit values, the - * input is assumed to be unsigned linear color values that represent - * the range 0-1. In the case of IEEE values, the 0-1 range is assumed to - * be the normal linear color range, in addition over 1 values are - * accepted up to a value of about 25.0 to encode "hot" highlights and such. - * The encoding is lossless for 8-bit values, slightly lossy for the - * other bit depths. The actual color precision should be better - * than the human eye can perceive with extra room to allow for - * error introduced by further image computation. As with any quantized - * color format, it is possible to perform image calculations which - * expose the quantization error. This format should certainly be less - * susceptible to such errors than standard 8-bit encodings, but more - * susceptible than straight 16-bit or 32-bit encodings. - * - * On reading the internal format is converted to the desired output format. - * The program can request which format it desires by setting the internal - * pseudo tag TIFFTAG_PIXARLOGDATAFMT to one of these possible values: - * PIXARLOGDATAFMT_FLOAT = provide IEEE float values. - * PIXARLOGDATAFMT_16BIT = provide unsigned 16-bit integer values - * PIXARLOGDATAFMT_8BIT = provide unsigned 8-bit integer values - * - * alternately PIXARLOGDATAFMT_8BITABGR provides unsigned 8-bit integer - * values with the difference that if there are exactly three or four channels - * (rgb or rgba) it swaps the channel order (bgr or abgr). - * - * PIXARLOGDATAFMT_11BITLOG provides the internal encoding directly - * packed in 16-bit values. However no tools are supplied for interpreting - * these values. - * - * "hot" (over 1.0) areas written in floating point get clamped to - * 1.0 in the integer data types. - * - * When the file is closed after writing, the bit depth and sample format - * are set always to appear as if 8-bit data has been written into it. - * That way a naive program unaware of the particulars of the encoding - * gets the format it is most likely able to handle. - * - * The codec does it's own horizontal differencing step on the coded - * values so the libraries predictor stuff should be turned off. - * The codec also handle byte swapping the encoded values as necessary - * since the library does not have the information necessary - * to know the bit depth of the raw unencoded buffer. - * - * NOTE: This decoder does not appear to update tif_rawcp, and tif_rawcc. - * This can cause problems with the implementation of CHUNKY_STRIP_READ_SUPPORT - * as noted in http://trac.osgeo.org/gdal/ticket/3894. FrankW - Jan'11 - */ - -#include "predict.h" -#include "zlib.h" - -#include -#include -#include - -/* Tables for converting to/from 11 bit coded values */ - -#define TSIZE 2048 /* decode table size (11-bit tokens) */ -#define TSIZEP1 2049 /* Plus one for slop */ -#define ONE 1250 /* token value of 1.0 exactly */ -#define RATIO 1.004 /* nominal ratio for log part */ - -#define CODE_MASK 0x7ff /* 11 bits. */ - -static float Fltsize; -static float LogK1, LogK2; - -#define REPEAT(n, op) \ - { \ - int i; \ - i = n; \ - do \ - { \ - i--; \ - op; \ - } while (i > 0); \ - } - -static void horizontalAccumulateF(uint16_t *wp, int n, int stride, float *op, - float *ToLinearF) -{ - register unsigned int cr, cg, cb, ca, mask; - register float t0, t1, t2, t3; - - if (n >= stride) - { - mask = CODE_MASK; - if (stride == 3) - { - t0 = ToLinearF[cr = (wp[0] & mask)]; - t1 = ToLinearF[cg = (wp[1] & mask)]; - t2 = ToLinearF[cb = (wp[2] & mask)]; - op[0] = t0; - op[1] = t1; - op[2] = t2; - n -= 3; - while (n > 0) - { - wp += 3; - op += 3; - n -= 3; - t0 = ToLinearF[(cr += wp[0]) & mask]; - t1 = ToLinearF[(cg += wp[1]) & mask]; - t2 = ToLinearF[(cb += wp[2]) & mask]; - op[0] = t0; - op[1] = t1; - op[2] = t2; - } - } - else if (stride == 4) - { - t0 = ToLinearF[cr = (wp[0] & mask)]; - t1 = ToLinearF[cg = (wp[1] & mask)]; - t2 = ToLinearF[cb = (wp[2] & mask)]; - t3 = ToLinearF[ca = (wp[3] & mask)]; - op[0] = t0; - op[1] = t1; - op[2] = t2; - op[3] = t3; - n -= 4; - while (n > 0) - { - wp += 4; - op += 4; - n -= 4; - t0 = ToLinearF[(cr += wp[0]) & mask]; - t1 = ToLinearF[(cg += wp[1]) & mask]; - t2 = ToLinearF[(cb += wp[2]) & mask]; - t3 = ToLinearF[(ca += wp[3]) & mask]; - op[0] = t0; - op[1] = t1; - op[2] = t2; - op[3] = t3; - } - } - else - { - REPEAT(stride, *op = ToLinearF[*wp & mask]; wp++; op++) - n -= stride; - while (n > 0) - { - REPEAT(stride, wp[stride] += *wp; *op = ToLinearF[*wp & mask]; - wp++; op++) - n -= stride; - } - } - } -} - -static void horizontalAccumulate12(uint16_t *wp, int n, int stride, int16_t *op, - float *ToLinearF) -{ - register unsigned int cr, cg, cb, ca, mask; - register float t0, t1, t2, t3; - -#define SCALE12 2048.0F -#define CLAMP12(t) (((t) < 3071) ? (uint16_t)(t) : 3071) - - if (n >= stride) - { - mask = CODE_MASK; - if (stride == 3) - { - t0 = ToLinearF[cr = (wp[0] & mask)] * SCALE12; - t1 = ToLinearF[cg = (wp[1] & mask)] * SCALE12; - t2 = ToLinearF[cb = (wp[2] & mask)] * SCALE12; - op[0] = CLAMP12(t0); - op[1] = CLAMP12(t1); - op[2] = CLAMP12(t2); - n -= 3; - while (n > 0) - { - wp += 3; - op += 3; - n -= 3; - t0 = ToLinearF[(cr += wp[0]) & mask] * SCALE12; - t1 = ToLinearF[(cg += wp[1]) & mask] * SCALE12; - t2 = ToLinearF[(cb += wp[2]) & mask] * SCALE12; - op[0] = CLAMP12(t0); - op[1] = CLAMP12(t1); - op[2] = CLAMP12(t2); - } - } - else if (stride == 4) - { - t0 = ToLinearF[cr = (wp[0] & mask)] * SCALE12; - t1 = ToLinearF[cg = (wp[1] & mask)] * SCALE12; - t2 = ToLinearF[cb = (wp[2] & mask)] * SCALE12; - t3 = ToLinearF[ca = (wp[3] & mask)] * SCALE12; - op[0] = CLAMP12(t0); - op[1] = CLAMP12(t1); - op[2] = CLAMP12(t2); - op[3] = CLAMP12(t3); - n -= 4; - while (n > 0) - { - wp += 4; - op += 4; - n -= 4; - t0 = ToLinearF[(cr += wp[0]) & mask] * SCALE12; - t1 = ToLinearF[(cg += wp[1]) & mask] * SCALE12; - t2 = ToLinearF[(cb += wp[2]) & mask] * SCALE12; - t3 = ToLinearF[(ca += wp[3]) & mask] * SCALE12; - op[0] = CLAMP12(t0); - op[1] = CLAMP12(t1); - op[2] = CLAMP12(t2); - op[3] = CLAMP12(t3); - } - } - else - { - REPEAT(stride, t0 = ToLinearF[*wp & mask] * SCALE12; - *op = CLAMP12(t0); wp++; op++) - n -= stride; - while (n > 0) - { - REPEAT(stride, wp[stride] += *wp; - t0 = ToLinearF[wp[stride] & mask] * SCALE12; - *op = CLAMP12(t0); wp++; op++) - n -= stride; - } - } - } -} - -static void horizontalAccumulate16(uint16_t *wp, int n, int stride, - uint16_t *op, uint16_t *ToLinear16) -{ - register unsigned int cr, cg, cb, ca, mask; - - if (n >= stride) - { - mask = CODE_MASK; - if (stride == 3) - { - op[0] = ToLinear16[cr = (wp[0] & mask)]; - op[1] = ToLinear16[cg = (wp[1] & mask)]; - op[2] = ToLinear16[cb = (wp[2] & mask)]; - n -= 3; - while (n > 0) - { - wp += 3; - op += 3; - n -= 3; - op[0] = ToLinear16[(cr += wp[0]) & mask]; - op[1] = ToLinear16[(cg += wp[1]) & mask]; - op[2] = ToLinear16[(cb += wp[2]) & mask]; - } - } - else if (stride == 4) - { - op[0] = ToLinear16[cr = (wp[0] & mask)]; - op[1] = ToLinear16[cg = (wp[1] & mask)]; - op[2] = ToLinear16[cb = (wp[2] & mask)]; - op[3] = ToLinear16[ca = (wp[3] & mask)]; - n -= 4; - while (n > 0) - { - wp += 4; - op += 4; - n -= 4; - op[0] = ToLinear16[(cr += wp[0]) & mask]; - op[1] = ToLinear16[(cg += wp[1]) & mask]; - op[2] = ToLinear16[(cb += wp[2]) & mask]; - op[3] = ToLinear16[(ca += wp[3]) & mask]; - } - } - else - { - REPEAT(stride, *op = ToLinear16[*wp & mask]; wp++; op++) - n -= stride; - while (n > 0) - { - REPEAT(stride, wp[stride] += *wp; *op = ToLinear16[*wp & mask]; - wp++; op++) - n -= stride; - } - } - } -} - -/* - * Returns the log encoded 11-bit values with the horizontal - * differencing undone. - */ -static void horizontalAccumulate11(uint16_t *wp, int n, int stride, - uint16_t *op) -{ - register unsigned int cr, cg, cb, ca, mask; - - if (n >= stride) - { - mask = CODE_MASK; - if (stride == 3) - { - op[0] = wp[0]; - op[1] = wp[1]; - op[2] = wp[2]; - cr = wp[0]; - cg = wp[1]; - cb = wp[2]; - n -= 3; - while (n > 0) - { - wp += 3; - op += 3; - n -= 3; - op[0] = (uint16_t)((cr += wp[0]) & mask); - op[1] = (uint16_t)((cg += wp[1]) & mask); - op[2] = (uint16_t)((cb += wp[2]) & mask); - } - } - else if (stride == 4) - { - op[0] = wp[0]; - op[1] = wp[1]; - op[2] = wp[2]; - op[3] = wp[3]; - cr = wp[0]; - cg = wp[1]; - cb = wp[2]; - ca = wp[3]; - n -= 4; - while (n > 0) - { - wp += 4; - op += 4; - n -= 4; - op[0] = (uint16_t)((cr += wp[0]) & mask); - op[1] = (uint16_t)((cg += wp[1]) & mask); - op[2] = (uint16_t)((cb += wp[2]) & mask); - op[3] = (uint16_t)((ca += wp[3]) & mask); - } - } - else - { - REPEAT(stride, *op = *wp & mask; wp++; op++) - n -= stride; - while (n > 0) - { - REPEAT(stride, wp[stride] += *wp; *op = *wp & mask; wp++; op++) - n -= stride; - } - } - } -} - -static void horizontalAccumulate8(uint16_t *wp, int n, int stride, - unsigned char *op, unsigned char *ToLinear8) -{ - register unsigned int cr, cg, cb, ca, mask; - - if (n >= stride) - { - mask = CODE_MASK; - if (stride == 3) - { - op[0] = ToLinear8[cr = (wp[0] & mask)]; - op[1] = ToLinear8[cg = (wp[1] & mask)]; - op[2] = ToLinear8[cb = (wp[2] & mask)]; - n -= 3; - while (n > 0) - { - n -= 3; - wp += 3; - op += 3; - op[0] = ToLinear8[(cr += wp[0]) & mask]; - op[1] = ToLinear8[(cg += wp[1]) & mask]; - op[2] = ToLinear8[(cb += wp[2]) & mask]; - } - } - else if (stride == 4) - { - op[0] = ToLinear8[cr = (wp[0] & mask)]; - op[1] = ToLinear8[cg = (wp[1] & mask)]; - op[2] = ToLinear8[cb = (wp[2] & mask)]; - op[3] = ToLinear8[ca = (wp[3] & mask)]; - n -= 4; - while (n > 0) - { - n -= 4; - wp += 4; - op += 4; - op[0] = ToLinear8[(cr += wp[0]) & mask]; - op[1] = ToLinear8[(cg += wp[1]) & mask]; - op[2] = ToLinear8[(cb += wp[2]) & mask]; - op[3] = ToLinear8[(ca += wp[3]) & mask]; - } - } - else - { - REPEAT(stride, *op = ToLinear8[*wp & mask]; wp++; op++) - n -= stride; - while (n > 0) - { - REPEAT(stride, wp[stride] += *wp; *op = ToLinear8[*wp & mask]; - wp++; op++) - n -= stride; - } - } - } -} - -static void horizontalAccumulate8abgr(uint16_t *wp, int n, int stride, - unsigned char *op, - unsigned char *ToLinear8) -{ - register unsigned int cr, cg, cb, ca, mask; - register unsigned char t0, t1, t2, t3; - - if (n >= stride) - { - mask = CODE_MASK; - if (stride == 3) - { - op[0] = 0; - t1 = ToLinear8[cb = (wp[2] & mask)]; - t2 = ToLinear8[cg = (wp[1] & mask)]; - t3 = ToLinear8[cr = (wp[0] & mask)]; - op[1] = t1; - op[2] = t2; - op[3] = t3; - n -= 3; - while (n > 0) - { - n -= 3; - wp += 3; - op += 4; - op[0] = 0; - t1 = ToLinear8[(cb += wp[2]) & mask]; - t2 = ToLinear8[(cg += wp[1]) & mask]; - t3 = ToLinear8[(cr += wp[0]) & mask]; - op[1] = t1; - op[2] = t2; - op[3] = t3; - } - } - else if (stride == 4) - { - t0 = ToLinear8[ca = (wp[3] & mask)]; - t1 = ToLinear8[cb = (wp[2] & mask)]; - t2 = ToLinear8[cg = (wp[1] & mask)]; - t3 = ToLinear8[cr = (wp[0] & mask)]; - op[0] = t0; - op[1] = t1; - op[2] = t2; - op[3] = t3; - n -= 4; - while (n > 0) - { - n -= 4; - wp += 4; - op += 4; - t0 = ToLinear8[(ca += wp[3]) & mask]; - t1 = ToLinear8[(cb += wp[2]) & mask]; - t2 = ToLinear8[(cg += wp[1]) & mask]; - t3 = ToLinear8[(cr += wp[0]) & mask]; - op[0] = t0; - op[1] = t1; - op[2] = t2; - op[3] = t3; - } - } - else - { - REPEAT(stride, *op = ToLinear8[*wp & mask]; wp++; op++) - n -= stride; - while (n > 0) - { - REPEAT(stride, wp[stride] += *wp; *op = ToLinear8[*wp & mask]; - wp++; op++) - n -= stride; - } - } - } -} - -/* - * State block for each open TIFF - * file using PixarLog compression/decompression. - */ -typedef struct -{ - TIFFPredictorState predict; - z_stream stream; - tmsize_t tbuf_size; /* only set/used on reading for now */ - uint16_t *tbuf; - uint16_t stride; - int state; - int user_datafmt; - int quality; -#define PLSTATE_INIT 1 - - TIFFVSetMethod vgetparent; /* super-class method */ - TIFFVSetMethod vsetparent; /* super-class method */ - - float *ToLinearF; - uint16_t *ToLinear16; - unsigned char *ToLinear8; - uint16_t *FromLT2; - uint16_t *From14; /* Really for 16-bit data, but we shift down 2 */ - uint16_t *From8; - -} PixarLogState; - -static int PixarLogMakeTables(TIFF *tif, PixarLogState *sp) -{ - - /* - * We make several tables here to convert between various external - * representations (float, 16-bit, and 8-bit) and the internal - * 11-bit companded representation. The 11-bit representation has two - * distinct regions. A linear bottom end up through .018316 in steps - * of about .000073, and a region of constant ratio up to about 25. - * These floating point numbers are stored in the main table ToLinearF. - * All other tables are derived from this one. The tables (and the - * ratios) are continuous at the internal seam. - */ - - int nlin, lt2size; - int i, j; - double b, c, linstep, v; - float *ToLinearF; - uint16_t *ToLinear16; - unsigned char *ToLinear8; - uint16_t *FromLT2; - uint16_t *From14; /* Really for 16-bit data, but we shift down 2 */ - uint16_t *From8; - - c = log(RATIO); - nlin = (int)(1. / c); /* nlin must be an integer */ - c = 1. / nlin; - b = exp(-c * ONE); /* multiplicative scale factor [b*exp(c*ONE) = 1] */ - linstep = b * c * exp(1.); - - 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)); - 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)); - ToLinear16 = (uint16_t *)_TIFFmallocExt(tif, TSIZEP1 * sizeof(uint16_t)); - ToLinear8 = - (unsigned char *)_TIFFmallocExt(tif, TSIZEP1 * sizeof(unsigned char)); - if (FromLT2 == NULL || From14 == NULL || From8 == NULL || - ToLinearF == NULL || ToLinear16 == NULL || ToLinear8 == NULL) - { - if (FromLT2) - _TIFFfreeExt(tif, FromLT2); - if (From14) - _TIFFfreeExt(tif, From14); - if (From8) - _TIFFfreeExt(tif, From8); - if (ToLinearF) - _TIFFfreeExt(tif, ToLinearF); - if (ToLinear16) - _TIFFfreeExt(tif, ToLinear16); - if (ToLinear8) - _TIFFfreeExt(tif, ToLinear8); - sp->FromLT2 = NULL; - sp->From14 = NULL; - sp->From8 = NULL; - sp->ToLinearF = NULL; - sp->ToLinear16 = NULL; - sp->ToLinear8 = NULL; - return 0; - } - - j = 0; - - for (i = 0; i < nlin; i++) - { - v = i * linstep; - ToLinearF[j++] = (float)v; - } - - for (i = nlin; i < TSIZE; i++) - ToLinearF[j++] = (float)(b * exp(c * i)); - - ToLinearF[2048] = ToLinearF[2047]; - - for (i = 0; i < TSIZEP1; i++) - { - v = ToLinearF[i] * 65535.0 + 0.5; - ToLinear16[i] = (v > 65535.0) ? 65535 : (uint16_t)v; - v = 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]) - j++; - FromLT2[i] = (uint16_t)j; - } - - /* - * Since we lose info anyway on 16-bit data, we set up a 14-bit - * table and shift 16-bit values down two bits on input. - * saves a little table space. - */ - j = 0; - for (i = 0; i < 16384; i++) - { - while ((i / 16383.) * (i / 16383.) > ToLinearF[j] * ToLinearF[j + 1]) - j++; - From14[i] = (uint16_t)j; - } - - j = 0; - for (i = 0; i < 256; i++) - { - while ((i / 255.) * (i / 255.) > ToLinearF[j] * ToLinearF[j + 1]) - j++; - From8[i] = (uint16_t)j; - } - - Fltsize = (float)(lt2size / 2); - - sp->ToLinearF = ToLinearF; - sp->ToLinear16 = ToLinear16; - sp->ToLinear8 = ToLinear8; - sp->FromLT2 = FromLT2; - sp->From14 = From14; - sp->From8 = From8; - - return 1; -} - -#define DecoderState(tif) ((PixarLogState *)(tif)->tif_data) -#define EncoderState(tif) ((PixarLogState *)(tif)->tif_data) - -static int PixarLogEncode(TIFF *tif, uint8_t *bp, tmsize_t cc, uint16_t s); -static int PixarLogDecode(TIFF *tif, uint8_t *op, tmsize_t occ, uint16_t s); - -#define PIXARLOGDATAFMT_UNKNOWN -1 - -static int PixarLogGuessDataFmt(TIFFDirectory *td) -{ - int guess = PIXARLOGDATAFMT_UNKNOWN; - int format = td->td_sampleformat; - - /* If the user didn't tell us his datafmt, - * take our best guess from the bitspersample. - */ - switch (td->td_bitspersample) - { - case 32: - if (format == SAMPLEFORMAT_IEEEFP) - guess = PIXARLOGDATAFMT_FLOAT; - break; - case 16: - if (format == SAMPLEFORMAT_VOID || format == SAMPLEFORMAT_UINT) - guess = PIXARLOGDATAFMT_16BIT; - break; - case 12: - if (format == SAMPLEFORMAT_VOID || format == SAMPLEFORMAT_INT) - guess = PIXARLOGDATAFMT_12BITPICIO; - break; - case 11: - if (format == SAMPLEFORMAT_VOID || format == SAMPLEFORMAT_UINT) - guess = PIXARLOGDATAFMT_11BITLOG; - break; - case 8: - if (format == SAMPLEFORMAT_VOID || format == SAMPLEFORMAT_UINT) - guess = PIXARLOGDATAFMT_8BIT; - break; - } - - return guess; -} - -static tmsize_t multiply_ms(tmsize_t m1, tmsize_t m2) -{ - return _TIFFMultiplySSize(NULL, m1, m2, NULL); -} - -static tmsize_t add_ms(tmsize_t m1, tmsize_t m2) -{ - assert(m1 >= 0 && m2 >= 0); - /* if either input is zero, assume overflow already occurred */ - if (m1 == 0 || m2 == 0) - return 0; - else if (m1 > TIFF_TMSIZE_T_MAX - m2) - return 0; - - return m1 + m2; -} - -static int PixarLogFixupTags(TIFF *tif) -{ - (void)tif; - return (1); -} - -static int PixarLogSetupDecode(TIFF *tif) -{ - static const char module[] = "PixarLogSetupDecode"; - TIFFDirectory *td = &tif->tif_dir; - PixarLogState *sp = DecoderState(tif); - tmsize_t tbuf_size; - uint32_t strip_height; - - assert(sp != NULL); - - /* This function can possibly be called several times by */ - /* PredictorSetupDecode() if this function succeeds but */ - /* PredictorSetup() fails */ - if ((sp->state & PLSTATE_INIT) != 0) - return 1; - - strip_height = td->td_rowsperstrip; - if (strip_height > td->td_imagelength) - strip_height = td->td_imagelength; - - /* Make sure no byte swapping happens on the data - * after decompression. */ - tif->tif_postdecode = _TIFFNoPostDecode; - - /* for some reason, we can't do this in TIFFInitPixarLog */ - - sp->stride = - (td->td_planarconfig == PLANARCONFIG_CONTIG ? td->td_samplesperpixel - : 1); - tbuf_size = multiply_ms( - 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); - if (tbuf_size == 0) - return (0); /* TODO: this is an error return without error report - through TIFFErrorExt */ - sp->tbuf = (uint16_t *)_TIFFmallocExt(tif, tbuf_size); - if (sp->tbuf == NULL) - return (0); - sp->tbuf_size = tbuf_size; - if (sp->user_datafmt == PIXARLOGDATAFMT_UNKNOWN) - sp->user_datafmt = PixarLogGuessDataFmt(td); - if (sp->user_datafmt == PIXARLOGDATAFMT_UNKNOWN) - { - _TIFFfreeExt(tif, sp->tbuf); - sp->tbuf = NULL; - sp->tbuf_size = 0; - TIFFErrorExtR(tif, module, - "PixarLog compression can't handle bits depth/data " - "format combination (depth: %" PRIu16 ")", - td->td_bitspersample); - return (0); - } - - if (inflateInit(&sp->stream) != Z_OK) - { - _TIFFfreeExt(tif, sp->tbuf); - sp->tbuf = NULL; - sp->tbuf_size = 0; - TIFFErrorExtR(tif, module, "%s", - sp->stream.msg ? sp->stream.msg : "(null)"); - return (0); - } - else - { - sp->state |= PLSTATE_INIT; - return (1); - } -} - -/* - * Setup state for decoding a strip. - */ -static int PixarLogPreDecode(TIFF *tif, uint16_t s) -{ - static const char module[] = "PixarLogPreDecode"; - PixarLogState *sp = DecoderState(tif); - - (void)s; - assert(sp != NULL); - sp->stream.next_in = tif->tif_rawdata; - assert(sizeof(sp->stream.avail_in) == 4); /* if this assert gets raised, - 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)tif->tif_rawcc; - if ((tmsize_t)sp->stream.avail_in != tif->tif_rawcc) - { - TIFFErrorExtR(tif, module, "ZLib cannot deal with buffers this size"); - return (0); - } - return (inflateReset(&sp->stream) == Z_OK); -} - -static int PixarLogDecode(TIFF *tif, uint8_t *op, tmsize_t occ, uint16_t s) -{ - static const char module[] = "PixarLogDecode"; - TIFFDirectory *td = &tif->tif_dir; - PixarLogState *sp = DecoderState(tif); - tmsize_t i; - tmsize_t nsamples; - int llen; - uint16_t *up; - - switch (sp->user_datafmt) - { - case PIXARLOGDATAFMT_FLOAT: - nsamples = 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 */ - break; - case PIXARLOGDATAFMT_8BIT: - case PIXARLOGDATAFMT_8BITABGR: - nsamples = occ; - break; - default: - TIFFErrorExtR(tif, module, - "%" PRIu16 " bit input not supported in PixarLog", - td->td_bitspersample); - return 0; - } - - llen = sp->stride * td->td_imagewidth; - - (void)s; - assert(sp != NULL); - - sp->stream.next_in = tif->tif_rawcp; - sp->stream.avail_in = (uInt)tif->tif_rawcc; - - sp->stream.next_out = (unsigned char *)sp->tbuf; - assert(sizeof(sp->stream.avail_out) == 4); /* if this assert gets raised, - 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)) - { - TIFFErrorExtR(tif, module, "ZLib cannot deal with buffers this size"); - return (0); - } - /* Check that we will not fill more than what was allocated */ - if ((tmsize_t)sp->stream.avail_out > sp->tbuf_size) - { - TIFFErrorExtR(tif, module, "sp->stream.avail_out > sp->tbuf_size"); - return (0); - } - do - { - int state = inflate(&sp->stream, Z_PARTIAL_FLUSH); - if (state == Z_STREAM_END) - { - break; /* XXX */ - } - if (state == Z_DATA_ERROR) - { - TIFFErrorExtR( - tif, module, "Decoding error at scanline %" PRIu32 ", %s", - tif->tif_row, sp->stream.msg ? sp->stream.msg : "(null)"); - return (0); - } - if (state != Z_OK) - { - TIFFErrorExtR(tif, module, "ZLib error: %s", - sp->stream.msg ? sp->stream.msg : "(null)"); - return (0); - } - } while (sp->stream.avail_out > 0); - - /* hopefully, we got all the bytes we needed */ - if (sp->stream.avail_out != 0) - { - TIFFErrorExtR(tif, module, - "Not enough data at scanline %" PRIu32 - " (short %u bytes)", - tif->tif_row, sp->stream.avail_out); - return (0); - } - - tif->tif_rawcp = sp->stream.next_in; - tif->tif_rawcc = sp->stream.avail_in; - - up = sp->tbuf; - /* Swap bytes in the data if from a different endian machine. */ - if (tif->tif_flags & TIFF_SWAB) - TIFFSwabArrayOfShort(up, nsamples); - - /* - * if llen is not an exact multiple of nsamples, the decode operation - * may overflow the output buffer, so truncate it enough to prevent - * that but still salvage as much data as possible. - */ - if (nsamples % llen) - { - TIFFWarningExtR(tif, module, - "stride %d is not a multiple of sample count, " - "%" TIFF_SSIZE_FORMAT ", data truncated.", - llen, nsamples); - nsamples -= nsamples % llen; - } - - for (i = 0; i < nsamples; i += llen, up += llen) - { - switch (sp->user_datafmt) - { - case PIXARLOGDATAFMT_FLOAT: - horizontalAccumulateF(up, llen, sp->stride, (float *)op, - sp->ToLinearF); - op += llen * sizeof(float); - break; - case PIXARLOGDATAFMT_16BIT: - horizontalAccumulate16(up, llen, sp->stride, (uint16_t *)op, - sp->ToLinear16); - op += llen * sizeof(uint16_t); - break; - case PIXARLOGDATAFMT_12BITPICIO: - horizontalAccumulate12(up, llen, sp->stride, (int16_t *)op, - sp->ToLinearF); - op += llen * sizeof(int16_t); - break; - case PIXARLOGDATAFMT_11BITLOG: - horizontalAccumulate11(up, llen, sp->stride, (uint16_t *)op); - op += llen * sizeof(uint16_t); - break; - case PIXARLOGDATAFMT_8BIT: - horizontalAccumulate8(up, llen, sp->stride, (unsigned char *)op, - sp->ToLinear8); - op += llen * sizeof(unsigned char); - break; - case PIXARLOGDATAFMT_8BITABGR: - horizontalAccumulate8abgr(up, llen, sp->stride, - (unsigned char *)op, sp->ToLinear8); - op += llen * sizeof(unsigned char); - break; - default: - TIFFErrorExtR(tif, module, "Unsupported bits/sample: %" PRIu16, - td->td_bitspersample); - return (0); - } - } - - return (1); -} - -static int PixarLogSetupEncode(TIFF *tif) -{ - static const char module[] = "PixarLogSetupEncode"; - TIFFDirectory *td = &tif->tif_dir; - PixarLogState *sp = EncoderState(tif); - tmsize_t tbuf_size; - - assert(sp != NULL); - - /* for some reason, we can't do this in TIFFInitPixarLog */ - - sp->stride = - (td->td_planarconfig == PLANARCONFIG_CONTIG ? td->td_samplesperpixel - : 1); - tbuf_size = - multiply_ms(multiply_ms(multiply_ms(sp->stride, td->td_imagewidth), - td->td_rowsperstrip), - sizeof(uint16_t)); - if (tbuf_size == 0) - return (0); /* TODO: this is an error return without error report - through TIFFErrorExt */ - sp->tbuf = (uint16_t *)_TIFFmallocExt(tif, tbuf_size); - if (sp->tbuf == NULL) - return (0); - if (sp->user_datafmt == PIXARLOGDATAFMT_UNKNOWN) - sp->user_datafmt = PixarLogGuessDataFmt(td); - if (sp->user_datafmt == PIXARLOGDATAFMT_UNKNOWN) - { - TIFFErrorExtR(tif, module, - "PixarLog compression can't handle %" PRIu16 - " bit linear encodings", - td->td_bitspersample); - return (0); - } - - if (deflateInit(&sp->stream, sp->quality) != Z_OK) - { - TIFFErrorExtR(tif, module, "%s", - sp->stream.msg ? sp->stream.msg : "(null)"); - return (0); - } - else - { - sp->state |= PLSTATE_INIT; - return (1); - } -} - -/* - * Reset encoding state at the start of a strip. - */ -static int PixarLogPreEncode(TIFF *tif, uint16_t s) -{ - static const char module[] = "PixarLogPreEncode"; - PixarLogState *sp = EncoderState(tif); - - (void)s; - assert(sp != NULL); - sp->stream.next_out = tif->tif_rawdata; - assert(sizeof(sp->stream.avail_out) == 4); /* if this assert gets raised, - 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)tif->tif_rawdatasize; - if ((tmsize_t)sp->stream.avail_out != tif->tif_rawdatasize) - { - TIFFErrorExtR(tif, module, "ZLib cannot deal with buffers this size"); - return (0); - } - return (deflateReset(&sp->stream) == Z_OK); -} - -static void horizontalDifferenceF(float *ip, int 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) - - mask = CODE_MASK; - if (n >= stride) - { - if (stride == 3) - { - r2 = wp[0] = (uint16_t)CLAMP(ip[0]); - g2 = wp[1] = (uint16_t)CLAMP(ip[1]); - b2 = wp[2] = (uint16_t)CLAMP(ip[2]); - n -= 3; - while (n > 0) - { - n -= 3; - wp += 3; - ip += 3; - r1 = (int32_t)CLAMP(ip[0]); - wp[0] = (uint16_t)((r1 - r2) & mask); - r2 = r1; - g1 = (int32_t)CLAMP(ip[1]); - wp[1] = (uint16_t)((g1 - g2) & mask); - g2 = g1; - b1 = (int32_t)CLAMP(ip[2]); - wp[2] = (uint16_t)((b1 - b2) & mask); - b2 = b1; - } - } - else if (stride == 4) - { - r2 = wp[0] = (uint16_t)CLAMP(ip[0]); - g2 = wp[1] = (uint16_t)CLAMP(ip[1]); - b2 = wp[2] = (uint16_t)CLAMP(ip[2]); - a2 = wp[3] = (uint16_t)CLAMP(ip[3]); - n -= 4; - while (n > 0) - { - n -= 4; - wp += 4; - ip += 4; - r1 = (int32_t)CLAMP(ip[0]); - wp[0] = (uint16_t)((r1 - r2) & mask); - r2 = r1; - g1 = (int32_t)CLAMP(ip[1]); - wp[1] = (uint16_t)((g1 - g2) & mask); - g2 = g1; - b1 = (int32_t)CLAMP(ip[2]); - wp[2] = (uint16_t)((b1 - b2) & mask); - b2 = b1; - a1 = (int32_t)CLAMP(ip[3]); - wp[3] = (uint16_t)((a1 - a2) & mask); - a2 = a1; - } - } - else - { - REPEAT(stride, wp[0] = (uint16_t)CLAMP(ip[0]); wp++; ip++) - n -= stride; - while (n > 0) - { - REPEAT(stride, - wp[0] = (uint16_t)(((int32_t)CLAMP(ip[0]) - - (int32_t)CLAMP(ip[-stride])) & - mask); - wp++; ip++) - n -= stride; - } - } - } -} - -static void horizontalDifference16(unsigned short *ip, int n, int stride, - unsigned short *wp, uint16_t *From14) -{ - register int r1, g1, b1, a1, r2, g2, b2, a2, mask; - -/* assumption is unsigned pixel values */ -#undef CLAMP -#define CLAMP(v) From14[(v) >> 2] - - mask = CODE_MASK; - if (n >= stride) - { - if (stride == 3) - { - r2 = wp[0] = CLAMP(ip[0]); - g2 = wp[1] = CLAMP(ip[1]); - b2 = wp[2] = CLAMP(ip[2]); - n -= 3; - while (n > 0) - { - n -= 3; - wp += 3; - ip += 3; - r1 = CLAMP(ip[0]); - wp[0] = (uint16_t)((r1 - r2) & mask); - r2 = r1; - g1 = CLAMP(ip[1]); - wp[1] = (uint16_t)((g1 - g2) & mask); - g2 = g1; - b1 = CLAMP(ip[2]); - wp[2] = (uint16_t)((b1 - b2) & mask); - b2 = b1; - } - } - else if (stride == 4) - { - r2 = wp[0] = CLAMP(ip[0]); - g2 = wp[1] = CLAMP(ip[1]); - b2 = wp[2] = CLAMP(ip[2]); - a2 = wp[3] = CLAMP(ip[3]); - n -= 4; - while (n > 0) - { - n -= 4; - wp += 4; - ip += 4; - r1 = CLAMP(ip[0]); - wp[0] = (uint16_t)((r1 - r2) & mask); - r2 = r1; - g1 = CLAMP(ip[1]); - wp[1] = (uint16_t)((g1 - g2) & mask); - g2 = g1; - b1 = CLAMP(ip[2]); - wp[2] = (uint16_t)((b1 - b2) & mask); - b2 = b1; - a1 = CLAMP(ip[3]); - wp[3] = (uint16_t)((a1 - a2) & mask); - a2 = a1; - } - } - else - { - REPEAT(stride, wp[0] = CLAMP(ip[0]); wp++; ip++) - n -= stride; - while (n > 0) - { - REPEAT(stride, - wp[0] = (uint16_t)((CLAMP(ip[0]) - CLAMP(ip[-stride])) & - mask); - wp++; ip++) - n -= stride; - } - } - } -} - -static void horizontalDifference8(unsigned char *ip, int n, int stride, - unsigned short *wp, uint16_t *From8) -{ - register int r1, g1, b1, a1, r2, g2, b2, a2, mask; - -#undef CLAMP -#define CLAMP(v) (From8[(v)]) - - mask = CODE_MASK; - if (n >= stride) - { - if (stride == 3) - { - r2 = wp[0] = CLAMP(ip[0]); - g2 = wp[1] = CLAMP(ip[1]); - b2 = wp[2] = CLAMP(ip[2]); - n -= 3; - while (n > 0) - { - n -= 3; - r1 = CLAMP(ip[3]); - wp[3] = (uint16_t)((r1 - r2) & mask); - r2 = r1; - g1 = CLAMP(ip[4]); - wp[4] = (uint16_t)((g1 - g2) & mask); - g2 = g1; - b1 = CLAMP(ip[5]); - wp[5] = (uint16_t)((b1 - b2) & mask); - b2 = b1; - wp += 3; - ip += 3; - } - } - else if (stride == 4) - { - r2 = wp[0] = CLAMP(ip[0]); - g2 = wp[1] = CLAMP(ip[1]); - b2 = wp[2] = CLAMP(ip[2]); - a2 = wp[3] = CLAMP(ip[3]); - n -= 4; - while (n > 0) - { - n -= 4; - r1 = CLAMP(ip[4]); - wp[4] = (uint16_t)((r1 - r2) & mask); - r2 = r1; - g1 = CLAMP(ip[5]); - wp[5] = (uint16_t)((g1 - g2) & mask); - g2 = g1; - b1 = CLAMP(ip[6]); - wp[6] = (uint16_t)((b1 - b2) & mask); - b2 = b1; - a1 = CLAMP(ip[7]); - wp[7] = (uint16_t)((a1 - a2) & mask); - a2 = a1; - wp += 4; - ip += 4; - } - } - else - { - REPEAT(stride, wp[0] = CLAMP(ip[0]); wp++; ip++) - n -= stride; - while (n > 0) - { - REPEAT(stride, - wp[0] = (uint16_t)((CLAMP(ip[0]) - CLAMP(ip[-stride])) & - mask); - wp++; ip++) - n -= stride; - } - } - } -} - -/* - * Encode a chunk of pixels. - */ -static int PixarLogEncode(TIFF *tif, uint8_t *bp, tmsize_t cc, uint16_t s) -{ - static const char module[] = "PixarLogEncode"; - TIFFDirectory *td = &tif->tif_dir; - PixarLogState *sp = EncoderState(tif); - tmsize_t i; - tmsize_t n; - int llen; - unsigned short *up; - - (void)s; - - switch (sp->user_datafmt) - { - case PIXARLOGDATAFMT_FLOAT: - n = 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 */ - break; - case PIXARLOGDATAFMT_8BIT: - case PIXARLOGDATAFMT_8BITABGR: - n = cc; - break; - default: - TIFFErrorExtR(tif, module, - "%" PRIu16 " bit input not supported in PixarLog", - td->td_bitspersample); - return 0; - } - - llen = 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)) - { - TIFFErrorExtR(tif, module, "Too many input bytes provided"); - return 0; - } - - for (i = 0, up = sp->tbuf; i < n; i += llen, up += llen) - { - switch (sp->user_datafmt) - { - case PIXARLOGDATAFMT_FLOAT: - horizontalDifferenceF((float *)bp, llen, sp->stride, up, - sp->FromLT2); - bp += llen * sizeof(float); - break; - case PIXARLOGDATAFMT_16BIT: - horizontalDifference16((uint16_t *)bp, llen, sp->stride, up, - sp->From14); - bp += llen * sizeof(uint16_t); - break; - case PIXARLOGDATAFMT_8BIT: - horizontalDifference8((unsigned char *)bp, llen, sp->stride, up, - sp->From8); - bp += llen * sizeof(unsigned char); - break; - default: - TIFFErrorExtR(tif, module, - "%" PRIu16 " bit input not supported in PixarLog", - td->td_bitspersample); - return 0; - } - } - - sp->stream.next_in = (unsigned char *)sp->tbuf; - assert(sizeof(sp->stream.avail_in) == 4); /* if this assert gets raised, - 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) - { - TIFFErrorExtR(tif, module, "ZLib cannot deal with buffers this size"); - return (0); - } - - do - { - if (deflate(&sp->stream, Z_NO_FLUSH) != Z_OK) - { - TIFFErrorExtR(tif, module, "Encoder error: %s", - sp->stream.msg ? sp->stream.msg : "(null)"); - return (0); - } - if (sp->stream.avail_out == 0) - { - tif->tif_rawcc = tif->tif_rawdatasize; - if (!TIFFFlushData1(tif)) - return 0; - sp->stream.next_out = tif->tif_rawdata; - sp->stream.avail_out = - (uInt)tif - ->tif_rawdatasize; /* this is a safe typecast, as check is - made already in PixarLogPreEncode */ - } - } while (sp->stream.avail_in > 0); - return (1); -} - -/* - * Finish off an encoded strip by flushing the last - * string and tacking on an End Of Information code. - */ - -static int PixarLogPostEncode(TIFF *tif) -{ - static const char module[] = "PixarLogPostEncode"; - PixarLogState *sp = EncoderState(tif); - int state; - - sp->stream.avail_in = 0; - - do - { - state = deflate(&sp->stream, Z_FINISH); - switch (state) - { - case Z_STREAM_END: - case Z_OK: - if ((tmsize_t)sp->stream.avail_out != tif->tif_rawdatasize) - { - tif->tif_rawcc = - tif->tif_rawdatasize - sp->stream.avail_out; - if (!TIFFFlushData1(tif)) - return 0; - sp->stream.next_out = tif->tif_rawdata; - sp->stream.avail_out = - (uInt)tif->tif_rawdatasize; /* this is a safe typecast, - as check is made already - in PixarLogPreEncode */ - } - break; - default: - TIFFErrorExtR(tif, module, "ZLib error: %s", - sp->stream.msg ? sp->stream.msg : "(null)"); - return (0); - } - } while (state != Z_STREAM_END); - return (1); -} - -static void PixarLogClose(TIFF *tif) -{ - PixarLogState *sp = (PixarLogState *)tif->tif_data; - TIFFDirectory *td = &tif->tif_dir; - - assert(sp != 0); - /* In a really sneaky (and really incorrect, and untruthful, and - * troublesome, and error-prone) maneuver that completely goes against - * the spirit of TIFF, and breaks TIFF, on close, we covertly - * modify both bitspersample and sampleformat in the directory to - * indicate 8-bit linear. This way, the decode "just works" even for - * readers that don't know about PixarLog, or how to set - * the PIXARLOGDATFMT pseudo-tag. - */ - - if (sp->state & PLSTATE_INIT) - { - /* We test the state to avoid an issue such as in - * http://bugzilla.maptools.org/show_bug.cgi?id=2604 - * What appends in that case is that the bitspersample is 1 and - * a TransferFunction is set. The size of the TransferFunction - * depends on 1<td_bitspersample = 8; - td->td_sampleformat = SAMPLEFORMAT_UINT; - } -} - -static void PixarLogCleanup(TIFF *tif) -{ - PixarLogState *sp = (PixarLogState *)tif->tif_data; - - assert(sp != 0); - - (void)TIFFPredictorCleanup(tif); - - tif->tif_tagmethods.vgetfield = sp->vgetparent; - tif->tif_tagmethods.vsetfield = sp->vsetparent; - - if (sp->FromLT2) - _TIFFfreeExt(tif, sp->FromLT2); - if (sp->From14) - _TIFFfreeExt(tif, sp->From14); - if (sp->From8) - _TIFFfreeExt(tif, sp->From8); - if (sp->ToLinearF) - _TIFFfreeExt(tif, sp->ToLinearF); - if (sp->ToLinear16) - _TIFFfreeExt(tif, sp->ToLinear16); - if (sp->ToLinear8) - _TIFFfreeExt(tif, sp->ToLinear8); - if (sp->state & PLSTATE_INIT) - { - if (tif->tif_mode == O_RDONLY) - inflateEnd(&sp->stream); - else - deflateEnd(&sp->stream); - } - if (sp->tbuf) - _TIFFfreeExt(tif, sp->tbuf); - _TIFFfreeExt(tif, sp); - tif->tif_data = NULL; - - _TIFFSetDefaultCompressionState(tif); -} - -static int PixarLogVSetField(TIFF *tif, uint32_t tag, va_list ap) -{ - static const char module[] = "PixarLogVSetField"; - PixarLogState *sp = (PixarLogState *)tif->tif_data; - int result; - - switch (tag) - { - case TIFFTAG_PIXARLOGQUALITY: - sp->quality = (int)va_arg(ap, int); - if (tif->tif_mode != O_RDONLY && (sp->state & PLSTATE_INIT)) - { - if (deflateParams(&sp->stream, sp->quality, - Z_DEFAULT_STRATEGY) != Z_OK) - { - TIFFErrorExtR(tif, module, "ZLib error: %s", - sp->stream.msg ? sp->stream.msg : "(null)"); - return (0); - } - } - return (1); - case TIFFTAG_PIXARLOGDATAFMT: - sp->user_datafmt = (int)va_arg(ap, int); - /* Tweak the TIFF header so that the rest of libtiff knows what - * size of data will be passed between app and library, and - * assume that the app knows what it is doing and is not - * confused by these header manipulations... - */ - switch (sp->user_datafmt) - { - case PIXARLOGDATAFMT_8BIT: - case PIXARLOGDATAFMT_8BITABGR: - TIFFSetField(tif, TIFFTAG_BITSPERSAMPLE, 8); - TIFFSetField(tif, TIFFTAG_SAMPLEFORMAT, SAMPLEFORMAT_UINT); - break; - case PIXARLOGDATAFMT_11BITLOG: - TIFFSetField(tif, TIFFTAG_BITSPERSAMPLE, 16); - TIFFSetField(tif, TIFFTAG_SAMPLEFORMAT, SAMPLEFORMAT_UINT); - break; - case PIXARLOGDATAFMT_12BITPICIO: - TIFFSetField(tif, TIFFTAG_BITSPERSAMPLE, 16); - TIFFSetField(tif, TIFFTAG_SAMPLEFORMAT, SAMPLEFORMAT_INT); - break; - case PIXARLOGDATAFMT_16BIT: - TIFFSetField(tif, TIFFTAG_BITSPERSAMPLE, 16); - TIFFSetField(tif, TIFFTAG_SAMPLEFORMAT, SAMPLEFORMAT_UINT); - break; - case PIXARLOGDATAFMT_FLOAT: - TIFFSetField(tif, TIFFTAG_BITSPERSAMPLE, 32); - TIFFSetField(tif, TIFFTAG_SAMPLEFORMAT, - SAMPLEFORMAT_IEEEFP); - break; - } - /* - * Must recalculate sizes should bits/sample change. - */ - tif->tif_tilesize = - isTiled(tif) ? TIFFTileSize(tif) : (tmsize_t)(-1); - tif->tif_scanlinesize = TIFFScanlineSize(tif); - result = 1; /* NB: pseudo tag */ - break; - default: - result = (*sp->vsetparent)(tif, tag, ap); - } - return (result); -} - -static int PixarLogVGetField(TIFF *tif, uint32_t tag, va_list ap) -{ - PixarLogState *sp = (PixarLogState *)tif->tif_data; - - switch (tag) - { - case TIFFTAG_PIXARLOGQUALITY: - *va_arg(ap, int *) = sp->quality; - break; - case TIFFTAG_PIXARLOGDATAFMT: - *va_arg(ap, int *) = sp->user_datafmt; - break; - default: - return (*sp->vgetparent)(tif, tag, ap); - } - return (1); -} - -static const TIFFField pixarlogFields[] = { - {TIFFTAG_PIXARLOGDATAFMT, 0, 0, TIFF_ANY, 0, TIFF_SETGET_INT, - TIFF_SETGET_UNDEFINED, FIELD_PSEUDO, FALSE, FALSE, "", NULL}, - {TIFFTAG_PIXARLOGQUALITY, 0, 0, TIFF_ANY, 0, TIFF_SETGET_INT, - TIFF_SETGET_UNDEFINED, FIELD_PSEUDO, FALSE, FALSE, "", NULL}}; - -int TIFFInitPixarLog(TIFF *tif, int scheme) -{ - static const char module[] = "TIFFInitPixarLog"; - - PixarLogState *sp; - - (void)scheme; - assert(scheme == COMPRESSION_PIXARLOG); - - /* - * Merge codec-specific tag information. - */ - if (!_TIFFMergeFields(tif, pixarlogFields, TIFFArrayCount(pixarlogFields))) - { - TIFFErrorExtR(tif, module, - "Merging PixarLog codec-specific tags failed"); - return 0; - } - - /* - * Allocate state block so tag methods have storage to record values. - */ - tif->tif_data = (uint8_t *)_TIFFmallocExt(tif, sizeof(PixarLogState)); - if (tif->tif_data == NULL) - goto bad; - sp = (PixarLogState *)tif->tif_data; - _TIFFmemset(sp, 0, sizeof(*sp)); - sp->stream.data_type = Z_BINARY; - sp->user_datafmt = PIXARLOGDATAFMT_UNKNOWN; - - /* - * Install codec methods. - */ - tif->tif_fixuptags = PixarLogFixupTags; - tif->tif_setupdecode = PixarLogSetupDecode; - tif->tif_predecode = PixarLogPreDecode; - tif->tif_decoderow = PixarLogDecode; - tif->tif_decodestrip = PixarLogDecode; - tif->tif_decodetile = PixarLogDecode; - tif->tif_setupencode = PixarLogSetupEncode; - tif->tif_preencode = PixarLogPreEncode; - tif->tif_postencode = PixarLogPostEncode; - tif->tif_encoderow = PixarLogEncode; - tif->tif_encodestrip = PixarLogEncode; - tif->tif_encodetile = PixarLogEncode; - tif->tif_close = PixarLogClose; - tif->tif_cleanup = PixarLogCleanup; - - /* Override SetField so we can handle our private pseudo-tag */ - sp->vgetparent = tif->tif_tagmethods.vgetfield; - tif->tif_tagmethods.vgetfield = PixarLogVGetField; /* hook for codec tags */ - sp->vsetparent = tif->tif_tagmethods.vsetfield; - tif->tif_tagmethods.vsetfield = PixarLogVSetField; /* hook for codec tags */ - - /* Default values for codec-specific fields */ - sp->quality = Z_DEFAULT_COMPRESSION; /* default comp. level */ - sp->state = 0; - - /* we don't wish to use the predictor, - * the default is none, which predictor value 1 - */ - (void)TIFFPredictorInit(tif); - - /* - * build the companding tables - */ - PixarLogMakeTables(tif, sp); - - return (1); -bad: - TIFFErrorExtR(tif, module, "No space for PixarLog state block"); - return (0); -} -#endif /* PIXARLOG_SUPPORT */ diff --git a/src/3rd/tiff/predict.c b/src/3rd/tiff/predict.c deleted file mode 100644 index fa6ce6f03a3..00000000000 --- a/src/3rd/tiff/predict.c +++ /dev/null @@ -1,1046 +0,0 @@ -/* - * Copyright (c) 1988-1997 Sam Leffler - * Copyright (c) 1991-1997 Silicon Graphics, Inc. - * - * Permission to use, copy, modify, distribute, and sell this software and - * its documentation for any purpose is hereby granted without fee, provided - * that (i) the above copyright notices and this permission notice appear in - * all copies of the software and related documentation, and (ii) the names of - * Sam Leffler and Silicon Graphics may not be used in any advertising or - * publicity relating to the software without the specific, prior written - * permission of Sam Leffler and Silicon Graphics. - * - * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, - * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY - * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. - * - * IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR - * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, - * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, - * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF - * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE - * OF THIS SOFTWARE. - */ - -/* - * TIFF Library. - * - * Predictor Tag Support (used by multiple codecs). - */ -#include "predict.h" -#include "tiffiop.h" - -#define PredictorState(tif) ((TIFFPredictorState *)(tif)->tif_data) - -static int horAcc8(TIFF *tif, uint8_t *cp0, tmsize_t cc); -static int horAcc16(TIFF *tif, uint8_t *cp0, tmsize_t cc); -static int horAcc32(TIFF *tif, uint8_t *cp0, tmsize_t cc); -static int horAcc64(TIFF *tif, uint8_t *cp0, tmsize_t cc); -static int swabHorAcc16(TIFF *tif, uint8_t *cp0, tmsize_t cc); -static int swabHorAcc32(TIFF *tif, uint8_t *cp0, tmsize_t cc); -static int swabHorAcc64(TIFF *tif, uint8_t *cp0, tmsize_t cc); -static int horDiff8(TIFF *tif, uint8_t *cp0, tmsize_t cc); -static int horDiff16(TIFF *tif, uint8_t *cp0, tmsize_t cc); -static int horDiff32(TIFF *tif, uint8_t *cp0, tmsize_t cc); -static int horDiff64(TIFF *tif, uint8_t *cp0, tmsize_t cc); -static int swabHorDiff16(TIFF *tif, uint8_t *cp0, tmsize_t cc); -static int swabHorDiff32(TIFF *tif, uint8_t *cp0, tmsize_t cc); -static int swabHorDiff64(TIFF *tif, uint8_t *cp0, tmsize_t cc); -static int fpAcc(TIFF *tif, uint8_t *cp0, tmsize_t cc); -static int fpDiff(TIFF *tif, uint8_t *cp0, tmsize_t cc); -static int PredictorDecodeRow(TIFF *tif, uint8_t *op0, tmsize_t occ0, - uint16_t s); -static int PredictorDecodeTile(TIFF *tif, uint8_t *op0, tmsize_t occ0, - uint16_t s); -static int PredictorEncodeRow(TIFF *tif, uint8_t *bp, tmsize_t cc, uint16_t s); -static int PredictorEncodeTile(TIFF *tif, uint8_t *bp0, tmsize_t cc0, - uint16_t s); - -static int PredictorSetup(TIFF *tif) -{ - static const char module[] = "PredictorSetup"; - - TIFFPredictorState *sp = PredictorState(tif); - TIFFDirectory *td = &tif->tif_dir; - - switch (sp->predictor) /* no differencing */ - { - case PREDICTOR_NONE: - return 1; - case PREDICTOR_HORIZONTAL: - if (td->td_bitspersample != 8 && td->td_bitspersample != 16 && - td->td_bitspersample != 32 && td->td_bitspersample != 64) - { - TIFFErrorExtR(tif, module, - "Horizontal differencing \"Predictor\" not " - "supported with %" PRIu16 "-bit samples", - td->td_bitspersample); - return 0; - } - break; - case PREDICTOR_FLOATINGPOINT: - if (td->td_sampleformat != SAMPLEFORMAT_IEEEFP) - { - TIFFErrorExtR( - tif, module, - "Floating point \"Predictor\" not supported with %" PRIu16 - " data format", - td->td_sampleformat); - return 0; - } - if (td->td_bitspersample != 16 && td->td_bitspersample != 24 && - td->td_bitspersample != 32 && td->td_bitspersample != 64) - { /* Should 64 be allowed? */ - TIFFErrorExtR( - tif, module, - "Floating point \"Predictor\" not supported with %" PRIu16 - "-bit samples", - td->td_bitspersample); - return 0; - } - break; - default: - TIFFErrorExtR(tif, module, "\"Predictor\" value %d not supported", - sp->predictor); - return 0; - } - sp->stride = - (td->td_planarconfig == PLANARCONFIG_CONTIG ? td->td_samplesperpixel - : 1); - /* - * Calculate the scanline/tile-width size in bytes. - */ - if (isTiled(tif)) - sp->rowsize = TIFFTileRowSize(tif); - else - sp->rowsize = TIFFScanlineSize(tif); - if (sp->rowsize == 0) - return 0; - - return 1; -} - -static int PredictorSetupDecode(TIFF *tif) -{ - TIFFPredictorState *sp = PredictorState(tif); - TIFFDirectory *td = &tif->tif_dir; - - /* Note: when PredictorSetup() fails, the effets of setupdecode() */ - /* will not be "canceled" so setupdecode() might be robust to */ - /* be called several times. */ - if (!(*sp->setupdecode)(tif) || !PredictorSetup(tif)) - return 0; - - if (sp->predictor == 2) - { - switch (td->td_bitspersample) - { - case 8: - sp->decodepfunc = horAcc8; - break; - case 16: - sp->decodepfunc = horAcc16; - break; - case 32: - sp->decodepfunc = horAcc32; - break; - case 64: - sp->decodepfunc = horAcc64; - break; - } - /* - * Override default decoding method with one that does the - * predictor stuff. - */ - if (tif->tif_decoderow != PredictorDecodeRow) - { - sp->decoderow = tif->tif_decoderow; - tif->tif_decoderow = PredictorDecodeRow; - sp->decodestrip = tif->tif_decodestrip; - tif->tif_decodestrip = PredictorDecodeTile; - sp->decodetile = tif->tif_decodetile; - tif->tif_decodetile = PredictorDecodeTile; - } - - /* - * If the data is horizontally differenced 16-bit data that - * requires byte-swapping, then it must be byte swapped before - * the accumulation step. We do this with a special-purpose - * routine and override the normal post decoding logic that - * the library setup when the directory was read. - */ - if (tif->tif_flags & TIFF_SWAB) - { - if (sp->decodepfunc == horAcc16) - { - sp->decodepfunc = swabHorAcc16; - tif->tif_postdecode = _TIFFNoPostDecode; - } - else if (sp->decodepfunc == horAcc32) - { - sp->decodepfunc = swabHorAcc32; - tif->tif_postdecode = _TIFFNoPostDecode; - } - else if (sp->decodepfunc == horAcc64) - { - sp->decodepfunc = swabHorAcc64; - tif->tif_postdecode = _TIFFNoPostDecode; - } - } - } - - else if (sp->predictor == 3) - { - sp->decodepfunc = fpAcc; - /* - * Override default decoding method with one that does the - * predictor stuff. - */ - if (tif->tif_decoderow != PredictorDecodeRow) - { - sp->decoderow = tif->tif_decoderow; - tif->tif_decoderow = PredictorDecodeRow; - sp->decodestrip = tif->tif_decodestrip; - tif->tif_decodestrip = PredictorDecodeTile; - sp->decodetile = tif->tif_decodetile; - tif->tif_decodetile = PredictorDecodeTile; - } - /* - * The data should not be swapped outside of the floating - * point predictor, the accumulation routine should return - * byres in the native order. - */ - if (tif->tif_flags & TIFF_SWAB) - { - tif->tif_postdecode = _TIFFNoPostDecode; - } - /* - * Allocate buffer to keep the decoded bytes before - * rearranging in the right order - */ - } - - return 1; -} - -static int PredictorSetupEncode(TIFF *tif) -{ - TIFFPredictorState *sp = PredictorState(tif); - TIFFDirectory *td = &tif->tif_dir; - - if (!(*sp->setupencode)(tif) || !PredictorSetup(tif)) - return 0; - - if (sp->predictor == 2) - { - switch (td->td_bitspersample) - { - case 8: - sp->encodepfunc = horDiff8; - break; - case 16: - sp->encodepfunc = horDiff16; - break; - case 32: - sp->encodepfunc = horDiff32; - break; - case 64: - sp->encodepfunc = horDiff64; - break; - } - /* - * Override default encoding method with one that does the - * predictor stuff. - */ - if (tif->tif_encoderow != PredictorEncodeRow) - { - sp->encoderow = tif->tif_encoderow; - tif->tif_encoderow = PredictorEncodeRow; - sp->encodestrip = tif->tif_encodestrip; - tif->tif_encodestrip = PredictorEncodeTile; - sp->encodetile = tif->tif_encodetile; - tif->tif_encodetile = PredictorEncodeTile; - } - - /* - * If the data is horizontally differenced 16-bit data that - * requires byte-swapping, then it must be byte swapped after - * the differentiation step. We do this with a special-purpose - * routine and override the normal post decoding logic that - * the library setup when the directory was read. - */ - if (tif->tif_flags & TIFF_SWAB) - { - if (sp->encodepfunc == horDiff16) - { - sp->encodepfunc = swabHorDiff16; - tif->tif_postdecode = _TIFFNoPostDecode; - } - else if (sp->encodepfunc == horDiff32) - { - sp->encodepfunc = swabHorDiff32; - tif->tif_postdecode = _TIFFNoPostDecode; - } - else if (sp->encodepfunc == horDiff64) - { - sp->encodepfunc = swabHorDiff64; - tif->tif_postdecode = _TIFFNoPostDecode; - } - } - } - - else if (sp->predictor == 3) - { - sp->encodepfunc = fpDiff; - /* - * Override default encoding method with one that does the - * predictor stuff. - */ - if (tif->tif_encoderow != PredictorEncodeRow) - { - sp->encoderow = tif->tif_encoderow; - tif->tif_encoderow = PredictorEncodeRow; - sp->encodestrip = tif->tif_encodestrip; - tif->tif_encodestrip = PredictorEncodeTile; - sp->encodetile = tif->tif_encodetile; - tif->tif_encodetile = PredictorEncodeTile; - } - } - - return 1; -} - -#define REPEAT4(n, op) \ - switch (n) \ - { \ - default: \ - { \ - tmsize_t i; \ - for (i = n - 4; i > 0; i--) \ - { \ - op; \ - } \ - } /*-fallthrough*/ \ - case 4: \ - op; /*-fallthrough*/ \ - case 3: \ - op; /*-fallthrough*/ \ - case 2: \ - op; /*-fallthrough*/ \ - case 1: \ - op; /*-fallthrough*/ \ - case 0:; \ - } - -/* Remarks related to C standard compliance in all below functions : */ -/* - to avoid any undefined behavior, we only operate on unsigned types */ -/* since the behavior of "overflows" is defined (wrap over) */ -/* - when storing into the byte stream, we explicitly mask with 0xff so */ -/* as to make icc -check=conversions happy (not necessary by the standard) */ - -TIFF_NOSANITIZE_UNSIGNED_INT_OVERFLOW -static int horAcc8(TIFF *tif, uint8_t *cp0, tmsize_t cc) -{ - tmsize_t stride = PredictorState(tif)->stride; - - unsigned char *cp = (unsigned char *)cp0; - if ((cc % stride) != 0) - { - TIFFErrorExtR(tif, "horAcc8", "%s", "(cc%stride)!=0"); - return 0; - } - - if (cc > stride) - { - /* - * Pipeline the most common cases. - */ - if (stride == 3) - { - unsigned int cr = cp[0]; - unsigned int cg = cp[1]; - unsigned int cb = cp[2]; - tmsize_t i = stride; - for (; i < cc; i += stride) - { - cp[i + 0] = (unsigned char)((cr += cp[i + 0]) & 0xff); - cp[i + 1] = (unsigned char)((cg += cp[i + 1]) & 0xff); - cp[i + 2] = (unsigned char)((cb += cp[i + 2]) & 0xff); - } - } - else if (stride == 4) - { - unsigned int cr = cp[0]; - unsigned int cg = cp[1]; - unsigned int cb = cp[2]; - unsigned int ca = cp[3]; - tmsize_t i = stride; - for (; i < cc; i += stride) - { - cp[i + 0] = (unsigned char)((cr += cp[i + 0]) & 0xff); - cp[i + 1] = (unsigned char)((cg += cp[i + 1]) & 0xff); - cp[i + 2] = (unsigned char)((cb += cp[i + 2]) & 0xff); - cp[i + 3] = (unsigned char)((ca += cp[i + 3]) & 0xff); - } - } - else - { - cc -= stride; - do - { - REPEAT4(stride, - cp[stride] = (unsigned char)((cp[stride] + *cp) & 0xff); - cp++) - cc -= stride; - } while (cc > 0); - } - } - return 1; -} - -static int swabHorAcc16(TIFF *tif, uint8_t *cp0, tmsize_t cc) -{ - uint16_t *wp = (uint16_t *)cp0; - tmsize_t wc = cc / 2; - - TIFFSwabArrayOfShort(wp, wc); - return horAcc16(tif, cp0, cc); -} - -TIFF_NOSANITIZE_UNSIGNED_INT_OVERFLOW -static int horAcc16(TIFF *tif, uint8_t *cp0, tmsize_t cc) -{ - tmsize_t stride = PredictorState(tif)->stride; - uint16_t *wp = (uint16_t *)cp0; - tmsize_t wc = cc / 2; - - if ((cc % (2 * stride)) != 0) - { - TIFFErrorExtR(tif, "horAcc16", "%s", "cc%(2*stride))!=0"); - return 0; - } - - if (wc > stride) - { - wc -= stride; - do - { - REPEAT4(stride, wp[stride] = (uint16_t)(((unsigned int)wp[stride] + - (unsigned int)wp[0]) & - 0xffff); - wp++) - wc -= stride; - } while (wc > 0); - } - return 1; -} - -static int swabHorAcc32(TIFF *tif, uint8_t *cp0, tmsize_t cc) -{ - uint32_t *wp = (uint32_t *)cp0; - tmsize_t wc = cc / 4; - - TIFFSwabArrayOfLong(wp, wc); - return horAcc32(tif, cp0, cc); -} - -TIFF_NOSANITIZE_UNSIGNED_INT_OVERFLOW -static int horAcc32(TIFF *tif, uint8_t *cp0, tmsize_t cc) -{ - tmsize_t stride = PredictorState(tif)->stride; - uint32_t *wp = (uint32_t *)cp0; - tmsize_t wc = cc / 4; - - if ((cc % (4 * stride)) != 0) - { - TIFFErrorExtR(tif, "horAcc32", "%s", "cc%(4*stride))!=0"); - return 0; - } - - if (wc > stride) - { - wc -= stride; - do - { - REPEAT4(stride, wp[stride] += wp[0]; wp++) - wc -= stride; - } while (wc > 0); - } - return 1; -} - -static int swabHorAcc64(TIFF *tif, uint8_t *cp0, tmsize_t cc) -{ - uint64_t *wp = (uint64_t *)cp0; - tmsize_t wc = cc / 8; - - TIFFSwabArrayOfLong8(wp, wc); - return horAcc64(tif, cp0, cc); -} - -TIFF_NOSANITIZE_UNSIGNED_INT_OVERFLOW -static int horAcc64(TIFF *tif, uint8_t *cp0, tmsize_t cc) -{ - tmsize_t stride = PredictorState(tif)->stride; - uint64_t *wp = (uint64_t *)cp0; - tmsize_t wc = cc / 8; - - if ((cc % (8 * stride)) != 0) - { - TIFFErrorExtR(tif, "horAcc64", "%s", "cc%(8*stride))!=0"); - return 0; - } - - if (wc > stride) - { - wc -= stride; - do - { - REPEAT4(stride, wp[stride] += wp[0]; wp++) - wc -= stride; - } while (wc > 0); - } - return 1; -} - -/* - * Floating point predictor accumulation routine. - */ -static int fpAcc(TIFF *tif, uint8_t *cp0, tmsize_t cc) -{ - tmsize_t stride = PredictorState(tif)->stride; - uint32_t bps = tif->tif_dir.td_bitspersample / 8; - tmsize_t wc = cc / bps; - tmsize_t count = cc; - uint8_t *cp = (uint8_t *)cp0; - uint8_t *tmp; - - if (cc % (bps * stride) != 0) - { - TIFFErrorExtR(tif, "fpAcc", "%s", "cc%(bps*stride))!=0"); - return 0; - } - - tmp = (uint8_t *)_TIFFmallocExt(tif, cc); - if (!tmp) - return 0; - - while (count > stride) - { - REPEAT4(stride, - cp[stride] = (unsigned char)((cp[stride] + cp[0]) & 0xff); - cp++) - count -= stride; - } - - _TIFFmemcpy(tmp, cp0, cc); - cp = (uint8_t *)cp0; - for (count = 0; count < wc; count++) - { - uint32_t byte; - for (byte = 0; byte < bps; byte++) - { -#if WORDS_BIGENDIAN - cp[bps * count + byte] = tmp[byte * wc + count]; -#else - cp[bps * count + byte] = tmp[(bps - byte - 1) * wc + count]; -#endif - } - } - _TIFFfreeExt(tif, tmp); - return 1; -} - -/* - * Decode a scanline and apply the predictor routine. - */ -static int PredictorDecodeRow(TIFF *tif, uint8_t *op0, tmsize_t occ0, - uint16_t s) -{ - TIFFPredictorState *sp = PredictorState(tif); - - assert(sp != NULL); - assert(sp->decoderow != NULL); - assert(sp->decodepfunc != NULL); - - if ((*sp->decoderow)(tif, op0, occ0, s)) - { - return (*sp->decodepfunc)(tif, op0, occ0); - } - else - return 0; -} - -/* - * Decode a tile/strip and apply the predictor routine. - * Note that horizontal differencing must be done on a - * row-by-row basis. The width of a "row" has already - * been calculated at pre-decode time according to the - * strip/tile dimensions. - */ -static int PredictorDecodeTile(TIFF *tif, uint8_t *op0, tmsize_t occ0, - uint16_t s) -{ - TIFFPredictorState *sp = PredictorState(tif); - - assert(sp != NULL); - assert(sp->decodetile != NULL); - - if ((*sp->decodetile)(tif, op0, occ0, s)) - { - tmsize_t rowsize = sp->rowsize; - assert(rowsize > 0); - if ((occ0 % rowsize) != 0) - { - TIFFErrorExtR(tif, "PredictorDecodeTile", "%s", - "occ0%rowsize != 0"); - return 0; - } - assert(sp->decodepfunc != NULL); - while (occ0 > 0) - { - if (!(*sp->decodepfunc)(tif, op0, rowsize)) - return 0; - occ0 -= rowsize; - op0 += rowsize; - } - return 1; - } - else - return 0; -} - -TIFF_NOSANITIZE_UNSIGNED_INT_OVERFLOW -static int horDiff8(TIFF *tif, uint8_t *cp0, tmsize_t cc) -{ - TIFFPredictorState *sp = PredictorState(tif); - tmsize_t stride = sp->stride; - unsigned char *cp = (unsigned char *)cp0; - - if ((cc % stride) != 0) - { - TIFFErrorExtR(tif, "horDiff8", "%s", "(cc%stride)!=0"); - return 0; - } - - if (cc > stride) - { - cc -= stride; - /* - * Pipeline the most common cases. - */ - if (stride == 3) - { - unsigned int r1, g1, b1; - unsigned int r2 = cp[0]; - unsigned int g2 = cp[1]; - unsigned int b2 = cp[2]; - do - { - r1 = cp[3]; - cp[3] = (unsigned char)((r1 - r2) & 0xff); - r2 = r1; - g1 = cp[4]; - cp[4] = (unsigned char)((g1 - g2) & 0xff); - g2 = g1; - b1 = cp[5]; - cp[5] = (unsigned char)((b1 - b2) & 0xff); - b2 = b1; - cp += 3; - } while ((cc -= 3) > 0); - } - else if (stride == 4) - { - unsigned int r1, g1, b1, a1; - unsigned int r2 = cp[0]; - unsigned int g2 = cp[1]; - unsigned int b2 = cp[2]; - unsigned int a2 = cp[3]; - do - { - r1 = cp[4]; - cp[4] = (unsigned char)((r1 - r2) & 0xff); - r2 = r1; - g1 = cp[5]; - cp[5] = (unsigned char)((g1 - g2) & 0xff); - g2 = g1; - b1 = cp[6]; - cp[6] = (unsigned char)((b1 - b2) & 0xff); - b2 = b1; - a1 = cp[7]; - cp[7] = (unsigned char)((a1 - a2) & 0xff); - a2 = a1; - cp += 4; - } while ((cc -= 4) > 0); - } - else - { - cp += cc - 1; - do - { - REPEAT4(stride, - cp[stride] = - (unsigned char)((cp[stride] - cp[0]) & 0xff); - cp--) - } while ((cc -= stride) > 0); - } - } - return 1; -} - -TIFF_NOSANITIZE_UNSIGNED_INT_OVERFLOW -static int horDiff16(TIFF *tif, uint8_t *cp0, tmsize_t cc) -{ - TIFFPredictorState *sp = PredictorState(tif); - tmsize_t stride = sp->stride; - uint16_t *wp = (uint16_t *)cp0; - tmsize_t wc = cc / 2; - - if ((cc % (2 * stride)) != 0) - { - TIFFErrorExtR(tif, "horDiff8", "%s", "(cc%(2*stride))!=0"); - return 0; - } - - if (wc > stride) - { - wc -= stride; - wp += wc - 1; - do - { - REPEAT4(stride, wp[stride] = (uint16_t)(((unsigned int)wp[stride] - - (unsigned int)wp[0]) & - 0xffff); - wp--) - wc -= stride; - } while (wc > 0); - } - return 1; -} - -static int swabHorDiff16(TIFF *tif, uint8_t *cp0, tmsize_t cc) -{ - uint16_t *wp = (uint16_t *)cp0; - tmsize_t wc = cc / 2; - - if (!horDiff16(tif, cp0, cc)) - return 0; - - TIFFSwabArrayOfShort(wp, wc); - return 1; -} - -TIFF_NOSANITIZE_UNSIGNED_INT_OVERFLOW -static int horDiff32(TIFF *tif, uint8_t *cp0, tmsize_t cc) -{ - TIFFPredictorState *sp = PredictorState(tif); - tmsize_t stride = sp->stride; - uint32_t *wp = (uint32_t *)cp0; - tmsize_t wc = cc / 4; - - if ((cc % (4 * stride)) != 0) - { - TIFFErrorExtR(tif, "horDiff32", "%s", "(cc%(4*stride))!=0"); - return 0; - } - - if (wc > stride) - { - wc -= stride; - wp += wc - 1; - do - { - REPEAT4(stride, wp[stride] -= wp[0]; wp--) - wc -= stride; - } while (wc > 0); - } - return 1; -} - -static int swabHorDiff32(TIFF *tif, uint8_t *cp0, tmsize_t cc) -{ - uint32_t *wp = (uint32_t *)cp0; - tmsize_t wc = cc / 4; - - if (!horDiff32(tif, cp0, cc)) - return 0; - - TIFFSwabArrayOfLong(wp, wc); - return 1; -} - -TIFF_NOSANITIZE_UNSIGNED_INT_OVERFLOW -static int horDiff64(TIFF *tif, uint8_t *cp0, tmsize_t cc) -{ - TIFFPredictorState *sp = PredictorState(tif); - tmsize_t stride = sp->stride; - uint64_t *wp = (uint64_t *)cp0; - tmsize_t wc = cc / 8; - - if ((cc % (8 * stride)) != 0) - { - TIFFErrorExtR(tif, "horDiff64", "%s", "(cc%(8*stride))!=0"); - return 0; - } - - if (wc > stride) - { - wc -= stride; - wp += wc - 1; - do - { - REPEAT4(stride, wp[stride] -= wp[0]; wp--) - wc -= stride; - } while (wc > 0); - } - return 1; -} - -static int swabHorDiff64(TIFF *tif, uint8_t *cp0, tmsize_t cc) -{ - uint64_t *wp = (uint64_t *)cp0; - tmsize_t wc = cc / 8; - - if (!horDiff64(tif, cp0, cc)) - return 0; - - TIFFSwabArrayOfLong8(wp, wc); - return 1; -} - -/* - * Floating point predictor differencing routine. - */ -TIFF_NOSANITIZE_UNSIGNED_INT_OVERFLOW -static int fpDiff(TIFF *tif, uint8_t *cp0, tmsize_t cc) -{ - tmsize_t stride = PredictorState(tif)->stride; - uint32_t bps = tif->tif_dir.td_bitspersample / 8; - tmsize_t wc = cc / bps; - tmsize_t count; - uint8_t *cp = (uint8_t *)cp0; - uint8_t *tmp; - - if ((cc % (bps * stride)) != 0) - { - TIFFErrorExtR(tif, "fpDiff", "%s", "(cc%(bps*stride))!=0"); - return 0; - } - - tmp = (uint8_t *)_TIFFmallocExt(tif, cc); - if (!tmp) - return 0; - - _TIFFmemcpy(tmp, cp0, cc); - for (count = 0; count < wc; count++) - { - uint32_t byte; - for (byte = 0; byte < bps; byte++) - { -#if WORDS_BIGENDIAN - cp[byte * wc + count] = tmp[bps * count + byte]; -#else - cp[(bps - byte - 1) * wc + count] = tmp[bps * count + byte]; -#endif - } - } - _TIFFfreeExt(tif, tmp); - - cp = (uint8_t *)cp0; - cp += cc - stride - 1; - for (count = cc; count > stride; count -= stride) - REPEAT4(stride, - cp[stride] = (unsigned char)((cp[stride] - cp[0]) & 0xff); - cp--) - return 1; -} - -static int PredictorEncodeRow(TIFF *tif, uint8_t *bp, tmsize_t cc, uint16_t s) -{ - TIFFPredictorState *sp = PredictorState(tif); - - assert(sp != NULL); - assert(sp->encodepfunc != NULL); - assert(sp->encoderow != NULL); - - /* XXX horizontal differencing alters user's data XXX */ - if (!(*sp->encodepfunc)(tif, bp, cc)) - return 0; - return (*sp->encoderow)(tif, bp, cc, s); -} - -static int PredictorEncodeTile(TIFF *tif, uint8_t *bp0, tmsize_t cc0, - uint16_t s) -{ - static const char module[] = "PredictorEncodeTile"; - TIFFPredictorState *sp = PredictorState(tif); - uint8_t *working_copy; - tmsize_t cc = cc0, rowsize; - unsigned char *bp; - int result_code; - - assert(sp != NULL); - assert(sp->encodepfunc != NULL); - assert(sp->encodetile != NULL); - - /* - * Do predictor manipulation in a working buffer to avoid altering - * the callers buffer. http://trac.osgeo.org/gdal/ticket/1965 - */ - working_copy = (uint8_t *)_TIFFmallocExt(tif, cc0); - if (working_copy == NULL) - { - TIFFErrorExtR(tif, module, - "Out of memory allocating %" PRId64 " byte temp buffer.", - (int64_t)cc0); - return 0; - } - memcpy(working_copy, bp0, cc0); - bp = working_copy; - - rowsize = sp->rowsize; - assert(rowsize > 0); - if ((cc0 % rowsize) != 0) - { - TIFFErrorExtR(tif, "PredictorEncodeTile", "%s", "(cc0%rowsize)!=0"); - _TIFFfreeExt(tif, working_copy); - return 0; - } - while (cc > 0) - { - (*sp->encodepfunc)(tif, bp, rowsize); - cc -= rowsize; - bp += rowsize; - } - result_code = (*sp->encodetile)(tif, working_copy, cc0, s); - - _TIFFfreeExt(tif, working_copy); - - return result_code; -} - -#define FIELD_PREDICTOR (FIELD_CODEC + 0) /* XXX */ - -static const TIFFField predictFields[] = { - {TIFFTAG_PREDICTOR, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, - TIFF_SETGET_UINT16, FIELD_PREDICTOR, FALSE, FALSE, "Predictor", NULL}, -}; - -static int PredictorVSetField(TIFF *tif, uint32_t tag, va_list ap) -{ - TIFFPredictorState *sp = PredictorState(tif); - - assert(sp != NULL); - assert(sp->vsetparent != NULL); - - switch (tag) - { - case TIFFTAG_PREDICTOR: - sp->predictor = (uint16_t)va_arg(ap, uint16_vap); - TIFFSetFieldBit(tif, FIELD_PREDICTOR); - break; - default: - return (*sp->vsetparent)(tif, tag, ap); - } - tif->tif_flags |= TIFF_DIRTYDIRECT; - return 1; -} - -static int PredictorVGetField(TIFF *tif, uint32_t tag, va_list ap) -{ - TIFFPredictorState *sp = PredictorState(tif); - - assert(sp != NULL); - assert(sp->vgetparent != NULL); - - switch (tag) - { - case TIFFTAG_PREDICTOR: - *va_arg(ap, uint16_t *) = (uint16_t)sp->predictor; - break; - default: - return (*sp->vgetparent)(tif, tag, ap); - } - return 1; -} - -static void PredictorPrintDir(TIFF *tif, FILE *fd, long flags) -{ - TIFFPredictorState *sp = PredictorState(tif); - - (void)flags; - if (TIFFFieldSet(tif, FIELD_PREDICTOR)) - { - fprintf(fd, " Predictor: "); - switch (sp->predictor) - { - case 1: - fprintf(fd, "none "); - break; - case 2: - fprintf(fd, "horizontal differencing "); - break; - case 3: - fprintf(fd, "floating point predictor "); - break; - } - fprintf(fd, "%d (0x%x)\n", sp->predictor, sp->predictor); - } - if (sp->printdir) - (*sp->printdir)(tif, fd, flags); -} - -int TIFFPredictorInit(TIFF *tif) -{ - TIFFPredictorState *sp = PredictorState(tif); - - assert(sp != 0); - - /* - * Merge codec-specific tag information. - */ - if (!_TIFFMergeFields(tif, predictFields, TIFFArrayCount(predictFields))) - { - TIFFErrorExtR(tif, "TIFFPredictorInit", - "Merging Predictor codec-specific tags failed"); - return 0; - } - - /* - * Override parent get/set field methods. - */ - sp->vgetparent = tif->tif_tagmethods.vgetfield; - tif->tif_tagmethods.vgetfield = - PredictorVGetField; /* hook for predictor tag */ - sp->vsetparent = tif->tif_tagmethods.vsetfield; - tif->tif_tagmethods.vsetfield = - PredictorVSetField; /* hook for predictor tag */ - sp->printdir = tif->tif_tagmethods.printdir; - tif->tif_tagmethods.printdir = - PredictorPrintDir; /* hook for predictor tag */ - - sp->setupdecode = tif->tif_setupdecode; - tif->tif_setupdecode = PredictorSetupDecode; - sp->setupencode = tif->tif_setupencode; - tif->tif_setupencode = PredictorSetupEncode; - - sp->predictor = 1; /* default value */ - sp->encodepfunc = NULL; /* no predictor routine */ - sp->decodepfunc = NULL; /* no predictor routine */ - return 1; -} - -int TIFFPredictorCleanup(TIFF *tif) -{ - TIFFPredictorState *sp = PredictorState(tif); - - assert(sp != 0); - - tif->tif_tagmethods.vgetfield = sp->vgetparent; - tif->tif_tagmethods.vsetfield = sp->vsetparent; - tif->tif_tagmethods.printdir = sp->printdir; - tif->tif_setupdecode = sp->setupdecode; - tif->tif_setupencode = sp->setupencode; - - return 1; -} diff --git a/src/3rd/tiff/predict.h b/src/3rd/tiff/predict.h deleted file mode 100644 index de773283520..00000000000 --- a/src/3rd/tiff/predict.h +++ /dev/null @@ -1,74 +0,0 @@ -/* - * Copyright (c) 1995-1997 Sam Leffler - * Copyright (c) 1995-1997 Silicon Graphics, Inc. - * - * Permission to use, copy, modify, distribute, and sell this software and - * its documentation for any purpose is hereby granted without fee, provided - * that (i) the above copyright notices and this permission notice appear in - * all copies of the software and related documentation, and (ii) the names of - * Sam Leffler and Silicon Graphics may not be used in any advertising or - * publicity relating to the software without the specific, prior written - * permission of Sam Leffler and Silicon Graphics. - * - * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, - * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY - * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. - * - * IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR - * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, - * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, - * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF - * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE - * OF THIS SOFTWARE. - */ - -#ifndef _TIFFPREDICT_ -#define _TIFFPREDICT_ - -#include "tiffio.h" -#include "tiffiop.h" - -/* - * ``Library-private'' Support for the Predictor Tag - */ - -typedef int (*TIFFEncodeDecodeMethod)(TIFF *tif, uint8_t *buf, tmsize_t size); - -/* - * Codecs that want to support the Predictor tag must place - * this structure first in their private state block so that - * the predictor code can cast tif_data to find its state. - */ -typedef struct -{ - int predictor; /* predictor tag value */ - tmsize_t stride; /* sample stride over data */ - tmsize_t rowsize; /* tile/strip row size */ - - TIFFCodeMethod encoderow; /* parent codec encode/decode row */ - TIFFCodeMethod encodestrip; /* parent codec encode/decode strip */ - TIFFCodeMethod encodetile; /* parent codec encode/decode tile */ - TIFFEncodeDecodeMethod encodepfunc; /* horizontal differencer */ - - TIFFCodeMethod decoderow; /* parent codec encode/decode row */ - TIFFCodeMethod decodestrip; /* parent codec encode/decode strip */ - TIFFCodeMethod decodetile; /* parent codec encode/decode tile */ - TIFFEncodeDecodeMethod decodepfunc; /* horizontal accumulator */ - - TIFFVGetMethod vgetparent; /* super-class method */ - TIFFVSetMethod vsetparent; /* super-class method */ - TIFFPrintMethod printdir; /* super-class method */ - TIFFBoolMethod setupdecode; /* super-class method */ - TIFFBoolMethod setupencode; /* super-class method */ -} TIFFPredictorState; - -#if defined(__cplusplus) -extern "C" -{ -#endif - extern int TIFFPredictorInit(TIFF *); - extern int TIFFPredictorCleanup(TIFF *); -#if defined(__cplusplus) -} -#endif -#endif /* _TIFFPREDICT_ */ diff --git a/src/3rd/tiff/print.c b/src/3rd/tiff/print.c deleted file mode 100644 index e49dc1c9c6d..00000000000 --- a/src/3rd/tiff/print.c +++ /dev/null @@ -1,756 +0,0 @@ -/* - * Copyright (c) 1988-1997 Sam Leffler - * Copyright (c) 1991-1997 Silicon Graphics, Inc. - * - * Permission to use, copy, modify, distribute, and sell this software and - * its documentation for any purpose is hereby granted without fee, provided - * that (i) the above copyright notices and this permission notice appear in - * all copies of the software and related documentation, and (ii) the names of - * Sam Leffler and Silicon Graphics may not be used in any advertising or - * publicity relating to the software without the specific, prior written - * permission of Sam Leffler and Silicon Graphics. - * - * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, - * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY - * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. - * - * IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR - * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, - * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, - * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF - * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE - * OF THIS SOFTWARE. - */ - -/* - * TIFF Library. - * - * Directory Printing Support - */ -#include "tiffiop.h" -#include - -#include - -static void _TIFFprintAsciiBounded(FILE *fd, const char *cp, size_t max_chars); - -static const char *const photoNames[] = { - "min-is-white", /* PHOTOMETRIC_MINISWHITE */ - "min-is-black", /* PHOTOMETRIC_MINISBLACK */ - "RGB color", /* PHOTOMETRIC_RGB */ - "palette color (RGB from colormap)", /* PHOTOMETRIC_PALETTE */ - "transparency mask", /* PHOTOMETRIC_MASK */ - "separated", /* PHOTOMETRIC_SEPARATED */ - "YCbCr", /* PHOTOMETRIC_YCBCR */ - "7 (0x7)", - "CIE L*a*b*", /* PHOTOMETRIC_CIELAB */ - "ICC L*a*b*", /* PHOTOMETRIC_ICCLAB */ - "ITU L*a*b*" /* PHOTOMETRIC_ITULAB */ -}; -#define NPHOTONAMES (sizeof(photoNames) / sizeof(photoNames[0])) - -static const char *const orientNames[] = { - "0 (0x0)", - "row 0 top, col 0 lhs", /* ORIENTATION_TOPLEFT */ - "row 0 top, col 0 rhs", /* ORIENTATION_TOPRIGHT */ - "row 0 bottom, col 0 rhs", /* ORIENTATION_BOTRIGHT */ - "row 0 bottom, col 0 lhs", /* ORIENTATION_BOTLEFT */ - "row 0 lhs, col 0 top", /* ORIENTATION_LEFTTOP */ - "row 0 rhs, col 0 top", /* ORIENTATION_RIGHTTOP */ - "row 0 rhs, col 0 bottom", /* ORIENTATION_RIGHTBOT */ - "row 0 lhs, col 0 bottom", /* ORIENTATION_LEFTBOT */ -}; -#define NORIENTNAMES (sizeof(orientNames) / sizeof(orientNames[0])) - -static const struct tagname -{ - uint16_t tag; - const char *name; -} tagnames[] = { - {TIFFTAG_GDAL_METADATA, "GDAL Metadata"}, - {TIFFTAG_GDAL_NODATA, "GDAL NoDataValue"}, -}; -#define NTAGS (sizeof(tagnames) / sizeof(tagnames[0])) - -static void _TIFFPrintField(FILE *fd, const TIFFField *fip, - uint32_t value_count, void *raw_data) -{ - uint32_t j; - - /* Print a user-friendly name for tags of relatively common use, but */ - /* which aren't registered by libtiff itself. */ - const char *field_name = fip->field_name; - if (TIFFFieldIsAnonymous(fip)) - { - size_t i; - for (i = 0; i < NTAGS; ++i) - { - if (fip->field_tag == tagnames[i].tag) - { - field_name = tagnames[i].name; - break; - } - } - } - fprintf(fd, " %s: ", field_name); - - for (j = 0; j < value_count; j++) - { - if (fip->field_type == TIFF_BYTE) - fprintf(fd, "%" PRIu8, ((uint8_t *)raw_data)[j]); - else if (fip->field_type == TIFF_UNDEFINED) - fprintf(fd, "0x%" PRIx8, ((uint8_t *)raw_data)[j]); - else if (fip->field_type == TIFF_SBYTE) - fprintf(fd, "%" PRId8, ((int8_t *)raw_data)[j]); - else if (fip->field_type == TIFF_SHORT) - fprintf(fd, "%" PRIu16, ((uint16_t *)raw_data)[j]); - else if (fip->field_type == TIFF_SSHORT) - fprintf(fd, "%" PRId16, ((int16_t *)raw_data)[j]); - else if (fip->field_type == TIFF_LONG) - fprintf(fd, "%" PRIu32, ((uint32_t *)raw_data)[j]); - else if (fip->field_type == TIFF_SLONG) - fprintf(fd, "%" PRId32, ((int32_t *)raw_data)[j]); - else if (fip->field_type == TIFF_IFD) - fprintf(fd, "0x%" PRIx32, ((uint32_t *)raw_data)[j]); - else if (fip->field_type == TIFF_RATIONAL || - fip->field_type == TIFF_SRATIONAL) - { - int tv_size = TIFFFieldSetGetSize(fip); - if (tv_size == 8) - fprintf(fd, "%lf", ((double *)raw_data)[j]); - else - fprintf(fd, "%f", ((float *)raw_data)[j]); - } - else if (fip->field_type == TIFF_FLOAT) - fprintf(fd, "%f", ((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) - fprintf(fd, "%" PRId64, ((int64_t *)raw_data)[j]); - else if (fip->field_type == TIFF_IFD8) - fprintf(fd, "0x%" PRIx64, ((uint64_t *)raw_data)[j]); - else if (fip->field_type == TIFF_DOUBLE) - fprintf(fd, "%lf", ((double *)raw_data)[j]); - else if (fip->field_type == TIFF_ASCII) - { - fprintf(fd, "%s", (char *)raw_data); - break; - } - else - { - fprintf(fd, ""); - break; - } - - if (j < value_count - 1) - fprintf(fd, ","); - } - - fprintf(fd, "\n"); -} - -static int _TIFFPrettyPrintField(TIFF *tif, const TIFFField *fip, FILE *fd, - uint32_t tag, uint32_t value_count, - void *raw_data) -{ - (void)tif; - - /* do not try to pretty print auto-defined fields */ - if (TIFFFieldIsAnonymous(fip)) - { - return 0; - } - - switch (tag) - { - case TIFFTAG_INKSET: - if (value_count == 2 && fip->field_type == TIFF_SHORT) - { - fprintf(fd, " Ink Set: "); - switch (*((uint16_t *)raw_data)) - { - case INKSET_CMYK: - fprintf(fd, "CMYK\n"); - break; - default: - fprintf(fd, "%" PRIu16 " (0x%" PRIx16 ")\n", - *((uint16_t *)raw_data), - *((uint16_t *)raw_data)); - break; - } - return 1; - } - return 0; - - case TIFFTAG_DOTRANGE: - if (value_count == 2 && fip->field_type == TIFF_SHORT) - { - fprintf(fd, " Dot Range: %" PRIu16 "-%" PRIu16 "\n", - ((uint16_t *)raw_data)[0], ((uint16_t *)raw_data)[1]); - return 1; - } - return 0; - - 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]); - return 1; - } - return 0; - - case TIFFTAG_XMLPACKET: - { - uint32_t i; - - fprintf(fd, " XMLPacket (XMP Metadata):\n"); - for (i = 0; i < value_count; i++) - fputc(((char *)raw_data)[i], fd); - fprintf(fd, "\n"); - return 1; - } - case TIFFTAG_RICHTIFFIPTC: - fprintf(fd, " RichTIFFIPTC Data: , %" PRIu32 " bytes\n", - value_count); - return 1; - - case TIFFTAG_PHOTOSHOP: - fprintf(fd, " Photoshop Data: , %" PRIu32 " bytes\n", - value_count); - return 1; - - case TIFFTAG_ICCPROFILE: - fprintf(fd, " ICC Profile: , %" PRIu32 " bytes\n", - value_count); - return 1; - - case TIFFTAG_STONITS: - if (value_count == 1 && fip->field_type == TIFF_DOUBLE) - { - fprintf(fd, " Sample to Nits conversion factor: %.4e\n", - *((double *)raw_data)); - return 1; - } - return 0; - } - - return 0; -} - -/* - * Print the contents of the current directory - * to the specified stdio file stream. - */ -void TIFFPrintDirectory(TIFF *tif, FILE *fd, long flags) -{ - TIFFDirectory *td = &tif->tif_dir; - char *sep; - long l, n; - - fprintf(fd, "TIFF Directory at offset 0x%" PRIx64 " (%" PRIu64 ")\n", - tif->tif_diroff, tif->tif_diroff); - if (TIFFFieldSet(tif, FIELD_SUBFILETYPE)) - { - fprintf(fd, " Subfile Type:"); - sep = " "; - if (td->td_subfiletype & FILETYPE_REDUCEDIMAGE) - { - fprintf(fd, "%sreduced-resolution image", sep); - sep = "/"; - } - if (td->td_subfiletype & FILETYPE_PAGE) - { - fprintf(fd, "%smulti-page document", sep); - sep = "/"; - } - if (td->td_subfiletype & FILETYPE_MASK) - fprintf(fd, "%stransparency mask", sep); - fprintf(fd, " (%" PRIu32 " = 0x%" PRIx32 ")\n", td->td_subfiletype, - td->td_subfiletype); - } - if (TIFFFieldSet(tif, FIELD_IMAGEDIMENSIONS)) - { - fprintf(fd, " Image Width: %" PRIu32 " Image Length: %" PRIu32, - td->td_imagewidth, td->td_imagelength); - if (TIFFFieldSet(tif, FIELD_IMAGEDEPTH)) - fprintf(fd, " Image Depth: %" PRIu32, td->td_imagedepth); - fprintf(fd, "\n"); - } - if (TIFFFieldSet(tif, FIELD_TILEDIMENSIONS)) - { - fprintf(fd, " Tile Width: %" PRIu32 " Tile Length: %" PRIu32, - td->td_tilewidth, td->td_tilelength); - if (TIFFFieldSet(tif, FIELD_TILEDEPTH)) - fprintf(fd, " Tile Depth: %" PRIu32, td->td_tiledepth); - fprintf(fd, "\n"); - } - if (TIFFFieldSet(tif, FIELD_RESOLUTION)) - { - fprintf(fd, " Resolution: %g, %g", td->td_xresolution, - td->td_yresolution); - if (TIFFFieldSet(tif, FIELD_RESOLUTIONUNIT)) - { - switch (td->td_resolutionunit) - { - case RESUNIT_NONE: - fprintf(fd, " (unitless)"); - break; - case RESUNIT_INCH: - fprintf(fd, " pixels/inch"); - break; - case RESUNIT_CENTIMETER: - fprintf(fd, " pixels/cm"); - break; - default: - fprintf(fd, " (unit %" PRIu16 " = 0x%" PRIx16 ")", - td->td_resolutionunit, td->td_resolutionunit); - break; - } - } - fprintf(fd, "\n"); - } - if (TIFFFieldSet(tif, FIELD_POSITION)) - fprintf(fd, " Position: %g, %g\n", td->td_xposition, td->td_yposition); - if (TIFFFieldSet(tif, FIELD_BITSPERSAMPLE)) - fprintf(fd, " Bits/Sample: %" PRIu16 "\n", td->td_bitspersample); - if (TIFFFieldSet(tif, FIELD_SAMPLEFORMAT)) - { - fprintf(fd, " Sample Format: "); - switch (td->td_sampleformat) - { - case SAMPLEFORMAT_VOID: - fprintf(fd, "void\n"); - break; - case SAMPLEFORMAT_INT: - fprintf(fd, "signed integer\n"); - break; - case SAMPLEFORMAT_UINT: - fprintf(fd, "unsigned integer\n"); - break; - case SAMPLEFORMAT_IEEEFP: - fprintf(fd, "IEEE floating point\n"); - break; - case SAMPLEFORMAT_COMPLEXINT: - fprintf(fd, "complex signed integer\n"); - break; - case SAMPLEFORMAT_COMPLEXIEEEFP: - fprintf(fd, "complex IEEE floating point\n"); - break; - default: - fprintf(fd, "%" PRIu16 " (0x%" PRIx16 ")\n", - td->td_sampleformat, td->td_sampleformat); - break; - } - } - if (TIFFFieldSet(tif, FIELD_COMPRESSION)) - { - const TIFFCodec *c = TIFFFindCODEC(td->td_compression); - fprintf(fd, " Compression Scheme: "); - if (c) - fprintf(fd, "%s\n", c->name); - else - fprintf(fd, "%" PRIu16 " (0x%" PRIx16 ")\n", td->td_compression, - td->td_compression); - } - if (TIFFFieldSet(tif, FIELD_PHOTOMETRIC)) - { - fprintf(fd, " Photometric Interpretation: "); - if (td->td_photometric < NPHOTONAMES) - fprintf(fd, "%s\n", photoNames[td->td_photometric]); - else - { - switch (td->td_photometric) - { - case PHOTOMETRIC_LOGL: - fprintf(fd, "CIE Log2(L)\n"); - break; - case PHOTOMETRIC_LOGLUV: - fprintf(fd, "CIE Log2(L) (u',v')\n"); - break; - default: - fprintf(fd, "%" PRIu16 " (0x%" PRIx16 ")\n", - td->td_photometric, td->td_photometric); - break; - } - } - } - if (TIFFFieldSet(tif, FIELD_EXTRASAMPLES) && td->td_extrasamples) - { - uint16_t i; - fprintf(fd, " Extra Samples: %" PRIu16 "<", td->td_extrasamples); - sep = ""; - for (i = 0; i < td->td_extrasamples; i++) - { - switch (td->td_sampleinfo[i]) - { - case EXTRASAMPLE_UNSPECIFIED: - fprintf(fd, "%sunspecified", sep); - break; - case EXTRASAMPLE_ASSOCALPHA: - fprintf(fd, "%sassoc-alpha", sep); - break; - case EXTRASAMPLE_UNASSALPHA: - fprintf(fd, "%sunassoc-alpha", sep); - break; - default: - fprintf(fd, "%s%" PRIu16 " (0x%" PRIx16 ")", sep, - td->td_sampleinfo[i], td->td_sampleinfo[i]); - break; - } - sep = ", "; - } - fprintf(fd, ">\n"); - } - if (TIFFFieldSet(tif, FIELD_INKNAMES)) - { - char *cp; - uint16_t i; - fprintf(fd, " Ink Names: "); - i = td->td_samplesperpixel; - sep = ""; - for (cp = td->td_inknames; - 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); - fputs(sep, fd); - _TIFFprintAsciiBounded(fd, cp, max_chars); - sep = ", "; - } - fputs("\n", fd); - } - if (TIFFFieldSet(tif, FIELD_NUMBEROFINKS)) - { - fprintf(fd, " NumberOfInks: %d\n", td->td_numberofinks); - } - if (TIFFFieldSet(tif, FIELD_THRESHHOLDING)) - { - fprintf(fd, " Thresholding: "); - switch (td->td_threshholding) - { - case THRESHHOLD_BILEVEL: - fprintf(fd, "bilevel art scan\n"); - break; - case THRESHHOLD_HALFTONE: - fprintf(fd, "halftone or dithered scan\n"); - break; - case THRESHHOLD_ERRORDIFFUSE: - fprintf(fd, "error diffused\n"); - break; - default: - fprintf(fd, "%" PRIu16 " (0x%" PRIx16 ")\n", - td->td_threshholding, td->td_threshholding); - break; - } - } - if (TIFFFieldSet(tif, FIELD_FILLORDER)) - { - fprintf(fd, " FillOrder: "); - switch (td->td_fillorder) - { - case FILLORDER_MSB2LSB: - fprintf(fd, "msb-to-lsb\n"); - break; - case FILLORDER_LSB2MSB: - fprintf(fd, "lsb-to-msb\n"); - break; - default: - fprintf(fd, "%" PRIu16 " (0x%" PRIx16 ")\n", td->td_fillorder, - td->td_fillorder); - break; - } - } - if (TIFFFieldSet(tif, FIELD_YCBCRSUBSAMPLING)) - { - fprintf(fd, " YCbCr Subsampling: %" PRIu16 ", %" PRIu16 "\n", - td->td_ycbcrsubsampling[0], td->td_ycbcrsubsampling[1]); - } - if (TIFFFieldSet(tif, FIELD_YCBCRPOSITIONING)) - { - fprintf(fd, " YCbCr Positioning: "); - switch (td->td_ycbcrpositioning) - { - case YCBCRPOSITION_CENTERED: - fprintf(fd, "centered\n"); - break; - case YCBCRPOSITION_COSITED: - fprintf(fd, "cosited\n"); - break; - default: - fprintf(fd, "%" PRIu16 " (0x%" PRIx16 ")\n", - td->td_ycbcrpositioning, td->td_ycbcrpositioning); - break; - } - } - if (TIFFFieldSet(tif, FIELD_HALFTONEHINTS)) - fprintf(fd, " Halftone Hints: light %" PRIu16 " dark %" PRIu16 "\n", - td->td_halftonehints[0], td->td_halftonehints[1]); - if (TIFFFieldSet(tif, FIELD_ORIENTATION)) - { - fprintf(fd, " Orientation: "); - if (td->td_orientation < NORIENTNAMES) - fprintf(fd, "%s\n", orientNames[td->td_orientation]); - else - fprintf(fd, "%" PRIu16 " (0x%" PRIx16 ")\n", td->td_orientation, - td->td_orientation); - } - if (TIFFFieldSet(tif, FIELD_SAMPLESPERPIXEL)) - fprintf(fd, " Samples/Pixel: %" PRIx16 "\n", td->td_samplesperpixel); - if (TIFFFieldSet(tif, FIELD_ROWSPERSTRIP)) - { - fprintf(fd, " Rows/Strip: "); - if (td->td_rowsperstrip == (uint32_t)-1) - fprintf(fd, "(infinite)\n"); - else - fprintf(fd, "%" PRIu32 "\n", td->td_rowsperstrip); - } - if (TIFFFieldSet(tif, FIELD_MINSAMPLEVALUE)) - fprintf(fd, " Min Sample Value: %" PRIu16 "\n", td->td_minsamplevalue); - if (TIFFFieldSet(tif, FIELD_MAXSAMPLEVALUE)) - fprintf(fd, " Max Sample Value: %" PRIu16 "\n", td->td_maxsamplevalue); - if (TIFFFieldSet(tif, FIELD_SMINSAMPLEVALUE)) - { - int i; - int count = - (tif->tif_flags & TIFF_PERSAMPLE) ? td->td_samplesperpixel : 1; - fprintf(fd, " SMin Sample Value:"); - for (i = 0; i < count; ++i) - fprintf(fd, " %g", td->td_sminsamplevalue[i]); - fprintf(fd, "\n"); - } - if (TIFFFieldSet(tif, FIELD_SMAXSAMPLEVALUE)) - { - int i; - int count = - (tif->tif_flags & TIFF_PERSAMPLE) ? td->td_samplesperpixel : 1; - fprintf(fd, " SMax Sample Value:"); - for (i = 0; i < count; ++i) - fprintf(fd, " %g", td->td_smaxsamplevalue[i]); - fprintf(fd, "\n"); - } - if (TIFFFieldSet(tif, FIELD_PLANARCONFIG)) - { - fprintf(fd, " Planar Configuration: "); - switch (td->td_planarconfig) - { - case PLANARCONFIG_CONTIG: - fprintf(fd, "single image plane\n"); - break; - case PLANARCONFIG_SEPARATE: - fprintf(fd, "separate image planes\n"); - break; - default: - fprintf(fd, "%" PRIu16 " (0x%" PRIx16 ")\n", - td->td_planarconfig, td->td_planarconfig); - break; - } - } - 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)) - { - 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]); - } - else - fprintf(fd, "(present)\n"); - } - if (TIFFFieldSet(tif, FIELD_REFBLACKWHITE)) - { - int i; - 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]); - } - if (TIFFFieldSet(tif, FIELD_TRANSFERFUNCTION)) - { - fprintf(fd, " Transfer Function: "); - if (flags & TIFFPRINT_CURVES) - { - fprintf(fd, "\n"); - n = 1L << td->td_bitspersample; - for (l = 0; l < n; l++) - { - 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); - } - } - else - fprintf(fd, "(present)\n"); - } - if (TIFFFieldSet(tif, FIELD_SUBIFD) && (td->td_subifd)) - { - uint16_t i; - fprintf(fd, " SubIFD Offsets:"); - for (i = 0; i < td->td_nsubifd; i++) - fprintf(fd, " %5" PRIu64, td->td_subifd[i]); - fputc('\n', fd); - } - - /* - ** Custom tag support. - */ - { - int i; - short count; - - count = (short)TIFFGetTagListCount(tif); - for (i = 0; i < count; i++) - { - uint32_t tag = TIFFGetTagListEntry(tif, i); - const TIFFField *fip; - uint32_t value_count; - int mem_alloc = 0; - void *raw_data = NULL; - uint16_t dotrange[2]; /* must be kept in that scope and not moved in - the below TIFFTAG_DOTRANGE specific case */ - - fip = TIFFFieldWithTag(tif, tag); - if (fip == NULL) - continue; - - if (fip->field_passcount) - { - if (fip->field_readcount == TIFF_VARIABLE2) - { - if (TIFFGetField(tif, tag, &value_count, &raw_data) != 1) - continue; - } - else if (fip->field_readcount == TIFF_VARIABLE) - { - uint16_t small_value_count; - if (TIFFGetField(tif, tag, &small_value_count, &raw_data) != - 1) - continue; - value_count = small_value_count; - } - else - { - assert(fip->field_readcount == TIFF_VARIABLE || - fip->field_readcount == TIFF_VARIABLE2); - continue; - } - } - else - { - if (fip->field_readcount == TIFF_VARIABLE || - fip->field_readcount == TIFF_VARIABLE2) - value_count = 1; - else if (fip->field_readcount == TIFF_SPP) - value_count = td->td_samplesperpixel; - else - value_count = fip->field_readcount; - if (fip->field_tag == TIFFTAG_DOTRANGE && - strcmp(fip->field_name, "DotRange") == 0) - { - /* TODO: This is an evil exception and should not have been - handled this way ... likely best if we move it into - the directory structure with an explicit field in - libtiff 4.1 and assign it a FIELD_ value */ - raw_data = dotrange; - TIFFGetField(tif, tag, dotrange + 0, dotrange + 1); - } - else if (fip->field_type == TIFF_ASCII || - fip->field_readcount == TIFF_VARIABLE || - fip->field_readcount == TIFF_VARIABLE2 || - fip->field_readcount == TIFF_SPP || value_count > 1) - { - if (TIFFGetField(tif, tag, &raw_data) != 1) - continue; - } - else - { - /*--: Rational2Double: For Rationals evaluate - * "set_field_type" to determine internal storage size. */ - int tv_size = TIFFFieldSetGetSize(fip); - raw_data = _TIFFmallocExt(tif, tv_size * value_count); - mem_alloc = 1; - if (TIFFGetField(tif, tag, raw_data) != 1) - { - _TIFFfreeExt(tif, raw_data); - continue; - } - } - } - - /* - * Catch the tags which needs to be specially handled - * and pretty print them. If tag not handled in - * _TIFFPrettyPrintField() fall down and print it as - * any other tag. - */ - if (raw_data != NULL && - !_TIFFPrettyPrintField(tif, fip, fd, tag, value_count, - raw_data)) - _TIFFPrintField(fd, fip, value_count, raw_data); - - if (mem_alloc) - _TIFFfreeExt(tif, raw_data); - } - } - - if (tif->tif_tagmethods.printdir) - (*tif->tif_tagmethods.printdir)(tif, fd, flags); - - if ((flags & TIFFPRINT_STRIPS) && TIFFFieldSet(tif, FIELD_STRIPOFFSETS)) - { - uint32_t s; - - fprintf(fd, " %" PRIu32 " %s:\n", td->td_nstrips, - isTiled(tif) ? "Tiles" : "Strips"); - for (s = 0; s < td->td_nstrips; s++) - fprintf(fd, " %3" PRIu32 ": [%8" PRIu64 ", %8" PRIu64 "]\n", s, - TIFFGetStrileOffset(tif, s), - TIFFGetStrileByteCount(tif, s)); - } -} - -void _TIFFprintAscii(FILE *fd, const char *cp) -{ - _TIFFprintAsciiBounded(fd, cp, strlen(cp)); -} - -static void _TIFFprintAsciiBounded(FILE *fd, const char *cp, size_t max_chars) -{ - for (; max_chars > 0 && *cp != '\0'; cp++, max_chars--) - { - const char *tp; - - if (isprint((int)*cp)) - { - fputc(*cp, fd); - continue; - } - for (tp = "\tt\bb\rr\nn\vv"; *tp; tp++) - if (*tp++ == *cp) - break; - if (*tp) - fprintf(fd, "\\%c", *tp); - else - fprintf(fd, "\\%03o", *cp & 0xff); - } -} - -void _TIFFprintAsciiTag(FILE *fd, const char *name, const char *value) -{ - fprintf(fd, " %s: \"", name); - _TIFFprintAscii(fd, value); - fprintf(fd, "\"\n"); -} diff --git a/src/3rd/tiff/read.c b/src/3rd/tiff/read.c deleted file mode 100644 index 4fec83969ea..00000000000 --- a/src/3rd/tiff/read.c +++ /dev/null @@ -1,1624 +0,0 @@ -/* - * Copyright (c) 1988-1997 Sam Leffler - * Copyright (c) 1991-1997 Silicon Graphics, Inc. - * - * Permission to use, copy, modify, distribute, and sell this software and - * its documentation for any purpose is hereby granted without fee, provided - * that (i) the above copyright notices and this permission notice appear in - * all copies of the software and related documentation, and (ii) the names of - * Sam Leffler and Silicon Graphics may not be used in any advertising or - * publicity relating to the software without the specific, prior written - * permission of Sam Leffler and Silicon Graphics. - * - * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, - * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY - * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. - * - * IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR - * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, - * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, - * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF - * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE - * OF THIS SOFTWARE. - */ - -/* - * TIFF Library. - * Scanline-oriented Read Support - */ -#include "tiffiop.h" -#include - -int TIFFFillStrip(TIFF *tif, uint32_t strip); -int TIFFFillTile(TIFF *tif, uint32_t tile); -static int TIFFStartStrip(TIFF *tif, uint32_t strip); -static int TIFFStartTile(TIFF *tif, uint32_t tile); -static int TIFFCheckRead(TIFF *, int); -static tmsize_t TIFFReadRawStrip1(TIFF *tif, uint32_t strip, void *buf, - tmsize_t size, const char *module); -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 \ - (THRESHOLD_MULTIPLIER * THRESHOLD_MULTIPLIER * THRESHOLD_MULTIPLIER * \ - INITIAL_THRESHOLD) - -#define TIFF_INT64_MAX ((((int64_t)0x7FFFFFFF) << 32) | 0xFFFFFFFF) - -/* Read 'size' bytes in tif_rawdata buffer starting at offset 'rawdata_offset' - * Returns 1 in case of success, 0 otherwise. */ -static int TIFFReadAndRealloc(TIFF *tif, tmsize_t size, tmsize_t rawdata_offset, - int is_strip, uint32_t strip_or_tile, - const char *module) -{ -#if SIZEOF_SIZE_T == 8 - tmsize_t threshold = INITIAL_THRESHOLD; -#endif - tmsize_t already_read = 0; - -#if SIZEOF_SIZE_T != 8 - /* On 32 bit processes, if the request is large enough, check against */ - /* file size */ - if (size > 1000 * 1000 * 1000) - { - uint64_t filesize = TIFFGetFileSize(tif); - if ((uint64_t)size >= filesize) - { - TIFFErrorExtR(tif, module, - "Chunk size requested is larger than file size."); - return 0; - } - } -#endif - - /* On 64 bit processes, read first a maximum of 1 MB, then 10 MB, etc */ - /* so as to avoid allocating too much memory in case the file is too */ - /* short. We could ask for the file size, but this might be */ - /* expensive with some I/O layers (think of reading a gzipped file) */ - /* Restrict to 64 bit processes, so as to avoid reallocs() */ - /* on 32 bit processes where virtual memory is scarce. */ - while (already_read < size) - { - tmsize_t bytes_read; - tmsize_t to_read = size - already_read; -#if SIZEOF_SIZE_T == 8 - if (to_read >= threshold && threshold < MAX_THRESHOLD && - already_read + to_read + rawdata_offset > tif->tif_rawdatasize) - { - to_read = threshold; - threshold *= THRESHOLD_MULTIPLIER; - } -#endif - if (already_read + to_read + rawdata_offset > tif->tif_rawdatasize) - { - 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); - if (tif->tif_rawdatasize == 0) - { - TIFFErrorExtR(tif, module, "Invalid buffer size"); - return 0; - } - new_rawdata = - (uint8_t *)_TIFFrealloc(tif->tif_rawdata, tif->tif_rawdatasize); - if (new_rawdata == 0) - { - TIFFErrorExtR(tif, module, - "No space for data buffer at scanline %" PRIu32, - tif->tif_row); - _TIFFfreeExt(tif, tif->tif_rawdata); - tif->tif_rawdata = 0; - tif->tif_rawdatasize = 0; - return 0; - } - tif->tif_rawdata = new_rawdata; - } - if (tif->tif_rawdata == NULL) - { - /* should not happen in practice but helps CoverityScan */ - return 0; - } - - bytes_read = TIFFReadFile( - tif, tif->tif_rawdata + rawdata_offset + already_read, to_read); - 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); - 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); - } - else - { - TIFFErrorExtR(tif, module, - "Read error at row %" PRIu32 ", col %" PRIu32 - ", tile %" PRIu32 "; " - "got %" TIFF_SSIZE_FORMAT - " bytes, expected %" TIFF_SSIZE_FORMAT "", - tif->tif_row, tif->tif_col, strip_or_tile, - already_read, size); - } - return 0; - } - } - return 1; -} - -static int TIFFFillStripPartial(TIFF *tif, int strip, tmsize_t read_ahead, - int restart) -{ - static const char module[] = "TIFFFillStripPartial"; - register TIFFDirectory *td = &tif->tif_dir; - tmsize_t unused_data; - uint64_t read_offset; - tmsize_t to_read; - tmsize_t read_ahead_mod; - /* tmsize_t bytecountm; */ - - /* - * Expand raw data buffer, if needed, to hold data - * strip coming from file (perhaps should set upper - * bound on the size of a buffer we'll use?). - */ - - /* bytecountm=(tmsize_t) TIFFGetStrileByteCount(tif, strip); */ - - /* Not completely sure where the * 2 comes from, but probably for */ - /* an exponentional growth strategy of tif_rawdatasize */ - if (read_ahead < TIFF_TMSIZE_T_MAX / 2) - read_ahead_mod = read_ahead * 2; - else - read_ahead_mod = read_ahead; - if (read_ahead_mod > tif->tif_rawdatasize) - { - assert(restart); - - tif->tif_curstrip = NOSTRIP; - if ((tif->tif_flags & TIFF_MYBUFFER) == 0) - { - TIFFErrorExtR(tif, module, - "Data buffer too small to hold part of strip %d", - strip); - return (0); - } - } - - if (restart) - { - tif->tif_rawdataloaded = 0; - tif->tif_rawdataoff = 0; - } - - /* - ** If we are reading more data, move any unused data to the - ** start of the buffer. - */ - if (tif->tif_rawdataloaded > 0) - unused_data = - tif->tif_rawdataloaded - (tif->tif_rawcp - tif->tif_rawdata); - else - unused_data = 0; - - if (unused_data > 0) - { - assert((tif->tif_flags & TIFF_BUFFERMMAP) == 0); - memmove(tif->tif_rawdata, tif->tif_rawcp, 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; - - if (!SeekOK(tif, read_offset)) - { - TIFFErrorExtR(tif, module, - "Seek error at scanline %" PRIu32 ", strip %d", - tif->tif_row, strip); - return 0; - } - - /* - ** How much do we want to read? - */ - if (read_ahead_mod > tif->tif_rawdatasize) - 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) - { - to_read = (tmsize_t)TIFFGetStrileByteCount(tif, strip) - - tif->tif_rawdataoff - tif->tif_rawdataloaded; - } - - assert((tif->tif_flags & TIFF_BUFFERMMAP) == 0); - if (!TIFFReadAndRealloc(tif, to_read, unused_data, 1, /* is_strip */ - 0, /* strip_or_tile */ - module)) - { - return 0; - } - - tif->tif_rawdataoff = - tif->tif_rawdataoff + tif->tif_rawdataloaded - unused_data; - tif->tif_rawdataloaded = unused_data + to_read; - - tif->tif_rawcc = tif->tif_rawdataloaded; - tif->tif_rawcp = tif->tif_rawdata; - - if (!isFillOrder(tif, td->td_fillorder) && - (tif->tif_flags & TIFF_NOBITREV) == 0) - { - assert((tif->tif_flags & TIFF_BUFFERMMAP) == 0); - TIFFReverseBits(tif->tif_rawdata + unused_data, to_read); - } - - /* - ** When starting a strip from the beginning we need to - ** restart the decoder. - */ - if (restart) - { - -#ifdef JPEG_SUPPORT - /* A bit messy since breaks the codec abstraction. Ultimately */ - /* there should be a function pointer for that, but it seems */ - /* only JPEG is affected. */ - /* 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)) - { - if (TIFFJPEGIsFullStripRequired(tif)) - { - return TIFFFillStrip(tif, strip); - } - } -#endif - - return TIFFStartStrip(tif, strip); - } - else - { - return 1; - } -} - -/* - * Seek to a random row+sample in a file. - * - * Only used by TIFFReadScanline, and is only used on - * strip organized files. We do some tricky stuff to try - * and avoid reading the whole compressed raw data for big - * strips. - */ -static int TIFFSeek(TIFF *tif, uint32_t row, uint16_t sample) -{ - register TIFFDirectory *td = &tif->tif_dir; - uint32_t strip; - int whole_strip; - tmsize_t read_ahead = 0; - - /* - ** Establish what strip we are working from. - */ - if (row >= td->td_imagelength) - { /* out of range */ - TIFFErrorExtR(tif, tif->tif_name, - "%" PRIu32 ": Row out of range, max %" PRIu32 "", row, - td->td_imagelength); - return (0); - } - if (td->td_planarconfig == PLANARCONFIG_SEPARATE) - { - if (sample >= td->td_samplesperpixel) - { - TIFFErrorExtR(tif, tif->tif_name, - "%" PRIu16 ": Sample out of range, max %" PRIu16 "", - sample, td->td_samplesperpixel); - return (0); - } - strip = (uint32_t)sample * td->td_stripsperimage + - row / td->td_rowsperstrip; - } - 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? - */ -#if defined(CHUNKY_STRIP_READ_SUPPORT) - whole_strip = TIFFGetStrileByteCount(tif, strip) < 10 || isMapped(tif); - if (td->td_compression == COMPRESSION_LERC || - td->td_compression == COMPRESSION_JBIG) - { - /* Ideally plugins should have a way to declare they don't support - * chunk strip */ - whole_strip = 1; - } -#else - whole_strip = 1; -#endif - - if (!whole_strip) - { - /* 16 is for YCbCr mode where we may need to read 16 */ - /* lines at a time to get a decompressed line, and 5000 */ - /* is some constant value, for example for JPEG tables */ - if (tif->tif_scanlinesize < TIFF_TMSIZE_T_MAX / 16 && - tif->tif_scanlinesize * 16 < TIFF_TMSIZE_T_MAX - 5000) - { - read_ahead = tif->tif_scanlinesize * 16 + 5000; - } - else - { - read_ahead = tif->tif_scanlinesize; - } - } - - /* - * If we haven't loaded this strip, do so now, possibly - * only reading the first part. - */ - if (strip != tif->tif_curstrip) - { /* different strip, refill */ - - if (whole_strip) - { - if (!TIFFFillStrip(tif, strip)) - return (0); - } - else - { - if (!TIFFFillStripPartial(tif, strip, read_ahead, 1)) - return 0; - } - } - - /* - ** If we already have some data loaded, do we need to read some more? - */ - else if (!whole_strip) - { - if (((tif->tif_rawdata + tif->tif_rawdataloaded) - tif->tif_rawcp) < - read_ahead && - (uint64_t)tif->tif_rawdataoff + tif->tif_rawdataloaded < - TIFFGetStrileByteCount(tif, strip)) - { - if (!TIFFFillStripPartial(tif, strip, read_ahead, 0)) - return 0; - } - } - - if (row < tif->tif_row) - { - /* - * Moving backwards within the same strip: backup - * to the start and then decode forward (below). - * - * NB: If you're planning on lots of random access within a - * strip, it's better to just read and decode the entire - * strip, and then access the decoded data in a random fashion. - */ - - if (tif->tif_rawdataoff != 0) - { - if (!TIFFFillStripPartial(tif, strip, read_ahead, 1)) - return 0; - } - else - { - if (!TIFFStartStrip(tif, strip)) - return (0); - } - } - - if (row != tif->tif_row) - { - /* - * Seek forward to the desired row. - */ - - /* TODO: Will this really work with partial buffers? */ - - if (!(*tif->tif_seek)(tif, row - tif->tif_row)) - return (0); - tif->tif_row = row; - } - - return (1); -} - -int TIFFReadScanline(TIFF *tif, void *buf, uint32_t row, uint16_t sample) -{ - int e; - - if (!TIFFCheckRead(tif, 0)) - return (-1); - if ((e = TIFFSeek(tif, row, sample)) != 0) - { - /* - * Decompress desired row into user buffer. - */ - e = (*tif->tif_decoderow)(tif, (uint8_t *)buf, tif->tif_scanlinesize, - sample); - - /* we are now poised at the beginning of the next row */ - tif->tif_row = row + 1; - - if (e) - (*tif->tif_postdecode)(tif, (uint8_t *)buf, tif->tif_scanlinesize); - } - return (e > 0 ? 1 : -1); -} - -/* - * Calculate the strip size according to the number of - * rows in the strip (check for truncated last strip on any - * of the separations). - */ -static tmsize_t TIFFReadEncodedStripGetStripSize(TIFF *tif, uint32_t strip, - uint16_t *pplane) -{ - static const char module[] = "TIFFReadEncodedStrip"; - TIFFDirectory *td = &tif->tif_dir; - uint32_t rowsperstrip; - uint32_t stripsperplane; - uint32_t stripinplane; - uint32_t rows; - tmsize_t stripsize; - if (!TIFFCheckRead(tif, 0)) - return ((tmsize_t)(-1)); - if (strip >= td->td_nstrips) - { - TIFFErrorExtR(tif, module, - "%" PRIu32 ": Strip out of range, max %" PRIu32, strip, - td->td_nstrips); - return ((tmsize_t)(-1)); - } - - rowsperstrip = td->td_rowsperstrip; - if (rowsperstrip > td->td_imagelength) - rowsperstrip = td->td_imagelength; - stripsperplane = - TIFFhowmany_32_maxuint_compat(td->td_imagelength, rowsperstrip); - stripinplane = (strip % stripsperplane); - if (pplane) - *pplane = (uint16_t)(strip / stripsperplane); - rows = td->td_imagelength - stripinplane * rowsperstrip; - if (rows > rowsperstrip) - rows = rowsperstrip; - stripsize = TIFFVStripSize(tif, rows); - if (stripsize == 0) - return ((tmsize_t)(-1)); - return stripsize; -} - -/* - * Read a strip of data and decompress the specified - * amount into the user-supplied buffer. - */ -tmsize_t TIFFReadEncodedStrip(TIFF *tif, uint32_t strip, void *buf, - tmsize_t size) -{ - static const char module[] = "TIFFReadEncodedStrip"; - TIFFDirectory *td = &tif->tif_dir; - tmsize_t stripsize; - uint16_t plane; - - stripsize = TIFFReadEncodedStripGetStripSize(tif, strip, &plane); - if (stripsize == ((tmsize_t)(-1))) - return ((tmsize_t)(-1)); - - /* shortcut to avoid an extra memcpy() */ - if (td->td_compression == COMPRESSION_NONE && size != (tmsize_t)(-1) && - size >= stripsize && !isMapped(tif) && - ((tif->tif_flags & TIFF_NOREADRAW) == 0)) - { - if (TIFFReadRawStrip1(tif, strip, buf, stripsize, module) != stripsize) - return ((tmsize_t)(-1)); - - if (!isFillOrder(tif, td->td_fillorder) && - (tif->tif_flags & TIFF_NOBITREV) == 0) - TIFFReverseBits(buf, stripsize); - - (*tif->tif_postdecode)(tif, buf, stripsize); - return (stripsize); - } - - if ((size != (tmsize_t)(-1)) && (size < stripsize)) - stripsize = size; - if (!TIFFFillStrip(tif, strip)) - return ((tmsize_t)(-1)); - if ((*tif->tif_decodestrip)(tif, buf, stripsize, plane) <= 0) - return ((tmsize_t)(-1)); - (*tif->tif_postdecode)(tif, buf, stripsize); - return (stripsize); -} - -/* Variant of TIFFReadEncodedStrip() that does - * * if *buf == NULL, *buf = _TIFFmallocExt(tif, bufsizetoalloc) only after - * TIFFFillStrip() has succeeded. This avoid excessive memory allocation in case - * of truncated file. - * * calls regular TIFFReadEncodedStrip() if *buf != NULL - */ -tmsize_t _TIFFReadEncodedStripAndAllocBuffer(TIFF *tif, uint32_t strip, - void **buf, - tmsize_t bufsizetoalloc, - tmsize_t size_to_read) -{ - tmsize_t this_stripsize; - uint16_t plane; - - if (*buf != NULL) - { - return TIFFReadEncodedStrip(tif, strip, *buf, size_to_read); - } - - this_stripsize = TIFFReadEncodedStripGetStripSize(tif, strip, &plane); - if (this_stripsize == ((tmsize_t)(-1))) - return ((tmsize_t)(-1)); - - if ((size_to_read != (tmsize_t)(-1)) && (size_to_read < this_stripsize)) - this_stripsize = size_to_read; - if (!TIFFFillStrip(tif, strip)) - return ((tmsize_t)(-1)); - - *buf = _TIFFmallocExt(tif, 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) - return ((tmsize_t)(-1)); - (*tif->tif_postdecode)(tif, *buf, this_stripsize); - return (this_stripsize); -} - -static tmsize_t TIFFReadRawStrip1(TIFF *tif, uint32_t strip, void *buf, - tmsize_t size, const char *module) -{ - assert((tif->tif_flags & TIFF_NOREADRAW) == 0); - if (!isMapped(tif)) - { - tmsize_t cc; - - if (!SeekOK(tif, TIFFGetStrileOffset(tif, strip))) - { - TIFFErrorExtR(tif, module, - "Seek error at scanline %" PRIu32 ", strip %" PRIu32, - tif->tif_row, strip); - return ((tmsize_t)(-1)); - } - cc = TIFFReadFile(tif, buf, size); - if (cc != size) - { - TIFFErrorExtR(tif, module, - "Read error at scanline %" PRIu32 - "; got %" TIFF_SSIZE_FORMAT - " bytes, expected %" TIFF_SSIZE_FORMAT, - tif->tif_row, cc, size); - return ((tmsize_t)(-1)); - } - } - else - { - tmsize_t ma = 0; - tmsize_t n; - if ((TIFFGetStrileOffset(tif, strip) > (uint64_t)TIFF_TMSIZE_T_MAX) || - ((ma = (tmsize_t)TIFFGetStrileOffset(tif, strip)) > tif->tif_size)) - { - n = 0; - } - else if (ma > TIFF_TMSIZE_T_MAX - size) - { - n = 0; - } - else - { - tmsize_t mb = ma + size; - if (mb > tif->tif_size) - n = tif->tif_size - ma; - else - n = size; - } - if (n != size) - { - TIFFErrorExtR(tif, module, - "Read error at scanline %" PRIu32 ", strip %" PRIu32 - "; got %" TIFF_SSIZE_FORMAT - " bytes, expected %" TIFF_SSIZE_FORMAT, - tif->tif_row, strip, n, size); - return ((tmsize_t)(-1)); - } - _TIFFmemcpy(buf, tif->tif_base + ma, size); - } - return (size); -} - -static tmsize_t TIFFReadRawStripOrTile2(TIFF *tif, uint32_t strip_or_tile, - int is_strip, tmsize_t size, - const char *module) -{ - assert(!isMapped(tif)); - assert((tif->tif_flags & TIFF_NOREADRAW) == 0); - - if (!SeekOK(tif, TIFFGetStrileOffset(tif, strip_or_tile))) - { - if (is_strip) - { - TIFFErrorExtR(tif, module, - "Seek error at scanline %" PRIu32 ", strip %" PRIu32, - tif->tif_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); - } - return ((tmsize_t)(-1)); - } - - if (!TIFFReadAndRealloc(tif, size, 0, is_strip, strip_or_tile, module)) - { - return ((tmsize_t)(-1)); - } - - return (size); -} - -/* - * Read a strip of data from the file. - */ -tmsize_t TIFFReadRawStrip(TIFF *tif, uint32_t strip, void *buf, tmsize_t size) -{ - static const char module[] = "TIFFReadRawStrip"; - TIFFDirectory *td = &tif->tif_dir; - uint64_t bytecount64; - tmsize_t bytecountm; - - if (!TIFFCheckRead(tif, 0)) - return ((tmsize_t)(-1)); - if (strip >= td->td_nstrips) - { - TIFFErrorExtR(tif, module, - "%" PRIu32 ": Strip out of range, max %" PRIu32, strip, - td->td_nstrips); - return ((tmsize_t)(-1)); - } - if (tif->tif_flags & TIFF_NOREADRAW) - { - TIFFErrorExtR(tif, module, - "Compression scheme does not support access to raw " - "uncompressed data"); - return ((tmsize_t)(-1)); - } - bytecount64 = TIFFGetStrileByteCount(tif, strip); - if (size != (tmsize_t)(-1) && (uint64_t)size <= bytecount64) - bytecountm = size; - else - bytecountm = _TIFFCastUInt64ToSSize(tif, bytecount64, module); - if (bytecountm == 0) - { - return ((tmsize_t)(-1)); - } - return (TIFFReadRawStrip1(tif, strip, buf, bytecountm, module)); -} - -TIFF_NOSANITIZE_UNSIGNED_INT_OVERFLOW -static uint64_t NoSanitizeSubUInt64(uint64_t a, uint64_t b) { return a - b; } - -/* - * Read the specified strip and setup for decoding. The data buffer is - * expanded, as necessary, to hold the strip's data. - */ -int TIFFFillStrip(TIFF *tif, uint32_t strip) -{ - static const char module[] = "TIFFFillStrip"; - TIFFDirectory *td = &tif->tif_dir; - - if ((tif->tif_flags & TIFF_NOREADRAW) == 0) - { - uint64_t bytecount = TIFFGetStrileByteCount(tif, strip); - if (bytecount == 0 || bytecount > (uint64_t)TIFF_INT64_MAX) - { - TIFFErrorExtR(tif, module, - "Invalid strip byte count %" PRIu64 - ", strip %" PRIu32, - bytecount, strip); - return (0); - } - - /* 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) - { - /* 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) - { - 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); - bytecount = newbytecount; - } - } - - if (isMapped(tif)) - { - /* - * We must check for overflow, potentially causing - * an OOB read. Instead of simple - * - * TIFFGetStrileOffset(tif, strip)+bytecount > tif->tif_size - * - * comparison (which can overflow) we do the following - * two comparisons: - */ - if (bytecount > (uint64_t)tif->tif_size || - TIFFGetStrileOffset(tif, strip) > - (uint64_t)tif->tif_size - bytecount) - { - /* - * This error message might seem strange, but - * it's what would happen if a read were done - * instead. - */ - TIFFErrorExtR( - tif, module, - - "Read error on strip %" PRIu32 "; " - "got %" PRIu64 " bytes, expected %" PRIu64, - strip, - NoSanitizeSubUInt64(tif->tif_size, - TIFFGetStrileOffset(tif, strip)), - bytecount); - tif->tif_curstrip = NOSTRIP; - return (0); - } - } - - if (isMapped(tif) && (isFillOrder(tif, td->td_fillorder) || - (tif->tif_flags & TIFF_NOBITREV))) - { - /* - * The image is mapped into memory and we either don't - * need to flip bits or the compression routine is - * going to handle this operation itself. In this - * case, avoid copying the raw data and instead just - * reference the data from the memory mapped file - * image. This assumes that the decompression - * routines do not modify the contents of the raw data - * buffer (if they try to, the application will get a - * fault since the file is mapped read-only). - */ - if ((tif->tif_flags & TIFF_MYBUFFER) && tif->tif_rawdata) - { - _TIFFfreeExt(tif, tif->tif_rawdata); - tif->tif_rawdata = NULL; - tif->tif_rawdatasize = 0; - } - tif->tif_flags &= ~TIFF_MYBUFFER; - tif->tif_rawdatasize = (tmsize_t)bytecount; - tif->tif_rawdata = - tif->tif_base + (tmsize_t)TIFFGetStrileOffset(tif, strip); - tif->tif_rawdataoff = 0; - tif->tif_rawdataloaded = (tmsize_t)bytecount; - - /* - * When we have tif_rawdata reference directly into the memory - * mapped file we need to be pretty careful about how we use the - * rawdata. It is not a general purpose working buffer as it - * normally otherwise is. So we keep track of this fact to avoid - * using it improperly. - */ - tif->tif_flags |= TIFF_BUFFERMMAP; - } - else - { - /* - * Expand raw data buffer, if needed, to hold data - * strip coming from file (perhaps should set upper - * bound on the size of a buffer we'll use?). - */ - tmsize_t bytecountm; - bytecountm = (tmsize_t)bytecount; - if ((uint64_t)bytecountm != bytecount) - { - TIFFErrorExtR(tif, module, "Integer overflow"); - return (0); - } - if (bytecountm > tif->tif_rawdatasize) - { - tif->tif_curstrip = NOSTRIP; - if ((tif->tif_flags & TIFF_MYBUFFER) == 0) - { - TIFFErrorExtR( - tif, module, - "Data buffer too small to hold strip %" PRIu32, strip); - return (0); - } - } - if (tif->tif_flags & TIFF_BUFFERMMAP) - { - tif->tif_curstrip = NOSTRIP; - tif->tif_rawdata = NULL; - tif->tif_rawdatasize = 0; - tif->tif_flags &= ~TIFF_BUFFERMMAP; - } - - if (isMapped(tif)) - { - if (bytecountm > tif->tif_rawdatasize && - !TIFFReadBufferSetup(tif, 0, bytecountm)) - { - return (0); - } - if (TIFFReadRawStrip1(tif, strip, tif->tif_rawdata, bytecountm, - module) != bytecountm) - { - return (0); - } - } - else - { - if (TIFFReadRawStripOrTile2(tif, strip, 1, bytecountm, - module) != bytecountm) - { - return (0); - } - } - - tif->tif_rawdataoff = 0; - tif->tif_rawdataloaded = bytecountm; - - if (!isFillOrder(tif, td->td_fillorder) && - (tif->tif_flags & TIFF_NOBITREV) == 0) - TIFFReverseBits(tif->tif_rawdata, bytecountm); - } - } - return (TIFFStartStrip(tif, strip)); -} - -/* - * Tile-oriented Read Support - * Contributed by Nancy Cam (Silicon Graphics). - */ - -/* - * Read and decompress a tile of data. The - * tile is selected by the (x,y,z,s) coordinates. - */ -tmsize_t TIFFReadTile(TIFF *tif, void *buf, uint32_t x, uint32_t y, uint32_t z, - uint16_t s) -{ - if (!TIFFCheckRead(tif, 1) || !TIFFCheckTile(tif, x, y, z, s)) - return ((tmsize_t)(-1)); - return (TIFFReadEncodedTile(tif, TIFFComputeTile(tif, x, y, z, s), buf, - (tmsize_t)(-1))); -} - -/* - * Read a tile of data and decompress the specified - * amount into the user-supplied buffer. - */ -tmsize_t TIFFReadEncodedTile(TIFF *tif, uint32_t tile, void *buf, tmsize_t size) -{ - static const char module[] = "TIFFReadEncodedTile"; - TIFFDirectory *td = &tif->tif_dir; - tmsize_t tilesize = tif->tif_tilesize; - - if (!TIFFCheckRead(tif, 1)) - return ((tmsize_t)(-1)); - if (tile >= td->td_nstrips) - { - TIFFErrorExtR(tif, module, - "%" PRIu32 ": Tile out of range, max %" PRIu32, tile, - td->td_nstrips); - return ((tmsize_t)(-1)); - } - - /* shortcut to avoid an extra memcpy() */ - if (td->td_compression == COMPRESSION_NONE && size != (tmsize_t)(-1) && - size >= tilesize && !isMapped(tif) && - ((tif->tif_flags & TIFF_NOREADRAW) == 0)) - { - if (TIFFReadRawTile1(tif, tile, buf, tilesize, module) != tilesize) - return ((tmsize_t)(-1)); - - if (!isFillOrder(tif, td->td_fillorder) && - (tif->tif_flags & TIFF_NOBITREV) == 0) - TIFFReverseBits(buf, tilesize); - - (*tif->tif_postdecode)(tif, buf, tilesize); - return (tilesize); - } - - if (size == (tmsize_t)(-1)) - size = tilesize; - else if (size > tilesize) - size = tilesize; - if (TIFFFillTile(tif, tile) && - (*tif->tif_decodetile)(tif, (uint8_t *)buf, size, - (uint16_t)(tile / td->td_stripsperimage))) - { - (*tif->tif_postdecode)(tif, (uint8_t *)buf, size); - return (size); - } - else - return ((tmsize_t)(-1)); -} - -/* Variant of TIFFReadTile() that does - * * if *buf == NULL, *buf = _TIFFmallocExt(tif, bufsizetoalloc) only after - * TIFFFillTile() has succeeded. This avoid excessive memory allocation in case - * of truncated file. - * * calls regular TIFFReadEncodedTile() if *buf != NULL - */ -tmsize_t _TIFFReadTileAndAllocBuffer(TIFF *tif, void **buf, - tmsize_t bufsizetoalloc, uint32_t x, - uint32_t y, uint32_t z, uint16_t s) -{ - if (!TIFFCheckRead(tif, 1) || !TIFFCheckTile(tif, x, y, z, s)) - return ((tmsize_t)(-1)); - return (_TIFFReadEncodedTileAndAllocBuffer( - tif, TIFFComputeTile(tif, x, y, z, s), buf, bufsizetoalloc, - (tmsize_t)(-1))); -} - -/* Variant of TIFFReadEncodedTile() that does - * * if *buf == NULL, *buf = _TIFFmallocExt(tif, bufsizetoalloc) only after - * TIFFFillTile() has succeeded. This avoid excessive memory allocation in case - * of truncated file. - * * calls regular TIFFReadEncodedTile() if *buf != NULL - */ -tmsize_t _TIFFReadEncodedTileAndAllocBuffer(TIFF *tif, uint32_t tile, - void **buf, tmsize_t bufsizetoalloc, - tmsize_t size_to_read) -{ - static const char module[] = "_TIFFReadEncodedTileAndAllocBuffer"; - TIFFDirectory *td = &tif->tif_dir; - tmsize_t tilesize = tif->tif_tilesize; - - if (*buf != NULL) - { - return TIFFReadEncodedTile(tif, tile, *buf, size_to_read); - } - - if (!TIFFCheckRead(tif, 1)) - return ((tmsize_t)(-1)); - if (tile >= td->td_nstrips) - { - TIFFErrorExtR(tif, module, - "%" PRIu32 ": Tile out of range, max %" PRIu32, tile, - td->td_nstrips); - return ((tmsize_t)(-1)); - } - - if (!TIFFFillTile(tif, tile)) - return ((tmsize_t)(-1)); - - /* Sanity checks to avoid excessive memory allocation */ - /* Cf https://gitlab.com/libtiff/libtiff/-/issues/479 */ - if (td->td_compression == COMPRESSION_NONE) - { - if (tif->tif_rawdatasize != tilesize) - { - TIFFErrorExtR(tif, TIFFFileName(tif), - "Invalid tile byte count for tile %u. " - "Expected %" PRIu64 ", got %" PRIu64, - tile, (uint64_t)tilesize, - (uint64_t)tif->tif_rawdatasize); - return ((tmsize_t)(-1)); - } - } - else - { - /* 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 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) - { - 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)); - } - } - - *buf = _TIFFmallocExt(tif, bufsizetoalloc); - if (*buf == NULL) - { - TIFFErrorExtR(tif, TIFFFileName(tif), "No space for tile buffer"); - return ((tmsize_t)(-1)); - } - _TIFFmemset(*buf, 0, bufsizetoalloc); - - if (size_to_read == (tmsize_t)(-1)) - size_to_read = tilesize; - else if (size_to_read > tilesize) - size_to_read = tilesize; - if ((*tif->tif_decodetile)(tif, (uint8_t *)*buf, size_to_read, - (uint16_t)(tile / td->td_stripsperimage))) - { - (*tif->tif_postdecode)(tif, (uint8_t *)*buf, size_to_read); - return (size_to_read); - } - else - return ((tmsize_t)(-1)); -} - -static tmsize_t TIFFReadRawTile1(TIFF *tif, uint32_t tile, void *buf, - tmsize_t size, const char *module) -{ - assert((tif->tif_flags & TIFF_NOREADRAW) == 0); - if (!isMapped(tif)) - { - tmsize_t cc; - - if (!SeekOK(tif, TIFFGetStrileOffset(tif, tile))) - { - TIFFErrorExtR(tif, module, - "Seek error at row %" PRIu32 ", col %" PRIu32 - ", tile %" PRIu32, - tif->tif_row, tif->tif_col, tile); - return ((tmsize_t)(-1)); - } - cc = TIFFReadFile(tif, buf, size); - if (cc != size) - { - TIFFErrorExtR(tif, module, - "Read error at row %" PRIu32 ", col %" PRIu32 - "; got %" TIFF_SSIZE_FORMAT - " bytes, expected %" TIFF_SSIZE_FORMAT, - tif->tif_row, tif->tif_col, cc, size); - return ((tmsize_t)(-1)); - } - } - else - { - tmsize_t ma, mb; - tmsize_t n; - ma = (tmsize_t)TIFFGetStrileOffset(tif, tile); - mb = ma + size; - if ((TIFFGetStrileOffset(tif, tile) > (uint64_t)TIFF_TMSIZE_T_MAX) || - (ma > tif->tif_size)) - n = 0; - else if ((mb < ma) || (mb < size) || (mb > tif->tif_size)) - n = tif->tif_size - ma; - else - n = size; - if (n != size) - { - TIFFErrorExtR(tif, module, - "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); - return ((tmsize_t)(-1)); - } - _TIFFmemcpy(buf, tif->tif_base + ma, size); - } - return (size); -} - -/* - * Read a tile of data from the file. - */ -tmsize_t TIFFReadRawTile(TIFF *tif, uint32_t tile, void *buf, tmsize_t size) -{ - static const char module[] = "TIFFReadRawTile"; - TIFFDirectory *td = &tif->tif_dir; - uint64_t bytecount64; - tmsize_t bytecountm; - - if (!TIFFCheckRead(tif, 1)) - return ((tmsize_t)(-1)); - if (tile >= td->td_nstrips) - { - TIFFErrorExtR(tif, module, - "%" PRIu32 ": Tile out of range, max %" PRIu32, tile, - td->td_nstrips); - return ((tmsize_t)(-1)); - } - if (tif->tif_flags & TIFF_NOREADRAW) - { - TIFFErrorExtR(tif, module, - "Compression scheme does not support access to raw " - "uncompressed data"); - return ((tmsize_t)(-1)); - } - bytecount64 = TIFFGetStrileByteCount(tif, tile); - if (size != (tmsize_t)(-1) && (uint64_t)size <= bytecount64) - bytecountm = size; - else - bytecountm = _TIFFCastUInt64ToSSize(tif, bytecount64, module); - if (bytecountm == 0) - { - return ((tmsize_t)(-1)); - } - return (TIFFReadRawTile1(tif, tile, buf, bytecountm, module)); -} - -/* - * Read the specified tile and setup for decoding. The data buffer is - * expanded, as necessary, to hold the tile's data. - */ -int TIFFFillTile(TIFF *tif, uint32_t tile) -{ - static const char module[] = "TIFFFillTile"; - TIFFDirectory *td = &tif->tif_dir; - - if ((tif->tif_flags & TIFF_NOREADRAW) == 0) - { - uint64_t bytecount = TIFFGetStrileByteCount(tif, tile); - if (bytecount == 0 || bytecount > (uint64_t)TIFF_INT64_MAX) - { - TIFFErrorExtR(tif, module, - "%" PRIu64 ": Invalid tile byte count, tile %" PRIu32, - bytecount, tile); - return (0); - } - - /* 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) - { - /* 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) - { - 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); - bytecount = newbytecount; - } - } - - if (isMapped(tif)) - { - /* - * We must check for overflow, potentially causing - * an OOB read. Instead of simple - * - * TIFFGetStrileOffset(tif, tile)+bytecount > tif->tif_size - * - * comparison (which can overflow) we do the following - * two comparisons: - */ - if (bytecount > (uint64_t)tif->tif_size || - TIFFGetStrileOffset(tif, tile) > - (uint64_t)tif->tif_size - bytecount) - { - tif->tif_curtile = NOTILE; - return (0); - } - } - - if (isMapped(tif) && (isFillOrder(tif, td->td_fillorder) || - (tif->tif_flags & TIFF_NOBITREV))) - { - /* - * The image is mapped into memory and we either don't - * need to flip bits or the compression routine is - * going to handle this operation itself. In this - * case, avoid copying the raw data and instead just - * reference the data from the memory mapped file - * image. This assumes that the decompression - * routines do not modify the contents of the raw data - * buffer (if they try to, the application will get a - * fault since the file is mapped read-only). - */ - if ((tif->tif_flags & TIFF_MYBUFFER) && tif->tif_rawdata) - { - _TIFFfreeExt(tif, tif->tif_rawdata); - tif->tif_rawdata = NULL; - tif->tif_rawdatasize = 0; - } - tif->tif_flags &= ~TIFF_MYBUFFER; - - tif->tif_rawdatasize = (tmsize_t)bytecount; - tif->tif_rawdata = - tif->tif_base + (tmsize_t)TIFFGetStrileOffset(tif, tile); - tif->tif_rawdataoff = 0; - tif->tif_rawdataloaded = (tmsize_t)bytecount; - tif->tif_flags |= TIFF_BUFFERMMAP; - } - else - { - /* - * Expand raw data buffer, if needed, to hold data - * tile coming from file (perhaps should set upper - * bound on the size of a buffer we'll use?). - */ - tmsize_t bytecountm; - bytecountm = (tmsize_t)bytecount; - if ((uint64_t)bytecountm != bytecount) - { - TIFFErrorExtR(tif, module, "Integer overflow"); - return (0); - } - if (bytecountm > tif->tif_rawdatasize) - { - tif->tif_curtile = NOTILE; - if ((tif->tif_flags & TIFF_MYBUFFER) == 0) - { - TIFFErrorExtR(tif, module, - "Data buffer too small to hold tile %" PRIu32, - tile); - return (0); - } - } - if (tif->tif_flags & TIFF_BUFFERMMAP) - { - tif->tif_curtile = NOTILE; - tif->tif_rawdata = NULL; - tif->tif_rawdatasize = 0; - tif->tif_flags &= ~TIFF_BUFFERMMAP; - } - - if (isMapped(tif)) - { - if (bytecountm > tif->tif_rawdatasize && - !TIFFReadBufferSetup(tif, 0, bytecountm)) - { - return (0); - } - if (TIFFReadRawTile1(tif, tile, tif->tif_rawdata, bytecountm, - module) != bytecountm) - { - return (0); - } - } - else - { - if (TIFFReadRawStripOrTile2(tif, tile, 0, bytecountm, module) != - bytecountm) - { - return (0); - } - } - - tif->tif_rawdataoff = 0; - tif->tif_rawdataloaded = bytecountm; - - if (tif->tif_rawdata != NULL && - !isFillOrder(tif, td->td_fillorder) && - (tif->tif_flags & TIFF_NOBITREV) == 0) - TIFFReverseBits(tif->tif_rawdata, tif->tif_rawdataloaded); - } - } - return (TIFFStartTile(tif, tile)); -} - -/* - * Setup the raw data buffer in preparation for - * reading a strip of raw data. If the buffer - * is specified as zero, then a buffer of appropriate - * size is allocated by the library. Otherwise, - * the client must guarantee that the buffer is - * large enough to hold any individual strip of - * raw data. - */ -int TIFFReadBufferSetup(TIFF *tif, void *bp, tmsize_t size) -{ - static const char module[] = "TIFFReadBufferSetup"; - - assert((tif->tif_flags & TIFF_NOREADRAW) == 0); - tif->tif_flags &= ~TIFF_BUFFERMMAP; - - if (tif->tif_rawdata) - { - if (tif->tif_flags & TIFF_MYBUFFER) - _TIFFfreeExt(tif, tif->tif_rawdata); - tif->tif_rawdata = NULL; - tif->tif_rawdatasize = 0; - } - if (bp) - { - tif->tif_rawdatasize = size; - tif->tif_rawdata = (uint8_t *)bp; - tif->tif_flags &= ~TIFF_MYBUFFER; - } - else - { - tif->tif_rawdatasize = (tmsize_t)TIFFroundup_64((uint64_t)size, 1024); - if (tif->tif_rawdatasize == 0) - { - TIFFErrorExtR(tif, module, "Invalid buffer size"); - return (0); - } - /* Initialize to zero to avoid uninitialized buffers in case of */ - /* short reads (http://bugzilla.maptools.org/show_bug.cgi?id=2651) */ - tif->tif_rawdata = - (uint8_t *)_TIFFcallocExt(tif, 1, tif->tif_rawdatasize); - tif->tif_flags |= TIFF_MYBUFFER; - } - if (tif->tif_rawdata == NULL) - { - TIFFErrorExtR(tif, module, - "No space for data buffer at scanline %" PRIu32, - tif->tif_row); - tif->tif_rawdatasize = 0; - return (0); - } - return (1); -} - -/* - * Set state to appear as if a - * strip has just been read in. - */ -static int TIFFStartStrip(TIFF *tif, uint32_t strip) -{ - TIFFDirectory *td = &tif->tif_dir; - - if ((tif->tif_flags & TIFF_CODERSETUP) == 0) - { - if (!(*tif->tif_setupdecode)(tif)) - return (0); - tif->tif_flags |= TIFF_CODERSETUP; - } - tif->tif_curstrip = strip; - tif->tif_row = (strip % td->td_stripsperimage) * td->td_rowsperstrip; - tif->tif_flags &= ~TIFF_BUF4WRITE; - - if (tif->tif_flags & TIFF_NOREADRAW) - { - tif->tif_rawcp = NULL; - tif->tif_rawcc = 0; - } - else - { - tif->tif_rawcp = tif->tif_rawdata; - if (tif->tif_rawdataloaded > 0) - tif->tif_rawcc = tif->tif_rawdataloaded; - else - tif->tif_rawcc = (tmsize_t)TIFFGetStrileByteCount(tif, strip); - } - if ((*tif->tif_predecode)(tif, (uint16_t)(strip / td->td_stripsperimage)) == - 0) - { - /* Needed for example for scanline access, if tif_predecode */ - /* fails, and we try to read the same strip again. Without invalidating - */ - /* tif_curstrip, we'd call tif_decoderow() on a possibly invalid */ - /* codec state. */ - tif->tif_curstrip = NOSTRIP; - return 0; - } - return 1; -} - -/* - * Set state to appear as if a - * tile has just been read in. - */ -static int TIFFStartTile(TIFF *tif, uint32_t tile) -{ - static const char module[] = "TIFFStartTile"; - TIFFDirectory *td = &tif->tif_dir; - uint32_t howmany32; - - if ((tif->tif_flags & TIFF_CODERSETUP) == 0) - { - if (!(*tif->tif_setupdecode)(tif)) - return (0); - tif->tif_flags |= TIFF_CODERSETUP; - } - tif->tif_curtile = tile; - howmany32 = TIFFhowmany_32(td->td_imagewidth, td->td_tilewidth); - if (howmany32 == 0) - { - TIFFErrorExtR(tif, module, "Zero tiles"); - return 0; - } - tif->tif_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_flags &= ~TIFF_BUF4WRITE; - if (tif->tif_flags & TIFF_NOREADRAW) - { - tif->tif_rawcp = NULL; - tif->tif_rawcc = 0; - } - else - { - tif->tif_rawcp = tif->tif_rawdata; - if (tif->tif_rawdataloaded > 0) - tif->tif_rawcc = tif->tif_rawdataloaded; - else - tif->tif_rawcc = (tmsize_t)TIFFGetStrileByteCount(tif, tile); - } - return ( - (*tif->tif_predecode)(tif, (uint16_t)(tile / td->td_stripsperimage))); -} - -static int TIFFCheckRead(TIFF *tif, int tiles) -{ - if (tif->tif_mode == O_WRONLY) - { - TIFFErrorExtR(tif, tif->tif_name, "File not open for reading"); - return (0); - } - if (tiles ^ isTiled(tif)) - { - TIFFErrorExtR(tif, tif->tif_name, - tiles ? "Can not read tiles from a striped image" - : "Can not read scanlines from a tiled image"); - return (0); - } - return (1); -} - -/* Use the provided input buffer (inbuf, insize) and decompress it into - * (outbuf, outsize). - * This function replaces the use of - * TIFFReadEncodedStrip()/TIFFReadEncodedTile() when the user can provide the - * buffer for the input data, for example when he wants to avoid libtiff to read - * the strile offset/count values from the [Strip|Tile][Offsets/ByteCounts] - * array. inbuf content must be writable (if bit reversal is needed) Returns 1 - * in case of success, 0 otherwise. - */ -int TIFFReadFromUserBuffer(TIFF *tif, uint32_t strile, void *inbuf, - tmsize_t insize, void *outbuf, tmsize_t outsize) -{ - static const char module[] = "TIFFReadFromUserBuffer"; - TIFFDirectory *td = &tif->tif_dir; - int ret = 1; - uint32_t old_tif_flags = tif->tif_flags; - tmsize_t old_rawdatasize = tif->tif_rawdatasize; - void *old_rawdata = tif->tif_rawdata; - - if (tif->tif_mode == O_WRONLY) - { - TIFFErrorExtR(tif, tif->tif_name, "File not open for reading"); - return 0; - } - if (tif->tif_flags & TIFF_NOREADRAW) - { - TIFFErrorExtR(tif, module, - "Compression scheme does not support access to raw " - "uncompressed data"); - return 0; - } - - tif->tif_flags &= ~TIFF_MYBUFFER; - tif->tif_flags |= TIFF_BUFFERMMAP; - tif->tif_rawdatasize = insize; - tif->tif_rawdata = inbuf; - tif->tif_rawdataoff = 0; - tif->tif_rawdataloaded = insize; - - if (!isFillOrder(tif, td->td_fillorder) && - (tif->tif_flags & TIFF_NOBITREV) == 0) - { - TIFFReverseBits(inbuf, insize); - } - - if (TIFFIsTiled(tif)) - { - if (!TIFFStartTile(tif, strile) || - !(*tif->tif_decodetile)(tif, (uint8_t *)outbuf, outsize, - (uint16_t)(strile / td->td_stripsperimage))) - { - ret = 0; - } - } - else - { - uint32_t rowsperstrip = td->td_rowsperstrip; - uint32_t stripsperplane; - if (rowsperstrip > td->td_imagelength) - rowsperstrip = td->td_imagelength; - stripsperplane = - TIFFhowmany_32_maxuint_compat(td->td_imagelength, rowsperstrip); - if (!TIFFStartStrip(tif, strile) || - !(*tif->tif_decodestrip)(tif, (uint8_t *)outbuf, outsize, - (uint16_t)(strile / stripsperplane))) - { - ret = 0; - } - } - if (ret) - { - (*tif->tif_postdecode)(tif, (uint8_t *)outbuf, outsize); - } - - if (!isFillOrder(tif, td->td_fillorder) && - (tif->tif_flags & TIFF_NOBITREV) == 0) - { - TIFFReverseBits(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_rawdataoff = 0; - tif->tif_rawdataloaded = 0; - - return ret; -} - -void _TIFFNoPostDecode(TIFF *tif, uint8_t *buf, tmsize_t cc) -{ - (void)tif; - (void)buf; - (void)cc; -} - -void _TIFFSwab16BitData(TIFF *tif, uint8_t *buf, tmsize_t cc) -{ - (void)tif; - assert((cc & 1) == 0); - TIFFSwabArrayOfShort((uint16_t *)buf, cc / 2); -} - -void _TIFFSwab24BitData(TIFF *tif, uint8_t *buf, tmsize_t cc) -{ - (void)tif; - assert((cc % 3) == 0); - TIFFSwabArrayOfTriples((uint8_t *)buf, cc / 3); -} - -void _TIFFSwab32BitData(TIFF *tif, uint8_t *buf, tmsize_t cc) -{ - (void)tif; - assert((cc & 3) == 0); - TIFFSwabArrayOfLong((uint32_t *)buf, cc / 4); -} - -void _TIFFSwab64BitData(TIFF *tif, uint8_t *buf, tmsize_t cc) -{ - (void)tif; - assert((cc & 7) == 0); - TIFFSwabArrayOfDouble((double *)buf, cc / 8); -} diff --git a/src/3rd/tiff/strip.c b/src/3rd/tiff/strip.c deleted file mode 100644 index 820a2544c38..00000000000 --- a/src/3rd/tiff/strip.c +++ /dev/null @@ -1,350 +0,0 @@ -/* - * Copyright (c) 1991-1997 Sam Leffler - * Copyright (c) 1991-1997 Silicon Graphics, Inc. - * - * Permission to use, copy, modify, distribute, and sell this software and - * its documentation for any purpose is hereby granted without fee, provided - * that (i) the above copyright notices and this permission notice appear in - * all copies of the software and related documentation, and (ii) the names of - * Sam Leffler and Silicon Graphics may not be used in any advertising or - * publicity relating to the software without the specific, prior written - * permission of Sam Leffler and Silicon Graphics. - * - * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, - * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY - * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. - * - * IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR - * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, - * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, - * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF - * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE - * OF THIS SOFTWARE. - */ - -/* - * TIFF Library. - * - * Strip-organized Image Support Routines. - */ -#include "tiffiop.h" - -/* - * Compute which strip a (row,sample) value is in. - */ -uint32_t TIFFComputeStrip(TIFF *tif, uint32_t row, uint16_t sample) -{ - static const char module[] = "TIFFComputeStrip"; - TIFFDirectory *td = &tif->tif_dir; - uint32_t strip; - - strip = row / td->td_rowsperstrip; - if (td->td_planarconfig == PLANARCONFIG_SEPARATE) - { - if (sample >= td->td_samplesperpixel) - { - TIFFErrorExtR(tif, module, "%lu: Sample out of range, max %lu", - (unsigned long)sample, - (unsigned long)td->td_samplesperpixel); - return (0); - } - strip += (uint32_t)sample * td->td_stripsperimage; - } - return (strip); -} - -/* - * Compute how many strips are in an image. - */ -uint32_t TIFFNumberOfStrips(TIFF *tif) -{ - TIFFDirectory *td = &tif->tif_dir; - uint32_t nstrips; - - nstrips = (td->td_rowsperstrip == (uint32_t)-1 - ? 1 - : TIFFhowmany_32(td->td_imagelength, td->td_rowsperstrip)); - if (td->td_planarconfig == PLANARCONFIG_SEPARATE) - nstrips = - _TIFFMultiply32(tif, nstrips, (uint32_t)td->td_samplesperpixel, - "TIFFNumberOfStrips"); - return (nstrips); -} - -/* - * Compute the # bytes in a variable height, row-aligned strip. - */ -uint64_t TIFFVStripSize64(TIFF *tif, uint32_t nrows) -{ - static const char module[] = "TIFFVStripSize64"; - TIFFDirectory *td = &tif->tif_dir; - if (nrows == (uint32_t)(-1)) - nrows = td->td_imagelength; - if ((td->td_planarconfig == PLANARCONFIG_CONTIG) && - (td->td_photometric == PHOTOMETRIC_YCBCR) && (!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; - if (td->td_samplesperpixel != 3) - { - TIFFErrorExtR(tif, module, "Invalid td_samplesperpixel value"); - return 0; - } - 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_imagewidth, 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, TIFFScanlineSize64(tif), module)); -} -tmsize_t TIFFVStripSize(TIFF *tif, uint32_t nrows) -{ - static const char module[] = "TIFFVStripSize"; - uint64_t m; - m = TIFFVStripSize64(tif, nrows); - return _TIFFCastUInt64ToSSize(tif, m, module); -} - -/* - * Compute the # bytes in a raw strip. - */ -uint64_t TIFFRawStripSize64(TIFF *tif, uint32_t strip) -{ - static const char module[] = "TIFFRawStripSize64"; - uint64_t bytecount = TIFFGetStrileByteCount(tif, strip); - - if (bytecount == 0) - { - TIFFErrorExtR(tif, module, - "%" PRIu64 ": Invalid strip byte count, strip %lu", - (uint64_t)bytecount, (unsigned long)strip); - bytecount = (uint64_t)-1; - } - - return bytecount; -} -tmsize_t TIFFRawStripSize(TIFF *tif, uint32_t strip) -{ - static const char module[] = "TIFFRawStripSize"; - uint64_t m; - tmsize_t n; - m = TIFFRawStripSize64(tif, strip); - if (m == (uint64_t)(-1)) - n = (tmsize_t)(-1); - else - { - n = (tmsize_t)m; - if ((uint64_t)n != m) - { - TIFFErrorExtR(tif, module, "Integer overflow"); - n = 0; - } - } - return (n); -} - -/* - * Compute the # bytes in a (row-aligned) strip. - * - * Note that if RowsPerStrip is larger than the - * recorded ImageLength, then the strip size is - * truncated to reflect the actual space required - * to hold the strip. - */ -uint64_t TIFFStripSize64(TIFF *tif) -{ - TIFFDirectory *td = &tif->tif_dir; - uint32_t rps = td->td_rowsperstrip; - if (rps > td->td_imagelength) - rps = td->td_imagelength; - return (TIFFVStripSize64(tif, rps)); -} -tmsize_t TIFFStripSize(TIFF *tif) -{ - static const char module[] = "TIFFStripSize"; - uint64_t m; - m = TIFFStripSize64(tif); - return _TIFFCastUInt64ToSSize(tif, m, module); -} - -/* - * Compute a default strip size based on the image - * characteristics and a requested value. If the - * request is <1 then we choose a strip size according - * to certain heuristics. - */ -uint32_t TIFFDefaultStripSize(TIFF *tif, uint32_t request) -{ - return (*tif->tif_defstripsize)(tif, request); -} - -uint32_t _TIFFDefaultStripSize(TIFF *tif, uint32_t s) -{ - if ((int32_t)s < 1) - { - /* - * If RowsPerStrip is unspecified, try to break the - * image up into strips that are approximately - * STRIP_SIZE_DEFAULT bytes long. - */ - uint64_t scanlinesize; - uint64_t rows; - scanlinesize = TIFFScanlineSize64(tif); - if (scanlinesize == 0) - scanlinesize = 1; - rows = (uint64_t)STRIP_SIZE_DEFAULT / scanlinesize; - if (rows == 0) - rows = 1; - else if (rows > 0xFFFFFFFF) - rows = 0xFFFFFFFF; - s = (uint32_t)rows; - } - return (s); -} - -/* - * Return the number of bytes to read/write in a call to - * one of the scanline-oriented i/o routines. Note that - * this number may be 1/samples-per-pixel if data is - * stored as separate planes. - * The ScanlineSize in case of YCbCrSubsampling is defined as the - * strip size divided by the strip height, i.e. the size of a pack of vertical - * subsampling lines divided by vertical subsampling. It should thus make - * sense when multiplied by a multiple of vertical subsampling. - */ -uint64_t TIFFScanlineSize64(TIFF *tif) -{ - static const char module[] = "TIFFScanlineSize64"; - TIFFDirectory *td = &tif->tif_dir; - uint64_t scanline_size; - if (td->td_planarconfig == PLANARCONFIG_CONTIG) - { - if ((td->td_photometric == PHOTOMETRIC_YCBCR) && - (td->td_samplesperpixel == 3) && (!isUpSampled(tif))) - { - uint16_t ycbcrsubsampling[2]; - uint16_t samplingblock_samples; - uint32_t samplingblocks_hor; - uint64_t samplingrow_samples; - uint64_t samplingrow_size; - if (td->td_samplesperpixel != 3) - { - TIFFErrorExtR(tif, module, "Invalid td_samplesperpixel value"); - return 0; - } - 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"); - return 0; - } - samplingblock_samples = - ycbcrsubsampling[0] * ycbcrsubsampling[1] + 2; - samplingblocks_hor = - TIFFhowmany_32(td->td_imagewidth, ycbcrsubsampling[0]); - samplingrow_samples = _TIFFMultiply64( - tif, samplingblocks_hor, samplingblock_samples, module); - samplingrow_size = - TIFFhowmany_64(_TIFFMultiply64(tif, samplingrow_samples, - td->td_bitspersample, module), - 8); - scanline_size = (samplingrow_size / ycbcrsubsampling[1]); - } - else - { - uint64_t scanline_samples; - scanline_samples = _TIFFMultiply64(tif, td->td_imagewidth, - td->td_samplesperpixel, module); - scanline_size = - TIFFhowmany_64(_TIFFMultiply64(tif, scanline_samples, - td->td_bitspersample, module), - 8); - } - } - else - { - scanline_size = - TIFFhowmany_64(_TIFFMultiply64(tif, td->td_imagewidth, - td->td_bitspersample, module), - 8); - } - if (scanline_size == 0) - { - TIFFErrorExtR(tif, module, "Computed scanline size is zero"); - return 0; - } - return (scanline_size); -} -tmsize_t TIFFScanlineSize(TIFF *tif) -{ - static const char module[] = "TIFFScanlineSize"; - uint64_t m; - m = TIFFScanlineSize64(tif); - return _TIFFCastUInt64ToSSize(tif, m, module); -} - -/* - * Return the number of bytes required to store a complete - * decoded and packed raster scanline (as opposed to the - * I/O size returned by TIFFScanlineSize which may be less - * if data is store as separate planes). - */ -uint64_t TIFFRasterScanlineSize64(TIFF *tif) -{ - static const char module[] = "TIFFRasterScanlineSize64"; - TIFFDirectory *td = &tif->tif_dir; - uint64_t scanline; - - scanline = - _TIFFMultiply64(tif, td->td_bitspersample, td->td_imagewidth, module); - if (td->td_planarconfig == PLANARCONFIG_CONTIG) - { - scanline = - _TIFFMultiply64(tif, scanline, td->td_samplesperpixel, module); - return (TIFFhowmany8_64(scanline)); - } - else - return (_TIFFMultiply64(tif, TIFFhowmany8_64(scanline), - td->td_samplesperpixel, module)); -} -tmsize_t TIFFRasterScanlineSize(TIFF *tif) -{ - static const char module[] = "TIFFRasterScanlineSize"; - uint64_t m; - m = TIFFRasterScanlineSize64(tif); - return _TIFFCastUInt64ToSSize(tif, m, module); -} diff --git a/src/3rd/tiff/swab.c b/src/3rd/tiff/swab.c deleted file mode 100644 index 827b025ce7a..00000000000 --- a/src/3rd/tiff/swab.c +++ /dev/null @@ -1,329 +0,0 @@ -/* - * Copyright (c) 1988-1997 Sam Leffler - * Copyright (c) 1991-1997 Silicon Graphics, Inc. - * - * Permission to use, copy, modify, distribute, and sell this software and - * its documentation for any purpose is hereby granted without fee, provided - * that (i) the above copyright notices and this permission notice appear in - * all copies of the software and related documentation, and (ii) the names of - * Sam Leffler and Silicon Graphics may not be used in any advertising or - * publicity relating to the software without the specific, prior written - * permission of Sam Leffler and Silicon Graphics. - * - * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, - * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY - * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. - * - * IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR - * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, - * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, - * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF - * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE - * OF THIS SOFTWARE. - */ - -/* - * TIFF Library Bit & Byte Swapping Support. - * - * XXX We assume short = 16-bits and long = 32-bits XXX - */ -#include "tiffiop.h" - -#if defined(DISABLE_CHECK_TIFFSWABMACROS) || !defined(TIFFSwabShort) -void TIFFSwabShort(uint16_t *wp) -{ - register unsigned char *cp = (unsigned char *)wp; - unsigned char t; - assert(sizeof(uint16_t) == 2); - t = cp[1]; - cp[1] = cp[0]; - cp[0] = t; -} -#endif - -#if defined(DISABLE_CHECK_TIFFSWABMACROS) || !defined(TIFFSwabLong) -void TIFFSwabLong(uint32_t *lp) -{ - register unsigned char *cp = (unsigned char *)lp; - unsigned char t; - assert(sizeof(uint32_t) == 4); - t = cp[3]; - cp[3] = cp[0]; - cp[0] = t; - t = cp[2]; - cp[2] = cp[1]; - cp[1] = t; -} -#endif - -#if defined(DISABLE_CHECK_TIFFSWABMACROS) || !defined(TIFFSwabLong8) -void TIFFSwabLong8(uint64_t *lp) -{ - register unsigned char *cp = (unsigned char *)lp; - unsigned char t; - assert(sizeof(uint64_t) == 8); - t = cp[7]; - cp[7] = cp[0]; - cp[0] = t; - t = cp[6]; - cp[6] = cp[1]; - cp[1] = t; - t = cp[5]; - cp[5] = cp[2]; - cp[2] = t; - t = cp[4]; - cp[4] = cp[3]; - cp[3] = t; -} -#endif - -#if defined(DISABLE_CHECK_TIFFSWABMACROS) || !defined(TIFFSwabArrayOfShort) -void TIFFSwabArrayOfShort(register uint16_t *wp, tmsize_t n) -{ - register unsigned char *cp; - register unsigned char t; - assert(sizeof(uint16_t) == 2); - /* XXX unroll loop some */ - while (n-- > 0) - { - cp = (unsigned char *)wp; - t = cp[1]; - cp[1] = cp[0]; - cp[0] = t; - wp++; - } -} -#endif - -#if defined(DISABLE_CHECK_TIFFSWABMACROS) || !defined(TIFFSwabArrayOfTriples) -void TIFFSwabArrayOfTriples(register uint8_t *tp, tmsize_t n) -{ - unsigned char *cp; - unsigned char t; - - /* XXX unroll loop some */ - while (n-- > 0) - { - cp = (unsigned char *)tp; - t = cp[2]; - cp[2] = cp[0]; - cp[0] = t; - tp += 3; - } -} -#endif - -#if defined(DISABLE_CHECK_TIFFSWABMACROS) || !defined(TIFFSwabArrayOfLong) -void TIFFSwabArrayOfLong(register uint32_t *lp, tmsize_t n) -{ - register unsigned char *cp; - register unsigned char t; - assert(sizeof(uint32_t) == 4); - /* XXX unroll loop some */ - while (n-- > 0) - { - cp = (unsigned char *)lp; - t = cp[3]; - cp[3] = cp[0]; - cp[0] = t; - t = cp[2]; - cp[2] = cp[1]; - cp[1] = t; - lp++; - } -} -#endif - -#if defined(DISABLE_CHECK_TIFFSWABMACROS) || !defined(TIFFSwabArrayOfLong8) -void TIFFSwabArrayOfLong8(register uint64_t *lp, tmsize_t n) -{ - register unsigned char *cp; - register unsigned char t; - assert(sizeof(uint64_t) == 8); - /* XXX unroll loop some */ - while (n-- > 0) - { - cp = (unsigned char *)lp; - t = cp[7]; - cp[7] = cp[0]; - cp[0] = t; - t = cp[6]; - cp[6] = cp[1]; - cp[1] = t; - t = cp[5]; - cp[5] = cp[2]; - cp[2] = t; - t = cp[4]; - cp[4] = cp[3]; - cp[3] = t; - lp++; - } -} -#endif - -#if defined(DISABLE_CHECK_TIFFSWABMACROS) || !defined(TIFFSwabFloat) -void TIFFSwabFloat(float *fp) -{ - register unsigned char *cp = (unsigned char *)fp; - unsigned char t; - assert(sizeof(float) == 4); - t = cp[3]; - cp[3] = cp[0]; - cp[0] = t; - t = cp[2]; - cp[2] = cp[1]; - cp[1] = t; -} -#endif - -#if defined(DISABLE_CHECK_TIFFSWABMACROS) || !defined(TIFFSwabArrayOfFloat) -void TIFFSwabArrayOfFloat(register float *fp, tmsize_t n) -{ - register unsigned char *cp; - register unsigned char t; - assert(sizeof(float) == 4); - /* XXX unroll loop some */ - while (n-- > 0) - { - cp = (unsigned char *)fp; - t = cp[3]; - cp[3] = cp[0]; - cp[0] = t; - t = cp[2]; - cp[2] = cp[1]; - cp[1] = t; - fp++; - } -} -#endif - -#if defined(DISABLE_CHECK_TIFFSWABMACROS) || !defined(TIFFSwabDouble) -void TIFFSwabDouble(double *dp) -{ - register unsigned char *cp = (unsigned char *)dp; - unsigned char t; - assert(sizeof(double) == 8); - t = cp[7]; - cp[7] = cp[0]; - cp[0] = t; - t = cp[6]; - cp[6] = cp[1]; - cp[1] = t; - t = cp[5]; - cp[5] = cp[2]; - cp[2] = t; - t = cp[4]; - cp[4] = cp[3]; - cp[3] = t; -} -#endif - -#if defined(DISABLE_CHECK_TIFFSWABMACROS) || !defined(TIFFSwabArrayOfDouble) -void TIFFSwabArrayOfDouble(double *dp, tmsize_t n) -{ - register unsigned char *cp; - register unsigned char t; - assert(sizeof(double) == 8); - /* XXX unroll loop some */ - while (n-- > 0) - { - cp = (unsigned char *)dp; - t = cp[7]; - cp[7] = cp[0]; - cp[0] = t; - t = cp[6]; - cp[6] = cp[1]; - cp[1] = t; - t = cp[5]; - cp[5] = cp[2]; - cp[2] = t; - t = cp[4]; - cp[4] = cp[3]; - cp[3] = t; - dp++; - } -} -#endif - -/* - * Bit reversal tables. TIFFBitRevTable[] gives - * the bit reversed value of . Used in various - * places in the library when the FillOrder requires - * bit reversal of byte values (e.g. CCITT Fax 3 - * encoding/decoding). TIFFNoBitRevTable is provided - * for algorithms that want an equivalent table that - * do not reverse bit values. - */ -static const unsigned char TIFFBitRevTable[256] = { - 0x00, 0x80, 0x40, 0xc0, 0x20, 0xa0, 0x60, 0xe0, 0x10, 0x90, 0x50, 0xd0, - 0x30, 0xb0, 0x70, 0xf0, 0x08, 0x88, 0x48, 0xc8, 0x28, 0xa8, 0x68, 0xe8, - 0x18, 0x98, 0x58, 0xd8, 0x38, 0xb8, 0x78, 0xf8, 0x04, 0x84, 0x44, 0xc4, - 0x24, 0xa4, 0x64, 0xe4, 0x14, 0x94, 0x54, 0xd4, 0x34, 0xb4, 0x74, 0xf4, - 0x0c, 0x8c, 0x4c, 0xcc, 0x2c, 0xac, 0x6c, 0xec, 0x1c, 0x9c, 0x5c, 0xdc, - 0x3c, 0xbc, 0x7c, 0xfc, 0x02, 0x82, 0x42, 0xc2, 0x22, 0xa2, 0x62, 0xe2, - 0x12, 0x92, 0x52, 0xd2, 0x32, 0xb2, 0x72, 0xf2, 0x0a, 0x8a, 0x4a, 0xca, - 0x2a, 0xaa, 0x6a, 0xea, 0x1a, 0x9a, 0x5a, 0xda, 0x3a, 0xba, 0x7a, 0xfa, - 0x06, 0x86, 0x46, 0xc6, 0x26, 0xa6, 0x66, 0xe6, 0x16, 0x96, 0x56, 0xd6, - 0x36, 0xb6, 0x76, 0xf6, 0x0e, 0x8e, 0x4e, 0xce, 0x2e, 0xae, 0x6e, 0xee, - 0x1e, 0x9e, 0x5e, 0xde, 0x3e, 0xbe, 0x7e, 0xfe, 0x01, 0x81, 0x41, 0xc1, - 0x21, 0xa1, 0x61, 0xe1, 0x11, 0x91, 0x51, 0xd1, 0x31, 0xb1, 0x71, 0xf1, - 0x09, 0x89, 0x49, 0xc9, 0x29, 0xa9, 0x69, 0xe9, 0x19, 0x99, 0x59, 0xd9, - 0x39, 0xb9, 0x79, 0xf9, 0x05, 0x85, 0x45, 0xc5, 0x25, 0xa5, 0x65, 0xe5, - 0x15, 0x95, 0x55, 0xd5, 0x35, 0xb5, 0x75, 0xf5, 0x0d, 0x8d, 0x4d, 0xcd, - 0x2d, 0xad, 0x6d, 0xed, 0x1d, 0x9d, 0x5d, 0xdd, 0x3d, 0xbd, 0x7d, 0xfd, - 0x03, 0x83, 0x43, 0xc3, 0x23, 0xa3, 0x63, 0xe3, 0x13, 0x93, 0x53, 0xd3, - 0x33, 0xb3, 0x73, 0xf3, 0x0b, 0x8b, 0x4b, 0xcb, 0x2b, 0xab, 0x6b, 0xeb, - 0x1b, 0x9b, 0x5b, 0xdb, 0x3b, 0xbb, 0x7b, 0xfb, 0x07, 0x87, 0x47, 0xc7, - 0x27, 0xa7, 0x67, 0xe7, 0x17, 0x97, 0x57, 0xd7, 0x37, 0xb7, 0x77, 0xf7, - 0x0f, 0x8f, 0x4f, 0xcf, 0x2f, 0xaf, 0x6f, 0xef, 0x1f, 0x9f, 0x5f, 0xdf, - 0x3f, 0xbf, 0x7f, 0xff}; -static const unsigned char TIFFNoBitRevTable[256] = { - 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, - 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, - 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, 0x20, 0x21, 0x22, 0x23, - 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, - 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, 0x3b, - 0x3c, 0x3d, 0x3e, 0x3f, 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, - 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f, 0x50, 0x51, 0x52, 0x53, - 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f, - 0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a, 0x6b, - 0x6c, 0x6d, 0x6e, 0x6f, 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, - 0x78, 0x79, 0x7a, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f, 0x80, 0x81, 0x82, 0x83, - 0x84, 0x85, 0x86, 0x87, 0x88, 0x89, 0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f, - 0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x99, 0x9a, 0x9b, - 0x9c, 0x9d, 0x9e, 0x9f, 0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7, - 0xa8, 0xa9, 0xaa, 0xab, 0xac, 0xad, 0xae, 0xaf, 0xb0, 0xb1, 0xb2, 0xb3, - 0xb4, 0xb5, 0xb6, 0xb7, 0xb8, 0xb9, 0xba, 0xbb, 0xbc, 0xbd, 0xbe, 0xbf, - 0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7, 0xc8, 0xc9, 0xca, 0xcb, - 0xcc, 0xcd, 0xce, 0xcf, 0xd0, 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, - 0xd8, 0xd9, 0xda, 0xdb, 0xdc, 0xdd, 0xde, 0xdf, 0xe0, 0xe1, 0xe2, 0xe3, - 0xe4, 0xe5, 0xe6, 0xe7, 0xe8, 0xe9, 0xea, 0xeb, 0xec, 0xed, 0xee, 0xef, - 0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8, 0xf9, 0xfa, 0xfb, - 0xfc, 0xfd, 0xfe, 0xff, -}; - -const unsigned char *TIFFGetBitRevTable(int reversed) -{ - return (reversed ? TIFFBitRevTable : TIFFNoBitRevTable); -} - -void TIFFReverseBits(uint8_t *cp, tmsize_t n) -{ - for (; n > 8; n -= 8) - { - cp[0] = TIFFBitRevTable[cp[0]]; - cp[1] = TIFFBitRevTable[cp[1]]; - cp[2] = TIFFBitRevTable[cp[2]]; - cp[3] = TIFFBitRevTable[cp[3]]; - cp[4] = TIFFBitRevTable[cp[4]]; - cp[5] = TIFFBitRevTable[cp[5]]; - cp[6] = TIFFBitRevTable[cp[6]]; - cp[7] = TIFFBitRevTable[cp[7]]; - cp += 8; - } - while (n-- > 0) - { - *cp = TIFFBitRevTable[*cp]; - cp++; - } -} diff --git a/src/3rd/tiff/t4.h b/src/3rd/tiff/t4.h deleted file mode 100644 index f933d4a336c..00000000000 --- a/src/3rd/tiff/t4.h +++ /dev/null @@ -1,284 +0,0 @@ -/* - * Copyright (c) 1988-1997 Sam Leffler - * Copyright (c) 1991-1997 Silicon Graphics, Inc. - * - * Permission to use, copy, modify, distribute, and sell this software and - * its documentation for any purpose is hereby granted without fee, provided - * that (i) the above copyright notices and this permission notice appear in - * all copies of the software and related documentation, and (ii) the names of - * Sam Leffler and Silicon Graphics may not be used in any advertising or - * publicity relating to the software without the specific, prior written - * permission of Sam Leffler and Silicon Graphics. - * - * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, - * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY - * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. - * - * IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR - * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, - * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, - * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF - * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE - * OF THIS SOFTWARE. - */ - -#ifndef _T4_ -#define _T4_ -/* - * CCITT T.4 1D Huffman runlength codes and - * related definitions. Given the small sizes - * of these tables it does not seem - * worthwhile to make code & length 8 bits. - */ -typedef struct tableentry -{ - unsigned short length; /* bit length of g3 code */ - unsigned short code; /* g3 code */ - short runlen; /* run length in bits */ -} tableentry; - -#define EOL 0x001 /* EOL code value - 0000 0000 0000 1 */ - -/* status values returned instead of a run length */ -#define G3CODE_EOL -1 /* NB: ACT_EOL - ACT_WRUNT */ -#define G3CODE_INVALID -2 /* NB: ACT_INVALID - ACT_WRUNT */ -#define G3CODE_EOF -3 /* end of input data */ -#define G3CODE_INCOMP -4 /* incomplete run code */ - -/* - * Note that these tables are ordered such that the - * index into the table is known to be either the - * run length, or (run length / 64) + a fixed offset. - * - * NB: The G3CODE_INVALID entries are only used - * during state generation (see mkg3states.c). - */ -#ifdef G3CODES -const tableentry TIFFFaxWhiteCodes[] = { - {8, 0x35, 0}, /* 0011 0101 */ - {6, 0x7, 1}, /* 0001 11 */ - {4, 0x7, 2}, /* 0111 */ - {4, 0x8, 3}, /* 1000 */ - {4, 0xB, 4}, /* 1011 */ - {4, 0xC, 5}, /* 1100 */ - {4, 0xE, 6}, /* 1110 */ - {4, 0xF, 7}, /* 1111 */ - {5, 0x13, 8}, /* 1001 1 */ - {5, 0x14, 9}, /* 1010 0 */ - {5, 0x7, 10}, /* 0011 1 */ - {5, 0x8, 11}, /* 0100 0 */ - {6, 0x8, 12}, /* 0010 00 */ - {6, 0x3, 13}, /* 0000 11 */ - {6, 0x34, 14}, /* 1101 00 */ - {6, 0x35, 15}, /* 1101 01 */ - {6, 0x2A, 16}, /* 1010 10 */ - {6, 0x2B, 17}, /* 1010 11 */ - {7, 0x27, 18}, /* 0100 111 */ - {7, 0xC, 19}, /* 0001 100 */ - {7, 0x8, 20}, /* 0001 000 */ - {7, 0x17, 21}, /* 0010 111 */ - {7, 0x3, 22}, /* 0000 011 */ - {7, 0x4, 23}, /* 0000 100 */ - {7, 0x28, 24}, /* 0101 000 */ - {7, 0x2B, 25}, /* 0101 011 */ - {7, 0x13, 26}, /* 0010 011 */ - {7, 0x24, 27}, /* 0100 100 */ - {7, 0x18, 28}, /* 0011 000 */ - {8, 0x2, 29}, /* 0000 0010 */ - {8, 0x3, 30}, /* 0000 0011 */ - {8, 0x1A, 31}, /* 0001 1010 */ - {8, 0x1B, 32}, /* 0001 1011 */ - {8, 0x12, 33}, /* 0001 0010 */ - {8, 0x13, 34}, /* 0001 0011 */ - {8, 0x14, 35}, /* 0001 0100 */ - {8, 0x15, 36}, /* 0001 0101 */ - {8, 0x16, 37}, /* 0001 0110 */ - {8, 0x17, 38}, /* 0001 0111 */ - {8, 0x28, 39}, /* 0010 1000 */ - {8, 0x29, 40}, /* 0010 1001 */ - {8, 0x2A, 41}, /* 0010 1010 */ - {8, 0x2B, 42}, /* 0010 1011 */ - {8, 0x2C, 43}, /* 0010 1100 */ - {8, 0x2D, 44}, /* 0010 1101 */ - {8, 0x4, 45}, /* 0000 0100 */ - {8, 0x5, 46}, /* 0000 0101 */ - {8, 0xA, 47}, /* 0000 1010 */ - {8, 0xB, 48}, /* 0000 1011 */ - {8, 0x52, 49}, /* 0101 0010 */ - {8, 0x53, 50}, /* 0101 0011 */ - {8, 0x54, 51}, /* 0101 0100 */ - {8, 0x55, 52}, /* 0101 0101 */ - {8, 0x24, 53}, /* 0010 0100 */ - {8, 0x25, 54}, /* 0010 0101 */ - {8, 0x58, 55}, /* 0101 1000 */ - {8, 0x59, 56}, /* 0101 1001 */ - {8, 0x5A, 57}, /* 0101 1010 */ - {8, 0x5B, 58}, /* 0101 1011 */ - {8, 0x4A, 59}, /* 0100 1010 */ - {8, 0x4B, 60}, /* 0100 1011 */ - {8, 0x32, 61}, /* 0011 0010 */ - {8, 0x33, 62}, /* 0011 0011 */ - {8, 0x34, 63}, /* 0011 0100 */ - {5, 0x1B, 64}, /* 1101 1 */ - {5, 0x12, 128}, /* 1001 0 */ - {6, 0x17, 192}, /* 0101 11 */ - {7, 0x37, 256}, /* 0110 111 */ - {8, 0x36, 320}, /* 0011 0110 */ - {8, 0x37, 384}, /* 0011 0111 */ - {8, 0x64, 448}, /* 0110 0100 */ - {8, 0x65, 512}, /* 0110 0101 */ - {8, 0x68, 576}, /* 0110 1000 */ - {8, 0x67, 640}, /* 0110 0111 */ - {9, 0xCC, 704}, /* 0110 0110 0 */ - {9, 0xCD, 768}, /* 0110 0110 1 */ - {9, 0xD2, 832}, /* 0110 1001 0 */ - {9, 0xD3, 896}, /* 0110 1001 1 */ - {9, 0xD4, 960}, /* 0110 1010 0 */ - {9, 0xD5, 1024}, /* 0110 1010 1 */ - {9, 0xD6, 1088}, /* 0110 1011 0 */ - {9, 0xD7, 1152}, /* 0110 1011 1 */ - {9, 0xD8, 1216}, /* 0110 1100 0 */ - {9, 0xD9, 1280}, /* 0110 1100 1 */ - {9, 0xDA, 1344}, /* 0110 1101 0 */ - {9, 0xDB, 1408}, /* 0110 1101 1 */ - {9, 0x98, 1472}, /* 0100 1100 0 */ - {9, 0x99, 1536}, /* 0100 1100 1 */ - {9, 0x9A, 1600}, /* 0100 1101 0 */ - {6, 0x18, 1664}, /* 0110 00 */ - {9, 0x9B, 1728}, /* 0100 1101 1 */ - {11, 0x8, 1792}, /* 0000 0001 000 */ - {11, 0xC, 1856}, /* 0000 0001 100 */ - {11, 0xD, 1920}, /* 0000 0001 101 */ - {12, 0x12, 1984}, /* 0000 0001 0010 */ - {12, 0x13, 2048}, /* 0000 0001 0011 */ - {12, 0x14, 2112}, /* 0000 0001 0100 */ - {12, 0x15, 2176}, /* 0000 0001 0101 */ - {12, 0x16, 2240}, /* 0000 0001 0110 */ - {12, 0x17, 2304}, /* 0000 0001 0111 */ - {12, 0x1C, 2368}, /* 0000 0001 1100 */ - {12, 0x1D, 2432}, /* 0000 0001 1101 */ - {12, 0x1E, 2496}, /* 0000 0001 1110 */ - {12, 0x1F, 2560}, /* 0000 0001 1111 */ - {12, 0x1, G3CODE_EOL}, /* 0000 0000 0001 */ - {9, 0x1, G3CODE_INVALID}, /* 0000 0000 1 */ - {10, 0x1, G3CODE_INVALID}, /* 0000 0000 01 */ - {11, 0x1, G3CODE_INVALID}, /* 0000 0000 001 */ - {12, 0x0, G3CODE_INVALID}, /* 0000 0000 0000 */ -}; - -const tableentry TIFFFaxBlackCodes[] = { - {10, 0x37, 0}, /* 0000 1101 11 */ - {3, 0x2, 1}, /* 010 */ - {2, 0x3, 2}, /* 11 */ - {2, 0x2, 3}, /* 10 */ - {3, 0x3, 4}, /* 011 */ - {4, 0x3, 5}, /* 0011 */ - {4, 0x2, 6}, /* 0010 */ - {5, 0x3, 7}, /* 0001 1 */ - {6, 0x5, 8}, /* 0001 01 */ - {6, 0x4, 9}, /* 0001 00 */ - {7, 0x4, 10}, /* 0000 100 */ - {7, 0x5, 11}, /* 0000 101 */ - {7, 0x7, 12}, /* 0000 111 */ - {8, 0x4, 13}, /* 0000 0100 */ - {8, 0x7, 14}, /* 0000 0111 */ - {9, 0x18, 15}, /* 0000 1100 0 */ - {10, 0x17, 16}, /* 0000 0101 11 */ - {10, 0x18, 17}, /* 0000 0110 00 */ - {10, 0x8, 18}, /* 0000 0010 00 */ - {11, 0x67, 19}, /* 0000 1100 111 */ - {11, 0x68, 20}, /* 0000 1101 000 */ - {11, 0x6C, 21}, /* 0000 1101 100 */ - {11, 0x37, 22}, /* 0000 0110 111 */ - {11, 0x28, 23}, /* 0000 0101 000 */ - {11, 0x17, 24}, /* 0000 0010 111 */ - {11, 0x18, 25}, /* 0000 0011 000 */ - {12, 0xCA, 26}, /* 0000 1100 1010 */ - {12, 0xCB, 27}, /* 0000 1100 1011 */ - {12, 0xCC, 28}, /* 0000 1100 1100 */ - {12, 0xCD, 29}, /* 0000 1100 1101 */ - {12, 0x68, 30}, /* 0000 0110 1000 */ - {12, 0x69, 31}, /* 0000 0110 1001 */ - {12, 0x6A, 32}, /* 0000 0110 1010 */ - {12, 0x6B, 33}, /* 0000 0110 1011 */ - {12, 0xD2, 34}, /* 0000 1101 0010 */ - {12, 0xD3, 35}, /* 0000 1101 0011 */ - {12, 0xD4, 36}, /* 0000 1101 0100 */ - {12, 0xD5, 37}, /* 0000 1101 0101 */ - {12, 0xD6, 38}, /* 0000 1101 0110 */ - {12, 0xD7, 39}, /* 0000 1101 0111 */ - {12, 0x6C, 40}, /* 0000 0110 1100 */ - {12, 0x6D, 41}, /* 0000 0110 1101 */ - {12, 0xDA, 42}, /* 0000 1101 1010 */ - {12, 0xDB, 43}, /* 0000 1101 1011 */ - {12, 0x54, 44}, /* 0000 0101 0100 */ - {12, 0x55, 45}, /* 0000 0101 0101 */ - {12, 0x56, 46}, /* 0000 0101 0110 */ - {12, 0x57, 47}, /* 0000 0101 0111 */ - {12, 0x64, 48}, /* 0000 0110 0100 */ - {12, 0x65, 49}, /* 0000 0110 0101 */ - {12, 0x52, 50}, /* 0000 0101 0010 */ - {12, 0x53, 51}, /* 0000 0101 0011 */ - {12, 0x24, 52}, /* 0000 0010 0100 */ - {12, 0x37, 53}, /* 0000 0011 0111 */ - {12, 0x38, 54}, /* 0000 0011 1000 */ - {12, 0x27, 55}, /* 0000 0010 0111 */ - {12, 0x28, 56}, /* 0000 0010 1000 */ - {12, 0x58, 57}, /* 0000 0101 1000 */ - {12, 0x59, 58}, /* 0000 0101 1001 */ - {12, 0x2B, 59}, /* 0000 0010 1011 */ - {12, 0x2C, 60}, /* 0000 0010 1100 */ - {12, 0x5A, 61}, /* 0000 0101 1010 */ - {12, 0x66, 62}, /* 0000 0110 0110 */ - {12, 0x67, 63}, /* 0000 0110 0111 */ - {10, 0xF, 64}, /* 0000 0011 11 */ - {12, 0xC8, 128}, /* 0000 1100 1000 */ - {12, 0xC9, 192}, /* 0000 1100 1001 */ - {12, 0x5B, 256}, /* 0000 0101 1011 */ - {12, 0x33, 320}, /* 0000 0011 0011 */ - {12, 0x34, 384}, /* 0000 0011 0100 */ - {12, 0x35, 448}, /* 0000 0011 0101 */ - {13, 0x6C, 512}, /* 0000 0011 0110 0 */ - {13, 0x6D, 576}, /* 0000 0011 0110 1 */ - {13, 0x4A, 640}, /* 0000 0010 0101 0 */ - {13, 0x4B, 704}, /* 0000 0010 0101 1 */ - {13, 0x4C, 768}, /* 0000 0010 0110 0 */ - {13, 0x4D, 832}, /* 0000 0010 0110 1 */ - {13, 0x72, 896}, /* 0000 0011 1001 0 */ - {13, 0x73, 960}, /* 0000 0011 1001 1 */ - {13, 0x74, 1024}, /* 0000 0011 1010 0 */ - {13, 0x75, 1088}, /* 0000 0011 1010 1 */ - {13, 0x76, 1152}, /* 0000 0011 1011 0 */ - {13, 0x77, 1216}, /* 0000 0011 1011 1 */ - {13, 0x52, 1280}, /* 0000 0010 1001 0 */ - {13, 0x53, 1344}, /* 0000 0010 1001 1 */ - {13, 0x54, 1408}, /* 0000 0010 1010 0 */ - {13, 0x55, 1472}, /* 0000 0010 1010 1 */ - {13, 0x5A, 1536}, /* 0000 0010 1101 0 */ - {13, 0x5B, 1600}, /* 0000 0010 1101 1 */ - {13, 0x64, 1664}, /* 0000 0011 0010 0 */ - {13, 0x65, 1728}, /* 0000 0011 0010 1 */ - {11, 0x8, 1792}, /* 0000 0001 000 */ - {11, 0xC, 1856}, /* 0000 0001 100 */ - {11, 0xD, 1920}, /* 0000 0001 101 */ - {12, 0x12, 1984}, /* 0000 0001 0010 */ - {12, 0x13, 2048}, /* 0000 0001 0011 */ - {12, 0x14, 2112}, /* 0000 0001 0100 */ - {12, 0x15, 2176}, /* 0000 0001 0101 */ - {12, 0x16, 2240}, /* 0000 0001 0110 */ - {12, 0x17, 2304}, /* 0000 0001 0111 */ - {12, 0x1C, 2368}, /* 0000 0001 1100 */ - {12, 0x1D, 2432}, /* 0000 0001 1101 */ - {12, 0x1E, 2496}, /* 0000 0001 1110 */ - {12, 0x1F, 2560}, /* 0000 0001 1111 */ - {12, 0x1, G3CODE_EOL}, /* 0000 0000 0001 */ - {9, 0x1, G3CODE_INVALID}, /* 0000 0000 1 */ - {10, 0x1, G3CODE_INVALID}, /* 0000 0000 01 */ - {11, 0x1, G3CODE_INVALID}, /* 0000 0000 001 */ - {12, 0x0, G3CODE_INVALID}, /* 0000 0000 0000 */ -}; -#else -extern const tableentry TIFFFaxWhiteCodes[]; -extern const tableentry TIFFFaxBlackCodes[]; -#endif -#endif /* _T4_ */ diff --git a/src/3rd/tiff/thunder.c b/src/3rd/tiff/thunder.c deleted file mode 100644 index 1f97362ca39..00000000000 --- a/src/3rd/tiff/thunder.c +++ /dev/null @@ -1,198 +0,0 @@ -/* - * Copyright (c) 1988-1997 Sam Leffler - * Copyright (c) 1991-1997 Silicon Graphics, Inc. - * - * Permission to use, copy, modify, distribute, and sell this software and - * its documentation for any purpose is hereby granted without fee, provided - * that (i) the above copyright notices and this permission notice appear in - * all copies of the software and related documentation, and (ii) the names of - * Sam Leffler and Silicon Graphics may not be used in any advertising or - * publicity relating to the software without the specific, prior written - * permission of Sam Leffler and Silicon Graphics. - * - * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, - * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY - * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. - * - * IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR - * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, - * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, - * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF - * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE - * OF THIS SOFTWARE. - */ - -#include "tiffiop.h" -#include -#ifdef THUNDER_SUPPORT -/* - * TIFF Library. - * - * ThunderScan 4-bit Compression Algorithm Support - */ - -/* - * ThunderScan uses an encoding scheme designed for - * 4-bit pixel values. Data is encoded in bytes, with - * each byte split into a 2-bit code word and a 6-bit - * data value. The encoding gives raw data, runs of - * pixels, or pixel values encoded as a delta from the - * previous pixel value. For the latter, either 2-bit - * 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_CODE 0xc0 /* mask for 2-bit code word */ -/* code values */ -#define THUNDER_RUN 0x00 /* run of pixels w/ encoded count */ -#define THUNDER_2BITDELTAS 0x40 /* 3 pixels w/ encoded 2-bit deltas */ -#define DELTA2_SKIP 2 /* skip code for 2-bit deltas */ -#define THUNDER_3BITDELTAS 0x80 /* 2 pixels w/ encoded 3-bit deltas */ -#define DELTA3_SKIP 4 /* skip code for 3-bit deltas */ -#define THUNDER_RAW 0xc0 /* raw data encoded */ - -static const int twobitdeltas[4] = {0, 1, 0, -1}; -static const int threebitdeltas[8] = {0, 1, 2, 3, 0, -3, -2, -1}; - -#define SETPIXEL(op, v) \ - { \ - lastpixel = (v)&0xf; \ - if (npixels < maxpixels) \ - { \ - if (npixels++ & 1) \ - *op++ |= lastpixel; \ - else \ - op[0] = (uint8_t)(lastpixel << 4); \ - } \ - } - -static int ThunderSetupDecode(TIFF *tif) -{ - static const char module[] = "ThunderSetupDecode"; - - if (tif->tif_dir.td_bitspersample != 4) - { - TIFFErrorExtR(tif, module, - "Wrong bitspersample value (%d), Thunder decoder only " - "supports 4bits per sample.", - (int)tif->tif_dir.td_bitspersample); - return 0; - } - - return (1); -} - -static int ThunderDecode(TIFF *tif, uint8_t *op, tmsize_t maxpixels) -{ - static const char module[] = "ThunderDecode"; - register unsigned char *bp; - register tmsize_t cc; - unsigned int lastpixel; - tmsize_t npixels; - - bp = (unsigned char *)tif->tif_rawcp; - cc = tif->tif_rawcc; - lastpixel = 0; - npixels = 0; - while (cc > 0 && npixels < maxpixels) - { - int n, delta; - - n = *bp++; - cc--; - switch (n & THUNDER_CODE) - { - case THUNDER_RUN: /* pixel run */ - /* - * Replicate the last pixel n times, - * where n is the lower-order 6 bits. - */ - if (npixels & 1) - { - op[0] |= lastpixel; - lastpixel = *op++; - npixels++; - n--; - } - else - lastpixel |= lastpixel << 4; - npixels += n; - if (npixels < maxpixels) - { - for (; n > 0; n -= 2) - *op++ = (uint8_t)lastpixel; - } - if (n == -1) - *--op &= 0xf0; - lastpixel &= 0xf; - break; - case THUNDER_2BITDELTAS: /* 2-bit deltas */ - if ((delta = ((n >> 4) & 3)) != DELTA2_SKIP) - SETPIXEL(op, - (unsigned)((int)lastpixel + twobitdeltas[delta])); - if ((delta = ((n >> 2) & 3)) != DELTA2_SKIP) - SETPIXEL(op, - (unsigned)((int)lastpixel + twobitdeltas[delta])); - if ((delta = (n & 3)) != DELTA2_SKIP) - SETPIXEL(op, - (unsigned)((int)lastpixel + twobitdeltas[delta])); - break; - case THUNDER_3BITDELTAS: /* 3-bit deltas */ - if ((delta = ((n >> 3) & 7)) != DELTA3_SKIP) - SETPIXEL( - op, (unsigned)((int)lastpixel + threebitdeltas[delta])); - if ((delta = (n & 7)) != DELTA3_SKIP) - SETPIXEL( - op, (unsigned)((int)lastpixel + threebitdeltas[delta])); - break; - case THUNDER_RAW: /* raw data */ - SETPIXEL(op, n); - break; - } - } - tif->tif_rawcp = (uint8_t *)bp; - tif->tif_rawcc = cc; - if (npixels != maxpixels) - { - TIFFErrorExtR(tif, module, - "%s data at scanline %lu (%" PRIu64 " != %" PRIu64 ")", - npixels < maxpixels ? "Not enough" : "Too much", - (unsigned long)tif->tif_row, (uint64_t)npixels, - (uint64_t)maxpixels); - return (0); - } - - return (1); -} - -static int ThunderDecodeRow(TIFF *tif, uint8_t *buf, tmsize_t occ, uint16_t s) -{ - static const char module[] = "ThunderDecodeRow"; - uint8_t *row = buf; - - (void)s; - if (occ % tif->tif_scanlinesize) - { - TIFFErrorExtR(tif, module, "Fractional scanlines cannot be read"); - return (0); - } - while (occ > 0) - { - if (!ThunderDecode(tif, row, tif->tif_dir.td_imagewidth)) - return (0); - occ -= tif->tif_scanlinesize; - row += tif->tif_scanlinesize; - } - return (1); -} - -int TIFFInitThunderScan(TIFF *tif, int scheme) -{ - (void)scheme; - - tif->tif_setupdecode = ThunderSetupDecode; - tif->tif_decoderow = ThunderDecodeRow; - tif->tif_decodestrip = ThunderDecodeRow; - return (1); -} -#endif /* THUNDER_SUPPORT */ diff --git a/src/3rd/tiff/tiff.diff b/src/3rd/tiff/tiff.diff deleted file mode 100644 index f1f09d6f78f..00000000000 --- a/src/3rd/tiff/tiff.diff +++ /dev/null @@ -1,701 +0,0 @@ -diff --strip-trailing-cr -urN tiff.orig/dir.c tiff/dir.c ---- tiff.orig/dir.c 2023-05-22 14:03:41.000000000 +0000 -+++ tiff/dir.c 2023-11-06 22:26:31.000000000 +0000 -@@ -571,9 +571,9 @@ - break; - case TIFFTAG_INKNAMES: - { -+ uint16_t ninksinstring; - v = (uint16_t)va_arg(ap, uint16_vap); - s = va_arg(ap, char *); -- uint16_t ninksinstring; - ninksinstring = countInkNamesString(tif, v, s); - status = ninksinstring > 0; - if (ninksinstring > 0) -@@ -771,8 +771,9 @@ - } - else - { -+ size_t len; - mb = (const char *)va_arg(ap, const char *); -- size_t len = strlen(mb) + 1; -+ len = strlen(mb) + 1; - if (len >= 0x80000000U) - { - status = 0; -@@ -853,7 +854,8 @@ - if (tv->info->field_type == TIFF_LONG8) - { - uint64_t *pui64 = (uint64_t *)tv->value; -- for (int i = 0; i < tv->count; i++) -+ int i; -+ for (i = 0; i < tv->count; i++) - { - if (pui64[i] > 0xffffffffu) - { -@@ -872,7 +874,8 @@ - else if (tv->info->field_type == TIFF_SLONG8) - { - int64_t *pi64 = (int64_t *)tv->value; -- for (int i = 0; i < tv->count; i++) -+ int i; -+ for (i = 0; i < tv->count; i++) - { - if (pi64[i] > 2147483647 || - pi64[i] < (-2147483647 - 1)) -diff --strip-trailing-cr -urN tiff.orig/dirread.c tiff/dirread.c ---- tiff.orig/dirread.c 2023-07-18 14:59:48.000000000 +0000 -+++ tiff/dirread.c 2023-11-06 22:33:50.000000000 +0000 -@@ -2781,7 +2781,7 @@ - case TIFF_FLOAT: - if (tif->tif_flags & TIFF_SWAB) - TIFFSwabArrayOfLong((uint32_t *)origdata, count); -- TIFFCvtIEEEDoubleToNative(tif, count, (float *)origdata); -+ TIFFCvtIEEEFloatToNative(tif, count, (float *)origdata); - *value = (float *)origdata; - return (TIFFReadDirEntryErrOk); - } -@@ -5427,6 +5427,9 @@ - */ - int _TIFFCheckDirNumberAndOffset(TIFF *tif, tdir_t dirn, uint64_t diroff) - { -+ TIFFOffsetAndDirNumber entry; -+ TIFFOffsetAndDirNumber *foundEntry; -+ - if (diroff == 0) /* no more directories */ - return 0; - -@@ -5461,11 +5464,10 @@ - * loop - * - no: add to list or update offset at that IFD number - */ -- TIFFOffsetAndDirNumber entry; - entry.offset = diroff; - entry.dirNumber = dirn; - -- TIFFOffsetAndDirNumber *foundEntry = -+ foundEntry = - (TIFFOffsetAndDirNumber *)TIFFHashSetLookup( - tif->tif_map_dir_offset_to_number, &entry); - if (foundEntry) -@@ -5494,12 +5496,13 @@ - if (foundEntry->offset != diroff) - { - TIFFOffsetAndDirNumber entryOld; -+ TIFFOffsetAndDirNumber *foundEntryOld; - entryOld.offset = foundEntry->offset; - entryOld.dirNumber = dirn; - /* We must remove first from tif_map_dir_number_to_offset as the */ - /* entry is owned (and thus freed) by */ - /* tif_map_dir_offset_to_number */ -- TIFFOffsetAndDirNumber *foundEntryOld = -+ foundEntryOld = - (TIFFOffsetAndDirNumber *)TIFFHashSetLookup( - tif->tif_map_dir_number_to_offset, &entryOld); - if (foundEntryOld) -@@ -5515,6 +5518,7 @@ - foundEntryOld); - } - -+ { - TIFFOffsetAndDirNumber *entryPtr = (TIFFOffsetAndDirNumber *)malloc( - sizeof(TIFFOffsetAndDirNumber)); - if (entryPtr == NULL) -@@ -5539,6 +5543,7 @@ - "Insertion in tif_map_dir_number_to_offset failed"); - return 0; - } -+ } - } - return 1; - } -@@ -5553,6 +5558,7 @@ - return 0; - } - -+ { - TIFFOffsetAndDirNumber *entryPtr = - (TIFFOffsetAndDirNumber *)malloc(sizeof(TIFFOffsetAndDirNumber)); - if (entryPtr == NULL) -@@ -5577,6 +5583,7 @@ - "Insertion in tif_map_dir_number_to_offset failed"); - return 0; - } -+ } - - return 1; - } /* --- _TIFFCheckDirNumberAndOffset() ---*/ -@@ -5590,6 +5597,8 @@ - */ - int _TIFFGetDirNumberFromOffset(TIFF *tif, uint64_t diroff, tdir_t *dirn) - { -+ TIFFOffsetAndDirNumber entry; -+ TIFFOffsetAndDirNumber *foundEntry; - if (diroff == 0) /* no more directories */ - return 0; - -@@ -5599,11 +5608,10 @@ - */ - if (tif->tif_map_dir_offset_to_number == NULL) - return 0; -- TIFFOffsetAndDirNumber entry; - entry.offset = diroff; - entry.dirNumber = 0; /* not used */ - -- TIFFOffsetAndDirNumber *foundEntry = -+ foundEntry = - (TIFFOffsetAndDirNumber *)TIFFHashSetLookup( - tif->tif_map_dir_offset_to_number, &entry); - if (foundEntry) -@@ -5636,13 +5644,14 @@ - int _TIFFGetOffsetFromDirNumber(TIFF *tif, tdir_t dirn, uint64_t *diroff) - { - -+ TIFFOffsetAndDirNumber entry; -+ TIFFOffsetAndDirNumber *foundEntry; - if (tif->tif_map_dir_number_to_offset == NULL) - return 0; -- TIFFOffsetAndDirNumber entry; - entry.offset = 0; /* not used */ - entry.dirNumber = dirn; - -- TIFFOffsetAndDirNumber *foundEntry = -+ foundEntry = - (TIFFOffsetAndDirNumber *)TIFFHashSetLookup( - tif->tif_map_dir_number_to_offset, &entry); - if (foundEntry) -@@ -5662,17 +5671,18 @@ - */ - int _TIFFRemoveEntryFromDirectoryListByOffset(TIFF *tif, uint64_t diroff) - { -+ TIFFOffsetAndDirNumber entryOld; -+ TIFFOffsetAndDirNumber *foundEntryOldOff; - if (tif->tif_map_dir_offset_to_number == NULL) - return 1; - -- TIFFOffsetAndDirNumber entryOld; - entryOld.offset = diroff; - entryOld.dirNumber = 0; - /* We must remove first from tif_map_dir_number_to_offset as the - * entry is owned (and thus freed) by tif_map_dir_offset_to_number. - * However, we need firstly to find the directory number from offset. */ - -- TIFFOffsetAndDirNumber *foundEntryOldOff = -+ foundEntryOldOff = - (TIFFOffsetAndDirNumber *)TIFFHashSetLookup( - tif->tif_map_dir_offset_to_number, &entryOld); - if (foundEntryOldOff) -diff --strip-trailing-cr -urN tiff.orig/dirwrite.c tiff/dirwrite.c ---- tiff.orig/dirwrite.c 2023-06-26 13:18:09.000000000 +0000 -+++ tiff/dirwrite.c 2023-11-06 22:40:09.000000000 +0000 -@@ -311,6 +311,7 @@ - int TIFFRewriteDirectory(TIFF *tif) - { - static const char module[] = "TIFFRewriteDirectory"; -+ uint64_t torewritediroff; - - /* We don't need to do anything special if it hasn't been written. */ - if (tif->tif_diroff == 0) -@@ -320,7 +321,7 @@ - * Find and zero the pointer to this directory, so that TIFFLinkDirectory - * will cause it to be added after this directories current pre-link. - */ -- uint64_t torewritediroff = tif->tif_diroff; -+ torewritediroff = tif->tif_diroff; - - if (!(tif->tif_flags & TIFF_BIGTIFF)) - { -@@ -2068,6 +2069,7 @@ - uint16_t n; - uint16_t *o; - int p; -+ int i; - if (dir == NULL) - { - (*ndir)++; -@@ -2082,7 +2084,7 @@ - /* clang-format on */ - - /* Check for proper number of transferfunctions */ -- for (int i = 0; i < n; i++) -+ for (i = 0; i < n; i++) - { - if (tif->tif_dir.td_transferfunction[i] == NULL) - { -@@ -2562,7 +2564,7 @@ - } - else - { -- nMax = ((9223372036854775807 - 1) / 2); /* for ULLONG range */ -+ nMax = ((HB_ULL( 9223372036854775807 ) - 1) / 2); /* for ULLONG range */ - } - fMax = (double)nMax; - -@@ -2816,7 +2818,7 @@ - { - assert(count < 0x40000000); - assert(sizeof(float) == 4); -- TIFFCvtNativeToIEEEFloat(tif, count, &value); -+ TIFFCvtNativeToIEEEFloat(tif, count, value); - if (tif->tif_flags & TIFF_SWAB) - TIFFSwabArrayOfFloat(value, count); - return (TIFFWriteDirectoryTagData(tif, ndir, dir, tag, TIFF_FLOAT, count, -@@ -2830,7 +2832,7 @@ - { - assert(count < 0x20000000); - assert(sizeof(double) == 8); -- TIFFCvtNativeToIEEEDouble(tif, count, &value); -+ TIFFCvtNativeToIEEEDouble(tif, count, value); - if (tif->tif_flags & TIFF_SWAB) - TIFFSwabArrayOfDouble(value, count); - return (TIFFWriteDirectoryTagData(tif, ndir, dir, tag, TIFF_DOUBLE, count, -diff --strip-trailing-cr -urN tiff.orig/error.c tiff/error.c ---- tiff.orig/error.c 2023-05-22 13:49:02.000000000 +0000 -+++ tiff/error.c 2023-11-06 21:36:11.000000000 +0000 -@@ -83,9 +83,10 @@ - va_list ap; - if (opts && opts->errorhandler) - { -+ int stop; - va_start(ap, fmt); -- int stop = opts->errorhandler(NULL, opts->errorhandler_user_data, -- module, fmt, ap); -+ stop = opts->errorhandler(NULL, opts->errorhandler_user_data, -+ module, fmt, ap); - va_end(ap); - if (stop) - return; -@@ -109,8 +110,9 @@ - va_list ap; - if (tif && tif->tif_errorhandler) - { -+ int stop; - va_start(ap, fmt); -- int stop = (*tif->tif_errorhandler)( -+ stop = (*tif->tif_errorhandler)( - tif, tif->tif_errorhandler_user_data, module, fmt, ap); - va_end(ap); - if (stop) -@@ -125,7 +127,7 @@ - if (_TIFFerrorHandlerExt) - { - va_start(ap, fmt); -- (*_TIFFerrorHandlerExt)(tif ? tif->tif_clientdata : NULL, module, fmt, -+ (*_TIFFerrorHandlerExt)(tif ? tif->tif_clientdata : (thandle_t)0, module, fmt, - ap); - va_end(ap); - } -diff --strip-trailing-cr -urN tiff.orig/getimage.c tiff/getimage.c ---- tiff.orig/getimage.c 2023-05-22 13:49:02.000000000 +0000 -+++ tiff/getimage.c 2023-11-06 21:45:16.000000000 +0000 -@@ -796,9 +796,11 @@ - this_tw = tw - fromskew; - this_toskew = toskew + fromskew; - } -+ { - tmsize_t roffset = (tmsize_t)y * w + tocol; - (*put)(img, raster + roffset, tocol, y, this_tw, nrow, fromskew, - this_toskew, buf + pos); -+ } - tocol += this_tw; - col += this_tw; - /* -@@ -999,10 +1001,12 @@ - this_tw = tw - fromskew; - this_toskew = toskew + fromskew; - } -+ { - tmsize_t roffset = (tmsize_t)y * w + tocol; - (*put)(img, raster + roffset, tocol, y, this_tw, nrow, fromskew, - this_toskew, p0 + pos, p1 + pos, p2 + pos, - (alpha ? (pa + pos) : NULL)); -+ } - tocol += this_tw; - col += this_tw; - /* -@@ -1122,9 +1126,11 @@ - - pos = ((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, w, nrow, fromskew, toskew, - buf + pos); -+ } - y += ((flip & FLIP_VERTICALLY) ? -(int32_t)nrow : (int32_t)nrow); - } - -@@ -1291,9 +1297,11 @@ - - pos = ((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, w, nrow, fromskew, toskew, p0 + pos, - p1 + pos, p2 + pos, (alpha ? (pa + pos) : NULL)); -+ } - y += ((flip & FLIP_VERTICALLY) ? -(int32_t)nrow : (int32_t)nrow); - } - -diff --strip-trailing-cr -urN tiff.orig/hash_set.c tiff/hash_set.c ---- tiff.orig/hash_set.c 2023-05-22 14:03:41.000000000 +0000 -+++ tiff/hash_set.c 2023-11-06 22:14:24.000000000 +0000 -@@ -26,7 +26,7 @@ - * DEALINGS IN THE SOFTWARE. - ****************************************************************************/ - --#include "tif_config.h" -+#include "tiffconf.h" - - #include "hash_set.h" - -@@ -225,15 +225,17 @@ - - static void TIFFHashSetClearInternal(TIFFHashSet *set, bool bFinalize) - { -+ int i; - assert(set != NULL); -- for (int i = 0; i < set->nAllocatedSize; i++) -+ for (i = 0; i < set->nAllocatedSize; i++) - { - TIFFList *cur = set->tabList[i]; - while (cur) - { -+ TIFFList *psNext; - if (set->fnFreeEltFunc) - set->fnFreeEltFunc(cur->pData); -- TIFFList *psNext = cur->psNext; -+ psNext = cur->psNext; - if (bFinalize) - free(cur); - else -@@ -368,6 +370,7 @@ - int nNewAllocatedSize = anPrimes[set->nIndiceAllocatedSize]; - TIFFList **newTabList = - (TIFFList **)(calloc(sizeof(TIFFList *), nNewAllocatedSize)); -+ int i; - if (newTabList == NULL) - return false; - #ifdef HASH_DEBUG -@@ -378,7 +381,7 @@ - set->nCollisions * 100.0 / set->nSize); - set->nCollisions = 0; - #endif -- for (int i = 0; i < set->nAllocatedSize; i++) -+ for (i = 0; i < set->nAllocatedSize; i++) - { - TIFFList *cur = set->tabList[i]; - while (cur) -@@ -439,8 +442,9 @@ - - bool TIFFHashSetInsert(TIFFHashSet *set, void *elt) - { -+ void **pElt; - assert(set != NULL); -- void **pElt = TIFFHashSetFindPtr(set, elt); -+ pElt = TIFFHashSetFindPtr(set, elt); - if (pElt) - { - if (set->fnFreeEltFunc) -@@ -464,12 +468,14 @@ - } - } - -+ { - const unsigned long nHashVal = set->fnHashFunc(elt) % set->nAllocatedSize; - #ifdef HASH_DEBUG - if (set->tabList[nHashVal]) - set->nCollisions++; - #endif - -+ { - TIFFList *new_elt = TIFFHashSetGetNewListElt(set); - if (new_elt == NULL) - { -@@ -481,6 +487,8 @@ - new_elt->psNext = set->tabList[nHashVal]; - set->tabList[nHashVal] = new_elt; - set->nSize++; -+ } -+ } - - return true; - } -@@ -501,8 +509,9 @@ - - void *TIFFHashSetLookup(TIFFHashSet *set, const void *elt) - { -+ void **pElt; - assert(set != NULL); -- void **pElt = TIFFHashSetFindPtr(set, elt); -+ pElt = TIFFHashSetFindPtr(set, elt); - if (pElt) - return *pElt; - -@@ -532,6 +541,7 @@ - } - } - -+ { - int nHashVal = (int)(set->fnHashFunc(elt) % set->nAllocatedSize); - TIFFList *cur = set->tabList[nHashVal]; - TIFFList *prev = NULL; -@@ -558,6 +568,7 @@ - prev = cur; - cur = cur->psNext; - } -+ } - return false; - } - -diff --strip-trailing-cr -urN tiff.orig/open.c tiff/open.c ---- tiff.orig/open.c 2023-05-22 14:03:41.000000000 +0000 -+++ tiff/open.c 2023-11-06 22:41:24.000000000 +0000 -@@ -219,6 +219,7 @@ - m = _TIFFgetMode(opts, clientdata, mode, module); - if (m == -1) - goto bad2; -+ { - tmsize_t 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) -@@ -232,6 +233,7 @@ - goto bad2; - } - tif = (TIFF *)_TIFFmallocExt(NULL, size_to_alloc); -+ } - if (tif == NULL) - { - _TIFFErrorEarly(opts, clientdata, module, -diff --strip-trailing-cr -urN tiff.orig/print.c tiff/print.c ---- tiff.orig/print.c 2023-05-22 13:49:02.000000000 +0000 -+++ tiff/print.c 2023-11-06 22:15:34.000000000 +0000 -@@ -82,7 +82,8 @@ - const char *field_name = fip->field_name; - if (TIFFFieldIsAnonymous(fip)) - { -- for (size_t i = 0; i < NTAGS; ++i) -+ size_t i; -+ for (i = 0; i < NTAGS; ++i) - { - if (fip->field_tag == tagnames[i].tag) - { -diff --strip-trailing-cr -urN tiff.orig/tiffconf.h tiff/tiffconf.h ---- tiff.orig/tiffconf.h 2023-05-22 14:03:41.000000000 +0000 -+++ tiff/tiffconf.h 2023-11-06 12:58:27.000000000 +0000 -@@ -13,38 +13,43 @@ - #ifndef _TIFFCONF_ - #define _TIFFCONF_ - -+#include "hbdefs.h" -+#include "hb_io.h" - --#include --#include --#include -- -+#include /* For PRIu16 */ - - /* Signed 16-bit type */ --#undef TIFF_INT16_T -+#define TIFF_INT16_T HB_I16 - - /* Signed 32-bit type */ --#undef TIFF_INT32_T -+#define TIFF_INT32_T HB_I32 - - /* Signed 64-bit type */ --#undef TIFF_INT64_T -+#define TIFF_INT64_T HB_I64 - - /* Signed 8-bit type */ --#undef TIFF_INT8_T -+#define TIFF_INT8_T HB_I8 - - /* Unsigned 16-bit type */ --#undef TIFF_UINT16_T -+#define TIFF_UINT16_T HB_U16 - - /* Unsigned 32-bit type */ --#undef TIFF_UINT32_T -+#define TIFF_UINT32_T HB_U32 - - /* Unsigned 64-bit type */ --#undef TIFF_UINT64_T -+#define TIFF_UINT64_T HB_U64 - - /* Unsigned 8-bit type */ --#undef TIFF_UINT8_T -+#define TIFF_UINT8_T HB_U8 - - /* Signed size type */ --#undef TIFF_SSIZE_T -+#define TIFF_SSIZE_T HB_ISIZ -+ -+/* Signed size type formatter */ -+#define TIFF_SSIZE_FORMAT "" HB_PFS "d" -+ -+/* file handler */ -+#define TIFF_FILE_HANDLE HB_FHANDLE - - /* Compatibility stuff. */ - -@@ -66,28 +71,40 @@ - - /* Native cpu byte order: 1 if big-endian (Motorola) or 0 if little-endian - (Intel) */ --#undef HOST_BIGENDIAN -+#if defined( HB_BIG_ENDIAN ) -+ #define HOST_BIGENDIAN -+#endif - -+#if 0 - /* Support CCITT Group 3 & 4 algorithms */ - #undef CCITT_SUPPORT -+#endif - -+#if 0 - /* Support JPEG compression (requires IJG JPEG library) */ - #undef JPEG_SUPPORT -+#endif - - /* Support JBIG compression (requires JBIG-KIT library) */ - #undef JBIG_SUPPORT - -+#if 0 - /* Support LERC compression */ - #undef LERC_SUPPORT -+#endif - - /* Support LogLuv high dynamic range encoding */ - #undef LOGLUV_SUPPORT - -+#if 0 - /* Support LZW algorithm */ - #undef LZW_SUPPORT -+#endif - -+#if 0 - /* Support NeXT 2-bit RLE algorithm */ - #undef NEXT_SUPPORT -+#endif - - /* Support Old JPEG compresson (read contrib/ojpeg/README first! Compilation - fails with unpatched IJG JPEG library) */ -@@ -102,11 +119,15 @@ - /* Support ThunderScan 4-bit RLE algorithm */ - #undef THUNDER_SUPPORT - -+#if 0 - /* Support Deflate compression */ - #undef ZIP_SUPPORT -+#endif - -+#if 0 - /* Support libdeflate enhanced compression */ - #undef LIBDEFLATE_SUPPORT -+#endif - - /* Support strip chopping (whether or not to convert single-strip uncompressed - images to multiple strips of ~8Kb to reduce memory usage) */ -@@ -139,6 +160,24 @@ - #define PHOTOSHOP_SUPPORT - #define IPTC_SUPPORT - -+#if ! defined( HB_OS_UNIX ) -+#ifndef O_RDONLY -+#define O_RDONLY 0 -+#endif -+#ifndef O_RDWR -+#define O_RDWR 2 -+#endif -+#ifndef O_WRONLY -+#define O_WRONLY 000001 -+#endif -+#ifndef O_CREAT -+#define O_CREAT 000100 -+#endif -+#ifndef O_TRUNC -+#define O_TRUNC 001000 -+#endif -+#endif -+ - #endif /* _TIFFCONF_ */ - - /* clang-format on */ -diff --strip-trailing-cr -urN tiff.orig/tiffio.h tiff/tiffio.h ---- tiff.orig/tiffio.h 2023-09-05 10:01:39.000000000 +0000 -+++ tiff/tiffio.h 2023-11-05 17:01:47.000000000 +0000 -@@ -103,6 +103,8 @@ - #else - typedef HFILE thandle_t; /* client data handle */ - #endif /* __WIN32__ */ -+#elif defined(TIFF_FILE_HANDLE) -+typedef TIFF_FILE_HANDLE thandle_t; /* client data handle */ - #else - typedef void *thandle_t; /* client data handle */ - #endif /* USE_WIN32_FILEIO */ -diff --strip-trailing-cr -urN tiff.orig/tiffiop.h tiff/tiffiop.h ---- tiff.orig/tiffiop.h 2023-05-22 14:03:41.000000000 +0000 -+++ tiff/tiffiop.h 2023-11-05 17:38:19.000000000 +0000 -@@ -28,7 +28,7 @@ - * ``Library-private'' definitions. - */ - --#include "tif_config.h" -+#include "tiffconf.h" - - #ifdef HAVE_FCNTL_H - #include -diff --strip-trailing-cr -urN tiff.orig/unix.c tiff/unix.c ---- tiff.orig/unix.c 2023-05-22 13:49:02.000000000 +0000 -+++ tiff/unix.c 2023-11-06 13:14:04.000000000 +0000 -@@ -27,7 +27,7 @@ - * Windows Common RunTime Library. - */ - --#include "tif_config.h" -+#include "tiffconf.h" - - #ifdef HAVE_SYS_TYPES_H - #include -@@ -228,7 +228,7 @@ - int m, fd; - TIFF *tif; - -- m = _TIFFgetMode(opts, NULL, mode, module); -+ m = _TIFFgetMode(opts, (thandle_t)0, mode, module); - if (m == -1) - return ((TIFF *)0); - -@@ -242,12 +242,12 @@ - { - if (errno > 0 && strerror(errno) != NULL) - { -- _TIFFErrorEarly(opts, NULL, module, "%s: %s", name, -+ _TIFFErrorEarly(opts, (thandle_t)0, module, "%s: %s", name, - strerror(errno)); - } - else - { -- _TIFFErrorEarly(opts, NULL, module, "%s: Cannot open", name); -+ _TIFFErrorEarly(opts, (thandle_t)0, module, "%s: Cannot open", name); - } - return ((TIFF *)0); - } -diff --strip-trailing-cr -urN tiff.orig/warn.c tiff/warn.c ---- tiff.orig/warn.c 2023-05-22 13:49:02.000000000 +0000 -+++ tiff/warn.c 2023-11-06 22:20:35.000000000 +0000 -@@ -82,9 +82,10 @@ - va_list ap; - if (tif && tif->tif_warnhandler) - { -+ int stop; - va_start(ap, fmt); -- int stop = (*tif->tif_warnhandler)(tif, tif->tif_warnhandler_user_data, -- module, fmt, ap); -+ stop = (*tif->tif_warnhandler)(tif, tif->tif_warnhandler_user_data, -+ module, fmt, ap); - va_end(ap); - if (stop) - return; diff --git a/src/3rd/tiff/tiff.h b/src/3rd/tiff/tiff.h deleted file mode 100644 index d8da33dc383..00000000000 --- a/src/3rd/tiff/tiff.h +++ /dev/null @@ -1,899 +0,0 @@ -/* - * Copyright (c) 1988-1997 Sam Leffler - * Copyright (c) 1991-1997 Silicon Graphics, Inc. - * - * Permission to use, copy, modify, distribute, and sell this software and - * its documentation for any purpose is hereby granted without fee, provided - * that (i) the above copyright notices and this permission notice appear in - * all copies of the software and related documentation, and (ii) the names of - * Sam Leffler and Silicon Graphics may not be used in any advertising or - * publicity relating to the software without the specific, prior written - * permission of Sam Leffler and Silicon Graphics. - * - * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, - * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY - * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. - * - * IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR - * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, - * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, - * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF - * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE - * OF THIS SOFTWARE. - */ - -#ifndef _TIFF_ -#define _TIFF_ - -#include "tiffconf.h" - -/* - * Tag Image File Format (TIFF) - * - * Based on Rev 6.0 from: - * Developer's Desk - * Aldus Corporation - * 411 First Ave. South - * Suite 200 - * Seattle, WA 98104 - * 206-622-5500 - * - * (http://partners.adobe.com/asn/developer/PDFS/TN/TIFF6.pdf) - * - * For BigTIFF design notes see the following links - * http://www.remotesensing.org/libtiff/bigtiffdesign.html - * http://www.awaresystems.be/imaging/tiff/bigtiff.html - */ - -#define TIFF_VERSION_CLASSIC 42 -#define TIFF_VERSION_BIG 43 - -#define TIFF_BIGENDIAN 0x4d4d -#define TIFF_LITTLEENDIAN 0x4949 -#define MDI_LITTLEENDIAN 0x5045 -#define MDI_BIGENDIAN 0x4550 - -/* - * Intrinsic data types required by the file format: - * - * 8-bit quantities int8_t/uint_8_t - * 16-bit quantities int16_t/uint_16_t - * 32-bit quantities int32_t/uint_32_t - * 64-bit quantities int64_t/uint_64_t - * strings unsigned char* - */ -#ifdef __GNUC__ -#define TIFF_GCC_DEPRECATED __attribute__((deprecated)) -#else -#define TIFF_GCC_DEPRECATED -#endif -#ifdef _MSC_VER -#define TIFF_MSC_DEPRECATED \ - __declspec(deprecated("libtiff type deprecated; please use corresponding " \ - "C99 stdint.h type")) -#else -#define TIFF_MSC_DEPRECATED -#endif - -#ifndef TIFF_DISABLE_DEPRECATED -typedef TIFF_MSC_DEPRECATED int8_t int8 TIFF_GCC_DEPRECATED; -typedef TIFF_MSC_DEPRECATED uint8_t uint8 TIFF_GCC_DEPRECATED; - -typedef TIFF_MSC_DEPRECATED int16_t int16 TIFF_GCC_DEPRECATED; -typedef TIFF_MSC_DEPRECATED uint16_t uint16 TIFF_GCC_DEPRECATED; - -typedef TIFF_MSC_DEPRECATED int32_t int32 TIFF_GCC_DEPRECATED; -typedef TIFF_MSC_DEPRECATED uint32_t uint32 TIFF_GCC_DEPRECATED; - -typedef TIFF_MSC_DEPRECATED int64_t int64 TIFF_GCC_DEPRECATED; -typedef TIFF_MSC_DEPRECATED uint64_t uint64 TIFF_GCC_DEPRECATED; -#endif /* TIFF_DISABLE_DEPRECATED */ - -/* - * Some types as promoted in a variable argument list - * We use uint16_vap rather then directly using int, because this way - * we document the type we actually want to pass through, conceptually, - * rather then confusing the issue by merely stating the type it gets - * promoted to - */ - -typedef int uint16_vap; - -/* - * TIFF header. - */ -typedef struct -{ - uint16_t tiff_magic; /* magic number (defines byte order) */ - uint16_t tiff_version; /* TIFF version number */ -} TIFFHeaderCommon; -typedef struct -{ - uint16_t tiff_magic; /* magic number (defines byte order) */ - uint16_t tiff_version; /* TIFF version number */ - uint32_t tiff_diroff; /* byte offset to first directory */ -} TIFFHeaderClassic; -typedef struct -{ - uint16_t tiff_magic; /* magic number (defines byte order) */ - uint16_t tiff_version; /* TIFF version number */ - uint16_t tiff_offsetsize; /* size of offsets, should be 8 */ - uint16_t tiff_unused; /* unused word, should be 0 */ - uint64_t tiff_diroff; /* byte offset to first directory */ -} TIFFHeaderBig; - -/* - * NB: In the comments below, - * - items marked with a + are obsoleted by revision 5.0, - * - items marked with a ! are introduced in revision 6.0. - * - items marked with a % are introduced post revision 6.0. - * - items marked with a $ are obsoleted by revision 6.0. - * - items marked with a & are introduced by Adobe DNG specification. - */ - -/* - * Tag data type information. - * - * Note: RATIONALs are the ratio of two 32-bit integer values. - *--: - * Note2: TIFF_IFD8 data type is used in tiffFields[]-tag definition in order to - distinguish the write-handling of those tags between ClassicTIFF and BigTiff: - For ClassicTIFF libtiff writes a 32-bit value and the TIFF_IFD - type-id into the file For BigTIFF libtiff writes a 64-bit value and the - TIFF_IFD8 type-id into the file - */ -typedef enum -{ - TIFF_NOTYPE = 0, /* placeholder */ - TIFF_BYTE = 1, /* 8-bit unsigned integer */ - TIFF_ASCII = 2, /* 8-bit bytes w/ last byte null */ - TIFF_SHORT = 3, /* 16-bit unsigned integer */ - TIFF_LONG = 4, /* 32-bit unsigned integer */ - TIFF_RATIONAL = 5, /* 64-bit unsigned fraction */ - TIFF_SBYTE = 6, /* !8-bit signed integer */ - TIFF_UNDEFINED = 7, /* !8-bit untyped data */ - TIFF_SSHORT = 8, /* !16-bit signed integer */ - TIFF_SLONG = 9, /* !32-bit signed integer */ - TIFF_SRATIONAL = 10, /* !64-bit signed fraction */ - TIFF_FLOAT = 11, /* !32-bit IEEE floating point */ - TIFF_DOUBLE = 12, /* !64-bit IEEE floating point */ - TIFF_IFD = 13, /* %32-bit unsigned integer (offset) */ - TIFF_LONG8 = 16, /* BigTIFF 64-bit unsigned integer */ - TIFF_SLONG8 = 17, /* BigTIFF 64-bit signed integer */ - TIFF_IFD8 = 18 /* BigTIFF 64-bit unsigned integer (offset) */ -} TIFFDataType; - -/* - * TIFF Tag Definitions. - */ -/* clang-format off */ /* for better readability of tag comments */ -#define TIFFTAG_SUBFILETYPE 254 /* subfile data descriptor */ -#define FILETYPE_REDUCEDIMAGE 0x1 /* reduced resolution version */ -#define FILETYPE_PAGE 0x2 /* one page of many */ -#define FILETYPE_MASK 0x4 /* transparency mask */ -#define TIFFTAG_OSUBFILETYPE 255 /* +kind of data in subfile */ -#define OFILETYPE_IMAGE 1 /* full resolution image data */ -#define OFILETYPE_REDUCEDIMAGE 2 /* reduced size image data */ -#define OFILETYPE_PAGE 3 /* one page of many */ -#define TIFFTAG_IMAGEWIDTH 256 /* image width in pixels */ -#define TIFFTAG_IMAGELENGTH 257 /* image height in pixels */ -#define TIFFTAG_BITSPERSAMPLE 258 /* bits per channel (sample) */ -#define TIFFTAG_COMPRESSION 259 /* data compression technique */ -#define COMPRESSION_NONE 1 /* dump mode */ -#define COMPRESSION_CCITTRLE 2 /* CCITT modified Huffman RLE */ -#define COMPRESSION_CCITTFAX3 3 /* CCITT Group 3 fax encoding */ -#define COMPRESSION_CCITT_T4 3 /* CCITT T.4 (TIFF 6 name) */ -#define COMPRESSION_CCITTFAX4 4 /* CCITT Group 4 fax encoding */ -#define COMPRESSION_CCITT_T6 4 /* CCITT T.6 (TIFF 6 name) */ -#define COMPRESSION_LZW 5 /* Lempel-Ziv & Welch */ -#define COMPRESSION_OJPEG 6 /* !6.0 JPEG */ -#define COMPRESSION_JPEG 7 /* %JPEG DCT compression */ -#define COMPRESSION_T85 9 /* !TIFF/FX T.85 JBIG compression */ -#define COMPRESSION_T43 10 /* !TIFF/FX T.43 colour by layered JBIG compression */ -#define COMPRESSION_NEXT 32766 /* NeXT 2-bit RLE */ -#define COMPRESSION_CCITTRLEW 32771 /* #1 w/ word alignment */ -#define COMPRESSION_PACKBITS 32773 /* Macintosh RLE */ -#define COMPRESSION_THUNDERSCAN 32809 /* ThunderScan RLE */ -/* codes 32895-32898 are reserved for ANSI IT8 TIFF/IT */ -#define COMPRESSION_DCS 32947 /* Kodak DCS encoding */ -#define COMPRESSION_JBIG 34661 /* ISO JBIG */ -#define COMPRESSION_SGILOG 34676 /* SGI Log Luminance RLE */ -#define COMPRESSION_SGILOG24 34677 /* SGI Log 24-bit packed */ -#define COMPRESSION_JP2000 34712 /* Leadtools JPEG2000 */ -#define COMPRESSION_LERC 34887 /* ESRI Lerc codec: https://github.com/Esri/lerc */ -/* compression codes 34887-34889 are reserved for ESRI */ -#define COMPRESSION_LZMA 34925 /* LZMA2 */ -#define COMPRESSION_ZSTD 50000 /* ZSTD: WARNING not registered in Adobe-maintained registry */ -#define COMPRESSION_WEBP 50001 /* WEBP: WARNING not registered in Adobe-maintained registry */ -#define COMPRESSION_JXL 50002 /* JPEGXL: WARNING not registered in Adobe-maintained registry */ -#define TIFFTAG_PHOTOMETRIC 262 /* photometric interpretation */ -#define PHOTOMETRIC_MINISWHITE 0 /* min value is white */ -#define PHOTOMETRIC_MINISBLACK 1 /* min value is black */ -#define PHOTOMETRIC_RGB 2 /* RGB color model */ -#define PHOTOMETRIC_PALETTE 3 /* color map indexed */ -#define PHOTOMETRIC_MASK 4 /* $holdout mask */ -#define PHOTOMETRIC_SEPARATED 5 /* !color separations */ -#define PHOTOMETRIC_YCBCR 6 /* !CCIR 601 */ -#define PHOTOMETRIC_CIELAB 8 /* !1976 CIE L*a*b* */ -#define PHOTOMETRIC_ICCLAB 9 /* ICC L*a*b* [Adobe TIFF Technote 4] */ -#define PHOTOMETRIC_ITULAB 10 /* ITU L*a*b* */ -#define PHOTOMETRIC_CFA 32803 /* color filter array */ -#define PHOTOMETRIC_LOGL 32844 /* CIE Log2(L) */ -#define PHOTOMETRIC_LOGLUV 32845 /* CIE Log2(L) (u',v') */ -#define TIFFTAG_THRESHHOLDING 263 /* +thresholding used on data */ -#define THRESHHOLD_BILEVEL 1 /* b&w art scan */ -#define THRESHHOLD_HALFTONE 2 /* or dithered scan */ -#define THRESHHOLD_ERRORDIFFUSE 3 /* usually floyd-steinberg */ -#define TIFFTAG_CELLWIDTH 264 /* +dithering matrix width */ -#define TIFFTAG_CELLLENGTH 265 /* +dithering matrix height */ -#define TIFFTAG_FILLORDER 266 /* data order within a byte */ -#define FILLORDER_MSB2LSB 1 /* most significant -> least */ -#define FILLORDER_LSB2MSB 2 /* least significant -> most */ -#define TIFFTAG_DOCUMENTNAME 269 /* name of doc. image is from */ -#define TIFFTAG_IMAGEDESCRIPTION 270 /* info about image */ -#define TIFFTAG_MAKE 271 /* scanner manufacturer name */ -#define TIFFTAG_MODEL 272 /* scanner model name/number */ -#define TIFFTAG_STRIPOFFSETS 273 /* offsets to data strips */ -#define TIFFTAG_ORIENTATION 274 /* +image orientation */ -#define ORIENTATION_TOPLEFT 1 /* row 0 top, col 0 lhs */ -#define ORIENTATION_TOPRIGHT 2 /* row 0 top, col 0 rhs */ -#define ORIENTATION_BOTRIGHT 3 /* row 0 bottom, col 0 rhs */ -#define ORIENTATION_BOTLEFT 4 /* row 0 bottom, col 0 lhs */ -#define ORIENTATION_LEFTTOP 5 /* row 0 lhs, col 0 top */ -#define ORIENTATION_RIGHTTOP 6 /* row 0 rhs, col 0 top */ -#define ORIENTATION_RIGHTBOT 7 /* row 0 rhs, col 0 bottom */ -#define ORIENTATION_LEFTBOT 8 /* row 0 lhs, col 0 bottom */ -#define TIFFTAG_SAMPLESPERPIXEL 277 /* samples per pixel */ -#define TIFFTAG_ROWSPERSTRIP 278 /* rows per strip of data */ -#define TIFFTAG_STRIPBYTECOUNTS 279 /* bytes counts for strips */ -#define TIFFTAG_MINSAMPLEVALUE 280 /* +minimum sample value */ -#define TIFFTAG_MAXSAMPLEVALUE 281 /* +maximum sample value */ -#define TIFFTAG_XRESOLUTION 282 /* pixels/resolution in x */ -#define TIFFTAG_YRESOLUTION 283 /* pixels/resolution in y */ -#define TIFFTAG_PLANARCONFIG 284 /* storage organization */ -#define PLANARCONFIG_CONTIG 1 /* single image plane */ -#define PLANARCONFIG_SEPARATE 2 /* separate planes of data */ -#define TIFFTAG_PAGENAME 285 /* page name image is from */ -#define TIFFTAG_XPOSITION 286 /* x page offset of image lhs */ -#define TIFFTAG_YPOSITION 287 /* y page offset of image lhs */ -#define TIFFTAG_FREEOFFSETS 288 /* +byte offset to free block */ -#define TIFFTAG_FREEBYTECOUNTS 289 /* +sizes of free blocks */ -#define TIFFTAG_GRAYRESPONSEUNIT 290 /* $gray scale curve accuracy */ -#define GRAYRESPONSEUNIT_10S 1 /* tenths of a unit */ -#define GRAYRESPONSEUNIT_100S 2 /* hundredths of a unit */ -#define GRAYRESPONSEUNIT_1000S 3 /* thousandths of a unit */ -#define GRAYRESPONSEUNIT_10000S 4 /* ten-thousandths of a unit */ -#define GRAYRESPONSEUNIT_100000S 5 /* hundred-thousandths */ -#define TIFFTAG_GRAYRESPONSECURVE 291 /* $gray scale response curve */ -#define TIFFTAG_GROUP3OPTIONS 292 /* 32 flag bits */ -#define TIFFTAG_T4OPTIONS 292 /* TIFF 6.0 proper name alias */ -#define GROUP3OPT_2DENCODING 0x1 /* 2-dimensional coding */ -#define GROUP3OPT_UNCOMPRESSED 0x2 /* data not compressed */ -#define GROUP3OPT_FILLBITS 0x4 /* fill to byte boundary */ -#define TIFFTAG_GROUP4OPTIONS 293 /* 32 flag bits */ -#define TIFFTAG_T6OPTIONS 293 /* TIFF 6.0 proper name */ -#define GROUP4OPT_UNCOMPRESSED 0x2 /* data not compressed */ -#define TIFFTAG_RESOLUTIONUNIT 296 /* units of resolutions */ -#define RESUNIT_NONE 1 /* no meaningful units */ -#define RESUNIT_INCH 2 /* english */ -#define RESUNIT_CENTIMETER 3 /* metric */ -#define TIFFTAG_PAGENUMBER 297 /* page numbers of multi-page */ -#define TIFFTAG_COLORRESPONSEUNIT 300 /* $color curve accuracy */ -#define COLORRESPONSEUNIT_10S 1 /* tenths of a unit */ -#define COLORRESPONSEUNIT_100S 2 /* hundredths of a unit */ -#define COLORRESPONSEUNIT_1000S 3 /* thousandths of a unit */ -#define COLORRESPONSEUNIT_10000S 4 /* ten-thousandths of a unit */ -#define COLORRESPONSEUNIT_100000S 5 /* hundred-thousandths */ -#define TIFFTAG_TRANSFERFUNCTION 301 /* !colorimetry info */ -#define TIFFTAG_SOFTWARE 305 /* name & release */ -#define TIFFTAG_DATETIME 306 /* creation date and time */ -#define TIFFTAG_ARTIST 315 /* creator of image */ -#define TIFFTAG_HOSTCOMPUTER 316 /* machine where created */ -#define TIFFTAG_PREDICTOR 317 /* prediction scheme w/ LZW */ -#define PREDICTOR_NONE 1 /* no prediction scheme used */ -#define PREDICTOR_HORIZONTAL 2 /* horizontal differencing */ -#define PREDICTOR_FLOATINGPOINT 3 /* floating point predictor */ -#define TIFFTAG_WHITEPOINT 318 /* image white point */ -#define TIFFTAG_PRIMARYCHROMATICITIES 319 /* !primary chromaticities */ -#define TIFFTAG_COLORMAP 320 /* RGB map for palette image */ -#define TIFFTAG_HALFTONEHINTS 321 /* !highlight+shadow info */ -#define TIFFTAG_TILEWIDTH 322 /* !tile width in pixels */ -#define TIFFTAG_TILELENGTH 323 /* !tile height in pixels */ -#define TIFFTAG_TILEOFFSETS 324 /* !offsets to data tiles */ -#define TIFFTAG_TILEBYTECOUNTS 325 /* !byte counts for tiles */ -#define TIFFTAG_BADFAXLINES 326 /* lines w/ wrong pixel count */ -#define TIFFTAG_CLEANFAXDATA 327 /* regenerated line info */ -#define CLEANFAXDATA_CLEAN 0 /* no errors detected */ -#define CLEANFAXDATA_REGENERATED 1 /* receiver regenerated lines */ -#define CLEANFAXDATA_UNCLEAN 2 /* uncorrected errors exist */ -#define TIFFTAG_CONSECUTIVEBADFAXLINES 328 /* max consecutive bad lines */ -#define TIFFTAG_SUBIFD 330 /* subimage descriptors */ -#define TIFFTAG_INKSET 332 /* !inks in separated image */ -#define INKSET_CMYK 1 /* !cyan-magenta-yellow-black color */ -#define INKSET_MULTIINK 2 /* !multi-ink or hi-fi color */ -#define TIFFTAG_INKNAMES 333 /* !ascii names of inks */ -#define TIFFTAG_NUMBEROFINKS 334 /* !number of inks */ -#define TIFFTAG_DOTRANGE 336 /* !0% and 100% dot codes */ -#define TIFFTAG_TARGETPRINTER 337 /* !separation target */ -#define TIFFTAG_EXTRASAMPLES 338 /* !info about extra samples */ -#define EXTRASAMPLE_UNSPECIFIED 0 /* !unspecified data */ -#define EXTRASAMPLE_ASSOCALPHA 1 /* !associated alpha data */ -#define EXTRASAMPLE_UNASSALPHA 2 /* !unassociated alpha data */ -#define TIFFTAG_SAMPLEFORMAT 339 /* !data sample format */ -#define SAMPLEFORMAT_UINT 1 /* !unsigned integer data */ -#define SAMPLEFORMAT_INT 2 /* !signed integer data */ -#define SAMPLEFORMAT_IEEEFP 3 /* !IEEE floating point data */ -#define SAMPLEFORMAT_VOID 4 /* !untyped data */ -#define SAMPLEFORMAT_COMPLEXINT 5 /* !complex signed int */ -#define SAMPLEFORMAT_COMPLEXIEEEFP 6 /* !complex ieee floating */ -#define TIFFTAG_SMINSAMPLEVALUE 340 /* !variable MinSampleValue */ -#define TIFFTAG_SMAXSAMPLEVALUE 341 /* !variable MaxSampleValue */ -#define TIFFTAG_CLIPPATH 343 /* %ClipPath [Adobe TIFF technote 2] */ -#define TIFFTAG_XCLIPPATHUNITS 344 /* %XClipPathUnits [Adobe TIFF technote 2] */ -#define TIFFTAG_YCLIPPATHUNITS 345 /* %YClipPathUnits [Adobe TIFF technote 2] */ -#define TIFFTAG_INDEXED 346 /* %Indexed [Adobe TIFF Technote 3] */ -#define TIFFTAG_JPEGTABLES 347 /* %JPEG table stream */ -#define TIFFTAG_OPIPROXY 351 /* %OPI Proxy [Adobe TIFF technote] */ -/* Tags 400-435 are from the TIFF/FX spec */ -#define TIFFTAG_GLOBALPARAMETERSIFD 400 /* ! */ -#define TIFFTAG_PROFILETYPE 401 /* ! */ -#define PROFILETYPE_UNSPECIFIED 0 /* ! */ -#define PROFILETYPE_G3_FAX 1 /* ! */ -#define TIFFTAG_FAXPROFILE 402 /* ! */ -#define FAXPROFILE_S 1 /* !TIFF/FX FAX profile S */ -#define FAXPROFILE_F 2 /* !TIFF/FX FAX profile F */ -#define FAXPROFILE_J 3 /* !TIFF/FX FAX profile J */ -#define FAXPROFILE_C 4 /* !TIFF/FX FAX profile C */ -#define FAXPROFILE_L 5 /* !TIFF/FX FAX profile L */ -#define FAXPROFILE_M 6 /* !TIFF/FX FAX profile LM */ -#define TIFFTAG_CODINGMETHODS 403 /* !TIFF/FX coding methods */ -#define CODINGMETHODS_T4_1D (1 << 1) /* !T.4 1D */ -#define CODINGMETHODS_T4_2D (1 << 2) /* !T.4 2D */ -#define CODINGMETHODS_T6 (1 << 3) /* !T.6 */ -#define CODINGMETHODS_T85 (1 << 4) /* !T.85 JBIG */ -#define CODINGMETHODS_T42 (1 << 5) /* !T.42 JPEG */ -#define CODINGMETHODS_T43 (1 << 6) /* !T.43 colour by layered JBIG */ -#define TIFFTAG_VERSIONYEAR 404 /* !TIFF/FX version year */ -#define TIFFTAG_MODENUMBER 405 /* !TIFF/FX mode number */ -#define TIFFTAG_DECODE 433 /* !TIFF/FX decode */ -#define TIFFTAG_IMAGEBASECOLOR 434 /* !TIFF/FX image base colour */ -#define TIFFTAG_T82OPTIONS 435 /* !TIFF/FX T.82 options */ -/* - * Tags 512-521 are obsoleted by Technical Note #2 which specifies a - * revised JPEG-in-TIFF scheme. - */ -#define TIFFTAG_JPEGPROC 512 /* !JPEG processing algorithm */ -#define JPEGPROC_BASELINE 1 /* !baseline sequential */ -#define JPEGPROC_LOSSLESS 14 /* !Huffman coded lossless */ -#define TIFFTAG_JPEGIFOFFSET 513 /* !pointer to SOI marker */ -#define TIFFTAG_JPEGIFBYTECOUNT 514 /* !JFIF stream length */ -#define TIFFTAG_JPEGRESTARTINTERVAL 515 /* !restart interval length */ -#define TIFFTAG_JPEGLOSSLESSPREDICTORS 517 /* !lossless proc predictor */ -#define TIFFTAG_JPEGPOINTTRANSFORM 518 /* !lossless point transform */ -#define TIFFTAG_JPEGQTABLES 519 /* !Q matrix offsets */ -#define TIFFTAG_JPEGDCTABLES 520 /* !DCT table offsets */ -#define TIFFTAG_JPEGACTABLES 521 /* !AC coefficient offsets */ -#define TIFFTAG_YCBCRCOEFFICIENTS 529 /* !RGB -> YCbCr transform */ -#define TIFFTAG_YCBCRSUBSAMPLING 530 /* !YCbCr subsampling factors */ -#define TIFFTAG_YCBCRPOSITIONING 531 /* !subsample positioning */ -#define YCBCRPOSITION_CENTERED 1 /* !as in PostScript Level 2 */ -#define YCBCRPOSITION_COSITED 2 /* !as in CCIR 601-1 */ -#define TIFFTAG_REFERENCEBLACKWHITE 532 /* !colorimetry info */ -#define TIFFTAG_STRIPROWCOUNTS 559 /* !TIFF/FX strip row counts */ -#define TIFFTAG_XMLPACKET 700 /* %XML packet [Adobe XMP Specification, January 2004 */ -#define TIFFTAG_OPIIMAGEID 32781 /* %OPI ImageID [Adobe TIFF technote] */ -/* For eiStream Annotation Specification, Version 1.00.06 see - * http://web.archive.org/web/20050309141348/http://www.kofile.com/support%20pro/faqs/annospec.htm */ -#define TIFFTAG_TIFFANNOTATIONDATA 32932 -/* tags 32952-32956 are private tags registered to Island Graphics */ -#define TIFFTAG_REFPTS 32953 /* image reference points */ -#define TIFFTAG_REGIONTACKPOINT 32954 /* region-xform tack point */ -#define TIFFTAG_REGIONWARPCORNERS 32955 /* warp quadrilateral */ -#define TIFFTAG_REGIONAFFINE 32956 /* affine transformation mat */ -/* tags 32995-32999 are private tags registered to SGI */ -#define TIFFTAG_MATTEING 32995 /* $use ExtraSamples */ -#define TIFFTAG_DATATYPE 32996 /* $use SampleFormat */ -#define TIFFTAG_IMAGEDEPTH 32997 /* z depth of image */ -#define TIFFTAG_TILEDEPTH 32998 /* z depth/data tile */ -/* tags 33300-33309 are private tags registered to Pixar */ -/* - * TIFFTAG_PIXAR_IMAGEFULLWIDTH and TIFFTAG_PIXAR_IMAGEFULLLENGTH - * are set when an image has been cropped out of a larger image. - * They reflect the size of the original uncropped image. - * The TIFFTAG_XPOSITION and TIFFTAG_YPOSITION can be used - * to determine the position of the smaller image in the larger one. - */ -#define TIFFTAG_PIXAR_IMAGEFULLWIDTH 33300 /* full image size in x */ -#define TIFFTAG_PIXAR_IMAGEFULLLENGTH 33301 /* full image size in y */ -/* Tags 33302-33306 are used to identify special image modes and data - * used by Pixar's texture formats. - */ -#define TIFFTAG_PIXAR_TEXTUREFORMAT 33302 /* texture map format */ -#define TIFFTAG_PIXAR_WRAPMODES 33303 /* s & t wrap modes */ -#define TIFFTAG_PIXAR_FOVCOT 33304 /* cotan(fov) for env. maps */ -#define TIFFTAG_PIXAR_MATRIX_WORLDTOSCREEN 33305 -#define TIFFTAG_PIXAR_MATRIX_WORLDTOCAMERA 33306 -/* tag 33405 is a private tag registered to Eastman Kodak */ -#define TIFFTAG_WRITERSERIALNUMBER 33405 /* device serial number */ -#define TIFFTAG_CFAREPEATPATTERNDIM 33421 /* (alias for TIFFTAG_EP_CFAREPEATPATTERNDIM)*/ -#define TIFFTAG_CFAPATTERN 33422 /* (alias for TIFFTAG_EP_CFAPATTERN) */ -#define TIFFTAG_BATTERYLEVEL 33423 /* (alias for TIFFTAG_EP_BATTERYLEVEL) */ -/* tag 33432 is listed in the 6.0 spec w/ unknown ownership */ -#define TIFFTAG_COPYRIGHT 33432 /* copyright string */ -/* Tags 33445-33452 are used for Molecular Dynamics GEL fileformat, - * see http://research.stowers-institute.org/mcm/efg/ScientificSoftware/Utility/TiffTags/GEL-FileFormat.pdf - * (2023: the above web site is unavailable but tags are explained briefly at - * https://www.awaresystems.be/imaging/tiff/tifftags/docs/gel.html - */ -#define TIFFTAG_MD_FILETAG 33445 /* Specifies the pixel data format encoding in the GEL file format. */ -#define TIFFTAG_MD_SCALEPIXEL 33446 /* scale factor */ -#define TIFFTAG_MD_COLORTABLE 33447 /* conversion from 16bit to 8bit */ -#define TIFFTAG_MD_LABNAME 33448 /* name of the lab that scanned this file. */ -#define TIFFTAG_MD_SAMPLEINFO 33449 /* information about the scanned GEL sample */ -#define TIFFTAG_MD_PREPDATE 33450 /* information about the date the sample was prepared YY/MM/DD */ -#define TIFFTAG_MD_PREPTIME 33451 /* information about the time the sample was prepared HH:MM*/ -#define TIFFTAG_MD_FILEUNITS 33452 /* Units for data in this file, as used in the GEL file format. */ -/* IPTC TAG from RichTIFF specifications */ -#define TIFFTAG_RICHTIFFIPTC 33723 -#define TIFFTAG_INGR_PACKET_DATA_TAG 33918 /* Intergraph Application specific storage. */ -#define TIFFTAG_INGR_FLAG_REGISTERS 33919 /* Intergraph Application specific flags. */ -#define TIFFTAG_IRASB_TRANSORMATION_MATRIX 33920 /* Originally part of Intergraph's GeoTIFF tags, but likely understood by IrasB only. */ -#define TIFFTAG_MODELTIEPOINTTAG 33922 /* GeoTIFF */ -/* 34016-34029 are reserved for ANSI IT8 TIFF/IT */ -#define TIFFTAG_STONITS 37439 /* Sample value to Nits */ -/* tag 34929 is a private tag registered to FedEx */ -#define TIFFTAG_FEDEX_EDR 34929 /* unknown use */ -#define TIFFTAG_IMAGESOURCEDATA 37724 /* http://justsolve.archiveteam.org/wiki/PSD, http://www.adobe.com/devnet-apps/photoshop/fileformatashtml/ */ -#define TIFFTAG_INTEROPERABILITYIFD 40965 /* Pointer to EXIF Interoperability private directory */ -#define TIFFTAG_GDAL_METADATA 42112 /* Used by the GDAL library */ -#define TIFFTAG_GDAL_NODATA 42113 /* Used by the GDAL library */ -#define TIFFTAG_OCE_SCANJOB_DESCRIPTION 50215 /* Used in the Oce scanning process */ -#define TIFFTAG_OCE_APPLICATION_SELECTOR 50216 /* Used in the Oce scanning process. */ -#define TIFFTAG_OCE_IDENTIFICATION_NUMBER 50217 -#define TIFFTAG_OCE_IMAGELOGIC_CHARACTERISTICS 50218 -/* tags 50674 to 50677 are reserved for ESRI */ -#define TIFFTAG_LERC_PARAMETERS 50674 /* Stores LERC version and additional compression method */ - -/* Adobe Digital Negative (DNG) format tags */ -#define TIFFTAG_DNGVERSION 50706 /* &DNG version number */ -#define TIFFTAG_DNGBACKWARDVERSION 50707 /* &DNG compatibility version */ -#define TIFFTAG_UNIQUECAMERAMODEL 50708 /* &name for the camera model */ -#define TIFFTAG_LOCALIZEDCAMERAMODEL 50709 /* &localized camera model name (UTF-8) */ -#define TIFFTAG_CFAPLANECOLOR 50710 /* &CFAPattern->LinearRaw space mapping */ -#define TIFFTAG_CFALAYOUT 50711 /* &spatial layout of the CFA */ -#define TIFFTAG_LINEARIZATIONTABLE 50712 /* &lookup table description */ -#define TIFFTAG_BLACKLEVELREPEATDIM 50713 /* &repeat pattern size for the BlackLevel tag */ -#define TIFFTAG_BLACKLEVEL 50714 /* &zero light encoding level */ -#define TIFFTAG_BLACKLEVELDELTAH 50715 /* &zero light encoding level differences (columns) */ -#define TIFFTAG_BLACKLEVELDELTAV 50716 /* &zero light encoding level differences (rows) */ -#define TIFFTAG_WHITELEVEL 50717 /* &fully saturated encoding level */ -#define TIFFTAG_DEFAULTSCALE 50718 /* &default scale factors */ -#define TIFFTAG_DEFAULTCROPORIGIN 50719 /* &origin of the final image area */ -#define TIFFTAG_DEFAULTCROPSIZE 50720 /* &size of the final image area */ -#define TIFFTAG_COLORMATRIX1 50721 /* &XYZ->reference color space transformation matrix 1 */ -#define TIFFTAG_COLORMATRIX2 50722 /* &XYZ->reference color space transformation matrix 2 */ -#define TIFFTAG_CAMERACALIBRATION1 50723 /* &calibration matrix 1 */ -#define TIFFTAG_CAMERACALIBRATION2 50724 /* &calibration matrix 2 */ -#define TIFFTAG_REDUCTIONMATRIX1 50725 /* &dimensionality reduction matrix 1 */ -#define TIFFTAG_REDUCTIONMATRIX2 50726 /* &dimensionality reduction matrix 2 */ -#define TIFFTAG_ANALOGBALANCE 50727 /* &gain applied the stored raw values*/ -#define TIFFTAG_ASSHOTNEUTRAL 50728 /* &selected white balance in linear reference space */ -#define TIFFTAG_ASSHOTWHITEXY 50729 /* &selected white balance in x-y chromaticity coordinates */ -#define TIFFTAG_BASELINEEXPOSURE 50730 /* &how much to move the zero point */ -#define TIFFTAG_BASELINENOISE 50731 /* &relative noise level */ -#define TIFFTAG_BASELINESHARPNESS 50732 /* &relative amount of sharpening */ -/* TIFFTAG_BAYERGREENSPLIT: &how closely the values of the green pixels in the blue/green rows - * track the values of the green pixels in the red/green rows */ -#define TIFFTAG_BAYERGREENSPLIT 50733 -#define TIFFTAG_LINEARRESPONSELIMIT 50734 /* &non-linear encoding range */ -#define TIFFTAG_CAMERASERIALNUMBER 50735 /* &camera's serial number */ -#define TIFFTAG_LENSINFO 50736 /* info about the lens */ -#define TIFFTAG_CHROMABLURRADIUS 50737 /* &chroma blur radius */ -#define TIFFTAG_ANTIALIASSTRENGTH 50738 /* &relative strength of the camera's anti-alias filter */ -#define TIFFTAG_SHADOWSCALE 50739 /* &used by Adobe Camera Raw */ -#define TIFFTAG_DNGPRIVATEDATA 50740 /* &manufacturer's private data */ -#define TIFFTAG_MAKERNOTESAFETY 50741 /* &whether the EXIF MakerNote tag is safe to preserve along with the rest of the EXIF data */ -#define TIFFTAG_CALIBRATIONILLUMINANT1 50778 /* &illuminant 1 */ -#define TIFFTAG_CALIBRATIONILLUMINANT2 50779 /* &illuminant 2 */ -#define TIFFTAG_BESTQUALITYSCALE 50780 /* &best quality multiplier */ -#define TIFFTAG_RAWDATAUNIQUEID 50781 /* &unique identifier for the raw image data */ -#define TIFFTAG_ORIGINALRAWFILENAME 50827 /* &file name of the original raw file (UTF-8) */ -#define TIFFTAG_ORIGINALRAWFILEDATA 50828 /* &contents of the original raw file */ -#define TIFFTAG_ACTIVEAREA 50829 /* &active (non-masked) pixels of the sensor */ -#define TIFFTAG_MASKEDAREAS 50830 /* &list of coordinates of fully masked pixels */ -#define TIFFTAG_ASSHOTICCPROFILE 50831 /* &these two tags used to */ -#define TIFFTAG_ASSHOTPREPROFILEMATRIX 50832 /* map cameras's color space into ICC profile space */ -#define TIFFTAG_CURRENTICCPROFILE 50833 /* & */ -#define TIFFTAG_CURRENTPREPROFILEMATRIX 50834 /* & */ - -/* DNG 1.2.0.0 */ -#define TIFFTAG_COLORIMETRICREFERENCE 50879 /* &colorimetric reference */ -#define TIFFTAG_CAMERACALIBRATIONSIGNATURE 50931 /* &camera calibration signature (UTF-8) */ -#define TIFFTAG_PROFILECALIBRATIONSIGNATURE 50932 /* &profile calibration signature (UTF-8) */ -/* TIFFTAG_EXTRACAMERAPROFILES 50933 &extra camera profiles : is already defined for GeoTIFF DGIWG */ -#define TIFFTAG_ASSHOTPROFILENAME 50934 /* &as shot profile name (UTF-8) */ -#define TIFFTAG_NOISEREDUCTIONAPPLIED 50935 /* &amount of applied noise reduction */ -#define TIFFTAG_PROFILENAME 50936 /* &camera profile name (UTF-8) */ -#define TIFFTAG_PROFILEHUESATMAPDIMS 50937 /* &dimensions of HSV mapping */ -#define TIFFTAG_PROFILEHUESATMAPDATA1 50938 /* &first HSV mapping table */ -#define TIFFTAG_PROFILEHUESATMAPDATA2 50939 /* &second HSV mapping table */ -#define TIFFTAG_PROFILETONECURVE 50940 /* &default tone curve */ -#define TIFFTAG_PROFILEEMBEDPOLICY 50941 /* &profile embedding policy */ -#define TIFFTAG_PROFILECOPYRIGHT 50942 /* &profile copyright information (UTF-8) */ -#define TIFFTAG_FORWARDMATRIX1 50964 /* &matrix for mapping white balanced camera colors to XYZ D50 */ -#define TIFFTAG_FORWARDMATRIX2 50965 /* &matrix for mapping white balanced camera colors to XYZ D50 */ -#define TIFFTAG_PREVIEWAPPLICATIONNAME 50966 /* &name of application that created preview (UTF-8) */ -#define TIFFTAG_PREVIEWAPPLICATIONVERSION 50967 /* &version of application that created preview (UTF-8) */ -#define TIFFTAG_PREVIEWSETTINGSNAME 50968 /* &name of conversion settings (UTF-8) */ -#define TIFFTAG_PREVIEWSETTINGSDIGEST 50969 /* &unique id of conversion settings */ -#define TIFFTAG_PREVIEWCOLORSPACE 50970 /* &preview color space */ -#define TIFFTAG_PREVIEWDATETIME 50971 /* &date/time preview was rendered */ -#define TIFFTAG_RAWIMAGEDIGEST 50972 /* &md5 of raw image data */ -#define TIFFTAG_ORIGINALRAWFILEDIGEST 50973 /* &md5 of the data stored in the OriginalRawFileData tag */ -#define TIFFTAG_SUBTILEBLOCKSIZE 50974 /* &subtile block size */ -#define TIFFTAG_ROWINTERLEAVEFACTOR 50975 /* &number of interleaved fields */ -#define TIFFTAG_PROFILELOOKTABLEDIMS 50981 /* &num of input samples in each dim of default "look" table */ -#define TIFFTAG_PROFILELOOKTABLEDATA 50982 /* &default "look" table for use as starting point */ - -/* DNG 1.3.0.0 */ -#define TIFFTAG_OPCODELIST1 51008 /* &opcodes that should be applied to raw image after reading */ -#define TIFFTAG_OPCODELIST2 51009 /* &opcodes that should be applied after mapping to linear reference */ -#define TIFFTAG_OPCODELIST3 51022 /* &opcodes that should be applied after demosaicing */ -#define TIFFTAG_NOISEPROFILE 51041 /* &noise profile */ - -/* DNG 1.4.0.0 */ -#define TIFFTAG_DEFAULTUSERCROP 51125 /* &default user crop rectangle in relative coords */ -#define TIFFTAG_DEFAULTBLACKRENDER 51110 /* &black rendering hint */ -#define TIFFTAG_BASELINEEXPOSUREOFFSET 51109 /* &baseline exposure offset */ -#define TIFFTAG_PROFILELOOKTABLEENCODING 51108 /* &3D LookTable indexing conversion */ -#define TIFFTAG_PROFILEHUESATMAPENCODING 51107 /* &3D HueSatMap indexing conversion */ -#define TIFFTAG_ORIGINALDEFAULTFINALSIZE 51089 /* &default final size of larger original file for this proxy */ -#define TIFFTAG_ORIGINALBESTQUALITYFINALSIZE 51090 /* &best quality final size of larger original file for this proxy */ -#define TIFFTAG_ORIGINALDEFAULTCROPSIZE 51091 /* &the default crop size of larger original file for this proxy */ -#define TIFFTAG_NEWRAWIMAGEDIGEST 51111 /* &modified MD5 digest of the raw image data */ -#define TIFFTAG_RAWTOPREVIEWGAIN 51112 /* &The gain between the main raw FD and the preview IFD containing this tag */ - -/* DNG 1.5.0.0 */ -#define TIFFTAG_DEPTHFORMAT 51177 /* &encoding of the depth data in the file */ -#define TIFFTAG_DEPTHNEAR 51178 /* &distance from the camera represented by value 0 in the depth map */ -#define TIFFTAG_DEPTHFAR 51179 /* &distance from the camera represented by the maximum value in the depth map */ -#define TIFFTAG_DEPTHUNITS 51180 /* &measurement units for DepthNear and DepthFar */ -#define TIFFTAG_DEPTHMEASURETYPE 51181 /* &measurement geometry for the depth map */ -#define TIFFTAG_ENHANCEPARAMS 51182 /* &a string that documents how the enhanced image data was processed. */ - -/* DNG 1.6.0.0 */ -#define TIFFTAG_PROFILEGAINTABLEMAP 52525 /* &spatially varying gain tables that can be applied as starting point */ -#define TIFFTAG_SEMANTICNAME 52526 /* &a string that identifies the semantic mask */ -#define TIFFTAG_SEMANTICINSTANCEID 52528 /* &a string that identifies a specific instance in a semantic mask */ -#define TIFFTAG_MASKSUBAREA 52536 /* &the crop rectangle of this IFD's mask, relative to the main image */ -#define TIFFTAG_RGBTABLES 52543 /* &color transforms to apply to masked image regions */ -#define TIFFTAG_CALIBRATIONILLUMINANT3 52529 /* &the illuminant used for the third set of color calibration tags */ -#define TIFFTAG_COLORMATRIX3 52531 /* &matrix to convert XYZ values to reference camera native color space under CalibrationIlluminant3 */ -#define TIFFTAG_CAMERACALIBRATION3 52530 /* &matrix to transform reference camera native space values to individual camera native space values under CalibrationIlluminant3 */ -#define TIFFTAG_REDUCTIONMATRIX3 52538 /* &dimensionality reduction matrix for use in color conversion to XYZ under CalibrationIlluminant3 */ -#define TIFFTAG_PROFILEHUESATMAPDATA3 52537 /* &the data for the third HSV table */ -#define TIFFTAG_FORWARDMATRIX3 52532 /* &matrix to map white balanced camera colors to XYZ D50 */ -#define TIFFTAG_ILLUMINANTDATA1 52533 /* &data for the first calibration illuminant */ -#define TIFFTAG_ILLUMINANTDATA2 52534 /* &data for the second calibration illuminant */ -#define TIFFTAG_ILLUMINANTDATA3 53535 /* &data for the third calibration illuminant */ - -/* TIFF/EP */ -#define TIFFTAG_EP_CFAREPEATPATTERNDIM 33421 /* dimensions of CFA pattern */ -#define TIFFTAG_EP_CFAPATTERN 33422 /* color filter array pattern */ -#define TIFFTAG_EP_BATTERYLEVEL 33423 /* battery level (rational or ASCII) */ -#define TIFFTAG_EP_INTERLACE 34857 /* Number of multi-field images */ -/* TIFFTAG_EP_IPTC_NAA and TIFFTAG_RICHTIFFIPTC share the same tag number (33723) - * LibTIFF type is UNDEFINED or BYTE, but often times incorrectly specified as LONG, - * because TIFF/EP (ISO/DIS 12234-2) specifies type LONG or ASCII. */ -#define TIFFTAG_EP_IPTC_NAA 33723 /* Alias IPTC/NAA Newspaper Association RichTIFF */ -#define TIFFTAG_EP_TIMEZONEOFFSET 34858 /* Time zone offset relative to UTC */ -#define TIFFTAG_EP_SELFTIMERMODE 34859 /* Number of seconds capture was delayed from button press */ -#define TIFFTAG_EP_FLASHENERGY 37387 /* Flash energy, or range if there is uncertainty */ -#define TIFFTAG_EP_SPATIALFREQUENCYRESPONSE 37388 /* Spatial frequency response */ -#define TIFFTAG_EP_NOISE 37389 /* Camera noise measurement values */ -#define TIFFTAG_EP_FOCALPLANEXRESOLUTION 37390 /* Focal plane X resolution */ -#define TIFFTAG_EP_FOCALPLANEYRESOLUTION 37391 /* Focal plane Y resolution */ -#define TIFFTAG_EP_FOCALPLANERESOLUTIONUNIT 37392 /* Focal plane resolution unit */ -#define TIFFTAG_EP_IMAGENUMBER 37393 /* Number of image when several of burst shot stored in same TIFF/EP */ -#define TIFFTAG_EP_SECURITYCLASSIFICATION 37394 /* Security classification */ -#define TIFFTAG_EP_IMAGEHISTORY 37395 /* Record of what has been done to the image */ -#define TIFFTAG_EP_EXPOSUREINDEX 37397 /* Exposure index */ -#define TIFFTAG_EP_STANDARDID 37398 /* TIFF/EP standard version, n.n.n.n */ -#define TIFFTAG_EP_SENSINGMETHOD 37399 /* Type of image sensor */ -/* - * TIFF/EP tags equivalent to EXIF tags - * Note that TIFF-EP and EXIF use nearly the same metadata tag set, but TIFF-EP stores the tags in IFD 0, - * while EXIF store the tags in a separate IFD. Either location is allowed by DNG, but the EXIF location is preferred. - */ -#define TIFFTAG_EP_EXPOSURETIME 33434 /* Exposure time */ -#define TIFFTAG_EP_FNUMBER 33437 /* F number */ -#define TIFFTAG_EP_EXPOSUREPROGRAM 34850 /* Exposure program */ -#define TIFFTAG_EP_SPECTRALSENSITIVITY 34852 /* Spectral sensitivity */ -#define TIFFTAG_EP_ISOSPEEDRATINGS 34855 /* ISO speed rating */ -#define TIFFTAG_EP_OECF 34856 /* Optoelectric conversion factor */ -#define TIFFTAG_EP_DATETIMEORIGINAL 36867 /* Date and time of original data generation */ -#define TIFFTAG_EP_COMPRESSEDBITSPERPIXEL 37122 /* Image compression mode */ -#define TIFFTAG_EP_SHUTTERSPEEDVALUE 37377 /* Shutter speed */ -#define TIFFTAG_EP_APERTUREVALUE 37378 /* Aperture */ -#define TIFFTAG_EP_BRIGHTNESSVALUE 37379 /* Brightness */ -#define TIFFTAG_EP_EXPOSUREBIASVALUE 37380 /* Exposure bias */ -#define TIFFTAG_EP_MAXAPERTUREVALUE 37381 /* Maximum lens aperture */ -#define TIFFTAG_EP_SUBJECTDISTANCE 37382 /* Subject distance */ -#define TIFFTAG_EP_METERINGMODE 37383 /* Metering mode */ -#define TIFFTAG_EP_LIGHTSOURCE 37384 /* Light source */ -#define TIFFTAG_EP_FLASH 37385 /* Flash */ -#define TIFFTAG_EP_FOCALLENGTH 37386 /* Lens focal length */ -#define TIFFTAG_EP_SUBJECTLOCATION 37396 /* Subject location (area) */ - -#define TIFFTAG_RPCCOEFFICIENT 50844 /* Define by GDAL for geospatial georeferencing through RPC: http://geotiff.maptools.org/rpc_prop.html */ -#define TIFFTAG_ALIAS_LAYER_METADATA 50784 /* Alias Sketchbook Pro layer usage description. */ - -/* GeoTIFF DGIWG */ -#define TIFFTAG_TIFF_RSID 50908 /* https://www.awaresystems.be/imaging/tiff/tifftags/tiff_rsid.html */ -#define TIFFTAG_GEO_METADATA 50909 /* https://www.awaresystems.be/imaging/tiff/tifftags/geo_metadata.html */ -#define TIFFTAG_EXTRACAMERAPROFILES 50933 /* http://wwwimages.adobe.com/www.adobe.com/content/dam/Adobe/en/products/photoshop/pdfs/dng_spec_1.4.0.0.pdf */ - -/* tag 65535 is an undefined tag used by Eastman Kodak */ -#define TIFFTAG_DCSHUESHIFTVALUES 65535 /* hue shift correction data */ - -/* - * The following are ``pseudo tags'' that can be used to control - * codec-specific functionality. These tags are not written to file. - * Note that these values start at 0xffff+1 so that they'll never - * collide with Aldus-assigned tags. - * - * If you want your private pseudo tags ``registered'' (i.e. added to - * this file), please post a bug report via the tracking system at - * http://www.remotesensing.org/libtiff/bugs.html with the appropriate - * C definitions to add. - */ -#define TIFFTAG_FAXMODE 65536 /* Group 3/4 format control */ -#define FAXMODE_CLASSIC 0x0000 /* default, include RTC */ -#define FAXMODE_NORTC 0x0001 /* no RTC at end of data */ -#define FAXMODE_NOEOL 0x0002 /* no EOL code at end of row */ -#define FAXMODE_BYTEALIGN 0x0004 /* byte align row */ -#define FAXMODE_WORDALIGN 0x0008 /* word align row */ -#define FAXMODE_CLASSF FAXMODE_NORTC /* TIFF Class F */ -#define TIFFTAG_JPEGQUALITY 65537 /* Compression quality level */ -/* Note: quality level is on the IJG 0-100 scale. Default value is 75 */ -#define TIFFTAG_JPEGCOLORMODE 65538 /* Auto RGB<=>YCbCr convert? */ -#define JPEGCOLORMODE_RAW 0x0000 /* no conversion (default) */ -#define JPEGCOLORMODE_RGB 0x0001 /* do auto conversion */ -#define TIFFTAG_JPEGTABLESMODE 65539 /* What to put in JPEGTables */ -#define JPEGTABLESMODE_QUANT 0x0001 /* include quantization tbls */ -#define JPEGTABLESMODE_HUFF 0x0002 /* include Huffman tbls */ -/* Note: default is JPEGTABLESMODE_QUANT | JPEGTABLESMODE_HUFF */ -#define TIFFTAG_FAXFILLFUNC 65540 /* G3/G4 fill function */ -#define TIFFTAG_PIXARLOGDATAFMT 65549 /* PixarLogCodec I/O data sz */ -#define PIXARLOGDATAFMT_8BIT 0 /* regular u_char samples */ -#define PIXARLOGDATAFMT_8BITABGR 1 /* ABGR-order u_chars */ -#define PIXARLOGDATAFMT_11BITLOG 2 /* 11-bit log-encoded (raw) */ -#define PIXARLOGDATAFMT_12BITPICIO 3 /* as per PICIO (1.0==2048) */ -#define PIXARLOGDATAFMT_16BIT 4 /* signed short samples */ -#define PIXARLOGDATAFMT_FLOAT 5 /* IEEE float samples */ -/* 65550-65556 are allocated to Oceana Matrix */ -#define TIFFTAG_DCSIMAGERTYPE 65550 /* imager model & filter */ -#define DCSIMAGERMODEL_M3 0 /* M3 chip (1280 x 1024) */ -#define DCSIMAGERMODEL_M5 1 /* M5 chip (1536 x 1024) */ -#define DCSIMAGERMODEL_M6 2 /* M6 chip (3072 x 2048) */ -#define DCSIMAGERFILTER_IR 0 /* infrared filter */ -#define DCSIMAGERFILTER_MONO 1 /* monochrome filter */ -#define DCSIMAGERFILTER_CFA 2 /* color filter array */ -#define DCSIMAGERFILTER_OTHER 3 /* other filter */ -#define TIFFTAG_DCSINTERPMODE 65551 /* interpolation mode */ -#define DCSINTERPMODE_NORMAL 0x0 /* whole image, default */ -#define DCSINTERPMODE_PREVIEW 0x1 /* preview of image (384x256) */ -#define TIFFTAG_DCSBALANCEARRAY 65552 /* color balance values */ -#define TIFFTAG_DCSCORRECTMATRIX 65553 /* color correction values */ -#define TIFFTAG_DCSGAMMA 65554 /* gamma value */ -#define TIFFTAG_DCSTOESHOULDERPTS 65555 /* toe & shoulder points */ -#define TIFFTAG_DCSCALIBRATIONFD 65556 /* calibration file desc */ -/* Note: quality level is on the ZLIB 1-9 scale. Default value is -1 */ -#define TIFFTAG_ZIPQUALITY 65557 /* compression quality level */ -#define TIFFTAG_PIXARLOGQUALITY 65558 /* PixarLog uses same scale */ -/* 65559 is allocated to Oceana Matrix */ -#define TIFFTAG_DCSCLIPRECTANGLE 65559 /* area of image to acquire */ -#define TIFFTAG_SGILOGDATAFMT 65560 /* SGILog user data format */ -#define SGILOGDATAFMT_FLOAT 0 /* IEEE float samples */ -#define SGILOGDATAFMT_16BIT 1 /* 16-bit samples */ -#define SGILOGDATAFMT_RAW 2 /* uninterpreted data */ -#define SGILOGDATAFMT_8BIT 3 /* 8-bit RGB monitor values */ -#define TIFFTAG_SGILOGENCODE 65561 /* SGILog data encoding control*/ -#define SGILOGENCODE_NODITHER 0 /* do not dither encoded values*/ -#define SGILOGENCODE_RANDITHER 1 /* randomly dither encd values */ -#define TIFFTAG_LZMAPRESET 65562 /* LZMA2 preset (compression level) */ -#define TIFFTAG_PERSAMPLE 65563 /* interface for per sample tags */ -#define PERSAMPLE_MERGED 0 /* present as a single value */ -#define PERSAMPLE_MULTI 1 /* present as multiple values */ -#define TIFFTAG_ZSTD_LEVEL 65564 /* ZSTD compression level */ -#define TIFFTAG_LERC_VERSION 65565 /* LERC version */ -#define LERC_VERSION_2_4 4 -#define TIFFTAG_LERC_ADD_COMPRESSION 65566 /* LERC additional compression */ -#define LERC_ADD_COMPRESSION_NONE 0 -#define LERC_ADD_COMPRESSION_DEFLATE 1 -#define LERC_ADD_COMPRESSION_ZSTD 2 -#define TIFFTAG_LERC_MAXZERROR 65567 /* LERC maximum error */ -#define TIFFTAG_WEBP_LEVEL 65568 /* WebP compression level */ -#define TIFFTAG_WEBP_LOSSLESS 65569 /* WebP lossless/lossy */ -#define TIFFTAG_WEBP_LOSSLESS_EXACT 65571 /* WebP lossless exact mode. Set-only mode. Default is 1. Can be set to 0 to increase compression rate, but R,G,B in areas where alpha = 0 will not be preserved */ -#define TIFFTAG_DEFLATE_SUBCODEC 65570 /* ZIP codec: to get/set the sub-codec to use. Will default to libdeflate when available */ -#define DEFLATE_SUBCODEC_ZLIB 0 -#define DEFLATE_SUBCODEC_LIBDEFLATE 1 - -/* - * EXIF tags - */ -#define EXIFTAG_EXPOSURETIME 33434 /* Exposure time */ -#define EXIFTAG_FNUMBER 33437 /* F number */ -#define EXIFTAG_EXPOSUREPROGRAM 34850 /* Exposure program */ -#define EXIFTAG_SPECTRALSENSITIVITY 34852 /* Spectral sensitivity */ -/* After EXIF 2.2.1 ISOSpeedRatings is named PhotographicSensitivity. - In addition, while "Count=Any", only 1 count should be used. */ -#define EXIFTAG_ISOSPEEDRATINGS 34855 /* ISO speed rating */ -#define EXIFTAG_PHOTOGRAPHICSENSITIVITY 34855 /* Photographic Sensitivity (new name for tag 34855) */ -#define EXIFTAG_OECF 34856 /* Optoelectric conversion factor */ -#define EXIFTAG_EXIFVERSION 36864 /* Exif version */ -#define EXIFTAG_DATETIMEORIGINAL 36867 /* Date and time of original data generation */ -#define EXIFTAG_DATETIMEDIGITIZED 36868 /* Date and time of digital data generation */ -#define EXIFTAG_COMPONENTSCONFIGURATION 37121 /* Meaning of each component */ -#define EXIFTAG_COMPRESSEDBITSPERPIXEL 37122 /* Image compression mode */ -#define EXIFTAG_SHUTTERSPEEDVALUE 37377 /* Shutter speed */ -#define EXIFTAG_APERTUREVALUE 37378 /* Aperture */ -#define EXIFTAG_BRIGHTNESSVALUE 37379 /* Brightness */ -#define EXIFTAG_EXPOSUREBIASVALUE 37380 /* Exposure bias */ -#define EXIFTAG_MAXAPERTUREVALUE 37381 /* Maximum lens aperture */ -#define EXIFTAG_SUBJECTDISTANCE 37382 /* Subject distance */ -#define EXIFTAG_METERINGMODE 37383 /* Metering mode */ -#define EXIFTAG_LIGHTSOURCE 37384 /* Light source */ -#define EXIFTAG_FLASH 37385 /* Flash */ -#define EXIFTAG_FOCALLENGTH 37386 /* Lens focal length */ -#define EXIFTAG_SUBJECTAREA 37396 /* Subject area */ -#define EXIFTAG_MAKERNOTE 37500 /* Manufacturer notes */ -#define EXIFTAG_USERCOMMENT 37510 /* User comments */ -#define EXIFTAG_SUBSECTIME 37520 /* DateTime subseconds */ -#define EXIFTAG_SUBSECTIMEORIGINAL 37521 /* DateTimeOriginal subseconds */ -#define EXIFTAG_SUBSECTIMEDIGITIZED 37522 /* DateTimeDigitized subseconds */ -#define EXIFTAG_FLASHPIXVERSION 40960 /* Supported Flashpix version */ -#define EXIFTAG_COLORSPACE 40961 /* Color space information */ -#define EXIFTAG_PIXELXDIMENSION 40962 /* Valid image width */ -#define EXIFTAG_PIXELYDIMENSION 40963 /* Valid image height */ -#define EXIFTAG_RELATEDSOUNDFILE 40964 /* Related audio file */ -#define EXIFTAG_FLASHENERGY 41483 /* Flash energy */ -#define EXIFTAG_SPATIALFREQUENCYRESPONSE 41484 /* Spatial frequency response */ -#define EXIFTAG_FOCALPLANEXRESOLUTION 41486 /* Focal plane X resolution */ -#define EXIFTAG_FOCALPLANEYRESOLUTION 41487 /* Focal plane Y resolution */ -#define EXIFTAG_FOCALPLANERESOLUTIONUNIT 41488 /* Focal plane resolution unit */ -#define EXIFTAG_SUBJECTLOCATION 41492 /* Subject location */ -#define EXIFTAG_EXPOSUREINDEX 41493 /* Exposure index */ -#define EXIFTAG_SENSINGMETHOD 41495 /* Sensing method */ -#define EXIFTAG_FILESOURCE 41728 /* File source */ -#define EXIFTAG_SCENETYPE 41729 /* Scene type */ -#define EXIFTAG_CFAPATTERN 41730 /* CFA pattern */ -#define EXIFTAG_CUSTOMRENDERED 41985 /* Custom image processing */ -#define EXIFTAG_EXPOSUREMODE 41986 /* Exposure mode */ -#define EXIFTAG_WHITEBALANCE 41987 /* White balance */ -#define EXIFTAG_DIGITALZOOMRATIO 41988 /* Digital zoom ratio */ -#define EXIFTAG_FOCALLENGTHIN35MMFILM 41989 /* Focal length in 35 mm film */ -#define EXIFTAG_SCENECAPTURETYPE 41990 /* Scene capture type */ -#define EXIFTAG_GAINCONTROL 41991 /* Gain control */ -#define EXIFTAG_CONTRAST 41992 /* Contrast */ -#define EXIFTAG_SATURATION 41993 /* Saturation */ -#define EXIFTAG_SHARPNESS 41994 /* Sharpness */ -#define EXIFTAG_DEVICESETTINGDESCRIPTION 41995 /* Device settings description */ -#define EXIFTAG_SUBJECTDISTANCERANGE 41996 /* Subject distance range */ -#define EXIFTAG_IMAGEUNIQUEID 42016 /* Unique image ID */ - -/*--: New for EXIF-Version 2.32, May 2019 ... */ -#define EXIFTAG_SENSITIVITYTYPE 34864 /* The SensitivityType tag indicates which one of the parameters of ISO12232 is the PhotographicSensitivity tag. */ -#define EXIFTAG_STANDARDOUTPUTSENSITIVITY 34865 /* This tag indicates the standard output sensitivity value of a camera or input device defined in ISO 12232. */ -#define EXIFTAG_RECOMMENDEDEXPOSUREINDEX 34866 /* recommended exposure index */ -#define EXIFTAG_ISOSPEED 34867 /* ISO speed value */ -#define EXIFTAG_ISOSPEEDLATITUDEYYY 34868 /* ISO speed latitude yyy */ -#define EXIFTAG_ISOSPEEDLATITUDEZZZ 34869 /* ISO speed latitude zzz */ -#define EXIFTAG_OFFSETTIME 36880 /* offset from UTC of the time of DateTime tag. */ -#define EXIFTAG_OFFSETTIMEORIGINAL 36881 /* offset from UTC of the time of DateTimeOriginal tag. */ -#define EXIFTAG_OFFSETTIMEDIGITIZED 36882 /* offset from UTC of the time of DateTimeDigitized tag. */ -#define EXIFTAG_TEMPERATURE 37888 /* Temperature as the ambient situation at the shot in dergee Celsius */ -#define EXIFTAG_HUMIDITY 37889 /* Humidity as the ambient situation at the shot in percent */ -#define EXIFTAG_PRESSURE 37890 /* Pressure as the ambient situation at the shot hecto-Pascal (hPa) */ -#define EXIFTAG_WATERDEPTH 37891 /* WaterDepth as the ambient situation at the shot in meter (m) */ -#define EXIFTAG_ACCELERATION 37892 /* Acceleration (a scalar regardless of direction) as the ambientsituation at the shot in units of mGal (10-5 m/s^2) */ -/* EXIFTAG_CAMERAELEVATIONANGLE: Elevation/depression. angle of the orientation of the camera(imaging optical axis) - * as the ambient situation at the shot in degree from -180deg to +180deg. */ -#define EXIFTAG_CAMERAELEVATIONANGLE 37893 -#define EXIFTAG_CAMERAOWNERNAME 42032 /* owner of a camera */ -#define EXIFTAG_BODYSERIALNUMBER 42033 /* serial number of the body of the camera */ -/* EXIFTAG_LENSSPECIFICATION: minimum focal length (in mm), maximum focal length (in mm),minimum F number in the minimum focal length, - * and minimum F number in the maximum focal length, */ -#define EXIFTAG_LENSSPECIFICATION 42034 -#define EXIFTAG_LENSMAKE 42035 /* the lens manufacturer */ -#define EXIFTAG_LENSMODEL 42036 /* the lens model name and model number */ -#define EXIFTAG_LENSSERIALNUMBER 42037 /* the serial number of the interchangeable lens */ -#define EXIFTAG_GAMMA 42240 /* value of coefficient gamma */ -#define EXIFTAG_COMPOSITEIMAGE 42080 /* composite image */ -#define EXIFTAG_SOURCEIMAGENUMBEROFCOMPOSITEIMAGE 42081 /* source image number of composite image */ -#define EXIFTAG_SOURCEEXPOSURETIMESOFCOMPOSITEIMAGE 42082 /* source exposure times of composite image */ - -/* - * EXIF-GPS tags (Version 2.31, July 2016) - */ -#define GPSTAG_VERSIONID 0 /* Indicates the version of GPSInfoIFD. */ -#define GPSTAG_LATITUDEREF 1 /* Indicates whether the latitude is north or south latitude. */ -#define GPSTAG_LATITUDE 2 /* Indicates the latitude. */ -#define GPSTAG_LONGITUDEREF 3 /* Indicates whether the longitude is east or west longitude. */ -#define GPSTAG_LONGITUDE 4 /* Indicates the longitude. */ -#define GPSTAG_ALTITUDEREF 5 /* Indicates the altitude used as the reference altitude. */ -#define GPSTAG_ALTITUDE 6 /* Indicates the altitude based on the reference in GPSAltitudeRef. */ -#define GPSTAG_TIMESTAMP 7 /*Indicates the time as UTC (Coordinated Universal Time). */ -#define GPSTAG_SATELLITES 8 /*Indicates the GPS satellites used for measurements. */ -#define GPSTAG_STATUS 9 /* Indicates the status of the GPS receiver when the image is recorded. */ -#define GPSTAG_MEASUREMODE 10 /* Indicates the GPS measurement mode. */ -#define GPSTAG_DOP 11 /* Indicates the GPS DOP (data degree of precision). */ -#define GPSTAG_SPEEDREF 12 /* Indicates the unit used to express the GPS receiver speed of movement. */ -#define GPSTAG_SPEED 13 /* Indicates the speed of GPS receiver movement. */ -#define GPSTAG_TRACKREF 14 /* Indicates the reference for giving the direction of GPS receiver movement. */ -#define GPSTAG_TRACK 15 /* Indicates the direction of GPS receiver movement. */ -#define GPSTAG_IMGDIRECTIONREF 16 /* Indicates the reference for giving the direction of the image when it is captured. */ -#define GPSTAG_IMGDIRECTION 17 /* Indicates the direction of the image when it was captured. */ -#define GPSTAG_MAPDATUM 18 /* Indicates the geodetic survey data used by the GPS receiver. (e.g. WGS-84) */ -#define GPSTAG_DESTLATITUDEREF 19 /* Indicates whether the latitude of the destination point is north or south latitude. */ -#define GPSTAG_DESTLATITUDE 20 /* Indicates the latitude of the destination point. */ -#define GPSTAG_DESTLONGITUDEREF 21 /* Indicates whether the longitude of the destination point is east or west longitude. */ -#define GPSTAG_DESTLONGITUDE 22 /* Indicates the longitude of the destination point. */ -#define GPSTAG_DESTBEARINGREF 23 /* Indicates the reference used for giving the bearing to the destination point. */ -#define GPSTAG_DESTBEARING 24 /* Indicates the bearing to the destination point. */ -#define GPSTAG_DESTDISTANCEREF 25 /* Indicates the unit used to express the distance to the destination point. */ -#define GPSTAG_DESTDISTANCE 26 /* Indicates the distance to the destination point. */ -#define GPSTAG_PROCESSINGMETHOD 27 /* A character string recording the name of the method used for location finding. */ -#define GPSTAG_AREAINFORMATION 28 /* A character string recording the name of the GPS area. */ -#define GPSTAG_DATESTAMP 29 /* A character string recording date and time information relative to UTC (Coordinated Universal Time). */ -#define GPSTAG_DIFFERENTIAL 30 /* Indicates whether differential correction is applied to the GPS receiver. */ -#define GPSTAG_GPSHPOSITIONINGERROR 31 /* Indicates horizontal positioning errors in meters. */ - -#endif /* _TIFF_ */ diff --git a/src/3rd/tiff/tiffconf.h b/src/3rd/tiff/tiffconf.h deleted file mode 100644 index 04a78ab90c4..00000000000 --- a/src/3rd/tiff/tiffconf.h +++ /dev/null @@ -1,183 +0,0 @@ -/* - Configuration defines for installed libtiff. - This file maintained for backward compatibility. Do not use definitions - from this file in your programs. -*/ - -/* clang-format off */ -/* clang-format disabled because CMake scripts are very sensitive to the - * formatting of this file. configure_file variables of type "@VAR@" are - * modified by clang-format and won't be substituted. - */ - -#ifndef _TIFFCONF_ -#define _TIFFCONF_ - -#include "hbdefs.h" -#include "hb_io.h" - -#include /* For PRIu16 */ - -/* Signed 16-bit type */ -#define TIFF_INT16_T HB_I16 - -/* Signed 32-bit type */ -#define TIFF_INT32_T HB_I32 - -/* Signed 64-bit type */ -#define TIFF_INT64_T HB_I64 - -/* Signed 8-bit type */ -#define TIFF_INT8_T HB_I8 - -/* Unsigned 16-bit type */ -#define TIFF_UINT16_T HB_U16 - -/* Unsigned 32-bit type */ -#define TIFF_UINT32_T HB_U32 - -/* Unsigned 64-bit type */ -#define TIFF_UINT64_T HB_U64 - -/* Unsigned 8-bit type */ -#define TIFF_UINT8_T HB_U8 - -/* Signed size type */ -#define TIFF_SSIZE_T HB_ISIZ - -/* Signed size type formatter */ -#define TIFF_SSIZE_FORMAT "" HB_PFS "d" - -/* file handler */ -#define TIFF_FILE_HANDLE HB_FHANDLE - -/* Compatibility stuff. */ - -/* Define as 0 or 1 according to the floating point format supported by the - machine */ -#undef HAVE_IEEEFP - -/* The concept of HOST_FILLORDER is broken. Since libtiff 4.5.1 - * this macro will always be hardcoded to FILLORDER_LSB2MSB on all - * architectures, to reflect past long behavior of doing so on x86 architecture. - * Note however that the default FillOrder used by libtiff is FILLORDER_MSB2LSB, - * as mandated per the TIFF specification. - * The influence of HOST_FILLORDER is only when passing the 'H' mode in - * TIFFOpen(). - * You should NOT rely on this macro to decide the CPU endianness! - * This macro will be removed in libtiff 4.6 - */ -#define HOST_FILLORDER FILLORDER_LSB2MSB - -/* Native cpu byte order: 1 if big-endian (Motorola) or 0 if little-endian - (Intel) */ -#if defined( HB_BIG_ENDIAN ) - #define HOST_BIGENDIAN -#endif - -#if 0 -/* Support CCITT Group 3 & 4 algorithms */ -#undef CCITT_SUPPORT -#endif - -#if 0 -/* Support JPEG compression (requires IJG JPEG library) */ -#undef JPEG_SUPPORT -#endif - -/* Support JBIG compression (requires JBIG-KIT library) */ -#undef JBIG_SUPPORT - -#if 0 -/* Support LERC compression */ -#undef LERC_SUPPORT -#endif - -/* Support LogLuv high dynamic range encoding */ -#undef LOGLUV_SUPPORT - -#if 0 -/* Support LZW algorithm */ -#undef LZW_SUPPORT -#endif - -#if 0 -/* Support NeXT 2-bit RLE algorithm */ -#undef NEXT_SUPPORT -#endif - -/* Support Old JPEG compresson (read contrib/ojpeg/README first! Compilation - fails with unpatched IJG JPEG library) */ -#undef OJPEG_SUPPORT - -/* Support Macintosh PackBits algorithm */ -#undef PACKBITS_SUPPORT - -/* Support Pixar log-format algorithm (requires Zlib) */ -#undef PIXARLOG_SUPPORT - -/* Support ThunderScan 4-bit RLE algorithm */ -#undef THUNDER_SUPPORT - -#if 0 -/* Support Deflate compression */ -#undef ZIP_SUPPORT -#endif - -#if 0 -/* Support libdeflate enhanced compression */ -#undef LIBDEFLATE_SUPPORT -#endif - -/* Support strip chopping (whether or not to convert single-strip uncompressed - images to multiple strips of ~8Kb to reduce memory usage) */ -#undef STRIPCHOP_DEFAULT - -/* Enable SubIFD tag (330) support */ -#undef SUBIFD_SUPPORT - -/* Treat extra sample as alpha (default enabled). The RGBA interface will - treat a fourth sample with no EXTRASAMPLE_ value as being ASSOCALPHA. Many - packages produce RGBA files but don't mark the alpha properly. */ -#undef DEFAULT_EXTRASAMPLE_AS_ALPHA - -/* Pick up YCbCr subsampling info from the JPEG data stream to support files - lacking the tag (default enabled). */ -#undef CHECK_JPEG_YCBCR_SUBSAMPLING - -/* Support MS MDI magic number files as TIFF */ -#undef MDI_SUPPORT - -/* - * Feature support definitions. - * XXX: These macros are obsoleted. Don't use them in your apps! - * Macros stays here for backward compatibility and should be always defined. - */ -#define COLORIMETRY_SUPPORT -#define YCBCR_SUPPORT -#define CMYK_SUPPORT -#define ICC_SUPPORT -#define PHOTOSHOP_SUPPORT -#define IPTC_SUPPORT - -#if ! defined( HB_OS_UNIX ) -#ifndef O_RDONLY -#define O_RDONLY 0 -#endif -#ifndef O_RDWR -#define O_RDWR 2 -#endif -#ifndef O_WRONLY -#define O_WRONLY 000001 -#endif -#ifndef O_CREAT -#define O_CREAT 000100 -#endif -#ifndef O_TRUNC -#define O_TRUNC 001000 -#endif -#endif - -#endif /* _TIFFCONF_ */ - -/* clang-format on */ diff --git a/src/3rd/tiff/tiffio.h b/src/3rd/tiff/tiffio.h deleted file mode 100644 index 45a679a4202..00000000000 --- a/src/3rd/tiff/tiffio.h +++ /dev/null @@ -1,655 +0,0 @@ -/* - * Copyright (c) 1988-1997 Sam Leffler - * Copyright (c) 1991-1997 Silicon Graphics, Inc. - * - * Permission to use, copy, modify, distribute, and sell this software and - * its documentation for any purpose is hereby granted without fee, provided - * that (i) the above copyright notices and this permission notice appear in - * all copies of the software and related documentation, and (ii) the names of - * Sam Leffler and Silicon Graphics may not be used in any advertising or - * publicity relating to the software without the specific, prior written - * permission of Sam Leffler and Silicon Graphics. - * - * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, - * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY - * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. - * - * IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR - * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, - * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, - * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF - * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE - * OF THIS SOFTWARE. - */ - -#ifndef _TIFFIO_ -#define _TIFFIO_ - -/* - * TIFF I/O Library Definitions. - */ -#include "tiff.h" -#include "tiffvers.h" - -/* - * TIFF is defined as an incomplete type to hide the - * library's internal data structures from clients. - */ -typedef struct tiff TIFF; - -/* - * The following typedefs define the intrinsic size of - * data types used in the *exported* interfaces. These - * definitions depend on the proper definition of types - * in tiff.h. Note also that the varargs interface used - * to pass tag types and values uses the types defined in - * tiff.h directly. - * - * NB: ttag_t is unsigned int and not unsigned short because - * ANSI C requires that the type before the ellipsis be a - * promoted type (i.e. one of int, unsigned int, pointer, - * or double) and because we defined pseudo-tags that are - * outside the range of legal Aldus-assigned tags. - * NB: tsize_t is signed and not unsigned because some functions - * return -1. - * NB: toff_t is not off_t for many reasons; TIFFs max out at - * 32-bit file offsets, and BigTIFF maxes out at 64-bit - * offsets being the most important, and to ensure use of - * a consistently unsigned type across architectures. - * Prior to libtiff 4.0, this was an unsigned 32 bit type. - */ -/* - * this is the machine addressing size type, only it's signed, so make it - * int32_t on 32bit machines, int64_t on 64bit machines - */ -typedef TIFF_SSIZE_T tmsize_t; -#define TIFF_TMSIZE_T_MAX (tmsize_t)(SIZE_MAX >> 1) - -typedef uint64_t toff_t; /* file offset */ -/* the following are deprecated and should be replaced by their defining - counterparts */ -typedef uint32_t ttag_t; /* directory tag */ -typedef uint32_t tdir_t; /* directory index */ -typedef uint16_t tsample_t; /* sample number */ -typedef uint32_t tstrile_t; /* strip or tile number */ -typedef tstrile_t tstrip_t; /* strip number */ -typedef tstrile_t ttile_t; /* tile number */ -typedef tmsize_t tsize_t; /* i/o size in bytes */ -typedef void *tdata_t; /* image data ref */ - -#if !defined(__WIN32__) && (defined(_WIN32) || defined(WIN32)) -#define __WIN32__ -#endif - -/* - * On windows you should define USE_WIN32_FILEIO if you are using tif_win32.c - * or AVOID_WIN32_FILEIO if you are using something else (like tif_unix.c). - * - * By default tif_unix.c is assumed. - */ - -#if defined(_WINDOWS) || defined(__WIN32__) || defined(_Windows) -#if !defined(__CYGWIN) && !defined(AVOID_WIN32_FILEIO) && \ - !defined(USE_WIN32_FILEIO) -#define AVOID_WIN32_FILEIO -#endif -#endif - -#if defined(USE_WIN32_FILEIO) -#define VC_EXTRALEAN -#include -#ifdef __WIN32__ -DECLARE_HANDLE(thandle_t); /* Win32 file handle */ -#else -typedef HFILE thandle_t; /* client data handle */ -#endif /* __WIN32__ */ -#elif defined(TIFF_FILE_HANDLE) -typedef TIFF_FILE_HANDLE thandle_t; /* client data handle */ -#else -typedef void *thandle_t; /* client data handle */ -#endif /* USE_WIN32_FILEIO */ - -/* - * Flags to pass to TIFFPrintDirectory to control - * printing of data structures that are potentially - * very large. Bit-or these flags to enable printing - * multiple items. - */ -#define TIFFPRINT_NONE 0x0 /* no extra info */ -#define TIFFPRINT_STRIPS 0x1 /* strips/tiles info */ -#define TIFFPRINT_CURVES 0x2 /* color/gray response curves */ -#define TIFFPRINT_COLORMAP 0x4 /* colormap */ -#define TIFFPRINT_JPEGQTABLES 0x100 /* JPEG Q matrices */ -#define TIFFPRINT_JPEGACTABLES 0x200 /* JPEG AC tables */ -#define TIFFPRINT_JPEGDCTABLES 0x200 /* JPEG DC tables */ - -/* - * Colour conversion stuff - */ - -/* reference white */ -#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) - -/* Structure for holding information about a display device. */ - -typedef unsigned char TIFFRGBValue; /* 8-bit samples */ - -typedef struct -{ - float d_mat[3][3]; /* XYZ -> luminance matrix */ - float d_YCR; /* Light o/p for reference white */ - float d_YCG; - float d_YCB; - uint32_t d_Vrwr; /* Pixel values for ref. white */ - uint32_t d_Vrwg; - uint32_t d_Vrwb; - float d_Y0R; /* Residual light for black pixel */ - float d_Y0G; - float d_Y0B; - float d_gammaR; /* Gamma values for the three guns */ - float d_gammaG; - float d_gammaB; -} TIFFDisplay; - -typedef struct -{ /* YCbCr->RGB support */ - TIFFRGBValue *clamptab; /* range clamping table */ - int *Cr_r_tab; - int *Cb_b_tab; - int32_t *Cr_g_tab; - int32_t *Cb_g_tab; - int32_t *Y_tab; -} TIFFYCbCrToRGB; - -typedef struct -{ /* CIE Lab 1976->RGB support */ - int range; /* Size of conversion table */ -#define CIELABTORGB_TABLE_RANGE 1500 - float rstep, gstep, bstep; - float X0, Y0, Z0; /* Reference white point */ - TIFFDisplay display; - float Yr2r[CIELABTORGB_TABLE_RANGE + 1]; /* Conversion of Yr to r */ - float Yg2g[CIELABTORGB_TABLE_RANGE + 1]; /* Conversion of Yg to g */ - float Yb2b[CIELABTORGB_TABLE_RANGE + 1]; /* Conversion of Yb to b */ -} TIFFCIELabToRGB; - -/* - * RGBA-style image support. - */ -typedef struct _TIFFRGBAImage TIFFRGBAImage; -/* - * The image reading and conversion routines invoke - * ``put routines'' to copy/image/whatever tiles of - * raw image data. A default set of routines are - * provided to convert/copy raw image data to 8-bit - * packed ABGR format rasters. Applications can supply - * alternate routines that unpack the data into a - * different format or, for example, unpack the data - * and draw the unpacked raster on the display. - */ -typedef void (*tileContigRoutine)(TIFFRGBAImage *, uint32_t *, uint32_t, - uint32_t, uint32_t, uint32_t, int32_t, - int32_t, unsigned char *); -typedef void (*tileSeparateRoutine)(TIFFRGBAImage *, uint32_t *, uint32_t, - uint32_t, uint32_t, uint32_t, int32_t, - int32_t, unsigned char *, unsigned char *, - unsigned char *, unsigned char *); -/* - * RGBA-reader state. - */ -struct _TIFFRGBAImage -{ - TIFF *tif; /* image handle */ - int stoponerr; /* stop on read error */ - int isContig; /* data is packed/separate */ - int alpha; /* type of alpha data present */ - uint32_t width; /* image width */ - uint32_t height; /* image height */ - uint16_t bitspersample; /* image bits/sample */ - uint16_t samplesperpixel; /* image samples/pixel */ - uint16_t orientation; /* image orientation */ - uint16_t req_orientation; /* requested orientation */ - uint16_t photometric; /* image photometric interp */ - uint16_t *redcmap; /* colormap palette */ - uint16_t *greencmap; - uint16_t *bluecmap; - /* get image data routine */ - int (*get)(TIFFRGBAImage *, uint32_t *, uint32_t, uint32_t); - /* put decoded strip/tile */ - union - { - void (*any)(TIFFRGBAImage *); - tileContigRoutine contig; - tileSeparateRoutine separate; - } put; - TIFFRGBValue *Map; /* sample mapping array */ - uint32_t **BWmap; /* black&white map */ - uint32_t **PALmap; /* palette image map */ - TIFFYCbCrToRGB *ycbcr; /* YCbCr conversion state */ - TIFFCIELabToRGB *cielab; /* CIE L*a*b conversion state */ - - uint8_t *UaToAa; /* Unassociated alpha to associated alpha conversion LUT */ - uint8_t *Bitdepth16To8; /* LUT for conversion from 16bit to 8bit values */ - - int row_offset; - int col_offset; -}; - -/* - * Macros for extracting components from the - * packed ABGR form returned by TIFFReadRGBAImage. - */ -#define TIFFGetR(abgr) ((abgr)&0xff) -#define TIFFGetG(abgr) (((abgr) >> 8) & 0xff) -#define TIFFGetB(abgr) (((abgr) >> 16) & 0xff) -#define TIFFGetA(abgr) (((abgr) >> 24) & 0xff) - -/* - * A CODEC is a software package that implements decoding, - * encoding, or decoding+encoding of a compression algorithm. - * The library provides a collection of builtin codecs. - * More codecs may be registered through calls to the library - * and/or the builtin implementations may be overridden. - */ -typedef int (*TIFFInitMethod)(TIFF *, int); -typedef struct -{ - char *name; - uint16_t scheme; - TIFFInitMethod init; -} TIFFCodec; - -typedef struct -{ - uint32_t uNum; - uint32_t uDenom; -} TIFFRational_t; - -#include -#include - -/* share internal LogLuv conversion routines? */ -#ifndef LOGLUV_PUBLIC -#define LOGLUV_PUBLIC 1 -#endif - -#if defined(__GNUC__) || defined(__clang__) || defined(__attribute__) -#define TIFF_ATTRIBUTE(x) __attribute__(x) -#else -#define TIFF_ATTRIBUTE(x) /*nothing*/ -#endif - -#if defined(c_plusplus) || defined(__cplusplus) -extern "C" -{ -#endif - typedef void (*TIFFErrorHandler)(const char *, const char *, va_list); - typedef void (*TIFFErrorHandlerExt)(thandle_t, const char *, const char *, - va_list); - typedef int (*TIFFErrorHandlerExtR)(TIFF *, void *user_data, const char *, - const char *, va_list); - typedef tmsize_t (*TIFFReadWriteProc)(thandle_t, void *, tmsize_t); - typedef toff_t (*TIFFSeekProc)(thandle_t, toff_t, int); - typedef int (*TIFFCloseProc)(thandle_t); - typedef toff_t (*TIFFSizeProc)(thandle_t); - typedef int (*TIFFMapFileProc)(thandle_t, void **base, toff_t *size); - typedef void (*TIFFUnmapFileProc)(thandle_t, void *base, toff_t size); - typedef void (*TIFFExtendProc)(TIFF *); - - extern const char *TIFFGetVersion(void); - - extern const TIFFCodec *TIFFFindCODEC(uint16_t); - extern TIFFCodec *TIFFRegisterCODEC(uint16_t, const char *, TIFFInitMethod); - extern void TIFFUnRegisterCODEC(TIFFCodec *); - extern int TIFFIsCODECConfigured(uint16_t); - extern TIFFCodec *TIFFGetConfiguredCODECs(void); - - /* - * Auxiliary functions. - */ - - extern void *_TIFFmalloc(tmsize_t s); - extern void *_TIFFcalloc(tmsize_t nmemb, tmsize_t siz); - extern void *_TIFFrealloc(void *p, tmsize_t s); - extern void _TIFFmemset(void *p, int v, tmsize_t c); - extern void _TIFFmemcpy(void *d, const void *s, tmsize_t c); - extern int _TIFFmemcmp(const void *p1, const void *p2, tmsize_t c); - extern void _TIFFfree(void *p); - - /* - ** Stuff, related to tag handling and creating custom tags. - */ - extern int TIFFGetTagListCount(TIFF *); - extern uint32_t TIFFGetTagListEntry(TIFF *, int tag_index); - -#define TIFF_ANY TIFF_NOTYPE /* for field descriptor searching */ -#define TIFF_VARIABLE -1 /* marker for variable length tags */ -#define TIFF_SPP -2 /* marker for SamplesPerPixel tags */ -#define TIFF_VARIABLE2 -3 /* marker for uint32_t var-length tags */ - -#define FIELD_CUSTOM 65 - - typedef struct _TIFFField TIFFField; - typedef struct _TIFFFieldArray TIFFFieldArray; - - extern const TIFFField *TIFFFindField(TIFF *, uint32_t, TIFFDataType); - extern const TIFFField *TIFFFieldWithTag(TIFF *, uint32_t); - extern const TIFFField *TIFFFieldWithName(TIFF *, const char *); - - extern uint32_t TIFFFieldTag(const TIFFField *); - extern const char *TIFFFieldName(const TIFFField *); - extern TIFFDataType TIFFFieldDataType(const TIFFField *); - extern int TIFFFieldPassCount(const TIFFField *); - extern int TIFFFieldReadCount(const TIFFField *); - extern int TIFFFieldWriteCount(const TIFFField *); - extern int - TIFFFieldSetGetSize(const TIFFField *); /* returns internal storage size of - TIFFSetGetFieldType in bytes. */ - extern int TIFFFieldSetGetCountSize( - const TIFFField *); /* returns size of count parameter 0=none, - 2=uint16_t, 4=uint32_t */ - extern int TIFFFieldIsAnonymous(const TIFFField *); - - typedef int (*TIFFVSetMethod)(TIFF *, uint32_t, va_list); - typedef int (*TIFFVGetMethod)(TIFF *, uint32_t, va_list); - typedef void (*TIFFPrintMethod)(TIFF *, FILE *, long); - - typedef struct - { - TIFFVSetMethod vsetfield; /* tag set routine */ - TIFFVGetMethod vgetfield; /* tag get routine */ - TIFFPrintMethod printdir; /* directory print routine */ - } TIFFTagMethods; - - extern TIFFTagMethods *TIFFAccessTagMethods(TIFF *); - extern void *TIFFGetClientInfo(TIFF *, const char *); - extern void TIFFSetClientInfo(TIFF *, void *, const char *); - - extern void TIFFCleanup(TIFF *tif); - extern void TIFFClose(TIFF *tif); - extern int TIFFFlush(TIFF *tif); - extern int TIFFFlushData(TIFF *tif); - extern int TIFFGetField(TIFF *tif, uint32_t tag, ...); - extern int TIFFVGetField(TIFF *tif, uint32_t tag, va_list ap); - extern int TIFFGetFieldDefaulted(TIFF *tif, uint32_t tag, ...); - extern int TIFFVGetFieldDefaulted(TIFF *tif, uint32_t tag, va_list ap); - extern int TIFFReadDirectory(TIFF *tif); - extern int TIFFReadCustomDirectory(TIFF *tif, toff_t diroff, - const TIFFFieldArray *infoarray); - extern int TIFFReadEXIFDirectory(TIFF *tif, toff_t diroff); - extern int TIFFReadGPSDirectory(TIFF *tif, toff_t diroff); - extern uint64_t TIFFScanlineSize64(TIFF *tif); - extern tmsize_t TIFFScanlineSize(TIFF *tif); - extern uint64_t TIFFRasterScanlineSize64(TIFF *tif); - extern tmsize_t TIFFRasterScanlineSize(TIFF *tif); - extern uint64_t TIFFStripSize64(TIFF *tif); - extern tmsize_t TIFFStripSize(TIFF *tif); - extern uint64_t TIFFRawStripSize64(TIFF *tif, uint32_t strip); - extern tmsize_t TIFFRawStripSize(TIFF *tif, uint32_t strip); - extern uint64_t TIFFVStripSize64(TIFF *tif, uint32_t nrows); - extern tmsize_t TIFFVStripSize(TIFF *tif, uint32_t nrows); - extern uint64_t TIFFTileRowSize64(TIFF *tif); - extern tmsize_t TIFFTileRowSize(TIFF *tif); - extern uint64_t TIFFTileSize64(TIFF *tif); - extern tmsize_t TIFFTileSize(TIFF *tif); - extern uint64_t TIFFVTileSize64(TIFF *tif, uint32_t nrows); - extern tmsize_t TIFFVTileSize(TIFF *tif, uint32_t nrows); - extern uint32_t TIFFDefaultStripSize(TIFF *tif, uint32_t request); - extern void TIFFDefaultTileSize(TIFF *, uint32_t *, uint32_t *); - extern int TIFFFileno(TIFF *); - extern int TIFFSetFileno(TIFF *, int); - extern thandle_t TIFFClientdata(TIFF *); - extern thandle_t TIFFSetClientdata(TIFF *, thandle_t); - extern int TIFFGetMode(TIFF *); - extern int TIFFSetMode(TIFF *, int); - extern int TIFFIsTiled(TIFF *); - extern int TIFFIsByteSwapped(TIFF *); - extern int TIFFIsUpSampled(TIFF *); - extern int TIFFIsMSB2LSB(TIFF *); - extern int TIFFIsBigEndian(TIFF *); - extern int TIFFIsBigTIFF(TIFF *); - extern TIFFReadWriteProc TIFFGetReadProc(TIFF *); - extern TIFFReadWriteProc TIFFGetWriteProc(TIFF *); - extern TIFFSeekProc TIFFGetSeekProc(TIFF *); - extern TIFFCloseProc TIFFGetCloseProc(TIFF *); - extern TIFFSizeProc TIFFGetSizeProc(TIFF *); - extern TIFFMapFileProc TIFFGetMapFileProc(TIFF *); - extern TIFFUnmapFileProc TIFFGetUnmapFileProc(TIFF *); - extern uint32_t TIFFCurrentRow(TIFF *); - extern tdir_t TIFFCurrentDirectory(TIFF *); - extern tdir_t TIFFNumberOfDirectories(TIFF *); - extern uint64_t TIFFCurrentDirOffset(TIFF *); - extern uint32_t TIFFCurrentStrip(TIFF *); - extern uint32_t TIFFCurrentTile(TIFF *tif); - extern int TIFFReadBufferSetup(TIFF *tif, void *bp, tmsize_t size); - extern int TIFFWriteBufferSetup(TIFF *tif, void *bp, tmsize_t size); - extern int TIFFSetupStrips(TIFF *); - extern int TIFFWriteCheck(TIFF *, int, const char *); - extern void TIFFFreeDirectory(TIFF *); - extern int TIFFCreateDirectory(TIFF *); - extern int TIFFCreateCustomDirectory(TIFF *, const TIFFFieldArray *); - extern int TIFFCreateEXIFDirectory(TIFF *); - extern int TIFFCreateGPSDirectory(TIFF *); - extern int TIFFLastDirectory(TIFF *); - extern int TIFFSetDirectory(TIFF *, tdir_t); - extern int TIFFSetSubDirectory(TIFF *, uint64_t); - extern int TIFFUnlinkDirectory(TIFF *, tdir_t); - extern int TIFFSetField(TIFF *, uint32_t, ...); - extern int TIFFVSetField(TIFF *, uint32_t, va_list); - extern int TIFFUnsetField(TIFF *, uint32_t); - extern int TIFFWriteDirectory(TIFF *); - extern int TIFFWriteCustomDirectory(TIFF *, uint64_t *); - extern int TIFFCheckpointDirectory(TIFF *); - extern int TIFFRewriteDirectory(TIFF *); - extern int TIFFDeferStrileArrayWriting(TIFF *); - extern int TIFFForceStrileArrayWriting(TIFF *); - -#if defined(c_plusplus) || defined(__cplusplus) - extern void TIFFPrintDirectory(TIFF *, FILE *, long = 0); - extern int TIFFReadScanline(TIFF *tif, void *buf, uint32_t row, - uint16_t sample = 0); - extern int TIFFWriteScanline(TIFF *tif, void *buf, uint32_t row, - uint16_t sample = 0); - extern int TIFFReadRGBAImage(TIFF *, uint32_t, uint32_t, uint32_t *, - int = 0); - extern int TIFFReadRGBAImageOriented(TIFF *, uint32_t, uint32_t, uint32_t *, - int = ORIENTATION_BOTLEFT, int = 0); -#else -extern void TIFFPrintDirectory(TIFF *, FILE *, long); -extern int TIFFReadScanline(TIFF *tif, void *buf, uint32_t row, - uint16_t sample); -extern int TIFFWriteScanline(TIFF *tif, void *buf, uint32_t row, - uint16_t sample); -extern int TIFFReadRGBAImage(TIFF *, uint32_t, uint32_t, uint32_t *, int); -extern int TIFFReadRGBAImageOriented(TIFF *, uint32_t, uint32_t, uint32_t *, - int, int); -#endif - - extern int TIFFReadRGBAStrip(TIFF *, uint32_t, uint32_t *); - extern int TIFFReadRGBATile(TIFF *, uint32_t, uint32_t, uint32_t *); - extern int TIFFReadRGBAStripExt(TIFF *, uint32_t, uint32_t *, - int stop_on_error); - extern int TIFFReadRGBATileExt(TIFF *, uint32_t, uint32_t, uint32_t *, - int stop_on_error); - extern int TIFFRGBAImageOK(TIFF *, char[1024]); - extern int TIFFRGBAImageBegin(TIFFRGBAImage *, TIFF *, int, char[1024]); - extern int TIFFRGBAImageGet(TIFFRGBAImage *, uint32_t *, uint32_t, - uint32_t); - extern void TIFFRGBAImageEnd(TIFFRGBAImage *); - - extern const char *TIFFFileName(TIFF *); - extern const char *TIFFSetFileName(TIFF *, const char *); - extern void TIFFError(const char *, const char *, ...) - TIFF_ATTRIBUTE((__format__(__printf__, 2, 3))); - extern void TIFFErrorExt(thandle_t, const char *, const char *, ...) - TIFF_ATTRIBUTE((__format__(__printf__, 3, 4))); - extern void TIFFWarning(const char *, const char *, ...) - TIFF_ATTRIBUTE((__format__(__printf__, 2, 3))); - extern void TIFFWarningExt(thandle_t, const char *, const char *, ...) - TIFF_ATTRIBUTE((__format__(__printf__, 3, 4))); - extern TIFFErrorHandler TIFFSetErrorHandler(TIFFErrorHandler); - extern TIFFErrorHandlerExt TIFFSetErrorHandlerExt(TIFFErrorHandlerExt); - extern TIFFErrorHandler TIFFSetWarningHandler(TIFFErrorHandler); - extern TIFFErrorHandlerExt TIFFSetWarningHandlerExt(TIFFErrorHandlerExt); - - extern void TIFFWarningExtR(TIFF *, const char *, const char *, ...) - TIFF_ATTRIBUTE((__format__(__printf__, 3, 4))); - extern void TIFFErrorExtR(TIFF *, const char *, const char *, ...) - TIFF_ATTRIBUTE((__format__(__printf__, 3, 4))); - - typedef struct TIFFOpenOptions TIFFOpenOptions; - extern TIFFOpenOptions *TIFFOpenOptionsAlloc(void); - extern void TIFFOpenOptionsFree(TIFFOpenOptions *); - extern void - TIFFOpenOptionsSetMaxSingleMemAlloc(TIFFOpenOptions *opts, - tmsize_t max_single_mem_alloc); - extern void - TIFFOpenOptionsSetErrorHandlerExtR(TIFFOpenOptions *opts, - TIFFErrorHandlerExtR handler, - void *errorhandler_user_data); - extern void - TIFFOpenOptionsSetWarningHandlerExtR(TIFFOpenOptions *opts, - TIFFErrorHandlerExtR handler, - void *warnhandler_user_data); - - extern TIFF *TIFFOpen(const char *, const char *); - extern TIFF *TIFFOpenExt(const char *, const char *, TIFFOpenOptions *opts); -#ifdef __WIN32__ - extern TIFF *TIFFOpenW(const wchar_t *, const char *); - extern TIFF *TIFFOpenWExt(const wchar_t *, const char *, - TIFFOpenOptions *opts); -#endif /* __WIN32__ */ - extern TIFF *TIFFFdOpen(int, const char *, const char *); - extern TIFF *TIFFFdOpenExt(int, const char *, const char *, - TIFFOpenOptions *opts); - extern TIFF *TIFFClientOpen(const char *, const char *, thandle_t, - TIFFReadWriteProc, TIFFReadWriteProc, - TIFFSeekProc, TIFFCloseProc, TIFFSizeProc, - TIFFMapFileProc, TIFFUnmapFileProc); - extern TIFF *TIFFClientOpenExt(const char *, const char *, thandle_t, - TIFFReadWriteProc, TIFFReadWriteProc, - TIFFSeekProc, TIFFCloseProc, TIFFSizeProc, - TIFFMapFileProc, TIFFUnmapFileProc, - TIFFOpenOptions *opts); - extern TIFFExtendProc TIFFSetTagExtender(TIFFExtendProc); - extern uint32_t TIFFComputeTile(TIFF *tif, uint32_t x, uint32_t y, - uint32_t z, uint16_t s); - extern int TIFFCheckTile(TIFF *tif, uint32_t x, uint32_t y, uint32_t z, - uint16_t s); - extern uint32_t TIFFNumberOfTiles(TIFF *); - extern tmsize_t TIFFReadTile(TIFF *tif, void *buf, uint32_t x, uint32_t y, - uint32_t z, uint16_t s); - extern tmsize_t TIFFWriteTile(TIFF *tif, void *buf, uint32_t x, uint32_t y, - uint32_t z, uint16_t s); - extern uint32_t TIFFComputeStrip(TIFF *, uint32_t, uint16_t); - extern uint32_t TIFFNumberOfStrips(TIFF *); - extern tmsize_t TIFFReadEncodedStrip(TIFF *tif, uint32_t strip, void *buf, - tmsize_t size); - extern tmsize_t TIFFReadRawStrip(TIFF *tif, uint32_t strip, void *buf, - tmsize_t size); - extern tmsize_t TIFFReadEncodedTile(TIFF *tif, uint32_t tile, void *buf, - tmsize_t size); - extern tmsize_t TIFFReadRawTile(TIFF *tif, uint32_t tile, void *buf, - tmsize_t size); - extern int TIFFReadFromUserBuffer(TIFF *tif, uint32_t strile, void *inbuf, - tmsize_t insize, void *outbuf, - tmsize_t outsize); - extern tmsize_t TIFFWriteEncodedStrip(TIFF *tif, uint32_t strip, void *data, - tmsize_t cc); - extern tmsize_t TIFFWriteRawStrip(TIFF *tif, uint32_t strip, void *data, - tmsize_t cc); - extern tmsize_t TIFFWriteEncodedTile(TIFF *tif, uint32_t tile, void *data, - tmsize_t cc); - extern tmsize_t TIFFWriteRawTile(TIFF *tif, uint32_t tile, void *data, - tmsize_t cc); - extern int TIFFDataWidth( - TIFFDataType); /* table of tag datatype widths within TIFF file. */ - extern void TIFFSetWriteOffset(TIFF *tif, toff_t off); - extern void TIFFSwabShort(uint16_t *); - extern void TIFFSwabLong(uint32_t *); - extern void TIFFSwabLong8(uint64_t *); - extern void TIFFSwabFloat(float *); - extern void TIFFSwabDouble(double *); - extern void TIFFSwabArrayOfShort(uint16_t *wp, tmsize_t n); - extern void TIFFSwabArrayOfTriples(uint8_t *tp, tmsize_t n); - extern void TIFFSwabArrayOfLong(uint32_t *lp, tmsize_t n); - extern void TIFFSwabArrayOfLong8(uint64_t *lp, tmsize_t n); - extern void TIFFSwabArrayOfFloat(float *fp, tmsize_t n); - extern void TIFFSwabArrayOfDouble(double *dp, tmsize_t n); - extern void TIFFReverseBits(uint8_t *cp, tmsize_t n); - extern const unsigned char *TIFFGetBitRevTable(int); - - extern uint64_t TIFFGetStrileOffset(TIFF *tif, uint32_t strile); - extern uint64_t TIFFGetStrileByteCount(TIFF *tif, uint32_t strile); - extern uint64_t TIFFGetStrileOffsetWithErr(TIFF *tif, uint32_t strile, - int *pbErr); - extern uint64_t TIFFGetStrileByteCountWithErr(TIFF *tif, uint32_t strile, - int *pbErr); - -#ifdef LOGLUV_PUBLIC -#define U_NEU 0.210526316 -#define V_NEU 0.473684211 -#define UVSCALE 410. - extern double LogL16toY(int); - extern double LogL10toY(int); - extern void XYZtoRGB24(float *, uint8_t *); - extern int uv_decode(double *, double *, int); - extern void LogLuv24toXYZ(uint32_t, float *); - extern void LogLuv32toXYZ(uint32_t, float *); -#if defined(c_plusplus) || defined(__cplusplus) - extern int LogL16fromY(double, int = SGILOGENCODE_NODITHER); - extern int LogL10fromY(double, int = SGILOGENCODE_NODITHER); - extern int uv_encode(double, double, int = SGILOGENCODE_NODITHER); - extern uint32_t LogLuv24fromXYZ(float *, int = SGILOGENCODE_NODITHER); - extern uint32_t LogLuv32fromXYZ(float *, int = SGILOGENCODE_NODITHER); -#else - extern int LogL16fromY(double, int); - extern int LogL10fromY(double, int); - extern int uv_encode(double, double, int); - extern uint32_t LogLuv24fromXYZ(float *, int); - extern uint32_t LogLuv32fromXYZ(float *, int); -#endif -#endif /* LOGLUV_PUBLIC */ - - extern int TIFFCIELabToRGBInit(TIFFCIELabToRGB *, const TIFFDisplay *, - float *); - extern void TIFFCIELabToXYZ(TIFFCIELabToRGB *, uint32_t, int32_t, int32_t, - float *, float *, float *); - extern void TIFFXYZToRGB(TIFFCIELabToRGB *, float, float, float, uint32_t *, - uint32_t *, uint32_t *); - - extern int TIFFYCbCrToRGBInit(TIFFYCbCrToRGB *, float *, float *); - extern void TIFFYCbCrtoRGB(TIFFYCbCrToRGB *, uint32_t, int32_t, int32_t, - uint32_t *, uint32_t *, uint32_t *); - - /**************************************************************************** - * O B S O L E T E D I N T E R F A C E S - * - * Don't use this stuff in your applications, it may be removed in the - *future libtiff versions. - ****************************************************************************/ - typedef struct - { - ttag_t field_tag; /* field's tag */ - short field_readcount; /* read count/TIFF_VARIABLE/TIFF_SPP */ - short field_writecount; /* write count/TIFF_VARIABLE */ - TIFFDataType field_type; /* type of associated data */ - 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 */ - } TIFFFieldInfo; - - extern int TIFFMergeFieldInfo(TIFF *, const TIFFFieldInfo[], uint32_t); - -#if defined(c_plusplus) || defined(__cplusplus) -} -#endif - -#endif /* _TIFFIO_ */ diff --git a/src/3rd/tiff/tiffiop.h b/src/3rd/tiff/tiffiop.h deleted file mode 100644 index ecbf5d12f16..00000000000 --- a/src/3rd/tiff/tiffiop.h +++ /dev/null @@ -1,523 +0,0 @@ -/* - * Copyright (c) 1988-1997 Sam Leffler - * Copyright (c) 1991-1997 Silicon Graphics, Inc. - * - * Permission to use, copy, modify, distribute, and sell this software and - * its documentation for any purpose is hereby granted without fee, provided - * that (i) the above copyright notices and this permission notice appear in - * all copies of the software and related documentation, and (ii) the names of - * Sam Leffler and Silicon Graphics may not be used in any advertising or - * publicity relating to the software without the specific, prior written - * permission of Sam Leffler and Silicon Graphics. - * - * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, - * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY - * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. - * - * IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR - * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, - * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, - * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF - * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE - * OF THIS SOFTWARE. - */ - -#ifndef _TIFFIOP_ -#define _TIFFIOP_ -/* - * ``Library-private'' definitions. - */ - -#include "tiffconf.h" - -#ifdef HAVE_FCNTL_H -#include -#endif - -#ifdef HAVE_SYS_TYPES_H -#include -#endif - -#include - -#ifdef HAVE_ASSERT_H -#include -#else -#define assert(x) -#endif - -#include "hash_set.h" -#include "tiffio.h" - -#include "dir.h" - -#include - -#ifndef STRIP_SIZE_DEFAULT -#define STRIP_SIZE_DEFAULT 8192 -#endif - -#ifndef TIFF_MAX_DIR_COUNT -#define TIFF_MAX_DIR_COUNT 1048576 -#endif - -#define TIFF_NON_EXISTENT_DIR_NUMBER UINT_MAX - -#define streq(a, b) (strcmp(a, b) == 0) -#define strneq(a, b, n) (strncmp(a, b, n) == 0) - -#ifndef TRUE -#define TRUE 1 -#define FALSE 0 -#endif - -typedef struct client_info -{ - struct client_info *next; - void *data; - char *name; -} TIFFClientInfoLink; - -/* - * Typedefs for ``method pointers'' used internally. - * these are deprecated and provided only for backwards compatibility. - */ -typedef unsigned char tidataval_t; /* internal image data value type */ -typedef tidataval_t *tidata_t; /* reference to internal image data */ - -typedef void (*TIFFVoidMethod)(TIFF *); -typedef int (*TIFFBoolMethod)(TIFF *); -typedef int (*TIFFPreMethod)(TIFF *, uint16_t); -typedef int (*TIFFCodeMethod)(TIFF *tif, uint8_t *buf, tmsize_t size, - uint16_t sample); -typedef int (*TIFFSeekMethod)(TIFF *, uint32_t); -typedef void (*TIFFPostMethod)(TIFF *tif, uint8_t *buf, tmsize_t size); -typedef uint32_t (*TIFFStripMethod)(TIFF *, uint32_t); -typedef void (*TIFFTileMethod)(TIFF *, uint32_t *, uint32_t *); - -struct TIFFOffsetAndDirNumber -{ - uint64_t offset; - tdir_t dirNumber; -}; -typedef struct TIFFOffsetAndDirNumber TIFFOffsetAndDirNumber; - -struct tiff -{ - char *tif_name; /* name of open file */ - int tif_fd; /* open file descriptor */ - int tif_mode; /* open mode (O_*) */ - uint32_t tif_flags; -#define TIFF_FILLORDER 0x00003U /* natural bit fill order for machine */ -#define TIFF_DIRTYHEADER 0x00004U /* header must be written on close */ -#define TIFF_DIRTYDIRECT 0x00008U /* current directory must be written */ -#define TIFF_BUFFERSETUP 0x00010U /* data buffers setup */ -#define TIFF_CODERSETUP 0x00020U /* encoder/decoder setup done */ -#define TIFF_BEENWRITING 0x00040U /* written 1+ scanlines to file */ -#define TIFF_SWAB 0x00080U /* byte swap file information */ -#define TIFF_NOBITREV 0x00100U /* inhibit bit reversal logic */ -#define TIFF_MYBUFFER 0x00200U /* my raw data buffer; free on close */ -#define TIFF_ISTILED 0x00400U /* file is tile, not strip- based */ -#define TIFF_MAPPED 0x00800U /* file is mapped into memory */ -#define TIFF_POSTENCODE 0x01000U /* need call to postencode routine */ -#define TIFF_INSUBIFD 0x02000U /* currently writing a subifd */ -#define TIFF_UPSAMPLED 0x04000U /* library is doing data up-sampling */ -#define TIFF_STRIPCHOP 0x08000U /* enable strip chopping support */ -#define TIFF_HEADERONLY \ - 0x10000U /* read header only, do not process the first directory */ -#define TIFF_NOREADRAW \ - 0x20000U /* skip reading of raw uncompressed image data */ -#define TIFF_INCUSTOMIFD 0x40000U /* currently writing a custom IFD */ -#define TIFF_BIGTIFF 0x80000U /* read/write bigtiff */ -#define TIFF_BUF4WRITE 0x100000U /* rawcc bytes are for writing */ -#define TIFF_DIRTYSTRIP 0x200000U /* stripoffsets/stripbytecount dirty*/ -#define TIFF_PERSAMPLE 0x400000U /* get/set per sample tags as arrays */ -#define TIFF_BUFFERMMAP \ - 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_CHOPPEDUPARRAYS \ - 0x4000000U /* set when allocChoppedUpStripArrays() has modified strip \ - array */ - uint64_t tif_diroff; /* file offset of current directory */ - uint64_t tif_nextdiroff; /* file offset of following directory */ - uint64_t tif_lastdiroff; /* file offset of last directory written so far */ - TIFFHashSet *tif_map_dir_offset_to_number; - TIFFHashSet *tif_map_dir_number_to_offset; - int tif_setdirectory_force_absolute; /* switch between relative and absolute - stepping in TIFFSetDirectory() */ - TIFFDirectory tif_dir; /* internal rep of current directory */ - TIFFDirectory - tif_customdir; /* custom IFDs are separated from the main ones */ - union - { - TIFFHeaderCommon common; - TIFFHeaderClassic classic; - TIFFHeaderBig big; - } tif_header; - uint16_t tif_header_size; /* file's header block and its length */ - uint32_t tif_row; /* current scanline */ - tdir_t tif_curdir; /* current directory (index) */ - uint32_t tif_curstrip; /* current strip for read/write */ - uint64_t tif_curoff; /* current offset for read/write */ - uint64_t tif_lastvalidoff; /* last valid offset allowed for rewrite in - place. Used only by TIFFAppendToStrip() */ - uint64_t tif_dataoff; /* current offset for writing dir */ - /* SubIFD support */ - uint16_t tif_nsubifd; /* remaining subifds to write */ - 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 */ - TIFFBoolMethod tif_setupdecode; /* called once before predecode */ - TIFFPreMethod tif_predecode; /* pre- row/strip/tile decoding */ - TIFFBoolMethod tif_setupencode; /* called once before preencode */ - int tif_encodestatus; - TIFFPreMethod tif_preencode; /* pre- row/strip/tile encoding */ - TIFFBoolMethod tif_postencode; /* post- row/strip/tile encoding */ - TIFFCodeMethod tif_decoderow; /* scanline decoding routine */ - TIFFCodeMethod tif_encoderow; /* scanline encoding routine */ - TIFFCodeMethod tif_decodestrip; /* strip decoding routine */ - TIFFCodeMethod tif_encodestrip; /* strip encoding routine */ - TIFFCodeMethod tif_decodetile; /* tile decoding routine */ - TIFFCodeMethod tif_encodetile; /* tile encoding routine */ - TIFFVoidMethod tif_close; /* cleanup-on-close routine */ - TIFFSeekMethod tif_seek; /* position within a strip routine */ - 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 */ - /* 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 */ - tmsize_t tif_rawdataloaded; /* amount of data in rawdata */ - uint8_t *tif_rawcp; /* current spot in raw buffer */ - tmsize_t tif_rawcc; /* bytes unread from raw buffer */ - /* memory-mapped file support */ - uint8_t *tif_base; /* base of mapped file */ - tmsize_t tif_size; /* size of mapped file region (bytes, thus tmsize_t) */ - TIFFMapFileProc tif_mapproc; /* map file method */ - TIFFUnmapFileProc tif_unmapproc; /* unmap file method */ - /* input/output callback methods */ - thandle_t tif_clientdata; /* callback parameter */ - TIFFReadWriteProc tif_readproc; /* read method */ - TIFFReadWriteProc tif_writeproc; /* write method */ - TIFFSeekProc tif_seekproc; /* lseek method */ - TIFFCloseProc tif_closeproc; /* close method */ - TIFFSizeProc tif_sizeproc; /* filesize method */ - /* post-decoding support */ - TIFFPostMethod tif_postdecode; /* post decoding routine */ - /* tag support */ - TIFFField **tif_fields; /* sorted table of registered tags */ - size_t tif_nfields; /* # entries in registered tag table */ - const TIFFField *tif_foundfield; /* cached pointer to already found tag */ - TIFFTagMethods tif_tagmethods; /* tag get/set/print routines */ - TIFFClientInfoLink *tif_clientinfo; /* extra client information. */ - /* Backward compatibility stuff. We need these two fields for - * setting up an old tag extension scheme. */ - TIFFFieldArray *tif_fieldscompat; - size_t tif_nfieldscompat; - /* Error handler support */ - TIFFErrorHandlerExtR tif_errorhandler; - void *tif_errorhandler_user_data; - TIFFErrorHandlerExtR tif_warnhandler; - void *tif_warnhandler_user_data; - tmsize_t tif_max_single_mem_alloc; /* in bytes. 0 for unlimited */ -}; - -struct TIFFOpenOptions -{ - TIFFErrorHandlerExtR errorhandler; /* may be NULL */ - void *errorhandler_user_data; /* may be NULL */ - TIFFErrorHandlerExtR warnhandler; /* may be NULL */ - void *warnhandler_user_data; /* may be NULL */ - tmsize_t max_single_mem_alloc; /* in bytes. 0 for unlimited */ -}; - -#define isPseudoTag(t) (t > 0xffff) /* is tag value normal or pseudo */ - -#define isTiled(tif) (((tif)->tif_flags & TIFF_ISTILED) != 0) -#define isMapped(tif) (((tif)->tif_flags & TIFF_MAPPED) != 0) -#define isFillOrder(tif, o) (((tif)->tif_flags & (o)) != 0) -#define isUpSampled(tif) (((tif)->tif_flags & TIFF_UPSAMPLED) != 0) -#define TIFFReadFile(tif, buf, size) \ - ((*(tif)->tif_readproc)((tif)->tif_clientdata, (buf), (size))) -#define TIFFWriteFile(tif, buf, size) \ - ((*(tif)->tif_writeproc)((tif)->tif_clientdata, (buf), (size))) -#define TIFFSeekFile(tif, off, whence) \ - ((*(tif)->tif_seekproc)((tif)->tif_clientdata, (off), (whence))) -#define TIFFCloseFile(tif) ((*(tif)->tif_closeproc)((tif)->tif_clientdata)) -#define TIFFGetFileSize(tif) ((*(tif)->tif_sizeproc)((tif)->tif_clientdata)) -#define TIFFMapFileContents(tif, paddr, psize) \ - ((*(tif)->tif_mapproc)((tif)->tif_clientdata, (paddr), (psize))) -#define TIFFUnmapFileContents(tif, addr, size) \ - ((*(tif)->tif_unmapproc)((tif)->tif_clientdata, (addr), (size))) - -/* - * Default Read/Seek/Write definitions. - */ -#ifndef ReadOK -#define ReadOK(tif, buf, size) (TIFFReadFile((tif), (buf), (size)) == (size)) -#endif -#ifndef SeekOK -#define SeekOK(tif, off) _TIFFSeekOK(tif, off) -#endif -#ifndef WriteOK -#define WriteOK(tif, buf, size) (TIFFWriteFile((tif), (buf), (size)) == (size)) -#endif - -/* NB: the uint32_t casts are to silence certain ANSI-C compilers */ -#define TIFFhowmany_32(x, y) \ - (((uint32_t)x < (0xffffffff - (uint32_t)(y - 1))) \ - ? ((((uint32_t)(x)) + (((uint32_t)(y)) - 1)) / ((uint32_t)(y))) \ - : 0U) -/* Variant of TIFFhowmany_32() that doesn't return 0 if x close to MAXUINT. */ -/* Caution: TIFFhowmany_32_maxuint_compat(x,y)*y might overflow */ -#define TIFFhowmany_32_maxuint_compat(x, y) \ - (((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)) -#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)) - -/* 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)0) - -#define TIFFmax(A, B) ((A) > (B) ? (A) : (B)) -#define TIFFmin(A, B) ((A) < (B) ? (A) : (B)) - -#define TIFFArrayCount(a) (sizeof(a) / sizeof((a)[0])) - -/* - Support for large files. - - Windows read/write APIs support only 'unsigned int' rather than 'size_t'. - Windows off_t is only 32-bit, even in 64-bit builds. -*/ -#if defined(HAVE_FSEEKO) -/* - Use fseeko() and ftello() if they are available since they use - 'off_t' rather than 'long'. It is wrong to use fseeko() and - ftello() only on systems with special LFS support since some systems - (e.g. FreeBSD) support a 64-bit off_t by default. - - For MinGW, __MSVCRT_VERSION__ must be at least 0x800 to expose these - interfaces. The MinGW compiler must support the requested version. MinGW - does not distribute the CRT (it is supplied by Microsoft) so the correct CRT - must be available on the target computer in order for the program to run. -*/ -#if defined(HAVE_FSEEKO) -#define fseek(stream, offset, whence) fseeko(stream, offset, whence) -#define ftell(stream, offset, whence) ftello(stream, offset, whence) -#endif -#endif -#if defined(__WIN32__) && !(defined(_MSC_VER) && _MSC_VER < 1400) && \ - !(defined(__MSVCRT_VERSION__) && __MSVCRT_VERSION__ < 0x800) -typedef unsigned int TIFFIOSize_t; -#define _TIFF_lseek_f(fildes, offset, whence) \ - _lseeki64(fildes, /* __int64 */ offset, whence) -/* #define _TIFF_tell_f(fildes) /\* __int64 *\/ _telli64(fildes) */ -#define _TIFF_fseek_f(stream, offset, whence) \ - _fseeki64(stream, /* __int64 */ offset, whence) -#define _TIFF_fstat_f(fildes, stat_buff) \ - _fstati64(fildes, /* struct _stati64 */ stat_buff) -/* #define _TIFF_ftell_f(stream) /\* __int64 *\/ _ftelli64(stream) */ -/* #define _TIFF_stat_f(path,stat_buff) _stati64(path,/\* struct _stati64 *\/ - * stat_buff) */ -#define _TIFF_stat_s struct _stati64 -#define _TIFF_off_t __int64 -#else -typedef size_t TIFFIOSize_t; -#define _TIFF_lseek_f(fildes, offset, whence) lseek(fildes, offset, whence) -/* #define _TIFF_tell_f(fildes) (_TIFF_lseek_f(fildes,0,SEEK_CUR)) */ -#define _TIFF_fseek_f(stream, offset, whence) fseek(stream, offset, whence) -#define _TIFF_fstat_f(fildes, stat_buff) fstat(fildes, stat_buff) -/* #define _TIFF_ftell_f(stream) ftell(stream) */ -/* #define _TIFF_stat_f(path,stat_buff) stat(path,stat_buff) */ -#define _TIFF_stat_s struct stat -#define _TIFF_off_t off_t -#endif - -#if defined(__has_attribute) && defined(__clang__) -#if __has_attribute(no_sanitize) -#define TIFF_NOSANITIZE_UNSIGNED_INT_OVERFLOW \ - __attribute__((no_sanitize("unsigned-integer-overflow"))) -#else -#define TIFF_NOSANITIZE_UNSIGNED_INT_OVERFLOW -#endif -#else -#define TIFF_NOSANITIZE_UNSIGNED_INT_OVERFLOW -#endif - -#if defined(__cplusplus) -extern "C" -{ -#endif - extern int _TIFFgetMode(TIFFOpenOptions *opts, thandle_t clientdata, - const char *mode, const char *module); - extern int _TIFFNoRowEncode(TIFF *tif, uint8_t *pp, tmsize_t cc, - uint16_t s); - extern int _TIFFNoStripEncode(TIFF *tif, uint8_t *pp, tmsize_t cc, - uint16_t s); - extern int _TIFFNoTileEncode(TIFF *, uint8_t *pp, tmsize_t cc, uint16_t s); - extern int _TIFFNoRowDecode(TIFF *tif, uint8_t *pp, tmsize_t cc, - uint16_t s); - extern int _TIFFNoStripDecode(TIFF *tif, uint8_t *pp, tmsize_t cc, - uint16_t s); - extern int _TIFFNoTileDecode(TIFF *, uint8_t *pp, tmsize_t cc, uint16_t s); - extern void _TIFFNoPostDecode(TIFF *tif, uint8_t *buf, tmsize_t cc); - extern int _TIFFNoPreCode(TIFF *tif, uint16_t s); - extern int _TIFFNoSeek(TIFF *tif, uint32_t off); - extern void _TIFFSwab16BitData(TIFF *tif, uint8_t *buf, tmsize_t cc); - extern void _TIFFSwab24BitData(TIFF *tif, uint8_t *buf, tmsize_t cc); - extern void _TIFFSwab32BitData(TIFF *tif, uint8_t *buf, tmsize_t cc); - extern void _TIFFSwab64BitData(TIFF *tif, uint8_t *buf, tmsize_t cc); - extern int TIFFFlushData1(TIFF *tif); - extern int TIFFDefaultDirectory(TIFF *tif); - extern void _TIFFSetDefaultCompressionState(TIFF *tif); - extern int _TIFFRewriteField(TIFF *, uint16_t, TIFFDataType, tmsize_t, - void *); - extern int TIFFSetCompressionScheme(TIFF *tif, int scheme); - extern int TIFFSetDefaultCompressionState(TIFF *tif); - extern uint32_t _TIFFDefaultStripSize(TIFF *tif, uint32_t s); - extern void _TIFFDefaultTileSize(TIFF *tif, uint32_t *tw, uint32_t *th); - - extern void _TIFFsetByteArray(void **, const void *, uint32_t); - extern void _TIFFsetByteArrayExt(TIFF *, void **, const void *, uint32_t); - extern void _TIFFsetShortArray(uint16_t **, const uint16_t *, uint32_t); - extern void _TIFFsetShortArrayExt(TIFF *, uint16_t **, const uint16_t *, - uint32_t); - extern void _TIFFsetLongArray(uint32_t **, const uint32_t *, uint32_t); - extern void _TIFFsetLongArrayExt(TIFF *, uint32_t **, const uint32_t *, - uint32_t); - extern void _TIFFsetFloatArray(float **, const float *, uint32_t); - extern void _TIFFsetFloatArrayExt(TIFF *, float **, const float *, - uint32_t); - extern void _TIFFsetDoubleArray(double **, const double *, uint32_t); - extern void _TIFFsetDoubleArrayExt(TIFF *, double **, const double *, - uint32_t); - - extern void _TIFFprintAscii(FILE *, const char *); - extern void _TIFFprintAsciiTag(FILE *, const char *, const char *); - - extern TIFFErrorHandler _TIFFwarningHandler; - extern TIFFErrorHandler _TIFFerrorHandler; - extern TIFFErrorHandlerExt _TIFFwarningHandlerExt; - extern TIFFErrorHandlerExt _TIFFerrorHandlerExt; - void _TIFFErrorEarly(TIFFOpenOptions *opts, thandle_t clientdata, - const char *module, const char *fmt, ...) - TIFF_ATTRIBUTE((__format__(__printf__, 4, 5))); - - extern uint32_t _TIFFMultiply32(TIFF *, uint32_t, uint32_t, const char *); - extern uint64_t _TIFFMultiply64(TIFF *, uint64_t, uint64_t, const char *); - extern tmsize_t _TIFFMultiplySSize(TIFF *, tmsize_t, tmsize_t, - const char *); - extern tmsize_t _TIFFCastUInt64ToSSize(TIFF *, uint64_t, const char *); - extern void *_TIFFCheckMalloc(TIFF *, tmsize_t, tmsize_t, const char *); - extern void *_TIFFCheckRealloc(TIFF *, void *, tmsize_t, tmsize_t, - const char *); - - extern double _TIFFUInt64ToDouble(uint64_t); - extern float _TIFFUInt64ToFloat(uint64_t); - - extern float _TIFFClampDoubleToFloat(double); - extern uint32_t _TIFFClampDoubleToUInt32(double); - - extern void _TIFFCleanupIFDOffsetAndNumberMaps(TIFF *tif); - - extern tmsize_t _TIFFReadEncodedStripAndAllocBuffer(TIFF *tif, - uint32_t strip, - void **buf, - tmsize_t bufsizetoalloc, - tmsize_t size_to_read); - extern tmsize_t _TIFFReadEncodedTileAndAllocBuffer(TIFF *tif, uint32_t tile, - void **buf, - tmsize_t bufsizetoalloc, - tmsize_t size_to_read); - extern tmsize_t _TIFFReadTileAndAllocBuffer(TIFF *tif, void **buf, - tmsize_t bufsizetoalloc, - uint32_t x, uint32_t y, - uint32_t z, uint16_t s); - extern int _TIFFSeekOK(TIFF *tif, toff_t off); - - extern int TIFFInitDumpMode(TIFF *, int); -#ifdef PACKBITS_SUPPORT - extern int TIFFInitPackBits(TIFF *, int); -#endif -#ifdef CCITT_SUPPORT - extern int TIFFInitCCITTRLE(TIFF *, int), TIFFInitCCITTRLEW(TIFF *, int); - extern int TIFFInitCCITTFax3(TIFF *, int), TIFFInitCCITTFax4(TIFF *, int); -#endif -#ifdef THUNDER_SUPPORT - extern int TIFFInitThunderScan(TIFF *, int); -#endif -#ifdef NEXT_SUPPORT - extern int TIFFInitNeXT(TIFF *, int); -#endif -#ifdef LZW_SUPPORT - extern int TIFFInitLZW(TIFF *, int); -#endif -#ifdef OJPEG_SUPPORT - extern int TIFFInitOJPEG(TIFF *, int); -#endif -#ifdef JPEG_SUPPORT - extern int TIFFInitJPEG(TIFF *, int); - extern int TIFFJPEGIsFullStripRequired(TIFF *); -#endif -#ifdef JBIG_SUPPORT - extern int TIFFInitJBIG(TIFF *, int); -#endif -#ifdef ZIP_SUPPORT - extern int TIFFInitZIP(TIFF *, int); -#endif -#ifdef PIXARLOG_SUPPORT - extern int TIFFInitPixarLog(TIFF *, int); -#endif -#ifdef LOGLUV_SUPPORT - extern int TIFFInitSGILog(TIFF *, int); -#endif -#ifdef LERC_SUPPORT - extern int TIFFInitLERC(TIFF *tif, int); -#endif -#ifdef LZMA_SUPPORT - extern int TIFFInitLZMA(TIFF *, int); -#endif -#ifdef ZSTD_SUPPORT - extern int TIFFInitZSTD(TIFF *, int); -#endif -#ifdef WEBP_SUPPORT - extern int TIFFInitWebP(TIFF *, int); -#endif - extern const TIFFCodec _TIFFBuiltinCODECS[]; - extern void TIFFCIELab16ToXYZ(TIFFCIELabToRGB *, uint32_t l, int32_t a, - int32_t b, float *, float *, float *); - - extern void *_TIFFmallocExt(TIFF *tif, tmsize_t s); - extern void *_TIFFcallocExt(TIFF *tif, tmsize_t nmemb, tmsize_t siz); - extern void *_TIFFreallocExt(TIFF *tif, void *p, tmsize_t s); - extern void _TIFFfreeExt(TIFF *tif, void *p); - -#if defined(__cplusplus) -} -#endif -#endif /* _TIFFIOP_ */ diff --git a/src/3rd/tiff/tiffvers.h b/src/3rd/tiff/tiffvers.h deleted file mode 100644 index 892e9a0b239..00000000000 --- a/src/3rd/tiff/tiffvers.h +++ /dev/null @@ -1,36 +0,0 @@ -/* tiffvers.h version information is updated according to version information - * in configure.ac */ - -/* clang-format off */ - -/* clang-format disabled because FindTIFF.cmake is very sensitive to the - * formatting of below line being a single line. - * Furthermore, configure_file variables of type "@VAR@" are - * modified by clang-format and won't be substituted by CMake. - */ -#define TIFFLIB_VERSION_STR "LIBTIFF, Version 4.6.0\nCopyright (c) 1988-1996 Sam Leffler\nCopyright (c) 1991-1996 Silicon Graphics, Inc." -/* - * This define can be used in code that requires - * compilation-related definitions specific to a - * version or versions of the library. Runtime - * version checking should be done based on the - * string returned by TIFFGetVersion. - */ -#define TIFFLIB_VERSION 20230908 - -/* The following defines have been added in 4.5.0 */ -#define TIFFLIB_MAJOR_VERSION 4 -#define TIFFLIB_MINOR_VERSION 6 -#define TIFFLIB_MICRO_VERSION 0 -#define TIFFLIB_VERSION_STR_MAJ_MIN_MIC "4.6.0" - -/* Macro added in 4.5.0. Returns TRUE if the current libtiff version is - * greater or equal to major.minor.micro - */ -#define TIFFLIB_AT_LEAST(major, minor, micro) \ - (TIFFLIB_MAJOR_VERSION > (major) || \ - (TIFFLIB_MAJOR_VERSION == (major) && TIFFLIB_MINOR_VERSION > (minor)) || \ - (TIFFLIB_MAJOR_VERSION == (major) && TIFFLIB_MINOR_VERSION == (minor) && \ - TIFFLIB_MICRO_VERSION >= (micro))) - -/* clang-format on */ diff --git a/src/3rd/tiff/tile.c b/src/3rd/tiff/tile.c deleted file mode 100644 index f07032f731f..00000000000 --- a/src/3rd/tiff/tile.c +++ /dev/null @@ -1,284 +0,0 @@ -/* - * Copyright (c) 1991-1997 Sam Leffler - * Copyright (c) 1991-1997 Silicon Graphics, Inc. - * - * Permission to use, copy, modify, distribute, and sell this software and - * its documentation for any purpose is hereby granted without fee, provided - * that (i) the above copyright notices and this permission notice appear in - * all copies of the software and related documentation, and (ii) the names of - * Sam Leffler and Silicon Graphics may not be used in any advertising or - * publicity relating to the software without the specific, prior written - * permission of Sam Leffler and Silicon Graphics. - * - * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, - * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY - * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. - * - * IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR - * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, - * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, - * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF - * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE - * OF THIS SOFTWARE. - */ - -/* - * TIFF Library. - * - * Tiled Image Support Routines. - */ -#include "tiffiop.h" - -/* - * Compute which tile an (x,y,z,s) value is in. - */ -uint32_t TIFFComputeTile(TIFF *tif, uint32_t x, uint32_t y, uint32_t z, - uint16_t s) -{ - TIFFDirectory *td = &tif->tif_dir; - uint32_t dx = td->td_tilewidth; - uint32_t dy = td->td_tilelength; - uint32_t dz = td->td_tiledepth; - uint32_t tile = 1; - - if (td->td_imagedepth == 1) - z = 0; - if (dx == (uint32_t)-1) - dx = td->td_imagewidth; - if (dy == (uint32_t)-1) - dy = td->td_imagelength; - if (dz == (uint32_t)-1) - dz = td->td_imagedepth; - if (dx != 0 && dy != 0 && dz != 0) - { - 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); - - 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; - } - return (tile); -} - -/* - * Check an (x,y,z,s) coordinate - * against the image bounds. - */ -int TIFFCheckTile(TIFF *tif, uint32_t x, uint32_t y, uint32_t z, uint16_t s) -{ - TIFFDirectory *td = &tif->tif_dir; - - if (x >= td->td_imagewidth) - { - TIFFErrorExtR(tif, tif->tif_name, "%lu: Col out of range, max %lu", - (unsigned long)x, (unsigned long)(td->td_imagewidth - 1)); - return (0); - } - if (y >= td->td_imagelength) - { - TIFFErrorExtR(tif, tif->tif_name, "%lu: Row out of range, max %lu", - (unsigned long)y, - (unsigned long)(td->td_imagelength - 1)); - return (0); - } - if (z >= td->td_imagedepth) - { - TIFFErrorExtR(tif, tif->tif_name, "%lu: Depth out of range, max %lu", - (unsigned long)z, (unsigned long)(td->td_imagedepth - 1)); - return (0); - } - if (td->td_planarconfig == PLANARCONFIG_SEPARATE && - s >= td->td_samplesperpixel) - { - TIFFErrorExtR(tif, tif->tif_name, "%lu: Sample out of range, max %lu", - (unsigned long)s, - (unsigned long)(td->td_samplesperpixel - 1)); - return (0); - } - return (1); -} - -/* - * Compute how many tiles are in an image. - */ -uint32_t TIFFNumberOfTiles(TIFF *tif) -{ - TIFFDirectory *td = &tif->tif_dir; - uint32_t dx = td->td_tilewidth; - uint32_t dy = td->td_tilelength; - uint32_t dz = td->td_tiledepth; - uint32_t ntiles; - - if (dx == (uint32_t)-1) - dx = td->td_imagewidth; - if (dy == (uint32_t)-1) - dy = td->td_imagelength; - if (dz == (uint32_t)-1) - dz = td->td_imagedepth; - ntiles = - (dx == 0 || dy == 0 || dz == 0) - ? 0 - : _TIFFMultiply32( - tif, - _TIFFMultiply32(tif, TIFFhowmany_32(td->td_imagewidth, dx), - TIFFhowmany_32(td->td_imagelength, dy), - "TIFFNumberOfTiles"), - TIFFhowmany_32(td->td_imagedepth, dz), "TIFFNumberOfTiles"); - if (td->td_planarconfig == PLANARCONFIG_SEPARATE) - ntiles = _TIFFMultiply32(tif, ntiles, td->td_samplesperpixel, - "TIFFNumberOfTiles"); - return (ntiles); -} - -/* - * Compute the # bytes in each row of a tile. - */ -uint64_t TIFFTileRowSize64(TIFF *tif) -{ - static const char module[] = "TIFFTileRowSize64"; - TIFFDirectory *td = &tif->tif_dir; - uint64_t rowsize; - uint64_t tilerowsize; - - if (td->td_tilelength == 0) - { - TIFFErrorExtR(tif, module, "Tile length is zero"); - return 0; - } - if (td->td_tilewidth == 0) - { - TIFFErrorExtR(tif, module, "Tile width is zero"); - return (0); - } - rowsize = _TIFFMultiply64(tif, td->td_bitspersample, td->td_tilewidth, - "TIFFTileRowSize"); - if (td->td_planarconfig == PLANARCONFIG_CONTIG) - { - if (td->td_samplesperpixel == 0) - { - TIFFErrorExtR(tif, module, "Samples per pixel is zero"); - return 0; - } - rowsize = _TIFFMultiply64(tif, rowsize, td->td_samplesperpixel, - "TIFFTileRowSize"); - } - tilerowsize = TIFFhowmany8_64(rowsize); - if (tilerowsize == 0) - { - TIFFErrorExtR(tif, module, "Computed tile row size is zero"); - return 0; - } - return (tilerowsize); -} -tmsize_t TIFFTileRowSize(TIFF *tif) -{ - static const char module[] = "TIFFTileRowSize"; - uint64_t m; - m = TIFFTileRowSize64(tif); - return _TIFFCastUInt64ToSSize(tif, m, module); -} - -/* - * Compute the # bytes in a variable length, row-aligned tile. - */ -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)); -} -tmsize_t TIFFVTileSize(TIFF *tif, uint32_t nrows) -{ - static const char module[] = "TIFFVTileSize"; - uint64_t m; - m = TIFFVTileSize64(tif, nrows); - return _TIFFCastUInt64ToSSize(tif, m, module); -} - -/* - * Compute the # bytes in a row-aligned tile. - */ -uint64_t TIFFTileSize64(TIFF *tif) -{ - return (TIFFVTileSize64(tif, tif->tif_dir.td_tilelength)); -} -tmsize_t TIFFTileSize(TIFF *tif) -{ - static const char module[] = "TIFFTileSize"; - uint64_t m; - m = TIFFTileSize64(tif); - return _TIFFCastUInt64ToSSize(tif, m, module); -} - -/* - * Compute a default tile size based on the image - * characteristics and a requested value. If a - * request is <1 then we choose a size according - * to certain heuristics. - */ -void TIFFDefaultTileSize(TIFF *tif, uint32_t *tw, uint32_t *th) -{ - (*tif->tif_deftilesize)(tif, tw, th); -} - -void _TIFFDefaultTileSize(TIFF *tif, uint32_t *tw, uint32_t *th) -{ - (void)tif; - if (*(int32_t *)tw < 1) - *tw = 256; - if (*(int32_t *)th < 1) - *th = 256; - /* roundup to a multiple of 16 per the spec */ - if (*tw & 0xf) - *tw = TIFFroundup_32(*tw, 16); - if (*th & 0xf) - *th = TIFFroundup_32(*th, 16); -} diff --git a/src/3rd/tiff/unix.c b/src/3rd/tiff/unix.c deleted file mode 100644 index 14abf05d7a5..00000000000 --- a/src/3rd/tiff/unix.c +++ /dev/null @@ -1,370 +0,0 @@ -/* - * Copyright (c) 1988-1997 Sam Leffler - * Copyright (c) 1991-1997 Silicon Graphics, Inc. - * - * Permission to use, copy, modify, distribute, and sell this software and - * its documentation for any purpose is hereby granted without fee, provided - * that (i) the above copyright notices and this permission notice appear in - * all copies of the software and related documentation, and (ii) the names of - * Sam Leffler and Silicon Graphics may not be used in any advertising or - * publicity relating to the software without the specific, prior written - * permission of Sam Leffler and Silicon Graphics. - * - * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, - * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY - * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. - * - * IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR - * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, - * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, - * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF - * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE - * OF THIS SOFTWARE. - */ - -/* - * TIFF Library UNIX-specific Routines. These are should also work with the - * Windows Common RunTime Library. - */ - -#include "tiffconf.h" - -#ifdef HAVE_SYS_TYPES_H -#include -#endif - -#include - -#include -#include -#include - -#ifdef HAVE_UNISTD_H -#include -#endif - -#ifdef HAVE_FCNTL_H -#include -#endif - -#ifdef HAVE_IO_H -#include -#endif - -#include "tiffiop.h" - -#define TIFF_IO_MAX 2147483647U - -typedef union fd_as_handle_union -{ - int fd; - thandle_t h; -} fd_as_handle_union_t; - -static tmsize_t _tiffReadProc(thandle_t fd, void *buf, tmsize_t size) -{ - fd_as_handle_union_t fdh; - const size_t bytes_total = (size_t)size; - size_t bytes_read; - tmsize_t count = -1; - if ((tmsize_t)bytes_total != size) - { - errno = EINVAL; - return (tmsize_t)-1; - } - fdh.h = fd; - for (bytes_read = 0; bytes_read < bytes_total; bytes_read += count) - { - char *buf_offset = (char *)buf + bytes_read; - size_t io_size = bytes_total - bytes_read; - if (io_size > TIFF_IO_MAX) - io_size = TIFF_IO_MAX; - count = read(fdh.fd, buf_offset, (TIFFIOSize_t)io_size); - if (count <= 0) - break; - } - if (count < 0) - return (tmsize_t)-1; - return (tmsize_t)bytes_read; -} - -static tmsize_t _tiffWriteProc(thandle_t fd, void *buf, tmsize_t size) -{ - fd_as_handle_union_t fdh; - const size_t bytes_total = (size_t)size; - size_t bytes_written; - tmsize_t count = -1; - if ((tmsize_t)bytes_total != size) - { - errno = EINVAL; - return (tmsize_t)-1; - } - fdh.h = fd; - for (bytes_written = 0; bytes_written < bytes_total; bytes_written += count) - { - const char *buf_offset = (char *)buf + bytes_written; - size_t io_size = bytes_total - bytes_written; - if (io_size > TIFF_IO_MAX) - io_size = TIFF_IO_MAX; - count = write(fdh.fd, buf_offset, (TIFFIOSize_t)io_size); - if (count <= 0) - break; - } - if (count < 0) - return (tmsize_t)-1; - return (tmsize_t)bytes_written; - /* return ((tmsize_t) write(fdh.fd, buf, bytes_total)); */ -} - -static uint64_t _tiffSeekProc(thandle_t fd, uint64_t off, int whence) -{ - fd_as_handle_union_t fdh; - _TIFF_off_t off_io = (_TIFF_off_t)off; - if ((uint64_t)off_io != off) - { - errno = EINVAL; - return (uint64_t)-1; /* this is really gross */ - } - fdh.h = fd; - return ((uint64_t)_TIFF_lseek_f(fdh.fd, off_io, whence)); -} - -static int _tiffCloseProc(thandle_t fd) -{ - fd_as_handle_union_t fdh; - fdh.h = fd; - return (close(fdh.fd)); -} - -static uint64_t _tiffSizeProc(thandle_t fd) -{ - _TIFF_stat_s sb; - fd_as_handle_union_t fdh; - fdh.h = fd; - if (_TIFF_fstat_f(fdh.fd, &sb) < 0) - return (0); - else - return ((uint64_t)sb.st_size); -} - -#ifdef HAVE_MMAP -#include - -static int _tiffMapProc(thandle_t fd, void **pbase, toff_t *psize) -{ - uint64_t size64 = _tiffSizeProc(fd); - tmsize_t sizem = (tmsize_t)size64; - if (size64 && (uint64_t)sizem == size64) - { - fd_as_handle_union_t fdh; - fdh.h = fd; - *pbase = - (void *)mmap(0, (size_t)sizem, PROT_READ, MAP_SHARED, fdh.fd, 0); - if (*pbase != (void *)-1) - { - *psize = (tmsize_t)sizem; - return (1); - } - } - return (0); -} - -static void _tiffUnmapProc(thandle_t fd, void *base, toff_t size) -{ - (void)fd; - (void)munmap(base, (off_t)size); -} -#else /* !HAVE_MMAP */ -static int _tiffMapProc(thandle_t fd, void **pbase, toff_t *psize) -{ - (void)fd; - (void)pbase; - (void)psize; - return (0); -} - -static void _tiffUnmapProc(thandle_t fd, void *base, toff_t size) -{ - (void)fd; - (void)base; - (void)size; -} -#endif /* !HAVE_MMAP */ - -/* - * Open a TIFF file descriptor for read/writing. - */ -TIFF *TIFFFdOpen(int fd, const char *name, const char *mode) -{ - return TIFFFdOpenExt(fd, name, mode, NULL); -} - -TIFF *TIFFFdOpenExt(int fd, const char *name, const char *mode, - TIFFOpenOptions *opts) -{ - TIFF *tif; - - fd_as_handle_union_t fdh; - fdh.fd = fd; - tif = TIFFClientOpenExt(name, mode, fdh.h, _tiffReadProc, _tiffWriteProc, - _tiffSeekProc, _tiffCloseProc, _tiffSizeProc, - _tiffMapProc, _tiffUnmapProc, opts); - if (tif) - tif->tif_fd = fd; - return (tif); -} - -/* - * Open a TIFF file for read/writing. - */ -TIFF *TIFFOpen(const char *name, const char *mode) -{ - return TIFFOpenExt(name, mode, NULL); -} - -TIFF *TIFFOpenExt(const char *name, const char *mode, TIFFOpenOptions *opts) -{ - static const char module[] = "TIFFOpen"; - int m, fd; - TIFF *tif; - - m = _TIFFgetMode(opts, (thandle_t)0, mode, module); - if (m == -1) - return ((TIFF *)0); - -/* for cygwin and mingw */ -#ifdef O_BINARY - m |= O_BINARY; -#endif - - fd = open(name, m, 0666); - if (fd < 0) - { - if (errno > 0 && strerror(errno) != NULL) - { - _TIFFErrorEarly(opts, (thandle_t)0, module, "%s: %s", name, - strerror(errno)); - } - else - { - _TIFFErrorEarly(opts, (thandle_t)0, module, "%s: Cannot open", name); - } - return ((TIFF *)0); - } - - tif = TIFFFdOpenExt((int)fd, name, mode, opts); - if (!tif) - close(fd); - return tif; -} - -#ifdef __WIN32__ -#include -/* - * Open a TIFF file with a Unicode filename, for read/writing. - */ -TIFF *TIFFOpenW(const wchar_t *name, const char *mode) -{ - return TIFFOpenWExt(name, mode, NULL); -} -TIFF *TIFFOpenWExt(const wchar_t *name, const char *mode, TIFFOpenOptions *opts) -{ - static const char module[] = "TIFFOpenW"; - int m, fd; - int mbsize; - char *mbname; - TIFF *tif; - - m = _TIFFgetMode(opts, NULL, mode, module); - if (m == -1) - return ((TIFF *)0); - -/* for cygwin and mingw */ -#ifdef O_BINARY - m |= O_BINARY; -#endif - - fd = _wopen(name, m, 0666); - if (fd < 0) - { - _TIFFErrorEarly(opts, NULL, module, "%ls: Cannot open", name); - return ((TIFF *)0); - } - - mbname = NULL; - mbsize = WideCharToMultiByte(CP_ACP, 0, name, -1, NULL, 0, NULL, NULL); - if (mbsize > 0) - { - mbname = _TIFFmalloc(mbsize); - if (!mbname) - { - _TIFFErrorEarly( - opts, NULL, module, - "Can't allocate space for filename conversion buffer"); - return ((TIFF *)0); - } - - WideCharToMultiByte(CP_ACP, 0, name, -1, mbname, mbsize, NULL, NULL); - } - - tif = TIFFFdOpenExt((int)fd, (mbname != NULL) ? mbname : "", mode, - opts); - - _TIFFfree(mbname); - - if (!tif) - close(fd); - return tif; -} -#endif - -void *_TIFFmalloc(tmsize_t s) -{ - if (s == 0) - return ((void *)NULL); - - return (malloc((size_t)s)); -} - -void *_TIFFcalloc(tmsize_t nmemb, tmsize_t siz) -{ - if (nmemb == 0 || siz == 0) - return ((void *)NULL); - - return calloc((size_t)nmemb, (size_t)siz); -} - -void _TIFFfree(void *p) { free(p); } - -void *_TIFFrealloc(void *p, tmsize_t s) { return (realloc(p, (size_t)s)); } - -void _TIFFmemset(void *p, int v, tmsize_t c) { memset(p, v, (size_t)c); } - -void _TIFFmemcpy(void *d, const void *s, tmsize_t c) -{ - memcpy(d, s, (size_t)c); -} - -int _TIFFmemcmp(const void *p1, const void *p2, tmsize_t c) -{ - return (memcmp(p1, p2, (size_t)c)); -} - -static void unixWarningHandler(const char *module, const char *fmt, va_list ap) -{ - if (module != NULL) - fprintf(stderr, "%s: ", module); - fprintf(stderr, "Warning, "); - vfprintf(stderr, fmt, ap); - fprintf(stderr, ".\n"); -} -TIFFErrorHandler _TIFFwarningHandler = unixWarningHandler; - -static void unixErrorHandler(const char *module, const char *fmt, va_list ap) -{ - if (module != NULL) - fprintf(stderr, "%s: ", module); - vfprintf(stderr, fmt, ap); - fprintf(stderr, ".\n"); -} -TIFFErrorHandler _TIFFerrorHandler = unixErrorHandler; diff --git a/src/3rd/tiff/uvcode.h b/src/3rd/tiff/uvcode.h deleted file mode 100644 index fc877292449..00000000000 --- a/src/3rd/tiff/uvcode.h +++ /dev/null @@ -1,93 +0,0 @@ -/* Version 1.0 generated April 7, 1997 by Greg Ward Larson, SGI */ -#define UV_SQSIZ (float)0.003500 -#define UV_NDIVS 16289 -#define UV_VSTART (float)0.016940 -#define UV_NVS 163 -static const struct -{ - float ustart; - short nus, ncum; -} uv_row[UV_NVS] = { - {(float)0.247663, 4, 0}, {(float)0.243779, 6, 4}, - {(float)0.241684, 7, 10}, {(float)0.237874, 9, 17}, - {(float)0.235906, 10, 26}, {(float)0.232153, 12, 36}, - {(float)0.228352, 14, 48}, {(float)0.226259, 15, 62}, - {(float)0.222371, 17, 77}, {(float)0.220410, 18, 94}, - {(float)0.214710, 21, 112}, {(float)0.212714, 22, 133}, - {(float)0.210721, 23, 155}, {(float)0.204976, 26, 178}, - {(float)0.202986, 27, 204}, {(float)0.199245, 29, 231}, - {(float)0.195525, 31, 260}, {(float)0.193560, 32, 291}, - {(float)0.189878, 34, 323}, {(float)0.186216, 36, 357}, - {(float)0.186216, 36, 393}, {(float)0.182592, 38, 429}, - {(float)0.179003, 40, 467}, {(float)0.175466, 42, 507}, - {(float)0.172001, 44, 549}, {(float)0.172001, 44, 593}, - {(float)0.168612, 46, 637}, {(float)0.168612, 46, 683}, - {(float)0.163575, 49, 729}, {(float)0.158642, 52, 778}, - {(float)0.158642, 52, 830}, {(float)0.158642, 52, 882}, - {(float)0.153815, 55, 934}, {(float)0.153815, 55, 989}, - {(float)0.149097, 58, 1044}, {(float)0.149097, 58, 1102}, - {(float)0.142746, 62, 1160}, {(float)0.142746, 62, 1222}, - {(float)0.142746, 62, 1284}, {(float)0.138270, 65, 1346}, - {(float)0.138270, 65, 1411}, {(float)0.138270, 65, 1476}, - {(float)0.132166, 69, 1541}, {(float)0.132166, 69, 1610}, - {(float)0.126204, 73, 1679}, {(float)0.126204, 73, 1752}, - {(float)0.126204, 73, 1825}, {(float)0.120381, 77, 1898}, - {(float)0.120381, 77, 1975}, {(float)0.120381, 77, 2052}, - {(float)0.120381, 77, 2129}, {(float)0.112962, 82, 2206}, - {(float)0.112962, 82, 2288}, {(float)0.112962, 82, 2370}, - {(float)0.107450, 86, 2452}, {(float)0.107450, 86, 2538}, - {(float)0.107450, 86, 2624}, {(float)0.107450, 86, 2710}, - {(float)0.100343, 91, 2796}, {(float)0.100343, 91, 2887}, - {(float)0.100343, 91, 2978}, {(float)0.095126, 95, 3069}, - {(float)0.095126, 95, 3164}, {(float)0.095126, 95, 3259}, - {(float)0.095126, 95, 3354}, {(float)0.088276, 100, 3449}, - {(float)0.088276, 100, 3549}, {(float)0.088276, 100, 3649}, - {(float)0.088276, 100, 3749}, {(float)0.081523, 105, 3849}, - {(float)0.081523, 105, 3954}, {(float)0.081523, 105, 4059}, - {(float)0.081523, 105, 4164}, {(float)0.074861, 110, 4269}, - {(float)0.074861, 110, 4379}, {(float)0.074861, 110, 4489}, - {(float)0.074861, 110, 4599}, {(float)0.068290, 115, 4709}, - {(float)0.068290, 115, 4824}, {(float)0.068290, 115, 4939}, - {(float)0.068290, 115, 5054}, {(float)0.063573, 119, 5169}, - {(float)0.063573, 119, 5288}, {(float)0.063573, 119, 5407}, - {(float)0.063573, 119, 5526}, {(float)0.057219, 124, 5645}, - {(float)0.057219, 124, 5769}, {(float)0.057219, 124, 5893}, - {(float)0.057219, 124, 6017}, {(float)0.050985, 129, 6141}, - {(float)0.050985, 129, 6270}, {(float)0.050985, 129, 6399}, - {(float)0.050985, 129, 6528}, {(float)0.050985, 129, 6657}, - {(float)0.044859, 134, 6786}, {(float)0.044859, 134, 6920}, - {(float)0.044859, 134, 7054}, {(float)0.044859, 134, 7188}, - {(float)0.040571, 138, 7322}, {(float)0.040571, 138, 7460}, - {(float)0.040571, 138, 7598}, {(float)0.040571, 138, 7736}, - {(float)0.036339, 142, 7874}, {(float)0.036339, 142, 8016}, - {(float)0.036339, 142, 8158}, {(float)0.036339, 142, 8300}, - {(float)0.032139, 146, 8442}, {(float)0.032139, 146, 8588}, - {(float)0.032139, 146, 8734}, {(float)0.032139, 146, 8880}, - {(float)0.027947, 150, 9026}, {(float)0.027947, 150, 9176}, - {(float)0.027947, 150, 9326}, {(float)0.023739, 154, 9476}, - {(float)0.023739, 154, 9630}, {(float)0.023739, 154, 9784}, - {(float)0.023739, 154, 9938}, {(float)0.019504, 158, 10092}, - {(float)0.019504, 158, 10250}, {(float)0.019504, 158, 10408}, - {(float)0.016976, 161, 10566}, {(float)0.016976, 161, 10727}, - {(float)0.016976, 161, 10888}, {(float)0.016976, 161, 11049}, - {(float)0.012639, 165, 11210}, {(float)0.012639, 165, 11375}, - {(float)0.012639, 165, 11540}, {(float)0.009991, 168, 11705}, - {(float)0.009991, 168, 11873}, {(float)0.009991, 168, 12041}, - {(float)0.009016, 170, 12209}, {(float)0.009016, 170, 12379}, - {(float)0.009016, 170, 12549}, {(float)0.006217, 173, 12719}, - {(float)0.006217, 173, 12892}, {(float)0.005097, 175, 13065}, - {(float)0.005097, 175, 13240}, {(float)0.005097, 175, 13415}, - {(float)0.003909, 177, 13590}, {(float)0.003909, 177, 13767}, - {(float)0.002340, 177, 13944}, {(float)0.002389, 170, 14121}, - {(float)0.001068, 164, 14291}, {(float)0.001653, 157, 14455}, - {(float)0.000717, 150, 14612}, {(float)0.001614, 143, 14762}, - {(float)0.000270, 136, 14905}, {(float)0.000484, 129, 15041}, - {(float)0.001103, 123, 15170}, {(float)0.001242, 115, 15293}, - {(float)0.001188, 109, 15408}, {(float)0.001011, 103, 15517}, - {(float)0.000709, 97, 15620}, {(float)0.000301, 89, 15717}, - {(float)0.002416, 82, 15806}, {(float)0.003251, 76, 15888}, - {(float)0.003246, 69, 15964}, {(float)0.004141, 62, 16033}, - {(float)0.005963, 55, 16095}, {(float)0.008839, 47, 16150}, - {(float)0.010490, 40, 16197}, {(float)0.016994, 31, 16237}, - {(float)0.023659, 21, 16268}, -}; diff --git a/src/3rd/tiff/version.c b/src/3rd/tiff/version.c deleted file mode 100644 index 0b6c9bc00a8..00000000000 --- a/src/3rd/tiff/version.c +++ /dev/null @@ -1,28 +0,0 @@ -/* - * Copyright (c) 1992-1997 Sam Leffler - * Copyright (c) 1992-1997 Silicon Graphics, Inc. - * - * Permission to use, copy, modify, distribute, and sell this software and - * its documentation for any purpose is hereby granted without fee, provided - * that (i) the above copyright notices and this permission notice appear in - * all copies of the software and related documentation, and (ii) the names of - * Sam Leffler and Silicon Graphics may not be used in any advertising or - * publicity relating to the software without the specific, prior written - * permission of Sam Leffler and Silicon Graphics. - * - * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, - * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY - * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. - * - * IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR - * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, - * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, - * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF - * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE - * OF THIS SOFTWARE. - */ -#include "tiffiop.h" - -static const char TIFFVersion[] = TIFFLIB_VERSION_STR; - -const char *TIFFGetVersion(void) { return (TIFFVersion); } diff --git a/src/3rd/tiff/warn.c b/src/3rd/tiff/warn.c deleted file mode 100644 index ee8f37ceed8..00000000000 --- a/src/3rd/tiff/warn.c +++ /dev/null @@ -1,106 +0,0 @@ -/* - * Copyright (c) 1988-1997 Sam Leffler - * Copyright (c) 1991-1997 Silicon Graphics, Inc. - * - * Permission to use, copy, modify, distribute, and sell this software and - * its documentation for any purpose is hereby granted without fee, provided - * that (i) the above copyright notices and this permission notice appear in - * all copies of the software and related documentation, and (ii) the names of - * Sam Leffler and Silicon Graphics may not be used in any advertising or - * publicity relating to the software without the specific, prior written - * permission of Sam Leffler and Silicon Graphics. - * - * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, - * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY - * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. - * - * IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR - * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, - * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, - * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF - * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE - * OF THIS SOFTWARE. - */ - -/* - * TIFF Library. - */ -#include "tiffiop.h" - -TIFFErrorHandlerExt _TIFFwarningHandlerExt = NULL; - -TIFFErrorHandler TIFFSetWarningHandler(TIFFErrorHandler handler) -{ - TIFFErrorHandler prev = _TIFFwarningHandler; - _TIFFwarningHandler = handler; - return (prev); -} - -TIFFErrorHandlerExt TIFFSetWarningHandlerExt(TIFFErrorHandlerExt handler) -{ - TIFFErrorHandlerExt prev = _TIFFwarningHandlerExt; - _TIFFwarningHandlerExt = handler; - return (prev); -} - -void TIFFWarning(const char *module, const char *fmt, ...) -{ - va_list ap; - if (_TIFFwarningHandler) - { - va_start(ap, fmt); - (*_TIFFwarningHandler)(module, fmt, ap); - va_end(ap); - } - if (_TIFFwarningHandlerExt) - { - va_start(ap, fmt); - (*_TIFFwarningHandlerExt)(0, module, fmt, ap); - va_end(ap); - } -} - -void TIFFWarningExt(thandle_t fd, const char *module, const char *fmt, ...) -{ - va_list ap; - if (_TIFFwarningHandler) - { - va_start(ap, fmt); - (*_TIFFwarningHandler)(module, fmt, ap); - va_end(ap); - } - if (_TIFFwarningHandlerExt) - { - va_start(ap, fmt); - (*_TIFFwarningHandlerExt)(fd, module, fmt, ap); - va_end(ap); - } -} - -void TIFFWarningExtR(TIFF *tif, const char *module, const char *fmt, ...) -{ - va_list ap; - if (tif && tif->tif_warnhandler) - { - int stop; - va_start(ap, fmt); - stop = (*tif->tif_warnhandler)(tif, tif->tif_warnhandler_user_data, - module, fmt, ap); - va_end(ap); - if (stop) - return; - } - if (_TIFFwarningHandler) - { - va_start(ap, fmt); - (*_TIFFwarningHandler)(module, fmt, ap); - va_end(ap); - } - if (_TIFFwarningHandlerExt) - { - va_start(ap, fmt); - (*_TIFFwarningHandlerExt)(tif ? tif->tif_clientdata : 0, module, fmt, - ap); - va_end(ap); - } -} diff --git a/src/3rd/tiff/webp.c b/src/3rd/tiff/webp.c deleted file mode 100644 index bf9d77eb9be..00000000000 --- a/src/3rd/tiff/webp.c +++ /dev/null @@ -1,881 +0,0 @@ -/* - * Copyright (c) 2018, Mapbox - * Author: - * - * Permission to use, copy, modify, distribute, and sell this software and - * its documentation for any purpose is hereby granted without fee, provided - * that (i) the above copyright notices and this permission notice appear in - * all copies of the software and related documentation, and (ii) the names of - * Sam Leffler and Silicon Graphics may not be used in any advertising or - * publicity relating to the software without the specific, prior written - * permission of Sam Leffler and Silicon Graphics. - * - * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, - * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY - * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. - * - * IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR - * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, - * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, - * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF - * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE - * OF THIS SOFTWARE. - */ - -#include "tiffiop.h" -#ifdef WEBP_SUPPORT -/* - * TIFF Library. - * - * WEBP Compression Support - * - */ - -#include "webp/decode.h" -#include "webp/encode.h" - -#include -#include - -#define LSTATE_INIT_DECODE 0x01 -#define LSTATE_INIT_ENCODE 0x02 -/* - * State block for each open TIFF - * file using WEBP compression/decompression. - */ -typedef struct -{ - uint16_t nSamples; /* number of samples per pixel */ - - int lossless; /* lossy/lossless compression */ - int lossless_exact; /* lossless exact mode. If TRUE, R,G,B values in areas - with alpha = 0 will be preserved */ - int quality_level; /* compression level */ - WebPPicture sPicture; /* WebP Picture */ - WebPConfig sEncoderConfig; /* WebP encoder config */ - uint8_t *pBuffer; /* buffer to hold raw data on encoding */ - unsigned int buffer_offset; /* current offset into the buffer */ - unsigned int buffer_size; - - WebPIDecoder *psDecoder; /* WebPIDecoder */ - WebPDecBuffer sDecBuffer; /* Decoder buffer */ - int last_y; /* Last row decoded */ - - int state; /* state flags */ - - TIFFVGetMethod vgetparent; /* super-class method */ - TIFFVSetMethod vsetparent; /* super-class method */ -} WebPState; - -#define LState(tif) ((WebPState *)(tif)->tif_data) -#define DecoderState(tif) LState(tif) -#define EncoderState(tif) LState(tif) - -static int TWebPEncode(TIFF *tif, uint8_t *bp, tmsize_t cc, uint16_t s); -static int TWebPDecode(TIFF *tif, uint8_t *op, tmsize_t occ, uint16_t s); - -static int TWebPDatasetWriter(const uint8_t *data, size_t data_size, - const WebPPicture *const picture) -{ - static const char module[] = "TWebPDatasetWriter"; - TIFF *tif = (TIFF *)(picture->custom_ptr); - - if ((tif->tif_rawcc + (tmsize_t)data_size) > tif->tif_rawdatasize) - { - TIFFErrorExtR( - tif, module, "Buffer too small by %" TIFF_SIZE_FORMAT " bytes.", - (size_t)(tif->tif_rawcc + data_size - tif->tif_rawdatasize)); - return 0; - } - else - { - _TIFFmemcpy(tif->tif_rawcp, data, data_size); - tif->tif_rawcc += data_size; - tif->tif_rawcp += data_size; - return 1; - } -} - -/* - * Encode a chunk of pixels. - */ -static int TWebPEncode(TIFF *tif, uint8_t *bp, tmsize_t cc, uint16_t s) -{ - static const char module[] = "TWebPEncode"; - WebPState *sp = EncoderState(tif); - (void)s; - - assert(sp != NULL); - assert(sp->state == LSTATE_INIT_ENCODE); - - if ((uint64_t)sp->buffer_offset + (uint64_t)cc > sp->buffer_size) - { - TIFFErrorExtR(tif, module, "Too many bytes to be written"); - return 0; - } - - memcpy(sp->pBuffer + sp->buffer_offset, bp, cc); - sp->buffer_offset += (unsigned)cc; - - return 1; -} - -static int TWebPDecode(TIFF *tif, uint8_t *op, tmsize_t occ, uint16_t s) -{ - static const char module[] = "WebPDecode"; - VP8StatusCode status = VP8_STATUS_OK; - WebPState *sp = DecoderState(tif); - uint32_t segment_width, segment_height; - bool decode_whole_strile = false; - - (void)s; - - assert(sp != NULL); - assert(sp->state == LSTATE_INIT_DECODE); - - if (sp->psDecoder == NULL) - { - TIFFDirectory *td = &tif->tif_dir; - uint32_t buffer_size; - - if (isTiled(tif)) - { - segment_width = td->td_tilewidth; - segment_height = td->td_tilelength; - } - 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; - } - - int webp_width, webp_height; - if (!WebPGetInfo(tif->tif_rawcp, - (uint64_t)tif->tif_rawcc > UINT32_MAX - ? UINT32_MAX - : (uint32_t)tif->tif_rawcc, - &webp_width, &webp_height)) - { - TIFFErrorExtR(tif, module, "WebPGetInfo() failed"); - return 0; - } - if ((uint32_t)webp_width != segment_width || - (uint32_t)webp_height != segment_height) - { - TIFFErrorExtR( - tif, module, "WebP blob dimension is %dx%d. Expected %ux%u", - webp_width, webp_height, segment_width, segment_height); - return 0; - } - -#if WEBP_DECODER_ABI_VERSION >= 0x0002 - WebPDecoderConfig config; - if (!WebPInitDecoderConfig(&config)) - { - TIFFErrorExtR(tif, module, "WebPInitDecoderConfig() failed"); - return 0; - } - - const bool bWebPGetFeaturesOK = - WebPGetFeatures(tif->tif_rawcp, - (uint64_t)tif->tif_rawcc > UINT32_MAX - ? UINT32_MAX - : (uint32_t)tif->tif_rawcc, - &config.input) == VP8_STATUS_OK; - - WebPFreeDecBuffer(&config.output); - - if (!bWebPGetFeaturesOK) - { - TIFFErrorExtR(tif, module, "WebPInitDecoderConfig() failed"); - return 0; - } - - const int webp_bands = config.input.has_alpha ? 4 : 3; - if (webp_bands != sp->nSamples && - /* We accept the situation where the WebP blob has only 3 bands, - * whereas the raster is 4 bands. This can happen when the alpha - * channel is fully opaque, and WebP decoding works fine in that - * situation. - */ - !(webp_bands == 3 && sp->nSamples == 4)) - { - TIFFErrorExtR(tif, module, - "WebP blob band count is %d. Expected %d", webp_bands, - sp->nSamples); - return 0; - } -#endif - - buffer_size = segment_width * segment_height * sp->nSamples; - if (occ == (tmsize_t)buffer_size) - { - /* If decoding the whole strip/tile, we can directly use the */ - /* output buffer */ - decode_whole_strile = true; - } - else if (sp->pBuffer == NULL || buffer_size > sp->buffer_size) - { - if (sp->pBuffer != NULL) - { - _TIFFfreeExt(tif, sp->pBuffer); - sp->pBuffer = NULL; - } - - sp->pBuffer = _TIFFmallocExt(tif, buffer_size); - if (!sp->pBuffer) - { - TIFFErrorExtR(tif, module, "Cannot allocate buffer"); - return 0; - } - sp->buffer_size = buffer_size; - } - - sp->last_y = 0; - - WebPInitDecBuffer(&sp->sDecBuffer); - - sp->sDecBuffer.is_external_memory = 1; - sp->sDecBuffer.width = segment_width; - sp->sDecBuffer.height = segment_height; - sp->sDecBuffer.u.RGBA.rgba = decode_whole_strile ? op : sp->pBuffer; - sp->sDecBuffer.u.RGBA.stride = segment_width * sp->nSamples; - sp->sDecBuffer.u.RGBA.size = buffer_size; - - if (sp->nSamples > 3) - { - sp->sDecBuffer.colorspace = MODE_RGBA; - } - else - { - sp->sDecBuffer.colorspace = MODE_RGB; - } - - sp->psDecoder = WebPINewDecoder(&sp->sDecBuffer); - - if (sp->psDecoder == NULL) - { - TIFFErrorExtR(tif, module, "Unable to allocate WebP decoder."); - return 0; - } - } - - if (occ % sp->sDecBuffer.u.RGBA.stride) - { - TIFFErrorExtR(tif, module, "Fractional scanlines cannot be read"); - return 0; - } - - status = WebPIAppend(sp->psDecoder, tif->tif_rawcp, tif->tif_rawcc); - - if (status != VP8_STATUS_OK && status != VP8_STATUS_SUSPENDED) - { - if (status == VP8_STATUS_INVALID_PARAM) - { - TIFFErrorExtR(tif, module, "Invalid parameter used."); - } - else if (status == VP8_STATUS_OUT_OF_MEMORY) - { - TIFFErrorExtR(tif, module, "Out of memory."); - } - else - { - TIFFErrorExtR(tif, module, "Unrecognized error."); - } - return 0; - } - else - { - int current_y, stride; - uint8_t *buf; - - /* Returns the RGB/A image decoded so far */ - buf = WebPIDecGetRGB(sp->psDecoder, ¤t_y, NULL, NULL, &stride); - - if ((buf != NULL) && - (occ <= (tmsize_t)stride * (current_y - sp->last_y))) - { - const int numberOfExpectedLines = - (int)(occ / sp->sDecBuffer.u.RGBA.stride); - if (decode_whole_strile) - { - if (current_y != numberOfExpectedLines) - { - TIFFErrorExtR(tif, module, - "Unable to decode WebP data: less lines than " - "expected."); - return 0; - } - } - else - { - memcpy(op, buf + (sp->last_y * stride), occ); - } - - tif->tif_rawcp += tif->tif_rawcc; - tif->tif_rawcc = 0; - sp->last_y += numberOfExpectedLines; - - if (decode_whole_strile) - { - /* We can now free the decoder as we're completely done */ - if (sp->psDecoder != NULL) - { - WebPIDelete(sp->psDecoder); - WebPFreeDecBuffer(&sp->sDecBuffer); - sp->psDecoder = NULL; - } - } - return 1; - } - else - { - TIFFErrorExtR(tif, module, "Unable to decode WebP data."); - return 0; - } - } -} - -static int TWebPFixupTags(TIFF *tif) -{ - (void)tif; - if (tif->tif_dir.td_planarconfig != PLANARCONFIG_CONTIG) - { - static const char module[] = "TWebPFixupTags"; - TIFFErrorExtR(tif, module, - "TIFF WEBP requires data to be stored contiguously in " - "RGB e.g. RGBRGBRGB " -#if WEBP_ENCODER_ABI_VERSION >= 0x0100 - "or RGBARGBARGBA" -#endif - ); - return 0; - } - return 1; -} - -static int TWebPSetupDecode(TIFF *tif) -{ - static const char module[] = "WebPSetupDecode"; - uint16_t nBitsPerSample = tif->tif_dir.td_bitspersample; - uint16_t sampleFormat = tif->tif_dir.td_sampleformat; - - WebPState *sp = DecoderState(tif); - assert(sp != NULL); - - sp->nSamples = tif->tif_dir.td_samplesperpixel; - - /* check band count */ - if (sp->nSamples != 3 -#if WEBP_ENCODER_ABI_VERSION >= 0x0100 - && sp->nSamples != 4 -#endif - ) - { - TIFFErrorExtR(tif, module, - "WEBP driver doesn't support %d bands. Must be 3 (RGB) " -#if WEBP_ENCODER_ABI_VERSION >= 0x0100 - "or 4 (RGBA) " -#endif - "bands.", - sp->nSamples); - return 0; - } - - /* check bits per sample and data type */ - if ((nBitsPerSample != 8) && (sampleFormat != 1)) - { - TIFFErrorExtR(tif, module, "WEBP driver requires 8 bit unsigned data"); - return 0; - } - - /* if we were last encoding, terminate this mode */ - if (sp->state & LSTATE_INIT_ENCODE) - { - WebPPictureFree(&sp->sPicture); - if (sp->pBuffer != NULL) - { - _TIFFfreeExt(tif, sp->pBuffer); - sp->pBuffer = NULL; - } - sp->buffer_offset = 0; - sp->state = 0; - } - - sp->state |= LSTATE_INIT_DECODE; - - return 1; -} - -/* - * Setup state for decoding a strip. - */ -static int TWebPPreDecode(TIFF *tif, uint16_t s) -{ - static const char module[] = "TWebPPreDecode"; - uint32_t segment_width, segment_height; - WebPState *sp = DecoderState(tif); - TIFFDirectory *td = &tif->tif_dir; - (void)s; - assert(sp != NULL); - - if (isTiled(tif)) - { - segment_width = td->td_tilewidth; - segment_height = td->td_tilelength; - } - 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; - } - - if (segment_width > 16383 || segment_height > 16383) - { - TIFFErrorExtR(tif, module, - "WEBP maximum image dimensions are 16383 x 16383."); - return 0; - } - - if ((sp->state & LSTATE_INIT_DECODE) == 0) - tif->tif_setupdecode(tif); - - if (sp->psDecoder != NULL) - { - WebPIDelete(sp->psDecoder); - WebPFreeDecBuffer(&sp->sDecBuffer); - sp->psDecoder = NULL; - } - - return 1; -} - -static int TWebPSetupEncode(TIFF *tif) -{ - static const char module[] = "WebPSetupEncode"; - uint16_t nBitsPerSample = tif->tif_dir.td_bitspersample; - uint16_t sampleFormat = tif->tif_dir.td_sampleformat; - - WebPState *sp = EncoderState(tif); - assert(sp != NULL); - - sp->nSamples = tif->tif_dir.td_samplesperpixel; - - /* check band count */ - if (sp->nSamples != 3 -#if WEBP_ENCODER_ABI_VERSION >= 0x0100 - && sp->nSamples != 4 -#endif - ) - { - TIFFErrorExtR(tif, module, - "WEBP driver doesn't support %d bands. Must be 3 (RGB) " -#if WEBP_ENCODER_ABI_VERSION >= 0x0100 - "or 4 (RGBA) " -#endif - "bands.", - sp->nSamples); - return 0; - } - - /* check bits per sample and data type */ - if ((nBitsPerSample != 8) || (sampleFormat != SAMPLEFORMAT_UINT)) - { - TIFFErrorExtR(tif, module, "WEBP driver requires 8 bit unsigned data"); - return 0; - } - - if (sp->state & LSTATE_INIT_DECODE) - { - WebPIDelete(sp->psDecoder); - WebPFreeDecBuffer(&sp->sDecBuffer); - sp->psDecoder = NULL; - sp->last_y = 0; - sp->state = 0; - } - - sp->state |= LSTATE_INIT_ENCODE; - - if (!WebPPictureInit(&sp->sPicture)) - { - TIFFErrorExtR(tif, module, "Error initializing WebP picture."); - return 0; - } - - if (!WebPConfigInitInternal(&sp->sEncoderConfig, WEBP_PRESET_DEFAULT, - (float)sp->quality_level, - WEBP_ENCODER_ABI_VERSION)) - { - TIFFErrorExtR(tif, module, - "Error creating WebP encoder configuration."); - return 0; - } - -// WebPConfigInitInternal above sets lossless to false -#if WEBP_ENCODER_ABI_VERSION >= 0x0100 - sp->sEncoderConfig.lossless = sp->lossless; - if (sp->lossless) - { - sp->sPicture.use_argb = 1; -#if WEBP_ENCODER_ABI_VERSION >= 0x0209 - sp->sEncoderConfig.exact = sp->lossless_exact; -#endif - } -#endif - - if (!WebPValidateConfig(&sp->sEncoderConfig)) - { - TIFFErrorExtR(tif, module, "Error with WebP encoder configuration."); - return 0; - } - - return 1; -} - -/* - * Reset encoding state at the start of a strip. - */ -static int TWebPPreEncode(TIFF *tif, uint16_t s) -{ - static const char module[] = "TWebPPreEncode"; - uint32_t segment_width, segment_height; - WebPState *sp = EncoderState(tif); - TIFFDirectory *td = &tif->tif_dir; - - (void)s; - - assert(sp != NULL); - if (sp->state != LSTATE_INIT_ENCODE) - tif->tif_setupencode(tif); - - /* - * Set encoding parameters for this strip/tile. - */ - if (isTiled(tif)) - { - segment_width = td->td_tilewidth; - segment_height = td->td_tilelength; - } - 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; - } - - if (segment_width > 16383 || segment_height > 16383) - { - TIFFErrorExtR(tif, module, - "WEBP maximum image dimensions are 16383 x 16383."); - return 0; - } - - /* set up buffer for raw data */ - /* given above check and that nSamples <= 4, buffer_size is <= 1 GB */ - sp->buffer_size = segment_width * segment_height * sp->nSamples; - - if (sp->pBuffer != NULL) - { - _TIFFfreeExt(tif, sp->pBuffer); - sp->pBuffer = NULL; - } - - sp->pBuffer = _TIFFmallocExt(tif, sp->buffer_size); - if (!sp->pBuffer) - { - TIFFErrorExtR(tif, module, "Cannot allocate buffer"); - return 0; - } - sp->buffer_offset = 0; - - sp->sPicture.width = segment_width; - sp->sPicture.height = segment_height; - sp->sPicture.writer = TWebPDatasetWriter; - sp->sPicture.custom_ptr = tif; - - return 1; -} - -/* - * Finish off an encoded strip by flushing it. - */ -static int TWebPPostEncode(TIFF *tif) -{ - static const char module[] = "WebPPostEncode"; - int64_t stride; - WebPState *sp = EncoderState(tif); - assert(sp != NULL); - - assert(sp->state == LSTATE_INIT_ENCODE); - - stride = (int64_t)sp->sPicture.width * sp->nSamples; - -#if WEBP_ENCODER_ABI_VERSION >= 0x0100 - if (sp->nSamples == 4) - { - if (!WebPPictureImportRGBA(&sp->sPicture, sp->pBuffer, (int)stride)) - { - TIFFErrorExtR(tif, module, "WebPPictureImportRGBA() failed"); - return 0; - } - } - else -#endif - if (!WebPPictureImportRGB(&sp->sPicture, sp->pBuffer, (int)stride)) - { - TIFFErrorExtR(tif, module, "WebPPictureImportRGB() failed"); - return 0; - } - - if (!WebPEncode(&sp->sEncoderConfig, &sp->sPicture)) - { - -#if WEBP_ENCODER_ABI_VERSION >= 0x0100 - const char *pszErrorMsg = NULL; - switch (sp->sPicture.error_code) - { - case VP8_ENC_ERROR_OUT_OF_MEMORY: - pszErrorMsg = "Out of memory"; - break; - case VP8_ENC_ERROR_BITSTREAM_OUT_OF_MEMORY: - pszErrorMsg = "Out of memory while flushing bits"; - break; - case VP8_ENC_ERROR_NULL_PARAMETER: - pszErrorMsg = "A pointer parameter is NULL"; - break; - case VP8_ENC_ERROR_INVALID_CONFIGURATION: - pszErrorMsg = "Configuration is invalid"; - break; - case VP8_ENC_ERROR_BAD_DIMENSION: - pszErrorMsg = "Picture has invalid width/height"; - break; - case VP8_ENC_ERROR_PARTITION0_OVERFLOW: - pszErrorMsg = "Partition is bigger than 512k. Try using less " - "SEGMENTS, or increase PARTITION_LIMIT value"; - break; - case VP8_ENC_ERROR_PARTITION_OVERFLOW: - pszErrorMsg = "Partition is bigger than 16M"; - break; - case VP8_ENC_ERROR_BAD_WRITE: - pszErrorMsg = "Error while fludshing bytes"; - break; - case VP8_ENC_ERROR_FILE_TOO_BIG: - pszErrorMsg = "File is bigger than 4G"; - break; - case VP8_ENC_ERROR_USER_ABORT: - pszErrorMsg = "User interrupted"; - break; - default: - TIFFErrorExtR(tif, module, - "WebPEncode returned an unknown error code: %d", - sp->sPicture.error_code); - pszErrorMsg = "Unknown WebP error type."; - break; - } - TIFFErrorExtR(tif, module, "WebPEncode() failed : %s", pszErrorMsg); -#else - TIFFErrorExtR(tif, module, "Error in WebPEncode()"); -#endif - return 0; - } - - sp->sPicture.custom_ptr = NULL; - - if (!TIFFFlushData1(tif)) - { - TIFFErrorExtR(tif, module, "Error flushing TIFF WebP encoder."); - return 0; - } - - return 1; -} - -static void TWebPCleanup(TIFF *tif) -{ - WebPState *sp = LState(tif); - - assert(sp != 0); - - tif->tif_tagmethods.vgetfield = sp->vgetparent; - tif->tif_tagmethods.vsetfield = sp->vsetparent; - - if (sp->state & LSTATE_INIT_ENCODE) - { - WebPPictureFree(&sp->sPicture); - } - - if (sp->psDecoder != NULL) - { - WebPIDelete(sp->psDecoder); - WebPFreeDecBuffer(&sp->sDecBuffer); - sp->psDecoder = NULL; - sp->last_y = 0; - } - - if (sp->pBuffer != NULL) - { - _TIFFfreeExt(tif, sp->pBuffer); - sp->pBuffer = NULL; - } - - _TIFFfreeExt(tif, tif->tif_data); - tif->tif_data = NULL; - - _TIFFSetDefaultCompressionState(tif); -} - -static int TWebPVSetField(TIFF *tif, uint32_t tag, va_list ap) -{ - static const char module[] = "WebPVSetField"; - WebPState *sp = LState(tif); - - switch (tag) - { - case TIFFTAG_WEBP_LEVEL: - sp->quality_level = (int)va_arg(ap, int); - if (sp->quality_level <= 0 || sp->quality_level > 100.0f) - { - TIFFWarningExtR(tif, module, - "WEBP_LEVEL should be between 1 and 100"); - } - return 1; - case TIFFTAG_WEBP_LOSSLESS: -#if WEBP_ENCODER_ABI_VERSION >= 0x0100 - sp->lossless = va_arg(ap, int); - if (sp->lossless) - { - sp->quality_level = 100; - } - return 1; -#else - TIFFErrorExtR( - tif, module, - "Need to upgrade WEBP driver, this version doesn't support " - "lossless compression."); - return 0; -#endif - case TIFFTAG_WEBP_LOSSLESS_EXACT: -#if WEBP_ENCODER_ABI_VERSION >= 0x0209 - sp->lossless_exact = va_arg(ap, int); - return 1; -#else - TIFFErrorExtR( - tif, module, - "Need to upgrade WEBP driver, this version doesn't support " - "lossless compression."); - return 0; -#endif - default: - return (*sp->vsetparent)(tif, tag, ap); - } - /*NOTREACHED*/ -} - -static int TWebPVGetField(TIFF *tif, uint32_t tag, va_list ap) -{ - WebPState *sp = LState(tif); - - switch (tag) - { - case TIFFTAG_WEBP_LEVEL: - *va_arg(ap, int *) = sp->quality_level; - break; - case TIFFTAG_WEBP_LOSSLESS: - *va_arg(ap, int *) = sp->lossless; - break; - case TIFFTAG_WEBP_LOSSLESS_EXACT: - *va_arg(ap, int *) = sp->lossless_exact; - break; - default: - return (*sp->vgetparent)(tif, tag, ap); - } - return 1; -} - -static const TIFFField TWebPFields[] = { - {TIFFTAG_WEBP_LEVEL, 0, 0, TIFF_ANY, 0, TIFF_SETGET_INT, - TIFF_SETGET_UNDEFINED, FIELD_PSEUDO, TRUE, FALSE, "WEBP quality", NULL}, - {TIFFTAG_WEBP_LOSSLESS, 0, 0, TIFF_ANY, 0, TIFF_SETGET_INT, - TIFF_SETGET_UNDEFINED, FIELD_PSEUDO, TRUE, FALSE, "WEBP lossless/lossy", - NULL}, - {TIFFTAG_WEBP_LOSSLESS_EXACT, 0, 0, TIFF_ANY, 0, TIFF_SETGET_INT, - TIFF_SETGET_UNDEFINED, FIELD_PSEUDO, TRUE, FALSE, "WEBP exact lossless", - NULL}, -}; - -int TIFFInitWebP(TIFF *tif, int scheme) -{ - static const char module[] = "TIFFInitWebP"; - WebPState *sp; - - (void)scheme; - assert(scheme == COMPRESSION_WEBP); - - /* - * Merge codec-specific tag information. - */ - if (!_TIFFMergeFields(tif, TWebPFields, TIFFArrayCount(TWebPFields))) - { - TIFFErrorExtR(tif, module, "Merging WebP codec-specific tags failed"); - return 0; - } - - /* - * Allocate state block so tag methods have storage to record values. - */ - tif->tif_data = (uint8_t *)_TIFFmallocExt(tif, sizeof(WebPState)); - if (tif->tif_data == NULL) - goto bad; - sp = LState(tif); - - /* - * Override parent get/set field methods. - */ - sp->vgetparent = tif->tif_tagmethods.vgetfield; - tif->tif_tagmethods.vgetfield = TWebPVGetField; /* hook for codec tags */ - sp->vsetparent = tif->tif_tagmethods.vsetfield; - tif->tif_tagmethods.vsetfield = TWebPVSetField; /* hook for codec tags */ - - /* Default values for codec-specific fields */ - sp->quality_level = 75; /* default comp. level */ - sp->lossless = 0; /* default to false */ - sp->lossless_exact = 1; /* exact lossless mode (if lossless enabled) */ - sp->state = 0; - sp->nSamples = 0; - sp->psDecoder = NULL; - sp->last_y = 0; - - sp->buffer_offset = 0; - sp->pBuffer = NULL; - - /* - * Install codec methods. - * Notes: - * encoderow is not supported - */ - tif->tif_fixuptags = TWebPFixupTags; - tif->tif_setupdecode = TWebPSetupDecode; - tif->tif_predecode = TWebPPreDecode; - tif->tif_decoderow = TWebPDecode; - tif->tif_decodestrip = TWebPDecode; - tif->tif_decodetile = TWebPDecode; - tif->tif_setupencode = TWebPSetupEncode; - tif->tif_preencode = TWebPPreEncode; - tif->tif_postencode = TWebPPostEncode; - tif->tif_encoderow = TWebPEncode; - tif->tif_encodestrip = TWebPEncode; - tif->tif_encodetile = TWebPEncode; - tif->tif_cleanup = TWebPCleanup; - - return 1; -bad: - TIFFErrorExtR(tif, module, "No space for WebP state block"); - return 0; -} - -#endif /* WEBP_SUPPORT */ diff --git a/src/3rd/tiff/win32.c b/src/3rd/tiff/win32.c deleted file mode 100644 index 1a6b86dffb5..00000000000 --- a/src/3rd/tiff/win32.c +++ /dev/null @@ -1,442 +0,0 @@ -/* - * Copyright (c) 1988-1997 Sam Leffler - * Copyright (c) 1991-1997 Silicon Graphics, Inc. - * - * Permission to use, copy, modify, distribute, and sell this software and - * its documentation for any purpose is hereby granted without fee, provided - * that (i) the above copyright notices and this permission notice appear in - * all copies of the software and related documentation, and (ii) the names of - * Sam Leffler and Silicon Graphics may not be used in any advertising or - * publicity relating to the software without the specific, prior written - * permission of Sam Leffler and Silicon Graphics. - * - * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, - * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY - * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. - * - * IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR - * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, - * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, - * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF - * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE - * OF THIS SOFTWARE. - */ - -/* - * TIFF Library Win32-specific Routines. Adapted from tif_unix.c 4/5/95 by - * Scott Wagner (wagner@itek.com), Itek Graphix, Rochester, NY USA - */ - -#include "tiffiop.h" -#include - -#include - -/* - CreateFileA/CreateFileW return type 'HANDLE' while TIFFFdOpen() takes 'int', - which is formally incompatible and can even seemingly be of different size: - HANDLE is 64 bit under Win64, while int is still 32 bits there. - - However, only the lower 32 bits of a HANDLE are significant under Win64 as, - for interoperability reasons, they must have the same values in 32- and - 64-bit programs running on the same system, see - - https://docs.microsoft.com/en-us/windows/win32/winprog64/interprocess-communication - - Because of this, it is safe to define the following trivial functions for - casting between ints and HANDLEs, which are only really needed to avoid - compiler warnings (and, perhaps, to make the code slightly more clear). - Note that using the intermediate cast to "intptr_t" is crucial for warning - avoidance, as this integer type has the same size as HANDLE in all builds. -*/ - -static inline thandle_t thandle_from_int(int ifd) -{ - return (thandle_t)(intptr_t)ifd; -} - -static inline int thandle_to_int(thandle_t fd) { return (int)(intptr_t)fd; } - -static tmsize_t _tiffReadProc(thandle_t fd, void *buf, tmsize_t size) -{ - /* tmsize_t is 64bit on 64bit systems, but the WinAPI ReadFile takes - * 32bit sizes, so we loop through the data in suitable 32bit sized - * chunks */ - uint8_t *ma; - uint64_t mb; - DWORD n; - DWORD o; - tmsize_t p; - ma = (uint8_t *)buf; - mb = size; - p = 0; - while (mb > 0) - { - n = 0x80000000UL; - if ((uint64_t)n > mb) - n = (DWORD)mb; - if (!ReadFile(fd, (LPVOID)ma, n, &o, NULL)) - return (0); - ma += o; - mb -= o; - p += o; - if (o != n) - break; - } - return (p); -} - -static tmsize_t _tiffWriteProc(thandle_t fd, void *buf, tmsize_t size) -{ - /* tmsize_t is 64bit on 64bit systems, but the WinAPI WriteFile takes - * 32bit sizes, so we loop through the data in suitable 32bit sized - * chunks */ - uint8_t *ma; - uint64_t mb; - DWORD n; - DWORD o; - tmsize_t p; - ma = (uint8_t *)buf; - mb = size; - p = 0; - while (mb > 0) - { - n = 0x80000000UL; - if ((uint64_t)n > mb) - n = (DWORD)mb; - if (!WriteFile(fd, (LPVOID)ma, n, &o, NULL)) - return (0); - ma += o; - mb -= o; - p += o; - if (o != n) - break; - } - return (p); -} - -static uint64_t _tiffSeekProc(thandle_t fd, uint64_t off, int whence) -{ - LARGE_INTEGER offli; - DWORD dwMoveMethod; - offli.QuadPart = off; - switch (whence) - { - case SEEK_SET: - dwMoveMethod = FILE_BEGIN; - break; - case SEEK_CUR: - dwMoveMethod = FILE_CURRENT; - break; - case SEEK_END: - dwMoveMethod = FILE_END; - break; - default: - dwMoveMethod = FILE_BEGIN; - break; - } - offli.LowPart = - SetFilePointer(fd, offli.LowPart, &offli.HighPart, dwMoveMethod); - if ((offli.LowPart == INVALID_SET_FILE_POINTER) && - (GetLastError() != NO_ERROR)) - offli.QuadPart = 0; - return (offli.QuadPart); -} - -static int _tiffCloseProc(thandle_t fd) { return (CloseHandle(fd) ? 0 : -1); } - -static uint64_t _tiffSizeProc(thandle_t fd) -{ - LARGE_INTEGER m; - if (GetFileSizeEx(fd, &m)) - return (m.QuadPart); - else - return (0); -} - -static int _tiffDummyMapProc(thandle_t fd, void **pbase, toff_t *psize) -{ - (void)fd; - (void)pbase; - (void)psize; - return (0); -} - -/* - * From "Hermann Josef Hill" : - * - * Windows uses both a handle and a pointer for file mapping, - * but according to the SDK documentation and Richter's book - * "Advanced Windows Programming" it is safe to free the handle - * after obtaining the file mapping pointer - * - * This removes a nasty OS dependency and cures a problem - * with Visual C++ 5.0 - */ -static int _tiffMapProc(thandle_t fd, void **pbase, toff_t *psize) -{ - uint64_t size; - tmsize_t sizem; - HANDLE hMapFile; - - size = _tiffSizeProc(fd); - sizem = (tmsize_t)size; - if (!size || (uint64_t)sizem != size) - return (0); - - /* By passing in 0 for the maximum file size, it specifies that we - create a file mapping object for the full file size. */ - hMapFile = CreateFileMapping(fd, NULL, PAGE_READONLY, 0, 0, NULL); - if (hMapFile == NULL) - return (0); - *pbase = MapViewOfFile(hMapFile, FILE_MAP_READ, 0, 0, 0); - CloseHandle(hMapFile); - if (*pbase == NULL) - return (0); - *psize = size; - return (1); -} - -static void _tiffDummyUnmapProc(thandle_t fd, void *base, toff_t size) -{ - (void)fd; - (void)base; - (void)size; -} - -static void _tiffUnmapProc(thandle_t fd, void *base, toff_t size) -{ - (void)fd; - (void)size; - UnmapViewOfFile(base); -} - -/* - * Open a TIFF file descriptor for read/writing. - * Note that TIFFFdOpen and TIFFOpen recognise the character 'u' in the mode - * string, which forces the file to be opened unmapped. - */ -TIFF *TIFFFdOpen(int ifd, const char *name, const char *mode) -{ - return TIFFFdOpenExt(ifd, name, mode, NULL); -} - -TIFF *TIFFFdOpenExt(int ifd, const char *name, const char *mode, - TIFFOpenOptions *opts) -{ - TIFF *tif; - int fSuppressMap; - int m; - - fSuppressMap = 0; - for (m = 0; mode[m] != 0; m++) - { - if (mode[m] == 'u') - { - fSuppressMap = 1; - break; - } - } - - tif = TIFFClientOpenExt( - name, mode, thandle_from_int(ifd), _tiffReadProc, _tiffWriteProc, - _tiffSeekProc, _tiffCloseProc, _tiffSizeProc, - fSuppressMap ? _tiffDummyMapProc : _tiffMapProc, - fSuppressMap ? _tiffDummyUnmapProc : _tiffUnmapProc, opts); - if (tif) - tif->tif_fd = ifd; - return (tif); -} - -#ifndef _WIN32_WCE - -/* - * Open a TIFF file for read/writing. - */ -TIFF *TIFFOpen(const char *name, const char *mode) -{ - return TIFFOpenExt(name, mode, NULL); -} - -TIFF *TIFFOpenExt(const char *name, const char *mode, TIFFOpenOptions *opts) -{ - static const char module[] = "TIFFOpen"; - thandle_t fd; - int m; - DWORD dwMode; - TIFF *tif; - - m = _TIFFgetMode(opts, NULL, mode, module); - - switch (m) - { - case O_RDONLY: - dwMode = OPEN_EXISTING; - break; - case O_RDWR: - dwMode = OPEN_EXISTING; - break; - case O_RDWR | O_CREAT: - dwMode = OPEN_ALWAYS; - break; - case O_RDWR | O_TRUNC: - dwMode = CREATE_ALWAYS; - break; - case O_RDWR | O_CREAT | O_TRUNC: - dwMode = CREATE_ALWAYS; - break; - default: - return ((TIFF *)0); - } - - fd = (thandle_t)CreateFileA( - name, (m == O_RDONLY) ? GENERIC_READ : (GENERIC_READ | GENERIC_WRITE), - FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, dwMode, - (m == O_RDONLY) ? FILE_ATTRIBUTE_READONLY : FILE_ATTRIBUTE_NORMAL, - NULL); - if (fd == INVALID_HANDLE_VALUE) - { - _TIFFErrorEarly(opts, NULL, module, "%s: Cannot open", name); - return ((TIFF *)0); - } - - tif = TIFFFdOpenExt(thandle_to_int(fd), name, mode, opts); - if (!tif) - CloseHandle(fd); - return tif; -} - -/* - * Open a TIFF file with a Unicode filename, for read/writing. - */ -TIFF *TIFFOpenW(const wchar_t *name, const char *mode) -{ - return TIFFOpenWExt(name, mode, NULL); -} - -TIFF *TIFFOpenWExt(const wchar_t *name, const char *mode, TIFFOpenOptions *opts) -{ - static const char module[] = "TIFFOpenW"; - thandle_t fd; - int m; - DWORD dwMode; - int mbsize; - char *mbname; - TIFF *tif; - - m = _TIFFgetMode(opts, NULL, mode, module); - - switch (m) - { - case O_RDONLY: - dwMode = OPEN_EXISTING; - break; - case O_RDWR: - dwMode = OPEN_EXISTING; - break; - case O_RDWR | O_CREAT: - dwMode = OPEN_ALWAYS; - break; - case O_RDWR | O_TRUNC: - dwMode = CREATE_ALWAYS; - break; - case O_RDWR | O_CREAT | O_TRUNC: - dwMode = CREATE_ALWAYS; - break; - default: - return ((TIFF *)0); - } - - fd = (thandle_t)CreateFileW( - name, (m == O_RDONLY) ? GENERIC_READ : (GENERIC_READ | GENERIC_WRITE), - FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, dwMode, - (m == O_RDONLY) ? FILE_ATTRIBUTE_READONLY : FILE_ATTRIBUTE_NORMAL, - NULL); - if (fd == INVALID_HANDLE_VALUE) - { - _TIFFErrorEarly(opts, NULL, module, "%S: Cannot open", name); - return ((TIFF *)0); - } - - mbname = NULL; - mbsize = WideCharToMultiByte(CP_ACP, 0, name, -1, NULL, 0, NULL, NULL); - if (mbsize > 0) - { - mbname = (char *)_TIFFmalloc(mbsize); - if (!mbname) - { - _TIFFErrorEarly( - opts, NULL, module, - "Can't allocate space for filename conversion buffer"); - return ((TIFF *)0); - } - - WideCharToMultiByte(CP_ACP, 0, name, -1, mbname, mbsize, NULL, NULL); - } - - tif = TIFFFdOpenExt(thandle_to_int(fd), - (mbname != NULL) ? mbname : "", mode, opts); - if (!tif) - CloseHandle(fd); - - _TIFFfree(mbname); - - return tif; -} - -#endif /* ndef _WIN32_WCE */ - -void *_TIFFmalloc(tmsize_t s) -{ - if (s == 0) - return ((void *)NULL); - - return (malloc((size_t)s)); -} - -void *_TIFFcalloc(tmsize_t nmemb, tmsize_t siz) -{ - if (nmemb == 0 || siz == 0) - return ((void *)NULL); - - return calloc((size_t)nmemb, (size_t)siz); -} - -void _TIFFfree(void *p) { free(p); } - -void *_TIFFrealloc(void *p, tmsize_t s) { return (realloc(p, (size_t)s)); } - -void _TIFFmemset(void *p, int v, tmsize_t c) { memset(p, v, (size_t)c); } - -void _TIFFmemcpy(void *d, const void *s, tmsize_t c) -{ - memcpy(d, s, (size_t)c); -} - -int _TIFFmemcmp(const void *p1, const void *p2, tmsize_t c) -{ - return (memcmp(p1, p2, (size_t)c)); -} - -#ifndef _WIN32_WCE - -static void Win32WarningHandler(const char *module, const char *fmt, va_list ap) -{ - if (module != NULL) - fprintf(stderr, "%s: ", module); - fprintf(stderr, "Warning, "); - vfprintf(stderr, fmt, ap); - fprintf(stderr, ".\n"); -} -TIFFErrorHandler _TIFFwarningHandler = Win32WarningHandler; - -static void Win32ErrorHandler(const char *module, const char *fmt, va_list ap) -{ - if (module != NULL) - fprintf(stderr, "%s: ", module); - vfprintf(stderr, fmt, ap); - fprintf(stderr, ".\n"); -} -TIFFErrorHandler _TIFFerrorHandler = Win32ErrorHandler; - -#endif /* ndef _WIN32_WCE */ diff --git a/src/3rd/tiff/write.c b/src/3rd/tiff/write.c deleted file mode 100644 index 6631a782fd3..00000000000 --- a/src/3rd/tiff/write.c +++ /dev/null @@ -1,960 +0,0 @@ -/* - * Copyright (c) 1988-1997 Sam Leffler - * Copyright (c) 1991-1997 Silicon Graphics, Inc. - * - * Permission to use, copy, modify, distribute, and sell this software and - * its documentation for any purpose is hereby granted without fee, provided - * that (i) the above copyright notices and this permission notice appear in - * all copies of the software and related documentation, and (ii) the names of - * Sam Leffler and Silicon Graphics may not be used in any advertising or - * publicity relating to the software without the specific, prior written - * permission of Sam Leffler and Silicon Graphics. - * - * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, - * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY - * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. - * - * IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR - * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, - * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, - * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF - * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE - * OF THIS SOFTWARE. - */ - -/* - * TIFF Library. - * - * Scanline-oriented Write Support - */ -#include "tiffiop.h" -#include - -#define STRIPINCR 20 /* expansion factor on strip array */ - -#define WRITECHECKSTRIPS(tif, module) \ - (((tif)->tif_flags & TIFF_BEENWRITING) || TIFFWriteCheck((tif), 0, module)) -#define WRITECHECKTILES(tif, module) \ - (((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)) - -static int TIFFGrowStrips(TIFF *tif, uint32_t delta, const char *module); -static int TIFFAppendToStrip(TIFF *tif, uint32_t strip, uint8_t *data, - tmsize_t cc); - -int TIFFWriteScanline(TIFF *tif, void *buf, uint32_t row, uint16_t sample) -{ - static const char module[] = "TIFFWriteScanline"; - register TIFFDirectory *td; - int status, imagegrew = 0; - uint32_t strip; - - if (!WRITECHECKSTRIPS(tif, module)) - return (-1); - /* - * Handle delayed allocation of data buffer. This - * permits it to be sized more intelligently (using - * directory information). - */ - if (!BUFFERCHECK(tif)) - return (-1); - tif->tif_flags |= TIFF_BUF4WRITE; /* not strictly sure this is right*/ - - td = &tif->tif_dir; - /* - * Extend image length if needed - * (but only for PlanarConfig=1). - */ - if (row >= td->td_imagelength) - { /* extend image */ - if (td->td_planarconfig == PLANARCONFIG_SEPARATE) - { - TIFFErrorExtR( - tif, module, - "Can not change \"ImageLength\" when using separate planes"); - return (-1); - } - td->td_imagelength = row + 1; - imagegrew = 1; - } - /* - * Calculate strip and check for crossings. - */ - if (td->td_planarconfig == PLANARCONFIG_SEPARATE) - { - if (sample >= td->td_samplesperpixel) - { - TIFFErrorExtR(tif, module, "%lu: Sample out of range, max %lu", - (unsigned long)sample, - (unsigned long)td->td_samplesperpixel); - return (-1); - } - strip = sample * td->td_stripsperimage + row / td->td_rowsperstrip; - } - else - strip = row / td->td_rowsperstrip; - /* - * Check strip array to make sure there's space. We don't support - * dynamically growing files that have data organized in separate - * bitplanes because it's too painful. In that case we require that - * the imagelength be set properly before the first write (so that the - * strips array will be fully allocated above). - */ - if (strip >= td->td_nstrips && !TIFFGrowStrips(tif, 1, module)) - return (-1); - if (strip != tif->tif_curstrip) - { - /* - * Changing strips -- flush any data present. - */ - if (!TIFFFlushData(tif)) - return (-1); - tif->tif_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 - * imagelength is known). - */ - if (strip >= td->td_stripsperimage && imagegrew) - td->td_stripsperimage = - TIFFhowmany_32(td->td_imagelength, td->td_rowsperstrip); - if (td->td_stripsperimage == 0) - { - TIFFErrorExtR(tif, module, "Zero strips per image"); - return (-1); - } - tif->tif_row = (strip % td->td_stripsperimage) * td->td_rowsperstrip; - if ((tif->tif_flags & TIFF_CODERSETUP) == 0) - { - if (!(*tif->tif_setupencode)(tif)) - return (-1); - tif->tif_flags |= TIFF_CODERSETUP; - } - - tif->tif_rawcc = 0; - tif->tif_rawcp = tif->tif_rawdata; - - /* this informs TIFFAppendToStrip() we have changed strip */ - tif->tif_curoff = 0; - - if (!(*tif->tif_preencode)(tif, sample)) - return (-1); - tif->tif_flags |= TIFF_POSTENCODE; - } - /* - * Ensure the write is either sequential or at the - * 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_row) - { - /* - * Moving backwards within the same strip: - * backup to the start and then decode - * forward (below). - */ - tif->tif_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)) - return (-1); - tif->tif_row = row; - } - - /* swab if needed - note that source buffer will be altered */ - tif->tif_postdecode(tif, (uint8_t *)buf, tif->tif_scanlinesize); - - status = (*tif->tif_encoderow)(tif, (uint8_t *)buf, tif->tif_scanlinesize, - sample); - - /* we are now poised at the beginning of the next row */ - tif->tif_row = row + 1; - return (status); -} - -/* Make sure that at the first attempt of rewriting a tile/strip, we will have - */ -/* more bytes available in the output buffer than the previous byte count, */ -/* so that TIFFAppendToStrip() will detect the overflow when it is called the - * first */ -/* time if the new compressed tile is bigger than the older one. (GDAL #4771) */ -static int _TIFFReserveLargeEnoughWriteBuffer(TIFF *tif, uint32_t strip_or_tile) -{ - TIFFDirectory *td = &tif->tif_dir; - if (td->td_stripbytecount_p[strip_or_tile] > 0) - { - /* The +1 is to ensure at least one extra bytes */ - /* The +4 is because the LZW encoder flushes 4 bytes before the limit */ - uint64_t safe_buffer_size = - (uint64_t)(td->td_stripbytecount_p[strip_or_tile] + 1 + 4); - if (tif->tif_rawdatasize <= (tmsize_t)safe_buffer_size) - { - if (!(TIFFWriteBufferSetup( - tif, NULL, - (tmsize_t)TIFFroundup_64(safe_buffer_size, 1024)))) - return 0; - } - } - return 1; -} - -/* - * Encode the supplied data and write it to the - * specified strip. - * - * NB: Image length must be setup before writing. - */ -tmsize_t TIFFWriteEncodedStrip(TIFF *tif, uint32_t strip, void *data, - tmsize_t cc) -{ - static const char module[] = "TIFFWriteEncodedStrip"; - TIFFDirectory *td = &tif->tif_dir; - uint16_t sample; - - if (!WRITECHECKSTRIPS(tif, module)) - return ((tmsize_t)-1); - /* - * Check strip array to make sure there's space. - * We don't support dynamically growing files that - * have data organized in separate bitplanes because - * it's too painful. In that case we require that - * the imagelength be set properly before the first - * write (so that the strips array will be fully - * allocated above). - */ - if (strip >= td->td_nstrips) - { - if (td->td_planarconfig == PLANARCONFIG_SEPARATE) - { - TIFFErrorExtR( - tif, module, - "Can not grow image by strips when using separate planes"); - return ((tmsize_t)-1); - } - if (!TIFFGrowStrips(tif, 1, module)) - return ((tmsize_t)-1); - td->td_stripsperimage = - TIFFhowmany_32(td->td_imagelength, td->td_rowsperstrip); - } - /* - * Handle delayed allocation of data buffer. This - * permits it to be sized according to the directory - * info. - */ - if (!BUFFERCHECK(tif)) - return ((tmsize_t)-1); - - tif->tif_flags |= TIFF_BUF4WRITE; - - tif->tif_curstrip = strip; - - /* this informs TIFFAppendToStrip() we have changed or reset strip */ - tif->tif_curoff = 0; - - if (!_TIFFReserveLargeEnoughWriteBuffer(tif, strip)) - { - return ((tmsize_t)(-1)); - } - - tif->tif_rawcc = 0; - tif->tif_rawcp = tif->tif_rawdata; - - if (td->td_stripsperimage == 0) - { - TIFFErrorExtR(tif, module, "Zero strips per image"); - return ((tmsize_t)-1); - } - - tif->tif_row = (strip % td->td_stripsperimage) * td->td_rowsperstrip; - if ((tif->tif_flags & TIFF_CODERSETUP) == 0) - { - if (!(*tif->tif_setupencode)(tif)) - return ((tmsize_t)-1); - tif->tif_flags |= TIFF_CODERSETUP; - } - - tif->tif_flags &= ~TIFF_POSTENCODE; - - /* shortcut to avoid an extra memcpy() */ - if (td->td_compression == COMPRESSION_NONE) - { - /* swab if needed - note that source buffer will be altered */ - tif->tif_postdecode(tif, (uint8_t *)data, cc); - - if (!isFillOrder(tif, td->td_fillorder) && - (tif->tif_flags & TIFF_NOBITREV) == 0) - TIFFReverseBits((uint8_t *)data, cc); - - if (cc > 0 && !TIFFAppendToStrip(tif, strip, (uint8_t *)data, cc)) - return ((tmsize_t)-1); - return (cc); - } - - sample = (uint16_t)(strip / td->td_stripsperimage); - if (!(*tif->tif_preencode)(tif, sample)) - return ((tmsize_t)-1); - - /* swab if needed - note that source buffer will be altered */ - tif->tif_postdecode(tif, (uint8_t *)data, cc); - - if (!(*tif->tif_encodestrip)(tif, (uint8_t *)data, cc, sample)) - return ((tmsize_t)-1); - if (!(*tif->tif_postencode)(tif)) - return ((tmsize_t)-1); - if (!isFillOrder(tif, td->td_fillorder) && - (tif->tif_flags & TIFF_NOBITREV) == 0) - TIFFReverseBits(tif->tif_rawdata, tif->tif_rawcc); - if (tif->tif_rawcc > 0 && - !TIFFAppendToStrip(tif, strip, tif->tif_rawdata, tif->tif_rawcc)) - return ((tmsize_t)-1); - tif->tif_rawcc = 0; - tif->tif_rawcp = tif->tif_rawdata; - return (cc); -} - -/* - * Write the supplied data to the specified strip. - * - * NB: Image length must be setup before writing. - */ -tmsize_t TIFFWriteRawStrip(TIFF *tif, uint32_t strip, void *data, tmsize_t cc) -{ - static const char module[] = "TIFFWriteRawStrip"; - TIFFDirectory *td = &tif->tif_dir; - - if (!WRITECHECKSTRIPS(tif, module)) - return ((tmsize_t)-1); - /* - * Check strip array to make sure there's space. - * We don't support dynamically growing files that - * have data organized in separate bitplanes because - * it's too painful. In that case we require that - * the imagelength be set properly before the first - * write (so that the strips array will be fully - * allocated above). - */ - if (strip >= td->td_nstrips) - { - if (td->td_planarconfig == PLANARCONFIG_SEPARATE) - { - TIFFErrorExtR( - tif, module, - "Can not grow image by strips when using separate planes"); - return ((tmsize_t)-1); - } - /* - * Watch out for a growing image. The value of - * strips/image will initially be 1 (since it - * can't be deduced until the imagelength is known). - */ - if (strip >= td->td_stripsperimage) - td->td_stripsperimage = - TIFFhowmany_32(td->td_imagelength, td->td_rowsperstrip); - if (!TIFFGrowStrips(tif, 1, module)) - return ((tmsize_t)-1); - } - - if (tif->tif_curstrip != strip) - { - tif->tif_curstrip = strip; - - /* this informs TIFFAppendToStrip() we have changed or reset strip */ - tif->tif_curoff = 0; - } - - if (td->td_stripsperimage == 0) - { - TIFFErrorExtR(tif, module, "Zero strips per image"); - return ((tmsize_t)-1); - } - tif->tif_row = (strip % td->td_stripsperimage) * td->td_rowsperstrip; - return (TIFFAppendToStrip(tif, strip, (uint8_t *)data, cc) ? cc - : (tmsize_t)-1); -} - -/* - * Write and compress a tile of data. The - * tile is selected by the (x,y,z,s) coordinates. - */ -tmsize_t TIFFWriteTile(TIFF *tif, void *buf, uint32_t x, uint32_t y, uint32_t z, - uint16_t s) -{ - if (!TIFFCheckTile(tif, x, y, z, s)) - return ((tmsize_t)(-1)); - /* - * NB: A tile size of -1 is used instead of tif_tilesize knowing - * that TIFFWriteEncodedTile will clamp this to the tile size. - * This is done because the tile size may not be defined until - * after the output buffer is setup in TIFFWriteBufferSetup. - */ - return (TIFFWriteEncodedTile(tif, TIFFComputeTile(tif, x, y, z, s), buf, - (tmsize_t)(-1))); -} - -/* - * Encode the supplied data and write it to the - * specified tile. There must be space for the - * data. The function clamps individual writes - * to a tile to the tile size, but does not (and - * can not) check that multiple writes to the same - * tile do not write more than tile size data. - * - * NB: Image length must be setup before writing; this - * interface does not support automatically growing - * the image on each write (as TIFFWriteScanline does). - */ -tmsize_t TIFFWriteEncodedTile(TIFF *tif, uint32_t tile, void *data, tmsize_t cc) -{ - static const char module[] = "TIFFWriteEncodedTile"; - TIFFDirectory *td; - uint16_t sample; - uint32_t howmany32; - - if (!WRITECHECKTILES(tif, module)) - return ((tmsize_t)(-1)); - td = &tif->tif_dir; - if (tile >= td->td_nstrips) - { - TIFFErrorExtR(tif, module, "Tile %lu out of range, max %lu", - (unsigned long)tile, (unsigned long)td->td_nstrips); - return ((tmsize_t)(-1)); - } - /* - * Handle delayed allocation of data buffer. This - * permits it to be sized more intelligently (using - * directory information). - */ - if (!BUFFERCHECK(tif)) - return ((tmsize_t)(-1)); - - tif->tif_flags |= TIFF_BUF4WRITE; - - tif->tif_curtile = tile; - - /* this informs TIFFAppendToStrip() we have changed or reset tile */ - tif->tif_curoff = 0; - - if (!_TIFFReserveLargeEnoughWriteBuffer(tif, tile)) - { - return ((tmsize_t)(-1)); - } - - tif->tif_rawcc = 0; - tif->tif_rawcp = tif->tif_rawdata; - - /* - * Compute tiles per row & per column to compute - * current row and column - */ - howmany32 = TIFFhowmany_32(td->td_imagelength, td->td_tilelength); - if (howmany32 == 0) - { - TIFFErrorExtR(tif, module, "Zero tiles"); - return ((tmsize_t)(-1)); - } - tif->tif_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; - - if ((tif->tif_flags & TIFF_CODERSETUP) == 0) - { - if (!(*tif->tif_setupencode)(tif)) - return ((tmsize_t)(-1)); - tif->tif_flags |= TIFF_CODERSETUP; - } - tif->tif_flags &= ~TIFF_POSTENCODE; - - /* - * Clamp write amount to the tile size. This is mostly - * 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; - - /* shortcut to avoid an extra memcpy() */ - if (td->td_compression == COMPRESSION_NONE) - { - /* swab if needed - note that source buffer will be altered */ - tif->tif_postdecode(tif, (uint8_t *)data, cc); - - if (!isFillOrder(tif, td->td_fillorder) && - (tif->tif_flags & TIFF_NOBITREV) == 0) - TIFFReverseBits((uint8_t *)data, cc); - - if (cc > 0 && !TIFFAppendToStrip(tif, tile, (uint8_t *)data, cc)) - return ((tmsize_t)-1); - return (cc); - } - - sample = (uint16_t)(tile / td->td_stripsperimage); - if (!(*tif->tif_preencode)(tif, sample)) - return ((tmsize_t)(-1)); - /* swab if needed - note that source buffer will be altered */ - tif->tif_postdecode(tif, (uint8_t *)data, cc); - - if (!(*tif->tif_encodetile)(tif, (uint8_t *)data, cc, sample)) - return ((tmsize_t)-1); - if (!(*tif->tif_postencode)(tif)) - return ((tmsize_t)(-1)); - if (!isFillOrder(tif, td->td_fillorder) && - (tif->tif_flags & TIFF_NOBITREV) == 0) - TIFFReverseBits((uint8_t *)tif->tif_rawdata, tif->tif_rawcc); - if (tif->tif_rawcc > 0 && - !TIFFAppendToStrip(tif, tile, tif->tif_rawdata, tif->tif_rawcc)) - return ((tmsize_t)(-1)); - tif->tif_rawcc = 0; - tif->tif_rawcp = tif->tif_rawdata; - return (cc); -} - -/* - * Write the supplied data to the specified strip. - * There must be space for the data; we don't check - * if strips overlap! - * - * NB: Image length must be setup before writing; this - * interface does not support automatically growing - * the image on each write (as TIFFWriteScanline does). - */ -tmsize_t TIFFWriteRawTile(TIFF *tif, uint32_t tile, void *data, tmsize_t cc) -{ - static const char module[] = "TIFFWriteRawTile"; - - if (!WRITECHECKTILES(tif, module)) - return ((tmsize_t)(-1)); - if (tile >= tif->tif_dir.td_nstrips) - { - TIFFErrorExtR(tif, module, "Tile %lu out of range, max %lu", - (unsigned long)tile, - (unsigned long)tif->tif_dir.td_nstrips); - return ((tmsize_t)(-1)); - } - return (TIFFAppendToStrip(tif, tile, (uint8_t *)data, cc) ? cc - : (tmsize_t)(-1)); -} - -#define isUnspecified(tif, f) \ - (TIFFFieldSet(tif, f) && (tif)->tif_dir.td_imagelength == 0) - -int TIFFSetupStrips(TIFF *tif) -{ - TIFFDirectory *td = &tif->tif_dir; - - if (isTiled(tif)) - td->td_stripsperimage = isUnspecified(tif, FIELD_TILEDIMENSIONS) - ? td->td_samplesperpixel - : TIFFNumberOfTiles(tif); - else - td->td_stripsperimage = isUnspecified(tif, FIELD_ROWSPERSTRIP) - ? td->td_samplesperpixel - : TIFFNumberOfStrips(tif); - td->td_nstrips = td->td_stripsperimage; - /* TIFFWriteDirectoryTagData has a limitation to 0x80000000U bytes */ - if (td->td_nstrips >= - 0x80000000U / ((tif->tif_flags & TIFF_BIGTIFF) ? 0x8U : 0x4U)) - { - TIFFErrorExtR(tif, "TIFFSetupStrips", - "Too large Strip/Tile Offsets/ByteCounts arrays"); - return 0; - } - if (td->td_planarconfig == PLANARCONFIG_SEPARATE) - td->td_stripsperimage /= td->td_samplesperpixel; - td->td_stripoffset_p = (uint64_t *)_TIFFCheckMalloc( - tif, td->td_nstrips, sizeof(uint64_t), "for \"StripOffsets\" array"); - td->td_stripbytecount_p = (uint64_t *)_TIFFCheckMalloc( - tif, td->td_nstrips, sizeof(uint64_t), "for \"StripByteCounts\" array"); - if (td->td_stripoffset_p == NULL || td->td_stripbytecount_p == NULL) - return (0); - /* - * 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)); - TIFFSetFieldBit(tif, FIELD_STRIPOFFSETS); - TIFFSetFieldBit(tif, FIELD_STRIPBYTECOUNTS); - return (1); -} -#undef isUnspecified - -/* - * Verify file is writable and that the directory - * information is setup properly. In doing the latter - * we also "freeze" the state of the directory so - * that important information is not changed. - */ -int TIFFWriteCheck(TIFF *tif, int tiles, const char *module) -{ - if (tif->tif_mode == O_RDONLY) - { - TIFFErrorExtR(tif, module, "File not open for writing"); - return (0); - } - if (tiles ^ isTiled(tif)) - { - TIFFErrorExtR(tif, module, - tiles ? "Can not write tiles to a striped image" - : "Can not write scanlines to a tiled image"); - return (0); - } - - _TIFFFillStriles(tif); - - /* - * On the first write verify all the required information - * has been setup and initialize any data structures that - * had to wait until directory information was set. - * Note that a lot of our work is assumed to remain valid - * because we disallow any of the important parameters - * from changing after we start writing (i.e. once - * TIFF_BEENWRITING is set, TIFFSetField will only allow - * the image's length to be changed). - */ - if (!TIFFFieldSet(tif, FIELD_IMAGEDIMENSIONS)) - { - TIFFErrorExtR(tif, module, - "Must set \"ImageWidth\" before writing data"); - return (0); - } - if (tif->tif_dir.td_stripoffset_p == NULL && !TIFFSetupStrips(tif)) - { - tif->tif_dir.td_nstrips = 0; - TIFFErrorExtR(tif, module, "No space for %s arrays", - isTiled(tif) ? "tile" : "strip"); - return (0); - } - if (isTiled(tif)) - { - tif->tif_tilesize = TIFFTileSize(tif); - if (tif->tif_tilesize == 0) - return (0); - } - else - tif->tif_tilesize = (tmsize_t)(-1); - tif->tif_scanlinesize = TIFFScanlineSize(tif); - if (tif->tif_scanlinesize == 0) - return (0); - tif->tif_flags |= TIFF_BEENWRITING; - - if (tif->tif_dir.td_stripoffset_entry.tdir_tag != 0 && - tif->tif_dir.td_stripoffset_entry.tdir_count == 0 && - tif->tif_dir.td_stripoffset_entry.tdir_type == 0 && - tif->tif_dir.td_stripoffset_entry.tdir_offset.toff_long8 == 0 && - tif->tif_dir.td_stripbytecount_entry.tdir_tag != 0 && - tif->tif_dir.td_stripbytecount_entry.tdir_count == 0 && - tif->tif_dir.td_stripbytecount_entry.tdir_type == 0 && - tif->tif_dir.td_stripbytecount_entry.tdir_offset.toff_long8 == 0 && - !(tif->tif_flags & TIFF_DIRTYDIRECT)) - { - TIFFForceStrileArrayWriting(tif); - } - - return (1); -} - -/* - * Setup the raw data buffer used for encoding. - */ -int TIFFWriteBufferSetup(TIFF *tif, void *bp, tmsize_t size) -{ - static const char module[] = "TIFFWriteBufferSetup"; - - if (tif->tif_rawdata) - { - if (tif->tif_flags & TIFF_MYBUFFER) - { - _TIFFfreeExt(tif, tif->tif_rawdata); - tif->tif_flags &= ~TIFF_MYBUFFER; - } - tif->tif_rawdata = NULL; - } - if (size == (tmsize_t)(-1)) - { - size = (isTiled(tif) ? tif->tif_tilesize : TIFFStripSize(tif)); - - /* Adds 10% margin for cases where compression would expand a bit */ - if (size < TIFF_TMSIZE_T_MAX - size / 10) - size += size / 10; - /* - * Make raw data buffer at least 8K - */ - if (size < 8 * 1024) - size = 8 * 1024; - bp = NULL; /* NB: force malloc */ - } - if (bp == NULL) - { - bp = _TIFFmallocExt(tif, size); - if (bp == NULL) - { - TIFFErrorExtR(tif, module, "No space for output buffer"); - return (0); - } - tif->tif_flags |= TIFF_MYBUFFER; - } - else - tif->tif_flags &= ~TIFF_MYBUFFER; - tif->tif_rawdata = (uint8_t *)bp; - tif->tif_rawdatasize = size; - tif->tif_rawcc = 0; - tif->tif_rawcp = tif->tif_rawdata; - tif->tif_flags |= TIFF_BUFFERSETUP; - return (1); -} - -/* - * Grow the strip data structures by delta strips. - */ -static int TIFFGrowStrips(TIFF *tif, uint32_t delta, const char *module) -{ - TIFFDirectory *td = &tif->tif_dir; - uint64_t *new_stripoffset; - uint64_t *new_stripbytecount; - - assert(td->td_planarconfig == PLANARCONFIG_CONTIG); - new_stripoffset = (uint64_t *)_TIFFreallocExt( - tif, td->td_stripoffset_p, (td->td_nstrips + delta) * sizeof(uint64_t)); - new_stripbytecount = (uint64_t *)_TIFFreallocExt( - tif, td->td_stripbytecount_p, - (td->td_nstrips + delta) * sizeof(uint64_t)); - 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)); - _TIFFmemset(td->td_stripbytecount_p + td->td_nstrips, 0, - delta * sizeof(uint64_t)); - td->td_nstrips += delta; - tif->tif_flags |= TIFF_DIRTYDIRECT; - - return (1); -} - -/* - * Append the data to the specified strip. - */ -static int TIFFAppendToStrip(TIFF *tif, uint32_t strip, uint8_t *data, - tmsize_t cc) -{ - static const char module[] = "TIFFAppendToStrip"; - TIFFDirectory *td = &tif->tif_dir; - uint64_t m; - int64_t old_byte_count = -1; - - if (tif->tif_curoff == 0) - tif->tif_lastvalidoff = 0; - - if (td->td_stripoffset_p[strip] == 0 || tif->tif_curoff == 0) - { - assert(td->td_nstrips > 0); - - if (td->td_stripbytecount_p[strip] != 0 && - td->td_stripoffset_p[strip] != 0 && - td->td_stripbytecount_p[strip] >= (uint64_t)cc) - { - /* - * There is already tile data on disk, and the new tile - * data we have will fit in the same space. The only - * aspect of this that is risky is that there could be - * more data to append to this strip before we are done - * depending on how we are getting called. - */ - if (!SeekOK(tif, td->td_stripoffset_p[strip])) - { - TIFFErrorExtR(tif, module, "Seek error at scanline %lu", - (unsigned long)tif->tif_row); - return (0); - } - - tif->tif_lastvalidoff = - td->td_stripoffset_p[strip] + td->td_stripbytecount_p[strip]; - } - else - { - /* - * Seek to end of file, and set that as our location to - * write this strip. - */ - td->td_stripoffset_p[strip] = TIFFSeekFile(tif, 0, SEEK_END); - tif->tif_flags |= TIFF_DIRTYSTRIP; - } - - tif->tif_curoff = td->td_stripoffset_p[strip]; - - /* - * We are starting a fresh strip/tile, so set the size to zero. - */ - old_byte_count = td->td_stripbytecount_p[strip]; - td->td_stripbytecount_p[strip] = 0; - } - - m = tif->tif_curoff + cc; - if (!(tif->tif_flags & TIFF_BIGTIFF)) - m = (uint32_t)m; - if ((m < tif->tif_curoff) || (m < (uint64_t)cc)) - { - TIFFErrorExtR(tif, module, "Maximum TIFF file size exceeded"); - return (0); - } - - if (tif->tif_lastvalidoff != 0 && m > tif->tif_lastvalidoff && - td->td_stripbytecount_p[strip] > 0) - { - /* Ouch: we have detected that we are rewriting in place a strip/tile */ - /* with several calls to TIFFAppendToStrip(). The first call was with */ - /* a size smaller than the previous size of the strip/tile, so we */ - /* opted to rewrite in place, but a following call causes us to go */ - /* outsize of the strip/tile area, so we have to finally go for a */ - /* append-at-end-of-file strategy, and start by moving what we already - */ - /* wrote. */ - tmsize_t tempSize; - void *temp; - uint64_t offsetRead; - uint64_t offsetWrite; - uint64_t toCopy = td->td_stripbytecount_p[strip]; - - if (toCopy < 1024 * 1024) - tempSize = (tmsize_t)toCopy; - else - tempSize = 1024 * 1024; - - offsetRead = td->td_stripoffset_p[strip]; - offsetWrite = TIFFSeekFile(tif, 0, SEEK_END); - - m = offsetWrite + toCopy + cc; - if (!(tif->tif_flags & TIFF_BIGTIFF) && m != (uint32_t)m) - { - TIFFErrorExtR(tif, module, "Maximum TIFF file size exceeded"); - return (0); - } - - temp = _TIFFmallocExt(tif, tempSize); - if (temp == NULL) - { - TIFFErrorExtR(tif, module, "No space for output buffer"); - return (0); - } - - tif->tif_flags |= TIFF_DIRTYSTRIP; - - td->td_stripoffset_p[strip] = offsetWrite; - td->td_stripbytecount_p[strip] = 0; - - /* Move data written by previous calls to us at end of file */ - while (toCopy > 0) - { - if (!SeekOK(tif, offsetRead)) - { - TIFFErrorExtR(tif, module, "Seek error"); - _TIFFfreeExt(tif, temp); - return (0); - } - if (!ReadOK(tif, temp, tempSize)) - { - TIFFErrorExtR(tif, module, "Cannot read"); - _TIFFfreeExt(tif, temp); - return (0); - } - if (!SeekOK(tif, offsetWrite)) - { - TIFFErrorExtR(tif, module, "Seek error"); - _TIFFfreeExt(tif, temp); - return (0); - } - if (!WriteOK(tif, temp, tempSize)) - { - TIFFErrorExtR(tif, module, "Cannot write"); - _TIFFfreeExt(tif, temp); - return (0); - } - offsetRead += tempSize; - offsetWrite += tempSize; - td->td_stripbytecount_p[strip] += tempSize; - toCopy -= tempSize; - } - _TIFFfreeExt(tif, temp); - - /* Append the data of this call */ - offsetWrite += cc; - m = offsetWrite; - } - - if (!WriteOK(tif, data, cc)) - { - TIFFErrorExtR(tif, module, "Write error at scanline %lu", - (unsigned long)tif->tif_row); - return (0); - } - tif->tif_curoff = m; - td->td_stripbytecount_p[strip] += cc; - - if ((int64_t)td->td_stripbytecount_p[strip] != old_byte_count) - tif->tif_flags |= TIFF_DIRTYSTRIP; - - return (1); -} - -/* - * Internal version of TIFFFlushData that can be - * called by ``encodestrip routines'' w/o concern - * for infinite recursion. - */ -int TIFFFlushData1(TIFF *tif) -{ - if (tif->tif_rawcc > 0 && tif->tif_flags & TIFF_BUF4WRITE) - { - 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)) - { - /* We update those variables even in case of error since there's */ - /* code that doesn't really check the return code of this */ - /* function */ - tif->tif_rawcc = 0; - tif->tif_rawcp = tif->tif_rawdata; - return (0); - } - tif->tif_rawcc = 0; - tif->tif_rawcp = tif->tif_rawdata; - } - return (1); -} - -/* - * Set the current write offset. This should only be - * used to set the offset to a known previous location - * (very carefully), or to 0 so that the next write gets - * appended to the end of the file. - */ -void TIFFSetWriteOffset(TIFF *tif, toff_t off) -{ - tif->tif_curoff = off; - tif->tif_lastvalidoff = 0; -} diff --git a/src/3rd/tiff/zip.c b/src/3rd/tiff/zip.c deleted file mode 100644 index ea58612969f..00000000000 --- a/src/3rd/tiff/zip.c +++ /dev/null @@ -1,731 +0,0 @@ -/* - * Copyright (c) 1995-1997 Sam Leffler - * Copyright (c) 1995-1997 Silicon Graphics, Inc. - * - * Permission to use, copy, modify, distribute, and sell this software and - * its documentation for any purpose is hereby granted without fee, provided - * that (i) the above copyright notices and this permission notice appear in - * all copies of the software and related documentation, and (ii) the names of - * Sam Leffler and Silicon Graphics may not be used in any advertising or - * publicity relating to the software without the specific, prior written - * permission of Sam Leffler and Silicon Graphics. - * - * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, - * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY - * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. - * - * IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR - * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, - * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, - * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF - * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE - * OF THIS SOFTWARE. - */ - -#include "tiffiop.h" -#ifdef ZIP_SUPPORT -/* - * TIFF Library. - * - * ZIP (aka Deflate) Compression Support - * - * This file is an interface to the zlib library written by - * Jean-loup Gailly and Mark Adler. You must use version 1.0 or later - * of the library. - * - * Optionally, libdeflate (https://github.com/ebiggers/libdeflate) may be used - * to do the compression and decompression, but only for whole strips and tiles. - * For scanline access, zlib will be sued as a fallback. - */ -#include "predict.h" -#include "zlib.h" - -#if LIBDEFLATE_SUPPORT -#include "libdeflate.h" -#endif -#define LIBDEFLATE_MAX_COMPRESSION_LEVEL 12 - -#include - -/* - * Sigh, ZLIB_VERSION is defined as a string so there's no - * way to do a proper check here. Instead we guess based - * on the presence of #defines that were added between the - * 0.95 and 1.0 distributions. - */ -#if !defined(Z_NO_COMPRESSION) || !defined(Z_DEFLATED) -#error "Antiquated ZLIB software; you must use version 1.0 or later" -#endif - -#define SAFE_MSG(sp) ((sp)->stream.msg == NULL ? "" : (sp)->stream.msg) - -/* - * State block for each open TIFF - * file using ZIP compression/decompression. - */ -typedef struct -{ - TIFFPredictorState predict; - z_stream stream; - int zipquality; /* compression level */ - int state; /* state flags */ - int subcodec; /* DEFLATE_SUBCODEC_ZLIB or DEFLATE_SUBCODEC_LIBDEFLATE */ -#if LIBDEFLATE_SUPPORT - int libdeflate_state; /* -1 = until first time ZIPEncode() / ZIPDecode() is - called, 0 = use zlib, 1 = use libdeflate */ - struct libdeflate_decompressor *libdeflate_dec; - struct libdeflate_compressor *libdeflate_enc; -#endif -#define ZSTATE_INIT_DECODE 0x01 -#define ZSTATE_INIT_ENCODE 0x02 - - TIFFVGetMethod vgetparent; /* super-class method */ - TIFFVSetMethod vsetparent; /* super-class method */ -} ZIPState; - -#define ZState(tif) ((ZIPState *)(tif)->tif_data) -#define DecoderState(tif) ZState(tif) -#define EncoderState(tif) ZState(tif) - -static int ZIPEncode(TIFF *tif, uint8_t *bp, tmsize_t cc, uint16_t s); -static int ZIPDecode(TIFF *tif, uint8_t *op, tmsize_t occ, uint16_t s); - -static int ZIPFixupTags(TIFF *tif) -{ - (void)tif; - return (1); -} - -static int ZIPSetupDecode(TIFF *tif) -{ - static const char module[] = "ZIPSetupDecode"; - ZIPState *sp = DecoderState(tif); - - assert(sp != NULL); - - /* if we were last encoding, terminate this mode */ - if (sp->state & ZSTATE_INIT_ENCODE) - { - deflateEnd(&sp->stream); - sp->state = 0; - } - - /* This function can possibly be called several times by */ - /* PredictorSetupDecode() if this function succeeds but */ - /* PredictorSetup() fails */ - if ((sp->state & ZSTATE_INIT_DECODE) == 0 && - inflateInit(&sp->stream) != Z_OK) - { - TIFFErrorExtR(tif, module, "%s", SAFE_MSG(sp)); - return (0); - } - else - { - sp->state |= ZSTATE_INIT_DECODE; - return (1); - } -} - -/* - * Setup state for decoding a strip. - */ -static int ZIPPreDecode(TIFF *tif, uint16_t s) -{ - ZIPState *sp = DecoderState(tif); - - (void)s; - assert(sp != NULL); - - if ((sp->state & ZSTATE_INIT_DECODE) == 0) - tif->tif_setupdecode(tif); - -#if LIBDEFLATE_SUPPORT - sp->libdeflate_state = -1; -#endif - sp->stream.next_in = tif->tif_rawdata; - assert(sizeof(sp->stream.avail_in) == 4); /* if this assert gets raised, - 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 = (uint64_t)tif->tif_rawcc < 0xFFFFFFFFU - ? (uInt)tif->tif_rawcc - : 0xFFFFFFFFU; - return (inflateReset(&sp->stream) == Z_OK); -} - -static int ZIPDecode(TIFF *tif, uint8_t *op, tmsize_t occ, uint16_t s) -{ - static const char module[] = "ZIPDecode"; - ZIPState *sp = DecoderState(tif); - - (void)s; - assert(sp != NULL); - assert(sp->state == ZSTATE_INIT_DECODE); - -#if LIBDEFLATE_SUPPORT - if (sp->libdeflate_state == 1) - return 0; - - /* If we have libdeflate support and we are asked to read a whole */ - /* strip/tile, then go for using it */ - do - { - TIFFDirectory *td = &tif->tif_dir; - - if (sp->libdeflate_state == 0) - break; - if (sp->subcodec == DEFLATE_SUBCODEC_ZLIB) - break; - - /* Check if we are in the situation where we can use libdeflate */ - if (isTiled(tif)) - { - if (TIFFTileSize64(tif) != (uint64_t)occ) - break; - } - else - { - uint32_t strip_height = td->td_imagelength - tif->tif_row; - if (strip_height > td->td_rowsperstrip) - strip_height = td->td_rowsperstrip; - if (TIFFVStripSize64(tif, strip_height) != (uint64_t)occ) - break; - } - - /* Check for overflow */ - if ((size_t)tif->tif_rawcc != (uint64_t)tif->tif_rawcc) - break; - if ((size_t)occ != (uint64_t)occ) - break; - - /* Go for decompression using libdeflate */ - { - enum libdeflate_result res; - if (sp->libdeflate_dec == NULL) - { - sp->libdeflate_dec = libdeflate_alloc_decompressor(); - if (sp->libdeflate_dec == NULL) - { - break; - } - } - - sp->libdeflate_state = 1; - - res = libdeflate_zlib_decompress(sp->libdeflate_dec, tif->tif_rawcp, - (size_t)tif->tif_rawcc, op, - (size_t)occ, NULL); - - tif->tif_rawcp += tif->tif_rawcc; - tif->tif_rawcc = 0; - - /* We accept LIBDEFLATE_INSUFFICIENT_SPACE has a return */ - /* There are odd files in the wild where the last strip, when */ - /* it is smaller in height than td_rowsperstrip, actually contains - */ - /* data for td_rowsperstrip lines. Just ignore that silently. */ - if (res != LIBDEFLATE_SUCCESS && - res != LIBDEFLATE_INSUFFICIENT_SPACE) - { - TIFFErrorExtR(tif, module, "Decoding error at scanline %lu", - (unsigned long)tif->tif_row); - return 0; - } - - return 1; - } - } while (0); - sp->libdeflate_state = 0; -#endif /* LIBDEFLATE_SUPPORT */ - - sp->stream.next_in = tif->tif_rawcp; - - sp->stream.next_out = op; - assert(sizeof(sp->stream.avail_out) == 4); /* if this assert gets raised, - 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 */ - do - { - int state; - uInt avail_in_before = (uint64_t)tif->tif_rawcc <= 0xFFFFFFFFU - ? (uInt)tif->tif_rawcc - : 0xFFFFFFFFU; - uInt avail_out_before = - (uint64_t)occ < 0xFFFFFFFFU ? (uInt)occ : 0xFFFFFFFFU; - sp->stream.avail_in = avail_in_before; - sp->stream.avail_out = avail_out_before; - /* coverity[overrun-buffer-arg] */ - state = inflate(&sp->stream, Z_PARTIAL_FLUSH); - tif->tif_rawcc -= (avail_in_before - sp->stream.avail_in); - occ -= (avail_out_before - sp->stream.avail_out); - if (state == Z_STREAM_END) - break; - if (state == Z_DATA_ERROR) - { - TIFFErrorExtR(tif, module, "Decoding error at scanline %lu, %s", - (unsigned long)tif->tif_row, SAFE_MSG(sp)); - return (0); - } - if (state != Z_OK) - { - TIFFErrorExtR(tif, module, "ZLib error: %s", SAFE_MSG(sp)); - return (0); - } - } while (occ > 0); - if (occ != 0) - { - TIFFErrorExtR(tif, module, - "Not enough data at scanline %lu (short %" PRIu64 - " bytes)", - (unsigned long)tif->tif_row, (uint64_t)occ); - return (0); - } - - tif->tif_rawcp = sp->stream.next_in; - - return (1); -} - -static int ZIPSetupEncode(TIFF *tif) -{ - static const char module[] = "ZIPSetupEncode"; - ZIPState *sp = EncoderState(tif); - int cappedQuality; - - assert(sp != NULL); - if (sp->state & ZSTATE_INIT_DECODE) - { - inflateEnd(&sp->stream); - sp->state = 0; - } - - cappedQuality = sp->zipquality; - if (cappedQuality > Z_BEST_COMPRESSION) - cappedQuality = Z_BEST_COMPRESSION; - - if (deflateInit(&sp->stream, cappedQuality) != Z_OK) - { - TIFFErrorExtR(tif, module, "%s", SAFE_MSG(sp)); - return (0); - } - else - { - sp->state |= ZSTATE_INIT_ENCODE; - return (1); - } -} - -/* - * Reset encoding state at the start of a strip. - */ -static int ZIPPreEncode(TIFF *tif, uint16_t s) -{ - ZIPState *sp = EncoderState(tif); - - (void)s; - assert(sp != NULL); - if (sp->state != ZSTATE_INIT_ENCODE) - tif->tif_setupencode(tif); - -#if LIBDEFLATE_SUPPORT - sp->libdeflate_state = -1; -#endif - sp->stream.next_out = tif->tif_rawdata; - assert(sizeof(sp->stream.avail_out) == 4); /* if this assert gets raised, - 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 = (uint64_t)tif->tif_rawdatasize <= 0xFFFFFFFFU - ? (uInt)tif->tif_rawdatasize - : 0xFFFFFFFFU; - return (deflateReset(&sp->stream) == Z_OK); -} - -/* - * Encode a chunk of pixels. - */ -static int ZIPEncode(TIFF *tif, uint8_t *bp, tmsize_t cc, uint16_t s) -{ - static const char module[] = "ZIPEncode"; - ZIPState *sp = EncoderState(tif); - - assert(sp != NULL); - assert(sp->state == ZSTATE_INIT_ENCODE); - - (void)s; - -#if LIBDEFLATE_SUPPORT - if (sp->libdeflate_state == 1) - return 0; - - /* If we have libdeflate support and we are asked to write a whole */ - /* strip/tile, then go for using it */ - do - { - TIFFDirectory *td = &tif->tif_dir; - - if (sp->libdeflate_state == 0) - break; - if (sp->subcodec == DEFLATE_SUBCODEC_ZLIB) - break; - - /* Libdeflate does not support the 0-compression level */ - if (sp->zipquality == Z_NO_COMPRESSION) - break; - - /* Check if we are in the situation where we can use libdeflate */ - if (isTiled(tif)) - { - if (TIFFTileSize64(tif) != (uint64_t)cc) - break; - } - else - { - uint32_t strip_height = td->td_imagelength - tif->tif_row; - if (strip_height > td->td_rowsperstrip) - strip_height = td->td_rowsperstrip; - if (TIFFVStripSize64(tif, strip_height) != (uint64_t)cc) - break; - } - - /* Check for overflow */ - if ((size_t)tif->tif_rawdatasize != (uint64_t)tif->tif_rawdatasize) - break; - if ((size_t)cc != (uint64_t)cc) - break; - - /* Go for compression using libdeflate */ - { - size_t nCompressedBytes; - if (sp->libdeflate_enc == NULL) - { - /* To get results as good as zlib, we asked for an extra */ - /* level of compression */ - sp->libdeflate_enc = libdeflate_alloc_compressor( - sp->zipquality == Z_DEFAULT_COMPRESSION ? 7 - : sp->zipquality >= 6 && sp->zipquality <= 9 - ? sp->zipquality + 1 - : sp->zipquality); - if (sp->libdeflate_enc == NULL) - { - TIFFErrorExtR(tif, module, "Cannot allocate compressor"); - break; - } - } - - /* Make sure the output buffer is large enough for the worse case. - */ - /* In TIFFWriteBufferSetup(), when libtiff allocates the buffer */ - /* we've taken a 10% margin over the uncompressed size, which should - */ - /* be large enough even for the the worse case scenario. */ - if (libdeflate_zlib_compress_bound(sp->libdeflate_enc, (size_t)cc) > - (size_t)tif->tif_rawdatasize) - { - break; - } - - sp->libdeflate_state = 1; - nCompressedBytes = libdeflate_zlib_compress( - sp->libdeflate_enc, bp, (size_t)cc, tif->tif_rawdata, - (size_t)tif->tif_rawdatasize); - - if (nCompressedBytes == 0) - { - TIFFErrorExtR(tif, module, "Encoder error at scanline %lu", - (unsigned long)tif->tif_row); - return 0; - } - - tif->tif_rawcc = nCompressedBytes; - - if (!TIFFFlushData1(tif)) - return 0; - - return 1; - } - } while (0); - sp->libdeflate_state = 0; -#endif /* LIBDEFLATE_SUPPORT */ - - sp->stream.next_in = bp; - assert(sizeof(sp->stream.avail_in) == 4); /* if this assert gets raised, - 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 */ - do - { - uInt avail_in_before = - (uint64_t)cc <= 0xFFFFFFFFU ? (uInt)cc : 0xFFFFFFFFU; - sp->stream.avail_in = avail_in_before; - /* coverity[overrun-buffer-arg] */ - if (deflate(&sp->stream, Z_NO_FLUSH) != Z_OK) - { - TIFFErrorExtR(tif, module, "Encoder error: %s", SAFE_MSG(sp)); - return (0); - } - if (sp->stream.avail_out == 0) - { - tif->tif_rawcc = tif->tif_rawdatasize; - if (!TIFFFlushData1(tif)) - return 0; - sp->stream.next_out = tif->tif_rawdata; - sp->stream.avail_out = (uint64_t)tif->tif_rawdatasize <= 0xFFFFFFFFU - ? (uInt)tif->tif_rawdatasize - : 0xFFFFFFFFU; - } - cc -= (avail_in_before - sp->stream.avail_in); - } while (cc > 0); - return (1); -} - -/* - * Finish off an encoded strip by flushing the last - * string and tacking on an End Of Information code. - */ -static int ZIPPostEncode(TIFF *tif) -{ - static const char module[] = "ZIPPostEncode"; - ZIPState *sp = EncoderState(tif); - int state; - -#if LIBDEFLATE_SUPPORT - if (sp->libdeflate_state == 1) - return 1; -#endif - - sp->stream.avail_in = 0; - do - { - state = deflate(&sp->stream, Z_FINISH); - switch (state) - { - case Z_STREAM_END: - case Z_OK: - if ((tmsize_t)sp->stream.avail_out != tif->tif_rawdatasize) - { - tif->tif_rawcc = - tif->tif_rawdatasize - sp->stream.avail_out; - if (!TIFFFlushData1(tif)) - return 0; - sp->stream.next_out = tif->tif_rawdata; - sp->stream.avail_out = - (uint64_t)tif->tif_rawdatasize <= 0xFFFFFFFFU - ? (uInt)tif->tif_rawdatasize - : 0xFFFFFFFFU; - } - break; - default: - TIFFErrorExtR(tif, module, "ZLib error: %s", SAFE_MSG(sp)); - return (0); - } - } while (state != Z_STREAM_END); - return (1); -} - -static void ZIPCleanup(TIFF *tif) -{ - ZIPState *sp = ZState(tif); - - assert(sp != 0); - - (void)TIFFPredictorCleanup(tif); - - tif->tif_tagmethods.vgetfield = sp->vgetparent; - tif->tif_tagmethods.vsetfield = sp->vsetparent; - - if (sp->state & ZSTATE_INIT_ENCODE) - { - deflateEnd(&sp->stream); - sp->state = 0; - } - else if (sp->state & ZSTATE_INIT_DECODE) - { - inflateEnd(&sp->stream); - sp->state = 0; - } - -#if LIBDEFLATE_SUPPORT - if (sp->libdeflate_dec) - libdeflate_free_decompressor(sp->libdeflate_dec); - if (sp->libdeflate_enc) - libdeflate_free_compressor(sp->libdeflate_enc); -#endif - - _TIFFfreeExt(tif, sp); - tif->tif_data = NULL; - - _TIFFSetDefaultCompressionState(tif); -} - -static int ZIPVSetField(TIFF *tif, uint32_t tag, va_list ap) -{ - static const char module[] = "ZIPVSetField"; - ZIPState *sp = ZState(tif); - - switch (tag) - { - case TIFFTAG_ZIPQUALITY: - sp->zipquality = (int)va_arg(ap, int); - if (sp->zipquality < Z_DEFAULT_COMPRESSION || - sp->zipquality > LIBDEFLATE_MAX_COMPRESSION_LEVEL) - { - TIFFErrorExtR( - tif, module, - "Invalid ZipQuality value. Should be in [-1,%d] range", - LIBDEFLATE_MAX_COMPRESSION_LEVEL); - return 0; - } - - if (sp->state & ZSTATE_INIT_ENCODE) - { - int cappedQuality = sp->zipquality; - if (cappedQuality > Z_BEST_COMPRESSION) - cappedQuality = Z_BEST_COMPRESSION; - if (deflateParams(&sp->stream, cappedQuality, - Z_DEFAULT_STRATEGY) != Z_OK) - { - TIFFErrorExtR(tif, module, "ZLib error: %s", SAFE_MSG(sp)); - return (0); - } - } - -#if LIBDEFLATE_SUPPORT - if (sp->libdeflate_enc) - { - libdeflate_free_compressor(sp->libdeflate_enc); - sp->libdeflate_enc = NULL; - } -#endif - - return (1); - - case TIFFTAG_DEFLATE_SUBCODEC: - sp->subcodec = (int)va_arg(ap, int); - if (sp->subcodec != DEFLATE_SUBCODEC_ZLIB && - sp->subcodec != DEFLATE_SUBCODEC_LIBDEFLATE) - { - TIFFErrorExtR(tif, module, "Invalid DeflateCodec value."); - return 0; - } -#if !LIBDEFLATE_SUPPORT - if (sp->subcodec == DEFLATE_SUBCODEC_LIBDEFLATE) - { - TIFFErrorExtR(tif, module, - "DeflateCodec = DEFLATE_SUBCODEC_LIBDEFLATE " - "unsupported in this build"); - return 0; - } -#endif - return 1; - - default: - return (*sp->vsetparent)(tif, tag, ap); - } - /*NOTREACHED*/ -} - -static int ZIPVGetField(TIFF *tif, uint32_t tag, va_list ap) -{ - ZIPState *sp = ZState(tif); - - switch (tag) - { - case TIFFTAG_ZIPQUALITY: - *va_arg(ap, int *) = sp->zipquality; - break; - - case TIFFTAG_DEFLATE_SUBCODEC: - *va_arg(ap, int *) = sp->subcodec; - break; - - default: - return (*sp->vgetparent)(tif, tag, ap); - } - return (1); -} - -static const TIFFField zipFields[] = { - {TIFFTAG_ZIPQUALITY, 0, 0, TIFF_ANY, 0, TIFF_SETGET_INT, - TIFF_SETGET_UNDEFINED, FIELD_PSEUDO, TRUE, FALSE, "", NULL}, - {TIFFTAG_DEFLATE_SUBCODEC, 0, 0, TIFF_ANY, 0, TIFF_SETGET_INT, - TIFF_SETGET_UNDEFINED, FIELD_PSEUDO, TRUE, FALSE, "", NULL}, -}; - -int TIFFInitZIP(TIFF *tif, int scheme) -{ - static const char module[] = "TIFFInitZIP"; - ZIPState *sp; - - assert((scheme == COMPRESSION_DEFLATE) || - (scheme == COMPRESSION_ADOBE_DEFLATE)); -#ifdef NDEBUG - (void)scheme; -#endif - - /* - * Merge codec-specific tag information. - */ - if (!_TIFFMergeFields(tif, zipFields, TIFFArrayCount(zipFields))) - { - TIFFErrorExtR(tif, module, - "Merging Deflate codec-specific tags failed"); - return 0; - } - - /* - * Allocate state block so tag methods have storage to record values. - */ - tif->tif_data = (uint8_t *)_TIFFcallocExt(tif, sizeof(ZIPState), 1); - if (tif->tif_data == NULL) - goto bad; - sp = ZState(tif); - sp->stream.zalloc = NULL; - sp->stream.zfree = NULL; - sp->stream.opaque = NULL; - sp->stream.data_type = Z_BINARY; - - /* - * Override parent get/set field methods. - */ - sp->vgetparent = tif->tif_tagmethods.vgetfield; - tif->tif_tagmethods.vgetfield = ZIPVGetField; /* hook for codec tags */ - sp->vsetparent = tif->tif_tagmethods.vsetfield; - tif->tif_tagmethods.vsetfield = ZIPVSetField; /* hook for codec tags */ - - /* Default values for codec-specific fields */ - sp->zipquality = Z_DEFAULT_COMPRESSION; /* default comp. level */ - sp->state = 0; -#if LIBDEFLATE_SUPPORT - sp->subcodec = DEFLATE_SUBCODEC_LIBDEFLATE; -#else - sp->subcodec = DEFLATE_SUBCODEC_ZLIB; -#endif - - /* - * Install codec methods. - */ - tif->tif_fixuptags = ZIPFixupTags; - tif->tif_setupdecode = ZIPSetupDecode; - tif->tif_predecode = ZIPPreDecode; - tif->tif_decoderow = ZIPDecode; - tif->tif_decodestrip = ZIPDecode; - tif->tif_decodetile = ZIPDecode; - tif->tif_setupencode = ZIPSetupEncode; - tif->tif_preencode = ZIPPreEncode; - tif->tif_postencode = ZIPPostEncode; - tif->tif_encoderow = ZIPEncode; - tif->tif_encodestrip = ZIPEncode; - tif->tif_encodetile = ZIPEncode; - tif->tif_cleanup = ZIPCleanup; - /* - * Setup predictor setup. - */ - (void)TIFFPredictorInit(tif); - return (1); -bad: - TIFFErrorExtR(tif, module, "No space for ZIP state block"); - return (0); -} -#endif /* ZIP_SUPPORT */ diff --git a/src/3rd/tiff/zstd.c b/src/3rd/tiff/zstd.c deleted file mode 100644 index 425977abb98..00000000000 --- a/src/3rd/tiff/zstd.c +++ /dev/null @@ -1,436 +0,0 @@ -/* - * Copyright (c) 2017, Planet Labs - * Author: - * - * Permission to use, copy, modify, distribute, and sell this software and - * its documentation for any purpose is hereby granted without fee, provided - * that (i) the above copyright notices and this permission notice appear in - * all copies of the software and related documentation, and (ii) the names of - * Sam Leffler and Silicon Graphics may not be used in any advertising or - * publicity relating to the software without the specific, prior written - * permission of Sam Leffler and Silicon Graphics. - * - * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, - * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY - * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. - * - * IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR - * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, - * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, - * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF - * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE - * OF THIS SOFTWARE. - */ - -#include "tiffiop.h" -#ifdef ZSTD_SUPPORT -/* - * TIFF Library. - * - * ZSTD Compression Support - * - */ - -#include "predict.h" -#include "zstd.h" - -#include - -/* - * State block for each open TIFF file using ZSTD compression/decompression. - */ -typedef struct -{ - TIFFPredictorState predict; - ZSTD_DStream *dstream; - ZSTD_CStream *cstream; - int compression_level; /* compression level */ - ZSTD_outBuffer out_buffer; - int state; /* state flags */ -#define LSTATE_INIT_DECODE 0x01 -#define LSTATE_INIT_ENCODE 0x02 - - TIFFVGetMethod vgetparent; /* super-class method */ - TIFFVSetMethod vsetparent; /* super-class method */ -} ZSTDState; - -#define LState(tif) ((ZSTDState *)(tif)->tif_data) -#define DecoderState(tif) LState(tif) -#define EncoderState(tif) LState(tif) - -static int ZSTDEncode(TIFF *tif, uint8_t *bp, tmsize_t cc, uint16_t s); -static int ZSTDDecode(TIFF *tif, uint8_t *op, tmsize_t occ, uint16_t s); - -static int ZSTDFixupTags(TIFF *tif) -{ - (void)tif; - return 1; -} - -static int ZSTDSetupDecode(TIFF *tif) -{ - ZSTDState *sp = DecoderState(tif); - - assert(sp != NULL); - - /* if we were last encoding, terminate this mode */ - if (sp->state & LSTATE_INIT_ENCODE) - { - ZSTD_freeCStream(sp->cstream); - sp->cstream = NULL; - sp->state = 0; - } - - sp->state |= LSTATE_INIT_DECODE; - return 1; -} - -/* - * Setup state for decoding a strip. - */ -static int ZSTDPreDecode(TIFF *tif, uint16_t s) -{ - static const char module[] = "ZSTDPreDecode"; - ZSTDState *sp = DecoderState(tif); - size_t zstd_ret; - - (void)s; - assert(sp != NULL); - - if ((sp->state & LSTATE_INIT_DECODE) == 0) - tif->tif_setupdecode(tif); - - if (sp->dstream == NULL) - { - sp->dstream = ZSTD_createDStream(); - if (sp->dstream == NULL) - { - TIFFErrorExtR(tif, module, "Cannot allocate decompression stream"); - return 0; - } - } - - zstd_ret = ZSTD_initDStream(sp->dstream); - if (ZSTD_isError(zstd_ret)) - { - TIFFErrorExtR(tif, module, "Error in ZSTD_initDStream(): %s", - ZSTD_getErrorName(zstd_ret)); - return 0; - } - - return 1; -} - -static int ZSTDDecode(TIFF *tif, uint8_t *op, tmsize_t occ, uint16_t s) -{ - static const char module[] = "ZSTDDecode"; - ZSTDState *sp = DecoderState(tif); - ZSTD_inBuffer in_buffer; - ZSTD_outBuffer out_buffer; - size_t zstd_ret; - - (void)s; - assert(sp != NULL); - assert(sp->state == LSTATE_INIT_DECODE); - - in_buffer.src = tif->tif_rawcp; - in_buffer.size = (size_t)tif->tif_rawcc; - in_buffer.pos = 0; - - out_buffer.dst = op; - out_buffer.size = (size_t)occ; - out_buffer.pos = 0; - - do - { - zstd_ret = ZSTD_decompressStream(sp->dstream, &out_buffer, &in_buffer); - if (ZSTD_isError(zstd_ret)) - { - TIFFErrorExtR(tif, module, "Error in ZSTD_decompressStream(): %s", - ZSTD_getErrorName(zstd_ret)); - return 0; - } - } while (zstd_ret != 0 && in_buffer.pos < in_buffer.size && - out_buffer.pos < out_buffer.size); - - if (out_buffer.pos < (size_t)occ) - { - TIFFErrorExtR(tif, module, - "Not enough data at scanline %lu (short %lu bytes)", - (unsigned long)tif->tif_row, - (unsigned long)((size_t)occ - out_buffer.pos)); - return 0; - } - - tif->tif_rawcp += in_buffer.pos; - tif->tif_rawcc -= in_buffer.pos; - - return 1; -} - -static int ZSTDSetupEncode(TIFF *tif) -{ - ZSTDState *sp = EncoderState(tif); - - assert(sp != NULL); - if (sp->state & LSTATE_INIT_DECODE) - { - ZSTD_freeDStream(sp->dstream); - sp->dstream = NULL; - sp->state = 0; - } - - sp->state |= LSTATE_INIT_ENCODE; - return 1; -} - -/* - * Reset encoding state at the start of a strip. - */ -static int ZSTDPreEncode(TIFF *tif, uint16_t s) -{ - static const char module[] = "ZSTDPreEncode"; - ZSTDState *sp = EncoderState(tif); - size_t zstd_ret; - - (void)s; - assert(sp != NULL); - if (sp->state != LSTATE_INIT_ENCODE) - tif->tif_setupencode(tif); - - if (sp->cstream == NULL) - { - sp->cstream = ZSTD_createCStream(); - if (sp->cstream == NULL) - { - TIFFErrorExtR(tif, module, "Cannot allocate compression stream"); - return 0; - } - } - - zstd_ret = ZSTD_initCStream(sp->cstream, sp->compression_level); - if (ZSTD_isError(zstd_ret)) - { - TIFFErrorExtR(tif, module, "Error in ZSTD_initCStream(): %s", - ZSTD_getErrorName(zstd_ret)); - return 0; - } - - sp->out_buffer.dst = tif->tif_rawdata; - sp->out_buffer.size = (size_t)tif->tif_rawdatasize; - sp->out_buffer.pos = 0; - - return 1; -} - -/* - * Encode a chunk of pixels. - */ -static int ZSTDEncode(TIFF *tif, uint8_t *bp, tmsize_t cc, uint16_t s) -{ - static const char module[] = "ZSTDEncode"; - ZSTDState *sp = EncoderState(tif); - ZSTD_inBuffer in_buffer; - size_t zstd_ret; - - assert(sp != NULL); - assert(sp->state == LSTATE_INIT_ENCODE); - - (void)s; - - in_buffer.src = bp; - in_buffer.size = (size_t)cc; - in_buffer.pos = 0; - - do - { - zstd_ret = - ZSTD_compressStream(sp->cstream, &sp->out_buffer, &in_buffer); - if (ZSTD_isError(zstd_ret)) - { - TIFFErrorExtR(tif, module, "Error in ZSTD_compressStream(): %s", - ZSTD_getErrorName(zstd_ret)); - return 0; - } - if (sp->out_buffer.pos == sp->out_buffer.size) - { - tif->tif_rawcc = tif->tif_rawdatasize; - if (!TIFFFlushData1(tif)) - return 0; - sp->out_buffer.dst = tif->tif_rawcp; - sp->out_buffer.pos = 0; - } - } while (in_buffer.pos < in_buffer.size); - - return 1; -} - -/* - * Finish off an encoded strip by flushing it. - */ -static int ZSTDPostEncode(TIFF *tif) -{ - static const char module[] = "ZSTDPostEncode"; - ZSTDState *sp = EncoderState(tif); - size_t zstd_ret; - - do - { - zstd_ret = ZSTD_endStream(sp->cstream, &sp->out_buffer); - if (ZSTD_isError(zstd_ret)) - { - TIFFErrorExtR(tif, module, "Error in ZSTD_endStream(): %s", - ZSTD_getErrorName(zstd_ret)); - return 0; - } - if (sp->out_buffer.pos > 0) - { - tif->tif_rawcc = sp->out_buffer.pos; - if (!TIFFFlushData1(tif)) - return 0; - sp->out_buffer.dst = tif->tif_rawcp; - sp->out_buffer.pos = 0; - } - } while (zstd_ret != 0); - return 1; -} - -static void ZSTDCleanup(TIFF *tif) -{ - ZSTDState *sp = LState(tif); - - assert(sp != 0); - - (void)TIFFPredictorCleanup(tif); - - tif->tif_tagmethods.vgetfield = sp->vgetparent; - tif->tif_tagmethods.vsetfield = sp->vsetparent; - - if (sp->dstream) - { - ZSTD_freeDStream(sp->dstream); - sp->dstream = NULL; - } - if (sp->cstream) - { - ZSTD_freeCStream(sp->cstream); - sp->cstream = NULL; - } - _TIFFfreeExt(tif, sp); - tif->tif_data = NULL; - - _TIFFSetDefaultCompressionState(tif); -} - -static int ZSTDVSetField(TIFF *tif, uint32_t tag, va_list ap) -{ - static const char module[] = "ZSTDVSetField"; - ZSTDState *sp = LState(tif); - - switch (tag) - { - case TIFFTAG_ZSTD_LEVEL: - sp->compression_level = (int)va_arg(ap, int); - if (sp->compression_level <= 0 || - sp->compression_level > ZSTD_maxCLevel()) - { - TIFFWarningExtR(tif, module, - "ZSTD_LEVEL should be between 1 and %d", - ZSTD_maxCLevel()); - } - return 1; - default: - return (*sp->vsetparent)(tif, tag, ap); - } - /*NOTREACHED*/ -} - -static int ZSTDVGetField(TIFF *tif, uint32_t tag, va_list ap) -{ - ZSTDState *sp = LState(tif); - - switch (tag) - { - case TIFFTAG_ZSTD_LEVEL: - *va_arg(ap, int *) = sp->compression_level; - break; - default: - return (*sp->vgetparent)(tif, tag, ap); - } - return 1; -} - -static const TIFFField ZSTDFields[] = { - {TIFFTAG_ZSTD_LEVEL, 0, 0, TIFF_ANY, 0, TIFF_SETGET_INT, - TIFF_SETGET_UNDEFINED, FIELD_PSEUDO, TRUE, FALSE, "ZSTD compression_level", - NULL}, -}; - -int TIFFInitZSTD(TIFF *tif, int scheme) -{ - static const char module[] = "TIFFInitZSTD"; - ZSTDState *sp; - - (void)scheme; - assert(scheme == COMPRESSION_ZSTD); - - /* - * Merge codec-specific tag information. - */ - if (!_TIFFMergeFields(tif, ZSTDFields, TIFFArrayCount(ZSTDFields))) - { - TIFFErrorExtR(tif, module, "Merging ZSTD codec-specific tags failed"); - return 0; - } - - /* - * Allocate state block so tag methods have storage to record values. - */ - tif->tif_data = (uint8_t *)_TIFFmallocExt(tif, sizeof(ZSTDState)); - if (tif->tif_data == NULL) - goto bad; - sp = LState(tif); - - /* - * Override parent get/set field methods. - */ - sp->vgetparent = tif->tif_tagmethods.vgetfield; - tif->tif_tagmethods.vgetfield = ZSTDVGetField; /* hook for codec tags */ - sp->vsetparent = tif->tif_tagmethods.vsetfield; - tif->tif_tagmethods.vsetfield = ZSTDVSetField; /* hook for codec tags */ - - /* Default values for codec-specific fields */ - sp->compression_level = 9; /* default comp. level */ - sp->state = 0; - sp->dstream = 0; - sp->cstream = 0; - sp->out_buffer.dst = NULL; - sp->out_buffer.size = 0; - sp->out_buffer.pos = 0; - - /* - * Install codec methods. - */ - tif->tif_fixuptags = ZSTDFixupTags; - tif->tif_setupdecode = ZSTDSetupDecode; - tif->tif_predecode = ZSTDPreDecode; - tif->tif_decoderow = ZSTDDecode; - tif->tif_decodestrip = ZSTDDecode; - tif->tif_decodetile = ZSTDDecode; - tif->tif_setupencode = ZSTDSetupEncode; - tif->tif_preencode = ZSTDPreEncode; - tif->tif_postencode = ZSTDPostEncode; - tif->tif_encoderow = ZSTDEncode; - tif->tif_encodestrip = ZSTDEncode; - tif->tif_encodetile = ZSTDEncode; - tif->tif_cleanup = ZSTDCleanup; - /* - * Setup predictor setup. - */ - (void)TIFFPredictorInit(tif); - return 1; -bad: - TIFFErrorExtR(tif, module, "No space for ZSTD state block"); - return 0; -} -#endif /* ZSTD_SUPPORT */