/* $Id: tif_dirwrite.c,v 1.37.2.6 2009-10-31 21:51:08 bfriesen Exp $ */

/*
 * Copyright (c) 1988-1997 Sam Leffler
 * Copyright (c) 1991-1997 Silicon Graphics, Inc.
 *
 * Permission to use, copy, modify, distribute, and sell this software and 
 * its documentation for any purpose is hereby granted without fee, provided
 * that (i) the above copyright notices and this permission notice appear in
 * all copies of the software and related documentation, and (ii) the names of
 * Sam Leffler and Silicon Graphics may not be used in any advertising or
 * publicity relating to the software without the specific, prior written
 * permission of Sam Leffler and Silicon Graphics.
 * 
 * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, 
 * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY 
 * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.  
 * 
 * IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR
 * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND,
 * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
 * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF 
 * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE 
 * OF THIS SOFTWARE.
 */

/*
 * TIFF Library.
 *
 * Directory Write Support Routines.
 */
#include "tiffiop.h"

#ifdef HAVE_IEEEFP
# define	TIFFCvtNativeToIEEEFloat(tif, n, fp)
# define	TIFFCvtNativeToIEEEDouble(tif, n, dp)
#else
extern	void TIFFCvtNativeToIEEEFloat(TIFF*, uint32, float*);
extern	void TIFFCvtNativeToIEEEDouble(TIFF*, uint32, double*);
#endif

static	int TIFFWriteNormalTag(TIFF*, TIFFDirEntry*, const TIFFFieldInfo*);
static	void TIFFSetupShortLong(TIFF*, ttag_t, TIFFDirEntry*, uint32);
static	void TIFFSetupShort(TIFF*, ttag_t, TIFFDirEntry*, uint16);
static	int TIFFSetupShortPair(TIFF*, ttag_t, TIFFDirEntry*);
static	int TIFFWritePerSampleShorts(TIFF*, ttag_t, TIFFDirEntry*);
static	int TIFFWritePerSampleAnys(TIFF*, TIFFDataType, ttag_t, TIFFDirEntry*);
static	int TIFFWriteShortTable(TIFF*, ttag_t, TIFFDirEntry*, uint32, uint16**);
static	int TIFFWriteShortArray(TIFF*, TIFFDirEntry*, uint16*);
static	int TIFFWriteLongArray(TIFF *, TIFFDirEntry*, uint32*);
static	int TIFFWriteRationalArray(TIFF *, TIFFDirEntry*, float*);
static	int TIFFWriteFloatArray(TIFF *, TIFFDirEntry*, float*);
static	int TIFFWriteDoubleArray(TIFF *, TIFFDirEntry*, double*);
static	int TIFFWriteByteArray(TIFF*, TIFFDirEntry*, char*);
static	int TIFFWriteAnyArray(TIFF*,
	    TIFFDataType, ttag_t, TIFFDirEntry*, uint32, double*);
static	int TIFFWriteTransferFunction(TIFF*, TIFFDirEntry*);
static	int TIFFWriteInkNames(TIFF*, TIFFDirEntry*);
static	int TIFFWriteData(TIFF*, TIFFDirEntry*, char*);
static	int TIFFLinkDirectory(TIFF*);

#define	WriteRationalPair(type, tag1, v1, tag2, v2) {		\
	TIFFWriteRational((tif), (type), (tag1), (dir), (v1))	\
	TIFFWriteRational((tif), (type), (tag2), (dir)+1, (v2))	\
	(dir)++;						\
}
#define	TIFFWriteRational(tif, type, tag, dir, v)		\
	(dir)->tdir_tag = (tag);				\
	(dir)->tdir_type = (type);				\
	(dir)->tdir_count = 1;					\
	if (!TIFFWriteRationalArray((tif), (dir), &(v)))	\
		goto bad;

/*
 * Write the contents of the current directory
 * to the specified file.  This routine doesn't
 * handle overwriting a directory with auxiliary
 * storage that's been changed.
 */
