Blame contrib/pds/tif_pdsdirwrite.c

Packit 7838c8
/* $Header: /cvs/maptools/cvsroot/libtiff/contrib/pds/tif_pdsdirwrite.c,v 1.4 2010-06-08 18:55:15 bfriesen Exp $ */
Packit 7838c8
Packit 7838c8
/* When writing data to TIFF files, it is often useful to store application-
Packit 7838c8
   specific data in a private TIFF directory so that the tags don't need to
Packit 7838c8
   be registered and won't conflict with other people's user-defined tags.
Packit 7838c8
   One needs to have a registered public tag which contains some amount of
Packit 7838c8
   raw data. That raw data, however, is interpreted at an independent,
Packit 7838c8
   separate, private tiff directory. This file provides some routines which
Packit 7838c8
   will be useful for converting that data from its raw binary form into
Packit 7838c8
   the proper form for your application.
Packit 7838c8
*/
Packit 7838c8
Packit 7838c8
/*
Packit 7838c8
 * Copyright (c) 1988-1996 Sam Leffler
Packit 7838c8
 * Copyright (c) 1991-1996 Silicon Graphics, Inc.
Packit 7838c8
 * Copyright (c( 1996 USAF Phillips Laboratory
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
 * These routines written by Conrad J. Poelman on a single late-night of
Packit 7838c8
 * March 20-21, 1996.
Packit 7838c8
 *
Packit 7838c8
 * The entire purpose of this file is to provide a single external function,
Packit 7838c8
 * TIFFWritePrivateDataSubDirectory(). This function is intended for use
Packit 7838c8
 * in writing a private subdirectory structure into a TIFF file. The
Packit 7838c8
 * actual reading of data from the structure is handled by the getFieldFn(),
Packit 7838c8
 * which is passed to TIFFWritePrivateDataSubDirectory() as a parameter. The
Packit 7838c8
 * idea is to enable any application wishing to read private subdirectories to
Packit 7838c8
 * do so easily using this function, without modifying the TIFF library.
Packit 7838c8
 *
Packit 7838c8
 * The astute observer will notice that only two functions are at all different
Packit 7838c8
 * from the original tif_dirwrite.c file: TIFFWritePrivateDataSubDirectory()and
Packit 7838c8
 * TIFFWriteNormalSubTag(). All the other stuff that makes this file so huge
Packit 7838c8
 * is only necessary because all of those functions are declared static in
Packit 7838c8
 * tif_dirwrite.c, so we have to totally duplicate them in order to use them.
Packit 7838c8
 *
Packit 7838c8
 * Oh, also please note the bug-fix in the routine TIFFWriteNormalSubTag(),
Packit 7838c8
 * which equally should be applied to TIFFWriteNormalTag().
Packit 7838c8
 *
Packit 7838c8
 */
Packit 7838c8
#include "tiffiop.h"
Packit 7838c8
Packit 7838c8
#if HAVE_IEEEFP
Packit 7838c8
#define	TIFFCvtNativeToIEEEFloat(tif, n, fp)
Packit 7838c8
#define	TIFFCvtNativeToIEEEDouble(tif, n, dp)
Packit 7838c8
#else
Packit 7838c8
extern	void TIFFCvtNativeToIEEEFloat(TIFF*, uint32, float*);
Packit 7838c8
extern	void TIFFCvtNativeToIEEEDouble(TIFF*, uint32, double*);
Packit 7838c8
#endif
Packit 7838c8
Packit 7838c8
static	int TIFFWriteNormalTag(TIFF*, TIFFDirEntry*, const TIFFFieldInfo*);
Packit 7838c8
static	int TIFFWriteNormalSubTag(TIFF*, TIFFDirEntry*, const TIFFFieldInfo*,
Packit 7838c8
				  int (*getFieldFn)(TIFF *tif,ttag_t tag,...));
Packit 7838c8
static	void TIFFSetupShortLong(TIFF*, ttag_t, TIFFDirEntry*, uint32);
Packit 7838c8
static	int TIFFSetupShortPair(TIFF*, ttag_t, TIFFDirEntry*);
Packit 7838c8
static	int TIFFWritePerSampleShorts(TIFF*, ttag_t, TIFFDirEntry*);
Packit 7838c8
static	int TIFFWritePerSampleAnys(TIFF*, TIFFDataType, ttag_t, TIFFDirEntry*);
Packit 7838c8
static	int TIFFWriteShortTable(TIFF*, ttag_t, TIFFDirEntry*, uint32, uint16**);
Packit 7838c8
static	int TIFFWriteShortArray(TIFF*,
Packit 7838c8
	    TIFFDataType, ttag_t, TIFFDirEntry*, uint32, uint16*);
Packit 7838c8
static	int TIFFWriteLongArray(TIFF *,
Packit 7838c8
	    TIFFDataType, ttag_t, TIFFDirEntry*, uint32, uint32*);
Packit 7838c8
static	int TIFFWriteRationalArray(TIFF *,
Packit 7838c8
	    TIFFDataType, ttag_t, TIFFDirEntry*, uint32, float*);
Packit 7838c8
static	int TIFFWriteFloatArray(TIFF *,
Packit 7838c8
	    TIFFDataType, ttag_t, TIFFDirEntry*, uint32, float*);
Packit 7838c8
static	int TIFFWriteDoubleArray(TIFF *,
Packit 7838c8
	    TIFFDataType, ttag_t, TIFFDirEntry*, uint32, double*);
Packit 7838c8
static	int TIFFWriteByteArray(TIFF*, TIFFDirEntry*, char*);
Packit 7838c8
static	int TIFFWriteAnyArray(TIFF*,
Packit 7838c8
	    TIFFDataType, ttag_t, TIFFDirEntry*, uint32, double*);
Packit 7838c8
#ifdef COLORIMETRY_SUPPORT
Packit 7838c8
static	int TIFFWriteTransferFunction(TIFF*, TIFFDirEntry*);
Packit 7838c8
#endif
Packit 7838c8
static	int TIFFWriteData(TIFF*, TIFFDirEntry*, char*);
Packit 7838c8
static	int TIFFLinkDirectory(TIFF*);
Packit 7838c8
Packit 7838c8
#define	WriteRationalPair(type, tag1, v1, tag2, v2) {		\
Packit 7838c8
	if (!TIFFWriteRational(tif, type, tag1, dir, v1))	\
Packit 7838c8
		goto bad;					\
Packit 7838c8
	if (!TIFFWriteRational(tif, type, tag2, dir+1, v2))	\
Packit 7838c8
		goto bad;					\
Packit 7838c8
	dir++;							\
Packit 7838c8
}
Packit 7838c8
#define	TIFFWriteRational(tif, type, tag, dir, v) \
Packit 7838c8
	TIFFWriteRationalArray((tif), (type), (tag), (dir), 1, &(v))
Packit 7838c8
#ifndef TIFFWriteRational
Packit 7838c8
static	int TIFFWriteRational(TIFF*,
Packit 7838c8
	    TIFFDataType, ttag_t, TIFFDirEntry*, float);
