OLD | NEW |
| (Empty) |
1 /* $Id: tif_dir.c,v 1.113 2012-06-14 20:32:53 fwarmerdam 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 static void | |
44 setByteArray(void** vpp, void* vp, size_t nmemb, size_t elem_size) | |
45 { | |
46 if (*vpp) | |
47 _TIFFfree(*vpp), *vpp = 0; | |
48 if (vp) { | |
49 tmsize_t bytes = (tmsize_t)(nmemb * elem_size); | |
50 if (elem_size && bytes / elem_size == nmemb) | |
51 *vpp = (void*) _TIFFmalloc(bytes); | |
52 if (*vpp) | |
53 _TIFFmemcpy(*vpp, vp, bytes); | |
54 } | |
55 } | |
56 void _TIFFsetByteArray(void** vpp, void* vp, uint32 n) | |
57 { setByteArray(vpp, vp, n, 1); } | |
58 void _TIFFsetString(char** cpp, char* cp) | |
59 { setByteArray((void**) cpp, (void*) cp, strlen(cp)+1, 1); } | |
60 void _TIFFsetNString(char** cpp, char* cp, uint32 n) | |
61 { setByteArray((void**) cpp, (void*) cp, n, 1); } | |
62 void _TIFFsetShortArray(uint16** wpp, uint16* wp, uint32 n) | |
63 { setByteArray((void**) wpp, (void*) wp, n, sizeof (uint16)); } | |
64 void _TIFFsetLongArray(uint32** lpp, uint32* lp, uint32 n) | |
65 { setByteArray((void**) lpp, (void*) lp, n, sizeof (uint32)); } | |
66 void _TIFFsetLong8Array(uint64** lpp, uint64* lp, uint32 n) | |
67 { setByteArray((void**) lpp, (void*) lp, n, sizeof (uint64)); } | |
68 void _TIFFsetFloatArray(float** fpp, float* fp, uint32 n) | |
69 { setByteArray((void**) fpp, (void*) fp, n, sizeof (float)); } | |
70 void _TIFFsetDoubleArray(double** dpp, double* dp, uint32 n) | |
71 { setByteArray((void**) dpp, (void*) dp, n, sizeof (double)); } | |
72 | |
73 static void | |
74 setDoubleArrayOneValue(double** vpp, double value, size_t nmemb) | |
75 { | |
76 if (*vpp) | |
77 _TIFFfree(*vpp); | |
78 *vpp = _TIFFmalloc(nmemb*sizeof(double)); | |
79 if (*vpp) | |
80 { | |
81 while (nmemb--) | |
82 ((double*)*vpp)[nmemb] = value; | |
83 } | |
84 } | |
85 | |
86 /* | |
87 * Install extra samples information. | |
88 */ | |
89 static int | |
90 setExtraSamples(TIFFDirectory* td, va_list ap, uint32* v) | |
91 { | |
92 /* XXX: Unassociated alpha data == 999 is a known Corel Draw bug, see below */ | |
93 #define EXTRASAMPLE_COREL_UNASSALPHA 999 | |
94 | |
95 uint16* va; | |
96 uint32 i; | |
97 | |
98 *v = (uint16) va_arg(ap, uint16_vap); | |
99 if ((uint16) *v > td->td_samplesperpixel) | |
100 return 0; | |
101 va = va_arg(ap, uint16*); | |
102 if (*v > 0 && va == NULL) /* typically missing param */ | |
103 return 0; | |
104 for (i = 0; i < *v; i++) { | |
105 if (va[i] > EXTRASAMPLE_UNASSALPHA) { | |
106 /* | |
107 * XXX: Corel Draw is known to produce incorrect | |
108 * ExtraSamples tags which must be patched here if we | |
109 * want to be able to open some of the damaged TIFF | |
110 * files: | |
111 */ | |
112 if (va[i] == EXTRASAMPLE_COREL_UNASSALPHA) | |
113 va[i] = EXTRASAMPLE_UNASSALPHA; | |
114 else | |
115 return 0; | |
116 } | |
117 } | |
118 td->td_extrasamples = (uint16) *v; | |
119 _TIFFsetShortArray(&td->td_sampleinfo, va, td->td_extrasamples); | |
120 return 1; | |
121 | |
122 #undef EXTRASAMPLE_COREL_UNASSALPHA | |
123 } | |
124 | |
125 /* | |
126 * Confirm we have "samplesperpixel" ink names separated by \0. Returns | |
127 * zero if the ink names are not as expected. | |
128 */ | |
129 static uint32 | |
130 checkInkNamesString(TIFF* tif, uint32 slen, const char* s) | |
131 { | |
132 TIFFDirectory* td = &tif->tif_dir; | |
133 uint16 i = td->td_samplesperpixel; | |
134 | |
135 if (slen > 0) { | |
136 const char* ep = s+slen; | |
137 const char* cp = s; | |
138 for (; i > 0; i--) { | |
139 for (; cp < ep && *cp != '\0'; cp++) {} | |
140 if (cp >= ep) | |
141 goto bad; | |
142 cp++; /* skip \0 */ | |
143 } | |
144 return ((uint32)(cp-s)); | |
145 } | |
146 bad: | |
147 TIFFErrorExt(tif->tif_clientdata, "TIFFSetField", | |
148 "%s: Invalid InkNames value; expecting %d names, found %d", | |
149 tif->tif_name, | |
150 td->td_samplesperpixel, | |
151 td->td_samplesperpixel-i); | |
152 return (0); | |
153 } | |
154 | |
155 static int | |
156 _TIFFVSetField(TIFF* tif, uint32 tag, va_list ap) | |
157 { | |
158 static const char module[] = "_TIFFVSetField"; | |
159 | |
160 TIFFDirectory* td = &tif->tif_dir; | |
161 int status = 1; | |
162 uint32 v32, i, v; | |
163 char* s; | |
164 const TIFFField *fip = TIFFFindField(tif, tag, TIFF_ANY); | |
165 uint32 standard_tag = tag; | |
166 | |
167 /* | |
168 * We want to force the custom code to be used for custom | |
169 * fields even if the tag happens to match a well known | |
170 * one - important for reinterpreted handling of standard | |
171 * tag values in custom directories (ie. EXIF) | |
172 */ | |
173 if (fip->field_bit == FIELD_CUSTOM) { | |
174 standard_tag = 0; | |
175 } | |
176 | |
177 switch (standard_tag) { | |
178 case TIFFTAG_SUBFILETYPE: | |
179 td->td_subfiletype = (uint32) va_arg(ap, uint32); | |
180 break; | |
181 case TIFFTAG_IMAGEWIDTH: | |
182 td->td_imagewidth = (uint32) va_arg(ap, uint32); | |
183 break; | |
184 case TIFFTAG_IMAGELENGTH: | |
185 td->td_imagelength = (uint32) va_arg(ap, uint32); | |
186 break; | |
187 case TIFFTAG_BITSPERSAMPLE: | |
188 td->td_bitspersample = (uint16) va_arg(ap, uint16_vap); | |
189 /* | |
190 * If the data require post-decoding processing to byte-swap | |
191 * samples, set it up here. Note that since tags are required | |
192 * to be ordered, compression code can override this behaviour | |
193 * in the setup method if it wants to roll the post decoding | |
194 * work in with its normal work. | |
195 */ | |
196 if (tif->tif_flags & TIFF_SWAB) { | |
197 if (td->td_bitspersample == 8) | |
198 tif->tif_postdecode = _TIFFNoPostDecode; | |
199 else if (td->td_bitspersample == 16) | |
200 tif->tif_postdecode = _TIFFSwab16BitData; | |
201 else if (td->td_bitspersample == 24) | |
202 tif->tif_postdecode = _TIFFSwab24BitData; | |
203 else if (td->td_bitspersample == 32) | |
204 tif->tif_postdecode = _TIFFSwab32BitData; | |
205 else if (td->td_bitspersample == 64) | |
206 tif->tif_postdecode = _TIFFSwab64BitData; | |
207 else if (td->td_bitspersample == 128) /* two 64's */ | |
208 tif->tif_postdecode = _TIFFSwab64BitData; | |
209 } | |
210 break; | |
211 case TIFFTAG_COMPRESSION: | |
212 v = (uint16) va_arg(ap, uint16_vap); | |
213 /* | |
214 * If we're changing the compression scheme, the notify the | |
215 * previous module so that it can cleanup any state it's | |
216 * setup. | |
217 */ | |
218 if (TIFFFieldSet(tif, FIELD_COMPRESSION)) { | |
219 if ((uint32)td->td_compression == v) | |
220 break; | |
221 (*tif->tif_cleanup)(tif); | |
222 tif->tif_flags &= ~TIFF_CODERSETUP; | |
223 } | |
224 /* | |
225 * Setup new compression routine state. | |
226 */ | |
227 if( (status = TIFFSetCompressionScheme(tif, v)) != 0 ) | |
228 td->td_compression = (uint16) v; | |
229 else | |
230 status = 0; | |
231 break; | |
232 case TIFFTAG_PHOTOMETRIC: | |
233 td->td_photometric = (uint16) va_arg(ap, uint16_vap); | |
234 break; | |
235 case TIFFTAG_THRESHHOLDING: | |
236 td->td_threshholding = (uint16) va_arg(ap, uint16_vap); | |
237 break; | |
238 case TIFFTAG_FILLORDER: | |
239 v = (uint16) va_arg(ap, uint16_vap); | |
240 if (v != FILLORDER_LSB2MSB && v != FILLORDER_MSB2LSB) | |
241 goto badvalue; | |
242 td->td_fillorder = (uint16) v; | |
243 break; | |
244 case TIFFTAG_ORIENTATION: | |
245 v = (uint16) va_arg(ap, uint16_vap); | |
246 if (v < ORIENTATION_TOPLEFT || ORIENTATION_LEFTBOT < v) | |
247 goto badvalue; | |
248 else | |
249 td->td_orientation = (uint16) v; | |
250 break; | |
251 case TIFFTAG_SAMPLESPERPIXEL: | |
252 v = (uint16) va_arg(ap, uint16_vap); | |
253 if (v == 0) | |
254 goto badvalue; | |
255 td->td_samplesperpixel = (uint16) v; | |
256 break; | |
257 case TIFFTAG_ROWSPERSTRIP: | |
258 v32 = (uint32) va_arg(ap, uint32); | |
259 if (v32 == 0) | |
260 goto badvalue32; | |
261 td->td_rowsperstrip = v32; | |
262 if (!TIFFFieldSet(tif, FIELD_TILEDIMENSIONS)) { | |
263 td->td_tilelength = v32; | |
264 td->td_tilewidth = td->td_imagewidth; | |
265 } | |
266 break; | |
267 case TIFFTAG_MINSAMPLEVALUE: | |
268 td->td_minsamplevalue = (uint16) va_arg(ap, uint16_vap); | |
269 break; | |
270 case TIFFTAG_MAXSAMPLEVALUE: | |
271 td->td_maxsamplevalue = (uint16) va_arg(ap, uint16_vap); | |
272 break; | |
273 case TIFFTAG_SMINSAMPLEVALUE: | |
274 if (tif->tif_flags & TIFF_PERSAMPLE) | |
275 _TIFFsetDoubleArray(&td->td_sminsamplevalue, va_arg(ap,
double*), td->td_samplesperpixel); | |
276 else | |
277 setDoubleArrayOneValue(&td->td_sminsamplevalue, va_arg(a
p, double), td->td_samplesperpixel); | |
278 break; | |
279 case TIFFTAG_SMAXSAMPLEVALUE: | |
280 if (tif->tif_flags & TIFF_PERSAMPLE) | |
281 _TIFFsetDoubleArray(&td->td_smaxsamplevalue, va_arg(ap,
double*), td->td_samplesperpixel); | |
282 else | |
283 setDoubleArrayOneValue(&td->td_smaxsamplevalue, va_arg(a
p, double), td->td_samplesperpixel); | |
284 break; | |
285 case TIFFTAG_XRESOLUTION: | |
286 td->td_xresolution = (float) va_arg(ap, double); | |
287 break; | |
288 case TIFFTAG_YRESOLUTION: | |
289 td->td_yresolution = (float) va_arg(ap, double); | |
290 break; | |
291 case TIFFTAG_PLANARCONFIG: | |
292 v = (uint16) va_arg(ap, uint16_vap); | |
293 if (v != PLANARCONFIG_CONTIG && v != PLANARCONFIG_SEPARATE) | |
294 goto badvalue; | |
295 td->td_planarconfig = (uint16) v; | |
296 break; | |
297 case TIFFTAG_XPOSITION: | |
298 td->td_xposition = (float) va_arg(ap, double); | |
299 break; | |
300 case TIFFTAG_YPOSITION: | |
301 td->td_yposition = (float) va_arg(ap, double); | |
302 break; | |
303 case TIFFTAG_RESOLUTIONUNIT: | |
304 v = (uint16) va_arg(ap, uint16_vap); | |
305 if (v < RESUNIT_NONE || RESUNIT_CENTIMETER < v) | |
306 goto badvalue; | |
307 td->td_resolutionunit = (uint16) v; | |
308 break; | |
309 case TIFFTAG_PAGENUMBER: | |
310 td->td_pagenumber[0] = (uint16) va_arg(ap, uint16_vap); | |
311 td->td_pagenumber[1] = (uint16) va_arg(ap, uint16_vap); | |
312 break; | |
313 case TIFFTAG_HALFTONEHINTS: | |
314 td->td_halftonehints[0] = (uint16) va_arg(ap, uint16_vap); | |
315 td->td_halftonehints[1] = (uint16) va_arg(ap, uint16_vap); | |
316 break; | |
317 case TIFFTAG_COLORMAP: | |
318 v32 = (uint32)(1L<<td->td_bitspersample); | |
319 _TIFFsetShortArray(&td->td_colormap[0], va_arg(ap, uint16*), v32
); | |
320 _TIFFsetShortArray(&td->td_colormap[1], va_arg(ap, uint16*), v32
); | |
321 _TIFFsetShortArray(&td->td_colormap[2], va_arg(ap, uint16*), v32
); | |
322 break; | |
323 case TIFFTAG_EXTRASAMPLES: | |
324 if (!setExtraSamples(td, ap, &v)) | |
325 goto badvalue; | |
326 break; | |
327 case TIFFTAG_MATTEING: | |
328 td->td_extrasamples = (((uint16) va_arg(ap, uint16_vap)) != 0); | |
329 if (td->td_extrasamples) { | |
330 uint16 sv = EXTRASAMPLE_ASSOCALPHA; | |
331 _TIFFsetShortArray(&td->td_sampleinfo, &sv, 1); | |
332 } | |
333 break; | |
334 case TIFFTAG_TILEWIDTH: | |
335 v32 = (uint32) va_arg(ap, uint32); | |
336 if (v32 % 16) { | |
337 if (tif->tif_mode != O_RDONLY) | |
338 goto badvalue32; | |
339 TIFFWarningExt(tif->tif_clientdata, tif->tif_name, | |
340 "Nonstandard tile width %d, convert file", v32); | |
341 } | |
342 td->td_tilewidth = v32; | |
343 tif->tif_flags |= TIFF_ISTILED; | |
344 break; | |
345 case TIFFTAG_TILELENGTH: | |
346 v32 = (uint32) va_arg(ap, uint32); | |
347 if (v32 % 16) { | |
348 if (tif->tif_mode != O_RDONLY) | |
349 goto badvalue32; | |
350 TIFFWarningExt(tif->tif_clientdata, tif->tif_name, | |
351 "Nonstandard tile length %d, convert file", v32); | |
352 } | |
353 td->td_tilelength = v32; | |
354 tif->tif_flags |= TIFF_ISTILED; | |
355 break; | |
356 case TIFFTAG_TILEDEPTH: | |
357 v32 = (uint32) va_arg(ap, uint32); | |
358 if (v32 == 0) | |
359 goto badvalue32; | |
360 td->td_tiledepth = v32; | |
361 break; | |
362 case TIFFTAG_DATATYPE: | |
363 v = (uint16) va_arg(ap, uint16_vap); | |
364 switch (v) { | |
365 case DATATYPE_VOID: v = SAMPLEFORMAT_VOID; break; | |
366 case DATATYPE_INT: v = SAMPLEFORMAT_INT; break; | |
367 case DATATYPE_UINT: v = SAMPLEFORMAT_UINT; break; | |
368 case DATATYPE_IEEEFP: v = SAMPLEFORMAT_IEEEFP;break; | |
369 default: goto badvalue; | |
370 } | |
371 td->td_sampleformat = (uint16) v; | |
372 break; | |
373 case TIFFTAG_SAMPLEFORMAT: | |
374 v = (uint16) va_arg(ap, uint16_vap); | |
375 if (v < SAMPLEFORMAT_UINT || SAMPLEFORMAT_COMPLEXIEEEFP < v) | |
376 goto badvalue; | |
377 td->td_sampleformat = (uint16) v; | |
378 | |
379 /* Try to fix up the SWAB function for complex data. */ | |
380 if( td->td_sampleformat == SAMPLEFORMAT_COMPLEXINT | |
381 && td->td_bitspersample == 32 | |
382 && tif->tif_postdecode == _TIFFSwab32BitData ) | |
383 tif->tif_postdecode = _TIFFSwab16BitData; | |
384 else if( (td->td_sampleformat == SAMPLEFORMAT_COMPLEXINT | |
385 || td->td_sampleformat == SAMPLEFORMAT_COMPLEXIEEEFP) | |
386 && td->td_bitspersample == 64 | |
387 && tif->tif_postdecode == _TIFFSwab64BitData ) | |
388 tif->tif_postdecode = _TIFFSwab32BitData; | |
389 break; | |
390 case TIFFTAG_IMAGEDEPTH: | |
391 td->td_imagedepth = (uint32) va_arg(ap, uint32); | |
392 break; | |
393 case TIFFTAG_SUBIFD: | |
394 if ((tif->tif_flags & TIFF_INSUBIFD) == 0) { | |
395 td->td_nsubifd = (uint16) va_arg(ap, uint16_vap); | |
396 _TIFFsetLong8Array(&td->td_subifd, (uint64*) va_arg(ap,
uint64*), | |
397 (long) td->td_nsubifd); | |
398 } else { | |
399 TIFFErrorExt(tif->tif_clientdata, module, | |
400 "%s: Sorry, cannot nest SubIFDs", | |
401 tif->tif_name); | |
402 status = 0; | |
403 } | |
404 break; | |
405 case TIFFTAG_YCBCRPOSITIONING: | |
406 td->td_ycbcrpositioning = (uint16) va_arg(ap, uint16_vap); | |
407 break; | |
408 case TIFFTAG_YCBCRSUBSAMPLING: | |
409 td->td_ycbcrsubsampling[0] = (uint16) va_arg(ap, uint16_vap); | |
410 td->td_ycbcrsubsampling[1] = (uint16) va_arg(ap, uint16_vap); | |
411 break; | |
412 case TIFFTAG_TRANSFERFUNCTION: | |
413 v = (td->td_samplesperpixel - td->td_extrasamples) > 1 ? 3 : 1; | |
414 for (i = 0; i < v; i++) | |
415 _TIFFsetShortArray(&td->td_transferfunction[i], | |
416 va_arg(ap, uint16*), 1L<<td->td_bitspersample); | |
417 break; | |
418 case TIFFTAG_REFERENCEBLACKWHITE: | |
419 /* XXX should check for null range */ | |
420 _TIFFsetFloatArray(&td->td_refblackwhite, va_arg(ap, float*), 6)
; | |
421 break; | |
422 case TIFFTAG_INKNAMES: | |
423 v = (uint16) va_arg(ap, uint16_vap); | |
424 s = va_arg(ap, char*); | |
425 v = checkInkNamesString(tif, v, s); | |
426 status = v > 0; | |
427 if( v > 0 ) { | |
428 _TIFFsetNString(&td->td_inknames, s, v); | |
429 td->td_inknameslen = v; | |
430 } | |
431 break; | |
432 case TIFFTAG_PERSAMPLE: | |
433 v = (uint16) va_arg(ap, uint16_vap); | |
434 if( v == PERSAMPLE_MULTI ) | |
435 tif->tif_flags |= TIFF_PERSAMPLE; | |
436 else | |
437 tif->tif_flags &= ~TIFF_PERSAMPLE; | |
438 break; | |
439 default: { | |
440 TIFFTagValue *tv; | |
441 int tv_size, iCustom; | |
442 | |
443 /* | |
444 * This can happen if multiple images are open with different | |
445 * codecs which have private tags. The global tag information | |
446 * table may then have tags that are valid for one file but not | |
447 * the other. If the client tries to set a tag that is not valid | |
448 * for the image's codec then we'll arrive here. This | |
449 * happens, for example, when tiffcp is used to convert between | |
450 * compression schemes and codec-specific tags are blindly copie
d. | |
451 */ | |
452 if(fip == NULL || fip->field_bit != FIELD_CUSTOM) { | |
453 TIFFErrorExt(tif->tif_clientdata, module, | |
454 "%s: Invalid %stag \"%s\" (not supported by codec)", | |
455 tif->tif_name, isPseudoTag(tag) ? "pseudo-" : "", | |
456 fip ? fip->field_name : "Unknown"); | |
457 status = 0; | |
458 break; | |
459 } | |
460 | |
461 /* | |
462 * Find the existing entry for this custom value. | |
463 */ | |
464 tv = NULL; | |
465 for (iCustom = 0; iCustom < td->td_customValueCount; iCustom++)
{ | |
466 if (td->td_customValues[iCustom].info->field_tag == tag)
{ | |
467 tv = td->td_customValues + iCustom; | |
468 if (tv->value != NULL) { | |
469 _TIFFfree(tv->value); | |
470 tv->value = NULL; | |
471 } | |
472 break; | |
473 } | |
474 } | |
475 | |
476 /* | |
477 * Grow the custom list if the entry was not found. | |
478 */ | |
479 if(tv == NULL) { | |
480 TIFFTagValue *new_customValues; | |
481 | |
482 td->td_customValueCount++; | |
483 new_customValues = (TIFFTagValue *) | |
484 _TIFFrealloc(td->td_customValues, | |
485 sizeof(TIFFTagValue) * td->td_customValueCount); | |
486 if (!new_customValues) { | |
487 TIFFErrorExt(tif->tif_clientdata, module, | |
488 "%s: Failed to allocate space for list of cu
stom values", | |
489 tif->tif_name); | |
490 status = 0; | |
491 goto end; | |
492 } | |
493 | |
494 td->td_customValues = new_customValues; | |
495 | |
496 tv = td->td_customValues + (td->td_customValueCount - 1)
; | |
497 tv->info = fip; | |
498 tv->value = NULL; | |
499 tv->count = 0; | |
500 } | |
501 | |
502 /* | |
503 * Set custom value ... save a copy of the custom tag value. | |
504 */ | |
505 tv_size = _TIFFDataSize(fip->field_type); | |
506 if (tv_size == 0) { | |
507 status = 0; | |
508 TIFFErrorExt(tif->tif_clientdata, module, | |
509 "%s: Bad field type %d for \"%s\"", | |
510 tif->tif_name, fip->field_type, | |
511 fip->field_name); | |
512 goto end; | |
513 } | |
514 | |
515 if (fip->field_type == TIFF_ASCII) | |
516 { | |
517 uint32 ma; | |
518 char* mb; | |
519 if (fip->field_passcount) | |
520 { | |
521 assert(fip->field_writecount==TIFF_VARIABLE2); | |
522 ma=(uint32)va_arg(ap,uint32); | |
523 mb=(char*)va_arg(ap,char*); | |
524 } | |
525 else | |
526 { | |
527 mb=(char*)va_arg(ap,char*); | |
528 ma=(uint32)(strlen(mb)+1); | |
529 } | |
530 tv->count=ma; | |
531 setByteArray(&tv->value,mb,ma,1); | |
532 } | |
533 else | |
534 { | |
535 if (fip->field_passcount) { | |
536 if (fip->field_writecount == TIFF_VARIABLE2) | |
537 tv->count = (uint32) va_arg(ap, uint32); | |
538 else | |
539 tv->count = (int) va_arg(ap, int); | |
540 } else if (fip->field_writecount == TIFF_VARIABLE | |
541 || fip->field_writecount == TIFF_VARIABLE2) | |
542 tv->count = 1; | |
543 else if (fip->field_writecount == TIFF_SPP) | |
544 tv->count = td->td_samplesperpixel; | |
545 else | |
546 tv->count = fip->field_writecount; | |
547 | |
548 if (tv->count == 0) { | |
549 status = 0; | |
550 TIFFErrorExt(tif->tif_clientdata, module, | |
551 "%s: Null count for \"%s\" (type " | |
552 "%d, writecount %d, passcount %d)", | |
553 tif->tif_name, | |
554 fip->field_name, | |
555 fip->field_type, | |
556 fip->field_writecount, | |
557 fip->field_passcount); | |
558 goto end; | |
559 } | |
560 | |
561 tv->value = _TIFFCheckMalloc(tif, tv->count, tv_size, | |
562 "custom tag binary object"); | |
563 if (!tv->value) { | |
564 status = 0; | |
565 goto end; | |
566 } | |
567 | |
568 if (fip->field_tag == TIFFTAG_DOTRANGE | |
569 && strcmp(fip->field_name,"DotRange") == 0) { | |
570 /* TODO: This is an evil exception and should no
t have been | |
571 handled this way ... likely best if we move i
t into | |
572 the directory structure with an explicit fiel
d in | |
573 libtiff 4.1 and assign it a FIELD_ value */ | |
574 uint16 v[2]; | |
575 v[0] = (uint16)va_arg(ap, int); | |
576 v[1] = (uint16)va_arg(ap, int); | |
577 _TIFFmemcpy(tv->value, &v, 4); | |
578 } | |
579 | |
580 else if (fip->field_passcount | |
581 || fip->field_writecount == TIFF_VARIABLE | |
582 || fip->field_writecount == TIFF_VARIABLE2 | |
583 || fip->field_writecount == TIFF_SPP | |
584 || tv->count > 1) { | |
585 _TIFFmemcpy(tv->value, va_arg(ap, void *), | |
586 tv->count * tv_size); | |
587 } else { | |
588 char *val = (char *)tv->value; | |
589 assert( tv->count == 1 ); | |
590 | |
591 switch (fip->field_type) { | |
592 case TIFF_BYTE: | |
593 case TIFF_UNDEFINED: | |
594 { | |
595 uint8 v = (uint8)va_arg(ap, int)
; | |
596 _TIFFmemcpy(val, &v, tv_size); | |
597 } | |
598 break; | |
599 case TIFF_SBYTE: | |
600 { | |
601 int8 v = (int8)va_arg(ap, int); | |
602 _TIFFmemcpy(val, &v, tv_size); | |
603 } | |
604 break; | |
605 case TIFF_SHORT: | |
606 { | |
607 uint16 v = (uint16)va_arg(ap, in
t); | |
608 _TIFFmemcpy(val, &v, tv_size); | |
609 } | |
610 break; | |
611 case TIFF_SSHORT: | |
612 { | |
613 int16 v = (int16)va_arg(ap, int)
; | |
614 _TIFFmemcpy(val, &v, tv_size); | |
615 } | |
616 break; | |
617 case TIFF_LONG: | |
618 case TIFF_IFD: | |
619 { | |
620 uint32 v = va_arg(ap, uint32); | |
621 _TIFFmemcpy(val, &v, tv_size); | |
622 } | |
623 break; | |
624 case TIFF_SLONG: | |
625 { | |
626 int32 v = va_arg(ap, int32); | |
627 _TIFFmemcpy(val, &v, tv_size); | |
628 } | |
629 break; | |
630 case TIFF_LONG8: | |
631 case TIFF_IFD8: | |
632 { | |
633 uint64 v = va_arg(ap, uint64); | |
634 _TIFFmemcpy(val, &v, tv_size); | |
635 } | |
636 break; | |
637 case TIFF_SLONG8: | |
638 { | |
639 int64 v = va_arg(ap, int64); | |
640 _TIFFmemcpy(val, &v, tv_size); | |
641 } | |
642 break; | |
643 case TIFF_RATIONAL: | |
644 case TIFF_SRATIONAL: | |
645 case TIFF_FLOAT: | |
646 { | |
647 float v = (float)va_arg(ap, doub
le); | |
648 _TIFFmemcpy(val, &v, tv_size); | |
649 } | |
650 break; | |
651 case TIFF_DOUBLE: | |
652 { | |
653 double v = va_arg(ap, double); | |
654 _TIFFmemcpy(val, &v, tv_size); | |
655 } | |
656 break; | |
657 default: | |
658 _TIFFmemset(val, 0, tv_size); | |
659 status = 0; | |
660 break; | |
661 } | |
662 } | |
663 } | |
664 } | |
665 } | |
666 if (status) { | |
667 const TIFFField* fip=TIFFFieldWithTag(tif,tag); | |
668 if (fip) | |
669 TIFFSetFieldBit(tif, fip->field_bit); | |
670 tif->tif_flags |= TIFF_DIRTYDIRECT; | |
671 } | |
672 | |
673 end: | |
674 va_end(ap); | |
675 return (status); | |
676 badvalue: | |
677 { | |
678 const TIFFField* fip=TIFFFieldWithTag(tif,tag); | |
679 TIFFErrorExt(tif->tif_clientdata, module, | |
680 "%s: Bad value %u for \"%s\" tag", | |
681 tif->tif_name, v, | |
682 fip ? fip->field_name : "Unknown"); | |
683 va_end(ap); | |
684 } | |
685 return (0); | |
686 badvalue32: | |
687 { | |
688 const TIFFField* fip=TIFFFieldWithTag(tif,tag); | |
689 TIFFErrorExt(tif->tif_clientdata, module, | |
690 "%s: Bad value %u for \"%s\" tag", | |
691 tif->tif_name, v32, | |
692 fip ? fip->field_name : "Unknown"); | |
693 va_end(ap); | |
694 } | |
695 return (0); | |
696 } | |
697 | |
698 /* | |
699 * Return 1/0 according to whether or not | |
700 * it is permissible to set the tag's value. | |
701 * Note that we allow ImageLength to be changed | |
702 * so that we can append and extend to images. | |
703 * Any other tag may not be altered once writing | |
704 * has commenced, unless its value has no effect | |
705 * on the format of the data that is written. | |
706 */ | |
707 static int | |
708 OkToChangeTag(TIFF* tif, uint32 tag) | |
709 { | |
710 const TIFFField* fip = TIFFFindField(tif, tag, TIFF_ANY); | |
711 if (!fip) { /* unknown tag */ | |
712 TIFFErrorExt(tif->tif_clientdata, "TIFFSetField", "%s: Unknown %
stag %u", | |
713 tif->tif_name, isPseudoTag(tag) ? "pseudo-" : "", tag); | |
714 return (0); | |
715 } | |
716 if (tag != TIFFTAG_IMAGELENGTH && (tif->tif_flags & TIFF_BEENWRITING) && | |
717 !fip->field_oktochange) { | |
718 /* | |
719 * Consult info table to see if tag can be changed | |
720 * after we've started writing. We only allow changes | |
721 * to those tags that don't/shouldn't affect the | |
722 * compression and/or format of the data. | |
723 */ | |
724 TIFFErrorExt(tif->tif_clientdata, "TIFFSetField", | |
725 "%s: Cannot modify tag \"%s\" while writing", | |
726 tif->tif_name, fip->field_name); | |
727 return (0); | |
728 } | |
729 return (1); | |
730 } | |
731 | |
732 /* | |
733 * Record the value of a field in the | |
734 * internal directory structure. The | |
735 * field will be written to the file | |
736 * when/if the directory structure is | |
737 * updated. | |
738 */ | |
739 int | |
740 TIFFSetField(TIFF* tif, uint32 tag, ...) | |
741 { | |
742 va_list ap; | |
743 int status; | |
744 | |
745 va_start(ap, tag); | |
746 status = TIFFVSetField(tif, tag, ap); | |
747 va_end(ap); | |
748 return (status); | |
749 } | |
750 | |
751 /* | |
752 * Clear the contents of the field in the internal structure. | |
753 */ | |
754 int | |
755 TIFFUnsetField(TIFF* tif, uint32 tag) | |
756 { | |
757 const TIFFField *fip = TIFFFieldWithTag(tif, tag); | |
758 TIFFDirectory* td = &tif->tif_dir; | |
759 | |
760 if( !fip ) | |
761 return 0; | |
762 | |
763 if( fip->field_bit != FIELD_CUSTOM ) | |
764 TIFFClrFieldBit(tif, fip->field_bit); | |
765 else | |
766 { | |
767 TIFFTagValue *tv = NULL; | |
768 int i; | |
769 | |
770 for (i = 0; i < td->td_customValueCount; i++) { | |
771 | |
772 tv = td->td_customValues + i; | |
773 if( tv->info->field_tag == tag ) | |
774 break; | |
775 } | |
776 | |
777 if( i < td->td_customValueCount ) | |
778 { | |
779 _TIFFfree(tv->value); | |
780 for( ; i < td->td_customValueCount-1; i++) { | |
781 td->td_customValues[i] = td->td_customValues[i+1]; | |
782 } | |
783 td->td_customValueCount--; | |
784 } | |
785 } | |
786 | |
787 tif->tif_flags |= TIFF_DIRTYDIRECT; | |
788 | |
789 return (1); | |
790 } | |
791 | |
792 /* | |
793 * Like TIFFSetField, but taking a varargs | |
794 * parameter list. This routine is useful | |
795 * for building higher-level interfaces on | |
796 * top of the library. | |
797 */ | |
798 int | |
799 TIFFVSetField(TIFF* tif, uint32 tag, va_list ap) | |
800 { | |
801 return OkToChangeTag(tif, tag) ? | |
802 (*tif->tif_tagmethods.vsetfield)(tif, tag, ap) : 0; | |
803 } | |
804 | |
805 static int | |
806 _TIFFVGetField(TIFF* tif, uint32 tag, va_list ap) | |
807 { | |
808 TIFFDirectory* td = &tif->tif_dir; | |
809 int ret_val = 1; | |
810 uint32 standard_tag = tag; | |
811 const TIFFField* fip = TIFFFindField(tif, tag, TIFF_ANY); | |
812 | |
813 /* | |
814 * We want to force the custom code to be used for custom | |
815 * fields even if the tag happens to match a well known | |
816 * one - important for reinterpreted handling of standard | |
817 * tag values in custom directories (ie. EXIF) | |
818 */ | |
819 if (fip->field_bit == FIELD_CUSTOM) { | |
820 standard_tag = 0; | |
821 } | |
822 | |
823 switch (standard_tag) { | |
824 case TIFFTAG_SUBFILETYPE: | |
825 *va_arg(ap, uint32*) = td->td_subfiletype; | |
826 break; | |
827 case TIFFTAG_IMAGEWIDTH: | |
828 *va_arg(ap, uint32*) = td->td_imagewidth; | |
829 break; | |
830 case TIFFTAG_IMAGELENGTH: | |
831 *va_arg(ap, uint32*) = td->td_imagelength; | |
832 break; | |
833 case TIFFTAG_BITSPERSAMPLE: | |
834 *va_arg(ap, uint16*) = td->td_bitspersample; | |
835 break; | |
836 case TIFFTAG_COMPRESSION: | |
837 *va_arg(ap, uint16*) = td->td_compression; | |
838 break; | |
839 case TIFFTAG_PHOTOMETRIC: | |
840 *va_arg(ap, uint16*) = td->td_photometric; | |
841 break; | |
842 case TIFFTAG_THRESHHOLDING: | |
843 *va_arg(ap, uint16*) = td->td_threshholding; | |
844 break; | |
845 case TIFFTAG_FILLORDER: | |
846 *va_arg(ap, uint16*) = td->td_fillorder; | |
847 break; | |
848 case TIFFTAG_ORIENTATION: | |
849 *va_arg(ap, uint16*) = td->td_orientation; | |
850 break; | |
851 case TIFFTAG_SAMPLESPERPIXEL: | |
852 *va_arg(ap, uint16*) = td->td_samplesperpixel; | |
853 break; | |
854 case TIFFTAG_ROWSPERSTRIP: | |
855 *va_arg(ap, uint32*) = td->td_rowsperstrip; | |
856 break; | |
857 case TIFFTAG_MINSAMPLEVALUE: | |
858 *va_arg(ap, uint16*) = td->td_minsamplevalue; | |
859 break; | |
860 case TIFFTAG_MAXSAMPLEVALUE: | |
861 *va_arg(ap, uint16*) = td->td_maxsamplevalue; | |
862 break; | |
863 case TIFFTAG_SMINSAMPLEVALUE: | |
864 if (tif->tif_flags & TIFF_PERSAMPLE) | |
865 *va_arg(ap, double**) = td->td_sminsamplevalue; | |
866 else | |
867 { | |
868 /* libtiff historially treats this as a single v
alue. */ | |
869 uint16 i; | |
870 double v = td->td_sminsamplevalue[0]; | |
871 for (i=1; i < td->td_samplesperpixel; ++i) | |
872 if( td->td_sminsamplevalue[i] < v ) | |
873 v = td->td_sminsamplevalue[i]; | |
874 *va_arg(ap, double*) = v; | |
875 } | |
876 break; | |
877 case TIFFTAG_SMAXSAMPLEVALUE: | |
878 if (tif->tif_flags & TIFF_PERSAMPLE) | |
879 *va_arg(ap, double**) = td->td_smaxsamplevalue; | |
880 else | |
881 { | |
882 /* libtiff historially treats this as a single v
alue. */ | |
883 uint16 i; | |
884 double v = td->td_smaxsamplevalue[0]; | |
885 for (i=1; i < td->td_samplesperpixel; ++i) | |
886 if( td->td_smaxsamplevalue[i] > v ) | |
887 v = td->td_smaxsamplevalue[i]; | |
888 *va_arg(ap, double*) = v; | |
889 } | |
890 break; | |
891 case TIFFTAG_XRESOLUTION: | |
892 *va_arg(ap, float*) = td->td_xresolution; | |
893 break; | |
894 case TIFFTAG_YRESOLUTION: | |
895 *va_arg(ap, float*) = td->td_yresolution; | |
896 break; | |
897 case TIFFTAG_PLANARCONFIG: | |
898 *va_arg(ap, uint16*) = td->td_planarconfig; | |
899 break; | |
900 case TIFFTAG_XPOSITION: | |
901 *va_arg(ap, float*) = td->td_xposition; | |
902 break; | |
903 case TIFFTAG_YPOSITION: | |
904 *va_arg(ap, float*) = td->td_yposition; | |
905 break; | |
906 case TIFFTAG_RESOLUTIONUNIT: | |
907 *va_arg(ap, uint16*) = td->td_resolutionunit; | |
908 break; | |
909 case TIFFTAG_PAGENUMBER: | |
910 *va_arg(ap, uint16*) = td->td_pagenumber[0]; | |
911 *va_arg(ap, uint16*) = td->td_pagenumber[1]; | |
912 break; | |
913 case TIFFTAG_HALFTONEHINTS: | |
914 *va_arg(ap, uint16*) = td->td_halftonehints[0]; | |
915 *va_arg(ap, uint16*) = td->td_halftonehints[1]; | |
916 break; | |
917 case TIFFTAG_COLORMAP: | |
918 *va_arg(ap, uint16**) = td->td_colormap[0]; | |
919 *va_arg(ap, uint16**) = td->td_colormap[1]; | |
920 *va_arg(ap, uint16**) = td->td_colormap[2]; | |
921 break; | |
922 case TIFFTAG_STRIPOFFSETS: | |
923 case TIFFTAG_TILEOFFSETS: | |
924 _TIFFFillStriles( tif ); | |
925 *va_arg(ap, uint64**) = td->td_stripoffset; | |
926 break; | |
927 case TIFFTAG_STRIPBYTECOUNTS: | |
928 case TIFFTAG_TILEBYTECOUNTS: | |
929 _TIFFFillStriles( tif ); | |
930 *va_arg(ap, uint64**) = td->td_stripbytecount; | |
931 break; | |
932 case TIFFTAG_MATTEING: | |
933 *va_arg(ap, uint16*) = | |
934 (td->td_extrasamples == 1 && | |
935 td->td_sampleinfo[0] == EXTRASAMPLE_ASSOCALPHA); | |
936 break; | |
937 case TIFFTAG_EXTRASAMPLES: | |
938 *va_arg(ap, uint16*) = td->td_extrasamples; | |
939 *va_arg(ap, uint16**) = td->td_sampleinfo; | |
940 break; | |
941 case TIFFTAG_TILEWIDTH: | |
942 *va_arg(ap, uint32*) = td->td_tilewidth; | |
943 break; | |
944 case TIFFTAG_TILELENGTH: | |
945 *va_arg(ap, uint32*) = td->td_tilelength; | |
946 break; | |
947 case TIFFTAG_TILEDEPTH: | |
948 *va_arg(ap, uint32*) = td->td_tiledepth; | |
949 break; | |
950 case TIFFTAG_DATATYPE: | |
951 switch (td->td_sampleformat) { | |
952 case SAMPLEFORMAT_UINT: | |
953 *va_arg(ap, uint16*) = DATATYPE_UINT; | |
954 break; | |
955 case SAMPLEFORMAT_INT: | |
956 *va_arg(ap, uint16*) = DATATYPE_INT; | |
957 break; | |
958 case SAMPLEFORMAT_IEEEFP: | |
959 *va_arg(ap, uint16*) = DATATYPE_IEEEFP; | |
960 break; | |
961 case SAMPLEFORMAT_VOID: | |
962 *va_arg(ap, uint16*) = DATATYPE_VOID; | |
963 break; | |
964 } | |
965 break; | |
966 case TIFFTAG_SAMPLEFORMAT: | |
967 *va_arg(ap, uint16*) = td->td_sampleformat; | |
968 break; | |
969 case TIFFTAG_IMAGEDEPTH: | |
970 *va_arg(ap, uint32*) = td->td_imagedepth; | |
971 break; | |
972 case TIFFTAG_SUBIFD: | |
973 *va_arg(ap, uint16*) = td->td_nsubifd; | |
974 *va_arg(ap, uint64**) = td->td_subifd; | |
975 break; | |
976 case TIFFTAG_YCBCRPOSITIONING: | |
977 *va_arg(ap, uint16*) = td->td_ycbcrpositioning; | |
978 break; | |
979 case TIFFTAG_YCBCRSUBSAMPLING: | |
980 *va_arg(ap, uint16*) = td->td_ycbcrsubsampling[0]; | |
981 *va_arg(ap, uint16*) = td->td_ycbcrsubsampling[1]; | |
982 break; | |
983 case TIFFTAG_TRANSFERFUNCTION: | |
984 *va_arg(ap, uint16**) = td->td_transferfunction[0]; | |
985 if (td->td_samplesperpixel - td->td_extrasamples > 1) { | |
986 *va_arg(ap, uint16**) = td->td_transferfunction[
1]; | |
987 *va_arg(ap, uint16**) = td->td_transferfunction[
2]; | |
988 } | |
989 break; | |
990 case TIFFTAG_REFERENCEBLACKWHITE: | |
991 *va_arg(ap, float**) = td->td_refblackwhite; | |
992 break; | |
993 case TIFFTAG_INKNAMES: | |
994 *va_arg(ap, char**) = td->td_inknames; | |
995 break; | |
996 default: | |
997 { | |
998 int i; | |
999 | |
1000 /* | |
1001 * This can happen if multiple images are open | |
1002 * with different codecs which have private | |
1003 * tags. The global tag information table may | |
1004 * then have tags that are valid for one file | |
1005 * but not the other. If the client tries to | |
1006 * get a tag that is not valid for the image's | |
1007 * codec then we'll arrive here. | |
1008 */ | |
1009 if( fip == NULL || fip->field_bit != FIELD_CUSTO
M ) | |
1010 { | |
1011 TIFFErrorExt(tif->tif_clientdata, "_TIFF
VGetField", | |
1012 "%s: Invalid %stag \"%s\" " | |
1013 "(not supported by codec)", | |
1014 tif->tif_name, | |
1015 isPseudoTag(tag) ? "pseudo-" : "", | |
1016 fip ? fip->field_name : "Unknown"); | |
1017 ret_val = 0; | |
1018 break; | |
1019 } | |
1020 | |
1021 /* | |
1022 * Do we have a custom value? | |
1023 */ | |
1024 ret_val = 0; | |
1025 for (i = 0; i < td->td_customValueCount; i++) { | |
1026 TIFFTagValue *tv = td->td_customValues +
i; | |
1027 | |
1028 if (tv->info->field_tag != tag) | |
1029 continue; | |
1030 | |
1031 if (fip->field_passcount) { | |
1032 if (fip->field_readcount == TIFF
_VARIABLE2) | |
1033 *va_arg(ap, uint32*) = (
uint32)tv->count; | |
1034 else /* Assume TIFF_VARIABLE */ | |
1035 *va_arg(ap, uint16*) = (
uint16)tv->count; | |
1036 *va_arg(ap, void **) = tv->value
; | |
1037 ret_val = 1; | |
1038 } else if (fip->field_tag == TIFFTAG_DOT
RANGE | |
1039 && strcmp(fip->field_name,"Do
tRange") == 0) { | |
1040 /* TODO: This is an evil excepti
on and should not have been | |
1041 handled this way ... likely b
est if we move it into | |
1042 the directory structure with
an explicit field in | |
1043 libtiff 4.1 and assign it a F
IELD_ value */ | |
1044 *va_arg(ap, uint16*) = ((uint16
*)tv->value)[0]; | |
1045 *va_arg(ap, uint16*) = ((uint16
*)tv->value)[1]; | |
1046 ret_val = 1; | |
1047 } else { | |
1048 if (fip->field_type == TIFF_ASCI
I | |
1049 || fip->field_readcount == T
IFF_VARIABLE | |
1050 || fip->field_readcount == T
IFF_VARIABLE2 | |
1051 || fip->field_readcount == T
IFF_SPP | |
1052 || tv->count > 1) { | |
1053 *va_arg(ap, void **) = t
v->value; | |
1054 ret_val = 1; | |
1055 } else { | |
1056 char *val = (char *)tv->
value; | |
1057 assert( tv->count == 1 )
; | |
1058 switch (fip->field_type)
{ | |
1059 case TIFF_BYTE: | |
1060 case TIFF_UNDEFINED: | |
1061 *va_arg(ap, uint
8*) = | |
1062 *(uint8
*)val; | |
1063 ret_val = 1; | |
1064 break; | |
1065 case TIFF_SBYTE: | |
1066 *va_arg(ap, int8
*) = | |
1067 *(int8 *
)val; | |
1068 ret_val = 1; | |
1069 break; | |
1070 case TIFF_SHORT: | |
1071 *va_arg(ap, uint
16*) = | |
1072 *(uint16
*)val; | |
1073 ret_val = 1; | |
1074 break; | |
1075 case TIFF_SSHORT: | |
1076 *va_arg(ap, int1
6*) = | |
1077 *(int16
*)val; | |
1078 ret_val = 1; | |
1079 break; | |
1080 case TIFF_LONG: | |
1081 case TIFF_IFD: | |
1082 *va_arg(ap, uint
32*) = | |
1083 *(uint32
*)val; | |
1084 ret_val = 1; | |
1085 break; | |
1086 case TIFF_SLONG: | |
1087 *va_arg(ap, int3
2*) = | |
1088 *(int32
*)val; | |
1089 ret_val = 1; | |
1090 break; | |
1091 case TIFF_LONG8: | |
1092 case TIFF_IFD8: | |
1093 *va_arg(ap, uint
64*) = | |
1094 *(uint64
*)val; | |
1095 ret_val = 1; | |
1096 break; | |
1097 case TIFF_SLONG8: | |
1098 *va_arg(ap, int6
4*) = | |
1099 *(int64
*)val; | |
1100 ret_val = 1; | |
1101 break; | |
1102 case TIFF_RATIONAL: | |
1103 case TIFF_SRATIONAL: | |
1104 case TIFF_FLOAT: | |
1105 *va_arg(ap, floa
t*) = | |
1106 *(float
*)val; | |
1107 ret_val = 1; | |
1108 break; | |
1109 case TIFF_DOUBLE: | |
1110 *va_arg(ap, doub
le*) = | |
1111 *(double
*)val; | |
1112 ret_val = 1; | |
1113 break; | |
1114 default: | |
1115 ret_val = 0; | |
1116 break; | |
1117 } | |
1118 } | |
1119 } | |
1120 break; | |
1121 } | |
1122 } | |
1123 } | |
1124 return(ret_val); | |
1125 } | |
1126 | |
1127 /* | |
1128 * Return the value of a field in the | |
1129 * internal directory structure. | |
1130 */ | |
1131 int | |
1132 TIFFGetField(TIFF* tif, uint32 tag, ...) | |
1133 { | |
1134 int status; | |
1135 va_list ap; | |
1136 | |
1137 va_start(ap, tag); | |
1138 status = TIFFVGetField(tif, tag, ap); | |
1139 va_end(ap); | |
1140 return (status); | |
1141 } | |
1142 | |
1143 /* | |
1144 * Like TIFFGetField, but taking a varargs | |
1145 * parameter list. This routine is useful | |
1146 * for building higher-level interfaces on | |
1147 * top of the library. | |
1148 */ | |
1149 int | |
1150 TIFFVGetField(TIFF* tif, uint32 tag, va_list ap) | |
1151 { | |
1152 const TIFFField* fip = TIFFFindField(tif, tag, TIFF_ANY); | |
1153 return (fip && (isPseudoTag(tag) || TIFFFieldSet(tif, fip->field_bit)) ? | |
1154 (*tif->tif_tagmethods.vgetfield)(tif, tag, ap) : 0); | |
1155 } | |
1156 | |
1157 #define CleanupField(member) { \ | |
1158 if (td->member) { \ | |
1159 _TIFFfree(td->member); \ | |
1160 td->member = 0; \ | |
1161 } \ | |
1162 } | |
1163 | |
1164 /* | |
1165 * Release storage associated with a directory. | |
1166 */ | |
1167 void | |
1168 TIFFFreeDirectory(TIFF* tif) | |
1169 { | |
1170 TIFFDirectory *td = &tif->tif_dir; | |
1171 int i; | |
1172 | |
1173 _TIFFmemset(td->td_fieldsset, 0, FIELD_SETLONGS); | |
1174 CleanupField(td_sminsamplevalue); | |
1175 CleanupField(td_smaxsamplevalue); | |
1176 CleanupField(td_colormap[0]); | |
1177 CleanupField(td_colormap[1]); | |
1178 CleanupField(td_colormap[2]); | |
1179 CleanupField(td_sampleinfo); | |
1180 CleanupField(td_subifd); | |
1181 CleanupField(td_inknames); | |
1182 CleanupField(td_refblackwhite); | |
1183 CleanupField(td_transferfunction[0]); | |
1184 CleanupField(td_transferfunction[1]); | |
1185 CleanupField(td_transferfunction[2]); | |
1186 CleanupField(td_stripoffset); | |
1187 CleanupField(td_stripbytecount); | |
1188 TIFFClrFieldBit(tif, FIELD_YCBCRSUBSAMPLING); | |
1189 TIFFClrFieldBit(tif, FIELD_YCBCRPOSITIONING); | |
1190 | |
1191 /* Cleanup custom tag values */ | |
1192 for( i = 0; i < td->td_customValueCount; i++ ) { | |
1193 if (td->td_customValues[i].value) | |
1194 _TIFFfree(td->td_customValues[i].value); | |
1195 } | |
1196 | |
1197 td->td_customValueCount = 0; | |
1198 CleanupField(td_customValues); | |
1199 | |
1200 #if defined(DEFER_STRILE_LOAD) | |
1201 _TIFFmemset( &(td->td_stripoffset_entry), 0, sizeof(TIFFDirEntry)); | |
1202 _TIFFmemset( &(td->td_stripbytecount_entry), 0, sizeof(TIFFDirEntry)); | |
1203 #endif | |
1204 } | |
1205 #undef CleanupField | |
1206 | |
1207 /* | |
1208 * Client Tag extension support (from Niles Ritter). | |
1209 */ | |
1210 static TIFFExtendProc _TIFFextender = (TIFFExtendProc) NULL; | |
1211 | |
1212 TIFFExtendProc | |
1213 TIFFSetTagExtender(TIFFExtendProc extender) | |
1214 { | |
1215 TIFFExtendProc prev = _TIFFextender; | |
1216 _TIFFextender = extender; | |
1217 return (prev); | |
1218 } | |
1219 | |
1220 /* | |
1221 * Setup for a new directory. Should we automatically call | |
1222 * TIFFWriteDirectory() if the current one is dirty? | |
1223 * | |
1224 * The newly created directory will not exist on the file till | |
1225 * TIFFWriteDirectory(), TIFFFlush() or TIFFClose() is called. | |
1226 */ | |
1227 int | |
1228 TIFFCreateDirectory(TIFF* tif) | |
1229 { | |
1230 TIFFDefaultDirectory(tif); | |
1231 tif->tif_diroff = 0; | |
1232 tif->tif_nextdiroff = 0; | |
1233 tif->tif_curoff = 0; | |
1234 tif->tif_row = (uint32) -1; | |
1235 tif->tif_curstrip = (uint32) -1; | |
1236 | |
1237 return 0; | |
1238 } | |
1239 | |
1240 int | |
1241 TIFFCreateCustomDirectory(TIFF* tif, const TIFFFieldArray* infoarray) | |
1242 { | |
1243 TIFFDefaultDirectory(tif); | |
1244 | |
1245 /* | |
1246 * Reset the field definitions to match the application provided list. | |
1247 * Hopefully TIFFDefaultDirectory() won't have done anything irreversabl
e | |
1248 * based on it's assumption this is an image directory. | |
1249 */ | |
1250 _TIFFSetupFields(tif, infoarray); | |
1251 | |
1252 tif->tif_diroff = 0; | |
1253 tif->tif_nextdiroff = 0; | |
1254 tif->tif_curoff = 0; | |
1255 tif->tif_row = (uint32) -1; | |
1256 tif->tif_curstrip = (uint32) -1; | |
1257 | |
1258 return 0; | |
1259 } | |
1260 | |
1261 int | |
1262 TIFFCreateEXIFDirectory(TIFF* tif) | |
1263 { | |
1264 const TIFFFieldArray* exifFieldArray; | |
1265 exifFieldArray = _TIFFGetExifFields(); | |
1266 return TIFFCreateCustomDirectory(tif, exifFieldArray); | |
1267 } | |
1268 | |
1269 /* | |
1270 * Setup a default directory structure. | |
1271 */ | |
1272 int | |
1273 TIFFDefaultDirectory(TIFF* tif) | |
1274 { | |
1275 register TIFFDirectory* td = &tif->tif_dir; | |
1276 const TIFFFieldArray* tiffFieldArray; | |
1277 | |
1278 tiffFieldArray = _TIFFGetFields(); | |
1279 _TIFFSetupFields(tif, tiffFieldArray); | |
1280 | |
1281 _TIFFmemset(td, 0, sizeof (*td)); | |
1282 td->td_fillorder = FILLORDER_MSB2LSB; | |
1283 td->td_bitspersample = 1; | |
1284 td->td_threshholding = THRESHHOLD_BILEVEL; | |
1285 td->td_orientation = ORIENTATION_TOPLEFT; | |
1286 td->td_samplesperpixel = 1; | |
1287 td->td_rowsperstrip = (uint32) -1; | |
1288 td->td_tilewidth = 0; | |
1289 td->td_tilelength = 0; | |
1290 td->td_tiledepth = 1; | |
1291 td->td_stripbytecountsorted = 1; /* Our own arrays always sorted. */ | |
1292 td->td_resolutionunit = RESUNIT_INCH; | |
1293 td->td_sampleformat = SAMPLEFORMAT_UINT; | |
1294 td->td_imagedepth = 1; | |
1295 td->td_ycbcrsubsampling[0] = 2; | |
1296 td->td_ycbcrsubsampling[1] = 2; | |
1297 td->td_ycbcrpositioning = YCBCRPOSITION_CENTERED; | |
1298 tif->tif_postdecode = _TIFFNoPostDecode; | |
1299 tif->tif_foundfield = NULL; | |
1300 tif->tif_tagmethods.vsetfield = _TIFFVSetField; | |
1301 tif->tif_tagmethods.vgetfield = _TIFFVGetField; | |
1302 tif->tif_tagmethods.printdir = NULL; | |
1303 /* | |
1304 * Give client code a chance to install their own | |
1305 * tag extensions & methods, prior to compression overloads. | |
1306 */ | |
1307 if (_TIFFextender) | |
1308 (*_TIFFextender)(tif); | |
1309 (void) TIFFSetField(tif, TIFFTAG_COMPRESSION, COMPRESSION_NONE); | |
1310 /* | |
1311 * NB: The directory is marked dirty as a result of setting | |
1312 * up the default compression scheme. However, this really | |
1313 * isn't correct -- we want TIFF_DIRTYDIRECT to be set only | |
1314 * if the user does something. We could just do the setup | |
1315 * by hand, but it seems better to use the normal mechanism | |
1316 * (i.e. TIFFSetField). | |
1317 */ | |
1318 tif->tif_flags &= ~TIFF_DIRTYDIRECT; | |
1319 | |
1320 /* | |
1321 * As per http://bugzilla.remotesensing.org/show_bug.cgi?id=19 | |
1322 * we clear the ISTILED flag when setting up a new directory. | |
1323 * Should we also be clearing stuff like INSUBIFD? | |
1324 */ | |
1325 tif->tif_flags &= ~TIFF_ISTILED; | |
1326 | |
1327 return (1); | |
1328 } | |
1329 | |
1330 static int | |
1331 TIFFAdvanceDirectory(TIFF* tif, uint64* nextdir, uint64* off) | |
1332 { | |
1333 static const char module[] = "TIFFAdvanceDirectory"; | |
1334 if (isMapped(tif)) | |
1335 { | |
1336 uint64 poff=*nextdir; | |
1337 if (!(tif->tif_flags&TIFF_BIGTIFF)) | |
1338 { | |
1339 tmsize_t poffa,poffb,poffc,poffd; | |
1340 uint16 dircount; | |
1341 uint32 nextdir32; | |
1342 poffa=(tmsize_t)poff; | |
1343 poffb=poffa+sizeof(uint16); | |
1344 if (((uint64)poffa!=poff)||(poffb<poffa)||(poffb<(tmsize
_t)sizeof(uint16))||(poffb>tif->tif_size)) | |
1345 { | |
1346 TIFFErrorExt(tif->tif_clientdata,module,"Error f
etching directory count"); | |
1347 return(0); | |
1348 } | |
1349 _TIFFmemcpy(&dircount,tif->tif_base+poffa,sizeof(uint16)
); | |
1350 if (tif->tif_flags&TIFF_SWAB) | |
1351 TIFFSwabShort(&dircount); | |
1352 poffc=poffb+dircount*12; | |
1353 poffd=poffc+sizeof(uint32); | |
1354 if ((poffc<poffb)||(poffc<dircount*12)||(poffd<poffc)||(
poffd<(tmsize_t)sizeof(uint32))||(poffd>tif->tif_size)) | |
1355 { | |
1356 TIFFErrorExt(tif->tif_clientdata,module,"Error f
etching directory link"); | |
1357 return(0); | |
1358 } | |
1359 if (off!=NULL) | |
1360 *off=(uint64)poffc; | |
1361 _TIFFmemcpy(&nextdir32,tif->tif_base+poffc,sizeof(uint32
)); | |
1362 if (tif->tif_flags&TIFF_SWAB) | |
1363 TIFFSwabLong(&nextdir32); | |
1364 *nextdir=nextdir32; | |
1365 } | |
1366 else | |
1367 { | |
1368 tmsize_t poffa,poffb,poffc,poffd; | |
1369 uint64 dircount64; | |
1370 uint16 dircount16; | |
1371 poffa=(tmsize_t)poff; | |
1372 poffb=poffa+sizeof(uint64); | |
1373 if (((uint64)poffa!=poff)||(poffb<poffa)||(poffb<(tmsize
_t)sizeof(uint64))||(poffb>tif->tif_size)) | |
1374 { | |
1375 TIFFErrorExt(tif->tif_clientdata,module,"Error f
etching directory count"); | |
1376 return(0); | |
1377 } | |
1378 _TIFFmemcpy(&dircount64,tif->tif_base+poffa,sizeof(uint6
4)); | |
1379 if (tif->tif_flags&TIFF_SWAB) | |
1380 TIFFSwabLong8(&dircount64); | |
1381 if (dircount64>0xFFFF) | |
1382 { | |
1383 TIFFErrorExt(tif->tif_clientdata,module,"Sanity
check on directory count failed"); | |
1384 return(0); | |
1385 } | |
1386 dircount16=(uint16)dircount64; | |
1387 poffc=poffb+dircount16*20; | |
1388 poffd=poffc+sizeof(uint64); | |
1389 if ((poffc<poffb)||(poffc<dircount16*20)||(poffd<poffc)|
|(poffd<(tmsize_t)sizeof(uint64))||(poffd>tif->tif_size)) | |
1390 { | |
1391 TIFFErrorExt(tif->tif_clientdata,module,"Error f
etching directory link"); | |
1392 return(0); | |
1393 } | |
1394 if (off!=NULL) | |
1395 *off=(uint64)poffc; | |
1396 _TIFFmemcpy(nextdir,tif->tif_base+poffc,sizeof(uint64)); | |
1397 if (tif->tif_flags&TIFF_SWAB) | |
1398 TIFFSwabLong8(nextdir); | |
1399 } | |
1400 return(1); | |
1401 } | |
1402 else | |
1403 { | |
1404 if (!(tif->tif_flags&TIFF_BIGTIFF)) | |
1405 { | |
1406 uint16 dircount; | |
1407 uint32 nextdir32; | |
1408 if (!SeekOK(tif, *nextdir) || | |
1409 !ReadOK(tif, &dircount, sizeof (uint16))) { | |
1410 TIFFErrorExt(tif->tif_clientdata, module, "%s: E
rror fetching directory count", | |
1411 tif->tif_name); | |
1412 return (0); | |
1413 } | |
1414 if (tif->tif_flags & TIFF_SWAB) | |
1415 TIFFSwabShort(&dircount); | |
1416 if (off != NULL) | |
1417 *off = TIFFSeekFile(tif, | |
1418 dircount*12, SEEK_CUR); | |
1419 else | |
1420 (void) TIFFSeekFile(tif, | |
1421 dircount*12, SEEK_CUR); | |
1422 if (!ReadOK(tif, &nextdir32, sizeof (uint32))) { | |
1423 TIFFErrorExt(tif->tif_clientdata, module, "%s: E
rror fetching directory link", | |
1424 tif->tif_name); | |
1425 return (0); | |
1426 } | |
1427 if (tif->tif_flags & TIFF_SWAB) | |
1428 TIFFSwabLong(&nextdir32); | |
1429 *nextdir=nextdir32; | |
1430 } | |
1431 else | |
1432 { | |
1433 uint64 dircount64; | |
1434 uint16 dircount16; | |
1435 if (!SeekOK(tif, *nextdir) || | |
1436 !ReadOK(tif, &dircount64, sizeof (uint64))) { | |
1437 TIFFErrorExt(tif->tif_clientdata, module, "%s: E
rror fetching directory count", | |
1438 tif->tif_name); | |
1439 return (0); | |
1440 } | |
1441 if (tif->tif_flags & TIFF_SWAB) | |
1442 TIFFSwabLong8(&dircount64); | |
1443 if (dircount64>0xFFFF) | |
1444 { | |
1445 TIFFErrorExt(tif->tif_clientdata, module, "Error
fetching directory count"); | |
1446 return(0); | |
1447 } | |
1448 dircount16 = (uint16)dircount64; | |
1449 if (off != NULL) | |
1450 *off = TIFFSeekFile(tif, | |
1451 dircount16*20, SEEK_CUR); | |
1452 else | |
1453 (void) TIFFSeekFile(tif, | |
1454 dircount16*20, SEEK_CUR); | |
1455 if (!ReadOK(tif, nextdir, sizeof (uint64))) { | |
1456 TIFFErrorExt(tif->tif_clientdata, module, "%s: E
rror fetching directory link", | |
1457 tif->tif_name); | |
1458 return (0); | |
1459 } | |
1460 if (tif->tif_flags & TIFF_SWAB) | |
1461 TIFFSwabLong8(nextdir); | |
1462 } | |
1463 return (1); | |
1464 } | |
1465 } | |
1466 | |
1467 /* | |
1468 * Count the number of directories in a file. | |
1469 */ | |
1470 uint16 | |
1471 TIFFNumberOfDirectories(TIFF* tif) | |
1472 { | |
1473 uint64 nextdir; | |
1474 uint16 n; | |
1475 if (!(tif->tif_flags&TIFF_BIGTIFF)) | |
1476 nextdir = tif->tif_header.classic.tiff_diroff; | |
1477 else | |
1478 nextdir = tif->tif_header.big.tiff_diroff; | |
1479 n = 0; | |
1480 while (nextdir != 0 && TIFFAdvanceDirectory(tif, &nextdir, NULL)) | |
1481 n++; | |
1482 return (n); | |
1483 } | |
1484 | |
1485 /* | |
1486 * Set the n-th directory as the current directory. | |
1487 * NB: Directories are numbered starting at 0. | |
1488 */ | |
1489 int | |
1490 TIFFSetDirectory(TIFF* tif, uint16 dirn) | |
1491 { | |
1492 uint64 nextdir; | |
1493 uint16 n; | |
1494 | |
1495 if (!(tif->tif_flags&TIFF_BIGTIFF)) | |
1496 nextdir = tif->tif_header.classic.tiff_diroff; | |
1497 else | |
1498 nextdir = tif->tif_header.big.tiff_diroff; | |
1499 for (n = dirn; n > 0 && nextdir != 0; n--) | |
1500 if (!TIFFAdvanceDirectory(tif, &nextdir, NULL)) | |
1501 return (0); | |
1502 tif->tif_nextdiroff = nextdir; | |
1503 /* | |
1504 * Set curdir to the actual directory index. The | |
1505 * -1 is because TIFFReadDirectory will increment | |
1506 * tif_curdir after successfully reading the directory. | |
1507 */ | |
1508 tif->tif_curdir = (dirn - n) - 1; | |
1509 /* | |
1510 * Reset tif_dirnumber counter and start new list of seen directories. | |
1511 * We need this to prevent IFD loops. | |
1512 */ | |
1513 tif->tif_dirnumber = 0; | |
1514 return (TIFFReadDirectory(tif)); | |
1515 } | |
1516 | |
1517 /* | |
1518 * Set the current directory to be the directory | |
1519 * located at the specified file offset. This interface | |
1520 * is used mainly to access directories linked with | |
1521 * the SubIFD tag (e.g. thumbnail images). | |
1522 */ | |
1523 int | |
1524 TIFFSetSubDirectory(TIFF* tif, uint64 diroff) | |
1525 { | |
1526 tif->tif_nextdiroff = diroff; | |
1527 /* | |
1528 * Reset tif_dirnumber counter and start new list of seen directories. | |
1529 * We need this to prevent IFD loops. | |
1530 */ | |
1531 tif->tif_dirnumber = 0; | |
1532 return (TIFFReadDirectory(tif)); | |
1533 } | |
1534 | |
1535 /* | |
1536 * Return file offset of the current directory. | |
1537 */ | |
1538 uint64 | |
1539 TIFFCurrentDirOffset(TIFF* tif) | |
1540 { | |
1541 return (tif->tif_diroff); | |
1542 } | |
1543 | |
1544 /* | |
1545 * Return an indication of whether or not we are | |
1546 * at the last directory in the file. | |
1547 */ | |
1548 int | |
1549 TIFFLastDirectory(TIFF* tif) | |
1550 { | |
1551 return (tif->tif_nextdiroff == 0); | |
1552 } | |
1553 | |
1554 /* | |
1555 * Unlink the specified directory from the directory chain. | |
1556 */ | |
1557 int | |
1558 TIFFUnlinkDirectory(TIFF* tif, uint16 dirn) | |
1559 { | |
1560 static const char module[] = "TIFFUnlinkDirectory"; | |
1561 uint64 nextdir; | |
1562 uint64 off; | |
1563 uint16 n; | |
1564 | |
1565 if (tif->tif_mode == O_RDONLY) { | |
1566 TIFFErrorExt(tif->tif_clientdata, module, | |
1567 "Can not unlink directory in read-only file"); | |
1568 return (0); | |
1569 } | |
1570 /* | |
1571 * Go to the directory before the one we want | |
1572 * to unlink and nab the offset of the link | |
1573 * field we'll need to patch. | |
1574 */ | |
1575 if (!(tif->tif_flags&TIFF_BIGTIFF)) | |
1576 { | |
1577 nextdir = tif->tif_header.classic.tiff_diroff; | |
1578 off = 4; | |
1579 } | |
1580 else | |
1581 { | |
1582 nextdir = tif->tif_header.big.tiff_diroff; | |
1583 off = 8; | |
1584 } | |
1585 for (n = dirn-1; n > 0; n--) { | |
1586 if (nextdir == 0) { | |
1587 TIFFErrorExt(tif->tif_clientdata, module, "Directory %d
does not exist", dirn); | |
1588 return (0); | |
1589 } | |
1590 if (!TIFFAdvanceDirectory(tif, &nextdir, &off)) | |
1591 return (0); | |
1592 } | |
1593 /* | |
1594 * Advance to the directory to be unlinked and fetch | |
1595 * the offset of the directory that follows. | |
1596 */ | |
1597 if (!TIFFAdvanceDirectory(tif, &nextdir, NULL)) | |
1598 return (0); | |
1599 /* | |
1600 * Go back and patch the link field of the preceding | |
1601 * directory to point to the offset of the directory | |
1602 * that follows. | |
1603 */ | |
1604 (void) TIFFSeekFile(tif, off, SEEK_SET); | |
1605 if (!(tif->tif_flags&TIFF_BIGTIFF)) | |
1606 { | |
1607 uint32 nextdir32; | |
1608 nextdir32=(uint32)nextdir; | |
1609 assert((uint64)nextdir32==nextdir); | |
1610 if (tif->tif_flags & TIFF_SWAB) | |
1611 TIFFSwabLong(&nextdir32); | |
1612 if (!WriteOK(tif, &nextdir32, sizeof (uint32))) { | |
1613 TIFFErrorExt(tif->tif_clientdata, module, "Error writing
directory link"); | |
1614 return (0); | |
1615 } | |
1616 } | |
1617 else | |
1618 { | |
1619 if (tif->tif_flags & TIFF_SWAB) | |
1620 TIFFSwabLong8(&nextdir); | |
1621 if (!WriteOK(tif, &nextdir, sizeof (uint64))) { | |
1622 TIFFErrorExt(tif->tif_clientdata, module, "Error writing
directory link"); | |
1623 return (0); | |
1624 } | |
1625 } | |
1626 /* | |
1627 * Leave directory state setup safely. We don't have | |
1628 * facilities for doing inserting and removing directories, | |
1629 * so it's safest to just invalidate everything. This | |
1630 * means that the caller can only append to the directory | |
1631 * chain. | |
1632 */ | |
1633 (*tif->tif_cleanup)(tif); | |
1634 if ((tif->tif_flags & TIFF_MYBUFFER) && tif->tif_rawdata) { | |
1635 _TIFFfree(tif->tif_rawdata); | |
1636 tif->tif_rawdata = NULL; | |
1637 tif->tif_rawcc = 0; | |
1638 tif->tif_rawdataoff = 0; | |
1639 tif->tif_rawdataloaded = 0; | |
1640 } | |
1641 tif->tif_flags &= ~(TIFF_BEENWRITING|TIFF_BUFFERSETUP|TIFF_POSTENCODE|TI
FF_BUF4WRITE); | |
1642 TIFFFreeDirectory(tif); | |
1643 TIFFDefaultDirectory(tif); | |
1644 tif->tif_diroff = 0; /* force link on next write */ | |
1645 tif->tif_nextdiroff = 0; /* next write must be at end */ | |
1646 tif->tif_curoff = 0; | |
1647 tif->tif_row = (uint32) -1; | |
1648 tif->tif_curstrip = (uint32) -1; | |
1649 return (1); | |
1650 } | |
1651 | |
1652 /* vim: set ts=8 sts=8 sw=8 noet: */ | |
1653 /* | |
1654 * Local Variables: | |
1655 * mode: c | |
1656 * c-basic-offset: 8 | |
1657 * fill-column: 78 | |
1658 * End: | |
1659 */ | |
1660 | |
OLD | NEW |