static int
_TIFFWriteDirectory(TIFF* tif, int done)
{
	uint16 dircount;
	toff_t diroff;
	ttag_t tag;
	uint32 nfields;
	tsize_t dirsize;
	char* data;
	TIFFDirEntry* dir;
	TIFFDirectory* td;
	unsigned long b, fields[FIELD_SETLONGS];
	int fi, nfi;

	if (tif->tif_mode == O_RDONLY)
		return (1);
	/*
	 * Clear write state so that subsequent images with
	 * different characteristics get the right buffers
	 * setup for them.
	 */
	if (done)
	{
		if (tif->tif_flags & TIFF_POSTENCODE) {
			tif->tif_flags &= ~TIFF_POSTENCODE;
			if (!(*tif->tif_postencode)(tif)) {
				TIFFErrorExt(tif->tif_clientdata,
					     tif->tif_name,
				"Error post-encoding before directory write");
				return (0);
			}
		}
		(*tif->tif_close)(tif);		/* shutdown encoder */
		/*
		 * Flush any data that might have been written
 		 * by the compression close+cleanup routines.
		 */
		if (tif->tif_rawcc > 0
                    && (tif->tif_flags & TIFF_BEENWRITING) != 0
                    && !TIFFFlushData1(tif)) {
			TIFFErrorExt(tif->tif_clientdata, tif->tif_name,
			    "Error flushing data before directory write");
			return (0);
		}
		if ((tif->tif_flags & TIFF_MYBUFFER) && tif->tif_rawdata) {
			_TIFFfree(tif->tif_rawdata);
			tif->tif_rawdata = NULL;
			tif->tif_rawcc = 0;
			tif->tif_rawdatasize = 0;
		}
		tif->tif_flags &= ~(TIFF_BEENWRITING|TIFF_BUFFERSETUP);
	}

	td = &tif->tif_dir;
	/*
	 * Size the directory so that we can calculate
	 * offsets for the data items that aren't kept
	 * in-place in each field.
	 */
	nfields = 0;
	for (b = 0; b <= FIELD_LAST; b++)
		if (TIFFFieldSet(tif, b) && b != FIELD_CUSTOM)
			nfields += (b < FIELD_SUBFILETYPE ? 2 : 1);
	nfields += td->td_customValueCount;
	dirsize = nfields * sizeof (TIFFDirEntry);
	data = (char*) _TIFFmalloc(dirsize);
	if (data == NULL) {
		TIFFErrorExt(tif->tif_clientdata, tif->tif_name,
			     "Cannot write directory, out of space");
		return (0);
	}
	/*
	 * Directory hasn't been placed yet, put
	 * it at the end of the file and link it
	 * into the existing directory structure.
	 */
	if (tif->tif_diroff == 0 && !TIFFLinkDirectory(tif))
		goto bad;
	tif->tif_dataoff = (toff_t)(
	    tif->tif_diroff + sizeof (uint16) + dirsize + sizeof (toff_t));
	if (tif->tif_dataoff & 1)
		tif->tif_dataoff++;
	(void) TIFFSeekFile(tif, tif->tif_dataoff, SEEK_SET);
	tif->tif_curdir++;
	dir = (TIFFDirEntry*) data;
	/*
	 * Setup external form of directory
	 * entries and write data items.
	 */
	_TIFFmemcpy(fields, td->td_fieldsset, sizeof (fields));
	/*
	 * Write out ExtraSamples tag only if
	 * extra samples are present in the data.
	 */
	if (FieldSet(fields, FIELD_EXTRASAMPLES) && !td->td_extrasamples) {
		ResetFieldBit(fields, FIELD_EXTRASAMPLES);
		nfields--;
		dirsize -= sizeof (TIFFDirEntry);
	}								/*XXX*/
	for (fi = 0, nfi = tif->tif_nfields; nfi > 0; nfi--, fi++) {
		const TIFFFieldInfo* fip = tif->tif_fieldinfo[fi];

		/*
		 * For custom fields, we test to see if the custom field
		 * is set or not.  For normal fields, we just use the
		 * FieldSet test.
		*/
		if( fip->field_bit == FIELD_CUSTOM )
		{
			int ci, is_set = FALSE;

			for( ci = 0; ci < td->td_customValueCount; ci++ )
				is_set |= (td->td_customValues[ci].info == fip);

			if( !is_set )
				continue;
		}
		else if (!FieldSet(fields, fip->field_bit))
			continue;

		/*
		 * Handle other fields.
		 */
		switch (fip->field_bit)
		{
		case FIELD_STRIPOFFSETS:
			/*
			 * We use one field bit for both strip and tile

			 * offsets, and so must be careful in selecting
			 * the appropriate field descriptor (so that tags
			 * are written in sorted order).
			 */
			tag = isTiled(tif) ?
			    TIFFTAG_TILEOFFSETS : TIFFTAG_STRIPOFFSETS;
			if (tag != fip->field_tag)
				continue;
			
			dir->tdir_tag = (uint16) tag;
			dir->tdir_type = (uint16) TIFF_LONG;
			dir->tdir_count = (uint32) td->td_nstrips;
			if (!TIFFWriteLongArray(tif, dir, td->td_stripoffset))
				goto bad;
			break;
		case FIELD_STRIPBYTECOUNTS:
			/*
			 * We use one field bit for both strip and tile
			 * byte counts, and so must be careful in selecting
			 * the appropriate field descriptor (so that tags
			 * are written in sorted order).
			 */
			tag = isTiled(tif) ?
			    TIFFTAG_TILEBYTECOUNTS : TIFFTAG_STRIPBYTECOUNTS;
			if (tag != fip->field_tag)
				continue;
			
			dir->tdir_tag = (uint16) tag;
			dir->tdir_type = (uint16) TIFF_LONG;
			dir->tdir_count = (uint32) td->td_nstrips;
			if (!TIFFWriteLongArray(tif, dir, td->td_stripbytecount))
				goto bad;
			break;
		case FIELD_ROWSPERSTRIP:
			TIFFSetupShortLong(tif, TIFFTAG_ROWSPERSTRIP,
			    dir, td->td_rowsperstrip);
			break;
		case FIELD_COLORMAP:
			if (!TIFFWriteShortTable(tif, TIFFTAG_COLORMAP, dir,
			    3, td->td_colormap))
				goto bad;
			break;
		case FIELD_IMAGEDIMENSIONS:
			TIFFSetupShortLong(tif, TIFFTAG_IMAGEWIDTH,
			    dir++, td->td_imagewidth);
			TIFFSetupShortLong(tif, TIFFTAG_IMAGELENGTH,
			    dir, td->td_imagelength);
			break;
		case FIELD_TILEDIMENSIONS:
			TIFFSetupShortLong(tif, TIFFTAG_TILEWIDTH,
			    dir++, td->td_tilewidth);
			TIFFSetupShortLong(tif, TIFFTAG_TILELENGTH,
			    dir, td->td_tilelength);
			break;
		case FIELD_COMPRESSION:
			TIFFSetupShort(tif, TIFFTAG_COMPRESSION,
			    dir, td->td_compression);
			break;
		case FIELD_PHOTOMETRIC:
			TIFFSetupShort(tif, TIFFTAG_PHOTOMETRIC,
			    dir, td->td_photometric);
			break;
		case FIELD_POSITION:
			WriteRationalPair(TIFF_RATIONAL,
			    TIFFTAG_XPOSITION, td->td_xposition,
			    TIFFTAG_YPOSITION, td->td_yposition);
			break;
		case FIELD_RESOLUTION:
			WriteRationalPair(TIFF_RATIONAL,
			    TIFFTAG_XRESOLUTION, td->td_xresolution,
			    TIFFTAG_YRESOLUTION, td->td_yresolution);
			break;
		case FIELD_BITSPERSAMPLE:
		case FIELD_MINSAMPLEVALUE:
		case FIELD_MAXSAMPLEVALUE:
		case FIELD_SAMPLEFORMAT:
			if (!TIFFWritePerSampleShorts(tif, fip->field_tag, dir))
				goto bad;
			break;
		case FIELD_SMINSAMPLEVALUE:
		case FIELD_SMAXSAMPLEVALUE:
			if (!TIFFWritePerSampleAnys(tif,
			    _TIFFSampleToTagType(tif), fip->field_tag, dir))
				goto bad;
			break;
		case FIELD_PAGENUMBER:
		case FIELD_HALFTONEHINTS:
		case FIELD_YCBCRSUBSAMPLING:
			if (!TIFFSetupShortPair(tif, fip->field_tag, dir))
				goto bad;
			break;
		case FIELD_INKNAMES:
			if (!TIFFWriteInkNames(tif, dir))
				goto bad;
			break;
		case FIELD_TRANSFERFUNCTION:
			if (!TIFFWriteTransferFunction(tif, dir))
				goto bad;
			break;
		case FIELD_SUBIFD:
			/*
			 * XXX: Always write this field using LONG type
			 * for backward compatibility.
			 */
			dir->tdir_tag = (uint16) fip->field_tag;
			dir->tdir_type = (uint16) TIFF_LONG;
			dir->tdir_count = (uint32) td->td_nsubifd;
			if (!TIFFWriteLongArray(tif, dir, td->td_subifd))
				goto bad;
			/*
			 * Total hack: if this directory includes a SubIFD
			 * tag then force the next <n> directories to be
			 * written as ``sub directories'' of this one.  This
			 * is used to write things like thumbnails and
			 * image masks that one wants to keep out of the
			 * normal directory linkage access mechanism.
			 */
			if (dir->tdir_count > 0) {
				tif->tif_flags |= TIFF_INSUBIFD;
				tif->tif_nsubifd = (uint16) dir->tdir_count;
				if (dir->tdir_count > 1)
					tif->tif_subifdoff = dir->tdir_offset;
				else
					tif->tif_subifdoff = (uint32)(
					      tif->tif_diroff
					    + sizeof (uint16)
					    + ((char*)&dir->tdir_offset-data));
			}
			break;
		default:
			/* XXX: Should be fixed and removed. */
			if (fip->field_tag == TIFFTAG_DOTRANGE) {
				if (!TIFFSetupShortPair(tif, fip->field_tag, dir))
					goto bad;
			}
			else if (!TIFFWriteNormalTag(tif, dir, fip))
				goto bad;
			break;
		}
		dir++;
                
		if( fip->field_bit != FIELD_CUSTOM )
			ResetFieldBit(fields, fip->field_bit);
	}

	/*
	 * Write directory.
	 */
	dircount = (uint16) nfields;
	diroff = (uint32) tif->tif_nextdiroff;
	if (tif->tif_flags & TIFF_SWAB) {
		/*
		 * The file's byte order is opposite to the
		 * native machine architecture.  We overwrite
		 * the directory information with impunity
		 * because it'll be released below after we
		 * write it to the file.  Note that all the
		 * other tag construction routines assume that
		 * we do this byte-swapping; i.e. they only
		 * byte-swap indirect data.
		 */
		for (dir = (TIFFDirEntry*) data; dircount; dir++, dircount--) {
			TIFFSwabArrayOfShort(&dir->tdir_tag, 2);
			TIFFSwabArrayOfLong(&dir->tdir_count, 2);
		}
		dircount = (uint16) nfields;
		TIFFSwabShort(&dircount);
		TIFFSwabLong(&diroff);
	}
	(void) TIFFSeekFile(tif, tif->tif_diroff, SEEK_SET);
	if (!WriteOK(tif, &dircount, sizeof (dircount))) {
		TIFFErrorExt(tif->tif_clientdata, tif->tif_name,
			     "Error writing directory count");
		goto bad;
	}
	if (!WriteOK(tif, data, dirsize)) {
		TIFFErrorExt(tif->tif_clientdata, tif->tif_name,
			     "Error writing directory contents");
		goto bad;
	}
	if (!WriteOK(tif, &diroff, sizeof (uint32))) {
		TIFFErrorExt(tif->tif_clientdata, tif->tif_name,
			     "Error writing directory link");
		goto bad;
	}
	if (done) {
		TIFFFreeDirectory(tif);
		tif->tif_flags &= ~TIFF_DIRTYDIRECT;
		(*tif->tif_cleanup)(tif);

		/*
		* Reset directory-related state for subsequent
		* directories.
		*/
		TIFFCreateDirectory(tif);
	}
	_TIFFfree(data);
	return (1);
bad:
	_TIFFfree(data);
	return (0);
}
#undef WriteRationalPair

