Coverage Report

Created: 2022-10-31 07:00

/src/ghostpdl/tiff/libtiff/tif_dir.c
Line
Count
Source (jump to first uncovered line)
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
34
/*
35
 * These are used in the backwards compatibility code...
36
 */
37
0
#define DATATYPE_VOID   0       /* !untyped data */
38
0
#define DATATYPE_INT    1       /* !signed integer data */
39
0
#define DATATYPE_UINT   2       /* !unsigned integer data */
40
0
#define DATATYPE_IEEEFP   3       /* !IEEE floating point data */
41
42
static void
43
setByteArray(void** vpp, void* vp, size_t nmemb, size_t elem_size)
44
1.82k
{
45
1.82k
  if (*vpp) {
46
0
    _TIFFfree(*vpp);
47
0
    *vpp = 0;
48
0
  }
49
1.82k
  if (vp) {
50
1.82k
    tmsize_t bytes = _TIFFMultiplySSize(NULL, nmemb, elem_size, NULL);
51
1.82k
    if (bytes)
52
1.82k
      *vpp = (void*) _TIFFmalloc(bytes);
53
1.82k
    if (*vpp)
54
1.82k
      _TIFFmemcpy(*vpp, vp, bytes);
55
1.82k
  }
56
1.82k
}
57
void _TIFFsetByteArray(void** vpp, void* vp, uint32_t n)
58
0
    { setByteArray(vpp, vp, n, 1); }
59
void _TIFFsetString(char** cpp, char* cp)
60
0
    { setByteArray((void**) cpp, (void*) cp, strlen(cp)+1, 1); }
61
static void _TIFFsetNString(char** cpp, char* cp, uint32_t n)
62
0
    { setByteArray((void**) cpp, (void*) cp, n, 1); }
63
void _TIFFsetShortArray(uint16_t** wpp, uint16_t* wp, uint32_t n)
64
0
    { setByteArray((void**) wpp, (void*) wp, n, sizeof (uint16_t)); }
65
void _TIFFsetLongArray(uint32_t** lpp, uint32_t* lp, uint32_t n)
66
0
    { setByteArray((void**) lpp, (void*) lp, n, sizeof (uint32_t)); }
67
static void _TIFFsetLong8Array(uint64_t** lpp, uint64_t* lp, uint32_t n)
68
0
    { setByteArray((void**) lpp, (void*) lp, n, sizeof (uint64_t)); }
69
void _TIFFsetFloatArray(float** fpp, float* fp, uint32_t n)
70
0
    { setByteArray((void**) fpp, (void*) fp, n, sizeof (float)); }
71
void _TIFFsetDoubleArray(double** dpp, double* dp, uint32_t n)
72
0
    { setByteArray((void**) dpp, (void*) dp, n, sizeof (double)); }
73
74
static void
75
setDoubleArrayOneValue(double** vpp, double value, size_t nmemb)
76
0
{
77
0
  if (*vpp)
78
0
    _TIFFfree(*vpp);
79
0
  *vpp = _TIFFmalloc(nmemb*sizeof(double));
80
0
  if (*vpp)
81
0
  {
82
0
    while (nmemb--)
83
0
      ((double*)*vpp)[nmemb] = value;
84
0
  }
85
0
}
86
87
/*
88
 * Install extra samples information.
89
 */
90
static int
91
setExtraSamples(TIFF* tif, va_list ap, uint32_t* v)
92
0
{
93
/* XXX: Unassociated alpha data == 999 is a known Corel Draw bug, see below */
94
0
#define EXTRASAMPLE_COREL_UNASSALPHA 999 
95
96
0
  uint16_t* va;
97
0
  uint32_t i;
98
0
        TIFFDirectory* td = &tif->tif_dir;
99
0
        static const char module[] = "setExtraSamples";
100
101
0
  *v = (uint16_t) va_arg(ap, uint16_vap);
102
0
  if ((uint16_t) *v > td->td_samplesperpixel)
103
0
    return 0;
104
0
  va = va_arg(ap, uint16_t*);
105
0
  if (*v > 0 && va == NULL)   /* typically missing param */
106
0
    return 0;
107
0
  for (i = 0; i < *v; i++) {
108
0
    if (va[i] > EXTRASAMPLE_UNASSALPHA) {
109
      /*
110
       * XXX: Corel Draw is known to produce incorrect
111
       * ExtraSamples tags which must be patched here if we
112
       * want to be able to open some of the damaged TIFF
113
       * files: 
114
       */
115
0
      if (va[i] == EXTRASAMPLE_COREL_UNASSALPHA)
116
0
        va[i] = EXTRASAMPLE_UNASSALPHA;
117
0
      else
118
0
        return 0;
119
0
    }
120
0
  }
121
122
0
        if ( td->td_transferfunction[0] != NULL && (td->td_samplesperpixel - *v > 1) &&
123
0
                !(td->td_samplesperpixel - td->td_extrasamples > 1))
124
0
        {
125
0
                TIFFWarningExt(tif->tif_clientdata,module,
126
0
                    "ExtraSamples tag value is changing, "
127
0
                    "but TransferFunction was read with a different value. Canceling it");
128
0
                TIFFClrFieldBit(tif,FIELD_TRANSFERFUNCTION);
129
0
                _TIFFfree(td->td_transferfunction[0]);
130
0
                td->td_transferfunction[0] = NULL;
131
0
        }
132
133
0
  td->td_extrasamples = (uint16_t) *v;
134
0
  _TIFFsetShortArray(&td->td_sampleinfo, va, td->td_extrasamples);
135
0
  return 1;
136
137
0
#undef EXTRASAMPLE_COREL_UNASSALPHA
138
0
}
139
140
/*
141
 * Confirm we have "samplesperpixel" ink names separated by \0.  Returns 
142
 * zero if the ink names are not as expected.
143
 */
