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