Packit 7838c8
#endif
Packit 7838c8
Packit 7838c8
/* This function will write an entire directory to the disk, and return the
Packit 7838c8
   offset value indicating where in the file it wrote the beginning of the
Packit 7838c8
   directory structure. This is NOT the same as the offset value before
Packit 7838c8
   calling this function, because some of the fields may have caused various
Packit 7838c8
   data items to be written out BEFORE writing the directory structure.
Packit 7838c8
Packit 7838c8
   This code was basically written by ripping of the TIFFWriteDirectory() 
Packit 7838c8
   code and generalizing it, using RPS's TIFFWritePliIfd() code for
Packit 7838c8
   inspiration.  My original goal was to make this code general enough that
Packit 7838c8
   the original TIFFWriteDirectory() could be rewritten to just call this
Packit 7838c8
   function with the appropriate field and field-accessing arguments.
Packit 7838c8
Packit 7838c8
   However, now I realize that there's a lot of code that gets executed for
Packit 7838c8
   the main, standard TIFF directories that does not apply to special
Packit 7838c8
   private subdirectories, so such a reimplementation for the sake of
Packit 7838c8
   eliminating redundant or duplicate code is probably not possible,
Packit 7838c8
   unless we also pass in a Main flag to indiciate which type of handling
Packit 7838c8
   to do, which would be kind of a hack. I've marked those places where I
Packit 7838c8
   changed or ripped out code which would have to be re-inserted to
Packit 7838c8
   generalize this function. If it can be done in a clean and graceful way,
Packit 7838c8
   it would be a great way to generalize the TIFF library. Otherwise, I'll
Packit 7838c8
   just leave this code here where it duplicates but remains on top of and
Packit 7838c8
   hopefully mostly independent of the main TIFF library.
Packit 7838c8
Packit 7838c8
   The caller will probably want to free the sub directory structure after
Packit 7838c8
   returning from this call, since otherwise once written out, the user
Packit 7838c8
   is likely to forget about it and leave data lying around.
Packit 7838c8
*/
Packit 7838c8
toff_t
Packit 7838c8
TIFFWritePrivateDataSubDirectory(TIFF* tif,
Packit 7838c8
				 uint32 pdir_fieldsset[], int pdir_fields_last,
Packit 7838c8
				 TIFFFieldInfo *field_info,
Packit 7838c8
				 int (*getFieldFn)(TIFF *tif, ttag_t tag, ...))
