LCOV - code coverage report
Current view: top level - frmts/gtiff/libtiff - tif_dir.c (source / functions) Hit Total Coverage
Test: gdal_filtered.info Lines: 682 1278 53.4 %
Date: 2026-06-28 22:25:56 Functions: 26 39 66.7 %

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

Generated by: LCOV version 1.14