144
static uint32_t
145
checkInkNamesString(TIFF* tif, uint32_t slen, const char* s)
146
0
{
147
0
  TIFFDirectory* td = &tif->tif_dir;
148
0
  uint16_t i = td->td_samplesperpixel;
149
150
0
  if (slen > 0) {
151
0
    const char* ep = s+slen;
152
0
    const char* cp = s;
153
0
    for (; i > 0; i--) {
154
0
      for (; cp < ep && *cp != '\0'; cp++) {}
155
0
      if (cp >= ep)
156
0
        goto bad;
157
0
      cp++;       /* skip \0 */
158
0
    }
159
0
    return ((uint32_t)(cp - s));
160
0
  }
161
0
bad:
162
0
  TIFFErrorExt(tif->tif_clientdata, "TIFFSetField",
163
0
      "%s: Invalid InkNames value; expecting %"PRIu16" names, found %"PRIu16,
164
0
      tif->tif_name,
165
0
      td->td_samplesperpixel,
166
0
      (uint16_t)(td->td_samplesperpixel-i));
167
0
  return (0);
168
0
}
169
170
static int
171
_TIFFVSetField(TIFF* tif, uint32_t tag, va_list ap)
172
35.2k
{
173
35.2k
  static const char module[] = "_TIFFVSetField";
174
175
35.2k
  TIFFDirectory* td = &tif->tif_dir;
176
35.2k
  int status = 1;
177
35.2k
  uint32_t v32, i, v;
178
35.2k
    double dblval;
179
35.2k
  char* s;
180
35.2k
  const TIFFField *fip = TIFFFindField(tif, tag, TIFF_ANY);
181
35.2k
  uint32_t standard_tag = tag;
182
35.2k
  if( fip == NULL ) /* cannot happen since OkToChangeTag() already checks it */
183
0
      return 0;
184
  /*
185
   * We want to force the custom code to be used for custom
186
   * fields even if the tag happens to match a well known 
187
   * one - important for reinterpreted handling of standard
188
   * tag values in custom directories (i.e. EXIF) 
189
   */
190
35.2k
  if (fip->field_bit == FIELD_CUSTOM) {
191
1.82k
    standard_tag = 0;
192
1.82k
  }
193
194
35.2k
  switch (standard_tag) {
195
914
  case TIFFTAG_SUBFILETYPE:
196
914
    td->td_subfiletype = (uint32_t) va_arg(ap, uint32_t);
197
914
    break;
198
2.19k
  case TIFFTAG_IMAGEWIDTH:
199
2.19k
    td->td_imagewidth = (uint32_t) va_arg(ap, uint32_t);
200
2.19k
    break;
201
2.19k
  case TIFFTAG_IMAGELENGTH:
202
2.19k
    td->td_imagelength = (uint32_t) va_arg(ap, uint32_t);
203
2.19k
    break;
204
2.19k
  case TIFFTAG_BITSPERSAMPLE:
205
2.19k
    td->td_bitspersample = (uint16_t) va_arg(ap, uint16_vap);
206
    /*
207
     * If the data require post-decoding processing to byte-swap
208
     * samples, set it up here.  Note that since tags are required
209
     * to be ordered, compression code can override this behavior
210
     * in the setup method if it wants to roll the post decoding
211
     * work in with its normal work.
212
     */
213
2.19k
    if (tif->tif_flags & TIFF_SWAB) {
214
0
      if (td->td_bitspersample == 8)
215
0
        tif->tif_postdecode = _TIFFNoPostDecode;
216
0
      else if (td->td_bitspersample == 16)
217
0
        tif->tif_postdecode = _TIFFSwab16BitData;
218
0
      else if (td->td_bitspersample == 24)
219
0
        tif->tif_postdecode = _TIFFSwab24BitData;
220
0
      else if (td->td_bitspersample == 32)
221
0
        tif->tif_postdecode = _TIFFSwab32BitData;
222
0
      else if (td->td_bitspersample == 64)
223
0
        tif->tif_postdecode = _TIFFSwab64BitData;
224
0
      else if (td->td_bitspersample == 128) /* two 64's */
225
0
        tif->tif_postdecode = _TIFFSwab64BitData;
226
0
    }
227
2.19k
    break;
228
6.57k
  case TIFFTAG_COMPRESSION:
229
6.57k
    v = (uint16_t) va_arg(ap, uint16_vap);
230
    /*
231
     * If we're changing the compression scheme, the notify the
232
     * previous module so that it can cleanup any state it's
233
     * setup.
234
     */
235
6.57k
    if (TIFFFieldSet(tif, FIELD_COMPRESSION)) {
236
2.19k
      if ((uint32_t)td->td_compression == v)
237
0
        break;
238
2.19k
      (*tif->tif_cleanup)(tif);
239
2.19k
      tif->tif_flags &= ~TIFF_CODERSETUP;
240
2.19k
    }
241
    /*
242
     * Setup new compression routine state.
243
     */
244
6.57k
    if( (status = TIFFSetCompressionScheme(tif, v)) != 0 )
245
6.57k
        td->td_compression = (uint16_t) v;
246
0
    else
247
0
        status = 0;
248
6.57k
    break;
249
2.19k
  case TIFFTAG_PHOTOMETRIC:
250
2.19k
    td->td_photometric = (uint16_t) va_arg(ap, uint16_vap);
251
2.19k
    break;
252
0
  case TIFFTAG_THRESHHOLDING:
253
0
    td->td_threshholding = (uint16_t) va_arg(ap, uint16_vap);
254
0
    break;
255
2.19k
  case TIFFTAG_FILLORDER:
256
2.19k
    v = (uint16_t) va_arg(ap, uint16_vap);
257
2.19k
    if (v != FILLORDER_LSB2MSB && v != FILLORDER_MSB2LSB)
258
0
      goto badvalue;
259
2.19k
    td->td_fillorder = (uint16_t) v;
260
2.19k
    break;
261
2.19k
  case TIFFTAG_ORIENTATION:
262
2.19k
    v = (uint16_t) va_arg(ap, uint16_vap);
263
2.19k
    if (v < ORIENTATION_TOPLEFT || ORIENTATION_LEFTBOT < v)
264
0
      goto badvalue;
265
2.19k
    else
266
2.19k
      td->td_orientation = (uint16_t) v;
267
2.19k
    break;
268
2.19k
  case TIFFTAG_SAMPLESPERPIXEL:
269
2.19k
    v = (uint16_t) va_arg(ap, uint16_vap);
270
2.19k
    if (v == 0)
271
0
      goto badvalue;
272
2.19k
        if( v != td->td_samplesperpixel )
273
1.01k
        {
274
            /* See http://bugzilla.maptools.org/show_bug.cgi?id=2500 */
275
1.01k
            if( td->td_sminsamplevalue != NULL )
276
0
            {
277
0
                TIFFWarningExt(tif->tif_clientdata,module,
278
0
                    "SamplesPerPixel tag value is changing, "
279
0
                    "but SMinSampleValue tag was read with a different value. Canceling it");
280
0
                TIFFClrFieldBit(tif,FIELD_SMINSAMPLEVALUE);
281
0
                _TIFFfree(td->td_sminsamplevalue);
282
0
                td->td_sminsamplevalue = NULL;
283
0
            }
284
1.01k
            if( td->td_smaxsamplevalue != NULL )
285
0
            {
286
0
                TIFFWarningExt(tif->tif_clientdata,module,
287
0
                    "SamplesPerPixel tag value is changing, "
288
0
                    "but SMaxSampleValue tag was read with a different value. Canceling it");
289
0
                TIFFClrFieldBit(tif,FIELD_SMAXSAMPLEVALUE);
290
0
                _TIFFfree(td->td_smaxsamplevalue);
291
0
                td->td_smaxsamplevalue = NULL;
292
0
            }
293
            /* Test if 3 transfer functions instead of just one are now needed
294
               See http://bugzilla.maptools.org/show_bug.cgi?id=2820 */
295
1.01k
            if( td->td_transferfunction[0] != NULL && (v - td->td_extrasamples > 1) &&
296
1.01k
                !(td->td_samplesperpixel - td->td_extrasamples > 1))
297
0
            {
298
0
                    TIFFWarningExt(tif->tif_clientdata,module,
299
0
                        "SamplesPerPixel tag value is changing, "
300
0
                        "but TransferFunction was read with a different value. Canceling it");
301
0
                    TIFFClrFieldBit(tif,FIELD_TRANSFERFUNCTION);
302
0
                    _TIFFfree(td->td_transferfunction[0]);
303
0
                    td->td_transferfunction[0] = NULL;
304
0
            }
305
1.01k
        }
306
2.19k
    td->td_samplesperpixel = (uint16_t) v;
307
2.19k
    break;
308
2.19k
  case TIFFTAG_ROWSPERSTRIP:
309
2.19k
    v32 = (uint32_t) va_arg(ap, uint32_t);
310
2.19k
    if (v32 == 0)
311
0
      goto badvalue32;
312
2.19k
    td->td_rowsperstrip = v32;
313
2.19k
    if (!TIFFFieldSet(tif, FIELD_TILEDIMENSIONS)) {
314
2.19k
      td->td_tilelength = v32;
315
2.19k
      td->td_tilewidth = td->td_imagewidth;
316
2.19k
    }
317
2.19k
    break;
318
0
  case TIFFTAG_MINSAMPLEVALUE:
319
0
    td->td_minsamplevalue = (uint16_t) va_arg(ap, uint16_vap);
320
0
    break;
321
0
  case TIFFTAG_MAXSAMPLEVALUE:
322
0
    td->td_maxsamplevalue = (uint16_t) va_arg(ap, uint16_vap);
323
0
    break;
324
0
  case TIFFTAG_SMINSAMPLEVALUE:
325
0
    if (tif->tif_flags & TIFF_PERSAMPLE)
326
0
      _TIFFsetDoubleArray(&td->td_sminsamplevalue, va_arg(ap, double*), td->td_samplesperpixel);
327
0
    else
328
0
      setDoubleArrayOneValue(&td->td_sminsamplevalue, va_arg(ap, double), td->td_samplesperpixel);
329
0
    break;
330
0
  case TIFFTAG_SMAXSAMPLEVALUE:
331
0
    if (tif->tif_flags & TIFF_PERSAMPLE)
332
0
      _TIFFsetDoubleArray(&td->td_smaxsamplevalue, va_arg(ap, double*), td->td_samplesperpixel);
333
0
    else
334
0
      setDoubleArrayOneValue(&td->td_smaxsamplevalue, va_arg(ap, double), td->td_samplesperpixel);
335
0
    break;
336
2.19k
  case TIFFTAG_XRESOLUTION:
337
2.19k
        dblval = va_arg(ap, double);
338
2.19k
        if( dblval < 0 )
339
0
            goto badvaluedouble;
340
2.19k
    td->td_xresolution = _TIFFClampDoubleToFloat( dblval );
341
2.19k
    break;
342
2.19k
  case TIFFTAG_YRESOLUTION:
343
2.19k
        dblval = va_arg(ap, double);
344
2.19k
        if( dblval < 0 )
345
0
            goto badvaluedouble;
346
2.19k
    td->td_yresolution = _TIFFClampDoubleToFloat( dblval );
347
2.19k
    break;
348
2.19k
  case TIFFTAG_PLANARCONFIG:
349
2.19k
    v = (uint16_t) va_arg(ap, uint16_vap);
350
2.19k
    if (v != PLANARCONFIG_CONTIG && v != PLANARCONFIG_SEPARATE)
351
0
      goto badvalue;
352
2.19k
    td->td_planarconfig = (uint16_t) v;
353
2.19k
    break;
354
0
  case TIFFTAG_XPOSITION:
355
0
    td->td_xposition = _TIFFClampDoubleToFloat( va_arg(ap, double) );
356
0
    break;
357
0
  case TIFFTAG_YPOSITION:
358
0
    td->td_yposition = _TIFFClampDoubleToFloat( va_arg(ap, double) );
359
0
    break;
360
914
  case TIFFTAG_RESOLUTIONUNIT:
361
914
    v = (uint16_t) va_arg(ap, uint16_vap);
362
914
    if (v < RESUNIT_NONE || RESUNIT_CENTIMETER < v)
363
0
      goto badvalue;
364
914
    td->td_resolutionunit = (uint16_t) v;
365
914
    break;
366
914
  case TIFFTAG_PAGENUMBER:
367
914
    td->td_pagenumber[0] = (uint16_t) va_arg(ap, uint16_vap);
368
914
    td->td_pagenumber[1] = (uint16_t) va_arg(ap, uint16_vap);
369
914
    break;
370
0
  case TIFFTAG_HALFTONEHINTS:
371
0
    td->td_halftonehints[0] = (uint16_t) va_arg(ap, uint16_vap);
372
0
    td->td_halftonehints[1] = (uint16_t) va_arg(ap, uint16_vap);
373
0
    break;
374
0
  case TIFFTAG_COLORMAP:
375
0
    v32 = (uint32_t)(1L << td->td_bitspersample);
376
0
    _TIFFsetShortArray(&td->td_colormap[0], va_arg(ap, uint16_t*), v32);
377
0
    _TIFFsetShortArray(&td->td_colormap[1], va_arg(ap, uint16_t*), v32);
378
0
    _TIFFsetShortArray(&td->td_colormap[2], va_arg(ap, uint16_t*), v32);
379
0
    break;
380
0
  case TIFFTAG_EXTRASAMPLES:
381
0
    if (!setExtraSamples(tif, ap, &v))
382
0
      goto badvalue;
383
0
    break;
384
0
  case TIFFTAG_MATTEING:
385
0
    td->td_extrasamples =  (((uint16_t) va_arg(ap, uint16_vap)) != 0);
386
0
    if (td->td_extrasamples) {
387
0
      uint16_t sv = EXTRASAMPLE_ASSOCALPHA;
388
0
      _TIFFsetShortArray(&td->td_sampleinfo, &sv, 1);
389
0
    }
390
0
    break;
391
0
  case TIFFTAG_TILEWIDTH:
392
0
    v32 = (uint32_t) va_arg(ap, uint32_t);
393
0
    if (v32 % 16) {
394
0
      if (tif->tif_mode != O_RDONLY)
395
0
        goto badvalue32;
396
0
      TIFFWarningExt(tif->tif_clientdata, tif->tif_name,
397
0
        "Nonstandard tile width %"PRIu32", convert file", v32);
398
0
    }
399
0
    td->td_tilewidth = v32;
400
0
    tif->tif_flags |= TIFF_ISTILED;
401
0
    break;
402
0
  case TIFFTAG_TILELENGTH:
403
0
    v32 = (uint32_t) va_arg(ap, uint32_t);
404
0
    if (v32 % 16) {
405
0
      if (tif->tif_mode != O_RDONLY)
406
0
        goto badvalue32;
407
0
      TIFFWarningExt(tif->tif_clientdata, tif->tif_name,
408
0
          "Nonstandard tile length %"PRIu32", convert file", v32);
409
0
    }
410
0
    td->td_tilelength = v32;
411
0
    tif->tif_flags |= TIFF_ISTILED;
412
0
    break;
413
0
  case TIFFTAG_TILEDEPTH:
414
0
    v32 = (uint32_t) va_arg(ap, uint32_t);
415
0
    if (v32 == 0)
416
0
      goto badvalue32;
417
0
    td->td_tiledepth = v32;
418
0
    break;
419
0
  case TIFFTAG_DATATYPE:
420
0
    v = (uint16_t) va_arg(ap, uint16_vap);
421
0
    switch (v) {
422
0
    case DATATYPE_VOID: v = SAMPLEFORMAT_VOID; break;
423
0
    case DATATYPE_INT: v = SAMPLEFORMAT_INT; break;
424
0
    case DATATYPE_UINT: v = SAMPLEFORMAT_UINT; break;
425
0
    case DATATYPE_IEEEFP: v = SAMPLEFORMAT_IEEEFP;break;
426
0
    default:    goto badvalue;
427
0
    }
428
0
    td->td_sampleformat = (uint16_t) v;
429
0
    break;
430
0
  case TIFFTAG_SAMPLEFORMAT:
431
0
    v = (uint16_t) va_arg(ap, uint16_vap);
432
0
    if (v < SAMPLEFORMAT_UINT || SAMPLEFORMAT_COMPLEXIEEEFP < v)
433
0
      goto badvalue;
434
0
    td->td_sampleformat = (uint16_t) v;
435
436
    /*  Try to fix up the SWAB function for complex data. */
437
0
    if( td->td_sampleformat == SAMPLEFORMAT_COMPLEXINT
438
0
        && td->td_bitspersample == 32
439
0
        && tif->tif_postdecode == _TIFFSwab32BitData )
440
0
        tif->tif_postdecode = _TIFFSwab16BitData;
441
0
    else if( (td->td_sampleformat == SAMPLEFORMAT_COMPLEXINT
442
0
        || td->td_sampleformat == SAMPLEFORMAT_COMPLEXIEEEFP)
443
0
       && td->td_bitspersample == 64
444
0
       && tif->tif_postdecode == _TIFFSwab64BitData )
445
0
        tif->tif_postdecode = _TIFFSwab32BitData;
446
0
    break;
447
0
  case TIFFTAG_IMAGEDEPTH:
448
0
    td->td_imagedepth = (uint32_t) va_arg(ap, uint32_t);
449
0
    break;
450
0
  case TIFFTAG_SUBIFD:
451
0
    if ((tif->tif_flags & TIFF_INSUBIFD) == 0) {
452
0
      td->td_nsubifd = (uint16_t) va_arg(ap, uint16_vap);
453
0
      _TIFFsetLong8Array(&td->td_subifd, (uint64_t*) va_arg(ap, uint64_t*),
454
0
          (uint32_t) td->td_nsubifd);
455
0
    } else {
456
0
      TIFFErrorExt(tif->tif_clientdata, module,
457
0
             "%s: Sorry, cannot nest SubIFDs",
458
0
             tif->tif_name);
459
0
      status = 0;
460
0
    }
461
0
    break;
462
0
  case TIFFTAG_YCBCRPOSITIONING:
463
0
    td->td_ycbcrpositioning = (uint16_t) va_arg(ap, uint16_vap);
464
0
    break;
465
0
  case TIFFTAG_YCBCRSUBSAMPLING:
466
0
    td->td_ycbcrsubsampling[0] = (uint16_t) va_arg(ap, uint16_vap);
467
0
    td->td_ycbcrsubsampling[1] = (uint16_t) va_arg(ap, uint16_vap);
468
0
    break;
469
0
  case TIFFTAG_TRANSFERFUNCTION:
470
0
    v = (td->td_samplesperpixel - td->td_extrasamples) > 1 ? 3 : 1;
471
0
    for (i = 0; i < v; i++)
472
0
      _TIFFsetShortArray(&td->td_transferfunction[i],
473
0
                               va_arg(ap, uint16_t*), 1U << td->td_bitspersample);
474
0
    break;
475
0
  case TIFFTAG_REFERENCEBLACKWHITE:
476
    /* XXX should check for null range */
477
0
    _TIFFsetFloatArray(&td->td_refblackwhite, va_arg(ap, float*), 6);
478
0
    break;
479
0
  case TIFFTAG_INKNAMES:
480
0
    v = (uint16_t) va_arg(ap, uint16_vap);
481
0
    s = va_arg(ap, char*);
482
0
    v = checkInkNamesString(tif, v, s);
483
0
    status = v > 0;
484
0
    if( v > 0 ) {
485
0
      _TIFFsetNString(&td->td_inknames, s, v);
486
0
      td->td_inknameslen = v;
487
0
    }
488
0
    break;
489
0
  case TIFFTAG_PERSAMPLE:
490
0
    v = (uint16_t) va_arg(ap, uint16_vap);
491
0
    if( v == PERSAMPLE_MULTI )
492
0
      tif->tif_flags |= TIFF_PERSAMPLE;
493
0
    else
494
0
      tif->tif_flags &= ~TIFF_PERSAMPLE;
495
0
    break;
496
1.82k
  default: {
497
1.82k
    TIFFTagValue *tv;
498
1.82k
    int tv_size, iCustom;
499
500
    /*
501
     * This can happen if multiple images are open with different
502
     * codecs which have private tags.  The global tag information
503
     * table may then have tags that are valid for one file but not
504
     * the other. If the client tries to set a tag that is not valid
505
     * for the image's codec then we'll arrive here.  This
506
     * happens, for example, when tiffcp is used to convert between
507
     * compression schemes and codec-specific tags are blindly copied.
508
     */
509
1.82k
    if(fip->field_bit != FIELD_CUSTOM) {
510
0
      TIFFErrorExt(tif->tif_clientdata, module,
511
0
          "%s: Invalid %stag \"%s\" (not supported by codec)",
512
0
          tif->tif_name, isPseudoTag(tag) ? "pseudo-" : "",
513
0
          fip->field_name);
514
0
      status = 0;
515
0
      break;
516
0
    }
517
518
    /*
519
     * Find the existing entry for this custom value.
520
     */
521
1.82k
    tv = NULL;
522
2.74k
    for (iCustom = 0; iCustom < td->td_customValueCount; iCustom++) {
523
914
      if (td->td_customValues[iCustom].info->field_tag == tag) {
524
0
        tv = td->td_customValues + iCustom;
525
0
        if (tv->value != NULL) {
526
0
          _TIFFfree(tv->value);
527
0
          tv->value = NULL;
528
0
        }
529
0
        break;
530
0
      }
531
914
    }
532
533
    /*
534
     * Grow the custom list if the entry was not found.
535
     */
536
1.82k
    if(tv == NULL) {
537
1.82k
      TIFFTagValue *new_customValues;
538
539
1.82k
      td->td_customValueCount++;
540
1.82k
      new_customValues = (TIFFTagValue *)
541
1.82k
          _TIFFrealloc(td->td_customValues,
542
1.82k
          sizeof(TIFFTagValue) * td->td_customValueCount);
543
1.82k
      if (!new_customValues) {
544
0
        TIFFErrorExt(tif->tif_clientdata, module,
545
0
            "%s: Failed to allocate space for list of custom values",
546
0
            tif->tif_name);
547
0
        status = 0;
548
0
        goto end;
549
0
      }
550
551
1.82k
      td->td_customValues = new_customValues;
552
553
1.82k
      tv = td->td_customValues + (td->td_customValueCount - 1);
554
1.82k
      tv->info = fip;
555
1.82k
      tv->value = NULL;
556
1.82k
      tv->count = 0;
557
1.82k
    }
558
559
    /*
560
     * Set custom value ... save a copy of the custom tag value.
561
     */
562
1.82k
    tv_size = _TIFFDataSize(fip->field_type);
563
    /*--: Rational2Double: For Rationals evaluate "set_field_type" to determine internal storage size. */
564
1.82k
    if (fip->field_type == TIFF_RATIONAL || fip->field_type == TIFF_SRATIONAL) {
565
0
      tv_size = _TIFFSetGetFieldSize(fip->set_field_type);
566
0
    }
567
1.82k
    if (tv_size == 0) {
568
0
      status = 0;
569
0
      TIFFErrorExt(tif->tif_clientdata, module,
570
0
          "%s: Bad field type %d for \"%s\"",
571
0
          tif->tif_name, fip->field_type,
572
0
          fip->field_name);
573
0
      goto end;
574
0
    }
575
576
1.82k
    if (fip->field_type == TIFF_ASCII)
577
1.82k
    {
578
1.82k
      uint32_t ma;
579
1.82k
      char* mb;
580
1.82k
      if (fip->field_passcount)
581
0
      {
582
0
        assert(fip->field_writecount==TIFF_VARIABLE2);
583
0
        ma=(uint32_t)va_arg(ap, uint32_t);
584
0
        mb=(char*)va_arg(ap,char*);
585
0
      }
586
1.82k
      else
587
1.82k
      {
588
1.82k
        mb=(char*)va_arg(ap,char*);
589
1.82k
        ma=(uint32_t)(strlen(mb) + 1);
590
1.82k
      }
591
1.82k
      tv->count=ma;
592
1.82k
      setByteArray(&tv->value,mb,ma,1);
593
1.82k
    }
594
0
    else
595
0
    {
596
0
      if (fip->field_passcount) {
597
0
        if (fip->field_writecount == TIFF_VARIABLE2)
598
0
          tv->count = (uint32_t) va_arg(ap, uint32_t);
599
0
        else
600
0
          tv->count = (int) va_arg(ap, int);
601
0
      } else if (fip->field_writecount == TIFF_VARIABLE
602
0
         || fip->field_writecount == TIFF_VARIABLE2)
603
0
        tv->count = 1;
604
0
      else if (fip->field_writecount == TIFF_SPP)
605
0
        tv->count = td->td_samplesperpixel;
606
0
      else
607
0
        tv->count = fip->field_writecount;
608
609
0
      if (tv->count == 0) {
610
0
        status = 0;
611
0
        TIFFErrorExt(tif->tif_clientdata, module,
612
0
               "%s: Null count for \"%s\" (type "
613
0
               "%d, writecount %d, passcount %d)",
614
0
               tif->tif_name,
615
0
               fip->field_name,
616
0
               fip->field_type,
617
0
               fip->field_writecount,
618
0
               fip->field_passcount);
619
0
        goto end;
620
0
      }
621
622
0
      tv->value = _TIFFCheckMalloc(tif, tv->count, tv_size,
623
0
          "custom tag binary object");
624
0
      if (!tv->value) {
625
0
        status = 0;
626
0
        goto end;
627
0
      }
628
629
0
      if (fip->field_tag == TIFFTAG_DOTRANGE 
630
0
          && strcmp(fip->field_name,"DotRange") == 0) {
631
        /* TODO: This is an evil exception and should not have been
632
           handled this way ... likely best if we move it into
633
           the directory structure with an explicit field in 
634
           libtiff 4.1 and assign it a FIELD_ value */
635
0
        uint16_t v2[2];
636
0
        v2[0] = (uint16_t)va_arg(ap, int);
637
0
        v2[1] = (uint16_t)va_arg(ap, int);
638
0
        _TIFFmemcpy(tv->value, &v2, 4);
639
0
      }
640
641
0
      else if (fip->field_passcount
642
0
          || fip->field_writecount == TIFF_VARIABLE
643
0
          || fip->field_writecount == TIFF_VARIABLE2
644
0
          || fip->field_writecount == TIFF_SPP
645
0
          || tv->count > 1) {
646
        /*--: Rational2Double: For Rationals tv_size is set above to 4 or 8 according to fip->set_field_type! */
647
0
        _TIFFmemcpy(tv->value, va_arg(ap, void *),
648
0
            tv->count * tv_size);
649
0
      } else {
650
0
        char *val = (char *)tv->value;
651
0
        assert( tv->count == 1 );
652
653
0
        switch (fip->field_type) {
654
0
        case TIFF_BYTE:
655
0
        case TIFF_UNDEFINED:
656
0
          {
657
0
            uint8_t v2 = (uint8_t)va_arg(ap, int);
658
0
            _TIFFmemcpy(val, &v2, tv_size);
659
0
          }
660
0
          break;
661
0
        case TIFF_SBYTE:
662
0
          {
663
0
            int8_t v2 = (int8_t)va_arg(ap, int);
664
0
            _TIFFmemcpy(val, &v2, tv_size);
665
0
          }
666
0
          break;
667
0
        case TIFF_SHORT:
668
0
          {
669
0
            uint16_t v2 = (uint16_t)va_arg(ap, int);
670
0
            _TIFFmemcpy(val, &v2, tv_size);
671
0
          }
672
0
          break;
673
0
        case TIFF_SSHORT:
674
0
          {
675
0
            int16_t v2 = (int16_t)va_arg(ap, int);
676
0
            _TIFFmemcpy(val, &v2, tv_size);
677
0
          }
678
0
          break;
679
0
        case TIFF_LONG:
680
0
        case TIFF_IFD:
681
0
          {
682
0
            uint32_t v2 = va_arg(ap, uint32_t);
683
0
            _TIFFmemcpy(val, &v2, tv_size);
684
0
          }
685
0
          break;
686
0
        case TIFF_SLONG:
687
0
          {
688
0
            int32_t v2 = va_arg(ap, int32_t);
689
0
            _TIFFmemcpy(val, &v2, tv_size);
690
0
          }
691
0
          break;
692
0
        case TIFF_LONG8:
693
0
        case TIFF_IFD8:
694
0
          {
695
0
            uint64_t v2 = va_arg(ap, uint64_t);
696
0
            _TIFFmemcpy(val, &v2, tv_size);
697
0
          }
698
0
          break;
699
0
        case TIFF_SLONG8:
700
0
          {
701
0
            int64_t v2 = va_arg(ap, int64_t);
702
0
            _TIFFmemcpy(val, &v2, tv_size);
703
0
          }
704
0
          break;
705
0
        case TIFF_RATIONAL:
706
0
        case TIFF_SRATIONAL:
707
          /*-- Rational2Double: For Rationals tv_size is set above to 4 or 8 according to fip->set_field_type! */
708
0
          {
709
0
            if (tv_size == 8) {
710
0
              double v2 = va_arg(ap, double);
711
0
              _TIFFmemcpy(val, &v2, tv_size);
712
0
            } else {
713
              /*-- default should be tv_size == 4 */
714
0
              float v3 = (float)va_arg(ap, double);
715
0
              _TIFFmemcpy(val, &v3, tv_size);
716
              /*-- ToDo: After Testing, this should be removed and tv_size==4 should be set as default. */
717
0
              if (tv_size != 4) {
718
0
                TIFFErrorExt(0,"TIFFLib: _TIFFVSetField()", "Rational2Double: .set_field_type in not 4 but %d", tv_size); 
719
0
              }
720
0
            }
721
0
          }
722
0
          break;
723
0
        case TIFF_FLOAT:
724
0
          {
725
0
            float v2 = _TIFFClampDoubleToFloat(va_arg(ap, double));
726
0
            _TIFFmemcpy(val, &v2, tv_size);
727
0
          }
728
0
          break;
729
0
        case TIFF_DOUBLE:
730
0
          {
731
0
            double v2 = va_arg(ap, double);
732
0
            _TIFFmemcpy(val, &v2, tv_size);
733
0
          }
734
0
          break;
735
0
        default:
736
0
          _TIFFmemset(val, 0, tv_size);
737
0
          status = 0;
738
0
          break;
739
0
        }
740
0
      }
741
0
    }
742
1.82k
  }
743
35.2k
  }
744
35.2k
  if (status) {
745
35.2k
    const TIFFField* fip2=TIFFFieldWithTag(tif,tag);
746
35.2k
    if (fip2)                
747
35.2k
      TIFFSetFieldBit(tif, fip2->field_bit);
748
35.2k
    tif->tif_flags |= TIFF_DIRTYDIRECT;
749
35.2k
  }
750
751
35.2k
end:
752
35.2k
  va_end(ap);
753
35.2k
  return (status);
754
0
badvalue:
755
0
        {
756
0
    const TIFFField* fip2=TIFFFieldWithTag(tif,tag);
757
0
    TIFFErrorExt(tif->tif_clientdata, module,
758
0
         "%s: Bad value %"PRIu32" for \"%s\" tag",
759
0
         tif->tif_name, v,
760
0
         fip2 ? fip2->field_name : "Unknown");
761
0
    va_end(ap);
762
0
        }
763
0
  return (0);
764
0
badvalue32:
765
0
        {
766
0
    const TIFFField* fip2=TIFFFieldWithTag(tif,tag);
767
0
    TIFFErrorExt(tif->tif_clientdata, module,
768
0
         "%s: Bad value %"PRIu32" for \"%s\" tag",
769
0
         tif->tif_name, v32,
770
0
         fip2 ? fip2->field_name : "Unknown");
771
0
    va_end(ap);
772
0
        }
773
0
  return (0);
774
0
badvaluedouble:
775
0
        {
776
0
        const TIFFField* fip2=TIFFFieldWithTag(tif,tag);
777
0
        TIFFErrorExt(tif->tif_clientdata, module,
778
0
             "%s: Bad value %f for \"%s\" tag",
779
0
             tif->tif_name, dblval,
780
0
             fip2 ? fip2->field_name : "Unknown");
781
0
        va_end(ap);
782
0
        }
783
0
    return (0);
784
35.2k
}
785
786
/*
787
 * Return 1/0 according to whether or not
788
 * it is permissible to set the tag's value.
789
 * Note that we allow ImageLength to be changed
790
 * so that we can append and extend to images.
791
 * Any other tag may not be altered once writing
792
 * has commenced, unless its value has no effect
793
 * on the format of the data that is written.
794
 */
