"Initial commit to Gerrit"
[profile/ivi/libtiff.git] / libtiff / tif_dir.c
1 /* $Id: tif_dir.c,v 1.75.2.6 2010-07-02 09:49:23 dron 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 setByteArray(void** vpp, void* vp, size_t nmemb, size_t elem_size)
45 {
46         if (*vpp)
47                 _TIFFfree(*vpp), *vpp = 0;
48         if (vp) {
49                 tsize_t bytes = nmemb * elem_size;
50                 if (elem_size && bytes / elem_size == nmemb)
51                         *vpp = (void*) _TIFFmalloc(bytes);
52                 if (*vpp)
53                         _TIFFmemcpy(*vpp, vp, bytes);
54         }
55 }
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)); }
70
71 /*
72  * Install extra samples information.
73  */
74 static int
75 setExtraSamples(TIFFDirectory* td, va_list ap, uint32* v)
76 {
77 /* XXX: Unassociated alpha data == 999 is a known Corel Draw bug, see below */
78 #define EXTRASAMPLE_COREL_UNASSALPHA 999 
79
80         uint16* va;
81         uint32 i;
82
83         *v = va_arg(ap, uint32);
84         if ((uint16) *v > td->td_samplesperpixel)
85                 return 0;
86         va = va_arg(ap, uint16*);
87         if (*v > 0 && va == NULL)               /* typically missing param */
88                 return 0;
89         for (i = 0; i < *v; i++) {
90                 if (va[i] > EXTRASAMPLE_UNASSALPHA) {
91                         /*
92                          * XXX: Corel Draw is known to produce incorrect
93                          * ExtraSamples tags which must be patched here if we
94                          * want to be able to open some of the damaged TIFF
95                          * files: 
96                          */
97                         if (va[i] == EXTRASAMPLE_COREL_UNASSALPHA)
98                                 va[i] = EXTRASAMPLE_UNASSALPHA;
99                         else
100                                 return 0;
101                 }
102         }
103         td->td_extrasamples = (uint16) *v;
104         _TIFFsetShortArray(&td->td_sampleinfo, va, td->td_extrasamples);
105         return 1;
106
107 #undef EXTRASAMPLE_COREL_UNASSALPHA
108 }
109
110 static uint32
111 checkInkNamesString(TIFF* tif, uint32 slen, const char* s)
112 {
113         TIFFDirectory* td = &tif->tif_dir;
114         uint16 i = td->td_samplesperpixel;
115
116         if (slen > 0) {
117                 const char* ep = s+slen;
118                 const char* cp = s;
119                 for (; i > 0; i--) {
120                         for (; *cp != '\0'; cp++)
121                                 if (cp >= ep)
122                                         goto bad;
123                         cp++;                           /* skip \0 */
124                 }
125                 return (cp-s);
126         }
127 bad:
128         TIFFErrorExt(tif->tif_clientdata, "TIFFSetField",
129             "%s: Invalid InkNames value; expecting %d names, found %d",
130             tif->tif_name,
131             td->td_samplesperpixel,
132             td->td_samplesperpixel-i);
133         return (0);
134 }
135
136 static int
137 _TIFFVSetField(TIFF* tif, ttag_t tag, va_list ap)
138 {
139         static const char module[] = "_TIFFVSetField";
140
141         TIFFDirectory* td = &tif->tif_dir;
142         int status = 1;
143         uint32 v32, i, v;
144         char* s;
145
146         switch (tag) {
147         case TIFFTAG_SUBFILETYPE:
148                 td->td_subfiletype = va_arg(ap, uint32);
149                 break;
150         case TIFFTAG_IMAGEWIDTH:
151                 td->td_imagewidth = va_arg(ap, uint32);
152                 break;
153         case TIFFTAG_IMAGELENGTH:
154                 td->td_imagelength = va_arg(ap, uint32);
155                 break;
156         case TIFFTAG_BITSPERSAMPLE:
157                 td->td_bitspersample = (uint16) va_arg(ap, int);
158                 /*
159                  * If the data require post-decoding processing to byte-swap
160                  * samples, set it up here.  Note that since tags are required
161                  * to be ordered, compression code can override this behaviour
162                  * in the setup method if it wants to roll the post decoding
163                  * work in with its normal work.
164                  */
165                 if (tif->tif_flags & TIFF_SWAB) {
166                         if (td->td_bitspersample == 8)
167                                 tif->tif_postdecode = _TIFFNoPostDecode;
168                         else if (td->td_bitspersample == 16)
169                                 tif->tif_postdecode = _TIFFSwab16BitData;
170                         else if (td->td_bitspersample == 24)
171                                 tif->tif_postdecode = _TIFFSwab24BitData;
172                         else if (td->td_bitspersample == 32)
173                                 tif->tif_postdecode = _TIFFSwab32BitData;
174                         else if (td->td_bitspersample == 64)
175                                 tif->tif_postdecode = _TIFFSwab64BitData;
176                         else if (td->td_bitspersample == 128) /* two 64's */
177                                 tif->tif_postdecode = _TIFFSwab64BitData;
178                 }
179                 break;
180         case TIFFTAG_COMPRESSION:
181                 v = va_arg(ap, uint32) & 0xffff;
182                 /*
183                  * If we're changing the compression scheme, the notify the
184                  * previous module so that it can cleanup any state it's
185                  * setup.
186                  */
187                 if (TIFFFieldSet(tif, FIELD_COMPRESSION)) {
188                         if (td->td_compression == v)
189                                 break;
190                         (*tif->tif_cleanup)(tif);
191                         tif->tif_flags &= ~TIFF_CODERSETUP;
192                 }
193                 /*
194                  * Setup new compression routine state.
195                  */
196                 if( (status = TIFFSetCompressionScheme(tif, v)) != 0 )
197                     td->td_compression = (uint16) v;
198                 else
199                     status = 0;
200                 break;
201         case TIFFTAG_PHOTOMETRIC:
202                 td->td_photometric = (uint16) va_arg(ap, int);
203                 break;
204         case TIFFTAG_THRESHHOLDING:
205                 td->td_threshholding = (uint16) va_arg(ap, int);
206                 break;
207         case TIFFTAG_FILLORDER:
208                 v = va_arg(ap, uint32);
209                 if (v != FILLORDER_LSB2MSB && v != FILLORDER_MSB2LSB)
210                         goto badvalue;
211                 td->td_fillorder = (uint16) v;
212                 break;
213         case TIFFTAG_ORIENTATION:
214                 v = va_arg(ap, uint32);
215                 if (v < ORIENTATION_TOPLEFT || ORIENTATION_LEFTBOT < v)
216                         goto badvalue;
217                 else
218                         td->td_orientation = (uint16) v;
219                 break;
220         case TIFFTAG_SAMPLESPERPIXEL:
221                 /* XXX should cross check -- e.g. if pallette, then 1 */
222                 v = va_arg(ap, uint32);
223                 if (v == 0)
224                         goto badvalue;
225                 td->td_samplesperpixel = (uint16) v;
226                 break;
227         case TIFFTAG_ROWSPERSTRIP:
228                 v32 = va_arg(ap, uint32);
229                 if (v32 == 0)
230                         goto badvalue32;
231                 td->td_rowsperstrip = v32;
232                 if (!TIFFFieldSet(tif, FIELD_TILEDIMENSIONS)) {
233                         td->td_tilelength = v32;
234                         td->td_tilewidth = td->td_imagewidth;
235                 }
236                 break;
237         case TIFFTAG_MINSAMPLEVALUE:
238                 td->td_minsamplevalue = (uint16) va_arg(ap, int);
239                 break;
240         case TIFFTAG_MAXSAMPLEVALUE:
241                 td->td_maxsamplevalue = (uint16) va_arg(ap, int);
242                 break;
243         case TIFFTAG_SMINSAMPLEVALUE:
244                 td->td_sminsamplevalue = va_arg(ap, double);
245                 break;
246         case TIFFTAG_SMAXSAMPLEVALUE:
247                 td->td_smaxsamplevalue = va_arg(ap, double);
248                 break;
249         case TIFFTAG_XRESOLUTION:
250                 td->td_xresolution = (float) va_arg(ap, double);
251                 break;
252         case TIFFTAG_YRESOLUTION:
253                 td->td_yresolution = (float) va_arg(ap, double);
254                 break;
255         case TIFFTAG_PLANARCONFIG:
256                 v = va_arg(ap, uint32);
257                 if (v != PLANARCONFIG_CONTIG && v != PLANARCONFIG_SEPARATE)
258                         goto badvalue;
259                 td->td_planarconfig = (uint16) v;
260                 break;
261         case TIFFTAG_XPOSITION:
262                 td->td_xposition = (float) va_arg(ap, double);
263                 break;
264         case TIFFTAG_YPOSITION:
265                 td->td_yposition = (float) va_arg(ap, double);
266                 break;
267         case TIFFTAG_RESOLUTIONUNIT:
268                 v = va_arg(ap, uint32);
269                 if (v < RESUNIT_NONE || RESUNIT_CENTIMETER < v)
270                         goto badvalue;
271                 td->td_resolutionunit = (uint16) v;
272                 break;
273         case TIFFTAG_PAGENUMBER:
274                 td->td_pagenumber[0] = (uint16) va_arg(ap, int);
275                 td->td_pagenumber[1] = (uint16) va_arg(ap, int);
276                 break;
277         case TIFFTAG_HALFTONEHINTS:
278                 td->td_halftonehints[0] = (uint16) va_arg(ap, int);
279                 td->td_halftonehints[1] = (uint16) va_arg(ap, int);
280                 break;
281         case TIFFTAG_COLORMAP:
282                 v32 = (uint32)(1L<<td->td_bitspersample);
283                 _TIFFsetShortArray(&td->td_colormap[0], va_arg(ap, uint16*), v32);
284                 _TIFFsetShortArray(&td->td_colormap[1], va_arg(ap, uint16*), v32);
285                 _TIFFsetShortArray(&td->td_colormap[2], va_arg(ap, uint16*), v32);
286                 break;
287         case TIFFTAG_EXTRASAMPLES:
288                 if (!setExtraSamples(td, ap, &v))
289                         goto badvalue;
290                 break;
291         case TIFFTAG_MATTEING:
292                 td->td_extrasamples = (uint16) (va_arg(ap, int) != 0);
293                 if (td->td_extrasamples) {
294                         uint16 sv = EXTRASAMPLE_ASSOCALPHA;
295                         _TIFFsetShortArray(&td->td_sampleinfo, &sv, 1);
296                 }
297                 break;
298         case TIFFTAG_TILEWIDTH:
299                 v32 = va_arg(ap, uint32);
300                 if (v32 % 16) {
301                         if (tif->tif_mode != O_RDONLY)
302                                 goto badvalue32;
303                         TIFFWarningExt(tif->tif_clientdata, tif->tif_name,
304                                 "Nonstandard tile width %d, convert file", v32);
305                 }
306                 td->td_tilewidth = v32;
307                 tif->tif_flags |= TIFF_ISTILED;
308                 break;
309         case TIFFTAG_TILELENGTH:
310                 v32 = va_arg(ap, uint32);
311                 if (v32 % 16) {
312                         if (tif->tif_mode != O_RDONLY)
313                                 goto badvalue32;
314                         TIFFWarningExt(tif->tif_clientdata, tif->tif_name,
315                             "Nonstandard tile length %d, convert file", v32);
316                 }
317                 td->td_tilelength = v32;
318                 tif->tif_flags |= TIFF_ISTILED;
319                 break;
320         case TIFFTAG_TILEDEPTH:
321                 v32 = va_arg(ap, uint32);
322                 if (v32 == 0)
323                         goto badvalue32;
324                 td->td_tiledepth = v32;
325                 break;
326         case TIFFTAG_DATATYPE:
327                 v = va_arg(ap, uint32);
328                 switch (v) {
329                 case DATATYPE_VOID:     v = SAMPLEFORMAT_VOID;  break;
330                 case DATATYPE_INT:      v = SAMPLEFORMAT_INT;   break;
331                 case DATATYPE_UINT:     v = SAMPLEFORMAT_UINT;  break;
332                 case DATATYPE_IEEEFP:   v = SAMPLEFORMAT_IEEEFP;break;
333                 default:                goto badvalue;
334                 }
335                 td->td_sampleformat = (uint16) v;
336                 break;
337         case TIFFTAG_SAMPLEFORMAT:
338                 v = va_arg(ap, uint32);
339                 if (v < SAMPLEFORMAT_UINT || SAMPLEFORMAT_COMPLEXIEEEFP < v)
340                         goto badvalue;
341                 td->td_sampleformat = (uint16) v;
342
343                 /*  Try to fix up the SWAB function for complex data. */
344                 if( td->td_sampleformat == SAMPLEFORMAT_COMPLEXINT 
345                     && td->td_bitspersample == 32
346                     && tif->tif_postdecode == _TIFFSwab32BitData )
347                     tif->tif_postdecode = _TIFFSwab16BitData;
348                 else if( (td->td_sampleformat == SAMPLEFORMAT_COMPLEXINT 
349                           || td->td_sampleformat == SAMPLEFORMAT_COMPLEXIEEEFP)
350                          && td->td_bitspersample == 64
351                          && tif->tif_postdecode == _TIFFSwab64BitData )
352                     tif->tif_postdecode = _TIFFSwab32BitData;
353                 break;
354         case TIFFTAG_IMAGEDEPTH:
355                 td->td_imagedepth = va_arg(ap, uint32);
356                 break;
357         case TIFFTAG_SUBIFD:
358                 if ((tif->tif_flags & TIFF_INSUBIFD) == 0) {
359                         td->td_nsubifd = (uint16) va_arg(ap, int);
360                         _TIFFsetLongArray(&td->td_subifd, va_arg(ap, uint32*),
361                             (long) td->td_nsubifd);
362                 } else {
363                         TIFFErrorExt(tif->tif_clientdata, module,
364                                      "%s: Sorry, cannot nest SubIFDs",
365                                      tif->tif_name);
366                         status = 0;
367                 }
368                 break;
369         case TIFFTAG_YCBCRPOSITIONING:
370                 td->td_ycbcrpositioning = (uint16) va_arg(ap, int);
371                 break;
372         case TIFFTAG_YCBCRSUBSAMPLING:
373                 td->td_ycbcrsubsampling[0] = (uint16) va_arg(ap, int);
374                 td->td_ycbcrsubsampling[1] = (uint16) va_arg(ap, int);
375                 break;
376         case TIFFTAG_TRANSFERFUNCTION:
377                 v = (td->td_samplesperpixel - td->td_extrasamples) > 1 ? 3 : 1;
378                 for (i = 0; i < v; i++)
379                         _TIFFsetShortArray(&td->td_transferfunction[i],
380                             va_arg(ap, uint16*), 1L<<td->td_bitspersample);
381                 break;
382         case TIFFTAG_REFERENCEBLACKWHITE:
383                 /* XXX should check for null range */
384                 _TIFFsetFloatArray(&td->td_refblackwhite, va_arg(ap, float*), 6);
385                 break;
386         case TIFFTAG_INKNAMES:
387                 v = va_arg(ap, uint32);
388                 s = va_arg(ap, char*);
389                 v = checkInkNamesString(tif, v, s);
390                 status = v > 0;
391                 if( v > 0 ) {
392                         _TIFFsetNString(&td->td_inknames, s, v);
393                         td->td_inknameslen = v;
394                 }
395                 break;
396         default: {
397             TIFFTagValue *tv;
398             int tv_size, iCustom;
399             const TIFFFieldInfo* fip = _TIFFFindFieldInfo(tif, tag, TIFF_ANY);
400
401             /*
402              * This can happen if multiple images are open with different
403              * codecs which have private tags.  The global tag information
404              * table may then have tags that are valid for one file but not
405              * the other. If the client tries to set a tag that is not valid
406              * for the image's codec then we'll arrive here.  This
407              * happens, for example, when tiffcp is used to convert between
408              * compression schemes and codec-specific tags are blindly copied.
409              */
410             if(fip == NULL || fip->field_bit != FIELD_CUSTOM) {
411                 TIFFErrorExt(tif->tif_clientdata, module,
412                              "%s: Invalid %stag \"%s\" (not supported by codec)",
413                              tif->tif_name, isPseudoTag(tag) ? "pseudo-" : "",
414                              fip ? fip->field_name : "Unknown");
415                 status = 0;
416                 break;
417             }
418
419             /*
420              * Find the existing entry for this custom value.
421              */
422             tv = NULL;
423             for (iCustom = 0; iCustom < td->td_customValueCount; iCustom++) {
424                     if (td->td_customValues[iCustom].info->field_tag == tag) {
425                             tv = td->td_customValues + iCustom;
426                             if (tv->value != NULL) {
427                                     _TIFFfree(tv->value);
428                                     tv->value = NULL;
429                             }
430                             break;
431                     }
432             }
433
434             /*
435              * Grow the custom list if the entry was not found.
436              */
437             if(tv == NULL) {
438                 TIFFTagValue    *new_customValues;
439                 
440                 td->td_customValueCount++;
441                 new_customValues = (TIFFTagValue *)
442                         _TIFFrealloc(td->td_customValues,
443                                      sizeof(TIFFTagValue) * td->td_customValueCount);
444                 if (!new_customValues) {
445                         TIFFErrorExt(tif->tif_clientdata, module,
446                 "%s: Failed to allocate space for list of custom values",
447                                   tif->tif_name);
448                         status = 0;
449                         goto end;
450                 }
451
452                 td->td_customValues = new_customValues;
453
454                 tv = td->td_customValues + (td->td_customValueCount - 1);
455                 tv->info = fip;
456                 tv->value = NULL;
457                 tv->count = 0;
458             }
459
460             /*
461              * Set custom value ... save a copy of the custom tag value.
462              */
463             tv_size = _TIFFDataSize(fip->field_type);
464             if (tv_size == 0) {
465                     status = 0;
466                     TIFFErrorExt(tif->tif_clientdata, module,
467                                  "%s: Bad field type %d for \"%s\"",
468                                  tif->tif_name, fip->field_type,
469                                  fip->field_name);
470                     goto end;
471             }
472            
473             if(fip->field_passcount) {
474                     if (fip->field_writecount == TIFF_VARIABLE2)
475                         tv->count = (uint32) va_arg(ap, uint32);
476                     else
477                         tv->count = (int) va_arg(ap, int);
478             } else if (fip->field_writecount == TIFF_VARIABLE
479                        || fip->field_writecount == TIFF_VARIABLE2)
480                 tv->count = 1;
481             else if (fip->field_writecount == TIFF_SPP)
482                 tv->count = td->td_samplesperpixel;
483             else
484                 tv->count = fip->field_writecount;
485             
486     
487             if (fip->field_type == TIFF_ASCII)
488                     _TIFFsetString((char **)&tv->value, va_arg(ap, char *));
489             else {
490                 tv->value = _TIFFCheckMalloc(tif, tv_size, tv->count,
491                                              "Tag Value");
492                 if (!tv->value) {
493                     status = 0;
494                     goto end;
495                 }
496
497                 if ((fip->field_passcount
498                     || fip->field_writecount == TIFF_VARIABLE
499                     || fip->field_writecount == TIFF_VARIABLE2
500                     || fip->field_writecount == TIFF_SPP
501                     || tv->count > 1)
502                     && fip->field_tag != TIFFTAG_PAGENUMBER
503                     && fip->field_tag != TIFFTAG_HALFTONEHINTS
504                     && fip->field_tag != TIFFTAG_YCBCRSUBSAMPLING
505                     && fip->field_tag != TIFFTAG_DOTRANGE) {
506                     _TIFFmemcpy(tv->value, va_arg(ap, void *),
507                                 tv->count * tv_size);
508                 } else {
509                     /*
510                      * XXX: The following loop required to handle
511                      * TIFFTAG_PAGENUMBER, TIFFTAG_HALFTONEHINTS,
512                      * TIFFTAG_YCBCRSUBSAMPLING and TIFFTAG_DOTRANGE tags.
513                      * These tags are actually arrays and should be passed as
514                      * array pointers to TIFFSetField() function, but actually
515                      * passed as a list of separate values. This behaviour
516                      * must be changed in the future!
517                      */
518                     int i;
519                     char *val = (char *)tv->value;
520
521                     for (i = 0; i < tv->count; i++, val += tv_size) {
522                             switch (fip->field_type) {
523                                 case TIFF_BYTE:
524                                 case TIFF_UNDEFINED:
525                                     {
526                                         uint8 v = (uint8)va_arg(ap, int);
527                                         _TIFFmemcpy(val, &v, tv_size);
528                                     }
529                                     break;
530                                 case TIFF_SBYTE:
531                                     {
532                                         int8 v = (int8)va_arg(ap, int);
533                                         _TIFFmemcpy(val, &v, tv_size);
534                                     }
535                                     break;
536                                 case TIFF_SHORT:
537                                     {
538                                         uint16 v = (uint16)va_arg(ap, int);
539                                         _TIFFmemcpy(val, &v, tv_size);
540                                     }
541                                     break;
542                                 case TIFF_SSHORT:
543                                     {
544                                         int16 v = (int16)va_arg(ap, int);
545                                         _TIFFmemcpy(val, &v, tv_size);
546                                     }
547                                     break;
548                                 case TIFF_LONG:
549                                 case TIFF_IFD:
550                                     {
551                                         uint32 v = va_arg(ap, uint32);
552                                         _TIFFmemcpy(val, &v, tv_size);
553                                     }
554                                     break;
555                                 case TIFF_SLONG:
556                                     {
557                                         int32 v = va_arg(ap, int32);
558                                         _TIFFmemcpy(val, &v, tv_size);
559                                     }
560                                     break;
561                                 case TIFF_RATIONAL:
562                                 case TIFF_SRATIONAL:
563                                 case TIFF_FLOAT:
564                                     {
565                                         float v = (float)va_arg(ap, double);
566                                         _TIFFmemcpy(val, &v, tv_size);
567                                     }
568                                     break;
569                                 case TIFF_DOUBLE:
570                                     {
571                                         double v = va_arg(ap, double);
572                                         _TIFFmemcpy(val, &v, tv_size);
573                                     }
574                                     break;
575                                 default:
576                                     _TIFFmemset(val, 0, tv_size);
577                                     status = 0;
578                                     break;
579                             }
580                     }
581                 }
582             }
583           }
584         }
585         if (status) {
586                 TIFFSetFieldBit(tif, _TIFFFieldWithTag(tif, tag)->field_bit);
587                 tif->tif_flags |= TIFF_DIRTYDIRECT;
588         }
589
590 end:
591         va_end(ap);
592         return (status);
593 badvalue:
594         TIFFErrorExt(tif->tif_clientdata, module,
595                      "%s: Bad value %d for \"%s\" tag",
596                      tif->tif_name, v,
597                      _TIFFFieldWithTag(tif, tag)->field_name);
598         va_end(ap);
599         return (0);
600 badvalue32:
601         TIFFErrorExt(tif->tif_clientdata, module,
602                      "%s: Bad value %u for \"%s\" tag",
603                      tif->tif_name, v32,
604                      _TIFFFieldWithTag(tif, tag)->field_name);
605         va_end(ap);
606         return (0);
607 }
608
609 /*
610  * Return 1/0 according to whether or not
611  * it is permissible to set the tag's value.
612  * Note that we allow ImageLength to be changed
613  * so that we can append and extend to images.
614  * Any other tag may not be altered once writing
615  * has commenced, unless its value has no effect
616  * on the format of the data that is written.
617  */
618 static int
619 OkToChangeTag(TIFF* tif, ttag_t tag)
620 {
621         const TIFFFieldInfo* fip = _TIFFFindFieldInfo(tif, tag, TIFF_ANY);
622         if (!fip) {                     /* unknown tag */
623                 TIFFErrorExt(tif->tif_clientdata, "TIFFSetField", "%s: Unknown %stag %u",
624                     tif->tif_name, isPseudoTag(tag) ? "pseudo-" : "", tag);
625                 return (0);
626         }
627         if (tag != TIFFTAG_IMAGELENGTH && (tif->tif_flags & TIFF_BEENWRITING) &&
628             !fip->field_oktochange) {
629                 /*
630                  * Consult info table to see if tag can be changed
631                  * after we've started writing.  We only allow changes
632                  * to those tags that don't/shouldn't affect the
633                  * compression and/or format of the data.
634                  */
635                 TIFFErrorExt(tif->tif_clientdata, "TIFFSetField",
636                     "%s: Cannot modify tag \"%s\" while writing",
637                     tif->tif_name, fip->field_name);
638                 return (0);
639         }
640         return (1);
641 }
642
643 /*
644  * Record the value of a field in the
645  * internal directory structure.  The
646  * field will be written to the file
647  * when/if the directory structure is
648  * updated.
649  */
650 int
651 TIFFSetField(TIFF* tif, ttag_t tag, ...)
652 {
653         va_list ap;
654         int status;
655
656         va_start(ap, tag);
657         status = TIFFVSetField(tif, tag, ap);
658         va_end(ap);
659         return (status);
660 }
661
662 /*
663  * Like TIFFSetField, but taking a varargs
664  * parameter list.  This routine is useful
665  * for building higher-level interfaces on
666  * top of the library.
667  */
668 int
669 TIFFVSetField(TIFF* tif, ttag_t tag, va_list ap)
670 {
671         return OkToChangeTag(tif, tag) ?
672             (*tif->tif_tagmethods.vsetfield)(tif, tag, ap) : 0;
673 }
674
675 static int
676 _TIFFVGetField(TIFF* tif, ttag_t tag, va_list ap)
677 {
678     TIFFDirectory* td = &tif->tif_dir;
679     int            ret_val = 1;
680
681     switch (tag) {
682         case TIFFTAG_SUBFILETYPE:
683             *va_arg(ap, uint32*) = td->td_subfiletype;
684             break;
685         case TIFFTAG_IMAGEWIDTH:
686             *va_arg(ap, uint32*) = td->td_imagewidth;
687             break;
688         case TIFFTAG_IMAGELENGTH:
689             *va_arg(ap, uint32*) = td->td_imagelength;
690             break;
691         case TIFFTAG_BITSPERSAMPLE:
692             *va_arg(ap, uint16*) = td->td_bitspersample;
693             break;
694         case TIFFTAG_COMPRESSION:
695             *va_arg(ap, uint16*) = td->td_compression;
696             break;
697         case TIFFTAG_PHOTOMETRIC:
698             *va_arg(ap, uint16*) = td->td_photometric;
699             break;
700         case TIFFTAG_THRESHHOLDING:
701             *va_arg(ap, uint16*) = td->td_threshholding;
702             break;
703         case TIFFTAG_FILLORDER:
704             *va_arg(ap, uint16*) = td->td_fillorder;
705             break;
706         case TIFFTAG_ORIENTATION:
707             *va_arg(ap, uint16*) = td->td_orientation;
708             break;
709         case TIFFTAG_SAMPLESPERPIXEL:
710             *va_arg(ap, uint16*) = td->td_samplesperpixel;
711             break;
712         case TIFFTAG_ROWSPERSTRIP:
713             *va_arg(ap, uint32*) = td->td_rowsperstrip;
714             break;
715         case TIFFTAG_MINSAMPLEVALUE:
716             *va_arg(ap, uint16*) = td->td_minsamplevalue;
717             break;
718         case TIFFTAG_MAXSAMPLEVALUE:
719             *va_arg(ap, uint16*) = td->td_maxsamplevalue;
720             break;
721         case TIFFTAG_SMINSAMPLEVALUE:
722             *va_arg(ap, double*) = td->td_sminsamplevalue;
723             break;
724         case TIFFTAG_SMAXSAMPLEVALUE:
725             *va_arg(ap, double*) = td->td_smaxsamplevalue;
726             break;
727         case TIFFTAG_XRESOLUTION:
728             *va_arg(ap, float*) = td->td_xresolution;
729             break;
730         case TIFFTAG_YRESOLUTION:
731             *va_arg(ap, float*) = td->td_yresolution;
732             break;
733         case TIFFTAG_PLANARCONFIG:
734             *va_arg(ap, uint16*) = td->td_planarconfig;
735             break;
736         case TIFFTAG_XPOSITION:
737             *va_arg(ap, float*) = td->td_xposition;
738             break;
739         case TIFFTAG_YPOSITION:
740             *va_arg(ap, float*) = td->td_yposition;
741             break;
742         case TIFFTAG_RESOLUTIONUNIT:
743             *va_arg(ap, uint16*) = td->td_resolutionunit;
744             break;
745         case TIFFTAG_PAGENUMBER:
746             *va_arg(ap, uint16*) = td->td_pagenumber[0];
747             *va_arg(ap, uint16*) = td->td_pagenumber[1];
748             break;
749         case TIFFTAG_HALFTONEHINTS:
750             *va_arg(ap, uint16*) = td->td_halftonehints[0];
751             *va_arg(ap, uint16*) = td->td_halftonehints[1];
752             break;
753         case TIFFTAG_COLORMAP:
754             *va_arg(ap, uint16**) = td->td_colormap[0];
755             *va_arg(ap, uint16**) = td->td_colormap[1];
756             *va_arg(ap, uint16**) = td->td_colormap[2];
757             break;
758         case TIFFTAG_STRIPOFFSETS:
759         case TIFFTAG_TILEOFFSETS:
760             *va_arg(ap, uint32**) = td->td_stripoffset;
761             break;
762         case TIFFTAG_STRIPBYTECOUNTS:
763         case TIFFTAG_TILEBYTECOUNTS:
764             *va_arg(ap, uint32**) = td->td_stripbytecount;
765             break;
766         case TIFFTAG_MATTEING:
767             *va_arg(ap, uint16*) =
768                 (td->td_extrasamples == 1 &&
769                  td->td_sampleinfo[0] == EXTRASAMPLE_ASSOCALPHA);
770             break;
771         case TIFFTAG_EXTRASAMPLES:
772             *va_arg(ap, uint16*) = td->td_extrasamples;
773             *va_arg(ap, uint16**) = td->td_sampleinfo;
774             break;
775         case TIFFTAG_TILEWIDTH:
776             *va_arg(ap, uint32*) = td->td_tilewidth;
777             break;
778         case TIFFTAG_TILELENGTH:
779             *va_arg(ap, uint32*) = td->td_tilelength;
780             break;
781         case TIFFTAG_TILEDEPTH:
782             *va_arg(ap, uint32*) = td->td_tiledepth;
783             break;
784         case TIFFTAG_DATATYPE:
785             switch (td->td_sampleformat) {
786                 case SAMPLEFORMAT_UINT:
787                     *va_arg(ap, uint16*) = DATATYPE_UINT;
788                     break;
789                 case SAMPLEFORMAT_INT:
790                     *va_arg(ap, uint16*) = DATATYPE_INT;
791                     break;
792                 case SAMPLEFORMAT_IEEEFP:
793                     *va_arg(ap, uint16*) = DATATYPE_IEEEFP;
794                     break;
795                 case SAMPLEFORMAT_VOID:
796                     *va_arg(ap, uint16*) = DATATYPE_VOID;
797                     break;
798             }
799             break;
800         case TIFFTAG_SAMPLEFORMAT:
801             *va_arg(ap, uint16*) = td->td_sampleformat;
802             break;
803         case TIFFTAG_IMAGEDEPTH:
804             *va_arg(ap, uint32*) = td->td_imagedepth;
805             break;
806         case TIFFTAG_SUBIFD:
807             *va_arg(ap, uint16*) = td->td_nsubifd;
808             *va_arg(ap, uint32**) = td->td_subifd;
809             break;
810         case TIFFTAG_YCBCRPOSITIONING:
811             *va_arg(ap, uint16*) = td->td_ycbcrpositioning;
812             break;
813         case TIFFTAG_YCBCRSUBSAMPLING:
814             *va_arg(ap, uint16*) = td->td_ycbcrsubsampling[0];
815             *va_arg(ap, uint16*) = td->td_ycbcrsubsampling[1];
816             break;
817         case TIFFTAG_TRANSFERFUNCTION:
818             *va_arg(ap, uint16**) = td->td_transferfunction[0];
819             if (td->td_samplesperpixel - td->td_extrasamples > 1) {
820                 *va_arg(ap, uint16**) = td->td_transferfunction[1];
821                 *va_arg(ap, uint16**) = td->td_transferfunction[2];
822             }
823             break;
824         case TIFFTAG_REFERENCEBLACKWHITE:
825             *va_arg(ap, float**) = td->td_refblackwhite;
826             break;
827         case TIFFTAG_INKNAMES:
828             *va_arg(ap, char**) = td->td_inknames;
829             break;
830         default:
831         {
832             const TIFFFieldInfo* fip = _TIFFFindFieldInfo(tif, tag, TIFF_ANY);
833             int           i;
834             
835             /*
836              * This can happen if multiple images are open with different
837              * codecs which have private tags.  The global tag information
838              * table may then have tags that are valid for one file but not
839              * the other. If the client tries to get a tag that is not valid
840              * for the image's codec then we'll arrive here.
841              */
842             if( fip == NULL || fip->field_bit != FIELD_CUSTOM )
843             {
844                     TIFFErrorExt(tif->tif_clientdata, "_TIFFVGetField",
845                                  "%s: Invalid %stag \"%s\" "
846                                  "(not supported by codec)",
847                                  tif->tif_name,
848                                  isPseudoTag(tag) ? "pseudo-" : "",
849                                  fip ? fip->field_name : "Unknown");
850                     ret_val = 0;
851                     break;
852             }
853
854             /*
855              * Do we have a custom value?
856              */
857             ret_val = 0;
858             for (i = 0; i < td->td_customValueCount; i++) {
859                 TIFFTagValue *tv = td->td_customValues + i;
860
861                 if (tv->info->field_tag != tag)
862                         continue;
863                 
864                 if (fip->field_passcount) {
865                         if (fip->field_readcount == TIFF_VARIABLE2) 
866                                 *va_arg(ap, uint32*) = (uint32)tv->count;
867                         else    /* Assume TIFF_VARIABLE */
868                                 *va_arg(ap, uint16*) = (uint16)tv->count;
869                         *va_arg(ap, void **) = tv->value;
870                         ret_val = 1;
871                 } else {
872                         if ((fip->field_type == TIFF_ASCII
873                             || fip->field_readcount == TIFF_VARIABLE
874                             || fip->field_readcount == TIFF_VARIABLE2
875                             || fip->field_readcount == TIFF_SPP
876                             || tv->count > 1)
877                             && fip->field_tag != TIFFTAG_PAGENUMBER
878                             && fip->field_tag != TIFFTAG_HALFTONEHINTS
879                             && fip->field_tag != TIFFTAG_YCBCRSUBSAMPLING
880                             && fip->field_tag != TIFFTAG_DOTRANGE) {
881                                 *va_arg(ap, void **) = tv->value;
882                                 ret_val = 1;
883                         } else {
884                             int j;
885                             char *val = (char *)tv->value;
886
887                             for (j = 0; j < tv->count;
888                                  j++, val += _TIFFDataSize(tv->info->field_type)) {
889                                 switch (fip->field_type) {
890                                         case TIFF_BYTE:
891                                         case TIFF_UNDEFINED:
892                                                 *va_arg(ap, uint8*) =
893                                                         *(uint8 *)val;
894                                                 ret_val = 1;
895                                                 break;
896                                         case TIFF_SBYTE:
897                                                 *va_arg(ap, int8*) =
898                                                         *(int8 *)val;
899                                                 ret_val = 1;
900                                                 break;
901                                         case TIFF_SHORT:
902                                                 *va_arg(ap, uint16*) =
903                                                         *(uint16 *)val;
904                                                 ret_val = 1;
905                                                 break;
906                                         case TIFF_SSHORT:
907                                                 *va_arg(ap, int16*) =
908                                                         *(int16 *)val;
909                                                 ret_val = 1;
910                                                 break;
911                                         case TIFF_LONG:
912                                         case TIFF_IFD:
913                                                 *va_arg(ap, uint32*) =
914                                                         *(uint32 *)val;
915                                                 ret_val = 1;
916                                                 break;
917                                         case TIFF_SLONG:
918                                                 *va_arg(ap, int32*) =
919                                                         *(int32 *)val;
920                                                 ret_val = 1;
921                                                 break;
922                                         case TIFF_RATIONAL:
923                                         case TIFF_SRATIONAL:
924                                         case TIFF_FLOAT:
925                                                 *va_arg(ap, float*) =
926                                                         *(float *)val;
927                                                 ret_val = 1;
928                                                 break;
929                                         case TIFF_DOUBLE:
930                                                 *va_arg(ap, double*) =
931                                                         *(double *)val;
932                                                 ret_val = 1;
933                                                 break;
934                                         default:
935                                                 ret_val = 0;
936                                                 break;
937                                 }
938                             }
939                         }
940                 }
941                 break;
942             }
943         }
944     }
945     return(ret_val);
946 }
947
948 /*
949  * Return the value of a field in the
950  * internal directory structure.
951  */
952 int
953 TIFFGetField(TIFF* tif, ttag_t tag, ...)
954 {
955         int status;
956         va_list ap;
957
958         va_start(ap, tag);
959         status = TIFFVGetField(tif, tag, ap);
960         va_end(ap);
961         return (status);
962 }
963
964 /*
965  * Like TIFFGetField, but taking a varargs
966  * parameter list.  This routine is useful
967  * for building higher-level interfaces on
968  * top of the library.
969  */
970 int
971 TIFFVGetField(TIFF* tif, ttag_t tag, va_list ap)
972 {
973         const TIFFFieldInfo* fip = _TIFFFindFieldInfo(tif, tag, TIFF_ANY);
974         return (fip && (isPseudoTag(tag) || TIFFFieldSet(tif, fip->field_bit)) ?
975             (*tif->tif_tagmethods.vgetfield)(tif, tag, ap) : 0);
976 }
977
978 #define CleanupField(member) {          \
979     if (td->member) {                   \
980         _TIFFfree(td->member);          \
981         td->member = 0;                 \
982     }                                   \
983 }
984
985 /*
986  * Release storage associated with a directory.
987  */
988 void
989 TIFFFreeDirectory(TIFF* tif)
990 {
991         TIFFDirectory *td = &tif->tif_dir;
992         int            i;
993
994         _TIFFmemset(td->td_fieldsset, 0, FIELD_SETLONGS);
995         CleanupField(td_colormap[0]);
996         CleanupField(td_colormap[1]);
997         CleanupField(td_colormap[2]);
998         CleanupField(td_sampleinfo);
999         CleanupField(td_subifd);
1000         CleanupField(td_inknames);
1001         CleanupField(td_refblackwhite);
1002         CleanupField(td_transferfunction[0]);
1003         CleanupField(td_transferfunction[1]);
1004         CleanupField(td_transferfunction[2]);
1005         CleanupField(td_stripoffset);
1006         CleanupField(td_stripbytecount);
1007         TIFFClrFieldBit(tif, FIELD_YCBCRSUBSAMPLING);
1008         TIFFClrFieldBit(tif, FIELD_YCBCRPOSITIONING);
1009
1010         /* Cleanup custom tag values */
1011         for( i = 0; i < td->td_customValueCount; i++ ) {
1012                 if (td->td_customValues[i].value)
1013                         _TIFFfree(td->td_customValues[i].value);
1014         }
1015
1016         td->td_customValueCount = 0;
1017         CleanupField(td_customValues);
1018 }
1019 #undef CleanupField
1020
1021 /*
1022  * Client Tag extension support (from Niles Ritter).
1023  */
1024 static TIFFExtendProc _TIFFextender = (TIFFExtendProc) NULL;
1025
1026 TIFFExtendProc
1027 TIFFSetTagExtender(TIFFExtendProc extender)
1028 {
1029         TIFFExtendProc prev = _TIFFextender;
1030         _TIFFextender = extender;
1031         return (prev);
1032 }
1033
1034 /*
1035  * Setup for a new directory.  Should we automatically call
1036  * TIFFWriteDirectory() if the current one is dirty?
1037  *
1038  * The newly created directory will not exist on the file till
1039  * TIFFWriteDirectory(), TIFFFlush() or TIFFClose() is called.
1040  */
1041 int
1042 TIFFCreateDirectory(TIFF* tif)
1043 {
1044     TIFFDefaultDirectory(tif);
1045     tif->tif_diroff = 0;
1046     tif->tif_nextdiroff = 0;
1047     tif->tif_curoff = 0;
1048     tif->tif_row = (uint32) -1;
1049     tif->tif_curstrip = (tstrip_t) -1;
1050
1051     return 0;
1052 }
1053
1054 /*
1055  * Setup a default directory structure.
1056  */
1057 int
1058 TIFFDefaultDirectory(TIFF* tif)
1059 {
1060         register TIFFDirectory* td = &tif->tif_dir;
1061
1062         size_t tiffFieldInfoCount;
1063         const TIFFFieldInfo *tiffFieldInfo =
1064             _TIFFGetFieldInfo(&tiffFieldInfoCount);
1065         _TIFFSetupFieldInfo(tif, tiffFieldInfo, tiffFieldInfoCount);
1066
1067         _TIFFmemset(td, 0, sizeof (*td));
1068         td->td_fillorder = FILLORDER_MSB2LSB;
1069         td->td_bitspersample = 1;
1070         td->td_threshholding = THRESHHOLD_BILEVEL;
1071         td->td_orientation = ORIENTATION_TOPLEFT;
1072         td->td_samplesperpixel = 1;
1073         td->td_rowsperstrip = (uint32) -1;
1074         td->td_tilewidth = 0;
1075         td->td_tilelength = 0;
1076         td->td_tiledepth = 1;
1077         td->td_stripbytecountsorted = 1; /* Our own arrays always sorted. */
1078         td->td_resolutionunit = RESUNIT_INCH;
1079         td->td_sampleformat = SAMPLEFORMAT_UINT;
1080         td->td_imagedepth = 1;
1081         td->td_ycbcrsubsampling[0] = 2;
1082         td->td_ycbcrsubsampling[1] = 2;
1083         td->td_ycbcrpositioning = YCBCRPOSITION_CENTERED;
1084         tif->tif_postdecode = _TIFFNoPostDecode;
1085         tif->tif_foundfield = NULL;
1086         tif->tif_tagmethods.vsetfield = _TIFFVSetField;
1087         tif->tif_tagmethods.vgetfield = _TIFFVGetField;
1088         tif->tif_tagmethods.printdir = NULL;
1089         /*
1090          *  Give client code a chance to install their own
1091          *  tag extensions & methods, prior to compression overloads.
1092          */
1093         if (_TIFFextender)
1094                 (*_TIFFextender)(tif);
1095         (void) TIFFSetField(tif, TIFFTAG_COMPRESSION, COMPRESSION_NONE);
1096         /*
1097          * NB: The directory is marked dirty as a result of setting
1098          * up the default compression scheme.  However, this really
1099          * isn't correct -- we want TIFF_DIRTYDIRECT to be set only
1100          * if the user does something.  We could just do the setup
1101          * by hand, but it seems better to use the normal mechanism
1102          * (i.e. TIFFSetField).
1103          */
1104         tif->tif_flags &= ~TIFF_DIRTYDIRECT;
1105
1106         /*
1107          * As per http://bugzilla.remotesensing.org/show_bug.cgi?id=19
1108          * we clear the ISTILED flag when setting up a new directory.
1109          * Should we also be clearing stuff like INSUBIFD?
1110          */
1111         tif->tif_flags &= ~TIFF_ISTILED;
1112         /*
1113          * Clear other directory-specific fields.
1114          */
1115         tif->tif_tilesize = -1;
1116         tif->tif_scanlinesize = -1;
1117
1118         return (1);
1119 }
1120
1121 static int
1122 TIFFAdvanceDirectory(TIFF* tif, uint32* nextdir, toff_t* off)
1123 {
1124         static const char module[] = "TIFFAdvanceDirectory";
1125         uint16 dircount;
1126         if (isMapped(tif))
1127         {
1128                 toff_t poff=*nextdir;
1129                 if (poff+sizeof(uint16) > tif->tif_size)
1130                 {
1131                         TIFFErrorExt(tif->tif_clientdata, module, "%s: Error fetching directory count",
1132                             tif->tif_name);
1133                         return (0);
1134                 }
1135                 _TIFFmemcpy(&dircount, tif->tif_base+poff, sizeof (uint16));
1136                 if (tif->tif_flags & TIFF_SWAB)
1137                         TIFFSwabShort(&dircount);
1138                 poff+=sizeof (uint16)+dircount*sizeof (TIFFDirEntry);
1139                 if (off != NULL)
1140                         *off = poff;
1141                 if (((toff_t) (poff+sizeof (uint32))) > tif->tif_size)
1142                 {
1143                         TIFFErrorExt(tif->tif_clientdata, module, "%s: Error fetching directory link",
1144                             tif->tif_name);
1145                         return (0);
1146                 }
1147                 _TIFFmemcpy(nextdir, tif->tif_base+poff, sizeof (uint32));
1148                 if (tif->tif_flags & TIFF_SWAB)
1149                         TIFFSwabLong(nextdir);
1150                 return (1);
1151         }
1152         else
1153         {
1154                 if (!SeekOK(tif, *nextdir) ||
1155                     !ReadOK(tif, &dircount, sizeof (uint16))) {
1156                         TIFFErrorExt(tif->tif_clientdata, module, "%s: Error fetching directory count",
1157                             tif->tif_name);
1158                         return (0);
1159                 }
1160                 if (tif->tif_flags & TIFF_SWAB)
1161                         TIFFSwabShort(&dircount);
1162                 if (off != NULL)
1163                         *off = TIFFSeekFile(tif,
1164                             dircount*sizeof (TIFFDirEntry), SEEK_CUR);
1165                 else
1166                         (void) TIFFSeekFile(tif,
1167                             dircount*sizeof (TIFFDirEntry), SEEK_CUR);
1168                 if (!ReadOK(tif, nextdir, sizeof (uint32))) {
1169                         TIFFErrorExt(tif->tif_clientdata, module, "%s: Error fetching directory link",
1170                             tif->tif_name);
1171                         return (0);
1172                 }
1173                 if (tif->tif_flags & TIFF_SWAB)
1174                         TIFFSwabLong(nextdir);
1175                 return (1);
1176         }
1177 }
1178
1179 /*
1180  * Count the number of directories in a file.
1181  */
1182 tdir_t
1183 TIFFNumberOfDirectories(TIFF* tif)
1184 {
1185     toff_t nextdir = tif->tif_header.tiff_diroff;
1186     tdir_t n = 0;
1187     
1188     while (nextdir != 0 && TIFFAdvanceDirectory(tif, &nextdir, NULL))
1189         n++;
1190     return (n);
1191 }
1192
1193 /*
1194  * Set the n-th directory as the current directory.
1195  * NB: Directories are numbered starting at 0.
1196  */
1197 int
1198 TIFFSetDirectory(TIFF* tif, tdir_t dirn)
1199 {
1200         toff_t nextdir;
1201         tdir_t n;
1202
1203         nextdir = tif->tif_header.tiff_diroff;
1204         for (n = dirn; n > 0 && nextdir != 0; n--)
1205                 if (!TIFFAdvanceDirectory(tif, &nextdir, NULL))
1206                         return (0);
1207         tif->tif_nextdiroff = nextdir;
1208         /*
1209          * Set curdir to the actual directory index.  The
1210          * -1 is because TIFFReadDirectory will increment
1211          * tif_curdir after successfully reading the directory.
1212          */
1213         tif->tif_curdir = (dirn - n) - 1;
1214         /*
1215          * Reset tif_dirnumber counter and start new list of seen directories.
1216          * We need this to prevent IFD loops.
1217          */
1218         tif->tif_dirnumber = 0;
1219         return (TIFFReadDirectory(tif));
1220 }
1221
1222 /*
1223  * Set the current directory to be the directory
1224  * located at the specified file offset.  This interface
1225  * is used mainly to access directories linked with
1226  * the SubIFD tag (e.g. thumbnail images).
1227  */
1228 int
1229 TIFFSetSubDirectory(TIFF* tif, uint32 diroff)
1230 {
1231         tif->tif_nextdiroff = diroff;
1232         /*
1233          * Reset tif_dirnumber counter and start new list of seen directories.
1234          * We need this to prevent IFD loops.
1235          */
1236         tif->tif_dirnumber = 0;
1237         return (TIFFReadDirectory(tif));
1238 }
1239
1240 /*
1241  * Return file offset of the current directory.
1242  */
1243 uint32
1244 TIFFCurrentDirOffset(TIFF* tif)
1245 {
1246         return (tif->tif_diroff);
1247 }
1248
1249 /*
1250  * Return an indication of whether or not we are
1251  * at the last directory in the file.
1252  */
1253 int
1254 TIFFLastDirectory(TIFF* tif)
1255 {
1256         return (tif->tif_nextdiroff == 0);
1257 }
1258
1259 /*
1260  * Unlink the specified directory from the directory chain.
1261  */
1262 int
1263 TIFFUnlinkDirectory(TIFF* tif, tdir_t dirn)
1264 {
1265         static const char module[] = "TIFFUnlinkDirectory";
1266         toff_t nextdir;
1267         toff_t off;
1268         tdir_t n;
1269
1270         if (tif->tif_mode == O_RDONLY) {
1271                 TIFFErrorExt(tif->tif_clientdata, module,
1272                              "Can not unlink directory in read-only file");
1273                 return (0);
1274         }
1275         /*
1276          * Go to the directory before the one we want
1277          * to unlink and nab the offset of the link
1278          * field we'll need to patch.
1279          */
1280         nextdir = tif->tif_header.tiff_diroff;
1281         off = sizeof (uint16) + sizeof (uint16);
1282         for (n = dirn-1; n > 0; n--) {
1283                 if (nextdir == 0) {
1284                         TIFFErrorExt(tif->tif_clientdata, module, "Directory %d does not exist", dirn);
1285                         return (0);
1286                 }
1287                 if (!TIFFAdvanceDirectory(tif, &nextdir, &off))
1288                         return (0);
1289         }
1290         /*
1291          * Advance to the directory to be unlinked and fetch
1292          * the offset of the directory that follows.
1293          */
1294         if (!TIFFAdvanceDirectory(tif, &nextdir, NULL))
1295                 return (0);
1296         /*
1297          * Go back and patch the link field of the preceding
1298          * directory to point to the offset of the directory
1299          * that follows.
1300          */
1301         (void) TIFFSeekFile(tif, off, SEEK_SET);
1302         if (tif->tif_flags & TIFF_SWAB)
1303                 TIFFSwabLong(&nextdir);
1304         if (!WriteOK(tif, &nextdir, sizeof (uint32))) {
1305                 TIFFErrorExt(tif->tif_clientdata, module, "Error writing directory link");
1306                 return (0);
1307         }
1308         /*
1309          * Leave directory state setup safely.  We don't have
1310          * facilities for doing inserting and removing directories,
1311          * so it's safest to just invalidate everything.  This
1312          * means that the caller can only append to the directory
1313          * chain.
1314          */
1315         (*tif->tif_cleanup)(tif);
1316         if ((tif->tif_flags & TIFF_MYBUFFER) && tif->tif_rawdata) {
1317                 _TIFFfree(tif->tif_rawdata);
1318                 tif->tif_rawdata = NULL;
1319                 tif->tif_rawcc = 0;
1320         }
1321         tif->tif_flags &= ~(TIFF_BEENWRITING|TIFF_BUFFERSETUP|TIFF_POSTENCODE);
1322         TIFFFreeDirectory(tif);
1323         TIFFDefaultDirectory(tif);
1324         tif->tif_diroff = 0;                    /* force link on next write */
1325         tif->tif_nextdiroff = 0;                /* next write must be at end */
1326         tif->tif_curoff = 0;
1327         tif->tif_row = (uint32) -1;
1328         tif->tif_curstrip = (tstrip_t) -1;
1329         return (1);
1330 }
1331
1332 /*                      [BFC]
1333  *
1334  * Author: Bruce Cameron <cameron@petris.com>
1335  *
1336  * Set a table of tags that are to be replaced during directory process by the
1337  * 'IGNORE' state - or return TRUE/FALSE for the requested tag such that
1338  * 'ReadDirectory' can use the stored information.
1339  *
1340  * FIXME: this is never used properly. Should be removed in the future.
1341  */
1342 int
1343 TIFFReassignTagToIgnore (enum TIFFIgnoreSense task, int TIFFtagID)
1344 {
1345     static int TIFFignoretags [FIELD_LAST];
1346     static int tagcount = 0 ;
1347     int         i;                                      /* Loop index */
1348     int         j;                                      /* Loop index */
1349
1350     switch (task)
1351     {
1352       case TIS_STORE:
1353         if ( tagcount < (FIELD_LAST - 1) )
1354         {
1355             for ( j = 0 ; j < tagcount ; ++j )
1356             {                                   /* Do not add duplicate tag */
1357                 if ( TIFFignoretags [j] == TIFFtagID )
1358                     return (TRUE) ;
1359             }
1360             TIFFignoretags [tagcount++] = TIFFtagID ;
1361             return (TRUE) ;
1362         }
1363         break ;
1364         
1365       case TIS_EXTRACT:
1366         for ( i = 0 ; i < tagcount ; ++i )
1367         {
1368             if ( TIFFignoretags [i] == TIFFtagID )
1369                 return (TRUE) ;
1370         }
1371         break;
1372         
1373       case TIS_EMPTY:
1374         tagcount = 0 ;                  /* Clear the list */
1375         return (TRUE) ;
1376         
1377       default:
1378         break;
1379     }
1380     
1381     return (FALSE);
1382 }
1383
1384 /* vim: set ts=8 sts=8 sw=8 noet: */
1385 /*
1386  * Local Variables:
1387  * mode: c
1388  * c-basic-offset: 8
1389  * fill-column: 78
1390  * End:
1391  */