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