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