Blame libtiff/tif_dir.c

Packit 7838c8
/* $Id: tif_dir.c,v 1.131 2017-07-11 21:38:04 erouault Exp $ */
Packit 7838c8
Packit 7838c8
/*
Packit 7838c8
 * Copyright (c) 1988-1997 Sam Leffler
Packit 7838c8
 * Copyright (c) 1991-1997 Silicon Graphics, Inc.
Packit 7838c8
 *
Packit 7838c8
 * Permission to use, copy, modify, distribute, and sell this software and 
Packit 7838c8
 * its documentation for any purpose is hereby granted without fee, provided
Packit 7838c8
 * that (i) the above copyright notices and this permission notice appear in
Packit 7838c8
 * all copies of the software and related documentation, and (ii) the names of
Packit 7838c8
 * Sam Leffler and Silicon Graphics may not be used in any advertising or
Packit 7838c8
 * publicity relating to the software without the specific, prior written
Packit 7838c8
 * permission of Sam Leffler and Silicon Graphics.
Packit 7838c8
 * 
Packit 7838c8
 * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, 
Packit 7838c8
 * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY 
Packit 7838c8
 * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.  
Packit 7838c8
 * 
Packit 7838c8
 * IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR
Packit 7838c8
 * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND,
Packit 7838c8
 * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
Packit 7838c8
 * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF 
Packit 7838c8
 * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE 
Packit 7838c8
 * OF THIS SOFTWARE.
Packit 7838c8
 */
Packit 7838c8
Packit 7838c8
/*
Packit 7838c8
 * TIFF Library.
Packit 7838c8
 *
Packit 7838c8
 * Directory Tag Get & Set Routines.
Packit 7838c8
 * (and also some miscellaneous stuff)
Packit 7838c8
 */
Packit 7838c8
#include "tiffiop.h"
Packit 7838c8
#include <float.h>
Packit 7838c8
Packit 7838c8
/*
Packit 7838c8
 * These are used in the backwards compatibility code...
Packit 7838c8
 */
Packit 7838c8
#define DATATYPE_VOID		0       /* !untyped data */
Packit 7838c8
#define DATATYPE_INT		1       /* !signed integer data */
Packit 7838c8
#define DATATYPE_UINT		2       /* !unsigned integer data */
Packit 7838c8
#define DATATYPE_IEEEFP		3       /* !IEEE floating point data */
Packit 7838c8
Packit 7838c8
static void
Packit 7838c8
setByteArray(void** vpp, void* vp, size_t nmemb, size_t elem_size)
Packit 7838c8
{
Packit 7838c8
	if (*vpp) {
Packit 7838c8
		_TIFFfree(*vpp);
Packit 7838c8
		*vpp = 0;
Packit 7838c8
	}
Packit 7838c8
	if (vp) {
Packit 7838c8
		tmsize_t bytes = (tmsize_t)(nmemb * elem_size);
Packit 7838c8
		if (elem_size && bytes / elem_size == nmemb)
Packit 7838c8
			*vpp = (void*) _TIFFmalloc(bytes);
Packit 7838c8
		if (*vpp)
Packit 7838c8
			_TIFFmemcpy(*vpp, vp, bytes);
Packit 7838c8
	}
Packit 7838c8
}
Packit 7838c8
void _TIFFsetByteArray(void** vpp, void* vp, uint32 n)
Packit 7838c8
    { setByteArray(vpp, vp, n, 1); }
Packit 7838c8
void _TIFFsetString(char** cpp, char* cp)
Packit 7838c8
    { setByteArray((void**) cpp, (void*) cp, strlen(cp)+1, 1); }
Packit 7838c8
static void _TIFFsetNString(char** cpp, char* cp, uint32 n)
Packit 7838c8
    { setByteArray((void**) cpp, (void*) cp, n, 1); }
Packit 7838c8
void _TIFFsetShortArray(uint16** wpp, uint16* wp, uint32 n)
Packit 7838c8
    { setByteArray((void**) wpp, (void*) wp, n, sizeof (uint16)); }
Packit 7838c8
void _TIFFsetLongArray(uint32** lpp, uint32* lp, uint32 n)
Packit 7838c8
    { setByteArray((void**) lpp, (void*) lp, n, sizeof (uint32)); }
Packit 7838c8
static void _TIFFsetLong8Array(uint64** lpp, uint64* lp, uint32 n)
Packit 7838c8
    { setByteArray((void**) lpp, (void*) lp, n, sizeof (uint64)); }
Packit 7838c8
void _TIFFsetFloatArray(float** fpp, float* fp, uint32 n)
Packit 7838c8
    { setByteArray((void**) fpp, (void*) fp, n, sizeof (float)); }
Packit 7838c8
void _TIFFsetDoubleArray(double** dpp, double* dp, uint32 n)
Packit 7838c8
    { setByteArray((void**) dpp, (void*) dp, n, sizeof (double)); }
Packit 7838c8
Packit 7838c8
static void
Packit 7838c8
setDoubleArrayOneValue(double** vpp, double value, size_t nmemb)
Packit 7838c8
{
Packit 7838c8
	if (*vpp)
Packit 7838c8
		_TIFFfree(*vpp);
Packit 7838c8
	*vpp = _TIFFmalloc(nmemb*sizeof(double));
Packit 7838c8
	if (*vpp)
Packit 7838c8
	{
Packit 7838c8
		while (nmemb--)
Packit 7838c8
			((double*)*vpp)[nmemb] = value;
Packit 7838c8
	}
Packit 7838c8
}
Packit 7838c8
Packit 7838c8
/*
Packit 7838c8
 * Install extra samples information.
Packit 7838c8
 */
Packit 7838c8
static int
Packit 7838c8
setExtraSamples(TIFFDirectory* td, va_list ap, uint32* v)
Packit 7838c8
{
Packit 7838c8
/* XXX: Unassociated alpha data == 999 is a known Corel Draw bug, see below */
Packit 7838c8
#define EXTRASAMPLE_COREL_UNASSALPHA 999 
Packit 7838c8
Packit 7838c8
	uint16* va;
Packit 7838c8
	uint32 i;
Packit 7838c8
Packit 7838c8
	*v = (uint16) va_arg(ap, uint16_vap);
Packit 7838c8
	if ((uint16) *v > td->td_samplesperpixel)
Packit 7838c8
		return 0;
Packit 7838c8
	va = va_arg(ap, uint16*);
Packit 7838c8
	if (*v > 0 && va == NULL)		/* typically missing param */
Packit 7838c8
		return 0;
Packit 7838c8
	for (i = 0; i < *v; i++) {
Packit 7838c8
		if (va[i] > EXTRASAMPLE_UNASSALPHA) {
Packit 7838c8
			/*
Packit 7838c8
			 * XXX: Corel Draw is known to produce incorrect
Packit 7838c8
			 * ExtraSamples tags which must be patched here if we
Packit 7838c8
			 * want to be able to open some of the damaged TIFF
Packit 7838c8
			 * files: 
Packit 7838c8
			 */
Packit 7838c8
			if (va[i] == EXTRASAMPLE_COREL_UNASSALPHA)
Packit 7838c8
				va[i] = EXTRASAMPLE_UNASSALPHA;
Packit 7838c8
			else
Packit 7838c8
				return 0;
Packit 7838c8
		}
Packit 7838c8
	}
Packit 7838c8
	td->td_extrasamples = (uint16) *v;
Packit 7838c8
	_TIFFsetShortArray(&td->td_sampleinfo, va, td->td_extrasamples);
Packit 7838c8
	return 1;
Packit 7838c8
Packit 7838c8
#undef EXTRASAMPLE_COREL_UNASSALPHA
Packit 7838c8
}
Packit 7838c8
Packit 7838c8
/*
Packit 7838c8
 * Confirm we have "samplesperpixel" ink names separated by \0.  Returns 
Packit 7838c8
 * zero if the ink names are not as expected.
Packit 7838c8
 */
