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 10325 : setByteArray(void** vpp, void* vp, size_t nmemb, size_t elem_size)
45 : {
46 10325 : if (*vpp)
47 25 : _TIFFfree(*vpp), *vpp = 0;
48 10325 : if (vp) {
49 10325 : tmsize_t bytes = (tmsize_t)(nmemb * elem_size);
50 10325 : if (elem_size && bytes / elem_size == nmemb)
51 10325 : *vpp = (void*) _TIFFmalloc(bytes);
52 10325 : if (*vpp)
53 10325 : _TIFFmemcpy(*vpp, vp, bytes);
54 : }
55 10325 : }
56 251 : void _TIFFsetByteArray(void** vpp, void* vp, uint32 n)
57 251 : { setByteArray(vpp, vp, n, 1); }
58 0 : void _TIFFsetString(char** cpp, char* cp)
59 0 : { setByteArray((void**) cpp, (void*) cp, strlen(cp)+1, 1); }
60 0 : void _TIFFsetNString(char** cpp, char* cp, uint32 n)
61 0 : { setByteArray((void**) cpp, (void*) cp, n, 1); }
62 1452 : void _TIFFsetShortArray(uint16** wpp, uint16* wp, uint32 n)
63 1452 : { setByteArray((void**) wpp, (void*) wp, n, sizeof (uint16)); }
64 0 : void _TIFFsetLongArray(uint32** lpp, uint32* lp, uint32 n)
65 0 : { setByteArray((void**) lpp, (void*) lp, n, sizeof (uint32)); }
66 0 : void _TIFFsetLong8Array(uint64** lpp, uint64* lp, uint32 n)
67 0 : { setByteArray((void**) lpp, (void*) lp, n, sizeof (uint64)); }
68 221 : void _TIFFsetFloatArray(float** fpp, float* fp, uint32 n)
69 221 : { setByteArray((void**) fpp, (void*) fp, n, sizeof (float)); }
70 0 : void _TIFFsetDoubleArray(double** dpp, double* dp, uint32 n)
71 0 : { setByteArray((void**) dpp, (void*) dp, n, sizeof (double)); }
72 :
73 : static void
74 0 : setDoubleArrayOneValue(double** vpp, double value, size_t nmemb)
75 : {
76 0 : if (*vpp)
77 0 : _TIFFfree(*vpp);
78 0 : *vpp = _TIFFmalloc(nmemb*sizeof(double));
79 0 : if (*vpp)
80 : {
81 0 : while (nmemb--)
82 0 : ((double*)*vpp)[nmemb] = value;
83 : }
84 0 : }
85 :
86 : /*
87 : * Install extra samples information.
88 : */
89 : static int
90 753 : 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 753 : *v = (uint16) va_arg(ap, uint16_vap);
99 753 : if ((uint16) *v > td->td_samplesperpixel)
100 0 : return 0;
101 753 : va = va_arg(ap, uint16*);
102 753 : if (*v > 0 && va == NULL) /* typically missing param */
103 0 : return 0;
104 657135 : for (i = 0; i < *v; i++) {
105 656382 : 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 0 : if (va[i] == EXTRASAMPLE_COREL_UNASSALPHA)
113 0 : va[i] = EXTRASAMPLE_UNASSALPHA;
114 : else
115 0 : return 0;
116 : }
117 : }
118 753 : td->td_extrasamples = (uint16) *v;
119 753 : _TIFFsetShortArray(&td->td_sampleinfo, va, td->td_extrasamples);
120 753 : 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 0 : checkInkNamesString(TIFF* tif, uint32 slen, const char* s)
131 : {
132 0 : TIFFDirectory* td = &tif->tif_dir;
133 0 : uint16 i = td->td_samplesperpixel;
134 :
135 0 : if (slen > 0) {
136 0 : const char* ep = s+slen;
137 0 : const char* cp = s;
138 0 : for (; i > 0; i--) {
139 0 : for (; cp < ep && *cp != '\0'; cp++) {}
140 0 : if (cp >= ep)
141 0 : goto bad;
142 0 : cp++; /* skip \0 */
143 : }
144 0 : return ((uint32)(cp-s));
145 : }
146 : bad:
147 0 : TIFFErrorExt(tif->tif_clientdata, "TIFFSetField",
148 : "%s: Invalid InkNames value; expecting %d names, found %d",
149 : tif->tif_name,
150 0 : td->td_samplesperpixel,
151 : td->td_samplesperpixel-i);
152 0 : return (0);
153 : }
154 :
155 : static int
156 169273 : _TIFFVSetField(TIFF* tif, uint32 tag, va_list ap)
157 : {
158 : static const char module[] = "_TIFFVSetField";
159 :
160 169273 : TIFFDirectory* td = &tif->tif_dir;
161 169273 : int status = 1;
162 : uint32 v32, i, v;
163 : char* s;
164 169273 : const TIFFField *fip = TIFFFindField(tif, tag, TIFF_ANY);
165 169273 : 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 169273 : if (fip->field_bit == FIELD_CUSTOM) {
174 34210 : standard_tag = 0;
175 : }
176 :
177 169273 : switch (standard_tag) {
178 : case TIFFTAG_SUBFILETYPE:
179 2431 : td->td_subfiletype = (uint32) va_arg(ap, uint32);
180 2431 : break;
181 : case TIFFTAG_IMAGEWIDTH:
182 11704 : td->td_imagewidth = (uint32) va_arg(ap, uint32);
183 11704 : break;
184 : case TIFFTAG_IMAGELENGTH:
185 11704 : td->td_imagelength = (uint32) va_arg(ap, uint32);
186 11704 : break;
187 : case TIFFTAG_BITSPERSAMPLE:
188 11696 : 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 11696 : if (tif->tif_flags & TIFF_SWAB) {
197 436 : if (td->td_bitspersample == 8)
198 352 : tif->tif_postdecode = _TIFFNoPostDecode;
199 84 : else if (td->td_bitspersample == 16)
200 26 : tif->tif_postdecode = _TIFFSwab16BitData;
201 58 : else if (td->td_bitspersample == 24)
202 0 : tif->tif_postdecode = _TIFFSwab24BitData;
203 58 : else if (td->td_bitspersample == 32)
204 58 : tif->tif_postdecode = _TIFFSwab32BitData;
205 0 : else if (td->td_bitspersample == 64)
206 0 : tif->tif_postdecode = _TIFFSwab64BitData;
207 0 : else if (td->td_bitspersample == 128) /* two 64's */
208 0 : tif->tif_postdecode = _TIFFSwab64BitData;
209 : }
210 11696 : break;
211 : case TIFFTAG_COMPRESSION:
212 25082 : 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 25082 : if (TIFFFieldSet(tif, FIELD_COMPRESSION)) {
219 11672 : if ((uint32)td->td_compression == v)
220 10508 : break;
221 1164 : (*tif->tif_cleanup)(tif);
222 1164 : tif->tif_flags &= ~TIFF_CODERSETUP;
223 : }
224 : /*
225 : * Setup new compression routine state.
226 : */
227 14574 : if( (status = TIFFSetCompressionScheme(tif, v)) != 0 )
228 14574 : td->td_compression = (uint16) v;
229 : else
230 0 : status = 0;
231 14574 : break;
232 : case TIFFTAG_PHOTOMETRIC:
233 11697 : td->td_photometric = (uint16) va_arg(ap, uint16_vap);
234 11697 : break;
235 : case TIFFTAG_THRESHHOLDING:
236 0 : td->td_threshholding = (uint16) va_arg(ap, uint16_vap);
237 0 : break;
238 : case TIFFTAG_FILLORDER:
239 4 : v = (uint16) va_arg(ap, uint16_vap);
240 4 : if (v != FILLORDER_LSB2MSB && v != FILLORDER_MSB2LSB)
241 0 : goto badvalue;
242 4 : td->td_fillorder = (uint16) v;
243 4 : break;
244 : case TIFFTAG_ORIENTATION:
245 69 : v = (uint16) va_arg(ap, uint16_vap);
246 69 : if (v < ORIENTATION_TOPLEFT || ORIENTATION_LEFTBOT < v)
247 : goto badvalue;
248 : else
249 69 : td->td_orientation = (uint16) v;
250 69 : break;
251 : case TIFFTAG_SAMPLESPERPIXEL:
252 11696 : v = (uint16) va_arg(ap, uint16_vap);
253 11696 : if (v == 0)
254 0 : goto badvalue;
255 11696 : td->td_samplesperpixel = (uint16) v;
256 11696 : break;
257 : case TIFFTAG_ROWSPERSTRIP:
258 9259 : v32 = (uint32) va_arg(ap, uint32);
259 9259 : if (v32 == 0)
260 0 : goto badvalue32;
261 9259 : td->td_rowsperstrip = v32;
262 9259 : if (!TIFFFieldSet(tif, FIELD_TILEDIMENSIONS)) {
263 9259 : td->td_tilelength = v32;
264 9259 : td->td_tilewidth = td->td_imagewidth;
265 : }
266 9259 : break;
267 : case TIFFTAG_MINSAMPLEVALUE:
268 0 : td->td_minsamplevalue = (uint16) va_arg(ap, uint16_vap);
269 0 : break;
270 : case TIFFTAG_MAXSAMPLEVALUE:
271 0 : td->td_maxsamplevalue = (uint16) va_arg(ap, uint16_vap);
272 0 : break;
273 : case TIFFTAG_SMINSAMPLEVALUE:
274 0 : if (tif->tif_flags & TIFF_PERSAMPLE)
275 0 : _TIFFsetDoubleArray(&td->td_sminsamplevalue, va_arg(ap, double*), td->td_samplesperpixel);
276 : else
277 0 : setDoubleArrayOneValue(&td->td_sminsamplevalue, va_arg(ap, double), td->td_samplesperpixel);
278 0 : break;
279 : case TIFFTAG_SMAXSAMPLEVALUE:
280 0 : if (tif->tif_flags & TIFF_PERSAMPLE)
281 0 : _TIFFsetDoubleArray(&td->td_smaxsamplevalue, va_arg(ap, double*), td->td_samplesperpixel);
282 : else
283 0 : setDoubleArrayOneValue(&td->td_smaxsamplevalue, va_arg(ap, double), td->td_samplesperpixel);
284 0 : break;
285 : case TIFFTAG_XRESOLUTION:
286 71 : td->td_xresolution = (float) va_arg(ap, double);
287 71 : break;
288 : case TIFFTAG_YRESOLUTION:
289 71 : td->td_yresolution = (float) va_arg(ap, double);
290 71 : break;
291 : case TIFFTAG_PLANARCONFIG:
292 21898 : v = (uint16) va_arg(ap, uint16_vap);
293 21898 : if (v != PLANARCONFIG_CONTIG && v != PLANARCONFIG_SEPARATE)
294 0 : goto badvalue;
295 21898 : td->td_planarconfig = (uint16) v;
296 21898 : break;
297 : case TIFFTAG_XPOSITION:
298 0 : td->td_xposition = (float) va_arg(ap, double);
299 0 : break;
300 : case TIFFTAG_YPOSITION:
301 0 : td->td_yposition = (float) va_arg(ap, double);
302 0 : break;
303 : case TIFFTAG_RESOLUTIONUNIT:
304 71 : v = (uint16) va_arg(ap, uint16_vap);
305 71 : if (v < RESUNIT_NONE || RESUNIT_CENTIMETER < v)
306 : goto badvalue;
307 71 : td->td_resolutionunit = (uint16) v;
308 71 : break;
309 : case TIFFTAG_PAGENUMBER:
310 0 : td->td_pagenumber[0] = (uint16) va_arg(ap, uint16_vap);
311 0 : td->td_pagenumber[1] = (uint16) va_arg(ap, uint16_vap);
312 0 : break;
313 : case TIFFTAG_HALFTONEHINTS:
314 0 : td->td_halftonehints[0] = (uint16) va_arg(ap, uint16_vap);
315 0 : td->td_halftonehints[1] = (uint16) va_arg(ap, uint16_vap);
316 0 : break;
317 : case TIFFTAG_COLORMAP:
318 233 : v32 = (uint32)(1L<<td->td_bitspersample);
319 233 : _TIFFsetShortArray(&td->td_colormap[0], va_arg(ap, uint16*), v32);
320 233 : _TIFFsetShortArray(&td->td_colormap[1], va_arg(ap, uint16*), v32);
321 233 : _TIFFsetShortArray(&td->td_colormap[2], va_arg(ap, uint16*), v32);
322 233 : break;
323 : case TIFFTAG_EXTRASAMPLES:
324 753 : if (!setExtraSamples(td, ap, &v))
325 0 : goto badvalue;
326 753 : break;
327 : case TIFFTAG_MATTEING:
328 0 : td->td_extrasamples = (((uint16) va_arg(ap, uint16_vap)) != 0);
329 0 : if (td->td_extrasamples) {
330 0 : uint16 sv = EXTRASAMPLE_ASSOCALPHA;
331 0 : _TIFFsetShortArray(&td->td_sampleinfo, &sv, 1);
332 : }
333 0 : break;
334 : case TIFFTAG_TILEWIDTH:
335 2434 : v32 = (uint32) va_arg(ap, uint32);
336 2434 : if (v32 % 16) {
337 0 : if (tif->tif_mode != O_RDONLY)
338 0 : goto badvalue32;
339 0 : TIFFWarningExt(tif->tif_clientdata, tif->tif_name,
340 : "Nonstandard tile width %d, convert file", v32);
341 : }
342 2434 : td->td_tilewidth = v32;
343 2434 : tif->tif_flags |= TIFF_ISTILED;
344 2434 : break;
345 : case TIFFTAG_TILELENGTH:
346 2434 : v32 = (uint32) va_arg(ap, uint32);
347 2434 : if (v32 % 16) {
348 0 : if (tif->tif_mode != O_RDONLY)
349 0 : goto badvalue32;
350 0 : TIFFWarningExt(tif->tif_clientdata, tif->tif_name,
351 : "Nonstandard tile length %d, convert file", v32);
352 : }
353 2434 : td->td_tilelength = v32;
354 2434 : tif->tif_flags |= TIFF_ISTILED;
355 2434 : break;
356 : case TIFFTAG_TILEDEPTH:
357 0 : v32 = (uint32) va_arg(ap, uint32);
358 0 : if (v32 == 0)
359 0 : goto badvalue32;
360 0 : td->td_tiledepth = v32;
361 0 : break;
362 : case TIFFTAG_DATATYPE:
363 0 : v = (uint16) va_arg(ap, uint16_vap);
364 0 : switch (v) {
365 0 : case DATATYPE_VOID: v = SAMPLEFORMAT_VOID; break;
366 0 : case DATATYPE_INT: v = SAMPLEFORMAT_INT; break;
367 0 : case DATATYPE_UINT: v = SAMPLEFORMAT_UINT; break;
368 0 : case DATATYPE_IEEEFP: v = SAMPLEFORMAT_IEEEFP;break;
369 0 : default: goto badvalue;
370 : }
371 0 : td->td_sampleformat = (uint16) v;
372 0 : break;
373 : case TIFFTAG_SAMPLEFORMAT:
374 11525 : v = (uint16) va_arg(ap, uint16_vap);
375 11525 : if (v < SAMPLEFORMAT_UINT || SAMPLEFORMAT_COMPLEXIEEEFP < v)
376 : goto badvalue;
377 11525 : td->td_sampleformat = (uint16) v;
378 :
379 : /* Try to fix up the SWAB function for complex data. */
380 12633 : if( td->td_sampleformat == SAMPLEFORMAT_COMPLEXINT
381 11525 : && td->td_bitspersample == 32
382 1108 : && tif->tif_postdecode == _TIFFSwab32BitData )
383 0 : tif->tif_postdecode = _TIFFSwab16BitData;
384 24590 : else if( (td->td_sampleformat == SAMPLEFORMAT_COMPLEXINT
385 22312 : || td->td_sampleformat == SAMPLEFORMAT_COMPLEXIEEEFP)
386 : && td->td_bitspersample == 64
387 2278 : && tif->tif_postdecode == _TIFFSwab64BitData )
388 0 : tif->tif_postdecode = _TIFFSwab32BitData;
389 11525 : break;
390 : case TIFFTAG_IMAGEDEPTH:
391 0 : td->td_imagedepth = (uint32) va_arg(ap, uint32);
392 0 : break;
393 : case TIFFTAG_SUBIFD:
394 0 : if ((tif->tif_flags & TIFF_INSUBIFD) == 0) {
395 0 : td->td_nsubifd = (uint16) va_arg(ap, uint16_vap);
396 0 : _TIFFsetLong8Array(&td->td_subifd, (uint64*) va_arg(ap, uint64*),
397 : (long) td->td_nsubifd);
398 : } else {
399 0 : TIFFErrorExt(tif->tif_clientdata, module,
400 : "%s: Sorry, cannot nest SubIFDs",
401 : tif->tif_name);
402 0 : status = 0;
403 : }
404 0 : break;
405 : case TIFFTAG_YCBCRPOSITIONING:
406 0 : td->td_ycbcrpositioning = (uint16) va_arg(ap, uint16_vap);
407 0 : break;
408 : case TIFFTAG_YCBCRSUBSAMPLING:
409 10 : td->td_ycbcrsubsampling[0] = (uint16) va_arg(ap, uint16_vap);
410 10 : td->td_ycbcrsubsampling[1] = (uint16) va_arg(ap, uint16_vap);
411 10 : break;
412 : case TIFFTAG_TRANSFERFUNCTION:
413 0 : v = (td->td_samplesperpixel - td->td_extrasamples) > 1 ? 3 : 1;
414 0 : for (i = 0; i < v; i++)
415 0 : _TIFFsetShortArray(&td->td_transferfunction[i],
416 0 : va_arg(ap, uint16*), 1L<<td->td_bitspersample);
417 0 : break;
418 : case TIFFTAG_REFERENCEBLACKWHITE:
419 : /* XXX should check for null range */
420 221 : _TIFFsetFloatArray(&td->td_refblackwhite, va_arg(ap, float*), 6);
421 221 : break;
422 : case TIFFTAG_INKNAMES:
423 0 : v = (uint16) va_arg(ap, uint16_vap);
424 0 : s = va_arg(ap, char*);
425 0 : v = checkInkNamesString(tif, v, s);
426 0 : status = v > 0;
427 0 : if( v > 0 ) {
428 0 : _TIFFsetNString(&td->td_inknames, s, v);
429 0 : td->td_inknameslen = v;
430 : }
431 0 : break;
432 : case TIFFTAG_PERSAMPLE:
433 0 : v = (uint16) va_arg(ap, uint16_vap);
434 0 : if( v == PERSAMPLE_MULTI )
435 0 : tif->tif_flags |= TIFF_PERSAMPLE;
436 : else
437 0 : tif->tif_flags &= ~TIFF_PERSAMPLE;
438 0 : 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 copied.
451 : */
452 34210 : if(fip == NULL || fip->field_bit != FIELD_CUSTOM) {
453 0 : 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 0 : status = 0;
458 0 : break;
459 : }
460 :
461 : /*
462 : * Find the existing entry for this custom value.
463 : */
464 34210 : tv = NULL;
465 95411 : for (iCustom = 0; iCustom < td->td_customValueCount; iCustom++) {
466 61253 : if (td->td_customValues[iCustom].info->field_tag == tag) {
467 52 : tv = td->td_customValues + iCustom;
468 52 : if (tv->value != NULL) {
469 52 : _TIFFfree(tv->value);
470 52 : tv->value = NULL;
471 : }
472 52 : break;
473 : }
474 : }
475 :
476 : /*
477 : * Grow the custom list if the entry was not found.
478 : */
479 34210 : if(tv == NULL) {
480 : TIFFTagValue *new_customValues;
481 :
482 34158 : td->td_customValueCount++;
483 68316 : new_customValues = (TIFFTagValue *)
484 34158 : _TIFFrealloc(td->td_customValues,
485 34158 : sizeof(TIFFTagValue) * td->td_customValueCount);
486 34158 : if (!new_customValues) {
487 0 : TIFFErrorExt(tif->tif_clientdata, module,
488 : "%s: Failed to allocate space for list of custom values",
489 : tif->tif_name);
490 0 : status = 0;
491 0 : goto end;
492 : }
493 :
494 34158 : td->td_customValues = new_customValues;
495 :
496 34158 : tv = td->td_customValues + (td->td_customValueCount - 1);
497 34158 : tv->info = fip;
498 34158 : tv->value = NULL;
499 34158 : tv->count = 0;
500 : }
501 :
502 : /*
503 : * Set custom value ... save a copy of the custom tag value.
504 : */
505 34210 : tv_size = _TIFFDataSize(fip->field_type);
506 34210 : if (tv_size == 0) {
507 0 : status = 0;
508 0 : TIFFErrorExt(tif->tif_clientdata, module,
509 : "%s: Bad field type %d for \"%s\"",
510 0 : tif->tif_name, fip->field_type,
511 : fip->field_name);
512 0 : goto end;
513 : }
514 :
515 34210 : if (fip->field_type == TIFF_ASCII)
516 : {
517 : uint32 ma;
518 : char* mb;
519 8401 : if (fip->field_passcount)
520 : {
521 0 : assert(fip->field_writecount==TIFF_VARIABLE2);
522 0 : ma=(uint32)va_arg(ap,uint32);
523 0 : mb=(char*)va_arg(ap,char*);
524 : }
525 : else
526 : {
527 8401 : mb=(char*)va_arg(ap,char*);
528 8401 : ma=(uint32)(strlen(mb)+1);
529 : }
530 8401 : tv->count=ma;
531 8401 : setByteArray(&tv->value,mb,ma,1);
532 : }
533 : else
534 : {
535 25809 : if (fip->field_passcount) {
536 25799 : if (fip->field_writecount == TIFF_VARIABLE2)
537 6 : tv->count = (uint32) va_arg(ap, uint32);
538 : else
539 25793 : tv->count = (int) va_arg(ap, int);
540 20 : } else if (fip->field_writecount == TIFF_VARIABLE
541 20 : || fip->field_writecount == TIFF_VARIABLE2)
542 0 : tv->count = 1;
543 10 : else if (fip->field_writecount == TIFF_SPP)
544 0 : tv->count = td->td_samplesperpixel;
545 : else
546 10 : tv->count = fip->field_writecount;
547 :
548 25809 : if (tv->count == 0) {
549 0 : status = 0;
550 0 : 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 0 : fip->field_type,
556 0 : fip->field_writecount,
557 0 : fip->field_passcount);
558 0 : goto end;
559 : }
560 :
561 25809 : tv->value = _TIFFCheckMalloc(tif, tv->count, tv_size,
562 : "custom tag binary object");
563 25809 : if (!tv->value) {
564 0 : status = 0;
565 0 : goto end;
566 : }
567 :
568 25809 : if (fip->field_tag == TIFFTAG_DOTRANGE
569 25809 : && strcmp(fip->field_name,"DotRange") == 0) {
570 : /* TODO: This is an evil exception and should not have been
571 : handled this way ... likely best if we move it into
572 : the directory structure with an explicit field in
573 : libtiff 4.1 and assign it a FIELD_ value */
574 : uint16 v[2];
575 0 : v[0] = (uint16)va_arg(ap, int);
576 0 : v[1] = (uint16)va_arg(ap, int);
577 0 : _TIFFmemcpy(tv->value, &v, 4);
578 : }
579 :
580 51649 : else if (fip->field_passcount
581 25809 : || fip->field_writecount == TIFF_VARIABLE
582 10 : || fip->field_writecount == TIFF_VARIABLE2
583 10 : || fip->field_writecount == TIFF_SPP
584 20 : || tv->count > 1) {
585 25800 : _TIFFmemcpy(tv->value, va_arg(ap, void *),
586 25800 : tv->count * tv_size);
587 : } else {
588 9 : char *val = (char *)tv->value;
589 9 : assert( tv->count == 1 );
590 :
591 9 : switch (fip->field_type) {
592 : case TIFF_BYTE:
593 : case TIFF_UNDEFINED:
594 : {
595 0 : uint8 v = (uint8)va_arg(ap, int);
596 0 : _TIFFmemcpy(val, &v, tv_size);
597 : }
598 0 : break;
599 : case TIFF_SBYTE:
600 : {
601 0 : int8 v = (int8)va_arg(ap, int);
602 0 : _TIFFmemcpy(val, &v, tv_size);
603 : }
604 0 : break;
605 : case TIFF_SHORT:
606 : {
607 0 : uint16 v = (uint16)va_arg(ap, int);
608 0 : _TIFFmemcpy(val, &v, tv_size);
609 : }
610 0 : break;
611 : case TIFF_SSHORT:
612 : {
613 0 : int16 v = (int16)va_arg(ap, int);
614 0 : _TIFFmemcpy(val, &v, tv_size);
615 : }
616 0 : break;
617 : case TIFF_LONG:
618 : case TIFF_IFD:
619 : {
620 0 : uint32 v = va_arg(ap, uint32);
621 0 : _TIFFmemcpy(val, &v, tv_size);
622 : }
623 0 : break;
624 : case TIFF_SLONG:
625 : {
626 0 : int32 v = va_arg(ap, int32);
627 0 : _TIFFmemcpy(val, &v, tv_size);
628 : }
629 0 : break;
630 : case TIFF_LONG8:
631 : case TIFF_IFD8:
632 : {
633 9 : uint64 v = va_arg(ap, uint64);
634 9 : _TIFFmemcpy(val, &v, tv_size);
635 : }
636 9 : break;
637 : case TIFF_SLONG8:
638 : {
639 0 : int64 v = va_arg(ap, int64);
640 0 : _TIFFmemcpy(val, &v, tv_size);
641 : }
642 0 : break;
643 : case TIFF_RATIONAL:
644 : case TIFF_SRATIONAL:
645 : case TIFF_FLOAT:
646 : {
647 0 : float v = (float)va_arg(ap, double);
648 0 : _TIFFmemcpy(val, &v, tv_size);
649 : }
650 0 : break;
651 : case TIFF_DOUBLE:
652 : {
653 0 : double v = va_arg(ap, double);
654 0 : _TIFFmemcpy(val, &v, tv_size);
655 : }
656 0 : break;
657 : default:
658 0 : _TIFFmemset(val, 0, tv_size);
659 0 : status = 0;
660 : break;
661 : }
662 : }
663 : }
664 : }
665 : }
666 169273 : if (status) {
667 169273 : const TIFFField* fip=TIFFFieldWithTag(tif,tag);
668 169273 : if (fip)
669 169273 : TIFFSetFieldBit(tif, fip->field_bit);
670 169273 : tif->tif_flags |= TIFF_DIRTYDIRECT;
671 : }
672 :
673 : end:
674 169273 : va_end(ap);
675 169273 : return (status);
676 : badvalue:
677 : {
678 0 : const TIFFField* fip=TIFFFieldWithTag(tif,tag);
679 0 : 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 0 : va_end(ap);
684 : }
685 0 : return (0);
686 : badvalue32:
687 : {
688 0 : const TIFFField* fip=TIFFFieldWithTag(tif,tag);
689 0 : 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 0 : va_end(ap);
694 : }
695 0 : 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 170663 : OkToChangeTag(TIFF* tif, uint32 tag)
709 : {
710 170663 : const TIFFField* fip = TIFFFindField(tif, tag, TIFF_ANY);
711 170663 : if (!fip) { /* unknown tag */
712 0 : TIFFErrorExt(tif->tif_clientdata, "TIFFSetField", "%s: Unknown %stag %u",
713 : tif->tif_name, isPseudoTag(tag) ? "pseudo-" : "", tag);
714 0 : return (0);
715 : }
716 170714 : if (tag != TIFFTAG_IMAGELENGTH && (tif->tif_flags & TIFF_BEENWRITING) &&
717 51 : !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 0 : TIFFErrorExt(tif->tif_clientdata, "TIFFSetField",
725 : "%s: Cannot modify tag \"%s\" while writing",
726 : tif->tif_name, fip->field_name);
727 0 : return (0);
728 : }
729 170663 : 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 170663 : TIFFSetField(TIFF* tif, uint32 tag, ...)
741 : {
742 : va_list ap;
743 : int status;
744 :
745 170663 : va_start(ap, tag);
746 170663 : status = TIFFVSetField(tif, tag, ap);
747 170663 : va_end(ap);
748 170663 : return (status);
749 : }
750 :
751 : /*
752 : * Clear the contents of the field in the internal structure.
753 : */
754 : int
755 2118 : TIFFUnsetField(TIFF* tif, uint32 tag)
756 : {
757 2118 : const TIFFField *fip = TIFFFieldWithTag(tif, tag);
758 2118 : TIFFDirectory* td = &tif->tif_dir;
759 :
760 2118 : if( !fip )
761 0 : return 0;
762 :
763 2118 : if( fip->field_bit != FIELD_CUSTOM )
764 1 : TIFFClrFieldBit(tif, fip->field_bit);
765 : else
766 : {
767 2117 : TIFFTagValue *tv = NULL;
768 : int i;
769 :
770 2127 : for (i = 0; i < td->td_customValueCount; i++) {
771 :
772 16 : tv = td->td_customValues + i;
773 16 : if( tv->info->field_tag == tag )
774 6 : break;
775 : }
776 :
777 2117 : if( i < td->td_customValueCount )
778 : {
779 6 : _TIFFfree(tv->value);
780 16 : for( ; i < td->td_customValueCount-1; i++) {
781 10 : td->td_customValues[i] = td->td_customValues[i+1];
782 : }
783 6 : td->td_customValueCount--;
784 : }
785 : }
786 :
787 2118 : tif->tif_flags |= TIFF_DIRTYDIRECT;
788 :
789 2118 : 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 170663 : TIFFVSetField(TIFF* tif, uint32 tag, va_list ap)
800 : {
801 341326 : return OkToChangeTag(tif, tag) ?
802 170663 : (*tif->tif_tagmethods.vsetfield)(tif, tag, ap) : 0;
803 : }
804 :
805 : static int
806 628269 : _TIFFVGetField(TIFF* tif, uint32 tag, va_list ap)
807 : {
808 628269 : TIFFDirectory* td = &tif->tif_dir;
809 628269 : int ret_val = 1;
810 628269 : uint32 standard_tag = tag;
811 628269 : 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 628269 : if (fip->field_bit == FIELD_CUSTOM) {
820 57426 : standard_tag = 0;
821 : }
822 :
823 628269 : switch (standard_tag) {
824 : case TIFFTAG_SUBFILETYPE:
825 292 : *va_arg(ap, uint32*) = td->td_subfiletype;
826 292 : break;
827 : case TIFFTAG_IMAGEWIDTH:
828 8243 : *va_arg(ap, uint32*) = td->td_imagewidth;
829 8243 : break;
830 : case TIFFTAG_IMAGELENGTH:
831 8243 : *va_arg(ap, uint32*) = td->td_imagelength;
832 8243 : break;
833 : case TIFFTAG_BITSPERSAMPLE:
834 5488 : *va_arg(ap, uint16*) = td->td_bitspersample;
835 5488 : break;
836 : case TIFFTAG_COMPRESSION:
837 10932 : *va_arg(ap, uint16*) = td->td_compression;
838 10932 : break;
839 : case TIFFTAG_PHOTOMETRIC:
840 6836 : *va_arg(ap, uint16*) = td->td_photometric;
841 6836 : break;
842 : case TIFFTAG_THRESHHOLDING:
843 0 : *va_arg(ap, uint16*) = td->td_threshholding;
844 0 : break;
845 : case TIFFTAG_FILLORDER:
846 0 : *va_arg(ap, uint16*) = td->td_fillorder;
847 0 : break;
848 : case TIFFTAG_ORIENTATION:
849 0 : *va_arg(ap, uint16*) = td->td_orientation;
850 0 : break;
851 : case TIFFTAG_SAMPLESPERPIXEL:
852 4356 : *va_arg(ap, uint16*) = td->td_samplesperpixel;
853 4356 : break;
854 : case TIFFTAG_ROWSPERSTRIP:
855 8047 : *va_arg(ap, uint32*) = td->td_rowsperstrip;
856 8047 : break;
857 : case TIFFTAG_MINSAMPLEVALUE:
858 0 : *va_arg(ap, uint16*) = td->td_minsamplevalue;
859 0 : break;
860 : case TIFFTAG_MAXSAMPLEVALUE:
861 0 : *va_arg(ap, uint16*) = td->td_maxsamplevalue;
862 0 : break;
863 : case TIFFTAG_SMINSAMPLEVALUE:
864 0 : if (tif->tif_flags & TIFF_PERSAMPLE)
865 0 : *va_arg(ap, double**) = td->td_sminsamplevalue;
866 : else
867 : {
868 : /* libtiff historially treats this as a single value. */
869 : uint16 i;
870 0 : double v = td->td_sminsamplevalue[0];
871 0 : for (i=1; i < td->td_samplesperpixel; ++i)
872 0 : if( td->td_sminsamplevalue[i] < v )
873 0 : v = td->td_sminsamplevalue[i];
874 0 : *va_arg(ap, double*) = v;
875 : }
876 0 : break;
877 : case TIFFTAG_SMAXSAMPLEVALUE:
878 0 : if (tif->tif_flags & TIFF_PERSAMPLE)
879 0 : *va_arg(ap, double**) = td->td_smaxsamplevalue;
880 : else
881 : {
882 : /* libtiff historially treats this as a single value. */
883 : uint16 i;
884 0 : double v = td->td_smaxsamplevalue[0];
885 0 : for (i=1; i < td->td_samplesperpixel; ++i)
886 0 : if( td->td_smaxsamplevalue[i] > v )
887 0 : v = td->td_smaxsamplevalue[i];
888 0 : *va_arg(ap, double*) = v;
889 : }
890 0 : break;
891 : case TIFFTAG_XRESOLUTION:
892 46 : *va_arg(ap, float*) = td->td_xresolution;
893 46 : break;
894 : case TIFFTAG_YRESOLUTION:
895 46 : *va_arg(ap, float*) = td->td_yresolution;
896 46 : break;
897 : case TIFFTAG_PLANARCONFIG:
898 9367 : *va_arg(ap, uint16*) = td->td_planarconfig;
899 9367 : break;
900 : case TIFFTAG_XPOSITION:
901 0 : *va_arg(ap, float*) = td->td_xposition;
902 0 : break;
903 : case TIFFTAG_YPOSITION:
904 0 : *va_arg(ap, float*) = td->td_yposition;
905 0 : break;
906 : case TIFFTAG_RESOLUTIONUNIT:
907 46 : *va_arg(ap, uint16*) = td->td_resolutionunit;
908 46 : break;
909 : case TIFFTAG_PAGENUMBER:
910 0 : *va_arg(ap, uint16*) = td->td_pagenumber[0];
911 0 : *va_arg(ap, uint16*) = td->td_pagenumber[1];
912 0 : break;
913 : case TIFFTAG_HALFTONEHINTS:
914 0 : *va_arg(ap, uint16*) = td->td_halftonehints[0];
915 0 : *va_arg(ap, uint16*) = td->td_halftonehints[1];
916 0 : break;
917 : case TIFFTAG_COLORMAP:
918 81 : *va_arg(ap, uint16**) = td->td_colormap[0];
919 81 : *va_arg(ap, uint16**) = td->td_colormap[1];
920 81 : *va_arg(ap, uint16**) = td->td_colormap[2];
921 81 : break;
922 : case TIFFTAG_STRIPOFFSETS:
923 : case TIFFTAG_TILEOFFSETS:
924 1390 : _TIFFFillStriles( tif );
925 1390 : *va_arg(ap, uint64**) = td->td_stripoffset;
926 1390 : break;
927 : case TIFFTAG_STRIPBYTECOUNTS:
928 : case TIFFTAG_TILEBYTECOUNTS:
929 106848 : _TIFFFillStriles( tif );
930 106848 : *va_arg(ap, uint64**) = td->td_stripbytecount;
931 106848 : break;
932 : case TIFFTAG_MATTEING:
933 0 : *va_arg(ap, uint16*) =
934 0 : (td->td_extrasamples == 1 &&
935 0 : td->td_sampleinfo[0] == EXTRASAMPLE_ASSOCALPHA);
936 0 : break;
937 : case TIFFTAG_EXTRASAMPLES:
938 393891 : *va_arg(ap, uint16*) = td->td_extrasamples;
939 393891 : *va_arg(ap, uint16**) = td->td_sampleinfo;
940 393891 : break;
941 : case TIFFTAG_TILEWIDTH:
942 732 : *va_arg(ap, uint32*) = td->td_tilewidth;
943 732 : break;
944 : case TIFFTAG_TILELENGTH:
945 732 : *va_arg(ap, uint32*) = td->td_tilelength;
946 732 : break;
947 : case TIFFTAG_TILEDEPTH:
948 0 : *va_arg(ap, uint32*) = td->td_tiledepth;
949 0 : break;
950 : case TIFFTAG_DATATYPE:
951 0 : switch (td->td_sampleformat) {
952 : case SAMPLEFORMAT_UINT:
953 0 : *va_arg(ap, uint16*) = DATATYPE_UINT;
954 0 : break;
955 : case SAMPLEFORMAT_INT:
956 0 : *va_arg(ap, uint16*) = DATATYPE_INT;
957 0 : break;
958 : case SAMPLEFORMAT_IEEEFP:
959 0 : *va_arg(ap, uint16*) = DATATYPE_IEEEFP;
960 0 : break;
961 : case SAMPLEFORMAT_VOID:
962 0 : *va_arg(ap, uint16*) = DATATYPE_VOID;
963 : break;
964 : }
965 0 : break;
966 : case TIFFTAG_SAMPLEFORMAT:
967 5203 : *va_arg(ap, uint16*) = td->td_sampleformat;
968 5203 : break;
969 : case TIFFTAG_IMAGEDEPTH:
970 0 : *va_arg(ap, uint32*) = td->td_imagedepth;
971 0 : break;
972 : case TIFFTAG_SUBIFD:
973 0 : *va_arg(ap, uint16*) = td->td_nsubifd;
974 0 : *va_arg(ap, uint64**) = td->td_subifd;
975 0 : break;
976 : case TIFFTAG_YCBCRPOSITIONING:
977 0 : *va_arg(ap, uint16*) = td->td_ycbcrpositioning;
978 0 : break;
979 : case TIFFTAG_YCBCRSUBSAMPLING:
980 12 : *va_arg(ap, uint16*) = td->td_ycbcrsubsampling[0];
981 12 : *va_arg(ap, uint16*) = td->td_ycbcrsubsampling[1];
982 12 : break;
983 : case TIFFTAG_TRANSFERFUNCTION:
984 0 : *va_arg(ap, uint16**) = td->td_transferfunction[0];
985 0 : if (td->td_samplesperpixel - td->td_extrasamples > 1) {
986 0 : *va_arg(ap, uint16**) = td->td_transferfunction[1];
987 0 : *va_arg(ap, uint16**) = td->td_transferfunction[2];
988 : }
989 0 : break;
990 : case TIFFTAG_REFERENCEBLACKWHITE:
991 12 : *va_arg(ap, float**) = td->td_refblackwhite;
992 12 : break;
993 : case TIFFTAG_INKNAMES:
994 0 : *va_arg(ap, char**) = td->td_inknames;
995 0 : 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 57426 : if( fip == NULL || fip->field_bit != FIELD_CUSTOM )
1010 : {
1011 0 : TIFFErrorExt(tif->tif_clientdata, "_TIFFVGetField",
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 0 : ret_val = 0;
1018 0 : break;
1019 : }
1020 :
1021 : /*
1022 : * Do we have a custom value?
1023 : */
1024 57426 : ret_val = 0;
1025 486560 : for (i = 0; i < td->td_customValueCount; i++) {
1026 204725 : TIFFTagValue *tv = td->td_customValues + i;
1027 :
1028 204725 : if (tv->info->field_tag != tag)
1029 185854 : continue;
1030 :
1031 18871 : if (fip->field_passcount) {
1032 14466 : if (fip->field_readcount == TIFF_VARIABLE2)
1033 2 : *va_arg(ap, uint32*) = (uint32)tv->count;
1034 : else /* Assume TIFF_VARIABLE */
1035 14464 : *va_arg(ap, uint16*) = (uint16)tv->count;
1036 14466 : *va_arg(ap, void **) = tv->value;
1037 14466 : ret_val = 1;
1038 4405 : } else if (fip->field_tag == TIFFTAG_DOTRANGE
1039 4405 : && strcmp(fip->field_name,"DotRange") == 0) {
1040 : /* TODO: This is an evil exception and should not have been
1041 : handled this way ... likely best if we move it into
1042 : the directory structure with an explicit field in
1043 : libtiff 4.1 and assign it a FIELD_ value */
1044 0 : *va_arg(ap, uint16*) = ((uint16 *)tv->value)[0];
1045 0 : *va_arg(ap, uint16*) = ((uint16 *)tv->value)[1];
1046 0 : ret_val = 1;
1047 : } else {
1048 8826 : if (fip->field_type == TIFF_ASCII
1049 4405 : || fip->field_readcount == TIFF_VARIABLE
1050 5 : || fip->field_readcount == TIFF_VARIABLE2
1051 5 : || fip->field_readcount == TIFF_SPP
1052 10 : || tv->count > 1) {
1053 4401 : *va_arg(ap, void **) = tv->value;
1054 4401 : ret_val = 1;
1055 : } else {
1056 4 : char *val = (char *)tv->value;
1057 4 : assert( tv->count == 1 );
1058 4 : switch (fip->field_type) {
1059 : case TIFF_BYTE:
1060 : case TIFF_UNDEFINED:
1061 0 : *va_arg(ap, uint8*) =
1062 0 : *(uint8 *)val;
1063 0 : ret_val = 1;
1064 0 : break;
1065 : case TIFF_SBYTE:
1066 0 : *va_arg(ap, int8*) =
1067 0 : *(int8 *)val;
1068 0 : ret_val = 1;
1069 0 : break;
1070 : case TIFF_SHORT:
1071 0 : *va_arg(ap, uint16*) =
1072 0 : *(uint16 *)val;
1073 0 : ret_val = 1;
1074 0 : break;
1075 : case TIFF_SSHORT:
1076 0 : *va_arg(ap, int16*) =
1077 0 : *(int16 *)val;
1078 0 : ret_val = 1;
1079 0 : break;
1080 : case TIFF_LONG:
1081 : case TIFF_IFD:
1082 0 : *va_arg(ap, uint32*) =
1083 0 : *(uint32 *)val;
1084 0 : ret_val = 1;
1085 0 : break;
1086 : case TIFF_SLONG:
1087 0 : *va_arg(ap, int32*) =
1088 0 : *(int32 *)val;
1089 0 : ret_val = 1;
1090 0 : break;
1091 : case TIFF_LONG8:
1092 : case TIFF_IFD8:
1093 8 : *va_arg(ap, uint64*) =
1094 4 : *(uint64 *)val;
1095 4 : ret_val = 1;
1096 4 : break;
1097 : case TIFF_SLONG8:
1098 0 : *va_arg(ap, int64*) =
1099 0 : *(int64 *)val;
1100 0 : ret_val = 1;
1101 0 : break;
1102 : case TIFF_RATIONAL:
1103 : case TIFF_SRATIONAL:
1104 : case TIFF_FLOAT:
1105 0 : *va_arg(ap, float*) =
1106 0 : *(float *)val;
1107 0 : ret_val = 1;
1108 0 : break;
1109 : case TIFF_DOUBLE:
1110 0 : *va_arg(ap, double*) =
1111 0 : *(double *)val;
1112 0 : ret_val = 1;
1113 0 : break;
1114 : default:
1115 0 : ret_val = 0;
1116 : break;
1117 : }
1118 : }
1119 : }
1120 18871 : break;
1121 : }
1122 : }
1123 : }
1124 628269 : return(ret_val);
1125 : }
1126 :
1127 : /*
1128 : * Return the value of a field in the
1129 : * internal directory structure.
1130 : */
1131 : int
1132 677399 : TIFFGetField(TIFF* tif, uint32 tag, ...)
1133 : {
1134 : int status;
1135 : va_list ap;
1136 :
1137 677399 : va_start(ap, tag);
1138 677399 : status = TIFFVGetField(tif, tag, ap);
1139 677399 : va_end(ap);
1140 677399 : 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 679006 : TIFFVGetField(TIFF* tif, uint32 tag, va_list ap)
1151 : {
1152 679006 : const TIFFField* fip = TIFFFindField(tif, tag, TIFF_ANY);
1153 1307974 : return (fip && (isPseudoTag(tag) || TIFFFieldSet(tif, fip->field_bit)) ?
1154 628968 : (*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 20350 : TIFFFreeDirectory(TIFF* tif)
1169 : {
1170 20350 : TIFFDirectory *td = &tif->tif_dir;
1171 : int i;
1172 :
1173 20350 : _TIFFmemset(td->td_fieldsset, 0, FIELD_SETLONGS);
1174 20350 : CleanupField(td_sminsamplevalue);
1175 20350 : CleanupField(td_smaxsamplevalue);
1176 20350 : CleanupField(td_colormap[0]);
1177 20350 : CleanupField(td_colormap[1]);
1178 20350 : CleanupField(td_colormap[2]);
1179 20350 : CleanupField(td_sampleinfo);
1180 20350 : CleanupField(td_subifd);
1181 20350 : CleanupField(td_inknames);
1182 20350 : CleanupField(td_refblackwhite);
1183 20350 : CleanupField(td_transferfunction[0]);
1184 20350 : CleanupField(td_transferfunction[1]);
1185 20350 : CleanupField(td_transferfunction[2]);
1186 20350 : CleanupField(td_stripoffset);
1187 20350 : CleanupField(td_stripbytecount);
1188 20350 : TIFFClrFieldBit(tif, FIELD_YCBCRSUBSAMPLING);
1189 20350 : TIFFClrFieldBit(tif, FIELD_YCBCRPOSITIONING);
1190 :
1191 : /* Cleanup custom tag values */
1192 54502 : for( i = 0; i < td->td_customValueCount; i++ ) {
1193 34152 : if (td->td_customValues[i].value)
1194 34152 : _TIFFfree(td->td_customValues[i].value);
1195 : }
1196 :
1197 20350 : td->td_customValueCount = 0;
1198 20350 : CleanupField(td_customValues);
1199 :
1200 : #if defined(DEFER_STRILE_LOAD)
1201 20350 : _TIFFmemset( &(td->td_stripoffset_entry), 0, sizeof(TIFFDirEntry));
1202 20350 : _TIFFmemset( &(td->td_stripbytecount_entry), 0, sizeof(TIFFDirEntry));
1203 : #endif
1204 20350 : }
1205 : #undef CleanupField
1206 :
1207 : /*
1208 : * Client Tag extension support (from Niles Ritter).
1209 : */
1210 : static TIFFExtendProc _TIFFextender = (TIFFExtendProc) NULL;
1211 :
1212 : TIFFExtendProc
1213 885 : TIFFSetTagExtender(TIFFExtendProc extender)
1214 : {
1215 885 : TIFFExtendProc prev = _TIFFextender;
1216 885 : _TIFFextender = extender;
1217 885 : 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 1893 : TIFFCreateDirectory(TIFF* tif)
1229 : {
1230 1893 : TIFFDefaultDirectory(tif);
1231 1893 : tif->tif_diroff = 0;
1232 1893 : tif->tif_nextdiroff = 0;
1233 1893 : tif->tif_curoff = 0;
1234 1893 : tif->tif_row = (uint32) -1;
1235 1893 : tif->tif_curstrip = (uint32) -1;
1236 :
1237 1893 : return 0;
1238 : }
1239 :
1240 : int
1241 0 : TIFFCreateCustomDirectory(TIFF* tif, const TIFFFieldArray* infoarray)
1242 : {
1243 0 : TIFFDefaultDirectory(tif);
1244 :
1245 : /*
1246 : * Reset the field definitions to match the application provided list.
1247 : * Hopefully TIFFDefaultDirectory() won't have done anything irreversable
1248 : * based on it's assumption this is an image directory.
1249 : */
1250 0 : _TIFFSetupFields(tif, infoarray);
1251 :
1252 0 : tif->tif_diroff = 0;
1253 0 : tif->tif_nextdiroff = 0;
1254 0 : tif->tif_curoff = 0;
1255 0 : tif->tif_row = (uint32) -1;
1256 0 : tif->tif_curstrip = (uint32) -1;
1257 :
1258 0 : return 0;
1259 : }
1260 :
1261 : int
1262 0 : TIFFCreateEXIFDirectory(TIFF* tif)
1263 : {
1264 : const TIFFFieldArray* exifFieldArray;
1265 0 : exifFieldArray = _TIFFGetExifFields();
1266 0 : return TIFFCreateCustomDirectory(tif, exifFieldArray);
1267 : }
1268 :
1269 : /*
1270 : * Setup a default directory structure.
1271 : */
1272 : int
1273 13410 : TIFFDefaultDirectory(TIFF* tif)
1274 : {
1275 13410 : register TIFFDirectory* td = &tif->tif_dir;
1276 : const TIFFFieldArray* tiffFieldArray;
1277 :
1278 13410 : tiffFieldArray = _TIFFGetFields();
1279 13410 : _TIFFSetupFields(tif, tiffFieldArray);
1280 :
1281 13410 : _TIFFmemset(td, 0, sizeof (*td));
1282 13410 : td->td_fillorder = FILLORDER_MSB2LSB;
1283 13410 : td->td_bitspersample = 1;
1284 13410 : td->td_threshholding = THRESHHOLD_BILEVEL;
1285 13410 : td->td_orientation = ORIENTATION_TOPLEFT;
1286 13410 : td->td_samplesperpixel = 1;
1287 13410 : td->td_rowsperstrip = (uint32) -1;
1288 13410 : td->td_tilewidth = 0;
1289 13410 : td->td_tilelength = 0;
1290 13410 : td->td_tiledepth = 1;
1291 13410 : td->td_stripbytecountsorted = 1; /* Our own arrays always sorted. */
1292 13410 : td->td_resolutionunit = RESUNIT_INCH;
1293 13410 : td->td_sampleformat = SAMPLEFORMAT_UINT;
1294 13410 : td->td_imagedepth = 1;
1295 13410 : td->td_ycbcrsubsampling[0] = 2;
1296 13410 : td->td_ycbcrsubsampling[1] = 2;
1297 13410 : td->td_ycbcrpositioning = YCBCRPOSITION_CENTERED;
1298 13410 : tif->tif_postdecode = _TIFFNoPostDecode;
1299 13410 : tif->tif_foundfield = NULL;
1300 13410 : tif->tif_tagmethods.vsetfield = _TIFFVSetField;
1301 13410 : tif->tif_tagmethods.vgetfield = _TIFFVGetField;
1302 13410 : 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 13410 : if (_TIFFextender)
1308 13410 : (*_TIFFextender)(tif);
1309 13410 : (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 13410 : 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 13410 : tif->tif_flags &= ~TIFF_ISTILED;
1326 :
1327 13410 : return (1);
1328 : }
1329 :
1330 : static int
1331 985 : TIFFAdvanceDirectory(TIFF* tif, uint64* nextdir, uint64* off)
1332 : {
1333 : static const char module[] = "TIFFAdvanceDirectory";
1334 985 : if (isMapped(tif))
1335 : {
1336 0 : uint64 poff=*nextdir;
1337 0 : if (!(tif->tif_flags&TIFF_BIGTIFF))
1338 : {
1339 : tmsize_t poffa,poffb,poffc,poffd;
1340 : uint16 dircount;
1341 : uint32 nextdir32;
1342 0 : poffa=(tmsize_t)poff;
1343 0 : poffb=poffa+sizeof(uint16);
1344 0 : if (((uint64)poffa!=poff)||(poffb<poffa)||(poffb<(tmsize_t)sizeof(uint16))||(poffb>tif->tif_size))
1345 : {
1346 0 : TIFFErrorExt(tif->tif_clientdata,module,"Error fetching directory count");
1347 0 : return(0);
1348 : }
1349 0 : _TIFFmemcpy(&dircount,tif->tif_base+poffa,sizeof(uint16));
1350 0 : if (tif->tif_flags&TIFF_SWAB)
1351 0 : TIFFSwabShort(&dircount);
1352 0 : poffc=poffb+dircount*12;
1353 0 : poffd=poffc+sizeof(uint32);
1354 0 : if ((poffc<poffb)||(poffc<dircount*12)||(poffd<poffc)||(poffd<(tmsize_t)sizeof(uint32))||(poffd>tif->tif_size))
1355 : {
1356 0 : TIFFErrorExt(tif->tif_clientdata,module,"Error fetching directory link");
1357 0 : return(0);
1358 : }
1359 0 : if (off!=NULL)
1360 0 : *off=(uint64)poffc;
1361 0 : _TIFFmemcpy(&nextdir32,tif->tif_base+poffc,sizeof(uint32));
1362 0 : if (tif->tif_flags&TIFF_SWAB)
1363 0 : TIFFSwabLong(&nextdir32);
1364 0 : *nextdir=nextdir32;
1365 : }
1366 : else
1367 : {
1368 : tmsize_t poffa,poffb,poffc,poffd;
1369 : uint64 dircount64;
1370 : uint16 dircount16;
1371 0 : poffa=(tmsize_t)poff;
1372 0 : poffb=poffa+sizeof(uint64);
1373 0 : if (((uint64)poffa!=poff)||(poffb<poffa)||(poffb<(tmsize_t)sizeof(uint64))||(poffb>tif->tif_size))
1374 : {
1375 0 : TIFFErrorExt(tif->tif_clientdata,module,"Error fetching directory count");
1376 0 : return(0);
1377 : }
1378 0 : _TIFFmemcpy(&dircount64,tif->tif_base+poffa,sizeof(uint64));
1379 0 : if (tif->tif_flags&TIFF_SWAB)
1380 0 : TIFFSwabLong8(&dircount64);
1381 0 : if (dircount64>0xFFFF)
1382 : {
1383 0 : TIFFErrorExt(tif->tif_clientdata,module,"Sanity check on directory count failed");
1384 0 : return(0);
1385 : }
1386 0 : dircount16=(uint16)dircount64;
1387 0 : poffc=poffb+dircount16*20;
1388 0 : poffd=poffc+sizeof(uint64);
1389 0 : if ((poffc<poffb)||(poffc<dircount16*20)||(poffd<poffc)||(poffd<(tmsize_t)sizeof(uint64))||(poffd>tif->tif_size))
1390 : {
1391 0 : TIFFErrorExt(tif->tif_clientdata,module,"Error fetching directory link");
1392 0 : return(0);
1393 : }
1394 0 : if (off!=NULL)
1395 0 : *off=(uint64)poffc;
1396 0 : _TIFFmemcpy(nextdir,tif->tif_base+poffc,sizeof(uint64));
1397 0 : if (tif->tif_flags&TIFF_SWAB)
1398 0 : TIFFSwabLong8(nextdir);
1399 : }
1400 0 : return(1);
1401 : }
1402 : else
1403 : {
1404 985 : if (!(tif->tif_flags&TIFF_BIGTIFF))
1405 : {
1406 : uint16 dircount;
1407 : uint32 nextdir32;
1408 1930 : if (!SeekOK(tif, *nextdir) ||
1409 965 : !ReadOK(tif, &dircount, sizeof (uint16))) {
1410 0 : TIFFErrorExt(tif->tif_clientdata, module, "%s: Error fetching directory count",
1411 : tif->tif_name);
1412 0 : return (0);
1413 : }
1414 965 : if (tif->tif_flags & TIFF_SWAB)
1415 99 : TIFFSwabShort(&dircount);
1416 965 : if (off != NULL)
1417 2 : *off = TIFFSeekFile(tif,
1418 : dircount*12, SEEK_CUR);
1419 : else
1420 963 : (void) TIFFSeekFile(tif,
1421 : dircount*12, SEEK_CUR);
1422 965 : if (!ReadOK(tif, &nextdir32, sizeof (uint32))) {
1423 0 : TIFFErrorExt(tif->tif_clientdata, module, "%s: Error fetching directory link",
1424 : tif->tif_name);
1425 0 : return (0);
1426 : }
1427 965 : if (tif->tif_flags & TIFF_SWAB)
1428 99 : TIFFSwabLong(&nextdir32);
1429 965 : *nextdir=nextdir32;
1430 : }
1431 : else
1432 : {
1433 : uint64 dircount64;
1434 : uint16 dircount16;
1435 40 : if (!SeekOK(tif, *nextdir) ||
1436 20 : !ReadOK(tif, &dircount64, sizeof (uint64))) {
1437 0 : TIFFErrorExt(tif->tif_clientdata, module, "%s: Error fetching directory count",
1438 : tif->tif_name);
1439 0 : return (0);
1440 : }
1441 20 : if (tif->tif_flags & TIFF_SWAB)
1442 0 : TIFFSwabLong8(&dircount64);
1443 20 : if (dircount64>0xFFFF)
1444 : {
1445 0 : TIFFErrorExt(tif->tif_clientdata, module, "Error fetching directory count");
1446 0 : return(0);
1447 : }
1448 20 : dircount16 = (uint16)dircount64;
1449 20 : if (off != NULL)
1450 0 : *off = TIFFSeekFile(tif,
1451 : dircount16*20, SEEK_CUR);
1452 : else
1453 20 : (void) TIFFSeekFile(tif,
1454 : dircount16*20, SEEK_CUR);
1455 20 : if (!ReadOK(tif, nextdir, sizeof (uint64))) {
1456 0 : TIFFErrorExt(tif->tif_clientdata, module, "%s: Error fetching directory link",
1457 : tif->tif_name);
1458 0 : return (0);
1459 : }
1460 20 : if (tif->tif_flags & TIFF_SWAB)
1461 0 : TIFFSwabLong8(nextdir);
1462 : }
1463 985 : return (1);
1464 : }
1465 : }
1466 :
1467 : /*
1468 : * Count the number of directories in a file.
1469 : */
1470 : uint16
1471 265 : TIFFNumberOfDirectories(TIFF* tif)
1472 : {
1473 : uint64 nextdir;
1474 : uint16 n;
1475 265 : if (!(tif->tif_flags&TIFF_BIGTIFF))
1476 255 : nextdir = tif->tif_header.classic.tiff_diroff;
1477 : else
1478 10 : nextdir = tif->tif_header.big.tiff_diroff;
1479 265 : n = 0;
1480 1153 : while (nextdir != 0 && TIFFAdvanceDirectory(tif, &nextdir, NULL))
1481 623 : n++;
1482 265 : 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 1237 : TIFFSetDirectory(TIFF* tif, uint16 dirn)
1491 : {
1492 : uint64 nextdir;
1493 : uint16 n;
1494 :
1495 1237 : if (!(tif->tif_flags&TIFF_BIGTIFF))
1496 1216 : nextdir = tif->tif_header.classic.tiff_diroff;
1497 : else
1498 21 : nextdir = tif->tif_header.big.tiff_diroff;
1499 1595 : for (n = dirn; n > 0 && nextdir != 0; n--)
1500 358 : if (!TIFFAdvanceDirectory(tif, &nextdir, NULL))
1501 0 : return (0);
1502 1237 : 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 1237 : 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 1237 : tif->tif_dirnumber = 0;
1514 1237 : 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 1905 : TIFFSetSubDirectory(TIFF* tif, uint64 diroff)
1525 : {
1526 1905 : 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 1905 : tif->tif_dirnumber = 0;
1532 1905 : return (TIFFReadDirectory(tif));
1533 : }
1534 :
1535 : /*
1536 : * Return file offset of the current directory.
1537 : */
1538 : uint64
1539 238657 : TIFFCurrentDirOffset(TIFF* tif)
1540 : {
1541 238657 : 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 1772 : TIFFLastDirectory(TIFF* tif)
1550 : {
1551 1772 : return (tif->tif_nextdiroff == 0);
1552 : }
1553 :
1554 : /*
1555 : * Unlink the specified directory from the directory chain.
1556 : */
1557 : int
1558 2 : TIFFUnlinkDirectory(TIFF* tif, uint16 dirn)
1559 : {
1560 : static const char module[] = "TIFFUnlinkDirectory";
1561 : uint64 nextdir;
1562 : uint64 off;
1563 : uint16 n;
1564 :
1565 2 : if (tif->tif_mode == O_RDONLY) {
1566 0 : TIFFErrorExt(tif->tif_clientdata, module,
1567 : "Can not unlink directory in read-only file");
1568 0 : 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 2 : if (!(tif->tif_flags&TIFF_BIGTIFF))
1576 : {
1577 2 : nextdir = tif->tif_header.classic.tiff_diroff;
1578 2 : off = 4;
1579 : }
1580 : else
1581 : {
1582 0 : nextdir = tif->tif_header.big.tiff_diroff;
1583 0 : off = 8;
1584 : }
1585 4 : for (n = dirn-1; n > 0; n--) {
1586 2 : if (nextdir == 0) {
1587 0 : TIFFErrorExt(tif->tif_clientdata, module, "Directory %d does not exist", dirn);
1588 0 : return (0);
1589 : }
1590 2 : if (!TIFFAdvanceDirectory(tif, &nextdir, &off))
1591 0 : return (0);
1592 : }
1593 : /*
1594 : * Advance to the directory to be unlinked and fetch
1595 : * the offset of the directory that follows.
1596 : */
1597 2 : if (!TIFFAdvanceDirectory(tif, &nextdir, NULL))
1598 0 : 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 2 : (void) TIFFSeekFile(tif, off, SEEK_SET);
1605 2 : if (!(tif->tif_flags&TIFF_BIGTIFF))
1606 : {
1607 : uint32 nextdir32;
1608 2 : nextdir32=(uint32)nextdir;
1609 2 : assert((uint64)nextdir32==nextdir);
1610 2 : if (tif->tif_flags & TIFF_SWAB)
1611 1 : TIFFSwabLong(&nextdir32);
1612 2 : if (!WriteOK(tif, &nextdir32, sizeof (uint32))) {
1613 0 : TIFFErrorExt(tif->tif_clientdata, module, "Error writing directory link");
1614 0 : return (0);
1615 : }
1616 : }
1617 : else
1618 : {
1619 0 : if (tif->tif_flags & TIFF_SWAB)
1620 0 : TIFFSwabLong8(&nextdir);
1621 0 : if (!WriteOK(tif, &nextdir, sizeof (uint64))) {
1622 0 : TIFFErrorExt(tif->tif_clientdata, module, "Error writing directory link");
1623 0 : 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 2 : (*tif->tif_cleanup)(tif);
1634 2 : if ((tif->tif_flags & TIFF_MYBUFFER) && tif->tif_rawdata) {
1635 0 : _TIFFfree(tif->tif_rawdata);
1636 0 : tif->tif_rawdata = NULL;
1637 0 : tif->tif_rawcc = 0;
1638 0 : tif->tif_rawdataoff = 0;
1639 0 : tif->tif_rawdataloaded = 0;
1640 : }
1641 2 : tif->tif_flags &= ~(TIFF_BEENWRITING|TIFF_BUFFERSETUP|TIFF_POSTENCODE|TIFF_BUF4WRITE);
1642 2 : TIFFFreeDirectory(tif);
1643 2 : TIFFDefaultDirectory(tif);
1644 2 : tif->tif_diroff = 0; /* force link on next write */
1645 2 : tif->tif_nextdiroff = 0; /* next write must be at end */
1646 2 : tif->tif_curoff = 0;
1647 2 : tif->tif_row = (uint32) -1;
1648 2 : tif->tif_curstrip = (uint32) -1;
1649 2 : 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 : */
|