795
static int
796
OkToChangeTag(TIFF* tif, uint32_t tag)
797
37.0k
{
798
37.0k
  const TIFFField* fip = TIFFFindField(tif, tag, TIFF_ANY);
799
37.0k
  if (!fip) {     /* unknown tag */
800
0
    TIFFErrorExt(tif->tif_clientdata, "TIFFSetField", "%s: Unknown %stag %"PRIu32,
801
0
        tif->tif_name, isPseudoTag(tag) ? "pseudo-" : "", tag);
802
0
    return (0);
803
0
  }
804
37.0k
  if (tag != TIFFTAG_IMAGELENGTH && (tif->tif_flags & TIFF_BEENWRITING) &&
805
37.0k
      !fip->field_oktochange) {
806
    /*
807
     * Consult info table to see if tag can be changed
808
     * after we've started writing.  We only allow changes
809
     * to those tags that don't/shouldn't affect the
810
     * compression and/or format of the data.
811
     */
812
0
    TIFFErrorExt(tif->tif_clientdata, "TIFFSetField",
813
0
        "%s: Cannot modify tag \"%s\" while writing",
814
0
        tif->tif_name, fip->field_name);
815
0
    return (0);
816
0
  }
817
37.0k
  return (1);
818
37.0k
}
819
820
/*
821
 * Record the value of a field in the
822
 * internal directory structure.  The
823
 * field will be written to the file
824
 * when/if the directory structure is
825
 * updated.
826
 */
