1 | /* $Header: /afs/dev.mit.edu/source/repository/third/tiff/libtiff/tif_dir.c,v 1.1.1.1 2002-12-26 02:37:18 ghudson Exp $ */ |
---|
2 | |
---|
3 | /* |
---|
4 | * Copyright (c) 1988-1997 Sam Leffler |
---|
5 | * Copyright (c) 1991-1997 Silicon Graphics, Inc. |
---|
6 | * |
---|
7 | * Permission to use, copy, modify, distribute, and sell this software and |
---|
8 | * its documentation for any purpose is hereby granted without fee, provided |
---|
9 | * that (i) the above copyright notices and this permission notice appear in |
---|
10 | * all copies of the software and related documentation, and (ii) the names of |
---|
11 | * Sam Leffler and Silicon Graphics may not be used in any advertising or |
---|
12 | * publicity relating to the software without the specific, prior written |
---|
13 | * permission of Sam Leffler and Silicon Graphics. |
---|
14 | * |
---|
15 | * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, |
---|
16 | * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY |
---|
17 | * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. |
---|
18 | * |
---|
19 | * IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR |
---|
20 | * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, |
---|
21 | * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, |
---|
22 | * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF |
---|
23 | * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE |
---|
24 | * OF THIS SOFTWARE. |
---|
25 | */ |
---|
26 | |
---|
27 | /* |
---|
28 | * TIFF Library. |
---|
29 | * |
---|
30 | * Directory Tag Get & Set Routines. |
---|
31 | * (and also some miscellaneous stuff) |
---|
32 | */ |
---|
33 | #include "tiffiop.h" |
---|
34 | |
---|
35 | /* |
---|
36 | * These are used in the backwards compatibility code... |
---|
37 | */ |
---|
38 | #define DATATYPE_VOID 0 /* !untyped data */ |
---|
39 | #define DATATYPE_INT 1 /* !signed integer data */ |
---|
40 | #define DATATYPE_UINT 2 /* !unsigned integer data */ |
---|
41 | #define DATATYPE_IEEEFP 3 /* !IEEE floating point data */ |
---|
42 | |
---|
43 | void |
---|
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 | } |
---|
51 | void _TIFFsetString(char** cpp, char* cp) |
---|
52 | { _TIFFsetByteArray((void**) cpp, (void*) cp, (long) (strlen(cp)+1)); } |
---|
53 | void _TIFFsetNString(char** cpp, char* cp, long n) |
---|
54 | { _TIFFsetByteArray((void**) cpp, (void*) cp, n); } |
---|
55 | void _TIFFsetShortArray(uint16** wpp, uint16* wp, long n) |
---|
56 | { _TIFFsetByteArray((void**) wpp, (void*) wp, n*sizeof (uint16)); } |
---|
57 | void _TIFFsetLongArray(uint32** lpp, uint32* lp, long n) |
---|
58 | { _TIFFsetByteArray((void**) lpp, (void*) lp, n*sizeof (uint32)); } |
---|
59 | void _TIFFsetFloatArray(float** fpp, float* fp, long n) |
---|
60 | { _TIFFsetByteArray((void**) fpp, (void*) fp, n*sizeof (float)); } |
---|
61 | void _TIFFsetDoubleArray(double** dpp, double* dp, long n) |
---|
62 | { _TIFFsetByteArray((void**) dpp, (void*) dp, n*sizeof (double)); } |
---|
63 | |
---|
64 | /* |
---|
65 | * Install extra samples information. |
---|
66 | */ |
---|
67 | static int |
---|
68 | setExtraSamples(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 |
---|
88 | static int |
---|
89 | checkInkNamesString(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 | } |
---|
105 | bad: |
---|
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 | |
---|
115 | static 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 | else |
---|
173 | status = 0; |
---|
174 | break; |
---|
175 | case TIFFTAG_PHOTOMETRIC: |
---|
176 | td->td_photometric = (uint16) va_arg(ap, int); |
---|
177 | break; |
---|
178 | case TIFFTAG_THRESHHOLDING: |
---|
179 | td->td_threshholding = (uint16) va_arg(ap, int); |
---|
180 | break; |
---|
181 | case TIFFTAG_FILLORDER: |
---|
182 | v = va_arg(ap, int); |
---|
183 | if (v != FILLORDER_LSB2MSB && v != FILLORDER_MSB2LSB) |
---|
184 | goto badvalue; |
---|
185 | td->td_fillorder = (uint16) v; |
---|
186 | break; |
---|
187 | case TIFFTAG_DOCUMENTNAME: |
---|
188 | _TIFFsetString(&td->td_documentname, va_arg(ap, char*)); |
---|
189 | break; |
---|
190 | case TIFFTAG_ARTIST: |
---|
191 | _TIFFsetString(&td->td_artist, va_arg(ap, char*)); |
---|
192 | break; |
---|
193 | case TIFFTAG_DATETIME: |
---|
194 | _TIFFsetString(&td->td_datetime, va_arg(ap, char*)); |
---|
195 | break; |
---|
196 | case TIFFTAG_HOSTCOMPUTER: |
---|
197 | _TIFFsetString(&td->td_hostcomputer, va_arg(ap, char*)); |
---|
198 | break; |
---|
199 | case TIFFTAG_IMAGEDESCRIPTION: |
---|
200 | _TIFFsetString(&td->td_imagedescription, va_arg(ap, char*)); |
---|
201 | break; |
---|
202 | case TIFFTAG_MAKE: |
---|
203 | _TIFFsetString(&td->td_make, va_arg(ap, char*)); |
---|
204 | break; |
---|
205 | case TIFFTAG_MODEL: |
---|
206 | _TIFFsetString(&td->td_model, va_arg(ap, char*)); |
---|
207 | break; |
---|
208 | case TIFFTAG_SOFTWARE: |
---|
209 | _TIFFsetString(&td->td_software, va_arg(ap, char*)); |
---|
210 | break; |
---|
211 | case TIFFTAG_COPYRIGHT: |
---|
212 | _TIFFsetString(&td->td_copyright, va_arg(ap, char*)); |
---|
213 | break; |
---|
214 | case TIFFTAG_ORIENTATION: |
---|
215 | v = va_arg(ap, int); |
---|
216 | if (v < ORIENTATION_TOPLEFT || ORIENTATION_LEFTBOT < v) { |
---|
217 | TIFFWarning(tif->tif_name, |
---|
218 | "Bad value %ld for \"%s\" tag ignored", |
---|
219 | v, _TIFFFieldWithTag(tif, tag)->field_name); |
---|
220 | } else |
---|
221 | td->td_orientation = (uint16) v; |
---|
222 | break; |
---|
223 | case TIFFTAG_SAMPLESPERPIXEL: |
---|
224 | /* XXX should cross check -- e.g. if pallette, then 1 */ |
---|
225 | v = va_arg(ap, int); |
---|
226 | if (v == 0) |
---|
227 | goto badvalue; |
---|
228 | td->td_samplesperpixel = (uint16) v; |
---|
229 | break; |
---|
230 | case TIFFTAG_ROWSPERSTRIP: |
---|
231 | v32 = va_arg(ap, uint32); |
---|
232 | if (v32 == 0) |
---|
233 | goto badvalue32; |
---|
234 | td->td_rowsperstrip = v32; |
---|
235 | if (!TIFFFieldSet(tif, FIELD_TILEDIMENSIONS)) { |
---|
236 | td->td_tilelength = v32; |
---|
237 | td->td_tilewidth = td->td_imagewidth; |
---|
238 | } |
---|
239 | break; |
---|
240 | case TIFFTAG_MINSAMPLEVALUE: |
---|
241 | td->td_minsamplevalue = (uint16) va_arg(ap, int); |
---|
242 | break; |
---|
243 | case TIFFTAG_MAXSAMPLEVALUE: |
---|
244 | td->td_maxsamplevalue = (uint16) va_arg(ap, int); |
---|
245 | break; |
---|
246 | case TIFFTAG_SMINSAMPLEVALUE: |
---|
247 | td->td_sminsamplevalue = (double) va_arg(ap, dblparam_t); |
---|
248 | break; |
---|
249 | case TIFFTAG_SMAXSAMPLEVALUE: |
---|
250 | td->td_smaxsamplevalue = (double) va_arg(ap, dblparam_t); |
---|
251 | break; |
---|
252 | case TIFFTAG_XRESOLUTION: |
---|
253 | td->td_xresolution = (float) va_arg(ap, dblparam_t); |
---|
254 | break; |
---|
255 | case TIFFTAG_YRESOLUTION: |
---|
256 | td->td_yresolution = (float) va_arg(ap, dblparam_t); |
---|
257 | break; |
---|
258 | case TIFFTAG_PLANARCONFIG: |
---|
259 | v = va_arg(ap, int); |
---|
260 | if (v != PLANARCONFIG_CONTIG && v != PLANARCONFIG_SEPARATE) |
---|
261 | goto badvalue; |
---|
262 | td->td_planarconfig = (uint16) v; |
---|
263 | break; |
---|
264 | case TIFFTAG_PAGENAME: |
---|
265 | _TIFFsetString(&td->td_pagename, va_arg(ap, char*)); |
---|
266 | break; |
---|
267 | case TIFFTAG_XPOSITION: |
---|
268 | td->td_xposition = (float) va_arg(ap, dblparam_t); |
---|
269 | break; |
---|
270 | case TIFFTAG_YPOSITION: |
---|
271 | td->td_yposition = (float) va_arg(ap, dblparam_t); |
---|
272 | break; |
---|
273 | case TIFFTAG_RESOLUTIONUNIT: |
---|
274 | v = va_arg(ap, int); |
---|
275 | if (v < RESUNIT_NONE || RESUNIT_CENTIMETER < v) |
---|
276 | goto badvalue; |
---|
277 | td->td_resolutionunit = (uint16) v; |
---|
278 | break; |
---|
279 | case TIFFTAG_PAGENUMBER: |
---|
280 | td->td_pagenumber[0] = (uint16) va_arg(ap, int); |
---|
281 | td->td_pagenumber[1] = (uint16) va_arg(ap, int); |
---|
282 | break; |
---|
283 | case TIFFTAG_HALFTONEHINTS: |
---|
284 | td->td_halftonehints[0] = (uint16) va_arg(ap, int); |
---|
285 | td->td_halftonehints[1] = (uint16) va_arg(ap, int); |
---|
286 | break; |
---|
287 | case TIFFTAG_COLORMAP: |
---|
288 | v32 = (uint32)(1L<<td->td_bitspersample); |
---|
289 | _TIFFsetShortArray(&td->td_colormap[0], va_arg(ap, uint16*), v32); |
---|
290 | _TIFFsetShortArray(&td->td_colormap[1], va_arg(ap, uint16*), v32); |
---|
291 | _TIFFsetShortArray(&td->td_colormap[2], va_arg(ap, uint16*), v32); |
---|
292 | break; |
---|
293 | case TIFFTAG_EXTRASAMPLES: |
---|
294 | if (!setExtraSamples(td, ap, &v)) |
---|
295 | goto badvalue; |
---|
296 | break; |
---|
297 | case TIFFTAG_MATTEING: |
---|
298 | td->td_extrasamples = (uint16) (va_arg(ap, int) != 0); |
---|
299 | if (td->td_extrasamples) { |
---|
300 | uint16 sv = EXTRASAMPLE_ASSOCALPHA; |
---|
301 | _TIFFsetShortArray(&td->td_sampleinfo, &sv, 1); |
---|
302 | } |
---|
303 | break; |
---|
304 | case TIFFTAG_TILEWIDTH: |
---|
305 | v32 = va_arg(ap, uint32); |
---|
306 | if (v32 % 16) { |
---|
307 | if (tif->tif_mode != O_RDONLY) |
---|
308 | goto badvalue32; |
---|
309 | TIFFWarning(tif->tif_name, |
---|
310 | "Nonstandard tile width %d, convert file", v32); |
---|
311 | } |
---|
312 | td->td_tilewidth = v32; |
---|
313 | tif->tif_flags |= TIFF_ISTILED; |
---|
314 | break; |
---|
315 | case TIFFTAG_TILELENGTH: |
---|
316 | v32 = va_arg(ap, uint32); |
---|
317 | if (v32 % 16) { |
---|
318 | if (tif->tif_mode != O_RDONLY) |
---|
319 | goto badvalue32; |
---|
320 | TIFFWarning(tif->tif_name, |
---|
321 | "Nonstandard tile length %d, convert file", v32); |
---|
322 | } |
---|
323 | td->td_tilelength = v32; |
---|
324 | tif->tif_flags |= TIFF_ISTILED; |
---|
325 | break; |
---|
326 | case TIFFTAG_TILEDEPTH: |
---|
327 | v32 = va_arg(ap, uint32); |
---|
328 | if (v32 == 0) |
---|
329 | goto badvalue32; |
---|
330 | td->td_tiledepth = v32; |
---|
331 | break; |
---|
332 | case TIFFTAG_DATATYPE: |
---|
333 | v = va_arg(ap, int); |
---|
334 | switch (v) { |
---|
335 | case DATATYPE_VOID: v = SAMPLEFORMAT_VOID; break; |
---|
336 | case DATATYPE_INT: v = SAMPLEFORMAT_INT; break; |
---|
337 | case DATATYPE_UINT: v = SAMPLEFORMAT_UINT; break; |
---|
338 | case DATATYPE_IEEEFP: v = SAMPLEFORMAT_IEEEFP;break; |
---|
339 | default: goto badvalue; |
---|
340 | } |
---|
341 | td->td_sampleformat = (uint16) v; |
---|
342 | break; |
---|
343 | case TIFFTAG_SAMPLEFORMAT: |
---|
344 | v = va_arg(ap, int); |
---|
345 | if (v < SAMPLEFORMAT_UINT || SAMPLEFORMAT_COMPLEXIEEEFP < v) |
---|
346 | goto badvalue; |
---|
347 | td->td_sampleformat = (uint16) v; |
---|
348 | break; |
---|
349 | case TIFFTAG_IMAGEDEPTH: |
---|
350 | td->td_imagedepth = va_arg(ap, uint32); |
---|
351 | break; |
---|
352 | case TIFFTAG_STONITS: |
---|
353 | d = va_arg(ap, dblparam_t); |
---|
354 | if (d <= 0.) |
---|
355 | goto badvaluedbl; |
---|
356 | td->td_stonits = d; |
---|
357 | break; |
---|
358 | |
---|
359 | /* Begin Pixar Tags */ |
---|
360 | case TIFFTAG_PIXAR_IMAGEFULLWIDTH: |
---|
361 | td->td_imagefullwidth = va_arg(ap, uint32); |
---|
362 | break; |
---|
363 | case TIFFTAG_PIXAR_IMAGEFULLLENGTH: |
---|
364 | td->td_imagefulllength = va_arg(ap, uint32); |
---|
365 | break; |
---|
366 | case TIFFTAG_PIXAR_TEXTUREFORMAT: |
---|
367 | _TIFFsetString(&td->td_textureformat, va_arg(ap, char*)); |
---|
368 | break; |
---|
369 | case TIFFTAG_PIXAR_WRAPMODES: |
---|
370 | _TIFFsetString(&td->td_wrapmodes, va_arg(ap, char*)); |
---|
371 | break; |
---|
372 | case TIFFTAG_PIXAR_FOVCOT: |
---|
373 | td->td_fovcot = (float) va_arg(ap, dblparam_t); |
---|
374 | break; |
---|
375 | case TIFFTAG_PIXAR_MATRIX_WORLDTOSCREEN: |
---|
376 | _TIFFsetFloatArray(&td->td_matrixWorldToScreen, |
---|
377 | va_arg(ap, float*), 16); |
---|
378 | break; |
---|
379 | case TIFFTAG_PIXAR_MATRIX_WORLDTOCAMERA: |
---|
380 | _TIFFsetFloatArray(&td->td_matrixWorldToCamera, |
---|
381 | va_arg(ap, float*), 16); |
---|
382 | break; |
---|
383 | /* End Pixar Tags */ |
---|
384 | |
---|
385 | #if SUBIFD_SUPPORT |
---|
386 | case TIFFTAG_SUBIFD: |
---|
387 | if ((tif->tif_flags & TIFF_INSUBIFD) == 0) { |
---|
388 | td->td_nsubifd = (uint16) va_arg(ap, int); |
---|
389 | _TIFFsetLongArray(&td->td_subifd, va_arg(ap, uint32*), |
---|
390 | (long) td->td_nsubifd); |
---|
391 | } else { |
---|
392 | TIFFError(tif->tif_name, "Sorry, cannot nest SubIFDs"); |
---|
393 | status = 0; |
---|
394 | } |
---|
395 | break; |
---|
396 | #endif |
---|
397 | #ifdef YCBCR_SUPPORT |
---|
398 | case TIFFTAG_YCBCRCOEFFICIENTS: |
---|
399 | _TIFFsetFloatArray(&td->td_ycbcrcoeffs, va_arg(ap, float*), 3); |
---|
400 | break; |
---|
401 | case TIFFTAG_YCBCRPOSITIONING: |
---|
402 | td->td_ycbcrpositioning = (uint16) va_arg(ap, int); |
---|
403 | break; |
---|
404 | case TIFFTAG_YCBCRSUBSAMPLING: |
---|
405 | td->td_ycbcrsubsampling[0] = (uint16) va_arg(ap, int); |
---|
406 | td->td_ycbcrsubsampling[1] = (uint16) va_arg(ap, int); |
---|
407 | break; |
---|
408 | #endif |
---|
409 | #ifdef COLORIMETRY_SUPPORT |
---|
410 | case TIFFTAG_WHITEPOINT: |
---|
411 | _TIFFsetFloatArray(&td->td_whitepoint, va_arg(ap, float*), 2); |
---|
412 | break; |
---|
413 | case TIFFTAG_PRIMARYCHROMATICITIES: |
---|
414 | _TIFFsetFloatArray(&td->td_primarychromas, va_arg(ap, float*), 6); |
---|
415 | break; |
---|
416 | case TIFFTAG_TRANSFERFUNCTION: |
---|
417 | v = (td->td_samplesperpixel - td->td_extrasamples) > 1 ? 3 : 1; |
---|
418 | for (i = 0; i < v; i++) |
---|
419 | _TIFFsetShortArray(&td->td_transferfunction[i], |
---|
420 | va_arg(ap, uint16*), 1L<<td->td_bitspersample); |
---|
421 | break; |
---|
422 | case TIFFTAG_REFERENCEBLACKWHITE: |
---|
423 | /* XXX should check for null range */ |
---|
424 | _TIFFsetFloatArray(&td->td_refblackwhite, va_arg(ap, float*), 6); |
---|
425 | break; |
---|
426 | #endif |
---|
427 | #ifdef CMYK_SUPPORT |
---|
428 | case TIFFTAG_INKSET: |
---|
429 | td->td_inkset = (uint16) va_arg(ap, int); |
---|
430 | break; |
---|
431 | case TIFFTAG_DOTRANGE: |
---|
432 | /* XXX should check for null range */ |
---|
433 | td->td_dotrange[0] = (uint16) va_arg(ap, int); |
---|
434 | td->td_dotrange[1] = (uint16) va_arg(ap, int); |
---|
435 | break; |
---|
436 | case TIFFTAG_INKNAMES: |
---|
437 | i = va_arg(ap, int); |
---|
438 | s = va_arg(ap, char*); |
---|
439 | i = checkInkNamesString(tif, i, s); |
---|
440 | status = i > 0; |
---|
441 | if( i > 0 ) { |
---|
442 | _TIFFsetNString(&td->td_inknames, s, i); |
---|
443 | td->td_inknameslen = i; |
---|
444 | } |
---|
445 | break; |
---|
446 | case TIFFTAG_NUMBEROFINKS: |
---|
447 | td->td_ninks = (uint16) va_arg(ap, int); |
---|
448 | break; |
---|
449 | case TIFFTAG_TARGETPRINTER: |
---|
450 | _TIFFsetString(&td->td_targetprinter, va_arg(ap, char*)); |
---|
451 | break; |
---|
452 | #endif |
---|
453 | #ifdef ICC_SUPPORT |
---|
454 | case TIFFTAG_ICCPROFILE: |
---|
455 | td->td_profileLength = (uint32) va_arg(ap, uint32); |
---|
456 | _TIFFsetByteArray(&td->td_profileData, va_arg(ap, void*), |
---|
457 | td->td_profileLength); |
---|
458 | break; |
---|
459 | #endif |
---|
460 | #ifdef PHOTOSHOP_SUPPORT |
---|
461 | case TIFFTAG_PHOTOSHOP: |
---|
462 | td->td_photoshopLength = (uint32) va_arg(ap, uint32); |
---|
463 | _TIFFsetByteArray (&td->td_photoshopData, va_arg(ap, void*), |
---|
464 | td->td_photoshopLength); |
---|
465 | break; |
---|
466 | #endif |
---|
467 | #ifdef IPTC_SUPPORT |
---|
468 | case TIFFTAG_RICHTIFFIPTC: |
---|
469 | td->td_richtiffiptcLength = (uint32) va_arg(ap, uint32); |
---|
470 | #ifdef PHOTOSHOP_SUPPORT |
---|
471 | _TIFFsetLongArray ((uint32**)&td->td_richtiffiptcData, va_arg(ap, uint32*), |
---|
472 | td->td_richtiffiptcLength); |
---|
473 | #else |
---|
474 | _TIFFsetByteArray (&td->td_photoshopData, va_arg(ap, void*), |
---|
475 | td->td_photoshopLength); |
---|
476 | #endif |
---|
477 | break; |
---|
478 | #endif |
---|
479 | default: |
---|
480 | /* |
---|
481 | * This can happen if multiple images are open with |
---|
482 | * different codecs which have private tags. The |
---|
483 | * global tag information table may then have tags |
---|
484 | * that are valid for one file but not the other. |
---|
485 | * If the client tries to set a tag that is not valid |
---|
486 | * for the image's codec then we'll arrive here. This |
---|
487 | * happens, for example, when tiffcp is used to convert |
---|
488 | * between compression schemes and codec-specific tags |
---|
489 | * are blindly copied. |
---|
490 | */ |
---|
491 | TIFFError("TIFFSetField", |
---|
492 | "%s: Invalid %stag \"%s\" (not supported by codec)", |
---|
493 | tif->tif_name, isPseudoTag(tag) ? "pseduo-" : "", |
---|
494 | _TIFFFieldWithTag(tif, tag)->field_name); |
---|
495 | status = 0; |
---|
496 | break; |
---|
497 | } |
---|
498 | if (status) { |
---|
499 | TIFFSetFieldBit(tif, _TIFFFieldWithTag(tif, tag)->field_bit); |
---|
500 | tif->tif_flags |= TIFF_DIRTYDIRECT; |
---|
501 | } |
---|
502 | va_end(ap); |
---|
503 | return (status); |
---|
504 | badvalue: |
---|
505 | TIFFError(tif->tif_name, "%d: Bad value for \"%s\"", v, |
---|
506 | _TIFFFieldWithTag(tif, tag)->field_name); |
---|
507 | va_end(ap); |
---|
508 | return (0); |
---|
509 | badvalue32: |
---|
510 | TIFFError(tif->tif_name, "%ld: Bad value for \"%s\"", v32, |
---|
511 | _TIFFFieldWithTag(tif, tag)->field_name); |
---|
512 | va_end(ap); |
---|
513 | return (0); |
---|
514 | badvaluedbl: |
---|
515 | TIFFError(tif->tif_name, "%f: Bad value for \"%s\"", d, |
---|
516 | _TIFFFieldWithTag(tif, tag)->field_name); |
---|
517 | va_end(ap); |
---|
518 | return (0); |
---|
519 | } |
---|
520 | |
---|
521 | /* |
---|
522 | * Return 1/0 according to whether or not |
---|
523 | * it is permissible to set the tag's value. |
---|
524 | * Note that we allow ImageLength to be changed |
---|
525 | * so that we can append and extend to images. |
---|
526 | * Any other tag may not be altered once writing |
---|
527 | * has commenced, unless its value has no effect |
---|
528 | * on the format of the data that is written. |
---|
529 | */ |
---|
530 | static int |
---|
531 | OkToChangeTag(TIFF* tif, ttag_t tag) |
---|
532 | { |
---|
533 | const TIFFFieldInfo* fip = _TIFFFindFieldInfo(tif, tag, TIFF_ANY); |
---|
534 | if (!fip) { /* unknown tag */ |
---|
535 | TIFFError("TIFFSetField", "%s: Unknown %stag %u", |
---|
536 | tif->tif_name, isPseudoTag(tag) ? "pseudo-" : "", tag); |
---|
537 | return (0); |
---|
538 | } |
---|
539 | if (tag != TIFFTAG_IMAGELENGTH && (tif->tif_flags & TIFF_BEENWRITING) && |
---|
540 | !fip->field_oktochange) { |
---|
541 | /* |
---|
542 | * Consult info table to see if tag can be changed |
---|
543 | * after we've started writing. We only allow changes |
---|
544 | * to those tags that don't/shouldn't affect the |
---|
545 | * compression and/or format of the data. |
---|
546 | */ |
---|
547 | TIFFError("TIFFSetField", |
---|
548 | "%s: Cannot modify tag \"%s\" while writing", |
---|
549 | tif->tif_name, fip->field_name); |
---|
550 | return (0); |
---|
551 | } |
---|
552 | return (1); |
---|
553 | } |
---|
554 | |
---|
555 | /* |
---|
556 | * Record the value of a field in the |
---|
557 | * internal directory structure. The |
---|
558 | * field will be written to the file |
---|
559 | * when/if the directory structure is |
---|
560 | * updated. |
---|
561 | */ |
---|
562 | int |
---|
563 | TIFFSetField(TIFF* tif, ttag_t tag, ...) |
---|
564 | { |
---|
565 | va_list ap; |
---|
566 | int status; |
---|
567 | |
---|
568 | va_start(ap, tag); |
---|
569 | status = TIFFVSetField(tif, tag, ap); |
---|
570 | va_end(ap); |
---|
571 | return (status); |
---|
572 | } |
---|
573 | |
---|
574 | /* |
---|
575 | * Like TIFFSetField, but taking a varargs |
---|
576 | * parameter list. This routine is useful |
---|
577 | * for building higher-level interfaces on |
---|
578 | * top of the library. |
---|
579 | */ |
---|
580 | int |
---|
581 | TIFFVSetField(TIFF* tif, ttag_t tag, va_list ap) |
---|
582 | { |
---|
583 | return OkToChangeTag(tif, tag) ? |
---|
584 | (*tif->tif_vsetfield)(tif, tag, ap) : 0; |
---|
585 | } |
---|
586 | |
---|
587 | static int |
---|
588 | _TIFFVGetField(TIFF* tif, ttag_t tag, va_list ap) |
---|
589 | { |
---|
590 | TIFFDirectory* td = &tif->tif_dir; |
---|
591 | |
---|
592 | switch (tag) { |
---|
593 | case TIFFTAG_SUBFILETYPE: |
---|
594 | *va_arg(ap, uint32*) = td->td_subfiletype; |
---|
595 | break; |
---|
596 | case TIFFTAG_IMAGEWIDTH: |
---|
597 | *va_arg(ap, uint32*) = td->td_imagewidth; |
---|
598 | break; |
---|
599 | case TIFFTAG_IMAGELENGTH: |
---|
600 | *va_arg(ap, uint32*) = td->td_imagelength; |
---|
601 | break; |
---|
602 | case TIFFTAG_BITSPERSAMPLE: |
---|
603 | *va_arg(ap, uint16*) = td->td_bitspersample; |
---|
604 | break; |
---|
605 | case TIFFTAG_COMPRESSION: |
---|
606 | *va_arg(ap, uint16*) = td->td_compression; |
---|
607 | break; |
---|
608 | case TIFFTAG_PHOTOMETRIC: |
---|
609 | *va_arg(ap, uint16*) = td->td_photometric; |
---|
610 | break; |
---|
611 | case TIFFTAG_THRESHHOLDING: |
---|
612 | *va_arg(ap, uint16*) = td->td_threshholding; |
---|
613 | break; |
---|
614 | case TIFFTAG_FILLORDER: |
---|
615 | *va_arg(ap, uint16*) = td->td_fillorder; |
---|
616 | break; |
---|
617 | case TIFFTAG_DOCUMENTNAME: |
---|
618 | *va_arg(ap, char**) = td->td_documentname; |
---|
619 | break; |
---|
620 | case TIFFTAG_ARTIST: |
---|
621 | *va_arg(ap, char**) = td->td_artist; |
---|
622 | break; |
---|
623 | case TIFFTAG_DATETIME: |
---|
624 | *va_arg(ap, char**) = td->td_datetime; |
---|
625 | break; |
---|
626 | case TIFFTAG_HOSTCOMPUTER: |
---|
627 | *va_arg(ap, char**) = td->td_hostcomputer; |
---|
628 | break; |
---|
629 | case TIFFTAG_IMAGEDESCRIPTION: |
---|
630 | *va_arg(ap, char**) = td->td_imagedescription; |
---|
631 | break; |
---|
632 | case TIFFTAG_MAKE: |
---|
633 | *va_arg(ap, char**) = td->td_make; |
---|
634 | break; |
---|
635 | case TIFFTAG_MODEL: |
---|
636 | *va_arg(ap, char**) = td->td_model; |
---|
637 | break; |
---|
638 | case TIFFTAG_SOFTWARE: |
---|
639 | *va_arg(ap, char**) = td->td_software; |
---|
640 | break; |
---|
641 | case TIFFTAG_COPYRIGHT: |
---|
642 | *va_arg(ap, char**) = td->td_copyright; |
---|
643 | break; |
---|
644 | case TIFFTAG_ORIENTATION: |
---|
645 | *va_arg(ap, uint16*) = td->td_orientation; |
---|
646 | break; |
---|
647 | case TIFFTAG_SAMPLESPERPIXEL: |
---|
648 | *va_arg(ap, uint16*) = td->td_samplesperpixel; |
---|
649 | break; |
---|
650 | case TIFFTAG_ROWSPERSTRIP: |
---|
651 | *va_arg(ap, uint32*) = td->td_rowsperstrip; |
---|
652 | break; |
---|
653 | case TIFFTAG_MINSAMPLEVALUE: |
---|
654 | *va_arg(ap, uint16*) = td->td_minsamplevalue; |
---|
655 | break; |
---|
656 | case TIFFTAG_MAXSAMPLEVALUE: |
---|
657 | *va_arg(ap, uint16*) = td->td_maxsamplevalue; |
---|
658 | break; |
---|
659 | case TIFFTAG_SMINSAMPLEVALUE: |
---|
660 | *va_arg(ap, double*) = td->td_sminsamplevalue; |
---|
661 | break; |
---|
662 | case TIFFTAG_SMAXSAMPLEVALUE: |
---|
663 | *va_arg(ap, double*) = td->td_smaxsamplevalue; |
---|
664 | break; |
---|
665 | case TIFFTAG_XRESOLUTION: |
---|
666 | *va_arg(ap, float*) = td->td_xresolution; |
---|
667 | break; |
---|
668 | case TIFFTAG_YRESOLUTION: |
---|
669 | *va_arg(ap, float*) = td->td_yresolution; |
---|
670 | break; |
---|
671 | case TIFFTAG_PLANARCONFIG: |
---|
672 | *va_arg(ap, uint16*) = td->td_planarconfig; |
---|
673 | break; |
---|
674 | case TIFFTAG_XPOSITION: |
---|
675 | *va_arg(ap, float*) = td->td_xposition; |
---|
676 | break; |
---|
677 | case TIFFTAG_YPOSITION: |
---|
678 | *va_arg(ap, float*) = td->td_yposition; |
---|
679 | break; |
---|
680 | case TIFFTAG_PAGENAME: |
---|
681 | *va_arg(ap, char**) = td->td_pagename; |
---|
682 | break; |
---|
683 | case TIFFTAG_RESOLUTIONUNIT: |
---|
684 | *va_arg(ap, uint16*) = td->td_resolutionunit; |
---|
685 | break; |
---|
686 | case TIFFTAG_PAGENUMBER: |
---|
687 | *va_arg(ap, uint16*) = td->td_pagenumber[0]; |
---|
688 | *va_arg(ap, uint16*) = td->td_pagenumber[1]; |
---|
689 | break; |
---|
690 | case TIFFTAG_HALFTONEHINTS: |
---|
691 | *va_arg(ap, uint16*) = td->td_halftonehints[0]; |
---|
692 | *va_arg(ap, uint16*) = td->td_halftonehints[1]; |
---|
693 | break; |
---|
694 | case TIFFTAG_COLORMAP: |
---|
695 | *va_arg(ap, uint16**) = td->td_colormap[0]; |
---|
696 | *va_arg(ap, uint16**) = td->td_colormap[1]; |
---|
697 | *va_arg(ap, uint16**) = td->td_colormap[2]; |
---|
698 | break; |
---|
699 | case TIFFTAG_STRIPOFFSETS: |
---|
700 | case TIFFTAG_TILEOFFSETS: |
---|
701 | *va_arg(ap, uint32**) = td->td_stripoffset; |
---|
702 | break; |
---|
703 | case TIFFTAG_STRIPBYTECOUNTS: |
---|
704 | case TIFFTAG_TILEBYTECOUNTS: |
---|
705 | *va_arg(ap, uint32**) = td->td_stripbytecount; |
---|
706 | break; |
---|
707 | case TIFFTAG_MATTEING: |
---|
708 | *va_arg(ap, uint16*) = |
---|
709 | (td->td_extrasamples == 1 && |
---|
710 | td->td_sampleinfo[0] == EXTRASAMPLE_ASSOCALPHA); |
---|
711 | break; |
---|
712 | case TIFFTAG_EXTRASAMPLES: |
---|
713 | *va_arg(ap, uint16*) = td->td_extrasamples; |
---|
714 | *va_arg(ap, uint16**) = td->td_sampleinfo; |
---|
715 | break; |
---|
716 | case TIFFTAG_TILEWIDTH: |
---|
717 | *va_arg(ap, uint32*) = td->td_tilewidth; |
---|
718 | break; |
---|
719 | case TIFFTAG_TILELENGTH: |
---|
720 | *va_arg(ap, uint32*) = td->td_tilelength; |
---|
721 | break; |
---|
722 | case TIFFTAG_TILEDEPTH: |
---|
723 | *va_arg(ap, uint32*) = td->td_tiledepth; |
---|
724 | break; |
---|
725 | case TIFFTAG_DATATYPE: |
---|
726 | switch (td->td_sampleformat) { |
---|
727 | case SAMPLEFORMAT_UINT: |
---|
728 | *va_arg(ap, uint16*) = DATATYPE_UINT; |
---|
729 | break; |
---|
730 | case SAMPLEFORMAT_INT: |
---|
731 | *va_arg(ap, uint16*) = DATATYPE_INT; |
---|
732 | break; |
---|
733 | case SAMPLEFORMAT_IEEEFP: |
---|
734 | *va_arg(ap, uint16*) = DATATYPE_IEEEFP; |
---|
735 | break; |
---|
736 | case SAMPLEFORMAT_VOID: |
---|
737 | *va_arg(ap, uint16*) = DATATYPE_VOID; |
---|
738 | break; |
---|
739 | } |
---|
740 | break; |
---|
741 | case TIFFTAG_SAMPLEFORMAT: |
---|
742 | *va_arg(ap, uint16*) = td->td_sampleformat; |
---|
743 | break; |
---|
744 | case TIFFTAG_IMAGEDEPTH: |
---|
745 | *va_arg(ap, uint32*) = td->td_imagedepth; |
---|
746 | break; |
---|
747 | case TIFFTAG_STONITS: |
---|
748 | *va_arg(ap, double*) = td->td_stonits; |
---|
749 | break; |
---|
750 | #if SUBIFD_SUPPORT |
---|
751 | case TIFFTAG_SUBIFD: |
---|
752 | *va_arg(ap, uint16*) = td->td_nsubifd; |
---|
753 | *va_arg(ap, uint32**) = td->td_subifd; |
---|
754 | break; |
---|
755 | #endif |
---|
756 | #ifdef YCBCR_SUPPORT |
---|
757 | case TIFFTAG_YCBCRCOEFFICIENTS: |
---|
758 | *va_arg(ap, float**) = td->td_ycbcrcoeffs; |
---|
759 | break; |
---|
760 | case TIFFTAG_YCBCRPOSITIONING: |
---|
761 | *va_arg(ap, uint16*) = td->td_ycbcrpositioning; |
---|
762 | break; |
---|
763 | case TIFFTAG_YCBCRSUBSAMPLING: |
---|
764 | *va_arg(ap, uint16*) = td->td_ycbcrsubsampling[0]; |
---|
765 | *va_arg(ap, uint16*) = td->td_ycbcrsubsampling[1]; |
---|
766 | break; |
---|
767 | #endif |
---|
768 | #ifdef COLORIMETRY_SUPPORT |
---|
769 | case TIFFTAG_WHITEPOINT: |
---|
770 | *va_arg(ap, float**) = td->td_whitepoint; |
---|
771 | break; |
---|
772 | case TIFFTAG_PRIMARYCHROMATICITIES: |
---|
773 | *va_arg(ap, float**) = td->td_primarychromas; |
---|
774 | break; |
---|
775 | case TIFFTAG_TRANSFERFUNCTION: |
---|
776 | *va_arg(ap, uint16**) = td->td_transferfunction[0]; |
---|
777 | if (td->td_samplesperpixel - td->td_extrasamples > 1) { |
---|
778 | *va_arg(ap, uint16**) = td->td_transferfunction[1]; |
---|
779 | *va_arg(ap, uint16**) = td->td_transferfunction[2]; |
---|
780 | } |
---|
781 | break; |
---|
782 | case TIFFTAG_REFERENCEBLACKWHITE: |
---|
783 | *va_arg(ap, float**) = td->td_refblackwhite; |
---|
784 | break; |
---|
785 | #endif |
---|
786 | #ifdef CMYK_SUPPORT |
---|
787 | case TIFFTAG_INKSET: |
---|
788 | *va_arg(ap, uint16*) = td->td_inkset; |
---|
789 | break; |
---|
790 | case TIFFTAG_DOTRANGE: |
---|
791 | *va_arg(ap, uint16*) = td->td_dotrange[0]; |
---|
792 | *va_arg(ap, uint16*) = td->td_dotrange[1]; |
---|
793 | break; |
---|
794 | case TIFFTAG_INKNAMES: |
---|
795 | *va_arg(ap, char**) = td->td_inknames; |
---|
796 | break; |
---|
797 | case TIFFTAG_NUMBEROFINKS: |
---|
798 | *va_arg(ap, uint16*) = td->td_ninks; |
---|
799 | break; |
---|
800 | case TIFFTAG_TARGETPRINTER: |
---|
801 | *va_arg(ap, char**) = td->td_targetprinter; |
---|
802 | break; |
---|
803 | #endif |
---|
804 | #ifdef ICC_SUPPORT |
---|
805 | case TIFFTAG_ICCPROFILE: |
---|
806 | *va_arg(ap, uint32*) = td->td_profileLength; |
---|
807 | *va_arg(ap, void**) = td->td_profileData; |
---|
808 | break; |
---|
809 | #endif |
---|
810 | #ifdef PHOTOSHOP_SUPPORT |
---|
811 | case TIFFTAG_PHOTOSHOP: |
---|
812 | *va_arg(ap, uint32*) = td->td_photoshopLength; |
---|
813 | *va_arg(ap, void**) = td->td_photoshopData; |
---|
814 | break; |
---|
815 | #endif |
---|
816 | #ifdef IPTC_SUPPORT |
---|
817 | case TIFFTAG_RICHTIFFIPTC: |
---|
818 | *va_arg(ap, uint32*) = td->td_richtiffiptcLength; |
---|
819 | *va_arg(ap, void**) = td->td_richtiffiptcData; |
---|
820 | break; |
---|
821 | #endif |
---|
822 | /* Begin Pixar Tags */ |
---|
823 | case TIFFTAG_PIXAR_IMAGEFULLWIDTH: |
---|
824 | *va_arg(ap, uint32*) = td->td_imagefullwidth; |
---|
825 | break; |
---|
826 | case TIFFTAG_PIXAR_IMAGEFULLLENGTH: |
---|
827 | *va_arg(ap, uint32*) = td->td_imagefulllength; |
---|
828 | break; |
---|
829 | case TIFFTAG_PIXAR_TEXTUREFORMAT: |
---|
830 | *va_arg(ap, char**) = td->td_textureformat; |
---|
831 | break; |
---|
832 | case TIFFTAG_PIXAR_WRAPMODES: |
---|
833 | *va_arg(ap, char**) = td->td_wrapmodes; |
---|
834 | break; |
---|
835 | case TIFFTAG_PIXAR_FOVCOT: |
---|
836 | *va_arg(ap, float*) = td->td_fovcot; |
---|
837 | break; |
---|
838 | case TIFFTAG_PIXAR_MATRIX_WORLDTOSCREEN: |
---|
839 | *va_arg(ap, float**) = td->td_matrixWorldToScreen; |
---|
840 | break; |
---|
841 | case TIFFTAG_PIXAR_MATRIX_WORLDTOCAMERA: |
---|
842 | *va_arg(ap, float**) = td->td_matrixWorldToCamera; |
---|
843 | break; |
---|
844 | /* End Pixar Tags */ |
---|
845 | |
---|
846 | default: |
---|
847 | /* |
---|
848 | * This can happen if multiple images are open with |
---|
849 | * different codecs which have private tags. The |
---|
850 | * global tag information table may then have tags |
---|
851 | * that are valid for one file but not the other. |
---|
852 | * If the client tries to get a tag that is not valid |
---|
853 | * for the image's codec then we'll arrive here. |
---|
854 | */ |
---|
855 | TIFFError("TIFFGetField", |
---|
856 | "%s: Invalid %stag \"%s\" (not supported by codec)", |
---|
857 | tif->tif_name, isPseudoTag(tag) ? "pseudo-" : "", |
---|
858 | _TIFFFieldWithTag(tif, tag)->field_name); |
---|
859 | break; |
---|
860 | } |
---|
861 | return (1); |
---|
862 | } |
---|
863 | |
---|
864 | /* |
---|
865 | * Return the value of a field in the |
---|
866 | * internal directory structure. |
---|
867 | */ |
---|
868 | int |
---|
869 | TIFFGetField(TIFF* tif, ttag_t tag, ...) |
---|
870 | { |
---|
871 | int status; |
---|
872 | va_list ap; |
---|
873 | |
---|
874 | va_start(ap, tag); |
---|
875 | status = TIFFVGetField(tif, tag, ap); |
---|
876 | va_end(ap); |
---|
877 | return (status); |
---|
878 | } |
---|
879 | |
---|
880 | /* |
---|
881 | * Like TIFFGetField, but taking a varargs |
---|
882 | * parameter list. This routine is useful |
---|
883 | * for building higher-level interfaces on |
---|
884 | * top of the library. |
---|
885 | */ |
---|
886 | int |
---|
887 | TIFFVGetField(TIFF* tif, ttag_t tag, va_list ap) |
---|
888 | { |
---|
889 | const TIFFFieldInfo* fip = _TIFFFindFieldInfo(tif, tag, TIFF_ANY); |
---|
890 | return (fip && (isPseudoTag(tag) || TIFFFieldSet(tif, fip->field_bit)) ? |
---|
891 | (*tif->tif_vgetfield)(tif, tag, ap) : 0); |
---|
892 | } |
---|
893 | |
---|
894 | #define CleanupField(member) { \ |
---|
895 | if (td->member) { \ |
---|
896 | _TIFFfree(td->member); \ |
---|
897 | td->member = 0; \ |
---|
898 | } \ |
---|
899 | } |
---|
900 | |
---|
901 | /* |
---|
902 | * Release storage associated with a directory. |
---|
903 | */ |
---|
904 | void |
---|
905 | TIFFFreeDirectory(TIFF* tif) |
---|
906 | { |
---|
907 | register TIFFDirectory *td = &tif->tif_dir; |
---|
908 | |
---|
909 | CleanupField(td_colormap[0]); |
---|
910 | CleanupField(td_colormap[1]); |
---|
911 | CleanupField(td_colormap[2]); |
---|
912 | CleanupField(td_documentname); |
---|
913 | CleanupField(td_artist); |
---|
914 | CleanupField(td_datetime); |
---|
915 | CleanupField(td_hostcomputer); |
---|
916 | CleanupField(td_imagedescription); |
---|
917 | CleanupField(td_make); |
---|
918 | CleanupField(td_model); |
---|
919 | CleanupField(td_software); |
---|
920 | CleanupField(td_copyright); |
---|
921 | CleanupField(td_pagename); |
---|
922 | CleanupField(td_sampleinfo); |
---|
923 | #if SUBIFD_SUPPORT |
---|
924 | CleanupField(td_subifd); |
---|
925 | #endif |
---|
926 | #ifdef YCBCR_SUPPORT |
---|
927 | CleanupField(td_ycbcrcoeffs); |
---|
928 | #endif |
---|
929 | #ifdef CMYK_SUPPORT |
---|
930 | CleanupField(td_inknames); |
---|
931 | CleanupField(td_targetprinter); |
---|
932 | #endif |
---|
933 | #ifdef COLORIMETRY_SUPPORT |
---|
934 | CleanupField(td_whitepoint); |
---|
935 | CleanupField(td_primarychromas); |
---|
936 | CleanupField(td_refblackwhite); |
---|
937 | CleanupField(td_transferfunction[0]); |
---|
938 | CleanupField(td_transferfunction[1]); |
---|
939 | CleanupField(td_transferfunction[2]); |
---|
940 | #endif |
---|
941 | #ifdef ICC_SUPPORT |
---|
942 | CleanupField(td_profileData); |
---|
943 | #endif |
---|
944 | #ifdef PHOTOSHOP_SUPPORT |
---|
945 | CleanupField(td_photoshopData); |
---|
946 | #endif |
---|
947 | #ifdef IPTC_SUPPORT |
---|
948 | CleanupField(td_richtiffiptcData); |
---|
949 | #endif |
---|
950 | CleanupField(td_stripoffset); |
---|
951 | CleanupField(td_stripbytecount); |
---|
952 | /* Begin Pixar Tags */ |
---|
953 | CleanupField(td_textureformat); |
---|
954 | CleanupField(td_wrapmodes); |
---|
955 | CleanupField(td_matrixWorldToScreen); |
---|
956 | CleanupField(td_matrixWorldToCamera); |
---|
957 | /* End Pixar Tags */ |
---|
958 | } |
---|
959 | #undef CleanupField |
---|
960 | |
---|
961 | /* |
---|
962 | * Client Tag extension support (from Niles Ritter). |
---|
963 | */ |
---|
964 | static TIFFExtendProc _TIFFextender = (TIFFExtendProc) NULL; |
---|
965 | |
---|
966 | TIFFExtendProc |
---|
967 | TIFFSetTagExtender(TIFFExtendProc extender) |
---|
968 | { |
---|
969 | TIFFExtendProc prev = _TIFFextender; |
---|
970 | _TIFFextender = extender; |
---|
971 | return (prev); |
---|
972 | } |
---|
973 | |
---|
974 | /* |
---|
975 | * Setup for a new directory. Should we automatically call |
---|
976 | * TIFFWriteDirectory() if the current one is dirty? |
---|
977 | * |
---|
978 | * The newly created directory will not exist on the file till |
---|
979 | * TIFFWriteDirectory(), TIFFFlush() or TIFFClose() is called. |
---|
980 | */ |
---|
981 | int |
---|
982 | TIFFCreateDirectory(TIFF* tif) |
---|
983 | { |
---|
984 | TIFFDefaultDirectory(tif); |
---|
985 | tif->tif_diroff = 0; |
---|
986 | tif->tif_nextdiroff = 0; |
---|
987 | tif->tif_curoff = 0; |
---|
988 | tif->tif_row = (uint32) -1; |
---|
989 | tif->tif_curstrip = (tstrip_t) -1; |
---|
990 | |
---|
991 | return 0; |
---|
992 | } |
---|
993 | |
---|
994 | /* |
---|
995 | * Setup a default directory structure. |
---|
996 | */ |
---|
997 | int |
---|
998 | TIFFDefaultDirectory(TIFF* tif) |
---|
999 | { |
---|
1000 | register TIFFDirectory* td = &tif->tif_dir; |
---|
1001 | |
---|
1002 | _TIFFSetupFieldInfo(tif); |
---|
1003 | _TIFFmemset(td, 0, sizeof (*td)); |
---|
1004 | td->td_fillorder = FILLORDER_MSB2LSB; |
---|
1005 | td->td_bitspersample = 1; |
---|
1006 | td->td_threshholding = THRESHHOLD_BILEVEL; |
---|
1007 | td->td_orientation = ORIENTATION_TOPLEFT; |
---|
1008 | td->td_samplesperpixel = 1; |
---|
1009 | td->td_rowsperstrip = (uint32) -1; |
---|
1010 | td->td_tilewidth = (uint32) -1; |
---|
1011 | td->td_tilelength = (uint32) -1; |
---|
1012 | td->td_tiledepth = 1; |
---|
1013 | td->td_resolutionunit = RESUNIT_INCH; |
---|
1014 | td->td_sampleformat = SAMPLEFORMAT_UINT; |
---|
1015 | td->td_imagedepth = 1; |
---|
1016 | #ifdef YCBCR_SUPPORT |
---|
1017 | td->td_ycbcrsubsampling[0] = 2; |
---|
1018 | td->td_ycbcrsubsampling[1] = 2; |
---|
1019 | td->td_ycbcrpositioning = YCBCRPOSITION_CENTERED; |
---|
1020 | #endif |
---|
1021 | #ifdef CMYK_SUPPORT |
---|
1022 | td->td_inkset = INKSET_CMYK; |
---|
1023 | td->td_ninks = 4; |
---|
1024 | #endif |
---|
1025 | tif->tif_postdecode = _TIFFNoPostDecode; |
---|
1026 | tif->tif_vsetfield = _TIFFVSetField; |
---|
1027 | tif->tif_vgetfield = _TIFFVGetField; |
---|
1028 | tif->tif_printdir = NULL; |
---|
1029 | /* |
---|
1030 | * Give client code a chance to install their own |
---|
1031 | * tag extensions & methods, prior to compression overloads. |
---|
1032 | */ |
---|
1033 | if (_TIFFextender) |
---|
1034 | (*_TIFFextender)(tif); |
---|
1035 | (void) TIFFSetField(tif, TIFFTAG_COMPRESSION, COMPRESSION_NONE); |
---|
1036 | /* |
---|
1037 | * NB: The directory is marked dirty as a result of setting |
---|
1038 | * up the default compression scheme. However, this really |
---|
1039 | * isn't correct -- we want TIFF_DIRTYDIRECT to be set only |
---|
1040 | * if the user does something. We could just do the setup |
---|
1041 | * by hand, but it seems better to use the normal mechanism |
---|
1042 | * (i.e. TIFFSetField). |
---|
1043 | */ |
---|
1044 | tif->tif_flags &= ~TIFF_DIRTYDIRECT; |
---|
1045 | |
---|
1046 | /* |
---|
1047 | * As per http://bugzilla.remotesensing.org/show_bug.cgi?id=19 |
---|
1048 | * we clear the ISTILED flag when setting up a new directory. |
---|
1049 | * Should we also be clearing stuff like INSUBIFD? |
---|
1050 | */ |
---|
1051 | tif->tif_flags &= ~TIFF_ISTILED; |
---|
1052 | |
---|
1053 | return (1); |
---|
1054 | } |
---|
1055 | |
---|
1056 | static int |
---|
1057 | TIFFAdvanceDirectory(TIFF* tif, uint32* nextdir, toff_t* off) |
---|
1058 | { |
---|
1059 | static const char module[] = "TIFFAdvanceDirectory"; |
---|
1060 | uint16 dircount; |
---|
1061 | if (isMapped(tif)) |
---|
1062 | { |
---|
1063 | toff_t poff=*nextdir; |
---|
1064 | if (poff+sizeof(uint16) > tif->tif_size) |
---|
1065 | { |
---|
1066 | TIFFError(module, "%s: Error fetching directory count", |
---|
1067 | tif->tif_name); |
---|
1068 | return (0); |
---|
1069 | } |
---|
1070 | _TIFFmemcpy(&dircount, tif->tif_base+poff, sizeof (uint16)); |
---|
1071 | if (tif->tif_flags & TIFF_SWAB) |
---|
1072 | TIFFSwabShort(&dircount); |
---|
1073 | poff+=sizeof (uint16)+dircount*sizeof (TIFFDirEntry); |
---|
1074 | if (off != NULL) |
---|
1075 | *off = poff; |
---|
1076 | if (((toff_t) (poff+sizeof (uint32))) > tif->tif_size) |
---|
1077 | { |
---|
1078 | TIFFError(module, "%s: Error fetching directory link", |
---|
1079 | tif->tif_name); |
---|
1080 | return (0); |
---|
1081 | } |
---|
1082 | _TIFFmemcpy(nextdir, tif->tif_base+poff, sizeof (uint32)); |
---|
1083 | if (tif->tif_flags & TIFF_SWAB) |
---|
1084 | TIFFSwabLong(nextdir); |
---|
1085 | return (1); |
---|
1086 | } |
---|
1087 | else |
---|
1088 | { |
---|
1089 | if (!SeekOK(tif, *nextdir) || |
---|
1090 | !ReadOK(tif, &dircount, sizeof (uint16))) { |
---|
1091 | TIFFError(module, "%s: Error fetching directory count", |
---|
1092 | tif->tif_name); |
---|
1093 | return (0); |
---|
1094 | } |
---|
1095 | if (tif->tif_flags & TIFF_SWAB) |
---|
1096 | TIFFSwabShort(&dircount); |
---|
1097 | if (off != NULL) |
---|
1098 | *off = TIFFSeekFile(tif, |
---|
1099 | dircount*sizeof (TIFFDirEntry), SEEK_CUR); |
---|
1100 | else |
---|
1101 | (void) TIFFSeekFile(tif, |
---|
1102 | dircount*sizeof (TIFFDirEntry), SEEK_CUR); |
---|
1103 | if (!ReadOK(tif, nextdir, sizeof (uint32))) { |
---|
1104 | TIFFError(module, "%s: Error fetching directory link", |
---|
1105 | tif->tif_name); |
---|
1106 | return (0); |
---|
1107 | } |
---|
1108 | if (tif->tif_flags & TIFF_SWAB) |
---|
1109 | TIFFSwabLong(nextdir); |
---|
1110 | return (1); |
---|
1111 | } |
---|
1112 | } |
---|
1113 | |
---|
1114 | /* |
---|
1115 | * Count the number of directories in a file. |
---|
1116 | */ |
---|
1117 | tdir_t |
---|
1118 | TIFFNumberOfDirectories(TIFF* tif) |
---|
1119 | { |
---|
1120 | toff_t nextdir = tif->tif_header.tiff_diroff; |
---|
1121 | tdir_t n = 0; |
---|
1122 | |
---|
1123 | while (nextdir != 0 && TIFFAdvanceDirectory(tif, &nextdir, NULL)) |
---|
1124 | n++; |
---|
1125 | return (n); |
---|
1126 | } |
---|
1127 | |
---|
1128 | /* |
---|
1129 | * Set the n-th directory as the current directory. |
---|
1130 | * NB: Directories are numbered starting at 0. |
---|
1131 | */ |
---|
1132 | int |
---|
1133 | TIFFSetDirectory(TIFF* tif, tdir_t dirn) |
---|
1134 | { |
---|
1135 | toff_t nextdir; |
---|
1136 | tdir_t n; |
---|
1137 | |
---|
1138 | nextdir = tif->tif_header.tiff_diroff; |
---|
1139 | for (n = dirn; n > 0 && nextdir != 0; n--) |
---|
1140 | if (!TIFFAdvanceDirectory(tif, &nextdir, NULL)) |
---|
1141 | return (0); |
---|
1142 | tif->tif_nextdiroff = nextdir; |
---|
1143 | /* |
---|
1144 | * Set curdir to the actual directory index. The |
---|
1145 | * -1 is because TIFFReadDirectory will increment |
---|
1146 | * tif_curdir after successfully reading the directory. |
---|
1147 | */ |
---|
1148 | tif->tif_curdir = (dirn - n) - 1; |
---|
1149 | return (TIFFReadDirectory(tif)); |
---|
1150 | } |
---|
1151 | |
---|
1152 | /* |
---|
1153 | * Set the current directory to be the directory |
---|
1154 | * located at the specified file offset. This interface |
---|
1155 | * is used mainly to access directories linked with |
---|
1156 | * the SubIFD tag (e.g. thumbnail images). |
---|
1157 | */ |
---|
1158 | int |
---|
1159 | TIFFSetSubDirectory(TIFF* tif, uint32 diroff) |
---|
1160 | { |
---|
1161 | tif->tif_nextdiroff = diroff; |
---|
1162 | return (TIFFReadDirectory(tif)); |
---|
1163 | } |
---|
1164 | |
---|
1165 | /* |
---|
1166 | * Return file offset of the current directory. |
---|
1167 | */ |
---|
1168 | uint32 |
---|
1169 | TIFFCurrentDirOffset(TIFF* tif) |
---|
1170 | { |
---|
1171 | return (tif->tif_diroff); |
---|
1172 | } |
---|
1173 | |
---|
1174 | /* |
---|
1175 | * Return an indication of whether or not we are |
---|
1176 | * at the last directory in the file. |
---|
1177 | */ |
---|
1178 | int |
---|
1179 | TIFFLastDirectory(TIFF* tif) |
---|
1180 | { |
---|
1181 | return (tif->tif_nextdiroff == 0); |
---|
1182 | } |
---|
1183 | |
---|
1184 | /* |
---|
1185 | * Unlink the specified directory from the directory chain. |
---|
1186 | */ |
---|
1187 | int |
---|
1188 | TIFFUnlinkDirectory(TIFF* tif, tdir_t dirn) |
---|
1189 | { |
---|
1190 | static const char module[] = "TIFFUnlinkDirectory"; |
---|
1191 | toff_t nextdir; |
---|
1192 | toff_t off; |
---|
1193 | tdir_t n; |
---|
1194 | |
---|
1195 | if (tif->tif_mode == O_RDONLY) { |
---|
1196 | TIFFError(module, "Can not unlink directory in read-only file"); |
---|
1197 | return (0); |
---|
1198 | } |
---|
1199 | /* |
---|
1200 | * Go to the directory before the one we want |
---|
1201 | * to unlink and nab the offset of the link |
---|
1202 | * field we'll need to patch. |
---|
1203 | */ |
---|
1204 | nextdir = tif->tif_header.tiff_diroff; |
---|
1205 | off = sizeof (uint16) + sizeof (uint16); |
---|
1206 | for (n = dirn-1; n > 0; n--) { |
---|
1207 | if (nextdir == 0) { |
---|
1208 | TIFFError(module, "Directory %d does not exist", dirn); |
---|
1209 | return (0); |
---|
1210 | } |
---|
1211 | if (!TIFFAdvanceDirectory(tif, &nextdir, &off)) |
---|
1212 | return (0); |
---|
1213 | } |
---|
1214 | /* |
---|
1215 | * Advance to the directory to be unlinked and fetch |
---|
1216 | * the offset of the directory that follows. |
---|
1217 | */ |
---|
1218 | if (!TIFFAdvanceDirectory(tif, &nextdir, NULL)) |
---|
1219 | return (0); |
---|
1220 | /* |
---|
1221 | * Go back and patch the link field of the preceding |
---|
1222 | * directory to point to the offset of the directory |
---|
1223 | * that follows. |
---|
1224 | */ |
---|
1225 | (void) TIFFSeekFile(tif, off, SEEK_SET); |
---|
1226 | if (tif->tif_flags & TIFF_SWAB) |
---|
1227 | TIFFSwabLong(&nextdir); |
---|
1228 | if (!WriteOK(tif, &nextdir, sizeof (uint32))) { |
---|
1229 | TIFFError(module, "Error writing directory link"); |
---|
1230 | return (0); |
---|
1231 | } |
---|
1232 | /* |
---|
1233 | * Leave directory state setup safely. We don't have |
---|
1234 | * facilities for doing inserting and removing directories, |
---|
1235 | * so it's safest to just invalidate everything. This |
---|
1236 | * means that the caller can only append to the directory |
---|
1237 | * chain. |
---|
1238 | */ |
---|
1239 | (*tif->tif_cleanup)(tif); |
---|
1240 | if ((tif->tif_flags & TIFF_MYBUFFER) && tif->tif_rawdata) { |
---|
1241 | _TIFFfree(tif->tif_rawdata); |
---|
1242 | tif->tif_rawdata = NULL; |
---|
1243 | tif->tif_rawcc = 0; |
---|
1244 | } |
---|
1245 | tif->tif_flags &= ~(TIFF_BEENWRITING|TIFF_BUFFERSETUP|TIFF_POSTENCODE); |
---|
1246 | TIFFFreeDirectory(tif); |
---|
1247 | TIFFDefaultDirectory(tif); |
---|
1248 | tif->tif_diroff = 0; /* force link on next write */ |
---|
1249 | tif->tif_nextdiroff = 0; /* next write must be at end */ |
---|
1250 | tif->tif_curoff = 0; |
---|
1251 | tif->tif_row = (uint32) -1; |
---|
1252 | tif->tif_curstrip = (tstrip_t) -1; |
---|
1253 | return (1); |
---|
1254 | } |
---|
1255 | |
---|
1256 | /* [BFC] |
---|
1257 | * |
---|
1258 | * Author: Bruce Cameron <cameron@petris.com> |
---|
1259 | * |
---|
1260 | * Set a table of tags that are to be replaced during directory process by the |
---|
1261 | * 'IGNORE' state - or return TRUE/FALSE for the requested tag such that |
---|
1262 | * 'ReadDirectory' can use the stored information. |
---|
1263 | */ |
---|
1264 | int |
---|
1265 | TIFFReassignTagToIgnore (enum TIFFIgnoreSense task, int TIFFtagID) |
---|
1266 | { |
---|
1267 | static int TIFFignoretags [FIELD_LAST]; |
---|
1268 | static int tagcount = 0 ; |
---|
1269 | int i; /* Loop index */ |
---|
1270 | int j; /* Loop index */ |
---|
1271 | |
---|
1272 | switch (task) |
---|
1273 | { |
---|
1274 | case TIS_STORE: |
---|
1275 | if ( tagcount < (FIELD_LAST - 1) ) |
---|
1276 | { |
---|
1277 | for ( j = 0 ; j < tagcount ; ++j ) |
---|
1278 | { /* Do not add duplicate tag */ |
---|
1279 | if ( TIFFignoretags [j] == TIFFtagID ) |
---|
1280 | return (TRUE) ; |
---|
1281 | } |
---|
1282 | TIFFignoretags [tagcount++] = TIFFtagID ; |
---|
1283 | return (TRUE) ; |
---|
1284 | } |
---|
1285 | break ; |
---|
1286 | |
---|
1287 | case TIS_EXTRACT: |
---|
1288 | for ( i = 0 ; i < tagcount ; ++i ) |
---|
1289 | { |
---|
1290 | if ( TIFFignoretags [i] == TIFFtagID ) |
---|
1291 | return (TRUE) ; |
---|
1292 | } |
---|
1293 | break; |
---|
1294 | |
---|
1295 | case TIS_EMPTY: |
---|
1296 | tagcount = 0 ; /* Clear the list */ |
---|
1297 | return (TRUE) ; |
---|
1298 | |
---|
1299 | default: |
---|
1300 | break; |
---|
1301 | } |
---|
1302 | |
---|
1303 | return (FALSE); |
---|
1304 | } |
---|