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