4  * Copyright (c) 1988-1997 Sam Leffler 
   5  * Copyright (c) 1991-1997 Silicon Graphics, Inc. 
   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. 
  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.   
  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  
  30  * Directory Tag Get & Set Routines. 
  31  * (and also some miscellaneous stuff) 
  36  * These are used in the backwards compatibility code... 
  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 */ 
  44 setByteArray(void** vpp
, void* vp
, size_t nmemb
, size_t elem_size
) 
  47                 _TIFFfree(*vpp
), *vpp 
= 0; 
  49                 tsize_t bytes 
= nmemb 
* elem_size
; 
  50                 if (elem_size 
&& bytes 
/ elem_size 
== nmemb
) 
  51                         *vpp 
= (void*) _TIFFmalloc(bytes
); 
  53                         _TIFFmemcpy(*vpp
, vp
, bytes
); 
  56 void _TIFFsetByteArray(void** vpp
, void* vp
, uint32 n
) 
  57     { setByteArray(vpp
, vp
, n
, 1); } 
  58 void _TIFFsetString(char** cpp
, char* cp
) 
  59     { setByteArray((void**) cpp
, (void*) cp
, strlen(cp
)+1, 1); } 
  60 void _TIFFsetNString(char** cpp
, char* cp
, uint32 n
) 
  61     { setByteArray((void**) cpp
, (void*) cp
, n
, 1); } 
  62 void _TIFFsetShortArray(uint16
** wpp
, uint16
* wp
, uint32 n
) 
  63     { setByteArray((void**) wpp
, (void*) wp
, n
, sizeof (uint16
)); } 
  64 void _TIFFsetLongArray(uint32
** lpp
, uint32
* lp
, uint32 n
) 
  65     { setByteArray((void**) lpp
, (void*) lp
, n
, sizeof (uint32
)); } 
  66 void _TIFFsetFloatArray(float** fpp
, float* fp
, uint32 n
) 
  67     { setByteArray((void**) fpp
, (void*) fp
, n
, sizeof (float)); } 
  68 void _TIFFsetDoubleArray(double** dpp
, double* dp
, uint32 n
) 
  69     { setByteArray((void**) dpp
, (void*) dp
, n
, sizeof (double)); } 
  72  * Install extra samples information. 
  75 setExtraSamples(TIFFDirectory
* td
, va_list ap
, uint32
* v
) 
  80         *v 
= va_arg(ap
, uint32
); 
  81         if ((uint16
) *v 
> td
->td_samplesperpixel
) 
  83         va 
= va_arg(ap
, uint16
*); 
  84         if (*v 
> 0 && va 
== NULL
)               /* typically missing param */ 
  86         for (i 
= 0; i 
< *v
; i
++) 
  87                 if (va
[i
] > EXTRASAMPLE_UNASSALPHA
) 
  89         td
->td_extrasamples 
= (uint16
) *v
; 
  90         _TIFFsetShortArray(&td
->td_sampleinfo
, va
, td
->td_extrasamples
); 
  95 checkInkNamesString(TIFF
* tif
, uint32 slen
, const char* s
) 
  97         TIFFDirectory
* td 
= &tif
->tif_dir
; 
  98         uint16 i 
= td
->td_samplesperpixel
; 
 101                 const char* ep 
= s
+slen
; 
 104                         for (; *cp 
!= '\0'; cp
++) 
 112         TIFFErrorExt(tif
->tif_clientdata
, "TIFFSetField", 
 113             "%s: Invalid InkNames value; expecting %d names, found %d", 
 115             td
->td_samplesperpixel
, 
 116             td
->td_samplesperpixel
-i
); 
 121 _TIFFVSetField(TIFF
* tif
, ttag_t tag
, va_list ap
) 
 123         static const char module[] = "_TIFFVSetField"; 
 125         TIFFDirectory
* td 
= &tif
->tif_dir
; 
 131         case TIFFTAG_SUBFILETYPE
: 
 132                 td
->td_subfiletype 
= va_arg(ap
, uint32
); 
 134         case TIFFTAG_IMAGEWIDTH
: 
 135                 td
->td_imagewidth 
= va_arg(ap
, uint32
); 
 137         case TIFFTAG_IMAGELENGTH
: 
 138                 td
->td_imagelength 
= va_arg(ap
, uint32
); 
 140         case TIFFTAG_BITSPERSAMPLE
: 
 141                 td
