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