int
TIFFWriteDirectory(TIFF* tif)
{
	return _TIFFWriteDirectory(tif, TRUE);
}

/*
 * Similar to TIFFWriteDirectory(), writes the directory out
 * but leaves all data structures in memory so that it can be
 * written again.  This will make a partially written TIFF file
 * readable before it is successfully completed/closed.
 */ 
int
TIFFCheckpointDirectory(TIFF* tif)
{
	int rc;
	/* Setup the strips arrays, if they haven't already been. */
	if (tif->tif_dir.td_stripoffset == NULL)
	    (void) TIFFSetupStrips(tif);
	rc = _TIFFWriteDirectory(tif, FALSE);
	(void) TIFFSetWriteOffset(tif, TIFFSeekFile(tif, 0, SEEK_END));
	return rc;
}

static int
_TIFFWriteCustomDirectory(TIFF* tif, toff_t *pdiroff)
{
	uint16 dircount;
	uint32 nfields;
	tsize_t dirsize;
	char* data;
	TIFFDirEntry* dir;
	TIFFDirectory* td;
	unsigned long b, fields[FIELD_SETLONGS];
	int fi, nfi;

	if (tif->tif_mode == O_RDONLY)
		return (1);

	td = &tif->tif_dir;
	/*
	 * Size the directory so that we can calculate
	 * offsets for the data items that aren't kept
	 * in-place in each field.
	 */
	nfields = 0;
	for (b = 0; b <= FIELD_LAST; b++)
		if (TIFFFieldSet(tif, b) && b != FIELD_CUSTOM)
			nfields += (b < FIELD_SUBFILETYPE ? 2 : 1);
	nfields += td->td_customValueCount;
	dirsize = nfields * sizeof (TIFFDirEntry);
	data = (char*) _TIFFmalloc(dirsize);
	if (data == NULL) {
		TIFFErrorExt(tif->tif_clientdata, tif->tif_name,
			     "Cannot write directory, out of space");
		return (0);
	}
	/*
	 * Put the directory  at the end of the file.
	 */
	tif->tif_diroff = (TIFFSeekFile(tif, (toff_t) 0, SEEK_END)+1) &~ 1;
	tif->tif_dataoff = (toff_t)(
	    tif->tif_diroff + sizeof (uint16) + dirsize + sizeof (toff_t));
	if (tif->tif_dataoff & 1)
		tif->tif_dataoff++;
	(void) TIFFSeekFile(tif, tif->tif_dataoff, SEEK_SET);
	dir = (TIFFDirEntry*) data;
	/*
	 * Setup external form of directory
	 * entries and write data items.
	 */
	_TIFFmemcpy(fields, td->td_fieldsset, sizeof (fields));

	for (fi = 0, nfi = tif->tif_nfields; nfi > 0; nfi--, fi++) {
		const TIFFFieldInfo* fip = tif->tif_fieldinfo[fi];

		/*
		 * For custom fields, we test to see if the custom field
		 * is set or not.  For normal fields, we just use the
		 * FieldSet test.
		*/
		if( fip->field_bit == FIELD_CUSTOM )
		{
			int ci, is_set = FALSE;

			for( ci = 0; ci < td->td_customValueCount; ci++ )
				is_set |= (td->td_customValues[ci].info == fip);

			if( !is_set )
				continue;
		}
		else if (!FieldSet(fields, fip->field_bit))
			continue;
                
		if( fip->field_bit != FIELD_CUSTOM )
			ResetFieldBit(fields, fip->field_bit);
	}

	/*
	 * Write directory.
	 */
	dircount = (uint16) nfields;
	*pdiroff = (uint32) tif->tif_nextdiroff;
	if (tif->tif_flags & TIFF_SWAB) {
		/*
		 * The file's byte order is opposite to the
		 * native machine architecture.  We overwrite
		 * the directory information with impunity
		 * because it'll be released below after we
		 * write it to the file.  Note that all the
		 * other tag construction routines assume that
		 * we do this byte-swapping; i.e. they only
		 * byte-swap indirect data.
		 */
		for (dir = (TIFFDirEntry*) data; dircount; dir++, dircount--) {
			TIFFSwabArrayOfShort(&dir->tdir_tag, 2);
			TIFFSwabArrayOfLong(&dir->tdir_count, 2);
		}
		dircount = (uint16) nfields;
		TIFFSwabShort(&dircount);
		TIFFSwabLong(pdiroff);
	}
	(void) TIFFSeekFile(tif, tif->tif_diroff, SEEK_SET);
	if (!WriteOK(tif, &dircount, sizeof (dircount))) {
		TIFFErrorExt(tif->tif_clientdata, tif->tif_name,
			     "Error writing directory count");
		goto bad;
	}
	if (!WriteOK(tif, data, dirsize)) {
		TIFFErrorExt(tif->tif_clientdata, tif->tif_name,
			     "Error writing directory contents");
		goto bad;
	}
	if (!WriteOK(tif, pdiroff, sizeof (uint32))) {
		TIFFErrorExt(tif->tif_clientdata, tif->tif_name,
			     "Error writing directory link");
		goto bad;
	}
	_TIFFfree(data);
	return (1);
bad:
	_TIFFfree(data);
	return (0);
}

