1 /* Id */
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
setByteArray(void ** vpp,void * vp,size_t nmemb,size_t elem_size)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 tsize_t bytes = 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 }
_TIFFsetByteArray(void ** vpp,void * vp,uint32 n)56 void _TIFFsetByteArray(void** vpp, void* vp, uint32 n)
57 { setByteArray(vpp, vp, n, 1); }
_TIFFsetString(char ** cpp,char * cp)58 void _TIFFsetString(char** cpp, char* cp)
59 { setByteArray((void**) cpp, (void*) cp, strlen(cp)+1, 1); }
_TIFFsetNString(char ** cpp,char * cp,uint32 n)60 void _TIFFsetNString(char** cpp, char* cp, uint32 n)
61 { setByteArray((void**) cpp, (void*) cp, n, 1); }
_TIFFsetShortArray(uint16 ** wpp,uint16 * wp,uint32 n)62 void _TIFFsetShortArray(uint16** wpp, uint16* wp, uint32 n)
63 { setByteArray((void**) wpp, (void*) wp, n, sizeof (uint16)); }
_TIFFsetLongArray(uint32 ** lpp,uint32 * lp,uint32 n)64 void _TIFFsetLongArray(uint32** lpp, uint32* lp, uint32 n)
65 { setByteArray((void**) lpp, (void*) lp, n, sizeof (uint32)); }
_TIFFsetFloatArray(float ** fpp,float * fp,uint32 n)66 void _TIFFsetFloatArray(float** fpp, float* fp, uint32 n)
67 { setByteArray((void**) fpp, (void*) fp, n, sizeof (float)); }
_TIFFsetDoubleArray(double ** dpp,double * dp,uint32 n)68 void _TIFFsetDoubleArray(double** dpp, double* dp, uint32 n)
69 { setByteArray((void**) dpp, (void*) dp, n, sizeof (double)); }
70
71 /*
72 * Install extra samples information.
73 */
74 static int
setExtraSamples(TIFFDirectory * td,va_list ap,uint32 * v)75 setExtraSamples(TIFFDirectory* td, va_list ap, uint32* v)
76 {
77 uint16* va;
78 uint32 i;
79
80 *v = va_arg(ap, uint32);
81 if ((uint16) *v > td->td_samplesperpixel)
82 return (0);
83 va = va_arg(ap, uint16*);
84 if (*v > 0 && va == NULL) /* typically missing param */
85 return (0);
86 for (i = 0; i < *v; i++)
87 if (va[i] > EXTRASAMPLE_UNASSALPHA)
88 return (0);
89 td->td_extrasamples = (uint16) *v;
90 _TIFFsetShortArray(&td->td_sampleinfo, va, td->td_extrasamples);
91 return (1);
92 }
93
94 static uint32
checkInkNamesString(TIFF * tif,uint32 slen,const char * s)95 checkInkNamesString(TIFF* tif, uint32 slen, const char* s)
96 {
97 TIFFDirectory* td = &tif->tif_dir;
98 uint16 i = td->td_samplesperpixel;
99
100 if (slen > 0) {
101 const char* ep = s+slen;
102 const char* cp = s;
103 for (; i > 0; i--) {
104 for (; *cp != '\0'; cp++)
105 if (cp >= ep)
106 goto bad;
107 cp++; /* skip \0 */
108 }
109 return (cp-s);
110 }
111 bad:
112 TIFFErrorExt(tif->tif_clientdata, "TIFFSetField",
113 "%s: Invalid InkNames value; expecting %d names, found %d",
114 tif->tif_name,
115 td->td_samplesperpixel,
116 td->td_samplesperpixel-i);
117 return (0);
118 }
119
120 static int
_TIFFVSetField(TIFF * tif,ttag_t tag,va_list ap)121 _TIFFVSetField(TIFF* tif, ttag_t tag, va_list ap)
122 {
123 static const char module[] = "_TIFFVSetField";
124
125 TIFFDirectory* td = &tif->tif_dir;
126 int status = 1;
127 uint32 v32, i, v;
128 char* s;
129
130 switch (tag) {
131 case TIFFTAG_SUBFILETYPE:
132 td->td_subfiletype = va_arg(ap, uint32);
133 break;
134 case TIFFTAG_IMAGEWIDTH:
135 td->td_imagewidth = va_arg(ap, uint32);
136 break;
137 case TIFFTAG_IMAGELENGTH:
138 td->td_imagelength = va_arg(ap, uint32);
139 break;
140 case TIFFTAG_BITSPERSAMPLE:
141 td->td_bitspersample = (uint16) va_arg(ap, int);
142 /*
143 * If the data require post-decoding processing to byte-swap
144 * samples, set it up here. Note that since tags are required
145 * to be ordered, compression code can override this behaviour
146 * in the setup method if it wants to roll the post decoding
147 * work in with its normal work.
148 */
149 if (tif->tif_flags & TIFF_SWAB) {
150 if (td->td_bitspersample == 16)
151 tif->tif_postdecode = _TIFFSwab16BitData;
152 else if (td->td_bitspersample == 24)
153 tif->tif_postdecode = _TIFFSwab24BitData;
154 else if (td->td_bitspersample == 32)
155 tif->tif_postdecode = _TIFFSwab32BitData;
156 else if (td->td_bitspersample == 64)
157 tif->tif_postdecode = _TIFFSwab64BitData;
158 else if (td->td_bitspersample == 128) /* two 64's */
159 tif->tif_postdecode = _TIFFSwab64BitData;
160 }
161 break;
162 case TIFFTAG_COMPRESSION:
163 v = va_arg(ap, uint32) & 0xffff;
164 /*
165 * If we're changing the compression scheme, the notify the
166 * previous module so that it can cleanup any state it's
167 * setup.
168 */
169 if (TIFFFieldSet(tif, FIELD_COMPRESSION)) {
170 if (td->td_compression == v)
171 break;
172 (*tif->tif_cleanup)(tif);
173 tif->tif_flags &= ~TIFF_CODERSETUP;
174 }
175 /*
176 * Setup new compression routine state.
177 */
178 if( (status = TIFFSetCompressionScheme(tif, v)) != 0 )
179 td->td_compression = (uint16) v;
180 else
181 status = 0;
182 break;
183 case TIFFTAG_PHOTOMETRIC:
184 td->td_photometric = (uint16) va_arg(ap, int);
185 break;
186 case TIFFTAG_THRESHHOLDING:
187 td->td_threshholding = (uint16) va_arg(ap, int);
188 break;
189 case TIFFTAG_FILLORDER:
190 v = va_arg(ap, uint32);
191 if (v != FILLORDER_LSB2MSB && v != FILLORDER_MSB2LSB)
192 goto badvalue;
193 td->td_fillorder = (uint16) v;
194 break;
195 case TIFFTAG_ORIENTATION:
196 v = va_arg(ap, uint32);
197 if (v < ORIENTATION_TOPLEFT || ORIENTATION_LEFTBOT < v) {
198 TIFFWarningExt(tif->tif_clientdata, tif->tif_name,
199 "Bad value %lu for \"%s\" tag ignored",
200 v, _TIFFFieldWithTag(tif, tag)->field_name);
201 } else
202 td->td_orientation = (uint16) v;
203 break;
204 case TIFFTAG_SAMPLESPERPIXEL:
205 /* XXX should cross check -- e.g. if pallette, then 1 */
206 v = va_arg(ap, uint32);
207 if (v == 0)
208 goto badvalue;
209 td->td_samplesperpixel = (uint16) v;
210 break;
211 case TIFFTAG_ROWSPERSTRIP:
212 v32 = va_arg(ap, uint32);
213 if (v32 == 0)
214 goto badvalue32;
215 td->td_rowsperstrip = v32;
216 if (!TIFFFieldSet(tif, FIELD_TILEDIMENSIONS)) {
217 td->td_tilelength = v32;
218 td->td_tilewidth = td->td_imagewidth;
219 }
220 break;
221 case TIFFTAG_MINSAMPLEVALUE:
222 td->td_minsamplevalue = (uint16) va_arg(ap, int);
223 break;
224 case TIFFTAG_MAXSAMPLEVALUE:
225 td->td_maxsamplevalue = (uint16) va_arg(ap, int);
226 break;
227 case TIFFTAG_SMINSAMPLEVALUE:
228 td->td_sminsamplevalue = va_arg(ap, double);
229 break;
230 case TIFFTAG_SMAXSAMPLEVALUE:
231 td->td_smaxsamplevalue = va_arg(ap, double);
232 break;
233 case TIFFTAG_XRESOLUTION:
234 td->td_xresolution = (float) va_arg(ap, double);
235 break;
236 case TIFFTAG_YRESOLUTION:
237 td->td_yresolution = (float) va_arg(ap, double);
238 break;
239 case TIFFTAG_PLANARCONFIG:
240 v = va_arg(ap, uint32);
241 if (v != PLANARCONFIG_CONTIG && v != PLANARCONFIG_SEPARATE)
242 goto badvalue;
243 td->td_planarconfig = (uint16) v;
244 break;
245 case TIFFTAG_XPOSITION:
246 td->td_xposition = (float) va_arg(ap, double);
247 break;
248 case TIFFTAG_YPOSITION:
249 td->td_yposition = (float) va_arg(ap, double);
250 break;
251 case TIFFTAG_RESOLUTIONUNIT:
252 v = va_arg(ap, uint32);
253 if (v < RESUNIT_NONE || RESUNIT_CENTIMETER < v)
254 goto badvalue;
255 td->td_resolutionunit = (uint16) v;
256 break;
257 case TIFFTAG_PAGENUMBER:
258 td->td_pagenumber[0] = (uint16) va_arg(ap, int);
259 td->td_pagenumber[1] = (uint16) va_arg(ap, int);
260 break;
261 case TIFFTAG_HALFTONEHINTS:
262 td->td_halftonehints[0] = (uint16) va_arg(ap, int);
263 td->td_halftonehints[1] = (uint16) va_arg(ap, int);
264 break;
265 case TIFFTAG_COLORMAP:
266 v32 = (uint32)(1L<<td->td_bitspersample);
267 _TIFFsetShortArray(&td->td_colormap[0], va_arg(ap, uint16*), v32);
268 _TIFFsetShortArray(&td->td_colormap[1], va_arg(ap, uint16*), v32);
269 _TIFFsetShortArray(&td->td_colormap[2], va_arg(ap, uint16*), v32);
270 break;
271 case TIFFTAG_EXTRASAMPLES:
272 if (!setExtraSamples(td, ap, &v))
273 goto badvalue;
274 break;
275 case TIFFTAG_MATTEING:
276 td->td_extrasamples = (uint16) (va_arg(ap, int) != 0);
277 if (td->td_extrasamples) {
278 uint16 sv = EXTRASAMPLE_ASSOCALPHA;
279 _TIFFsetShortArray(&td->td_sampleinfo, &sv, 1);
280 }
281 break;
282 case TIFFTAG_TILEWIDTH:
283 v32 = va_arg(ap, uint32);
284 if (v32 % 16) {
285 if (tif->tif_mode != O_RDONLY)
286 goto badvalue32;
287 TIFFWarningExt(tif->tif_clientdata, tif->tif_name,
288 "Nonstandard tile width %d, convert file", v32);
289 }
290 td->td_tilewidth = v32;
291 tif->tif_flags |= TIFF_ISTILED;
292 break;
293 case TIFFTAG_TILELENGTH:
294 v32 = va_arg(ap, uint32);
295 if (v32 % 16) {
296 if (tif->tif_mode != O_RDONLY)
297 goto badvalue32;
298 TIFFWarningExt(tif->tif_clientdata, tif->tif_name,
299 "Nonstandard tile length %d, convert file", v32);
300 }
301 td->td_tilelength = v32;
302 tif->tif_flags |= TIFF_ISTILED;
303 break;
304 case TIFFTAG_TILEDEPTH:
305 v32 = va_arg(ap, uint32);
306 if (v32 == 0)
307 goto badvalue32;
308 td->td_tiledepth = v32;
309 break;
310 case TIFFTAG_DATATYPE:
311 v = va_arg(ap, uint32);
312 switch (v) {
313 case DATATYPE_VOID: v = SAMPLEFORMAT_VOID; break;
314 case DATATYPE_INT: v = SAMPLEFORMAT_INT; break;
315 case DATATYPE_UINT: v = SAMPLEFORMAT_UINT; break;
316 case DATATYPE_IEEEFP: v = SAMPLEFORMAT_IEEEFP;break;
317 default: goto badvalue;
318 }
319 td->td_sampleformat = (uint16) v;
320 break;
321 case TIFFTAG_SAMPLEFORMAT:
322 v = va_arg(ap, uint32);
323 if (v < SAMPLEFORMAT_UINT || SAMPLEFORMAT_COMPLEXIEEEFP < v)
324 goto badvalue;
325 td->td_sampleformat = (uint16) v;
326
327 /* Try to fix up the SWAB function for complex data. */
328 if( td->td_sampleformat == SAMPLEFORMAT_COMPLEXINT
329 && td->td_bitspersample == 32
330 && tif->tif_postdecode == _TIFFSwab32BitData )
331 tif->tif_postdecode = _TIFFSwab16BitData;
332 else if( (td->td_sampleformat == SAMPLEFORMAT_COMPLEXINT
333 || td->td_sampleformat == SAMPLEFORMAT_COMPLEXIEEEFP)
334 && td->td_bitspersample == 64
335 && tif->tif_postdecode == _TIFFSwab64BitData )
336 tif->tif_postdecode = _TIFFSwab32BitData;
337 break;
338 case TIFFTAG_IMAGEDEPTH:
339 td->td_imagedepth = va_arg(ap, uint32);
340 break;
341 case TIFFTAG_SUBIFD:
342 if ((tif->tif_flags & TIFF_INSUBIFD) == 0) {
343 td->td_nsubifd = (uint16) va_arg(ap, int);
344 _TIFFsetLongArray(&td->td_subifd, va_arg(ap, uint32*),
345 (long) td->td_nsubifd);
346 } else {
347 TIFFErrorExt(tif->tif_clientdata, module, "%s: Sorry, cannot nest SubIFDs",
348 tif->tif_name);
349 status = 0;
350 }
351 break;
352 case TIFFTAG_YCBCRPOSITIONING:
353 td->td_ycbcrpositioning = (uint16) va_arg(ap, int);
354 break;
355 case TIFFTAG_YCBCRSUBSAMPLING:
356 td->td_ycbcrsubsampling[0] = (uint16) va_arg(ap, int);
357 td->td_ycbcrsubsampling[1] = (uint16) va_arg(ap, int);
358 break;
359 case TIFFTAG_TRANSFERFUNCTION:
360 v = (td->td_samplesperpixel - td->td_extrasamples) > 1 ? 3 : 1;
361 for (i = 0; i < v; i++)
362 _TIFFsetShortArray(&td->td_transferfunction[i],
363 va_arg(ap, uint16*), 1L<<td->td_bitspersample);
364 break;
365 case TIFFTAG_INKNAMES:
366 v = va_arg(ap, uint32);
367 s = va_arg(ap, char*);
368 v = checkInkNamesString(tif, v, s);
369 status = v > 0;
370 if( v > 0 ) {
371 _TIFFsetNString(&td->td_inknames, s, v);
372 td->td_inknameslen = v;
373 }
374 break;
375 default: {
376 const TIFFFieldInfo* fip = _TIFFFindFieldInfo(tif, tag, TIFF_ANY);
377 TIFFTagValue *tv;
378 int tv_size, iCustom;
379
380 /*
381 * This can happen if multiple images are open with different
382 * codecs which have private tags. The global tag information
383 * table may then have tags that are valid for one file but not
384 * the other. If the client tries to set a tag that is not valid
385 * for the image's codec then we'll arrive here. This
386 * happens, for example, when tiffcp is used to convert between
387 * compression schemes and codec-specific tags are blindly copied.
388 */
389 if(fip == NULL || fip->field_bit != FIELD_CUSTOM) {
390 TIFFErrorExt(tif->tif_clientdata, module,
391 "%s: Invalid %stag \"%s\" (not supported by codec)",
392 tif->tif_name, isPseudoTag(tag) ? "pseudo-" : "",
393 _TIFFFieldWithTag(tif, tag)->field_name);
394 status = 0;
395 break;
396 }
397
398 /*
399 * Find the existing entry for this custom value.
400 */
401 tv = NULL;
402 for(iCustom = 0; iCustom < td->td_customValueCount; iCustom++) {
403 if(td->td_customValues[iCustom].info == fip) {
404 tv = td->td_customValues + iCustom;
405 if(tv->value != NULL)
406 {
407 _TIFFfree(tv->value);
408 tv->value = NULL;
409 }
410 break;
411 }
412 }
413
414 /*
415 * Grow the custom list if the entry was not found.
416 */
417 if(tv == NULL) {
418 TIFFTagValue *new_customValues;
419
420 td->td_customValueCount++;
421 new_customValues = (TIFFTagValue *)
422 _TIFFrealloc(td->td_customValues,
423 sizeof(TIFFTagValue) * td->td_customValueCount);
424 if (!new_customValues) {
425 TIFFErrorExt(tif->tif_clientdata, module,
426 "%s: Failed to allocate space for list of custom values",
427 tif->tif_name);
428 status = 0;
429 goto end;
430 }
431
432 td->td_customValues = new_customValues;
433
434 tv = td->td_customValues + (td->td_customValueCount-1);
435 tv->info = fip;
436 tv->value = NULL;
437 tv->count = 0;
438 }
439
440 /*
441 * Set custom value ... save a copy of the custom tag value.
442 */
443 tv_size = _TIFFDataSize(fip->field_type);
444 if (tv_size == 0) {
445 status = 0;
446 TIFFErrorExt(tif->tif_clientdata, module,
447 "%s: Bad field type %d for \"%s\"",
448 tif->tif_name, fip->field_type,
449 fip->field_name);
450 goto end;
451 }
452
453 if(fip->field_passcount) {
454 if (fip->field_writecount == TIFF_VARIABLE2)
455 tv->count = (uint32) va_arg(ap, uint32);
456 else
457 tv->count = (int) va_arg(ap, int);
458 } else if (fip->field_writecount == TIFF_VARIABLE
459 || fip->field_writecount == TIFF_VARIABLE2)
460 tv->count = 1;
461 else if (fip->field_writecount == TIFF_SPP)
462 tv->count = td->td_samplesperpixel;
463 else
464 tv->count = fip->field_writecount;
465
466
467 if (fip->field_type == TIFF_ASCII)
468 _TIFFsetString((char **)&tv->value, va_arg(ap, char *));
469 else {
470 tv->value = _TIFFmalloc(tv_size * tv->count);
471 if (!tv->value) {
472 status = 0;
473 goto end;
474 }
475
476 if ((fip->field_passcount
477 || fip->field_writecount == TIFF_VARIABLE
478 || fip->field_writecount == TIFF_VARIABLE2
479 || fip->field_writecount == TIFF_SPP
480 || tv->count > 1)
481 && fip->field_tag != TIFFTAG_PAGENUMBER
482 && fip->field_tag != TIFFTAG_HALFTONEHINTS
483 && fip->field_tag != TIFFTAG_YCBCRSUBSAMPLING
484 && fip->field_tag != TIFFTAG_DOTRANGE) {
485 _TIFFmemcpy(tv->value, va_arg(ap, void *),
486 tv->count * tv_size);
487 } else {
488 /*
489 * XXX: The following loop required to handle
490 * TIFFTAG_PAGENUMBER, TIFFTAG_HALFTONEHINTS,
491 * TIFFTAG_YCBCRSUBSAMPLING and TIFFTAG_DOTRANGE tags.
492 * These tags are actually arrays and should be passed as
493 * array pointers to TIFFSetField() function, but actually
494 * passed as a list of separate values. This behaviour
495 * must be changed in the future!
496 */
497 int i2;
498 char *val = (char *)tv->value;
499
500 for (i2 = 0; i2 < tv->count; i2++, val += tv_size) {
501 switch (fip->field_type) {
502 case TIFF_BYTE:
503 case TIFF_UNDEFINED:
504 {
505 uint8 v2 = (uint8)va_arg(ap, int);
506 _TIFFmemcpy(val, &v2, tv_size);
507 }
508 break;
509 case TIFF_SBYTE:
510 {
511 int8 v3 = (int8)va_arg(ap, int);
512 _TIFFmemcpy(val, &v3, tv_size);
513 }
514 break;
515 case TIFF_SHORT:
516 {
517 uint16 v4 = (uint16)va_arg(ap, int);
518 _TIFFmemcpy(val, &v4, tv_size);
519 }
520 break;
521 case TIFF_SSHORT:
522 {
523 int16 v5 = (int16)va_arg(ap, int);
524 _TIFFmemcpy(val, &v5, tv_size);
525 }
526 break;
527 case TIFF_LONG:
528 case TIFF_IFD:
529 {
530 uint32 v6 = va_arg(ap, uint32);
531 _TIFFmemcpy(val, &v6, tv_size);
532 }
533 break;
534 case TIFF_SLONG:
535 {
536 int32 v7 = va_arg(ap, int32);
537 _TIFFmemcpy(val, &v7, tv_size);
538 }
539 break;
540 case TIFF_RATIONAL:
541 case TIFF_SRATIONAL:
542 case TIFF_FLOAT:
543 {
544 float v8 = (float)va_arg(ap, double);
545 _TIFFmemcpy(val, &v8, tv_size);
546 }
547 break;
548 case TIFF_DOUBLE:
549 {
550 double v9 = va_arg(ap, double);
551 _TIFFmemcpy(val, &v9, tv_size);
552 }
553 break;
554 default:
555 _TIFFmemset(val, 0, tv_size);
556 status = 0;
557 break;
558 }
559 }
560 }
561 }
562 }
563 }
564 if (status) {
565 TIFFSetFieldBit(tif, _TIFFFieldWithTag(tif, tag)->field_bit);
566 tif->tif_flags |= TIFF_DIRTYDIRECT;
567 }
568
569 end:
570 va_end(ap);
571 return (status);
572 badvalue:
573 TIFFErrorExt(tif->tif_clientdata, module, "%s: Bad value %d for \"%s\"",
574 tif->tif_name, v, _TIFFFieldWithTag(tif, tag)->field_name);
575 va_end(ap);
576 return (0);
577 badvalue32:
578 TIFFErrorExt(tif->tif_clientdata, module, "%s: Bad value %ld for \"%s\"",
579 tif->tif_name, v32, _TIFFFieldWithTag(tif, tag)->field_name);
580 va_end(ap);
581 return (0);
582 }
583
584 /*
585 * Return 1/0 according to whether or not
586 * it is permissible to set the tag's value.
587 * Note that we allow ImageLength to be changed
588 * so that we can append and extend to images.
589 * Any other tag may not be altered once writing
590 * has commenced, unless its value has no effect
591 * on the format of the data that is written.
592 */
593 static int
OkToChangeTag(TIFF * tif,ttag_t tag)594 OkToChangeTag(TIFF* tif, ttag_t tag)
595 {
596 const TIFFFieldInfo* fip = _TIFFFindFieldInfo(tif, tag, TIFF_ANY);
597 if (!fip) { /* unknown tag */
598 TIFFErrorExt(tif->tif_clientdata, "TIFFSetField", "%s: Unknown %stag %u",
599 tif->tif_name, isPseudoTag(tag) ? "pseudo-" : "", tag);
600 return (0);
601 }
602 if (tag != TIFFTAG_IMAGELENGTH && (tif->tif_flags & TIFF_BEENWRITING) &&
603 !fip->field_oktochange) {
604 /*
605 * Consult info table to see if tag can be changed
606 * after we've started writing. We only allow changes
607 * to those tags that don't/shouldn't affect the
608 * compression and/or format of the data.
609 */
610 TIFFErrorExt(tif->tif_clientdata, "TIFFSetField",
611 "%s: Cannot modify tag \"%s\" while writing",
612 tif->tif_name, fip->field_name);
613 return (0);
614 }
615 return (1);
616 }
617
618 /*
619 * Record the value of a field in the
620 * internal directory structure. The
621 * field will be written to the file
622 * when/if the directory structure is
623 * updated.
624 */
625 int
TIFFSetField(TIFF * tif,ttag_t tag,...)626 TIFFSetField(TIFF* tif, ttag_t tag, ...)
627 {
628 va_list ap;
629 int status;
630
631 va_start(ap, tag);
632 status = TIFFVSetField(tif, tag, ap);
633 va_end(ap);
634 return (status);
635 }
636
637 /*
638 * Like TIFFSetField, but taking a varargs
639 * parameter list. This routine is useful
640 * for building higher-level interfaces on
641 * top of the library.
642 */
643 int
TIFFVSetField(TIFF * tif,ttag_t tag,va_list ap)644 TIFFVSetField(TIFF* tif, ttag_t tag, va_list ap)
645 {
646 return OkToChangeTag(tif, tag) ?
647 (*tif->tif_tagmethods.vsetfield)(tif, tag, ap) : 0;
648 }
649
650 static int
_TIFFVGetField(TIFF * tif,ttag_t tag,va_list ap)651 _TIFFVGetField(TIFF* tif, ttag_t tag, va_list ap)
652 {
653 TIFFDirectory* td = &tif->tif_dir;
654 int ret_val = 1;
655
656 switch (tag) {
657 case TIFFTAG_SUBFILETYPE:
658 *va_arg(ap, uint32*) = td->td_subfiletype;
659 break;
660 case TIFFTAG_IMAGEWIDTH:
661 *va_arg(ap, uint32*) = td->td_imagewidth;
662 break;
663 case TIFFTAG_IMAGELENGTH:
664 *va_arg(ap, uint32*) = td->td_imagelength;
665 break;
666 case TIFFTAG_BITSPERSAMPLE:
667 *va_arg(ap, uint16*) = td->td_bitspersample;
668 break;
669 case TIFFTAG_COMPRESSION:
670 *va_arg(ap, uint16*) = td->td_compression;
671 break;
672 case TIFFTAG_PHOTOMETRIC:
673 *va_arg(ap, uint16*) = td->td_photometric;
674 break;
675 case TIFFTAG_THRESHHOLDING:
676 *va_arg(ap, uint16*) = td->td_threshholding;
677 break;
678 case TIFFTAG_FILLORDER:
679 *va_arg(ap, uint16*) = td->td_fillorder;
680 break;
681 case TIFFTAG_ORIENTATION:
682 *va_arg(ap, uint16*) = td->td_orientation;
683 break;
684 case TIFFTAG_SAMPLESPERPIXEL:
685 *va_arg(ap, uint16*) = td->td_samplesperpixel;
686 break;
687 case TIFFTAG_ROWSPERSTRIP:
688 *va_arg(ap, uint32*) = td->td_rowsperstrip;
689 break;
690 case TIFFTAG_MINSAMPLEVALUE:
691 *va_arg(ap, uint16*) = td->td_minsamplevalue;
692 break;
693 case TIFFTAG_MAXSAMPLEVALUE:
694 *va_arg(ap, uint16*) = td->td_maxsamplevalue;
695 break;
696 case TIFFTAG_SMINSAMPLEVALUE:
697 *va_arg(ap, double*) = td->td_sminsamplevalue;
698 break;
699 case TIFFTAG_SMAXSAMPLEVALUE:
700 *va_arg(ap, double*) = td->td_smaxsamplevalue;
701 break;
702 case TIFFTAG_XRESOLUTION:
703 *va_arg(ap, float*) = td->td_xresolution;
704 break;
705 case TIFFTAG_YRESOLUTION:
706 *va_arg(ap, float*) = td->td_yresolution;
707 break;
708 case TIFFTAG_PLANARCONFIG:
709 *va_arg(ap, uint16*) = td->td_planarconfig;
710 break;
711 case TIFFTAG_XPOSITION:
712 *va_arg(ap, float*) = td->td_xposition;
713 break;
714 case TIFFTAG_YPOSITION:
715 *va_arg(ap, float*) = td->td_yposition;
716 break;
717 case TIFFTAG_RESOLUTIONUNIT:
718 *va_arg(ap, uint16*) = td->td_resolutionunit;
719 break;
720 case TIFFTAG_PAGENUMBER:
721 *va_arg(ap, uint16*) = td->td_pagenumber[0];
722 *va_arg(ap, uint16*) = td->td_pagenumber[1];
723 break;
724 case TIFFTAG_HALFTONEHINTS:
725 *va_arg(ap, uint16*) = td->td_halftonehints[0];
726 *va_arg(ap, uint16*) = td->td_halftonehints[1];
727 break;
728 case TIFFTAG_COLORMAP:
729 *va_arg(ap, uint16**) = td->td_colormap[0];
730 *va_arg(ap, uint16**) = td->td_colormap[1];
731 *va_arg(ap, uint16**) = td->td_colormap[2];
732 break;
733 case TIFFTAG_STRIPOFFSETS:
734 case TIFFTAG_TILEOFFSETS:
735 *va_arg(ap, uint32**) = td->td_stripoffset;
736 break;
737 case TIFFTAG_STRIPBYTECOUNTS:
738 case TIFFTAG_TILEBYTECOUNTS:
739 *va_arg(ap, uint32**) = td->td_stripbytecount;
740 break;
741 case TIFFTAG_MATTEING:
742 *va_arg(ap, uint16*) =
743 (td->td_extrasamples == 1 &&
744 td->td_sampleinfo[0] == EXTRASAMPLE_ASSOCALPHA);
745 break;
746 case TIFFTAG_EXTRASAMPLES:
747 *va_arg(ap, uint16*) = td->td_extrasamples;
748 *va_arg(ap, uint16**) = td->td_sampleinfo;
749 break;
750 case TIFFTAG_TILEWIDTH:
751 *va_arg(ap, uint32*) = td->td_tilewidth;
752 break;
753 case TIFFTAG_TILELENGTH:
754 *va_arg(ap, uint32*) = td->td_tilelength;
755 break;
756 case TIFFTAG_TILEDEPTH:
757 *va_arg(ap, uint32*) = td->td_tiledepth;
758 break;
759 case TIFFTAG_DATATYPE:
760 switch (td->td_sampleformat) {
761 case SAMPLEFORMAT_UINT:
762 *va_arg(ap, uint16*) = DATATYPE_UINT;
763 break;
764 case SAMPLEFORMAT_INT:
765 *va_arg(ap, uint16*) = DATATYPE_INT;
766 break;
767 case SAMPLEFORMAT_IEEEFP:
768 *va_arg(ap, uint16*) = DATATYPE_IEEEFP;
769 break;
770 case SAMPLEFORMAT_VOID:
771 *va_arg(ap, uint16*) = DATATYPE_VOID;
772 break;
773 }
774 break;
775 case TIFFTAG_SAMPLEFORMAT:
776 *va_arg(ap, uint16*) = td->td_sampleformat;
777 break;
778 case TIFFTAG_IMAGEDEPTH:
779 *va_arg(ap, uint32*) = td->td_imagedepth;
780 break;
781 case TIFFTAG_SUBIFD:
782 *va_arg(ap, uint16*) = td->td_nsubifd;
783 *va_arg(ap, uint32**) = td->td_subifd;
784 break;
785 case TIFFTAG_YCBCRPOSITIONING:
786 *va_arg(ap, uint16*) = td->td_ycbcrpositioning;
787 break;
788 case TIFFTAG_YCBCRSUBSAMPLING:
789 *va_arg(ap, uint16*) = td->td_ycbcrsubsampling[0];
790 *va_arg(ap, uint16*) = td->td_ycbcrsubsampling[1];
791 break;
792 case TIFFTAG_TRANSFERFUNCTION:
793 *va_arg(ap, uint16**) = td->td_transferfunction[0];
794 if (td->td_samplesperpixel - td->td_extrasamples > 1) {
795 *va_arg(ap, uint16**) = td->td_transferfunction[1];
796 *va_arg(ap, uint16**) = td->td_transferfunction[2];
797 }
798 break;
799 case TIFFTAG_INKNAMES:
800 *va_arg(ap, char**) = td->td_inknames;
801 break;
802 default:
803 {
804 const TIFFFieldInfo* fip = _TIFFFindFieldInfo(tif, tag, TIFF_ANY);
805 int i;
806
807 /*
808 * This can happen if multiple images are open with
809 * different codecs which have private tags. The
810 * global tag information table may then have tags
811 * that are valid for one file but not the other.
812 * If the client tries to get a tag that is not valid
813 * for the image's codec then we'll arrive here.
814 */
815 if( fip == NULL || fip->field_bit != FIELD_CUSTOM )
816 {
817 TIFFErrorExt(tif->tif_clientdata, "_TIFFVGetField",
818 "%s: Invalid %stag \"%s\" (not supported by codec)",
819 tif->tif_name, isPseudoTag(tag) ? "pseudo-" : "",
820 _TIFFFieldWithTag(tif, tag)->field_name);
821 ret_val = 0;
822 break;
823 }
824
825 /*
826 * Do we have a custom value?
827 */
828 ret_val = 0;
829 for (i = 0; i < td->td_customValueCount; i++) {
830 TIFFTagValue *tv = td->td_customValues + i;
831
832 if (tv->info->field_tag != tag)
833 continue;
834
835 if (fip->field_passcount) {
836 if (fip->field_readcount == TIFF_VARIABLE2)
837 *va_arg(ap, uint32*) = (uint32)tv->count;
838 else /* Assume TIFF_VARIABLE */
839 *va_arg(ap, uint16*) = (uint16)tv->count;
840 *va_arg(ap, void **) = tv->value;
841 ret_val = 1;
842 } else {
843 if ((fip->field_type == TIFF_ASCII
844 || fip->field_readcount == TIFF_VARIABLE
845 || fip->field_readcount == TIFF_VARIABLE2
846 || fip->field_readcount == TIFF_SPP
847 || tv->count > 1)
848 && fip->field_tag != TIFFTAG_PAGENUMBER
849 && fip->field_tag != TIFFTAG_HALFTONEHINTS
850 && fip->field_tag != TIFFTAG_YCBCRSUBSAMPLING
851 && fip->field_tag != TIFFTAG_DOTRANGE) {
852 *va_arg(ap, void **) = tv->value;
853 ret_val = 1;
854 } else {
855 int j;
856 char *val = (char *)tv->value;
857
858 for (j = 0; j < tv->count;
859 j++, val += _TIFFDataSize(tv->info->field_type)) {
860 switch (fip->field_type) {
861 case TIFF_BYTE:
862 case TIFF_UNDEFINED:
863 *va_arg(ap, uint8*) =
864 *(uint8 *)val;
865 ret_val = 1;
866 break;
867 case TIFF_SBYTE:
868 *va_arg(ap, int8*) =
869 *(int8 *)val;
870 ret_val = 1;
871 break;
872 case TIFF_SHORT:
873 *va_arg(ap, uint16*) =
874 *(uint16 *)val;
875 ret_val = 1;
876 break;
877 case TIFF_SSHORT:
878 *va_arg(ap, int16*) =
879 *(int16 *)val;
880 ret_val = 1;
881 break;
882 case TIFF_LONG:
883 case TIFF_IFD:
884 *va_arg(ap, uint32*) =
885 *(uint32 *)val;
886 ret_val = 1;
887 break;
888 case TIFF_SLONG:
889 *va_arg(ap, int32*) =
890 *(int32 *)val;
891 ret_val = 1;
892 break;
893 case TIFF_RATIONAL:
894 case TIFF_SRATIONAL:
895 case TIFF_FLOAT:
896 *va_arg(ap, float*) =
897 *(float *)val;
898 ret_val = 1;
899 break;
900 case TIFF_DOUBLE:
901 *va_arg(ap, double*) =
902 *(double *)val;
903 ret_val = 1;
904 break;
905 default:
906 ret_val = 0;
907 break;
908 }
909 }
910 }
911 }
912 break;
913 }
914 }
915 }
916 return(ret_val);
917 }
918
919 /*
920 * Return the value of a field in the
921 * internal directory structure.
922 */
923 int
TIFFGetField(TIFF * tif,ttag_t tag,...)924 TEXPORT TIFFGetField(TIFF* tif, ttag_t tag, ...)
925 {
926 int status;
927 va_list ap;
928
929 va_start(ap, tag);
930 status = TIFFVGetField(tif, tag, ap);
931 va_end(ap);
932 return (status);
933 }
934
935 /*
936 * Like TIFFGetField, but taking a varargs
937 * parameter list. This routine is useful
938 * for building higher-level interfaces on
939 * top of the library.
940 */
941 int
TIFFVGetField(TIFF * tif,ttag_t tag,va_list ap)942 TIFFVGetField(TIFF* tif, ttag_t tag, va_list ap)
943 {
944 const TIFFFieldInfo* fip = _TIFFFindFieldInfo(tif, tag, TIFF_ANY);
945 return (fip && (isPseudoTag(tag) || TIFFFieldSet(tif, fip->field_bit)) ?
946 (*tif->tif_tagmethods.vgetfield)(tif, tag, ap) : 0);
947 }
948
949 #define CleanupField(member) { \
950 if (td->member) { \
951 _TIFFfree(td->member); \
952 td->member = 0; \
953 } \
954 }
955
956 /*
957 * Release storage associated with a directory.
958 */
959 void
TIFFFreeDirectory(TIFF * tif)960 TIFFFreeDirectory(TIFF* tif)
961 {
962 TIFFDirectory *td = &tif->tif_dir;
963 int i;
964
965 _TIFFmemset(td->td_fieldsset, 0, FIELD_SETLONGS);
966 CleanupField(td_colormap[0]);
967 CleanupField(td_colormap[1]);
968 CleanupField(td_colormap[2]);
969 CleanupField(td_sampleinfo);
970 CleanupField(td_subifd);
971 CleanupField(td_inknames);
972 CleanupField(td_transferfunction[0]);
973 CleanupField(td_transferfunction[1]);
974 CleanupField(td_transferfunction[2]);
975 CleanupField(td_stripoffset);
976 CleanupField(td_stripbytecount);
977 TIFFClrFieldBit(tif, FIELD_YCBCRSUBSAMPLING);
978 TIFFClrFieldBit(tif, FIELD_YCBCRPOSITIONING);
979
980 /* Cleanup custom tag values */
981 for( i = 0; i < td->td_customValueCount; i++ ) {
982 if (td->td_customValues[i].value)
983 _TIFFfree(td->td_customValues[i].value);
984 }
985
986 td->td_customValueCount = 0;
987 CleanupField(td_customValues);
988 }
989 #undef CleanupField
990
991 /*
992 * Client Tag extension support (from Niles Ritter).
993 */
994 static TIFFExtendProc _TIFFextender = (TIFFExtendProc) NULL;
995
996 TIFFExtendProc
TIFFSetTagExtender(TIFFExtendProc extender)997 TIFFSetTagExtender(TIFFExtendProc extender)
998 {
999 TIFFExtendProc prev = _TIFFextender;
1000 _TIFFextender = extender;
1001 return (prev);
1002 }
1003
1004 /*
1005 * Setup for a new directory. Should we automatically call
1006 * TIFFWriteDirectory() if the current one is dirty?
1007 *
1008 * The newly created directory will not exist on the file till
1009 * TIFFWriteDirectory(), TIFFFlush() or TIFFClose() is called.
1010 */
1011 int
TIFFCreateDirectory(TIFF * tif)1012 TIFFCreateDirectory(TIFF* tif)
1013 {
1014 TIFFDefaultDirectory(tif);
1015 tif->tif_diroff = 0;
1016 tif->tif_nextdiroff = 0;
1017 tif->tif_curoff = 0;
1018 tif->tif_row = (uint32) -1;
1019 tif->tif_curstrip = (tstrip_t) -1;
1020
1021 return 0;
1022 }
1023
1024 /*
1025 * Setup a default directory structure.
1026 */
1027 int
TIFFDefaultDirectory(TIFF * tif)1028 TIFFDefaultDirectory(TIFF* tif)
1029 {
1030 register TIFFDirectory* td = &tif->tif_dir;
1031
1032 size_t tiffFieldInfoCount;
1033 const TIFFFieldInfo *tiffFieldInfo =
1034 _TIFFGetFieldInfo(&tiffFieldInfoCount);
1035 _TIFFSetupFieldInfo(tif, tiffFieldInfo, tiffFieldInfoCount);
1036
1037 _TIFFmemset(td, 0, sizeof (*td));
1038 td->td_fillorder = FILLORDER_MSB2LSB;
1039 td->td_bitspersample = 1;
1040 td->td_threshholding = THRESHHOLD_BILEVEL;
1041 td->td_orientation = ORIENTATION_TOPLEFT;
1042 td->td_samplesperpixel = 1;
1043 td->td_rowsperstrip = (uint32) -1;
1044 td->td_tilewidth = 0;
1045 td->td_tilelength = 0;
1046 td->td_tiledepth = 1;
1047 td->td_stripbytecountsorted = 1; /* Our own arrays always sorted. */
1048 td->td_resolutionunit = RESUNIT_INCH;
1049 td->td_sampleformat = SAMPLEFORMAT_UINT;
1050 td->td_imagedepth = 1;
1051 td->td_ycbcrsubsampling[0] = 2;
1052 td->td_ycbcrsubsampling[1] = 2;
1053 td->td_ycbcrpositioning = YCBCRPOSITION_CENTERED;
1054 tif->tif_postdecode = _TIFFNoPostDecode;
1055 tif->tif_foundfield = NULL;
1056 tif->tif_tagmethods.vsetfield = _TIFFVSetField;
1057 tif->tif_tagmethods.vgetfield = _TIFFVGetField;
1058 tif->tif_tagmethods.printdir = NULL;
1059 /*
1060 * Give client code a chance to install their own
1061 * tag extensions & methods, prior to compression overloads.
1062 */
1063 if (_TIFFextender)
1064 (*_TIFFextender)(tif);
1065 (void) TIFFSetField(tif, TIFFTAG_COMPRESSION, COMPRESSION_NONE);
1066 /*
1067 * NB: The directory is marked dirty as a result of setting
1068 * up the default compression scheme. However, this really
1069 * isn't correct -- we want TIFF_DIRTYDIRECT to be set only
1070 * if the user does something. We could just do the setup
1071 * by hand, but it seems better to use the normal mechanism
1072 * (i.e. TIFFSetField).
1073 */
1074 tif->tif_flags &= ~TIFF_DIRTYDIRECT;
1075
1076 /*
1077 * As per http://bugzilla.remotesensing.org/show_bug.cgi?id=19
1078 * we clear the ISTILED flag when setting up a new directory.
1079 * Should we also be clearing stuff like INSUBIFD?
1080 */
1081 tif->tif_flags &= ~TIFF_ISTILED;
1082
1083 return (1);
1084 }
1085
1086 static int
TIFFAdvanceDirectory(TIFF * tif,uint32 * nextdir,toff_t * off)1087 TIFFAdvanceDirectory(TIFF* tif, uint32* nextdir, toff_t* off)
1088 {
1089 static const char module[] = "TIFFAdvanceDirectory";
1090 uint16 dircount;
1091 if (isMapped(tif))
1092 {
1093 toff_t poff=*nextdir;
1094 if (poff+sizeof(uint16) > tif->tif_size)
1095 {
1096 TIFFErrorExt(tif->tif_clientdata, module, "%s: Error fetching directory count",
1097 tif->tif_name);
1098 return (0);
1099 }
1100 _TIFFmemcpy(&dircount, tif->tif_base+poff, sizeof (uint16));
1101 if (tif->tif_flags & TIFF_SWAB)
1102 TIFFSwabShort(&dircount);
1103 poff+=sizeof (uint16)+dircount*sizeof (TIFFDirEntry);
1104 if (off != NULL)
1105 *off = poff;
1106 if (((toff_t) (poff+sizeof (uint32))) > tif->tif_size)
1107 {
1108 TIFFErrorExt(tif->tif_clientdata, module, "%s: Error fetching directory link",
1109 tif->tif_name);
1110 return (0);
1111 }
1112 _TIFFmemcpy(nextdir, tif->tif_base+poff, sizeof (uint32));
1113 if (tif->tif_flags & TIFF_SWAB)
1114 TIFFSwabLong(nextdir);
1115 return (1);
1116 }
1117 else
1118 {
1119 if (!SeekOK(tif, *nextdir) ||
1120 !ReadOK(tif, &dircount, sizeof (uint16))) {
1121 TIFFErrorExt(tif->tif_clientdata, module, "%s: Error fetching directory count",
1122 tif->tif_name);
1123 return (0);
1124 }
1125 if (tif->tif_flags & TIFF_SWAB)
1126 TIFFSwabShort(&dircount);
1127 if (off != NULL)
1128 *off = TIFFSeekFile(tif,
1129 dircount*sizeof (TIFFDirEntry), SEEK_CUR);
1130 else
1131 (void) TIFFSeekFile(tif,
1132 dircount*sizeof (TIFFDirEntry), SEEK_CUR);
1133 if (!ReadOK(tif, nextdir, sizeof (uint32))) {
1134 TIFFErrorExt(tif->tif_clientdata, module, "%s: Error fetching directory link",
1135 tif->tif_name);
1136 return (0);
1137 }
1138 if (tif->tif_flags & TIFF_SWAB)
1139 TIFFSwabLong(nextdir);
1140 return (1);
1141 }
1142 }
1143
1144 /*
1145 * Count the number of directories in a file.
1146 */
1147 tdir_t
1148 TEXPORT
TIFFNumberOfDirectories(TIFF * tif)1149 TIFFNumberOfDirectories(TIFF* tif)
1150 {
1151 toff_t nextdir = tif->tif_header.tiff_diroff;
1152 tdir_t n = 0;
1153
1154 while (nextdir != 0 && TIFFAdvanceDirectory(tif, &nextdir, NULL))
1155 n++;
1156 return (n);
1157 }
1158
1159 /*
1160 * Set the n-th directory as the current directory.
1161 * NB: Directories are numbered starting at 0.
1162 */
1163 int
1164 TEXPORT
TIFFSetDirectory(TIFF * tif,tdir_t dirn)1165 TIFFSetDirectory(TIFF* tif, tdir_t dirn)
1166 {
1167 toff_t nextdir;
1168 tdir_t n;
1169
1170 nextdir = tif->tif_header.tiff_diroff;
1171 for (n = dirn; n > 0 && nextdir != 0; n--)
1172 if (!TIFFAdvanceDirectory(tif, &nextdir, NULL))
1173 return (0);
1174 tif->tif_nextdiroff = nextdir;
1175 /*
1176 * Set curdir to the actual directory index. The
1177 * -1 is because TIFFReadDirectory will increment
1178 * tif_curdir after successfully reading the directory.
1179 */
1180 tif->tif_curdir = (dirn - n) - 1;
1181 /*
1182 * Reset tif_dirnumber counter and start new list of seen directories.
1183 * We need this to prevent IFD loops.
1184 */
1185 tif->tif_dirnumber = 0;
1186 return (TIFFReadDirectory(tif));
1187 }
1188
1189 /*
1190 * Set the current directory to be the directory
1191 * located at the specified file offset. This interface
1192 * is used mainly to access directories linked with
1193 * the SubIFD tag (e.g. thumbnail images).
1194 */
1195 int
TIFFSetSubDirectory(TIFF * tif,uint32 diroff)1196 TIFFSetSubDirectory(TIFF* tif, uint32 diroff)
1197 {
1198 tif->tif_nextdiroff = diroff;
1199 /*
1200 * Reset tif_dirnumber counter and start new list of seen directories.
1201 * We need this to prevent IFD loops.
1202 */
1203 tif->tif_dirnumber = 0;
1204 return (TIFFReadDirectory(tif));
1205 }
1206
1207 /*
1208 * Return file offset of the current directory.
1209 */
1210 uint32
TIFFCurrentDirOffset(TIFF * tif)1211 TIFFCurrentDirOffset(TIFF* tif)
1212 {
1213 return (tif->tif_diroff);
1214 }
1215
1216 /*
1217 * Return an indication of whether or not we are
1218 * at the last directory in the file.
1219 */
1220 int
TIFFLastDirectory(TIFF * tif)1221 TIFFLastDirectory(TIFF* tif)
1222 {
1223 return (tif->tif_nextdiroff == 0);
1224 }
1225
1226 /*
1227 * Unlink the specified directory from the directory chain.
1228 */
1229 int
TIFFUnlinkDirectory(TIFF * tif,tdir_t dirn)1230 TIFFUnlinkDirectory(TIFF* tif, tdir_t dirn)
1231 {
1232 static const char module[] = "TIFFUnlinkDirectory";
1233 toff_t nextdir;
1234 toff_t off;
1235 tdir_t n;
1236
1237 if (tif->tif_mode == O_RDONLY) {
1238 TIFFErrorExt(tif->tif_clientdata, module,
1239 "Can not unlink directory in read-only file");
1240 return (0);
1241 }
1242 /*
1243 * Go to the directory before the one we want
1244 * to unlink and nab the offset of the link
1245 * field we'll need to patch.
1246 */
1247 nextdir = tif->tif_header.tiff_diroff;
1248 off = sizeof (uint16) + sizeof (uint16);
1249 for (n = dirn-1; n > 0; n--) {
1250 if (nextdir == 0) {
1251 TIFFErrorExt(tif->tif_clientdata, module, "Directory %d does not exist", dirn);
1252 return (0);
1253 }
1254 if (!TIFFAdvanceDirectory(tif, &nextdir, &off))
1255 return (0);
1256 }
1257 /*
1258 * Advance to the directory to be unlinked and fetch
1259 * the offset of the directory that follows.
1260 */
1261 if (!TIFFAdvanceDirectory(tif, &nextdir, NULL))
1262 return (0);
1263 /*
1264 * Go back and patch the link field of the preceding
1265 * directory to point to the offset of the directory
1266 * that follows.
1267 */
1268 (void) TIFFSeekFile(tif, off, SEEK_SET);
1269 if (tif->tif_flags & TIFF_SWAB)
1270 TIFFSwabLong(&nextdir);
1271 if (!WriteOK(tif, &nextdir, sizeof (uint32))) {
1272 TIFFErrorExt(tif->tif_clientdata, module, "Error writing directory link");
1273 return (0);
1274 }
1275 /*
1276 * Leave directory state setup safely. We don't have
1277 * facilities for doing inserting and removing directories,
1278 * so it's safest to just invalidate everything. This
1279 * means that the caller can only append to the directory
1280 * chain.
1281 */
1282 (*tif->tif_cleanup)(tif);
1283 if ((tif->tif_flags & TIFF_MYBUFFER) && tif->tif_rawdata) {
1284 _TIFFfree(tif->tif_rawdata);
1285 tif->tif_rawdata = NULL;
1286 tif->tif_rawcc = 0;
1287 }
1288 tif->tif_flags &= ~(TIFF_BEENWRITING|TIFF_BUFFERSETUP|TIFF_POSTENCODE);
1289 TIFFFreeDirectory(tif);
1290 TIFFDefaultDirectory(tif);
1291 tif->tif_diroff = 0; /* force link on next write */
1292 tif->tif_nextdiroff = 0; /* next write must be at end */
1293 tif->tif_curoff = 0;
1294 tif->tif_row = (uint32) -1;
1295 tif->tif_curstrip = (tstrip_t) -1;
1296 return (1);
1297 }
1298
1299 /* [BFC]
1300 *
1301 * Author: Bruce Cameron <cameron@petris.com>
1302 *
1303 * Set a table of tags that are to be replaced during directory process by the
1304 * 'IGNORE' state - or return TRUE/FALSE for the requested tag such that
1305 * 'ReadDirectory' can use the stored information.
1306 *
1307 * FIXME: this is never used properly. Should be removed in the future.
1308 */
1309 int
TIFFReassignTagToIgnore(enum TIFFIgnoreSense task,int TIFFtagID)1310 TIFFReassignTagToIgnore (enum TIFFIgnoreSense task, int TIFFtagID)
1311 {
1312 static int TIFFignoretags [FIELD_LAST];
1313 static int tagcount = 0 ;
1314 int i; /* Loop index */
1315 int j; /* Loop index */
1316
1317 switch (task)
1318 {
1319 case TIS_STORE:
1320 if ( tagcount < (FIELD_LAST - 1) )
1321 {
1322 for ( j = 0 ; j < tagcount ; ++j )
1323 { /* Do not add duplicate tag */
1324 if ( TIFFignoretags [j] == TIFFtagID )
1325 return (TRUE) ;
1326 }
1327 TIFFignoretags [tagcount++] = TIFFtagID ;
1328 return (TRUE) ;
1329 }
1330 break ;
1331
1332 case TIS_EXTRACT:
1333 for ( i = 0 ; i < tagcount ; ++i )
1334 {
1335 if ( TIFFignoretags [i] == TIFFtagID )
1336 return (TRUE) ;
1337 }
1338 break;
1339
1340 case TIS_EMPTY:
1341 tagcount = 0 ; /* Clear the list */
1342 return (TRUE) ;
1343
1344 default:
1345 break;
1346 }
1347
1348 return (FALSE);
1349 }
1350
1351 /* vim: set ts=8 sts=8 sw=8 noet: */
1352