827
int
828
TIFFSetField(TIFF* tif, uint32_t tag, ...)
829
37.0k
{
830
37.0k
  va_list ap;
831
37.0k
  int status;
832
833
37.0k
  va_start(ap, tag);
834
37.0k
  status = TIFFVSetField(tif, tag, ap);
835
37.0k
  va_end(ap);
836
37.0k
  return (status);
837
37.0k
}
838
839
/*
840
 * Clear the contents of the field in the internal structure.
841
 */
842
int
843
TIFFUnsetField(TIFF* tif, uint32_t tag)
844
0
{
845
0
    const TIFFField *fip =  TIFFFieldWithTag(tif, tag);
846
0
    TIFFDirectory* td = &tif->tif_dir;
847
848
0
    if( !fip )
849
0
        return 0;
850
851
0
    if( fip->field_bit != FIELD_CUSTOM )
852
0
        TIFFClrFieldBit(tif, fip->field_bit);
853
0
    else
854
0
    {
855
0
        TIFFTagValue *tv = NULL;
856
0
        int i;
857
858
0
        for (i = 0; i < td->td_customValueCount; i++) {
859
                
860
0
            tv = td->td_customValues + i;
861
0
            if( tv->info->field_tag == tag )
862
0
                break;
863
0
        }
864
865
0
        if( i < td->td_customValueCount )
866
0
        {
867
0
            _TIFFfree(tv->value);
868
0
            for( ; i < td->td_customValueCount-1; i++) {
869
0
                td->td_customValues[i] = td->td_customValues[i+1];
870
0
            }
871
0
            td->td_customValueCount--;
872
0
        }
873
0
    }
874
        
875
0
    tif->tif_flags |= TIFF_DIRTYDIRECT;
876
877
0
    return (1);
878
0
}
879
880
/*
881
 * Like TIFFSetField, but taking a varargs
882
 * parameter list.  This routine is useful
883
 * for building higher-level interfaces on
884
 * top of the library.
885
 */
