PageRenderTime 143ms CodeModel.GetById 64ms app.highlight 69ms RepoModel.GetById 1ms app.codeStats 0ms

/src/FreeImage/Source/LibTIFF/tif_dirwrite.c

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