->td_bitspersample 
= (uint16
) va_arg(ap
, int); 
 143                  * If the data require post-decoding processing to byte-swap 
 144                  * samples, set it up here.  Note that since tags are required 
 145                  * to be ordered, compression code can override this behaviour 
 146                  * in the setup method if it wants to roll the post decoding 
 147                  * work in with its normal work. 
 149                 if (tif
->tif_flags 
& TIFF_SWAB
) { 
 150                         if (td
->td_bitspersample 
== 16) 
 151                                 tif
->tif_postdecode 
= _TIFFSwab16BitData
; 
 152                         else if (td
->td_bitspersample 
== 24) 
 153                                 tif
->tif_postdecode 
= _TIFFSwab24BitData
; 
 154                         else if (td
->td_bitspersample 
== 32) 
 155                                 tif
->tif_postdecode 
= _TIFFSwab32BitData
; 
 156                         else if (td
->td_bitspersample 
== 64) 
 157                                 tif
->tif_postdecode 
= _TIFFSwab64BitData
; 
 158                         else if (td
->td_bitspersample 
== 128) /* two 64's */ 
 159                                 tif
->tif_postdecode 
= _TIFFSwab64BitData
; 
 162         case TIFFTAG_COMPRESSION
: 
 163                 v 
= va_arg(ap
, uint32
) & 0xffff; 
 165                  * If we're changing the compression scheme, the notify the 
 166                  * previous module so that it can cleanup any state it's 
 169                 if (TIFFFieldSet(tif
, FIELD_COMPRESSION
)) { 
 170                         if (td
->td_compression 
== v
) 
 172                         (*tif
->tif_cleanup
)(tif
); 
 173                         tif
->tif_flags 
&= ~TIFF_CODERSETUP
; 
 176                  * Setup new compression routine state. 
 178                 if( (status 
= TIFFSetCompressionScheme(tif
, v
)) != 0 ) 
 179                     td
->td_compression 
= (uint16
) v
; 
 183         case TIFFTAG_PHOTOMETRIC
: 
 184                 td
->td_photometric 
= (uint16
) va_arg(ap
, int); 
 186         case TIFFTAG_THRESHHOLDING
: 
 187                 td
->td_threshholding 
= (uint16
) va_arg(ap
, int); 
 189         case TIFFTAG_FILLORDER
: 
 190                 v 
= va_arg(ap
, uint32
); 
 191                 if (v 
!= FILLORDER_LSB2MSB 
&& v 
!= FILLORDER_MSB2LSB
) 
 193                 td
->td_fillorder 
= (uint16
) v
; 
 196         case TIFFTAG_ORIENTATION
: 
 197                 v 
= va_arg(ap
, uint32
); 
 198                 if (v 
< ORIENTATION_TOPLEFT 
|| ORIENTATION_LEFTBOT 
< v
) { 
 199                         TIFFWarningExt(tif
->tif_clientdata
, tif
->tif_name
, 
 200                             "Bad value %lu for \"%s\" tag ignored", 
 201                             v
, _TIFFFieldWithTag(tif
, tag
)->field_name
); 
 203                         td
->td_orientation 
= (uint16
) v
; 
 205         case TIFFTAG_SAMPLESPERPIXEL
: 
 206                 /* XXX should cross check -- e.g. if pallette, then 1 */ 
 207                 v 
= va_arg(ap
, uint32
); 
 210                 td
->td_samplesperpixel 
= (uint16
) v
; 
 212         case TIFFTAG_ROWSPERSTRIP
: 
 213                 v32 
= va_arg(ap
, uint32
); 
 216                 td
->td_rowsperstrip 
= v32
; 
 217                 if (!TIFFFieldSet(tif
, FIELD_TILEDIMENSIONS
)) { 
 218                         td
->td_tilelength 
= v32
; 
 219                         td
->td_tilewidth 
= td
->td_imagewidth
; 
 222         case TIFFTAG_MINSAMPLEVALUE
: 
 223                 td
->td_minsamplevalue 
= (uint16
) va_arg(ap
, int); 
 225         case TIFFTAG_MAXSAMPLEVALUE
: 
 226                 td
->td_maxsamplevalue 
= (uint16
) va_arg(ap
, int); 
 228         case TIFFTAG_SMINSAMPLEVALUE
: 
 229                 td
->td_sminsamplevalue 
= va_arg(ap
, double); 
 231         case TIFFTAG_SMAXSAMPLEVALUE
: 
 232                 td
->td_smaxsamplevalue 
= va_arg(ap
, double); 
 234         case TIFFTAG_XRESOLUTION
: 
 235                 td
->td_xresolution 
= (float) va_arg(ap
, double); 
 237         case TIFFTAG_YRESOLUTION
: 
 238                 td
->td_yresolution 
= (float) va_arg(ap
, double); 
 240         case TIFFTAG_PLANARCONFIG
: 
 241                 v 
= va_arg(ap
, uint32
); 
 242                 if (v 
!= PLANARCONFIG_CONTIG 
&& v 
!= PLANARCONFIG_SEPARATE
) 
 244                 td
->td_planarconfig 
= (uint16
) v
; 
 246         case TIFFTAG_XPOSITION
: 
 247                 td
->td_xposition 
= (float) va_arg(ap
, double); 
 249         case TIFFTAG_YPOSITION
: 
 250                 td
->td_yposition 
= (float) va_arg(ap
, double); 
 252         case TIFFTAG_RESOLUTIONUNIT
: 
 253                 v 
= va_arg(ap
, uint32
); 
 254                 if (v 
< RESUNIT_NONE 
|| RESUNIT_CENTIMETER 
< v
) 
 256                 td
->td_resolutionunit 
= (uint16
) v
; 
 258         case TIFFTAG_PAGENUMBER
: 
 259                 td
->td_pagenumber
[0] = (uint16
) va_arg(ap
, int); 
 260                 td
->td_pagenumber
[1] = (uint16
) va_arg(ap
, int); 
 262         case TIFFTAG_HALFTONEHINTS
: 
 263                 td
->td_halftonehints
[0] = (uint16
) va_arg(ap
, int); 
 264                 td
->td_halftonehints
[1] = (uint16
) va_arg(ap
, int); 
 266         case TIFFTAG_COLORMAP
: 
 267                 v32 
= (uint32
)(1L<<td
->td_bitspersample
); 
 268                 _TIFFsetShortArray(&td
->td_colormap
[0], va_arg(ap
, uint16
*), v32
); 
 269                 _TIFFsetShortArray(&td
->td_colormap
[1], va_arg(ap
, uint16
*), v32
); 
 270                 _TIFFsetShortArray(&td
->td_colormap
[2], va_arg(ap
, uint16
*), v32
); 
 272         case TIFFTAG_EXTRASAMPLES
: 
 273                 if (!setExtraSamples(td
, ap
, &v
)) 
 276         case TIFFTAG_MATTEING
: 
 277                 td
->td_extrasamples 
= (uint16
) (va_arg(ap
, int) != 0); 
 278                 if (td
->td_extrasamples
) { 
 279                         uint16 sv 
= EXTRASAMPLE_ASSOCALPHA
; 
 280                         _TIFFsetShortArray(&td
->td_sampleinfo
, &sv
, 1); 
 283         case TIFFTAG_TILEWIDTH
: 
 284                 v32 
= va_arg(ap
, uint32
); 
 286                         if (tif
->tif_mode 
!= O_RDONLY
) 
 288                         TIFFWarningExt(tif
->tif_clientdata
, tif
->tif_name
, 
 289                                 "Nonstandard tile width %d, convert file", v32
); 
 291                 td
->td_tilewidth 
= v32
; 
 292                 tif
->tif_flags 
|= TIFF_ISTILED
; 
 294         case TIFFTAG_TILELENGTH
: 
 295                 v32 
= va_arg(ap
, uint32
); 
 297                         if (tif
->tif_mode 
!= O_RDONLY
) 
 299                         TIFFWarningExt(tif
->tif_clientdata
, tif
->tif_name
, 
 300                             "Nonstandard tile length %d, convert file", v32
); 
 302                 td
->td_tilelength 
= v32
; 
 303                 tif
->tif_flags 
|= TIFF_ISTILED
; 
 305         case TIFFTAG_TILEDEPTH
: 
 306                 v32 
= va_arg(ap
, uint32
); 
 309                 td
->td_tiledepth 
= v32
; 
 311         case TIFFTAG_DATATYPE
: 
 312                 v 
= va_arg(ap
, uint32
); 
 314                 case DATATYPE_VOID
:     v 
= SAMPLEFORMAT_VOID
;  break; 
 315                 case DATATYPE_INT
:      v 
= SAMPLEFORMAT_INT
;   break; 
 316                 case DATATYPE_UINT
:     v 
= SAMPLEFORMAT_UINT
;  break; 
 317                 case DATATYPE_IEEEFP
:   v 
= SAMPLEFORMAT_IEEEFP
;break; 
 318                 default:                goto badvalue
; 
 320                 td
->td_sampleformat 
= (uint16
) v
; 
 322         case TIFFTAG_SAMPLEFORMAT
: 
 323                 v 
= va_arg(ap
, uint32
); 
 324                 if (v 
< SAMPLEFORMAT_UINT 
|| SAMPLEFORMAT_COMPLEXIEEEFP 
< v
) 
 326                 td
->td_sampleformat 
= (uint16
) v
; 
 328                 /*  Try to fix up the SWAB function for complex data. */ 
 329                 if( td
->td_sampleformat 
== SAMPLEFORMAT_COMPLEXINT 
 
 330                     && td
->td_bitspersample 
== 32 
 331                     && tif
->tif_postdecode 
== _TIFFSwab32BitData 
) 
 332                     tif
->tif_postdecode 
= _TIFFSwab16BitData
; 
 333                 else if( (td
->td_sampleformat 
== SAMPLEFORMAT_COMPLEXINT 
 
 334                           || td
->td_sampleformat 
== SAMPLEFORMAT_COMPLEXIEEEFP
) 
 335                          && td
->td_bitspersample 
== 64 
 336                          && tif
->tif_postdecode 
== _TIFFSwab64BitData 
) 
 337                     tif
->tif_postdecode 
= _TIFFSwab32BitData
; 
 339         case TIFFTAG_IMAGEDEPTH
: 
 340                 td
->td_imagedepth 
= va_arg(ap
, uint32
); 
 343                 if ((tif
->tif_flags 
& TIFF_INSUBIFD
) == 0) { 
 344                         td
->td_nsubifd 
= (uint16
) va_arg(ap
, int); 
 345                         _TIFFsetLongArray(&td
->td_subifd
, va_arg(ap
, uint32
*), 
 346                             (long) td
->td_nsubifd
); 
 348                         TIFFErrorExt(tif
->tif_clientdata
, module, "%s: Sorry, cannot nest SubIFDs", 
 353         case TIFFTAG_YCBCRPOSITIONING
: 
 354                 td
->td_ycbcrpositioning 
= (uint16
) va_arg(ap
, int); 
 356         case TIFFTAG_YCBCRSUBSAMPLING
: 
 357                 td
->td_ycbcrsubsampling
[0] = (uint16
) va_arg(ap
, int); 
 358                 td
->td_ycbcrsubsampling
[1] = (uint16
) va_arg(ap
, int); 
 360         case TIFFTAG_TRANSFERFUNCTION
: 
 361                 v 
= (td
->td_samplesperpixel 
- td
->td_extrasamples
) > 1 ? 3 : 1; 
 362                 for (i 
= 0; i 
< v
; i
++) 
 363                         _TIFFsetShortArray(&td
->td_transferfunction
[i
], 
 364                             va_arg(ap
, uint16
*), 1L<<td
->td_bitspersample
); 
 366         case TIFFTAG_INKNAMES
: 
 367                 v 
= va_arg(ap
, uint32
); 
 368                 s 
= va_arg(ap
, char*); 
 369                 v 
= checkInkNamesString(tif
, v
, s
); 
 372                         _TIFFsetNString(&td
->td_inknames
, s
, v
); 
 373                         td
->td_inknameslen 
= v
; 
 377             const TIFFFieldInfo
* fip 
= _TIFFFindFieldInfo(tif
, tag
, TIFF_ANY
); 
 379             int tv_size
, iCustom
; 
 382              * This can happen if multiple images are open with different 
 383              * codecs which have private tags.  The global tag information 
 384              * table may then have tags that are valid for one file but not 
 385              * the other. If the client tries to set a tag that is not valid 
 386              * for the image's codec then we'll arrive here.  This 
 387              * happens, for example, when tiffcp is used to convert between 
 388              * compression schemes and codec-specific tags are blindly copied. 
 390             if(fip 
== NULL 
|| fip
->field_bit 
!= FIELD_CUSTOM
) { 
 391                 TIFFErrorExt(tif
->tif_clientdata
, module, 
 392                     "%s: Invalid %stag \"%s\" (not supported by codec)", 
 393                     tif
->tif_name
, isPseudoTag(tag
) ? "pseudo-" : "", 
 394                     _TIFFFieldWithTag(tif
, tag
)->field_name
); 
 400              * Find the existing entry for this custom value. 
 403             for(iCustom 
= 0; iCustom 
< td
->td_customValueCount
; iCustom
++) { 
 404                 if(td
->td_customValues
[iCustom
].info 
== fip
) { 
 405                     tv 
= td
->td_customValues 
+ iCustom
; 
 406                     if(tv
->value 
!= NULL
) 
 408                         _TIFFfree(tv
->value
); 
 416              * Grow the custom list if the entry was not found. 
 419                 TIFFTagValue    
*new_customValues
; 
 421                 td
->td_customValueCount
++; 
 422                 new_customValues 
= (TIFFTagValue 
*) 
 423                         _TIFFrealloc(td
->td_customValues
, 
 424                                      sizeof(TIFFTagValue
) * td
->td_customValueCount
); 
 425                 if (!new_customValues
) { 
 426                         TIFFErrorExt(tif
->tif_clientdata
, module, 
 427                 "%s: Failed to allocate space for list of custom values", 
 433                 td
->td_customValues 
= new_customValues
; 
 435                 tv 
= td
->td_customValues 
+ (td
->td_customValueCount
-1); 
 442              * Set custom value ... save a copy of the custom tag value. 
 444             tv_size 
= _TIFFDataSize(fip
->field_type
); 
 447                     TIFFErrorExt(tif
->tif_clientdata
, module, 
 448                                  "%s: Bad field type %d for \"%s\"", 
 449                                  tif
->tif_name
, fip
->field_type
, 
 454             if(fip
->field_passcount
) { 
 455                     if (fip
->field_writecount 
== TIFF_VARIABLE2
) 
 456                         tv
->count 
= (uint32
) va_arg(ap
, uint32
); 
 458                         tv
->count 
= (int) va_arg(ap
, int); 
 459             } else if (fip
->field_writecount 
== TIFF_VARIABLE
 
 460                        || fip
->field_writecount 
== TIFF_VARIABLE2
) 
 462             else if (fip
->field_writecount 
== TIFF_SPP
) 
 463                 tv
->count 
= td
->td_samplesperpixel
; 
 465                 tv
->count 
= fip
->field_writecount
; 
 468             if (fip
->field_type 
== TIFF_ASCII
) 
 469                     _TIFFsetString((char **)&tv
->value
, va_arg(ap
, char *)); 
 471                 tv
->value 
= _TIFFmalloc(tv_size 
* tv
->count
); 
 477                 if ((fip
->field_passcount
 
 478                     || fip
->field_writecount 
== TIFF_VARIABLE
 
 479                     || fip
->field_writecount 
== TIFF_VARIABLE2
 
 480                     || fip
->field_writecount 
== TIFF_SPP
 
 482                     && fip
->field_tag 
!= TIFFTAG_PAGENUMBER
 
 483                     && fip
->field_tag 
!= TIFFTAG_HALFTONEHINTS
 
 484                     && fip
->field_tag 
!= TIFFTAG_YCBCRSUBSAMPLING
 
 485                     && fip
->field_tag 
!= TIFFTAG_DOTRANGE
) { 
 486                     _TIFFmemcpy(tv
->value
, va_arg(ap
, void *), 
 487                                 tv
->count 
* tv_size
); 
 490                      * XXX: The following loop required to handle 
 491                      * TIFFTAG_PAGENUMBER, TIFFTAG_HALFTONEHINTS, 
 492                      * TIFFTAG_YCBCRSUBSAMPLING and TIFFTAG_DOTRANGE tags. 
 493                      * These tags are actually arrays and should be passed as 
 494                      * array pointers to TIFFSetField() function, but actually 
 495                      * passed as a list of separate values. This behaviour 
 496                      * must be changed in the future! 
 499                     char *val 
= (char *)tv
->value
; 
 501                     for (i 
= 0; i 
< tv
->count
; i
++, val 
+= tv_size
) { 
 502                             switch (fip
->field_type
) { 
 506                                         uint8 v 
= (uint8
)va_arg(ap
, int); 
 507                                         _TIFFmemcpy(val
, &v
, tv_size
); 
 512                                         int8 v 
= (int8
)va_arg(ap
, int); 
 513                                         _TIFFmemcpy(val
, &v
, tv_size
); 
 518                                         uint16 v 
= (uint16
)va_arg(ap
, int); 
 519                                         _TIFFmemcpy(val
, &v
, tv_size
); 
 524                                         int16 v 
= (int16
)va_arg(ap
, int); 
 525                                         _TIFFmemcpy(val
, &v
, tv_size
); 
 531                                         uint32 v 
= va_arg(ap
, uint32
); 
 532                                         _TIFFmemcpy(val
, &v
, tv_size
); 
 537                                         int32 v 
= va_arg(ap
, int32
); 
 538                                         _TIFFmemcpy(val
, &v
, tv_size
); 
 545                                         float v 
= (float)va_arg(ap
, double); 
 546                                         _TIFFmemcpy(val
, &v
, tv_size
); 
 551                                         double v 
= va_arg(ap
, double); 
 552                                         _TIFFmemcpy(val
, &v
, tv_size
); 
 556                                     _TIFFmemset(val
, 0, tv_size
); 
 566                 TIFFSetFieldBit(tif
, _TIFFFieldWithTag(tif
, tag
)->field_bit
); 
 567                 tif
->tif_flags 
|= TIFF_DIRTYDIRECT
; 
 574         TIFFErrorExt(tif
->tif_clientdata
, module, "%s: Bad value %d for \"%s\"", 
 575                   tif
->tif_name
, v
, _TIFFFieldWithTag(tif
, tag
)->field_name
); 
 579         TIFFErrorExt(tif
->tif_clientdata
, module, "%s: Bad value %ld for \"%s\"", 
 580                    tif
->tif_name
, v32
, _TIFFFieldWithTag(tif
, tag
)->field_name
); 
 586  * Return 1/0 according to whether or not 
 587  * it is permissible to set the tag's value. 
 588  * Note that we allow ImageLength to be changed 
 589  * so that we can append and extend to images. 
 590  * Any other tag may not be altered once writing 
 591  * has commenced, unless its value has no effect 
 592  * on the format of the data that is written. 
 595 OkToChangeTag(TIFF
* tif
, ttag_t tag
) 
 597         const TIFFFieldInfo
* fip 
= _TIFFFindFieldInfo(tif
, tag
, TIFF_ANY
); 
 598         if (!fip
) {                     /* unknown tag */ 
 599                 TIFFErrorExt(tif
->tif_clientdata
, "TIFFSetField", "%s: Unknown %stag %u", 
 600                     tif
->tif_name
, isPseudoTag(tag
) ? "pseudo-" : "", tag
); 
 603         if (tag 
!= TIFFTAG_IMAGELENGTH 
&& (tif
->tif_flags 
& TIFF_BEENWRITING
) && 
 604             !fip
->field_oktochange
) { 
 606                  * Consult info table to see if tag can be changed 
 607                  * after we've started writing.  We only allow changes 
 608                  * to those tags that don't/shouldn't affect the 
 609                  * compression and/or format of the data. 
 611                 TIFFErrorExt(tif
->tif_clientdata
, "TIFFSetField", 
 612                     "%s: Cannot modify tag \"%s\" while writing", 
 613                     tif
->tif_name
, fip
->field_name
); 
 620  * Record the value of a field in the 
 621  * internal directory structure.  The 
 622  * field will be written to the file 
 623  * when/if the directory structure is 
 627 TIFFSetField(TIFF
* tif
, ttag_t tag
, ...) 
 633         status 
= TIFFVSetField(tif
, tag
, ap
); 
 639  * Like TIFFSetField, but taking a varargs 
 640  * parameter list.  This routine is useful 
 641  * for building higher-level interfaces on 
 642  * top of the library. 
 645 TIFFVSetField(TIFF
* tif
, ttag_t tag
, va_list ap
) 
 647         return OkToChangeTag(tif
, tag
) ? 
 648             (*tif
->tif_tagmethods
.vsetfield
)(tif
, tag
, ap
) : 0; 
 652 _TIFFVGetField(TIFF
* tif
, ttag_t tag
, va_list ap
) 
 654     TIFFDirectory
* td 
= &tif
->tif_dir
; 
 658         case TIFFTAG_SUBFILETYPE
: 
 659             *va_arg(ap
, uint32
*) = td
->td_subfiletype
; 
 661         case TIFFTAG_IMAGEWIDTH
: 
 662             *va_arg(ap
, uint32
*) = td
->td_imagewidth
; 
 664         case TIFFTAG_IMAGELENGTH
: 
 665             *va_arg(ap
, uint32
*) = td
->td_imagelength
; 
 667         case TIFFTAG_BITSPERSAMPLE
: 
 668             *va_arg(ap
, uint16
*) = td
->td_bitspersample
; 
 670         case TIFFTAG_COMPRESSION
: 
 671             *va_arg(ap
, uint16
*) = td
->td_compression
; 
 673         case TIFFTAG_PHOTOMETRIC
: 
 674             *va_arg(ap
, uint16
*) = td
->td_photometric
; 
 676         case TIFFTAG_THRESHHOLDING
: 
 677             *va_arg(ap
, uint16
*) = td
->td_threshholding
; 
 679         case TIFFTAG_FILLORDER
: 
 680             *va_arg(ap
, uint16
*) = td
->td_fillorder
; 
 682         case TIFFTAG_ORIENTATION
: 
 683             *va_arg(ap
, uint16
*) = td
->td_orientation
; 
 685         case TIFFTAG_SAMPLESPERPIXEL
: 
 686             *va_arg(ap
, uint16
*) = td
->td_samplesperpixel
; 
 688         case TIFFTAG_ROWSPERSTRIP
: 
 689             *va_arg(ap
, uint32
*) = td
->td_rowsperstrip
; 
 691         case TIFFTAG_MINSAMPLEVALUE
: 
 692             *va_arg(ap
, uint16
*) = td
->td_minsamplevalue
; 
 694         case TIFFTAG_MAXSAMPLEVALUE
: 
 695             *va_arg(ap
, uint16
*) = td
->td_maxsamplevalue
; 
 697         case TIFFTAG_SMINSAMPLEVALUE
: 
 698             *va_arg(ap
, double*) = td
->td_sminsamplevalue
; 
 700         case TIFFTAG_SMAXSAMPLEVALUE
: 
 701             *va_arg(ap
, double*) = td
->td_smaxsamplevalue
; 
 703         case TIFFTAG_XRESOLUTION
: 
 704             *va_arg(ap
, float*) = td
->td_xresolution
; 
 706         case TIFFTAG_YRESOLUTION
: 
 707             *va_arg(ap
, float*) = td
->td_yresolution
; 
 709         case TIFFTAG_PLANARCONFIG
: 
 710             *va_arg(ap
, uint16
*) = td
->td_planarconfig
; 
 712         case TIFFTAG_XPOSITION
: 
 713             *va_arg(ap
, float*) = td
->td_xposition
; 
 715         case TIFFTAG_YPOSITION
: 
 716             *va_arg(ap
, float*) = td
->td_yposition
; 
 718         case TIFFTAG_RESOLUTIONUNIT
: 
 719             *va_arg(ap
, uint16
*) = td
->td_resolutionunit
; 
 721         case TIFFTAG_PAGENUMBER
: 
 722             *va_arg(ap
, uint16
*) = td
->td_pagenumber
[0]; 
 723             *va_arg(ap
, uint16
*) = td
->td_pagenumber
[1]; 
 725         case TIFFTAG_HALFTONEHINTS
: 
 726             *va_arg(ap
, uint16
*) = td
->td_halftonehints
[0]; 
 727             *va_arg(ap
, uint16
*) = td
->td_halftonehints
[1]; 
 729         case TIFFTAG_COLORMAP
: 
 730             *va_arg(ap
, uint16
**) = td
->td_colormap
[0]; 
 731             *va_arg(ap
, uint16
**) = td
->td_colormap
[1]; 
 732             *va_arg(ap
, uint16
**) = td
->td_colormap
[2]; 
 734         case TIFFTAG_STRIPOFFSETS
: 
 735         case TIFFTAG_TILEOFFSETS
: 
 736             *va_arg(ap
, uint32
**) = td
->td_stripoffset
; 
 738         case TIFFTAG_STRIPBYTECOUNTS
: 
 739         case TIFFTAG_TILEBYTECOUNTS
: 
 740             *va_arg(ap
, uint32
**) = td
->td_stripbytecount
; 
 742         case TIFFTAG_MATTEING
: 
 743             *va_arg(ap
, uint16
*) = 
 744                 (td
->td_extrasamples 
== 1 && 
 745                  td
->td_sampleinfo
[0] == EXTRASAMPLE_ASSOCALPHA
); 
 747         case TIFFTAG_EXTRASAMPLES
: 
 748             *va_arg(ap
, uint16
*) = td
->td_extrasamples
; 
 749             *va_arg(ap
, uint16
**) = td
->td_sampleinfo
; 
 751         case TIFFTAG_TILEWIDTH
: 
 752             *va_arg(ap
, uint32
*) = td
->td_tilewidth
; 
 754         case TIFFTAG_TILELENGTH
: 
 755             *va_arg(ap
, uint32
*) = td
->td_tilelength
; 
 757         case TIFFTAG_TILEDEPTH
: 
 758             *va_arg(ap
, uint32
*) = td
->td_tiledepth
; 
 760         case TIFFTAG_DATATYPE
: 
 761             switch (td
->td_sampleformat
) { 
 762                 case SAMPLEFORMAT_UINT
: 
 763                     *va_arg(ap
, uint16
*) = DATATYPE_UINT
; 
 765                 case SAMPLEFORMAT_INT
: 
 766                     *va_arg(ap
, uint16
*) = DATATYPE_INT
; 
 768                 case SAMPLEFORMAT_IEEEFP
: 
 769                     *va_arg(ap
, uint16
*) = DATATYPE_IEEEFP
; 
 771                 case SAMPLEFORMAT_VOID
: 
 772                     *va_arg(ap
, uint16
*) = DATATYPE_VOID
; 
 776         case TIFFTAG_SAMPLEFORMAT
: 
 777             *va_arg(ap
, uint16
*) = td
->td_sampleformat
; 
 779         case TIFFTAG_IMAGEDEPTH
: 
 780             *va_arg(ap
, uint32
*) = td
->td_imagedepth
; 
 783             *va_arg(ap
, uint16
*) = td
->td_nsubifd
; 
 784             *va_arg(ap
, uint32
**) = td
->td_subifd
; 
 786         case TIFFTAG_YCBCRPOSITIONING
: 
 787             *va_arg(ap
, uint16
*) = td
->td_ycbcrpositioning
; 
 789         case TIFFTAG_YCBCRSUBSAMPLING
: 
 790             *va_arg(ap
, uint16
*) = td
->td_ycbcrsubsampling
[0]; 
 791             *va_arg(ap
, uint16
*) = td
->td_ycbcrsubsampling
[1]; 
 793         case TIFFTAG_TRANSFERFUNCTION
: 
 794             *va_arg(ap
, uint16
**) = td
->td_transferfunction
[0]; 
 795             if (td
->td_samplesperpixel 
- td
->td_extrasamples 
> 1) { 
 796                 *va_arg(ap
, uint16
**) = td
->td_transferfunction
[1]; 
 797                 *va_arg(ap
, uint16
**) = td
->td_transferfunction
[2]; 
 800         case TIFFTAG_INKNAMES
: 
 801             *va_arg(ap
, char**) = td
->td_inknames
; 
 805             const TIFFFieldInfo
* fip 
= _TIFFFindFieldInfo(tif
, tag
, TIFF_ANY
); 
 809              * This can happen if multiple images are open with 
 810              * different codecs which have private tags.  The 
 811              * global tag information table may then have tags 
 812              * that are valid for one file but not the other.  
 813              * If the client tries to get a tag that is not valid 
 814              * for the image's codec then we'll arrive here. 
 816             if( fip 
== NULL 
|| fip
->field_bit 
!= FIELD_CUSTOM 
) 
 818                                 TIFFErrorExt(tif
->tif_clientdata
, "_TIFFVGetField", 
 819                           "%s: Invalid %stag \"%s\" (not supported by codec)", 
 820                           tif
->tif_name
, isPseudoTag(tag
) ? "pseudo-" : "", 
 821                           _TIFFFieldWithTag(tif
, tag
)->field_name
); 
 827              * Do we have a custom value? 
 830             for (i 
= 0; i 
< td
->td_customValueCount
; i
++) { 
 831                 TIFFTagValue 
*tv 
= td
->td_customValues 
+ i
; 
 833                 if (tv
->info
->field_tag 
!= tag
) 
 836                 if (fip
->field_passcount
) { 
 837                         if (fip
->field_readcount 
== TIFF_VARIABLE2
)  
 838                                 *va_arg(ap
, uint32
*) = (uint32
)tv
->count
; 
 839                         else    /* Assume TIFF_VARIABLE */ 
 840                                 *va_arg(ap
, uint16
*) = (uint16
)tv
->count
; 
 841                         *va_arg(ap
, void **) = tv
->value
; 
 844                         if ((fip
->field_type 
== TIFF_ASCII
 
 845                             || fip
->field_readcount 
== TIFF_VARIABLE
 
 846                             || fip
->field_readcount 
== TIFF_VARIABLE2
 
 847                             || fip
->field_readcount 
== TIFF_SPP
 
 849                             && fip
->field_tag 
!= TIFFTAG_PAGENUMBER
 
 850                             && fip
->field_tag 
!= TIFFTAG_HALFTONEHINTS
 
 851                             && fip
->field_tag 
!= TIFFTAG_YCBCRSUBSAMPLING
 
 852                             && fip
->field_tag 
!= TIFFTAG_DOTRANGE
) { 
 853                                 *va_arg(ap
, void **) = tv
->value
; 
 857                             char *val 
= (char *)tv
->value
; 
 859                             for (j 
= 0; j 
< tv
->count
; 
 860                                  j
++, val 
+= _TIFFDataSize(tv
->info
->field_type
)) { 
 861                                 switch (fip
->field_type
) { 
 864                                                 *va_arg(ap
, uint8
*) = 
 874                                                 *va_arg(ap
, uint16
*) = 
 879                                                 *va_arg(ap
, int16
*) = 
 885                                                 *va_arg(ap
, uint32
*) = 
 890                                                 *va_arg(ap
, int32
*) = 
 897                                                 *va_arg(ap
, float*) = 
 902                                                 *va_arg(ap
, double*) = 
 921  * Return the value of a field in the 
 922  * internal directory structure. 
 925 TIFFGetField(TIFF
* tif
, ttag_t tag
, ...) 
 931         status 
= TIFFVGetField(tif
, tag
, ap
); 
 937  * Like TIFFGetField, but taking a varargs 
 938  * parameter list.  This routine is useful 
 939  * for building higher-level interfaces on 
 940  * top of the library. 
 943 TIFFVGetField(TIFF
* tif
, ttag_t tag
, va_list ap
) 
 945         const TIFFFieldInfo
* fip 
= _TIFFFindFieldInfo(tif
, tag
, TIFF_ANY
); 
 946         return (fip 
&& (isPseudoTag(tag
) || TIFFFieldSet(tif
, fip
->field_bit
)) ? 
 947             (*tif
->tif_tagmethods
.vgetfield
)(tif
, tag
, ap
) : 0); 
 950 #define CleanupField(member) {          \ 
 952         _TIFFfree(td->member);          \ 
 958  * Release storage associated with a directory. 
 961 TIFFFreeDirectory(TIFF
* tif
) 
 963         TIFFDirectory 
*td 
= &tif
->tif_dir
; 
 966         _TIFFmemset(td
->td_fieldsset
, 0, FIELD_SETLONGS
); 
 967         CleanupField(td_colormap
[0]); 
 968         CleanupField(td_colormap
[1]); 
 969         CleanupField(td_colormap
[2]); 
 970         CleanupField(td_sampleinfo
); 
 971         CleanupField(td_subifd
); 
 972         CleanupField(td_inknames
); 
 973         CleanupField(td_transferfunction
[0]); 
 974         CleanupField(td_transferfunction
[1]); 
 975         CleanupField(td_transferfunction
[2]); 
 976         CleanupField(td_stripoffset
); 
 977         CleanupField(td_stripbytecount
); 
 978         TIFFClrFieldBit(tif
, FIELD_YCBCRSUBSAMPLING
); 
 979         TIFFClrFieldBit(tif
, FIELD_YCBCRPOSITIONING
); 
 981         /* Cleanup custom tag values */ 
 982         for( i 
= 0; i 
< td
->td_customValueCount
; i
++ ) { 
 983                 if (td
->td_customValues
[i
].value
) 
 984                         _TIFFfree(td
->td_customValues
[i
].value
); 
 987         td
->td_customValueCount 
= 0; 
 988         CleanupField(td_customValues
); 
 993  * Client Tag extension support (from Niles Ritter). 
 995 static TIFFExtendProc _TIFFextender 
= (TIFFExtendProc
) NULL
; 
 998 TIFFSetTagExtender(TIFFExtendProc extender
) 
1000         TIFFExtendProc prev 
= _TIFFextender
; 
1001         _TIFFextender 
= extender
; 
1006  * Setup for a new directory.  Should we automatically call 
1007  * TIFFWriteDirectory() if the current one is dirty? 
1009  * The newly created directory will not exist on the file till 
1010  * TIFFWriteDirectory(), TIFFFlush() or TIFFClose() is called. 
1013 TIFFCreateDirectory(TIFF
* tif
) 
1015     TIFFDefaultDirectory(tif
); 
1016     tif
->tif_diroff 
= 0; 
1017     tif
->tif_nextdiroff 
= 0; 
1018     tif
->tif_curoff 
= 0; 
1019     tif
->tif_row 
= (uint32
) -1; 
1020     tif
->tif_curstrip 
= (tstrip_t
) -1; 
1026  * Setup a default directory structure. 
1029 TIFFDefaultDirectory(TIFF
* tif
) 
1031         register TIFFDirectory
* td 
= &tif
->tif_dir
; 
1033         size_t tiffFieldInfoCount
; 
1034         const TIFFFieldInfo 
*tiffFieldInfo 
= 
1035                 _TIFFGetFieldInfo(&tiffFieldInfoCount
); 
1036         _TIFFSetupFieldInfo(tif
, tiffFieldInfo
, tiffFieldInfoCount
); 
1038         _TIFFmemset(td
, 0, sizeof (*td
)); 
1039         td
->td_fillorder 
= FILLORDER_MSB2LSB
; 
1040         td
->td_bitspersample 
= 1; 
1041         td
->td_threshholding 
= THRESHHOLD_BILEVEL
; 
1042         td
->td_orientation 
= ORIENTATION_TOPLEFT
; 
1043         td
->td_samplesperpixel 
= 1; 
1044         td
->td_rowsperstrip 
= (uint32
) -1; 
1045         td
->td_tilewidth 
= 0; 
1046         td
->td_tilelength 
= 0; 
1047         td
->td_tiledepth 
= 1; 
1048         td
->td_stripbytecountsorted 
= 1; /* Our own arrays always sorted. */ 
1049         td
->td_resolutionunit 
= RESUNIT_INCH
; 
1050         td
->td_sampleformat 
= SAMPLEFORMAT_UINT
; 
1051         td
->td_imagedepth 
= 1; 
1052         td
->td_ycbcrsubsampling
[0] = 2; 
1053         td
->td_ycbcrsubsampling
[1] = 2; 
1054         td
->td_ycbcrpositioning 
= YCBCRPOSITION_CENTERED
; 
1055         tif
->tif_postdecode 
= _TIFFNoPostDecode
; 
1056         tif
->tif_foundfield 
= NULL
; 
1057         tif
->tif_tagmethods
.vsetfield 
= _TIFFVSetField
; 
1058         tif
->tif_tagmethods
.vgetfield 
= _TIFFVGetField
; 
1059         tif
->tif_tagmethods
.printdir 
= NULL
; 
1061          *  Give client code a chance to install their own 
1062          *  tag extensions & methods, prior to compression overloads. 
1065                 (*_TIFFextender
)(tif
); 
1066         (void) TIFFSetField(tif
, TIFFTAG_COMPRESSION
, COMPRESSION_NONE
); 
1068          * NB: The directory is marked dirty as a result of setting 
1069          * up the default compression scheme.  However, this really 
1070          * isn't correct -- we want TIFF_DIRTYDIRECT to be set only 
1071          * if the user does something.  We could just do the setup 
1072          * by hand, but it seems better to use the normal mechanism 
1073          * (i.e. TIFFSetField). 
1075         tif
->tif_flags 
&= ~TIFF_DIRTYDIRECT
; 
1078          * As per http://bugzilla.remotesensing.org/show_bug.cgi?id=19 
1079          * we clear the ISTILED flag when setting up a new directory. 
1080          * Should we also be clearing stuff like INSUBIFD? 
1082         tif
->tif_flags 
&= ~TIFF_ISTILED
; 
1088 TIFFAdvanceDirectory(TIFF
* tif
, uint32
* nextdir
, toff_t
* off
) 
1090     static const char module[] = "TIFFAdvanceDirectory"; 
1094         toff_t poff
=*nextdir
; 
1095         if (poff
+sizeof(uint16
) > tif
->tif_size
) 
1097                         TIFFErrorExt(tif
->tif_clientdata
, module, "%s: Error fetching directory count", 
1101         _TIFFmemcpy(&dircount
, tif
->tif_base
+poff
, sizeof (uint16
)); 
1102         if (tif
->tif_flags 
& TIFF_SWAB
) 
1103             TIFFSwabShort(&dircount
); 
1104         poff
+=sizeof (uint16
)+dircount
*sizeof (TIFFDirEntry
); 
1107         if (((toff_t
) (poff
+sizeof (uint32
))) > tif
->tif_size
) 
1109                         TIFFErrorExt(tif
->tif_clientdata
, module, "%s: Error fetching directory link", 
1113         _TIFFmemcpy(nextdir
, tif
->tif_base
+poff
, sizeof (uint32
)); 
1114         if (tif
->tif_flags 
& TIFF_SWAB
) 
1115             TIFFSwabLong(nextdir
); 
1120         if (!SeekOK(tif
, *nextdir
) || 
1121             !ReadOK(tif
, &dircount
, sizeof (uint16
))) { 
1122                         TIFFErrorExt(tif
->tif_clientdata
, module, "%s: Error fetching directory count", 
1126         if (tif
->tif_flags 
& TIFF_SWAB
) 
1127             TIFFSwabShort(&dircount
); 
1129             *off 
= TIFFSeekFile(tif
, 
1130                                 dircount
*sizeof (TIFFDirEntry
), SEEK_CUR
); 
1132             (void) TIFFSeekFile(tif
, 
1133                                 dircount
*sizeof (TIFFDirEntry
), SEEK_CUR
); 
1134         if (!ReadOK(tif
, nextdir
, sizeof (uint32
))) { 
1135                         TIFFErrorExt(tif
->tif_clientdata
, module, "%s: Error fetching directory link", 
1139         if (tif
->tif_flags 
& TIFF_SWAB
) 
1140             TIFFSwabLong(nextdir
); 
1146  * Count the number of directories in a file. 
1149 TIFFNumberOfDirectories(TIFF
* tif
) 
1151     toff_t nextdir 
= tif
->tif_header
.tiff_diroff
; 
1154     while (nextdir 
!= 0 && TIFFAdvanceDirectory(tif
, &nextdir
, NULL
)) 
1160  * Set the n-th directory as the current directory. 
1161  * NB: Directories are numbered starting at 0. 
1164 TIFFSetDirectory(TIFF
* tif
, tdir_t dirn
) 
1169         nextdir 
= tif
->tif_header
.tiff_diroff
; 
1170         for (n 
= dirn
; n 
> 0 && nextdir 
!= 0; n
--) 
1171                 if (!TIFFAdvanceDirectory(tif
, &nextdir
, NULL
)) 
1173         tif
->tif_nextdiroff 
= nextdir
; 
1175          * Set curdir to the actual directory index.  The 
1176          * -1 is because TIFFReadDirectory will increment 
1177          * tif_curdir after successfully reading the directory. 
1179         tif
->tif_curdir 
= (dirn 
- n
) - 1; 
1181          * Reset tif_dirnumber counter and start new list of seen directories. 
1182          * We need this to prevent IFD loops. 
1184         tif
->tif_dirnumber 
= 0; 
1185         return (TIFFReadDirectory(tif
)); 
1189  * Set the current directory to be the directory 
1190  * located at the specified file offset.  This interface 
1191  * is used mainly to access directories linked with 
1192  * the SubIFD tag (e.g. thumbnail images). 
1195 TIFFSetSubDirectory(TIFF
* tif
, uint32 diroff
) 
1197         tif
->tif_nextdiroff 
= diroff
; 
1199          * Reset tif_dirnumber counter and start new list of seen directories. 
1200          * We need this to prevent IFD loops. 
1202         tif
->tif_dirnumber 
= 0; 
1203         return (TIFFReadDirectory(tif
)); 
1207  * Return file offset of the current directory. 
1210 TIFFCurrentDirOffset(TIFF
* tif
) 
1212         return (tif
->tif_diroff
); 
1216  * Return an indication of whether or not we are 
1217  * at the last directory in the file. 
1220 TIFFLastDirectory(TIFF
* tif
) 
1222         return (tif
->tif_nextdiroff 
== 0); 
1226  * Unlink the specified directory from the directory chain. 
1229 TIFFUnlinkDirectory(TIFF
* tif
, tdir_t dirn
) 
1231         static const char module[] = "TIFFUnlinkDirectory"; 
1236         if (tif
->tif_mode 
== O_RDONLY
) { 
1237                 TIFFErrorExt(tif
->tif_clientdata
, module, 
1238                              "Can not unlink directory in read-only file"); 
1242          * Go to the directory before the one we want 
1243          * to unlink and nab the offset of the link 
1244          * field we'll need to patch. 
1246         nextdir 
= tif
->tif_header
.tiff_diroff
; 
1247         off 
= sizeof (uint16
) + sizeof (uint16
); 
1248         for (n 
= dirn
-1; n 
> 0; n
--) { 
1250                         TIFFErrorExt(tif
->tif_clientdata
, module, "Directory %d does not exist", dirn
); 
1253                 if (!TIFFAdvanceDirectory(tif
, &nextdir
, &off
)) 
1257          * Advance to the directory to be unlinked and fetch 
1258          * the offset of the directory that follows. 
1260         if (!TIFFAdvanceDirectory(tif
, &nextdir
, NULL
)) 
1263          * Go back and patch the link field of the preceding 
1264          * directory to point to the offset of the directory 
1267         (void) TIFFSeekFile(tif
, off
, SEEK_SET
); 
1268         if (tif
->tif_flags 
& TIFF_SWAB
) 
1269                 TIFFSwabLong(&nextdir
); 
1270         if (!WriteOK(tif
, &nextdir
, sizeof (uint32
))) { 
1271                 TIFFErrorExt(tif
->tif_clientdata
, module, "Error writing directory link"); 
1275          * Leave directory state setup safely.  We don't have 
1276          * facilities for doing inserting and removing directories, 
1277          * so it's safest to just invalidate everything.  This 
1278          * means that the caller can only append to the directory 
1281         (*tif
->tif_cleanup
)(tif
); 
1282         if ((tif
->tif_flags 
& TIFF_MYBUFFER
) && tif
->tif_rawdata
) { 
1283                 _TIFFfree(tif
->tif_rawdata
); 
1284                 tif
->tif_rawdata 
= NULL
; 
1287         tif
->tif_flags 
&= ~(TIFF_BEENWRITING
|TIFF_BUFFERSETUP
|TIFF_POSTENCODE
); 
1288         TIFFFreeDirectory(tif
); 
1289         TIFFDefaultDirectory(tif
); 
1290         tif
->tif_diroff 
= 0;                    /* force link on next write */ 
1291         tif
->tif_nextdiroff 
= 0;                /* next write must be at end */ 
1292         tif
->tif_curoff 
= 0; 
1293         tif
->tif_row 
= (uint32
) -1; 
1294         tif
->tif_curstrip 
= (tstrip_t
) -1; 
1300  * Author: Bruce Cameron <cameron@petris.com> 
1302  * Set a table of tags that are to be replaced during directory process by the 
1303  * 'IGNORE' state - or return TRUE/FALSE for the requested tag such that 
1304  * 'ReadDirectory' can use the stored information. 
1306  * FIXME: this is never used properly. Should be removed in the future. 
1309 TIFFReassignTagToIgnore (enum TIFFIgnoreSense task
, int TIFFtagID
) 
1311     static int TIFFignoretags 
[FIELD_LAST
]; 
1312     static int tagcount 
= 0 ; 
1313     int         i
;                                      /* Loop index */ 
1314     int         j
;                                      /* Loop index */ 
1319         if ( tagcount 
< (FIELD_LAST 
- 1) ) 
1321             for ( j 
= 0 ; j 
< tagcount 
; ++j 
) 
1322             {                                   /* Do not add duplicate tag */ 
1323                 if ( TIFFignoretags 
[j
] == TIFFtagID 
) 
1326             TIFFignoretags 
[tagcount
++] = TIFFtagID 
; 
1332         for ( i 
= 0 ; i 
< tagcount 
; ++i 
) 
1334             if ( TIFFignoretags 
[i
] == TIFFtagID 
) 
1340         tagcount 
= 0 ;                  /* Clear the list */ 
1350 /* vim: set ts=8 sts=8 sw=8 noet: */