886
int
887
TIFFVSetField(TIFF* tif, uint32_t tag, va_list ap)
888
37.0k
{
889
37.0k
  return OkToChangeTag(tif, tag) ?
890
37.0k
      (*tif->tif_tagmethods.vsetfield)(tif, tag, ap) : 0;
891
37.0k
}
892
893
static int
894
_TIFFVGetField(TIFF* tif, uint32_t tag, va_list ap)
895
0
{
896
0
  TIFFDirectory* td = &tif->tif_dir;
897
0
  int ret_val = 1;
898
0
  uint32_t standard_tag = tag;
899
0
  const TIFFField* fip = TIFFFindField(tif, tag, TIFF_ANY);
900
0
  if( fip == NULL ) /* cannot happen since TIFFGetField() already checks it */
901
0
      return 0;
902
903
  /*
904
   * We want to force the custom code to be used for custom
905
   * fields even if the tag happens to match a well known 
906
   * one - important for reinterpreted handling of standard
907
   * tag values in custom directories (i.e. EXIF) 
908
   */
909
0
  if (fip->field_bit == FIELD_CUSTOM) {
910
0
    standard_tag = 0;
911
0
  }
912
  
913
0
        if( standard_tag == TIFFTAG_NUMBEROFINKS )
914
0
        {
915
0
            int i;
916
0
            for (i = 0; i < td->td_customValueCount; i++) {
917
0
                uint16_t val;
918
0
                TIFFTagValue *tv = td->td_customValues + i;
919
0
                if (tv->info->field_tag != standard_tag)
920
0
                    continue;
921
0
                if( tv->value == NULL )
922
0
                    return 0;
923
0
                val = *(uint16_t *)tv->value;
924
                /* Truncate to SamplesPerPixel, since the */
925
                /* setting code for INKNAMES assume that there are SamplesPerPixel */
926
                /* inknames. */
927
                /* Fixes http://bugzilla.maptools.org/show_bug.cgi?id=2599 */
928
0
                if( val > td->td_samplesperpixel )
929
0
                {
930
0
                    TIFFWarningExt(tif->tif_clientdata,"_TIFFVGetField",
931
0
                                   "Truncating NumberOfInks from %u to %"PRIu16,
932
0
                                   val, td->td_samplesperpixel);
933
0
                    val = td->td_samplesperpixel;
934
0
                }
935
0
                *va_arg(ap, uint16_t*) = val;
936
0
                return 1;
937
0
            }
938
0
            return 0;
939
0
        }
940
941
0
  switch (standard_tag) {
942
0
    case TIFFTAG_SUBFILETYPE:
943
0
      *va_arg(ap, uint32_t*) = td->td_subfiletype;
944
0
      break;
945
0
    case TIFFTAG_IMAGEWIDTH:
946
0
      *va_arg(ap, uint32_t*) = td->td_imagewidth;
947
0
      break;
948
0
    case TIFFTAG_IMAGELENGTH:
949
0
      *va_arg(ap, uint32_t*) = td->td_imagelength;
950
0
      break;
951
0
    case TIFFTAG_BITSPERSAMPLE:
952
0
      *va_arg(ap, uint16_t*) = td->td_bitspersample;
953
0
      break;
954
0
    case TIFFTAG_COMPRESSION:
955
0
      *va_arg(ap, uint16_t*) = td->td_compression;
956
0
      break;
957
0
    case TIFFTAG_PHOTOMETRIC:
958
0
      *va_arg(ap, uint16_t*) = td->td_photometric;
959
0
      break;
960
0
    case TIFFTAG_THRESHHOLDING:
961
0
      *va_arg(ap, uint16_t*) = td->td_threshholding;
962
0
      break;
963
0
    case TIFFTAG_FILLORDER:
964
0
      *va_arg(ap, uint16_t*) = td->td_fillorder;
965
0
      break;
966
0
    case TIFFTAG_ORIENTATION:
967
0
      *va_arg(ap, uint16_t*) = td->td_orientation;
968
0
      break;
969
0
    case TIFFTAG_SAMPLESPERPIXEL:
970
0
      *va_arg(ap, uint16_t*) = td->td_samplesperpixel;
971
0
      break;
972
0
    case TIFFTAG_ROWSPERSTRIP:
973
0
      *va_arg(ap, uint32_t*) = td->td_rowsperstrip;
974
0
      break;
975
0
    case TIFFTAG_MINSAMPLEVALUE:
976
0
      *va_arg(ap, uint16_t*) = td->td_minsamplevalue;
977
0
      break;
978
0
    case TIFFTAG_MAXSAMPLEVALUE:
979
0
      *va_arg(ap, uint16_t*) = td->td_maxsamplevalue;
980
0
      break;
981
0
    case TIFFTAG_SMINSAMPLEVALUE:
982
0
      if (tif->tif_flags & TIFF_PERSAMPLE)
983
0
        *va_arg(ap, double**) = td->td_sminsamplevalue;
984
0
      else
985
0
      {
986
        /* libtiff historically treats this as a single value. */
987
0
        uint16_t i;
988
0
        double v = td->td_sminsamplevalue[0];
989
0
        for (i=1; i < td->td_samplesperpixel; ++i)
990
0
          if( td->td_sminsamplevalue[i] < v )
991
0
            v = td->td_sminsamplevalue[i];
992
0
        *va_arg(ap, double*) = v;
993
0
      }
994
0
      break;
995
0
    case TIFFTAG_SMAXSAMPLEVALUE:
996
0
      if (tif->tif_flags & TIFF_PERSAMPLE)
997
0
        *va_arg(ap, double**) = td->td_smaxsamplevalue;
998
0
      else
999
0
      {
1000
        /* libtiff historically treats this as a single value. */
1001
0
        uint16_t i;
1002
0
        double v = td->td_smaxsamplevalue[0];
1003
0
        for (i=1; i < td->td_samplesperpixel; ++i)
1004
0
          if( td->td_smaxsamplevalue[i] > v )
1005
0
            v = td->td_smaxsamplevalue[i];
1006
0
        *va_arg(ap, double*) = v;
1007
0
      }
1008
0
      break;
1009
0
    case TIFFTAG_XRESOLUTION:
1010
0
      *va_arg(ap, float*) = td->td_xresolution;
1011
0
      break;
1012
0
    case TIFFTAG_YRESOLUTION:
1013
0
      *va_arg(ap, float*) = td->td_yresolution;
1014
0
      break;
1015
0
    case TIFFTAG_PLANARCONFIG:
1016
0
      *va_arg(ap, uint16_t*) = td->td_planarconfig;
1017
0
      break;
1018
0
    case TIFFTAG_XPOSITION:
1019
0
      *va_arg(ap, float*) = td->td_xposition;
1020
0
      break;
1021
0
    case TIFFTAG_YPOSITION:
1022
0
      *va_arg(ap, float*) = td->td_yposition;
1023
0
      break;
1024
0
    case TIFFTAG_RESOLUTIONUNIT:
1025
0
      *va_arg(ap, uint16_t*) = td->td_resolutionunit;
1026
0
      break;
1027
0
    case TIFFTAG_PAGENUMBER:
1028
0
      *va_arg(ap, uint16_t*) = td->td_pagenumber[0];
1029
0
      *va_arg(ap, uint16_t*) = td->td_pagenumber[1];
1030
0
      break;
1031
0
    case TIFFTAG_HALFTONEHINTS:
1032
0
      *va_arg(ap, uint16_t*) = td->td_halftonehints[0];
1033
0
      *va_arg(ap, uint16_t*) = td->td_halftonehints[1];
1034
0
      break;
1035
0
    case TIFFTAG_COLORMAP:
1036
0
      *va_arg(ap, const uint16_t**) = td->td_colormap[0];
1037
0
      *va_arg(ap, const uint16_t**) = td->td_colormap[1];
1038
0
      *va_arg(ap, const uint16_t**) = td->td_colormap[2];
1039
0
      break;
1040
0
    case TIFFTAG_STRIPOFFSETS:
1041
0
    case TIFFTAG_TILEOFFSETS:
1042
0
      _TIFFFillStriles( tif );
1043
0
      *va_arg(ap, const uint64_t**) = td->td_stripoffset_p;
1044
0
      break;
1045
0
    case TIFFTAG_STRIPBYTECOUNTS:
1046
0
    case TIFFTAG_TILEBYTECOUNTS:
1047
0
      _TIFFFillStriles( tif );
1048
0
      *va_arg(ap, const uint64_t**) = td->td_stripbytecount_p;
1049
0
      break;
1050
0
    case TIFFTAG_MATTEING:
1051
0
      *va_arg(ap, uint16_t*) =
1052
0
          (td->td_extrasamples == 1 &&
1053
0
          td->td_sampleinfo[0] == EXTRASAMPLE_ASSOCALPHA);
1054
0
      break;
1055
0
    case TIFFTAG_EXTRASAMPLES:
1056
0
      *va_arg(ap, uint16_t*) = td->td_extrasamples;
1057
0
      *va_arg(ap, const uint16_t**) = td->td_sampleinfo;
1058
0
      break;
1059
0
    case TIFFTAG_TILEWIDTH:
1060
0
      *va_arg(ap, uint32_t*) = td->td_tilewidth;
1061
0
      break;
1062
0
    case TIFFTAG_TILELENGTH:
1063
0
      *va_arg(ap, uint32_t*) = td->td_tilelength;
1064
0
      break;
1065
0
    case TIFFTAG_TILEDEPTH:
1066
0
      *va_arg(ap, uint32_t*) = td->td_tiledepth;
1067
0
      break;
1068
0
    case TIFFTAG_DATATYPE:
1069
0
      switch (td->td_sampleformat) {
1070
0
        case SAMPLEFORMAT_UINT:
1071
0
          *va_arg(ap, uint16_t*) = DATATYPE_UINT;
1072
0
          break;
1073
0
        case SAMPLEFORMAT_INT:
1074
0
          *va_arg(ap, uint16_t*) = DATATYPE_INT;
1075
0
          break;
1076
0
        case SAMPLEFORMAT_IEEEFP:
1077
0
          *va_arg(ap, uint16_t*) = DATATYPE_IEEEFP;
1078
0
          break;
1079
0
        case SAMPLEFORMAT_VOID:
1080
0
          *va_arg(ap, uint16_t*) = DATATYPE_VOID;
1081
0
          break;
1082
0
      }
1083
0
      break;
1084
0
    case TIFFTAG_SAMPLEFORMAT:
1085
0
      *va_arg(ap, uint16_t*) = td->td_sampleformat;
1086
0
      break;
1087
0
    case TIFFTAG_IMAGEDEPTH:
1088
0
      *va_arg(ap, uint32_t*) = td->td_imagedepth;
1089
0
      break;
1090
0
    case TIFFTAG_SUBIFD:
1091
0
      *va_arg(ap, uint16_t*) = td->td_nsubifd;
1092
0
      *va_arg(ap, const uint64_t**) = td->td_subifd;
1093
0
      break;
1094
0
    case TIFFTAG_YCBCRPOSITIONING:
1095
0
      *va_arg(ap, uint16_t*) = td->td_ycbcrpositioning;
1096
0
      break;
1097
0
    case TIFFTAG_YCBCRSUBSAMPLING:
1098
0
      *va_arg(ap, uint16_t*) = td->td_ycbcrsubsampling[0];
1099
0
      *va_arg(ap, uint16_t*) = td->td_ycbcrsubsampling[1];
1100
0
      break;
1101
0
    case TIFFTAG_TRANSFERFUNCTION:
1102
0
      *va_arg(ap, const uint16_t**) = td->td_transferfunction[0];
1103
0
      if (td->td_samplesperpixel - td->td_extrasamples > 1) {
1104
0
        *va_arg(ap, const uint16_t**) = td->td_transferfunction[1];
1105
0
        *va_arg(ap, const uint16_t**) = td->td_transferfunction[2];
1106
0
      } else {
1107
0
        *va_arg(ap, const uint16_t**) = NULL;
1108
0
        *va_arg(ap, const uint16_t**) = NULL;
1109
0
      }
1110
0
      break;
1111
0
    case TIFFTAG_REFERENCEBLACKWHITE:
1112
0
      *va_arg(ap, const float**) = td->td_refblackwhite;
1113
0
      break;
1114
0
    case TIFFTAG_INKNAMES:
1115
0
      *va_arg(ap, const char**) = td->td_inknames;
1116
0
      break;
1117
0
    default:
1118
0
      {
1119
0
        int i;
1120
1121
        /*
1122
         * This can happen if multiple images are open
1123
         * with different codecs which have private
1124
         * tags.  The global tag information table may
1125
         * then have tags that are valid for one file
1126
         * but not the other. If the client tries to
1127
         * get a tag that is not valid for the image's
1128
         * codec then we'll arrive here.
1129
         */
1130
0
        if( fip->field_bit != FIELD_CUSTOM )
1131
0
        {
1132
0
          TIFFErrorExt(tif->tif_clientdata, "_TIFFVGetField",
1133
0
              "%s: Invalid %stag \"%s\" "
1134
0
              "(not supported by codec)",
1135
0
              tif->tif_name,
1136
0
              isPseudoTag(tag) ? "pseudo-" : "",
1137
0
              fip->field_name);
1138
0
          ret_val = 0;
1139
0
          break;
1140
0
        }
1141
1142
        /*
1143
         * Do we have a custom value?
1144
         */
1145
0
        ret_val = 0;
1146
0
        for (i = 0; i < td->td_customValueCount; i++) {
1147
0
          TIFFTagValue *tv = td->td_customValues + i;
1148
1149
0
          if (tv->info->field_tag != tag)
1150
0
            continue;
1151
1152
0
          if (fip->field_passcount) {
1153
0
            if (fip->field_readcount == TIFF_VARIABLE2)
1154
0
              *va_arg(ap, uint32_t*) = (uint32_t)tv->count;
1155
0
            else  /* Assume TIFF_VARIABLE */
1156
0
              *va_arg(ap, uint16_t*) = (uint16_t)tv->count;
1157
0
            *va_arg(ap, const void **) = tv->value;
1158
0
            ret_val = 1;
1159
0
          } else if (fip->field_tag == TIFFTAG_DOTRANGE
1160
0
               && strcmp(fip->field_name,"DotRange") == 0) {
1161
            /* TODO: This is an evil exception and should not have been
1162
               handled this way ... likely best if we move it into
1163
               the directory structure with an explicit field in 
1164
               libtiff 4.1 and assign it a FIELD_ value */
1165
0
            *va_arg(ap, uint16_t*) = ((uint16_t *)tv->value)[0];
1166
0
            *va_arg(ap, uint16_t*) = ((uint16_t *)tv->value)[1];
1167
0
            ret_val = 1;
1168
0
          } else {
1169
0
            if (fip->field_type == TIFF_ASCII
1170
0
                || fip->field_readcount == TIFF_VARIABLE
1171
0
                || fip->field_readcount == TIFF_VARIABLE2
1172
0
                || fip->field_readcount == TIFF_SPP
1173
0
                || tv->count > 1) {
1174
0
              *va_arg(ap, void **) = tv->value;
1175
0
              ret_val = 1;
1176
0
            } else {
1177
0
              char *val = (char *)tv->value;
1178
0
              assert( tv->count == 1 );
1179
0
              switch (fip->field_type) {
1180
0
              case TIFF_BYTE:
1181
0
              case TIFF_UNDEFINED:
1182
0
                *va_arg(ap, uint8_t*) =
1183
0
                  *(uint8_t *)val;
1184
0
                ret_val = 1;
1185
0
                break;
1186
0
              case TIFF_SBYTE:
1187
0
                *va_arg(ap, int8_t*) =
1188
0
                  *(int8_t *)val;
1189
0
                ret_val = 1;
1190
0
                break;
1191
0
              case TIFF_SHORT:
1192
0
                *va_arg(ap, uint16_t*) =
1193
0
                  *(uint16_t *)val;
1194
0
                ret_val = 1;
1195
0
                break;
1196
0
              case TIFF_SSHORT:
1197
0
                *va_arg(ap, int16_t*) =
1198
0
                  *(int16_t *)val;
1199
0
                ret_val = 1;
1200
0
                break;
1201
0
              case TIFF_LONG:
1202
0
              case TIFF_IFD:
1203
0
                *va_arg(ap, uint32_t*) =
1204
0
                  *(uint32_t *)val;
1205
0
                ret_val = 1;
1206
0
                break;
1207
0
              case TIFF_SLONG:
1208
0
                *va_arg(ap, int32_t*) =
1209
0
                  *(int32_t *)val;
1210
0
                ret_val = 1;
1211
0
                break;
1212
0
              case TIFF_LONG8:
1213
0
              case TIFF_IFD8:
1214
0
                *va_arg(ap, uint64_t*) =
1215
0
                  *(uint64_t *)val;
1216
0
                ret_val = 1;
1217
0
                break;
1218
0
              case TIFF_SLONG8:
1219
0
                *va_arg(ap, int64_t*) =
1220
0
                  *(int64_t *)val;
1221
0
                ret_val = 1;
1222
0
                break;
1223
0
              case TIFF_RATIONAL:
1224
0
              case TIFF_SRATIONAL:
1225
0
                {
1226
                  /*-- Rational2Double: For Rationals evaluate "set_field_type" to determine internal storage size and return value size. */
1227
0
                  int tv_size = _TIFFSetGetFieldSize(fip->set_field_type);
1228
0
                  if (tv_size == 8) {
1229
0
                    *va_arg(ap, double*) = *(double *)val;
1230
0
                    ret_val = 1;
1231
0
                  } else {
1232
                    /*-- default should be tv_size == 4  */
1233
0
                    *va_arg(ap, float*) = *(float *)val;
1234
0
                    ret_val = 1;
1235
                    /*-- ToDo: After Testing, this should be removed and tv_size==4 should be set as default. */
1236
0
                    if (tv_size != 4) {
1237
0
                      TIFFErrorExt(0,"TIFFLib: _TIFFVGetField()", "Rational2Double: .set_field_type in not 4 but %d", tv_size); 
1238
0
                    }
1239
0
                  }
1240
0
                }
1241
0
                break;
1242
0
              case TIFF_FLOAT:
1243
0
                *va_arg(ap, float*) =
1244
0
                  *(float *)val;
1245
0
                ret_val = 1;
1246
0
                break;
1247
0
              case TIFF_DOUBLE:
1248
0
                *va_arg(ap, double*) =
1249
0
                  *(double *)val;
1250
0
                ret_val = 1;
1251
0
                break;
1252
0
              default:
1253
0
                ret_val = 0;
1254
0
                break;
1255
0
              }
1256
0
            }
1257
0
          }
1258
0
          break;
1259
0
        }
1260
0
      }
1261
0
  }
1262
0
  return(ret_val);
1263
0
}
1264
1265
/*
1266
 * Return the value of a field in the
1267
 * internal directory structure.
1268
 */
