1 /* PDFlib GmbH cvsid:
2  * $Id: tif_dirwrite.c,v 1.12 2005/12/21 14:12:52 rjs Exp $ */
3 
4 /*
5  * Copyright (c) 1988-1997 Sam Leffler
6  * Copyright (c) 1991-1997 Silicon Graphics, Inc.
7  *
8  * Permission to use, copy, modify, distribute, and sell this software and
9  * its documentation for any purpose is hereby granted without fee, provided
10  * that (i) the above copyright notices and this permission notice appear in
11  * all copies of the software and related documentation, and (ii) the names of
12  * Sam Leffler and Silicon Graphics may not be used in any advertising or
13  * publicity relating to the software without the specific, prior written
14  * permission of Sam Leffler and Silicon Graphics.
15  *
16  * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND,
17  * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY
18  * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
19  *
20  * IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR
21  * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND,
22  * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
23  * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF
24  * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
25  * OF THIS SOFTWARE.
26  */
27 
28 /*
29  * TIFF Library.
30  *
31  * Directory Write Support Routines.
32  */
33 #include "tiffiop.h"
34 
35 #ifdef PDFLIB_TIFFWRITE_SUPPORT
36 
37 #ifdef HAVE_IEEEFP
38 # define	TIFFCvtNativeToIEEEFloat(tif, n, fp)
39 # define	TIFFCvtNativeToIEEEDouble(tif, n, dp)
40 #else
41 extern	void TIFFCvtNativeToIEEEFloat(TIFF*, uint32, float*);
42 extern	void TIFFCvtNativeToIEEEDouble(TIFF*, uint32, double*);
43 #endif
44 
45 static	int TIFFWriteNormalTag(TIFF*, TIFFDirEntry*, const TIFFFieldInfo*);
46 static	void TIFFSetupShortLong(TIFF*, ttag_t, TIFFDirEntry*, uint32);
47 static	void TIFFSetupShort(TIFF*, ttag_t, TIFFDirEntry*, uint16);
48 static	int TIFFSetupShortPair(TIFF*, ttag_t, TIFFDirEntry*);
49 static	int TIFFWritePerSampleShorts(TIFF*, ttag_t, TIFFDirEntry*);
50 static	int TIFFWritePerSampleAnys(TIFF*, TIFFDataType, ttag_t, TIFFDirEntry*);
51 static	int TIFFWriteShortTable(TIFF*, ttag_t, TIFFDirEntry*, uint32, uint16**);
52 static	int TIFFWriteShortArray(TIFF*, TIFFDirEntry*, uint16*);
53 static	int TIFFWriteLongArray(TIFF *, TIFFDirEntry*, uint32*);
54 static	int TIFFWriteRationalArray(TIFF *, TIFFDirEntry*, float*);
55 static	int TIFFWriteFloatArray(TIFF *, TIFFDirEntry*, float*);
56 static	int TIFFWriteDoubleArray(TIFF *, TIFFDirEntry*, double*);
57 static	int TIFFWriteByteArray(TIFF*, TIFFDirEntry*, char*);
58 static	int TIFFWriteAnyArray(TIFF*,
59 	    TIFFDataType, ttag_t, TIFFDirEntry*, uint32, double*);
60 static	int TIFFWriteTransferFunction(TIFF*, TIFFDirEntry*);
61 static	int TIFFWriteInkNames(TIFF*, TIFFDirEntry*);
62 static	int TIFFWriteData(TIFF*, TIFFDirEntry*, char*);
63 static	int TIFFLinkDirectory(TIFF*);
64 
65 #define	WriteRationalPair(type, tag1, v1, tag2, v2) {		\
66 	TIFFWriteRational((tif), (type), (tag1), (dir), (v1))	\
67 	TIFFWriteRational((tif), (type), (tag2), (dir)+1, (v2))	\
68 	(dir)++;						\
69 }
70 #define	TIFFWriteRational(tif, type, tag, dir, v)		\
71 	(dir)->tdir_tag = (tag);				\
72 	(dir)->tdir_type = (type);				\
73 	(dir)->tdir_count = 1;					\
74 	if (!TIFFWriteRationalArray((tif), (dir), &(v)))	\
75 		goto bad;
76 
77 /*
78  * Write the contents of the current directory
79  * to the specified file.  This routine doesn't
80  * handle overwriting a directory with auxiliary
81  * storage that's been changed.
82  */
83 static int
_TIFFWriteDirectory(TIFF * tif,int done)84 _TIFFWriteDirectory(TIFF* tif, int done)
85 {
86 	uint16 dircount;
87 	toff_t diroff;
88 	ttag_t tag;
89 	uint32 nfields;
90 	tsize_t dirsize;
91 	char* data;
92 	TIFFDirEntry* dir;
93 	TIFFDirectory* td;
94 	unsigned long b, fields[FIELD_SETLONGS];
95 	int fi, nfi;
96 
97 	if (tif->tif_mode == O_RDONLY)
98 		return (1);
99 	/*
100 	 * Clear write state so that subsequent images with
101 	 * different characteristics get the right buffers
102 	 * setup for them.
103 	 */
104 	if (done)
105 	{
106 	    if (tif->tif_flags & TIFF_POSTENCODE) {
107 		    tif->tif_flags &= ~TIFF_POSTENCODE;
108 		    if (!(*tif->tif_postencode)(tif)) {
109 			    _TIFFError(tif, tif->tif_name,
110 				"Error post-encoding before directory write");
111 			    return (0);
112 		    }
113 	    }
114 	    (*tif->tif_close)(tif);		/* shutdown encoder */
115 	    /*
116 	     * Flush any data that might have been written
117 	     * by the compression close+cleanup routines.
118 	     */
119 	    if (tif->tif_rawcc > 0 && !TIFFFlushData1(tif)) {
120 		    _TIFFError(tif, tif->tif_name,
121 			"Error flushing data before directory write");
122 		    return (0);
123 	    }
124 	    if ((tif->tif_flags & TIFF_MYBUFFER) && tif->tif_rawdata) {
125 		    _TIFFfree(tif->tif_rawdata);
126 		    tif->tif_rawdata = NULL;
127 		    tif->tif_rawcc = 0;
128 		    tif->tif_rawdatasize = 0;
129 	    }
130 	    tif->tif_flags &= ~(TIFF_BEENWRITING|TIFF_BUFFERSETUP);
131 	}
132 
133 	td = &tif->tif_dir;
134 	/*
135 	 * Size the directory so that we can calculate
136 	 * offsets for the data items that aren't kept
137 	 * in-place in each field.
138 	 */
139 	nfields = 0;
140 	for (b = 0; b <= FIELD_LAST; b++)
141 		if (TIFFFieldSet(tif, b) && b != FIELD_CUSTOM)
142 			nfields += (b < FIELD_SUBFILETYPE ? 2 : 1);
143         nfields += td->td_customValueCount;
144 	dirsize = nfields * sizeof (TIFFDirEntry);
145 	data = (char*) _TIFFmalloc(dirsize);
146 	if (data == NULL) {
147 		_TIFFError(tif, tif->tif_name,
148 		    "Cannot write directory, out of space");
149 		return (0);
150 	}
151 	/*
152 	 * Directory hasn't been placed yet, put
153 	 * it at the end of the file and link it
154 	 * into the existing directory structure.
155 	 */
156 	if (tif->tif_diroff == 0 && !TIFFLinkDirectory(tif))
157 		goto bad;
158 	tif->tif_dataoff = (toff_t)(
159 	    tif->tif_diroff + sizeof (uint16) + dirsize + sizeof (toff_t));
160 	if (tif->tif_dataoff & 1)
161 		tif->tif_dataoff++;
162 	(void) TIFFSeekFile(tif, tif->tif_dataoff, SEEK_SET);
163 	tif->tif_curdir++;
164 	dir = (TIFFDirEntry*) data;
165 	/*
166 	 * Setup external form of directory
167 	 * entries and write data items.
168 	 */
169 	_TIFFmemcpy(fields, td->td_fieldsset, sizeof (fields));
170 	/*
171 	 * Write out ExtraSamples tag only if
172 	 * extra samples are present in the data.
173 	 */
174 	if (FieldSet(fields, FIELD_EXTRASAMPLES) && !td->td_extrasamples) {
175 		ResetFieldBit(fields, FIELD_EXTRASAMPLES);
176 		nfields--;
177 		dirsize -= sizeof (TIFFDirEntry);
178 	}								/*XXX*/
179 	for (fi = 0, nfi = tif->tif_nfields; nfi > 0; nfi--, fi++) {
180 		const TIFFFieldInfo* fip = tif->tif_fieldinfo[fi];
181 
182                 /*
183                 ** For custom fields, we test to see if the custom field
184                 ** is set or not.  For normal fields, we just use the
185                 ** FieldSet test.
186                 */
187                 if( fip->field_bit == FIELD_CUSTOM )
188                 {
189                     int ci, is_set = FALSE;
190 
191                     for( ci = 0; ci < td->td_customValueCount; ci++ )
192                         is_set |= (td->td_customValues[ci].info == fip);
193 
194                     if( !is_set )
195                         continue;
196                 }
197 		else if (!FieldSet(fields, fip->field_bit))
198                     continue;
199 
200 
201                 /*
202                 ** Handle other fields.
203                 */
204 		switch (fip->field_bit)
205                 {
206 		case FIELD_STRIPOFFSETS:
207 			/*
208 			 * We use one field bit for both strip and tile
209 
210 			 * offsets, and so must be careful in selecting
211 			 * the appropriate field descriptor (so that tags
212 			 * are written in sorted order).
213 			 */
214 			tag = isTiled(tif) ?
215 			    TIFFTAG_TILEOFFSETS : TIFFTAG_STRIPOFFSETS;
216 			if (tag != fip->field_tag)
217 				continue;
218 
219 			dir->tdir_tag = (uint16) tag;
220 			dir->tdir_type = (uint16) TIFF_LONG;
221 			dir->tdir_count = (uint32) td->td_nstrips;
222 			if (!TIFFWriteLongArray(tif, dir, td->td_stripoffset))
223 				goto bad;
224 			break;
225 		case FIELD_STRIPBYTECOUNTS:
226 			/*
227 			 * We use one field bit for both strip and tile
228 			 * byte counts, and so must be careful in selecting
229 			 * the appropriate field descriptor (so that tags
230 			 * are written in sorted order).
231 			 */
232 			tag = isTiled(tif) ?
233 			    TIFFTAG_TILEBYTECOUNTS : TIFFTAG_STRIPBYTECOUNTS;
234 			if (tag != fip->field_tag)
235 				continue;
236 
237 			dir->tdir_tag = (uint16) tag;
238 			dir->tdir_type = (uint16) TIFF_LONG;
239 			dir->tdir_count = (uint32) td->td_nstrips;
240 			if (!TIFFWriteLongArray(tif, dir,
241 						td->td_stripbytecount))
242 				goto bad;
243 			break;
244 		case FIELD_ROWSPERSTRIP:
245 			TIFFSetupShortLong(tif, TIFFTAG_ROWSPERSTRIP,
246 			    dir, td->td_rowsperstrip);
247 			break;
248 		case FIELD_COLORMAP:
249 			if (!TIFFWriteShortTable(tif, TIFFTAG_COLORMAP, dir,
250 			    3, td->td_colormap))
251 				goto bad;
252 			break;
253 		case FIELD_IMAGEDIMENSIONS:
254 			TIFFSetupShortLong(tif, TIFFTAG_IMAGEWIDTH,
255 			    dir++, td->td_imagewidth);
256 			TIFFSetupShortLong(tif, TIFFTAG_IMAGELENGTH,
257 			    dir, td->td_imagelength);
258 			break;
259 		case FIELD_TILEDIMENSIONS:
260 			TIFFSetupShortLong(tif, TIFFTAG_TILEWIDTH,
261 			    dir++, td->td_tilewidth);
262 			TIFFSetupShortLong(tif, TIFFTAG_TILELENGTH,
263 			    dir, td->td_tilelength);
264 			break;
265 		case FIELD_COMPRESSION:
266 			TIFFSetupShort(tif, TIFFTAG_COMPRESSION,
267 			    dir, td->td_compression);
268 			break;
269 		case FIELD_PHOTOMETRIC:
270 			TIFFSetupShort(tif, TIFFTAG_PHOTOMETRIC,
271 			    dir, td->td_photometric);
272 			break;
273 		case FIELD_POSITION:
274 			WriteRationalPair(TIFF_RATIONAL,
275 			    TIFFTAG_XPOSITION, td->td_xposition,
276 			    TIFFTAG_YPOSITION, td->td_yposition);
277 			break;
278 		case FIELD_RESOLUTION:
279 			WriteRationalPair(TIFF_RATIONAL,
280 			    TIFFTAG_XRESOLUTION, td->td_xresolution,
281 			    TIFFTAG_YRESOLUTION, td->td_yresolution);
282 			break;
283 		case FIELD_BITSPERSAMPLE:
284 		case FIELD_MINSAMPLEVALUE:
285 		case FIELD_MAXSAMPLEVALUE:
286 		case FIELD_SAMPLEFORMAT:
287 			if (!TIFFWritePerSampleShorts(tif, fip->field_tag, dir))
288 				goto bad;
289 			break;
290 		case FIELD_SMINSAMPLEVALUE:
291 		case FIELD_SMAXSAMPLEVALUE:
292 			if (!TIFFWritePerSampleAnys(tif,
293 			    _TIFFSampleToTagType(tif), fip->field_tag, dir))
294 				goto bad;
295 			break;
296 		case FIELD_PAGENUMBER:
297 		case FIELD_HALFTONEHINTS:
298 		case FIELD_YCBCRSUBSAMPLING:
299 		case FIELD_DOTRANGE:
300 			if (!TIFFSetupShortPair(tif, fip->field_tag, dir))
301 				goto bad;
302 			break;
303 		case FIELD_INKNAMES:
304 			if (!TIFFWriteInkNames(tif, dir))
305 				goto bad;
306 			break;
307 		case FIELD_TRANSFERFUNCTION:
308 			if (!TIFFWriteTransferFunction(tif, dir))
309 				goto bad;
310 			break;
311 		case FIELD_SUBIFD:
312 			/*
313 			 * XXX: Always write this field using LONG type
314 			 * for backward compatibility.
315 			 */
316 			dir->tdir_tag = (uint16) fip->field_tag;
317 			dir->tdir_type = (uint16) TIFF_LONG;
318 			dir->tdir_count = (uint32) td->td_nsubifd;
319 			if (!TIFFWriteLongArray(tif, dir, td->td_subifd))
320 				goto bad;
321 			/*
322 			 * Total hack: if this directory includes a SubIFD
323 			 * tag then force the next <n> directories to be
324 			 * written as ``sub directories'' of this one.  This
325 			 * is used to write things like thumbnails and
326 			 * image masks that one wants to keep out of the
327 			 * normal directory linkage access mechanism.
328 			 */
329 			if (dir->tdir_count > 0) {
330 				tif->tif_flags |= TIFF_INSUBIFD;
331 				tif->tif_nsubifd = (uint16) dir->tdir_count;
332 				if (dir->tdir_count > 1)
333 					tif->tif_subifdoff = dir->tdir_offset;
334 				else
335 					tif->tif_subifdoff = (uint32)(
336 					      tif->tif_diroff
337 					    + sizeof (uint16)
338 					    + ((char*)&dir->tdir_offset-data));
339 			}
340 			break;
341 		default:
342 			if (!TIFFWriteNormalTag(tif, dir, fip))
343 				goto bad;
344 			break;
345 		}
346 		dir++;
347 
348                 if( fip->field_bit != FIELD_CUSTOM )
349                     ResetFieldBit(fields, fip->field_bit);
350 	}
351 
352 	/*
353 	 * Write directory.
354 	 */
355 	dircount = (uint16) nfields;
356 	diroff = (uint32) tif->tif_nextdiroff;
357 	if (tif->tif_flags & TIFF_SWAB) {
358 		/*
359 		 * The file's byte order is opposite to the
360 		 * native machine architecture.  We overwrite
361 		 * the directory information with impunity
362 		 * because it'll be released below after we
363 		 * write it to the file.  Note that all the
364 		 * other tag construction routines assume that
365 		 * we do this byte-swapping; i.e. they only
366 		 * byte-swap indirect data.
367 		 */
368 		for (dir = (TIFFDirEntry*) data; dircount; dir++, dircount--) {
369 			TIFFSwabArrayOfShort(&dir->tdir_tag, 2);
370 			TIFFSwabArrayOfLong(&dir->tdir_count, 2);
371 		}
372 		dircount = (uint16) nfields;
373 		TIFFSwabShort(&dircount);
374 		TIFFSwabLong(&diroff);
375 	}
376 	(void) TIFFSeekFile(tif, tif->tif_diroff, SEEK_SET);
377 	if (!WriteOK(tif, &dircount, sizeof (dircount))) {
378 		_TIFFError(tif, tif->tif_name, "Error writing directory count");
379 		goto bad;
380 	}
381 	if (!WriteOK(tif, data, dirsize)) {
382 		_TIFFError(tif, tif->tif_name,
383 			"Error writing directory contents");
384 		goto bad;
385 	}
386 	if (!WriteOK(tif, &diroff, sizeof (diroff))) {
387 		_TIFFError(tif, 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 	int i, status, samples = tif->tif_dir.td_samplesperpixel;
687 
688 	if (samples > NITEMS(buf)) {
689 		w = (uint16*) _TIFFmalloc(samples * sizeof (uint16));
690 		if (w == NULL) {
691 			_TIFFError(tif, tif->tif_name,
692 			    "No space to write per-sample shorts");
693 			return (0);
694 		}
695 	}
696 	TIFFGetField(tif, tag, &v);
697 	for (i = 0; i < samples; i++)
698 		w[i] = v;
699 
700 	dir->tdir_tag = (uint16) tag;
701 	dir->tdir_type = (uint16) TIFF_SHORT;
702 	dir->tdir_count = samples;
703 	status = TIFFWriteShortArray(tif, dir, w);
704 	if (w != buf)
705 		_TIFFfree((char*) w);
706 	return (status);
707 }
708 
709 /*
710  * Setup a directory entry that references a samples/pixel array of ``type''
711  * values and (potentially) write the associated indirect values.  The source
712  * data from TIFFGetField() for the specified tag must be returned as double.
713  */
714 static int
TIFFWritePerSampleAnys(TIFF * tif,TIFFDataType type,ttag_t tag,TIFFDirEntry * dir)715 TIFFWritePerSampleAnys(TIFF* tif,
716     TIFFDataType type, ttag_t tag, TIFFDirEntry* dir)
717 {
718 	double buf[10], v;
719 	double* w = buf;
720 	int i, status;
721 	int samples = (int) tif->tif_dir.td_samplesperpixel;
722 
723 	if (samples > NITEMS(buf)) {
724 		w = (double*) _TIFFmalloc(samples * sizeof (double));
725 		if (w == NULL) {
726 			_TIFFError(tif, tif->tif_name,
727 			    "No space to write per-sample values");
728 			return (0);
729 		}
730 	}
731 	TIFFGetField(tif, tag, &v);
732 	for (i = 0; i < samples; i++)
733 		w[i] = v;
734 	status = TIFFWriteAnyArray(tif, type, tag, dir, samples, w);
735 	if (w != buf)
736 		_TIFFfree(w);
737 	return (status);
738 }
739 #undef NITEMS
740 
741 /*
742  * Setup a pair of shorts that are returned by
743  * value, rather than as a reference to an array.
744  */
745 static int
TIFFSetupShortPair(TIFF * tif,ttag_t tag,TIFFDirEntry * dir)746 TIFFSetupShortPair(TIFF* tif, ttag_t tag, TIFFDirEntry* dir)
747 {
748 	uint16 v[2];
749 
750 	TIFFGetField(tif, tag, &v[0], &v[1]);
751 
752 	dir->tdir_tag = (uint16) tag;
753 	dir->tdir_type = (uint16) TIFF_SHORT;
754 	dir->tdir_count = 2;
755 	return (TIFFWriteShortArray(tif, dir, v));
756 }
757 
758 /*
759  * Setup a directory entry for an NxM table of shorts,
760  * where M is known to be 2**bitspersample, and write
761  * the associated indirect data.
762  */
763 static int
TIFFWriteShortTable(TIFF * tif,ttag_t tag,TIFFDirEntry * dir,uint32 n,uint16 ** table)764 TIFFWriteShortTable(TIFF* tif,
765     ttag_t tag, TIFFDirEntry* dir, uint32 n, uint16** table)
766 {
767 	uint32 i, off;
768 
769 	dir->tdir_tag = (uint16) tag;
770 	dir->tdir_type = (short) TIFF_SHORT;
771 	/* XXX -- yech, fool TIFFWriteData */
772 	dir->tdir_count = (uint32) (1L<<tif->tif_dir.td_bitspersample);
773 	off = tif->tif_dataoff;
774 	for (i = 0; i < n; i++)
775 		if (!TIFFWriteData(tif, dir, (char *)table[i]))
776 			return (0);
777 	dir->tdir_count *= n;
778 	dir->tdir_offset = off;
779 	return (1);
780 }
781 
782 /*
783  * Write/copy data associated with an ASCII or opaque tag value.
784  */
785 static int
TIFFWriteByteArray(TIFF * tif,TIFFDirEntry * dir,char * cp)786 TIFFWriteByteArray(TIFF* tif, TIFFDirEntry* dir, char* cp)
787 {
788 	if (dir->tdir_count > 4) {
789 		if (!TIFFWriteData(tif, dir, cp))
790 			return (0);
791 	} else
792 		_TIFFmemcpy(&dir->tdir_offset, cp, dir->tdir_count);
793 	return (1);
794 }
795 
796 /*
797  * Setup a directory entry of an array of SHORT
798  * or SSHORT and write the associated indirect values.
799  */
800 static int
TIFFWriteShortArray(TIFF * tif,TIFFDirEntry * dir,uint16 * v)801 TIFFWriteShortArray(TIFF* tif, TIFFDirEntry* dir, uint16* v)
802 {
803 	if (dir->tdir_count <= 2) {
804 		if (tif->tif_header.tiff_magic == TIFF_BIGENDIAN) {
805 			dir->tdir_offset = (uint32) ((long) v[0] << 16);
806 			if (dir->tdir_count == 2)
807 				dir->tdir_offset |= v[1] & 0xffff;
808 		} else {
809 			dir->tdir_offset = v[0] & 0xffff;
810 			if (dir->tdir_count == 2)
811 				dir->tdir_offset |= (long) v[1] << 16;
812 		}
813 		return (1);
814 	} else
815 		return (TIFFWriteData(tif, dir, (char*) v));
816 }
817 
818 /*
819  * Setup a directory entry of an array of LONG
820  * or SLONG and write the associated indirect values.
821  */
822 static int
TIFFWriteLongArray(TIFF * tif,TIFFDirEntry * dir,uint32 * v)823 TIFFWriteLongArray(TIFF* tif, TIFFDirEntry* dir, uint32* v)
824 {
825 	if (dir->tdir_count == 1) {
826 		dir->tdir_offset = v[0];
827 		return (1);
828 	} else
829 		return (TIFFWriteData(tif, dir, (char*) v));
830 }
831 
832 /*
833  * Setup a directory entry of an array of RATIONAL
834  * or SRATIONAL and write the associated indirect values.
835  */
836 static int
TIFFWriteRationalArray(TIFF * tif,TIFFDirEntry * dir,float * v)837 TIFFWriteRationalArray(TIFF* tif, TIFFDirEntry* dir, float* v)
838 {
839 	uint32 i;
840 	uint32* t;
841 	int status;
842 
843 	t = (uint32*) _TIFFmalloc(2 * dir->tdir_count * sizeof (uint32));
844 	if (t == NULL) {
845 		_TIFFError(tif, tif->tif_name,
846 		    "No space to write RATIONAL array");
847 		return (0);
848 	}
849 	for (i = 0; i < dir->tdir_count; i++) {
850 		float fv = v[i];
851 		int sign = 1;
852 		uint32 den;
853 
854 		if (fv < 0) {
855 			if (dir->tdir_type == TIFF_RATIONAL) {
856 				_TIFFWarning(tif, tif->tif_name,
857 	"\"%s\": Information lost writing value (%g) as (unsigned) RATIONAL",
858 				TIFFFieldWithTag(tif,dir->tdir_tag)->field_name,
859 				fv);
860 				fv = 0;
861 			} else
862 				fv = -fv, sign = -1;
863 		}
864 		den = 1L;
865 		if (fv > 0) {
866 			while (fv < 1L<<(31-3) && den < 1L<<(31-3))
867 				fv *= 1<<3, den *= 1L<<3;
868 		}
869 		t[2*i+0] = (uint32) (sign * (fv + 0.5));
870 		t[2*i+1] = den;
871 	}
872 	status = TIFFWriteData(tif, dir, (char *)t);
873 	_TIFFfree((char*) t);
874 	return (status);
875 }
876 
877 static int
TIFFWriteFloatArray(TIFF * tif,TIFFDirEntry * dir,float * v)878 TIFFWriteFloatArray(TIFF* tif, TIFFDirEntry* dir, float* v)
879 {
880 	TIFFCvtNativeToIEEEFloat(tif, dir->tdir_count, v);
881 	if (dir->tdir_count == 1) {
882 		dir->tdir_offset = *(uint32*) &v[0];
883 		return (1);
884 	} else
885 		return (TIFFWriteData(tif, dir, (char*) v));
886 }
887 
888 static int
TIFFWriteDoubleArray(TIFF * tif,TIFFDirEntry * dir,double * v)889 TIFFWriteDoubleArray(TIFF* tif, TIFFDirEntry* dir, double* v)
890 {
891 	TIFFCvtNativeToIEEEDouble(tif, dir->tdir_count, v);
892 	return (TIFFWriteData(tif, dir, (char*) v));
893 }
894 
895 /*
896  * Write an array of ``type'' values for a specified tag (i.e. this is a tag
897  * which is allowed to have different types, e.g. SMaxSampleType).
898  * Internally the data values are represented as double since a double can
899  * hold any of the TIFF tag types (yes, this should really be an abstract
900  * type tany_t for portability).  The data is converted into the specified
901  * type in a temporary buffer and then handed off to the appropriate array
902  * writer.
903  */
904 static int
TIFFWriteAnyArray(TIFF * tif,TIFFDataType type,ttag_t tag,TIFFDirEntry * dir,uint32 n,double * v)905 TIFFWriteAnyArray(TIFF* tif,
906     TIFFDataType type, ttag_t tag, TIFFDirEntry* dir, uint32 n, double* v)
907 {
908 	char buf[10 * sizeof(double)];
909 	char* w = buf;
910 	int i, status = 0;
911 
912 	if (n * TIFFDataWidth(type) > sizeof buf) {
913 		w = (char*) _TIFFmalloc(n * TIFFDataWidth(type));
914 		if (w == NULL) {
915 			_TIFFError(tif, tif->tif_name,
916 			    "No space to write array");
917 			return (0);
918 		}
919 	}
920 
921 	dir->tdir_tag = (uint16) tag;
922 	dir->tdir_type = (uint16) type;
923 	dir->tdir_count = n;
924 
925 	switch (type) {
926 	case TIFF_BYTE:
927 		{
928 			uint8* bp = (uint8*) w;
929 			for (i = 0; i < (int) n; i++)
930 				bp[i] = (uint8) v[i];
931 			if (!TIFFWriteByteArray(tif, dir, (char*) bp))
932 				goto out;
933 		}
934 		break;
935 	case TIFF_SBYTE:
936 		{
937 			int8* bp = (int8*) w;
938 			for (i = 0; i < (int) n; i++)
939 				bp[i] = (int8) v[i];
940 			if (!TIFFWriteByteArray(tif, dir, (char*) bp))
941 				goto out;
942 		}
943 		break;
944 	case TIFF_SHORT:
945 		{
946 			uint16* bp = (uint16*) w;
947 			for (i = 0; i < (int) n; i++)
948 				bp[i] = (uint16) v[i];
949 			if (!TIFFWriteShortArray(tif, dir, (uint16*)bp))
950 				goto out;
951 		}
952 		break;
953 	case TIFF_SSHORT:
954 		{
955 			int16* bp = (int16*) w;
956 			for (i = 0; i < (int) n; i++)
957 				bp[i] = (int16) v[i];
958 			if (!TIFFWriteShortArray(tif, dir, (uint16*)bp))
959 				goto out;
960 		}
961 		break;
962 	case TIFF_LONG:
963 		{
964 			uint32* bp = (uint32*) w;
965 			for (i = 0; i < (int) n; i++)
966 				bp[i] = (uint32) v[i];
967 			if (!TIFFWriteLongArray(tif, dir, bp))
968 				goto out;
969 		}
970 		break;
971 	case TIFF_SLONG:
972 		{
973 			int32* bp = (int32*) w;
974 			for (i = 0; i < (int) n; i++)
975 				bp[i] = (int32) v[i];
976 			if (!TIFFWriteLongArray(tif, dir, (uint32*) bp))
977 				goto out;
978 		}
979 		break;
980 	case TIFF_FLOAT:
981 		{
982 			float* bp = (float*) w;
983 			for (i = 0; i < (int) n; i++)
984 				bp[i] = (float) v[i];
985 			if (!TIFFWriteFloatArray(tif, dir, bp))
986 				goto out;
987 		}
988 		break;
989 	case TIFF_DOUBLE:
990 		return (TIFFWriteDoubleArray(tif, dir, v));
991 	default:
992 		/* TIFF_NOTYPE */
993 		/* TIFF_ASCII */
994 		/* TIFF_UNDEFINED */
995 		/* TIFF_RATIONAL */
996 		/* TIFF_SRATIONAL */
997 		goto out;
998 	}
999 	status = 1;
1000  out:
1001 	if (w != buf)
1002 		_TIFFfree(w);
1003 	return (status);
1004 }
1005 
1006 static int
TIFFWriteTransferFunction(TIFF * tif,TIFFDirEntry * dir)1007 TIFFWriteTransferFunction(TIFF* tif, TIFFDirEntry* dir)
1008 {
1009 	TIFFDirectory* td = &tif->tif_dir;
1010 	tsize_t n = (1L<<td->td_bitspersample) * sizeof (uint16);
1011 	uint16** tf = td->td_transferfunction;
1012 	int ncols;
1013 
1014 	/*
1015 	 * Check if the table can be written as a single column,
1016 	 * or if it must be written as 3 columns.  Note that we
1017 	 * write a 3-column tag if there are 2 samples/pixel and
1018 	 * a single column of data won't suffice--hmm.
1019 	 */
1020 	switch (td->td_samplesperpixel - td->td_extrasamples) {
1021 	default:	if (_TIFFmemcmp(tf[0], tf[2], n)) { ncols = 3; break; }
1022 	case 2:		if (_TIFFmemcmp(tf[0], tf[1], n)) { ncols = 3; break; }
1023 	case 1: case 0:	ncols = 1;
1024 	}
1025 	return (TIFFWriteShortTable(tif,
1026 	    TIFFTAG_TRANSFERFUNCTION, dir, ncols, tf));
1027 }
1028 
1029 static int
TIFFWriteInkNames(TIFF * tif,TIFFDirEntry * dir)1030 TIFFWriteInkNames(TIFF* tif, TIFFDirEntry* dir)
1031 {
1032 	TIFFDirectory* td = &tif->tif_dir;
1033 
1034 	dir->tdir_tag = TIFFTAG_INKNAMES;
1035 	dir->tdir_type = (short) TIFF_ASCII;
1036 	dir->tdir_count = td->td_inknameslen;
1037 	return (TIFFWriteByteArray(tif, dir, td->td_inknames));
1038 }
1039 
1040 /*
1041  * Write a contiguous directory item.
1042  */
1043 static int
TIFFWriteData(TIFF * tif,TIFFDirEntry * dir,char * cp)1044 TIFFWriteData(TIFF* tif, TIFFDirEntry* dir, char* cp)
1045 {
1046 	tsize_t cc;
1047 
1048 	if (tif->tif_flags & TIFF_SWAB) {
1049 		switch (dir->tdir_type) {
1050 		case TIFF_SHORT:
1051 		case TIFF_SSHORT:
1052 			TIFFSwabArrayOfShort((uint16*) cp, dir->tdir_count);
1053 			break;
1054 		case TIFF_LONG:
1055 		case TIFF_SLONG:
1056 		case TIFF_FLOAT:
1057 			TIFFSwabArrayOfLong((uint32*) cp, dir->tdir_count);
1058 			break;
1059 		case TIFF_RATIONAL:
1060 		case TIFF_SRATIONAL:
1061 			TIFFSwabArrayOfLong((uint32*) cp, 2*dir->tdir_count);
1062 			break;
1063 		case TIFF_DOUBLE:
1064 			TIFFSwabArrayOfDouble((double*) cp, dir->tdir_count);
1065 			break;
1066 		}
1067 	}
1068 	dir->tdir_offset = tif->tif_dataoff;
1069 	cc = dir->tdir_count * TIFFDataWidth((TIFFDataType) dir->tdir_type);
1070 	if (SeekOK(tif, dir->tdir_offset) &&
1071 	    WriteOK(tif, cp, cc)) {
1072 		tif->tif_dataoff += (cc + 1) & ~1;
1073 		return (1);
1074 	}
1075 	_TIFFError(tif, tif->tif_name, "Error writing data for field \"%s\"",
1076 	    TIFFFieldWithTag(tif, dir->tdir_tag)->field_name);
1077 	return (0);
1078 }
1079 
1080 /*
1081  * Similar to TIFFWriteDirectory(), but if the directory has already
1082  * been written once, it is relocated to the end of the file, in case it
1083  * has changed in size.  Note that this will result in the loss of the
1084  * previously used directory space.
1085  */
1086 
1087 int
TIFFRewriteDirectory(TIFF * tif)1088 TIFFRewriteDirectory( TIFF *tif )
1089 {
1090     static const char module[] = "TIFFRewriteDirectory";
1091 
1092     /* We don't need to do anything special if it hasn't been written. */
1093     if( tif->tif_diroff == 0 )
1094         return TIFFWriteDirectory( tif );
1095 
1096     /*
1097     ** Find and zero the pointer to this directory, so that TIFFLinkDirectory
1098     ** will cause it to be added after this directories current pre-link.
1099     */
1100 
1101     /* Is it the first directory in the file? */
1102     if (tif->tif_header.tiff_diroff == tif->tif_diroff)
1103     {
1104         tif->tif_header.tiff_diroff = 0;
1105         tif->tif_diroff = 0;
1106 
1107         TIFFSeekFile(tif, (toff_t)(TIFF_MAGIC_SIZE+TIFF_VERSION_SIZE),
1108 		     SEEK_SET);
1109         if (!WriteOK(tif, &(tif->tif_header.tiff_diroff),
1110                      sizeof (tif->tif_diroff)))
1111         {
1112             _TIFFError(tif, tif->tif_name, "Error updating TIFF header");
1113             return (0);
1114         }
1115     }
1116     else
1117     {
1118         toff_t  nextdir, off;
1119 
1120 	nextdir = tif->tif_header.tiff_diroff;
1121 	do {
1122 		uint16 dircount;
1123 
1124 		if (!SeekOK(tif, nextdir) ||
1125 		    !ReadOK(tif, &dircount, sizeof (dircount))) {
1126 			_TIFFError(tif,module,"Error fetching directory count");
1127 			return (0);
1128 		}
1129 		if (tif->tif_flags & TIFF_SWAB)
1130 			TIFFSwabShort(&dircount);
1131 		(void) TIFFSeekFile(tif,
1132 		    dircount * sizeof (TIFFDirEntry), SEEK_CUR);
1133 		if (!ReadOK(tif, &nextdir, sizeof (nextdir))) {
1134 			_TIFFError(tif, module,"Error fetching directory link");
1135 			return (0);
1136 		}
1137 		if (tif->tif_flags & TIFF_SWAB)
1138 			TIFFSwabLong(&nextdir);
1139 	} while (nextdir != tif->tif_diroff && nextdir != 0);
1140         off = TIFFSeekFile(tif, 0, SEEK_CUR); /* get current offset */
1141         (void) TIFFSeekFile(tif, off - (toff_t)sizeof(nextdir), SEEK_SET);
1142         tif->tif_diroff = 0;
1143 	if (!WriteOK(tif, &(tif->tif_diroff), sizeof (nextdir))) {
1144 		_TIFFError(tif, module, "Error writing directory link");
1145 		return (0);
1146 	}
1147     }
1148 
1149     /*
1150     ** Now use TIFFWriteDirectory() normally.
1151     */
1152 
1153     return TIFFWriteDirectory( tif );
1154 }
1155 
1156 
1157 /*
1158  * Link the current directory into the
1159  * directory chain for the file.
1160  */
1161 static int
TIFFLinkDirectory(TIFF * tif)1162 TIFFLinkDirectory(TIFF* tif)
1163 {
1164 	static const char module[] = "TIFFLinkDirectory";
1165 	toff_t nextdir;
1166 	toff_t diroff, off;
1167 
1168 	tif->tif_diroff = (TIFFSeekFile(tif, (toff_t) 0, SEEK_END)+1) &~ 1;
1169 	diroff = tif->tif_diroff;
1170 	if (tif->tif_flags & TIFF_SWAB)
1171 		TIFFSwabLong(&diroff);
1172 
1173 	/*
1174 	 * Handle SubIFDs
1175 	 */
1176         if (tif->tif_flags & TIFF_INSUBIFD) {
1177 		(void) TIFFSeekFile(tif, tif->tif_subifdoff, SEEK_SET);
1178 		if (!WriteOK(tif, &diroff, sizeof (diroff))) {
1179 			_TIFFError(tif, module,
1180 			    "%s: Error writing SubIFD directory link",
1181 			    tif->tif_name);
1182 			return (0);
1183 		}
1184 		/*
1185 		 * Advance to the next SubIFD or, if this is
1186 		 * the last one configured, revert back to the
1187 		 * normal directory linkage.
1188 		 */
1189 		if (--tif->tif_nsubifd)
1190 			tif->tif_subifdoff += sizeof (diroff);
1191 		else
1192 			tif->tif_flags &= ~TIFF_INSUBIFD;
1193 		return (1);
1194 	}
1195 
1196 	if (tif->tif_header.tiff_diroff == 0) {
1197 		/*
1198 		 * First directory, overwrite offset in header.
1199 		 */
1200 		tif->tif_header.tiff_diroff = tif->tif_diroff;
1201 		(void) TIFFSeekFile(tif,
1202 				    (toff_t)(TIFF_MAGIC_SIZE+TIFF_VERSION_SIZE),
1203                                     SEEK_SET);
1204 		if (!WriteOK(tif, &diroff, sizeof (diroff))) {
1205 			_TIFFError(tif, tif->tif_name,
1206 				"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 			_TIFFError(tif,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 			_TIFFError(tif, 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 		_TIFFError(tif, module, "Error writing directory link");
1238 		return (0);
1239 	}
1240 	return (1);
1241 }
1242 #endif /* PDFLIB_TIFFWRITE_SUPPORT */
1243 
1244 /* vim: set ts=8 sts=8 sw=8 noet: */
1245