Packit 7838c8
static uint32
Packit 7838c8
checkInkNamesString(TIFF* tif, uint32 slen, const char* s)
Packit 7838c8
{
Packit 7838c8
	TIFFDirectory* td = &tif->tif_dir;
Packit 7838c8
	uint16 i = td->td_samplesperpixel;
Packit 7838c8
Packit 7838c8
	if (slen > 0) {
Packit 7838c8
		const char* ep = s+slen;
Packit 7838c8
		const char* cp = s;
Packit 7838c8
		for (; i > 0; i--) {
Packit 7838c8
			for (; cp < ep && *cp != '\0'; cp++) {}
Packit 7838c8
			if (cp >= ep)
Packit 7838c8
				goto bad;
Packit 7838c8
			cp++;				/* skip \0 */
Packit 7838c8
		}
Packit 7838c8
		return ((uint32)(cp-s));
Packit 7838c8
	}
Packit 7838c8
bad:
Packit 7838c8
	TIFFErrorExt(tif->tif_clientdata, "TIFFSetField",
Packit 7838c8
	    "%s: Invalid InkNames value; expecting %d names, found %d",
Packit 7838c8
	    tif->tif_name,
Packit 7838c8
	    td->td_samplesperpixel,
Packit 7838c8
	    td->td_samplesperpixel-i);
Packit 7838c8
	return (0);
Packit 7838c8
}
Packit 7838c8
Packit 7838c8
static float TIFFClampDoubleToFloat( double val )
Packit 7838c8
{
Packit 7838c8
    if( val > FLT_MAX )
Packit 7838c8
        return FLT_MAX;
Packit 7838c8
    if( val < -FLT_MAX )
Packit 7838c8
        return -FLT_MAX;
Packit 7838c8
    return (float)val;
Packit 7838c8
}
Packit 7838c8
Packit 7838c8
static int
Packit 7838c8
_TIFFVSetField(TIFF* tif, uint32 tag, va_list ap)
Packit 7838c8
{
Packit 7838c8
	static const char module[] = "_TIFFVSetField";
Packit 7838c8
Packit 7838c8
	TIFFDirectory* td = &tif->tif_dir;
Packit 7838c8
	int status = 1;
Packit 7838c8
	uint32 v32, i, v;
Packit 7838c8
    double dblval;
Packit 7838c8
	char* s;
Packit 7838c8
	const TIFFField *fip = TIFFFindField(tif, tag, TIFF_ANY);
Packit 7838c8
	uint32 standard_tag = tag;
Packit 7838c8
	if( fip == NULL ) /* cannot happen since OkToChangeTag() already checks it */
Packit 7838c8
	    return 0;
Packit 7838c8
	/*
Packit 7838c8
	 * We want to force the custom code to be used for custom
Packit 7838c8
	 * fields even if the tag happens to match a well known 
Packit 7838c8
	 * one - important for reinterpreted handling of standard
Packit 7838c8
	 * tag values in custom directories (i.e. EXIF) 
Packit 7838c8
	 */
Packit 7838c8
	if (fip->field_bit == FIELD_CUSTOM) {
Packit 7838c8
		standard_tag = 0;
Packit 7838c8
	}
Packit 7838c8
Packit 7838c8
	switch (standard_tag) {
Packit 7838c8
	case TIFFTAG_SUBFILETYPE:
Packit 7838c8
		td->td_subfiletype = (uint32) va_arg(ap, uint32);
Packit 7838c8
		break;
Packit 7838c8
	case TIFFTAG_IMAGEWIDTH:
Packit 7838c8
		td->td_imagewidth = (uint32) va_arg(ap, uint32);
Packit 7838c8
		break;
Packit 7838c8
	case TIFFTAG_IMAGELENGTH:
Packit 7838c8
		td->td_imagelength = (uint32) va_arg(ap, uint32);
Packit 7838c8
		break;
Packit 7838c8
	case TIFFTAG_BITSPERSAMPLE:
Packit 7838c8
		td->td_bitspersample = (uint16) va_arg(ap, uint16_vap);
Packit 7838c8
		/*
Packit 7838c8
		 * If the data require post-decoding processing to byte-swap
Packit 7838c8
		 * samples, set it up here.  Note that since tags are required
Packit 7838c8
		 * to be ordered, compression code can override this behaviour
Packit 7838c8
		 * in the setup method if it wants to roll the post decoding
Packit 7838c8
		 * work in with its normal work.
Packit 7838c8
		 */
Packit 7838c8
		if (tif->tif_flags & TIFF_SWAB) {
Packit 7838c8
			if (td->td_bitspersample == 8)
Packit 7838c8
				tif->tif_postdecode = _TIFFNoPostDecode;
Packit 7838c8
			else if (td->td_bitspersample == 16)
Packit 7838c8
				tif->tif_postdecode = _TIFFSwab16BitData;
Packit 7838c8
			else if (td->td_bitspersample == 24)
Packit 7838c8
				tif->tif_postdecode = _TIFFSwab24BitData;
Packit 7838c8
			else if (td->td_bitspersample == 32)
Packit 7838c8
				tif->tif_postdecode = _TIFFSwab32BitData;
Packit 7838c8
			else if (td->td_bitspersample == 64)
Packit 7838c8
				tif->tif_postdecode = _TIFFSwab64BitData;
Packit 7838c8
			else if (td->td_bitspersample == 128) /* two 64's */
Packit 7838c8
				tif->tif_postdecode = _TIFFSwab64BitData;
Packit 7838c8
		}
Packit 7838c8
		break;
Packit 7838c8
	case TIFFTAG_COMPRESSION:
Packit 7838c8
		v = (uint16) va_arg(ap, uint16_vap);
Packit 7838c8
		/*
Packit 7838c8
		 * If we're changing the compression scheme, the notify the
Packit 7838c8
		 * previous module so that it can cleanup any state it's
Packit 7838c8
		 * setup.
Packit 7838c8
		 */
Packit 7838c8
		if (TIFFFieldSet(tif, FIELD_COMPRESSION)) {
Packit 7838c8
			if ((uint32)td->td_compression == v)
Packit 7838c8
				break;
Packit 7838c8
			(*tif->tif_cleanup)(tif);
Packit 7838c8
			tif->tif_flags &= ~TIFF_CODERSETUP;
Packit 7838c8
		}
Packit 7838c8
		/*
Packit 7838c8
		 * Setup new compression routine state.
Packit 7838c8
		 */
Packit 7838c8
		if( (status = TIFFSetCompressionScheme(tif, v)) != 0 )
Packit 7838c8
		    td->td_compression = (uint16) v;
Packit 7838c8
		else
Packit 7838c8
		    status = 0;
Packit 7838c8
		break;
Packit 7838c8
	case TIFFTAG_PHOTOMETRIC:
Packit 7838c8
		td->td_photometric = (uint16) va_arg(ap, uint16_vap);
Packit 7838c8
		break;
Packit 7838c8
	case TIFFTAG_THRESHHOLDING:
Packit 7838c8
		td->td_threshholding = (uint16) va_arg(ap, uint16_vap);
Packit 7838c8
		break;
Packit 7838c8
	case TIFFTAG_FILLORDER:
Packit 7838c8
		v = (uint16) va_arg(ap, uint16_vap);
Packit 7838c8
		if (v != FILLORDER_LSB2MSB && v != FILLORDER_MSB2LSB)
Packit 7838c8
			goto badvalue;
Packit 7838c8
		td->td_fillorder = (uint16) v;
Packit 7838c8
		break;
Packit 7838c8
	case TIFFTAG_ORIENTATION:
Packit 7838c8
		v = (uint16) va_arg(ap, uint16_vap);
Packit 7838c8
		if (v < ORIENTATION_TOPLEFT || ORIENTATION_LEFTBOT < v)
Packit 7838c8
			goto badvalue;
Packit 7838c8
		else
Packit 7838c8
			td->td_orientation = (uint16) v;
Packit 7838c8
		break;
Packit 7838c8
	case TIFFTAG_SAMPLESPERPIXEL:
Packit 7838c8
		v = (uint16) va_arg(ap, uint16_vap);
Packit 7838c8
		if (v == 0)
Packit 7838c8
			goto badvalue;
Packit 7838c8
        if( v != td->td_samplesperpixel )
Packit 7838c8
        {
Packit 7838c8
            /* See http://bugzilla.maptools.org/show_bug.cgi?id=2500 */
Packit 7838c8
            if( td->td_sminsamplevalue != NULL )
Packit 7838c8
            {
Packit 7838c8
                TIFFWarningExt(tif->tif_clientdata,module,
Packit 7838c8
                    "SamplesPerPixel tag value is changing, "
Packit 7838c8
                    "but SMinSampleValue tag was read with a different value. Cancelling it");
Packit 7838c8
                TIFFClrFieldBit(tif,FIELD_SMINSAMPLEVALUE);
Packit 7838c8
                _TIFFfree(td->td_sminsamplevalue);
Packit 7838c8
                td->td_sminsamplevalue = NULL;
Packit 7838c8
            }
Packit 7838c8
            if( td->td_smaxsamplevalue != NULL )
Packit 7838c8
            {
Packit 7838c8
                TIFFWarningExt(tif->tif_clientdata,module,
Packit 7838c8
                    "SamplesPerPixel tag value is changing, "
Packit 7838c8
                    "but SMaxSampleValue tag was read with a different value. Cancelling it");
Packit 7838c8
                TIFFClrFieldBit(tif,FIELD_SMAXSAMPLEVALUE);
Packit 7838c8
                _TIFFfree(td->td_smaxsamplevalue);
Packit 7838c8
                td->td_smaxsamplevalue = NULL;
Packit 7838c8
            }
Packit 7838c8
        }
Packit 7838c8
		td->td_samplesperpixel = (uint16) v;
Packit 7838c8
		break;
Packit 7838c8
	case TIFFTAG_ROWSPERSTRIP:
Packit 7838c8
		v32 = (uint32) va_arg(ap, uint32);
Packit 7838c8
		if (v32 == 0)
Packit 7838c8
			goto badvalue32;
Packit 7838c8
		td->td_rowsperstrip = v32;
Packit 7838c8
		if (!TIFFFieldSet(tif, FIELD_TILEDIMENSIONS)) {
Packit 7838c8
			td->td_tilelength = v32;
Packit 7838c8
			td->td_tilewidth = td->td_imagewidth;
Packit 7838c8
		}
Packit 7838c8
		break;
Packit 7838c8
	case TIFFTAG_MINSAMPLEVALUE:
Packit 7838c8
		td->td_minsamplevalue = (uint16) va_arg(ap, uint16_vap);
Packit 7838c8
		break;
Packit 7838c8
	case TIFFTAG_MAXSAMPLEVALUE:
Packit 7838c8
		td->td_maxsamplevalue = (uint16) va_arg(ap, uint16_vap);
Packit 7838c8
		break;
Packit 7838c8
	case TIFFTAG_SMINSAMPLEVALUE:
Packit 7838c8
		if (tif->tif_flags & TIFF_PERSAMPLE)
Packit 7838c8
			_TIFFsetDoubleArray(&td->td_sminsamplevalue, va_arg(ap, double*), td->td_samplesperpixel);
Packit 7838c8
		else
Packit 7838c8
			setDoubleArrayOneValue(&td->td_sminsamplevalue, va_arg(ap, double), td->td_samplesperpixel);
Packit 7838c8
		break;
Packit 7838c8
	case TIFFTAG_SMAXSAMPLEVALUE:
Packit 7838c8
		if (tif->tif_flags & TIFF_PERSAMPLE)
Packit 7838c8
			_TIFFsetDoubleArray(&td->td_smaxsamplevalue, va_arg(ap, double*), td->td_samplesperpixel);
Packit 7838c8
		else
Packit 7838c8
			setDoubleArrayOneValue(&td->td_smaxsamplevalue, va_arg(ap, double), td->td_samplesperpixel);
Packit 7838c8
		break;
Packit 7838c8
	case TIFFTAG_XRESOLUTION:
Packit 7838c8
        dblval = va_arg(ap, double);
Packit 7838c8
        if( dblval < 0 )
Packit 7838c8
            goto badvaluedouble;
Packit 7838c8
		td->td_xresolution = TIFFClampDoubleToFloat( dblval );
Packit 7838c8
		break;
Packit 7838c8
	case TIFFTAG_YRESOLUTION:
Packit 7838c8
        dblval = va_arg(ap, double);
Packit 7838c8
        if( dblval < 0 )
Packit 7838c8
            goto badvaluedouble;
Packit 7838c8
		td->td_yresolution = TIFFClampDoubleToFloat( dblval );
Packit 7838c8
		break;
Packit 7838c8
	case TIFFTAG_PLANARCONFIG:
Packit 7838c8
		v = (uint16) va_arg(ap, uint16_vap);
Packit 7838c8
		if (v != PLANARCONFIG_CONTIG && v != PLANARCONFIG_SEPARATE)
Packit 7838c8
			goto badvalue;
Packit 7838c8
		td->td_planarconfig = (uint16) v;
Packit 7838c8
		break;
Packit 7838c8
	case TIFFTAG_XPOSITION:
Packit 7838c8
		td->td_xposition = TIFFClampDoubleToFloat( va_arg(ap, double) );
Packit 7838c8
		break;
Packit 7838c8
	case TIFFTAG_YPOSITION:
Packit 7838c8
		td->td_yposition = TIFFClampDoubleToFloat( va_arg(ap, double) );
Packit 7838c8
		break;
Packit 7838c8
	case TIFFTAG_RESOLUTIONUNIT:
Packit 7838c8
		v = (uint16) va_arg(ap, uint16_vap);
Packit 7838c8
		if (v < RESUNIT_NONE || RESUNIT_CENTIMETER < v)
Packit 7838c8
			goto badvalue;
Packit 7838c8
		td->td_resolutionunit = (uint16) v;
Packit 7838c8
		break;
Packit 7838c8
	case TIFFTAG_PAGENUMBER:
Packit 7838c8
		td->td_pagenumber[0] = (uint16) va_arg(ap, uint16_vap);
Packit 7838c8
		td->td_pagenumber[1] = (uint16) va_arg(ap, uint16_vap);
Packit 7838c8
		break;
Packit 7838c8
	case TIFFTAG_HALFTONEHINTS:
Packit 7838c8
		td->td_halftonehints[0] = (uint16) va_arg(ap, uint16_vap);
Packit 7838c8
		td->td_halftonehints[1] = (uint16) va_arg(ap, uint16_vap);
Packit 7838c8
		break;
Packit 7838c8
	case TIFFTAG_COLORMAP:
Packit 7838c8
		v32 = (uint32)(1L<<td->td_bitspersample);
Packit 7838c8
		_TIFFsetShortArray(&td->td_colormap[0], va_arg(ap, uint16*), v32);
Packit 7838c8
		_TIFFsetShortArray(&td->td_colormap[1], va_arg(ap, uint16*), v32);
Packit 7838c8
		_TIFFsetShortArray(&td->td_colormap[2], va_arg(ap, uint16*), v32);
Packit 7838c8
		break;
Packit 7838c8
	case TIFFTAG_EXTRASAMPLES:
Packit 7838c8
		if (!setExtraSamples(td, ap, &v))
Packit 7838c8
			goto badvalue;
Packit 7838c8
		break;
Packit 7838c8
	case TIFFTAG_MATTEING:
Packit 7838c8
		td->td_extrasamples =  (((uint16) va_arg(ap, uint16_vap)) != 0);
Packit 7838c8
		if (td->td_extrasamples) {
Packit 7838c8
			uint16 sv = EXTRASAMPLE_ASSOCALPHA;
Packit 7838c8
			_TIFFsetShortArray(&td->td_sampleinfo, &sv, 1);
Packit 7838c8
		}
Packit 7838c8
		break;
Packit 7838c8
	case TIFFTAG_TILEWIDTH:
Packit 7838c8
		v32 = (uint32) va_arg(ap, uint32);
Packit 7838c8
		if (v32 % 16) {
Packit 7838c8
			if (tif->tif_mode != O_RDONLY)
Packit 7838c8
				goto badvalue32;
Packit 7838c8
			TIFFWarningExt(tif->tif_clientdata, tif->tif_name,
Packit 7838c8
				"Nonstandard tile width %d, convert file", v32);
Packit 7838c8
		}
Packit 7838c8
		td->td_tilewidth = v32;
Packit 7838c8
		tif->tif_flags |= TIFF_ISTILED;
Packit 7838c8
		break;
Packit 7838c8
	case TIFFTAG_TILELENGTH:
Packit 7838c8
		v32 = (uint32) va_arg(ap, uint32);
Packit 7838c8
		if (v32 % 16) {
Packit 7838c8
			if (tif->tif_mode != O_RDONLY)
Packit 7838c8
				goto badvalue32;
Packit 7838c8
			TIFFWarningExt(tif->tif_clientdata, tif->tif_name,
Packit 7838c8
			    "Nonstandard tile length %d, convert file", v32);
Packit 7838c8
		}
Packit 7838c8
		td->td_tilelength = v32;
Packit 7838c8
		tif->tif_flags |= TIFF_ISTILED;
Packit 7838c8
		break;
Packit 7838c8
	case TIFFTAG_TILEDEPTH:
Packit 7838c8
		v32 = (uint32) va_arg(ap, uint32);
Packit 7838c8
		if (v32 == 0)
Packit 7838c8
			goto badvalue32;
Packit 7838c8
		td->td_tiledepth = v32;
Packit 7838c8
		break;
Packit 7838c8
	case TIFFTAG_DATATYPE:
Packit 7838c8
		v = (uint16) va_arg(ap, uint16_vap);
Packit 7838c8
		switch (v) {
Packit 7838c8
		case DATATYPE_VOID:	v = SAMPLEFORMAT_VOID;	break;
Packit 7838c8
		case DATATYPE_INT:	v = SAMPLEFORMAT_INT;	break;
Packit 7838c8
		case DATATYPE_UINT:	v = SAMPLEFORMAT_UINT;	break;
Packit 7838c8
		case DATATYPE_IEEEFP:	v = SAMPLEFORMAT_IEEEFP;break;
Packit 7838c8
		default:		goto badvalue;
Packit 7838c8
		}
Packit 7838c8
		td->td_sampleformat = (uint16) v;
Packit 7838c8
		break;
Packit 7838c8
	case TIFFTAG_SAMPLEFORMAT:
Packit 7838c8
		v = (uint16) va_arg(ap, uint16_vap);
Packit 7838c8
		if (v < SAMPLEFORMAT_UINT || SAMPLEFORMAT_COMPLEXIEEEFP < v)
Packit 7838c8
			goto badvalue;
Packit 7838c8
		td->td_sampleformat = (uint16) v;
Packit 7838c8
Packit 7838c8
		/*  Try to fix up the SWAB function for complex data. */
Packit 7838c8
		if( td->td_sampleformat == SAMPLEFORMAT_COMPLEXINT
Packit 7838c8
		    && td->td_bitspersample == 32
Packit 7838c8
		    && tif->tif_postdecode == _TIFFSwab32BitData )
Packit 7838c8
		    tif->tif_postdecode = _TIFFSwab16BitData;
Packit 7838c8
		else if( (td->td_sampleformat == SAMPLEFORMAT_COMPLEXINT
Packit 7838c8
			  || td->td_sampleformat == SAMPLEFORMAT_COMPLEXIEEEFP)
Packit 7838c8
			 && td->td_bitspersample == 64
Packit 7838c8
			 && tif->tif_postdecode == _TIFFSwab64BitData )
Packit 7838c8
		    tif->tif_postdecode = _TIFFSwab32BitData;
Packit 7838c8
		break;
Packit 7838c8
	case TIFFTAG_IMAGEDEPTH:
Packit 7838c8
		td->td_imagedepth = (uint32) va_arg(ap, uint32);
Packit 7838c8
		break;
Packit 7838c8
	case TIFFTAG_SUBIFD:
Packit 7838c8
		if ((tif->tif_flags & TIFF_INSUBIFD) == 0) {
Packit 7838c8
			td->td_nsubifd = (uint16) va_arg(ap, uint16_vap);
Packit 7838c8
			_TIFFsetLong8Array(&td->td_subifd, (uint64*) va_arg(ap, uint64*),
Packit 7838c8
			    (uint32) td->td_nsubifd);
Packit 7838c8
		} else {
Packit 7838c8
			TIFFErrorExt(tif->tif_clientdata, module,
Packit 7838c8
				     "%s: Sorry, cannot nest SubIFDs",
Packit 7838c8
				     tif->tif_name);
Packit 7838c8
			status = 0;
Packit 7838c8
		}
Packit 7838c8
		break;
Packit 7838c8
	case TIFFTAG_YCBCRPOSITIONING:
Packit 7838c8
		td->td_ycbcrpositioning = (uint16) va_arg(ap, uint16_vap);
Packit 7838c8
		break;
Packit 7838c8
	case TIFFTAG_YCBCRSUBSAMPLING:
Packit 7838c8
		td->td_ycbcrsubsampling[0] = (uint16) va_arg(ap, uint16_vap);
Packit 7838c8
		td->td_ycbcrsubsampling[1] = (uint16) va_arg(ap, uint16_vap);
Packit 7838c8
		break;
Packit 7838c8
	case TIFFTAG_TRANSFERFUNCTION:
Packit 7838c8
		v = (td->td_samplesperpixel - td->td_extrasamples) > 1 ? 3 : 1;
Packit 7838c8
		for (i = 0; i < v; i++)
Packit 7838c8
			_TIFFsetShortArray(&td->td_transferfunction[i],
Packit 7838c8
			    va_arg(ap, uint16*), 1U<<td->td_bitspersample);
Packit 7838c8
		break;
Packit 7838c8
	case TIFFTAG_REFERENCEBLACKWHITE:
Packit 7838c8
		/* XXX should check for null range */
Packit 7838c8
		_TIFFsetFloatArray(&td->td_refblackwhite, va_arg(ap, float*), 6);
Packit 7838c8
		break;
Packit 7838c8
	case TIFFTAG_INKNAMES:
Packit 7838c8
		v = (uint16) va_arg(ap, uint16_vap);
Packit 7838c8
		s = va_arg(ap, char*);
Packit 7838c8
		v = checkInkNamesString(tif, v, s);
Packit 7838c8
		status = v > 0;
Packit 7838c8
		if( v > 0 ) {
Packit 7838c8
			_TIFFsetNString(&td->td_inknames, s, v);
Packit 7838c8
			td->td_inknameslen = v;
Packit 7838c8
		}
Packit 7838c8
		break;
Packit 7838c8
	case TIFFTAG_PERSAMPLE:
Packit 7838c8
		v = (uint16) va_arg(ap, uint16_vap);
Packit 7838c8
		if( v == PERSAMPLE_MULTI )
Packit 7838c8
			tif->tif_flags |= TIFF_PERSAMPLE;
Packit 7838c8
		else
Packit 7838c8
			tif->tif_flags &= ~TIFF_PERSAMPLE;
Packit 7838c8
		break;
Packit 7838c8
	default: {
Packit 7838c8
		TIFFTagValue *tv;
Packit 7838c8
		int tv_size, iCustom;
Packit 7838c8
Packit 7838c8
		/*
Packit 7838c8
		 * This can happen if multiple images are open with different
Packit 7838c8
		 * codecs which have private tags.  The global tag information
Packit 7838c8
		 * table may then have tags that are valid for one file but not
Packit 7838c8
		 * the other. If the client tries to set a tag that is not valid
Packit 7838c8
		 * for the image's codec then we'll arrive here.  This
Packit 7838c8
		 * happens, for example, when tiffcp is used to convert between
Packit 7838c8
		 * compression schemes and codec-specific tags are blindly copied.
Packit 7838c8
		 */
Packit 7838c8
		if(fip->field_bit != FIELD_CUSTOM) {
Packit 7838c8
			TIFFErrorExt(tif->tif_clientdata, module,
Packit 7838c8
			    "%s: Invalid %stag \"%s\" (not supported by codec)",
Packit 7838c8
			    tif->tif_name, isPseudoTag(tag) ? "pseudo-" : "",
Packit 7838c8
			    fip->field_name);
Packit 7838c8
			status = 0;
Packit 7838c8
			break;
Packit 7838c8
		}
Packit 7838c8
Packit 7838c8
		/*
Packit 7838c8
		 * Find the existing entry for this custom value.
Packit 7838c8
		 */
Packit 7838c8
		tv = NULL;
Packit 7838c8
		for (iCustom = 0; iCustom < td->td_customValueCount; iCustom++) {
Packit 7838c8
			if (td->td_customValues[iCustom].info->field_tag == tag) {
Packit 7838c8
				tv = td->td_customValues + iCustom;
Packit 7838c8
				if (tv->value != NULL) {
Packit 7838c8
					_TIFFfree(tv->value);
Packit 7838c8
					tv->value = NULL;
Packit 7838c8
				}
Packit 7838c8
				break;
Packit 7838c8
			}
Packit 7838c8
		}
Packit 7838c8
Packit 7838c8
		/*
Packit 7838c8
		 * Grow the custom list if the entry was not found.
Packit 7838c8
		 */
Packit 7838c8
		if(tv == NULL) {
Packit 7838c8
			TIFFTagValue *new_customValues;
Packit 7838c8
Packit 7838c8
			td->td_customValueCount++;
Packit 7838c8
			new_customValues = (TIFFTagValue *)
Packit 7838c8
			    _TIFFrealloc(td->td_customValues,
Packit 7838c8
			    sizeof(TIFFTagValue) * td->td_customValueCount);
Packit 7838c8
			if (!new_customValues) {
Packit 7838c8
				TIFFErrorExt(tif->tif_clientdata, module,
Packit 7838c8
				    "%s: Failed to allocate space for list of custom values",
Packit 7838c8
				    tif->tif_name);
Packit 7838c8
				status = 0;
Packit 7838c8
				goto end;
Packit 7838c8
			}
Packit 7838c8
Packit 7838c8
			td->td_customValues = new_customValues;
Packit 7838c8
Packit 7838c8
			tv = td->td_customValues + (td->td_customValueCount - 1);
Packit 7838c8
			tv->info = fip;
Packit 7838c8
			tv->value = NULL;
Packit 7838c8
			tv->count = 0;
Packit 7838c8
		}
Packit 7838c8
Packit 7838c8
		/*
Packit 7838c8
		 * Set custom value ... save a copy of the custom tag value.
Packit 7838c8
		 */
Packit 7838c8
		tv_size = _TIFFDataSize(fip->field_type);
Packit 7838c8
		if (tv_size == 0) {
Packit 7838c8
			status = 0;
Packit 7838c8
			TIFFErrorExt(tif->tif_clientdata, module,
Packit 7838c8
			    "%s: Bad field type %d for \"%s\"",
Packit 7838c8
			    tif->tif_name, fip->field_type,
Packit 7838c8
			    fip->field_name);
Packit 7838c8
			goto end;
Packit 7838c8
		}
Packit 7838c8
Packit 7838c8
		if (fip->field_type == TIFF_ASCII)
Packit 7838c8
		{
Packit 7838c8
			uint32 ma;
Packit 7838c8
			char* mb;
Packit 7838c8
			if (fip->field_passcount)
Packit 7838c8
			{
Packit 7838c8
				assert(fip->field_writecount==TIFF_VARIABLE2);
Packit 7838c8
				ma=(uint32)va_arg(ap,uint32);
Packit 7838c8
				mb=(char*)va_arg(ap,char*);
Packit 7838c8
			}
Packit 7838c8
			else
Packit 7838c8
			{
Packit 7838c8
				mb=(char*)va_arg(ap,char*);
Packit 7838c8
				ma=(uint32)(strlen(mb)+1);
Packit 7838c8
			}
Packit 7838c8
			tv->count=ma;
Packit 7838c8
			setByteArray(&tv->value,mb,ma,1);
Packit 7838c8
		}
Packit 7838c8
		else
Packit 7838c8
		{
Packit 7838c8
			if (fip->field_passcount) {
Packit 7838c8
				if (fip->field_writecount == TIFF_VARIABLE2)
Packit 7838c8
					tv->count = (uint32) va_arg(ap, uint32);
Packit 7838c8
				else
Packit 7838c8
					tv->count = (int) va_arg(ap, int);
Packit 7838c8
			} else if (fip->field_writecount == TIFF_VARIABLE
Packit 7838c8
			   || fip->field_writecount == TIFF_VARIABLE2)
Packit 7838c8
				tv->count = 1;
Packit 7838c8
			else if (fip->field_writecount == TIFF_SPP)
Packit 7838c8
				tv->count = td->td_samplesperpixel;
Packit 7838c8
			else
Packit 7838c8
				tv->count = fip->field_writecount;
Packit 7838c8
Packit 7838c8
			if (tv->count == 0) {
Packit 7838c8
				status = 0;
Packit 7838c8
				TIFFErrorExt(tif->tif_clientdata, module,
Packit 7838c8
					     "%s: Null count for \"%s\" (type "
Packit 7838c8
					     "%d, writecount %d, passcount %d)",
Packit 7838c8
					     tif->tif_name,
Packit 7838c8
					     fip->field_name,
Packit 7838c8
					     fip->field_type,
Packit 7838c8
					     fip->field_writecount,
Packit 7838c8
					     fip->field_passcount);
Packit 7838c8
				goto end;
Packit 7838c8
			}
Packit 7838c8
Packit 7838c8
			tv->value = _TIFFCheckMalloc(tif, tv->count, tv_size,
Packit 7838c8
			    "custom tag binary object");
Packit 7838c8
			if (!tv->value) {
Packit 7838c8
				status = 0;
Packit 7838c8
				goto end;
Packit 7838c8
			}
Packit 7838c8
Packit 7838c8
			if (fip->field_tag == TIFFTAG_DOTRANGE 
Packit 7838c8
			    && strcmp(fip->field_name,"DotRange") == 0) {
Packit 7838c8
				/* TODO: This is an evil exception and should not have been
Packit 7838c8
				   handled this way ... likely best if we move it into
Packit 7838c8
				   the directory structure with an explicit field in 
Packit 7838c8
				   libtiff 4.1 and assign it a FIELD_ value */
Packit 7838c8
				uint16 v2[2];
Packit 7838c8
				v2[0] = (uint16)va_arg(ap, int);
Packit 7838c8
				v2[1] = (uint16)va_arg(ap, int);
Packit 7838c8
				_TIFFmemcpy(tv->value, &v2, 4);
Packit 7838c8
			}
Packit 7838c8
Packit 7838c8
			else if (fip->field_passcount
Packit 7838c8
				  || fip->field_writecount == TIFF_VARIABLE
Packit 7838c8
				  || fip->field_writecount == TIFF_VARIABLE2
Packit 7838c8
				  || fip->field_writecount == TIFF_SPP
Packit 7838c8
				  || tv->count > 1) {
Packit 7838c8
				_TIFFmemcpy(tv->value, va_arg(ap, void *),
Packit 7838c8
				    tv->count * tv_size);
Packit 7838c8
			} else {
Packit 7838c8
				char *val = (char *)tv->value;
Packit 7838c8
				assert( tv->count == 1 );
Packit 7838c8
Packit 7838c8
				switch (fip->field_type) {
Packit 7838c8
				case TIFF_BYTE:
Packit 7838c8
				case TIFF_UNDEFINED:
Packit 7838c8
					{
Packit 7838c8
						uint8 v2 = (uint8)va_arg(ap, int);
Packit 7838c8
						_TIFFmemcpy(val, &v2, tv_size);
Packit 7838c8
					}
Packit 7838c8
					break;
Packit 7838c8
				case TIFF_SBYTE:
Packit 7838c8
					{
Packit 7838c8
						int8 v2 = (int8)va_arg(ap, int);
Packit 7838c8
						_TIFFmemcpy(val, &v2, tv_size);
Packit 7838c8
					}
Packit 7838c8
					break;
Packit 7838c8
				case TIFF_SHORT:
Packit 7838c8
					{
Packit 7838c8
						uint16 v2 = (uint16)va_arg(ap, int);
Packit 7838c8
						_TIFFmemcpy(val, &v2, tv_size);
Packit 7838c8
					}
Packit 7838c8
					break;
Packit 7838c8
				case TIFF_SSHORT:
Packit 7838c8
					{
Packit 7838c8
						int16 v2 = (int16)va_arg(ap, int);
Packit 7838c8
						_TIFFmemcpy(val, &v2, tv_size);
Packit 7838c8
					}
Packit 7838c8
					break;
Packit 7838c8
				case TIFF_LONG:
Packit 7838c8
				case TIFF_IFD:
Packit 7838c8
					{
Packit 7838c8
						uint32 v2 = va_arg(ap, uint32);
Packit 7838c8
						_TIFFmemcpy(val, &v2, tv_size);
Packit 7838c8
					}
Packit 7838c8
					break;
Packit 7838c8
				case TIFF_SLONG:
Packit 7838c8
					{
Packit 7838c8
						int32 v2 = va_arg(ap, int32);
Packit 7838c8
						_TIFFmemcpy(val, &v2, tv_size);
Packit 7838c8
					}
Packit 7838c8
					break;
Packit 7838c8
				case TIFF_LONG8:
Packit 7838c8
				case TIFF_IFD8:
Packit 7838c8
					{
Packit 7838c8
						uint64 v2 = va_arg(ap, uint64);
Packit 7838c8
						_TIFFmemcpy(val, &v2, tv_size);
Packit 7838c8
					}
Packit 7838c8
					break;
Packit 7838c8
				case TIFF_SLONG8:
Packit 7838c8
					{
Packit 7838c8
						int64 v2 = va_arg(ap, int64);
Packit 7838c8
						_TIFFmemcpy(val, &v2, tv_size);
Packit 7838c8
					}
Packit 7838c8
					break;
Packit 7838c8
				case TIFF_RATIONAL:
Packit 7838c8
				case TIFF_SRATIONAL:
Packit 7838c8
				case TIFF_FLOAT:
Packit 7838c8
					{
Packit 7838c8
						float v2 = TIFFClampDoubleToFloat(va_arg(ap, double));
Packit 7838c8
						_TIFFmemcpy(val, &v2, tv_size);
Packit 7838c8
					}
Packit 7838c8
					break;
Packit 7838c8
				case TIFF_DOUBLE:
Packit 7838c8
					{
Packit 7838c8
						double v2 = va_arg(ap, double);
Packit 7838c8
						_TIFFmemcpy(val, &v2, tv_size);
Packit 7838c8
					}
Packit 7838c8
					break;
Packit 7838c8
				default:
Packit 7838c8
					_TIFFmemset(val, 0, tv_size);
Packit 7838c8
					status = 0;
Packit 7838c8
					break;
Packit 7838c8
				}
Packit 7838c8
			}
Packit 7838c8
		}
Packit 7838c8
	}
Packit 7838c8
	}
Packit 7838c8
	if (status) {
Packit 7838c8
		const TIFFField* fip2=TIFFFieldWithTag(tif,tag);
Packit 7838c8
		if (fip2)                
Packit 7838c8
			TIFFSetFieldBit(tif, fip2->field_bit);
Packit 7838c8
		tif->tif_flags |= TIFF_DIRTYDIRECT;
Packit 7838c8
	}
Packit 7838c8
Packit 7838c8
end:
Packit 7838c8
	va_end(ap);
Packit 7838c8
	return (status);
Packit 7838c8
badvalue:
Packit 7838c8
        {
Packit 7838c8
		const TIFFField* fip2=TIFFFieldWithTag(tif,tag);
Packit 7838c8
		TIFFErrorExt(tif->tif_clientdata, module,
Packit 7838c8
		     "%s: Bad value %u for \"%s\" tag",
Packit 7838c8
		     tif->tif_name, v,
Packit 7838c8
		     fip2 ? fip2->field_name : "Unknown");
Packit 7838c8
		va_end(ap);
Packit 7838c8
        }
Packit 7838c8
	return (0);
Packit 7838c8
badvalue32:
Packit 7838c8
        {
Packit 7838c8
		const TIFFField* fip2=TIFFFieldWithTag(tif,tag);
Packit 7838c8
		TIFFErrorExt(tif->tif_clientdata, module,
Packit 7838c8
		     "%s: Bad value %u for \"%s\" tag",
Packit 7838c8
		     tif->tif_name, v32,
Packit 7838c8
		     fip2 ? fip2->field_name : "Unknown");
Packit 7838c8
		va_end(ap);
Packit 7838c8
        }
Packit 7838c8
	return (0);
Packit 7838c8
badvaluedouble:
Packit 7838c8
        {
Packit 7838c8
        const TIFFField* fip2=TIFFFieldWithTag(tif,tag);
Packit 7838c8
        TIFFErrorExt(tif->tif_clientdata, module,
Packit 7838c8
             "%s: Bad value %f for \"%s\" tag",
Packit 7838c8
             tif->tif_name, dblval,
Packit 7838c8
             fip2 ? fip2->field_name : "Unknown");
Packit 7838c8
        va_end(ap);
Packit 7838c8
        }
Packit 7838c8
    return (0);
Packit 7838c8
}
Packit 7838c8
Packit 7838c8
/*
Packit 7838c8
 * Return 1/0 according to whether or not
Packit 7838c8
 * it is permissible to set the tag's value.
Packit 7838c8
 * Note that we allow ImageLength to be changed
Packit 7838c8
 * so that we can append and extend to images.
Packit 7838c8
 * Any other tag may not be altered once writing
Packit 7838c8
 * has commenced, unless its value has no effect
Packit 7838c8
 * on the format of the data that is written.
Packit 7838c8
 */
