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