int
TIFFWriteCustomDirectory(TIFF* tif, toff_t *pdiroff)
{
	return _TIFFWriteCustomDirectory(tif, pdiroff);
}

/*
 * Process tags that are not special cased.
 */
static int
TIFFWriteNormalTag(TIFF* tif, TIFFDirEntry* dir, const TIFFFieldInfo* fip)
{
	uint16 wc = (uint16) fip->field_writecount;
	uint32 wc2;

	dir->tdir_tag = (uint16) fip->field_tag;
	dir->tdir_type = (uint16) fip->field_type;
	dir->tdir_count = wc;
	
	switch (fip->field_type) {
	case TIFF_SHORT:
	case TIFF_SSHORT:
		if (fip->field_passcount) {
			uint16* wp;
			if (wc == (uint16) TIFF_VARIABLE2) {
				TIFFGetField(tif, fip->field_tag, &wc2, &wp);
				dir->tdir_count = wc2;
			} else {	/* Assume TIFF_VARIABLE */
				TIFFGetField(tif, fip->field_tag, &wc, &wp);
				dir->tdir_count = wc;
			}
			if (!TIFFWriteShortArray(tif, dir, wp))
				return 0;
		} else {
			if (wc == 1) {
				uint16 sv;
				TIFFGetField(tif, fip->field_tag, &sv);
				dir->tdir_offset =
					TIFFInsertData(tif, dir->tdir_type, sv);
			} else {
				uint16* wp;
				TIFFGetField(tif, fip->field_tag, &wp);
				if (!TIFFWriteShortArray(tif, dir, wp))
					return 0;
			}
		}
		break;
	case TIFF_LONG:
	case TIFF_SLONG:
	case TIFF_IFD:
		if (fip->field_passcount) {
			uint32* lp;
			if (wc == (uint16) TIFF_VARIABLE2) {
				TIFFGetField(tif, fip->field_tag, &wc2, &lp);
				dir->tdir_count = wc2;
			} else {	/* Assume TIFF_VARIABLE */
				TIFFGetField(tif, fip->field_tag, &wc, &lp);
				dir->tdir_count = wc;
			}
			if (!TIFFWriteLongArray(tif, dir, lp))
				return 0;
		} else {
			if (wc == 1) {
				/* XXX handle LONG->SHORT conversion */
				TIFFGetField(tif, fip->field_tag,
					     &dir->tdir_offset);
			} else {
				uint32* lp;
				TIFFGetField(tif, fip->field_tag, &lp);
				if (!TIFFWriteLongArray(tif, dir, lp))
					return 0;
			}
		}
		break;
	case TIFF_RATIONAL:
	case TIFF_SRATIONAL:
		if (fip->field_passcount) {
			float* fp;
			if (wc == (uint16) TIFF_VARIABLE2) {
				TIFFGetField(tif, fip->field_tag, &wc2, &fp);
				dir->tdir_count = wc2;
			} else {	/* Assume TIFF_VARIABLE */
				TIFFGetField(tif, fip->field_tag, &wc, &fp);
				dir->tdir_count = wc;
			}
			if (!TIFFWriteRationalArray(tif, dir, fp))
				return 0;
		} else {
			if (wc == 1) {
				float fv;
				TIFFGetField(tif, fip->field_tag, &fv);
				if (!TIFFWriteRationalArray(tif, dir, &fv))
					return 0;
			} else {
				float* fp;
				TIFFGetField(tif, fip->field_tag, &fp);
				if (!TIFFWriteRationalArray(tif, dir, fp))
					return 0;
			}
		}
		break;
	case TIFF_FLOAT:
		if (fip->field_passcount) {
			float* fp;
			if (wc == (uint16) TIFF_VARIABLE2) {
				TIFFGetField(tif, fip->field_tag, &wc2, &fp);
				dir->tdir_count = wc2;
			} else {	/* Assume TIFF_VARIABLE */
				TIFFGetField(tif, fip->field_tag, &wc, &fp);
				dir->tdir_count = wc;
			}
			if (!TIFFWriteFloatArray(tif, dir, fp))
				return 0;
		} else {
			if (wc == 1) {
				float fv;
				TIFFGetField(tif, fip->field_tag, &fv);
				if (!TIFFWriteFloatArray(tif, dir, &fv))
					return 0;
			} else {
				float* fp;
				TIFFGetField(tif, fip->field_tag, &fp);
				if (!TIFFWriteFloatArray(tif, dir, fp))
					return 0;
			}
		}
		break;
	case TIFF_DOUBLE:
		if (fip->field_passcount) {
			double* dp;
			if (wc == (uint16) TIFF_VARIABLE2) {
				TIFFGetField(tif, fip->field_tag, &wc2, &dp);
				dir->tdir_count = wc2;
			} else {	/* Assume TIFF_VARIABLE */
				TIFFGetField(tif, fip->field_tag, &wc, &dp);
				dir->tdir_count = wc;
			}
			if (!TIFFWriteDoubleArray(tif, dir, dp))
				return 0;
		} else {
			if (wc == 1) {
				double dv;
				TIFFGetField(tif, fip->field_tag, &dv);
				if (!TIFFWriteDoubleArray(tif, dir, &dv))
					return 0;
			} else {
				double* dp;
				TIFFGetField(tif, fip->field_tag, &dp);
				if (!TIFFWriteDoubleArray(tif, dir, dp))
					return 0;
			}
		}
		break;
	case TIFF_ASCII:
		{ 
                    char* cp;
                    if (fip->field_passcount)
                    {
                        if( wc == (uint16) TIFF_VARIABLE2 )
                            TIFFGetField(tif, fip->field_tag, &wc2, &cp);
                        else
                            TIFFGetField(tif, fip->field_tag, &wc, &cp);
                    }
                    else
                        TIFFGetField(tif, fip->field_tag, &cp);

                    dir->tdir_count = (uint32) (strlen(cp) + 1);
                    if (!TIFFWriteByteArray(tif, dir, cp))
                        return (0);
		}
		break;

        case TIFF_BYTE:
        case TIFF_SBYTE:          
		if (fip->field_passcount) {
			char* cp;
			if (wc == (uint16) TIFF_VARIABLE2) {
				TIFFGetField(tif, fip->field_tag, &wc2, &cp);
				dir->tdir_count = wc2;
			} else {	/* Assume TIFF_VARIABLE */
				TIFFGetField(tif, fip->field_tag, &wc, &cp);
				dir->tdir_count = wc;
			}
			if (!TIFFWriteByteArray(tif, dir, cp))
				return 0;
		} else {
			if (wc == 1) {
				char cv;
				TIFFGetField(tif, fip->field_tag, &cv);
				if (!TIFFWriteByteArray(tif, dir, &cv))
					return 0;
			} else {
				char* cp;
				TIFFGetField(tif, fip->field_tag, &cp);
				if (!TIFFWriteByteArray(tif, dir, cp))
					return 0;
			}
		}
                break;

	case TIFF_UNDEFINED:
		{ char* cp;
		  if (wc == (unsigned short) TIFF_VARIABLE) {
			TIFFGetField(tif, fip->field_tag, &wc, &cp);
			dir->tdir_count = wc;
		  } else if (wc == (unsigned short) TIFF_VARIABLE2) {
			TIFFGetField(tif, fip->field_tag, &wc2, &cp);
			dir->tdir_count = wc2;
		  } else 
			TIFFGetField(tif, fip->field_tag, &cp);
		  if (!TIFFWriteByteArray(tif, dir, cp))
			return (0);
		}
		break;

        case TIFF_NOTYPE:
                break;
	}
	return (1);
}