1269
int
1270
TIFFGetField(TIFF* tif, uint32_t tag, ...)
1271
0
{
1272
0
  int status;
1273
0
  va_list ap;
1274
1275
0
  va_start(ap, tag);
1276
0
  status = TIFFVGetField(tif, tag, ap);
1277
0
  va_end(ap);
1278
0
  return (status);
1279
0
}
1280
1281
/*
1282
 * Like TIFFGetField, but taking a varargs
1283
 * parameter list.  This routine is useful
1284
 * for building higher-level interfaces on
1285
 * top of the library.
1286
 */
1287
int
1288
TIFFVGetField(TIFF* tif, uint32_t tag, va_list ap)
1289
0
{
1290
0
  const TIFFField* fip = TIFFFindField(tif, tag, TIFF_ANY);
1291
0
  return (fip && (isPseudoTag(tag) || TIFFFieldSet(tif, fip->field_bit)) ?
1292
0
      (*tif->tif_tagmethods.vgetfield)(tif, tag, ap) : 0);
1293
0
}
1294
1295
65.7k
#define CleanupField(member) {   \
1296
65.7k
    if (td->member) {     \
1297
5.29k
  _TIFFfree(td->member);    \
1298
5.29k
  td->member = 0;     \
1299
5.29k
    }          \
1300
65.7k
}
1301
1302
/*
1303
 * Release storage associated with a directory.
1304
 */
1305
void
1306
TIFFFreeDirectory(TIFF* tif)
1307
4.38k
{
1308
4.38k
  TIFFDirectory *td = &tif->tif_dir;
1309
4.38k
  int            i;
1310
1311
4.38k
  _TIFFmemset(td->td_fieldsset, 0, FIELD_SETLONGS);
1312
4.38k
  CleanupField(td_sminsamplevalue);
1313
4.38k
  CleanupField(td_smaxsamplevalue);
1314
4.38k
  CleanupField(td_colormap[0]);
1315
4.38k
  CleanupField(td_colormap[1]);
1316
4.38k
  CleanupField(td_colormap[2]);
1317
4.38k
  CleanupField(td_sampleinfo);
1318
4.38k
  CleanupField(td_subifd);
1319
4.38k
  CleanupField(td_inknames);
1320
4.38k
  CleanupField(td_refblackwhite);
1321
4.38k
  CleanupField(td_transferfunction[0]);
1322
4.38k
  CleanupField(td_transferfunction[1]);
1323
4.38k
  CleanupField(td_transferfunction[2]);
1324
4.38k
  CleanupField(td_stripoffset_p);
1325
4.38k
  CleanupField(td_stripbytecount_p);
1326
4.38k
        td->td_stripoffsetbyteallocsize = 0;
1327
4.38k
  TIFFClrFieldBit(tif, FIELD_YCBCRSUBSAMPLING);
1328
4.38k
  TIFFClrFieldBit(tif, FIELD_YCBCRPOSITIONING);
1329
1330
  /* Cleanup custom tag values */
1331
6.21k
  for( i = 0; i < td->td_customValueCount; i++ ) {
1332
1.82k
    if (td->td_customValues[i].value)
1333
1.82k
      _TIFFfree(td->td_customValues[i].value);
1334
1.82k
  }
1335
1336
4.38k
  td->td_customValueCount = 0;
1337
4.38k
  CleanupField(td_customValues);
1338
1339
4.38k
        _TIFFmemset( &(td->td_stripoffset_entry), 0, sizeof(TIFFDirEntry));
1340
4.38k
        _TIFFmemset( &(td->td_stripbytecount_entry), 0, sizeof(TIFFDirEntry));
1341
4.38k
}
1342
#undef CleanupField
1343
1344
/*
1345
 * Client Tag extension support (from Niles Ritter).
1346
 */
1347
static TIFFExtendProc _TIFFextender = (TIFFExtendProc) NULL;
1348
1349
TIFFExtendProc
1350
TIFFSetTagExtender(TIFFExtendProc extender)
1351
0
{
1352
0
  TIFFExtendProc prev = _TIFFextender;
1353
0
  _TIFFextender = extender;
1354
0
  return (prev);
1355
0
}
1356
1357
/*
1358
 * Setup for a new directory.  Should we automatically call
1359
 * TIFFWriteDirectory() if the current one is dirty?
1360
 *
1361
 * The newly created directory will not exist on the file till
1362
 * TIFFWriteDirectory(), TIFFFlush() or TIFFClose() is called.
1363
 */
