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

Generated by: LCOV version 1.14