Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(954)

Side by Side Diff: third_party/tiff_v403/tif_dir.c

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

Powered by Google App Engine
This is Rietveld 408576698