/*
 * Setup a directory entry with either a SHORT
 * or LONG type according to the value.
 */
static void
TIFFSetupShortLong(TIFF* tif, ttag_t tag, TIFFDirEntry* dir, uint32 v)
{
	dir->tdir_tag = (uint16) tag;
	dir->tdir_count = 1;
	if (v > 0xffffL) {
		dir->tdir_type = (short) TIFF_LONG;
		dir->tdir_offset = v;
	} else {
		dir->tdir_type = (short) TIFF_SHORT;
		dir->tdir_offset = TIFFInsertData(tif, (int) TIFF_SHORT, v);
	}
}

/*
 * Setup a SHORT directory entry
 */
static void
TIFFSetupShort(TIFF* tif, ttag_t tag, TIFFDirEntry* dir, uint16 v)
{
	dir->tdir_tag = (uint16) tag;
	dir->tdir_count = 1;
	dir->tdir_type = (short) TIFF_SHORT;
	dir->tdir_offset = TIFFInsertData(tif, (int) TIFF_SHORT, v);
}
#undef MakeShortDirent

#define	NITEMS(x)	(sizeof (x) / sizeof (x[0]))
/*
 * Setup a directory entry that references a
 * samples/pixel array of SHORT values and
 * (potentially) write the associated indirect
 * values.
 */
static int
TIFFWritePerSampleShorts(TIFF* tif, ttag_t tag, TIFFDirEntry* dir)
{
	uint16 buf[10], v;
	uint16* w = buf;
	uint16 i, samples = tif->tif_dir.td_samplesperpixel;
	int status;

	if (samples > NITEMS(buf)) {
		w = (uint16*) _TIFFmalloc(samples * sizeof (uint16));
		if (w == NULL) {
			TIFFErrorExt(tif->tif_clientdata, tif->tif_name,
			    "No space to write per-sample shorts");
			return (0);
		}
	}
	TIFFGetField(tif, tag, &v);
	for (i = 0; i < samples; i++)
		w[i] = v;
	
	dir->tdir_tag = (uint16) tag;
	dir->tdir_type = (uint16) TIFF_SHORT;
	dir->tdir_count = samples;
	status = TIFFWriteShortArray(tif, dir, w);
	if (w != buf)
		_TIFFfree((char*) w);
	return (status);
}

/*
 * Setup a directory entry that references a samples/pixel array of ``type''
 * values and (potentially) write the associated indirect values.  The source
 * data from TIFFGetField() for the specified tag must be returned as double.
 */
