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