Packit 7838c8
static int
Packit 7838c8
OkToChangeTag(TIFF* tif, uint32 tag)
Packit 7838c8
{
Packit 7838c8
	const TIFFField* fip = TIFFFindField(tif, tag, TIFF_ANY);
Packit 7838c8
	if (!fip) {			/* unknown tag */
Packit 7838c8
		TIFFErrorExt(tif->tif_clientdata, "TIFFSetField", "%s: Unknown %stag %u",
Packit 7838c8
		    tif->tif_name, isPseudoTag(tag) ? "pseudo-" : "", tag);
Packit 7838c8
		return (0);
Packit 7838c8
	}
Packit 7838c8
	if (tag != TIFFTAG_IMAGELENGTH && (tif->tif_flags & TIFF_BEENWRITING) &&
Packit 7838c8
	    !fip->field_oktochange) {
Packit 7838c8
		/*
Packit 7838c8
		 * Consult info table to see if tag can be changed
Packit 7838c8
		 * after we've started writing.  We only allow changes
Packit 7838c8
		 * to those tags that don't/shouldn't affect the
Packit 7838c8
		 * compression and/or format of the data.
Packit 7838c8
		 */
Packit 7838c8
		TIFFErrorExt(tif->tif_clientdata, "TIFFSetField",
Packit 7838c8
		    "%s: Cannot modify tag \"%s\" while writing",
Packit 7838c8
		    tif->tif_name, fip->field_name);
Packit 7838c8
		return (0);
Packit 7838c8
	}
Packit 7838c8
	return (1);
Packit 7838c8
}
Packit 7838c8
Packit 7838c8
/*
Packit 7838c8
 * Record the value of a field in the
Packit 7838c8
 * internal directory structure.  The
Packit 7838c8
 * field will be written to the file
Packit 7838c8
 * when/if the directory structure is
Packit 7838c8
 * updated.
Packit 7838c8
 */