1364
int
1365
TIFFCreateDirectory(TIFF* tif)
1366
2.19k
{
1367
2.19k
  TIFFDefaultDirectory(tif);
1368
2.19k
  tif->tif_diroff = 0;
1369
2.19k
  tif->tif_nextdiroff = 0;
1370
2.19k
  tif->tif_curoff = 0;
1371
2.19k
  tif->tif_row = (uint32_t) -1;
1372
2.19k
  tif->tif_curstrip = (uint32_t) -1;
1373
1374
2.19k
  return 0;
1375
2.19k
}
1376
1377
int
1378
TIFFCreateCustomDirectory(TIFF* tif, const TIFFFieldArray* infoarray)
1379
0
{
1380
0
  TIFFDefaultDirectory(tif);
1381
1382
  /*
1383
   * Reset the field definitions to match the application provided list. 
1384
   * Hopefully TIFFDefaultDirectory() won't have done anything irreversible
1385
   * based on it's assumption this is an image directory.
1386
   */
1387
0
  _TIFFSetupFields(tif, infoarray);
1388
1389
0
  tif->tif_diroff = 0;
1390
0
  tif->tif_nextdiroff = 0;
1391
0
  tif->tif_curoff = 0;
1392
0
  tif->tif_row = (uint32_t) -1;
1393
0
  tif->tif_curstrip = (uint32_t) -1;
1394
1395
0
  return 0;
1396
0
}
1397
1398
int
1399
TIFFCreateEXIFDirectory(TIFF* tif)
1400
0
{
1401
0
  const TIFFFieldArray* exifFieldArray;
1402
0
  exifFieldArray = _TIFFGetExifFields();
1403
0
  return TIFFCreateCustomDirectory(tif, exifFieldArray);
1404
0
}
1405
1406
/*
1407
 * Creates the EXIF GPS custom directory 
1408
 */
1409
int
1410
TIFFCreateGPSDirectory(TIFF* tif)
1411
0
{
1412
0
  const TIFFFieldArray* gpsFieldArray;
1413
0
  gpsFieldArray = _TIFFGetGpsFields();
1414
0
  return TIFFCreateCustomDirectory(tif, gpsFieldArray);
1415
0
}
1416
1417
/*
1418
 * Setup a default directory structure.
1419
 */
1420
int
1421
TIFFDefaultDirectory(TIFF* tif)
1422
4.38k
{
1423
4.38k
  register TIFFDirectory* td = &tif->tif_dir;
1424
4.38k
  const TIFFFieldArray* tiffFieldArray;
1425
1426
4.38k
  tiffFieldArray = _TIFFGetFields();
1427
4.38k
  _TIFFSetupFields(tif, tiffFieldArray);   
1428
1429
4.38k
  _TIFFmemset(td, 0, sizeof (*td));
1430
4.38k
  td->td_fillorder = FILLORDER_MSB2LSB;
1431
4.38k
  td->td_bitspersample = 1;
1432
4.38k
  td->td_threshholding = THRESHHOLD_BILEVEL;
1433
4.38k
  td->td_orientation = ORIENTATION_TOPLEFT;
1434
4.38k
  td->td_samplesperpixel = 1;
1435
4.38k
  td->td_rowsperstrip = (uint32_t) -1;
1436
4.38k
  td->td_tilewidth = 0;
1437
4.38k
  td->td_tilelength = 0;
1438
4.38k
  td->td_tiledepth = 1;
1439
#ifdef STRIPBYTECOUNTSORTED_UNUSED
1440
  td->td_stripbytecountsorted = 1; /* Our own arrays always sorted. */  
1441
#endif
1442
4.38k
  td->td_resolutionunit = RESUNIT_INCH;
1443
4.38k
  td->td_sampleformat = SAMPLEFORMAT_UINT;
1444
4.38k
  td->td_imagedepth = 1;
1445
4.38k
  td->td_ycbcrsubsampling[0] = 2;
1446
4.38k
  td->td_ycbcrsubsampling[1] = 2;
1447
4.38k
  td->td_ycbcrpositioning = YCBCRPOSITION_CENTERED;
1448
4.38k
  tif->tif_postdecode = _TIFFNoPostDecode;  
1449
4.38k
  tif->tif_foundfield = NULL;
1450
4.38k
  tif->tif_tagmethods.vsetfield = _TIFFVSetField;  
1451
4.38k
  tif->tif_tagmethods.vgetfield = _TIFFVGetField;
1452
4.38k
  tif->tif_tagmethods.printdir = NULL;
1453
  /*
1454
   *  Give client code a chance to install their own
1455
   *  tag extensions & methods, prior to compression overloads,
1456
   *  but do some prior cleanup first. (http://trac.osgeo.org/gdal/ticket/5054)
1457
   */
1458
4.38k
  if (tif->tif_nfieldscompat > 0) {
1459
0
    uint32_t i;
1460
1461
0
    for (i = 0; i < tif->tif_nfieldscompat; i++) {
1462
0
        if (tif->tif_fieldscompat[i].allocated_size)
1463
0
            _TIFFfree(tif->tif_fieldscompat[i].fields);
1464
0
    }
1465
0
    _TIFFfree(tif->tif_fieldscompat);
1466
0
    tif->tif_nfieldscompat = 0;
1467
0
    tif->tif_fieldscompat = NULL;
1468
0
  }
1469
4.38k
  if (_TIFFextender)
1470
0
    (*_TIFFextender)(tif);
1471
4.38k
  (void) TIFFSetField(tif, TIFFTAG_COMPRESSION, COMPRESSION_NONE);
1472
  /*
1473
   * NB: The directory is marked dirty as a result of setting
1474
   * up the default compression scheme.  However, this really
1475
   * isn't correct -- we want TIFF_DIRTYDIRECT to be set only
1476
   * if the user does something.  We could just do the setup
1477
   * by hand, but it seems better to use the normal mechanism
1478
   * (i.e. TIFFSetField).
1479
   */
1480
4.38k
  tif->tif_flags &= ~TIFF_DIRTYDIRECT;
1481
1482
  /*
1483
   * As per http://bugzilla.remotesensing.org/show_bug.cgi?id=19
1484
   * we clear the ISTILED flag when setting up a new directory.
1485
   * Should we also be clearing stuff like INSUBIFD?
1486
   */
1487
4.38k
  tif->tif_flags &= ~TIFF_ISTILED;
1488
1489
4.38k
  return (1);
1490
4.38k
}
1491
1492
static int
1493
TIFFAdvanceDirectory(TIFF* tif, uint64_t* nextdir, uint64_t* off)
1494
0
{
1495
0
  static const char module[] = "TIFFAdvanceDirectory";
1496
0
  if (isMapped(tif))
1497
0
  {
1498
0
    uint64_t poff=*nextdir;
1499
0
    if (!(tif->tif_flags&TIFF_BIGTIFF))
1500
0
    {
1501
0
      tmsize_t poffa,poffb,poffc,poffd;
1502
0
      uint16_t dircount;
1503
0
      uint32_t nextdir32;
1504
0
      poffa=(tmsize_t)poff;
1505
0
      poffb=poffa+sizeof(uint16_t);
1506
0
      if (((uint64_t)poffa != poff) || (poffb < poffa) || (poffb < (tmsize_t)sizeof(uint16_t)) || (poffb > tif->tif_size))
1507
0
      {
1508
0
        TIFFErrorExt(tif->tif_clientdata,module,"Error fetching directory count");
1509
0
                                  *nextdir=0;
1510
0
        return(0);
1511
0
      }
1512
0
      _TIFFmemcpy(&dircount,tif->tif_base+poffa,sizeof(uint16_t));
1513
0
      if (tif->tif_flags&TIFF_SWAB)
1514
0
        TIFFSwabShort(&dircount);
1515
0
      poffc=poffb+dircount*12;
1516
0
      poffd=poffc+sizeof(uint32_t);
1517
0
      if ((poffc<poffb) || (poffc<dircount*12) || (poffd<poffc) || (poffd<(tmsize_t)sizeof(uint32_t)) || (poffd > tif->tif_size))
1518
0
      {
1519
0
        TIFFErrorExt(tif->tif_clientdata,module,"Error fetching directory link");
1520
0
        return(0);
1521
0
      }
1522
0
      if (off!=NULL)
1523
0
        *off=(uint64_t)poffc;
1524
0
      _TIFFmemcpy(&nextdir32,tif->tif_base+poffc,sizeof(uint32_t));
1525
0
      if (tif->tif_flags&TIFF_SWAB)
1526
0
        TIFFSwabLong(&nextdir32);
1527
0
      *nextdir=nextdir32;
1528
0
    }
1529
0
    else
1530
0
    {
1531
0
      tmsize_t poffa,poffb,poffc,poffd;
1532
0
      uint64_t dircount64;
1533
0
      uint16_t dircount16;
1534
0
      poffa=(tmsize_t)poff;
1535
0
      poffb=poffa+sizeof(uint64_t);
1536
0
      if (((uint64_t)poffa != poff) || (poffb < poffa) || (poffb < (tmsize_t)sizeof(uint64_t)) || (poffb > tif->tif_size))
1537
0
      {
1538
0
        TIFFErrorExt(tif->tif_clientdata,module,"Error fetching directory count");
1539
0
        return(0);
1540
0
      }
1541
0
      _TIFFmemcpy(&dircount64,tif->tif_base+poffa,sizeof(uint64_t));
1542
0
      if (tif->tif_flags&TIFF_SWAB)
1543
0
        TIFFSwabLong8(&dircount64);
1544
0
      if (dircount64>0xFFFF)
1545
0
      {
1546
0
        TIFFErrorExt(tif->tif_clientdata,module,"Sanity check on directory count failed");
1547
0
        return(0);
1548
0
      }
1549
0
      dircount16=(uint16_t)dircount64;
1550
0
      poffc=poffb+dircount16*20;
1551
0
      poffd=poffc+sizeof(uint64_t);
1552
0
      if ((poffc<poffb) || (poffc<dircount16*20) || (poffd<poffc) || (poffd<(tmsize_t)sizeof(uint64_t)) || (poffd > tif->tif_size))
1553
0
      {
1554
0
        TIFFErrorExt(tif->tif_clientdata,module,"Error fetching directory link");
1555
0
        return(0);
1556
0
      }
1557
0
      if (off!=NULL)
1558
0
        *off=(uint64_t)poffc;
1559
0
      _TIFFmemcpy(nextdir,tif->tif_base+poffc,sizeof(uint64_t));
1560
0
      if (tif->tif_flags&TIFF_SWAB)
1561
0
        TIFFSwabLong8(nextdir);
1562
0
    }
1563
0
    return(1);
1564
0
  }
1565
0
  else
1566
0
  {
1567
0
    if (!(tif->tif_flags&TIFF_BIGTIFF))
1568
0
    {
1569
0
      uint16_t dircount;
1570
0
      uint32_t nextdir32;
1571
0
      if (!SeekOK(tif, *nextdir) ||
1572
0
          !ReadOK(tif, &dircount, sizeof (uint16_t))) {
1573
0
        TIFFErrorExt(tif->tif_clientdata, module, "%s: Error fetching directory count",
1574
0
            tif->tif_name);
1575
0
        return (0);
1576
0
      }
1577
0
      if (tif->tif_flags & TIFF_SWAB)
1578
0
        TIFFSwabShort(&dircount);
1579
0
      if (off != NULL)
1580
0
        *off = TIFFSeekFile(tif,
1581
0
            dircount*12, SEEK_CUR);
1582
0
      else
1583
0
        (void) TIFFSeekFile(tif,
1584
0
            dircount*12, SEEK_CUR);
1585
0
      if (!ReadOK(tif, &nextdir32, sizeof (uint32_t))) {
1586
0
        TIFFErrorExt(tif->tif_clientdata, module, "%s: Error fetching directory link",
1587
0
            tif->tif_name);
1588
0
        return (0);
1589
0
      }
1590
0
      if (tif->tif_flags & TIFF_SWAB)
1591
0
        TIFFSwabLong(&nextdir32);
1592
0
      *nextdir=nextdir32;
1593
0
    }
1594
0
    else
1595
0
    {
1596
0
      uint64_t dircount64;
1597
0
      uint16_t dircount16;
1598
0
      if (!SeekOK(tif, *nextdir) ||
1599
0
          !ReadOK(tif, &dircount64, sizeof (uint64_t))) {
1600
0
        TIFFErrorExt(tif->tif_clientdata, module, "%s: Error fetching directory count",
1601
0
            tif->tif_name);
1602
0
        return (0);
1603
0
      }
1604
0
      if (tif->tif_flags & TIFF_SWAB)
1605
0
        TIFFSwabLong8(&dircount64);
1606
0
      if (dircount64>0xFFFF)
1607
0
      {
1608
0
        TIFFErrorExt(tif->tif_clientdata, module, "Error fetching directory count");
1609
0
        return(0);
1610
0
      }
1611
0
      dircount16 = (uint16_t)dircount64;
1612
0
      if (off != NULL)
1613
0
        *off = TIFFSeekFile(tif,
1614
0
            dircount16*20, SEEK_CUR);
1615
0
      else
1616
0
        (void) TIFFSeekFile(tif,
1617
0
            dircount16*20, SEEK_CUR);
1618
0
      if (!ReadOK(tif, nextdir, sizeof (uint64_t))) {
1619
0
        TIFFErrorExt(tif->tif_clientdata, module,
1620
0
                                             "%s: Error fetching directory link",
1621
0
            tif->tif_name);
1622
0
        return (0);
1623
0
      }
1624
0
      if (tif->tif_flags & TIFF_SWAB)
1625
0
        TIFFSwabLong8(nextdir);
1626
0
    }
1627
0
    return (1);
1628
0
  }
1629
0
}
1630
1631
/*
1632
 * Count the number of directories in a file.
1633
 */
