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