Packit 7838c8
{
Packit 7838c8
	uint16 dircount;
Packit 7838c8
	uint32 diroff, nextdiroff;
Packit 7838c8
	ttag_t tag;
Packit 7838c8
	uint32 nfields;
Packit 7838c8
	tsize_t dirsize;
Packit 7838c8
	char* data;
Packit 7838c8
	TIFFDirEntry* dir;
Packit 7838c8
	u_long b, *fields, fields_size;
Packit 7838c8
	toff_t directory_offset;
Packit 7838c8
	TIFFFieldInfo* fip;
Packit 7838c8
Packit 7838c8
	/*
Packit 7838c8
	 * Deleted out all of the encoder flushing and such code from here -
Packit 7838c8
	 * not necessary for subdirectories.
Packit 7838c8
	 */
Packit 7838c8
Packit 7838c8
	/* Finish writing out any image data. */
Packit 7838c8
	TIFFFlushData(tif);
Packit 7838c8
Packit 7838c8
	/*
Packit 7838c8
	 * Size the directory so that we can calculate
Packit 7838c8
	 * offsets for the data items that aren't kept
Packit 7838c8
	 * in-place in each field.
Packit 7838c8
	 */
Packit 7838c8
	nfields = 0;
Packit 7838c8
	for (b = 0; b <= pdir_fields_last; b++)
Packit 7838c8
		if (FieldSet(pdir_fieldsset, b))
Packit 7838c8
			/* Deleted code to make size of first 4 tags 2
Packit 7838c8
			   instead of 1. */
Packit 7838c8
			nfields += 1;
Packit 7838c8
	dirsize = nfields * sizeof (TIFFDirEntry);
Packit 7838c8
	data = (char*) _TIFFmalloc(dirsize);
Packit 7838c8
	if (data == NULL) {
Packit 7838c8
		TIFFErrorExt(tif->tif_clientdata, tif->tif_name,
Packit 7838c8
		    "Cannot write private subdirectory, out of space");
Packit 7838c8
		return (0);
Packit 7838c8
	}
Packit 7838c8
	/*
Packit 7838c8
	 * Place directory in data section of the file. If there isn't one
Packit 7838c8
	 * yet, place it at the end of the file. The directory is treated as
Packit 7838c8
	 * data, so we don't link it into the directory structure at all.
Packit 7838c8
	 */
Packit 7838c8
	if (tif->tif_dataoff == 0)
Packit 7838c8
	    tif->tif_dataoff =(TIFFSeekFile(tif, (toff_t) 0, SEEK_END)+1) &~ 1;
Packit 7838c8
	diroff = tif->tif_dataoff;
Packit 7838c8
	tif->tif_dataoff = (toff_t)(
Packit 7838c8
	    diroff + sizeof (uint16) + dirsize + sizeof (toff_t));
Packit 7838c8
	if (tif->tif_dataoff & 1)
Packit 7838c8
		tif->tif_dataoff++;
Packit 7838c8
	(void) TIFFSeekFile(tif, tif->tif_dataoff, SEEK_SET);
Packit 7838c8
	/*tif->tif_curdir++;*/
Packit 7838c8
	dir = (TIFFDirEntry*) data;
Packit 7838c8
	/*
Packit 7838c8
	 * Setup external form of directory
Packit 7838c8
	 * entries and write data items.
Packit 7838c8
	 */
Packit 7838c8
	/*
Packit 7838c8
	 * We make a local copy of the fieldsset here so that we don't mess
Packit 7838c8
	 * up the original one when we call ResetFieldBit(). But I'm not sure
Packit 7838c8
	 * why the original code calls ResetFieldBit(), since we're already
Packit 7838c8
	 * going through the fields in order...
Packit 7838c8
	 *
Packit 7838c8
	 * fields_size is the number of uint32's we will need to hold the
Packit 7838c8
	 * bit-mask for all of the fields. If our highest field number is
Packit 7838c8
	 * 100, then we'll need 100 / (8*4)+1 == 4 uint32's to hold the
Packit 7838c8
	 * fieldset.
Packit 7838c8
	 *
Packit 7838c8
	 * Unlike the original code, we allocate fields dynamically based
Packit 7838c8
	 * on the requested pdir_fields_last value, allowing private
Packit 7838c8
	 * data subdirectories to contain more than the built-in code's limit
Packit 7838c8
	 * of 95 tags in a directory.
Packit 7838c8
	 */
Packit 7838c8
	fields_size = pdir_fields_last / (8*sizeof(uint32)) + 1;
Packit 7838c8
	fields = _TIFFmalloc(fields_size*sizeof(uint32));
Packit 7838c8
	_TIFFmemcpy(fields, pdir_fieldsset, fields_size * sizeof(uint32));
Packit 7838c8
Packit 7838c8
	/* Deleted "write out extra samples tag" code here. */
Packit 7838c8
Packit 7838c8
	/* Deleted code for checking a billion little special cases for the
Packit 7838c8
	 * standard TIFF tags. Should add a general mechanism for overloading
Packit 7838c8
	 * write function for each field, just like Brian kept telling me!!!
Packit 7838c8
	 */
Packit 7838c8
	for (fip = field_info; fip->field_tag; fip++) {
Packit 7838c8
		/* Deleted code to check for FIELD_IGNORE!! */
Packit 7838c8
		if (/* fip->field_bit == FIELD_IGNORE || */
Packit 7838c8
		    !FieldSet(fields, fip->field_bit))
Packit 7838c8
			continue;
Packit 7838c8
		if (!TIFFWriteNormalSubTag(tif, dir, fip, getFieldFn))
Packit 7838c8
			goto bad;
Packit 7838c8
		dir++;
Packit 7838c8
		ResetFieldBit(fields, fip->field_bit);
Packit 7838c8
	}
Packit 7838c8
Packit 7838c8
	/* Now we've written all of the referenced data, and are about to
Packit 7838c8
	   write the main directory structure, so grab the tif_dataoff value
Packit 7838c8
	   now so we can remember where we wrote the directory. */
Packit 7838c8
	directory_offset = tif->tif_dataoff;
Packit 7838c8
Packit 7838c8
	/*
Packit 7838c8
	 * Write directory.
Packit 7838c8
	 */
Packit 7838c8
	dircount = (uint16) nfields;
Packit 7838c8
	/* Deleted code to link to the next directory - we set it to zero! */
Packit 7838c8
	nextdiroff = 0;
Packit 7838c8
	if (tif->tif_flags & TIFF_SWAB) {
Packit 7838c8
		/*
Packit 7838c8
		 * The file's byte order is opposite to the
Packit 7838c8
		 * native machine architecture.  We overwrite
Packit 7838c8
		 * the directory information with impunity
Packit 7838c8
		 * because it'll be released below after we
Packit 7838c8
		 * write it to the file.  Note that all the
Packit 7838c8
		 * other tag construction routines assume that
Packit 7838c8
		 * we do this byte-swapping; i.e. they only
Packit 7838c8
		 * byte-swap indirect data.
Packit 7838c8
		 */
Packit 7838c8
		for (dir = (TIFFDirEntry*) data; dircount; dir++, dircount--) {
Packit 7838c8
			TIFFSwabArrayOfShort(&dir->tdir_tag, 2);
Packit 7838c8
			TIFFSwabArrayOfLong(&dir->tdir_count, 2);
Packit 7838c8
		}
Packit 7838c8
		dircount = (uint16) nfields;
Packit 7838c8
		TIFFSwabShort(&dircount);
Packit 7838c8
		TIFFSwabLong(&nextdiroff);
Packit 7838c8
	}
Packit 7838c8
Packit 7838c8
	(void) TIFFSeekFile(tif, tif->tif_dataoff, SEEK_SET);
Packit 7838c8
	if (!WriteOK(tif, &dircount, sizeof (dircount))) {
Packit 7838c8
		TIFFErrorExt(tif->tif_clientdata, tif->tif_name, "Error writing private subdirectory count");
Packit 7838c8
		goto bad;
Packit 7838c8
	}
Packit 7838c8
	if (!WriteOK(tif, data, dirsize)) {
Packit 7838c8
		TIFFErrorExt(tif->tif_clientdata, tif->tif_name, "Error writing private subdirectory contents");
Packit 7838c8
		goto bad;
Packit 7838c8
	}
Packit 7838c8
	if (!WriteOK(tif, &nextdiroff, sizeof (nextdiroff))) {
Packit 7838c8
		TIFFErrorExt(tif->tif_clientdata, tif->tif_name, "Error writing private subdirectory link");
Packit 7838c8
		goto bad;
Packit 7838c8
	}
Packit 7838c8
	tif->tif_dataoff += sizeof(dircount) + dirsize + sizeof(nextdiroff);
Packit 7838c8
Packit 7838c8
	_TIFFfree(data);
Packit 7838c8
	_TIFFfree(fields);
Packit 7838c8
	tif->tif_flags &= ~TIFF_DIRTYDIRECT;
Packit 7838c8
Packit 7838c8
#if (0)
Packit 7838c8
	/* This stuff commented out because I don't think we want it for
Packit 7838c8
	   subdirectories, but I could be wrong. */
Packit 7838c8
	(*tif->tif_cleanup)(tif);
Packit 7838c8
Packit 7838c8
	/*
Packit 7838c8
	 * Reset directory-related state for subsequent
Packit 7838c8
	 * directories.
Packit 7838c8
	 */
Packit 7838c8
	TIFFDefaultDirectory(tif);
Packit 7838c8
	tif->tif_curoff = 0;
Packit 7838c8
	tif->tif_row = (uint32) -1;
Packit 7838c8
	tif->tif_curstrip = (tstrip_t) -1;
Packit 7838c8
#endif
Packit 7838c8
Packit 7838c8
	return (directory_offset);
Packit 7838c8
bad:
Packit 7838c8
	_TIFFfree(data);
Packit 7838c8
	_TIFFfree(fields);
Packit 7838c8
	return (0);
Packit 7838c8
}
Packit 7838c8
#undef WriteRationalPair
Packit 7838c8
Packit 7838c8
/*
Packit 7838c8
 * Process tags that are not special cased.
Packit 7838c8
 */
Packit 7838c8
/* The standard function TIFFWriteNormalTag() could definitely be replaced
Packit 7838c8
   with a simple call to this function, just adding TIFFGetField() as the
Packit 7838c8
   last argument. */
Packit 7838c8
static int
Packit 7838c8
TIFFWriteNormalSubTag(TIFF* tif, TIFFDirEntry* dir, const TIFFFieldInfo* fip,
Packit 7838c8
		      int (*getFieldFn)(TIFF *tif, ttag_t tag, ...))