Packit 7838c8
int
Packit 7838c8
TIFFSetField(TIFF* tif, uint32 tag, ...)
Packit 7838c8
{
Packit 7838c8
	va_list ap;
Packit 7838c8
	int status;
Packit 7838c8
Packit 7838c8
	va_start(ap, tag);
Packit 7838c8
	status = TIFFVSetField(tif, tag, ap);
Packit 7838c8
	va_end(ap);
Packit 7838c8
	return (status);
Packit 7838c8
}
Packit 7838c8
Packit 7838c8
/*
Packit 7838c8
 * Clear the contents of the field in the internal structure.
Packit 7838c8
 */
Packit 7838c8
int
Packit 7838c8
TIFFUnsetField(TIFF* tif, uint32 tag)
Packit 7838c8
{
Packit 7838c8
    const TIFFField *fip =  TIFFFieldWithTag(tif, tag);
Packit 7838c8
    TIFFDirectory* td = &tif->tif_dir;
Packit 7838c8
Packit 7838c8
    if( !fip )
Packit 7838c8
        return 0;
Packit 7838c8
Packit 7838c8
    if( fip->field_bit != FIELD_CUSTOM )
Packit 7838c8
        TIFFClrFieldBit(tif, fip->field_bit);
Packit 7838c8
    else
Packit 7838c8
    {
Packit 7838c8
        TIFFTagValue *tv = NULL;
Packit 7838c8
        int i;
Packit 7838c8
Packit 7838c8
        for (i = 0; i < td->td_customValueCount; i++) {
Packit 7838c8
                
Packit 7838c8
            tv = td->td_customValues + i;
Packit 7838c8
            if( tv->info->field_tag == tag )
Packit 7838c8
                break;
Packit 7838c8
        }
Packit 7838c8
Packit 7838c8
        if( i < td->td_customValueCount )
Packit 7838c8
        {
Packit 7838c8
            _TIFFfree(tv->value);
Packit 7838c8
            for( ; i < td->td_customValueCount-1; i++) {
Packit 7838c8
                td->td_customValues[i] = td->td_customValues[i+1];
Packit 7838c8
            }
Packit 7838c8
            td->td_customValueCount--;
Packit 7838c8
        }
Packit 7838c8
    }
Packit 7838c8
        
Packit 7838c8
    tif->tif_flags |= TIFF_DIRTYDIRECT;
Packit 7838c8
Packit 7838c8
    return (1);
Packit 7838c8
}
Packit 7838c8
Packit 7838c8
/*
Packit 7838c8
 * Like TIFFSetField, but taking a varargs
Packit 7838c8
 * parameter list.  This routine is useful
Packit 7838c8
 * for building higher-level interfaces on
Packit 7838c8
 * top of the library.
Packit 7838c8
 */
