LCOV - code coverage report
Current view: directory - frmts/gtiff/libtiff - tif_dir.c (source / functions) Found Hit Coverage
Test: gdal_filtered.info Lines: 831 444 53.4 %
Date: 2011-12-18 Functions: 31 24 77.4 %

       1                 : /* $Id: tif_dir.c,v 1.107 2011-02-18 20:53:04 fwarmerdam Exp $ */
       2                 : 
       3                 : /*
       4                 :  * Copyright (c) 1988-1997 Sam Leffler
       5                 :  * Copyright (c) 1991-1997 Silicon Graphics, Inc.
       6                 :  *
       7                 :  * Permission to use, copy, modify, distribute, and sell this software and 
       8                 :  * its documentation for any purpose is hereby granted without fee, provided
       9                 :  * that (i) the above copyright notices and this permission notice appear in
      10                 :  * all copies of the software and related documentation, and (ii) the names of
      11                 :  * Sam Leffler and Silicon Graphics may not be used in any advertising or
      12                 :  * publicity relating to the software without the specific, prior written
      13                 :  * permission of Sam Leffler and Silicon Graphics.
      14                 :  * 
      15                 :  * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, 
      16                 :  * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY 
      17                 :  * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.  
      18                 :  * 
      19                 :  * IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR
      20                 :  * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND,
      21                 :  * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
      22                 :  * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF 
      23                 :  * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE 
      24                 :  * OF THIS SOFTWARE.
      25                 :  */
      26                 : 
      27                 : /*
      28                 :  * TIFF Library.
      29                 :  *
      30                 :  * Directory Tag Get & Set Routines.
      31                 :  * (and also some miscellaneous stuff)
      32                 :  */
      33                 : #include "tiffiop.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                 : static void
      44            6980 : setByteArray(void** vpp, void* vp, size_t nmemb, size_t elem_size)
      45                 : {
      46            6980 :   if (*vpp)
      47              15 :     _TIFFfree(*vpp), *vpp = 0;
      48            6980 :   if (vp) {
      49            6980 :     tmsize_t bytes = (tmsize_t)(nmemb * elem_size);
      50            6980 :     if (elem_size && bytes / elem_size == nmemb)
      51            6980 :       *vpp = (void*) _TIFFmalloc(bytes);
      52            6980 :     if (*vpp)
      53            6980 :       _TIFFmemcpy(*vpp, vp, bytes);
      54                 :   }
      55            6980 : }
      56             223 : void _TIFFsetByteArray(void** vpp, void* vp, uint32 n)
      57             223 :     { setByteArray(vpp, vp, n, 1); }
      58               0 : void _TIFFsetString(char** cpp, char* cp)
      59               0 :     { setByteArray((void**) cpp, (void*) cp, strlen(cp)+1, 1); }
      60               0 : void _TIFFsetNString(char** cpp, char* cp, uint32 n)
      61               0 :     { setByteArray((void**) cpp, (void*) cp, n, 1); }
      62            1139 : void _TIFFsetShortArray(uint16** wpp, uint16* wp, uint32 n)
      63            1139 :     { setByteArray((void**) wpp, (void*) wp, n, sizeof (uint16)); }
      64               0 : void _TIFFsetLongArray(uint32** lpp, uint32* lp, uint32 n)
      65               0 :     { setByteArray((void**) lpp, (void*) lp, n, sizeof (uint32)); }
      66               0 : void _TIFFsetLong8Array(uint64** lpp, uint64* lp, uint32 n)
      67               0 :     { setByteArray((void**) lpp, (void*) lp, n, sizeof (uint64)); }
      68             212 : void _TIFFsetFloatArray(float** fpp, float* fp, uint32 n)
      69             212 :     { setByteArray((void**) fpp, (void*) fp, n, sizeof (float)); }
      70               0 : void _TIFFsetDoubleArray(double** dpp, double* dp, uint32 n)
      71               0 :     { setByteArray((void**) dpp, (void*) dp, n, sizeof (double)); }
      72                 : 
      73                 : static void
      74               0 : setDoubleArrayOneValue(double** vpp, double value, size_t nmemb)
      75                 : {
      76               0 :   if (*vpp)
      77               0 :     _TIFFfree(*vpp);
      78               0 :   *vpp = _TIFFmalloc(nmemb*sizeof(double));
      79               0 :   if (*vpp)
      80                 :   {
      81               0 :     while (nmemb--)
      82               0 :       ((double*)*vpp)[nmemb] = value;
      83                 :   }
      84               0 : }
      85                 : 
      86                 : /*
      87                 :  * Install extra samples information.
      88                 :  */
      89                 : static int
      90             581 : setExtraSamples(TIFFDirectory* td, va_list ap, uint32* v)
      91                 : {
      92                 : /* XXX: Unassociated alpha data == 999 is a known Corel Draw bug, see below */
      93                 : #define EXTRASAMPLE_COREL_UNASSALPHA 999 
      94                 : 
      95                 :   uint16* va;
      96                 :   uint32 i;
      97                 : 
      98             581 :   *v = (uint16) va_arg(ap, uint16_vap);
      99             581 :   if ((uint16) *v > td->td_samplesperpixel)
     100               0 :     return 0;
     101             581 :   va = va_arg(ap, uint16*);
     102             581 :   if (*v > 0 && va == NULL)    /* typically missing param */
     103               0 :     return 0;
     104          525654 :   for (i = 0; i < *v; i++) {
     105          525073 :     if (va[i] > EXTRASAMPLE_UNASSALPHA) {
     106                 :       /*
     107                 :        * XXX: Corel Draw is known to produce incorrect
     108                 :        * ExtraSamples tags which must be patched here if we
     109                 :        * want to be able to open some of the damaged TIFF
     110                 :        * files: 
     111                 :        */
     112               0 :       if (va[i] == EXTRASAMPLE_COREL_UNASSALPHA)
     113               0 :         va[i] = EXTRASAMPLE_UNASSALPHA;
     114                 :       else
     115               0 :         return 0;
     116                 :     }
     117                 :   }
     118             581 :   td->td_extrasamples = (uint16) *v;
     119             581 :   _TIFFsetShortArray(&td->td_sampleinfo, va, td->td_extrasamples);
     120             581 :   return 1;
     121                 : 
     122                 : #undef EXTRASAMPLE_COREL_UNASSALPHA
     123                 : }
     124                 : 
     125                 : static uint32
     126               0 : checkInkNamesString(TIFF* tif, uint32 slen, const char* s)
     127                 : {
     128               0 :   TIFFDirectory* td = &tif->tif_dir;
     129               0 :   uint16 i = td->td_samplesperpixel;
     130                 : 
     131               0 :   if (slen > 0) {
     132               0 :     const char* ep = s+slen;
     133               0 :     const char* cp = s;
     134               0 :     for (; i > 0; i--) {
     135               0 :       for (; *cp != '\0'; cp++)
     136               0 :         if (cp >= ep)
     137               0 :           goto bad;
     138               0 :       cp++;       /* skip \0 */
     139                 :     }
     140               0 :     return ((uint32)(cp-s));
     141                 :   }
     142                 : bad:
     143               0 :   TIFFErrorExt(tif->tif_clientdata, "TIFFSetField",
     144                 :       "%s: Invalid InkNames value; expecting %d names, found %d",
     145                 :       tif->tif_name,
     146               0 :       td->td_samplesperpixel,
     147                 :       td->td_samplesperpixel-i);
     148               0 :   return (0);
     149                 : }
     150                 : 
     151                 : static int
     152          119066 : _TIFFVSetField(TIFF* tif, uint32 tag, va_list ap)
     153                 : {
     154                 :   static const char module[] = "_TIFFVSetField";
     155                 : 
     156          119066 :   TIFFDirectory* td = &tif->tif_dir;
     157          119066 :   int status = 1;
     158                 :   uint32 v32, i, v;
     159                 :   char* s;
     160                 : 
     161          119066 :   switch (tag) {
     162                 :   case TIFFTAG_SUBFILETYPE:
     163            2285 :     td->td_subfiletype = (uint32) va_arg(ap, uint32);
     164            2285 :     break;
     165                 :   case TIFFTAG_IMAGEWIDTH:
     166            8308 :     td->td_imagewidth = (uint32) va_arg(ap, uint32);
     167            8308 :     break;
     168                 :   case TIFFTAG_IMAGELENGTH:
     169            8308 :     td->td_imagelength = (uint32) va_arg(ap, uint32);
     170            8308 :     break;
     171                 :   case TIFFTAG_BITSPERSAMPLE:
     172            8304 :     td->td_bitspersample = (uint16) va_arg(ap, uint16_vap);
     173                 :     /*
     174                 :      * If the data require post-decoding processing to byte-swap
     175                 :      * samples, set it up here.  Note that since tags are required
     176                 :      * to be ordered, compression code can override this behaviour
     177                 :      * in the setup method if it wants to roll the post decoding
     178                 :      * work in with its normal work.
     179                 :      */
     180            8304 :     if (tif->tif_flags & TIFF_SWAB) {
     181             343 :       if (td->td_bitspersample == 8)
     182             273 :         tif->tif_postdecode = _TIFFNoPostDecode;
     183              70 :       else if (td->td_bitspersample == 16)
     184              24 :         tif->tif_postdecode = _TIFFSwab16BitData;
     185              46 :       else if (td->td_bitspersample == 24)
     186               0 :         tif->tif_postdecode = _TIFFSwab24BitData;
     187              46 :       else if (td->td_bitspersample == 32)
     188              46 :         tif->tif_postdecode = _TIFFSwab32BitData;
     189               0 :       else if (td->td_bitspersample == 64)
     190               0 :         tif->tif_postdecode = _TIFFSwab64BitData;
     191               0 :       else if (td->td_bitspersample == 128) /* two 64's */
     192               0 :         tif->tif_postdecode = _TIFFSwab64BitData;
     193                 :     }
     194            8304 :     break;
     195                 :   case TIFFTAG_COMPRESSION:
     196           18216 :     v = (uint16) va_arg(ap, uint16_vap);
     197                 :     /*
     198                 :      * If we're changing the compression scheme, the notify the
     199                 :      * previous module so that it can cleanup any state it's
     200                 :      * setup.
     201                 :      */
     202           18216 :     if (TIFFFieldSet(tif, FIELD_COMPRESSION)) {
     203            8279 :       if ((uint32)td->td_compression == v)
     204            7157 :         break;
     205            1122 :       (*tif->tif_cleanup)(tif);
     206            1122 :       tif->tif_flags &= ~TIFF_CODERSETUP;
     207                 :     }
     208                 :     /*
     209                 :      * Setup new compression routine state.
     210                 :      */
     211           11059 :     if( (status = TIFFSetCompressionScheme(tif, v)) != 0 )
     212           11059 :         td->td_compression = (uint16) v;
     213                 :     else
     214               0 :         status = 0;
     215           11059 :     break;
     216                 :   case TIFFTAG_PHOTOMETRIC:
     217            8306 :     td->td_photometric = (uint16) va_arg(ap, uint16_vap);
     218            8306 :     break;
     219                 :   case TIFFTAG_THRESHHOLDING:
     220               0 :     td->td_threshholding = (uint16) va_arg(ap, uint16_vap);
     221               0 :     break;
     222                 :   case TIFFTAG_FILLORDER:
     223               4 :     v = (uint16) va_arg(ap, uint16_vap);
     224               4 :     if (v != FILLORDER_LSB2MSB && v != FILLORDER_MSB2LSB)
     225               0 :       goto badvalue;
     226               4 :     td->td_fillorder = (uint16) v;
     227               4 :     break;
     228                 :   case TIFFTAG_ORIENTATION:
     229              54 :     v = (uint16) va_arg(ap, uint16_vap);
     230              54 :     if (v < ORIENTATION_TOPLEFT || ORIENTATION_LEFTBOT < v)
     231                 :       goto badvalue;
     232                 :     else
     233              54 :       td->td_orientation = (uint16) v;
     234              54 :     break;
     235                 :   case TIFFTAG_SAMPLESPERPIXEL:
     236            8304 :     v = (uint16) va_arg(ap, uint16_vap);
     237            8304 :     if (v == 0)
     238               0 :       goto badvalue;
     239            8304 :     td->td_samplesperpixel = (uint16) v;
     240            8304 :     break;
     241                 :   case TIFFTAG_ROWSPERSTRIP:
     242            6010 :     v32 = (uint32) va_arg(ap, uint32);
     243            6010 :     if (v32 == 0)
     244               0 :       goto badvalue32;
     245            6010 :     td->td_rowsperstrip = v32;
     246            6010 :     if (!TIFFFieldSet(tif, FIELD_TILEDIMENSIONS)) {
     247            6010 :       td->td_tilelength = v32;
     248            6010 :       td->td_tilewidth = td->td_imagewidth;
     249                 :     }
     250            6010 :     break;
     251                 :   case TIFFTAG_MINSAMPLEVALUE:
     252               0 :     td->td_minsamplevalue = (uint16) va_arg(ap, uint16_vap);
     253               0 :     break;
     254                 :   case TIFFTAG_MAXSAMPLEVALUE:
     255               0 :     td->td_maxsamplevalue = (uint16) va_arg(ap, uint16_vap);
     256               0 :     break;
     257                 :   case TIFFTAG_SMINSAMPLEVALUE:
     258               0 :     if (tif->tif_flags & TIFF_PERSAMPLE)
     259               0 :       _TIFFsetDoubleArray(&td->td_sminsamplevalue, va_arg(ap, double*), td->td_samplesperpixel);
     260                 :     else
     261               0 :       setDoubleArrayOneValue(&td->td_sminsamplevalue, va_arg(ap, double), td->td_samplesperpixel);
     262               0 :     break;
     263                 :   case TIFFTAG_SMAXSAMPLEVALUE:
     264               0 :     if (tif->tif_flags & TIFF_PERSAMPLE)
     265               0 :       _TIFFsetDoubleArray(&td->td_smaxsamplevalue, va_arg(ap, double*), td->td_samplesperpixel);
     266                 :     else
     267               0 :       setDoubleArrayOneValue(&td->td_smaxsamplevalue, va_arg(ap, double), td->td_samplesperpixel);
     268               0 :     break;
     269                 :   case TIFFTAG_XRESOLUTION:
     270              52 :     td->td_xresolution = (float) va_arg(ap, double);
     271              52 :     break;
     272                 :   case TIFFTAG_YRESOLUTION:
     273              52 :     td->td_yresolution = (float) va_arg(ap, double);
     274              52 :     break;
     275                 :   case TIFFTAG_PLANARCONFIG:
     276           15182 :     v = (uint16) va_arg(ap, uint16_vap);
     277           15182 :     if (v != PLANARCONFIG_CONTIG && v != PLANARCONFIG_SEPARATE)
     278               0 :       goto badvalue;
     279           15182 :     td->td_planarconfig = (uint16) v;
     280           15182 :     break;
     281                 :   case TIFFTAG_XPOSITION:
     282               0 :     td->td_xposition = (float) va_arg(ap, double);
     283               0 :     break;
     284                 :   case TIFFTAG_YPOSITION:
     285               0 :     td->td_yposition = (float) va_arg(ap, double);
     286               0 :     break;
     287                 :   case TIFFTAG_RESOLUTIONUNIT:
     288              52 :     v = (uint16) va_arg(ap, uint16_vap);
     289              52 :     if (v < RESUNIT_NONE || RESUNIT_CENTIMETER < v)
     290                 :       goto badvalue;
     291              52 :     td->td_resolutionunit = (uint16) v;
     292              52 :     break;
     293                 :   case TIFFTAG_PAGENUMBER:
     294               0 :     td->td_pagenumber[0] = (uint16) va_arg(ap, uint16_vap);
     295               0 :     td->td_pagenumber[1] = (uint16) va_arg(ap, uint16_vap);
     296               0 :     break;
     297                 :   case TIFFTAG_HALFTONEHINTS:
     298               0 :     td->td_halftonehints[0] = (uint16) va_arg(ap, uint16_vap);
     299               0 :     td->td_halftonehints[1] = (uint16) va_arg(ap, uint16_vap);
     300               0 :     break;
     301                 :   case TIFFTAG_COLORMAP:
     302             186 :     v32 = (uint32)(1L<<td->td_bitspersample);
     303             186 :     _TIFFsetShortArray(&td->td_colormap[0], va_arg(ap, uint16*), v32);
     304             186 :     _TIFFsetShortArray(&td->td_colormap[1], va_arg(ap, uint16*), v32);
     305             186 :     _TIFFsetShortArray(&td->td_colormap[2], va_arg(ap, uint16*), v32);
     306             186 :     break;
     307                 :   case TIFFTAG_EXTRASAMPLES:
     308             581 :     if (!setExtraSamples(td, ap, &v))
     309               0 :       goto badvalue;
     310             581 :     break;
     311                 :   case TIFFTAG_MATTEING:
     312               0 :     td->td_extrasamples =  (((uint16) va_arg(ap, uint16_vap)) != 0);
     313               0 :     if (td->td_extrasamples) {
     314               0 :       uint16 sv = EXTRASAMPLE_ASSOCALPHA;
     315               0 :       _TIFFsetShortArray(&td->td_sampleinfo, &sv, 1);
     316                 :     }
     317               0 :     break;
     318                 :   case TIFFTAG_TILEWIDTH:
     319            2286 :     v32 = (uint32) va_arg(ap, uint32);
     320            2286 :     if (v32 % 16) {
     321               0 :       if (tif->tif_mode != O_RDONLY)
     322               0 :         goto badvalue32;
     323               0 :       TIFFWarningExt(tif->tif_clientdata, tif->tif_name,
     324                 :         "Nonstandard tile width %d, convert file", v32);
     325                 :     }
     326            2286 :     td->td_tilewidth = v32;
     327            2286 :     tif->tif_flags |= TIFF_ISTILED;
     328            2286 :     break;
     329                 :   case TIFFTAG_TILELENGTH:
     330            2286 :     v32 = (uint32) va_arg(ap, uint32);
     331            2286 :     if (v32 % 16) {
     332               0 :       if (tif->tif_mode != O_RDONLY)
     333               0 :         goto badvalue32;
     334               0 :       TIFFWarningExt(tif->tif_clientdata, tif->tif_name,
     335                 :           "Nonstandard tile length %d, convert file", v32);
     336                 :     }
     337            2286 :     td->td_tilelength = v32;
     338            2286 :     tif->tif_flags |= TIFF_ISTILED;
     339            2286 :     break;
     340                 :   case TIFFTAG_TILEDEPTH:
     341               0 :     v32 = (uint32) va_arg(ap, uint32);
     342               0 :     if (v32 == 0)
     343               0 :       goto badvalue32;
     344               0 :     td->td_tiledepth = v32;
     345               0 :     break;
     346                 :   case TIFFTAG_DATATYPE:
     347               0 :     v = (uint16) va_arg(ap, uint16_vap);
     348               0 :     switch (v) {
     349               0 :     case DATATYPE_VOID: v = SAMPLEFORMAT_VOID;  break;
     350               0 :     case DATATYPE_INT:  v = SAMPLEFORMAT_INT; break;
     351               0 :     case DATATYPE_UINT: v = SAMPLEFORMAT_UINT;  break;
     352               0 :     case DATATYPE_IEEEFP: v = SAMPLEFORMAT_IEEEFP;break;
     353               0 :     default:    goto badvalue;
     354                 :     }
     355               0 :     td->td_sampleformat = (uint16) v;
     356               0 :     break;
     357                 :   case TIFFTAG_SAMPLEFORMAT:
     358            8189 :     v = (uint16) va_arg(ap, uint16_vap);
     359            8189 :     if (v < SAMPLEFORMAT_UINT || SAMPLEFORMAT_COMPLEXIEEEFP < v)
     360                 :       goto badvalue;
     361            8189 :     td->td_sampleformat = (uint16) v;
     362                 : 
     363                 :     /*  Try to fix up the SWAB function for complex data. */
     364            8914 :     if( td->td_sampleformat == SAMPLEFORMAT_COMPLEXINT
     365            8189 :         && td->td_bitspersample == 32
     366             725 :         && tif->tif_postdecode == _TIFFSwab32BitData )
     367               0 :         tif->tif_postdecode = _TIFFSwab16BitData;
     368           17386 :     else if( (td->td_sampleformat == SAMPLEFORMAT_COMPLEXINT
     369           15895 :         || td->td_sampleformat == SAMPLEFORMAT_COMPLEXIEEEFP)
     370                 :        && td->td_bitspersample == 64
     371            1491 :        && tif->tif_postdecode == _TIFFSwab64BitData )
     372               0 :         tif->tif_postdecode = _TIFFSwab32BitData;
     373            8189 :     break;
     374                 :   case TIFFTAG_IMAGEDEPTH:
     375               0 :     td->td_imagedepth = (uint32) va_arg(ap, uint32);
     376               0 :     break;
     377                 :   case TIFFTAG_SUBIFD:
     378               0 :     if ((tif->tif_flags & TIFF_INSUBIFD) == 0) {
     379               0 :       td->td_nsubifd = (uint16) va_arg(ap, uint16_vap);
     380               0 :       _TIFFsetLong8Array(&td->td_subifd, (uint64*) va_arg(ap, uint64*),
     381                 :           (long) td->td_nsubifd);
     382                 :     } else {
     383               0 :       TIFFErrorExt(tif->tif_clientdata, module,
     384                 :              "%s: Sorry, cannot nest SubIFDs",
     385                 :              tif->tif_name);
     386               0 :       status = 0;
     387                 :     }
     388               0 :     break;
     389                 :   case TIFFTAG_YCBCRPOSITIONING:
     390               0 :     td->td_ycbcrpositioning = (uint16) va_arg(ap, uint16_vap);
     391               0 :     break;
     392                 :   case TIFFTAG_YCBCRSUBSAMPLING:
     393               1 :     td->td_ycbcrsubsampling[0] = (uint16) va_arg(ap, uint16_vap);
     394               1 :     td->td_ycbcrsubsampling[1] = (uint16) va_arg(ap, uint16_vap);
     395               1 :     break;
     396                 :   case TIFFTAG_TRANSFERFUNCTION:
     397               0 :     v = (td->td_samplesperpixel - td->td_extrasamples) > 1 ? 3 : 1;
     398               0 :     for (i = 0; i < v; i++)
     399               0 :       _TIFFsetShortArray(&td->td_transferfunction[i],
     400               0 :           va_arg(ap, uint16*), 1L<<td->td_bitspersample);
     401               0 :     break;
     402                 :   case TIFFTAG_REFERENCEBLACKWHITE:
     403                 :     /* XXX should check for null range */
     404             212 :     _TIFFsetFloatArray(&td->td_refblackwhite, va_arg(ap, float*), 6);
     405             212 :     break;
     406                 :   case TIFFTAG_INKNAMES:
     407               0 :     v = (uint16) va_arg(ap, uint16_vap);
     408               0 :     s = va_arg(ap, char*);
     409               0 :     v = checkInkNamesString(tif, v, s);
     410               0 :     status = v > 0;
     411               0 :     if( v > 0 ) {
     412               0 :       _TIFFsetNString(&td->td_inknames, s, v);
     413               0 :       td->td_inknameslen = v;
     414                 :     }
     415               0 :     break;
     416                 :   case TIFFTAG_PERSAMPLE:
     417               0 :     v = (uint16) va_arg(ap, uint16_vap);
     418               0 :     if( v == PERSAMPLE_MULTI )
     419               0 :       tif->tif_flags |= TIFF_PERSAMPLE;
     420                 :     else
     421               0 :       tif->tif_flags &= ~TIFF_PERSAMPLE;
     422               0 :     break;
     423                 :   default: {
     424                 :     TIFFTagValue *tv;
     425                 :     int tv_size, iCustom;
     426           21888 :     const TIFFField *fip = TIFFFindField(tif, tag, TIFF_ANY);
     427                 : 
     428                 :     /*
     429                 :      * This can happen if multiple images are open with different
     430                 :      * codecs which have private tags.  The global tag information
     431                 :      * table may then have tags that are valid for one file but not
     432                 :      * the other. If the client tries to set a tag that is not valid
     433                 :      * for the image's codec then we'll arrive here.  This
     434                 :      * happens, for example, when tiffcp is used to convert between
     435                 :      * compression schemes and codec-specific tags are blindly copied.
     436                 :      */
     437           21888 :     if(fip == NULL || fip->field_bit != FIELD_CUSTOM) {
     438               0 :       TIFFErrorExt(tif->tif_clientdata, module,
     439                 :           "%s: Invalid %stag \"%s\" (not supported by codec)",
     440                 :           tif->tif_name, isPseudoTag(tag) ? "pseudo-" : "",
     441                 :           fip ? fip->field_name : "Unknown");
     442               0 :       status = 0;
     443               0 :       break;
     444                 :     }
     445                 : 
     446                 :     /*
     447                 :      * Find the existing entry for this custom value.
     448                 :      */
     449           21888 :     tv = NULL;
     450           61284 :     for (iCustom = 0; iCustom < td->td_customValueCount; iCustom++) {
     451           39453 :       if (td->td_customValues[iCustom].info->field_tag == tag) {
     452              57 :         tv = td->td_customValues + iCustom;
     453              57 :         if (tv->value != NULL) {
     454              57 :           _TIFFfree(tv->value);
     455              57 :           tv->value = NULL;
     456                 :         }
     457              57 :         break;
     458                 :       }
     459                 :     }
     460                 : 
     461                 :     /*
     462                 :      * Grow the custom list if the entry was not found.
     463                 :      */
     464           21888 :     if(tv == NULL) {
     465                 :       TIFFTagValue *new_customValues;
     466                 : 
     467           21831 :       td->td_customValueCount++;
     468           43662 :       new_customValues = (TIFFTagValue *)
     469           21831 :           _TIFFrealloc(td->td_customValues,
     470           21831 :           sizeof(TIFFTagValue) * td->td_customValueCount);
     471           21831 :       if (!new_customValues) {
     472               0 :         TIFFErrorExt(tif->tif_clientdata, module,
     473                 :             "%s: Failed to allocate space for list of custom values",
     474                 :             tif->tif_name);
     475               0 :         status = 0;
     476               0 :         goto end;
     477                 :       }
     478                 : 
     479           21831 :       td->td_customValues = new_customValues;
     480                 : 
     481           21831 :       tv = td->td_customValues + (td->td_customValueCount - 1);
     482           21831 :       tv->info = fip;
     483           21831 :       tv->value = NULL;
     484           21831 :       tv->count = 0;
     485                 :     }
     486                 : 
     487                 :     /*
     488                 :      * Set custom value ... save a copy of the custom tag value.
     489                 :      */
     490           21888 :     tv_size = _TIFFDataSize(fip->field_type);
     491           21888 :     if (tv_size == 0) {
     492               0 :       status = 0;
     493               0 :       TIFFErrorExt(tif->tif_clientdata, module,
     494                 :           "%s: Bad field type %d for \"%s\"",
     495               0 :           tif->tif_name, fip->field_type,
     496                 :           fip->field_name);
     497               0 :       goto end;
     498                 :     }
     499                 : 
     500           21888 :     if (fip->field_type == TIFF_ASCII)
     501                 :     {
     502                 :       uint32 ma;
     503                 :       char* mb;
     504            5406 :       if (fip->field_passcount)
     505                 :       {
     506               0 :         assert(fip->field_writecount==TIFF_VARIABLE2);
     507               0 :         ma=(uint32)va_arg(ap,uint32);
     508               0 :         mb=(char*)va_arg(ap,char*);
     509                 :       }
     510                 :       else
     511                 :       {
     512            5406 :         mb=(char*)va_arg(ap,char*);
     513            5406 :         ma=(uint32)(strlen(mb)+1);
     514                 :       }
     515            5406 :       tv->count=ma;
     516            5406 :       setByteArray(&tv->value,mb,ma,1);
     517                 :     }
     518                 :     else
     519                 :     {
     520           16482 :       if (fip->field_passcount) {
     521           16480 :         if (fip->field_writecount == TIFF_VARIABLE2)
     522               5 :           tv->count = (uint32) va_arg(ap, uint32);
     523                 :         else
     524           16475 :           tv->count = (int) va_arg(ap, int);
     525               4 :       } else if (fip->field_writecount == TIFF_VARIABLE
     526               4 :          || fip->field_writecount == TIFF_VARIABLE2)
     527               0 :         tv->count = 1;
     528               2 :       else if (fip->field_writecount == TIFF_SPP)
     529               0 :         tv->count = td->td_samplesperpixel;
     530                 :       else
     531               2 :         tv->count = fip->field_writecount;
     532                 : 
     533           16482 :       if (tv->count == 0) {
     534               0 :         status = 0;
     535               0 :         TIFFErrorExt(tif->tif_clientdata, module,
     536                 :                "%s: Null count for \"%s\" (type "
     537                 :                "%d, writecount %d, passcount %d)",
     538                 :                tif->tif_name,
     539                 :                fip->field_name,
     540               0 :                fip->field_type,
     541               0 :                fip->field_writecount,
     542               0 :                fip->field_passcount);
     543               0 :         goto end;
     544                 :       }
     545                 : 
     546           16482 :       tv->value = _TIFFCheckMalloc(tif, tv->count, tv_size,
     547                 :           "custom tag binary object");
     548           16482 :       if (!tv->value) {
     549               0 :         status = 0;
     550               0 :         goto end;
     551                 :       }
     552                 : 
     553           98895 :       if ((fip->field_passcount
     554           16482 :           || fip->field_writecount == TIFF_VARIABLE
     555               2 :           || fip->field_writecount == TIFF_VARIABLE2
     556               2 :           || fip->field_writecount == TIFF_SPP
     557               4 :           || tv->count > 1)
     558                 :           && fip->field_tag != TIFFTAG_PAGENUMBER
     559           16481 :           && fip->field_tag != TIFFTAG_HALFTONEHINTS
     560           16481 :           && fip->field_tag != TIFFTAG_YCBCRSUBSAMPLING
     561           32962 :           && fip->field_tag != TIFFTAG_DOTRANGE) {
     562           16481 :         _TIFFmemcpy(tv->value, va_arg(ap, void *),
     563           16481 :             tv->count * tv_size);
     564                 :       } else {
     565                 :         /*
     566                 :          * XXX: The following loop required to handle
     567                 :          * TIFFTAG_PAGENUMBER, TIFFTAG_HALFTONEHINTS,
     568                 :          * TIFFTAG_YCBCRSUBSAMPLING and TIFFTAG_DOTRANGE tags.
     569                 :          * These tags are actually arrays and should be passed as
     570                 :          * array pointers to TIFFSetField() function, but actually
     571                 :          * passed as a list of separate values. This behaviour
     572                 :          * must be changed in the future!
     573                 :          */
     574                 :         int i;
     575               1 :         char *val = (char *)tv->value;
     576                 : 
     577               2 :         for (i = 0; i < tv->count; i++, val += tv_size) {
     578               1 :           switch (fip->field_type) {
     579                 :             case TIFF_BYTE:
     580                 :             case TIFF_UNDEFINED:
     581                 :               {
     582               0 :                 uint8 v = (uint8)va_arg(ap, int);
     583               0 :                 _TIFFmemcpy(val, &v, tv_size);
     584                 :               }
     585               0 :               break;
     586                 :             case TIFF_SBYTE:
     587                 :               {
     588               0 :                 int8 v = (int8)va_arg(ap, int);
     589               0 :                 _TIFFmemcpy(val, &v, tv_size);
     590                 :               }
     591               0 :               break;
     592                 :             case TIFF_SHORT:
     593                 :               {
     594               0 :                 uint16 v = (uint16)va_arg(ap, int);
     595               0 :                 _TIFFmemcpy(val, &v, tv_size);
     596                 :               }
     597               0 :               break;
     598                 :             case TIFF_SSHORT:
     599                 :               {
     600               0 :                 int16 v = (int16)va_arg(ap, int);
     601               0 :                 _TIFFmemcpy(val, &v, tv_size);
     602                 :               }
     603               0 :               break;
     604                 :             case TIFF_LONG:
     605                 :             case TIFF_IFD:
     606                 :               {
     607               0 :                 uint32 v = va_arg(ap, uint32);
     608               0 :                 _TIFFmemcpy(val, &v, tv_size);
     609                 :               }
     610               0 :               break;
     611                 :             case TIFF_SLONG:
     612                 :               {
     613               0 :                 int32 v = va_arg(ap, int32);
     614               0 :                 _TIFFmemcpy(val, &v, tv_size);
     615                 :               }
     616               0 :               break;
     617                 :             case TIFF_LONG8:
     618                 :             case TIFF_IFD8:
     619                 :               {
     620               1 :                 uint64 v = va_arg(ap, uint64);
     621               1 :                 _TIFFmemcpy(val, &v, tv_size);
     622                 :               }
     623               1 :               break;
     624                 :             case TIFF_SLONG8:
     625                 :               {
     626               0 :                 int64 v = va_arg(ap, int64);
     627               0 :                 _TIFFmemcpy(val, &v, tv_size);
     628                 :               }
     629               0 :               break;
     630                 :             case TIFF_RATIONAL:
     631                 :             case TIFF_SRATIONAL:
     632                 :             case TIFF_FLOAT:
     633                 :               {
     634               0 :                 float v = (float)va_arg(ap, double);
     635               0 :                 _TIFFmemcpy(val, &v, tv_size);
     636                 :               }
     637               0 :               break;
     638                 :             case TIFF_DOUBLE:
     639                 :               {
     640               0 :                 double v = va_arg(ap, double);
     641               0 :                 _TIFFmemcpy(val, &v, tv_size);
     642                 :               }
     643               0 :               break;
     644                 :             default:
     645               0 :               _TIFFmemset(val, 0, tv_size);
     646               0 :               status = 0;
     647                 :               break;
     648                 :           }
     649                 :         }
     650                 :       }
     651                 :     }
     652                 :   }
     653                 :   }
     654          119066 :   if (status) {
     655          119066 :     TIFFSetFieldBit(tif, TIFFFieldWithTag(tif, tag)->field_bit);
     656          119066 :     tif->tif_flags |= TIFF_DIRTYDIRECT;
     657                 :   }
     658                 : 
     659                 : end:
     660          119066 :   va_end(ap);
     661          119066 :   return (status);
     662                 : badvalue:
     663               0 :   TIFFErrorExt(tif->tif_clientdata, module,
     664                 :          "%s: Bad value %u for \"%s\" tag",
     665                 :          tif->tif_name, v,
     666               0 :          TIFFFieldWithTag(tif, tag)->field_name);
     667               0 :   va_end(ap);
     668               0 :   return (0);
     669                 : badvalue32:
     670               0 :   TIFFErrorExt(tif->tif_clientdata, module,
     671                 :          "%s: Bad value %u for \"%s\" tag",
     672                 :          tif->tif_name, v32,
     673               0 :          TIFFFieldWithTag(tif, tag)->field_name);
     674               0 :   va_end(ap);
     675               0 :   return (0);
     676                 : }
     677                 : 
     678                 : /*
     679                 :  * Return 1/0 according to whether or not
     680                 :  * it is permissible to set the tag's value.
     681                 :  * Note that we allow ImageLength to be changed
     682                 :  * so that we can append and extend to images.
     683                 :  * Any other tag may not be altered once writing
     684                 :  * has commenced, unless its value has no effect
     685                 :  * on the format of the data that is written.
     686                 :  */
     687                 : static int
     688          120406 : OkToChangeTag(TIFF* tif, uint32 tag)
     689                 : {
     690          120406 :   const TIFFField* fip = TIFFFindField(tif, tag, TIFF_ANY);
     691          120406 :   if (!fip) {     /* unknown tag */
     692               0 :     TIFFErrorExt(tif->tif_clientdata, "TIFFSetField", "%s: Unknown %stag %u",
     693                 :         tif->tif_name, isPseudoTag(tag) ? "pseudo-" : "", tag);
     694               0 :     return (0);
     695                 :   }
     696          120456 :   if (tag != TIFFTAG_IMAGELENGTH && (tif->tif_flags & TIFF_BEENWRITING) &&
     697              50 :       !fip->field_oktochange) {
     698                 :     /*
     699                 :      * Consult info table to see if tag can be changed
     700                 :      * after we've started writing.  We only allow changes
     701                 :      * to those tags that don't/shouldn't affect the
     702                 :      * compression and/or format of the data.
     703                 :      */
     704               0 :     TIFFErrorExt(tif->tif_clientdata, "TIFFSetField",
     705                 :         "%s: Cannot modify tag \"%s\" while writing",
     706                 :         tif->tif_name, fip->field_name);
     707               0 :     return (0);
     708                 :   }
     709          120406 :   return (1);
     710                 : }
     711                 : 
     712                 : /*
     713                 :  * Record the value of a field in the
     714                 :  * internal directory structure.  The
     715                 :  * field will be written to the file
     716                 :  * when/if the directory structure is
     717                 :  * updated.
     718                 :  */
     719                 : int
     720          120406 : TIFFSetField(TIFF* tif, uint32 tag, ...)
     721                 : {
     722                 :   va_list ap;
     723                 :   int status;
     724                 : 
     725          120406 :   va_start(ap, tag);
     726          120406 :   status = TIFFVSetField(tif, tag, ap);
     727          120406 :   va_end(ap);
     728          120406 :   return (status);
     729                 : }
     730                 : 
     731                 : /*
     732                 :  * Clear the contents of the field in the internal structure.
     733                 :  */
     734                 : int
     735            2076 : TIFFUnsetField(TIFF* tif, uint32 tag)
     736                 : {
     737            2076 :     const TIFFField *fip =  TIFFFieldWithTag(tif, tag);
     738            2076 :     TIFFDirectory* td = &tif->tif_dir;
     739                 : 
     740            2076 :     if( !fip )
     741               0 :         return 0;
     742                 : 
     743            2076 :     if( fip->field_bit != FIELD_CUSTOM )
     744               1 :         TIFFClrFieldBit(tif, fip->field_bit);
     745                 :     else
     746                 :     {
     747            2075 :         TIFFTagValue *tv = NULL;
     748                 :         int i;
     749                 : 
     750            2085 :         for (i = 0; i < td->td_customValueCount; i++) {
     751                 :                 
     752              16 :             tv = td->td_customValues + i;
     753              16 :             if( tv->info->field_tag == tag )
     754               6 :                 break;
     755                 :         }
     756                 : 
     757            2075 :         if( i < td->td_customValueCount )
     758                 :         {
     759               6 :             _TIFFfree(tv->value);
     760              16 :             for( ; i < td->td_customValueCount-1; i++) {
     761              10 :                 td->td_customValues[i] = td->td_customValues[i+1];
     762                 :             }
     763               6 :             td->td_customValueCount--;
     764                 :         }
     765                 :     }
     766                 :         
     767            2076 :     tif->tif_flags |= TIFF_DIRTYDIRECT;
     768                 : 
     769            2076 :     return (1);
     770                 : }
     771                 : 
     772                 : /*
     773                 :  * Like TIFFSetField, but taking a varargs
     774                 :  * parameter list.  This routine is useful
     775                 :  * for building higher-level interfaces on
     776                 :  * top of the library.
     777                 :  */
     778                 : int
     779          120406 : TIFFVSetField(TIFF* tif, uint32 tag, va_list ap)
     780                 : {
     781          240812 :   return OkToChangeTag(tif, tag) ?
     782          120406 :       (*tif->tif_tagmethods.vsetfield)(tif, tag, ap) : 0;
     783                 : }
     784                 : 
     785                 : static int
     786          601293 : _TIFFVGetField(TIFF* tif, uint32 tag, va_list ap)
     787                 : {
     788          601293 :   TIFFDirectory* td = &tif->tif_dir;
     789          601293 :   int ret_val = 1;
     790                 : 
     791          601293 :   switch (tag) {
     792                 :     case TIFFTAG_SUBFILETYPE:
     793             277 :       *va_arg(ap, uint32*) = td->td_subfiletype;
     794             277 :       break;
     795                 :     case TIFFTAG_IMAGEWIDTH:
     796            4153 :       *va_arg(ap, uint32*) = td->td_imagewidth;
     797            4153 :       break;
     798                 :     case TIFFTAG_IMAGELENGTH:
     799            4153 :       *va_arg(ap, uint32*) = td->td_imagelength;
     800            4153 :       break;
     801                 :     case TIFFTAG_BITSPERSAMPLE:
     802            5223 :       *va_arg(ap, uint16*) = td->td_bitspersample;
     803            5223 :       break;
     804                 :     case TIFFTAG_COMPRESSION:
     805            6687 :       *va_arg(ap, uint16*) = td->td_compression;
     806            6687 :       break;
     807                 :     case TIFFTAG_PHOTOMETRIC:
     808            6502 :       *va_arg(ap, uint16*) = td->td_photometric;
     809            6502 :       break;
     810                 :     case TIFFTAG_THRESHHOLDING:
     811               0 :       *va_arg(ap, uint16*) = td->td_threshholding;
     812               0 :       break;
     813                 :     case TIFFTAG_FILLORDER:
     814               0 :       *va_arg(ap, uint16*) = td->td_fillorder;
     815               0 :       break;
     816                 :     case TIFFTAG_ORIENTATION:
     817               0 :       *va_arg(ap, uint16*) = td->td_orientation;
     818               0 :       break;
     819                 :     case TIFFTAG_SAMPLESPERPIXEL:
     820            4153 :       *va_arg(ap, uint16*) = td->td_samplesperpixel;
     821            4153 :       break;
     822                 :     case TIFFTAG_ROWSPERSTRIP:
     823            4330 :       *va_arg(ap, uint32*) = td->td_rowsperstrip;
     824            4330 :       break;
     825                 :     case TIFFTAG_MINSAMPLEVALUE:
     826               0 :       *va_arg(ap, uint16*) = td->td_minsamplevalue;
     827               0 :       break;
     828                 :     case TIFFTAG_MAXSAMPLEVALUE:
     829               0 :       *va_arg(ap, uint16*) = td->td_maxsamplevalue;
     830               0 :       break;
     831                 :     case TIFFTAG_SMINSAMPLEVALUE:
     832               0 :       if (tif->tif_flags & TIFF_PERSAMPLE)
     833               0 :         *va_arg(ap, double**) = td->td_sminsamplevalue;
     834                 :       else
     835                 :       {
     836                 :         /* libtiff historially treats this as a single value. */
     837                 :         uint16 i;
     838               0 :         double v = td->td_sminsamplevalue[0];
     839               0 :         for (i=1; i < td->td_samplesperpixel; ++i)
     840               0 :           if( td->td_sminsamplevalue[i] < v )
     841               0 :             v = td->td_sminsamplevalue[i];
     842               0 :         *va_arg(ap, double*) = v;
     843                 :       }
     844               0 :       break;
     845                 :     case TIFFTAG_SMAXSAMPLEVALUE:
     846               0 :       if (tif->tif_flags & TIFF_PERSAMPLE)
     847               0 :         *va_arg(ap, double**) = td->td_smaxsamplevalue;
     848                 :       else
     849                 :       {
     850                 :         /* libtiff historially treats this as a single value. */
     851                 :         uint16 i;
     852               0 :         double v = td->td_smaxsamplevalue[0];
     853               0 :         for (i=1; i < td->td_samplesperpixel; ++i)
     854               0 :           if( td->td_smaxsamplevalue[i] > v )
     855               0 :             v = td->td_smaxsamplevalue[i];
     856               0 :         *va_arg(ap, double*) = v;
     857                 :       }
     858               0 :       break;
     859                 :     case TIFFTAG_XRESOLUTION:
     860              41 :       *va_arg(ap, float*) = td->td_xresolution;
     861              41 :       break;
     862                 :     case TIFFTAG_YRESOLUTION:
     863              41 :       *va_arg(ap, float*) = td->td_yresolution;
     864              41 :       break;
     865                 :     case TIFFTAG_PLANARCONFIG:
     866            5223 :       *va_arg(ap, uint16*) = td->td_planarconfig;
     867            5223 :       break;
     868                 :     case TIFFTAG_XPOSITION:
     869               0 :       *va_arg(ap, float*) = td->td_xposition;
     870               0 :       break;
     871                 :     case TIFFTAG_YPOSITION:
     872               0 :       *va_arg(ap, float*) = td->td_yposition;
     873               0 :       break;
     874                 :     case TIFFTAG_RESOLUTIONUNIT:
     875              41 :       *va_arg(ap, uint16*) = td->td_resolutionunit;
     876              41 :       break;
     877                 :     case TIFFTAG_PAGENUMBER:
     878               0 :       *va_arg(ap, uint16*) = td->td_pagenumber[0];
     879               0 :       *va_arg(ap, uint16*) = td->td_pagenumber[1];
     880               0 :       break;
     881                 :     case TIFFTAG_HALFTONEHINTS:
     882               0 :       *va_arg(ap, uint16*) = td->td_halftonehints[0];
     883               0 :       *va_arg(ap, uint16*) = td->td_halftonehints[1];
     884               0 :       break;
     885                 :     case TIFFTAG_COLORMAP:
     886              81 :       *va_arg(ap, uint16**) = td->td_colormap[0];
     887              81 :       *va_arg(ap, uint16**) = td->td_colormap[1];
     888              81 :       *va_arg(ap, uint16**) = td->td_colormap[2];
     889              81 :       break;
     890                 :     case TIFFTAG_STRIPOFFSETS:
     891                 :     case TIFFTAG_TILEOFFSETS:
     892            1322 :       _TIFFFillStriles( tif );
     893            1322 :       *va_arg(ap, uint64**) = td->td_stripoffset;
     894            1322 :       break;
     895                 :     case TIFFTAG_STRIPBYTECOUNTS:
     896                 :     case TIFFTAG_TILEBYTECOUNTS:
     897          104267 :       _TIFFFillStriles( tif );
     898          104267 :       *va_arg(ap, uint64**) = td->td_stripbytecount;
     899          104267 :       break;
     900                 :     case TIFFTAG_MATTEING:
     901               0 :       *va_arg(ap, uint16*) =
     902               0 :           (td->td_extrasamples == 1 &&
     903               0 :           td->td_sampleinfo[0] == EXTRASAMPLE_ASSOCALPHA);
     904               0 :       break;
     905                 :     case TIFFTAG_EXTRASAMPLES:
     906          393856 :       *va_arg(ap, uint16*) = td->td_extrasamples;
     907          393856 :       *va_arg(ap, uint16**) = td->td_sampleinfo;
     908          393856 :       break;
     909                 :     case TIFFTAG_TILEWIDTH:
     910             699 :       *va_arg(ap, uint32*) = td->td_tilewidth;
     911             699 :       break;
     912                 :     case TIFFTAG_TILELENGTH:
     913             699 :       *va_arg(ap, uint32*) = td->td_tilelength;
     914             699 :       break;
     915                 :     case TIFFTAG_TILEDEPTH:
     916               0 :       *va_arg(ap, uint32*) = td->td_tiledepth;
     917               0 :       break;
     918                 :     case TIFFTAG_DATATYPE:
     919               0 :       switch (td->td_sampleformat) {
     920                 :         case SAMPLEFORMAT_UINT:
     921               0 :           *va_arg(ap, uint16*) = DATATYPE_UINT;
     922               0 :           break;
     923                 :         case SAMPLEFORMAT_INT:
     924               0 :           *va_arg(ap, uint16*) = DATATYPE_INT;
     925               0 :           break;
     926                 :         case SAMPLEFORMAT_IEEEFP:
     927               0 :           *va_arg(ap, uint16*) = DATATYPE_IEEEFP;
     928               0 :           break;
     929                 :         case SAMPLEFORMAT_VOID:
     930               0 :           *va_arg(ap, uint16*) = DATATYPE_VOID;
     931                 :           break;
     932                 :       }
     933               0 :       break;
     934                 :     case TIFFTAG_SAMPLEFORMAT:
     935            4993 :       *va_arg(ap, uint16*) = td->td_sampleformat;
     936            4993 :       break;
     937                 :     case TIFFTAG_IMAGEDEPTH:
     938               0 :       *va_arg(ap, uint32*) = td->td_imagedepth;
     939               0 :       break;
     940                 :     case TIFFTAG_SUBIFD:
     941               0 :       *va_arg(ap, uint16*) = td->td_nsubifd;
     942               0 :       *va_arg(ap, uint64**) = td->td_subifd;
     943               0 :       break;
     944                 :     case TIFFTAG_YCBCRPOSITIONING:
     945               0 :       *va_arg(ap, uint16*) = td->td_ycbcrpositioning;
     946               0 :       break;
     947                 :     case TIFFTAG_YCBCRSUBSAMPLING:
     948               0 :       *va_arg(ap, uint16*) = td->td_ycbcrsubsampling[0];
     949               0 :       *va_arg(ap, uint16*) = td->td_ycbcrsubsampling[1];
     950               0 :       break;
     951                 :     case TIFFTAG_TRANSFERFUNCTION:
     952               0 :       *va_arg(ap, uint16**) = td->td_transferfunction[0];
     953               0 :       if (td->td_samplesperpixel - td->td_extrasamples > 1) {
     954               0 :         *va_arg(ap, uint16**) = td->td_transferfunction[1];
     955               0 :         *va_arg(ap, uint16**) = td->td_transferfunction[2];
     956                 :       }
     957               0 :       break;
     958                 :     case TIFFTAG_REFERENCEBLACKWHITE:
     959              12 :       *va_arg(ap, float**) = td->td_refblackwhite;
     960              12 :       break;
     961                 :     case TIFFTAG_INKNAMES:
     962               0 :       *va_arg(ap, char**) = td->td_inknames;
     963               0 :       break;
     964                 :     default:
     965                 :       {
     966                 :         const TIFFField* fip =
     967           54540 :           TIFFFindField(tif, tag, TIFF_ANY);
     968                 :         int i;
     969                 : 
     970                 :         /*
     971                 :          * This can happen if multiple images are open
     972                 :          * with different codecs which have private
     973                 :          * tags.  The global tag information table may
     974                 :          * then have tags that are valid for one file
     975                 :          * but not the other. If the client tries to
     976                 :          * get a tag that is not valid for the image's
     977                 :          * codec then we'll arrive here.
     978                 :          */
     979           54540 :         if( fip == NULL || fip->field_bit != FIELD_CUSTOM )
     980                 :         {
     981               0 :           TIFFErrorExt(tif->tif_clientdata, "_TIFFVGetField",
     982                 :               "%s: Invalid %stag \"%s\" "
     983                 :               "(not supported by codec)",
     984                 :               tif->tif_name,
     985                 :               isPseudoTag(tag) ? "pseudo-" : "",
     986                 :               fip ? fip->field_name : "Unknown");
     987               0 :           ret_val = 0;
     988               0 :           break;
     989                 :         }
     990                 : 
     991                 :         /*
     992                 :          * Do we have a custom value?
     993                 :          */
     994           54540 :         ret_val = 0;
     995          464482 :         for (i = 0; i < td->td_customValueCount; i++) {
     996          195638 :           TIFFTagValue *tv = td->td_customValues + i;
     997                 : 
     998          195638 :           if (tv->info->field_tag != tag)
     999          177701 :             continue;
    1000                 : 
    1001           17937 :           if (fip->field_passcount) {
    1002           13846 :             if (fip->field_readcount == TIFF_VARIABLE2)
    1003               2 :               *va_arg(ap, uint32*) = (uint32)tv->count;
    1004                 :             else  /* Assume TIFF_VARIABLE */
    1005           13844 :               *va_arg(ap, uint16*) = (uint16)tv->count;
    1006           13846 :             *va_arg(ap, void **) = tv->value;
    1007           13846 :             ret_val = 1;
    1008                 :           } else {
    1009           24550 :             if ((fip->field_type == TIFF_ASCII
    1010            4091 :                 || fip->field_readcount == TIFF_VARIABLE
    1011               1 :                 || fip->field_readcount == TIFF_VARIABLE2
    1012               1 :                 || fip->field_readcount == TIFF_SPP
    1013               2 :                 || tv->count > 1)
    1014                 :                 && fip->field_tag != TIFFTAG_PAGENUMBER
    1015            4091 :                 && fip->field_tag != TIFFTAG_HALFTONEHINTS
    1016            4091 :                 && fip->field_tag != TIFFTAG_YCBCRSUBSAMPLING
    1017            8182 :                 && fip->field_tag != TIFFTAG_DOTRANGE) {
    1018            4091 :               *va_arg(ap, void **) = tv->value;
    1019            4091 :               ret_val = 1;
    1020                 :             } else {
    1021                 :               int j;
    1022               0 :               char *val = (char *)tv->value;
    1023                 : 
    1024               0 :               for (j = 0; j < tv->count;
    1025               0 :                   j++, val += _TIFFDataSize(tv->info->field_type)) {
    1026               0 :                 switch (fip->field_type) {
    1027                 :                   case TIFF_BYTE:
    1028                 :                   case TIFF_UNDEFINED:
    1029               0 :                     *va_arg(ap, uint8*) =
    1030               0 :                         *(uint8 *)val;
    1031               0 :                     ret_val = 1;
    1032               0 :                     break;
    1033                 :                   case TIFF_SBYTE:
    1034               0 :                     *va_arg(ap, int8*) =
    1035               0 :                         *(int8 *)val;
    1036               0 :                     ret_val = 1;
    1037               0 :                     break;
    1038                 :                   case TIFF_SHORT:
    1039               0 :                     *va_arg(ap, uint16*) =
    1040               0 :                         *(uint16 *)val;
    1041               0 :                     ret_val = 1;
    1042               0 :                     break;
    1043                 :                   case TIFF_SSHORT:
    1044               0 :                     *va_arg(ap, int16*) =
    1045               0 :                         *(int16 *)val;
    1046               0 :                     ret_val = 1;
    1047               0 :                     break;
    1048                 :                   case TIFF_LONG:
    1049                 :                   case TIFF_IFD:
    1050               0 :                     *va_arg(ap, uint32*) =
    1051               0 :                         *(uint32 *)val;
    1052               0 :                     ret_val = 1;
    1053               0 :                     break;
    1054                 :                   case TIFF_SLONG:
    1055               0 :                     *va_arg(ap, int32*) =
    1056               0 :                         *(int32 *)val;
    1057               0 :                     ret_val = 1;
    1058               0 :                     break;
    1059                 :                   case TIFF_LONG8:
    1060                 :                   case TIFF_IFD8:
    1061               0 :                     *va_arg(ap, uint64*) =
    1062               0 :                         *(uint64 *)val;
    1063               0 :                     ret_val = 1;
    1064               0 :                     break;
    1065                 :                   case TIFF_SLONG8:
    1066               0 :                     *va_arg(ap, int64*) =
    1067               0 :                         *(int64 *)val;
    1068               0 :                     ret_val = 1;
    1069               0 :                     break;
    1070                 :                   case TIFF_RATIONAL:
    1071                 :                   case TIFF_SRATIONAL:
    1072                 :                   case TIFF_FLOAT:
    1073               0 :                     *va_arg(ap, float*) =
    1074               0 :                         *(float *)val;
    1075               0 :                     ret_val = 1;
    1076               0 :                     break;
    1077                 :                   case TIFF_DOUBLE:
    1078               0 :                     *va_arg(ap, double*) =
    1079               0 :                         *(double *)val;
    1080               0 :                     ret_val = 1;
    1081               0 :                     break;
    1082                 :                   default:
    1083               0 :                     ret_val = 0;
    1084                 :                     break;
    1085                 :                 }
    1086                 :               }
    1087                 :             }
    1088                 :           }
    1089           17937 :           break;
    1090                 :         }
    1091                 :       }
    1092                 :   }
    1093          601293 :   return(ret_val);
    1094                 : }
    1095                 : 
    1096                 : /*
    1097                 :  * Return the value of a field in the
    1098                 :  * internal directory structure.
    1099                 :  */
    1100                 : int
    1101          647485 : TIFFGetField(TIFF* tif, uint32 tag, ...)
    1102                 : {
    1103                 :   int status;
    1104                 :   va_list ap;
    1105                 : 
    1106          647485 :   va_start(ap, tag);
    1107          647485 :   status = TIFFVGetField(tif, tag, ap);
    1108          647485 :   va_end(ap);
    1109          647485 :   return (status);
    1110                 : }
    1111                 : 
    1112                 : /*
    1113                 :  * Like TIFFGetField, but taking a varargs
    1114                 :  * parameter list.  This routine is useful
    1115                 :  * for building higher-level interfaces on
    1116                 :  * top of the library.
    1117                 :  */
    1118                 : int
    1119          649066 : TIFFVGetField(TIFF* tif, uint32 tag, va_list ap)
    1120                 : {
    1121          649066 :   const TIFFField* fip = TIFFFindField(tif, tag, TIFF_ANY);
    1122         1251029 :   return (fip && (isPseudoTag(tag) || TIFFFieldSet(tif, fip->field_bit)) ?
    1123          601963 :       (*tif->tif_tagmethods.vgetfield)(tif, tag, ap) : 0);
    1124                 : }
    1125                 : 
    1126                 : #define CleanupField(member) {    \
    1127                 :     if (td->member) {      \
    1128                 :   _TIFFfree(td->member);   \
    1129                 :   td->member = 0;      \
    1130                 :     }         \
    1131                 : }
    1132                 : 
    1133                 : /*
    1134                 :  * Release storage associated with a directory.
    1135                 :  */
    1136                 : void
    1137           13714 : TIFFFreeDirectory(TIFF* tif)
    1138                 : {
    1139           13714 :   TIFFDirectory *td = &tif->tif_dir;
    1140                 :   int            i;
    1141                 : 
    1142           13714 :   _TIFFmemset(td->td_fieldsset, 0, FIELD_SETLONGS);
    1143           13714 :   CleanupField(td_sminsamplevalue);
    1144           13714 :   CleanupField(td_smaxsamplevalue);
    1145           13714 :   CleanupField(td_colormap[0]);
    1146           13714 :   CleanupField(td_colormap[1]);
    1147           13714 :   CleanupField(td_colormap[2]);
    1148           13714 :   CleanupField(td_sampleinfo);
    1149           13714 :   CleanupField(td_subifd);
    1150           13714 :   CleanupField(td_inknames);
    1151           13714 :   CleanupField(td_refblackwhite);
    1152           13714 :   CleanupField(td_transferfunction[0]);
    1153           13714 :   CleanupField(td_transferfunction[1]);
    1154           13714 :   CleanupField(td_transferfunction[2]);
    1155           13714 :   CleanupField(td_stripoffset);
    1156           13714 :   CleanupField(td_stripbytecount);
    1157           13714 :   TIFFClrFieldBit(tif, FIELD_YCBCRSUBSAMPLING);
    1158           13714 :   TIFFClrFieldBit(tif, FIELD_YCBCRPOSITIONING);
    1159                 : 
    1160                 :   /* Cleanup custom tag values */
    1161           35539 :   for( i = 0; i < td->td_customValueCount; i++ ) {
    1162           21825 :     if (td->td_customValues[i].value)
    1163           21825 :       _TIFFfree(td->td_customValues[i].value);
    1164                 :   }
    1165                 : 
    1166           13714 :   td->td_customValueCount = 0;
    1167           13714 :   CleanupField(td_customValues);
    1168                 : 
    1169                 : #if defined(DEFER_STRILE_LOAD)
    1170           13714 :         _TIFFmemset( &(td->td_stripoffset_entry), 0, sizeof(TIFFDirEntry));
    1171           13714 :         _TIFFmemset( &(td->td_stripbytecount_entry), 0, sizeof(TIFFDirEntry));
    1172                 : #endif        
    1173           13714 : }
    1174                 : #undef CleanupField
    1175                 : 
    1176                 : /*
    1177                 :  * Client Tag extension support (from Niles Ritter).
    1178                 :  */
    1179                 : static TIFFExtendProc _TIFFextender = (TIFFExtendProc) NULL;
    1180                 : 
    1181                 : TIFFExtendProc
    1182             858 : TIFFSetTagExtender(TIFFExtendProc extender)
    1183                 : {
    1184             858 :   TIFFExtendProc prev = _TIFFextender;
    1185             858 :   _TIFFextender = extender;
    1186             858 :   return (prev);
    1187                 : }
    1188                 : 
    1189                 : /*
    1190                 :  * Setup for a new directory.  Should we automatically call
    1191                 :  * TIFFWriteDirectory() if the current one is dirty?
    1192                 :  *
    1193                 :  * The newly created directory will not exist on the file till
    1194                 :  * TIFFWriteDirectory(), TIFFFlush() or TIFFClose() is called.
    1195                 :  */
    1196                 : int
    1197            1806 : TIFFCreateDirectory(TIFF* tif)
    1198                 : {
    1199            1806 :   TIFFDefaultDirectory(tif);
    1200            1806 :   tif->tif_diroff = 0;
    1201            1806 :   tif->tif_nextdiroff = 0;
    1202            1806 :   tif->tif_curoff = 0;
    1203            1806 :   tif->tif_row = (uint32) -1;
    1204            1806 :   tif->tif_curstrip = (uint32) -1;
    1205                 : 
    1206            1806 :   return 0;
    1207                 : }
    1208                 : 
    1209                 : /*
    1210                 :  * Setup a default directory structure.
    1211                 :  */
    1212                 : int
    1213            9937 : TIFFDefaultDirectory(TIFF* tif)
    1214                 : {
    1215            9937 :   register TIFFDirectory* td = &tif->tif_dir;
    1216                 :   const TIFFFieldArray* tiffFieldArray;
    1217                 : 
    1218            9937 :   tiffFieldArray = _TIFFGetFields();
    1219            9937 :   _TIFFSetupFields(tif, tiffFieldArray);   
    1220                 : 
    1221            9937 :   _TIFFmemset(td, 0, sizeof (*td));
    1222            9937 :   td->td_fillorder = FILLORDER_MSB2LSB;
    1223            9937 :   td->td_bitspersample = 1;
    1224            9937 :   td->td_threshholding = THRESHHOLD_BILEVEL;
    1225            9937 :   td->td_orientation = ORIENTATION_TOPLEFT;
    1226            9937 :   td->td_samplesperpixel = 1;
    1227            9937 :   td->td_rowsperstrip = (uint32) -1;
    1228            9937 :   td->td_tilewidth = 0;
    1229            9937 :   td->td_tilelength = 0;
    1230            9937 :   td->td_tiledepth = 1;
    1231            9937 :   td->td_stripbytecountsorted = 1; /* Our own arrays always sorted. */  
    1232            9937 :   td->td_resolutionunit = RESUNIT_INCH;
    1233            9937 :   td->td_sampleformat = SAMPLEFORMAT_UINT;
    1234            9937 :   td->td_imagedepth = 1;
    1235            9937 :   td->td_ycbcrsubsampling[0] = 2;
    1236            9937 :   td->td_ycbcrsubsampling[1] = 2;
    1237            9937 :   td->td_ycbcrpositioning = YCBCRPOSITION_CENTERED;
    1238            9937 :   tif->tif_postdecode = _TIFFNoPostDecode;  
    1239            9937 :   tif->tif_foundfield = NULL;
    1240            9937 :   tif->tif_tagmethods.vsetfield = _TIFFVSetField;  
    1241            9937 :   tif->tif_tagmethods.vgetfield = _TIFFVGetField;
    1242            9937 :   tif->tif_tagmethods.printdir = NULL;
    1243                 :   /*
    1244                 :    *  Give client code a chance to install their own
    1245                 :    *  tag extensions & methods, prior to compression overloads.
    1246                 :    */
    1247            9937 :   if (_TIFFextender)
    1248            9937 :     (*_TIFFextender)(tif);
    1249            9937 :   (void) TIFFSetField(tif, TIFFTAG_COMPRESSION, COMPRESSION_NONE);
    1250                 :   /*
    1251                 :    * NB: The directory is marked dirty as a result of setting
    1252                 :    * up the default compression scheme.  However, this really
    1253                 :    * isn't correct -- we want TIFF_DIRTYDIRECT to be set only
    1254                 :    * if the user does something.  We could just do the setup
    1255                 :    * by hand, but it seems better to use the normal mechanism
    1256                 :    * (i.e. TIFFSetField).
    1257                 :    */
    1258            9937 :   tif->tif_flags &= ~TIFF_DIRTYDIRECT;
    1259                 : 
    1260                 :   /*
    1261                 :    * As per http://bugzilla.remotesensing.org/show_bug.cgi?id=19
    1262                 :    * we clear the ISTILED flag when setting up a new directory.
    1263                 :    * Should we also be clearing stuff like INSUBIFD?
    1264                 :    */
    1265            9937 :   tif->tif_flags &= ~TIFF_ISTILED;
    1266                 : 
    1267            9937 :   return (1);
    1268                 : }
    1269                 : 
    1270                 : static int
    1271             930 : TIFFAdvanceDirectory(TIFF* tif, uint64* nextdir, uint64* off)
    1272                 : {
    1273                 :   static const char module[] = "TIFFAdvanceDirectory";
    1274             930 :   if (isMapped(tif))
    1275                 :   {
    1276               0 :     uint64 poff=*nextdir;
    1277               0 :     if (!(tif->tif_flags&TIFF_BIGTIFF))
    1278                 :     {
    1279                 :       tmsize_t poffa,poffb,poffc,poffd;
    1280                 :       uint16 dircount;
    1281                 :       uint32 nextdir32;
    1282               0 :       poffa=(tmsize_t)poff;
    1283               0 :       poffb=poffa+sizeof(uint16);
    1284               0 :       if (((uint64)poffa!=poff)||(poffb<poffa)||(poffb<(tmsize_t)sizeof(uint16))||(poffb>tif->tif_size))
    1285                 :       {
    1286               0 :         TIFFErrorExt(tif->tif_clientdata,module,"Error fetching directory count");
    1287               0 :         return(0);
    1288                 :       }
    1289               0 :       _TIFFmemcpy(&dircount,tif->tif_base+poffa,sizeof(uint16));
    1290               0 :       if (tif->tif_flags&TIFF_SWAB)
    1291               0 :         TIFFSwabShort(&dircount);
    1292               0 :       poffc=poffb+dircount*12;
    1293               0 :       poffd=poffc+sizeof(uint32);
    1294               0 :       if ((poffc<poffb)||(poffc<dircount*12)||(poffd<poffc)||(poffd<(tmsize_t)sizeof(uint32))||(poffd>tif->tif_size))
    1295                 :       {
    1296               0 :         TIFFErrorExt(tif->tif_clientdata,module,"Error fetching directory link");
    1297               0 :         return(0);
    1298                 :       }
    1299               0 :       if (off!=NULL)
    1300               0 :         *off=(uint64)poffc;
    1301               0 :       _TIFFmemcpy(&nextdir32,tif->tif_base+poffc,sizeof(uint32));
    1302               0 :       if (tif->tif_flags&TIFF_SWAB)
    1303               0 :         TIFFSwabLong(&nextdir32);
    1304               0 :       *nextdir=nextdir32;
    1305                 :     }
    1306                 :     else
    1307                 :     {
    1308                 :       tmsize_t poffa,poffb,poffc,poffd;
    1309                 :       uint64 dircount64;
    1310                 :       uint16 dircount16;
    1311               0 :       poffa=(tmsize_t)poff;
    1312               0 :       poffb=poffa+sizeof(uint64);
    1313               0 :       if (((uint64)poffa!=poff)||(poffb<poffa)||(poffb<(tmsize_t)sizeof(uint64))||(poffb>tif->tif_size))
    1314                 :       {
    1315               0 :         TIFFErrorExt(tif->tif_clientdata,module,"Error fetching directory count");
    1316               0 :         return(0);
    1317                 :       }
    1318               0 :       _TIFFmemcpy(&dircount64,tif->tif_base+poffa,sizeof(uint64));
    1319               0 :       if (tif->tif_flags&TIFF_SWAB)
    1320               0 :         TIFFSwabLong8(&dircount64);
    1321               0 :       if (dircount64>0xFFFF)
    1322                 :       {
    1323               0 :         TIFFErrorExt(tif->tif_clientdata,module,"Sanity check on directory count failed");
    1324               0 :         return(0);
    1325                 :       }
    1326               0 :       dircount16=(uint16)dircount64;
    1327               0 :       poffc=poffb+dircount16*20;
    1328               0 :       poffd=poffc+sizeof(uint64);
    1329               0 :       if ((poffc<poffb)||(poffc<dircount16*20)||(poffd<poffc)||(poffd<(tmsize_t)sizeof(uint64))||(poffd>tif->tif_size))
    1330                 :       {
    1331               0 :         TIFFErrorExt(tif->tif_clientdata,module,"Error fetching directory link");
    1332               0 :         return(0);
    1333                 :       }
    1334               0 :       if (off!=NULL)
    1335               0 :         *off=(uint64)poffc;
    1336               0 :       _TIFFmemcpy(nextdir,tif->tif_base+poffc,sizeof(uint64));
    1337               0 :       if (tif->tif_flags&TIFF_SWAB)
    1338               0 :         TIFFSwabLong8(nextdir);
    1339                 :     }
    1340               0 :     return(1);
    1341                 :   }
    1342                 :   else
    1343                 :   {
    1344             930 :     if (!(tif->tif_flags&TIFF_BIGTIFF))
    1345                 :     {
    1346                 :       uint16 dircount;
    1347                 :       uint32 nextdir32;
    1348            1820 :       if (!SeekOK(tif, *nextdir) ||
    1349             910 :           !ReadOK(tif, &dircount, sizeof (uint16))) {
    1350               0 :         TIFFErrorExt(tif->tif_clientdata, module, "%s: Error fetching directory count",
    1351                 :             tif->tif_name);
    1352               0 :         return (0);
    1353                 :       }
    1354             910 :       if (tif->tif_flags & TIFF_SWAB)
    1355              75 :         TIFFSwabShort(&dircount);
    1356             910 :       if (off != NULL)
    1357               2 :         *off = TIFFSeekFile(tif,
    1358                 :             dircount*12, SEEK_CUR);
    1359                 :       else
    1360             908 :         (void) TIFFSeekFile(tif,
    1361                 :             dircount*12, SEEK_CUR);
    1362             910 :       if (!ReadOK(tif, &nextdir32, sizeof (uint32))) {
    1363               0 :         TIFFErrorExt(tif->tif_clientdata, module, "%s: Error fetching directory link",
    1364                 :             tif->tif_name);
    1365               0 :         return (0);
    1366                 :       }
    1367             910 :       if (tif->tif_flags & TIFF_SWAB)
    1368              75 :         TIFFSwabLong(&nextdir32);
    1369             910 :       *nextdir=nextdir32;
    1370                 :     }
    1371                 :     else
    1372                 :     {
    1373                 :       uint64 dircount64;
    1374                 :       uint16 dircount16;
    1375              40 :       if (!SeekOK(tif, *nextdir) ||
    1376              20 :           !ReadOK(tif, &dircount64, sizeof (uint64))) {
    1377               0 :         TIFFErrorExt(tif->tif_clientdata, module, "%s: Error fetching directory count",
    1378                 :             tif->tif_name);
    1379               0 :         return (0);
    1380                 :       }
    1381              20 :       if (tif->tif_flags & TIFF_SWAB)
    1382               0 :         TIFFSwabLong8(&dircount64);
    1383              20 :       if (dircount64>0xFFFF)
    1384                 :       {
    1385               0 :         TIFFErrorExt(tif->tif_clientdata, module, "Error fetching directory count");
    1386               0 :         return(0);
    1387                 :       }
    1388              20 :       dircount16 = (uint16)dircount64;
    1389              20 :       if (off != NULL)
    1390               0 :         *off = TIFFSeekFile(tif,
    1391                 :             dircount16*20, SEEK_CUR);
    1392                 :       else
    1393              20 :         (void) TIFFSeekFile(tif,
    1394                 :             dircount16*20, SEEK_CUR);
    1395              20 :       if (!ReadOK(tif, nextdir, sizeof (uint64))) {
    1396               0 :         TIFFErrorExt(tif->tif_clientdata, module, "%s: Error fetching directory link",
    1397                 :             tif->tif_name);
    1398               0 :         return (0);
    1399                 :       }
    1400              20 :       if (tif->tif_flags & TIFF_SWAB)
    1401               0 :         TIFFSwabLong8(nextdir);
    1402                 :     }
    1403             930 :     return (1);
    1404                 :   }
    1405                 : }
    1406                 : 
    1407                 : /*
    1408                 :  * Count the number of directories in a file.
    1409                 :  */
    1410                 : uint16
    1411             254 : TIFFNumberOfDirectories(TIFF* tif)
    1412                 : {
    1413                 :   uint64 nextdir;
    1414                 :   uint16 n;
    1415             254 :   if (!(tif->tif_flags&TIFF_BIGTIFF))
    1416             244 :     nextdir = tif->tif_header.classic.tiff_diroff;
    1417                 :   else
    1418              10 :     nextdir = tif->tif_header.big.tiff_diroff;
    1419             254 :   n = 0;
    1420            1098 :   while (nextdir != 0 && TIFFAdvanceDirectory(tif, &nextdir, NULL))
    1421             590 :     n++;
    1422             254 :   return (n);
    1423                 : }
    1424                 : 
    1425                 : /*
    1426                 :  * Set the n-th directory as the current directory.
    1427                 :  * NB: Directories are numbered starting at 0.
    1428                 :  */
    1429                 : int
    1430            1200 : TIFFSetDirectory(TIFF* tif, uint16 dirn)
    1431                 : {
    1432                 :   uint64 nextdir;
    1433                 :   uint16 n;
    1434                 : 
    1435            1200 :   if (!(tif->tif_flags&TIFF_BIGTIFF))
    1436            1179 :     nextdir = tif->tif_header.classic.tiff_diroff;
    1437                 :   else
    1438              21 :     nextdir = tif->tif_header.big.tiff_diroff;
    1439            1536 :   for (n = dirn; n > 0 && nextdir != 0; n--)
    1440             336 :     if (!TIFFAdvanceDirectory(tif, &nextdir, NULL))
    1441               0 :       return (0);
    1442            1200 :   tif->tif_nextdiroff = nextdir;
    1443                 :   /*
    1444                 :    * Set curdir to the actual directory index.  The
    1445                 :    * -1 is because TIFFReadDirectory will increment
    1446                 :    * tif_curdir after successfully reading the directory.
    1447                 :    */
    1448            1200 :   tif->tif_curdir = (dirn - n) - 1;
    1449                 :   /*
    1450                 :    * Reset tif_dirnumber counter and start new list of seen directories.
    1451                 :    * We need this to prevent IFD loops.
    1452                 :    */
    1453            1200 :   tif->tif_dirnumber = 0;
    1454            1200 :   return (TIFFReadDirectory(tif));
    1455                 : }
    1456                 : 
    1457                 : /*
    1458                 :  * Set the current directory to be the directory
    1459                 :  * located at the specified file offset.  This interface
    1460                 :  * is used mainly to access directories linked with
    1461                 :  * the SubIFD tag (e.g. thumbnail images).
    1462                 :  */
    1463                 : int
    1464            1790 : TIFFSetSubDirectory(TIFF* tif, uint64 diroff)
    1465                 : {
    1466            1790 :   tif->tif_nextdiroff = diroff;
    1467                 :   /*
    1468                 :    * Reset tif_dirnumber counter and start new list of seen directories.
    1469                 :    * We need this to prevent IFD loops.
    1470                 :    */
    1471            1790 :   tif->tif_dirnumber = 0;
    1472            1790 :   return (TIFFReadDirectory(tif));
    1473                 : }
    1474                 : 
    1475                 : /*
    1476                 :  * Return file offset of the current directory.
    1477                 :  */
    1478                 : uint64
    1479          233775 : TIFFCurrentDirOffset(TIFF* tif)
    1480                 : {
    1481          233775 :   return (tif->tif_diroff);
    1482                 : }
    1483                 : 
    1484                 : /*
    1485                 :  * Return an indication of whether or not we are
    1486                 :  * at the last directory in the file.
    1487                 :  */
    1488                 : int
    1489            1699 : TIFFLastDirectory(TIFF* tif)
    1490                 : {
    1491            1699 :   return (tif->tif_nextdiroff == 0);
    1492                 : }
    1493                 : 
    1494                 : /*
    1495                 :  * Unlink the specified directory from the directory chain.
    1496                 :  */
    1497                 : int
    1498               2 : TIFFUnlinkDirectory(TIFF* tif, uint16 dirn)
    1499                 : {
    1500                 :   static const char module[] = "TIFFUnlinkDirectory";
    1501                 :   uint64 nextdir;
    1502                 :   uint64 off;
    1503                 :   uint16 n;
    1504                 : 
    1505               2 :   if (tif->tif_mode == O_RDONLY) {
    1506               0 :     TIFFErrorExt(tif->tif_clientdata, module,
    1507                 :                              "Can not unlink directory in read-only file");
    1508               0 :     return (0);
    1509                 :   }
    1510                 :   /*
    1511                 :    * Go to the directory before the one we want
    1512                 :    * to unlink and nab the offset of the link
    1513                 :    * field we'll need to patch.
    1514                 :    */
    1515               2 :   if (!(tif->tif_flags&TIFF_BIGTIFF))
    1516                 :   {
    1517               2 :     nextdir = tif->tif_header.classic.tiff_diroff;
    1518               2 :     off = 4;
    1519                 :   }
    1520                 :   else
    1521                 :   {
    1522               0 :     nextdir = tif->tif_header.big.tiff_diroff;
    1523               0 :     off = 8;
    1524                 :   }
    1525               4 :   for (n = dirn-1; n > 0; n--) {
    1526               2 :     if (nextdir == 0) {
    1527               0 :       TIFFErrorExt(tif->tif_clientdata, module, "Directory %d does not exist", dirn);
    1528               0 :       return (0);
    1529                 :     }
    1530               2 :     if (!TIFFAdvanceDirectory(tif, &nextdir, &off))
    1531               0 :       return (0);
    1532                 :   }
    1533                 :   /*
    1534                 :    * Advance to the directory to be unlinked and fetch
    1535                 :    * the offset of the directory that follows.
    1536                 :    */
    1537               2 :   if (!TIFFAdvanceDirectory(tif, &nextdir, NULL))
    1538               0 :     return (0);
    1539                 :   /*
    1540                 :    * Go back and patch the link field of the preceding
    1541                 :    * directory to point to the offset of the directory
    1542                 :    * that follows.
    1543                 :    */
    1544               2 :   (void) TIFFSeekFile(tif, off, SEEK_SET);
    1545               2 :   if (!(tif->tif_flags&TIFF_BIGTIFF))
    1546                 :   {
    1547                 :     uint32 nextdir32;
    1548               2 :     nextdir32=(uint32)nextdir;
    1549               2 :     assert((uint64)nextdir32==nextdir);
    1550               2 :     if (tif->tif_flags & TIFF_SWAB)
    1551               1 :       TIFFSwabLong(&nextdir32);
    1552               2 :     if (!WriteOK(tif, &nextdir32, sizeof (uint32))) {
    1553               0 :       TIFFErrorExt(tif->tif_clientdata, module, "Error writing directory link");
    1554               0 :       return (0);
    1555                 :     }
    1556                 :   }
    1557                 :   else
    1558                 :   {
    1559               0 :     if (tif->tif_flags & TIFF_SWAB)
    1560               0 :       TIFFSwabLong8(&nextdir);
    1561               0 :     if (!WriteOK(tif, &nextdir, sizeof (uint64))) {
    1562               0 :       TIFFErrorExt(tif->tif_clientdata, module, "Error writing directory link");
    1563               0 :       return (0);
    1564                 :     }
    1565                 :   }
    1566                 :   /*
    1567                 :    * Leave directory state setup safely.  We don't have
    1568                 :    * facilities for doing inserting and removing directories,
    1569                 :    * so it's safest to just invalidate everything.  This
    1570                 :    * means that the caller can only append to the directory
    1571                 :    * chain.
    1572                 :    */
    1573               2 :   (*tif->tif_cleanup)(tif);
    1574               2 :   if ((tif->tif_flags & TIFF_MYBUFFER) && tif->tif_rawdata) {
    1575               0 :     _TIFFfree(tif->tif_rawdata);
    1576               0 :     tif->tif_rawdata = NULL;
    1577               0 :     tif->tif_rawcc = 0;
    1578               0 :                 tif->tif_rawdataoff = 0;
    1579               0 :                 tif->tif_rawdataloaded = 0;
    1580                 :   }
    1581               2 :   tif->tif_flags &= ~(TIFF_BEENWRITING|TIFF_BUFFERSETUP|TIFF_POSTENCODE|TIFF_BUF4WRITE);
    1582               2 :   TIFFFreeDirectory(tif);
    1583               2 :   TIFFDefaultDirectory(tif);
    1584               2 :   tif->tif_diroff = 0;     /* force link on next write */
    1585               2 :   tif->tif_nextdiroff = 0;   /* next write must be at end */
    1586               2 :   tif->tif_curoff = 0;
    1587               2 :   tif->tif_row = (uint32) -1;
    1588               2 :   tif->tif_curstrip = (uint32) -1;
    1589               2 :   return (1);
    1590                 : }
    1591                 : 
    1592                 : /* vim: set ts=8 sts=8 sw=8 noet: */
    1593                 : /*
    1594                 :  * Local Variables:
    1595                 :  * mode: c
    1596                 :  * c-basic-offset: 8
    1597                 :  * fill-column: 78
    1598                 :  * End:
    1599                 :  */

Generated by: LCOV version 1.7