LCOV - code coverage report
Current view: top level - frmts/gtiff/libtiff - tif_dir.c (source / functions) Hit Total Coverage
Test: gdal_filtered.info Lines: 680 1250 54.4 %
Date: 2024-05-04 12:52:34 Functions: 25 38 65.8 %

          Line data    Source code
       1             : /*
       2             :  * Copyright (c) 1988-1997 Sam Leffler
       3             :  * Copyright (c) 1991-1997 Silicon Graphics, Inc.
       4             :  *
       5             :  * Permission to use, copy, modify, distribute, and sell this software and
       6             :  * its documentation for any purpose is hereby granted without fee, provided
       7             :  * that (i) the above copyright notices and this permission notice appear in
       8             :  * all copies of the software and related documentation, and (ii) the names of
       9             :  * Sam Leffler and Silicon Graphics may not be used in any advertising or
      10             :  * publicity relating to the software without the specific, prior written
      11             :  * permission of Sam Leffler and Silicon Graphics.
      12             :  *
      13             :  * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND,
      14             :  * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY
      15             :  * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
      16             :  *
      17             :  * IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR
      18             :  * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND,
      19             :  * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
      20             :  * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF
      21             :  * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
      22             :  * OF THIS SOFTWARE.
      23             :  */
      24             : 
      25             : /*
      26             :  * TIFF Library.
      27             :  *
      28             :  * Directory Tag Get & Set Routines.
      29             :  * (and also some miscellaneous stuff)
      30             :  */
      31             : #include "tiffiop.h"
      32             : #include <float.h> /*--: for Rational2Double */
      33             : #include <limits.h>
      34             : 
      35             : /*
      36             :  * These are used in the backwards compatibility code...
      37             :  */
      38             : #define DATATYPE_VOID 0   /* !untyped data */
      39             : #define DATATYPE_INT 1    /* !signed integer data */
      40             : #define DATATYPE_UINT 2   /* !unsigned integer data */
      41             : #define DATATYPE_IEEEFP 3 /* !IEEE floating point data */
      42             : 
      43       43123 : static void setByteArray(TIFF *tif, void **vpp, const void *vp, size_t nmemb,
      44             :                          size_t elem_size)
      45             : {
      46       43123 :     if (*vpp)
      47             :     {
      48        1403 :         _TIFFfreeExt(tif, *vpp);
      49        1403 :         *vpp = 0;
      50             :     }
      51       43123 :     if (vp)
      52             :     {
      53       43090 :         tmsize_t bytes = _TIFFMultiplySSize(NULL, nmemb, elem_size, NULL);
      54       43113 :         if (bytes)
      55       43110 :             *vpp = (void *)_TIFFmallocExt(tif, bytes);
      56       43118 :         if (*vpp)
      57       43105 :             _TIFFmemcpy(*vpp, vp, bytes);
      58             :     }
      59       43143 : }
      60           0 : void _TIFFsetByteArray(void **vpp, const void *vp, uint32_t n)
      61             : {
      62           0 :     setByteArray(NULL, vpp, vp, n, 1);
      63           0 : }
      64        3107 : void _TIFFsetByteArrayExt(TIFF *tif, void **vpp, const void *vp, uint32_t n)
      65             : {
      66        3107 :     setByteArray(tif, vpp, vp, n, 1);
      67        3107 : }
      68             : 
      69           0 : static void _TIFFsetNString(TIFF *tif, char **cpp, const char *cp, uint32_t n)
      70             : {
      71           0 :     setByteArray(tif, (void **)cpp, cp, n, 1);
      72           0 : }
      73             : 
      74           0 : void _TIFFsetShortArray(uint16_t **wpp, const uint16_t *wp, uint32_t n)
      75             : {
      76           0 :     setByteArray(NULL, (void **)wpp, wp, n, sizeof(uint16_t));
      77           0 : }
      78        8480 : void _TIFFsetShortArrayExt(TIFF *tif, uint16_t **wpp, const uint16_t *wp,
      79             :                            uint32_t n)
      80             : {
      81        8480 :     setByteArray(tif, (void **)wpp, wp, n, sizeof(uint16_t));
      82        8480 : }
      83             : 
      84           0 : void _TIFFsetLongArray(uint32_t **lpp, const uint32_t *lp, uint32_t n)
      85             : {
      86           0 :     setByteArray(NULL, (void **)lpp, lp, n, sizeof(uint32_t));
      87           0 : }
      88           0 : void _TIFFsetLongArrayExt(TIFF *tif, uint32_t **lpp, const uint32_t *lp,
      89             :                           uint32_t n)
      90             : {
      91           0 :     setByteArray(tif, (void **)lpp, lp, n, sizeof(uint32_t));
      92           0 : }
      93             : 
      94          60 : static void _TIFFsetLong8Array(TIFF *tif, uint64_t **lpp, const uint64_t *lp,
      95             :                                uint32_t n)
      96             : {
      97          60 :     setByteArray(tif, (void **)lpp, lp, n, sizeof(uint64_t));
      98          60 : }
      99             : 
     100           0 : void _TIFFsetFloatArray(float **fpp, const float *fp, uint32_t n)
     101             : {
     102           0 :     setByteArray(NULL, (void **)fpp, fp, n, sizeof(float));
     103           0 : }
     104        1851 : void _TIFFsetFloatArrayExt(TIFF *tif, float **fpp, const float *fp, uint32_t n)
     105             : {
     106        1851 :     setByteArray(tif, (void **)fpp, fp, n, sizeof(float));
     107        1851 : }
     108             : 
     109           0 : void _TIFFsetDoubleArray(double **dpp, const double *dp, uint32_t n)
     110             : {
     111           0 :     setByteArray(NULL, (void **)dpp, dp, n, sizeof(double));
     112           0 : }
     113           0 : void _TIFFsetDoubleArrayExt(TIFF *tif, double **dpp, const double *dp,
     114             :                             uint32_t n)
     115             : {
     116           0 :     setByteArray(tif, (void **)dpp, dp, n, sizeof(double));
     117           0 : }
     118             : 
     119           0 : static void setDoubleArrayOneValue(TIFF *tif, double **vpp, double value,
     120             :                                    size_t nmemb)
     121             : {
     122           0 :     if (*vpp)
     123           0 :         _TIFFfreeExt(tif, *vpp);
     124           0 :     *vpp = _TIFFmallocExt(tif, nmemb * sizeof(double));
     125           0 :     if (*vpp)
     126             :     {
     127           0 :         while (nmemb--)
     128           0 :             ((double *)*vpp)[nmemb] = value;
     129             :     }
     130           0 : }
     131             : 
     132             : /*
     133             :  * Install extra samples information.
     134             :  */
     135        7287 : static int setExtraSamples(TIFF *tif, va_list ap, uint32_t *v)
     136             : {
     137             : /* XXX: Unassociated alpha data == 999 is a known Corel Draw bug, see below */
     138             : #define EXTRASAMPLE_COREL_UNASSALPHA 999
     139             : 
     140             :     uint16_t *va;
     141             :     uint32_t i;
     142        7287 :     TIFFDirectory *td = &tif->tif_dir;
     143             :     static const char module[] = "setExtraSamples";
     144             : 
     145        7287 :     *v = (uint16_t)va_arg(ap, uint16_vap);
     146        7287 :     if ((uint16_t)*v > td->td_samplesperpixel)
     147           0 :         return 0;
     148        7287 :     va = va_arg(ap, uint16_t *);
     149        7287 :     if (*v > 0 && va == NULL) /* typically missing param */
     150           0 :         return 0;
     151      804988 :     for (i = 0; i < *v; i++)
     152             :     {
     153      797701 :         if (va[i] > EXTRASAMPLE_UNASSALPHA)
     154             :         {
     155             :             /*
     156             :              * XXX: Corel Draw is known to produce incorrect
     157             :              * ExtraSamples tags which must be patched here if we
     158             :              * want to be able to open some of the damaged TIFF
     159             :              * files:
     160             :              */
     161           0 :             if (va[i] == EXTRASAMPLE_COREL_UNASSALPHA)
     162           0 :                 va[i] = EXTRASAMPLE_UNASSALPHA;
     163             :             else
     164           0 :                 return 0;
     165             :         }
     166             :     }
     167             : 
     168        7287 :     if (td->td_transferfunction[0] != NULL &&
     169           0 :         (td->td_samplesperpixel - *v > 1) &&
     170           0 :         !(td->td_samplesperpixel - td->td_extrasamples > 1))
     171             :     {
     172           0 :         TIFFWarningExtR(tif, module,
     173             :                         "ExtraSamples tag value is changing, "
     174             :                         "but TransferFunction was read with a different value. "
     175             :                         "Canceling it");
     176           0 :         TIFFClrFieldBit(tif, FIELD_TRANSFERFUNCTION);
     177           0 :         _TIFFfreeExt(tif, td->td_transferfunction[0]);
     178           0 :         td->td_transferfunction[0] = NULL;
     179             :     }
     180             : 
     181        7287 :     td->td_extrasamples = (uint16_t)*v;
     182        7287 :     _TIFFsetShortArrayExt(tif, &td->td_sampleinfo, va, td->td_extrasamples);
     183        7287 :     return 1;
     184             : 
     185             : #undef EXTRASAMPLE_COREL_UNASSALPHA
     186             : }
     187             : 
     188             : /*
     189             :  * Count ink names separated by \0.  Returns
     190             :  * zero if the ink names are not as expected.
     191             :  */
     192           0 : static uint16_t countInkNamesString(TIFF *tif, uint32_t slen, const char *s)
     193             : {
     194           0 :     uint16_t i = 0;
     195             : 
     196           0 :     if (slen > 0)
     197             :     {
     198           0 :         const char *ep = s + slen;
     199           0 :         const char *cp = s;
     200             :         do
     201             :         {
     202           0 :             for (; cp < ep && *cp != '\0'; cp++)
     203             :             {
     204             :             }
     205           0 :             if (cp >= ep)
     206           0 :                 goto bad;
     207           0 :             cp++; /* skip \0 */
     208           0 :             i++;
     209           0 :         } while (cp < ep);
     210           0 :         return (i);
     211             :     }
     212           0 : bad:
     213           0 :     TIFFErrorExtR(tif, "TIFFSetField",
     214             :                   "%s: Invalid InkNames value; no null at given buffer end "
     215             :                   "location %" PRIu32 ", after %" PRIu16 " ink",
     216             :                   tif->tif_name, slen, i);
     217           0 :     return (0);
     218             : }
     219             : 
     220      934491 : static int _TIFFVSetField(TIFF *tif, uint32_t tag, va_list ap)
     221             : {
     222             :     static const char module[] = "_TIFFVSetField";
     223             : 
     224      934491 :     TIFFDirectory *td = &tif->tif_dir;
     225      934491 :     int status = 1;
     226             :     uint32_t v32, v;
     227             :     double dblval;
     228             :     char *s;
     229      934491 :     const TIFFField *fip = TIFFFindField(tif, tag, TIFF_ANY);
     230      934418 :     uint32_t standard_tag = tag;
     231      934418 :     if (fip == NULL) /* cannot happen since OkToChangeTag() already checks it */
     232           0 :         return 0;
     233             :     /*
     234             :      * We want to force the custom code to be used for custom
     235             :      * fields even if the tag happens to match a well known
     236             :      * one - important for reinterpreted handling of standard
     237             :      * tag values in custom directories (i.e. EXIF)
     238             :      */
     239      934418 :     if (fip->field_bit == FIELD_CUSTOM)
     240             :     {
     241      103954 :         standard_tag = 0;
     242             :     }
     243             : 
     244      934418 :     switch (standard_tag)
     245             :     {
     246        5836 :         case TIFFTAG_SUBFILETYPE:
     247        5836 :             td->td_subfiletype = (uint32_t)va_arg(ap, uint32_t);
     248        5836 :             break;
     249       72910 :         case TIFFTAG_IMAGEWIDTH:
     250       72910 :             td->td_imagewidth = (uint32_t)va_arg(ap, uint32_t);
     251       72909 :             break;
     252       72910 :         case TIFFTAG_IMAGELENGTH:
     253       72910 :             td->td_imagelength = (uint32_t)va_arg(ap, uint32_t);
     254       72911 :             break;
     255       72895 :         case TIFFTAG_BITSPERSAMPLE:
     256       72895 :             td->td_bitspersample = (uint16_t)va_arg(ap, uint16_vap);
     257             :             /*
     258             :              * If the data require post-decoding processing to byte-swap
     259             :              * samples, set it up here.  Note that since tags are required
     260             :              * to be ordered, compression code can override this behavior
     261             :              * in the setup method if it wants to roll the post decoding
     262             :              * work in with its normal work.
     263             :              */
     264       72897 :             if (tif->tif_flags & TIFF_SWAB)
     265             :             {
     266         689 :                 if (td->td_bitspersample == 8)
     267         385 :                     tif->tif_postdecode = _TIFFNoPostDecode;
     268         304 :                 else if (td->td_bitspersample == 16)
     269         126 :                     tif->tif_postdecode = _TIFFSwab16BitData;
     270         178 :                 else if (td->td_bitspersample == 24)
     271           0 :                     tif->tif_postdecode = _TIFFSwab24BitData;
     272         178 :                 else if (td->td_bitspersample == 32)
     273         132 :                     tif->tif_postdecode = _TIFFSwab32BitData;
     274          46 :                 else if (td->td_bitspersample == 64)
     275          21 :                     tif->tif_postdecode = _TIFFSwab64BitData;
     276          25 :                 else if (td->td_bitspersample == 128) /* two 64's */
     277           7 :                     tif->tif_postdecode = _TIFFSwab64BitData;
     278             :             }
     279       72897 :             break;
     280      183596 :         case TIFFTAG_COMPRESSION:
     281      183596 :             v = (uint16_t)va_arg(ap, uint16_vap);
     282             :             /*
     283             :              * If we're changing the compression scheme, notify the
     284             :              * previous module so that it can cleanup any state it's
     285             :              * setup.
     286             :              */
     287      183597 :             if (TIFFFieldSet(tif, FIELD_COMPRESSION))
     288             :             {
     289       73550 :                 if ((uint32_t)td->td_compression == v)
     290       39480 :                     break;
     291       34070 :                 (*tif->tif_cleanup)(tif);
     292       34070 :                 tif->tif_flags &= ~TIFF_CODERSETUP;
     293             :             }
     294             :             /*
     295             :              * Setup new compression routine state.
     296             :              */
     297      144117 :             if ((status = TIFFSetCompressionScheme(tif, v)) != 0)
     298      144112 :                 td->td_compression = (uint16_t)v;
     299             :             else
     300           0 :                 status = 0;
     301      144107 :             break;
     302       72920 :         case TIFFTAG_PHOTOMETRIC:
     303       72920 :             td->td_photometric = (uint16_t)va_arg(ap, uint16_vap);
     304       72920 :             break;
     305           0 :         case TIFFTAG_THRESHHOLDING:
     306           0 :             td->td_threshholding = (uint16_t)va_arg(ap, uint16_vap);
     307           0 :             break;
     308           2 :         case TIFFTAG_FILLORDER:
     309           2 :             v = (uint16_t)va_arg(ap, uint16_vap);
     310           2 :             if (v != FILLORDER_LSB2MSB && v != FILLORDER_MSB2LSB)
     311           0 :                 goto badvalue;
     312           2 :             td->td_fillorder = (uint16_t)v;
     313           2 :             break;
     314          87 :         case TIFFTAG_ORIENTATION:
     315          87 :             v = (uint16_t)va_arg(ap, uint16_vap);
     316          87 :             if (v < ORIENTATION_TOPLEFT || ORIENTATION_LEFTBOT < v)
     317           0 :                 goto badvalue;
     318             :             else
     319          87 :                 td->td_orientation = (uint16_t)v;
     320          87 :             break;
     321       72899 :         case TIFFTAG_SAMPLESPERPIXEL:
     322       72899 :             v = (uint16_t)va_arg(ap, uint16_vap);
     323       72896 :             if (v == 0)
     324           0 :                 goto badvalue;
     325       72896 :             if (v != td->td_samplesperpixel)
     326             :             {
     327             :                 /* See http://bugzilla.maptools.org/show_bug.cgi?id=2500 */
     328       15427 :                 if (td->td_sminsamplevalue != NULL)
     329             :                 {
     330           0 :                     TIFFWarningExtR(tif, module,
     331             :                                     "SamplesPerPixel tag value is changing, "
     332             :                                     "but SMinSampleValue tag was read with a "
     333             :                                     "different value. Canceling it");
     334           0 :                     TIFFClrFieldBit(tif, FIELD_SMINSAMPLEVALUE);
     335           0 :                     _TIFFfreeExt(tif, td->td_sminsamplevalue);
     336           0 :                     td->td_sminsamplevalue = NULL;
     337             :                 }
     338       15427 :                 if (td->td_smaxsamplevalue != NULL)
     339             :                 {
     340           0 :                     TIFFWarningExtR(tif, module,
     341             :                                     "SamplesPerPixel tag value is changing, "
     342             :                                     "but SMaxSampleValue tag was read with a "
     343             :                                     "different value. Canceling it");
     344           0 :                     TIFFClrFieldBit(tif, FIELD_SMAXSAMPLEVALUE);
     345           0 :                     _TIFFfreeExt(tif, td->td_smaxsamplevalue);
     346           0 :                     td->td_smaxsamplevalue = NULL;
     347             :                 }
     348             :                 /* Test if 3 transfer functions instead of just one are now
     349             :                    needed See http://bugzilla.maptools.org/show_bug.cgi?id=2820
     350             :                  */
     351       15427 :                 if (td->td_transferfunction[0] != NULL &&
     352           0 :                     (v - td->td_extrasamples > 1) &&
     353           0 :                     !(td->td_samplesperpixel - td->td_extrasamples > 1))
     354             :                 {
     355           0 :                     TIFFWarningExtR(tif, module,
     356             :                                     "SamplesPerPixel tag value is changing, "
     357             :                                     "but TransferFunction was read with a "
     358             :                                     "different value. Canceling it");
     359           0 :                     TIFFClrFieldBit(tif, FIELD_TRANSFERFUNCTION);
     360           0 :                     _TIFFfreeExt(tif, td->td_transferfunction[0]);
     361           0 :                     td->td_transferfunction[0] = NULL;
     362             :                 }
     363             :             }
     364       72890 :             td->td_samplesperpixel = (uint16_t)v;
     365       72890 :             break;
     366       63917 :         case TIFFTAG_ROWSPERSTRIP:
     367       63917 :             v32 = (uint32_t)va_arg(ap, uint32_t);
     368       63914 :             if (v32 == 0)
     369           0 :                 goto badvalue32;
     370       63914 :             td->td_rowsperstrip = v32;
     371       63914 :             if (!TIFFFieldSet(tif, FIELD_TILEDIMENSIONS))
     372             :             {
     373       63912 :                 td->td_tilelength = v32;
     374       63912 :                 td->td_tilewidth = td->td_imagewidth;
     375             :             }
     376       63914 :             break;
     377           8 :         case TIFFTAG_MINSAMPLEVALUE:
     378           8 :             td->td_minsamplevalue = (uint16_t)va_arg(ap, uint16_vap);
     379           8 :             break;
     380           8 :         case TIFFTAG_MAXSAMPLEVALUE:
     381           8 :             td->td_maxsamplevalue = (uint16_t)va_arg(ap, uint16_vap);
     382           8 :             break;
     383           0 :         case TIFFTAG_SMINSAMPLEVALUE:
     384           0 :             if (tif->tif_flags & TIFF_PERSAMPLE)
     385           0 :                 _TIFFsetDoubleArrayExt(tif, &td->td_sminsamplevalue,
     386           0 :                                        va_arg(ap, double *),
     387           0 :                                        td->td_samplesperpixel);
     388             :             else
     389           0 :                 setDoubleArrayOneValue(tif, &td->td_sminsamplevalue,
     390             :                                        va_arg(ap, double),
     391           0 :                                        td->td_samplesperpixel);
     392           0 :             break;
     393           0 :         case TIFFTAG_SMAXSAMPLEVALUE:
     394           0 :             if (tif->tif_flags & TIFF_PERSAMPLE)
     395           0 :                 _TIFFsetDoubleArrayExt(tif, &td->td_smaxsamplevalue,
     396           0 :                                        va_arg(ap, double *),
     397           0 :                                        td->td_samplesperpixel);
     398             :             else
     399           0 :                 setDoubleArrayOneValue(tif, &td->td_smaxsamplevalue,
     400             :                                        va_arg(ap, double),
     401           0 :                                        td->td_samplesperpixel);
     402           0 :             break;
     403         129 :         case TIFFTAG_XRESOLUTION:
     404         129 :             dblval = va_arg(ap, double);
     405         129 :             if (dblval != dblval || dblval < 0)
     406           0 :                 goto badvaluedouble;
     407         129 :             td->td_xresolution = _TIFFClampDoubleToFloat(dblval);
     408         129 :             break;
     409         129 :         case TIFFTAG_YRESOLUTION:
     410         129 :             dblval = va_arg(ap, double);
     411         129 :             if (dblval != dblval || dblval < 0)
     412           0 :                 goto badvaluedouble;
     413         129 :             td->td_yresolution = _TIFFClampDoubleToFloat(dblval);
     414         129 :             break;
     415      110156 :         case TIFFTAG_PLANARCONFIG:
     416      110156 :             v = (uint16_t)va_arg(ap, uint16_vap);
     417      110169 :             if (v != PLANARCONFIG_CONTIG && v != PLANARCONFIG_SEPARATE)
     418           0 :                 goto badvalue;
     419      110169 :             td->td_planarconfig = (uint16_t)v;
     420      110169 :             break;
     421           1 :         case TIFFTAG_XPOSITION:
     422           1 :             td->td_xposition = _TIFFClampDoubleToFloat(va_arg(ap, double));
     423           1 :             break;
     424           1 :         case TIFFTAG_YPOSITION:
     425           1 :             td->td_yposition = _TIFFClampDoubleToFloat(va_arg(ap, double));
     426           1 :             break;
     427         133 :         case TIFFTAG_RESOLUTIONUNIT:
     428         133 :             v = (uint16_t)va_arg(ap, uint16_vap);
     429         133 :             if (v < RESUNIT_NONE || RESUNIT_CENTIMETER < v)
     430           0 :                 goto badvalue;
     431         133 :             td->td_resolutionunit = (uint16_t)v;
     432         133 :             break;
     433           0 :         case TIFFTAG_PAGENUMBER:
     434           0 :             td->td_pagenumber[0] = (uint16_t)va_arg(ap, uint16_vap);
     435           0 :             td->td_pagenumber[1] = (uint16_t)va_arg(ap, uint16_vap);
     436           0 :             break;
     437           0 :         case TIFFTAG_HALFTONEHINTS:
     438           0 :             td->td_halftonehints[0] = (uint16_t)va_arg(ap, uint16_vap);
     439           0 :             td->td_halftonehints[1] = (uint16_t)va_arg(ap, uint16_vap);
     440           0 :             break;
     441         378 :         case TIFFTAG_COLORMAP:
     442         378 :             v32 = (uint32_t)(1L << td->td_bitspersample);
     443         378 :             _TIFFsetShortArrayExt(tif, &td->td_colormap[0],
     444         378 :                                   va_arg(ap, uint16_t *), v32);
     445         378 :             _TIFFsetShortArrayExt(tif, &td->td_colormap[1],
     446         378 :                                   va_arg(ap, uint16_t *), v32);
     447         378 :             _TIFFsetShortArrayExt(tif, &td->td_colormap[2],
     448         378 :                                   va_arg(ap, uint16_t *), v32);
     449         378 :             break;
     450        7287 :         case TIFFTAG_EXTRASAMPLES:
     451        7287 :             if (!setExtraSamples(tif, ap, &v))
     452           0 :                 goto badvalue;
     453        7287 :             break;
     454           1 :         case TIFFTAG_MATTEING:
     455           1 :             td->td_extrasamples = (((uint16_t)va_arg(ap, uint16_vap)) != 0);
     456           1 :             if (td->td_extrasamples)
     457             :             {
     458           0 :                 uint16_t sv = EXTRASAMPLE_ASSOCALPHA;
     459           0 :                 _TIFFsetShortArrayExt(tif, &td->td_sampleinfo, &sv, 1);
     460             :             }
     461           1 :             break;
     462        9108 :         case TIFFTAG_TILEWIDTH:
     463        9108 :             v32 = (uint32_t)va_arg(ap, uint32_t);
     464        9108 :             if (v32 % 16)
     465             :             {
     466           2 :                 if (tif->tif_mode != O_RDONLY)
     467           0 :                     goto badvalue32;
     468           2 :                 TIFFWarningExtR(
     469           2 :                     tif, tif->tif_name,
     470             :                     "Nonstandard tile width %" PRIu32 ", convert file", v32);
     471             :             }
     472        9108 :             td->td_tilewidth = v32;
     473        9108 :             tif->tif_flags |= TIFF_ISTILED;
     474        9108 :             break;
     475        9108 :         case TIFFTAG_TILELENGTH:
     476        9108 :             v32 = (uint32_t)va_arg(ap, uint32_t);
     477        9108 :             if (v32 % 16)
     478             :             {
     479           4 :                 if (tif->tif_mode != O_RDONLY)
     480           1 :                     goto badvalue32;
     481           3 :                 TIFFWarningExtR(
     482           3 :                     tif, tif->tif_name,
     483             :                     "Nonstandard tile length %" PRIu32 ", convert file", v32);
     484             :             }
     485        9107 :             td->td_tilelength = v32;
     486        9107 :             tif->tif_flags |= TIFF_ISTILED;
     487        9107 :             break;
     488           0 :         case TIFFTAG_TILEDEPTH:
     489           0 :             v32 = (uint32_t)va_arg(ap, uint32_t);
     490           0 :             if (v32 == 0)
     491           0 :                 goto badvalue32;
     492           0 :             td->td_tiledepth = v32;
     493           0 :             break;
     494           0 :         case TIFFTAG_DATATYPE:
     495           0 :             v = (uint16_t)va_arg(ap, uint16_vap);
     496           0 :             switch (v)
     497             :             {
     498           0 :                 case DATATYPE_VOID:
     499           0 :                     v = SAMPLEFORMAT_VOID;
     500           0 :                     break;
     501           0 :                 case DATATYPE_INT:
     502           0 :                     v = SAMPLEFORMAT_INT;
     503           0 :                     break;
     504           0 :                 case DATATYPE_UINT:
     505           0 :                     v = SAMPLEFORMAT_UINT;
     506           0 :                     break;
     507           0 :                 case DATATYPE_IEEEFP:
     508           0 :                     v = SAMPLEFORMAT_IEEEFP;
     509           0 :                     break;
     510           0 :                 default:
     511           0 :                     goto badvalue;
     512             :             }
     513           0 :             td->td_sampleformat = (uint16_t)v;
     514           0 :             break;
     515       71914 :         case TIFFTAG_SAMPLEFORMAT:
     516       71914 :             v = (uint16_t)va_arg(ap, uint16_vap);
     517       71902 :             if (v < SAMPLEFORMAT_UINT || SAMPLEFORMAT_COMPLEXIEEEFP < v)
     518           1 :                 goto badvalue;
     519       71901 :             td->td_sampleformat = (uint16_t)v;
     520             : 
     521             :             /*  Try to fix up the SWAB function for complex data. */
     522       71901 :             if (td->td_sampleformat == SAMPLEFORMAT_COMPLEXINT &&
     523         801 :                 td->td_bitspersample == 32 &&
     524         482 :                 tif->tif_postdecode == _TIFFSwab32BitData)
     525          81 :                 tif->tif_postdecode = _TIFFSwab16BitData;
     526       71820 :             else if ((td->td_sampleformat == SAMPLEFORMAT_COMPLEXINT ||
     527       71108 :                       td->td_sampleformat == SAMPLEFORMAT_COMPLEXIEEEFP) &&
     528        1430 :                      td->td_bitspersample == 64 &&
     529         665 :                      tif->tif_postdecode == _TIFFSwab64BitData)
     530          14 :                 tif->tif_postdecode = _TIFFSwab32BitData;
     531       71901 :             break;
     532           0 :         case TIFFTAG_IMAGEDEPTH:
     533           0 :             td->td_imagedepth = (uint32_t)va_arg(ap, uint32_t);
     534           0 :             break;
     535          60 :         case TIFFTAG_SUBIFD:
     536          60 :             if ((tif->tif_flags & TIFF_INSUBIFD) == 0)
     537             :             {
     538          60 :                 td->td_nsubifd = (uint16_t)va_arg(ap, uint16_vap);
     539          60 :                 _TIFFsetLong8Array(tif, &td->td_subifd,
     540          60 :                                    (uint64_t *)va_arg(ap, uint64_t *),
     541          60 :                                    (uint32_t)td->td_nsubifd);
     542             :             }
     543             :             else
     544             :             {
     545           0 :                 TIFFErrorExtR(tif, module, "%s: Sorry, cannot nest SubIFDs",
     546             :                               tif->tif_name);
     547           0 :                 status = 0;
     548             :             }
     549          60 :             break;
     550          11 :         case TIFFTAG_YCBCRPOSITIONING:
     551          11 :             td->td_ycbcrpositioning = (uint16_t)va_arg(ap, uint16_vap);
     552          11 :             break;
     553        2171 :         case TIFFTAG_YCBCRSUBSAMPLING:
     554        2171 :             td->td_ycbcrsubsampling[0] = (uint16_t)va_arg(ap, uint16_vap);
     555        2171 :             td->td_ycbcrsubsampling[1] = (uint16_t)va_arg(ap, uint16_vap);
     556        2171 :             break;
     557          19 :         case TIFFTAG_TRANSFERFUNCTION:
     558             :         {
     559             :             uint32_t i;
     560          19 :             v = (td->td_samplesperpixel - td->td_extrasamples) > 1 ? 3 : 1;
     561          76 :             for (i = 0; i < v; i++)
     562          57 :                 _TIFFsetShortArrayExt(tif, &td->td_transferfunction[i],
     563          57 :                                       va_arg(ap, uint16_t *),
     564          57 :                                       1U << td->td_bitspersample);
     565          19 :             break;
     566             :         }
     567        1851 :         case TIFFTAG_REFERENCEBLACKWHITE:
     568             :             /* XXX should check for null range */
     569        1851 :             _TIFFsetFloatArrayExt(tif, &td->td_refblackwhite,
     570        1851 :                                   va_arg(ap, float *), 6);
     571        1851 :             break;
     572           0 :         case TIFFTAG_INKNAMES:
     573             :         {
     574           0 :             v = (uint16_t)va_arg(ap, uint16_vap);
     575           0 :             s = va_arg(ap, char *);
     576             :             uint16_t ninksinstring;
     577           0 :             ninksinstring = countInkNamesString(tif, v, s);
     578           0 :             status = ninksinstring > 0;
     579           0 :             if (ninksinstring > 0)
     580             :             {
     581           0 :                 _TIFFsetNString(tif, &td->td_inknames, s, v);
     582           0 :                 td->td_inknameslen = v;
     583             :                 /* Set NumberOfInks to the value ninksinstring */
     584           0 :                 if (TIFFFieldSet(tif, FIELD_NUMBEROFINKS))
     585             :                 {
     586           0 :                     if (td->td_numberofinks != ninksinstring)
     587             :                     {
     588           0 :                         TIFFErrorExtR(
     589             :                             tif, module,
     590             :                             "Warning %s; Tag %s:\n  Value %" PRIu16
     591             :                             " of NumberOfInks is different from the number of "
     592             :                             "inks %" PRIu16
     593             :                             ".\n  -> NumberOfInks value adapted to %" PRIu16 "",
     594           0 :                             tif->tif_name, fip->field_name, td->td_numberofinks,
     595             :                             ninksinstring, ninksinstring);
     596           0 :                         td->td_numberofinks = ninksinstring;
     597             :                     }
     598             :                 }
     599             :                 else
     600             :                 {
     601           0 :                     td->td_numberofinks = ninksinstring;
     602           0 :                     TIFFSetFieldBit(tif, FIELD_NUMBEROFINKS);
     603             :                 }
     604           0 :                 if (TIFFFieldSet(tif, FIELD_SAMPLESPERPIXEL))
     605             :                 {
     606           0 :                     if (td->td_numberofinks != td->td_samplesperpixel)
     607             :                     {
     608           0 :                         TIFFErrorExtR(tif, module,
     609             :                                       "Warning %s; Tag %s:\n  Value %" PRIu16
     610             :                                       " of NumberOfInks is different from the "
     611             :                                       "SamplesPerPixel value %" PRIu16 "",
     612             :                                       tif->tif_name, fip->field_name,
     613           0 :                                       td->td_numberofinks,
     614           0 :                                       td->td_samplesperpixel);
     615             :                     }
     616             :                 }
     617             :             }
     618             :         }
     619           0 :         break;
     620           0 :         case TIFFTAG_NUMBEROFINKS:
     621           0 :             v = (uint16_t)va_arg(ap, uint16_vap);
     622             :             /* If InkNames already set also NumberOfInks is set accordingly and
     623             :              * should be equal */
     624           0 :             if (TIFFFieldSet(tif, FIELD_INKNAMES))
     625             :             {
     626           0 :                 if (v != td->td_numberofinks)
     627             :                 {
     628           0 :                     TIFFErrorExtR(
     629             :                         tif, module,
     630             :                         "Error %s; Tag %s:\n  It is not possible to set the "
     631             :                         "value %" PRIu32
     632             :                         " for NumberOfInks\n  which is different from the "
     633             :                         "number of inks in the InkNames tag (%" PRIu16 ")",
     634           0 :                         tif->tif_name, fip->field_name, v, td->td_numberofinks);
     635             :                     /* Do not set / overwrite number of inks already set by
     636             :                      * InkNames case accordingly. */
     637           0 :                     status = 0;
     638             :                 }
     639             :             }
     640             :             else
     641             :             {
     642           0 :                 td->td_numberofinks = (uint16_t)v;
     643           0 :                 if (TIFFFieldSet(tif, FIELD_SAMPLESPERPIXEL))
     644             :                 {
     645           0 :                     if (td->td_numberofinks != td->td_samplesperpixel)
     646             :                     {
     647           0 :                         TIFFErrorExtR(tif, module,
     648             :                                       "Warning %s; Tag %s:\n  Value %" PRIu32
     649             :                                       " of NumberOfInks is different from the "
     650             :                                       "SamplesPerPixel value %" PRIu16 "",
     651             :                                       tif->tif_name, fip->field_name, v,
     652           0 :                                       td->td_samplesperpixel);
     653             :                     }
     654             :                 }
     655             :             }
     656           0 :             break;
     657           0 :         case TIFFTAG_PERSAMPLE:
     658           0 :             v = (uint16_t)va_arg(ap, uint16_vap);
     659           0 :             if (v == PERSAMPLE_MULTI)
     660           0 :                 tif->tif_flags |= TIFF_PERSAMPLE;
     661             :             else
     662           0 :                 tif->tif_flags &= ~TIFF_PERSAMPLE;
     663           0 :             break;
     664      103973 :         default:
     665             :         {
     666             :             TIFFTagValue *tv;
     667             :             int tv_size, iCustom;
     668             : 
     669             :             /*
     670             :              * This can happen if multiple images are open with different
     671             :              * codecs which have private tags.  The global tag information
     672             :              * table may then have tags that are valid for one file but not
     673             :              * the other. If the client tries to set a tag that is not valid
     674             :              * for the image's codec then we'll arrive here.  This
     675             :              * happens, for example, when tiffcp is used to convert between
     676             :              * compression schemes and codec-specific tags are blindly copied.
     677             :              *
     678             :              * This also happens when a FIELD_IGNORE tag is written.
     679             :              */
     680      103973 :             if (fip->field_bit == FIELD_IGNORE)
     681             :             {
     682           0 :                 TIFFErrorExtR(
     683             :                     tif, module,
     684             :                     "%s: Ignored %stag \"%s\" (not supported by libtiff)",
     685             :                     tif->tif_name, isPseudoTag(tag) ? "pseudo-" : "",
     686             :                     fip->field_name);
     687           0 :                 status = 0;
     688           0 :                 break;
     689             :             }
     690      103973 :             if (fip->field_bit != FIELD_CUSTOM)
     691             :             {
     692           0 :                 TIFFErrorExtR(
     693             :                     tif, module,
     694             :                     "%s: Invalid %stag \"%s\" (not supported by codec)",
     695             :                     tif->tif_name, isPseudoTag(tag) ? "pseudo-" : "",
     696             :                     fip->field_name);
     697           0 :                 status = 0;
     698           0 :                 break;
     699             :             }
     700             : 
     701             :             /*
     702             :              * Find the existing entry for this custom value.
     703             :              */
     704      103973 :             tv = NULL;
     705      263856 :             for (iCustom = 0; iCustom < td->td_customValueCount; iCustom++)
     706             :             {
     707      161927 :                 if (td->td_customValues[iCustom].info->field_tag == tag)
     708             :                 {
     709        2044 :                     tv = td->td_customValues + iCustom;
     710        2044 :                     if (tv->value != NULL)
     711             :                     {
     712        2044 :                         _TIFFfreeExt(tif, tv->value);
     713        2044 :                         tv->value = NULL;
     714             :                     }
     715        2044 :                     break;
     716             :                 }
     717             :             }
     718             : 
     719             :             /*
     720             :              * Grow the custom list if the entry was not found.
     721             :              */
     722      103973 :             if (tv == NULL)
     723             :             {
     724             :                 TIFFTagValue *new_customValues;
     725             : 
     726      101890 :                 td->td_customValueCount++;
     727      101890 :                 new_customValues = (TIFFTagValue *)_TIFFreallocExt(
     728      101890 :                     tif, td->td_customValues,
     729      101890 :                     sizeof(TIFFTagValue) * td->td_customValueCount);
     730      101927 :                 if (!new_customValues)
     731             :                 {
     732          45 :                     TIFFErrorExtR(tif, module,
     733             :                                   "%s: Failed to allocate space for list of "
     734             :                                   "custom values",
     735             :                                   tif->tif_name);
     736           0 :                     status = 0;
     737           0 :                     goto end;
     738             :                 }
     739             : 
     740      101882 :                 td->td_customValues = new_customValues;
     741             : 
     742      101882 :                 tv = td->td_customValues + (td->td_customValueCount - 1);
     743      101882 :                 tv->info = fip;
     744      101882 :                 tv->value = NULL;
     745      101882 :                 tv->count = 0;
     746             :             }
     747             : 
     748             :             /*
     749             :              * Set custom value ... save a copy of the custom tag value.
     750             :              */
     751             :             /*--: Rational2Double: For Rationals evaluate "set_field_type" to
     752             :              * determine internal storage size. */
     753      103965 :             tv_size = TIFFFieldSetGetSize(fip);
     754      103929 :             if (tv_size == 0)
     755             :             {
     756           3 :                 status = 0;
     757           3 :                 TIFFErrorExtR(tif, module, "%s: Bad field type %d for \"%s\"",
     758           3 :                               tif->tif_name, fip->field_type, fip->field_name);
     759           0 :                 goto end;
     760             :             }
     761             : 
     762      103926 :             if (fip->field_type == TIFF_ASCII)
     763             :             {
     764             :                 uint32_t ma;
     765             :                 const char *mb;
     766       29602 :                 if (fip->field_passcount)
     767             :                 {
     768           0 :                     assert(fip->field_writecount == TIFF_VARIABLE2);
     769           0 :                     ma = (uint32_t)va_arg(ap, uint32_t);
     770           0 :                     mb = (const char *)va_arg(ap, const char *);
     771             :                 }
     772             :                 else
     773             :                 {
     774       29602 :                     mb = (const char *)va_arg(ap, const char *);
     775       29597 :                     size_t len = strlen(mb) + 1;
     776       29597 :                     if (len >= 0x80000000U)
     777             :                     {
     778           0 :                         status = 0;
     779           0 :                         TIFFErrorExtR(tif, module,
     780             :                                       "%s: Too long string value for \"%s\". "
     781             :                                       "Maximum supported is 2147483647 bytes",
     782             :                                       tif->tif_name, fip->field_name);
     783           0 :                         goto end;
     784             :                     }
     785       29604 :                     ma = (uint32_t)len;
     786             :                 }
     787       29604 :                 tv->count = ma;
     788       29604 :                 setByteArray(tif, &tv->value, mb, ma, 1);
     789             :             }
     790             :             else
     791             :             {
     792       74324 :                 if (fip->field_passcount)
     793             :                 {
     794       74247 :                     if (fip->field_writecount == TIFF_VARIABLE2)
     795        3002 :                         tv->count = (uint32_t)va_arg(ap, uint32_t);
     796             :                     else
     797       71245 :                         tv->count = (int)va_arg(ap, int);
     798             :                 }
     799          77 :                 else if (fip->field_writecount == TIFF_VARIABLE ||
     800          71 :                          fip->field_writecount == TIFF_VARIABLE2)
     801           6 :                     tv->count = 1;
     802          71 :                 else if (fip->field_writecount == TIFF_SPP)
     803           0 :                     tv->count = td->td_samplesperpixel;
     804             :                 else
     805          71 :                     tv->count = fip->field_writecount;
     806             : 
     807       74304 :                 if (tv->count == 0)
     808             :                 {
     809           0 :                     status = 0;
     810           0 :                     TIFFErrorExtR(tif, module,
     811             :                                   "%s: Null count for \"%s\" (type "
     812             :                                   "%d, writecount %d, passcount %d)",
     813             :                                   tif->tif_name, fip->field_name,
     814           0 :                                   fip->field_type, fip->field_writecount,
     815           0 :                                   fip->field_passcount);
     816           0 :                     goto end;
     817             :                 }
     818             : 
     819       74304 :                 tv->value = _TIFFCheckMalloc(tif, tv->count, tv_size,
     820             :                                              "custom tag binary object");
     821       74343 :                 if (!tv->value)
     822             :                 {
     823           0 :                     status = 0;
     824           0 :                     goto end;
     825             :                 }
     826             : 
     827       74343 :                 if (fip->field_tag == TIFFTAG_DOTRANGE &&
     828           0 :                     strcmp(fip->field_name, "DotRange") == 0)
     829           0 :                 {
     830             :                     /* TODO: This is an evil exception and should not have been
     831             :                        handled this way ... likely best if we move it into
     832             :                        the directory structure with an explicit field in
     833             :                        libtiff 4.1 and assign it a FIELD_ value */
     834             :                     uint16_t v2[2];
     835           0 :                     v2[0] = (uint16_t)va_arg(ap, int);
     836           0 :                     v2[1] = (uint16_t)va_arg(ap, int);
     837           0 :                     _TIFFmemcpy(tv->value, &v2, 4);
     838             :                 }
     839             : 
     840       74343 :                 else if (fip->field_passcount ||
     841          71 :                          fip->field_writecount == TIFF_VARIABLE ||
     842          71 :                          fip->field_writecount == TIFF_VARIABLE2 ||
     843          71 :                          fip->field_writecount == TIFF_SPP || tv->count > 1)
     844             :                 {
     845             :                     /*--: Rational2Double: For Rationals tv_size is set above to
     846             :                      * 4 or 8 according to fip->set_field_type! */
     847       74326 :                     _TIFFmemcpy(tv->value, va_arg(ap, void *),
     848       74335 :                                 tv->count * tv_size);
     849             :                     /* Test here for too big values for LONG8, SLONG8 in
     850             :                      * ClassicTIFF and delete custom field from custom list */
     851       74309 :                     if (!(tif->tif_flags & TIFF_BIGTIFF))
     852             :                     {
     853       74213 :                         if (tv->info->field_type == TIFF_LONG8)
     854             :                         {
     855           0 :                             uint64_t *pui64 = (uint64_t *)tv->value;
     856           0 :                             for (int i = 0; i < tv->count; i++)
     857             :                             {
     858           0 :                                 if (pui64[i] > 0xffffffffu)
     859             :                                 {
     860           0 :                                     TIFFErrorExtR(
     861             :                                         tif, module,
     862             :                                         "%s: Bad LONG8 value %" PRIu64
     863             :                                         " at %d. array position for \"%s\" tag "
     864             :                                         "%d in ClassicTIFF. Tag won't be "
     865             :                                         "written to file",
     866           0 :                                         tif->tif_name, pui64[i], i,
     867             :                                         fip->field_name, tag);
     868           0 :                                     goto badvalueifd8long8;
     869             :                                 }
     870             :                             }
     871             :                         }
     872       74213 :                         else if (tv->info->field_type == TIFF_SLONG8)
     873             :                         {
     874           0 :                             int64_t *pi64 = (int64_t *)tv->value;
     875           0 :                             for (int i = 0; i < tv->count; i++)
     876             :                             {
     877           0 :                                 if (pi64[i] > 2147483647 ||
     878           0 :                                     pi64[i] < (-2147483647 - 1))
     879             :                                 {
     880           0 :                                     TIFFErrorExtR(
     881             :                                         tif, module,
     882             :                                         "%s: Bad SLONG8 value %" PRIi64
     883             :                                         " at %d. array position for \"%s\" tag "
     884             :                                         "%d in ClassicTIFF. Tag won't be "
     885             :                                         "written to file",
     886           0 :                                         tif->tif_name, pi64[i], i,
     887             :                                         fip->field_name, tag);
     888           0 :                                     goto badvalueifd8long8;
     889             :                                 }
     890             :                             }
     891             :                         }
     892             :                     }
     893             :                 }
     894             :                 else
     895             :                 {
     896           8 :                     char *val = (char *)tv->value;
     897           8 :                     assert(tv->count == 1);
     898             : 
     899           8 :                     switch (fip->field_type)
     900             :                     {
     901           0 :                         case TIFF_BYTE:
     902             :                         case TIFF_UNDEFINED:
     903             :                         {
     904           0 :                             uint8_t v2 = (uint8_t)va_arg(ap, int);
     905           0 :                             _TIFFmemcpy(val, &v2, tv_size);
     906             :                         }
     907           0 :                         break;
     908           0 :                         case TIFF_SBYTE:
     909             :                         {
     910           0 :                             int8_t v2 = (int8_t)va_arg(ap, int);
     911           0 :                             _TIFFmemcpy(val, &v2, tv_size);
     912             :                         }
     913           0 :                         break;
     914           0 :                         case TIFF_SHORT:
     915             :                         {
     916           0 :                             uint16_t v2 = (uint16_t)va_arg(ap, int);
     917           0 :                             _TIFFmemcpy(val, &v2, tv_size);
     918             :                         }
     919           0 :                         break;
     920           0 :                         case TIFF_SSHORT:
     921             :                         {
     922           0 :                             int16_t v2 = (int16_t)va_arg(ap, int);
     923           0 :                             _TIFFmemcpy(val, &v2, tv_size);
     924             :                         }
     925           0 :                         break;
     926           0 :                         case TIFF_LONG:
     927             :                         case TIFF_IFD:
     928             :                         {
     929           0 :                             uint32_t v2 = va_arg(ap, uint32_t);
     930           0 :                             _TIFFmemcpy(val, &v2, tv_size);
     931             :                         }
     932           0 :                         break;
     933           0 :                         case TIFF_SLONG:
     934             :                         {
     935           0 :                             int32_t v2 = va_arg(ap, int32_t);
     936           0 :                             _TIFFmemcpy(val, &v2, tv_size);
     937             :                         }
     938           0 :                         break;
     939           8 :                         case TIFF_LONG8:
     940             :                         case TIFF_IFD8:
     941             :                         {
     942           8 :                             uint64_t v2 = va_arg(ap, uint64_t);
     943           8 :                             _TIFFmemcpy(val, &v2, tv_size);
     944             :                             /* Test here for too big values for ClassicTIFF and
     945             :                              * delete custom field from custom list */
     946           8 :                             if (!(tif->tif_flags & TIFF_BIGTIFF) &&
     947           8 :                                 (v2 > 0xffffffffu))
     948             :                             {
     949           0 :                                 TIFFErrorExtR(
     950             :                                     tif, module,
     951             :                                     "%s: Bad LONG8 or IFD8 value %" PRIu64
     952             :                                     " for \"%s\" tag %d in ClassicTIFF. Tag "
     953             :                                     "won't be written to file",
     954             :                                     tif->tif_name, v2, fip->field_name, tag);
     955           0 :                                 goto badvalueifd8long8;
     956             :                             }
     957             :                         }
     958           8 :                         break;
     959           0 :                         case TIFF_SLONG8:
     960             :                         {
     961           0 :                             int64_t v2 = va_arg(ap, int64_t);
     962           0 :                             _TIFFmemcpy(val, &v2, tv_size);
     963             :                             /* Test here for too big values for ClassicTIFF and
     964             :                              * delete custom field from custom list */
     965           0 :                             if (!(tif->tif_flags & TIFF_BIGTIFF) &&
     966           0 :                                 ((v2 > 2147483647) || (v2 < (-2147483647 - 1))))
     967             :                             {
     968           0 :                                 TIFFErrorExtR(
     969             :                                     tif, module,
     970             :                                     "%s: Bad SLONG8 value %" PRIi64
     971             :                                     " for \"%s\" tag %d in ClassicTIFF. Tag "
     972             :                                     "won't be written to file",
     973             :                                     tif->tif_name, v2, fip->field_name, tag);
     974           0 :                                 goto badvalueifd8long8;
     975             :                             }
     976             :                         }
     977           0 :                         break;
     978           0 :                         case TIFF_RATIONAL:
     979             :                         case TIFF_SRATIONAL:
     980             :                             /*-- Rational2Double: For Rationals tv_size is set
     981             :                              * above to 4 or 8 according to fip->set_field_type!
     982             :                              */
     983             :                             {
     984           0 :                                 if (tv_size == 8)
     985             :                                 {
     986           0 :                                     double v2 = va_arg(ap, double);
     987           0 :                                     _TIFFmemcpy(val, &v2, tv_size);
     988             :                                 }
     989             :                                 else
     990             :                                 {
     991             :                                     /*-- default should be tv_size == 4 */
     992           0 :                                     float v3 = (float)va_arg(ap, double);
     993           0 :                                     _TIFFmemcpy(val, &v3, tv_size);
     994             :                                     /*-- ToDo: After Testing, this should be
     995             :                                      * removed and tv_size==4 should be set as
     996             :                                      * default. */
     997           0 :                                     if (tv_size != 4)
     998             :                                     {
     999           0 :                                         TIFFErrorExtR(
    1000             :                                             tif, module,
    1001             :                                             "Rational2Double: .set_field_type "
    1002             :                                             "in not 4 but %d",
    1003             :                                             tv_size);
    1004             :                                     }
    1005             :                                 }
    1006             :                             }
    1007           0 :                             break;
    1008           0 :                         case TIFF_FLOAT:
    1009             :                         {
    1010           0 :                             float v2 =
    1011           0 :                                 _TIFFClampDoubleToFloat(va_arg(ap, double));
    1012           0 :                             _TIFFmemcpy(val, &v2, tv_size);
    1013             :                         }
    1014           0 :                         break;
    1015           0 :                         case TIFF_DOUBLE:
    1016             :                         {
    1017           0 :                             double v2 = va_arg(ap, double);
    1018           0 :                             _TIFFmemcpy(val, &v2, tv_size);
    1019             :                         }
    1020           0 :                         break;
    1021           0 :                         default:
    1022           0 :                             _TIFFmemset(val, 0, tv_size);
    1023           0 :                             status = 0;
    1024           0 :                             break;
    1025             :                     }
    1026             :                 }
    1027             :             }
    1028             :         }
    1029             :     }
    1030      934334 :     if (status)
    1031             :     {
    1032      934334 :         const TIFFField *fip2 = TIFFFieldWithTag(tif, tag);
    1033      934373 :         if (fip2)
    1034      934348 :             TIFFSetFieldBit(tif, fip2->field_bit);
    1035      934373 :         tif->tif_flags |= TIFF_DIRTYDIRECT;
    1036             :     }
    1037             : 
    1038           0 : end:
    1039      934373 :     va_end(ap);
    1040      934373 :     return (status);
    1041           1 : badvalue:
    1042             : {
    1043           1 :     const TIFFField *fip2 = TIFFFieldWithTag(tif, tag);
    1044           0 :     TIFFErrorExtR(tif, module, "%s: Bad value %" PRIu32 " for \"%s\" tag",
    1045             :                   tif->tif_name, v, fip2 ? fip2->field_name : "Unknown");
    1046           0 :     va_end(ap);
    1047             : }
    1048           0 :     return (0);
    1049           1 : badvalue32:
    1050             : {
    1051           1 :     const TIFFField *fip2 = TIFFFieldWithTag(tif, tag);
    1052           1 :     TIFFErrorExtR(tif, module, "%s: Bad value %" PRIu32 " for \"%s\" tag",
    1053             :                   tif->tif_name, v32, fip2 ? fip2->field_name : "Unknown");
    1054           1 :     va_end(ap);
    1055             : }
    1056           1 :     return (0);
    1057           0 : badvaluedouble:
    1058             : {
    1059           0 :     const TIFFField *fip2 = TIFFFieldWithTag(tif, tag);
    1060           0 :     TIFFErrorExtR(tif, module, "%s: Bad value %f for \"%s\" tag", tif->tif_name,
    1061             :                   dblval, fip2 ? fip2->field_name : "Unknown");
    1062           0 :     va_end(ap);
    1063             : }
    1064           0 :     return (0);
    1065           0 : badvalueifd8long8:
    1066             : {
    1067             :     /* Error message issued already above. */
    1068           0 :     TIFFTagValue *tv2 = NULL;
    1069             :     int iCustom2, iC2;
    1070             :     /* Find the existing entry for this custom value. */
    1071           0 :     for (iCustom2 = 0; iCustom2 < td->td_customValueCount; iCustom2++)
    1072             :     {
    1073           0 :         if (td->td_customValues[iCustom2].info->field_tag == tag)
    1074             :         {
    1075           0 :             tv2 = td->td_customValues + (iCustom2);
    1076           0 :             break;
    1077             :         }
    1078             :     }
    1079           0 :     if (tv2 != NULL)
    1080             :     {
    1081             :         /* Remove custom field from custom list */
    1082           0 :         if (tv2->value != NULL)
    1083             :         {
    1084           0 :             _TIFFfreeExt(tif, tv2->value);
    1085           0 :             tv2->value = NULL;
    1086             :         }
    1087             :         /* Shorten list and close gap in customValues list.
    1088             :          * Re-allocation of td_customValues not necessary here. */
    1089           0 :         td->td_customValueCount--;
    1090           0 :         for (iC2 = iCustom2; iC2 < td->td_customValueCount; iC2++)
    1091             :         {
    1092           0 :             td->td_customValues[iC2] = td->td_customValues[iC2 + 1];
    1093             :         }
    1094             :     }
    1095             :     else
    1096             :     {
    1097           0 :         assert(0);
    1098             :     }
    1099           0 :     va_end(ap);
    1100             : }
    1101           0 :     return (0);
    1102             : } /*-- _TIFFVSetField() --*/
    1103             : 
    1104             : /*
    1105             :  * Return 1/0 according to whether or not
    1106             :  * it is permissible to set the tag's value.
    1107             :  * Note that we allow ImageLength to be changed
    1108             :  * so that we can append and extend to images.
    1109             :  * Any other tag may not be altered once writing
    1110             :  * has commenced, unless its value has no effect
    1111             :  * on the format of the data that is written.
    1112             :  */
    1113      957016 : static int OkToChangeTag(TIFF *tif, uint32_t tag)
    1114             : {
    1115      957016 :     const TIFFField *fip = TIFFFindField(tif, tag, TIFF_ANY);
    1116      957244 :     if (!fip)
    1117             :     { /* unknown tag */
    1118           0 :         TIFFErrorExtR(tif, "TIFFSetField", "%s: Unknown %stag %" PRIu32,
    1119             :                       tif->tif_name, isPseudoTag(tag) ? "pseudo-" : "", tag);
    1120           0 :         return (0);
    1121             :     }
    1122      957244 :     if (tag != TIFFTAG_IMAGELENGTH && (tif->tif_flags & TIFF_BEENWRITING) &&
    1123         742 :         !fip->field_oktochange)
    1124             :     {
    1125             :         /*
    1126             :          * Consult info table to see if tag can be changed
    1127             :          * after we've started writing.  We only allow changes
    1128             :          * to those tags that don't/shouldn't affect the
    1129             :          * compression and/or format of the data.
    1130             :          */
    1131           2 :         TIFFErrorExtR(tif, "TIFFSetField",
    1132             :                       "%s: Cannot modify tag \"%s\" while writing",
    1133             :                       tif->tif_name, fip->field_name);
    1134           2 :         return (0);
    1135             :     }
    1136      957242 :     return (1);
    1137             : }
    1138             : 
    1139             : /*
    1140             :  * Record the value of a field in the
    1141             :  * internal directory structure.  The
    1142             :  * field will be written to the file
    1143             :  * when/if the directory structure is
    1144             :  * updated.
    1145             :  */
    1146      957170 : int TIFFSetField(TIFF *tif, uint32_t tag, ...)
    1147             : {
    1148             :     va_list ap;
    1149             :     int status;
    1150             : 
    1151      957170 :     va_start(ap, tag);
    1152      957170 :     status = TIFFVSetField(tif, tag, ap);
    1153      957127 :     va_end(ap);
    1154      957127 :     return (status);
    1155             : }
    1156             : 
    1157             : /*
    1158             :  * Clear the contents of the field in the internal structure.
    1159             :  */
    1160        4501 : int TIFFUnsetField(TIFF *tif, uint32_t tag)
    1161             : {
    1162        4501 :     const TIFFField *fip = TIFFFieldWithTag(tif, tag);
    1163        4501 :     TIFFDirectory *td = &tif->tif_dir;
    1164             : 
    1165        4501 :     if (!fip)
    1166           0 :         return 0;
    1167             : 
    1168        4501 :     if (fip->field_bit != FIELD_CUSTOM)
    1169           5 :         TIFFClrFieldBit(tif, fip->field_bit);
    1170             :     else
    1171             :     {
    1172        4496 :         TIFFTagValue *tv = NULL;
    1173             :         int i;
    1174             : 
    1175        4805 :         for (i = 0; i < td->td_customValueCount; i++)
    1176             :         {
    1177             : 
    1178         387 :             tv = td->td_customValues + i;
    1179         387 :             if (tv->info->field_tag == tag)
    1180          78 :                 break;
    1181             :         }
    1182             : 
    1183        4496 :         if (i < td->td_customValueCount)
    1184             :         {
    1185          78 :             _TIFFfreeExt(tif, tv->value);
    1186         191 :             for (; i < td->td_customValueCount - 1; i++)
    1187             :             {
    1188         113 :                 td->td_customValues[i] = td->td_customValues[i + 1];
    1189             :             }
    1190          78 :             td->td_customValueCount--;
    1191             :         }
    1192             :     }
    1193             : 
    1194        4501 :     tif->tif_flags |= TIFF_DIRTYDIRECT;
    1195             : 
    1196        4501 :     return (1);
    1197             : }
    1198             : 
    1199             : /*
    1200             :  * Like TIFFSetField, but taking a varargs
    1201             :  * parameter list.  This routine is useful
    1202             :  * for building higher-level interfaces on
    1203             :  * top of the library.
    1204             :  */
    1205      957159 : int TIFFVSetField(TIFF *tif, uint32_t tag, va_list ap)
    1206             : {
    1207      957159 :     return OkToChangeTag(tif, tag)
    1208      957216 :                ? (*tif->tif_tagmethods.vsetfield)(tif, tag, ap)
    1209     1914340 :                : 0;
    1210             : }
    1211             : 
    1212     1378290 : static int _TIFFVGetField(TIFF *tif, uint32_t tag, va_list ap)
    1213             : {
    1214     1378290 :     TIFFDirectory *td = &tif->tif_dir;
    1215     1378290 :     int ret_val = 1;
    1216     1378290 :     uint32_t standard_tag = tag;
    1217     1378290 :     const TIFFField *fip = TIFFFindField(tif, tag, TIFF_ANY);
    1218     1378130 :     if (fip == NULL) /* cannot happen since TIFFGetField() already checks it */
    1219           0 :         return 0;
    1220             : 
    1221             :     /*
    1222             :      * We want to force the custom code to be used for custom
    1223             :      * fields even if the tag happens to match a well known
    1224             :      * one - important for reinterpreted handling of standard
    1225             :      * tag values in custom directories (i.e. EXIF)
    1226             :      */
    1227     1378130 :     if (fip->field_bit == FIELD_CUSTOM)
    1228             :     {
    1229      271186 :         standard_tag = 0;
    1230             :     }
    1231             : 
    1232     1378130 :     switch (standard_tag)
    1233             :     {
    1234        1176 :         case TIFFTAG_SUBFILETYPE:
    1235        1176 :             *va_arg(ap, uint32_t *) = td->td_subfiletype;
    1236        1176 :             break;
    1237       34534 :         case TIFFTAG_IMAGEWIDTH:
    1238       34534 :             *va_arg(ap, uint32_t *) = td->td_imagewidth;
    1239       34549 :             break;
    1240       34554 :         case TIFFTAG_IMAGELENGTH:
    1241       34554 :             *va_arg(ap, uint32_t *) = td->td_imagelength;
    1242       34553 :             break;
    1243       22634 :         case TIFFTAG_BITSPERSAMPLE:
    1244       22634 :             *va_arg(ap, uint16_t *) = td->td_bitspersample;
    1245       22629 :             break;
    1246       38293 :         case TIFFTAG_COMPRESSION:
    1247       38293 :             *va_arg(ap, uint16_t *) = td->td_compression;
    1248       38289 :             break;
    1249       27138 :         case TIFFTAG_PHOTOMETRIC:
    1250       27138 :             *va_arg(ap, uint16_t *) = td->td_photometric;
    1251       27132 :             break;
    1252           0 :         case TIFFTAG_THRESHHOLDING:
    1253           0 :             *va_arg(ap, uint16_t *) = td->td_threshholding;
    1254           0 :             break;
    1255           0 :         case TIFFTAG_FILLORDER:
    1256           0 :             *va_arg(ap, uint16_t *) = td->td_fillorder;
    1257           0 :             break;
    1258          16 :         case TIFFTAG_ORIENTATION:
    1259          16 :             *va_arg(ap, uint16_t *) = td->td_orientation;
    1260          16 :             break;
    1261       19908 :         case TIFFTAG_SAMPLESPERPIXEL:
    1262       19908 :             *va_arg(ap, uint16_t *) = td->td_samplesperpixel;
    1263       19893 :             break;
    1264       17928 :         case TIFFTAG_ROWSPERSTRIP:
    1265       17928 :             *va_arg(ap, uint32_t *) = td->td_rowsperstrip;
    1266       17924 :             break;
    1267           5 :         case TIFFTAG_MINSAMPLEVALUE:
    1268           5 :             *va_arg(ap, uint16_t *) = td->td_minsamplevalue;
    1269           5 :             break;
    1270           5 :         case TIFFTAG_MAXSAMPLEVALUE:
    1271           5 :             *va_arg(ap, uint16_t *) = td->td_maxsamplevalue;
    1272           5 :             break;
    1273           0 :         case TIFFTAG_SMINSAMPLEVALUE:
    1274           0 :             if (tif->tif_flags & TIFF_PERSAMPLE)
    1275           0 :                 *va_arg(ap, double **) = td->td_sminsamplevalue;
    1276             :             else
    1277             :             {
    1278             :                 /* libtiff historically treats this as a single value. */
    1279             :                 uint16_t i;
    1280           0 :                 double v = td->td_sminsamplevalue[0];
    1281           0 :                 for (i = 1; i < td->td_samplesperpixel; ++i)
    1282           0 :                     if (td->td_sminsamplevalue[i] < v)
    1283           0 :                         v = td->td_sminsamplevalue[i];
    1284           0 :                 *va_arg(ap, double *) = v;
    1285             :             }
    1286           0 :             break;
    1287           0 :         case TIFFTAG_SMAXSAMPLEVALUE:
    1288           0 :             if (tif->tif_flags & TIFF_PERSAMPLE)
    1289           0 :                 *va_arg(ap, double **) = td->td_smaxsamplevalue;
    1290             :             else
    1291             :             {
    1292             :                 /* libtiff historically treats this as a single value. */
    1293             :                 uint16_t i;
    1294           0 :                 double v = td->td_smaxsamplevalue[0];
    1295           0 :                 for (i = 1; i < td->td_samplesperpixel; ++i)
    1296           0 :                     if (td->td_smaxsamplevalue[i] > v)
    1297           0 :                         v = td->td_smaxsamplevalue[i];
    1298           0 :                 *va_arg(ap, double *) = v;
    1299             :             }
    1300           0 :             break;
    1301          86 :         case TIFFTAG_XRESOLUTION:
    1302          86 :             *va_arg(ap, float *) = td->td_xresolution;
    1303          86 :             break;
    1304          85 :         case TIFFTAG_YRESOLUTION:
    1305          85 :             *va_arg(ap, float *) = td->td_yresolution;
    1306          85 :             break;
    1307       22464 :         case TIFFTAG_PLANARCONFIG:
    1308       22464 :             *va_arg(ap, uint16_t *) = td->td_planarconfig;
    1309       22463 :             break;
    1310           0 :         case TIFFTAG_XPOSITION:
    1311           0 :             *va_arg(ap, float *) = td->td_xposition;
    1312           0 :             break;
    1313           0 :         case TIFFTAG_YPOSITION:
    1314           0 :             *va_arg(ap, float *) = td->td_yposition;
    1315           0 :             break;
    1316          88 :         case TIFFTAG_RESOLUTIONUNIT:
    1317          88 :             *va_arg(ap, uint16_t *) = td->td_resolutionunit;
    1318          88 :             break;
    1319           0 :         case TIFFTAG_PAGENUMBER:
    1320           0 :             *va_arg(ap, uint16_t *) = td->td_pagenumber[0];
    1321           0 :             *va_arg(ap, uint16_t *) = td->td_pagenumber[1];
    1322           0 :             break;
    1323           0 :         case TIFFTAG_HALFTONEHINTS:
    1324           0 :             *va_arg(ap, uint16_t *) = td->td_halftonehints[0];
    1325           0 :             *va_arg(ap, uint16_t *) = td->td_halftonehints[1];
    1326           0 :             break;
    1327         146 :         case TIFFTAG_COLORMAP:
    1328         146 :             *va_arg(ap, const uint16_t **) = td->td_colormap[0];
    1329         146 :             *va_arg(ap, const uint16_t **) = td->td_colormap[1];
    1330         146 :             *va_arg(ap, const uint16_t **) = td->td_colormap[2];
    1331         146 :             break;
    1332      123722 :         case TIFFTAG_STRIPOFFSETS:
    1333             :         case TIFFTAG_TILEOFFSETS:
    1334      123722 :             _TIFFFillStriles(tif);
    1335      123724 :             *va_arg(ap, const uint64_t **) = td->td_stripoffset_p;
    1336      123722 :             if (td->td_stripoffset_p == NULL)
    1337           0 :                 ret_val = 0;
    1338      123722 :             break;
    1339      131697 :         case TIFFTAG_STRIPBYTECOUNTS:
    1340             :         case TIFFTAG_TILEBYTECOUNTS:
    1341      131697 :             _TIFFFillStriles(tif);
    1342      131697 :             *va_arg(ap, const uint64_t **) = td->td_stripbytecount_p;
    1343      131698 :             if (td->td_stripbytecount_p == NULL)
    1344           0 :                 ret_val = 0;
    1345      131698 :             break;
    1346           0 :         case TIFFTAG_MATTEING:
    1347           0 :             *va_arg(ap, uint16_t *) =
    1348           0 :                 (td->td_extrasamples == 1 &&
    1349           0 :                  td->td_sampleinfo[0] == EXTRASAMPLE_ASSOCALPHA);
    1350           0 :             break;
    1351      599437 :         case TIFFTAG_EXTRASAMPLES:
    1352      599437 :             *va_arg(ap, uint16_t *) = td->td_extrasamples;
    1353      599437 :             *va_arg(ap, const uint16_t **) = td->td_sampleinfo;
    1354      599437 :             break;
    1355        3573 :         case TIFFTAG_TILEWIDTH:
    1356        3573 :             *va_arg(ap, uint32_t *) = td->td_tilewidth;
    1357        3573 :             break;
    1358        3573 :         case TIFFTAG_TILELENGTH:
    1359        3573 :             *va_arg(ap, uint32_t *) = td->td_tilelength;
    1360        3573 :             break;
    1361           0 :         case TIFFTAG_TILEDEPTH:
    1362           0 :             *va_arg(ap, uint32_t *) = td->td_tiledepth;
    1363           0 :             break;
    1364           0 :         case TIFFTAG_DATATYPE:
    1365           0 :             switch (td->td_sampleformat)
    1366             :             {
    1367           0 :                 case SAMPLEFORMAT_UINT:
    1368           0 :                     *va_arg(ap, uint16_t *) = DATATYPE_UINT;
    1369           0 :                     break;
    1370           0 :                 case SAMPLEFORMAT_INT:
    1371           0 :                     *va_arg(ap, uint16_t *) = DATATYPE_INT;
    1372           0 :                     break;
    1373           0 :                 case SAMPLEFORMAT_IEEEFP:
    1374           0 :                     *va_arg(ap, uint16_t *) = DATATYPE_IEEEFP;
    1375           0 :                     break;
    1376           0 :                 case SAMPLEFORMAT_VOID:
    1377           0 :                     *va_arg(ap, uint16_t *) = DATATYPE_VOID;
    1378           0 :                     break;
    1379             :             }
    1380           0 :             break;
    1381       21343 :         case TIFFTAG_SAMPLEFORMAT:
    1382       21343 :             *va_arg(ap, uint16_t *) = td->td_sampleformat;
    1383       21332 :             break;
    1384           0 :         case TIFFTAG_IMAGEDEPTH:
    1385           0 :             *va_arg(ap, uint32_t *) = td->td_imagedepth;
    1386           0 :             break;
    1387          16 :         case TIFFTAG_SUBIFD:
    1388          16 :             *va_arg(ap, uint16_t *) = td->td_nsubifd;
    1389          16 :             *va_arg(ap, const uint64_t **) = td->td_subifd;
    1390          16 :             break;
    1391           0 :         case TIFFTAG_YCBCRPOSITIONING:
    1392           0 :             *va_arg(ap, uint16_t *) = td->td_ycbcrpositioning;
    1393           0 :             break;
    1394        3671 :         case TIFFTAG_YCBCRSUBSAMPLING:
    1395        3671 :             *va_arg(ap, uint16_t *) = td->td_ycbcrsubsampling[0];
    1396        3671 :             *va_arg(ap, uint16_t *) = td->td_ycbcrsubsampling[1];
    1397        3676 :             break;
    1398           6 :         case TIFFTAG_TRANSFERFUNCTION:
    1399           6 :             *va_arg(ap, const uint16_t **) = td->td_transferfunction[0];
    1400           6 :             if (td->td_samplesperpixel - td->td_extrasamples > 1)
    1401             :             {
    1402           6 :                 *va_arg(ap, const uint16_t **) = td->td_transferfunction[1];
    1403           6 :                 *va_arg(ap, const uint16_t **) = td->td_transferfunction[2];
    1404             :             }
    1405             :             else
    1406             :             {
    1407           0 :                 *va_arg(ap, const uint16_t **) = NULL;
    1408           0 :                 *va_arg(ap, const uint16_t **) = NULL;
    1409             :             }
    1410           6 :             break;
    1411         771 :         case TIFFTAG_REFERENCEBLACKWHITE:
    1412         771 :             *va_arg(ap, const float **) = td->td_refblackwhite;
    1413         771 :             break;
    1414           0 :         case TIFFTAG_INKNAMES:
    1415           0 :             *va_arg(ap, const char **) = td->td_inknames;
    1416           0 :             break;
    1417           0 :         case TIFFTAG_NUMBEROFINKS:
    1418           0 :             *va_arg(ap, uint16_t *) = td->td_numberofinks;
    1419           0 :             break;
    1420      271265 :         default:
    1421             :         {
    1422             :             int i;
    1423             : 
    1424             :             /*
    1425             :              * This can happen if multiple images are open
    1426             :              * with different codecs which have private
    1427             :              * tags.  The global tag information table may
    1428             :              * then have tags that are valid for one file
    1429             :              * but not the other. If the client tries to
    1430             :              * get a tag that is not valid for the image's
    1431             :              * codec then we'll arrive here.
    1432             :              */
    1433      271265 :             if (fip->field_bit != FIELD_CUSTOM)
    1434             :             {
    1435           0 :                 TIFFErrorExtR(tif, "_TIFFVGetField",
    1436             :                               "%s: Invalid %stag \"%s\" "
    1437             :                               "(not supported by codec)",
    1438             :                               tif->tif_name, isPseudoTag(tag) ? "pseudo-" : "",
    1439             :                               fip->field_name);
    1440           0 :                 ret_val = 0;
    1441           0 :                 break;
    1442             :             }
    1443             : 
    1444             :             /*
    1445             :              * Do we have a custom value?
    1446             :              */
    1447      271265 :             ret_val = 0;
    1448     1120220 :             for (i = 0; i < td->td_customValueCount; i++)
    1449             :             {
    1450      903034 :                 TIFFTagValue *tv = td->td_customValues + i;
    1451             : 
    1452      903034 :                 if (tv->info->field_tag != tag)
    1453      848953 :                     continue;
    1454             : 
    1455       54081 :                 if (fip->field_passcount)
    1456             :                 {
    1457       38432 :                     if (fip->field_readcount == TIFF_VARIABLE2)
    1458         392 :                         *va_arg(ap, uint32_t *) = (uint32_t)tv->count;
    1459             :                     else /* Assume TIFF_VARIABLE */
    1460       38040 :                         *va_arg(ap, uint16_t *) = (uint16_t)tv->count;
    1461       38432 :                     *va_arg(ap, const void **) = tv->value;
    1462       38432 :                     ret_val = 1;
    1463             :                 }
    1464       15649 :                 else if (fip->field_tag == TIFFTAG_DOTRANGE &&
    1465           0 :                          strcmp(fip->field_name, "DotRange") == 0)
    1466             :                 {
    1467             :                     /* TODO: This is an evil exception and should not have been
    1468             :                        handled this way ... likely best if we move it into
    1469             :                        the directory structure with an explicit field in
    1470             :                        libtiff 4.1 and assign it a FIELD_ value */
    1471           0 :                     *va_arg(ap, uint16_t *) = ((uint16_t *)tv->value)[0];
    1472           0 :                     *va_arg(ap, uint16_t *) = ((uint16_t *)tv->value)[1];
    1473           0 :                     ret_val = 1;
    1474             :                 }
    1475             :                 else
    1476             :                 {
    1477       15649 :                     if (fip->field_type == TIFF_ASCII ||
    1478          39 :                         fip->field_readcount == TIFF_VARIABLE ||
    1479          39 :                         fip->field_readcount == TIFF_VARIABLE2 ||
    1480          39 :                         fip->field_readcount == TIFF_SPP || tv->count > 1)
    1481             :                     {
    1482       15643 :                         *va_arg(ap, void **) = tv->value;
    1483       15643 :                         ret_val = 1;
    1484             :                     }
    1485             :                     else
    1486             :                     {
    1487           6 :                         char *val = (char *)tv->value;
    1488           6 :                         assert(tv->count == 1);
    1489           6 :                         switch (fip->field_type)
    1490             :                         {
    1491           0 :                             case TIFF_BYTE:
    1492             :                             case TIFF_UNDEFINED:
    1493           0 :                                 *va_arg(ap, uint8_t *) = *(uint8_t *)val;
    1494           0 :                                 ret_val = 1;
    1495           0 :                                 break;
    1496           0 :                             case TIFF_SBYTE:
    1497           0 :                                 *va_arg(ap, int8_t *) = *(int8_t *)val;
    1498           0 :                                 ret_val = 1;
    1499           0 :                                 break;
    1500           0 :                             case TIFF_SHORT:
    1501           0 :                                 *va_arg(ap, uint16_t *) = *(uint16_t *)val;
    1502           0 :                                 ret_val = 1;
    1503           0 :                                 break;
    1504           0 :                             case TIFF_SSHORT:
    1505           0 :                                 *va_arg(ap, int16_t *) = *(int16_t *)val;
    1506           0 :                                 ret_val = 1;
    1507           0 :                                 break;
    1508           0 :                             case TIFF_LONG:
    1509             :                             case TIFF_IFD:
    1510           0 :                                 *va_arg(ap, uint32_t *) = *(uint32_t *)val;
    1511           0 :                                 ret_val = 1;
    1512           0 :                                 break;
    1513           0 :                             case TIFF_SLONG:
    1514           0 :                                 *va_arg(ap, int32_t *) = *(int32_t *)val;
    1515           0 :                                 ret_val = 1;
    1516           0 :                                 break;
    1517           6 :                             case TIFF_LONG8:
    1518             :                             case TIFF_IFD8:
    1519           6 :                                 *va_arg(ap, uint64_t *) = *(uint64_t *)val;
    1520           6 :                                 ret_val = 1;
    1521           6 :                                 break;
    1522           0 :                             case TIFF_SLONG8:
    1523           0 :                                 *va_arg(ap, int64_t *) = *(int64_t *)val;
    1524           0 :                                 ret_val = 1;
    1525           0 :                                 break;
    1526           0 :                             case TIFF_RATIONAL:
    1527             :                             case TIFF_SRATIONAL:
    1528             :                             {
    1529             :                                 /*-- Rational2Double: For Rationals evaluate
    1530             :                                  * "set_field_type" to determine internal
    1531             :                                  * storage size and return value size. */
    1532           0 :                                 int tv_size = TIFFFieldSetGetSize(fip);
    1533           0 :                                 if (tv_size == 8)
    1534             :                                 {
    1535           0 :                                     *va_arg(ap, double *) = *(double *)val;
    1536           0 :                                     ret_val = 1;
    1537             :                                 }
    1538             :                                 else
    1539             :                                 {
    1540             :                                     /*-- default should be tv_size == 4  */
    1541           0 :                                     *va_arg(ap, float *) = *(float *)val;
    1542           0 :                                     ret_val = 1;
    1543             :                                     /*-- ToDo: After Testing, this should be
    1544             :                                      * removed and tv_size==4 should be set as
    1545             :                                      * default. */
    1546           0 :                                     if (tv_size != 4)
    1547             :                                     {
    1548           0 :                                         TIFFErrorExtR(
    1549             :                                             tif, "_TIFFVGetField",
    1550             :                                             "Rational2Double: .set_field_type "
    1551             :                                             "in not 4 but %d",
    1552             :                                             tv_size);
    1553             :                                     }
    1554             :                                 }
    1555             :                             }
    1556           0 :                             break;
    1557           0 :                             case TIFF_FLOAT:
    1558           0 :                                 *va_arg(ap, float *) = *(float *)val;
    1559           0 :                                 ret_val = 1;
    1560           0 :                                 break;
    1561           0 :                             case TIFF_DOUBLE:
    1562           0 :                                 *va_arg(ap, double *) = *(double *)val;
    1563           0 :                                 ret_val = 1;
    1564           0 :                                 break;
    1565           0 :                             default:
    1566           0 :                                 ret_val = 0;
    1567           0 :                                 break;
    1568             :                         }
    1569             :                     }
    1570             :                 }
    1571       54081 :                 break;
    1572             :             }
    1573             :         }
    1574             :     }
    1575     1378110 :     return (ret_val);
    1576             : }
    1577             : 
    1578             : /*
    1579             :  * Return the value of a field in the
    1580             :  * internal directory structure.
    1581             :  */
    1582     1677650 : int TIFFGetField(TIFF *tif, uint32_t tag, ...)
    1583             : {
    1584             :     int status;
    1585             :     va_list ap;
    1586             : 
    1587     1677650 :     va_start(ap, tag);
    1588     1677650 :     status = TIFFVGetField(tif, tag, ap);
    1589     1677490 :     va_end(ap);
    1590     1677490 :     return (status);
    1591             : }
    1592             : 
    1593             : /*
    1594             :  * Like TIFFGetField, but taking a varargs
    1595             :  * parameter list.  This routine is useful
    1596             :  * for building higher-level interfaces on
    1597             :  * top of the library.
    1598             :  */
    1599     1689420 : int TIFFVGetField(TIFF *tif, uint32_t tag, va_list ap)
    1600             : {
    1601     1689420 :     const TIFFField *fip = TIFFFindField(tif, tag, TIFF_ANY);
    1602     1689570 :     return (fip && (isPseudoTag(tag) || TIFFFieldSet(tif, fip->field_bit))
    1603     1408280 :                 ? (*tif->tif_tagmethods.vgetfield)(tif, tag, ap)
    1604     3378910 :                 : 0);
    1605             : }
    1606             : 
    1607             : #define CleanupField(member)                                                   \
    1608             :     {                                                                          \
    1609             :         if (td->member)                                                        \
    1610             :         {                                                                      \
    1611             :             _TIFFfreeExt(tif, td->member);                                     \
    1612             :             td->member = 0;                                                    \
    1613             :         }                                                                      \
    1614             :     }
    1615             : 
    1616             : /*
    1617             :  * Release storage associated with a directory.
    1618             :  */
    1619      169346 : void TIFFFreeDirectory(TIFF *tif)
    1620             : {
    1621      169346 :     TIFFDirectory *td = &tif->tif_dir;
    1622             :     int i;
    1623             : 
    1624      169346 :     _TIFFmemset(td->td_fieldsset, 0, sizeof(td->td_fieldsset));
    1625      169325 :     CleanupField(td_sminsamplevalue);
    1626      169310 :     CleanupField(td_smaxsamplevalue);
    1627      169310 :     CleanupField(td_colormap[0]);
    1628      169310 :     CleanupField(td_colormap[1]);
    1629      169310 :     CleanupField(td_colormap[2]);
    1630      169310 :     CleanupField(td_sampleinfo);
    1631      169310 :     CleanupField(td_subifd);
    1632      169310 :     CleanupField(td_inknames);
    1633      169310 :     CleanupField(td_refblackwhite);
    1634      169310 :     CleanupField(td_transferfunction[0]);
    1635      169310 :     CleanupField(td_transferfunction[1]);
    1636      169310 :     CleanupField(td_transferfunction[2]);
    1637      169310 :     CleanupField(td_stripoffset_p);
    1638      169323 :     CleanupField(td_stripbytecount_p);
    1639      169329 :     td->td_stripoffsetbyteallocsize = 0;
    1640      169329 :     TIFFClrFieldBit(tif, FIELD_YCBCRSUBSAMPLING);
    1641      169329 :     TIFFClrFieldBit(tif, FIELD_YCBCRPOSITIONING);
    1642             : 
    1643             :     /* Cleanup custom tag values */
    1644      271208 :     for (i = 0; i < td->td_customValueCount; i++)
    1645             :     {
    1646      101879 :         if (td->td_customValues[i].value)
    1647      101879 :             _TIFFfreeExt(tif, td->td_customValues[i].value);
    1648             :     }
    1649             : 
    1650      169329 :     td->td_customValueCount = 0;
    1651      169329 :     CleanupField(td_customValues);
    1652             : 
    1653      169329 :     _TIFFmemset(&(td->td_stripoffset_entry), 0, sizeof(TIFFDirEntry));
    1654      169303 :     _TIFFmemset(&(td->td_stripbytecount_entry), 0, sizeof(TIFFDirEntry));
    1655             : 
    1656             :     /* Reset some internal parameters for IFD data size checking. */
    1657      169302 :     tif->tif_dir.td_dirdatasize_read = 0;
    1658      169302 :     tif->tif_dir.td_dirdatasize_write = 0;
    1659      169302 :     if (tif->tif_dir.td_dirdatasize_offsets != NULL)
    1660             :     {
    1661       37261 :         _TIFFfreeExt(tif, tif->tif_dir.td_dirdatasize_offsets);
    1662       37267 :         tif->tif_dir.td_dirdatasize_offsets = NULL;
    1663       37267 :         tif->tif_dir.td_dirdatasize_Noffsets = 0;
    1664             :     }
    1665      169308 : }
    1666             : #undef CleanupField
    1667             : 
    1668             : /*
    1669             :  * Client Tag extension support (from Niles Ritter).
    1670             :  */
    1671             : static TIFFExtendProc _TIFFextender = (TIFFExtendProc)NULL;
    1672             : 
    1673        1108 : TIFFExtendProc TIFFSetTagExtender(TIFFExtendProc extender)
    1674             : {
    1675        1108 :     TIFFExtendProc prev = _TIFFextender;
    1676        1108 :     _TIFFextender = extender;
    1677        1108 :     return (prev);
    1678             : }
    1679             : 
    1680             : /*
    1681             :  * Setup for a new directory.  Should we automatically call
    1682             :  * TIFFWriteDirectory() if the current one is dirty?
    1683             :  *
    1684             :  * The newly created directory will not exist on the file till
    1685             :  * TIFFWriteDirectory(), TIFFFlush() or TIFFClose() is called.
    1686             :  */
    1687       37806 : int TIFFCreateDirectory(TIFF *tif)
    1688             : {
    1689             :     /* Free previously allocated memory and setup default values. */
    1690       37806 :     TIFFFreeDirectory(tif);
    1691       37798 :     TIFFDefaultDirectory(tif);
    1692       37810 :     tif->tif_diroff = 0;
    1693       37810 :     tif->tif_nextdiroff = 0;
    1694       37810 :     tif->tif_curoff = 0;
    1695       37810 :     tif->tif_row = (uint32_t)-1;
    1696       37810 :     tif->tif_curstrip = (uint32_t)-1;
    1697             : 
    1698       37810 :     return 0;
    1699             : }
    1700             : 
    1701           0 : int TIFFCreateCustomDirectory(TIFF *tif, const TIFFFieldArray *infoarray)
    1702             : {
    1703             :     /* Free previously allocated memory and setup default values. */
    1704           0 :     TIFFFreeDirectory(tif);
    1705           0 :     TIFFDefaultDirectory(tif);
    1706             : 
    1707             :     /*
    1708             :      * Reset the field definitions to match the application provided list.
    1709             :      * Hopefully TIFFDefaultDirectory() won't have done anything irreversible
    1710             :      * based on it's assumption this is an image directory.
    1711             :      */
    1712           0 :     _TIFFSetupFields(tif, infoarray);
    1713             : 
    1714           0 :     tif->tif_diroff = 0;
    1715           0 :     tif->tif_nextdiroff = 0;
    1716           0 :     tif->tif_curoff = 0;
    1717           0 :     tif->tif_row = (uint32_t)-1;
    1718           0 :     tif->tif_curstrip = (uint32_t)-1;
    1719             :     /* invalidate directory index */
    1720           0 :     tif->tif_curdir = TIFF_NON_EXISTENT_DIR_NUMBER;
    1721             :     /* invalidate IFD loop lists */
    1722           0 :     _TIFFCleanupIFDOffsetAndNumberMaps(tif);
    1723             :     /* To be able to return from SubIFD or custom-IFD to main-IFD */
    1724           0 :     tif->tif_setdirectory_force_absolute = TRUE;
    1725             : 
    1726           0 :     return 0;
    1727             : }
    1728             : 
    1729           0 : int TIFFCreateEXIFDirectory(TIFF *tif)
    1730             : {
    1731             :     const TIFFFieldArray *exifFieldArray;
    1732           0 :     exifFieldArray = _TIFFGetExifFields();
    1733           0 :     return TIFFCreateCustomDirectory(tif, exifFieldArray);
    1734             : }
    1735             : 
    1736             : /*
    1737             :  * Creates the EXIF GPS custom directory
    1738             :  */
    1739           0 : int TIFFCreateGPSDirectory(TIFF *tif)
    1740             : {
    1741             :     const TIFFFieldArray *gpsFieldArray;
    1742           0 :     gpsFieldArray = _TIFFGetGpsFields();
    1743           0 :     return TIFFCreateCustomDirectory(tif, gpsFieldArray);
    1744             : }
    1745             : 
    1746             : /*
    1747             :  * Setup a default directory structure.
    1748             :  */
    1749      110042 : int TIFFDefaultDirectory(TIFF *tif)
    1750             : {
    1751      110042 :     register TIFFDirectory *td = &tif->tif_dir;
    1752             :     const TIFFFieldArray *tiffFieldArray;
    1753             : 
    1754      110042 :     tiffFieldArray = _TIFFGetFields();
    1755      110025 :     _TIFFSetupFields(tif, tiffFieldArray);
    1756             : 
    1757      110062 :     _TIFFmemset(td, 0, sizeof(*td));
    1758      110061 :     td->td_fillorder = FILLORDER_MSB2LSB;
    1759      110061 :     td->td_bitspersample = 1;
    1760      110061 :     td->td_threshholding = THRESHHOLD_BILEVEL;
    1761      110061 :     td->td_orientation = ORIENTATION_TOPLEFT;
    1762      110061 :     td->td_samplesperpixel = 1;
    1763      110061 :     td->td_rowsperstrip = (uint32_t)-1;
    1764      110061 :     td->td_tilewidth = 0;
    1765      110061 :     td->td_tilelength = 0;
    1766      110061 :     td->td_tiledepth = 1;
    1767             : #ifdef STRIPBYTECOUNTSORTED_UNUSED
    1768             :     td->td_stripbytecountsorted = 1; /* Our own arrays always sorted. */
    1769             : #endif
    1770      110061 :     td->td_resolutionunit = RESUNIT_INCH;
    1771      110061 :     td->td_sampleformat = SAMPLEFORMAT_UINT;
    1772      110061 :     td->td_imagedepth = 1;
    1773      110061 :     td->td_ycbcrsubsampling[0] = 2;
    1774      110061 :     td->td_ycbcrsubsampling[1] = 2;
    1775      110061 :     td->td_ycbcrpositioning = YCBCRPOSITION_CENTERED;
    1776      110061 :     tif->tif_postdecode = _TIFFNoPostDecode;
    1777      110061 :     tif->tif_foundfield = NULL;
    1778      110061 :     tif->tif_tagmethods.vsetfield = _TIFFVSetField;
    1779      110061 :     tif->tif_tagmethods.vgetfield = _TIFFVGetField;
    1780      110061 :     tif->tif_tagmethods.printdir = NULL;
    1781             :     /* additional default values */
    1782      110061 :     td->td_planarconfig = PLANARCONFIG_CONTIG;
    1783      110061 :     td->td_compression = COMPRESSION_NONE;
    1784      110061 :     td->td_subfiletype = 0;
    1785      110061 :     td->td_minsamplevalue = 0;
    1786             :     /* td_bitspersample=1 is always set in TIFFDefaultDirectory().
    1787             :      * Therefore, td_maxsamplevalue has to be re-calculated in
    1788             :      * TIFFGetFieldDefaulted(). */
    1789      110061 :     td->td_maxsamplevalue = 1; /* Default for td_bitspersample=1 */
    1790      110061 :     td->td_extrasamples = 0;
    1791      110061 :     td->td_sampleinfo = NULL;
    1792             : 
    1793             :     /*
    1794             :      *  Give client code a chance to install their own
    1795             :      *  tag extensions & methods, prior to compression overloads,
    1796             :      *  but do some prior cleanup first.
    1797             :      * (http://trac.osgeo.org/gdal/ticket/5054)
    1798             :      */
    1799      110061 :     if (tif->tif_nfieldscompat > 0)
    1800             :     {
    1801             :         uint32_t i;
    1802             : 
    1803      160805 :         for (i = 0; i < tif->tif_nfieldscompat; i++)
    1804             :         {
    1805      107201 :             if (tif->tif_fieldscompat[i].allocated_size)
    1806      107202 :                 _TIFFfreeExt(tif, tif->tif_fieldscompat[i].fields);
    1807             :         }
    1808       53604 :         _TIFFfreeExt(tif, tif->tif_fieldscompat);
    1809       53602 :         tif->tif_nfieldscompat = 0;
    1810       53602 :         tif->tif_fieldscompat = NULL;
    1811             :     }
    1812      110061 :     if (_TIFFextender)
    1813      110058 :         (*_TIFFextender)(tif);
    1814      110070 :     (void)TIFFSetField(tif, TIFFTAG_COMPRESSION, COMPRESSION_NONE);
    1815             :     /*
    1816             :      * NB: The directory is marked dirty as a result of setting
    1817             :      * up the default compression scheme.  However, this really
    1818             :      * isn't correct -- we want TIFF_DIRTYDIRECT to be set only
    1819             :      * if the user does something.  We could just do the setup
    1820             :      * by hand, but it seems better to use the normal mechanism
    1821             :      * (i.e. TIFFSetField).
    1822             :      */
    1823      110041 :     tif->tif_flags &= ~TIFF_DIRTYDIRECT;
    1824             : 
    1825             :     /*
    1826             :      * As per http://bugzilla.remotesensing.org/show_bug.cgi?id=19
    1827             :      * we clear the ISTILED flag when setting up a new directory.
    1828             :      * Should we also be clearing stuff like INSUBIFD?
    1829             :      */
    1830      110041 :     tif->tif_flags &= ~TIFF_ISTILED;
    1831             : 
    1832      110041 :     return (1);
    1833             : }
    1834             : 
    1835       11644 : static int TIFFAdvanceDirectory(TIFF *tif, uint64_t *nextdiroff, uint64_t *off,
    1836             :                                 tdir_t *nextdirnum)
    1837             : {
    1838             :     static const char module[] = "TIFFAdvanceDirectory";
    1839             : 
    1840             :     /* Add this directory to the directory list, if not already in. */
    1841       11644 :     if (!_TIFFCheckDirNumberAndOffset(tif, *nextdirnum, *nextdiroff))
    1842             :     {
    1843           0 :         TIFFErrorExtR(tif, module,
    1844             :                       "Starting directory %u at offset 0x%" PRIx64 " (%" PRIu64
    1845             :                       ") might cause an IFD loop",
    1846             :                       *nextdirnum, *nextdiroff, *nextdiroff);
    1847           0 :         *nextdiroff = 0;
    1848           0 :         *nextdirnum = 0;
    1849           0 :         return (0);
    1850             :     }
    1851             : 
    1852       11644 :     if (isMapped(tif))
    1853             :     {
    1854           0 :         uint64_t poff = *nextdiroff;
    1855           0 :         if (!(tif->tif_flags & TIFF_BIGTIFF))
    1856             :         {
    1857             :             tmsize_t poffa, poffb, poffc, poffd;
    1858             :             uint16_t dircount;
    1859             :             uint32_t nextdir32;
    1860           0 :             poffa = (tmsize_t)poff;
    1861           0 :             poffb = poffa + sizeof(uint16_t);
    1862           0 :             if (((uint64_t)poffa != poff) || (poffb < poffa) ||
    1863           0 :                 (poffb < (tmsize_t)sizeof(uint16_t)) || (poffb > tif->tif_size))
    1864             :             {
    1865           0 :                 TIFFErrorExtR(tif, module, "Error fetching directory count");
    1866           0 :                 *nextdiroff = 0;
    1867           0 :                 return (0);
    1868             :             }
    1869           0 :             _TIFFmemcpy(&dircount, tif->tif_base + poffa, sizeof(uint16_t));
    1870           0 :             if (tif->tif_flags & TIFF_SWAB)
    1871           0 :                 TIFFSwabShort(&dircount);
    1872           0 :             poffc = poffb + dircount * 12;
    1873           0 :             poffd = poffc + sizeof(uint32_t);
    1874           0 :             if ((poffc < poffb) || (poffc < dircount * 12) || (poffd < poffc) ||
    1875           0 :                 (poffd < (tmsize_t)sizeof(uint32_t)) || (poffd > tif->tif_size))
    1876             :             {
    1877           0 :                 TIFFErrorExtR(tif, module, "Error fetching directory link");
    1878           0 :                 return (0);
    1879             :             }
    1880           0 :             if (off != NULL)
    1881           0 :                 *off = (uint64_t)poffc;
    1882           0 :             _TIFFmemcpy(&nextdir32, tif->tif_base + poffc, sizeof(uint32_t));
    1883           0 :             if (tif->tif_flags & TIFF_SWAB)
    1884           0 :                 TIFFSwabLong(&nextdir32);
    1885           0 :             *nextdiroff = nextdir32;
    1886             :         }
    1887             :         else
    1888             :         {
    1889             :             tmsize_t poffa, poffb, poffc, poffd;
    1890             :             uint64_t dircount64;
    1891             :             uint16_t dircount16;
    1892           0 :             if (poff > (uint64_t)TIFF_TMSIZE_T_MAX - sizeof(uint64_t))
    1893             :             {
    1894           0 :                 TIFFErrorExtR(tif, module, "Error fetching directory count");
    1895           0 :                 return (0);
    1896             :             }
    1897           0 :             poffa = (tmsize_t)poff;
    1898           0 :             poffb = poffa + sizeof(uint64_t);
    1899           0 :             if (poffb > tif->tif_size)
    1900             :             {
    1901           0 :                 TIFFErrorExtR(tif, module, "Error fetching directory count");
    1902           0 :                 return (0);
    1903             :             }
    1904           0 :             _TIFFmemcpy(&dircount64, tif->tif_base + poffa, sizeof(uint64_t));
    1905           0 :             if (tif->tif_flags & TIFF_SWAB)
    1906           0 :                 TIFFSwabLong8(&dircount64);
    1907           0 :             if (dircount64 > 0xFFFF)
    1908             :             {
    1909           0 :                 TIFFErrorExtR(tif, module,
    1910             :                               "Sanity check on directory count failed");
    1911           0 :                 return (0);
    1912             :             }
    1913           0 :             dircount16 = (uint16_t)dircount64;
    1914           0 :             if (poffb > TIFF_TMSIZE_T_MAX - (tmsize_t)(dircount16 * 20) -
    1915             :                             (tmsize_t)sizeof(uint64_t))
    1916             :             {
    1917           0 :                 TIFFErrorExtR(tif, module, "Error fetching directory link");
    1918           0 :                 return (0);
    1919             :             }
    1920           0 :             poffc = poffb + dircount16 * 20;
    1921           0 :             poffd = poffc + sizeof(uint64_t);
    1922           0 :             if (poffd > tif->tif_size)
    1923             :             {
    1924           0 :                 TIFFErrorExtR(tif, module, "Error fetching directory link");
    1925           0 :                 return (0);
    1926             :             }
    1927           0 :             if (off != NULL)
    1928           0 :                 *off = (uint64_t)poffc;
    1929           0 :             _TIFFmemcpy(nextdiroff, tif->tif_base + poffc, sizeof(uint64_t));
    1930           0 :             if (tif->tif_flags & TIFF_SWAB)
    1931           0 :                 TIFFSwabLong8(nextdiroff);
    1932             :         }
    1933             :     }
    1934             :     else
    1935             :     {
    1936       11644 :         if (!(tif->tif_flags & TIFF_BIGTIFF))
    1937             :         {
    1938             :             uint16_t dircount;
    1939             :             uint32_t nextdir32;
    1940       21724 :             if (!SeekOK(tif, *nextdiroff) ||
    1941       10862 :                 !ReadOK(tif, &dircount, sizeof(uint16_t)))
    1942             :             {
    1943           6 :                 TIFFErrorExtR(tif, module, "%s: Error fetching directory count",
    1944             :                               tif->tif_name);
    1945           6 :                 return (0);
    1946             :             }
    1947       10856 :             if (tif->tif_flags & TIFF_SWAB)
    1948         275 :                 TIFFSwabShort(&dircount);
    1949       10856 :             if (off != NULL)
    1950           7 :                 *off = TIFFSeekFile(tif, dircount * 12, SEEK_CUR);
    1951             :             else
    1952       10849 :                 (void)TIFFSeekFile(tif, dircount * 12, SEEK_CUR);
    1953       10856 :             if (!ReadOK(tif, &nextdir32, sizeof(uint32_t)))
    1954             :             {
    1955           0 :                 TIFFErrorExtR(tif, module, "%s: Error fetching directory link",
    1956             :                               tif->tif_name);
    1957           0 :                 return (0);
    1958             :             }
    1959       10856 :             if (tif->tif_flags & TIFF_SWAB)
    1960         275 :                 TIFFSwabLong(&nextdir32);
    1961       10856 :             *nextdiroff = nextdir32;
    1962             :         }
    1963             :         else
    1964             :         {
    1965             :             uint64_t dircount64;
    1966             :             uint16_t dircount16;
    1967        1564 :             if (!SeekOK(tif, *nextdiroff) ||
    1968         782 :                 !ReadOK(tif, &dircount64, sizeof(uint64_t)))
    1969             :             {
    1970           0 :                 TIFFErrorExtR(tif, module, "%s: Error fetching directory count",
    1971             :                               tif->tif_name);
    1972           0 :                 return (0);
    1973             :             }
    1974         782 :             if (tif->tif_flags & TIFF_SWAB)
    1975           4 :                 TIFFSwabLong8(&dircount64);
    1976         782 :             if (dircount64 > 0xFFFF)
    1977             :             {
    1978           0 :                 TIFFErrorExtR(tif, module, "Error fetching directory count");
    1979           0 :                 return (0);
    1980             :             }
    1981         782 :             dircount16 = (uint16_t)dircount64;
    1982         782 :             if (off != NULL)
    1983           0 :                 *off = TIFFSeekFile(tif, dircount16 * 20, SEEK_CUR);
    1984             :             else
    1985         782 :                 (void)TIFFSeekFile(tif, dircount16 * 20, SEEK_CUR);
    1986         782 :             if (!ReadOK(tif, nextdiroff, sizeof(uint64_t)))
    1987             :             {
    1988           0 :                 TIFFErrorExtR(tif, module, "%s: Error fetching directory link",
    1989             :                               tif->tif_name);
    1990           0 :                 return (0);
    1991             :             }
    1992         782 :             if (tif->tif_flags & TIFF_SWAB)
    1993           4 :                 TIFFSwabLong8(nextdiroff);
    1994             :         }
    1995             :     }
    1996       11638 :     if (*nextdiroff != 0)
    1997             :     {
    1998        4970 :         (*nextdirnum)++;
    1999             :         /* Check next directory for IFD looping and if so, set it as last
    2000             :          * directory. */
    2001        4970 :         if (!_TIFFCheckDirNumberAndOffset(tif, *nextdirnum, *nextdiroff))
    2002             :         {
    2003           0 :             TIFFWarningExtR(
    2004             :                 tif, module,
    2005             :                 "the next directory %u at offset 0x%" PRIx64 " (%" PRIu64
    2006             :                 ") might be an IFD loop. Treating directory %d as "
    2007             :                 "last directory",
    2008           0 :                 *nextdirnum, *nextdiroff, *nextdiroff, (int)(*nextdirnum) - 1);
    2009           0 :             *nextdiroff = 0;
    2010           0 :             (*nextdirnum)--;
    2011             :         }
    2012             :     }
    2013       11638 :     return (1);
    2014             : }
    2015             : 
    2016             : /*
    2017             :  * Count the number of directories in a file.
    2018             :  */
    2019        6670 : tdir_t TIFFNumberOfDirectories(TIFF *tif)
    2020             : {
    2021             :     uint64_t nextdiroff;
    2022             :     tdir_t nextdirnum;
    2023             :     tdir_t n;
    2024        6670 :     if (!(tif->tif_flags & TIFF_BIGTIFF))
    2025        6410 :         nextdiroff = tif->tif_header.classic.tiff_diroff;
    2026             :     else
    2027         260 :         nextdiroff = tif->tif_header.big.tiff_diroff;
    2028        6670 :     nextdirnum = 0;
    2029        6670 :     n = 0;
    2030       29930 :     while (nextdiroff != 0 &&
    2031       11633 :            TIFFAdvanceDirectory(tif, &nextdiroff, NULL, &nextdirnum))
    2032             :     {
    2033       11627 :         ++n;
    2034             :     }
    2035        6670 :     return (n);
    2036             : }
    2037             : 
    2038             : /*
    2039             :  * Set the n-th directory as the current directory.
    2040             :  * NB: Directories are numbered starting at 0.
    2041             :  */
    2042        6930 : int TIFFSetDirectory(TIFF *tif, tdir_t dirn)
    2043             : {
    2044             :     uint64_t nextdiroff;
    2045        6930 :     tdir_t nextdirnum = 0;
    2046             :     tdir_t n;
    2047             : 
    2048        6930 :     if (tif->tif_setdirectory_force_absolute)
    2049             :     {
    2050             :         /* tif_setdirectory_force_absolute=1 will force parsing the main IFD
    2051             :          * chain from the beginning, thus IFD directory list needs to be cleared
    2052             :          * from possible SubIFD offsets.
    2053             :          */
    2054           0 :         _TIFFCleanupIFDOffsetAndNumberMaps(tif); /* invalidate IFD loop lists */
    2055             :     }
    2056             : 
    2057             :     /* Even faster path, if offset is available within IFD loop hash list. */
    2058       13860 :     if (!tif->tif_setdirectory_force_absolute &&
    2059        6930 :         _TIFFGetOffsetFromDirNumber(tif, dirn, &nextdiroff))
    2060             :     {
    2061             :         /* Set parameters for following TIFFReadDirectory() below. */
    2062        4948 :         tif->tif_nextdiroff = nextdiroff;
    2063        4948 :         tif->tif_curdir = dirn;
    2064             :         /* Reset to relative stepping */
    2065        4948 :         tif->tif_setdirectory_force_absolute = FALSE;
    2066             :     }
    2067             :     else
    2068             :     {
    2069             : 
    2070             :         /* Fast path when we just advance relative to the current directory:
    2071             :          * start at the current dir offset and continue to seek from there.
    2072             :          * Check special cases when relative is not allowed:
    2073             :          * - jump back from SubIFD or custom directory
    2074             :          * - right after TIFFWriteDirectory() jump back to that directory
    2075             :          *   using TIFFSetDirectory() */
    2076        5946 :         const int relative = (dirn >= tif->tif_curdir) &&
    2077        1982 :                              (tif->tif_diroff != 0) &&
    2078           0 :                              !tif->tif_setdirectory_force_absolute;
    2079             : 
    2080        1982 :         if (relative)
    2081             :         {
    2082           0 :             nextdiroff = tif->tif_diroff;
    2083           0 :             dirn -= tif->tif_curdir;
    2084           0 :             nextdirnum = tif->tif_curdir;
    2085             :         }
    2086        1982 :         else if (!(tif->tif_flags & TIFF_BIGTIFF))
    2087        1981 :             nextdiroff = tif->tif_header.classic.tiff_diroff;
    2088             :         else
    2089           1 :             nextdiroff = tif->tif_header.big.tiff_diroff;
    2090             : 
    2091             :         /* Reset to relative stepping */
    2092        1982 :         tif->tif_setdirectory_force_absolute = FALSE;
    2093             : 
    2094        1982 :         for (n = dirn; n > 0 && nextdiroff != 0; n--)
    2095           0 :             if (!TIFFAdvanceDirectory(tif, &nextdiroff, NULL, &nextdirnum))
    2096           0 :                 return (0);
    2097             :         /* If the n-th directory could not be reached (does not exist),
    2098             :          * return here without touching anything further. */
    2099        1982 :         if (nextdiroff == 0 || n > 0)
    2100           0 :             return (0);
    2101             : 
    2102        1982 :         tif->tif_nextdiroff = nextdiroff;
    2103             : 
    2104             :         /* Set curdir to the actual directory index. */
    2105        1982 :         if (relative)
    2106           0 :             tif->tif_curdir += dirn - n;
    2107             :         else
    2108        1982 :             tif->tif_curdir = dirn - n;
    2109             :     }
    2110             : 
    2111             :     /* The -1 decrement is because TIFFReadDirectory will increment
    2112             :      * tif_curdir after successfully reading the directory. */
    2113        6930 :     if (tif->tif_curdir == 0)
    2114        6255 :         tif->tif_curdir = TIFF_NON_EXISTENT_DIR_NUMBER;
    2115             :     else
    2116         675 :         tif->tif_curdir--;
    2117        6930 :     return (TIFFReadDirectory(tif));
    2118             : }
    2119             : 
    2120             : /*
    2121             :  * Set the current directory to be the directory
    2122             :  * located at the specified file offset.  This interface
    2123             :  * is used mainly to access directories linked with
    2124             :  * the SubIFD tag (e.g. thumbnail images).
    2125             :  */
    2126       13860 : int TIFFSetSubDirectory(TIFF *tif, uint64_t diroff)
    2127             : {
    2128             :     /* Match nextdiroff and curdir for consistent IFD-loop checking.
    2129             :      * Only with TIFFSetSubDirectory() the IFD list can be corrupted with
    2130             :      * invalid offsets within the main IFD tree. In the case of several subIFDs
    2131             :      * of a main image, there are two possibilities that are not even mutually
    2132             :      * exclusive. a.) The subIFD tag contains an array with all offsets of the
    2133             :      * subIFDs. b.) The SubIFDs are concatenated with their NextIFD parameters.
    2134             :      * (refer to
    2135             :      * https://www.awaresystems.be/imaging/tiff/specification/TIFFPM6.pdf.)
    2136             :      */
    2137             :     int retval;
    2138       13860 :     uint32_t curdir = 0;
    2139       13860 :     int8_t probablySubIFD = 0;
    2140       13860 :     if (diroff == 0)
    2141             :     {
    2142             :         /* Special case to invalidate the tif_lastdiroff member. */
    2143        5935 :         tif->tif_curdir = TIFF_NON_EXISTENT_DIR_NUMBER;
    2144             :     }
    2145             :     else
    2146             :     {
    2147        7925 :         if (!_TIFFGetDirNumberFromOffset(tif, diroff, &curdir))
    2148             :         {
    2149             :             /* Non-existing offsets might point to a SubIFD or invalid IFD.*/
    2150          43 :             probablySubIFD = 1;
    2151             :         }
    2152             :         /* -1 because TIFFReadDirectory() will increment tif_curdir. */
    2153        7925 :         tif->tif_curdir =
    2154        7925 :             curdir == 0 ? TIFF_NON_EXISTENT_DIR_NUMBER : curdir - 1;
    2155             :     }
    2156             : 
    2157       13860 :     tif->tif_nextdiroff = diroff;
    2158       13860 :     retval = TIFFReadDirectory(tif);
    2159             :     /* If failed, curdir was not incremented in TIFFReadDirectory(), so set it
    2160             :      * back, but leave it for diroff==0. */
    2161       13860 :     if (!retval && diroff != 0)
    2162             :     {
    2163           0 :         if (tif->tif_curdir == TIFF_NON_EXISTENT_DIR_NUMBER)
    2164           0 :             tif->tif_curdir = 0;
    2165             :         else
    2166           0 :             tif->tif_curdir++;
    2167             :     }
    2168       13860 :     if (probablySubIFD)
    2169             :     {
    2170          43 :         if (retval)
    2171             :         {
    2172             :             /* Reset IFD list to start new one for SubIFD chain and also start
    2173             :              * SubIFD chain with tif_curdir=0. */
    2174             :             /* invalidate IFD loop lists */
    2175          43 :             _TIFFCleanupIFDOffsetAndNumberMaps(tif);
    2176          43 :             tif->tif_curdir = 0; /* first directory of new chain */
    2177             :             /* add this offset to new IFD list */
    2178          43 :             _TIFFCheckDirNumberAndOffset(tif, tif->tif_curdir, diroff);
    2179             :         }
    2180             :         /* To be able to return from SubIFD or custom-IFD to main-IFD */
    2181          43 :         tif->tif_setdirectory_force_absolute = TRUE;
    2182             :     }
    2183             : 
    2184       13860 :     return (retval);
    2185             : }
    2186             : 
    2187             : /*
    2188             :  * Return file offset of the current directory.
    2189             :  */
    2190       88014 : uint64_t TIFFCurrentDirOffset(TIFF *tif) { return (tif->tif_diroff); }
    2191             : 
    2192             : /*
    2193             :  * Return an indication of whether or not we are
    2194             :  * at the last directory in the file.
    2195             :  */
    2196        6521 : int TIFFLastDirectory(TIFF *tif) { return (tif->tif_nextdiroff == 0); }
    2197             : 
    2198             : /*
    2199             :  * Unlink the specified directory from the directory chain.
    2200             :  * Note: First directory starts with number dirn=1.
    2201             :  * This is different to TIFFSetDirectory() where the first directory starts with
    2202             :  * zero.
    2203             :  */
    2204           4 : int TIFFUnlinkDirectory(TIFF *tif, tdir_t dirn)
    2205             : {
    2206             :     static const char module[] = "TIFFUnlinkDirectory";
    2207             :     uint64_t nextdir;
    2208             :     tdir_t nextdirnum;
    2209             :     uint64_t off;
    2210             :     tdir_t n;
    2211             : 
    2212           4 :     if (tif->tif_mode == O_RDONLY)
    2213             :     {
    2214           0 :         TIFFErrorExtR(tif, module,
    2215             :                       "Can not unlink directory in read-only file");
    2216           0 :         return (0);
    2217             :     }
    2218           4 :     if (dirn == 0)
    2219             :     {
    2220           0 :         TIFFErrorExtR(tif, module,
    2221             :                       "For TIFFUnlinkDirectory() first directory starts with "
    2222             :                       "number 1 and not 0");
    2223           0 :         return (0);
    2224             :     }
    2225             :     /*
    2226             :      * Go to the directory before the one we want
    2227             :      * to unlink and nab the offset of the link
    2228             :      * field we'll need to patch.
    2229             :      */
    2230           4 :     if (!(tif->tif_flags & TIFF_BIGTIFF))
    2231             :     {
    2232           4 :         nextdir = tif->tif_header.classic.tiff_diroff;
    2233           4 :         off = 4;
    2234             :     }
    2235             :     else
    2236             :     {
    2237           0 :         nextdir = tif->tif_header.big.tiff_diroff;
    2238           0 :         off = 8;
    2239             :     }
    2240           4 :     nextdirnum = 0; /* First directory is dirn=0 */
    2241             : 
    2242          11 :     for (n = dirn - 1; n > 0; n--)
    2243             :     {
    2244           7 :         if (nextdir == 0)
    2245             :         {
    2246           0 :             TIFFErrorExtR(tif, module, "Directory %u does not exist", dirn);
    2247           0 :             return (0);
    2248             :         }
    2249           7 :         if (!TIFFAdvanceDirectory(tif, &nextdir, &off, &nextdirnum))
    2250           0 :             return (0);
    2251             :     }
    2252             :     /*
    2253             :      * Advance to the directory to be unlinked and fetch
    2254             :      * the offset of the directory that follows.
    2255             :      */
    2256           4 :     if (!TIFFAdvanceDirectory(tif, &nextdir, NULL, &nextdirnum))
    2257           0 :         return (0);
    2258             :     /*
    2259             :      * Go back and patch the link field of the preceding
    2260             :      * directory to point to the offset of the directory
    2261             :      * that follows.
    2262             :      */
    2263           4 :     (void)TIFFSeekFile(tif, off, SEEK_SET);
    2264           4 :     if (!(tif->tif_flags & TIFF_BIGTIFF))
    2265             :     {
    2266             :         uint32_t nextdir32;
    2267           4 :         nextdir32 = (uint32_t)nextdir;
    2268           4 :         assert((uint64_t)nextdir32 == nextdir);
    2269           4 :         if (tif->tif_flags & TIFF_SWAB)
    2270           0 :             TIFFSwabLong(&nextdir32);
    2271           4 :         if (!WriteOK(tif, &nextdir32, sizeof(uint32_t)))
    2272             :         {
    2273           0 :             TIFFErrorExtR(tif, module, "Error writing directory link");
    2274           0 :             return (0);
    2275             :         }
    2276             :     }
    2277             :     else
    2278             :     {
    2279             :         /* Need local swap because nextdir has to be used unswapped below. */
    2280           0 :         uint64_t nextdir64 = nextdir;
    2281           0 :         if (tif->tif_flags & TIFF_SWAB)
    2282           0 :             TIFFSwabLong8(&nextdir64);
    2283           0 :         if (!WriteOK(tif, &nextdir64, sizeof(uint64_t)))
    2284             :         {
    2285           0 :             TIFFErrorExtR(tif, module, "Error writing directory link");
    2286           0 :             return (0);
    2287             :         }
    2288             :     }
    2289             : 
    2290             :     /* For dirn=1 (first directory) also update the libtiff internal
    2291             :      * base offset variables. */
    2292           4 :     if (dirn == 1)
    2293             :     {
    2294           0 :         if (!(tif->tif_flags & TIFF_BIGTIFF))
    2295           0 :             tif->tif_header.classic.tiff_diroff = (uint32_t)nextdir;
    2296             :         else
    2297           0 :             tif->tif_header.big.tiff_diroff = nextdir;
    2298             :     }
    2299             : 
    2300             :     /*
    2301             :      * Leave directory state setup safely.  We don't have
    2302             :      * facilities for doing inserting and removing directories,
    2303             :      * so it's safest to just invalidate everything.  This
    2304             :      * means that the caller can only append to the directory
    2305             :      * chain.
    2306             :      */
    2307           4 :     (*tif->tif_cleanup)(tif);
    2308           4 :     if ((tif->tif_flags & TIFF_MYBUFFER) && tif->tif_rawdata)
    2309             :     {
    2310           0 :         _TIFFfreeExt(tif, tif->tif_rawdata);
    2311           0 :         tif->tif_rawdata = NULL;
    2312           0 :         tif->tif_rawcc = 0;
    2313           0 :         tif->tif_rawdataoff = 0;
    2314           0 :         tif->tif_rawdataloaded = 0;
    2315             :     }
    2316           4 :     tif->tif_flags &= ~(TIFF_BEENWRITING | TIFF_BUFFERSETUP | TIFF_POSTENCODE |
    2317             :                         TIFF_BUF4WRITE);
    2318           4 :     TIFFFreeDirectory(tif);
    2319           4 :     TIFFDefaultDirectory(tif);
    2320           4 :     tif->tif_diroff = 0;     /* force link on next write */
    2321           4 :     tif->tif_nextdiroff = 0; /* next write must be at end */
    2322           4 :     tif->tif_lastdiroff = 0; /* will be updated on next link */
    2323           4 :     tif->tif_curoff = 0;
    2324           4 :     tif->tif_row = (uint32_t)-1;
    2325           4 :     tif->tif_curstrip = (uint32_t)-1;
    2326           4 :     tif->tif_curdir = TIFF_NON_EXISTENT_DIR_NUMBER;
    2327           4 :     _TIFFCleanupIFDOffsetAndNumberMaps(tif); /* invalidate IFD loop lists */
    2328           4 :     return (1);
    2329             : }

Generated by: LCOV version 1.14