Packit 7838c8
int
Packit 7838c8
TIFFVSetField(TIFF* tif, uint32 tag, va_list ap)
Packit 7838c8
{
Packit 7838c8
	return OkToChangeTag(tif, tag) ?
Packit 7838c8
	    (*tif->tif_tagmethods.vsetfield)(tif, tag, ap) : 0;
Packit 7838c8
}
Packit 7838c8
Packit 7838c8
static int
Packit 7838c8
_TIFFVGetField(TIFF* tif, uint32 tag, va_list ap)
Packit 7838c8
{
Packit 7838c8
	TIFFDirectory* td = &tif->tif_dir;
Packit 7838c8
	int ret_val = 1;
Packit 7838c8
	uint32 standard_tag = tag;
Packit 7838c8
	const TIFFField* fip = TIFFFindField(tif, tag, TIFF_ANY);
Packit 7838c8
	if( fip == NULL ) /* cannot happen since TIFFGetField() already checks it */
Packit 7838c8
	    return 0;
Packit 7838c8
	
Packit 7838c8
        if( tag == TIFFTAG_NUMBEROFINKS )
Packit 7838c8
        {
Packit 7838c8
            int i;
Packit 7838c8
            for (i = 0; i < td->td_customValueCount; i++) {
Packit 7838c8
                uint16 val;
Packit 7838c8
                TIFFTagValue *tv = td->td_customValues + i;
Packit 7838c8
                if (tv->info->field_tag != tag)
Packit 7838c8
                    continue;
Packit 7838c8
                if( tv->value == NULL )
Packit 7838c8
                    return 0;
Packit 7838c8
                val = *(uint16 *)tv->value;
Packit 7838c8
                /* Truncate to SamplesPerPixel, since the */
Packit 7838c8
                /* setting code for INKNAMES assume that there are SamplesPerPixel */
Packit 7838c8
                /* inknames. */
Packit 7838c8
                /* Fixes http://bugzilla.maptools.org/show_bug.cgi?id=2599 */
Packit 7838c8
                if( val > td->td_samplesperpixel )
Packit 7838c8
                {
Packit 7838c8
                    TIFFWarningExt(tif->tif_clientdata,"_TIFFVGetField",
Packit 7838c8
                                   "Truncating NumberOfInks from %u to %u",
Packit 7838c8
                                   val, td->td_samplesperpixel);
Packit 7838c8
                    val = td->td_samplesperpixel;
Packit 7838c8
                }
Packit 7838c8
                *va_arg(ap, uint16*) = val;
Packit 7838c8
                return 1;
Packit 7838c8
            }
Packit 7838c8
            return 0;
Packit 7838c8
        }
Packit 7838c8
Packit 7838c8
	/*
Packit 7838c8
	 * We want to force the custom code to be used for custom
Packit 7838c8
	 * fields even if the tag happens to match a well known 
Packit 7838c8
	 * one - important for reinterpreted handling of standard
Packit 7838c8
	 * tag values in custom directories (i.e. EXIF) 
Packit 7838c8
	 */
Packit 7838c8
	if (fip->field_bit == FIELD_CUSTOM) {
Packit 7838c8
		standard_tag = 0;
Packit 7838c8
	}
Packit 7838c8
Packit 7838c8
	switch (standard_tag) {
Packit 7838c8
		case TIFFTAG_SUBFILETYPE:
Packit 7838c8
			*va_arg(ap, uint32*) = td->td_subfiletype;
Packit 7838c8
			break;
Packit 7838c8
		case TIFFTAG_IMAGEWIDTH:
Packit 7838c8
			*va_arg(ap, uint32*) = td->td_imagewidth;
Packit 7838c8
			break;
Packit 7838c8
		case TIFFTAG_IMAGELENGTH:
Packit 7838c8
			*va_arg(ap, uint32*) = td->td_imagelength;
Packit 7838c8
			break;
Packit 7838c8
		case TIFFTAG_BITSPERSAMPLE:
Packit 7838c8
			*va_arg(ap, uint16*) = td->td_bitspersample;
Packit 7838c8
			break;
Packit 7838c8
		case TIFFTAG_COMPRESSION:
Packit 7838c8
			*va_arg(ap, uint16*) = td->td_compression;
Packit 7838c8
			break;
Packit 7838c8
		case TIFFTAG_PHOTOMETRIC:
Packit 7838c8
			*va_arg(ap, uint16*) = td->td_photometric;
Packit 7838c8
			break;
Packit 7838c8
		case TIFFTAG_THRESHHOLDING:
Packit 7838c8
			*va_arg(ap, uint16*) = td->td_threshholding;
Packit 7838c8
			break;
Packit 7838c8
		case TIFFTAG_FILLORDER:
Packit 7838c8
			*va_arg(ap, uint16*) = td->td_fillorder;
Packit 7838c8
			break;
Packit 7838c8
		case TIFFTAG_ORIENTATION:
Packit 7838c8
			*va_arg(ap, uint16*) = td->td_orientation;
Packit 7838c8
			break;
Packit 7838c8
		case TIFFTAG_SAMPLESPERPIXEL:
Packit 7838c8
			*va_arg(ap, uint16*) = td->td_samplesperpixel;
Packit 7838c8
			break;
Packit 7838c8
		case TIFFTAG_ROWSPERSTRIP:
Packit 7838c8
			*va_arg(ap, uint32*) = td->td_rowsperstrip;
Packit 7838c8
			break;
Packit 7838c8
		case TIFFTAG_MINSAMPLEVALUE:
Packit 7838c8
			*va_arg(ap, uint16*) = td->td_minsamplevalue;
Packit 7838c8
			break;
Packit 7838c8
		case TIFFTAG_MAXSAMPLEVALUE:
Packit 7838c8
			*va_arg(ap, uint16*) = td->td_maxsamplevalue;
Packit 7838c8
			break;
Packit 7838c8
		case TIFFTAG_SMINSAMPLEVALUE:
Packit 7838c8
			if (tif->tif_flags & TIFF_PERSAMPLE)
Packit 7838c8
				*va_arg(ap, double**) = td->td_sminsamplevalue;
Packit 7838c8
			else
Packit 7838c8
			{
Packit 7838c8
				/* libtiff historically treats this as a single value. */
Packit 7838c8
				uint16 i;
Packit 7838c8
				double v = td->td_sminsamplevalue[0];
Packit 7838c8
				for (i=1; i < td->td_samplesperpixel; ++i)
Packit 7838c8
					if( td->td_sminsamplevalue[i] < v )
Packit 7838c8
						v = td->td_sminsamplevalue[i];
Packit 7838c8
				*va_arg(ap, double*) = v;
Packit 7838c8
			}
Packit 7838c8
			break;
Packit 7838c8
		case TIFFTAG_SMAXSAMPLEVALUE:
Packit 7838c8
			if (tif->tif_flags & TIFF_PERSAMPLE)
Packit 7838c8
				*va_arg(ap, double**) = td->td_smaxsamplevalue;
Packit 7838c8
			else
Packit 7838c8
			{
Packit 7838c8
				/* libtiff historically treats this as a single value. */
Packit 7838c8
				uint16 i;
Packit 7838c8
				double v = td->td_smaxsamplevalue[0];
Packit 7838c8
				for (i=1; i < td->td_samplesperpixel; ++i)
Packit 7838c8
					if( td->td_smaxsamplevalue[i] > v )
Packit 7838c8
						v = td->td_smaxsamplevalue[i];
Packit 7838c8
				*va_arg(ap, double*) = v;
Packit 7838c8
			}
Packit 7838c8
			break;
Packit 7838c8
		case TIFFTAG_XRESOLUTION:
Packit 7838c8
			*va_arg(ap, float*) = td->td_xresolution;
Packit 7838c8
			break;
Packit 7838c8
		case TIFFTAG_YRESOLUTION:
Packit 7838c8
			*va_arg(ap, float*) = td->td_yresolution;
Packit 7838c8
			break;
Packit 7838c8
		case TIFFTAG_PLANARCONFIG:
Packit 7838c8
			*va_arg(ap, uint16*) = td->td_planarconfig;
Packit 7838c8
			break;
Packit 7838c8
		case TIFFTAG_XPOSITION:
Packit 7838c8
			*va_arg(ap, float*) = td->td_xposition;
Packit 7838c8
			break;
Packit 7838c8
		case TIFFTAG_YPOSITION:
Packit 7838c8
			*va_arg(ap, float*) = td->td_yposition;
Packit 7838c8
			break;
Packit 7838c8
		case TIFFTAG_RESOLUTIONUNIT:
Packit 7838c8
			*va_arg(ap, uint16*) = td->td_resolutionunit;
Packit 7838c8
			break;
Packit 7838c8
		case TIFFTAG_PAGENUMBER:
Packit 7838c8
			*va_arg(ap, uint16*) = td->td_pagenumber[0];
Packit 7838c8
			*va_arg(ap, uint16*) = td->td_pagenumber[1];
Packit 7838c8
			break;
Packit 7838c8
		case TIFFTAG_HALFTONEHINTS:
Packit 7838c8
			*va_arg(ap, uint16*) = td->td_halftonehints[0];
Packit 7838c8
			*va_arg(ap, uint16*) = td->td_halftonehints[1];
Packit 7838c8
			break;
Packit 7838c8
		case TIFFTAG_COLORMAP:
Packit 7838c8
			*va_arg(ap, uint16**) = td->td_colormap[0];
Packit 7838c8
			*va_arg(ap, uint16**) = td->td_colormap[1];
Packit 7838c8
			*va_arg(ap, uint16**) = td->td_colormap[2];
Packit 7838c8
			break;
Packit 7838c8
		case TIFFTAG_STRIPOFFSETS:
Packit 7838c8
		case TIFFTAG_TILEOFFSETS:
Packit 7838c8
			_TIFFFillStriles( tif );
Packit 7838c8
			*va_arg(ap, uint64**) = td->td_stripoffset;
Packit 7838c8
			break;
Packit 7838c8
		case TIFFTAG_STRIPBYTECOUNTS:
Packit 7838c8
		case TIFFTAG_TILEBYTECOUNTS:
Packit 7838c8
			_TIFFFillStriles( tif );
Packit 7838c8
			*va_arg(ap, uint64**) = td->td_stripbytecount;
Packit 7838c8
			break;
Packit 7838c8
		case TIFFTAG_MATTEING:
Packit 7838c8
			*va_arg(ap, uint16*) =
Packit 7838c8
			    (td->td_extrasamples == 1 &&
Packit 7838c8
			    td->td_sampleinfo[0] == EXTRASAMPLE_ASSOCALPHA);
Packit 7838c8
			break;
Packit 7838c8
		case TIFFTAG_EXTRASAMPLES:
Packit 7838c8
			*va_arg(ap, uint16*) = td->td_extrasamples;
Packit 7838c8
			*va_arg(ap, uint16**) = td->td_sampleinfo;
Packit 7838c8
			break;
Packit 7838c8
		case TIFFTAG_TILEWIDTH:
Packit 7838c8
			*va_arg(ap, uint32*) = td->td_tilewidth;
Packit 7838c8
			break;
Packit 7838c8
		case TIFFTAG_TILELENGTH:
Packit 7838c8
			*va_arg(ap, uint32*) = td->td_tilelength;
Packit 7838c8
			break;
Packit 7838c8
		case TIFFTAG_TILEDEPTH:
Packit 7838c8
			*va_arg(ap, uint32*) = td->td_tiledepth;
Packit 7838c8
			break;
Packit 7838c8
		case TIFFTAG_DATATYPE:
Packit 7838c8
			switch (td->td_sampleformat) {
Packit 7838c8
				case SAMPLEFORMAT_UINT:
Packit 7838c8
					*va_arg(ap, uint16*) = DATATYPE_UINT;
Packit 7838c8
					break;
Packit 7838c8
				case SAMPLEFORMAT_INT:
Packit 7838c8
					*va_arg(ap, uint16*) = DATATYPE_INT;
Packit 7838c8
					break;
Packit 7838c8
				case SAMPLEFORMAT_IEEEFP:
Packit 7838c8
					*va_arg(ap, uint16*) = DATATYPE_IEEEFP;
Packit 7838c8
					break;
Packit 7838c8
				case SAMPLEFORMAT_VOID:
Packit 7838c8
					*va_arg(ap, uint16*) = DATATYPE_VOID;
Packit 7838c8
					break;
Packit 7838c8
			}
Packit 7838c8
			break;
Packit 7838c8
		case TIFFTAG_SAMPLEFORMAT:
Packit 7838c8
			*va_arg(ap, uint16*) = td->td_sampleformat;
Packit 7838c8
			break;
Packit 7838c8
		case TIFFTAG_IMAGEDEPTH:
Packit 7838c8
			*va_arg(ap, uint32*) = td->td_imagedepth;
Packit 7838c8
			break;
Packit 7838c8
		case TIFFTAG_SUBIFD:
Packit 7838c8
			*va_arg(ap, uint16*) = td->td_nsubifd;
Packit 7838c8
			*va_arg(ap, uint64**) = td->td_subifd;
Packit 7838c8
			break;
Packit 7838c8
		case TIFFTAG_YCBCRPOSITIONING:
Packit 7838c8
			*va_arg(ap, uint16*) = td->td_ycbcrpositioning;
Packit 7838c8
			break;
Packit 7838c8
		case TIFFTAG_YCBCRSUBSAMPLING:
Packit 7838c8
			*va_arg(ap, uint16*) = td->td_ycbcrsubsampling[0];
Packit 7838c8
			*va_arg(ap, uint16*) = td->td_ycbcrsubsampling[1];
Packit 7838c8
			break;
Packit 7838c8
		case TIFFTAG_TRANSFERFUNCTION:
Packit 7838c8
			*va_arg(ap, uint16**) = td->td_transferfunction[0];
Packit 7838c8
			if (td->td_samplesperpixel - td->td_extrasamples > 1) {
Packit 7838c8
				*va_arg(ap, uint16**) = td->td_transferfunction[1];
Packit 7838c8
				*va_arg(ap, uint16**) = td->td_transferfunction[2];
Packit 7838c8
			}
Packit 7838c8
			break;
Packit 7838c8
		case TIFFTAG_REFERENCEBLACKWHITE:
Packit 7838c8
			*va_arg(ap, float**) = td->td_refblackwhite;
Packit 7838c8
			break;
Packit 7838c8
		case TIFFTAG_INKNAMES:
Packit 7838c8
			*va_arg(ap, char**) = td->td_inknames;
Packit 7838c8
			break;
Packit 7838c8
		default:
Packit 7838c8
			{
Packit 7838c8
				int i;
Packit 7838c8
Packit 7838c8
				/*
Packit 7838c8
				 * This can happen if multiple images are open
Packit 7838c8
				 * with different codecs which have private
Packit 7838c8
				 * tags.  The global tag information table may
Packit 7838c8
				 * then have tags that are valid for one file
Packit 7838c8
				 * but not the other. If the client tries to
Packit 7838c8
				 * get a tag that is not valid for the image's
Packit 7838c8
				 * codec then we'll arrive here.
Packit 7838c8
				 */
Packit 7838c8
				if( fip->field_bit != FIELD_CUSTOM )
Packit 7838c8
				{
Packit 7838c8
					TIFFErrorExt(tif->tif_clientdata, "_TIFFVGetField",
Packit 7838c8
					    "%s: Invalid %stag \"%s\" "
Packit 7838c8
					    "(not supported by codec)",
Packit 7838c8
					    tif->tif_name,
Packit 7838c8
					    isPseudoTag(tag) ? "pseudo-" : "",
Packit 7838c8
					    fip->field_name);
Packit 7838c8
					ret_val = 0;
Packit 7838c8
					break;
Packit 7838c8
				}
Packit 7838c8
Packit 7838c8
				/*
Packit 7838c8
				 * Do we have a custom value?
Packit 7838c8
				 */
Packit 7838c8
				ret_val = 0;
Packit 7838c8
				for (i = 0; i < td->td_customValueCount; i++) {
Packit 7838c8
					TIFFTagValue *tv = td->td_customValues + i;
Packit 7838c8
Packit 7838c8
					if (tv->info->field_tag != tag)
Packit 7838c8
						continue;
Packit 7838c8
Packit 7838c8
					if (fip->field_passcount) {
Packit 7838c8
						if (fip->field_readcount == TIFF_VARIABLE2)
Packit 7838c8
							*va_arg(ap, uint32*) = (uint32)tv->count;
Packit 7838c8
						else  /* Assume TIFF_VARIABLE */
Packit 7838c8
							*va_arg(ap, uint16*) = (uint16)tv->count;
Packit 7838c8
						*va_arg(ap, void **) = tv->value;
Packit 7838c8
						ret_val = 1;
Packit 7838c8
					} else if (fip->field_tag == TIFFTAG_DOTRANGE
Packit 7838c8
						   && strcmp(fip->field_name,"DotRange") == 0) {
Packit 7838c8
						/* TODO: This is an evil exception and should not have been
Packit 7838c8
						   handled this way ... likely best if we move it into
Packit 7838c8
						   the directory structure with an explicit field in 
Packit 7838c8
						   libtiff 4.1 and assign it a FIELD_ value */
Packit 7838c8
						*va_arg(ap, uint16*) = ((uint16 *)tv->value)[0];
Packit 7838c8
						*va_arg(ap, uint16*) = ((uint16 *)tv->value)[1];
Packit 7838c8
						ret_val = 1;
Packit 7838c8
					} else {
Packit 7838c8
						if (fip->field_type == TIFF_ASCII
Packit 7838c8
						    || fip->field_readcount == TIFF_VARIABLE
Packit 7838c8
						    || fip->field_readcount == TIFF_VARIABLE2
Packit 7838c8
						    || fip->field_readcount == TIFF_SPP
Packit 7838c8
						    || tv->count > 1) {
Packit 7838c8
							*va_arg(ap, void **) = tv->value;
Packit 7838c8
							ret_val = 1;
Packit 7838c8
						} else {
Packit 7838c8
							char *val = (char *)tv->value;
Packit 7838c8
							assert( tv->count == 1 );
Packit 7838c8
							switch (fip->field_type) {
Packit 7838c8
							case TIFF_BYTE:
Packit 7838c8
							case TIFF_UNDEFINED:
Packit 7838c8
								*va_arg(ap, uint8*) =
Packit 7838c8
									*(uint8 *)val;
Packit 7838c8
								ret_val = 1;
Packit 7838c8
								break;
Packit 7838c8
							case TIFF_SBYTE:
Packit 7838c8
								*va_arg(ap, int8*) =
Packit 7838c8
									*(int8 *)val;
Packit 7838c8
								ret_val = 1;
Packit 7838c8
								break;
Packit 7838c8
							case TIFF_SHORT:
Packit 7838c8
								*va_arg(ap, uint16*) =
Packit 7838c8
									*(uint16 *)val;
Packit 7838c8
								ret_val = 1;
Packit 7838c8
								break;
Packit 7838c8
							case TIFF_SSHORT:
Packit 7838c8
								*va_arg(ap, int16*) =
Packit 7838c8
									*(int16 *)val;
Packit 7838c8
								ret_val = 1;
Packit 7838c8
								break;
Packit 7838c8
							case TIFF_LONG:
Packit 7838c8
							case TIFF_IFD:
Packit 7838c8
								*va_arg(ap, uint32*) =
Packit 7838c8
									*(uint32 *)val;
Packit 7838c8
								ret_val = 1;
Packit 7838c8
								break;
Packit 7838c8
							case TIFF_SLONG:
Packit 7838c8
								*va_arg(ap, int32*) =
Packit 7838c8
									*(int32 *)val;
Packit 7838c8
								ret_val = 1;
Packit 7838c8
								break;
Packit 7838c8
							case TIFF_LONG8:
Packit 7838c8
							case TIFF_IFD8:
Packit 7838c8
								*va_arg(ap, uint64*) =
Packit 7838c8
									*(uint64 *)val;
Packit 7838c8
								ret_val = 1;
Packit 7838c8
								break;
Packit 7838c8
							case TIFF_SLONG8:
Packit 7838c8
								*va_arg(ap, int64*) =
Packit 7838c8
									*(int64 *)val;
Packit 7838c8
								ret_val = 1;
Packit 7838c8
								break;
Packit 7838c8
							case TIFF_RATIONAL:
Packit 7838c8
							case TIFF_SRATIONAL:
Packit 7838c8
							case TIFF_FLOAT:
Packit 7838c8
								*va_arg(ap, float*) =
Packit 7838c8
									*(float *)val;
Packit 7838c8
								ret_val = 1;
Packit 7838c8
								break;
Packit 7838c8
							case TIFF_DOUBLE:
Packit 7838c8
								*va_arg(ap, double*) =
Packit 7838c8
									*(double *)val;
Packit 7838c8
								ret_val = 1;
Packit 7838c8
								break;
Packit 7838c8
							default:
Packit 7838c8
								ret_val = 0;
Packit 7838c8
								break;
Packit 7838c8
							}
Packit 7838c8
						}
Packit 7838c8
					}
Packit 7838c8
					break;
Packit 7838c8
				}
Packit 7838c8
			}
Packit 7838c8
	}
Packit 7838c8
	return(ret_val);
Packit 7838c8
}
Packit 7838c8
Packit 7838c8
/*
Packit 7838c8
 * Return the value of a field in the
Packit 7838c8
 * internal directory structure.
Packit 7838c8
 */