static int
TIFFWritePerSampleAnys(TIFF* tif,
    TIFFDataType type, ttag_t tag, TIFFDirEntry* dir)
{
	double buf[10], v;
	double* w = buf;
	uint16 i, samples = tif->tif_dir.td_samplesperpixel;
	int status;

	if (samples > NITEMS(buf)) {
		w = (double*) _TIFFmalloc(samples * sizeof (double));
		if (w == NULL) {
			TIFFErrorExt(tif->tif_clientdata, tif->tif_name,
			    "No space to write per-sample values");
			return (0);
		}
	}
	TIFFGetField(tif, tag, &v);
	for (i = 0; i < samples; i++)
		w[i] = v;
	status = TIFFWriteAnyArray(tif, type, tag, dir, samples, w);
	if (w != buf)
		_TIFFfree(w);
	return (status);
}
#undef NITEMS

/*
 * Setup a pair of shorts that are returned by
 * value, rather than as a reference to an array.
 */
static int
TIFFSetupShortPair(TIFF* tif, ttag_t tag, TIFFDirEntry* dir)
{
	uint16 v[2];

	TIFFGetField(tif, tag, &v[0], &v[1]);

	dir->tdir_tag = (uint16) tag;
	dir->tdir_type = (uint16) TIFF_SHORT;
	dir->tdir_count = 2;
	return (TIFFWriteShortArray(tif, dir, v));
}

/*
 * Setup a directory entry for an NxM table of shorts,
 * where M is known to be 2**bitspersample, and write
 * the associated indirect data.
 */
static int
TIFFWriteShortTable(TIFF* tif,
    ttag_t tag, TIFFDirEntry* dir, uint32 n, uint16** table)
{
	uint32 i, off;

	dir->tdir_tag = (uint16) tag;
	dir->tdir_type = (short) TIFF_SHORT;
	/* XXX -- yech, fool TIFFWriteData */
	dir->tdir_count = (uint32) (1L<<tif->tif_dir.td_bitspersample);
	off = tif->tif_dataoff;
	for (i = 0; i < n; i++)
		if (!TIFFWriteData(tif, dir, (char *)table[i]))
			return (0);
	dir->tdir_count *= n;
	dir->tdir_offset = off;
	return (1);
}

/*
 * Write/copy data associated with an ASCII or opaque tag value.
 */
static int
TIFFWriteByteArray(TIFF* tif, TIFFDirEntry* dir, char* cp)
{
	if (dir->tdir_count <= 4) {
		if (tif->tif_header.tiff_magic == TIFF_BIGENDIAN) {
			dir->tdir_offset = (uint32)cp[0] << 24;
			if (dir->tdir_count >= 2)
				dir->tdir_offset |= (uint32)cp[1] << 16;
			if (dir->tdir_count >= 3)
				dir->tdir_offset |= (uint32)cp[2] << 8;
			if (dir->tdir_count == 4)
				dir->tdir_offset |= cp[3];
		} else {
			dir->tdir_offset = cp[0];
			if (dir->tdir_count >= 2)
				dir->tdir_offset |= (uint32) cp[1] << 8;
			if (dir->tdir_count >= 3)
				dir->tdir_offset |= (uint32) cp[2] << 16;
			if (dir->tdir_count == 4)
				dir->tdir_offset |= (uint32) cp[3] << 24;
		}
		return 1;
	} else
		return TIFFWriteData(tif, dir, cp);
}

/*
 * Setup a directory entry of an array of SHORT
 * or SSHORT and write the associated indirect values.
 */
static int
TIFFWriteShortArray(TIFF* tif, TIFFDirEntry* dir, uint16* v)
{
	if (dir->tdir_count <= 2) {
		if (tif->tif_header.tiff_magic == TIFF_BIGENDIAN) {
			dir->tdir_offset = (uint32) v[0] << 16;
			if (dir->tdir_count == 2)
				dir->tdir_offset |= v[1] & 0xffff;
		} else {
			dir->tdir_offset = v[0] & 0xffff;
			if (dir->tdir_count == 2)
				dir->tdir_offset |= (uint32) v[1] << 16;
		}
		return (1);
	} else
		return (TIFFWriteData(tif, dir, (char*) v));
}

/*
 * Setup a directory entry of an array of LONG
 * or SLONG and write the associated indirect values.
 */
static int
TIFFWriteLongArray(TIFF* tif, TIFFDirEntry* dir, uint32* v)
{
	if (dir->tdir_count == 1) {
		dir->tdir_offset = v[0];
		return (1);
	} else
		return (TIFFWriteData(tif, dir, (char*) v));
}

/*
 * Setup a directory entry of an array of RATIONAL
 * or SRATIONAL and write the associated indirect values.
 */
static int
TIFFWriteRationalArray(TIFF* tif, TIFFDirEntry* dir, float* v)
{
	uint32 i;
	uint32* t;
	int status;

	t = (uint32*) _TIFFmalloc(2 * dir->tdir_count * sizeof (uint32));
	if (t == NULL) {
		TIFFErrorExt(tif->tif_clientdata, tif->tif_name,
		    "No space to write RATIONAL array");
		return (0);
	}
	for (i = 0; i < dir->tdir_count; i++) {
		float fv = v[i];
		int sign = 1;
		uint32 den;

		if (fv < 0) {
			if (dir->tdir_type == TIFF_RATIONAL) {
				TIFFWarningExt(tif->tif_clientdata,
					       tif->tif_name,
	"\"%s\": Information lost writing value (%g) as (unsigned) RATIONAL",
				_TIFFFieldWithTag(tif,dir->tdir_tag)->field_name,
						fv);
				fv = 0;
			} else
				fv = -fv, sign = -1;
		}
		den = 1L;
		if (fv > 0) {
			while (fv < 1L<<(31-3) && den < 1L<<(31-3))
				fv *= 1<<3, den *= 1L<<3;
		}
		t[2*i+0] = (uint32) (sign * (fv + 0.5));
		t[2*i+1] = den;
	}
	status = TIFFWriteData(tif, dir, (char *)t);
	_TIFFfree((char*) t);
	return (status);
}

static int
TIFFWriteFloatArray(TIFF* tif, TIFFDirEntry* dir, float* v)
{
	TIFFCvtNativeToIEEEFloat(tif, dir->tdir_count, v);
	if (dir->tdir_count == 1) {
		dir->tdir_offset = *(uint32*) &v[0];
		return (1);
	} else
		return (TIFFWriteData(tif, dir, (char*) v));
}

static int
TIFFWriteDoubleArray(TIFF* tif, TIFFDirEntry* dir, double* v)
{
	TIFFCvtNativeToIEEEDouble(tif, dir->tdir_count, v);
	return (TIFFWriteData(tif, dir, (char*) v));
}

