Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
wine-mirror
GitHub Repository: wine-mirror/wine
Path: blob/master/libs/tiff/libtiff/tif_dir.c
4391 views
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
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
}
60
void _TIFFsetByteArray(void **vpp, const void *vp, uint32_t n)
61
{
62
setByteArray(NULL, vpp, vp, n, 1);
63
}
64
void _TIFFsetByteArrayExt(TIFF *tif, void **vpp, const void *vp, uint32_t n)
65
{
66
setByteArray(tif, vpp, vp, n, 1);
67
}
68
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
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
}
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
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
}
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
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
100
void _TIFFsetFloatArray(float **fpp, const float *fp, uint32_t n)
101
{
102
setByteArray(NULL, (void **)fpp, fp, n, sizeof(float));
103
}
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
109
void _TIFFsetDoubleArray(double **dpp, const double *dp, uint32_t n)
110
{
111
setByteArray(NULL, (void **)dpp, dp, n, sizeof(double));
112
}
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
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
*/
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
*/
192
static uint16_t countInkNamesString(TIFF *tif, uint32_t slen, const char *s)
193
{
194
uint16_t i = 0;
195
196
if (slen > 0)
197
{
198
const char *ep = s + slen;
199
const char *cp = s;
200
do
201
{
202
for (; cp < ep && *cp != '\0'; cp++)
203
{
204
}
205
if (cp >= ep)
206
goto bad;
207
cp++; /* skip \0 */
208
i++;
209
} while (cp < ep);
210
return (i);
211
}
212
bad:
213
TIFFErrorExtR(tif, "TIFFSetField",
214
"%s: Invalid InkNames value; no null at given buffer end "
215
"location %" PRIu32 ", after %" PRIu16 " ink",
216
tif->tif_name, slen, i);
217
return (0);
218
}
219
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
*/
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
*/
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
*/
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
*/
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
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
*/
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
*/
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
*/
1619
void TIFFFreeDirectory(TIFF *tif)
1620
{
1621
TIFFDirectory *td = &tif->tif_dir;
1622
int i;
1623
1624
_TIFFmemset(td->td_fieldsset, 0, sizeof(td->td_fieldsset));
1625
CleanupField(td_sminsamplevalue);
1626
CleanupField(td_smaxsamplevalue);
1627
CleanupField(td_colormap[0]);
1628
CleanupField(td_colormap[1]);
1629
CleanupField(td_colormap[2]);
1630
CleanupField(td_sampleinfo);
1631
CleanupField(td_subifd);
1632
CleanupField(td_inknames);
1633
CleanupField(td_refblackwhite);
1634
CleanupField(td_transferfunction[0]);
1635
CleanupField(td_transferfunction[1]);
1636
CleanupField(td_transferfunction[2]);
1637
CleanupField(td_stripoffset_p);
1638
CleanupField(td_stripbytecount_p);
1639
td->td_stripoffsetbyteallocsize = 0;
1640
TIFFClrFieldBit(tif, FIELD_YCBCRSUBSAMPLING);
1641
TIFFClrFieldBit(tif, FIELD_YCBCRPOSITIONING);
1642
1643
/* Cleanup custom tag values */
1644
for (i = 0; i < td->td_customValueCount; i++)
1645
{
1646
if (td->td_customValues[i].value)
1647
_TIFFfreeExt(tif, td->td_customValues[i].value);
1648
}
1649
1650
td->td_customValueCount = 0;
1651
CleanupField(td_customValues);
1652
1653
_TIFFmemset(&(td->td_stripoffset_entry), 0, sizeof(TIFFDirEntry));
1654
_TIFFmemset(&(td->td_stripbytecount_entry), 0, sizeof(TIFFDirEntry));
1655
1656
/* Reset some internal parameters for IFD data size checking. */
1657
tif->tif_dir.td_dirdatasize_read = 0;
1658
tif->tif_dir.td_dirdatasize_write = 0;
1659
if (tif->tif_dir.td_dirdatasize_offsets != NULL)
1660
{
1661
_TIFFfreeExt(tif, tif->tif_dir.td_dirdatasize_offsets);
1662
tif->tif_dir.td_dirdatasize_offsets = NULL;
1663
tif->tif_dir.td_dirdatasize_Noffsets = 0;
1664
}
1665
tif->tif_dir.td_iswrittentofile = FALSE;
1666
}
1667
#undef CleanupField
1668
1669
/*
1670
* Client Tag extension support (from Niles Ritter).
1671
*/
1672
static TIFFExtendProc _TIFFextender = (TIFFExtendProc)NULL;
1673
1674
TIFFExtendProc TIFFSetTagExtender(TIFFExtendProc extender)
1675
{
1676
TIFFExtendProc prev = _TIFFextender;
1677
_TIFFextender = extender;
1678
return (prev);
1679
}
1680
1681
/*
1682
* Setup for a new directory. Should we automatically call
1683
* TIFFWriteDirectory() if the current one is dirty?
1684
*
1685
* The newly created directory will not exist on the file till
1686
* TIFFWriteDirectory(), TIFFFlush() or TIFFClose() is called.
1687
*/
1688
int TIFFCreateDirectory(TIFF *tif)
1689
{
1690
/* Free previously allocated memory and setup default values. */
1691
TIFFFreeDirectory(tif);
1692
TIFFDefaultDirectory(tif);
1693
tif->tif_diroff = 0;
1694
tif->tif_nextdiroff = 0;
1695
tif->tif_curoff = 0;
1696
tif->tif_row = (uint32_t)-1;
1697
tif->tif_curstrip = (uint32_t)-1;
1698
tif->tif_dir.td_iswrittentofile = FALSE;
1699
1700
return 0;
1701
}
1702
1703
int TIFFCreateCustomDirectory(TIFF *tif, const TIFFFieldArray *infoarray)
1704
{
1705
/* Free previously allocated memory and setup default values. */
1706
TIFFFreeDirectory(tif);
1707
TIFFDefaultDirectory(tif);
1708
1709
/*
1710
* Reset the field definitions to match the application provided list.
1711
* Hopefully TIFFDefaultDirectory() won't have done anything irreversible
1712
* based on it's assumption this is an image directory.
1713
*/
1714
_TIFFSetupFields(tif, infoarray);
1715
1716
tif->tif_diroff = 0;
1717
tif->tif_nextdiroff = 0;
1718
tif->tif_curoff = 0;
1719
tif->tif_row = (uint32_t)-1;
1720
tif->tif_curstrip = (uint32_t)-1;
1721
/* invalidate directory index */
1722
tif->tif_curdir = TIFF_NON_EXISTENT_DIR_NUMBER;
1723
/* invalidate IFD loop lists */
1724
_TIFFCleanupIFDOffsetAndNumberMaps(tif);
1725
/* To be able to return from SubIFD or custom-IFD to main-IFD */
1726
tif->tif_setdirectory_force_absolute = TRUE;
1727
1728
return 0;
1729
}
1730
1731
int TIFFCreateEXIFDirectory(TIFF *tif)
1732
{
1733
const TIFFFieldArray *exifFieldArray;
1734
exifFieldArray = _TIFFGetExifFields();
1735
return TIFFCreateCustomDirectory(tif, exifFieldArray);
1736
}
1737
1738
/*
1739
* Creates the EXIF GPS custom directory
1740
*/
1741
int TIFFCreateGPSDirectory(TIFF *tif)
1742
{
1743
const TIFFFieldArray *gpsFieldArray;
1744
gpsFieldArray = _TIFFGetGpsFields();
1745
return TIFFCreateCustomDirectory(tif, gpsFieldArray);
1746
}
1747
1748
/*
1749
* Setup a default directory structure.
1750
*/
1751
int TIFFDefaultDirectory(TIFF *tif)
1752
{
1753
register TIFFDirectory *td = &tif->tif_dir;
1754
const TIFFFieldArray *tiffFieldArray;
1755
1756
tiffFieldArray = _TIFFGetFields();
1757
_TIFFSetupFields(tif, tiffFieldArray);
1758
1759
_TIFFmemset(td, 0, sizeof(*td));
1760
td->td_fillorder = FILLORDER_MSB2LSB;
1761
td->td_bitspersample = 1;
1762
td->td_threshholding = THRESHHOLD_BILEVEL;
1763
td->td_orientation = ORIENTATION_TOPLEFT;
1764
td->td_samplesperpixel = 1;
1765
td->td_rowsperstrip = (uint32_t)-1;
1766
td->td_tilewidth = 0;
1767
td->td_tilelength = 0;
1768
td->td_tiledepth = 1;
1769
#ifdef STRIPBYTECOUNTSORTED_UNUSED
1770
td->td_stripbytecountsorted = 1; /* Our own arrays always sorted. */
1771
#endif
1772
td->td_resolutionunit = RESUNIT_INCH;
1773
td->td_sampleformat = SAMPLEFORMAT_UINT;
1774
td->td_imagedepth = 1;
1775
td->td_ycbcrsubsampling[0] = 2;
1776
td->td_ycbcrsubsampling[1] = 2;
1777
td->td_ycbcrpositioning = YCBCRPOSITION_CENTERED;
1778
tif->tif_postdecode = _TIFFNoPostDecode;
1779
tif->tif_foundfield = NULL;
1780
tif->tif_tagmethods.vsetfield = _TIFFVSetField;
1781
tif->tif_tagmethods.vgetfield = _TIFFVGetField;
1782
tif->tif_tagmethods.printdir = NULL;
1783
/* additional default values */
1784
td->td_planarconfig = PLANARCONFIG_CONTIG;
1785
td->td_compression = COMPRESSION_NONE;
1786
td->td_subfiletype = 0;
1787
td->td_minsamplevalue = 0;
1788
/* td_bitspersample=1 is always set in TIFFDefaultDirectory().
1789
* Therefore, td_maxsamplevalue has to be re-calculated in
1790
* TIFFGetFieldDefaulted(). */
1791
td->td_maxsamplevalue = 1; /* Default for td_bitspersample=1 */
1792
td->td_extrasamples = 0;
1793
td->td_sampleinfo = NULL;
1794
1795
/*
1796
* Give client code a chance to install their own
1797
* tag extensions & methods, prior to compression overloads,
1798
* but do some prior cleanup first.
1799
* (http://trac.osgeo.org/gdal/ticket/5054)
1800
*/
1801
if (tif->tif_nfieldscompat > 0)
1802
{
1803
uint32_t i;
1804
1805
for (i = 0; i < tif->tif_nfieldscompat; i++)
1806
{
1807
if (tif->tif_fieldscompat[i].allocated_size)
1808
_TIFFfreeExt(tif, tif->tif_fieldscompat[i].fields);
1809
}
1810
_TIFFfreeExt(tif, tif->tif_fieldscompat);
1811
tif->tif_nfieldscompat = 0;
1812
tif->tif_fieldscompat = NULL;
1813
}
1814
if (_TIFFextender)
1815
(*_TIFFextender)(tif);
1816
(void)TIFFSetField(tif, TIFFTAG_COMPRESSION, COMPRESSION_NONE);
1817
/*
1818
* NB: The directory is marked dirty as a result of setting
1819
* up the default compression scheme. However, this really
1820
* isn't correct -- we want TIFF_DIRTYDIRECT to be set only
1821
* if the user does something. We could just do the setup
1822
* by hand, but it seems better to use the normal mechanism
1823
* (i.e. TIFFSetField).
1824
*/
1825
tif->tif_flags &= ~TIFF_DIRTYDIRECT;
1826
1827
/*
1828
* As per http://bugzilla.remotesensing.org/show_bug.cgi?id=19
1829
* we clear the ISTILED flag when setting up a new directory.
1830
* Should we also be clearing stuff like INSUBIFD?
1831
*/
1832
tif->tif_flags &= ~TIFF_ISTILED;
1833
1834
return (1);
1835
}
1836
1837
static int TIFFAdvanceDirectory(TIFF *tif, uint64_t *nextdiroff, uint64_t *off,
1838
tdir_t *nextdirnum)
1839
{
1840
static const char module[] = "TIFFAdvanceDirectory";
1841
1842
/* Add this directory to the directory list, if not already in. */
1843
if (!_TIFFCheckDirNumberAndOffset(tif, *nextdirnum, *nextdiroff))
1844
{
1845
TIFFErrorExtR(tif, module,
1846
"Starting directory %u at offset 0x%" PRIx64 " (%" PRIu64
1847
") might cause an IFD loop",
1848
*nextdirnum, *nextdiroff, *nextdiroff);
1849
*nextdiroff = 0;
1850
*nextdirnum = 0;
1851
return (0);
1852
}
1853
1854
if (isMapped(tif))
1855
{
1856
uint64_t poff = *nextdiroff;
1857
if (!(tif->tif_flags & TIFF_BIGTIFF))
1858
{
1859
tmsize_t poffa, poffb, poffc, poffd;
1860
uint16_t dircount;
1861
uint32_t nextdir32;
1862
poffa = (tmsize_t)poff;
1863
poffb = poffa + sizeof(uint16_t);
1864
if (((uint64_t)poffa != poff) || (poffb < poffa) ||
1865
(poffb < (tmsize_t)sizeof(uint16_t)) || (poffb > tif->tif_size))
1866
{
1867
TIFFErrorExtR(tif, module,
1868
"%s:%d: %s: Error fetching directory count",
1869
__FILE__, __LINE__, tif->tif_name);
1870
*nextdiroff = 0;
1871
return (0);
1872
}
1873
_TIFFmemcpy(&dircount, tif->tif_base + poffa, sizeof(uint16_t));
1874
if (tif->tif_flags & TIFF_SWAB)
1875
TIFFSwabShort(&dircount);
1876
poffc = poffb + dircount * 12;
1877
poffd = poffc + sizeof(uint32_t);
1878
if ((poffc < poffb) || (poffc < dircount * 12) || (poffd < poffc) ||
1879
(poffd < (tmsize_t)sizeof(uint32_t)) || (poffd > tif->tif_size))
1880
{
1881
TIFFErrorExtR(tif, module, "Error fetching directory link");
1882
return (0);
1883
}
1884
if (off != NULL)
1885
*off = (uint64_t)poffc;
1886
_TIFFmemcpy(&nextdir32, tif->tif_base + poffc, sizeof(uint32_t));
1887
if (tif->tif_flags & TIFF_SWAB)
1888
TIFFSwabLong(&nextdir32);
1889
*nextdiroff = nextdir32;
1890
}
1891
else
1892
{
1893
tmsize_t poffa, poffb, poffc, poffd;
1894
uint64_t dircount64;
1895
uint16_t dircount16;
1896
if (poff > (uint64_t)TIFF_TMSIZE_T_MAX - sizeof(uint64_t))
1897
{
1898
TIFFErrorExtR(tif, module,
1899
"%s:%d: %s: Error fetching directory count",
1900
__FILE__, __LINE__, tif->tif_name);
1901
return (0);
1902
}
1903
poffa = (tmsize_t)poff;
1904
poffb = poffa + sizeof(uint64_t);
1905
if (poffb > tif->tif_size)
1906
{
1907
TIFFErrorExtR(tif, module,
1908
"%s:%d: %s: Error fetching directory count",
1909
__FILE__, __LINE__, tif->tif_name);
1910
return (0);
1911
}
1912
_TIFFmemcpy(&dircount64, tif->tif_base + poffa, sizeof(uint64_t));
1913
if (tif->tif_flags & TIFF_SWAB)
1914
TIFFSwabLong8(&dircount64);
1915
if (dircount64 > 0xFFFF)
1916
{
1917
TIFFErrorExtR(tif, module,
1918
"Sanity check on directory count failed");
1919
return (0);
1920
}
1921
dircount16 = (uint16_t)dircount64;
1922
if (poffb > TIFF_TMSIZE_T_MAX - (tmsize_t)(dircount16 * 20) -
1923
(tmsize_t)sizeof(uint64_t))
1924
{
1925
TIFFErrorExtR(tif, module, "Error fetching directory link");
1926
return (0);
1927
}
1928
poffc = poffb + dircount16 * 20;
1929
poffd = poffc + sizeof(uint64_t);
1930
if (poffd > tif->tif_size)
1931
{
1932
TIFFErrorExtR(tif, module, "Error fetching directory link");
1933
return (0);
1934
}
1935
if (off != NULL)
1936
*off = (uint64_t)poffc;
1937
_TIFFmemcpy(nextdiroff, tif->tif_base + poffc, sizeof(uint64_t));
1938
if (tif->tif_flags & TIFF_SWAB)
1939
TIFFSwabLong8(nextdiroff);
1940
}
1941
}
1942
else
1943
{
1944
if (!(tif->tif_flags & TIFF_BIGTIFF))
1945
{
1946
uint16_t dircount;
1947
uint32_t nextdir32;
1948
if (!SeekOK(tif, *nextdiroff) ||
1949
!ReadOK(tif, &dircount, sizeof(uint16_t)))
1950
{
1951
TIFFErrorExtR(tif, module,
1952
"%s:%d: %s: Error fetching directory count",
1953
__FILE__, __LINE__, tif->tif_name);
1954
return (0);
1955
}
1956
if (tif->tif_flags & TIFF_SWAB)
1957
TIFFSwabShort(&dircount);
1958
if (off != NULL)
1959
*off = TIFFSeekFile(tif, dircount * 12, SEEK_CUR);
1960
else
1961
(void)TIFFSeekFile(tif, dircount * 12, SEEK_CUR);
1962
if (!ReadOK(tif, &nextdir32, sizeof(uint32_t)))
1963
{
1964
TIFFErrorExtR(tif, module, "%s: Error fetching directory link",
1965
tif->tif_name);
1966
return (0);
1967
}
1968
if (tif->tif_flags & TIFF_SWAB)
1969
TIFFSwabLong(&nextdir32);
1970
*nextdiroff = nextdir32;
1971
}
1972
else
1973
{
1974
uint64_t dircount64;
1975
uint16_t dircount16;
1976
if (!SeekOK(tif, *nextdiroff) ||
1977
!ReadOK(tif, &dircount64, sizeof(uint64_t)))
1978
{
1979
TIFFErrorExtR(tif, module,
1980
"%s:%d: %s: Error fetching directory count",
1981
__FILE__, __LINE__, tif->tif_name);
1982
return (0);
1983
}
1984
if (tif->tif_flags & TIFF_SWAB)
1985
TIFFSwabLong8(&dircount64);
1986
if (dircount64 > 0xFFFF)
1987
{
1988
TIFFErrorExtR(tif, module,
1989
"%s:%d: %s: Error fetching directory count",
1990
__FILE__, __LINE__, tif->tif_name);
1991
return (0);
1992
}
1993
dircount16 = (uint16_t)dircount64;
1994
if (off != NULL)
1995
*off = TIFFSeekFile(tif, dircount16 * 20, SEEK_CUR);
1996
else
1997
(void)TIFFSeekFile(tif, dircount16 * 20, SEEK_CUR);
1998
if (!ReadOK(tif, nextdiroff, sizeof(uint64_t)))
1999
{
2000
TIFFErrorExtR(tif, module, "%s: Error fetching directory link",
2001
tif->tif_name);
2002
return (0);
2003
}
2004
if (tif->tif_flags & TIFF_SWAB)
2005
TIFFSwabLong8(nextdiroff);
2006
}
2007
}
2008
if (*nextdiroff != 0)
2009
{
2010
(*nextdirnum)++;
2011
/* Check next directory for IFD looping and if so, set it as last
2012
* directory. */
2013
if (!_TIFFCheckDirNumberAndOffset(tif, *nextdirnum, *nextdiroff))
2014
{
2015
TIFFWarningExtR(
2016
tif, module,
2017
"the next directory %u at offset 0x%" PRIx64 " (%" PRIu64
2018
") might be an IFD loop. Treating directory %d as "
2019
"last directory",
2020
*nextdirnum, *nextdiroff, *nextdiroff, (int)(*nextdirnum) - 1);
2021
*nextdiroff = 0;
2022
(*nextdirnum)--;
2023
}
2024
}
2025
return (1);
2026
}
2027
2028
/*
2029
* Count the number of directories in a file.
2030
*/
2031
tdir_t TIFFNumberOfDirectories(TIFF *tif)
2032
{
2033
uint64_t nextdiroff;
2034
tdir_t nextdirnum;
2035
tdir_t n;
2036
if (!(tif->tif_flags & TIFF_BIGTIFF))
2037
nextdiroff = tif->tif_header.classic.tiff_diroff;
2038
else
2039
nextdiroff = tif->tif_header.big.tiff_diroff;
2040
nextdirnum = 0;
2041
n = 0;
2042
while (nextdiroff != 0 &&
2043
TIFFAdvanceDirectory(tif, &nextdiroff, NULL, &nextdirnum))
2044
{
2045
++n;
2046
}
2047
/* Update number of main-IFDs in file. */
2048
tif->tif_curdircount = n;
2049
return (n);
2050
}
2051
2052
/*
2053
* Set the n-th directory as the current directory.
2054
* NB: Directories are numbered starting at 0.
2055
*/
2056
int TIFFSetDirectory(TIFF *tif, tdir_t dirn)
2057
{
2058
uint64_t nextdiroff;
2059
tdir_t nextdirnum = 0;
2060
tdir_t n;
2061
2062
if (tif->tif_setdirectory_force_absolute)
2063
{
2064
/* tif_setdirectory_force_absolute=1 will force parsing the main IFD
2065
* chain from the beginning, thus IFD directory list needs to be cleared
2066
* from possible SubIFD offsets.
2067
*/
2068
_TIFFCleanupIFDOffsetAndNumberMaps(tif); /* invalidate IFD loop lists */
2069
}
2070
2071
/* Even faster path, if offset is available within IFD loop hash list. */
2072
if (!tif->tif_setdirectory_force_absolute &&
2073
_TIFFGetOffsetFromDirNumber(tif, dirn, &nextdiroff))
2074
{
2075
/* Set parameters for following TIFFReadDirectory() below. */
2076
tif->tif_nextdiroff = nextdiroff;
2077
tif->tif_curdir = dirn;
2078
/* Reset to relative stepping */
2079
tif->tif_setdirectory_force_absolute = FALSE;
2080
}
2081
else
2082
{
2083
2084
/* Fast path when we just advance relative to the current directory:
2085
* start at the current dir offset and continue to seek from there.
2086
* Check special cases when relative is not allowed:
2087
* - jump back from SubIFD or custom directory
2088
* - right after TIFFWriteDirectory() jump back to that directory
2089
* using TIFFSetDirectory() */
2090
const int relative = (dirn >= tif->tif_curdir) &&
2091
(tif->tif_diroff != 0) &&
2092
!tif->tif_setdirectory_force_absolute;
2093
2094
if (relative)
2095
{
2096
nextdiroff = tif->tif_diroff;
2097
dirn -= tif->tif_curdir;
2098
nextdirnum = tif->tif_curdir;
2099
}
2100
else if (!(tif->tif_flags & TIFF_BIGTIFF))
2101
nextdiroff = tif->tif_header.classic.tiff_diroff;
2102
else
2103
nextdiroff = tif->tif_header.big.tiff_diroff;
2104
2105
/* Reset to relative stepping */
2106
tif->tif_setdirectory_force_absolute = FALSE;
2107
2108
for (n = dirn; n > 0 && nextdiroff != 0; n--)
2109
if (!TIFFAdvanceDirectory(tif, &nextdiroff, NULL, &nextdirnum))
2110
return (0);
2111
/* If the n-th directory could not be reached (does not exist),
2112
* return here without touching anything further. */
2113
if (nextdiroff == 0 || n > 0)
2114
return (0);
2115
2116
tif->tif_nextdiroff = nextdiroff;
2117
2118
/* Set curdir to the actual directory index. */
2119
if (relative)
2120
tif->tif_curdir += dirn - n;
2121
else
2122
tif->tif_curdir = dirn - n;
2123
}
2124
2125
/* The -1 decrement is because TIFFReadDirectory will increment
2126
* tif_curdir after successfully reading the directory. */
2127
if (tif->tif_curdir == 0)
2128
tif->tif_curdir = TIFF_NON_EXISTENT_DIR_NUMBER;
2129
else
2130
tif->tif_curdir--;
2131
2132
tdir_t curdir = tif->tif_curdir;
2133
2134
int retval = TIFFReadDirectory(tif);
2135
2136
if (!retval && tif->tif_curdir == curdir)
2137
{
2138
/* If tif_curdir has not be incremented, TIFFFetchDirectory() in
2139
* TIFFReadDirectory() has failed and tif_curdir shall be set
2140
* specifically. */
2141
tif->tif_curdir = TIFF_NON_EXISTENT_DIR_NUMBER;
2142
}
2143
return (retval);
2144
}
2145
2146
/*
2147
* Set the current directory to be the directory
2148
* located at the specified file offset. This interface
2149
* is used mainly to access directories linked with
2150
* the SubIFD tag (e.g. thumbnail images).
2151
*/
2152
int TIFFSetSubDirectory(TIFF *tif, uint64_t diroff)
2153
{
2154
/* Match nextdiroff and curdir for consistent IFD-loop checking.
2155
* Only with TIFFSetSubDirectory() the IFD list can be corrupted with
2156
* invalid offsets within the main IFD tree. In the case of several subIFDs
2157
* of a main image, there are two possibilities that are not even mutually
2158
* exclusive. a.) The subIFD tag contains an array with all offsets of the
2159
* subIFDs. b.) The SubIFDs are concatenated with their NextIFD parameters.
2160
* (refer to
2161
* https://www.awaresystems.be/imaging/tiff/specification/TIFFPM6.pdf.)
2162
*/
2163
int retval;
2164
uint32_t curdir = 0;
2165
int8_t probablySubIFD = 0;
2166
if (diroff == 0)
2167
{
2168
/* Special case to set tif_diroff=0, which is done in
2169
* TIFFReadDirectory() below to indicate that the currently read IFD is
2170
* treated as a new, fresh IFD. */
2171
tif->tif_curdir = TIFF_NON_EXISTENT_DIR_NUMBER;
2172
tif->tif_dir.td_iswrittentofile = FALSE;
2173
}
2174
else
2175
{
2176
if (!_TIFFGetDirNumberFromOffset(tif, diroff, &curdir))
2177
{
2178
/* Non-existing offsets might point to a SubIFD or invalid IFD.*/
2179
probablySubIFD = 1;
2180
}
2181
/* -1 because TIFFReadDirectory() will increment tif_curdir. */
2182
if (curdir >= 1)
2183
tif->tif_curdir = curdir - 1;
2184
else
2185
tif->tif_curdir = TIFF_NON_EXISTENT_DIR_NUMBER;
2186
}
2187
curdir = tif->tif_curdir;
2188
2189
tif->tif_nextdiroff = diroff;
2190
retval = TIFFReadDirectory(tif);
2191
2192
/* tif_curdir is incremented in TIFFReadDirectory(), but if it has not been
2193
* incremented, TIFFFetchDirectory() has failed there and tif_curdir shall
2194
* be set specifically. */
2195
if (!retval && diroff != 0 && tif->tif_curdir == curdir)
2196
{
2197
tif->tif_curdir = TIFF_NON_EXISTENT_DIR_NUMBER;
2198
}
2199
2200
if (probablySubIFD)
2201
{
2202
if (retval)
2203
{
2204
/* Reset IFD list to start new one for SubIFD chain and also start
2205
* SubIFD chain with tif_curdir=0 for IFD loop checking. */
2206
/* invalidate IFD loop lists */
2207
_TIFFCleanupIFDOffsetAndNumberMaps(tif);
2208
tif->tif_curdir = 0; /* first directory of new chain */
2209
/* add this offset to new IFD list */
2210
_TIFFCheckDirNumberAndOffset(tif, tif->tif_curdir, diroff);
2211
}
2212
/* To be able to return from SubIFD or custom-IFD to main-IFD */
2213
tif->tif_setdirectory_force_absolute = TRUE;
2214
}
2215
2216
return (retval);
2217
}
2218
2219
/*
2220
* Return file offset of the current directory.
2221
*/
2222
uint64_t TIFFCurrentDirOffset(TIFF *tif) { return (tif->tif_diroff); }
2223
2224
/*
2225
* Return an indication of whether or not we are
2226
* at the last directory in the file.
2227
*/
2228
int TIFFLastDirectory(TIFF *tif) { return (tif->tif_nextdiroff == 0); }
2229
2230
/*
2231
* Unlink the specified directory from the directory chain.
2232
* Note: First directory starts with number dirn=1.
2233
* This is different to TIFFSetDirectory() where the first directory starts with
2234
* zero.
2235
*/
2236
int TIFFUnlinkDirectory(TIFF *tif, tdir_t dirn)
2237
{
2238
static const char module[] = "TIFFUnlinkDirectory";
2239
uint64_t nextdir;
2240
tdir_t nextdirnum;
2241
uint64_t off;
2242
tdir_t n;
2243
2244
if (tif->tif_mode == O_RDONLY)
2245
{
2246
TIFFErrorExtR(tif, module,
2247
"Can not unlink directory in read-only file");
2248
return (0);
2249
}
2250
if (dirn == 0)
2251
{
2252
TIFFErrorExtR(tif, module,
2253
"For TIFFUnlinkDirectory() first directory starts with "
2254
"number 1 and not 0");
2255
return (0);
2256
}
2257
/*
2258
* Go to the directory before the one we want
2259
* to unlink and nab the offset of the link
2260
* field we'll need to patch.
2261
*/
2262
if (!(tif->tif_flags & TIFF_BIGTIFF))
2263
{
2264
nextdir = tif->tif_header.classic.tiff_diroff;
2265
off = 4;
2266
}
2267
else
2268
{
2269
nextdir = tif->tif_header.big.tiff_diroff;
2270
off = 8;
2271
}
2272
nextdirnum = 0; /* First directory is dirn=0 */
2273
2274
for (n = dirn - 1; n > 0; n--)
2275
{
2276
if (nextdir == 0)
2277
{
2278
TIFFErrorExtR(tif, module, "Directory %u does not exist", dirn);
2279
return (0);
2280
}
2281
if (!TIFFAdvanceDirectory(tif, &nextdir, &off, &nextdirnum))
2282
return (0);
2283
}
2284
/*
2285
* Advance to the directory to be unlinked and fetch
2286
* the offset of the directory that follows.
2287
*/
2288
if (!TIFFAdvanceDirectory(tif, &nextdir, NULL, &nextdirnum))
2289
return (0);
2290
/*
2291
* Go back and patch the link field of the preceding
2292
* directory to point to the offset of the directory
2293
* that follows.
2294
*/
2295
(void)TIFFSeekFile(tif, off, SEEK_SET);
2296
if (!(tif->tif_flags & TIFF_BIGTIFF))
2297
{
2298
uint32_t nextdir32;
2299
nextdir32 = (uint32_t)nextdir;
2300
assert((uint64_t)nextdir32 == nextdir);
2301
if (tif->tif_flags & TIFF_SWAB)
2302
TIFFSwabLong(&nextdir32);
2303
if (!WriteOK(tif, &nextdir32, sizeof(uint32_t)))
2304
{
2305
TIFFErrorExtR(tif, module, "Error writing directory link");
2306
return (0);
2307
}
2308
}
2309
else
2310
{
2311
/* Need local swap because nextdir has to be used unswapped below. */
2312
uint64_t nextdir64 = nextdir;
2313
if (tif->tif_flags & TIFF_SWAB)
2314
TIFFSwabLong8(&nextdir64);
2315
if (!WriteOK(tif, &nextdir64, sizeof(uint64_t)))
2316
{
2317
TIFFErrorExtR(tif, module, "Error writing directory link");
2318
return (0);
2319
}
2320
}
2321
2322
/* For dirn=1 (first directory) also update the libtiff internal
2323
* base offset variables. */
2324
if (dirn == 1)
2325
{
2326
if (!(tif->tif_flags & TIFF_BIGTIFF))
2327
tif->tif_header.classic.tiff_diroff = (uint32_t)nextdir;
2328
else
2329
tif->tif_header.big.tiff_diroff = nextdir;
2330
}
2331
2332
/*
2333
* Leave directory state setup safely. We don't have
2334
* facilities for doing inserting and removing directories,
2335
* so it's safest to just invalidate everything. This
2336
* means that the caller can only append to the directory
2337
* chain.
2338
*/
2339
(*tif->tif_cleanup)(tif);
2340
if ((tif->tif_flags & TIFF_MYBUFFER) && tif->tif_rawdata)
2341
{
2342
_TIFFfreeExt(tif, tif->tif_rawdata);
2343
tif->tif_rawdata = NULL;
2344
tif->tif_rawcc = 0;
2345
tif->tif_rawdataoff = 0;
2346
tif->tif_rawdataloaded = 0;
2347
}
2348
tif->tif_flags &= ~(TIFF_BEENWRITING | TIFF_BUFFERSETUP | TIFF_POSTENCODE |
2349
TIFF_BUF4WRITE);
2350
TIFFFreeDirectory(tif);
2351
TIFFDefaultDirectory(tif);
2352
tif->tif_diroff = 0; /* force link on next write */
2353
tif->tif_nextdiroff = 0; /* next write must be at end */
2354
tif->tif_lastdiroff = 0; /* will be updated on next link */
2355
tif->tif_curoff = 0;
2356
tif->tif_row = (uint32_t)-1;
2357
tif->tif_curstrip = (uint32_t)-1;
2358
tif->tif_curdir = TIFF_NON_EXISTENT_DIR_NUMBER;
2359
if (tif->tif_curdircount > 0)
2360
tif->tif_curdircount--;
2361
else
2362
tif->tif_curdircount = TIFF_NON_EXISTENT_DIR_NUMBER;
2363
_TIFFCleanupIFDOffsetAndNumberMaps(tif); /* invalidate IFD loop lists */
2364
return (1);
2365
}
2366
2367