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