PageRenderTime 143ms CodeModel.GetById 48ms app.highlight 85ms RepoModel.GetById 1ms app.codeStats 1ms

/src/FreeImage/Source/LibTIFF/tif_dir.c

https://bitbucket.org/cabalistic/ogredeps/
C | 1391 lines | 1071 code | 72 blank | 248 comment | 229 complexity | f20bb1ca16c4e8967aada22a5abf6982 MD5 | raw file
   1/* $Id: tif_dir.c,v 1.38 2011/04/10 17:14:09 drolon Exp $ */
   2
   3/*
   4 * Copyright (c) 1988-1997 Sam Leffler
   5 * Copyright (c) 1991-1997 Silicon Graphics, Inc.
   6 *
   7 * Permission to use, copy, modify, distribute, and sell this software and 
   8 * its documentation for any purpose is hereby granted without fee, provided
   9 * that (i) the above copyright notices and this permission notice appear in
  10 * all copies of the software and related documentation, and (ii) the names of
  11 * Sam Leffler and Silicon Graphics may not be used in any advertising or
  12 * publicity relating to the software without the specific, prior written
  13 * permission of Sam Leffler and Silicon Graphics.
  14 * 
  15 * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, 
  16 * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY 
  17 * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.  
  18 * 
  19 * IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR
  20 * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND,
  21 * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
  22 * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF 
  23 * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE 
  24 * OF THIS SOFTWARE.
  25 */
  26
  27/*
  28 * TIFF Library.
  29 *
  30 * Directory Tag Get & Set Routines.
  31 * (and also some miscellaneous stuff)
  32 */
  33#include "tiffiop.h"
  34
  35/*
  36 * These are used in the backwards compatibility code...
  37 */
  38#define DATATYPE_VOID		0       /* !untyped data */
  39#define DATATYPE_INT		1       /* !signed integer data */
  40#define DATATYPE_UINT		2       /* !unsigned integer data */
  41#define DATATYPE_IEEEFP		3       /* !IEEE floating point data */
  42
  43static void
  44setByteArray(void** vpp, void* vp, size_t nmemb, size_t elem_size)
  45{
  46	if (*vpp)
  47		_TIFFfree(*vpp), *vpp = 0;
  48	if (vp) {
  49		tsize_t	bytes = nmemb * elem_size;
  50		if (elem_size && bytes / elem_size == nmemb)
  51			*vpp = (void*) _TIFFmalloc(bytes);
  52		if (*vpp)
  53			_TIFFmemcpy(*vpp, vp, bytes);
  54	}
  55}
  56void _TIFFsetByteArray(void** vpp, void* vp, uint32 n)
  57    { setByteArray(vpp, vp, n, 1); }
  58void _TIFFsetString(char** cpp, char* cp)
  59    { setByteArray((void**) cpp, (void*) cp, strlen(cp)+1, 1); }
  60void _TIFFsetNString(char** cpp, char* cp, uint32 n)
  61    { setByteArray((void**) cpp, (void*) cp, n, 1); }
  62void _TIFFsetShortArray(uint16** wpp, uint16* wp, uint32 n)
  63    { setByteArray((void**) wpp, (void*) wp, n, sizeof (uint16)); }
  64void _TIFFsetLongArray(uint32** lpp, uint32* lp, uint32 n)
  65    { setByteArray((void**) lpp, (void*) lp, n, sizeof (uint32)); }
  66void _TIFFsetFloatArray(float** fpp, float* fp, uint32 n)
  67    { setByteArray((void**) fpp, (void*) fp, n, sizeof (float)); }
  68void _TIFFsetDoubleArray(double** dpp, double* dp, uint32 n)
  69    { setByteArray((void**) dpp, (void*) dp, n, sizeof (double)); }
  70
  71/*
  72 * Install extra samples information.
  73 */
  74static int
  75setExtraSamples(TIFFDirectory* td, va_list ap, uint32* v)
  76{
  77/* XXX: Unassociated alpha data == 999 is a known Corel Draw bug, see below */
  78#define EXTRASAMPLE_COREL_UNASSALPHA 999 
  79
  80	uint16* va;
  81	uint32 i;
  82
  83	*v = va_arg(ap, uint32);
  84	if ((uint16) *v > td->td_samplesperpixel)
  85		return 0;
  86	va = va_arg(ap, uint16*);
  87	if (*v > 0 && va == NULL)		/* typically missing param */
  88		return 0;
  89	for (i = 0; i < *v; i++) {
  90		if (va[i] > EXTRASAMPLE_UNASSALPHA) {
  91			/*
  92			 * XXX: Corel Draw is known to produce incorrect
  93			 * ExtraSamples tags which must be patched here if we
  94			 * want to be able to open some of the damaged TIFF
  95			 * files: 
  96			 */
  97			if (va[i] == EXTRASAMPLE_COREL_UNASSALPHA)
  98				va[i] = EXTRASAMPLE_UNASSALPHA;
  99			else
 100				return 0;
 101		}
 102	}
 103	td->td_extrasamples = (uint16) *v;
 104	_TIFFsetShortArray(&td->td_sampleinfo, va, td->td_extrasamples);
 105	return 1;
 106
 107#undef EXTRASAMPLE_COREL_UNASSALPHA
 108}
 109
 110static uint32
 111checkInkNamesString(TIFF* tif, uint32 slen, const char* s)
 112{
 113	TIFFDirectory* td = &tif->tif_dir;
 114	uint16 i = td->td_samplesperpixel;
 115
 116	if (slen > 0) {
 117		const char* ep = s+slen;
 118		const char* cp = s;
 119		for (; i > 0; i--) {
 120			for (; *cp != '\0'; cp++)
 121				if (cp >= ep)
 122					goto bad;
 123			cp++;				/* skip \0 */
 124		}
 125		return (cp-s);
 126	}
 127bad:
 128	TIFFErrorExt(tif->tif_clientdata, "TIFFSetField",
 129	    "%s: Invalid InkNames value; expecting %d names, found %d",
 130	    tif->tif_name,
 131	    td->td_samplesperpixel,
 132	    td->td_samplesperpixel-i);
 133	return (0);
 134}
 135
 136static int
 137_TIFFVSetField(TIFF* tif, ttag_t tag, va_list ap)
 138{
 139	static const char module[] = "_TIFFVSetField";
 140
 141	TIFFDirectory* td = &tif->tif_dir;
 142	int status = 1;
 143	uint32 v32, i, v;
 144	char* s;
 145
 146	switch (tag) {
 147	case TIFFTAG_SUBFILETYPE:
 148		td->td_subfiletype = va_arg(ap, uint32);
 149		break;
 150	case TIFFTAG_IMAGEWIDTH:
 151		td->td_imagewidth = va_arg(ap, uint32);
 152		break;
 153	case TIFFTAG_IMAGELENGTH:
 154		td->td_imagelength = va_arg(ap, uint32);
 155		break;
 156	case TIFFTAG_BITSPERSAMPLE:
 157		td->td_bitspersample = (uint16) va_arg(ap, int);
 158		/*
 159		 * If the data require post-decoding processing to byte-swap
 160		 * samples, set it up here.  Note that since tags are required
 161		 * to be ordered, compression code can override this behaviour
 162		 * in the setup method if it wants to roll the post decoding
 163		 * work in with its normal work.
 164		 */
 165		if (tif->tif_flags & TIFF_SWAB) {
 166			if (td->td_bitspersample == 8)
 167				tif->tif_postdecode = _TIFFNoPostDecode;
 168			else if (td->td_bitspersample == 16)
 169				tif->tif_postdecode = _TIFFSwab16BitData;
 170			else if (td->td_bitspersample == 24)
 171				tif->tif_postdecode = _TIFFSwab24BitData;
 172			else if (td->td_bitspersample == 32)
 173				tif->tif_postdecode = _TIFFSwab32BitData;
 174			else if (td->td_bitspersample == 64)
 175				tif->tif_postdecode = _TIFFSwab64BitData;
 176			else if (td->td_bitspersample == 128) /* two 64's */
 177				tif->tif_postdecode = _TIFFSwab64BitData;
 178		}
 179		break;
 180	case TIFFTAG_COMPRESSION:
 181		v = va_arg(ap, uint32) & 0xffff;
 182		/*
 183		 * If we're changing the compression scheme, the notify the
 184		 * previous module so that it can cleanup any state it's
 185		 * setup.
 186		 */
 187		if (TIFFFieldSet(tif, FIELD_COMPRESSION)) {
 188			if (td->td_compression == v)
 189				break;
 190			(*tif->tif_cleanup)(tif);
 191			tif->tif_flags &= ~TIFF_CODERSETUP;
 192		}
 193		/*
 194		 * Setup new compression routine state.
 195		 */
 196		if( (status = TIFFSetCompressionScheme(tif, v)) != 0 )
 197                    td->td_compression = (uint16) v;
 198                else
 199                    status = 0;
 200		break;
 201	case TIFFTAG_PHOTOMETRIC:
 202		td->td_photometric = (uint16) va_arg(ap, int);
 203		break;
 204	case TIFFTAG_THRESHHOLDING:
 205		td->td_threshholding = (uint16) va_arg(ap, int);
 206		break;
 207	case TIFFTAG_FILLORDER:
 208		v = va_arg(ap, uint32);
 209		if (v != FILLORDER_LSB2MSB && v != FILLORDER_MSB2LSB)
 210			goto badvalue;
 211		td->td_fillorder = (uint16) v;
 212		break;
 213	case TIFFTAG_ORIENTATION:
 214		v = va_arg(ap, uint32);
 215		if (v < ORIENTATION_TOPLEFT || ORIENTATION_LEFTBOT < v)
 216			goto badvalue;
 217		else
 218			td->td_orientation = (uint16) v;
 219		break;
 220	case TIFFTAG_SAMPLESPERPIXEL:
 221		/* XXX should cross check -- e.g. if pallette, then 1 */
 222		v = va_arg(ap, uint32);
 223		if (v == 0)
 224			goto badvalue;
 225		td->td_samplesperpixel = (uint16) v;
 226		break;
 227	case TIFFTAG_ROWSPERSTRIP:
 228		v32 = va_arg(ap, uint32);
 229		if (v32 == 0)
 230			goto badvalue32;
 231		td->td_rowsperstrip = v32;
 232		if (!TIFFFieldSet(tif, FIELD_TILEDIMENSIONS)) {
 233			td->td_tilelength = v32;
 234			td->td_tilewidth = td->td_imagewidth;
 235		}
 236		break;
 237	case TIFFTAG_MINSAMPLEVALUE:
 238		td->td_minsamplevalue = (uint16) va_arg(ap, int);
 239		break;
 240	case TIFFTAG_MAXSAMPLEVALUE:
 241		td->td_maxsamplevalue = (uint16) va_arg(ap, int);
 242		break;
 243	case TIFFTAG_SMINSAMPLEVALUE:
 244		td->td_sminsamplevalue = va_arg(ap, double);
 245		break;
 246	case TIFFTAG_SMAXSAMPLEVALUE:
 247		td->td_smaxsamplevalue = va_arg(ap, double);
 248		break;
 249	case TIFFTAG_XRESOLUTION:
 250		td->td_xresolution = (float) va_arg(ap, double);
 251		break;
 252	case TIFFTAG_YRESOLUTION:
 253		td->td_yresolution = (float) va_arg(ap, double);
 254		break;
 255	case TIFFTAG_PLANARCONFIG:
 256		v = va_arg(ap, uint32);
 257		if (v != PLANARCONFIG_CONTIG && v != PLANARCONFIG_SEPARATE)
 258			goto badvalue;
 259		td->td_planarconfig = (uint16) v;
 260		break;
 261	case TIFFTAG_XPOSITION:
 262		td->td_xposition = (float) va_arg(ap, double);
 263		break;
 264	case TIFFTAG_YPOSITION:
 265		td->td_yposition = (float) va_arg(ap, double);
 266		break;
 267	case TIFFTAG_RESOLUTIONUNIT:
 268		v = va_arg(ap, uint32);
 269		if (v < RESUNIT_NONE || RESUNIT_CENTIMETER < v)
 270			goto badvalue;
 271		td->td_resolutionunit = (uint16) v;
 272		break;
 273	case TIFFTAG_PAGENUMBER:
 274		td->td_pagenumber[0] = (uint16) va_arg(ap, int);
 275		td->td_pagenumber[1] = (uint16) va_arg(ap, int);
 276		break;
 277	case TIFFTAG_HALFTONEHINTS:
 278		td->td_halftonehints[0] = (uint16) va_arg(ap, int);
 279		td->td_halftonehints[1] = (uint16) va_arg(ap, int);
 280		break;
 281	case TIFFTAG_COLORMAP:
 282		v32 = (uint32)(1L<<td->td_bitspersample);
 283		_TIFFsetShortArray(&td->td_colormap[0], va_arg(ap, uint16*), v32);
 284		_TIFFsetShortArray(&td->td_colormap[1], va_arg(ap, uint16*), v32);
 285		_TIFFsetShortArray(&td->td_colormap[2], va_arg(ap, uint16*), v32);
 286		break;
 287	case TIFFTAG_EXTRASAMPLES:
 288		if (!setExtraSamples(td, ap, &v))
 289			goto badvalue;
 290		break;
 291	case TIFFTAG_MATTEING:
 292		td->td_extrasamples = (uint16) (va_arg(ap, int) != 0);
 293		if (td->td_extrasamples) {
 294			uint16 sv = EXTRASAMPLE_ASSOCALPHA;
 295			_TIFFsetShortArray(&td->td_sampleinfo, &sv, 1);
 296		}
 297		break;
 298	case TIFFTAG_TILEWIDTH:
 299		v32 = va_arg(ap, uint32);
 300		if (v32 % 16) {
 301			if (tif->tif_mode != O_RDONLY)
 302				goto badvalue32;
 303			TIFFWarningExt(tif->tif_clientdata, tif->tif_name,
 304				"Nonstandard tile width %d, convert file", v32);
 305		}
 306		td->td_tilewidth = v32;
 307		tif->tif_flags |= TIFF_ISTILED;
 308		break;
 309	case TIFFTAG_TILELENGTH:
 310		v32 = va_arg(ap, uint32);
 311		if (v32 % 16) {
 312			if (tif->tif_mode != O_RDONLY)
 313				goto badvalue32;
 314			TIFFWarningExt(tif->tif_clientdata, tif->tif_name,
 315			    "Nonstandard tile length %d, convert file", v32);
 316		}
 317		td->td_tilelength = v32;
 318		tif->tif_flags |= TIFF_ISTILED;
 319		break;
 320	case TIFFTAG_TILEDEPTH:
 321		v32 = va_arg(ap, uint32);
 322		if (v32 == 0)
 323			goto badvalue32;
 324		td->td_tiledepth = v32;
 325		break;
 326	case TIFFTAG_DATATYPE:
 327		v = va_arg(ap, uint32);
 328		switch (v) {
 329		case DATATYPE_VOID:	v = SAMPLEFORMAT_VOID;	break;
 330		case DATATYPE_INT:	v = SAMPLEFORMAT_INT;	break;
 331		case DATATYPE_UINT:	v = SAMPLEFORMAT_UINT;	break;
 332		case DATATYPE_IEEEFP:	v = SAMPLEFORMAT_IEEEFP;break;
 333		default:		goto badvalue;
 334		}
 335		td->td_sampleformat = (uint16) v;
 336		break;
 337	case TIFFTAG_SAMPLEFORMAT:
 338		v = va_arg(ap, uint32);
 339		if (v < SAMPLEFORMAT_UINT || SAMPLEFORMAT_COMPLEXIEEEFP < v)
 340			goto badvalue;
 341		td->td_sampleformat = (uint16) v;
 342
 343                /*  Try to fix up the SWAB function for complex data. */
 344                if( td->td_sampleformat == SAMPLEFORMAT_COMPLEXINT 
 345                    && td->td_bitspersample == 32
 346                    && tif->tif_postdecode == _TIFFSwab32BitData )
 347                    tif->tif_postdecode = _TIFFSwab16BitData;
 348                else if( (td->td_sampleformat == SAMPLEFORMAT_COMPLEXINT 
 349                          || td->td_sampleformat == SAMPLEFORMAT_COMPLEXIEEEFP)
 350                         && td->td_bitspersample == 64
 351                         && tif->tif_postdecode == _TIFFSwab64BitData )
 352                    tif->tif_postdecode = _TIFFSwab32BitData;
 353		break;
 354	case TIFFTAG_IMAGEDEPTH:
 355		td->td_imagedepth = va_arg(ap, uint32);
 356		break;
 357	case TIFFTAG_SUBIFD:
 358		if ((tif->tif_flags & TIFF_INSUBIFD) == 0) {
 359			td->td_nsubifd = (uint16) va_arg(ap, int);
 360			_TIFFsetLongArray(&td->td_subifd, va_arg(ap, uint32*),
 361			    (long) td->td_nsubifd);
 362		} else {
 363			TIFFErrorExt(tif->tif_clientdata, module,
 364				     "%s: Sorry, cannot nest SubIFDs",
 365				     tif->tif_name);
 366			status = 0;
 367		}
 368		break;
 369	case TIFFTAG_YCBCRPOSITIONING:
 370		td->td_ycbcrpositioning = (uint16) va_arg(ap, int);
 371		break;
 372	case TIFFTAG_YCBCRSUBSAMPLING:
 373		td->td_ycbcrsubsampling[0] = (uint16) va_arg(ap, int);
 374		td->td_ycbcrsubsampling[1] = (uint16) va_arg(ap, int);
 375		break;
 376	case TIFFTAG_TRANSFERFUNCTION:
 377		v = (td->td_samplesperpixel - td->td_extrasamples) > 1 ? 3 : 1;
 378		for (i = 0; i < v; i++)
 379			_TIFFsetShortArray(&td->td_transferfunction[i],
 380			    va_arg(ap, uint16*), 1L<<td->td_bitspersample);
 381		break;
 382	case TIFFTAG_REFERENCEBLACKWHITE:
 383		/* XXX should check for null range */
 384		_TIFFsetFloatArray(&td->td_refblackwhite, va_arg(ap, float*), 6);
 385		break;
 386	case TIFFTAG_INKNAMES:
 387		v = va_arg(ap, uint32);
 388		s = va_arg(ap, char*);
 389		v = checkInkNamesString(tif, v, s);
 390                status = v > 0;
 391		if( v > 0 ) {
 392			_TIFFsetNString(&td->td_inknames, s, v);
 393			td->td_inknameslen = v;
 394		}
 395		break;
 396        default: {
 397            TIFFTagValue *tv;
 398            int tv_size, iCustom;
 399	    const TIFFFieldInfo* fip = _TIFFFindFieldInfo(tif, tag, TIFF_ANY);
 400
 401            /*
 402	     * This can happen if multiple images are open with different
 403	     * codecs which have private tags.  The global tag information
 404	     * table may then have tags that are valid for one file but not
 405	     * the other. If the client tries to set a tag that is not valid
 406	     * for the image's codec then we'll arrive here.  This
 407	     * happens, for example, when tiffcp is used to convert between
 408	     * compression schemes and codec-specific tags are blindly copied.
 409             */
 410            if(fip == NULL || fip->field_bit != FIELD_CUSTOM) {
 411		TIFFErrorExt(tif->tif_clientdata, module,
 412			     "%s: Invalid %stag \"%s\" (not supported by codec)",
 413			     tif->tif_name, isPseudoTag(tag) ? "pseudo-" : "",
 414			     fip ? fip->field_name : "Unknown");
 415		status = 0;
 416		break;
 417            }
 418
 419            /*
 420             * Find the existing entry for this custom value.
 421             */
 422            tv = NULL;
 423            for (iCustom = 0; iCustom < td->td_customValueCount; iCustom++) {
 424		    if (td->td_customValues[iCustom].info->field_tag == tag) {
 425			    tv = td->td_customValues + iCustom;
 426			    if (tv->value != NULL) {
 427				    _TIFFfree(tv->value);
 428				    tv->value = NULL;
 429			    }
 430			    break;
 431		    }
 432            }
 433
 434            /*
 435             * Grow the custom list if the entry was not found.
 436             */
 437            if(tv == NULL) {
 438		TIFFTagValue	*new_customValues;
 439		
 440		td->td_customValueCount++;
 441		new_customValues = (TIFFTagValue *)
 442			_TIFFrealloc(td->td_customValues,
 443				     sizeof(TIFFTagValue) * td->td_customValueCount);
 444		if (!new_customValues) {
 445			TIFFErrorExt(tif->tif_clientdata, module,
 446		"%s: Failed to allocate space for list of custom values",
 447				  tif->tif_name);
 448			status = 0;
 449			goto end;
 450		}
 451
 452		td->td_customValues = new_customValues;
 453
 454                tv = td->td_customValues + (td->td_customValueCount - 1);
 455                tv->info = fip;
 456                tv->value = NULL;
 457                tv->count = 0;
 458            }
 459
 460            /*
 461             * Set custom value ... save a copy of the custom tag value.
 462             */
 463	    tv_size = _TIFFDataSize(fip->field_type);
 464	    if (tv_size == 0) {
 465		    status = 0;
 466		    TIFFErrorExt(tif->tif_clientdata, module,
 467				 "%s: Bad field type %d for \"%s\"",
 468				 tif->tif_name, fip->field_type,
 469				 fip->field_name);
 470		    goto end;
 471	    }
 472           
 473            if(fip->field_passcount) {
 474		    if (fip->field_writecount == TIFF_VARIABLE2)
 475			tv->count = (uint32) va_arg(ap, uint32);
 476		    else
 477			tv->count = (int) va_arg(ap, int);
 478	    } else if (fip->field_writecount == TIFF_VARIABLE
 479		       || fip->field_writecount == TIFF_VARIABLE2)
 480		tv->count = 1;
 481	    else if (fip->field_writecount == TIFF_SPP)
 482		tv->count = td->td_samplesperpixel;
 483	    else
 484                tv->count = fip->field_writecount;
 485            
 486    
 487	    if (fip->field_type == TIFF_ASCII)
 488		    _TIFFsetString((char **)&tv->value, va_arg(ap, char *));
 489	    else {
 490		tv->value = _TIFFCheckMalloc(tif, tv_size, tv->count,
 491					     "Tag Value");
 492		if (!tv->value) {
 493		    status = 0;
 494		    goto end;
 495		}
 496
 497		if ((fip->field_passcount
 498		    || fip->field_writecount == TIFF_VARIABLE
 499		    || fip->field_writecount == TIFF_VARIABLE2
 500		    || fip->field_writecount == TIFF_SPP
 501		    || tv->count > 1)
 502		    && fip->field_tag != TIFFTAG_PAGENUMBER
 503		    && fip->field_tag != TIFFTAG_HALFTONEHINTS
 504		    && fip->field_tag != TIFFTAG_YCBCRSUBSAMPLING
 505		    && fip->field_tag != TIFFTAG_DOTRANGE) {
 506                    _TIFFmemcpy(tv->value, va_arg(ap, void *),
 507				tv->count * tv_size);
 508		} else {
 509		    /*
 510		     * XXX: The following loop required to handle
 511		     * TIFFTAG_PAGENUMBER, TIFFTAG_HALFTONEHINTS,
 512		     * TIFFTAG_YCBCRSUBSAMPLING and TIFFTAG_DOTRANGE tags.
 513		     * These tags are actually arrays and should be passed as
 514		     * array pointers to TIFFSetField() function, but actually
 515		     * passed as a list of separate values. This behaviour
 516		     * must be changed in the future!
 517		     */
 518		    int i;
 519		    char *val = (char *)tv->value;
 520
 521		    for (i = 0; i < tv->count; i++, val += tv_size) {
 522			    switch (fip->field_type) {
 523				case TIFF_BYTE:
 524				case TIFF_UNDEFINED:
 525				    {
 526					uint8 v = (uint8)va_arg(ap, int);
 527					_TIFFmemcpy(val, &v, tv_size);
 528				    }
 529				    break;
 530				case TIFF_SBYTE:
 531				    {
 532					int8 v = (int8)va_arg(ap, int);
 533					_TIFFmemcpy(val, &v, tv_size);
 534				    }
 535				    break;
 536				case TIFF_SHORT:
 537				    {
 538					uint16 v = (uint16)va_arg(ap, int);
 539					_TIFFmemcpy(val, &v, tv_size);
 540				    }
 541				    break;
 542				case TIFF_SSHORT:
 543				    {
 544					int16 v = (int16)va_arg(ap, int);
 545					_TIFFmemcpy(val, &v, tv_size);
 546				    }
 547				    break;
 548				case TIFF_LONG:
 549				case TIFF_IFD:
 550				    {
 551					uint32 v = va_arg(ap, uint32);
 552					_TIFFmemcpy(val, &v, tv_size);
 553				    }
 554				    break;
 555				case TIFF_SLONG:
 556				    {
 557					int32 v = va_arg(ap, int32);
 558					_TIFFmemcpy(val, &v, tv_size);
 559				    }
 560				    break;
 561				case TIFF_RATIONAL:
 562				case TIFF_SRATIONAL:
 563				case TIFF_FLOAT:
 564				    {
 565					float v = (float)va_arg(ap, double);
 566					_TIFFmemcpy(val, &v, tv_size);
 567				    }
 568				    break;
 569				case TIFF_DOUBLE:
 570				    {
 571					double v = va_arg(ap, double);
 572					_TIFFmemcpy(val, &v, tv_size);
 573				    }
 574				    break;
 575				default:
 576				    _TIFFmemset(val, 0, tv_size);
 577				    status = 0;
 578				    break;
 579			    }
 580		    }
 581		}
 582	    }
 583          }
 584	}
 585	if (status) {
 586		TIFFSetFieldBit(tif, _TIFFFieldWithTag(tif, tag)->field_bit);
 587		tif->tif_flags |= TIFF_DIRTYDIRECT;
 588	}
 589
 590end:
 591	va_end(ap);
 592	return (status);
 593badvalue:
 594	TIFFErrorExt(tif->tif_clientdata, module,
 595		     "%s: Bad value %d for \"%s\" tag",
 596		     tif->tif_name, v,
 597		     _TIFFFieldWithTag(tif, tag)->field_name);
 598	va_end(ap);
 599	return (0);
 600badvalue32:
 601	TIFFErrorExt(tif->tif_clientdata, module,
 602		     "%s: Bad value %u for \"%s\" tag",
 603		     tif->tif_name, v32,
 604		     _TIFFFieldWithTag(tif, tag)->field_name);
 605	va_end(ap);
 606	return (0);
 607}
 608
 609/*
 610 * Return 1/0 according to whether or not
 611 * it is permissible to set the tag's value.
 612 * Note that we allow ImageLength to be changed
 613 * so that we can append and extend to images.
 614 * Any other tag may not be altered once writing
 615 * has commenced, unless its value has no effect
 616 * on the format of the data that is written.
 617 */
 618static int
 619OkToChangeTag(TIFF* tif, ttag_t tag)
 620{
 621	const TIFFFieldInfo* fip = _TIFFFindFieldInfo(tif, tag, TIFF_ANY);
 622	if (!fip) {			/* unknown tag */
 623		TIFFErrorExt(tif->tif_clientdata, "TIFFSetField", "%s: Unknown %stag %u",
 624		    tif->tif_name, isPseudoTag(tag) ? "pseudo-" : "", tag);
 625		return (0);
 626	}
 627	if (tag != TIFFTAG_IMAGELENGTH && (tif->tif_flags & TIFF_BEENWRITING) &&
 628	    !fip->field_oktochange) {
 629		/*
 630		 * Consult info table to see if tag can be changed
 631		 * after we've started writing.  We only allow changes
 632		 * to those tags that don't/shouldn't affect the
 633		 * compression and/or format of the data.
 634		 */
 635		TIFFErrorExt(tif->tif_clientdata, "TIFFSetField",
 636		    "%s: Cannot modify tag \"%s\" while writing",
 637		    tif->tif_name, fip->field_name);
 638		return (0);
 639	}
 640	return (1);
 641}
 642
 643/*
 644 * Record the value of a field in the
 645 * internal directory structure.  The
 646 * field will be written to the file
 647 * when/if the directory structure is
 648 * updated.
 649 */
 650int
 651TIFFSetField(TIFF* tif, ttag_t tag, ...)
 652{
 653	va_list ap;
 654	int status;
 655
 656	va_start(ap, tag);
 657	status = TIFFVSetField(tif, tag, ap);
 658	va_end(ap);
 659	return (status);
 660}
 661
 662/*
 663 * Like TIFFSetField, but taking a varargs
 664 * parameter list.  This routine is useful
 665 * for building higher-level interfaces on
 666 * top of the library.
 667 */
 668int
 669TIFFVSetField(TIFF* tif, ttag_t tag, va_list ap)
 670{
 671	return OkToChangeTag(tif, tag) ?
 672	    (*tif->tif_tagmethods.vsetfield)(tif, tag, ap) : 0;
 673}
 674
 675static int
 676_TIFFVGetField(TIFF* tif, ttag_t tag, va_list ap)
 677{
 678    TIFFDirectory* td = &tif->tif_dir;
 679    int            ret_val = 1;
 680
 681    switch (tag) {
 682	case TIFFTAG_SUBFILETYPE:
 683            *va_arg(ap, uint32*) = td->td_subfiletype;
 684            break;
 685	case TIFFTAG_IMAGEWIDTH:
 686            *va_arg(ap, uint32*) = td->td_imagewidth;
 687            break;
 688	case TIFFTAG_IMAGELENGTH:
 689            *va_arg(ap, uint32*) = td->td_imagelength;
 690            break;
 691	case TIFFTAG_BITSPERSAMPLE:
 692            *va_arg(ap, uint16*) = td->td_bitspersample;
 693            break;
 694	case TIFFTAG_COMPRESSION:
 695            *va_arg(ap, uint16*) = td->td_compression;
 696            break;
 697	case TIFFTAG_PHOTOMETRIC:
 698            *va_arg(ap, uint16*) = td->td_photometric;
 699            break;
 700	case TIFFTAG_THRESHHOLDING:
 701            *va_arg(ap, uint16*) = td->td_threshholding;
 702            break;
 703	case TIFFTAG_FILLORDER:
 704            *va_arg(ap, uint16*) = td->td_fillorder;
 705            break;
 706	case TIFFTAG_ORIENTATION:
 707            *va_arg(ap, uint16*) = td->td_orientation;
 708            break;
 709	case TIFFTAG_SAMPLESPERPIXEL:
 710            *va_arg(ap, uint16*) = td->td_samplesperpixel;
 711            break;
 712	case TIFFTAG_ROWSPERSTRIP:
 713            *va_arg(ap, uint32*) = td->td_rowsperstrip;
 714            break;
 715	case TIFFTAG_MINSAMPLEVALUE:
 716            *va_arg(ap, uint16*) = td->td_minsamplevalue;
 717            break;
 718	case TIFFTAG_MAXSAMPLEVALUE:
 719            *va_arg(ap, uint16*) = td->td_maxsamplevalue;
 720            break;
 721	case TIFFTAG_SMINSAMPLEVALUE:
 722            *va_arg(ap, double*) = td->td_sminsamplevalue;
 723            break;
 724	case TIFFTAG_SMAXSAMPLEVALUE:
 725            *va_arg(ap, double*) = td->td_smaxsamplevalue;
 726            break;
 727	case TIFFTAG_XRESOLUTION:
 728            *va_arg(ap, float*) = td->td_xresolution;
 729            break;
 730	case TIFFTAG_YRESOLUTION:
 731            *va_arg(ap, float*) = td->td_yresolution;
 732            break;
 733	case TIFFTAG_PLANARCONFIG:
 734            *va_arg(ap, uint16*) = td->td_planarconfig;
 735            break;
 736	case TIFFTAG_XPOSITION:
 737            *va_arg(ap, float*) = td->td_xposition;
 738            break;
 739	case TIFFTAG_YPOSITION:
 740            *va_arg(ap, float*) = td->td_yposition;
 741            break;
 742	case TIFFTAG_RESOLUTIONUNIT:
 743            *va_arg(ap, uint16*) = td->td_resolutionunit;
 744            break;
 745	case TIFFTAG_PAGENUMBER:
 746            *va_arg(ap, uint16*) = td->td_pagenumber[0];
 747            *va_arg(ap, uint16*) = td->td_pagenumber[1];
 748            break;
 749	case TIFFTAG_HALFTONEHINTS:
 750            *va_arg(ap, uint16*) = td->td_halftonehints[0];
 751            *va_arg(ap, uint16*) = td->td_halftonehints[1];
 752            break;
 753	case TIFFTAG_COLORMAP:
 754            *va_arg(ap, uint16**) = td->td_colormap[0];
 755            *va_arg(ap, uint16**) = td->td_colormap[1];
 756            *va_arg(ap, uint16**) = td->td_colormap[2];
 757            break;
 758	case TIFFTAG_STRIPOFFSETS:
 759	case TIFFTAG_TILEOFFSETS:
 760            *va_arg(ap, uint32**) = td->td_stripoffset;
 761            break;
 762	case TIFFTAG_STRIPBYTECOUNTS:
 763	case TIFFTAG_TILEBYTECOUNTS:
 764            *va_arg(ap, uint32**) = td->td_stripbytecount;
 765            break;
 766	case TIFFTAG_MATTEING:
 767            *va_arg(ap, uint16*) =
 768                (td->td_extrasamples == 1 &&
 769                 td->td_sampleinfo[0] == EXTRASAMPLE_ASSOCALPHA);
 770            break;
 771	case TIFFTAG_EXTRASAMPLES:
 772            *va_arg(ap, uint16*) = td->td_extrasamples;
 773            *va_arg(ap, uint16**) = td->td_sampleinfo;
 774            break;
 775	case TIFFTAG_TILEWIDTH:
 776            *va_arg(ap, uint32*) = td->td_tilewidth;
 777            break;
 778	case TIFFTAG_TILELENGTH:
 779            *va_arg(ap, uint32*) = td->td_tilelength;
 780            break;
 781	case TIFFTAG_TILEDEPTH:
 782            *va_arg(ap, uint32*) = td->td_tiledepth;
 783            break;
 784	case TIFFTAG_DATATYPE:
 785            switch (td->td_sampleformat) {
 786		case SAMPLEFORMAT_UINT:
 787                    *va_arg(ap, uint16*) = DATATYPE_UINT;
 788                    break;
 789		case SAMPLEFORMAT_INT:
 790                    *va_arg(ap, uint16*) = DATATYPE_INT;
 791                    break;
 792		case SAMPLEFORMAT_IEEEFP:
 793                    *va_arg(ap, uint16*) = DATATYPE_IEEEFP;
 794                    break;
 795		case SAMPLEFORMAT_VOID:
 796                    *va_arg(ap, uint16*) = DATATYPE_VOID;
 797                    break;
 798            }
 799            break;
 800	case TIFFTAG_SAMPLEFORMAT:
 801            *va_arg(ap, uint16*) = td->td_sampleformat;
 802            break;
 803	case TIFFTAG_IMAGEDEPTH:
 804            *va_arg(ap, uint32*) = td->td_imagedepth;
 805            break;
 806	case TIFFTAG_SUBIFD:
 807            *va_arg(ap, uint16*) = td->td_nsubifd;
 808            *va_arg(ap, uint32**) = td->td_subifd;
 809            break;
 810	case TIFFTAG_YCBCRPOSITIONING:
 811            *va_arg(ap, uint16*) = td->td_ycbcrpositioning;
 812            break;
 813	case TIFFTAG_YCBCRSUBSAMPLING:
 814            *va_arg(ap, uint16*) = td->td_ycbcrsubsampling[0];
 815            *va_arg(ap, uint16*) = td->td_ycbcrsubsampling[1];
 816            break;
 817	case TIFFTAG_TRANSFERFUNCTION:
 818            *va_arg(ap, uint16**) = td->td_transferfunction[0];
 819            if (td->td_samplesperpixel - td->td_extrasamples > 1) {
 820                *va_arg(ap, uint16**) = td->td_transferfunction[1];
 821                *va_arg(ap, uint16**) = td->td_transferfunction[2];
 822            }
 823            break;
 824	case TIFFTAG_REFERENCEBLACKWHITE:
 825	    *va_arg(ap, float**) = td->td_refblackwhite;
 826	    break;
 827	case TIFFTAG_INKNAMES:
 828            *va_arg(ap, char**) = td->td_inknames;
 829            break;
 830        default:
 831        {
 832            const TIFFFieldInfo* fip = _TIFFFindFieldInfo(tif, tag, TIFF_ANY);
 833            int           i;
 834            
 835            /*
 836	     * This can happen if multiple images are open with different
 837	     * codecs which have private tags.  The global tag information
 838	     * table may then have tags that are valid for one file but not
 839	     * the other. If the client tries to get a tag that is not valid
 840	     * for the image's codec then we'll arrive here.
 841             */
 842            if( fip == NULL || fip->field_bit != FIELD_CUSTOM )
 843            {
 844		    TIFFErrorExt(tif->tif_clientdata, "_TIFFVGetField",
 845				 "%s: Invalid %stag \"%s\" "
 846				 "(not supported by codec)",
 847				 tif->tif_name,
 848				 isPseudoTag(tag) ? "pseudo-" : "",
 849				 fip ? fip->field_name : "Unknown");
 850		    ret_val = 0;
 851		    break;
 852            }
 853
 854            /*
 855	     * Do we have a custom value?
 856	     */
 857            ret_val = 0;
 858            for (i = 0; i < td->td_customValueCount; i++) {
 859		TIFFTagValue *tv = td->td_customValues + i;
 860
 861		if (tv->info->field_tag != tag)
 862			continue;
 863                
 864		if (fip->field_passcount) {
 865			if (fip->field_readcount == TIFF_VARIABLE2) 
 866				*va_arg(ap, uint32*) = (uint32)tv->count;
 867			else	/* Assume TIFF_VARIABLE */
 868				*va_arg(ap, uint16*) = (uint16)tv->count;
 869			*va_arg(ap, void **) = tv->value;
 870			ret_val = 1;
 871                } else {
 872			if ((fip->field_type == TIFF_ASCII
 873			    || fip->field_readcount == TIFF_VARIABLE
 874			    || fip->field_readcount == TIFF_VARIABLE2
 875			    || fip->field_readcount == TIFF_SPP
 876			    || tv->count > 1)
 877			    && fip->field_tag != TIFFTAG_PAGENUMBER
 878			    && fip->field_tag != TIFFTAG_HALFTONEHINTS
 879			    && fip->field_tag != TIFFTAG_YCBCRSUBSAMPLING
 880			    && fip->field_tag != TIFFTAG_DOTRANGE) {
 881				*va_arg(ap, void **) = tv->value;
 882				ret_val = 1;
 883			} else {
 884			    int j;
 885			    char *val = (char *)tv->value;
 886
 887			    for (j = 0; j < tv->count;
 888				 j++, val += _TIFFDataSize(tv->info->field_type)) {
 889				switch (fip->field_type) {
 890					case TIFF_BYTE:
 891					case TIFF_UNDEFINED:
 892						*va_arg(ap, uint8*) =
 893							*(uint8 *)val;
 894						ret_val = 1;
 895						break;
 896					case TIFF_SBYTE:
 897						*va_arg(ap, int8*) =
 898							*(int8 *)val;
 899						ret_val = 1;
 900						break;
 901					case TIFF_SHORT:
 902						*va_arg(ap, uint16*) =
 903							*(uint16 *)val;
 904						ret_val = 1;
 905						break;
 906					case TIFF_SSHORT:
 907						*va_arg(ap, int16*) =
 908							*(int16 *)val;
 909						ret_val = 1;
 910						break;
 911					case TIFF_LONG:
 912					case TIFF_IFD:
 913						*va_arg(ap, uint32*) =
 914							*(uint32 *)val;
 915						ret_val = 1;
 916						break;
 917					case TIFF_SLONG:
 918						*va_arg(ap, int32*) =
 919							*(int32 *)val;
 920						ret_val = 1;
 921						break;
 922					case TIFF_RATIONAL:
 923					case TIFF_SRATIONAL:
 924					case TIFF_FLOAT:
 925						*va_arg(ap, float*) =
 926							*(float *)val;
 927						ret_val = 1;
 928						break;
 929					case TIFF_DOUBLE:
 930						*va_arg(ap, double*) =
 931							*(double *)val;
 932						ret_val = 1;
 933						break;
 934					default:
 935						ret_val = 0;
 936						break;
 937				}
 938			    }
 939			}
 940                }
 941		break;
 942            }
 943        }
 944    }
 945    return(ret_val);
 946}
 947
 948/*
 949 * Return the value of a field in the
 950 * internal directory structure.
 951 */
 952int
 953TIFFGetField(TIFF* tif, ttag_t tag, ...)
 954{
 955	int status;
 956	va_list ap;
 957
 958	va_start(ap, tag);
 959	status = TIFFVGetField(tif, tag, ap);
 960	va_end(ap);
 961	return (status);
 962}
 963
 964/*
 965 * Like TIFFGetField, but taking a varargs
 966 * parameter list.  This routine is useful
 967 * for building higher-level interfaces on
 968 * top of the library.
 969 */
 970int
 971TIFFVGetField(TIFF* tif, ttag_t tag, va_list ap)
 972{
 973	const TIFFFieldInfo* fip = _TIFFFindFieldInfo(tif, tag, TIFF_ANY);
 974	return (fip && (isPseudoTag(tag) || TIFFFieldSet(tif, fip->field_bit)) ?
 975	    (*tif->tif_tagmethods.vgetfield)(tif, tag, ap) : 0);
 976}
 977
 978#define	CleanupField(member) {		\
 979    if (td->member) {			\
 980	_TIFFfree(td->member);		\
 981	td->member = 0;			\
 982    }					\
 983}
 984
 985/*
 986 * Release storage associated with a directory.
 987 */
 988void
 989TIFFFreeDirectory(TIFF* tif)
 990{
 991	TIFFDirectory *td = &tif->tif_dir;
 992	int            i;
 993
 994	_TIFFmemset(td->td_fieldsset, 0, FIELD_SETLONGS);
 995	CleanupField(td_colormap[0]);
 996	CleanupField(td_colormap[1]);
 997	CleanupField(td_colormap[2]);
 998	CleanupField(td_sampleinfo);
 999	CleanupField(td_subifd);
1000	CleanupField(td_inknames);
1001	CleanupField(td_refblackwhite);
1002	CleanupField(td_transferfunction[0]);
1003	CleanupField(td_transferfunction[1]);
1004	CleanupField(td_transferfunction[2]);
1005	CleanupField(td_stripoffset);
1006	CleanupField(td_stripbytecount);
1007	TIFFClrFieldBit(tif, FIELD_YCBCRSUBSAMPLING);
1008	TIFFClrFieldBit(tif, FIELD_YCBCRPOSITIONING);
1009
1010	/* Cleanup custom tag values */
1011	for( i = 0; i < td->td_customValueCount; i++ ) {
1012		if (td->td_customValues[i].value)
1013			_TIFFfree(td->td_customValues[i].value);
1014	}
1015
1016	td->td_customValueCount = 0;
1017	CleanupField(td_customValues);
1018}
1019#undef CleanupField
1020
1021/*
1022 * Client Tag extension support (from Niles Ritter).
1023 */
1024static TIFFExtendProc _TIFFextender = (TIFFExtendProc) NULL;
1025
1026TIFFExtendProc
1027TIFFSetTagExtender(TIFFExtendProc extender)
1028{
1029	TIFFExtendProc prev = _TIFFextender;
1030	_TIFFextender = extender;
1031	return (prev);
1032}
1033
1034/*
1035 * Setup for a new directory.  Should we automatically call
1036 * TIFFWriteDirectory() if the current one is dirty?
1037 *
1038 * The newly created directory will not exist on the file till
1039 * TIFFWriteDirectory(), TIFFFlush() or TIFFClose() is called.
1040 */
1041int
1042TIFFCreateDirectory(TIFF* tif)
1043{
1044    TIFFDefaultDirectory(tif);
1045    tif->tif_diroff = 0;
1046    tif->tif_nextdiroff = 0;
1047    tif->tif_curoff = 0;
1048    tif->tif_row = (uint32) -1;
1049    tif->tif_curstrip = (tstrip_t) -1;
1050
1051    return 0;
1052}
1053
1054/*
1055 * Setup a default directory structure.
1056 */
1057int
1058TIFFDefaultDirectory(TIFF* tif)
1059{
1060	register TIFFDirectory* td = &tif->tif_dir;
1061
1062	size_t tiffFieldInfoCount;
1063	const TIFFFieldInfo *tiffFieldInfo =
1064	    _TIFFGetFieldInfo(&tiffFieldInfoCount);
1065	_TIFFSetupFieldInfo(tif, tiffFieldInfo, tiffFieldInfoCount);
1066
1067	_TIFFmemset(td, 0, sizeof (*td));
1068	td->td_fillorder = FILLORDER_MSB2LSB;
1069	td->td_bitspersample = 1;
1070	td->td_threshholding = THRESHHOLD_BILEVEL;
1071	td->td_orientation = ORIENTATION_TOPLEFT;
1072	td->td_samplesperpixel = 1;
1073	td->td_rowsperstrip = (uint32) -1;
1074	td->td_tilewidth = 0;
1075	td->td_tilelength = 0;
1076	td->td_tiledepth = 1;
1077	td->td_stripbytecountsorted = 1; /* Our own arrays always sorted. */
1078	td->td_resolutionunit = RESUNIT_INCH;
1079	td->td_sampleformat = SAMPLEFORMAT_UINT;
1080	td->td_imagedepth = 1;
1081	td->td_ycbcrsubsampling[0] = 2;
1082	td->td_ycbcrsubsampling[1] = 2;
1083	td->td_ycbcrpositioning = YCBCRPOSITION_CENTERED;
1084	tif->tif_postdecode = _TIFFNoPostDecode;
1085	tif->tif_foundfield = NULL;
1086	tif->tif_tagmethods.vsetfield = _TIFFVSetField;
1087	tif->tif_tagmethods.vgetfield = _TIFFVGetField;
1088	tif->tif_tagmethods.printdir = NULL;
1089	/*
1090	 *  Give client code a chance to install their own
1091	 *  tag extensions & methods, prior to compression overloads.
1092	 */
1093	if (_TIFFextender)
1094		(*_TIFFextender)(tif);
1095	(void) TIFFSetField(tif, TIFFTAG_COMPRESSION, COMPRESSION_NONE);
1096	/*
1097	 * NB: The directory is marked dirty as a result of setting
1098	 * up the default compression scheme.  However, this really
1099	 * isn't correct -- we want TIFF_DIRTYDIRECT to be set only
1100	 * if the user does something.  We could just do the setup
1101	 * by hand, but it seems better to use the normal mechanism
1102	 * (i.e. TIFFSetField).
1103	 */
1104	tif->tif_flags &= ~TIFF_DIRTYDIRECT;
1105
1106	/*
1107	 * As per http://bugzilla.remotesensing.org/show_bug.cgi?id=19
1108	 * we clear the ISTILED flag when setting up a new directory.
1109	 * Should we also be clearing stuff like INSUBIFD?
1110	 */
1111	tif->tif_flags &= ~TIFF_ISTILED;
1112        /*
1113         * Clear other directory-specific fields.
1114         */
1115        tif->tif_tilesize = -1;
1116        tif->tif_scanlinesize = -1;
1117
1118	return (1);
1119}
1120
1121static int
1122TIFFAdvanceDirectory(TIFF* tif, uint32* nextdir, toff_t* off)
1123{
1124	static const char module[] = "TIFFAdvanceDirectory";
1125	uint16 dircount;
1126	if (isMapped(tif))
1127	{
1128		toff_t poff=*nextdir;
1129		if (poff+sizeof(uint16) > tif->tif_size)
1130		{
1131			TIFFErrorExt(tif->tif_clientdata, module, "%s: Error fetching directory count",
1132			    tif->tif_name);
1133			return (0);
1134		}
1135		_TIFFmemcpy(&dircount, tif->tif_base+poff, sizeof (uint16));
1136		if (tif->tif_flags & TIFF_SWAB)
1137			TIFFSwabShort(&dircount);
1138		poff+=sizeof (uint16)+dircount*sizeof (TIFFDirEntry);
1139		if (off != NULL)
1140			*off = poff;
1141		if (((toff_t) (poff+sizeof (uint32))) > tif->tif_size)
1142		{
1143			TIFFErrorExt(tif->tif_clientdata, module, "%s: Error fetching directory link",
1144			    tif->tif_name);
1145			return (0);
1146		}
1147		_TIFFmemcpy(nextdir, tif->tif_base+poff, sizeof (uint32));
1148		if (tif->tif_flags & TIFF_SWAB)
1149			TIFFSwabLong(nextdir);
1150		return (1);
1151	}
1152	else
1153	{
1154		if (!SeekOK(tif, *nextdir) ||
1155		    !ReadOK(tif, &dircount, sizeof (uint16))) {
1156			TIFFErrorExt(tif->tif_clientdata, module, "%s: Error fetching directory count",
1157			    tif->tif_name);
1158			return (0);
1159		}
1160		if (tif->tif_flags & TIFF_SWAB)
1161			TIFFSwabShort(&dircount);
1162		if (off != NULL)
1163			*off = TIFFSeekFile(tif,
1164			    dircount*sizeof (TIFFDirEntry), SEEK_CUR);
1165		else
1166			(void) TIFFSeekFile(tif,
1167			    dircount*sizeof (TIFFDirEntry), SEEK_CUR);
1168		if (!ReadOK(tif, nextdir, sizeof (uint32))) {
1169			TIFFErrorExt(tif->tif_clientdata, module, "%s: Error fetching directory link",
1170			    tif->tif_name);
1171			return (0);
1172		}
1173		if (tif->tif_flags & TIFF_SWAB)
1174			TIFFSwabLong(nextdir);
1175		return (1);
1176	}
1177}
1178
1179/*
1180 * Count the number of directories in a file.
1181 */
1182tdir_t
1183TIFFNumberOfDirectories(TIFF* tif)
1184{
1185    toff_t nextdir = tif->tif_header.tiff_diroff;
1186    tdir_t n = 0;
1187    
1188    while (nextdir != 0 && TIFFAdvanceDirectory(tif, &nextdir, NULL))
1189        n++;
1190    return (n);
1191}
1192
1193/*
1194 * Set the n-th directory as the current directory.
1195 * NB: Directories are numbered starting at 0.
1196 */
1197int
1198TIFFSetDirectory(TIFF* tif, tdir_t dirn)
1199{
1200	toff_t nextdir;
1201	tdir_t n;
1202
1203	nextdir = tif->tif_header.tiff_diroff;
1204	for (n = dirn; n > 0 && nextdir != 0; n--)
1205		if (!TIFFAdvanceDirectory(tif, &nextdir, NULL))
1206			return (0);
1207	tif->tif_nextdiroff = nextdir;
1208	/*
1209	 * Set curdir to the actual directory index.  The
1210	 * -1 is because TIFFReadDirectory will increment
1211	 * tif_curdir after successfully reading the directory.
1212	 */
1213	tif->tif_curdir = (dirn - n) - 1;
1214	/*
1215	 * Reset tif_dirnumber counter and start new list of seen directories.
1216	 * We need this to prevent IFD loops.
1217	 */
1218	tif->tif_dirnumber = 0;
1219	return (TIFFReadDirectory(tif));
1220}
1221
1222/*
1223 * Set the current directory to be the directory
1224 * located at the specified file offset.  This interface
1225 * is used mainly to access directories linked with
1226 * the SubIFD tag (e.g. thumbnail images).
1227 */
1228int
1229TIFFSetSubDirectory(TIFF* tif, uint32 diroff)
1230{
1231	tif->tif_nextdiroff = diroff;
1232	/*
1233	 * Reset tif_dirnumber counter and start new list of seen directories.
1234	 * We need this to prevent IFD loops.
1235	 */
1236	tif->tif_dirnumber = 0;
1237	return (TIFFReadDirectory(tif));
1238}
1239
1240/*
1241 * Return file offset of the current directory.
1242 */
1243uint32
1244TIFFCurrentDirOffset(TIFF* tif)
1245{
1246	return (tif->tif_diroff);
1247}
1248
1249/*
1250 * Return an indication of whether or not we are
1251 * at the last directory in the file.
1252 */
1253int
1254TIFFLastDirectory(TIFF* tif)
1255{
1256	return (tif->tif_nextdiroff == 0);
1257}
1258
1259/*
1260 * Unlink the specified directory from the directory chain.
1261 */
1262int
1263TIFFUnlinkDirectory(TIFF* tif, tdir_t dirn)
1264{
1265	static const char module[] = "TIFFUnlinkDirectory";
1266	toff_t nextdir;
1267	toff_t off;
1268	tdir_t n;
1269
1270	if (tif->tif_mode == O_RDONLY) {
1271		TIFFErrorExt(tif->tif_clientdata, module,
1272                             "Can not unlink directory in read-only file");
1273		return (0);
1274	}
1275	/*
1276	 * Go to the directory before the one we want
1277	 * to unlink and nab the offset of the link
1278	 * field we'll need to patch.
1279	 */
1280	nextdir = tif->tif_header.tiff_diroff;
1281	off = sizeof (uint16) + sizeof (uint16);
1282	for (n = dirn-1; n > 0; n--) {
1283		if (nextdir == 0) {
1284			TIFFErrorExt(tif->tif_clientdata, module, "Directory %d does not exist", dirn);
1285			return (0);
1286		}
1287		if (!TIFFAdvanceDirectory(tif, &nextdir, &off))
1288			return (0);
1289	}
1290	/*
1291	 * Advance to the directory to be unlinked and fetch
1292	 * the offset of the directory that follows.
1293	 */
1294	if (!TIFFAdvanceDirectory(tif, &nextdir, NULL))
1295		return (0);
1296	/*
1297	 * Go back and patch the link field of the preceding
1298	 * directory to point to the offset of the directory
1299	 * that follows.
1300	 */
1301	(void) TIFFSeekFile(tif, off, SEEK_SET);
1302	if (tif->tif_flags & TIFF_SWAB)
1303		TIFFSwabLong(&nextdir);
1304	if (!WriteOK(tif, &nextdir, sizeof (uint32))) {
1305		TIFFErrorExt(tif->tif_clientdata, module, "Error writing directory link");
1306		return (0);
1307	}
1308	/*
1309	 * Leave directory state setup safely.  We don't have
1310	 * facilities for doing inserting and removing directories,
1311	 * so it's safest to just invalidate everything.  This
1312	 * means that the caller can only append to the directory
1313	 * chain.
1314	 */
1315	(*tif->tif_cleanup)(tif);
1316	if ((tif->tif_flags & TIFF_MYBUFFER) && tif->tif_rawdata) {
1317		_TIFFfree(tif->tif_rawdata);
1318		tif->tif_rawdata = NULL;
1319		tif->tif_rawcc = 0;
1320	}
1321	tif->tif_flags &= ~(TIFF_BEENWRITING|TIFF_BUFFERSETUP|TIFF_POSTENCODE);
1322	TIFFFreeDirectory(tif);
1323	TIFFDefaultDirectory(tif);
1324	tif->tif_diroff = 0;			/* force link on next write */
1325	tif->tif_nextdiroff = 0;		/* next write must be at end */
1326	tif->tif_curoff = 0;
1327	tif->tif_row = (uint32) -1;
1328	tif->tif_curstrip = (tstrip_t) -1;
1329	return (1);
1330}
1331
1332/*			[BFC]
1333 *
1334 * Author: Bruce Cameron <cameron@petris.com>
1335 *
1336 * Set a table of tags that are to be replaced during directory process by the
1337 * 'IGNORE' state - or return TRUE/FALSE for the requested tag such that
1338 * 'ReadDirectory' can use the stored information.
1339 *
1340 * FIXME: this is never used properly. Should be removed in the future.
1341 */
1342int
1343TIFFReassignTagToIgnore (enum TIFFIgnoreSense task, int TIFFtagID)
1344{
1345    static int TIFFignoretags [FIELD_LAST];
1346    static int tagcount = 0 ;
1347    int		i;					/* Loop index */
1348    int		j;					/* Loop index */
1349
1350    switch (task)
1351    {
1352      case TIS_STORE:
1353        if ( tagcount < (FIELD_LAST - 1) )
1354        {
1355            for ( j = 0 ; j < tagcount ; ++j )
1356            {					/* Do not add duplicate tag */
1357                if ( TIFFignoretags [j] == TIFFtagID )
1358                    return (TRUE) ;
1359            }
1360            TIFFignoretags [tagcount++] = TIFFtagID ;
1361            return (TRUE) ;
1362        }
1363        break ;
1364        
1365      case TIS_EXTRACT:
1366        for ( i = 0 ; i < tagcount ; ++i )
1367        {
1368            if ( TIFFignoretags [i] == TIFFtagID )
1369                return (TRUE) ;
1370        }
1371        break;
1372        
1373      case TIS_EMPTY:
1374        tagcount = 0 ;			/* Clear the list */
1375        return (TRUE) ;
1376        
1377      default:
1378        break;
1379    }
1380    
1381    return (FALSE);
1382}
1383
1384/* vim: set ts=8 sts=8 sw=8 noet: */
1385/*
1386 * Local Variables:
1387 * mode: c
1388 * c-basic-offset: 8
1389 * fill-column: 78
1390 * End:
1391 */