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