1634
uint16_t
1635
TIFFNumberOfDirectories(TIFF* tif)
1636
0
{
1637
0
  static const char module[] = "TIFFNumberOfDirectories";
1638
0
  uint64_t nextdir;
1639
0
  uint16_t n;
1640
0
  if (!(tif->tif_flags&TIFF_BIGTIFF))
1641
0
    nextdir = tif->tif_header.classic.tiff_diroff;
1642
0
  else
1643
0
    nextdir = tif->tif_header.big.tiff_diroff;
1644
0
  n = 0;
1645
0
  while (nextdir != 0 && TIFFAdvanceDirectory(tif, &nextdir, NULL))
1646
0
        {
1647
0
                if (n != 65535) {
1648
0
                        ++n;
1649
0
                }
1650
0
    else
1651
0
                {
1652
0
                        TIFFErrorExt(tif->tif_clientdata, module,
1653
0
                                     "Directory count exceeded 65535 limit,"
1654
0
                                     " giving up on counting.");
1655
0
                        return (65535);
1656
0
                }
1657
0
        }
1658
0
  return (n);
1659
0
}
1660
1661
/*
1662
 * Set the n-th directory as the current directory.
1663
 * NB: Directories are numbered starting at 0.
1664
 */
1665
int
1666
TIFFSetDirectory(TIFF* tif, uint16_t dirn)
1667
0
{
1668
0
  uint64_t nextdir;
1669
0
  uint16_t n;
1670
1671
0
  if (!(tif->tif_flags&TIFF_BIGTIFF))
1672
0
    nextdir = tif->tif_header.classic.tiff_diroff;
1673
0
  else
1674
0
    nextdir = tif->tif_header.big.tiff_diroff;
1675
0
  for (n = dirn; n > 0 && nextdir != 0; n--)
1676
0
    if (!TIFFAdvanceDirectory(tif, &nextdir, NULL))
1677
0
      return (0);
1678
0
  tif->tif_nextdiroff = nextdir;
1679
  /*
1680
   * Set curdir to the actual directory index.  The
1681
   * -1 is because TIFFReadDirectory will increment
1682
   * tif_curdir after successfully reading the directory.
1683
   */
1684
0
  tif->tif_curdir = (dirn - n) - 1;
1685
  /*
1686
   * Reset tif_dirnumber counter and start new list of seen directories.
1687
   * We need this to prevent IFD loops.
1688
   */
1689
0
  tif->tif_dirnumber = 0;
1690
0
  return (TIFFReadDirectory(tif));
1691
0
}
1692
1693
/*
1694
 * Set the current directory to be the directory
1695
 * located at the specified file offset.  This interface
1696
 * is used mainly to access directories linked with
1697
 * the SubIFD tag (e.g. thumbnail images).
1698
 */
1699
int
1700
TIFFSetSubDirectory(TIFF* tif, uint64_t diroff)
1701
0
{
1702
0
  tif->tif_nextdiroff = diroff;
1703
  /*
1704
   * Reset tif_dirnumber counter and start new list of seen directories.
1705
   * We need this to prevent IFD loops.
1706
   */
1707
0
  tif->tif_dirnumber = 0;
1708
0
  return (TIFFReadDirectory(tif));
1709
0
}
1710
1711
/*
1712
 * Return file offset of the current directory.
1713
 */
1714
uint64_t
1715
TIFFCurrentDirOffset(TIFF* tif)
1716
0
{
1717
0
  return (tif->tif_diroff);
1718
0
}
1719
1720
/*
1721
 * Return an indication of whether or not we are
1722
 * at the last directory in the file.
1723
 */
1724
int
1725
TIFFLastDirectory(TIFF* tif)
1726
0
{
1727
0
  return (tif->tif_nextdiroff == 0);
1728
0
}
1729
1730
/*
1731
 * Unlink the specified directory from the directory chain.
1732
 */
1733
int
1734
TIFFUnlinkDirectory(TIFF* tif, uint16_t dirn)
1735
0
{
1736
0
  static const char module[] = "TIFFUnlinkDirectory";
1737
0
  uint64_t nextdir;
1738
0
  uint64_t off;
1739
0
  uint16_t n;
1740
1741
0
  if (tif->tif_mode == O_RDONLY) {
1742
0
    TIFFErrorExt(tif->tif_clientdata, module,
1743
0
                             "Can not unlink directory in read-only file");
1744
0
    return (0);
1745
0
  }
1746
  /*
1747
   * Go to the directory before the one we want
1748
   * to unlink and nab the offset of the link
1749
   * field we'll need to patch.
1750
   */
1751
0
  if (!(tif->tif_flags&TIFF_BIGTIFF))
1752
0
  {
1753
0
    nextdir = tif->tif_header.classic.tiff_diroff;
1754
0
    off = 4;
1755
0
  }
1756
0
  else
1757
0
  {
1758
0
    nextdir = tif->tif_header.big.tiff_diroff;
1759
0
    off = 8;
1760
0
  }
1761
0
  for (n = dirn-1; n > 0; n--) {
1762
0
    if (nextdir == 0) {
1763
0
      TIFFErrorExt(tif->tif_clientdata, module, "Directory %"PRIu16" does not exist", dirn);
1764
0
      return (0);
1765
0
    }
1766
0
    if (!TIFFAdvanceDirectory(tif, &nextdir, &off))
1767
0
      return (0);
1768
0
  }
1769
  /*
1770
   * Advance to the directory to be unlinked and fetch
1771
   * the offset of the directory that follows.
1772
   */
1773
0
  if (!TIFFAdvanceDirectory(tif, &nextdir, NULL))
1774
0
    return (0);
1775
  /*
1776
   * Go back and patch the link field of the preceding
1777
   * directory to point to the offset of the directory
1778
   * that follows.
1779
   */
1780
0
  (void) TIFFSeekFile(tif, off, SEEK_SET);
1781
0
  if (!(tif->tif_flags&TIFF_BIGTIFF))
1782
0
  {
1783
0
    uint32_t nextdir32;
1784
0
    nextdir32=(uint32_t)nextdir;
1785
0
    assert((uint64_t)nextdir32 == nextdir);
1786
0
    if (tif->tif_flags & TIFF_SWAB)
1787
0
      TIFFSwabLong(&nextdir32);
1788
0
    if (!WriteOK(tif, &nextdir32, sizeof (uint32_t))) {
1789
0
      TIFFErrorExt(tif->tif_clientdata, module, "Error writing directory link");
1790
0
      return (0);
1791
0
    }
1792
0
  }
1793
0
  else
1794
0
  {
1795
0
    if (tif->tif_flags & TIFF_SWAB)
1796
0
      TIFFSwabLong8(&nextdir);
1797
0
    if (!WriteOK(tif, &nextdir, sizeof (uint64_t))) {
1798
0
      TIFFErrorExt(tif->tif_clientdata, module, "Error writing directory link");
1799
0
      return (0);
1800
0
    }
1801
0
  }
1802
  /*
1803
   * Leave directory state setup safely.  We don't have
1804
   * facilities for doing inserting and removing directories,
1805
   * so it's safest to just invalidate everything.  This
1806
   * means that the caller can only append to the directory
1807
   * chain.
1808
   */
1809
0
  (*tif->tif_cleanup)(tif);
1810
0
  if ((tif->tif_flags & TIFF_MYBUFFER) && tif->tif_rawdata) {
1811
0
    _TIFFfree(tif->tif_rawdata);
1812
0
    tif->tif_rawdata = NULL;
1813
0
    tif->tif_rawcc = 0;
1814
0
                tif->tif_rawdataoff = 0;
1815
0
                tif->tif_rawdataloaded = 0;
1816
0
  }
1817
0
  tif->tif_flags &= ~(TIFF_BEENWRITING|TIFF_BUFFERSETUP|TIFF_POSTENCODE|TIFF_BUF4WRITE);
1818
0
  TIFFFreeDirectory(tif);
1819
0
  TIFFDefaultDirectory(tif);
1820
0
  tif->tif_diroff = 0;      /* force link on next write */
1821
0
  tif->tif_nextdiroff = 0;    /* next write must be at end */
1822
0
  tif->tif_curoff = 0;
1823
0
  tif->tif_row = (uint32_t) -1;
1824
0
  tif->tif_curstrip = (uint32_t) -1;
1825
0
  return (1);
1826
0
}
1827
1828
/* vim: set ts=8 sts=8 sw=8 noet: */
1829
/*
1830
 * Local Variables:
1831
 * mode: c
1832
 * c-basic-offset: 8
1833
 * fill-column: 78
1834
 * End:
1835
 */