Packit 7838c8
{
Packit 7838c8
	u_short wc = (u_short) fip->field_writecount;
Packit 7838c8
Packit 7838c8
	dir->tdir_tag = fip->field_tag;
Packit 7838c8
	dir->tdir_type = (u_short) fip->field_type;
Packit 7838c8
	dir->tdir_count = wc;
Packit 7838c8
#define	WRITEF(x,y)	x(tif, fip->field_type, fip->field_tag, dir, wc, y)
Packit 7838c8
	switch (fip->field_type) {
Packit 7838c8
	case TIFF_SHORT:
Packit 7838c8
	case TIFF_SSHORT:
Packit 7838c8
		if (wc > 1) {
Packit 7838c8
			uint16* wp;
Packit 7838c8
			if (wc == (u_short) TIFF_VARIABLE) {
Packit 7838c8
				(*getFieldFn)(tif, fip->field_tag, &wc, &wp);
Packit 7838c8
				dir->tdir_count = wc;
Packit 7838c8
			} else
Packit 7838c8
				(*getFieldFn)(tif, fip->field_tag, &wp);
Packit 7838c8
			if (!WRITEF(TIFFWriteShortArray, wp))
Packit 7838c8
				return (0);
Packit 7838c8
		} else {
Packit 7838c8
			uint16 sv;
Packit 7838c8
			(*getFieldFn)(tif, fip->field_tag, &sv;;
Packit 7838c8
			dir->tdir_offset =
Packit 7838c8
			    TIFFInsertData(tif, dir->tdir_type, sv);
Packit 7838c8
		}
Packit 7838c8
		break;
Packit 7838c8
	case TIFF_LONG:
Packit 7838c8
	case TIFF_SLONG:
Packit 7838c8
		if (wc > 1) {
Packit 7838c8
			uint32* lp;
Packit 7838c8
			if (wc == (u_short) TIFF_VARIABLE) {
Packit 7838c8
				(*getFieldFn)(tif, fip->field_tag, &wc, &lp);
Packit 7838c8
				dir->tdir_count = wc;
Packit 7838c8
			} else
Packit 7838c8
				(*getFieldFn)(tif, fip->field_tag, &lp);
Packit 7838c8
			if (!WRITEF(TIFFWriteLongArray, lp))
Packit 7838c8
				return (0);
Packit 7838c8
		} else {
Packit 7838c8
			/* XXX handle LONG->SHORT conversion */
Packit 7838c8
			(*getFieldFn)(tif, fip->field_tag, &dir->tdir_offset);
Packit 7838c8
		}
Packit 7838c8
		break;
Packit 7838c8
	case TIFF_RATIONAL:
Packit 7838c8
	case TIFF_SRATIONAL:
Packit 7838c8
		if (wc > 1) {
Packit 7838c8
			float* fp;
Packit 7838c8
			if (wc == (u_short) TIFF_VARIABLE) {
Packit 7838c8
				(*getFieldFn)(tif, fip->field_tag, &wc, &fp);
Packit 7838c8
				dir->tdir_count = wc;
Packit 7838c8
			} else
Packit 7838c8
				(*getFieldFn)(tif, fip->field_tag, &fp);
Packit 7838c8
			if (!WRITEF(TIFFWriteRationalArray, fp))
Packit 7838c8
				return (0);
Packit 7838c8
		} else {
Packit 7838c8
			float fv;
Packit 7838c8
			(*getFieldFn)(tif, fip->field_tag, &fv;;
Packit 7838c8
			if (!WRITEF(TIFFWriteRationalArray, &fv))
Packit 7838c8
				return (0);
Packit 7838c8
		}
Packit 7838c8
		break;
Packit 7838c8
	case TIFF_FLOAT:
Packit 7838c8
		if (wc > 1) {
Packit 7838c8
			float* fp;
Packit 7838c8
			if (wc == (u_short) TIFF_VARIABLE) {
Packit 7838c8
				(*getFieldFn)(tif, fip->field_tag, &wc, &fp);
Packit 7838c8
				dir->tdir_count = wc;
Packit 7838c8
			} else
Packit 7838c8
				(*getFieldFn)(tif, fip->field_tag, &fp);
Packit 7838c8
			if (!WRITEF(TIFFWriteFloatArray, fp))
Packit 7838c8
				return (0);
Packit 7838c8
		} else {
Packit 7838c8
			float fv;
Packit 7838c8
			(*getFieldFn)(tif, fip->field_tag, &fv;;
Packit 7838c8
			if (!WRITEF(TIFFWriteFloatArray, &fv))
Packit 7838c8
				return (0);
Packit 7838c8
		}
Packit 7838c8
		break;
Packit 7838c8
	case TIFF_DOUBLE:
Packit 7838c8
		/* Hey - I think this is a bug, or at least a "gross
Packit 7838c8
		   inconsistency", in the TIFF library. Look at the original
Packit 7838c8
		   TIFF library code below within the "#if (0) ... #else".
Packit 7838c8
		   Just from the type of *dp, you can see that this code
Packit 7838c8
		   expects TIFFGetField() to be handed a double ** for
Packit 7838c8
		   any TIFF_DOUBLE tag, even for the constant wc==1 case.
Packit 7838c8
		   This is totally inconsistent with other fields (like
Packit 7838c8
		   TIFF_FLOAT, above) and is also inconsistent with the
Packit 7838c8
		   TIFFSetField() function for TIFF_DOUBLEs, which expects
Packit 7838c8
		   to be passed a single double by value for the wc==1 case.
Packit 7838c8
		   (See the handling of TIFFFetchNormalTag() in tif_dirread.c
Packit 7838c8
		   for an example.) Maybe this function was written before
Packit 7838c8
		   TIFFWriteDoubleArray() was written, not that that's an
Packit 7838c8
		   excuse. Anyway, the new code below is a trivial modification
Packit 7838c8
		   of the TIFF_FLOAT code above. The fact that even single
Packit 7838c8
		   doubles get written out in the data segment and get an
Packit 7838c8
		   offset value stored is irrelevant here - that is all
Packit 7838c8
		   handled by TIFFWriteDoubleArray(). */
Packit 7838c8
#if (0)
Packit 7838c8
		{ double* dp;
Packit 7838c8
		  if (wc == (u_short) TIFF_VARIABLE) {
Packit 7838c8
			(*getFieldFn)(tif, fip->field_tag, &wc, &dp;;
Packit 7838c8
			dir->tdir_count = wc;
Packit 7838c8
		  } else
Packit 7838c8
			(*getFieldFn)(tif, fip->field_tag, &dp;;
Packit 7838c8
		  TIFFCvtNativeToIEEEDouble(tif, wc, dp);
Packit 7838c8
		  if (!TIFFWriteData(tif, dir, (char*) dp))
Packit 7838c8
			return (0);
Packit 7838c8
		}
Packit 7838c8
#else
Packit 7838c8
		if (wc > 1) {
Packit 7838c8
			double* dp;
Packit 7838c8
			if (wc == (u_short) TIFF_VARIABLE) {
Packit 7838c8
				(*getFieldFn)(tif, fip->field_tag, &wc, &dp;;
Packit 7838c8
				dir->tdir_count = wc;
Packit 7838c8
			} else
Packit 7838c8
				(*getFieldFn)(tif, fip->field_tag, &dp;;
Packit 7838c8
			if (!WRITEF(TIFFWriteDoubleArray, dp))
Packit 7838c8
				return (0);
Packit 7838c8
		} else {
Packit 7838c8
			double dv;
Packit 7838c8
			(*getFieldFn)(tif, fip->field_tag, &dv;;
Packit 7838c8
			if (!WRITEF(TIFFWriteDoubleArray, &dv))
Packit 7838c8
				return (0);
Packit 7838c8
		}
Packit 7838c8
#endif
Packit 7838c8
		break;
Packit 7838c8
	case TIFF_ASCII:
Packit 7838c8
		{ char* cp;
Packit 7838c8
		  (*getFieldFn)(tif, fip->field_tag, &cp;;
Packit 7838c8
		  dir->tdir_count = (uint32) (strlen(cp) + 1);
Packit 7838c8
		  if (!TIFFWriteByteArray(tif, dir, cp))
Packit 7838c8
			return (0);
Packit 7838c8
		}
Packit 7838c8
		break;
Packit 7838c8
	case TIFF_UNDEFINED:
Packit 7838c8
		{ char* cp;
Packit 7838c8
		  if (wc == (u_short) TIFF_VARIABLE) {
Packit 7838c8
			(*getFieldFn)(tif, fip->field_tag, &wc, &cp;;
Packit 7838c8
			dir->tdir_count = wc;
Packit 7838c8
		  } else 
Packit 7838c8
			(*getFieldFn)(tif, fip->field_tag, &cp;;
Packit 7838c8
		  if (!TIFFWriteByteArray(tif, dir, cp))
Packit 7838c8
			return (0);
Packit 7838c8
		}
Packit 7838c8
		break;
Packit 7838c8
	}
Packit 7838c8
	return (1);
Packit 7838c8
}
Packit 7838c8
#undef WRITEF
Packit 7838c8
Packit 7838c8
/* Everything after this is exactly duplicated from the standard tif_dirwrite.c
Packit 7838c8
   file, necessitated by the fact that they are declared static there so
Packit 7838c8
   we can't call them!
Packit 7838c8
*/
Packit 7838c8
/*
Packit 7838c8
 * Setup a directory entry with either a SHORT
Packit 7838c8
 * or LONG type according to the value.
Packit 7838c8
 */
Packit 7838c8
static void
Packit 7838c8
TIFFSetupShortLong(TIFF* tif, ttag_t tag, TIFFDirEntry* dir, uint32 v)
Packit 7838c8
{
Packit 7838c8
	dir->tdir_tag = tag;
Packit 7838c8
	dir->tdir_count = 1;
Packit 7838c8
	if (v > 0xffffL) {
Packit 7838c8
		dir->tdir_type = (short) TIFF_LONG;
Packit 7838c8
		dir->tdir_offset = v;
Packit 7838c8
	} else {
Packit 7838c8
		dir->tdir_type = (short) TIFF_SHORT;
Packit 7838c8
		dir->tdir_offset = TIFFInsertData(tif, (int) TIFF_SHORT, v);
Packit 7838c8
	}
Packit 7838c8
}
Packit 7838c8
#undef MakeShortDirent
Packit 7838c8
Packit 7838c8
#ifndef TIFFWriteRational
Packit 7838c8
/*
Packit 7838c8
 * Setup a RATIONAL directory entry and
Packit 7838c8
 * write the associated indirect value.
Packit 7838c8
 */
Packit 7838c8
static int
Packit 7838c8
TIFFWriteRational(TIFF* tif,
Packit 7838c8
    TIFFDataType type, ttag_t tag, TIFFDirEntry* dir, float v)
Packit 7838c8
{
Packit 7838c8
	return (TIFFWriteRationalArray(tif, type, tag, dir, 1, &v);;
Packit 7838c8
}
Packit 7838c8
#endif
Packit 7838c8
Packit 7838c8
#define	NITEMS(x)	(sizeof (x) / sizeof (x[0]))
Packit 7838c8
/*
Packit 7838c8
 * Setup a directory entry that references a
Packit 7838c8
 * samples/pixel array of SHORT values and
Packit 7838c8
 * (potentially) write the associated indirect
Packit 7838c8
 * values.
Packit 7838c8
 */
Packit 7838c8
static int
Packit 7838c8
TIFFWritePerSampleShorts(TIFF* tif, ttag_t tag, TIFFDirEntry* dir)
Packit 7838c8
{
Packit 7838c8
	uint16 buf[10], v;
Packit 7838c8
	uint16* w = buf;
Packit 7838c8
	int i, status, samples = tif->tif_dir.td_samplesperpixel;
Packit 7838c8
Packit 7838c8
	if (samples > NITEMS(buf))
Packit 7838c8
		w = (uint16*) _TIFFmalloc(samples * sizeof (uint16));
Packit 7838c8
	TIFFGetField(tif, tag, &v);
Packit 7838c8
	for (i = 0; i < samples; i++)
Packit 7838c8
		w[i] = v;
Packit 7838c8
	status = TIFFWriteShortArray(tif, TIFF_SHORT, tag, dir, samples, w);
Packit 7838c8
	if (w != buf)
Packit 7838c8
		_TIFFfree((char*) w);
Packit 7838c8
	return (status);
Packit 7838c8
}
Packit 7838c8
Packit 7838c8
/*
Packit 7838c8
 * Setup a directory entry that references a samples/pixel array of ``type''
Packit 7838c8
 * values and (potentially) write the associated indirect values.  The source
Packit 7838c8
 * data from TIFFGetField() for the specified tag must be returned as double.
Packit 7838c8
 */
Packit 7838c8
static int
Packit 7838c8
TIFFWritePerSampleAnys(TIFF* tif,
Packit 7838c8
    TIFFDataType type, ttag_t tag, TIFFDirEntry* dir)
Packit 7838c8
{
Packit 7838c8
	double buf[10], v;
Packit 7838c8
	double* w = buf;
Packit 7838c8
	int i, status;
Packit 7838c8
	int samples = (int) tif->tif_dir.td_samplesperpixel;
Packit 7838c8
Packit 7838c8
	if (samples > NITEMS(buf))
Packit 7838c8
		w = (double*) _TIFFmalloc(samples * sizeof (double));
Packit 7838c8
	TIFFGetField(tif, tag, &v);
Packit 7838c8
	for (i = 0; i < samples; i++)
Packit 7838c8
		w[i] = v;
Packit 7838c8
	status = TIFFWriteAnyArray(tif, type, tag, dir, samples, w);
Packit 7838c8
	if (w != buf)
Packit 7838c8
		_TIFFfree(w);
Packit 7838c8
	return (status);
Packit 7838c8
}
Packit 7838c8
#undef NITEMS
Packit 7838c8
Packit 7838c8
/*
Packit 7838c8
 * Setup a pair of shorts that are returned by
Packit 7838c8
 * value, rather than as a reference to an array.
Packit 7838c8
 */
Packit 7838c8
static int
Packit 7838c8
TIFFSetupShortPair(TIFF* tif, ttag_t tag, TIFFDirEntry* dir)
Packit 7838c8
{
Packit 7838c8
	uint16 v[2];
Packit 7838c8
Packit 7838c8
	TIFFGetField(tif, tag, &v[0], &v[1]);
Packit 7838c8
	return (TIFFWriteShortArray(tif, TIFF_SHORT, tag, dir, 2, v));
Packit 7838c8
}
Packit 7838c8
Packit 7838c8
/*
Packit 7838c8
 * Setup a directory entry for an NxM table of shorts,
Packit 7838c8
 * where M is known to be 2**bitspersample, and write
Packit 7838c8
 * the associated indirect data.
Packit 7838c8
 */
Packit 7838c8
static int
Packit 7838c8
TIFFWriteShortTable(TIFF* tif,
Packit 7838c8
    ttag_t tag, TIFFDirEntry* dir, uint32 n, uint16** table)
Packit 7838c8
{
Packit 7838c8
	uint32 i, off;
Packit 7838c8
Packit 7838c8
	dir->tdir_tag = tag;
Packit 7838c8
	dir->tdir_type = (short) TIFF_SHORT;
Packit 7838c8
	/* XXX -- yech, fool TIFFWriteData */
Packit 7838c8
	dir->tdir_count = (uint32) (1L<<tif->tif_dir.td_bitspersample);
Packit 7838c8
	off = tif->tif_dataoff;
Packit 7838c8
	for (i = 0; i < n; i++)
Packit 7838c8
		if (!TIFFWriteData(tif, dir, (char *)table[i]))
Packit 7838c8
			return (0);
Packit 7838c8
	dir->tdir_count *= n;
Packit 7838c8
	dir->tdir_offset = off;
Packit 7838c8
	return (1);
Packit 7838c8
}
Packit 7838c8
Packit 7838c8
/*
Packit 7838c8
 * Write/copy data associated with an ASCII or opaque tag value.
Packit 7838c8
 */
Packit 7838c8
static int
Packit 7838c8
TIFFWriteByteArray(TIFF* tif, TIFFDirEntry* dir, char* cp)
Packit 7838c8
{
Packit 7838c8
	if (dir->tdir_count > 4) {
Packit 7838c8
		if (!TIFFWriteData(tif, dir, cp))
Packit 7838c8
			return (0);
Packit 7838c8
	} else
Packit 7838c8
		_TIFFmemcpy(&dir->tdir_offset, cp, dir->tdir_count);
Packit 7838c8
	return (1);
Packit 7838c8
}
Packit 7838c8
Packit 7838c8
/*
Packit 7838c8
 * Setup a directory entry of an array of SHORT
Packit 7838c8
 * or SSHORT and write the associated indirect values.
Packit 7838c8
 */
Packit 7838c8
static int
Packit 7838c8
TIFFWriteShortArray(TIFF* tif,
Packit 7838c8
    TIFFDataType type, ttag_t tag, TIFFDirEntry* dir, uint32 n, uint16* v)
Packit 7838c8
{
Packit 7838c8
	dir->tdir_tag = tag;
Packit 7838c8
	dir->tdir_type = (short) type;
Packit 7838c8
	dir->tdir_count = n;
Packit 7838c8
	if (n <= 2) {
Packit 7838c8
		if (tif->tif_header.tiff_magic == TIFF_BIGENDIAN) {
Packit 7838c8
			dir->tdir_offset = (uint32) ((long) v[0] << 16);
Packit 7838c8
			if (n == 2)
Packit 7838c8
				dir->tdir_offset |= v[1] & 0xffff;
Packit 7838c8
		} else {
Packit 7838c8
			dir->tdir_offset = v[0] & 0xffff;
Packit 7838c8
			if (n == 2)
Packit 7838c8
				dir->tdir_offset |= (long) v[1] << 16;
Packit 7838c8
		}
Packit 7838c8
		return (1);
Packit 7838c8
	} else
Packit 7838c8
		return (TIFFWriteData(tif, dir, (char*) v));
Packit 7838c8
}
Packit 7838c8
Packit 7838c8
/*
Packit 7838c8
 * Setup a directory entry of an array of LONG
Packit 7838c8
 * or SLONG and write the associated indirect values.
Packit 7838c8
 */
Packit 7838c8
static int
Packit 7838c8
TIFFWriteLongArray(TIFF* tif,
Packit 7838c8
    TIFFDataType type, ttag_t tag, TIFFDirEntry* dir, uint32 n, uint32* v)
Packit 7838c8
{
Packit 7838c8
	dir->tdir_tag = tag;
Packit 7838c8
	dir->tdir_type = (short) type;
Packit 7838c8
	dir->tdir_count = n;
Packit 7838c8
	if (n == 1) {
Packit 7838c8
		dir->tdir_offset = v[0];
Packit 7838c8
		return (1);
Packit 7838c8
	} else
Packit 7838c8
		return (TIFFWriteData(tif, dir, (char*) v));
Packit 7838c8
}
Packit 7838c8
Packit 7838c8
/*
Packit 7838c8
 * Setup a directory entry of an array of RATIONAL
Packit 7838c8
 * or SRATIONAL and write the associated indirect values.
Packit 7838c8
 */
Packit 7838c8
static int
Packit 7838c8
TIFFWriteRationalArray(TIFF* tif,
Packit 7838c8
    TIFFDataType type, ttag_t tag, TIFFDirEntry* dir, uint32 n, float* v)
Packit 7838c8
{
Packit 7838c8
	uint32 i;
Packit 7838c8
	uint32* t;
Packit 7838c8
	int status;
Packit 7838c8
Packit 7838c8
	dir->tdir_tag = tag;
Packit 7838c8
	dir->tdir_type = (short) type;
Packit 7838c8
	dir->tdir_count = n;
Packit 7838c8
	t = (uint32*) _TIFFmalloc(2*n * sizeof (uint32));
Packit 7838c8
	for (i = 0; i < n; i++) {
Packit 7838c8
		float fv = v[i];
Packit 7838c8
		int sign = 1;
Packit 7838c8
		uint32 den;
Packit 7838c8
Packit 7838c8
		if (fv < 0) {
Packit 7838c8
			if (type == TIFF_RATIONAL) {
Packit 7838c8
				TIFFWarning(tif->tif_name,
Packit 7838c8
	"\"%s\": Information lost writing value (%g) as (unsigned) RATIONAL",
Packit 7838c8
				_TIFFFieldWithTag(tif,tag)->field_name, v);
Packit 7838c8
				fv = 0;
Packit 7838c8
			} else
Packit 7838c8
				fv = -fv, sign = -1;
Packit 7838c8
		}
Packit 7838c8
		den = 1L;
Packit 7838c8
		if (fv > 0) {
Packit 7838c8
			while (fv < 1L<<(31-3) && den < 1L<<(31-3))
Packit 7838c8
				fv *= 1<<3, den *= 1L<<3;
Packit 7838c8
		}
Packit 7838c8
		t[2*i+0] = sign * (fv + 0.5);
Packit 7838c8
		t[2*i+1] = den;
Packit 7838c8
	}
Packit 7838c8
	status = TIFFWriteData(tif, dir, (char *)t);
Packit 7838c8
	_TIFFfree((char*) t);
Packit 7838c8
	return (status);
Packit 7838c8
}
Packit 7838c8
Packit 7838c8
static int
Packit 7838c8
TIFFWriteFloatArray(TIFF* tif,
Packit 7838c8
    TIFFDataType type, ttag_t tag, TIFFDirEntry* dir, uint32 n, float* v)
Packit 7838c8
{
Packit 7838c8
	dir->tdir_tag = tag;
Packit 7838c8
	dir->tdir_type = (short) type;
Packit 7838c8
	dir->tdir_count = n;
Packit 7838c8
	TIFFCvtNativeToIEEEFloat(tif, n, v);
Packit 7838c8
	if (n == 1) {
Packit 7838c8
		dir->tdir_offset = *(uint32*) &v[0];
Packit 7838c8
		return (1);
Packit 7838c8
	} else
Packit 7838c8
		return (TIFFWriteData(tif, dir, (char*) v));
Packit 7838c8
}
Packit 7838c8
Packit 7838c8
static int
Packit 7838c8
TIFFWriteDoubleArray(TIFF* tif,
Packit 7838c8
    TIFFDataType type, ttag_t tag, TIFFDirEntry* dir, uint32 n, double* v)
Packit 7838c8
{
Packit 7838c8
	dir->tdir_tag = tag;
Packit 7838c8
	dir->tdir_type = (short) type;
Packit 7838c8
	dir->tdir_count = n;
Packit 7838c8
	TIFFCvtNativeToIEEEDouble(tif, n, v);
Packit 7838c8
	return (TIFFWriteData(tif, dir, (char*) v));
Packit 7838c8
}
Packit 7838c8
Packit 7838c8
/*
Packit 7838c8
 * Write an array of ``type'' values for a specified tag (i.e. this is a tag
Packit 7838c8
 * which is allowed to have different types, e.g. SMaxSampleType).
Packit 7838c8
 * Internally the data values are represented as double since a double can
Packit 7838c8
 * hold any of the TIFF tag types (yes, this should really be an abstract
Packit 7838c8
 * type tany_t for portability).  The data is converted into the specified
Packit 7838c8
 * type in a temporary buffer and then handed off to the appropriate array
Packit 7838c8
 * writer.
Packit 7838c8
 */
Packit 7838c8
static int
Packit 7838c8
TIFFWriteAnyArray(TIFF* tif,
Packit 7838c8
    TIFFDataType type, ttag_t tag, TIFFDirEntry* dir, uint32 n, double* v)
Packit 7838c8
{
Packit 7838c8
	char buf[10 * sizeof(double)];
Packit 7838c8
	char* w = buf;
Packit 7838c8
	int i, status = 0;
Packit 7838c8
Packit 7838c8
	if (n * TIFFDataWidth(type) > sizeof buf)
Packit 7838c8
		w = (char*) _TIFFmalloc(n * TIFFDataWidth(type));
Packit 7838c8
	switch (type) {
Packit 7838c8
	case TIFF_BYTE:
Packit 7838c8
		{ unsigned char* bp = (unsigned char*) w;
Packit 7838c8
		  for (i = 0; i < n; i++)
Packit 7838c8
			bp[i] = (unsigned char) v[i];
Packit 7838c8
		  dir->tdir_tag = tag;
Packit 7838c8
		  dir->tdir_type = (short) type;
Packit 7838c8
		  dir->tdir_count = n;
Packit 7838c8
		  if (!TIFFWriteByteArray(tif, dir, (char*) bp))
Packit 7838c8
			goto out;
Packit 7838c8
		}
Packit 7838c8
		break;
Packit 7838c8
	case TIFF_SBYTE:
Packit 7838c8
		{ signed char* bp = (signed char*) w;
Packit 7838c8
		  for (i = 0; i < n; i++)
Packit 7838c8
			bp[i] = (signed char) v[i];
Packit 7838c8
		  dir->tdir_tag = tag;
Packit 7838c8
		  dir->tdir_type = (short) type;
Packit 7838c8
		  dir->tdir_count = n;
Packit 7838c8
		  if (!TIFFWriteByteArray(tif, dir, (char*) bp))
Packit 7838c8
			goto out;
Packit 7838c8
		}
Packit 7838c8
		break;
Packit 7838c8
	case TIFF_SHORT:
Packit 7838c8
		{ uint16* bp = (uint16*) w;
Packit 7838c8
		  for (i = 0; i < n; i++)
Packit 7838c8
			bp[i] = (uint16) v[i];
Packit 7838c8
		  if (!TIFFWriteShortArray(tif, type, tag, dir, n, (uint16*)bp))
Packit 7838c8
				goto out;
Packit 7838c8
		}
Packit 7838c8
		break;
Packit 7838c8
	case TIFF_SSHORT:
Packit 7838c8
		{ int16* bp = (int16*) w;
Packit 7838c8
		  for (i = 0; i < n; i++)
Packit 7838c8
			bp[i] = (int16) v[i];
Packit 7838c8
		  if (!TIFFWriteShortArray(tif, type, tag, dir, n, (uint16*)bp))
Packit 7838c8
			goto out;
Packit 7838c8
		}
Packit 7838c8
		break;
Packit 7838c8
	case TIFF_LONG:
Packit 7838c8
		{ uint32* bp = (uint32*) w;
Packit 7838c8
		  for (i = 0; i < n; i++)
Packit 7838c8
			bp[i] = (uint32) v[i];
Packit 7838c8
		  if (!TIFFWriteLongArray(tif, type, tag, dir, n, bp))
Packit 7838c8
			goto out;
Packit 7838c8
		}
Packit 7838c8
		break;
Packit 7838c8
	case TIFF_SLONG:
Packit 7838c8
		{ int32* bp = (int32*) w;
Packit 7838c8
		  for (i = 0; i < n; i++)
Packit 7838c8
			bp[i] = (int32) v[i];
Packit 7838c8
		  if (!TIFFWriteLongArray(tif, type, tag, dir, n, (uint32*) bp))
Packit 7838c8
			goto out;
Packit 7838c8
		}
Packit 7838c8
		break;
Packit 7838c8
	case TIFF_FLOAT:
Packit 7838c8
		{ float* bp = (float*) w;
Packit 7838c8
		  for (i = 0; i < n; i++)
Packit 7838c8
			bp[i] = (float) v[i];
Packit 7838c8
		  if (!TIFFWriteFloatArray(tif, type, tag, dir, n, bp))
Packit 7838c8
			goto out;
Packit 7838c8
		}
Packit 7838c8
		break;
Packit 7838c8
	case TIFF_DOUBLE:
Packit 7838c8
		return (TIFFWriteDoubleArray(tif, type, tag, dir, n, v));
Packit 7838c8
	default:
Packit 7838c8
		/* TIFF_NOTYPE */
Packit 7838c8
		/* TIFF_ASCII */
Packit 7838c8
		/* TIFF_UNDEFINED */
Packit 7838c8
		/* TIFF_RATIONAL */
Packit 7838c8
		/* TIFF_SRATIONAL */
Packit 7838c8
		goto out;
Packit 7838c8
	}
Packit 7838c8
	status = 1;
Packit 7838c8
 out:
Packit 7838c8
	if (w != buf)
Packit 7838c8
		_TIFFfree(w);
Packit 7838c8
	return (status);
Packit 7838c8
}
Packit 7838c8
Packit 7838c8
#ifdef COLORIMETRY_SUPPORT
Packit 7838c8
static int
Packit 7838c8
TIFFWriteTransferFunction(TIFF* tif, TIFFDirEntry* dir)
Packit 7838c8
{
Packit 7838c8
	TIFFDirectory* td = &tif->tif_dir;
Packit 7838c8
	tsize_t n = (1L<<td->td_bitspersample) * sizeof (uint16);
Packit 7838c8
	uint16** tf = td->td_transferfunction;
Packit 7838c8
	int ncols;
Packit 7838c8
Packit 7838c8
	/*
Packit 7838c8
	 * Check if the table can be written as a single column,
Packit 7838c8
	 * or if it must be written as 3 columns.  Note that we
Packit 7838c8
	 * write a 3-column tag if there are 2 samples/pixel and
Packit 7838c8
	 * a single column of data won't suffice--hmm.
Packit 7838c8
	 */
Packit 7838c8
	switch (td->td_samplesperpixel - td->td_extrasamples) {
Packit 7838c8
	default:	if (_TIFFmemcmp(tf[0], tf[2], n)) { ncols = 3; break; }
Packit 7838c8
	case 2:		if (_TIFFmemcmp(tf[0], tf[1], n)) { ncols = 3; break; }
Packit 7838c8
	case 1: case 0:	ncols = 1;
Packit 7838c8
	}
Packit 7838c8
	return (TIFFWriteShortTable(tif,
Packit 7838c8
	    TIFFTAG_TRANSFERFUNCTION, dir, ncols, tf));
Packit 7838c8
}
Packit 7838c8
#endif
Packit 7838c8
Packit 7838c8
/*
Packit 7838c8
 * Write a contiguous directory item.
Packit 7838c8
 */
Packit 7838c8
static int
Packit 7838c8
TIFFWriteData(TIFF* tif, TIFFDirEntry* dir, char* cp)
Packit 7838c8
{
Packit 7838c8
	tsize_t cc;
Packit 7838c8
Packit 7838c8
	if (tif->tif_flags & TIFF_SWAB) {
Packit 7838c8
		switch (dir->tdir_type) {
Packit 7838c8
		case TIFF_SHORT:
Packit 7838c8
		case TIFF_SSHORT:
Packit 7838c8
			TIFFSwabArrayOfShort((uint16*) cp, dir->tdir_count);
Packit 7838c8
			break;
Packit 7838c8
		case TIFF_LONG:
Packit 7838c8
		case TIFF_SLONG:
Packit 7838c8
		case TIFF_FLOAT:
Packit 7838c8
			TIFFSwabArrayOfLong((uint32*) cp, dir->tdir_count);
Packit 7838c8
			break;
Packit 7838c8
		case TIFF_RATIONAL:
Packit 7838c8
		case TIFF_SRATIONAL:
Packit 7838c8
			TIFFSwabArrayOfLong((uint32*) cp, 2*dir->tdir_count);
Packit 7838c8
			break;
Packit 7838c8
		case TIFF_DOUBLE:
Packit 7838c8
			TIFFSwabArrayOfDouble((double*) cp, dir->tdir_count);
Packit 7838c8
			break;
Packit 7838c8
		}
Packit 7838c8
	}
Packit 7838c8
	dir->tdir_offset = tif->tif_dataoff;
Packit 7838c8
	cc = dir->tdir_count * TIFFDataWidth(dir->tdir_type);
Packit 7838c8
	if (SeekOK(tif, dir->tdir_offset) &&
Packit 7838c8
	    WriteOK(tif, cp, cc)) {
Packit 7838c8
		tif->tif_dataoff += (cc + 1) & ~1;
Packit 7838c8
		return (1);
Packit 7838c8
	}
Packit 7838c8
	TIFFErrorExt(tif->tif_clientdata, tif->tif_name, "Error writing data for field \"%s\"",
Packit 7838c8
	    _TIFFFieldWithTag(tif, dir->tdir_tag)->field_name);
Packit 7838c8
	return (0);
Packit 7838c8
}
Packit 7838c8
Packit 7838c8
/*
Packit 7838c8
 * Link the current directory into the
Packit 7838c8
 * directory chain for the file.
Packit 7838c8
 */
Packit 7838c8
static int
Packit 7838c8
TIFFLinkDirectory(TIFF* tif)
Packit 7838c8
{
Packit 7838c8
	static const char module[] = "TIFFLinkDirectory";
Packit 7838c8
	uint32 nextdir;
Packit 7838c8
	uint32 diroff;
Packit 7838c8
Packit 7838c8
	tif->tif_diroff = (TIFFSeekFile(tif, (toff_t) 0, SEEK_END)+1) &~ 1;
Packit 7838c8
	diroff = (uint32) tif->tif_diroff;
Packit 7838c8
	if (tif->tif_flags & TIFF_SWAB)
Packit 7838c8
		TIFFSwabLong(&diroff);
Packit 7838c8
#if SUBIFD_SUPPORT
Packit 7838c8
	if (tif->tif_flags & TIFF_INSUBIFD) {
Packit 7838c8
		(void) TIFFSeekFile(tif, tif->tif_subifdoff, SEEK_SET);
Packit 7838c8
		if (!WriteOK(tif, &diroff, sizeof (diroff))) {
Packit 7838c8
			TIFFErrorExt(tif->tif_clientdata, module,
Packit 7838c8
			    "%s: Error writing SubIFD directory link",
Packit 7838c8
			    tif->tif_name);
Packit 7838c8
			return (0);
Packit 7838c8
		}
Packit 7838c8
		/*
Packit 7838c8
		 * Advance to the next SubIFD or, if this is
Packit 7838c8
		 * the last one configured, revert back to the
Packit 7838c8
		 * normal directory linkage.
Packit 7838c8
		 */
Packit 7838c8
		if (--tif->tif_nsubifd)
Packit 7838c8
			tif->tif_subifdoff += sizeof (diroff);
Packit 7838c8
		else
Packit 7838c8
			tif->tif_flags &= ~TIFF_INSUBIFD;
Packit 7838c8
		return (1);
Packit 7838c8
	}
Packit 7838c8
#endif
Packit 7838c8
	if (tif->tif_header.tiff_diroff == 0) {
Packit 7838c8
		/*
Packit 7838c8
		 * First directory, overwrite offset in header.
Packit 7838c8
		 */
Packit 7838c8
		tif->tif_header.tiff_diroff = (uint32) tif->tif_diroff;
Packit 7838c8
#define	HDROFF(f)	((toff_t) &(((TIFFHeader*) 0)->f))
Packit 7838c8
		(void) TIFFSeekFile(tif, HDROFF(tiff_diroff), SEEK_SET);
Packit 7838c8
		if (!WriteOK(tif, &diroff, sizeof (diroff))) {
Packit 7838c8
			TIFFErrorExt(tif->tif_clientdata, tif->tif_name, "Error writing TIFF header");
Packit 7838c8
			return (0);
Packit 7838c8
		}
Packit 7838c8
		return (1);
Packit 7838c8
	}
Packit 7838c8
	/*
Packit 7838c8
	 * Not the first directory, search to the last and append.
Packit 7838c8
	 */
Packit 7838c8
	nextdir = tif->tif_header.tiff_diroff;
Packit 7838c8
	do {
Packit 7838c8
		uint16 dircount;
Packit 7838c8
Packit 7838c8
		if (!SeekOK(tif, nextdir) ||
Packit 7838c8
		    !ReadOK(tif, &dircount, sizeof (dircount))) {
Packit 7838c8
			TIFFErrorExt(tif->tif_clientdata, module, "Error fetching directory count");
Packit 7838c8
			return (0);
Packit 7838c8
		}
Packit 7838c8
		if (tif->tif_flags & TIFF_SWAB)
Packit 7838c8
			TIFFSwabShort(&dircount);
Packit 7838c8
		(void) TIFFSeekFile(tif,
Packit 7838c8
		    dircount * sizeof (TIFFDirEntry), SEEK_CUR);
Packit 7838c8
		if (!ReadOK(tif, &nextdir, sizeof (nextdir))) {
Packit 7838c8
			TIFFErrorExt(tif->tif_clientdata, module, "Error fetching directory link");
Packit 7838c8
			return (0);
Packit 7838c8
		}
Packit 7838c8
		if (tif->tif_flags & TIFF_SWAB)
Packit 7838c8
			TIFFSwabLong(&nextdir);
Packit 7838c8
	} while (nextdir != 0);
Packit 7838c8
	(void) TIFFSeekFile(tif, -(toff_t) sizeof (nextdir), SEEK_CUR);
Packit 7838c8
	if (!WriteOK(tif, &diroff, sizeof (diroff))) {
Packit 7838c8
		TIFFErrorExt(tif->tif_clientdata, module, "Error writing directory link");
Packit 7838c8
		return (0);
Packit 7838c8
	}
Packit 7838c8
	return (1);
Packit 7838c8
}
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
 */