Packit 7838c8
int
Packit 7838c8
TIFFGetField(TIFF* tif, uint32 tag, ...)
Packit 7838c8
{
Packit 7838c8
	int status;
Packit 7838c8
	va_list ap;
Packit 7838c8
Packit 7838c8
	va_start(ap, tag);
Packit 7838c8
	status = TIFFVGetField(tif, tag, ap);
Packit 7838c8
	va_end(ap);
Packit 7838c8
	return (status);
Packit 7838c8
}
Packit 7838c8
Packit 7838c8
/*
Packit 7838c8
 * Like TIFFGetField, but taking a varargs
Packit 7838c8
 * parameter list.  This routine is useful
Packit 7838c8
 * for building higher-level interfaces on
Packit 7838c8
 * top of the library.
Packit 7838c8
 */
Packit 7838c8
int
Packit 7838c8
TIFFVGetField(TIFF* tif, uint32 tag, va_list ap)
Packit 7838c8
{
Packit 7838c8
	const TIFFField* fip = TIFFFindField(tif, tag, TIFF_ANY);
Packit 7838c8
	return (fip && (isPseudoTag(tag) || TIFFFieldSet(tif, fip->field_bit)) ?
Packit 7838c8
	    (*tif->tif_tagmethods.vgetfield)(tif, tag, ap) : 0);
Packit 7838c8
}
Packit 7838c8
Packit 7838c8
#define	CleanupField(member) {		\
Packit 7838c8
    if (td->member) {			\
Packit 7838c8
	_TIFFfree(td->member);		\
Packit 7838c8
	td->member = 0;			\
Packit 7838c8
    }					\
Packit 7838c8
}
Packit 7838c8
Packit 7838c8
/*
Packit 7838c8
 * Release storage associated with a directory.
Packit 7838c8
 */
Packit 7838c8
void
Packit 7838c8
TIFFFreeDirectory(TIFF* tif)
Packit 7838c8
{
Packit 7838c8
	TIFFDirectory *td = &tif->tif_dir;
Packit 7838c8
	int            i;
Packit 7838c8
Packit 7838c8
	_TIFFmemset(td->td_fieldsset, 0, FIELD_SETLONGS);
Packit 7838c8
	CleanupField(td_sminsamplevalue);
Packit 7838c8
	CleanupField(td_smaxsamplevalue);
Packit 7838c8
	CleanupField(td_colormap[0]);
Packit 7838c8
	CleanupField(td_colormap[1]);
Packit 7838c8
	CleanupField(td_colormap[2]);
Packit 7838c8
	CleanupField(td_sampleinfo);
Packit 7838c8
	CleanupField(td_subifd);
Packit 7838c8
	CleanupField(td_inknames);
Packit 7838c8
	CleanupField(td_refblackwhite);
Packit 7838c8
	CleanupField(td_transferfunction[0]);
Packit 7838c8
	CleanupField(td_transferfunction[1]);
Packit 7838c8
	CleanupField(td_transferfunction[2]);
Packit 7838c8
	CleanupField(td_stripoffset);
Packit 7838c8
	CleanupField(td_stripbytecount);
Packit 7838c8
	TIFFClrFieldBit(tif, FIELD_YCBCRSUBSAMPLING);
Packit 7838c8
	TIFFClrFieldBit(tif, FIELD_YCBCRPOSITIONING);
Packit 7838c8
Packit 7838c8
	/* Cleanup custom tag values */
Packit 7838c8
	for( i = 0; i < td->td_customValueCount; i++ ) {
Packit 7838c8
		if (td->td_customValues[i].value)
Packit 7838c8
			_TIFFfree(td->td_customValues[i].value);
Packit 7838c8
	}
Packit 7838c8
Packit 7838c8
	td->td_customValueCount = 0;
Packit 7838c8
	CleanupField(td_customValues);
Packit 7838c8
Packit 7838c8
#if defined(DEFER_STRILE_LOAD)
Packit 7838c8
        _TIFFmemset( &(td->td_stripoffset_entry), 0, sizeof(TIFFDirEntry));
Packit 7838c8
        _TIFFmemset( &(td->td_stripbytecount_entry), 0, sizeof(TIFFDirEntry));
Packit 7838c8
#endif        
Packit 7838c8
}
Packit 7838c8
#undef CleanupField
Packit 7838c8
Packit 7838c8
/*
Packit 7838c8
 * Client Tag extension support (from Niles Ritter).
Packit 7838c8
 */
Packit 7838c8
static TIFFExtendProc _TIFFextender = (TIFFExtendProc) NULL;
Packit 7838c8
Packit 7838c8
TIFFExtendProc
Packit 7838c8
TIFFSetTagExtender(TIFFExtendProc extender)
Packit 7838c8
{
Packit 7838c8
	TIFFExtendProc prev = _TIFFextender;
Packit 7838c8
	_TIFFextender = extender;
Packit 7838c8
	return (prev);
Packit 7838c8
}
Packit 7838c8
Packit 7838c8
/*
Packit 7838c8
 * Setup for a new directory.  Should we automatically call
Packit 7838c8
 * TIFFWriteDirectory() if the current one is dirty?
Packit 7838c8
 *
Packit 7838c8
 * The newly created directory will not exist on the file till
Packit 7838c8
 * TIFFWriteDirectory(), TIFFFlush() or TIFFClose() is called.
Packit 7838c8
 */
