1 /* $Id: tif_dirwrite.c,v 1.34 2006/02/23 16:07:45 dron 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 Write Support Routines.
31  */
32 #include "tiffiop.h"
33 
34 #ifdef HAVE_IEEEFP
35 # define	TIFFCvtNativeToIEEEFloat(tif, n, fp)
36 # define	TIFFCvtNativeToIEEEDouble(tif, n, dp)
37 #else
38 extern	void TIFFCvtNativeToIEEEFloat(TIFF*, uint32, float*);
39 extern	void TIFFCvtNativeToIEEEDouble(TIFF*, uint32, double*);
40 #endif
41 
42 static	int TIFFWriteNormalTag(TIFF*, TIFFDirEntry*, const TIFFFieldInfo*);
43 static	void TIFFSetupShortLong(TIFF*, ttag_t, TIFFDirEntry*, uint32);
44 static	void TIFFSetupShort(TIFF*, ttag_t, TIFFDirEntry*, uint16);
45 static	int TIFFSetupShortPair(TIFF*, ttag_t, TIFFDirEntry*);
46 static	int TIFFWritePerSampleShorts(TIFF*, ttag_t, TIFFDirEntry*);
47 static	int TIFFWritePerSampleAnys(TIFF*, TIFFDataType, ttag_t, TIFFDirEntry*);
48 static	int TIFFWriteShortTable(TIFF*, ttag_t, TIFFDirEntry*, uint32, uint16**);
49 static	int TIFFWriteShortArray(TIFF*, TIFFDirEntry*, uint16*);
50 static	int TIFFWriteLongArray(TIFF *, TIFFDirEntry*, uint32*);
51 static	int TIFFWriteRationalArray(TIFF *, TIFFDirEntry*, float*);
52 static	int TIFFWriteFloatArray(TIFF *, TIFFDirEntry*, float*);
53 static	int TIFFWriteDoubleArray(TIFF *, TIFFDirEntry*, double*);
54 static	int TIFFWriteByteArray(TIFF*, TIFFDirEntry*, char*);
55 static	int TIFFWriteAnyArray(TIFF*,
56 	    TIFFDataType, ttag_t, TIFFDirEntry*, uint32, double*);
57 static	int TIFFWriteTransferFunction(TIFF*, TIFFDirEntry*);
58 static	int TIFFWriteInkNames(TIFF*, TIFFDirEntry*);
59 static	int TIFFWriteData(TIFF*, TIFFDirEntry*, char*);
60 static	int TIFFLinkDirectory(TIFF*);
61 
62 #define	WriteRationalPair(type, tag1, v1, tag2, v2) {		\
63 	TIFFWriteRational((tif), (type), (tag1), (dir), (v1))	\
64 	TIFFWriteRational((tif), (type), (tag2), (dir)+1, (v2))	\
65 	(dir)++;						\
66 }
67 #define	TIFFWriteRational(tif, type, tag, dir, v)		\
68 	(dir)->tdir_tag = (tag);				\
69 	(dir)->tdir_type = (type);				\
70 	(dir)->tdir_count = 1;					\
71 	if (!TIFFWriteRationalArray((tif), (dir), &(v)))	\
72 		goto bad;
73 
74 /*
75  * Write the contents of the current directory
76  * to the specified file.  This routine doesn't
77  * handle overwriting a directory with auxiliary
78  * storage that's been changed.
79  */
80 static int
_TIFFWriteDirectory(TIFF * tif,int done)81 _TIFFWriteDirectory(TIFF* tif, int done)
82 {
83 	uint16 dircount;
84 	toff_t diroff;
85 	ttag_t tag;
86 	uint32 nfields;
87 	tsize_t dirsize;
88 	char* data;
89 	TIFFDirEntry* dir;
90 	TIFFDirectory* td;
91 	unsigned long b, fields[FIELD_SETLONGS];
92 	int fi, nfi;
93 
94 	if (tif->tif_mode == O_RDONLY)
95 		return (1);
96 	/*
97 	 * Clear write state so that subsequent images with
98 	 * different characteristics get the right buffers
99 	 * setup for them.
100 	 */
101 	if (done)
102 	{
103 	    if (tif->tif_flags & TIFF_POSTENCODE) {
104 		    tif->tif_flags &= ~TIFF_POSTENCODE;
105 		    if (!(*tif->tif_postencode)(tif)) {
106 				TIFFErrorExt(tif->tif_clientdata, tif->tif_name,
107 				"Error post-encoding before directory write");
108 			    return (0);
109 		    }
110 	    }
111 	    (*tif->tif_close)(tif);		/* shutdown encoder */
112 	    /*
113 	     * Flush any data that might have been written
114 	     * by the compression close+cleanup routines.
115 	     */
116 	    if (tif->tif_rawcc > 0 && !TIFFFlushData1(tif)) {
117 			TIFFErrorExt(tif->tif_clientdata, tif->tif_name,
118 			"Error flushing data before directory write");
119 		    return (0);
120 	    }
121 	    if ((tif->tif_flags & TIFF_MYBUFFER) && tif->tif_rawdata) {
122 		    _TIFFfree(tif->tif_rawdata);
123 		    tif->tif_rawdata = NULL;
124 		    tif->tif_rawcc = 0;
125 		    tif->tif_rawdatasize = 0;
126 	    }
127 	    tif->tif_flags &= ~(TIFF_BEENWRITING|TIFF_BUFFERSETUP);
128 	}
129 
130 	td = &tif->tif_dir;
131 	/*
132 	 * Size the directory so that we can calculate
133 	 * offsets for the data items that aren't kept
134 	 * in-place in each field.
135 	 */
136 	nfields = 0;
137 	for (b = 0; b <= FIELD_LAST; b++)
138 		if (TIFFFieldSet(tif, b) && b != FIELD_CUSTOM)
139 			nfields += (b < FIELD_SUBFILETYPE ? 2 : 1);
140         nfields += td->td_customValueCount;
141 	dirsize = nfields * sizeof (TIFFDirEntry);
142 	data = (char*) _TIFFmalloc(dirsize);
143 	if (data == NULL) {
144 		TIFFErrorExt(tif->tif_clientdata, tif->tif_name,
145 		    "Cannot write directory, out of space");
146 		return (0);
147 	}
148 	/*
149 	 * Directory hasn't been placed yet, put
150 	 * it at the end of the file and link it
151 	 * into the existing directory structure.
152 	 */
153 	if (tif->tif_diroff == 0 && !TIFFLinkDirectory(tif))
154 		goto bad;
155 	tif->tif_dataoff = (toff_t)(
156 	    tif->tif_diroff + sizeof (uint16) + dirsize + sizeof (toff_t));
157 	if (tif->tif_dataoff & 1)
158 		tif->tif_dataoff++;
159 	(void) TIFFSeekFile(tif, tif->tif_dataoff, SEEK_SET);
160 	tif->tif_curdir++;
161 	dir = (TIFFDirEntry*) data;
162 	/*
163 	 * Setup external form of directory
164 	 * entries and write data items.
165 	 */
166 	_TIFFmemcpy(fields, td->td_fieldsset, sizeof (fields));
167 	/*
168 	 * Write out ExtraSamples tag only if
169 	 * extra samples are present in the data.
170 	 */
171 	if (FieldSet(fields, FIELD_EXTRASAMPLES) && !td->td_extrasamples) {
172 		ResetFieldBit(fields, FIELD_EXTRASAMPLES);
173 		nfields--;
174 		dirsize -= sizeof (TIFFDirEntry);
175 	}								/*XXX*/
176 	for (fi = 0, nfi = tif->tif_nfields; nfi > 0; nfi--, fi++) {
177 		const TIFFFieldInfo* fip = tif->tif_fieldinfo[fi];
178 
179                 /*
180                 ** For custom fields, we test to see if the custom field
181                 ** is set or not.  For normal fields, we just use the
182                 ** FieldSet test.
183                 */
184                 if( fip->field_bit == FIELD_CUSTOM )
185                 {
186                     int ci, is_set = FALSE;
187 
188                     for( ci = 0; ci < td->td_customValueCount; ci++ )
189                         is_set |= (td->td_customValues[ci].info == fip);
190 
191                     if( !is_set )
192                         continue;
193                 }
194 		else if (!FieldSet(fields, fip->field_bit))
195                     continue;
196 
197 
198                 /*
199                 ** Handle other fields.
200                 */
201 		switch (fip->field_bit)
202                 {
203 		case FIELD_STRIPOFFSETS:
204 			/*
205 			 * We use one field bit for both strip and tile
206 
207 			 * offsets, and so must be careful in selecting
208 			 * the appropriate field descriptor (so that tags
209 			 * are written in sorted order).
210 			 */
211 			tag = isTiled(tif) ?
212 			    TIFFTAG_TILEOFFSETS : TIFFTAG_STRIPOFFSETS;
213 			if (tag != fip->field_tag)
214 				continue;
215 
216 			dir->tdir_tag = (uint16) tag;
217 			dir->tdir_type = (uint16) TIFF_LONG;
218 			dir->tdir_count = (uint32) td->td_nstrips;
219 			if (!TIFFWriteLongArray(tif, dir, td->td_stripoffset))
220 				goto bad;
221 			break;
222 		case FIELD_STRIPBYTECOUNTS:
223 			/*
224 			 * We use one field bit for both strip and tile
225 			 * byte counts, and so must be careful in selecting
226 			 * the appropriate field descriptor (so that tags
227 			 * are written in sorted order).
228 			 */
229 			tag = isTiled(tif) ?
230 			    TIFFTAG_TILEBYTECOUNTS : TIFFTAG_STRIPBYTECOUNTS;
231 			if (tag != fip->field_tag)
232 				continue;
233 
234 			dir->tdir_tag = (uint16) tag;
235 			dir->tdir_type = (uint16) TIFF_LONG;
236 			dir->tdir_count = (uint32) td->td_nstrips;
237 			if (!TIFFWriteLongArray(tif, dir,
238 						td->td_stripbytecount))
239 				goto bad;
240 			break;
241 		case FIELD_ROWSPERSTRIP:
242 			TIFFSetupShortLong(tif, TIFFTAG_ROWSPERSTRIP,
243 			    dir, td->td_rowsperstrip);
244 			break;
245 		case FIELD_COLORMAP:
246 			if (!TIFFWriteShortTable(tif, TIFFTAG_COLORMAP, dir,
247 			    3, td->td_colormap))
248 				goto bad;
249 			break;
250 		case FIELD_IMAGEDIMENSIONS:
251 			TIFFSetupShortLong(tif, TIFFTAG_IMAGEWIDTH,
252 			    dir++, td->td_imagewidth);
253 			TIFFSetupShortLong(tif, TIFFTAG_IMAGELENGTH,
254 			    dir, td->td_imagelength);
255 			break;
256 		case FIELD_TILEDIMENSIONS:
257 			TIFFSetupShortLong(tif, TIFFTAG_TILEWIDTH,
258 			    dir++, td->td_tilewidth);
259 			TIFFSetupShortLong(tif, TIFFTAG_TILELENGTH,
260 			    dir, td->td_tilelength);
261 			break;
262 		case FIELD_COMPRESSION:
263 			TIFFSetupShort(tif, TIFFTAG_COMPRESSION,
264 			    dir, td->td_compression);
265 			break;
266 		case FIELD_PHOTOMETRIC:
267 			TIFFSetupShort(tif, TIFFTAG_PHOTOMETRIC,
268 			    dir, td->td_photometric);
269 			break;
270 		case FIELD_POSITION:
271 			WriteRationalPair(TIFF_RATIONAL,
272 			    TIFFTAG_XPOSITION, td->td_xposition,
273 			    TIFFTAG_YPOSITION, td->td_yposition);
274 			break;
275 		case FIELD_RESOLUTION:
276 			WriteRationalPair(TIFF_RATIONAL,
277 			    TIFFTAG_XRESOLUTION, td->td_xresolution,
278 			    TIFFTAG_YRESOLUTION, td->td_yresolution);
279 			break;
280 		case FIELD_BITSPERSAMPLE:
281 		case FIELD_MINSAMPLEVALUE:
282 		case FIELD_MAXSAMPLEVALUE:
283 		case FIELD_SAMPLEFORMAT:
284 			if (!TIFFWritePerSampleShorts(tif, fip->field_tag, dir))
285 				goto bad;
286 			break;
287 		case FIELD_SMINSAMPLEVALUE:
288 		case FIELD_SMAXSAMPLEVALUE:
289 			if (!TIFFWritePerSampleAnys(tif,
290 			    _TIFFSampleToTagType(tif), fip->field_tag, dir))
291 				goto bad;
292 			break;
293 		case FIELD_PAGENUMBER:
294 		case FIELD_HALFTONEHINTS:
295 		case FIELD_YCBCRSUBSAMPLING:
296 			if (!TIFFSetupShortPair(tif, fip->field_tag, dir))
297 				goto bad;
298 			break;
299 		case FIELD_INKNAMES:
300 			if (!TIFFWriteInkNames(tif, dir))
301 				goto bad;
302 			break;
303 		case FIELD_TRANSFERFUNCTION:
304 			if (!TIFFWriteTransferFunction(tif, dir))
305 				goto bad;
306 			break;
307 		case FIELD_SUBIFD:
308 			/*
309 			 * XXX: Always write this field using LONG type
310 			 * for backward compatibility.
311 			 */
312 			dir->tdir_tag = (uint16) fip->field_tag;
313 			dir->tdir_type = (uint16) TIFF_LONG;
314 			dir->tdir_count = (uint32) td->td_nsubifd;
315 			if (!TIFFWriteLongArray(tif, dir, td->td_subifd))
316 				goto bad;
317 			/*
318 			 * Total hack: if this directory includes a SubIFD
319 			 * tag then force the next <n> directories to be
320 			 * written as ``sub directories'' of this one.  This
321 			 * is used to write things like thumbnails and
322 			 * image masks that one wants to keep out of the
323 			 * normal directory linkage access mechanism.
324 			 */
325 			if (dir->tdir_count > 0) {
326 				tif->tif_flags |= TIFF_INSUBIFD;
327 				tif->tif_nsubifd = (uint16) dir->tdir_count;
328 				if (dir->tdir_count > 1)
329 					tif->tif_subifdoff = dir->tdir_offset;
330 				else
331 					tif->tif_subifdoff = (uint32)(
332 					      tif->tif_diroff
333 					    + sizeof (uint16)
334 					    + ((char*)&dir->tdir_offset-data));
335 			}
336 			break;
337 		default:
338 			/* XXX: Should be fixed and removed. */
339 			if (fip->field_tag == TIFFTAG_DOTRANGE) {
340 				if (!TIFFSetupShortPair(tif, fip->field_tag, dir))
341 					goto bad;
342 			}
343 			else if (!TIFFWriteNormalTag(tif, dir, fip))
344 				goto bad;
345 			break;
346 		}
347 		dir++;
348 
349                 if( fip->field_bit != FIELD_CUSTOM )
350                     ResetFieldBit(fields, fip->field_bit);
351 	}
352 
353 	/*
354 	 * Write directory.
355 	 */
356 	dircount = (uint16) nfields;
357 	diroff = (uint32) tif->tif_nextdiroff;
358 	if (tif->tif_flags & TIFF_SWAB) {
359 		/*
360 		 * The file's byte order is opposite to the
361 		 * native machine architecture.  We overwrite
362 		 * the directory information with impunity
363 		 * because it'll be released below after we
364 		 * write it to the file.  Note that all the
365 		 * other tag construction routines assume that
366 		 * we do this byte-swapping; i.e. they only
367 		 * byte-swap indirect data.
368 		 */
369 		for (dir = (TIFFDirEntry*) data; dircount; dir++, dircount--) {
370 			TIFFSwabArrayOfShort(&dir->tdir_tag, 2);
371 			TIFFSwabArrayOfLong(&dir->tdir_count, 2);
372 		}
373 		dircount = (uint16) nfields;
374 		TIFFSwabShort(&dircount);
375 		TIFFSwabLong(&diroff);
376 	}
377 	(void) TIFFSeekFile(tif, tif->tif_diroff, SEEK_SET);
378 	if (!WriteOK(tif, &dircount, sizeof (dircount))) {
379 		TIFFErrorExt(tif->tif_clientdata, tif->tif_name, "Error writing directory count");
380 		goto bad;
381 	}
382 	if (!WriteOK(tif, data, dirsize)) {
383 		TIFFErrorExt(tif->tif_clientdata, tif->tif_name, "Error writing directory contents");
384 		goto bad;
385 	}
386 	if (!WriteOK(tif, &diroff, sizeof (diroff))) {
387 		TIFFErrorExt(tif->tif_clientdata, tif->tif_name, "Error writing directory link");
388 		goto bad;
389 	}
390 	if (done) {
391 		TIFFFreeDirectory(tif);
392 		tif->tif_flags &= ~TIFF_DIRTYDIRECT;
393 		(*tif->tif_cleanup)(tif);
394 
395 		/*
396 		* Reset directory-related state for subsequent
397 		* directories.
398 		*/
399 		TIFFCreateDirectory(tif);
400 	}
401 	_TIFFfree(data);
402 	return (1);
403 bad:
404 	_TIFFfree(data);
405 	return (0);
406 }
407 #undef WriteRationalPair
408 
409 int
TIFFWriteDirectory(TIFF * tif)410 TIFFWriteDirectory(TIFF* tif)
411 {
412 	return _TIFFWriteDirectory(tif, TRUE);
413 }
414 
415 /*
416  * Similar to TIFFWriteDirectory(), writes the directory out
417  * but leaves all data structures in memory so that it can be
418  * written again.  This will make a partially written TIFF file
419  * readable before it is successfully completed/closed.
420  */
421 int
TIFFCheckpointDirectory(TIFF * tif)422 TIFFCheckpointDirectory(TIFF* tif)
423 {
424 	int rc;
425 	/* Setup the strips arrays, if they haven't already been. */
426 	if (tif->tif_dir.td_stripoffset == NULL)
427 	    (void) TIFFSetupStrips(tif);
428 	rc = _TIFFWriteDirectory(tif, FALSE);
429 	(void) TIFFSetWriteOffset(tif, TIFFSeekFile(tif, 0, SEEK_END));
430 	return rc;
431 }
432 
433 /*
434  * Process tags that are not special cased.
435  */
436 static int
TIFFWriteNormalTag(TIFF * tif,TIFFDirEntry * dir,const TIFFFieldInfo * fip)437 TIFFWriteNormalTag(TIFF* tif, TIFFDirEntry* dir, const TIFFFieldInfo* fip)
438 {
439 	uint16 wc = (uint16) fip->field_writecount;
440 	uint32 wc2;
441 
442 	dir->tdir_tag = (uint16) fip->field_tag;
443 	dir->tdir_type = (uint16) fip->field_type;
444 	dir->tdir_count = wc;
445 
446 	switch (fip->field_type) {
447 	case TIFF_SHORT:
448 	case TIFF_SSHORT:
449 		if (fip->field_passcount) {
450 			uint16* wp;
451 			if (wc == (uint16) TIFF_VARIABLE2) {
452 				TIFFGetField(tif, fip->field_tag, &wc2, &wp);
453 				dir->tdir_count = wc2;
454 			} else {	/* Assume TIFF_VARIABLE */
455 				TIFFGetField(tif, fip->field_tag, &wc, &wp);
456 				dir->tdir_count = wc;
457 			}
458 			if (!TIFFWriteShortArray(tif, dir, wp))
459 				return 0;
460 		} else {
461 			if (wc == 1) {
462 				uint16 sv;
463 				TIFFGetField(tif, fip->field_tag, &sv);
464 				dir->tdir_offset =
465 					TIFFInsertData(tif, dir->tdir_type, sv);
466 			} else {
467 				uint16* wp;
468 				TIFFGetField(tif, fip->field_tag, &wp);
469 				if (!TIFFWriteShortArray(tif, dir, wp))
470 					return 0;
471 			}
472 		}
473 		break;
474 	case TIFF_LONG:
475 	case TIFF_SLONG:
476 	case TIFF_IFD:
477 		if (fip->field_passcount) {
478 			uint32* lp;
479 			if (wc == (uint16) TIFF_VARIABLE2) {
480 				TIFFGetField(tif, fip->field_tag, &wc2, &lp);
481 				dir->tdir_count = wc2;
482 			} else {	/* Assume TIFF_VARIABLE */
483 				TIFFGetField(tif, fip->field_tag, &wc, &lp);
484 				dir->tdir_count = wc;
485 			}
486 			if (!TIFFWriteLongArray(tif, dir, lp))
487 				return 0;
488 		} else {
489 			if (wc == 1) {
490 				/* XXX handle LONG->SHORT conversion */
491 				TIFFGetField(tif, fip->field_tag,
492 					     &dir->tdir_offset);
493 			} else {
494 				uint32* lp;
495 				TIFFGetField(tif, fip->field_tag, &lp);
496 				if (!TIFFWriteLongArray(tif, dir, lp))
497 					return 0;
498 			}
499 		}
500 		break;
501 	case TIFF_RATIONAL:
502 	case TIFF_SRATIONAL:
503 		if (fip->field_passcount) {
504 			float* fp;
505 			if (wc == (uint16) TIFF_VARIABLE2) {
506 				TIFFGetField(tif, fip->field_tag, &wc2, &fp);
507 				dir->tdir_count = wc2;
508 			} else {	/* Assume TIFF_VARIABLE */
509 				TIFFGetField(tif, fip->field_tag, &wc, &fp);
510 				dir->tdir_count = wc;
511 			}
512 			if (!TIFFWriteRationalArray(tif, dir, fp))
513 				return 0;
514 		} else {
515 			if (wc == 1) {
516 				float fv;
517 				TIFFGetField(tif, fip->field_tag, &fv);
518 				if (!TIFFWriteRationalArray(tif, dir, &fv))
519 					return 0;
520 			} else {
521 				float* fp;
522 				TIFFGetField(tif, fip->field_tag, &fp);
523 				if (!TIFFWriteRationalArray(tif, dir, fp))
524 					return 0;
525 			}
526 		}
527 		break;
528 	case TIFF_FLOAT:
529 		if (fip->field_passcount) {
530 			float* fp;
531 			if (wc == (uint16) TIFF_VARIABLE2) {
532 				TIFFGetField(tif, fip->field_tag, &wc2, &fp);
533 				dir->tdir_count = wc2;
534 			} else {	/* Assume TIFF_VARIABLE */
535 				TIFFGetField(tif, fip->field_tag, &wc, &fp);
536 				dir->tdir_count = wc;
537 			}
538 			if (!TIFFWriteFloatArray(tif, dir, fp))
539 				return 0;
540 		} else {
541 			if (wc == 1) {
542 				float fv;
543 				TIFFGetField(tif, fip->field_tag, &fv);
544 				if (!TIFFWriteFloatArray(tif, dir, &fv))
545 					return 0;
546 			} else {
547 				float* fp;
548 				TIFFGetField(tif, fip->field_tag, &fp);
549 				if (!TIFFWriteFloatArray(tif, dir, fp))
550 					return 0;
551 			}
552 		}
553 		break;
554 	case TIFF_DOUBLE:
555 		if (fip->field_passcount) {
556 			double* dp;
557 			if (wc == (uint16) TIFF_VARIABLE2) {
558 				TIFFGetField(tif, fip->field_tag, &wc2, &dp);
559 				dir->tdir_count = wc2;
560 			} else {	/* Assume TIFF_VARIABLE */
561 				TIFFGetField(tif, fip->field_tag, &wc, &dp);
562 				dir->tdir_count = wc;
563 			}
564 			if (!TIFFWriteDoubleArray(tif, dir, dp))
565 				return 0;
566 		} else {
567 			if (wc == 1) {
568 				double dv;
569 				TIFFGetField(tif, fip->field_tag, &dv);
570 				if (!TIFFWriteDoubleArray(tif, dir, &dv))
571 					return 0;
572 			} else {
573 				double* dp;
574 				TIFFGetField(tif, fip->field_tag, &dp);
575 				if (!TIFFWriteDoubleArray(tif, dir, dp))
576 					return 0;
577 			}
578 		}
579 		break;
580 	case TIFF_ASCII:
581 		{
582                     char* cp;
583                     if (fip->field_passcount)
584                         TIFFGetField(tif, fip->field_tag, &wc, &cp);
585                     else
586                         TIFFGetField(tif, fip->field_tag, &cp);
587 
588                     dir->tdir_count = (uint32) (strlen(cp) + 1);
589                     if (!TIFFWriteByteArray(tif, dir, cp))
590                         return (0);
591 		}
592 		break;
593 
594         case TIFF_BYTE:
595         case TIFF_SBYTE:
596 		if (fip->field_passcount) {
597 			char* cp;
598 			if (wc == (uint16) TIFF_VARIABLE2) {
599 				TIFFGetField(tif, fip->field_tag, &wc2, &cp);
600 				dir->tdir_count = wc2;
601 			} else {	/* Assume TIFF_VARIABLE */
602 				TIFFGetField(tif, fip->field_tag, &wc, &cp);
603 				dir->tdir_count = wc;
604 			}
605 			if (!TIFFWriteByteArray(tif, dir, cp))
606 				return 0;
607 		} else {
608 			if (wc == 1) {
609 				char cv;
610 				TIFFGetField(tif, fip->field_tag, &cv);
611 				if (!TIFFWriteByteArray(tif, dir, &cv))
612 					return 0;
613 			} else {
614 				char* cp;
615 				TIFFGetField(tif, fip->field_tag, &cp);
616 				if (!TIFFWriteByteArray(tif, dir, cp))
617 					return 0;
618 			}
619 		}
620                 break;
621 
622 	case TIFF_UNDEFINED:
623 		{ char* cp;
624 		  if (wc == (unsigned short) TIFF_VARIABLE) {
625 			TIFFGetField(tif, fip->field_tag, &wc, &cp);
626 			dir->tdir_count = wc;
627 		  } else if (wc == (unsigned short) TIFF_VARIABLE2) {
628 			TIFFGetField(tif, fip->field_tag, &wc2, &cp);
629 			dir->tdir_count = wc2;
630 		  } else
631 			TIFFGetField(tif, fip->field_tag, &cp);
632 		  if (!TIFFWriteByteArray(tif, dir, cp))
633 			return (0);
634 		}
635 		break;
636 
637         case TIFF_NOTYPE:
638                 break;
639 	}
640 	return (1);
641 }
642 
643 /*
644  * Setup a directory entry with either a SHORT
645  * or LONG type according to the value.
646  */
647 static void
TIFFSetupShortLong(TIFF * tif,ttag_t tag,TIFFDirEntry * dir,uint32 v)648 TIFFSetupShortLong(TIFF* tif, ttag_t tag, TIFFDirEntry* dir, uint32 v)
649 {
650 	dir->tdir_tag = (uint16) tag;
651 	dir->tdir_count = 1;
652 	if (v > 0xffffL) {
653 		dir->tdir_type = (short) TIFF_LONG;
654 		dir->tdir_offset = v;
655 	} else {
656 		dir->tdir_type = (short) TIFF_SHORT;
657 		dir->tdir_offset = TIFFInsertData(tif, (int) TIFF_SHORT, v);
658 	}
659 }
660 
661 /*
662  * Setup a SHORT directory entry
663  */
664 static void
TIFFSetupShort(TIFF * tif,ttag_t tag,TIFFDirEntry * dir,uint16 v)665 TIFFSetupShort(TIFF* tif, ttag_t tag, TIFFDirEntry* dir, uint16 v)
666 {
667 	dir->tdir_tag = (uint16) tag;
668 	dir->tdir_count = 1;
669 	dir->tdir_type = (short) TIFF_SHORT;
670 	dir->tdir_offset = TIFFInsertData(tif, (int) TIFF_SHORT, v);
671 }
672 #undef MakeShortDirent
673 
674 #define	NITEMS(x)	(sizeof (x) / sizeof (x[0]))
675 /*
676  * Setup a directory entry that references a
677  * samples/pixel array of SHORT values and
678  * (potentially) write the associated indirect
679  * values.
680  */
681 static int
TIFFWritePerSampleShorts(TIFF * tif,ttag_t tag,TIFFDirEntry * dir)682 TIFFWritePerSampleShorts(TIFF* tif, ttag_t tag, TIFFDirEntry* dir)
683 {
684 	uint16 buf[10], v;
685 	uint16* w = buf;
686 	uint16 i, samples = tif->tif_dir.td_samplesperpixel;
687 	int status;
688 
689 	if (samples > NITEMS(buf)) {
690 		w = (uint16*) _TIFFmalloc(samples * sizeof (uint16));
691 		if (w == NULL) {
692 			TIFFErrorExt(tif->tif_clientdata, tif->tif_name,
693 			    "No space to write per-sample shorts");
694 			return (0);
695 		}
696 	}
697 	TIFFGetField(tif, tag, &v);
698 	for (i = 0; i < samples; i++)
699 		w[i] = v;
700 
701 	dir->tdir_tag = (uint16) tag;
702 	dir->tdir_type = (uint16) TIFF_SHORT;
703 	dir->tdir_count = samples;
704 	status = TIFFWriteShortArray(tif, dir, w);
705 	if (w != buf)
706 		_TIFFfree((char*) w);
707 	return (status);
708 }
709 
710 /*
711  * Setup a directory entry that references a samples/pixel array of ``type''
712  * values and (potentially) write the associated indirect values.  The source
713  * data from TIFFGetField() for the specified tag must be returned as double.
714  */
715 static int
TIFFWritePerSampleAnys(TIFF * tif,TIFFDataType type,ttag_t tag,TIFFDirEntry * dir)716 TIFFWritePerSampleAnys(TIFF* tif,
717     TIFFDataType type, ttag_t tag, TIFFDirEntry* dir)
718 {
719 	double buf[10], v;
720 	double* w = buf;
721 	uint16 i, samples = tif->tif_dir.td_samplesperpixel;
722 	int status;
723 
724 	if (samples > NITEMS(buf)) {
725 		w = (double*) _TIFFmalloc(samples * sizeof (double));
726 		if (w == NULL) {
727 			TIFFErrorExt(tif->tif_clientdata, tif->tif_name,
728 			    "No space to write per-sample values");
729 			return (0);
730 		}
731 	}
732 	TIFFGetField(tif, tag, &v);
733 	for (i = 0; i < samples; i++)
734 		w[i] = v;
735 	status = TIFFWriteAnyArray(tif, type, tag, dir, samples, w);
736 	if (w != buf)
737 		_TIFFfree(w);
738 	return (status);
739 }
740 #undef NITEMS
741 
742 /*
743  * Setup a pair of shorts that are returned by
744  * value, rather than as a reference to an array.
745  */
746 static int
TIFFSetupShortPair(TIFF * tif,ttag_t tag,TIFFDirEntry * dir)747 TIFFSetupShortPair(TIFF* tif, ttag_t tag, TIFFDirEntry* dir)
748 {
749 	uint16 v[2];
750 
751 	TIFFGetField(tif, tag, &v[0], &v[1]);
752 
753 	dir->tdir_tag = (uint16) tag;
754 	dir->tdir_type = (uint16) TIFF_SHORT;
755 	dir->tdir_count = 2;
756 	return (TIFFWriteShortArray(tif, dir, v));
757 }
758 
759 /*
760  * Setup a directory entry for an NxM table of shorts,
761  * where M is known to be 2**bitspersample, and write
762  * the associated indirect data.
763  */
764 static int
TIFFWriteShortTable(TIFF * tif,ttag_t tag,TIFFDirEntry * dir,uint32 n,uint16 ** table)765 TIFFWriteShortTable(TIFF* tif,
766     ttag_t tag, TIFFDirEntry* dir, uint32 n, uint16** table)
767 {
768 	uint32 i, off;
769 
770 	dir->tdir_tag = (uint16) tag;
771 	dir->tdir_type = (short) TIFF_SHORT;
772 	/* XXX -- yech, fool TIFFWriteData */
773 	dir->tdir_count = (uint32) (1L<<tif->tif_dir.td_bitspersample);
774 	off = tif->tif_dataoff;
775 	for (i = 0; i < n; i++)
776 		if (!TIFFWriteData(tif, dir, (char *)table[i]))
777 			return (0);
778 	dir->tdir_count *= n;
779 	dir->tdir_offset = off;
780 	return (1);
781 }
782 
783 /*
784  * Write/copy data associated with an ASCII or opaque tag value.
785  */
786 static int
TIFFWriteByteArray(TIFF * tif,TIFFDirEntry * dir,char * cp)787 TIFFWriteByteArray(TIFF* tif, TIFFDirEntry* dir, char* cp)
788 {
789 	if (dir->tdir_count > 4) {
790 		if (!TIFFWriteData(tif, dir, cp))
791 			return (0);
792 	} else
793 		_TIFFmemcpy(&dir->tdir_offset, cp, dir->tdir_count);
794 	return (1);
795 }
796 
797 /*
798  * Setup a directory entry of an array of SHORT
799  * or SSHORT and write the associated indirect values.
800  */
801 static int
TIFFWriteShortArray(TIFF * tif,TIFFDirEntry * dir,uint16 * v)802 TIFFWriteShortArray(TIFF* tif, TIFFDirEntry* dir, uint16* v)
803 {
804 	if (dir->tdir_count <= 2) {
805 		if (tif->tif_header.tiff_magic == TIFF_BIGENDIAN) {
806 			dir->tdir_offset = (uint32) ((long) v[0] << 16);
807 			if (dir->tdir_count == 2)
808 				dir->tdir_offset |= v[1] & 0xffff;
809 		} else {
810 			dir->tdir_offset = v[0] & 0xffff;
811 			if (dir->tdir_count == 2)
812 				dir->tdir_offset |= (long) v[1] << 16;
813 		}
814 		return (1);
815 	} else
816 		return (TIFFWriteData(tif, dir, (char*) v));
817 }
818 
819 /*
820  * Setup a directory entry of an array of LONG
821  * or SLONG and write the associated indirect values.
822  */
823 static int
TIFFWriteLongArray(TIFF * tif,TIFFDirEntry * dir,uint32 * v)824 TIFFWriteLongArray(TIFF* tif, TIFFDirEntry* dir, uint32* v)
825 {
826 	if (dir->tdir_count == 1) {
827 		dir->tdir_offset = v[0];
828 		return (1);
829 	} else
830 		return (TIFFWriteData(tif, dir, (char*) v));
831 }
832 
833 /*
834  * Setup a directory entry of an array of RATIONAL
835  * or SRATIONAL and write the associated indirect values.
836  */
837 static int
TIFFWriteRationalArray(TIFF * tif,TIFFDirEntry * dir,float * v)838 TIFFWriteRationalArray(TIFF* tif, TIFFDirEntry* dir, float* v)
839 {
840 	uint32 i;
841 	uint32* t;
842 	int status;
843 
844 	t = (uint32*) _TIFFmalloc(2 * dir->tdir_count * sizeof (uint32));
845 	if (t == NULL) {
846 		TIFFErrorExt(tif->tif_clientdata, tif->tif_name,
847 		    "No space to write RATIONAL array");
848 		return (0);
849 	}
850 	for (i = 0; i < dir->tdir_count; i++) {
851 		float fv = v[i];
852 		int sign = 1;
853 		uint32 den;
854 
855 		if (fv < 0) {
856 			if (dir->tdir_type == TIFF_RATIONAL) {
857 				TIFFWarningExt(tif->tif_clientdata, tif->tif_name,
858 	"\"%s\": Information lost writing value (%g) as (unsigned) RATIONAL",
859 				_TIFFFieldWithTag(tif,dir->tdir_tag)->field_name,
860 				fv);
861 				fv = 0;
862 			} else
863 				fv = -fv, sign = -1;
864 		}
865 		den = 1L;
866 		if (fv > 0) {
867 			while (fv < 1L<<(31-3) && den < 1L<<(31-3))
868 				fv *= 1<<3, den *= 1L<<3;
869 		}
870 		t[2*i+0] = (uint32) (sign * (fv + 0.5));
871 		t[2*i+1] = den;
872 	}
873 	status = TIFFWriteData(tif, dir, (char *)t);
874 	_TIFFfree((char*) t);
875 	return (status);
876 }
877 
878 static int
TIFFWriteFloatArray(TIFF * tif,TIFFDirEntry * dir,float * v)879 TIFFWriteFloatArray(TIFF* tif, TIFFDirEntry* dir, float* v)
880 {
881 	TIFFCvtNativeToIEEEFloat(tif, dir->tdir_count, v);
882 	if (dir->tdir_count == 1) {
883 		dir->tdir_offset = *(uint32*) &v[0];
884 		return (1);
885 	} else
886 		return (TIFFWriteData(tif, dir, (char*) v));
887 }
888 
889 static int
TIFFWriteDoubleArray(TIFF * tif,TIFFDirEntry * dir,double * v)890 TIFFWriteDoubleArray(TIFF* tif, TIFFDirEntry* dir, double* v)
891 {
892 	TIFFCvtNativeToIEEEDouble(tif, dir->tdir_count, v);
893 	return (TIFFWriteData(tif, dir, (char*) v));
894 }
895 
896 /*
897  * Write an array of ``type'' values for a specified tag (i.e. this is a tag
898  * which is allowed to have different types, e.g. SMaxSampleType).
899  * Internally the data values are represented as double since a double can
900  * hold any of the TIFF tag types (yes, this should really be an abstract
901  * type tany_t for portability).  The data is converted into the specified
902  * type in a temporary buffer and then handed off to the appropriate array
903  * writer.
904  */
905 static int
TIFFWriteAnyArray(TIFF * tif,TIFFDataType type,ttag_t tag,TIFFDirEntry * dir,uint32 n,double * v)906 TIFFWriteAnyArray(TIFF* tif,
907     TIFFDataType type, ttag_t tag, TIFFDirEntry* dir, uint32 n, double* v)
908 {
909 	char buf[10 * sizeof(double)];
910 	char* w = buf;
911 	int i, status = 0;
912 
913 	if (n * TIFFDataWidth(type) > sizeof buf) {
914 		w = (char*) _TIFFmalloc(n * TIFFDataWidth(type));
915 		if (w == NULL) {
916 			TIFFErrorExt(tif->tif_clientdata, tif->tif_name,
917 			    "No space to write array");
918 			return (0);
919 		}
920 	}
921 
922 	dir->tdir_tag = (uint16) tag;
923 	dir->tdir_type = (uint16) type;
924 	dir->tdir_count = n;
925 
926 	switch (type) {
927 	case TIFF_BYTE:
928 		{
929 			uint8* bp = (uint8*) w;
930 			for (i = 0; i < (int) n; i++)
931 				bp[i] = (uint8) v[i];
932 			if (!TIFFWriteByteArray(tif, dir, (char*) bp))
933 				goto out;
934 		}
935 		break;
936 	case TIFF_SBYTE:
937 		{
938 			int8* bp = (int8*) w;
939 			for (i = 0; i < (int) n; i++)
940 				bp[i] = (int8) v[i];
941 			if (!TIFFWriteByteArray(tif, dir, (char*) bp))
942 				goto out;
943 		}
944 		break;
945 	case TIFF_SHORT:
946 		{
947 			uint16* bp = (uint16*) w;
948 			for (i = 0; i < (int) n; i++)
949 				bp[i] = (uint16) v[i];
950 			if (!TIFFWriteShortArray(tif, dir, (uint16*)bp))
951 				goto out;
952 		}
953 		break;
954 	case TIFF_SSHORT:
955 		{
956 			int16* bp = (int16*) w;
957 			for (i = 0; i < (int) n; i++)
958 				bp[i] = (int16) v[i];
959 			if (!TIFFWriteShortArray(tif, dir, (uint16*)bp))
960 				goto out;
961 		}
962 		break;
963 	case TIFF_LONG:
964 		{
965 			uint32* bp = (uint32*) w;
966 			for (i = 0; i < (int) n; i++)
967 				bp[i] = (uint32) v[i];
968 			if (!TIFFWriteLongArray(tif, dir, bp))
969 				goto out;
970 		}
971 		break;
972 	case TIFF_SLONG:
973 		{
974 			int32* bp = (int32*) w;
975 			for (i = 0; i < (int) n; i++)
976 				bp[i] = (int32) v[i];
977 			if (!TIFFWriteLongArray(tif, dir, (uint32*) bp))
978 				goto out;
979 		}
980 		break;
981 	case TIFF_FLOAT:
982 		{
983 			float* bp = (float*) w;
984 			for (i = 0; i < (int) n; i++)
985 				bp[i] = (float) v[i];
986 			if (!TIFFWriteFloatArray(tif, dir, bp))
987 				goto out;
988 		}
989 		break;
990 	case TIFF_DOUBLE:
991 		return (TIFFWriteDoubleArray(tif, dir, v));
992 	default:
993 		/* TIFF_NOTYPE */
994 		/* TIFF_ASCII */
995 		/* TIFF_UNDEFINED */
996 		/* TIFF_RATIONAL */
997 		/* TIFF_SRATIONAL */
998 		goto out;
999 	}
1000 	status = 1;
1001  out:
1002 	if (w != buf)
1003 		_TIFFfree(w);
1004 	return (status);
1005 }
1006 
1007 static int
TIFFWriteTransferFunction(TIFF * tif,TIFFDirEntry * dir)1008 TIFFWriteTransferFunction(TIFF* tif, TIFFDirEntry* dir)
1009 {
1010 	TIFFDirectory* td = &tif->tif_dir;
1011 	tsize_t n = (1L<<td->td_bitspersample) * sizeof (uint16);
1012 	uint16** tf = td->td_transferfunction;
1013 	int ncols;
1014 
1015 	/*
1016 	 * Check if the table can be written as a single column,
1017 	 * or if it must be written as 3 columns.  Note that we
1018 	 * write a 3-column tag if there are 2 samples/pixel and
1019 	 * a single column of data won't suffice--hmm.
1020 	 */
1021 	switch (td->td_samplesperpixel - td->td_extrasamples) {
1022 	default:	if (_TIFFmemcmp(tf[0], tf[2], n)) { ncols = 3; break; }
1023 	case 2:		if (_TIFFmemcmp(tf[0], tf[1], n)) { ncols = 3; break; }
1024 	case 1: case 0:	ncols = 1;
1025 	}
1026 	return (TIFFWriteShortTable(tif,
1027 	    TIFFTAG_TRANSFERFUNCTION, dir, ncols, tf));
1028 }
1029 
1030 static int
TIFFWriteInkNames(TIFF * tif,TIFFDirEntry * dir)1031 TIFFWriteInkNames(TIFF* tif, TIFFDirEntry* dir)
1032 {
1033 	TIFFDirectory* td = &tif->tif_dir;
1034 
1035 	dir->tdir_tag = TIFFTAG_INKNAMES;
1036 	dir->tdir_type = (short) TIFF_ASCII;
1037 	dir->tdir_count = td->td_inknameslen;
1038 	return (TIFFWriteByteArray(tif, dir, td->td_inknames));
1039 }
1040 
1041 /*
1042  * Write a contiguous directory item.
1043  */
1044 static int
TIFFWriteData(TIFF * tif,TIFFDirEntry * dir,char * cp)1045 TIFFWriteData(TIFF* tif, TIFFDirEntry* dir, char* cp)
1046 {
1047 	tsize_t cc;
1048 
1049 	if (tif->tif_flags & TIFF_SWAB) {
1050 		switch (dir->tdir_type) {
1051 		case TIFF_SHORT:
1052 		case TIFF_SSHORT:
1053 			TIFFSwabArrayOfShort((uint16*) cp, dir->tdir_count);
1054 			break;
1055 		case TIFF_LONG:
1056 		case TIFF_SLONG:
1057 		case TIFF_FLOAT:
1058 			TIFFSwabArrayOfLong((uint32*) cp, dir->tdir_count);
1059 			break;
1060 		case TIFF_RATIONAL:
1061 		case TIFF_SRATIONAL:
1062 			TIFFSwabArrayOfLong((uint32*) cp, 2*dir->tdir_count);
1063 			break;
1064 		case TIFF_DOUBLE:
1065 			TIFFSwabArrayOfDouble((double*) cp, dir->tdir_count);
1066 			break;
1067 		}
1068 	}
1069 	dir->tdir_offset = tif->tif_dataoff;
1070 	cc = dir->tdir_count * TIFFDataWidth((TIFFDataType) dir->tdir_type);
1071 	if (SeekOK(tif, dir->tdir_offset) &&
1072 	    WriteOK(tif, cp, cc)) {
1073 		tif->tif_dataoff += (cc + 1) & ~1;
1074 		return (1);
1075 	}
1076 	TIFFErrorExt(tif->tif_clientdata, tif->tif_name, "Error writing data for field \"%s\"",
1077 	    _TIFFFieldWithTag(tif, dir->tdir_tag)->field_name);
1078 	return (0);
1079 }
1080 
1081 /*
1082  * Similar to TIFFWriteDirectory(), but if the directory has already
1083  * been written once, it is relocated to the end of the file, in case it
1084  * has changed in size.  Note that this will result in the loss of the
1085  * previously used directory space.
1086  */
1087 
1088 int
TIFFRewriteDirectory(TIFF * tif)1089 TIFFRewriteDirectory( TIFF *tif )
1090 {
1091     static const char module[] = "TIFFRewriteDirectory";
1092 
1093     /* We don't need to do anything special if it hasn't been written. */
1094     if( tif->tif_diroff == 0 )
1095         return TIFFWriteDirectory( tif );
1096 
1097     /*
1098     ** Find and zero the pointer to this directory, so that TIFFLinkDirectory
1099     ** will cause it to be added after this directories current pre-link.
1100     */
1101 
1102     /* Is it the first directory in the file? */
1103     if (tif->tif_header.tiff_diroff == tif->tif_diroff)
1104     {
1105         tif->tif_header.tiff_diroff = 0;
1106         tif->tif_diroff = 0;
1107 
1108         TIFFSeekFile(tif, (toff_t)(TIFF_MAGIC_SIZE+TIFF_VERSION_SIZE),
1109 		     SEEK_SET);
1110         if (!WriteOK(tif, &(tif->tif_header.tiff_diroff),
1111                      sizeof (tif->tif_diroff)))
1112         {
1113 			TIFFErrorExt(tif->tif_clientdata, tif->tif_name, "Error updating TIFF header");
1114             return (0);
1115         }
1116     }
1117     else
1118     {
1119         toff_t  nextdir, off;
1120 
1121 	nextdir = tif->tif_header.tiff_diroff;
1122 	do {
1123 		uint16 dircount;
1124 
1125 		if (!SeekOK(tif, nextdir) ||
1126 		    !ReadOK(tif, &dircount, sizeof (dircount))) {
1127 			TIFFErrorExt(tif->tif_clientdata, module, "Error fetching directory count");
1128 			return (0);
1129 		}
1130 		if (tif->tif_flags & TIFF_SWAB)
1131 			TIFFSwabShort(&dircount);
1132 		(void) TIFFSeekFile(tif,
1133 		    dircount * sizeof (TIFFDirEntry), SEEK_CUR);
1134 		if (!ReadOK(tif, &nextdir, sizeof (nextdir))) {
1135 			TIFFErrorExt(tif->tif_clientdata, module, "Error fetching directory link");
1136 			return (0);
1137 		}
1138 		if (tif->tif_flags & TIFF_SWAB)
1139 			TIFFSwabLong(&nextdir);
1140 	} while (nextdir != tif->tif_diroff && nextdir != 0);
1141         off = TIFFSeekFile(tif, 0, SEEK_CUR); /* get current offset */
1142         (void) TIFFSeekFile(tif, off - (toff_t)sizeof(nextdir), SEEK_SET);
1143         tif->tif_diroff = 0;
1144 	if (!WriteOK(tif, &(tif->tif_diroff), sizeof (nextdir))) {
1145 		TIFFErrorExt(tif->tif_clientdata, module, "Error writing directory link");
1146 		return (0);
1147 	}
1148     }
1149 
1150     /*
1151     ** Now use TIFFWriteDirectory() normally.
1152     */
1153 
1154     return TIFFWriteDirectory( tif );
1155 }
1156 
1157 
1158 /*
1159  * Link the current directory into the
1160  * directory chain for the file.
1161  */
1162 static int
TIFFLinkDirectory(TIFF * tif)1163 TIFFLinkDirectory(TIFF* tif)
1164 {
1165 	static const char module[] = "TIFFLinkDirectory";
1166 	toff_t nextdir;
1167 	toff_t diroff, off;
1168 
1169 	tif->tif_diroff = (TIFFSeekFile(tif, (toff_t) 0, SEEK_END)+1) &~ 1;
1170 	diroff = tif->tif_diroff;
1171 	if (tif->tif_flags & TIFF_SWAB)
1172 		TIFFSwabLong(&diroff);
1173 
1174 	/*
1175 	 * Handle SubIFDs
1176 	 */
1177         if (tif->tif_flags & TIFF_INSUBIFD) {
1178 		(void) TIFFSeekFile(tif, tif->tif_subifdoff, SEEK_SET);
1179 		if (!WriteOK(tif, &diroff, sizeof (diroff))) {
1180 			TIFFErrorExt(tif->tif_clientdata, module,
1181 			    "%s: Error writing SubIFD directory link",
1182 			    tif->tif_name);
1183 			return (0);
1184 		}
1185 		/*
1186 		 * Advance to the next SubIFD or, if this is
1187 		 * the last one configured, revert back to the
1188 		 * normal directory linkage.
1189 		 */
1190 		if (--tif->tif_nsubifd)
1191 			tif->tif_subifdoff += sizeof (diroff);
1192 		else
1193 			tif->tif_flags &= ~TIFF_INSUBIFD;
1194 		return (1);
1195 	}
1196 
1197 	if (tif->tif_header.tiff_diroff == 0) {
1198 		/*
1199 		 * First directory, overwrite offset in header.
1200 		 */
1201 		tif->tif_header.tiff_diroff = tif->tif_diroff;
1202 		(void) TIFFSeekFile(tif,
1203 				    (toff_t)(TIFF_MAGIC_SIZE+TIFF_VERSION_SIZE),
1204                                     SEEK_SET);
1205 		if (!WriteOK(tif, &diroff, sizeof (diroff))) {
1206 			TIFFErrorExt(tif->tif_clientdata, tif->tif_name, "Error writing TIFF header");
1207 			return (0);
1208 		}
1209 		return (1);
1210 	}
1211 	/*
1212 	 * Not the first directory, search to the last and append.
1213 	 */
1214 	nextdir = tif->tif_header.tiff_diroff;
1215 	do {
1216 		uint16 dircount;
1217 
1218 		if (!SeekOK(tif, nextdir) ||
1219 		    !ReadOK(tif, &dircount, sizeof (dircount))) {
1220 			TIFFErrorExt(tif->tif_clientdata, module, "Error fetching directory count");
1221 			return (0);
1222 		}
1223 		if (tif->tif_flags & TIFF_SWAB)
1224 			TIFFSwabShort(&dircount);
1225 		(void) TIFFSeekFile(tif,
1226 		    dircount * sizeof (TIFFDirEntry), SEEK_CUR);
1227 		if (!ReadOK(tif, &nextdir, sizeof (nextdir))) {
1228 			TIFFErrorExt(tif->tif_clientdata, module, "Error fetching directory link");
1229 			return (0);
1230 		}
1231 		if (tif->tif_flags & TIFF_SWAB)
1232 			TIFFSwabLong(&nextdir);
1233 	} while (nextdir != 0);
1234         off = TIFFSeekFile(tif, 0, SEEK_CUR); /* get current offset */
1235         (void) TIFFSeekFile(tif, off - (toff_t)sizeof(nextdir), SEEK_SET);
1236 	if (!WriteOK(tif, &diroff, sizeof (diroff))) {
1237 		TIFFErrorExt(tif->tif_clientdata, module, "Error writing directory link");
1238 		return (0);
1239 	}
1240 	return (1);
1241 }
1242 
1243 /* vim: set ts=8 sts=8 sw=8 noet: */
1244