• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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     const char *ep = s + slen;
196     const char *cp = s;
197 
198     if (slen > 0)
199     {
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, FIELD_SETLONGS);
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 
1706     return 0;
1707 }
1708 
TIFFCreateEXIFDirectory(TIFF * tif)1709 int TIFFCreateEXIFDirectory(TIFF *tif)
1710 {
1711     const TIFFFieldArray *exifFieldArray;
1712     exifFieldArray = _TIFFGetExifFields();
1713     return TIFFCreateCustomDirectory(tif, exifFieldArray);
1714 }
1715 
1716 /*
1717  * Creates the EXIF GPS custom directory
1718  */
TIFFCreateGPSDirectory(TIFF * tif)1719 int TIFFCreateGPSDirectory(TIFF *tif)
1720 {
1721     const TIFFFieldArray *gpsFieldArray;
1722     gpsFieldArray = _TIFFGetGpsFields();
1723     return TIFFCreateCustomDirectory(tif, gpsFieldArray);
1724 }
1725 
1726 /*
1727  * Setup a default directory structure.
1728  */
TIFFDefaultDirectory(TIFF * tif)1729 int TIFFDefaultDirectory(TIFF *tif)
1730 {
1731     register TIFFDirectory *td = &tif->tif_dir;
1732     const TIFFFieldArray *tiffFieldArray;
1733 
1734     tiffFieldArray = _TIFFGetFields();
1735     _TIFFSetupFields(tif, tiffFieldArray);
1736 
1737     _TIFFmemset(td, 0, sizeof(*td));
1738     td->td_fillorder = FILLORDER_MSB2LSB;
1739     td->td_bitspersample = 1;
1740     td->td_threshholding = THRESHHOLD_BILEVEL;
1741     td->td_orientation = ORIENTATION_TOPLEFT;
1742     td->td_samplesperpixel = 1;
1743     td->td_rowsperstrip = (uint32_t)-1;
1744     td->td_tilewidth = 0;
1745     td->td_tilelength = 0;
1746     td->td_tiledepth = 1;
1747 #ifdef STRIPBYTECOUNTSORTED_UNUSED
1748     td->td_stripbytecountsorted = 1; /* Our own arrays always sorted. */
1749 #endif
1750     td->td_resolutionunit = RESUNIT_INCH;
1751     td->td_sampleformat = SAMPLEFORMAT_UINT;
1752     td->td_imagedepth = 1;
1753     td->td_ycbcrsubsampling[0] = 2;
1754     td->td_ycbcrsubsampling[1] = 2;
1755     td->td_ycbcrpositioning = YCBCRPOSITION_CENTERED;
1756     tif->tif_postdecode = _TIFFNoPostDecode;
1757     tif->tif_foundfield = NULL;
1758     tif->tif_tagmethods.vsetfield = _TIFFVSetField;
1759     tif->tif_tagmethods.vgetfield = _TIFFVGetField;
1760     tif->tif_tagmethods.printdir = NULL;
1761     /* additional default values */
1762     td->td_planarconfig = PLANARCONFIG_CONTIG;
1763     td->td_compression = COMPRESSION_NONE;
1764     td->td_subfiletype = 0;
1765     td->td_minsamplevalue = 0;
1766     /* td_bitspersample=1 is always set in TIFFDefaultDirectory().
1767      * Therefore, td_maxsamplevalue has to be re-calculated in
1768      * TIFFGetFieldDefaulted(). */
1769     td->td_maxsamplevalue = 1; /* Default for td_bitspersample=1 */
1770     td->td_extrasamples = 0;
1771     td->td_sampleinfo = NULL;
1772 
1773     /*
1774      *  Give client code a chance to install their own
1775      *  tag extensions & methods, prior to compression overloads,
1776      *  but do some prior cleanup first.
1777      * (http://trac.osgeo.org/gdal/ticket/5054)
1778      */
1779     if (tif->tif_nfieldscompat > 0)
1780     {
1781         uint32_t i;
1782 
1783         for (i = 0; i < tif->tif_nfieldscompat; i++)
1784         {
1785             if (tif->tif_fieldscompat[i].allocated_size)
1786                 _TIFFfreeExt(tif, tif->tif_fieldscompat[i].fields);
1787         }
1788         _TIFFfreeExt(tif, tif->tif_fieldscompat);
1789         tif->tif_nfieldscompat = 0;
1790         tif->tif_fieldscompat = NULL;
1791     }
1792     if (_TIFFextender)
1793         (*_TIFFextender)(tif);
1794     (void)TIFFSetField(tif, TIFFTAG_COMPRESSION, COMPRESSION_NONE);
1795     /*
1796      * NB: The directory is marked dirty as a result of setting
1797      * up the default compression scheme.  However, this really
1798      * isn't correct -- we want TIFF_DIRTYDIRECT to be set only
1799      * if the user does something.  We could just do the setup
1800      * by hand, but it seems better to use the normal mechanism
1801      * (i.e. TIFFSetField).
1802      */
1803     tif->tif_flags &= ~TIFF_DIRTYDIRECT;
1804 
1805     /*
1806      * As per http://bugzilla.remotesensing.org/show_bug.cgi?id=19
1807      * we clear the ISTILED flag when setting up a new directory.
1808      * Should we also be clearing stuff like INSUBIFD?
1809      */
1810     tif->tif_flags &= ~TIFF_ISTILED;
1811 
1812     return (1);
1813 }
1814 
TIFFAdvanceDirectory(TIFF * tif,uint64_t * nextdiroff,uint64_t * off,tdir_t * nextdirnum)1815 static int TIFFAdvanceDirectory(TIFF *tif, uint64_t *nextdiroff, uint64_t *off,
1816                                 tdir_t *nextdirnum)
1817 {
1818     static const char module[] = "TIFFAdvanceDirectory";
1819 
1820     /* Add this directory to the directory list, if not already in. */
1821     if (!_TIFFCheckDirNumberAndOffset(tif, *nextdirnum, *nextdiroff))
1822     {
1823         TIFFErrorExtR(tif, module,
1824                       "Starting directory %u at offset 0x%" PRIx64 " (%" PRIu64
1825                       ") might cause an IFD loop",
1826                       *nextdirnum, *nextdiroff, *nextdiroff);
1827         *nextdiroff = 0;
1828         *nextdirnum = 0;
1829         return (0);
1830     }
1831 
1832     if (isMapped(tif))
1833     {
1834         uint64_t poff = *nextdiroff;
1835         if (!(tif->tif_flags & TIFF_BIGTIFF))
1836         {
1837             tmsize_t poffa, poffb, poffc, poffd;
1838             uint16_t dircount;
1839             uint32_t nextdir32;
1840             poffa = (tmsize_t)poff;
1841             poffb = poffa + sizeof(uint16_t);
1842             if (((uint64_t)poffa != poff) || (poffb < poffa) ||
1843                 (poffb < (tmsize_t)sizeof(uint16_t)) || (poffb > tif->tif_size))
1844             {
1845                 TIFFErrorExtR(tif, module, "Error fetching directory count");
1846                 *nextdiroff = 0;
1847                 return (0);
1848             }
1849             _TIFFmemcpy(&dircount, tif->tif_base + poffa, sizeof(uint16_t));
1850             if (tif->tif_flags & TIFF_SWAB)
1851                 TIFFSwabShort(&dircount);
1852             poffc = poffb + dircount * 12;
1853             poffd = poffc + sizeof(uint32_t);
1854             if ((poffc < poffb) || (poffc < dircount * 12) || (poffd < poffc) ||
1855                 (poffd < (tmsize_t)sizeof(uint32_t)) || (poffd > tif->tif_size))
1856             {
1857                 TIFFErrorExtR(tif, module, "Error fetching directory link");
1858                 return (0);
1859             }
1860             if (off != NULL)
1861                 *off = (uint64_t)poffc;
1862             _TIFFmemcpy(&nextdir32, tif->tif_base + poffc, sizeof(uint32_t));
1863             if (tif->tif_flags & TIFF_SWAB)
1864                 TIFFSwabLong(&nextdir32);
1865             *nextdiroff = nextdir32;
1866         }
1867         else
1868         {
1869             tmsize_t poffa, poffb, poffc, poffd;
1870             uint64_t dircount64;
1871             uint16_t dircount16;
1872             if (poff > (uint64_t)TIFF_TMSIZE_T_MAX - sizeof(uint64_t))
1873             {
1874                 TIFFErrorExtR(tif, module, "Error fetching directory count");
1875                 return (0);
1876             }
1877             poffa = (tmsize_t)poff;
1878             poffb = poffa + sizeof(uint64_t);
1879             if (poffb > tif->tif_size)
1880             {
1881                 TIFFErrorExtR(tif, module, "Error fetching directory count");
1882                 return (0);
1883             }
1884             _TIFFmemcpy(&dircount64, tif->tif_base + poffa, sizeof(uint64_t));
1885             if (tif->tif_flags & TIFF_SWAB)
1886                 TIFFSwabLong8(&dircount64);
1887             if (dircount64 > 0xFFFF)
1888             {
1889                 TIFFErrorExtR(tif, module,
1890                               "Sanity check on directory count failed");
1891                 return (0);
1892             }
1893             dircount16 = (uint16_t)dircount64;
1894             if (poffb > TIFF_TMSIZE_T_MAX - (tmsize_t)(dircount16 * 20) -
1895                             (tmsize_t)sizeof(uint64_t))
1896             {
1897                 TIFFErrorExtR(tif, module, "Error fetching directory link");
1898                 return (0);
1899             }
1900             poffc = poffb + dircount16 * 20;
1901             poffd = poffc + sizeof(uint64_t);
1902             if (poffd > tif->tif_size)
1903             {
1904                 TIFFErrorExtR(tif, module, "Error fetching directory link");
1905                 return (0);
1906             }
1907             if (off != NULL)
1908                 *off = (uint64_t)poffc;
1909             _TIFFmemcpy(nextdiroff, tif->tif_base + poffc, sizeof(uint64_t));
1910             if (tif->tif_flags & TIFF_SWAB)
1911                 TIFFSwabLong8(nextdiroff);
1912         }
1913     }
1914     else
1915     {
1916         if (!(tif->tif_flags & TIFF_BIGTIFF))
1917         {
1918             uint16_t dircount;
1919             uint32_t nextdir32;
1920             if (!SeekOK(tif, *nextdiroff) ||
1921                 !ReadOK(tif, &dircount, sizeof(uint16_t)))
1922             {
1923                 TIFFErrorExtR(tif, module, "%s: Error fetching directory count",
1924                               tif->tif_name);
1925                 return (0);
1926             }
1927             if (tif->tif_flags & TIFF_SWAB)
1928                 TIFFSwabShort(&dircount);
1929             if (off != NULL)
1930                 *off = TIFFSeekFile(tif, dircount * 12, SEEK_CUR);
1931             else
1932                 (void)TIFFSeekFile(tif, dircount * 12, SEEK_CUR);
1933             if (!ReadOK(tif, &nextdir32, sizeof(uint32_t)))
1934             {
1935                 TIFFErrorExtR(tif, module, "%s: Error fetching directory link",
1936                               tif->tif_name);
1937                 return (0);
1938             }
1939             if (tif->tif_flags & TIFF_SWAB)
1940                 TIFFSwabLong(&nextdir32);
1941             *nextdiroff = nextdir32;
1942         }
1943         else
1944         {
1945             uint64_t dircount64;
1946             uint16_t dircount16;
1947             if (!SeekOK(tif, *nextdiroff) ||
1948                 !ReadOK(tif, &dircount64, sizeof(uint64_t)))
1949             {
1950                 TIFFErrorExtR(tif, module, "%s: Error fetching directory count",
1951                               tif->tif_name);
1952                 return (0);
1953             }
1954             if (tif->tif_flags & TIFF_SWAB)
1955                 TIFFSwabLong8(&dircount64);
1956             if (dircount64 > 0xFFFF)
1957             {
1958                 TIFFErrorExtR(tif, module, "Error fetching directory count");
1959                 return (0);
1960             }
1961             dircount16 = (uint16_t)dircount64;
1962             if (off != NULL)
1963                 *off = TIFFSeekFile(tif, dircount16 * 20, SEEK_CUR);
1964             else
1965                 (void)TIFFSeekFile(tif, dircount16 * 20, SEEK_CUR);
1966             if (!ReadOK(tif, nextdiroff, sizeof(uint64_t)))
1967             {
1968                 TIFFErrorExtR(tif, module, "%s: Error fetching directory link",
1969                               tif->tif_name);
1970                 return (0);
1971             }
1972             if (tif->tif_flags & TIFF_SWAB)
1973                 TIFFSwabLong8(nextdiroff);
1974         }
1975     }
1976     if (*nextdiroff != 0)
1977     {
1978         (*nextdirnum)++;
1979         /* Check next directory for IFD looping and if so, set it as last
1980          * directory. */
1981         if (!_TIFFCheckDirNumberAndOffset(tif, *nextdirnum, *nextdiroff))
1982         {
1983             TIFFWarningExtR(
1984                 tif, module,
1985                 "the next directory %u at offset 0x%" PRIx64 " (%" PRIu64
1986                 ") might be an IFD loop. Treating directory %d as "
1987                 "last directory",
1988                 *nextdirnum, *nextdiroff, *nextdiroff, (int)(*nextdirnum) - 1);
1989             *nextdiroff = 0;
1990             (*nextdirnum)--;
1991         }
1992     }
1993     return (1);
1994 }
1995 
1996 /*
1997  * Count the number of directories in a file.
1998  */
TIFFNumberOfDirectories(TIFF * tif)1999 tdir_t TIFFNumberOfDirectories(TIFF *tif)
2000 {
2001     uint64_t nextdiroff;
2002     tdir_t nextdirnum;
2003     tdir_t n;
2004     if (!(tif->tif_flags & TIFF_BIGTIFF))
2005         nextdiroff = tif->tif_header.classic.tiff_diroff;
2006     else
2007         nextdiroff = tif->tif_header.big.tiff_diroff;
2008     nextdirnum = 0;
2009     n = 0;
2010     while (nextdiroff != 0 &&
2011            TIFFAdvanceDirectory(tif, &nextdiroff, NULL, &nextdirnum))
2012     {
2013         ++n;
2014     }
2015     return (n);
2016 }
2017 
2018 /*
2019  * Set the n-th directory as the current directory.
2020  * NB: Directories are numbered starting at 0.
2021  */
TIFFSetDirectory(TIFF * tif,tdir_t dirn)2022 int TIFFSetDirectory(TIFF *tif, tdir_t dirn)
2023 {
2024     uint64_t nextdiroff;
2025     tdir_t nextdirnum;
2026     tdir_t n;
2027 
2028     if (!(tif->tif_flags & TIFF_BIGTIFF))
2029         nextdiroff = tif->tif_header.classic.tiff_diroff;
2030     else
2031         nextdiroff = tif->tif_header.big.tiff_diroff;
2032     nextdirnum = 0;
2033     for (n = dirn; n > 0 && nextdiroff != 0; n--)
2034         if (!TIFFAdvanceDirectory(tif, &nextdiroff, NULL, &nextdirnum))
2035             return (0);
2036     /* If the n-th directory could not be reached (does not exist),
2037      * return here without touching anything further. */
2038     if (nextdiroff == 0 || n > 0)
2039         return (0);
2040 
2041     tif->tif_nextdiroff = nextdiroff;
2042     /*
2043      * Set curdir to the actual directory index.  The
2044      * -1 is because TIFFReadDirectory will increment
2045      * tif_curdir after successfully reading the directory.
2046      */
2047     tif->tif_curdir = (dirn - n) - 1;
2048     return (TIFFReadDirectory(tif));
2049 }
2050 
2051 /*
2052  * Set the current directory to be the directory
2053  * located at the specified file offset.  This interface
2054  * is used mainly to access directories linked with
2055  * the SubIFD tag (e.g. thumbnail images).
2056  */
TIFFSetSubDirectory(TIFF * tif,uint64_t diroff)2057 int TIFFSetSubDirectory(TIFF *tif, uint64_t diroff)
2058 {
2059     /* Match nextdiroff and curdir for consistent IFD-loop checking.
2060      * Only with TIFFSetSubDirectory() the IFD list can be corrupted with
2061      * invalid offsets within the main IFD tree. In the case of several subIFDs
2062      * of a main image, there are two possibilities that are not even mutually
2063      * exclusive. a.) The subIFD tag contains an array with all offsets of the
2064      * subIFDs. b.) The SubIFDs are concatenated with their NextIFD parameters.
2065      * (refer to
2066      * https://www.awaresystems.be/imaging/tiff/specification/TIFFPM6.pdf.)
2067      */
2068     int retval;
2069     uint32_t curdir = 0;
2070     int8_t probablySubIFD = 0;
2071     if (diroff == 0)
2072     {
2073         /* Special case to invalidate the tif_lastdiroff member. */
2074         tif->tif_curdir = TIFF_NON_EXISTENT_DIR_NUMBER;
2075     }
2076     else
2077     {
2078         if (!_TIFFGetDirNumberFromOffset(tif, diroff, &curdir))
2079         {
2080             /* Non-existing offsets might point to a SubIFD or invalid IFD.*/
2081             probablySubIFD = 1;
2082         }
2083         /* -1 because TIFFReadDirectory() will increment tif_curdir. */
2084         tif->tif_curdir =
2085             curdir == 0 ? TIFF_NON_EXISTENT_DIR_NUMBER : curdir - 1;
2086     }
2087 
2088     tif->tif_nextdiroff = diroff;
2089     retval = TIFFReadDirectory(tif);
2090     /* If failed, curdir was not incremented in TIFFReadDirectory(), so set it
2091      * back. */
2092     if (!retval)
2093     {
2094         if (tif->tif_curdir == TIFF_NON_EXISTENT_DIR_NUMBER)
2095             tif->tif_curdir = 0;
2096         else
2097             tif->tif_curdir++;
2098     }
2099     if (retval && probablySubIFD)
2100     {
2101         /* Reset IFD list to start new one for SubIFD chain and also start
2102          * SubIFD chain with tif_curdir=0. */
2103         tif->tif_dirnumber = 0;
2104         tif->tif_curdir = 0; /* first directory of new chain */
2105         /* add this offset to new IFD list */
2106         _TIFFCheckDirNumberAndOffset(tif, tif->tif_curdir, diroff);
2107     }
2108     return (retval);
2109 }
2110 
2111 /*
2112  * Return file offset of the current directory.
2113  */
TIFFCurrentDirOffset(TIFF * tif)2114 uint64_t TIFFCurrentDirOffset(TIFF *tif) { return (tif->tif_diroff); }
2115 
2116 /*
2117  * Return an indication of whether or not we are
2118  * at the last directory in the file.
2119  */
TIFFLastDirectory(TIFF * tif)2120 int TIFFLastDirectory(TIFF *tif) { return (tif->tif_nextdiroff == 0); }
2121 
2122 /*
2123  * Unlink the specified directory from the directory chain.
2124  * Note: First directory starts with number dirn=1.
2125  * This is different to TIFFSetDirectory() where the first directory starts with
2126  * zero.
2127  */
TIFFUnlinkDirectory(TIFF * tif,tdir_t dirn)2128 int TIFFUnlinkDirectory(TIFF *tif, tdir_t dirn)
2129 {
2130     static const char module[] = "TIFFUnlinkDirectory";
2131     uint64_t nextdir;
2132     tdir_t nextdirnum;
2133     uint64_t off;
2134     tdir_t n;
2135 
2136     if (tif->tif_mode == O_RDONLY)
2137     {
2138         TIFFErrorExtR(tif, module,
2139                       "Can not unlink directory in read-only file");
2140         return (0);
2141     }
2142     /*
2143      * Go to the directory before the one we want
2144      * to unlink and nab the offset of the link
2145      * field we'll need to patch.
2146      */
2147     if (!(tif->tif_flags & TIFF_BIGTIFF))
2148     {
2149         nextdir = tif->tif_header.classic.tiff_diroff;
2150         off = 4;
2151     }
2152     else
2153     {
2154         nextdir = tif->tif_header.big.tiff_diroff;
2155         off = 8;
2156     }
2157     nextdirnum = 0; /* First directory is dirn=0 */
2158 
2159     for (n = dirn - 1; n > 0; n--)
2160     {
2161         if (nextdir == 0)
2162         {
2163             TIFFErrorExtR(tif, module, "Directory %u does not exist", dirn);
2164             return (0);
2165         }
2166         if (!TIFFAdvanceDirectory(tif, &nextdir, &off, &nextdirnum))
2167             return (0);
2168     }
2169     /*
2170      * Advance to the directory to be unlinked and fetch
2171      * the offset of the directory that follows.
2172      */
2173     if (!TIFFAdvanceDirectory(tif, &nextdir, NULL, &nextdirnum))
2174         return (0);
2175     /*
2176      * Go back and patch the link field of the preceding
2177      * directory to point to the offset of the directory
2178      * that follows.
2179      */
2180     (void)TIFFSeekFile(tif, off, SEEK_SET);
2181     if (!(tif->tif_flags & TIFF_BIGTIFF))
2182     {
2183         uint32_t nextdir32;
2184         nextdir32 = (uint32_t)nextdir;
2185         assert((uint64_t)nextdir32 == nextdir);
2186         if (tif->tif_flags & TIFF_SWAB)
2187             TIFFSwabLong(&nextdir32);
2188         if (!WriteOK(tif, &nextdir32, sizeof(uint32_t)))
2189         {
2190             TIFFErrorExtR(tif, module, "Error writing directory link");
2191             return (0);
2192         }
2193     }
2194     else
2195     {
2196         if (tif->tif_flags & TIFF_SWAB)
2197             TIFFSwabLong8(&nextdir);
2198         if (!WriteOK(tif, &nextdir, sizeof(uint64_t)))
2199         {
2200             TIFFErrorExtR(tif, module, "Error writing directory link");
2201             return (0);
2202         }
2203     }
2204     /*
2205      * Leave directory state setup safely.  We don't have
2206      * facilities for doing inserting and removing directories,
2207      * so it's safest to just invalidate everything.  This
2208      * means that the caller can only append to the directory
2209      * chain.
2210      */
2211     (*tif->tif_cleanup)(tif);
2212     if ((tif->tif_flags & TIFF_MYBUFFER) && tif->tif_rawdata)
2213     {
2214         _TIFFfreeExt(tif, tif->tif_rawdata);
2215         tif->tif_rawdata = NULL;
2216         tif->tif_rawcc = 0;
2217         tif->tif_rawdataoff = 0;
2218         tif->tif_rawdataloaded = 0;
2219     }
2220     tif->tif_flags &= ~(TIFF_BEENWRITING | TIFF_BUFFERSETUP | TIFF_POSTENCODE |
2221                         TIFF_BUF4WRITE);
2222     TIFFFreeDirectory(tif);
2223     TIFFDefaultDirectory(tif);
2224     tif->tif_diroff = 0;     /* force link on next write */
2225     tif->tif_nextdiroff = 0; /* next write must be at end */
2226     tif->tif_lastdiroff = 0; /* will be updated on next link */
2227     tif->tif_curoff = 0;
2228     tif->tif_row = (uint32_t)-1;
2229     tif->tif_curstrip = (uint32_t)-1;
2230     return (1);
2231 }
2232