Packit 7838c8
int
Packit 7838c8
TIFFCreateDirectory(TIFF* tif)
Packit 7838c8
{
Packit 7838c8
	TIFFDefaultDirectory(tif);
Packit 7838c8
	tif->tif_diroff = 0;
Packit 7838c8
	tif->tif_nextdiroff = 0;
Packit 7838c8
	tif->tif_curoff = 0;
Packit 7838c8
	tif->tif_row = (uint32) -1;
Packit 7838c8
	tif->tif_curstrip = (uint32) -1;
Packit 7838c8
Packit 7838c8
	return 0;
Packit 7838c8
}
Packit 7838c8
Packit 7838c8
int
Packit 7838c8
TIFFCreateCustomDirectory(TIFF* tif, const TIFFFieldArray* infoarray)
Packit 7838c8
{
Packit 7838c8
	TIFFDefaultDirectory(tif);
Packit 7838c8
Packit 7838c8
	/*
Packit 7838c8
	 * Reset the field definitions to match the application provided list. 
Packit 7838c8
	 * Hopefully TIFFDefaultDirectory() won't have done anything irreversable
Packit 7838c8
	 * based on it's assumption this is an image directory.
Packit 7838c8
	 */
Packit 7838c8
	_TIFFSetupFields(tif, infoarray);
Packit 7838c8
Packit 7838c8
	tif->tif_diroff = 0;
Packit 7838c8
	tif->tif_nextdiroff = 0;
Packit 7838c8
	tif->tif_curoff = 0;
Packit 7838c8
	tif->tif_row = (uint32) -1;
Packit 7838c8
	tif->tif_curstrip = (uint32) -1;
Packit 7838c8
Packit 7838c8
	return 0;
Packit 7838c8
}
Packit 7838c8
Packit 7838c8
int
Packit 7838c8
TIFFCreateEXIFDirectory(TIFF* tif)
Packit 7838c8
{
Packit 7838c8
	const TIFFFieldArray* exifFieldArray;
Packit 7838c8
	exifFieldArray = _TIFFGetExifFields();
Packit 7838c8
	return TIFFCreateCustomDirectory(tif, exifFieldArray);
Packit 7838c8
}
Packit 7838c8
Packit 7838c8
/*
Packit 7838c8
 * Setup a default directory structure.
Packit 7838c8
 */
Packit 7838c8
int
Packit 7838c8
TIFFDefaultDirectory(TIFF* tif)
Packit 7838c8
{
Packit 7838c8
	register TIFFDirectory* td = &tif->tif_dir;
Packit 7838c8
	const TIFFFieldArray* tiffFieldArray;
Packit 7838c8
Packit 7838c8
	tiffFieldArray = _TIFFGetFields();
Packit 7838c8
	_TIFFSetupFields(tif, tiffFieldArray);   
Packit 7838c8
Packit 7838c8
	_TIFFmemset(td, 0, sizeof (*td));
Packit 7838c8
	td->td_fillorder = FILLORDER_MSB2LSB;
Packit 7838c8
	td->td_bitspersample = 1;
Packit 7838c8
	td->td_threshholding = THRESHHOLD_BILEVEL;
Packit 7838c8
	td->td_orientation = ORIENTATION_TOPLEFT;
Packit 7838c8
	td->td_samplesperpixel = 1;
Packit 7838c8
	td->td_rowsperstrip = (uint32) -1;
Packit 7838c8
	td->td_tilewidth = 0;
Packit 7838c8
	td->td_tilelength = 0;
Packit 7838c8
	td->td_tiledepth = 1;
Packit 7838c8
	td->td_stripbytecountsorted = 1; /* Our own arrays always sorted. */  
Packit 7838c8
	td->td_resolutionunit = RESUNIT_INCH;
Packit 7838c8
	td->td_sampleformat = SAMPLEFORMAT_UINT;
Packit 7838c8
	td->td_imagedepth = 1;
Packit 7838c8
	td->td_ycbcrsubsampling[0] = 2;
Packit 7838c8
	td->td_ycbcrsubsampling[1] = 2;
Packit 7838c8
	td->td_ycbcrpositioning = YCBCRPOSITION_CENTERED;
Packit 7838c8
	tif->tif_postdecode = _TIFFNoPostDecode;  
Packit 7838c8
	tif->tif_foundfield = NULL;
Packit 7838c8
	tif->tif_tagmethods.vsetfield = _TIFFVSetField;  
Packit 7838c8
	tif->tif_tagmethods.vgetfield = _TIFFVGetField;
Packit 7838c8
	tif->tif_tagmethods.printdir = NULL;
Packit 7838c8
	/*
Packit 7838c8
	 *  Give client code a chance to install their own
Packit 7838c8
	 *  tag extensions & methods, prior to compression overloads,
Packit 7838c8
	 *  but do some prior cleanup first. (http://trac.osgeo.org/gdal/ticket/5054)
Packit 7838c8
	 */
Packit 7838c8
	if (tif->tif_nfieldscompat > 0) {
Packit 7838c8
		uint32 i;
Packit 7838c8
Packit 7838c8
		for (i = 0; i < tif->tif_nfieldscompat; i++) {
Packit 7838c8
				if (tif->tif_fieldscompat[i].allocated_size)
Packit 7838c8
						_TIFFfree(tif->tif_fieldscompat[i].fields);
Packit 7838c8
		}
Packit 7838c8
		_TIFFfree(tif->tif_fieldscompat);
Packit 7838c8
		tif->tif_nfieldscompat = 0;
Packit 7838c8
		tif->tif_fieldscompat = NULL;
Packit 7838c8
	}
Packit 7838c8
	if (_TIFFextender)
Packit 7838c8
		(*_TIFFextender)(tif);
Packit 7838c8
	(void) TIFFSetField(tif, TIFFTAG_COMPRESSION, COMPRESSION_NONE);
Packit 7838c8
	/*
Packit 7838c8
	 * NB: The directory is marked dirty as a result of setting
Packit 7838c8
	 * up the default compression scheme.  However, this really
Packit 7838c8
	 * isn't correct -- we want TIFF_DIRTYDIRECT to be set only
Packit 7838c8
	 * if the user does something.  We could just do the setup
Packit 7838c8
	 * by hand, but it seems better to use the normal mechanism
Packit 7838c8
	 * (i.e. TIFFSetField).
Packit 7838c8
	 */
Packit 7838c8
	tif->tif_flags &= ~TIFF_DIRTYDIRECT;
Packit 7838c8
Packit 7838c8
	/*
Packit 7838c8
	 * As per http://bugzilla.remotesensing.org/show_bug.cgi?id=19
Packit 7838c8
	 * we clear the ISTILED flag when setting up a new directory.
Packit 7838c8
	 * Should we also be clearing stuff like INSUBIFD?
Packit 7838c8
	 */
Packit 7838c8
	tif->tif_flags &= ~TIFF_ISTILED;
Packit 7838c8
Packit 7838c8
	return (1);
Packit 7838c8
}
Packit 7838c8
Packit 7838c8
static int
Packit 7838c8
TIFFAdvanceDirectory(TIFF* tif, uint64* nextdir, uint64* off)
Packit 7838c8
{
Packit 7838c8
	static const char module[] = "TIFFAdvanceDirectory";
Packit 7838c8
	if (isMapped(tif))
Packit 7838c8
	{
Packit 7838c8
		uint64 poff=*nextdir;
Packit 7838c8
		if (!(tif->tif_flags&TIFF_BIGTIFF))
Packit 7838c8
		{
Packit 7838c8
			tmsize_t poffa,poffb,poffc,poffd;
Packit 7838c8
			uint16 dircount;
Packit 7838c8
			uint32 nextdir32;
Packit 7838c8
			poffa=(tmsize_t)poff;
Packit 7838c8
			poffb=poffa+sizeof(uint16);
Packit 7838c8
			if (((uint64)poffa!=poff)||(poffb<poffa)||(poffb<(tmsize_t)sizeof(uint16))||(poffb>tif->tif_size))
Packit 7838c8
			{
Packit 7838c8
				TIFFErrorExt(tif->tif_clientdata,module,"Error fetching directory count");
Packit 7838c8
                                  *nextdir=0;
Packit 7838c8
				return(0);
Packit 7838c8
			}
Packit 7838c8
			_TIFFmemcpy(&dircount,tif->tif_base+poffa,sizeof(uint16));
Packit 7838c8
			if (tif->tif_flags&TIFF_SWAB)
Packit 7838c8
				TIFFSwabShort(&dircount);
Packit 7838c8
			poffc=poffb+dircount*12;
Packit 7838c8
			poffd=poffc+sizeof(uint32);
Packit 7838c8
			if ((poffc<poffb)||(poffc<dircount*12)||(poffd<poffc)||(poffd<(tmsize_t)sizeof(uint32))||(poffd>tif->tif_size))
Packit 7838c8
			{
Packit 7838c8
				TIFFErrorExt(tif->tif_clientdata,module,"Error fetching directory link");
Packit 7838c8
				return(0);
Packit 7838c8
			}
Packit 7838c8
			if (off!=NULL)
Packit 7838c8
				*off=(uint64)poffc;
Packit 7838c8
			_TIFFmemcpy(&nextdir32,tif->tif_base+poffc,sizeof(uint32));
Packit 7838c8
			if (tif->tif_flags&TIFF_SWAB)
Packit 7838c8
				TIFFSwabLong(&nextdir32);
Packit 7838c8
			*nextdir=nextdir32;
Packit 7838c8
		}
Packit 7838c8
		else
Packit 7838c8
		{
Packit 7838c8
			tmsize_t poffa,poffb,poffc,poffd;
Packit 7838c8
			uint64 dircount64;
Packit 7838c8
			uint16 dircount16;
Packit 7838c8
			poffa=(tmsize_t)poff;
Packit 7838c8
			poffb=poffa+sizeof(uint64);
Packit 7838c8
			if (((uint64)poffa!=poff)||(poffb<poffa)||(poffb<(tmsize_t)sizeof(uint64))||(poffb>tif->tif_size))
Packit 7838c8
			{
Packit 7838c8
				TIFFErrorExt(tif->tif_clientdata,module,"Error fetching directory count");
Packit 7838c8
				return(0);
Packit 7838c8
			}
Packit 7838c8
			_TIFFmemcpy(&dircount64,tif->tif_base+poffa,sizeof(uint64));
Packit 7838c8
			if (tif->tif_flags&TIFF_SWAB)
Packit 7838c8
				TIFFSwabLong8(&dircount64);
Packit 7838c8
			if (dircount64>0xFFFF)
Packit 7838c8
			{
Packit 7838c8
				TIFFErrorExt(tif->tif_clientdata,module,"Sanity check on directory count failed");
Packit 7838c8
				return(0);
Packit 7838c8
			}
Packit 7838c8
			dircount16=(uint16)dircount64;
Packit 7838c8
			poffc=poffb+dircount16*20;
Packit 7838c8
			poffd=poffc+sizeof(uint64);
Packit 7838c8
			if ((poffc<poffb)||(poffc<dircount16*20)||(poffd<poffc)||(poffd<(tmsize_t)sizeof(uint64))||(poffd>tif->tif_size))
Packit 7838c8
			{
Packit 7838c8
				TIFFErrorExt(tif->tif_clientdata,module,"Error fetching directory link");
Packit 7838c8
				return(0);
Packit 7838c8
			}
Packit 7838c8
			if (off!=NULL)
Packit 7838c8
				*off=(uint64)poffc;
Packit 7838c8
			_TIFFmemcpy(nextdir,tif->tif_base+poffc,sizeof(uint64));
Packit 7838c8
			if (tif->tif_flags&TIFF_SWAB)
Packit 7838c8
				TIFFSwabLong8(nextdir);
Packit 7838c8
		}
Packit 7838c8
		return(1);
Packit 7838c8
	}
Packit 7838c8
	else
Packit 7838c8
	{
Packit 7838c8
		if (!(tif->tif_flags&TIFF_BIGTIFF))
Packit 7838c8
		{
Packit 7838c8
			uint16 dircount;
Packit 7838c8
			uint32 nextdir32;
Packit 7838c8
			if (!SeekOK(tif, *nextdir) ||
Packit 7838c8
			    !ReadOK(tif, &dircount, sizeof (uint16))) {
Packit 7838c8
				TIFFErrorExt(tif->tif_clientdata, module, "%s: Error fetching directory count",
Packit 7838c8
				    tif->tif_name);
Packit 7838c8
				return (0);
Packit 7838c8
			}
Packit 7838c8
			if (tif->tif_flags & TIFF_SWAB)
Packit 7838c8
				TIFFSwabShort(&dircount);
Packit 7838c8
			if (off != NULL)
Packit 7838c8
				*off = TIFFSeekFile(tif,
Packit 7838c8
				    dircount*12, SEEK_CUR);
Packit 7838c8
			else
Packit 7838c8
				(void) TIFFSeekFile(tif,
Packit 7838c8
				    dircount*12, SEEK_CUR);
Packit 7838c8
			if (!ReadOK(tif, &nextdir32, sizeof (uint32))) {
Packit 7838c8
				TIFFErrorExt(tif->tif_clientdata, module, "%s: Error fetching directory link",
Packit 7838c8
				    tif->tif_name);
Packit 7838c8
				return (0);
Packit 7838c8
			}
Packit 7838c8
			if (tif->tif_flags & TIFF_SWAB)
Packit 7838c8
				TIFFSwabLong(&nextdir32);
Packit 7838c8
			*nextdir=nextdir32;
Packit 7838c8
		}
Packit 7838c8
		else
Packit 7838c8
		{
Packit 7838c8
			uint64 dircount64;
Packit 7838c8
			uint16 dircount16;
Packit 7838c8
			if (!SeekOK(tif, *nextdir) ||
Packit 7838c8
			    !ReadOK(tif, &dircount64, sizeof (uint64))) {
Packit 7838c8
				TIFFErrorExt(tif->tif_clientdata, module, "%s: Error fetching directory count",
Packit 7838c8
				    tif->tif_name);
Packit 7838c8
				return (0);
Packit 7838c8
			}
Packit 7838c8
			if (tif->tif_flags & TIFF_SWAB)
Packit 7838c8
				TIFFSwabLong8(&dircount64);
Packit 7838c8
			if (dircount64>0xFFFF)
Packit 7838c8
			{
Packit 7838c8
				TIFFErrorExt(tif->tif_clientdata, module, "Error fetching directory count");
Packit 7838c8
				return(0);
Packit 7838c8
			}
Packit 7838c8
			dircount16 = (uint16)dircount64;
Packit 7838c8
			if (off != NULL)
Packit 7838c8
				*off = TIFFSeekFile(tif,
Packit 7838c8
				    dircount16*20, SEEK_CUR);
Packit 7838c8
			else
Packit 7838c8
				(void) TIFFSeekFile(tif,
Packit 7838c8
				    dircount16*20, SEEK_CUR);
Packit 7838c8
			if (!ReadOK(tif, nextdir, sizeof (uint64))) {
Packit 7838c8
				TIFFErrorExt(tif->tif_clientdata, module,
Packit 7838c8
                                             "%s: Error fetching directory link",
Packit 7838c8
				    tif->tif_name);
Packit 7838c8
				return (0);
Packit 7838c8
			}
Packit 7838c8
			if (tif->tif_flags & TIFF_SWAB)
Packit 7838c8
				TIFFSwabLong8(nextdir);
Packit 7838c8
		}
Packit 7838c8
		return (1);
Packit 7838c8
	}
Packit 7838c8
}
Packit 7838c8
Packit 7838c8
/*
Packit 7838c8
 * Count the number of directories in a file.
Packit 7838c8
 */
