xref: /aosp_15_r20/external/pdfium/third_party/libtiff/tif_dir.c (revision 3ac0a46f773bac49fa9476ec2b1cf3f8da5ec3a4)
1 /*
2  * Copyright (c) 1988-1997 Sam Leffler
3  * Copyright (c) 1991-1997 Silicon Graphics, Inc.
4  *
5  * Permission to use, copy, modify, distribute, and sell this software and
6  * its documentation for any purpose is hereby granted without fee, provided
7  * that (i) the above copyright notices and this permission notice appear in
8  * all copies of the software and related documentation, and (ii) the names of
9  * Sam Leffler and Silicon Graphics may not be used in any advertising or
10  * publicity relating to the software without the specific, prior written
11  * permission of Sam Leffler and Silicon Graphics.
12  *
13  * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND,
14  * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY
15  * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
16  *
17  * IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR
18  * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND,
19  * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
20  * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF
21  * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
22  * OF THIS SOFTWARE.
23  */
24 
25 /*
26  * TIFF Library.
27  *
28  * Directory Tag Get & Set Routines.
29  * (and also some miscellaneous stuff)
30  */
31 #include "tiffiop.h"
32 #include <float.h> /*--: for Rational2Double */
33 #include <limits.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 
setByteArray(TIFF * tif,void ** vpp,const void * vp,size_t nmemb,size_t elem_size)43 static void setByteArray(TIFF *tif, void **vpp, const void *vp, size_t nmemb,
44                          size_t elem_size)
45 {
46     if (*vpp)
47     {
48         _TIFFfreeExt(tif, *vpp);
49         *vpp = 0;
50     }
51     if (vp)
52     {
53         tmsize_t bytes = _TIFFMultiplySSize(NULL, nmemb, elem_size, NULL);
54         if (bytes)
55             *vpp = (void *)_TIFFmallocExt(tif, bytes);
56         if (*vpp)
57             _TIFFmemcpy(*vpp, vp, bytes);
58     }
59 }
_TIFFsetByteArray(void ** vpp,const void * vp,uint32_t n)60 void _TIFFsetByteArray(void **vpp, const void *vp, uint32_t n)
61 {
62     setByteArray(NULL, vpp, vp, n, 1);
63 }
_TIFFsetByteArrayExt(TIFF * tif,void ** vpp,const void * vp,uint32_t n)64 void _TIFFsetByteArrayExt(TIFF *tif, void **vpp, const void *vp, uint32_t n)
65 {
66     setByteArray(tif, vpp, vp, n, 1);
67 }
68 
_TIFFsetNString(TIFF * tif,char ** cpp,const char * cp,uint32_t n)69 static void _TIFFsetNString(TIFF *tif, char **cpp, const char *cp, uint32_t n)
70 {
71     setByteArray(tif, (void **)cpp, cp, n, 1);
72 }
73 
_TIFFsetShortArray(uint16_t ** wpp,const uint16_t * wp,uint32_t n)74 void _TIFFsetShortArray(uint16_t **wpp, const uint16_t *wp, uint32_t n)
75 {
76     setByteArray(NULL, (void **)wpp, wp, n, sizeof(uint16_t));
77 }
_TIFFsetShortArrayExt(TIFF * tif,uint16_t ** wpp,const uint16_t * wp,uint32_t n)78 void _TIFFsetShortArrayExt(TIFF *tif, uint16_t **wpp, const uint16_t *wp,
79                            uint32_t n)
80 {
81     setByteArray(tif, (void **)wpp, wp, n, sizeof(uint16_t));
82 }
83 
_TIFFsetLongArray(uint32_t ** lpp,const uint32_t * lp,uint32_t n)84 void _TIFFsetLongArray(uint32_t **lpp, const uint32_t *lp, uint32_t n)
85 {
86     setByteArray(NULL, (void **)lpp, lp, n, sizeof(uint32_t));
87 }
_TIFFsetLongArrayExt(TIFF * tif,uint32_t ** lpp,const uint32_t * lp,uint32_t n)88 void _TIFFsetLongArrayExt(TIFF *tif, uint32_t **lpp, const uint32_t *lp,
89                           uint32_t n)
90 {
91     setByteArray(tif, (void **)lpp, lp, n, sizeof(uint32_t));
92 }
93 
_TIFFsetLong8Array(TIFF * tif,uint64_t ** lpp,const uint64_t * lp,uint32_t n)94 static void _TIFFsetLong8Array(TIFF *tif, uint64_t **lpp, const uint64_t *lp,
95                                uint32_t n)
96 {
97     setByteArray(tif, (void **)lpp, lp, n, sizeof(uint64_t));
98 }
99 
_TIFFsetFloatArray(float ** fpp,const float * fp,uint32_t n)100 void _TIFFsetFloatArray(float **fpp, const float *fp, uint32_t n)
101 {
102     setByteArray(NULL, (void **)fpp, fp, n, sizeof(float));
103 }
_TIFFsetFloatArrayExt(TIFF * tif,float ** fpp,const float * fp,uint32_t n)104 void _TIFFsetFloatArrayExt(TIFF *tif, float **fpp, const float *fp, uint32_t n)
105 {
106     setByteArray(tif, (void **)fpp, fp, n, sizeof(float));
107 }
108 
_TIFFsetDoubleArray(double ** dpp,const double * dp,uint32_t n)109 void _TIFFsetDoubleArray(double **dpp, const double *dp, uint32_t n)
110 {
111     setByteArray(NULL, (void **)dpp, dp, n, sizeof(double));
112 }
_TIFFsetDoubleArrayExt(TIFF * tif,double ** dpp,const double * dp,uint32_t n)113 void _TIFFsetDoubleArrayExt(TIFF *tif, double **dpp, const double *dp,
114                             uint32_t n)
115 {
116     setByteArray(tif, (void **)dpp, dp, n, sizeof(double));
117 }
118 
setDoubleArrayOneValue(TIFF * tif,double ** vpp,double value,size_t nmemb)119 static void setDoubleArrayOneValue(TIFF *tif, double **vpp, double value,
120                                    size_t nmemb)
121 {
122     if (*vpp)
123         _TIFFfreeExt(tif, *vpp);
124     *vpp = _TIFFmallocExt(tif, nmemb * sizeof(double));
125     if (*vpp)
126     {
127         while (nmemb--)
128             ((double *)*vpp)[nmemb] = value;
129     }
130 }
131 
132 /*
133  * Install extra samples information.
134  */
setExtraSamples(TIFF * tif,va_list ap,uint32_t * v)135 static int setExtraSamples(TIFF *tif, va_list ap, uint32_t *v)
136 {
137 /* XXX: Unassociated alpha data == 999 is a known Corel Draw bug, see below */
138 #define EXTRASAMPLE_COREL_UNASSALPHA 999
139 
140     uint16_t *va;
141     uint32_t i;
142     TIFFDirectory *td = &tif->tif_dir;
143     static const char module[] = "setExtraSamples";
144 
145     *v = (uint16_t)va_arg(ap, uint16_vap);
146     if ((uint16_t)*v > td->td_samplesperpixel)
147         return 0;
148     va = va_arg(ap, uint16_t *);
149     if (*v > 0 && va == NULL) /* typically missing param */
150         return 0;
151     for (i = 0; i < *v; i++)
152     {
153         if (va[i] > EXTRASAMPLE_UNASSALPHA)
154         {
155             /*
156              * XXX: Corel Draw is known to produce incorrect
157              * ExtraSamples tags which must be patched here if we
158              * want to be able to open some of the damaged TIFF
159              * files:
160              */
161             if (va[i] == EXTRASAMPLE_COREL_UNASSALPHA)
162                 va[i] = EXTRASAMPLE_UNASSALPHA;
163             else
164                 return 0;
165         }
166     }
167 
168     if (td->td_transferfunction[0] != NULL &&
169         (td->td_samplesperpixel - *v > 1) &&
170         !(td->td_samplesperpixel - td->td_extrasamples > 1))
171     {
172         TIFFWarningExtR(tif, module,
173                         "ExtraSamples tag value is changing, "
174                         "but TransferFunction was read with a different value. "
175                         "Canceling it");
176         TIFFClrFieldBit(tif, FIELD_TRANSFERFUNCTION);
177         _TIFFfreeExt(tif, td->td_transferfunction[0]);
178         td->td_transferfunction[0] = NULL;
179     }
180 
181     td->td_extrasamples = (uint16_t)*v;
182     _TIFFsetShortArrayExt(tif, &td->td_sampleinfo, va, td->td_extrasamples);
183     return 1;
184 
185 #undef EXTRASAMPLE_COREL_UNASSALPHA
186 }
187 
188 /*
189  * Count ink names separated by \0.  Returns
190  * zero if the ink names are not as expected.
191  */
countInkNamesString(TIFF * tif,uint32_t slen,const char * s)192 static uint16_t countInkNamesString(TIFF *tif, uint32_t slen, const char *s)
193 {
194     uint16_t i = 0;
195 
196     if (slen > 0)
197     {
198         const char *ep = s + slen;
199         const char *cp = s;
200         do
201         {
202             for (; cp < ep && *cp != '\0'; cp++)
203             {
204             }
205             if (cp >= ep)
206                 goto bad;
207             cp++; /* skip \0 */
208             i++;
209         } while (cp < ep);
210         return (i);
211     }
212 bad:
213     TIFFErrorExtR(tif, "TIFFSetField",
214                   "%s: Invalid InkNames value; no NUL at given buffer end "
215                   "location %" PRIu32 ", after %" PRIu16 " ink",
216                   tif->tif_name, slen, i);
217     return (0);
218 }
219 
_TIFFVSetField(TIFF * tif,uint32_t tag,va_list ap)220 static int _TIFFVSetField(TIFF *tif, uint32_t tag, va_list ap)
221 {
222     static const char module[] = "_TIFFVSetField";
223 
224     TIFFDirectory *td = &tif->tif_dir;
225     int status = 1;
226     uint32_t v32, v;
227     double dblval;
228     char *s;
229     const TIFFField *fip = TIFFFindField(tif, tag, TIFF_ANY);
230     uint32_t standard_tag = tag;
231     if (fip == NULL) /* cannot happen since OkToChangeTag() already checks it */
232         return 0;
233     /*
234      * We want to force the custom code to be used for custom
235      * fields even if the tag happens to match a well known
236      * one - important for reinterpreted handling of standard
237      * tag values in custom directories (i.e. EXIF)
238      */
239     if (fip->field_bit == FIELD_CUSTOM)
240     {
241         standard_tag = 0;
242     }
243 
244     switch (standard_tag)
245     {
246         case TIFFTAG_SUBFILETYPE:
247             td->td_subfiletype = (uint32_t)va_arg(ap, uint32_t);
248             break;
249         case TIFFTAG_IMAGEWIDTH:
250             td->td_imagewidth = (uint32_t)va_arg(ap, uint32_t);
251             break;
252         case TIFFTAG_IMAGELENGTH:
253             td->td_imagelength = (uint32_t)va_arg(ap, uint32_t);
254             break;
255         case TIFFTAG_BITSPERSAMPLE:
256             td->td_bitspersample = (uint16_t)va_arg(ap, uint16_vap);
257             /*
258              * If the data require post-decoding processing to byte-swap
259              * samples, set it up here.  Note that since tags are required
260              * to be ordered, compression code can override this behavior
261              * in the setup method if it wants to roll the post decoding
262              * work in with its normal work.
263              */
264             if (tif->tif_flags & TIFF_SWAB)
265             {
266                 if (td->td_bitspersample == 8)
267                     tif->tif_postdecode = _TIFFNoPostDecode;
268                 else if (td->td_bitspersample == 16)
269                     tif->tif_postdecode = _TIFFSwab16BitData;
270                 else if (td->td_bitspersample == 24)
271                     tif->tif_postdecode = _TIFFSwab24BitData;
272                 else if (td->td_bitspersample == 32)
273                     tif->tif_postdecode = _TIFFSwab32BitData;
274                 else if (td->td_bitspersample == 64)
275                     tif->tif_postdecode = _TIFFSwab64BitData;
276                 else if (td->td_bitspersample == 128) /* two 64's */
277                     tif->tif_postdecode = _TIFFSwab64BitData;
278             }
279             break;
280         case TIFFTAG_COMPRESSION:
281             v = (uint16_t)va_arg(ap, uint16_vap);
282             /*
283              * If we're changing the compression scheme, notify the
284              * previous module so that it can cleanup any state it's
285              * setup.
286              */
287             if (TIFFFieldSet(tif, FIELD_COMPRESSION))
288             {
289                 if ((uint32_t)td->td_compression == v)
290                     break;
291                 (*tif->tif_cleanup)(tif);
292                 tif->tif_flags &= ~TIFF_CODERSETUP;
293             }
294             /*
295              * Setup new compression routine state.
296              */
297             if ((status = TIFFSetCompressionScheme(tif, v)) != 0)
298                 td->td_compression = (uint16_t)v;
299             else
300                 status = 0;
301             break;
302         case TIFFTAG_PHOTOMETRIC:
303             td->td_photometric = (uint16_t)va_arg(ap, uint16_vap);
304             break;
305         case TIFFTAG_THRESHHOLDING:
306             td->td_threshholding = (uint16_t)va_arg(ap, uint16_vap);
307             break;
308         case TIFFTAG_FILLORDER:
309             v = (uint16_t)va_arg(ap, uint16_vap);
310             if (v != FILLORDER_LSB2MSB && v != FILLORDER_MSB2LSB)
311                 goto badvalue;
312             td->td_fillorder = (uint16_t)v;
313             break;
314         case TIFFTAG_ORIENTATION:
315             v = (uint16_t)va_arg(ap, uint16_vap);
316             if (v < ORIENTATION_TOPLEFT || ORIENTATION_LEFTBOT < v)
317                 goto badvalue;
318             else
319                 td->td_orientation = (uint16_t)v;
320             break;
321         case TIFFTAG_SAMPLESPERPIXEL:
322             v = (uint16_t)va_arg(ap, uint16_vap);
323             if (v == 0)
324                 goto badvalue;
325             if (v != td->td_samplesperpixel)
326             {
327                 /* See http://bugzilla.maptools.org/show_bug.cgi?id=2500 */
328                 if (td->td_sminsamplevalue != NULL)
329                 {
330                     TIFFWarningExtR(tif, module,
331                                     "SamplesPerPixel tag value is changing, "
332                                     "but SMinSampleValue tag was read with a "
333                                     "different value. Canceling it");
334                     TIFFClrFieldBit(tif, FIELD_SMINSAMPLEVALUE);
335                     _TIFFfreeExt(tif, td->td_sminsamplevalue);
336                     td->td_sminsamplevalue = NULL;
337                 }
338                 if (td->td_smaxsamplevalue != NULL)
339                 {
340                     TIFFWarningExtR(tif, module,
341                                     "SamplesPerPixel tag value is changing, "
342                                     "but SMaxSampleValue tag was read with a "
343                                     "different value. Canceling it");
344                     TIFFClrFieldBit(tif, FIELD_SMAXSAMPLEVALUE);
345                     _TIFFfreeExt(tif, td->td_smaxsamplevalue);
346                     td->td_smaxsamplevalue = NULL;
347                 }
348                 /* Test if 3 transfer functions instead of just one are now
349                    needed See http://bugzilla.maptools.org/show_bug.cgi?id=2820
350                  */
351                 if (td->td_transferfunction[0] != NULL &&
352                     (v - td->td_extrasamples > 1) &&
353                     !(td->td_samplesperpixel - td->td_extrasamples > 1))
354                 {
355                     TIFFWarningExtR(tif, module,
356                                     "SamplesPerPixel tag value is changing, "
357                                     "but TransferFunction was read with a "
358                                     "different value. Canceling it");
359                     TIFFClrFieldBit(tif, FIELD_TRANSFERFUNCTION);
360                     _TIFFfreeExt(tif, td->td_transferfunction[0]);
361                     td->td_transferfunction[0] = NULL;
362                 }
363             }
364             td->td_samplesperpixel = (uint16_t)v;
365             break;
366         case TIFFTAG_ROWSPERSTRIP:
367             v32 = (uint32_t)va_arg(ap, uint32_t);
368             if (v32 == 0)
369                 goto badvalue32;
370             td->td_rowsperstrip = v32;
371             if (!TIFFFieldSet(tif, FIELD_TILEDIMENSIONS))
372             {
373                 td->td_tilelength = v32;
374                 td->td_tilewidth = td->td_imagewidth;
375             }
376             break;
377         case TIFFTAG_MINSAMPLEVALUE:
378             td->td_minsamplevalue = (uint16_t)va_arg(ap, uint16_vap);
379             break;
380         case TIFFTAG_MAXSAMPLEVALUE:
381             td->td_maxsamplevalue = (uint16_t)va_arg(ap, uint16_vap);
382             break;
383         case TIFFTAG_SMINSAMPLEVALUE:
384             if (tif->tif_flags & TIFF_PERSAMPLE)
385                 _TIFFsetDoubleArrayExt(tif, &td->td_sminsamplevalue,
386                                        va_arg(ap, double *),
387                                        td->td_samplesperpixel);
388             else
389                 setDoubleArrayOneValue(tif, &td->td_sminsamplevalue,
390                                        va_arg(ap, double),
391                                        td->td_samplesperpixel);
392             break;
393         case TIFFTAG_SMAXSAMPLEVALUE:
394             if (tif->tif_flags & TIFF_PERSAMPLE)
395                 _TIFFsetDoubleArrayExt(tif, &td->td_smaxsamplevalue,
396                                        va_arg(ap, double *),
397                                        td->td_samplesperpixel);
398             else
399                 setDoubleArrayOneValue(tif, &td->td_smaxsamplevalue,
400                                        va_arg(ap, double),
401                                        td->td_samplesperpixel);
402             break;
403         case TIFFTAG_XRESOLUTION:
404             dblval = va_arg(ap, double);
405             if (dblval != dblval || dblval < 0)
406                 goto badvaluedouble;
407             td->td_xresolution = _TIFFClampDoubleToFloat(dblval);
408             break;
409         case TIFFTAG_YRESOLUTION:
410             dblval = va_arg(ap, double);
411             if (dblval != dblval || dblval < 0)
412                 goto badvaluedouble;
413             td->td_yresolution = _TIFFClampDoubleToFloat(dblval);
414             break;
415         case TIFFTAG_PLANARCONFIG:
416             v = (uint16_t)va_arg(ap, uint16_vap);
417             if (v != PLANARCONFIG_CONTIG && v != PLANARCONFIG_SEPARATE)
418                 goto badvalue;
419             td->td_planarconfig = (uint16_t)v;
420             break;
421         case TIFFTAG_XPOSITION:
422             td->td_xposition = _TIFFClampDoubleToFloat(va_arg(ap, double));
423             break;
424         case TIFFTAG_YPOSITION:
425             td->td_yposition = _TIFFClampDoubleToFloat(va_arg(ap, double));
426             break;
427         case TIFFTAG_RESOLUTIONUNIT:
428             v = (uint16_t)va_arg(ap, uint16_vap);
429             if (v < RESUNIT_NONE || RESUNIT_CENTIMETER < v)
430                 goto badvalue;
431             td->td_resolutionunit = (uint16_t)v;
432             break;
433         case TIFFTAG_PAGENUMBER:
434             td->td_pagenumber[0] = (uint16_t)va_arg(ap, uint16_vap);
435             td->td_pagenumber[1] = (uint16_t)va_arg(ap, uint16_vap);
436             break;
437         case TIFFTAG_HALFTONEHINTS:
438             td->td_halftonehints[0] = (uint16_t)va_arg(ap, uint16_vap);
439             td->td_halftonehints[1] = (uint16_t)va_arg(ap, uint16_vap);
440             break;
441         case TIFFTAG_COLORMAP:
442             v32 = (uint32_t)(1L << td->td_bitspersample);
443             _TIFFsetShortArrayExt(tif, &td->td_colormap[0],
444                                   va_arg(ap, uint16_t *), v32);
445             _TIFFsetShortArrayExt(tif, &td->td_colormap[1],
446                                   va_arg(ap, uint16_t *), v32);
447             _TIFFsetShortArrayExt(tif, &td->td_colormap[2],
448                                   va_arg(ap, uint16_t *), v32);
449             break;
450         case TIFFTAG_EXTRASAMPLES:
451             if (!setExtraSamples(tif, ap, &v))
452                 goto badvalue;
453             break;
454         case TIFFTAG_MATTEING:
455             td->td_extrasamples = (((uint16_t)va_arg(ap, uint16_vap)) != 0);
456             if (td->td_extrasamples)
457             {
458                 uint16_t sv = EXTRASAMPLE_ASSOCALPHA;
459                 _TIFFsetShortArrayExt(tif, &td->td_sampleinfo, &sv, 1);
460             }
461             break;
462         case TIFFTAG_TILEWIDTH:
463             v32 = (uint32_t)va_arg(ap, uint32_t);
464             if (v32 % 16)
465             {
466                 if (tif->tif_mode != O_RDONLY)
467                     goto badvalue32;
468                 TIFFWarningExtR(
469                     tif, tif->tif_name,
470                     "Nonstandard tile width %" PRIu32 ", convert file", v32);
471             }
472             td->td_tilewidth = v32;
473             tif->tif_flags |= TIFF_ISTILED;
474             break;
475         case TIFFTAG_TILELENGTH:
476             v32 = (uint32_t)va_arg(ap, uint32_t);
477             if (v32 % 16)
478             {
479                 if (tif->tif_mode != O_RDONLY)
480                     goto badvalue32;
481                 TIFFWarningExtR(
482                     tif, tif->tif_name,
483                     "Nonstandard tile length %" PRIu32 ", convert file", v32);
484             }
485             td->td_tilelength = v32;
486             tif->tif_flags |= TIFF_ISTILED;
487             break;
488         case TIFFTAG_TILEDEPTH:
489             v32 = (uint32_t)va_arg(ap, uint32_t);
490             if (v32 == 0)
491                 goto badvalue32;
492             td->td_tiledepth = v32;
493             break;
494         case TIFFTAG_DATATYPE:
495             v = (uint16_t)va_arg(ap, uint16_vap);
496             switch (v)
497             {
498                 case DATATYPE_VOID:
499                     v = SAMPLEFORMAT_VOID;
500                     break;
501                 case DATATYPE_INT:
502                     v = SAMPLEFORMAT_INT;
503                     break;
504                 case DATATYPE_UINT:
505                     v = SAMPLEFORMAT_UINT;
506                     break;
507                 case DATATYPE_IEEEFP:
508                     v = SAMPLEFORMAT_IEEEFP;
509                     break;
510                 default:
511                     goto badvalue;
512             }
513             td->td_sampleformat = (uint16_t)v;
514             break;
515         case TIFFTAG_SAMPLEFORMAT:
516             v = (uint16_t)va_arg(ap, uint16_vap);
517             if (v < SAMPLEFORMAT_UINT || SAMPLEFORMAT_COMPLEXIEEEFP < v)
518                 goto badvalue;
519             td->td_sampleformat = (uint16_t)v;
520 
521             /*  Try to fix up the SWAB function for complex data. */
522             if (td->td_sampleformat == SAMPLEFORMAT_COMPLEXINT &&
523                 td->td_bitspersample == 32 &&
524                 tif->tif_postdecode == _TIFFSwab32BitData)
525                 tif->tif_postdecode = _TIFFSwab16BitData;
526             else if ((td->td_sampleformat == SAMPLEFORMAT_COMPLEXINT ||
527                       td->td_sampleformat == SAMPLEFORMAT_COMPLEXIEEEFP) &&
528                      td->td_bitspersample == 64 &&
529                      tif->tif_postdecode == _TIFFSwab64BitData)
530                 tif->tif_postdecode = _TIFFSwab32BitData;
531             break;
532         case TIFFTAG_IMAGEDEPTH:
533             td->td_imagedepth = (uint32_t)va_arg(ap, uint32_t);
534             break;
535         case TIFFTAG_SUBIFD:
536             if ((tif->tif_flags & TIFF_INSUBIFD) == 0)
537             {
538                 td->td_nsubifd = (uint16_t)va_arg(ap, uint16_vap);
539                 _TIFFsetLong8Array(tif, &td->td_subifd,
540                                    (uint64_t *)va_arg(ap, uint64_t *),
541                                    (uint32_t)td->td_nsubifd);
542             }
543             else
544             {
545                 TIFFErrorExtR(tif, module, "%s: Sorry, cannot nest SubIFDs",
546                               tif->tif_name);
547                 status = 0;
548             }
549             break;
550         case TIFFTAG_YCBCRPOSITIONING:
551             td->td_ycbcrpositioning = (uint16_t)va_arg(ap, uint16_vap);
552             break;
553         case TIFFTAG_YCBCRSUBSAMPLING:
554             td->td_ycbcrsubsampling[0] = (uint16_t)va_arg(ap, uint16_vap);
555             td->td_ycbcrsubsampling[1] = (uint16_t)va_arg(ap, uint16_vap);
556             break;
557         case TIFFTAG_TRANSFERFUNCTION:
558         {
559             uint32_t i;
560             v = (td->td_samplesperpixel - td->td_extrasamples) > 1 ? 3 : 1;
561             for (i = 0; i < v; i++)
562                 _TIFFsetShortArrayExt(tif, &td->td_transferfunction[i],
563                                       va_arg(ap, uint16_t *),
564                                       1U << td->td_bitspersample);
565             break;
566         }
567         case TIFFTAG_REFERENCEBLACKWHITE:
568             /* XXX should check for null range */
569             _TIFFsetFloatArrayExt(tif, &td->td_refblackwhite,
570                                   va_arg(ap, float *), 6);
571             break;
572         case TIFFTAG_INKNAMES:
573         {
574             v = (uint16_t)va_arg(ap, uint16_vap);
575             s = va_arg(ap, char *);
576             uint16_t ninksinstring;
577             ninksinstring = countInkNamesString(tif, v, s);
578             status = ninksinstring > 0;
579             if (ninksinstring > 0)
580             {
581                 _TIFFsetNString(tif, &td->td_inknames, s, v);
582                 td->td_inknameslen = v;
583                 /* Set NumberOfInks to the value ninksinstring */
584                 if (TIFFFieldSet(tif, FIELD_NUMBEROFINKS))
585                 {
586                     if (td->td_numberofinks != ninksinstring)
587                     {
588                         TIFFErrorExtR(
589                             tif, module,
590                             "Warning %s; Tag %s:\n  Value %" PRIu16
591                             " of NumberOfInks is different from the number of "
592                             "inks %" PRIu16
593                             ".\n  -> NumberOfInks value adapted to %" PRIu16 "",
594                             tif->tif_name, fip->field_name, td->td_numberofinks,
595                             ninksinstring, ninksinstring);
596                         td->td_numberofinks = ninksinstring;
597                     }
598                 }
599                 else
600                 {
601                     td->td_numberofinks = ninksinstring;
602                     TIFFSetFieldBit(tif, FIELD_NUMBEROFINKS);
603                 }
604                 if (TIFFFieldSet(tif, FIELD_SAMPLESPERPIXEL))
605                 {
606                     if (td->td_numberofinks != td->td_samplesperpixel)
607                     {
608                         TIFFErrorExtR(tif, module,
609                                       "Warning %s; Tag %s:\n  Value %" PRIu16
610                                       " of NumberOfInks is different from the "
611                                       "SamplesPerPixel value %" PRIu16 "",
612                                       tif->tif_name, fip->field_name,
613                                       td->td_numberofinks,
614                                       td->td_samplesperpixel);
615                     }
616                 }
617             }
618         }
619         break;
620         case TIFFTAG_NUMBEROFINKS:
621             v = (uint16_t)va_arg(ap, uint16_vap);
622             /* If InkNames already set also NumberOfInks is set accordingly and
623              * should be equal */
624             if (TIFFFieldSet(tif, FIELD_INKNAMES))
625             {
626                 if (v != td->td_numberofinks)
627                 {
628                     TIFFErrorExtR(
629                         tif, module,
630                         "Error %s; Tag %s:\n  It is not possible to set the "
631                         "value %" PRIu32
632                         " for NumberOfInks\n  which is different from the "
633                         "number of inks in the InkNames tag (%" PRIu16 ")",
634                         tif->tif_name, fip->field_name, v, td->td_numberofinks);
635                     /* Do not set / overwrite number of inks already set by
636                      * InkNames case accordingly. */
637                     status = 0;
638                 }
639             }
640             else
641             {
642                 td->td_numberofinks = (uint16_t)v;
643                 if (TIFFFieldSet(tif, FIELD_SAMPLESPERPIXEL))
644                 {
645                     if (td->td_numberofinks != td->td_samplesperpixel)
646                     {
647                         TIFFErrorExtR(tif, module,
648                                       "Warning %s; Tag %s:\n  Value %" PRIu32
649                                       " of NumberOfInks is different from the "
650                                       "SamplesPerPixel value %" PRIu16 "",
651                                       tif->tif_name, fip->field_name, v,
652                                       td->td_samplesperpixel);
653                     }
654                 }
655             }
656             break;
657         case TIFFTAG_PERSAMPLE:
658             v = (uint16_t)va_arg(ap, uint16_vap);
659             if (v == PERSAMPLE_MULTI)
660                 tif->tif_flags |= TIFF_PERSAMPLE;
661             else
662                 tif->tif_flags &= ~TIFF_PERSAMPLE;
663             break;
664         default:
665         {
666             TIFFTagValue *tv;
667             int tv_size, iCustom;
668 
669             /*
670              * This can happen if multiple images are open with different
671              * codecs which have private tags.  The global tag information
672              * table may then have tags that are valid for one file but not
673              * the other. If the client tries to set a tag that is not valid
674              * for the image's codec then we'll arrive here.  This
675              * happens, for example, when tiffcp is used to convert between
676              * compression schemes and codec-specific tags are blindly copied.
677              *
678              * This also happens when a FIELD_IGNORE tag is written.
679              */
680             if (fip->field_bit == FIELD_IGNORE)
681             {
682                 TIFFErrorExtR(
683                     tif, module,
684                     "%s: Ignored %stag \"%s\" (not supported by libtiff)",
685                     tif->tif_name, isPseudoTag(tag) ? "pseudo-" : "",
686                     fip->field_name);
687                 status = 0;
688                 break;
689             }
690             if (fip->field_bit != FIELD_CUSTOM)
691             {
692                 TIFFErrorExtR(
693                     tif, module,
694                     "%s: Invalid %stag \"%s\" (not supported by codec)",
695                     tif->tif_name, isPseudoTag(tag) ? "pseudo-" : "",
696                     fip->field_name);
697                 status = 0;
698                 break;
699             }
700 
701             /*
702              * Find the existing entry for this custom value.
703              */
704             tv = NULL;
705             for (iCustom = 0; iCustom < td->td_customValueCount; iCustom++)
706             {
707                 if (td->td_customValues[iCustom].info->field_tag == tag)
708                 {
709                     tv = td->td_customValues + iCustom;
710                     if (tv->value != NULL)
711                     {
712                         _TIFFfreeExt(tif, tv->value);
713                         tv->value = NULL;
714                     }
715                     break;
716                 }
717             }
718 
719             /*
720              * Grow the custom list if the entry was not found.
721              */
722             if (tv == NULL)
723             {
724                 TIFFTagValue *new_customValues;
725 
726                 td->td_customValueCount++;
727                 new_customValues = (TIFFTagValue *)_TIFFreallocExt(
728                     tif, td->td_customValues,
729                     sizeof(TIFFTagValue) * td->td_customValueCount);
730                 if (!new_customValues)
731                 {
732                     TIFFErrorExtR(tif, module,
733                                   "%s: Failed to allocate space for list of "
734                                   "custom values",
735                                   tif->tif_name);
736                     status = 0;
737                     goto end;
738                 }
739 
740                 td->td_customValues = new_customValues;
741 
742                 tv = td->td_customValues + (td->td_customValueCount - 1);
743                 tv->info = fip;
744                 tv->value = NULL;
745                 tv->count = 0;
746             }
747 
748             /*
749              * Set custom value ... save a copy of the custom tag value.
750              */
751             /*--: Rational2Double: For Rationals evaluate "set_field_type" to
752              * determine internal storage size. */
753             tv_size = TIFFFieldSetGetSize(fip);
754             if (tv_size == 0)
755             {
756                 status = 0;
757                 TIFFErrorExtR(tif, module, "%s: Bad field type %d for \"%s\"",
758                               tif->tif_name, fip->field_type, fip->field_name);
759                 goto end;
760             }
761 
762             if (fip->field_type == TIFF_ASCII)
763             {
764                 uint32_t ma;
765                 const char *mb;
766                 if (fip->field_passcount)
767                 {
768                     assert(fip->field_writecount == TIFF_VARIABLE2);
769                     ma = (uint32_t)va_arg(ap, uint32_t);
770                     mb = (const char *)va_arg(ap, const char *);
771                 }
772                 else
773                 {
774                     mb = (const char *)va_arg(ap, const char *);
775                     size_t len = strlen(mb) + 1;
776                     if (len >= 0x80000000U)
777                     {
778                         status = 0;
779                         TIFFErrorExtR(tif, module,
780                                       "%s: Too long string value for \"%s\". "
781                                       "Maximum supported is 2147483647 bytes",
782                                       tif->tif_name, fip->field_name);
783                         goto end;
784                     }
785                     ma = (uint32_t)len;
786                 }
787                 tv->count = ma;
788                 setByteArray(tif, &tv->value, mb, ma, 1);
789             }
790             else
791             {
792                 if (fip->field_passcount)
793                 {
794                     if (fip->field_writecount == TIFF_VARIABLE2)
795                         tv->count = (uint32_t)va_arg(ap, uint32_t);
796                     else
797                         tv->count = (int)va_arg(ap, int);
798                 }
799                 else if (fip->field_writecount == TIFF_VARIABLE ||
800                          fip->field_writecount == TIFF_VARIABLE2)
801                     tv->count = 1;
802                 else if (fip->field_writecount == TIFF_SPP)
803                     tv->count = td->td_samplesperpixel;
804                 else
805                     tv->count = fip->field_writecount;
806 
807                 if (tv->count == 0)
808                 {
809                     status = 0;
810                     TIFFErrorExtR(tif, module,
811                                   "%s: Null count for \"%s\" (type "
812                                   "%d, writecount %d, passcount %d)",
813                                   tif->tif_name, fip->field_name,
814                                   fip->field_type, fip->field_writecount,
815                                   fip->field_passcount);
816                     goto end;
817                 }
818 
819                 tv->value = _TIFFCheckMalloc(tif, tv->count, tv_size,
820                                              "custom tag binary object");
821                 if (!tv->value)
822                 {
823                     status = 0;
824                     goto end;
825                 }
826 
827                 if (fip->field_tag == TIFFTAG_DOTRANGE &&
828                     strcmp(fip->field_name, "DotRange") == 0)
829                 {
830                     /* TODO: This is an evil exception and should not have been
831                        handled this way ... likely best if we move it into
832                        the directory structure with an explicit field in
833                        libtiff 4.1 and assign it a FIELD_ value */
834                     uint16_t v2[2];
835                     v2[0] = (uint16_t)va_arg(ap, int);
836                     v2[1] = (uint16_t)va_arg(ap, int);
837                     _TIFFmemcpy(tv->value, &v2, 4);
838                 }
839 
840                 else if (fip->field_passcount ||
841                          fip->field_writecount == TIFF_VARIABLE ||
842                          fip->field_writecount == TIFF_VARIABLE2 ||
843                          fip->field_writecount == TIFF_SPP || tv->count > 1)
844                 {
845                     /*--: Rational2Double: For Rationals tv_size is set above to
846                      * 4 or 8 according to fip->set_field_type! */
847                     _TIFFmemcpy(tv->value, va_arg(ap, void *),
848                                 tv->count * tv_size);
849                     /* Test here for too big values for LONG8, SLONG8 in
850                      * ClassicTIFF and delete custom field from custom list */
851                     if (!(tif->tif_flags & TIFF_BIGTIFF))
852                     {
853                         if (tv->info->field_type == TIFF_LONG8)
854                         {
855                             uint64_t *pui64 = (uint64_t *)tv->value;
856                             for (int i = 0; i < tv->count; i++)
857                             {
858                                 if (pui64[i] > 0xffffffffu)
859                                 {
860                                     TIFFErrorExtR(
861                                         tif, module,
862                                         "%s: Bad LONG8 value %" PRIu64
863                                         " at %d. array position for \"%s\" tag "
864                                         "%d in ClassicTIFF. Tag won't be "
865                                         "written to file",
866                                         tif->tif_name, pui64[i], i,
867                                         fip->field_name, tag);
868                                     goto badvalueifd8long8;
869                                 }
870                             }
871                         }
872                         else if (tv->info->field_type == TIFF_SLONG8)
873                         {
874                             int64_t *pi64 = (int64_t *)tv->value;
875                             for (int i = 0; i < tv->count; i++)
876                             {
877                                 if (pi64[i] > 2147483647 ||
878                                     pi64[i] < (-2147483647 - 1))
879                                 {
880                                     TIFFErrorExtR(
881                                         tif, module,
882                                         "%s: Bad SLONG8 value %" PRIi64
883                                         " at %d. array position for \"%s\" tag "
884                                         "%d in ClassicTIFF. Tag won't be "
885                                         "written to file",
886                                         tif->tif_name, pi64[i], i,
887                                         fip->field_name, tag);
888                                     goto badvalueifd8long8;
889                                 }
890                             }
891                         }
892                     }
893                 }
894                 else
895                 {
896                     char *val = (char *)tv->value;
897                     assert(tv->count == 1);
898 
899                     switch (fip->field_type)
900                     {
901                         case TIFF_BYTE:
902                         case TIFF_UNDEFINED:
903                         {
904                             uint8_t v2 = (uint8_t)va_arg(ap, int);
905                             _TIFFmemcpy(val, &v2, tv_size);
906                         }
907                         break;
908                         case TIFF_SBYTE:
909                         {
910                             int8_t v2 = (int8_t)va_arg(ap, int);
911                             _TIFFmemcpy(val, &v2, tv_size);
912                         }
913                         break;
914                         case TIFF_SHORT:
915                         {
916                             uint16_t v2 = (uint16_t)va_arg(ap, int);
917                             _TIFFmemcpy(val, &v2, tv_size);
918                         }
919                         break;
920                         case TIFF_SSHORT:
921                         {
922                             int16_t v2 = (int16_t)va_arg(ap, int);
923                             _TIFFmemcpy(val, &v2, tv_size);
924                         }
925                         break;
926                         case TIFF_LONG:
927                         case TIFF_IFD:
928                         {
929                             uint32_t v2 = va_arg(ap, uint32_t);
930                             _TIFFmemcpy(val, &v2, tv_size);
931                         }
932                         break;
933                         case TIFF_SLONG:
934                         {
935                             int32_t v2 = va_arg(ap, int32_t);
936                             _TIFFmemcpy(val, &v2, tv_size);
937                         }
938                         break;
939                         case TIFF_LONG8:
940                         case TIFF_IFD8:
941                         {
942                             uint64_t v2 = va_arg(ap, uint64_t);
943                             _TIFFmemcpy(val, &v2, tv_size);
944                             /* Test here for too big values for ClassicTIFF and
945                              * delete custom field from custom list */
946                             if (!(tif->tif_flags & TIFF_BIGTIFF) &&
947                                 (v2 > 0xffffffffu))
948                             {
949                                 TIFFErrorExtR(
950                                     tif, module,
951                                     "%s: Bad LONG8 or IFD8 value %" PRIu64
952                                     " for \"%s\" tag %d in ClassicTIFF. Tag "
953                                     "won't be written to file",
954                                     tif->tif_name, v2, fip->field_name, tag);
955                                 goto badvalueifd8long8;
956                             }
957                         }
958                         break;
959                         case TIFF_SLONG8:
960                         {
961                             int64_t v2 = va_arg(ap, int64_t);
962                             _TIFFmemcpy(val, &v2, tv_size);
963                             /* Test here for too big values for ClassicTIFF and
964                              * delete custom field from custom list */
965                             if (!(tif->tif_flags & TIFF_BIGTIFF) &&
966                                 ((v2 > 2147483647) || (v2 < (-2147483647 - 1))))
967                             {
968                                 TIFFErrorExtR(
969                                     tif, module,
970                                     "%s: Bad SLONG8 value %" PRIi64
971                                     " for \"%s\" tag %d in ClassicTIFF. Tag "
972                                     "won't be written to file",
973                                     tif->tif_name, v2, fip->field_name, tag);
974                                 goto badvalueifd8long8;
975                             }
976                         }
977                         break;
978                         case TIFF_RATIONAL:
979                         case TIFF_SRATIONAL:
980                             /*-- Rational2Double: For Rationals tv_size is set
981                              * above to 4 or 8 according to fip->set_field_type!
982                              */
983                             {
984                                 if (tv_size == 8)
985                                 {
986                                     double v2 = va_arg(ap, double);
987                                     _TIFFmemcpy(val, &v2, tv_size);
988                                 }
989                                 else
990                                 {
991                                     /*-- default should be tv_size == 4 */
992                                     float v3 = (float)va_arg(ap, double);
993                                     _TIFFmemcpy(val, &v3, tv_size);
994                                     /*-- ToDo: After Testing, this should be
995                                      * removed and tv_size==4 should be set as
996                                      * default. */
997                                     if (tv_size != 4)
998                                     {
999                                         TIFFErrorExtR(
1000                                             tif, module,
1001                                             "Rational2Double: .set_field_type "
1002                                             "in not 4 but %d",
1003                                             tv_size);
1004                                     }
1005                                 }
1006                             }
1007                             break;
1008                         case TIFF_FLOAT:
1009                         {
1010                             float v2 =
1011                                 _TIFFClampDoubleToFloat(va_arg(ap, double));
1012                             _TIFFmemcpy(val, &v2, tv_size);
1013                         }
1014                         break;
1015                         case TIFF_DOUBLE:
1016                         {
1017                             double v2 = va_arg(ap, double);
1018                             _TIFFmemcpy(val, &v2, tv_size);
1019                         }
1020                         break;
1021                         default:
1022                             _TIFFmemset(val, 0, tv_size);
1023                             status = 0;
1024                             break;
1025                     }
1026                 }
1027             }
1028         }
1029     }
1030     if (status)
1031     {
1032         const TIFFField *fip2 = TIFFFieldWithTag(tif, tag);
1033         if (fip2)
1034             TIFFSetFieldBit(tif, fip2->field_bit);
1035         tif->tif_flags |= TIFF_DIRTYDIRECT;
1036     }
1037 
1038 end:
1039     va_end(ap);
1040     return (status);
1041 badvalue:
1042 {
1043     const TIFFField *fip2 = TIFFFieldWithTag(tif, tag);
1044     TIFFErrorExtR(tif, module, "%s: Bad value %" PRIu32 " for \"%s\" tag",
1045                   tif->tif_name, v, fip2 ? fip2->field_name : "Unknown");
1046     va_end(ap);
1047 }
1048     return (0);
1049 badvalue32:
1050 {
1051     const TIFFField *fip2 = TIFFFieldWithTag(tif, tag);
1052     TIFFErrorExtR(tif, module, "%s: Bad value %" PRIu32 " for \"%s\" tag",
1053                   tif->tif_name, v32, fip2 ? fip2->field_name : "Unknown");
1054     va_end(ap);
1055 }
1056     return (0);
1057 badvaluedouble:
1058 {
1059     const TIFFField *fip2 = TIFFFieldWithTag(tif, tag);
1060     TIFFErrorExtR(tif, module, "%s: Bad value %f for \"%s\" tag", tif->tif_name,
1061                   dblval, fip2 ? fip2->field_name : "Unknown");
1062     va_end(ap);
1063 }
1064     return (0);
1065 badvalueifd8long8:
1066 {
1067     /* Error message issued already above. */
1068     TIFFTagValue *tv2 = NULL;
1069     int iCustom2, iC2;
1070     /* Find the existing entry for this custom value. */
1071     for (iCustom2 = 0; iCustom2 < td->td_customValueCount; iCustom2++)
1072     {
1073         if (td->td_customValues[iCustom2].info->field_tag == tag)
1074         {
1075             tv2 = td->td_customValues + (iCustom2);
1076             break;
1077         }
1078     }
1079     if (tv2 != NULL)
1080     {
1081         /* Remove custom field from custom list */
1082         if (tv2->value != NULL)
1083         {
1084             _TIFFfreeExt(tif, tv2->value);
1085             tv2->value = NULL;
1086         }
1087         /* Shorten list and close gap in customValues list.
1088          * Re-allocation of td_customValues not necessary here. */
1089         td->td_customValueCount--;
1090         for (iC2 = iCustom2; iC2 < td->td_customValueCount; iC2++)
1091         {
1092             td->td_customValues[iC2] = td->td_customValues[iC2 + 1];
1093         }
1094     }
1095     else
1096     {
1097         assert(0);
1098     }
1099     va_end(ap);
1100 }
1101     return (0);
1102 } /*-- _TIFFVSetField() --*/
1103 
1104 /*
1105  * Return 1/0 according to whether or not
1106  * it is permissible to set the tag's value.
1107  * Note that we allow ImageLength to be changed
1108  * so that we can append and extend to images.
1109  * Any other tag may not be altered once writing
1110  * has commenced, unless its value has no effect
1111  * on the format of the data that is written.
1112  */
OkToChangeTag(TIFF * tif,uint32_t tag)1113 static int OkToChangeTag(TIFF *tif, uint32_t tag)
1114 {
1115     const TIFFField *fip = TIFFFindField(tif, tag, TIFF_ANY);
1116     if (!fip)
1117     { /* unknown tag */
1118         TIFFErrorExtR(tif, "TIFFSetField", "%s: Unknown %stag %" PRIu32,
1119                       tif->tif_name, isPseudoTag(tag) ? "pseudo-" : "", tag);
1120         return (0);
1121     }
1122     if (tag != TIFFTAG_IMAGELENGTH && (tif->tif_flags & TIFF_BEENWRITING) &&
1123         !fip->field_oktochange)
1124     {
1125         /*
1126          * Consult info table to see if tag can be changed
1127          * after we've started writing.  We only allow changes
1128          * to those tags that don't/shouldn't affect the
1129          * compression and/or format of the data.
1130          */
1131         TIFFErrorExtR(tif, "TIFFSetField",
1132                       "%s: Cannot modify tag \"%s\" while writing",
1133                       tif->tif_name, fip->field_name);
1134         return (0);
1135     }
1136     return (1);
1137 }
1138 
1139 /*
1140  * Record the value of a field in the
1141  * internal directory structure.  The
1142  * field will be written to the file
1143  * when/if the directory structure is
1144  * updated.
1145  */
TIFFSetField(TIFF * tif,uint32_t tag,...)1146 int TIFFSetField(TIFF *tif, uint32_t tag, ...)
1147 {
1148     va_list ap;
1149     int status;
1150 
1151     va_start(ap, tag);
1152     status = TIFFVSetField(tif, tag, ap);
1153     va_end(ap);
1154     return (status);
1155 }
1156 
1157 /*
1158  * Clear the contents of the field in the internal structure.
1159  */
TIFFUnsetField(TIFF * tif,uint32_t tag)1160 int TIFFUnsetField(TIFF *tif, uint32_t tag)
1161 {
1162     const TIFFField *fip = TIFFFieldWithTag(tif, tag);
1163     TIFFDirectory *td = &tif->tif_dir;
1164 
1165     if (!fip)
1166         return 0;
1167 
1168     if (fip->field_bit != FIELD_CUSTOM)
1169         TIFFClrFieldBit(tif, fip->field_bit);
1170     else
1171     {
1172         TIFFTagValue *tv = NULL;
1173         int i;
1174 
1175         for (i = 0; i < td->td_customValueCount; i++)
1176         {
1177 
1178             tv = td->td_customValues + i;
1179             if (tv->info->field_tag == tag)
1180                 break;
1181         }
1182 
1183         if (i < td->td_customValueCount)
1184         {
1185             _TIFFfreeExt(tif, tv->value);
1186             for (; i < td->td_customValueCount - 1; i++)
1187             {
1188                 td->td_customValues[i] = td->td_customValues[i + 1];
1189             }
1190             td->td_customValueCount--;
1191         }
1192     }
1193 
1194     tif->tif_flags |= TIFF_DIRTYDIRECT;
1195 
1196     return (1);
1197 }
1198 
1199 /*
1200  * Like TIFFSetField, but taking a varargs
1201  * parameter list.  This routine is useful
1202  * for building higher-level interfaces on
1203  * top of the library.
1204  */
TIFFVSetField(TIFF * tif,uint32_t tag,va_list ap)1205 int TIFFVSetField(TIFF *tif, uint32_t tag, va_list ap)
1206 {
1207     return OkToChangeTag(tif, tag)
1208                ? (*tif->tif_tagmethods.vsetfield)(tif, tag, ap)
1209                : 0;
1210 }
1211 
_TIFFVGetField(TIFF * tif,uint32_t tag,va_list ap)1212 static int _TIFFVGetField(TIFF *tif, uint32_t tag, va_list ap)
1213 {
1214     TIFFDirectory *td = &tif->tif_dir;
1215     int ret_val = 1;
1216     uint32_t standard_tag = tag;
1217     const TIFFField *fip = TIFFFindField(tif, tag, TIFF_ANY);
1218     if (fip == NULL) /* cannot happen since TIFFGetField() already checks it */
1219         return 0;
1220 
1221     /*
1222      * We want to force the custom code to be used for custom
1223      * fields even if the tag happens to match a well known
1224      * one - important for reinterpreted handling of standard
1225      * tag values in custom directories (i.e. EXIF)
1226      */
1227     if (fip->field_bit == FIELD_CUSTOM)
1228     {
1229         standard_tag = 0;
1230     }
1231 
1232     switch (standard_tag)
1233     {
1234         case TIFFTAG_SUBFILETYPE:
1235             *va_arg(ap, uint32_t *) = td->td_subfiletype;
1236             break;
1237         case TIFFTAG_IMAGEWIDTH:
1238             *va_arg(ap, uint32_t *) = td->td_imagewidth;
1239             break;
1240         case TIFFTAG_IMAGELENGTH:
1241             *va_arg(ap, uint32_t *) = td->td_imagelength;
1242             break;
1243         case TIFFTAG_BITSPERSAMPLE:
1244             *va_arg(ap, uint16_t *) = td->td_bitspersample;
1245             break;
1246         case TIFFTAG_COMPRESSION:
1247             *va_arg(ap, uint16_t *) = td->td_compression;
1248             break;
1249         case TIFFTAG_PHOTOMETRIC:
1250             *va_arg(ap, uint16_t *) = td->td_photometric;
1251             break;
1252         case TIFFTAG_THRESHHOLDING:
1253             *va_arg(ap, uint16_t *) = td->td_threshholding;
1254             break;
1255         case TIFFTAG_FILLORDER:
1256             *va_arg(ap, uint16_t *) = td->td_fillorder;
1257             break;
1258         case TIFFTAG_ORIENTATION:
1259             *va_arg(ap, uint16_t *) = td->td_orientation;
1260             break;
1261         case TIFFTAG_SAMPLESPERPIXEL:
1262             *va_arg(ap, uint16_t *) = td->td_samplesperpixel;
1263             break;
1264         case TIFFTAG_ROWSPERSTRIP:
1265             *va_arg(ap, uint32_t *) = td->td_rowsperstrip;
1266             break;
1267         case TIFFTAG_MINSAMPLEVALUE:
1268             *va_arg(ap, uint16_t *) = td->td_minsamplevalue;
1269             break;
1270         case TIFFTAG_MAXSAMPLEVALUE:
1271             *va_arg(ap, uint16_t *) = td->td_maxsamplevalue;
1272             break;
1273         case TIFFTAG_SMINSAMPLEVALUE:
1274             if (tif->tif_flags & TIFF_PERSAMPLE)
1275                 *va_arg(ap, double **) = td->td_sminsamplevalue;
1276             else
1277             {
1278                 /* libtiff historically treats this as a single value. */
1279                 uint16_t i;
1280                 double v = td->td_sminsamplevalue[0];
1281                 for (i = 1; i < td->td_samplesperpixel; ++i)
1282                     if (td->td_sminsamplevalue[i] < v)
1283                         v = td->td_sminsamplevalue[i];
1284                 *va_arg(ap, double *) = v;
1285             }
1286             break;
1287         case TIFFTAG_SMAXSAMPLEVALUE:
1288             if (tif->tif_flags & TIFF_PERSAMPLE)
1289                 *va_arg(ap, double **) = td->td_smaxsamplevalue;
1290             else
1291             {
1292                 /* libtiff historically treats this as a single value. */
1293                 uint16_t i;
1294                 double v = td->td_smaxsamplevalue[0];
1295                 for (i = 1; i < td->td_samplesperpixel; ++i)
1296                     if (td->td_smaxsamplevalue[i] > v)
1297                         v = td->td_smaxsamplevalue[i];
1298                 *va_arg(ap, double *) = v;
1299             }
1300             break;
1301         case TIFFTAG_XRESOLUTION:
1302             *va_arg(ap, float *) = td->td_xresolution;
1303             break;
1304         case TIFFTAG_YRESOLUTION:
1305             *va_arg(ap, float *) = td->td_yresolution;
1306             break;
1307         case TIFFTAG_PLANARCONFIG:
1308             *va_arg(ap, uint16_t *) = td->td_planarconfig;
1309             break;
1310         case TIFFTAG_XPOSITION:
1311             *va_arg(ap, float *) = td->td_xposition;
1312             break;
1313         case TIFFTAG_YPOSITION:
1314             *va_arg(ap, float *) = td->td_yposition;
1315             break;
1316         case TIFFTAG_RESOLUTIONUNIT:
1317             *va_arg(ap, uint16_t *) = td->td_resolutionunit;
1318             break;
1319         case TIFFTAG_PAGENUMBER:
1320             *va_arg(ap, uint16_t *) = td->td_pagenumber[0];
1321             *va_arg(ap, uint16_t *) = td->td_pagenumber[1];
1322             break;
1323         case TIFFTAG_HALFTONEHINTS:
1324             *va_arg(ap, uint16_t *) = td->td_halftonehints[0];
1325             *va_arg(ap, uint16_t *) = td->td_halftonehints[1];
1326             break;
1327         case TIFFTAG_COLORMAP:
1328             *va_arg(ap, const uint16_t **) = td->td_colormap[0];
1329             *va_arg(ap, const uint16_t **) = td->td_colormap[1];
1330             *va_arg(ap, const uint16_t **) = td->td_colormap[2];
1331             break;
1332         case TIFFTAG_STRIPOFFSETS:
1333         case TIFFTAG_TILEOFFSETS:
1334             _TIFFFillStriles(tif);
1335             *va_arg(ap, const uint64_t **) = td->td_stripoffset_p;
1336             if (td->td_stripoffset_p == NULL)
1337                 ret_val = 0;
1338             break;
1339         case TIFFTAG_STRIPBYTECOUNTS:
1340         case TIFFTAG_TILEBYTECOUNTS:
1341             _TIFFFillStriles(tif);
1342             *va_arg(ap, const uint64_t **) = td->td_stripbytecount_p;
1343             if (td->td_stripbytecount_p == NULL)
1344                 ret_val = 0;
1345             break;
1346         case TIFFTAG_MATTEING:
1347             *va_arg(ap, uint16_t *) =
1348                 (td->td_extrasamples == 1 &&
1349                  td->td_sampleinfo[0] == EXTRASAMPLE_ASSOCALPHA);
1350             break;
1351         case TIFFTAG_EXTRASAMPLES:
1352             *va_arg(ap, uint16_t *) = td->td_extrasamples;
1353             *va_arg(ap, const uint16_t **) = td->td_sampleinfo;
1354             break;
1355         case TIFFTAG_TILEWIDTH:
1356             *va_arg(ap, uint32_t *) = td->td_tilewidth;
1357             break;
1358         case TIFFTAG_TILELENGTH:
1359             *va_arg(ap, uint32_t *) = td->td_tilelength;
1360             break;
1361         case TIFFTAG_TILEDEPTH:
1362             *va_arg(ap, uint32_t *) = td->td_tiledepth;
1363             break;
1364         case TIFFTAG_DATATYPE:
1365             switch (td->td_sampleformat)
1366             {
1367                 case SAMPLEFORMAT_UINT:
1368                     *va_arg(ap, uint16_t *) = DATATYPE_UINT;
1369                     break;
1370                 case SAMPLEFORMAT_INT:
1371                     *va_arg(ap, uint16_t *) = DATATYPE_INT;
1372                     break;
1373                 case SAMPLEFORMAT_IEEEFP:
1374                     *va_arg(ap, uint16_t *) = DATATYPE_IEEEFP;
1375                     break;
1376                 case SAMPLEFORMAT_VOID:
1377                     *va_arg(ap, uint16_t *) = DATATYPE_VOID;
1378                     break;
1379             }
1380             break;
1381         case TIFFTAG_SAMPLEFORMAT:
1382             *va_arg(ap, uint16_t *) = td->td_sampleformat;
1383             break;
1384         case TIFFTAG_IMAGEDEPTH:
1385             *va_arg(ap, uint32_t *) = td->td_imagedepth;
1386             break;
1387         case TIFFTAG_SUBIFD:
1388             *va_arg(ap, uint16_t *) = td->td_nsubifd;
1389             *va_arg(ap, const uint64_t **) = td->td_subifd;
1390             break;
1391         case TIFFTAG_YCBCRPOSITIONING:
1392             *va_arg(ap, uint16_t *) = td->td_ycbcrpositioning;
1393             break;
1394         case TIFFTAG_YCBCRSUBSAMPLING:
1395             *va_arg(ap, uint16_t *) = td->td_ycbcrsubsampling[0];
1396             *va_arg(ap, uint16_t *) = td->td_ycbcrsubsampling[1];
1397             break;
1398         case TIFFTAG_TRANSFERFUNCTION:
1399             *va_arg(ap, const uint16_t **) = td->td_transferfunction[0];
1400             if (td->td_samplesperpixel - td->td_extrasamples > 1)
1401             {
1402                 *va_arg(ap, const uint16_t **) = td->td_transferfunction[1];
1403                 *va_arg(ap, const uint16_t **) = td->td_transferfunction[2];
1404             }
1405             else
1406             {
1407                 *va_arg(ap, const uint16_t **) = NULL;
1408                 *va_arg(ap, const uint16_t **) = NULL;
1409             }
1410             break;
1411         case TIFFTAG_REFERENCEBLACKWHITE:
1412             *va_arg(ap, const float **) = td->td_refblackwhite;
1413             break;
1414         case TIFFTAG_INKNAMES:
1415             *va_arg(ap, const char **) = td->td_inknames;
1416             break;
1417         case TIFFTAG_NUMBEROFINKS:
1418             *va_arg(ap, uint16_t *) = td->td_numberofinks;
1419             break;
1420         default:
1421         {
1422             int i;
1423 
1424             /*
1425              * This can happen if multiple images are open
1426              * with different codecs which have private
1427              * tags.  The global tag information table may
1428              * then have tags that are valid for one file
1429              * but not the other. If the client tries to
1430              * get a tag that is not valid for the image's
1431              * codec then we'll arrive here.
1432              */
1433             if (fip->field_bit != FIELD_CUSTOM)
1434             {
1435                 TIFFErrorExtR(tif, "_TIFFVGetField",
1436                               "%s: Invalid %stag \"%s\" "
1437                               "(not supported by codec)",
1438                               tif->tif_name, isPseudoTag(tag) ? "pseudo-" : "",
1439                               fip->field_name);
1440                 ret_val = 0;
1441                 break;
1442             }
1443 
1444             /*
1445              * Do we have a custom value?
1446              */
1447             ret_val = 0;
1448             for (i = 0; i < td->td_customValueCount; i++)
1449             {
1450                 TIFFTagValue *tv = td->td_customValues + i;
1451 
1452                 if (tv->info->field_tag != tag)
1453                     continue;
1454 
1455                 if (fip->field_passcount)
1456                 {
1457                     if (fip->field_readcount == TIFF_VARIABLE2)
1458                         *va_arg(ap, uint32_t *) = (uint32_t)tv->count;
1459                     else /* Assume TIFF_VARIABLE */
1460                         *va_arg(ap, uint16_t *) = (uint16_t)tv->count;
1461                     *va_arg(ap, const void **) = tv->value;
1462                     ret_val = 1;
1463                 }
1464                 else if (fip->field_tag == TIFFTAG_DOTRANGE &&
1465                          strcmp(fip->field_name, "DotRange") == 0)
1466                 {
1467                     /* TODO: This is an evil exception and should not have been
1468                        handled this way ... likely best if we move it into
1469                        the directory structure with an explicit field in
1470                        libtiff 4.1 and assign it a FIELD_ value */
1471                     *va_arg(ap, uint16_t *) = ((uint16_t *)tv->value)[0];
1472                     *va_arg(ap, uint16_t *) = ((uint16_t *)tv->value)[1];
1473                     ret_val = 1;
1474                 }
1475                 else
1476                 {
1477                     if (fip->field_type == TIFF_ASCII ||
1478                         fip->field_readcount == TIFF_VARIABLE ||
1479                         fip->field_readcount == TIFF_VARIABLE2 ||
1480                         fip->field_readcount == TIFF_SPP || tv->count > 1)
1481                     {
1482                         *va_arg(ap, void **) = tv->value;
1483                         ret_val = 1;
1484                     }
1485                     else
1486                     {
1487                         char *val = (char *)tv->value;
1488                         assert(tv->count == 1);
1489                         switch (fip->field_type)
1490                         {
1491                             case TIFF_BYTE:
1492                             case TIFF_UNDEFINED:
1493                                 *va_arg(ap, uint8_t *) = *(uint8_t *)val;
1494                                 ret_val = 1;
1495                                 break;
1496                             case TIFF_SBYTE:
1497                                 *va_arg(ap, int8_t *) = *(int8_t *)val;
1498                                 ret_val = 1;
1499                                 break;
1500                             case TIFF_SHORT:
1501                                 *va_arg(ap, uint16_t *) = *(uint16_t *)val;
1502                                 ret_val = 1;
1503                                 break;
1504                             case TIFF_SSHORT:
1505                                 *va_arg(ap, int16_t *) = *(int16_t *)val;
1506                                 ret_val = 1;
1507                                 break;
1508                             case TIFF_LONG:
1509                             case TIFF_IFD:
1510                                 *va_arg(ap, uint32_t *) = *(uint32_t *)val;
1511                                 ret_val = 1;
1512                                 break;
1513                             case TIFF_SLONG:
1514                                 *va_arg(ap, int32_t *) = *(int32_t *)val;
1515                                 ret_val = 1;
1516                                 break;
1517                             case TIFF_LONG8:
1518                             case TIFF_IFD8:
1519                                 *va_arg(ap, uint64_t *) = *(uint64_t *)val;
1520                                 ret_val = 1;
1521                                 break;
1522                             case TIFF_SLONG8:
1523                                 *va_arg(ap, int64_t *) = *(int64_t *)val;
1524                                 ret_val = 1;
1525                                 break;
1526                             case TIFF_RATIONAL:
1527                             case TIFF_SRATIONAL:
1528                             {
1529                                 /*-- Rational2Double: For Rationals evaluate
1530                                  * "set_field_type" to determine internal
1531                                  * storage size and return value size. */
1532                                 int tv_size = TIFFFieldSetGetSize(fip);
1533                                 if (tv_size == 8)
1534                                 {
1535                                     *va_arg(ap, double *) = *(double *)val;
1536                                     ret_val = 1;
1537                                 }
1538                                 else
1539                                 {
1540                                     /*-- default should be tv_size == 4  */
1541                                     *va_arg(ap, float *) = *(float *)val;
1542                                     ret_val = 1;
1543                                     /*-- ToDo: After Testing, this should be
1544                                      * removed and tv_size==4 should be set as
1545                                      * default. */
1546                                     if (tv_size != 4)
1547                                     {
1548                                         TIFFErrorExtR(
1549                                             tif, "_TIFFVGetField",
1550                                             "Rational2Double: .set_field_type "
1551                                             "in not 4 but %d",
1552                                             tv_size);
1553                                     }
1554                                 }
1555                             }
1556                             break;
1557                             case TIFF_FLOAT:
1558                                 *va_arg(ap, float *) = *(float *)val;
1559                                 ret_val = 1;
1560                                 break;
1561                             case TIFF_DOUBLE:
1562                                 *va_arg(ap, double *) = *(double *)val;
1563                                 ret_val = 1;
1564                                 break;
1565                             default:
1566                                 ret_val = 0;
1567                                 break;
1568                         }
1569                     }
1570                 }
1571                 break;
1572             }
1573         }
1574     }
1575     return (ret_val);
1576 }
1577 
1578 /*
1579  * Return the value of a field in the
1580  * internal directory structure.
1581  */
TIFFGetField(TIFF * tif,uint32_t tag,...)1582 int TIFFGetField(TIFF *tif, uint32_t tag, ...)
1583 {
1584     int status;
1585     va_list ap;
1586 
1587     va_start(ap, tag);
1588     status = TIFFVGetField(tif, tag, ap);
1589     va_end(ap);
1590     return (status);
1591 }
1592 
1593 /*
1594  * Like TIFFGetField, but taking a varargs
1595  * parameter list.  This routine is useful
1596  * for building higher-level interfaces on
1597  * top of the library.
1598  */
TIFFVGetField(TIFF * tif,uint32_t tag,va_list ap)1599 int TIFFVGetField(TIFF *tif, uint32_t tag, va_list ap)
1600 {
1601     const TIFFField *fip = TIFFFindField(tif, tag, TIFF_ANY);
1602     return (fip && (isPseudoTag(tag) || TIFFFieldSet(tif, fip->field_bit))
1603                 ? (*tif->tif_tagmethods.vgetfield)(tif, tag, ap)
1604                 : 0);
1605 }
1606 
1607 #define CleanupField(member)                                                   \
1608     {                                                                          \
1609         if (td->member)                                                        \
1610         {                                                                      \
1611             _TIFFfreeExt(tif, td->member);                                     \
1612             td->member = 0;                                                    \
1613         }                                                                      \
1614     }
1615 
1616 /*
1617  * Release storage associated with a directory.
1618  */
TIFFFreeDirectory(TIFF * tif)1619 void TIFFFreeDirectory(TIFF *tif)
1620 {
1621     TIFFDirectory *td = &tif->tif_dir;
1622     int i;
1623 
1624     _TIFFmemset(td->td_fieldsset, 0, sizeof(td->td_fieldsset));
1625     CleanupField(td_sminsamplevalue);
1626     CleanupField(td_smaxsamplevalue);
1627     CleanupField(td_colormap[0]);
1628     CleanupField(td_colormap[1]);
1629     CleanupField(td_colormap[2]);
1630     CleanupField(td_sampleinfo);
1631     CleanupField(td_subifd);
1632     CleanupField(td_inknames);
1633     CleanupField(td_refblackwhite);
1634     CleanupField(td_transferfunction[0]);
1635     CleanupField(td_transferfunction[1]);
1636     CleanupField(td_transferfunction[2]);
1637     CleanupField(td_stripoffset_p);
1638     CleanupField(td_stripbytecount_p);
1639     td->td_stripoffsetbyteallocsize = 0;
1640     TIFFClrFieldBit(tif, FIELD_YCBCRSUBSAMPLING);
1641     TIFFClrFieldBit(tif, FIELD_YCBCRPOSITIONING);
1642 
1643     /* Cleanup custom tag values */
1644     for (i = 0; i < td->td_customValueCount; i++)
1645     {
1646         if (td->td_customValues[i].value)
1647             _TIFFfreeExt(tif, td->td_customValues[i].value);
1648     }
1649 
1650     td->td_customValueCount = 0;
1651     CleanupField(td_customValues);
1652 
1653     _TIFFmemset(&(td->td_stripoffset_entry), 0, sizeof(TIFFDirEntry));
1654     _TIFFmemset(&(td->td_stripbytecount_entry), 0, sizeof(TIFFDirEntry));
1655 }
1656 #undef CleanupField
1657 
1658 /*
1659  * Client Tag extension support (from Niles Ritter).
1660  */
1661 static TIFFExtendProc _TIFFextender = (TIFFExtendProc)NULL;
1662 
TIFFSetTagExtender(TIFFExtendProc extender)1663 TIFFExtendProc TIFFSetTagExtender(TIFFExtendProc extender)
1664 {
1665     TIFFExtendProc prev = _TIFFextender;
1666     _TIFFextender = extender;
1667     return (prev);
1668 }
1669 
1670 /*
1671  * Setup for a new directory.  Should we automatically call
1672  * TIFFWriteDirectory() if the current one is dirty?
1673  *
1674  * The newly created directory will not exist on the file till
1675  * TIFFWriteDirectory(), TIFFFlush() or TIFFClose() is called.
1676  */
TIFFCreateDirectory(TIFF * tif)1677 int TIFFCreateDirectory(TIFF *tif)
1678 {
1679     TIFFDefaultDirectory(tif);
1680     tif->tif_diroff = 0;
1681     tif->tif_nextdiroff = 0;
1682     tif->tif_curoff = 0;
1683     tif->tif_row = (uint32_t)-1;
1684     tif->tif_curstrip = (uint32_t)-1;
1685 
1686     return 0;
1687 }
1688 
TIFFCreateCustomDirectory(TIFF * tif,const TIFFFieldArray * infoarray)1689 int TIFFCreateCustomDirectory(TIFF *tif, const TIFFFieldArray *infoarray)
1690 {
1691     TIFFDefaultDirectory(tif);
1692 
1693     /*
1694      * Reset the field definitions to match the application provided list.
1695      * Hopefully TIFFDefaultDirectory() won't have done anything irreversible
1696      * based on it's assumption this is an image directory.
1697      */
1698     _TIFFSetupFields(tif, infoarray);
1699 
1700     tif->tif_diroff = 0;
1701     tif->tif_nextdiroff = 0;
1702     tif->tif_curoff = 0;
1703     tif->tif_row = (uint32_t)-1;
1704     tif->tif_curstrip = (uint32_t)-1;
1705     /* invalidate directory index */
1706     tif->tif_curdir = TIFF_NON_EXISTENT_DIR_NUMBER;
1707     /* invalidate IFD loop lists */
1708     _TIFFCleanupIFDOffsetAndNumberMaps(tif);
1709     /* To be able to return from SubIFD or custom-IFD to main-IFD */
1710     tif->tif_setdirectory_force_absolute = TRUE;
1711 
1712     return 0;
1713 }
1714 
TIFFCreateEXIFDirectory(TIFF * tif)1715 int TIFFCreateEXIFDirectory(TIFF *tif)
1716 {
1717     const TIFFFieldArray *exifFieldArray;
1718     exifFieldArray = _TIFFGetExifFields();
1719     return TIFFCreateCustomDirectory(tif, exifFieldArray);
1720 }
1721 
1722 /*
1723  * Creates the EXIF GPS custom directory
1724  */
TIFFCreateGPSDirectory(TIFF * tif)1725 int TIFFCreateGPSDirectory(TIFF *tif)
1726 {
1727     const TIFFFieldArray *gpsFieldArray;
1728     gpsFieldArray = _TIFFGetGpsFields();
1729     return TIFFCreateCustomDirectory(tif, gpsFieldArray);
1730 }
1731 
1732 /*
1733  * Setup a default directory structure.
1734  */
TIFFDefaultDirectory(TIFF * tif)1735 int TIFFDefaultDirectory(TIFF *tif)
1736 {
1737     register TIFFDirectory *td = &tif->tif_dir;
1738     const TIFFFieldArray *tiffFieldArray;
1739 
1740     tiffFieldArray = _TIFFGetFields();
1741     _TIFFSetupFields(tif, tiffFieldArray);
1742 
1743     _TIFFmemset(td, 0, sizeof(*td));
1744     td->td_fillorder = FILLORDER_MSB2LSB;
1745     td->td_bitspersample = 1;
1746     td->td_threshholding = THRESHHOLD_BILEVEL;
1747     td->td_orientation = ORIENTATION_TOPLEFT;
1748     td->td_samplesperpixel = 1;
1749     td->td_rowsperstrip = (uint32_t)-1;
1750     td->td_tilewidth = 0;
1751     td->td_tilelength = 0;
1752     td->td_tiledepth = 1;
1753 #ifdef STRIPBYTECOUNTSORTED_UNUSED
1754     td->td_stripbytecountsorted = 1; /* Our own arrays always sorted. */
1755 #endif
1756     td->td_resolutionunit = RESUNIT_INCH;
1757     td->td_sampleformat = SAMPLEFORMAT_UINT;
1758     td->td_imagedepth = 1;
1759     td->td_ycbcrsubsampling[0] = 2;
1760     td->td_ycbcrsubsampling[1] = 2;
1761     td->td_ycbcrpositioning = YCBCRPOSITION_CENTERED;
1762     tif->tif_postdecode = _TIFFNoPostDecode;
1763     tif->tif_foundfield = NULL;
1764     tif->tif_tagmethods.vsetfield = _TIFFVSetField;
1765     tif->tif_tagmethods.vgetfield = _TIFFVGetField;
1766     tif->tif_tagmethods.printdir = NULL;
1767     /* additional default values */
1768     td->td_planarconfig = PLANARCONFIG_CONTIG;
1769     td->td_compression = COMPRESSION_NONE;
1770     td->td_subfiletype = 0;
1771     td->td_minsamplevalue = 0;
1772     /* td_bitspersample=1 is always set in TIFFDefaultDirectory().
1773      * Therefore, td_maxsamplevalue has to be re-calculated in
1774      * TIFFGetFieldDefaulted(). */
1775     td->td_maxsamplevalue = 1; /* Default for td_bitspersample=1 */
1776     td->td_extrasamples = 0;
1777     td->td_sampleinfo = NULL;
1778 
1779     /*
1780      *  Give client code a chance to install their own
1781      *  tag extensions & methods, prior to compression overloads,
1782      *  but do some prior cleanup first.
1783      * (http://trac.osgeo.org/gdal/ticket/5054)
1784      */
1785     if (tif->tif_nfieldscompat > 0)
1786     {
1787         uint32_t i;
1788 
1789         for (i = 0; i < tif->tif_nfieldscompat; i++)
1790         {
1791             if (tif->tif_fieldscompat[i].allocated_size)
1792                 _TIFFfreeExt(tif, tif->tif_fieldscompat[i].fields);
1793         }
1794         _TIFFfreeExt(tif, tif->tif_fieldscompat);
1795         tif->tif_nfieldscompat = 0;
1796         tif->tif_fieldscompat = NULL;
1797     }
1798     if (_TIFFextender)
1799         (*_TIFFextender)(tif);
1800     (void)TIFFSetField(tif, TIFFTAG_COMPRESSION, COMPRESSION_NONE);
1801     /*
1802      * NB: The directory is marked dirty as a result of setting
1803      * up the default compression scheme.  However, this really
1804      * isn't correct -- we want TIFF_DIRTYDIRECT to be set only
1805      * if the user does something.  We could just do the setup
1806      * by hand, but it seems better to use the normal mechanism
1807      * (i.e. TIFFSetField).
1808      */
1809     tif->tif_flags &= ~TIFF_DIRTYDIRECT;
1810 
1811     /*
1812      * As per http://bugzilla.remotesensing.org/show_bug.cgi?id=19
1813      * we clear the ISTILED flag when setting up a new directory.
1814      * Should we also be clearing stuff like INSUBIFD?
1815      */
1816     tif->tif_flags &= ~TIFF_ISTILED;
1817 
1818     return (1);
1819 }
1820 
TIFFAdvanceDirectory(TIFF * tif,uint64_t * nextdiroff,uint64_t * off,tdir_t * nextdirnum)1821 static int TIFFAdvanceDirectory(TIFF *tif, uint64_t *nextdiroff, uint64_t *off,
1822                                 tdir_t *nextdirnum)
1823 {
1824     static const char module[] = "TIFFAdvanceDirectory";
1825 
1826     /* Add this directory to the directory list, if not already in. */
1827     if (!_TIFFCheckDirNumberAndOffset(tif, *nextdirnum, *nextdiroff))
1828     {
1829         TIFFErrorExtR(tif, module,
1830                       "Starting directory %u at offset 0x%" PRIx64 " (%" PRIu64
1831                       ") might cause an IFD loop",
1832                       *nextdirnum, *nextdiroff, *nextdiroff);
1833         *nextdiroff = 0;
1834         *nextdirnum = 0;
1835         return (0);
1836     }
1837 
1838     if (isMapped(tif))
1839     {
1840         uint64_t poff = *nextdiroff;
1841         if (!(tif->tif_flags & TIFF_BIGTIFF))
1842         {
1843             tmsize_t poffa, poffb, poffc, poffd;
1844             uint16_t dircount;
1845             uint32_t nextdir32;
1846             poffa = (tmsize_t)poff;
1847             poffb = poffa + sizeof(uint16_t);
1848             if (((uint64_t)poffa != poff) || (poffb < poffa) ||
1849                 (poffb < (tmsize_t)sizeof(uint16_t)) || (poffb > tif->tif_size))
1850             {
1851                 TIFFErrorExtR(tif, module, "Error fetching directory count");
1852                 *nextdiroff = 0;
1853                 return (0);
1854             }
1855             _TIFFmemcpy(&dircount, tif->tif_base + poffa, sizeof(uint16_t));
1856             if (tif->tif_flags & TIFF_SWAB)
1857                 TIFFSwabShort(&dircount);
1858             poffc = poffb + dircount * 12;
1859             poffd = poffc + sizeof(uint32_t);
1860             if ((poffc < poffb) || (poffc < dircount * 12) || (poffd < poffc) ||
1861                 (poffd < (tmsize_t)sizeof(uint32_t)) || (poffd > tif->tif_size))
1862             {
1863                 TIFFErrorExtR(tif, module, "Error fetching directory link");
1864                 return (0);
1865             }
1866             if (off != NULL)
1867                 *off = (uint64_t)poffc;
1868             _TIFFmemcpy(&nextdir32, tif->tif_base + poffc, sizeof(uint32_t));
1869             if (tif->tif_flags & TIFF_SWAB)
1870                 TIFFSwabLong(&nextdir32);
1871             *nextdiroff = nextdir32;
1872         }
1873         else
1874         {
1875             tmsize_t poffa, poffb, poffc, poffd;
1876             uint64_t dircount64;
1877             uint16_t dircount16;
1878             if (poff > (uint64_t)TIFF_TMSIZE_T_MAX - sizeof(uint64_t))
1879             {
1880                 TIFFErrorExtR(tif, module, "Error fetching directory count");
1881                 return (0);
1882             }
1883             poffa = (tmsize_t)poff;
1884             poffb = poffa + sizeof(uint64_t);
1885             if (poffb > tif->tif_size)
1886             {
1887                 TIFFErrorExtR(tif, module, "Error fetching directory count");
1888                 return (0);
1889             }
1890             _TIFFmemcpy(&dircount64, tif->tif_base + poffa, sizeof(uint64_t));
1891             if (tif->tif_flags & TIFF_SWAB)
1892                 TIFFSwabLong8(&dircount64);
1893             if (dircount64 > 0xFFFF)
1894             {
1895                 TIFFErrorExtR(tif, module,
1896                               "Sanity check on directory count failed");
1897                 return (0);
1898             }
1899             dircount16 = (uint16_t)dircount64;
1900             if (poffb > TIFF_TMSIZE_T_MAX - (tmsize_t)(dircount16 * 20) -
1901                             (tmsize_t)sizeof(uint64_t))
1902             {
1903                 TIFFErrorExtR(tif, module, "Error fetching directory link");
1904                 return (0);
1905             }
1906             poffc = poffb + dircount16 * 20;
1907             poffd = poffc + sizeof(uint64_t);
1908             if (poffd > tif->tif_size)
1909             {
1910                 TIFFErrorExtR(tif, module, "Error fetching directory link");
1911                 return (0);
1912             }
1913             if (off != NULL)
1914                 *off = (uint64_t)poffc;
1915             _TIFFmemcpy(nextdiroff, tif->tif_base + poffc, sizeof(uint64_t));
1916             if (tif->tif_flags & TIFF_SWAB)
1917                 TIFFSwabLong8(nextdiroff);
1918         }
1919     }
1920     else
1921     {
1922         if (!(tif->tif_flags & TIFF_BIGTIFF))
1923         {
1924             uint16_t dircount;
1925             uint32_t nextdir32;
1926             if (!SeekOK(tif, *nextdiroff) ||
1927                 !ReadOK(tif, &dircount, sizeof(uint16_t)))
1928             {
1929                 TIFFErrorExtR(tif, module, "%s: Error fetching directory count",
1930                               tif->tif_name);
1931                 return (0);
1932             }
1933             if (tif->tif_flags & TIFF_SWAB)
1934                 TIFFSwabShort(&dircount);
1935             if (off != NULL)
1936                 *off = TIFFSeekFile(tif, dircount * 12, SEEK_CUR);
1937             else
1938                 (void)TIFFSeekFile(tif, dircount * 12, SEEK_CUR);
1939             if (!ReadOK(tif, &nextdir32, sizeof(uint32_t)))
1940             {
1941                 TIFFErrorExtR(tif, module, "%s: Error fetching directory link",
1942                               tif->tif_name);
1943                 return (0);
1944             }
1945             if (tif->tif_flags & TIFF_SWAB)
1946                 TIFFSwabLong(&nextdir32);
1947             *nextdiroff = nextdir32;
1948         }
1949         else
1950         {
1951             uint64_t dircount64;
1952             uint16_t dircount16;
1953             if (!SeekOK(tif, *nextdiroff) ||
1954                 !ReadOK(tif, &dircount64, sizeof(uint64_t)))
1955             {
1956                 TIFFErrorExtR(tif, module, "%s: Error fetching directory count",
1957                               tif->tif_name);
1958                 return (0);
1959             }
1960             if (tif->tif_flags & TIFF_SWAB)
1961                 TIFFSwabLong8(&dircount64);
1962             if (dircount64 > 0xFFFF)
1963             {
1964                 TIFFErrorExtR(tif, module, "Error fetching directory count");
1965                 return (0);
1966             }
1967             dircount16 = (uint16_t)dircount64;
1968             if (off != NULL)
1969                 *off = TIFFSeekFile(tif, dircount16 * 20, SEEK_CUR);
1970             else
1971                 (void)TIFFSeekFile(tif, dircount16 * 20, SEEK_CUR);
1972             if (!ReadOK(tif, nextdiroff, sizeof(uint64_t)))
1973             {
1974                 TIFFErrorExtR(tif, module, "%s: Error fetching directory link",
1975                               tif->tif_name);
1976                 return (0);
1977             }
1978             if (tif->tif_flags & TIFF_SWAB)
1979                 TIFFSwabLong8(nextdiroff);
1980         }
1981     }
1982     if (*nextdiroff != 0)
1983     {
1984         (*nextdirnum)++;
1985         /* Check next directory for IFD looping and if so, set it as last
1986          * directory. */
1987         if (!_TIFFCheckDirNumberAndOffset(tif, *nextdirnum, *nextdiroff))
1988         {
1989             TIFFWarningExtR(
1990                 tif, module,
1991                 "the next directory %u at offset 0x%" PRIx64 " (%" PRIu64
1992                 ") might be an IFD loop. Treating directory %d as "
1993                 "last directory",
1994                 *nextdirnum, *nextdiroff, *nextdiroff, (int)(*nextdirnum) - 1);
1995             *nextdiroff = 0;
1996             (*nextdirnum)--;
1997         }
1998     }
1999     return (1);
2000 }
2001 
2002 /*
2003  * Count the number of directories in a file.
2004  */
TIFFNumberOfDirectories(TIFF * tif)2005 tdir_t TIFFNumberOfDirectories(TIFF *tif)
2006 {
2007     uint64_t nextdiroff;
2008     tdir_t nextdirnum;
2009     tdir_t n;
2010     if (!(tif->tif_flags & TIFF_BIGTIFF))
2011         nextdiroff = tif->tif_header.classic.tiff_diroff;
2012     else
2013         nextdiroff = tif->tif_header.big.tiff_diroff;
2014     nextdirnum = 0;
2015     n = 0;
2016     while (nextdiroff != 0 &&
2017            TIFFAdvanceDirectory(tif, &nextdiroff, NULL, &nextdirnum))
2018     {
2019         ++n;
2020     }
2021     return (n);
2022 }
2023 
2024 /*
2025  * Set the n-th directory as the current directory.
2026  * NB: Directories are numbered starting at 0.
2027  */
TIFFSetDirectory(TIFF * tif,tdir_t dirn)2028 int TIFFSetDirectory(TIFF *tif, tdir_t dirn)
2029 {
2030     uint64_t nextdiroff;
2031     tdir_t nextdirnum = 0;
2032     tdir_t n;
2033 
2034     if (tif->tif_setdirectory_force_absolute)
2035     {
2036         /* tif_setdirectory_force_absolute=1 will force parsing the main IFD
2037          * chain from the beginning, thus IFD directory list needs to be cleared
2038          * from possible SubIFD offsets.
2039          */
2040         _TIFFCleanupIFDOffsetAndNumberMaps(tif); /* invalidate IFD loop lists */
2041     }
2042 
2043     /* Even faster path, if offset is available within IFD loop hash list. */
2044     if (!tif->tif_setdirectory_force_absolute &&
2045         _TIFFGetOffsetFromDirNumber(tif, dirn, &nextdiroff))
2046     {
2047         /* Set parameters for following TIFFReadDirectory() below. */
2048         tif->tif_nextdiroff = nextdiroff;
2049         tif->tif_curdir = dirn;
2050         /* Reset to relative stepping */
2051         tif->tif_setdirectory_force_absolute = FALSE;
2052     }
2053     else
2054     {
2055 
2056         /* Fast path when we just advance relative to the current directory:
2057          * start at the current dir offset and continue to seek from there.
2058          * Check special cases when relative is not allowed:
2059          * - jump back from SubIFD or custom directory
2060          * - right after TIFFWriteDirectory() jump back to that directory
2061          *   using TIFFSetDirectory() */
2062         const int relative = (dirn >= tif->tif_curdir) &&
2063                              (tif->tif_diroff != 0) &&
2064                              !tif->tif_setdirectory_force_absolute;
2065 
2066         if (relative)
2067         {
2068             nextdiroff = tif->tif_diroff;
2069             dirn -= tif->tif_curdir;
2070             nextdirnum = tif->tif_curdir;
2071         }
2072         else if (!(tif->tif_flags & TIFF_BIGTIFF))
2073             nextdiroff = tif->tif_header.classic.tiff_diroff;
2074         else
2075             nextdiroff = tif->tif_header.big.tiff_diroff;
2076 
2077         /* Reset to relative stepping */
2078         tif->tif_setdirectory_force_absolute = FALSE;
2079 
2080         for (n = dirn; n > 0 && nextdiroff != 0; n--)
2081             if (!TIFFAdvanceDirectory(tif, &nextdiroff, NULL, &nextdirnum))
2082                 return (0);
2083         /* If the n-th directory could not be reached (does not exist),
2084          * return here without touching anything further. */
2085         if (nextdiroff == 0 || n > 0)
2086             return (0);
2087 
2088         tif->tif_nextdiroff = nextdiroff;
2089 
2090         /* Set curdir to the actual directory index. */
2091         if (relative)
2092             tif->tif_curdir += dirn - n;
2093         else
2094             tif->tif_curdir = dirn - n;
2095     }
2096 
2097     /* The -1 decrement is because TIFFReadDirectory will increment
2098      * tif_curdir after successfully reading the directory. */
2099     if (tif->tif_curdir == 0)
2100         tif->tif_curdir = TIFF_NON_EXISTENT_DIR_NUMBER;
2101     else
2102         tif->tif_curdir--;
2103     return (TIFFReadDirectory(tif));
2104 }
2105 
2106 /*
2107  * Set the current directory to be the directory
2108  * located at the specified file offset.  This interface
2109  * is used mainly to access directories linked with
2110  * the SubIFD tag (e.g. thumbnail images).
2111  */
TIFFSetSubDirectory(TIFF * tif,uint64_t diroff)2112 int TIFFSetSubDirectory(TIFF *tif, uint64_t diroff)
2113 {
2114     /* Match nextdiroff and curdir for consistent IFD-loop checking.
2115      * Only with TIFFSetSubDirectory() the IFD list can be corrupted with
2116      * invalid offsets within the main IFD tree. In the case of several subIFDs
2117      * of a main image, there are two possibilities that are not even mutually
2118      * exclusive. a.) The subIFD tag contains an array with all offsets of the
2119      * subIFDs. b.) The SubIFDs are concatenated with their NextIFD parameters.
2120      * (refer to
2121      * https://www.awaresystems.be/imaging/tiff/specification/TIFFPM6.pdf.)
2122      */
2123     int retval;
2124     uint32_t curdir = 0;
2125     int8_t probablySubIFD = 0;
2126     if (diroff == 0)
2127     {
2128         /* Special case to invalidate the tif_lastdiroff member. */
2129         tif->tif_curdir = TIFF_NON_EXISTENT_DIR_NUMBER;
2130     }
2131     else
2132     {
2133         if (!_TIFFGetDirNumberFromOffset(tif, diroff, &curdir))
2134         {
2135             /* Non-existing offsets might point to a SubIFD or invalid IFD.*/
2136             probablySubIFD = 1;
2137         }
2138         /* -1 because TIFFReadDirectory() will increment tif_curdir. */
2139         tif->tif_curdir =
2140             curdir == 0 ? TIFF_NON_EXISTENT_DIR_NUMBER : curdir - 1;
2141     }
2142 
2143     tif->tif_nextdiroff = diroff;
2144     retval = TIFFReadDirectory(tif);
2145     /* If failed, curdir was not incremented in TIFFReadDirectory(), so set it
2146      * back, but leave it for diroff==0. */
2147     if (!retval && diroff != 0)
2148     {
2149         if (tif->tif_curdir == TIFF_NON_EXISTENT_DIR_NUMBER)
2150             tif->tif_curdir = 0;
2151         else
2152             tif->tif_curdir++;
2153     }
2154     if (retval && probablySubIFD)
2155     {
2156         /* Reset IFD list to start new one for SubIFD chain and also start
2157          * SubIFD chain with tif_curdir=0. */
2158         _TIFFCleanupIFDOffsetAndNumberMaps(tif); /* invalidate IFD loop lists */
2159         tif->tif_curdir = 0; /* first directory of new chain */
2160         /* add this offset to new IFD list */
2161         _TIFFCheckDirNumberAndOffset(tif, tif->tif_curdir, diroff);
2162         /* To be able to return from SubIFD or custom-IFD to main-IFD */
2163         tif->tif_setdirectory_force_absolute = TRUE;
2164     }
2165     return (retval);
2166 }
2167 
2168 /*
2169  * Return file offset of the current directory.
2170  */
TIFFCurrentDirOffset(TIFF * tif)2171 uint64_t TIFFCurrentDirOffset(TIFF *tif) { return (tif->tif_diroff); }
2172 
2173 /*
2174  * Return an indication of whether or not we are
2175  * at the last directory in the file.
2176  */
TIFFLastDirectory(TIFF * tif)2177 int TIFFLastDirectory(TIFF *tif) { return (tif->tif_nextdiroff == 0); }
2178 
2179 /*
2180  * Unlink the specified directory from the directory chain.
2181  * Note: First directory starts with number dirn=1.
2182  * This is different to TIFFSetDirectory() where the first directory starts with
2183  * zero.
2184  */
TIFFUnlinkDirectory(TIFF * tif,tdir_t dirn)2185 int TIFFUnlinkDirectory(TIFF *tif, tdir_t dirn)
2186 {
2187     static const char module[] = "TIFFUnlinkDirectory";
2188     uint64_t nextdir;
2189     tdir_t nextdirnum;
2190     uint64_t off;
2191     tdir_t n;
2192 
2193     if (tif->tif_mode == O_RDONLY)
2194     {
2195         TIFFErrorExtR(tif, module,
2196                       "Can not unlink directory in read-only file");
2197         return (0);
2198     }
2199     if (dirn == 0)
2200     {
2201         TIFFErrorExtR(tif, module,
2202                       "For TIFFUnlinkDirectory() first directory starts with "
2203                       "number 1 and not 0");
2204         return (0);
2205     }
2206     /*
2207      * Go to the directory before the one we want
2208      * to unlink and nab the offset of the link
2209      * field we'll need to patch.
2210      */
2211     if (!(tif->tif_flags & TIFF_BIGTIFF))
2212     {
2213         nextdir = tif->tif_header.classic.tiff_diroff;
2214         off = 4;
2215     }
2216     else
2217     {
2218         nextdir = tif->tif_header.big.tiff_diroff;
2219         off = 8;
2220     }
2221     nextdirnum = 0; /* First directory is dirn=0 */
2222 
2223     for (n = dirn - 1; n > 0; n--)
2224     {
2225         if (nextdir == 0)
2226         {
2227             TIFFErrorExtR(tif, module, "Directory %u does not exist", dirn);
2228             return (0);
2229         }
2230         if (!TIFFAdvanceDirectory(tif, &nextdir, &off, &nextdirnum))
2231             return (0);
2232     }
2233     /*
2234      * Advance to the directory to be unlinked and fetch
2235      * the offset of the directory that follows.
2236      */
2237     if (!TIFFAdvanceDirectory(tif, &nextdir, NULL, &nextdirnum))
2238         return (0);
2239     /*
2240      * Go back and patch the link field of the preceding
2241      * directory to point to the offset of the directory
2242      * that follows.
2243      */
2244     (void)TIFFSeekFile(tif, off, SEEK_SET);
2245     if (!(tif->tif_flags & TIFF_BIGTIFF))
2246     {
2247         uint32_t nextdir32;
2248         nextdir32 = (uint32_t)nextdir;
2249         assert((uint64_t)nextdir32 == nextdir);
2250         if (tif->tif_flags & TIFF_SWAB)
2251             TIFFSwabLong(&nextdir32);
2252         if (!WriteOK(tif, &nextdir32, sizeof(uint32_t)))
2253         {
2254             TIFFErrorExtR(tif, module, "Error writing directory link");
2255             return (0);
2256         }
2257     }
2258     else
2259     {
2260         if (tif->tif_flags & TIFF_SWAB)
2261             TIFFSwabLong8(&nextdir);
2262         if (!WriteOK(tif, &nextdir, sizeof(uint64_t)))
2263         {
2264             TIFFErrorExtR(tif, module, "Error writing directory link");
2265             return (0);
2266         }
2267     }
2268 
2269     /* For dirn=1 (first directory) also update the libtiff internal
2270      * base offset variables. */
2271     if (dirn == 1)
2272     {
2273         if (!(tif->tif_flags & TIFF_BIGTIFF))
2274             tif->tif_header.classic.tiff_diroff = (uint32_t)nextdir;
2275         else
2276             tif->tif_header.big.tiff_diroff = nextdir;
2277     }
2278 
2279     /*
2280      * Leave directory state setup safely.  We don't have
2281      * facilities for doing inserting and removing directories,
2282      * so it's safest to just invalidate everything.  This
2283      * means that the caller can only append to the directory
2284      * chain.
2285      */
2286     (*tif->tif_cleanup)(tif);
2287     if ((tif->tif_flags & TIFF_MYBUFFER) && tif->tif_rawdata)
2288     {
2289         _TIFFfreeExt(tif, tif->tif_rawdata);
2290         tif->tif_rawdata = NULL;
2291         tif->tif_rawcc = 0;
2292         tif->tif_rawdataoff = 0;
2293         tif->tif_rawdataloaded = 0;
2294     }
2295     tif->tif_flags &= ~(TIFF_BEENWRITING | TIFF_BUFFERSETUP | TIFF_POSTENCODE |
2296                         TIFF_BUF4WRITE);
2297     TIFFFreeDirectory(tif);
2298     TIFFDefaultDirectory(tif);
2299     tif->tif_diroff = 0;     /* force link on next write */
2300     tif->tif_nextdiroff = 0; /* next write must be at end */
2301     tif->tif_lastdiroff = 0; /* will be updated on next link */
2302     tif->tif_curoff = 0;
2303     tif->tif_row = (uint32_t)-1;
2304     tif->tif_curstrip = (uint32_t)-1;
2305     tif->tif_curdir = TIFF_NON_EXISTENT_DIR_NUMBER;
2306     _TIFFCleanupIFDOffsetAndNumberMaps(tif); /* invalidate IFD loop lists */
2307     return (1);
2308 }
2309