/*
 * Write an array of ``type'' values for a specified tag (i.e. this is a tag
 * which is allowed to have different types, e.g. SMaxSampleType).
 * Internally the data values are represented as double since a double can
 * hold any of the TIFF tag types (yes, this should really be an abstract
 * type tany_t for portability).  The data is converted into the specified
 * type in a temporary buffer and then handed off to the appropriate array
 * writer.
 */
static int
TIFFWriteAnyArray(TIFF* tif,
    TIFFDataType type, ttag_t tag, TIFFDirEntry* dir, uint32 n, double* v)
{
	char buf[10 * sizeof(double)];
	char* w = buf;
	int i, status = 0;

	if (n * TIFFDataWidth(type) > sizeof buf) {
		w = (char*) _TIFFmalloc(n * TIFFDataWidth(type));
		if (w == NULL) {
			TIFFErrorExt(tif->tif_clientdata, tif->tif_name,
				     "No space to write array");
			return (0);
		}
	}

	dir->tdir_tag = (uint16) tag;
	dir->tdir_type = (uint16) type;
	dir->tdir_count = n;

	switch (type) {
	case TIFF_BYTE:
		{ 
			uint8* bp = (uint8*) w;
			for (i = 0; i < (int) n; i++)
				bp[i] = (uint8) v[i];
			if (!TIFFWriteByteArray(tif, dir, (char*) bp))
				goto out;
		}
		break;
	case TIFF_SBYTE:
		{ 
			int8* bp = (int8*) w;
			for (i = 0; i < (int) n; i++)
				bp[i] = (int8) v[i];
			if (!TIFFWriteByteArray(tif, dir, (char*) bp))
				goto out;
		}
		break;
	case TIFF_SHORT:
		{
			uint16* bp = (uint16*) w;
			for (i = 0; i < (int) n; i++)
				bp[i] = (uint16) v[i];
			if (!TIFFWriteShortArray(tif, dir, (uint16*)bp))
				goto out;
		}
		break;
	case TIFF_SSHORT:
		{ 
			int16* bp = (int16*) w;
			for (i = 0; i < (int) n; i++)
				bp[i] = (int16) v[i];
			if (!TIFFWriteShortArray(tif, dir, (uint16*)bp))
				goto out;
		}
		break;
	case TIFF_LONG:
		{
			uint32* bp = (uint32*) w;
			for (i = 0; i < (int) n; i++)
				bp[i] = (uint32) v[i];
			if (!TIFFWriteLongArray(tif, dir, bp))
				goto out;
		}
		break;
	case TIFF_SLONG:
		{
			int32* bp = (int32*) w;
			for (i = 0; i < (int) n; i++)
				bp[i] = (int32) v[i];
			if (!TIFFWriteLongArray(tif, dir, (uint32*) bp))
				goto out;
		}
		break;
	case TIFF_FLOAT:
		{ 
			float* bp = (float*) w;
			for (i = 0; i < (int) n; i++)
				bp[i] = (float) v[i];
			if (!TIFFWriteFloatArray(tif, dir, bp))
				goto out;
		}
		break;
	case TIFF_DOUBLE:
                {
                    if( !TIFFWriteDoubleArray(tif, dir, v))
                        goto out;
                }
		break;
	default:
		/* TIFF_NOTYPE */
		/* TIFF_ASCII */
		/* TIFF_UNDEFINED */
		/* TIFF_RATIONAL */
		/* TIFF_SRATIONAL */
		goto out;
	}
	status = 1;
 out:
	if (w != buf)
		_TIFFfree(w);
	return (status);
}

static int
TIFFWriteTransferFunction(TIFF* tif, TIFFDirEntry* dir)
{
	TIFFDirectory* td = &tif->tif_dir;
	tsize_t n = (1L<<td->td_bitspersample) * sizeof (uint16);
	uint16** tf = td->td_transferfunction;
	int ncols;

	/*
	 * Check if the table can be written as a single column,
	 * or if it must be written as 3 columns.  Note that we
	 * write a 3-column tag if there are 2 samples/pixel and
	 * a single column of data won't suffice--hmm.
	 */
	switch (td->td_samplesperpixel - td->td_extrasamples) {
	default:	if (_TIFFmemcmp(tf[0], tf[2], n)) { ncols = 3; break; }
	case 2:		if (_TIFFmemcmp(tf[0], tf[1], n)) { ncols = 3; break; }
	case 1: case 0:	ncols = 1;
	}
	return (TIFFWriteShortTable(tif,
	    TIFFTAG_TRANSFERFUNCTION, dir, ncols, tf));
}

static int
TIFFWriteInkNames(TIFF* tif, TIFFDirEntry* dir)
{
	TIFFDirectory* td = &tif->tif_dir;

	dir->tdir_tag = TIFFTAG_INKNAMES;
	dir->tdir_type = (short) TIFF_ASCII;
	dir->tdir_count = td->td_inknameslen;
	return (TIFFWriteByteArray(tif, dir, td->td_inknames));
}

/*
 * Write a contiguous directory item.
 */
static int
TIFFWriteData(TIFF* tif, TIFFDirEntry* dir, char* cp)
{
	tsize_t cc;

	if (tif->tif_flags & TIFF_SWAB) {
		switch (dir->tdir_type) {
		case TIFF_SHORT:
		case TIFF_SSHORT:
			TIFFSwabArrayOfShort((uint16*) cp, dir->tdir_count);
			break;
		case TIFF_LONG:
		case TIFF_SLONG:
		case TIFF_FLOAT:
			TIFFSwabArrayOfLong((uint32*) cp, dir->tdir_count);
			break;
		case TIFF_RATIONAL:
		case TIFF_SRATIONAL:
			TIFFSwabArrayOfLong((uint32*) cp, 2*dir->tdir_count);
			break;
		case TIFF_DOUBLE:
			TIFFSwabArrayOfDouble((double*) cp, dir->tdir_count);
			break;
		}
	}
	dir->tdir_offset = tif->tif_dataoff;
	cc = dir->tdir_count * TIFFDataWidth((TIFFDataType) dir->tdir_type);
	if (SeekOK(tif, dir->tdir_offset) &&
	    WriteOK(tif, cp, cc)) {
		tif->tif_dataoff += (cc + 1) & ~1;
		return (1);
	}
	TIFFErrorExt(tif->tif_clientdata, tif->tif_name,
		     "Error writing data for field \"%s\"",
	_TIFFFieldWithTag(tif, dir->tdir_tag)->field_name);
	return (0);
}

