LCOV - code coverage report
Current view: directory - frmts/gtiff/libtiff - tif_dir.c (source / functions) Found Hit Coverage
Test: gdal_filtered.info Lines: 854 460 53.9 %
Date: 2012-12-26 Functions: 33 24 72.7 %

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

Generated by: LCOV version 1.7