Packit 7838c8
uint16
Packit 7838c8
TIFFNumberOfDirectories(TIFF* tif)
Packit 7838c8
{
Packit 7838c8
	static const char module[] = "TIFFNumberOfDirectories";
Packit 7838c8
	uint64 nextdir;
Packit 7838c8
	uint16 n;
Packit 7838c8
	if (!(tif->tif_flags&TIFF_BIGTIFF))
Packit 7838c8
		nextdir = tif->tif_header.classic.tiff_diroff;
Packit 7838c8
	else
Packit 7838c8
		nextdir = tif->tif_header.big.tiff_diroff;
Packit 7838c8
	n = 0;
Packit 7838c8
	while (nextdir != 0 && TIFFAdvanceDirectory(tif, &nextdir, NULL))
Packit 7838c8
        {
Packit 7838c8
                if (n != 65535) {
Packit 7838c8
                        ++n;
Packit 7838c8
                }
Packit 7838c8
		else
Packit 7838c8
                {
Packit 7838c8
                        TIFFErrorExt(tif->tif_clientdata, module,
Packit 7838c8
                                     "Directory count exceeded 65535 limit,"
Packit 7838c8
                                     " giving up on counting.");
Packit 7838c8
                        return (65535);
Packit 7838c8
                }
Packit 7838c8
        }
Packit 7838c8
	return (n);
Packit 7838c8
}
Packit 7838c8
Packit 7838c8
/*
Packit 7838c8
 * Set the n-th directory as the current directory.
Packit 7838c8
 * NB: Directories are numbered starting at 0.
Packit 7838c8
 */
Packit 7838c8
int
Packit 7838c8
TIFFSetDirectory(TIFF* tif, uint16 dirn)
Packit 7838c8
{
Packit 7838c8
	uint64 nextdir;
Packit 7838c8
	uint16 n;
Packit 7838c8
Packit 7838c8
	if (!(tif->tif_flags&TIFF_BIGTIFF))
Packit 7838c8
		nextdir = tif->tif_header.classic.tiff_diroff;
Packit 7838c8
	else
Packit 7838c8
		nextdir = tif->tif_header.big.tiff_diroff;
Packit 7838c8
	for (n = dirn; n > 0 && nextdir != 0; n--)
Packit 7838c8
		if (!TIFFAdvanceDirectory(tif, &nextdir, NULL))
Packit 7838c8
			return (0);
Packit 7838c8
	tif->tif_nextdiroff = nextdir;
Packit 7838c8
	/*
Packit 7838c8
	 * Set curdir to the actual directory index.  The
Packit 7838c8
	 * -1 is because TIFFReadDirectory will increment
Packit 7838c8
	 * tif_curdir after successfully reading the directory.
Packit 7838c8
	 */
Packit 7838c8
	tif->tif_curdir = (dirn - n) - 1;
Packit 7838c8
	/*
Packit 7838c8
	 * Reset tif_dirnumber counter and start new list of seen directories.
Packit 7838c8
	 * We need this to prevent IFD loops.
Packit 7838c8
	 */
Packit 7838c8
	tif->tif_dirnumber = 0;
Packit 7838c8
	return (TIFFReadDirectory(tif));
Packit 7838c8
}
Packit 7838c8
Packit 7838c8
/*
Packit 7838c8
 * Set the current directory to be the directory
Packit 7838c8
 * located at the specified file offset.  This interface
Packit 7838c8
 * is used mainly to access directories linked with
Packit 7838c8
 * the SubIFD tag (e.g. thumbnail images).
Packit 7838c8
 */
Packit 7838c8
int
Packit 7838c8
TIFFSetSubDirectory(TIFF* tif, uint64 diroff)
Packit 7838c8
{
Packit 7838c8
	tif->tif_nextdiroff = diroff;
Packit 7838c8
	/*
Packit 7838c8
	 * Reset tif_dirnumber counter and start new list of seen directories.
Packit 7838c8
	 * We need this to prevent IFD loops.
Packit 7838c8
	 */
Packit 7838c8
	tif->tif_dirnumber = 0;
Packit 7838c8
	return (TIFFReadDirectory(tif));
Packit 7838c8
}
Packit 7838c8
Packit 7838c8
/*
Packit 7838c8
 * Return file offset of the current directory.
Packit 7838c8
 */
Packit 7838c8
uint64
Packit 7838c8
TIFFCurrentDirOffset(TIFF* tif)
Packit 7838c8
{
Packit 7838c8
	return (tif->tif_diroff);
Packit 7838c8
}
Packit 7838c8
Packit 7838c8
/*
Packit 7838c8
 * Return an indication of whether or not we are
Packit 7838c8
 * at the last directory in the file.
Packit 7838c8
 */
Packit 7838c8
int
Packit 7838c8
TIFFLastDirectory(TIFF* tif)
Packit 7838c8
{
Packit 7838c8
	return (tif->tif_nextdiroff == 0);
Packit 7838c8
}
Packit 7838c8
Packit 7838c8
/*
Packit 7838c8
 * Unlink the specified directory from the directory chain.
Packit 7838c8
 */
Packit 7838c8
int
Packit 7838c8
TIFFUnlinkDirectory(TIFF* tif, uint16 dirn)
Packit 7838c8
{
Packit 7838c8
	static const char module[] = "TIFFUnlinkDirectory";
Packit 7838c8
	uint64 nextdir;
Packit 7838c8
	uint64 off;
Packit 7838c8
	uint16 n;
Packit 7838c8
Packit 7838c8
	if (tif->tif_mode == O_RDONLY) {
Packit 7838c8
		TIFFErrorExt(tif->tif_clientdata, module,
Packit 7838c8
                             "Can not unlink directory in read-only file");
Packit 7838c8
		return (0);
Packit 7838c8
	}
Packit 7838c8
	/*
Packit 7838c8
	 * Go to the directory before the one we want
Packit 7838c8
	 * to unlink and nab the offset of the link
Packit 7838c8
	 * field we'll need to patch.
Packit 7838c8
	 */
Packit 7838c8
	if (!(tif->tif_flags&TIFF_BIGTIFF))
Packit 7838c8
	{
Packit 7838c8
		nextdir = tif->tif_header.classic.tiff_diroff;
Packit 7838c8
		off = 4;
Packit 7838c8
	}
Packit 7838c8
	else
Packit 7838c8
	{
Packit 7838c8
		nextdir = tif->tif_header.big.tiff_diroff;
Packit 7838c8
		off = 8;
Packit 7838c8
	}
Packit 7838c8
	for (n = dirn-1; n > 0; n--) {
Packit 7838c8
		if (nextdir == 0) {
Packit 7838c8
			TIFFErrorExt(tif->tif_clientdata, module, "Directory %d does not exist", dirn);
Packit 7838c8
			return (0);
Packit 7838c8
		}
Packit 7838c8
		if (!TIFFAdvanceDirectory(tif, &nextdir, &off))
Packit 7838c8
			return (0);
Packit 7838c8
	}
Packit 7838c8
	/*
Packit 7838c8
	 * Advance to the directory to be unlinked and fetch
Packit 7838c8
	 * the offset of the directory that follows.
Packit 7838c8
	 */
Packit 7838c8
	if (!TIFFAdvanceDirectory(tif, &nextdir, NULL))
Packit 7838c8
		return (0);
Packit 7838c8
	/*
Packit 7838c8
	 * Go back and patch the link field of the preceding
Packit 7838c8
	 * directory to point to the offset of the directory
Packit 7838c8
	 * that follows.
Packit 7838c8
	 */
Packit 7838c8
	(void) TIFFSeekFile(tif, off, SEEK_SET);
Packit 7838c8
	if (!(tif->tif_flags&TIFF_BIGTIFF))
Packit 7838c8
	{
Packit 7838c8
		uint32 nextdir32;
Packit 7838c8
		nextdir32=(uint32)nextdir;
Packit 7838c8
		assert((uint64)nextdir32==nextdir);
Packit 7838c8
		if (tif->tif_flags & TIFF_SWAB)
Packit 7838c8
			TIFFSwabLong(&nextdir32);
Packit 7838c8
		if (!WriteOK(tif, &nextdir32, sizeof (uint32))) {
Packit 7838c8
			TIFFErrorExt(tif->tif_clientdata, module, "Error writing directory link");
Packit 7838c8
			return (0);
Packit 7838c8
		}
Packit 7838c8
	}
Packit 7838c8
	else
Packit 7838c8
	{
Packit 7838c8
		if (tif->tif_flags & TIFF_SWAB)
Packit 7838c8
			TIFFSwabLong8(&nextdir);
Packit 7838c8
		if (!WriteOK(tif, &nextdir, sizeof (uint64))) {
Packit 7838c8
			TIFFErrorExt(tif->tif_clientdata, module, "Error writing directory link");
Packit 7838c8
			return (0);
Packit 7838c8
		}
Packit 7838c8
	}
Packit 7838c8
	/*
Packit 7838c8
	 * Leave directory state setup safely.  We don't have
Packit 7838c8
	 * facilities for doing inserting and removing directories,
Packit 7838c8
	 * so it's safest to just invalidate everything.  This
Packit 7838c8
	 * means that the caller can only append to the directory
Packit 7838c8
	 * chain.
Packit 7838c8
	 */
Packit 7838c8
	(*tif->tif_cleanup)(tif);
Packit 7838c8
	if ((tif->tif_flags & TIFF_MYBUFFER) && tif->tif_rawdata) {
Packit 7838c8
		_TIFFfree(tif->tif_rawdata);
Packit 7838c8
		tif->tif_rawdata = NULL;
Packit 7838c8
		tif->tif_rawcc = 0;
Packit 7838c8
                tif->tif_rawdataoff = 0;
Packit 7838c8
                tif->tif_rawdataloaded = 0;
Packit 7838c8
	}
Packit 7838c8
	tif->tif_flags &= ~(TIFF_BEENWRITING|TIFF_BUFFERSETUP|TIFF_POSTENCODE|TIFF_BUF4WRITE);
Packit 7838c8
	TIFFFreeDirectory(tif);
Packit 7838c8
	TIFFDefaultDirectory(tif);
Packit 7838c8
	tif->tif_diroff = 0;			/* force link on next write */
Packit 7838c8
	tif->tif_nextdiroff = 0;		/* next write must be at end */
Packit 7838c8
	tif->tif_curoff = 0;
Packit 7838c8
	tif->tif_row = (uint32) -1;
Packit 7838c8
	tif->tif_curstrip = (uint32) -1;
Packit 7838c8
	return (1);
Packit 7838c8
}
Packit 7838c8
Packit 7838c8
/* vim: set ts=8 sts=8 sw=8 noet: */
Packit 7838c8
/*
Packit 7838c8
 * Local Variables:
Packit 7838c8
 * mode: c
Packit 7838c8
 * c-basic-offset: 8
Packit 7838c8
 * fill-column: 78
Packit 7838c8
 * End:
Packit 7838c8
 */