/*
 * Similar to TIFFWriteDirectory(), but if the directory has already
 * been written once, it is relocated to the end of the file, in case it
 * has changed in size.  Note that this will result in the loss of the 
 * previously used directory space. 
 */ 

int 
TIFFRewriteDirectory( TIFF *tif )
{
    static const char module[] = "TIFFRewriteDirectory";

    /* We don't need to do anything special if it hasn't been written. */
    if( tif->tif_diroff == 0 )
        return TIFFWriteDirectory( tif );

    /*
    ** Find and zero the pointer to this directory, so that TIFFLinkDirectory
    ** will cause it to be added after this directories current pre-link.
    */
    
    /* Is it the first directory in the file? */
    if (tif->tif_header.tiff_diroff == tif->tif_diroff) 
    {
        tif->tif_header.tiff_diroff = 0;
        tif->tif_diroff = 0;

        TIFFSeekFile(tif, (toff_t)(TIFF_MAGIC_SIZE+TIFF_VERSION_SIZE),
		     SEEK_SET);
        if (!WriteOK(tif, &(tif->tif_header.tiff_diroff), 
                     sizeof (tif->tif_diroff))) 
        {
			TIFFErrorExt(tif->tif_clientdata, tif->tif_name,
				     "Error updating TIFF header");
            return (0);
        }
    }
    else
    {
        toff_t  nextdir, off;

	nextdir = tif->tif_header.tiff_diroff;
	do {
		uint16 dircount;

		if (!SeekOK(tif, nextdir) ||
		    !ReadOK(tif, &dircount, sizeof (dircount))) {
			TIFFErrorExt(tif->tif_clientdata, module,
				     "Error fetching directory count");
			return (0);
		}
		if (tif->tif_flags & TIFF_SWAB)
			TIFFSwabShort(&dircount);
		(void) TIFFSeekFile(tif,
		    dircount * sizeof (TIFFDirEntry), SEEK_CUR);
		if (!ReadOK(tif, &nextdir, sizeof (nextdir))) {
			TIFFErrorExt(tif->tif_clientdata, module,
				     "Error fetching directory link");
			return (0);
		}
		if (tif->tif_flags & TIFF_SWAB)
			TIFFSwabLong(&nextdir);
	} while (nextdir != tif->tif_diroff && nextdir != 0);
        off = TIFFSeekFile(tif, 0, SEEK_CUR); /* get current offset */
        (void) TIFFSeekFile(tif, off - (toff_t)sizeof(nextdir), SEEK_SET);
        tif->tif_diroff = 0;
	if (!WriteOK(tif, &(tif->tif_diroff), sizeof (nextdir))) {
		TIFFErrorExt(tif->tif_clientdata, module,
			     "Error writing directory link");
		return (0);
	}
    }

    /*
    ** Now use TIFFWriteDirectory() normally.
    */

    return TIFFWriteDirectory( tif );
}


/*
 * Link the current directory into the directory chain for the file.
 */
static int
TIFFLinkDirectory(TIFF* tif)
{
	static const char module[] = "TIFFLinkDirectory";
	toff_t nextdir;
	toff_t diroff, off;

	tif->tif_diroff = (TIFFSeekFile(tif, (toff_t) 0, SEEK_END)+1) &~ 1;
	diroff = tif->tif_diroff;
	if (tif->tif_flags & TIFF_SWAB)
		TIFFSwabLong(&diroff);

	/*
	 * Handle SubIFDs
	 */
        if (tif->tif_flags & TIFF_INSUBIFD) {
		(void) TIFFSeekFile(tif, tif->tif_subifdoff, SEEK_SET);
		if (!WriteOK(tif, &diroff, sizeof (diroff))) {
			TIFFErrorExt(tif->tif_clientdata, module,
				     "%s: Error writing SubIFD directory link",
				     tif->tif_name);
			return (0);
		}
		/*
		 * Advance to the next SubIFD or, if this is
		 * the last one configured, revert back to the
		 * normal directory linkage.
		 */
		if (--tif->tif_nsubifd)
			tif->tif_subifdoff += sizeof (diroff);
		else
			tif->tif_flags &= ~TIFF_INSUBIFD;
		return (1);
	}

	if (tif->tif_header.tiff_diroff == 0) {
		/*
		 * First directory, overwrite offset in header.
		 */
		tif->tif_header.tiff_diroff = tif->tif_diroff;
		(void) TIFFSeekFile(tif,
				    (toff_t)(TIFF_MAGIC_SIZE+TIFF_VERSION_SIZE),
                                    SEEK_SET);
		if (!WriteOK(tif, &diroff, sizeof (diroff))) {
			TIFFErrorExt(tif->tif_clientdata, tif->tif_name,
				     "Error writing TIFF header");
			return (0);
		}
		return (1);
	}
	/*
	 * Not the first directory, search to the last and append.
	 */
	nextdir = tif->tif_header.tiff_diroff;
	do {
		uint16 dircount;

		if (!SeekOK(tif, nextdir) ||
		    !ReadOK(tif, &dircount, sizeof (dircount))) {
			TIFFErrorExt(tif->tif_clientdata, module,
				     "Error fetching directory count");
			return (0);
		}
		if (tif->tif_flags & TIFF_SWAB)
			TIFFSwabShort(&dircount);
		(void) TIFFSeekFile(tif,
		    dircount * sizeof (TIFFDirEntry), SEEK_CUR);
		if (!ReadOK(tif, &nextdir, sizeof (nextdir))) {
			TIFFErrorExt(tif->tif_clientdata, module,
				     "Error fetching directory link");
			return (0);
		}
		if (tif->tif_flags & TIFF_SWAB)
			TIFFSwabLong(&nextdir);
	} while (nextdir != 0);
        off = TIFFSeekFile(tif, 0, SEEK_CUR); /* get current offset */
        (void) TIFFSeekFile(tif, off - (toff_t)sizeof(nextdir), SEEK_SET);
	if (!WriteOK(tif, &diroff, sizeof (diroff))) {
		TIFFErrorExt(tif->tif_clientdata, module,
			     "Error writing directory link");
		return (0);
	}
	return (1);
}

/* vim: set ts=8 sts=8 sw=8 noet: */
