1/* $Id: tif_dirwrite.c,v 1.85 2017-01-11 16:09:02 erouault 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#include <float.h>
34
35#ifdef HAVE_IEEEFP
36#define TIFFCvtNativeToIEEEFloat(tif, n, fp)
37#define TIFFCvtNativeToIEEEDouble(tif, n, dp)
38#else
39extern void TIFFCvtNativeToIEEEFloat(TIFF* tif, uint32 n, float* fp);
40extern void TIFFCvtNativeToIEEEDouble(TIFF* tif, uint32 n, double* dp);
41#endif
42
43static int TIFFWriteDirectorySec(TIFF* tif, int isimage, int imagedone, uint64* pdiroff);
44
45static int TIFFWriteDirectoryTagSampleformatArray(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, double* value);
46#if 0
47static int TIFFWriteDirectoryTagSampleformatPerSample(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, double value);
48#endif
49
50static int TIFFWriteDirectoryTagAscii(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, char* value);
51static int TIFFWriteDirectoryTagUndefinedArray(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, uint8* value);
52#ifdef notdef
53static int TIFFWriteDirectoryTagByte(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint8 value);
54#endif
55static int TIFFWriteDirectoryTagByteArray(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, uint8* value);
56#if 0
57static int TIFFWriteDirectoryTagBytePerSample(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint8 value);
58#endif
59#ifdef notdef
60static int TIFFWriteDirectoryTagSbyte(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, int8 value);
61#endif
62static int TIFFWriteDirectoryTagSbyteArray(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, int8* value);
63#if 0
64static int TIFFWriteDirectoryTagSbytePerSample(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, int8 value);
65#endif
66static int TIFFWriteDirectoryTagShort(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint16 value);
67static int TIFFWriteDirectoryTagShortArray(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, uint16* value);
68static int TIFFWriteDirectoryTagShortPerSample(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint16 value);
69#ifdef notdef
70static int TIFFWriteDirectoryTagSshort(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, int16 value);
71#endif
72static int TIFFWriteDirectoryTagSshortArray(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, int16* value);
73#if 0
74static int TIFFWriteDirectoryTagSshortPerSample(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, int16 value);
75#endif
76static int TIFFWriteDirectoryTagLong(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 value);
77static int TIFFWriteDirectoryTagLongArray(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, uint32* value);
78#if 0
79static int TIFFWriteDirectoryTagLongPerSample(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 value);
80#endif
81#ifdef notdef
82static int TIFFWriteDirectoryTagSlong(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, int32 value);
83#endif
84static int TIFFWriteDirectoryTagSlongArray(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, int32* value);
85#if 0
86static int TIFFWriteDirectoryTagSlongPerSample(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, int32 value);
87#endif
88#ifdef notdef
89static int TIFFWriteDirectoryTagLong8(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint64 value);
90#endif
91static int TIFFWriteDirectoryTagLong8Array(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, uint64* value);
92#ifdef notdef
93static int TIFFWriteDirectoryTagSlong8(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, int64 value);
94#endif
95static int TIFFWriteDirectoryTagSlong8Array(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, int64* value);
96static int TIFFWriteDirectoryTagRational(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, double value);
97static int TIFFWriteDirectoryTagRationalArray(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, float* value);
98static int TIFFWriteDirectoryTagSrationalArray(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, float* value);
99#ifdef notdef
100static int TIFFWriteDirectoryTagFloat(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, float value);
101#endif
102static int TIFFWriteDirectoryTagFloatArray(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, float* value);
103#if 0
104static int TIFFWriteDirectoryTagFloatPerSample(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, float value);
105#endif
106#ifdef notdef
107static int TIFFWriteDirectoryTagDouble(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, double value);
108#endif
109static int TIFFWriteDirectoryTagDoubleArray(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, double* value);
110#if 0
111static int TIFFWriteDirectoryTagDoublePerSample(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, double value);
112#endif
113static int TIFFWriteDirectoryTagIfdArray(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, uint32* value);
114#ifdef notdef
115static int TIFFWriteDirectoryTagIfd8Array(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, uint64* value);
116#endif
117static int TIFFWriteDirectoryTagShortLong(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 value);
118static int TIFFWriteDirectoryTagLongLong8Array(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, uint64* value);
119static int TIFFWriteDirectoryTagIfdIfd8Array(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, uint64* value);
120#ifdef notdef
121static int TIFFWriteDirectoryTagShortLongLong8Array(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, uint64* value);
122#endif
123static int TIFFWriteDirectoryTagColormap(TIFF* tif, uint32* ndir, TIFFDirEntry* dir);
124static int TIFFWriteDirectoryTagTransferfunction(TIFF* tif, uint32* ndir, TIFFDirEntry* dir);
125static int TIFFWriteDirectoryTagSubifd(TIFF* tif, uint32* ndir, TIFFDirEntry* dir);
126
127static int TIFFWriteDirectoryTagCheckedAscii(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, char* value);
128static int TIFFWriteDirectoryTagCheckedUndefinedArray(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, uint8* value);
129#ifdef notdef
130static int TIFFWriteDirectoryTagCheckedByte(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint8 value);
131#endif
132static int TIFFWriteDirectoryTagCheckedByteArray(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, uint8* value);
133#ifdef notdef
134static int TIFFWriteDirectoryTagCheckedSbyte(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, int8 value);
135#endif
136static int TIFFWriteDirectoryTagCheckedSbyteArray(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, int8* value);
137static int TIFFWriteDirectoryTagCheckedShort(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint16 value);
138static int TIFFWriteDirectoryTagCheckedShortArray(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, uint16* value);
139#ifdef notdef
140static int TIFFWriteDirectoryTagCheckedSshort(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, int16 value);
141#endif
142static int TIFFWriteDirectoryTagCheckedSshortArray(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, int16* value);
143static int TIFFWriteDirectoryTagCheckedLong(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 value);
144static int TIFFWriteDirectoryTagCheckedLongArray(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, uint32* value);
145#ifdef notdef
146static int TIFFWriteDirectoryTagCheckedSlong(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, int32 value);
147#endif
148static int TIFFWriteDirectoryTagCheckedSlongArray(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, int32* value);
149#ifdef notdef
150static int TIFFWriteDirectoryTagCheckedLong8(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint64 value);
151#endif
152static int TIFFWriteDirectoryTagCheckedLong8Array(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, uint64* value);
153#ifdef notdef
154static int TIFFWriteDirectoryTagCheckedSlong8(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, int64 value);
155#endif
156static int TIFFWriteDirectoryTagCheckedSlong8Array(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, int64* value);
157static int TIFFWriteDirectoryTagCheckedRational(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, double value);
158static int TIFFWriteDirectoryTagCheckedRationalArray(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, float* value);
159static int TIFFWriteDirectoryTagCheckedSrationalArray(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, float* value);
160#ifdef notdef
161static int TIFFWriteDirectoryTagCheckedFloat(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, float value);
162#endif
163static int TIFFWriteDirectoryTagCheckedFloatArray(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, float* value);
164#ifdef notdef
165static int TIFFWriteDirectoryTagCheckedDouble(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, double value);
166#endif
167static int TIFFWriteDirectoryTagCheckedDoubleArray(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, double* value);
168static int TIFFWriteDirectoryTagCheckedIfdArray(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, uint32* value);
169static int TIFFWriteDirectoryTagCheckedIfd8Array(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, uint64* value);
170
171static int TIFFWriteDirectoryTagData(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint16 datatype, uint32 count, uint32 datalength, void* data);
172
173static int TIFFLinkDirectory(TIFF*);
174
175/*
176 * Write the contents of the current directory
177 * to the specified file.  This routine doesn't
178 * handle overwriting a directory with auxiliary
179 * storage that's been changed.
180 */
181int
182TIFFWriteDirectory(TIFF* tif)
183{
184	return TIFFWriteDirectorySec(tif,TRUE,TRUE,NULL);
185}
186
187/*
188 * Similar to TIFFWriteDirectory(), writes the directory out
189 * but leaves all data structures in memory so that it can be
190 * written again.  This will make a partially written TIFF file
191 * readable before it is successfully completed/closed.
192 */
193int
194TIFFCheckpointDirectory(TIFF* tif)
195{
196	int rc;
197	/* Setup the strips arrays, if they haven't already been. */
198	if (tif->tif_dir.td_stripoffset == NULL)
199	    (void) TIFFSetupStrips(tif);
200	rc = TIFFWriteDirectorySec(tif,TRUE,FALSE,NULL);
201	(void) TIFFSetWriteOffset(tif, TIFFSeekFile(tif, 0, SEEK_END));
202	return rc;
203}
204
205int
206TIFFWriteCustomDirectory(TIFF* tif, uint64* pdiroff)
207{
208	return TIFFWriteDirectorySec(tif,FALSE,FALSE,pdiroff);
209}
210
211/*
212 * Similar to TIFFWriteDirectory(), but if the directory has already
213 * been written once, it is relocated to the end of the file, in case it
214 * has changed in size.  Note that this will result in the loss of the
215 * previously used directory space.
216 */
217int
218TIFFRewriteDirectory( TIFF *tif )
219{
220	static const char module[] = "TIFFRewriteDirectory";
221
222	/* We don't need to do anything special if it hasn't been written. */
223	if( tif->tif_diroff == 0 )
224		return TIFFWriteDirectory( tif );
225
226	/*
227	 * Find and zero the pointer to this directory, so that TIFFLinkDirectory
228	 * will cause it to be added after this directories current pre-link.
229	 */
230
231	if (!(tif->tif_flags&TIFF_BIGTIFF))
232	{
233		if (tif->tif_header.classic.tiff_diroff == tif->tif_diroff)
234		{
235			tif->tif_header.classic.tiff_diroff = 0;
236			tif->tif_diroff = 0;
237
238			TIFFSeekFile(tif,4,SEEK_SET);
239			if (!WriteOK(tif, &(tif->tif_header.classic.tiff_diroff),4))
240			{
241				TIFFErrorExt(tif->tif_clientdata, tif->tif_name,
242				    "Error updating TIFF header");
243				return (0);
244			}
245		}
246		else
247		{
248			uint32 nextdir;
249			nextdir = tif->tif_header.classic.tiff_diroff;
250			while(1) {
251				uint16 dircount;
252				uint32 nextnextdir;
253
254				if (!SeekOK(tif, nextdir) ||
255				    !ReadOK(tif, &dircount, 2)) {
256					TIFFErrorExt(tif->tif_clientdata, module,
257					     "Error fetching directory count");
258					return (0);
259				}
260				if (tif->tif_flags & TIFF_SWAB)
261					TIFFSwabShort(&dircount);
262				(void) TIFFSeekFile(tif,
263				    nextdir+2+dircount*12, SEEK_SET);
264				if (!ReadOK(tif, &nextnextdir, 4)) {
265					TIFFErrorExt(tif->tif_clientdata, module,
266					     "Error fetching directory link");
267					return (0);
268				}
269				if (tif->tif_flags & TIFF_SWAB)
270					TIFFSwabLong(&nextnextdir);
271				if (nextnextdir==tif->tif_diroff)
272				{
273					uint32 m;
274					m=0;
275					(void) TIFFSeekFile(tif,
276					    nextdir+2+dircount*12, SEEK_SET);
277					if (!WriteOK(tif, &m, 4)) {
278						TIFFErrorExt(tif->tif_clientdata, module,
279						     "Error writing directory link");
280						return (0);
281					}
282					tif->tif_diroff=0;
283					break;
284				}
285				nextdir=nextnextdir;
286			}
287		}
288	}
289	else
290	{
291		if (tif->tif_header.big.tiff_diroff == tif->tif_diroff)
292		{
293			tif->tif_header.big.tiff_diroff = 0;
294			tif->tif_diroff = 0;
295
296			TIFFSeekFile(tif,8,SEEK_SET);
297			if (!WriteOK(tif, &(tif->tif_header.big.tiff_diroff),8))
298			{
299				TIFFErrorExt(tif->tif_clientdata, tif->tif_name,
300				    "Error updating TIFF header");
301				return (0);
302			}
303		}
304		else
305		{
306			uint64 nextdir;
307			nextdir = tif->tif_header.big.tiff_diroff;
308			while(1) {
309				uint64 dircount64;
310				uint16 dircount;
311				uint64 nextnextdir;
312
313				if (!SeekOK(tif, nextdir) ||
314				    !ReadOK(tif, &dircount64, 8)) {
315					TIFFErrorExt(tif->tif_clientdata, module,
316					     "Error fetching directory count");
317					return (0);
318				}
319				if (tif->tif_flags & TIFF_SWAB)
320					TIFFSwabLong8(&dircount64);
321				if (dircount64>0xFFFF)
322				{
323					TIFFErrorExt(tif->tif_clientdata, module,
324					     "Sanity check on tag count failed, likely corrupt TIFF");
325					return (0);
326				}
327				dircount=(uint16)dircount64;
328				(void) TIFFSeekFile(tif,
329				    nextdir+8+dircount*20, SEEK_SET);
330				if (!ReadOK(tif, &nextnextdir, 8)) {
331					TIFFErrorExt(tif->tif_clientdata, module,
332					     "Error fetching directory link");
333					return (0);
334				}
335				if (tif->tif_flags & TIFF_SWAB)
336					TIFFSwabLong8(&nextnextdir);
337				if (nextnextdir==tif->tif_diroff)
338				{
339					uint64 m;
340					m=0;
341					(void) TIFFSeekFile(tif,
342					    nextdir+8+dircount*20, SEEK_SET);
343					if (!WriteOK(tif, &m, 8)) {
344						TIFFErrorExt(tif->tif_clientdata, module,
345						     "Error writing directory link");
346						return (0);
347					}
348					tif->tif_diroff=0;
349					break;
350				}
351				nextdir=nextnextdir;
352			}
353		}
354	}
355
356	/*
357	 * Now use TIFFWriteDirectory() normally.
358	 */
359
360	return TIFFWriteDirectory( tif );
361}
362
363static int
364TIFFWriteDirectorySec(TIFF* tif, int isimage, int imagedone, uint64* pdiroff)
365{
366	static const char module[] = "TIFFWriteDirectorySec";
367	uint32 ndir;
368	TIFFDirEntry* dir;
369	uint32 dirsize;
370	void* dirmem;
371	uint32 m;
372	if (tif->tif_mode == O_RDONLY)
373		return (1);
374
375        _TIFFFillStriles( tif );
376
377	/*
378	 * Clear write state so that subsequent images with
379	 * different characteristics get the right buffers
380	 * setup for them.
381	 */
382	if (imagedone)
383	{
384		if (tif->tif_flags & TIFF_POSTENCODE)
385		{
386			tif->tif_flags &= ~TIFF_POSTENCODE;
387			if (!(*tif->tif_postencode)(tif))
388			{
389				TIFFErrorExt(tif->tif_clientdata,module,
390				    "Error post-encoding before directory write");
391				return (0);
392			}
393		}
394		(*tif->tif_close)(tif);       /* shutdown encoder */
395		/*
396		 * Flush any data that might have been written
397		 * by the compression close+cleanup routines.  But
398                 * be careful not to write stuff if we didn't add data
399                 * in the previous steps as the "rawcc" data may well be
400                 * a previously read tile/strip in mixed read/write mode.
401		 */
402		if (tif->tif_rawcc > 0
403		    && (tif->tif_flags & TIFF_BEENWRITING) != 0 )
404		{
405		    if( !TIFFFlushData1(tif) )
406                    {
407			TIFFErrorExt(tif->tif_clientdata, module,
408			    "Error flushing data before directory write");
409			return (0);
410                    }
411		}
412		if ((tif->tif_flags & TIFF_MYBUFFER) && tif->tif_rawdata)
413		{
414			_TIFFfree(tif->tif_rawdata);
415			tif->tif_rawdata = NULL;
416			tif->tif_rawcc = 0;
417			tif->tif_rawdatasize = 0;
418                        tif->tif_rawdataoff = 0;
419                        tif->tif_rawdataloaded = 0;
420		}
421		tif->tif_flags &= ~(TIFF_BEENWRITING|TIFF_BUFFERSETUP);
422	}
423	dir=NULL;
424	dirmem=NULL;
425	dirsize=0;
426	while (1)
427	{
428		ndir=0;
429		if (isimage)
430		{
431			if (TIFFFieldSet(tif,FIELD_IMAGEDIMENSIONS))
432			{
433				if (!TIFFWriteDirectoryTagShortLong(tif,&ndir,dir,TIFFTAG_IMAGEWIDTH,tif->tif_dir.td_imagewidth))
434					goto bad;
435				if (!TIFFWriteDirectoryTagShortLong(tif,&ndir,dir,TIFFTAG_IMAGELENGTH,tif->tif_dir.td_imagelength))
436					goto bad;
437			}
438			if (TIFFFieldSet(tif,FIELD_TILEDIMENSIONS))
439			{
440				if (!TIFFWriteDirectoryTagShortLong(tif,&ndir,dir,TIFFTAG_TILEWIDTH,tif->tif_dir.td_tilewidth))
441					goto bad;
442				if (!TIFFWriteDirectoryTagShortLong(tif,&ndir,dir,TIFFTAG_TILELENGTH,tif->tif_dir.td_tilelength))
443					goto bad;
444			}
445			if (TIFFFieldSet(tif,FIELD_RESOLUTION))
446			{
447				if (!TIFFWriteDirectoryTagRational(tif,&ndir,dir,TIFFTAG_XRESOLUTION,tif->tif_dir.td_xresolution))
448					goto bad;
449				if (!TIFFWriteDirectoryTagRational(tif,&ndir,dir,TIFFTAG_YRESOLUTION,tif->tif_dir.td_yresolution))
450					goto bad;
451			}
452			if (TIFFFieldSet(tif,FIELD_POSITION))
453			{
454				if (!TIFFWriteDirectoryTagRational(tif,&ndir,dir,TIFFTAG_XPOSITION,tif->tif_dir.td_xposition))
455					goto bad;
456				if (!TIFFWriteDirectoryTagRational(tif,&ndir,dir,TIFFTAG_YPOSITION,tif->tif_dir.td_yposition))
457					goto bad;
458			}
459			if (TIFFFieldSet(tif,FIELD_SUBFILETYPE))
460			{
461				if (!TIFFWriteDirectoryTagLong(tif,&ndir,dir,TIFFTAG_SUBFILETYPE,tif->tif_dir.td_subfiletype))
462					goto bad;
463			}
464			if (TIFFFieldSet(tif,FIELD_BITSPERSAMPLE))
465			{
466				if (!TIFFWriteDirectoryTagShortPerSample(tif,&ndir,dir,TIFFTAG_BITSPERSAMPLE,tif->tif_dir.td_bitspersample))
467					goto bad;
468			}
469			if (TIFFFieldSet(tif,FIELD_COMPRESSION))
470			{
471				if (!TIFFWriteDirectoryTagShort(tif,&ndir,dir,TIFFTAG_COMPRESSION,tif->tif_dir.td_compression))
472					goto bad;
473			}
474			if (TIFFFieldSet(tif,FIELD_PHOTOMETRIC))
475			{
476				if (!TIFFWriteDirectoryTagShort(tif,&ndir,dir,TIFFTAG_PHOTOMETRIC,tif->tif_dir.td_photometric))
477					goto bad;
478			}
479			if (TIFFFieldSet(tif,FIELD_THRESHHOLDING))
480			{
481				if (!TIFFWriteDirectoryTagShort(tif,&ndir,dir,TIFFTAG_THRESHHOLDING,tif->tif_dir.td_threshholding))
482					goto bad;
483			}
484			if (TIFFFieldSet(tif,FIELD_FILLORDER))
485			{
486				if (!TIFFWriteDirectoryTagShort(tif,&ndir,dir,TIFFTAG_FILLORDER,tif->tif_dir.td_fillorder))
487					goto bad;
488			}
489			if (TIFFFieldSet(tif,FIELD_ORIENTATION))
490			{
491				if (!TIFFWriteDirectoryTagShort(tif,&ndir,dir,TIFFTAG_ORIENTATION,tif->tif_dir.td_orientation))
492					goto bad;
493			}
494			if (TIFFFieldSet(tif,FIELD_SAMPLESPERPIXEL))
495			{
496				if (!TIFFWriteDirectoryTagShort(tif,&ndir,dir,TIFFTAG_SAMPLESPERPIXEL,tif->tif_dir.td_samplesperpixel))
497					goto bad;
498			}
499			if (TIFFFieldSet(tif,FIELD_ROWSPERSTRIP))
500			{
501				if (!TIFFWriteDirectoryTagShortLong(tif,&ndir,dir,TIFFTAG_ROWSPERSTRIP,tif->tif_dir.td_rowsperstrip))
502					goto bad;
503			}
504			if (TIFFFieldSet(tif,FIELD_MINSAMPLEVALUE))
505			{
506				if (!TIFFWriteDirectoryTagShortPerSample(tif,&ndir,dir,TIFFTAG_MINSAMPLEVALUE,tif->tif_dir.td_minsamplevalue))
507					goto bad;
508			}
509			if (TIFFFieldSet(tif,FIELD_MAXSAMPLEVALUE))
510			{
511				if (!TIFFWriteDirectoryTagShortPerSample(tif,&ndir,dir,TIFFTAG_MAXSAMPLEVALUE,tif->tif_dir.td_maxsamplevalue))
512					goto bad;
513			}
514			if (TIFFFieldSet(tif,FIELD_PLANARCONFIG))
515			{
516				if (!TIFFWriteDirectoryTagShort(tif,&ndir,dir,TIFFTAG_PLANARCONFIG,tif->tif_dir.td_planarconfig))
517					goto bad;
518			}
519			if (TIFFFieldSet(tif,FIELD_RESOLUTIONUNIT))
520			{
521				if (!TIFFWriteDirectoryTagShort(tif,&ndir,dir,TIFFTAG_RESOLUTIONUNIT,tif->tif_dir.td_resolutionunit))
522					goto bad;
523			}
524			if (TIFFFieldSet(tif,FIELD_PAGENUMBER))
525			{
526				if (!TIFFWriteDirectoryTagShortArray(tif,&ndir,dir,TIFFTAG_PAGENUMBER,2,&tif->tif_dir.td_pagenumber[0]))
527					goto bad;
528			}
529			if (TIFFFieldSet(tif,FIELD_STRIPBYTECOUNTS))
530			{
531				if (!isTiled(tif))
532				{
533					if (!TIFFWriteDirectoryTagLongLong8Array(tif,&ndir,dir,TIFFTAG_STRIPBYTECOUNTS,tif->tif_dir.td_nstrips,tif->tif_dir.td_stripbytecount))
534						goto bad;
535				}
536				else
537				{
538					if (!TIFFWriteDirectoryTagLongLong8Array(tif,&ndir,dir,TIFFTAG_TILEBYTECOUNTS,tif->tif_dir.td_nstrips,tif->tif_dir.td_stripbytecount))
539						goto bad;
540				}
541			}
542			if (TIFFFieldSet(tif,FIELD_STRIPOFFSETS))
543			{
544				if (!isTiled(tif))
545				{
546                    /* td_stripoffset might be NULL in an odd OJPEG case. See
547                     *  tif_dirread.c around line 3634.
548                     * XXX: OJPEG hack.
549                     * If a) compression is OJPEG, b) it's not a tiled TIFF,
550                     * and c) the number of strips is 1,
551                     * then we tolerate the absence of stripoffsets tag,
552                     * because, presumably, all required data is in the
553                     * JpegInterchangeFormat stream.
554                     * We can get here when using tiffset on such a file.
555                     * See http://bugzilla.maptools.org/show_bug.cgi?id=2500
556                    */
557                    if (tif->tif_dir.td_stripoffset != NULL &&
558                        !TIFFWriteDirectoryTagLongLong8Array(tif,&ndir,dir,TIFFTAG_STRIPOFFSETS,tif->tif_dir.td_nstrips,tif->tif_dir.td_stripoffset))
559                        goto bad;
560				}
561				else
562				{
563					if (!TIFFWriteDirectoryTagLongLong8Array(tif,&ndir,dir,TIFFTAG_TILEOFFSETS,tif->tif_dir.td_nstrips,tif->tif_dir.td_stripoffset))
564						goto bad;
565				}
566			}
567			if (TIFFFieldSet(tif,FIELD_COLORMAP))
568			{
569				if (!TIFFWriteDirectoryTagColormap(tif,&ndir,dir))
570					goto bad;
571			}
572			if (TIFFFieldSet(tif,FIELD_EXTRASAMPLES))
573			{
574				if (tif->tif_dir.td_extrasamples)
575				{
576					uint16 na;
577					uint16* nb;
578					TIFFGetFieldDefaulted(tif,TIFFTAG_EXTRASAMPLES,&na,&nb);
579					if (!TIFFWriteDirectoryTagShortArray(tif,&ndir,dir,TIFFTAG_EXTRASAMPLES,na,nb))
580						goto bad;
581				}
582			}
583			if (TIFFFieldSet(tif,FIELD_SAMPLEFORMAT))
584			{
585				if (!TIFFWriteDirectoryTagShortPerSample(tif,&ndir,dir,TIFFTAG_SAMPLEFORMAT,tif->tif_dir.td_sampleformat))
586					goto bad;
587			}
588			if (TIFFFieldSet(tif,FIELD_SMINSAMPLEVALUE))
589			{
590				if (!TIFFWriteDirectoryTagSampleformatArray(tif,&ndir,dir,TIFFTAG_SMINSAMPLEVALUE,tif->tif_dir.td_samplesperpixel,tif->tif_dir.td_sminsamplevalue))
591					goto bad;
592			}
593			if (TIFFFieldSet(tif,FIELD_SMAXSAMPLEVALUE))
594			{
595				if (!TIFFWriteDirectoryTagSampleformatArray(tif,&ndir,dir,TIFFTAG_SMAXSAMPLEVALUE,tif->tif_dir.td_samplesperpixel,tif->tif_dir.td_smaxsamplevalue))
596					goto bad;
597			}
598			if (TIFFFieldSet(tif,FIELD_IMAGEDEPTH))
599			{
600				if (!TIFFWriteDirectoryTagLong(tif,&ndir,dir,TIFFTAG_IMAGEDEPTH,tif->tif_dir.td_imagedepth))
601					goto bad;
602			}
603			if (TIFFFieldSet(tif,FIELD_TILEDEPTH))
604			{
605				if (!TIFFWriteDirectoryTagLong(tif,&ndir,dir,TIFFTAG_TILEDEPTH,tif->tif_dir.td_tiledepth))
606					goto bad;
607			}
608			if (TIFFFieldSet(tif,FIELD_HALFTONEHINTS))
609			{
610				if (!TIFFWriteDirectoryTagShortArray(tif,&ndir,dir,TIFFTAG_HALFTONEHINTS,2,&tif->tif_dir.td_halftonehints[0]))
611					goto bad;
612			}
613			if (TIFFFieldSet(tif,FIELD_YCBCRSUBSAMPLING))
614			{
615				if (!TIFFWriteDirectoryTagShortArray(tif,&ndir,dir,TIFFTAG_YCBCRSUBSAMPLING,2,&tif->tif_dir.td_ycbcrsubsampling[0]))
616					goto bad;
617			}
618			if (TIFFFieldSet(tif,FIELD_YCBCRPOSITIONING))
619			{
620				if (!TIFFWriteDirectoryTagShort(tif,&ndir,dir,TIFFTAG_YCBCRPOSITIONING,tif->tif_dir.td_ycbcrpositioning))
621					goto bad;
622			}
623			if (TIFFFieldSet(tif,FIELD_REFBLACKWHITE))
624			{
625				if (!TIFFWriteDirectoryTagRationalArray(tif,&ndir,dir,TIFFTAG_REFERENCEBLACKWHITE,6,tif->tif_dir.td_refblackwhite))
626					goto bad;
627			}
628			if (TIFFFieldSet(tif,FIELD_TRANSFERFUNCTION))
629			{
630				if (!TIFFWriteDirectoryTagTransferfunction(tif,&ndir,dir))
631					goto bad;
632			}
633			if (TIFFFieldSet(tif,FIELD_INKNAMES))
634			{
635				if (!TIFFWriteDirectoryTagAscii(tif,&ndir,dir,TIFFTAG_INKNAMES,tif->tif_dir.td_inknameslen,tif->tif_dir.td_inknames))
636					goto bad;
637			}
638			if (TIFFFieldSet(tif,FIELD_SUBIFD))
639			{
640				if (!TIFFWriteDirectoryTagSubifd(tif,&ndir,dir))
641					goto bad;
642			}
643			{
644				uint32 n;
645				for (n=0; n<tif->tif_nfields; n++) {
646					const TIFFField* o;
647					o = tif->tif_fields[n];
648					if ((o->field_bit>=FIELD_CODEC)&&(TIFFFieldSet(tif,o->field_bit)))
649					{
650						switch (o->get_field_type)
651						{
652							case TIFF_SETGET_ASCII:
653								{
654									uint32 pa;
655									char* pb;
656									assert(o->field_type==TIFF_ASCII);
657									assert(o->field_readcount==TIFF_VARIABLE);
658									assert(o->field_passcount==0);
659									TIFFGetField(tif,o->field_tag,&pb);
660									pa=(uint32)(strlen(pb));
661									if (!TIFFWriteDirectoryTagAscii(tif,&ndir,dir,(uint16)o->field_tag,pa,pb))
662										goto bad;
663								}
664								break;
665							case TIFF_SETGET_UINT16:
666								{
667									uint16 p;
668									assert(o->field_type==TIFF_SHORT);
669									assert(o->field_readcount==1);
670									assert(o->field_passcount==0);
671									TIFFGetField(tif,o->field_tag,&p);
672									if (!TIFFWriteDirectoryTagShort(tif,&ndir,dir,(uint16)o->field_tag,p))
673										goto bad;
674								}
675								break;
676							case TIFF_SETGET_UINT32:
677								{
678									uint32 p;
679									assert(o->field_type==TIFF_LONG);
680									assert(o->field_readcount==1);
681									assert(o->field_passcount==0);
682									TIFFGetField(tif,o->field_tag,&p);
683									if (!TIFFWriteDirectoryTagLong(tif,&ndir,dir,(uint16)o->field_tag,p))
684										goto bad;
685								}
686								break;
687							case TIFF_SETGET_C32_UINT8:
688								{
689									uint32 pa;
690									void* pb;
691									assert(o->field_type==TIFF_UNDEFINED);
692									assert(o->field_readcount==TIFF_VARIABLE2);
693									assert(o->field_passcount==1);
694									TIFFGetField(tif,o->field_tag,&pa,&pb);
695									if (!TIFFWriteDirectoryTagUndefinedArray(tif,&ndir,dir,(uint16)o->field_tag,pa,pb))
696										goto bad;
697								}
698								break;
699							default:
700								assert(0);   /* we should never get here */
701								break;
702						}
703					}
704				}
705			}
706		}
707		for (m=0; m<(uint32)(tif->tif_dir.td_customValueCount); m++)
708		{
709                        uint16 tag = (uint16)tif->tif_dir.td_customValues[m].info->field_tag;
710                        uint32 count = tif->tif_dir.td_customValues[m].count;
711			switch (tif->tif_dir.td_customValues[m].info->field_type)
712			{
713				case TIFF_ASCII:
714					if (!TIFFWriteDirectoryTagAscii(tif,&ndir,dir,tag,count,tif->tif_dir.td_customValues[m].value))
715						goto bad;
716					break;
717				case TIFF_UNDEFINED:
718					if (!TIFFWriteDirectoryTagUndefinedArray(tif,&ndir,dir,tag,count,tif->tif_dir.td_customValues[m].value))
719						goto bad;
720					break;
721				case TIFF_BYTE:
722					if (!TIFFWriteDirectoryTagByteArray(tif,&ndir,dir,tag,count,tif->tif_dir.td_customValues[m].value))
723						goto bad;
724					break;
725				case TIFF_SBYTE:
726					if (!TIFFWriteDirectoryTagSbyteArray(tif,&ndir,dir,tag,count,tif->tif_dir.td_customValues[m].value))
727						goto bad;
728					break;
729				case TIFF_SHORT:
730					if (!TIFFWriteDirectoryTagShortArray(tif,&ndir,dir,tag,count,tif->tif_dir.td_customValues[m].value))
731						goto bad;
732					break;
733				case TIFF_SSHORT:
734					if (!TIFFWriteDirectoryTagSshortArray(tif,&ndir,dir,tag,count,tif->tif_dir.td_customValues[m].value))
735						goto bad;
736					break;
737				case TIFF_LONG:
738					if (!TIFFWriteDirectoryTagLongArray(tif,&ndir,dir,tag,count,tif->tif_dir.td_customValues[m].value))
739						goto bad;
740					break;
741				case TIFF_SLONG:
742					if (!TIFFWriteDirectoryTagSlongArray(tif,&ndir,dir,tag,count,tif->tif_dir.td_customValues[m].value))
743						goto bad;
744					break;
745				case TIFF_LONG8:
746					if (!TIFFWriteDirectoryTagLong8Array(tif,&ndir,dir,tag,count,tif->tif_dir.td_customValues[m].value))
747						goto bad;
748					break;
749				case TIFF_SLONG8:
750					if (!TIFFWriteDirectoryTagSlong8Array(tif,&ndir,dir,tag,count,tif->tif_dir.td_customValues[m].value))
751						goto bad;
752					break;
753				case TIFF_RATIONAL:
754					if (!TIFFWriteDirectoryTagRationalArray(tif,&ndir,dir,tag,count,tif->tif_dir.td_customValues[m].value))
755						goto bad;
756					break;
757				case TIFF_SRATIONAL:
758					if (!TIFFWriteDirectoryTagSrationalArray(tif,&ndir,dir,tag,count,tif->tif_dir.td_customValues[m].value))
759						goto bad;
760					break;
761				case TIFF_FLOAT:
762					if (!TIFFWriteDirectoryTagFloatArray(tif,&ndir,dir,tag,count,tif->tif_dir.td_customValues[m].value))
763						goto bad;
764					break;
765				case TIFF_DOUBLE:
766					if (!TIFFWriteDirectoryTagDoubleArray(tif,&ndir,dir,tag,count,tif->tif_dir.td_customValues[m].value))
767						goto bad;
768					break;
769				case TIFF_IFD:
770					if (!TIFFWriteDirectoryTagIfdArray(tif,&ndir,dir,tag,count,tif->tif_dir.td_customValues[m].value))
771						goto bad;
772					break;
773				case TIFF_IFD8:
774					if (!TIFFWriteDirectoryTagIfdIfd8Array(tif,&ndir,dir,tag,count,tif->tif_dir.td_customValues[m].value))
775						goto bad;
776					break;
777				default:
778					assert(0);   /* we should never get here */
779					break;
780			}
781		}
782		if (dir!=NULL)
783			break;
784		dir=_TIFFmalloc(ndir*sizeof(TIFFDirEntry));
785		if (dir==NULL)
786		{
787			TIFFErrorExt(tif->tif_clientdata,module,"Out of memory");
788			goto bad;
789		}
790		if (isimage)
791		{
792			if ((tif->tif_diroff==0)&&(!TIFFLinkDirectory(tif)))
793				goto bad;
794		}
795		else
796			tif->tif_diroff=(TIFFSeekFile(tif,0,SEEK_END)+1)&(~((toff_t)1));
797		if (pdiroff!=NULL)
798			*pdiroff=tif->tif_diroff;
799		if (!(tif->tif_flags&TIFF_BIGTIFF))
800			dirsize=2+ndir*12+4;
801		else
802			dirsize=8+ndir*20+8;
803		tif->tif_dataoff=tif->tif_diroff+dirsize;
804		if (!(tif->tif_flags&TIFF_BIGTIFF))
805			tif->tif_dataoff=(uint32)tif->tif_dataoff;
806		if ((tif->tif_dataoff<tif->tif_diroff)||(tif->tif_dataoff<(uint64)dirsize))
807		{
808			TIFFErrorExt(tif->tif_clientdata,module,"Maximum TIFF file size exceeded");
809			goto bad;
810		}
811		if (tif->tif_dataoff&1)
812			tif->tif_dataoff++;
813		if (isimage)
814			tif->tif_curdir++;
815	}
816	if (isimage)
817	{
818		if (TIFFFieldSet(tif,FIELD_SUBIFD)&&(tif->tif_subifdoff==0))
819		{
820			uint32 na;
821			TIFFDirEntry* nb;
822			for (na=0, nb=dir; ; na++, nb++)
823			{
824				assert(na<ndir);
825				if (nb->tdir_tag==TIFFTAG_SUBIFD)
826					break;
827			}
828			if (!(tif->tif_flags&TIFF_BIGTIFF))
829				tif->tif_subifdoff=tif->tif_diroff+2+na*12+8;
830			else
831				tif->tif_subifdoff=tif->tif_diroff+8+na*20+12;
832		}
833	}
834	dirmem=_TIFFmalloc(dirsize);
835	if (dirmem==NULL)
836	{
837		TIFFErrorExt(tif->tif_clientdata,module,"Out of memory");
838		goto bad;
839	}
840	if (!(tif->tif_flags&TIFF_BIGTIFF))
841	{
842		uint8* n;
843		uint32 nTmp;
844		TIFFDirEntry* o;
845		n=dirmem;
846		*(uint16*)n=(uint16)ndir;
847		if (tif->tif_flags&TIFF_SWAB)
848			TIFFSwabShort((uint16*)n);
849		n+=2;
850		o=dir;
851		for (m=0; m<ndir; m++)
852		{
853			*(uint16*)n=o->tdir_tag;
854			if (tif->tif_flags&TIFF_SWAB)
855				TIFFSwabShort((uint16*)n);
856			n+=2;
857			*(uint16*)n=o->tdir_type;
858			if (tif->tif_flags&TIFF_SWAB)
859				TIFFSwabShort((uint16*)n);
860			n+=2;
861			nTmp = (uint32)o->tdir_count;
862			_TIFFmemcpy(n,&nTmp,4);
863			if (tif->tif_flags&TIFF_SWAB)
864				TIFFSwabLong((uint32*)n);
865			n+=4;
866			/* This is correct. The data has been */
867			/* swabbed previously in TIFFWriteDirectoryTagData */
868			_TIFFmemcpy(n,&o->tdir_offset,4);
869			n+=4;
870			o++;
871		}
872		nTmp = (uint32)tif->tif_nextdiroff;
873		if (tif->tif_flags&TIFF_SWAB)
874			TIFFSwabLong(&nTmp);
875		_TIFFmemcpy(n,&nTmp,4);
876	}
877	else
878	{
879		uint8* n;
880		TIFFDirEntry* o;
881		n=dirmem;
882		*(uint64*)n=ndir;
883		if (tif->tif_flags&TIFF_SWAB)
884			TIFFSwabLong8((uint64*)n);
885		n+=8;
886		o=dir;
887		for (m=0; m<ndir; m++)
888		{
889			*(uint16*)n=o->tdir_tag;
890			if (tif->tif_flags&TIFF_SWAB)
891				TIFFSwabShort((uint16*)n);
892			n+=2;
893			*(uint16*)n=o->tdir_type;
894			if (tif->tif_flags&TIFF_SWAB)
895				TIFFSwabShort((uint16*)n);
896			n+=2;
897			_TIFFmemcpy(n,&o->tdir_count,8);
898			if (tif->tif_flags&TIFF_SWAB)
899				TIFFSwabLong8((uint64*)n);
900			n+=8;
901			_TIFFmemcpy(n,&o->tdir_offset,8);
902			n+=8;
903			o++;
904		}
905		_TIFFmemcpy(n,&tif->tif_nextdiroff,8);
906		if (tif->tif_flags&TIFF_SWAB)
907			TIFFSwabLong8((uint64*)n);
908	}
909	_TIFFfree(dir);
910	dir=NULL;
911	if (!SeekOK(tif,tif->tif_diroff))
912	{
913		TIFFErrorExt(tif->tif_clientdata,module,"IO error writing directory");
914		goto bad;
915	}
916	if (!WriteOK(tif,dirmem,(tmsize_t)dirsize))
917	{
918		TIFFErrorExt(tif->tif_clientdata,module,"IO error writing directory");
919		goto bad;
920	}
921	_TIFFfree(dirmem);
922	if (imagedone)
923	{
924		TIFFFreeDirectory(tif);
925		tif->tif_flags &= ~TIFF_DIRTYDIRECT;
926		tif->tif_flags &= ~TIFF_DIRTYSTRIP;
927		(*tif->tif_cleanup)(tif);
928		/*
929		* Reset directory-related state for subsequent
930		* directories.
931		*/
932		TIFFCreateDirectory(tif);
933	}
934	return(1);
935bad:
936	if (dir!=NULL)
937		_TIFFfree(dir);
938	if (dirmem!=NULL)
939		_TIFFfree(dirmem);
940	return(0);
941}
942
943static float TIFFClampDoubleToFloat( double val )
944{
945    if( val > FLT_MAX )
946        return FLT_MAX;
947    if( val < -FLT_MAX )
948        return -FLT_MAX;
949    return (float)val;
950}
951
952static int8 TIFFClampDoubleToInt8( double val )
953{
954    if( val > 127 )
955        return 127;
956    if( val < -128 || val != val )
957        return -128;
958    return (int8)val;
959}
960
961static int16 TIFFClampDoubleToInt16( double val )
962{
963    if( val > 32767 )
964        return 32767;
965    if( val < -32768 || val != val )
966        return -32768;
967    return (int16)val;
968}
969
970static int32 TIFFClampDoubleToInt32( double val )
971{
972    if( val > 0x7FFFFFFF )
973        return 0x7FFFFFFF;
974    if( val < -0x7FFFFFFF-1 || val != val )
975        return -0x7FFFFFFF-1;
976    return (int32)val;
977}
978
979static uint8 TIFFClampDoubleToUInt8( double val )
980{
981    if( val < 0 )
982        return 0;
983    if( val > 255 || val != val )
984        return 255;
985    return (uint8)val;
986}
987
988static uint16 TIFFClampDoubleToUInt16( double val )
989{
990    if( val < 0 )
991        return 0;
992    if( val > 65535 || val != val )
993        return 65535;
994    return (uint16)val;
995}
996
997static uint32 TIFFClampDoubleToUInt32( double val )
998{
999    if( val < 0 )
1000        return 0;
1001    if( val > 0xFFFFFFFFU || val != val )
1002        return 0xFFFFFFFFU;
1003    return (uint32)val;
1004}
1005
1006static int
1007TIFFWriteDirectoryTagSampleformatArray(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, double* value)
1008{
1009	static const char module[] = "TIFFWriteDirectoryTagSampleformatArray";
1010	void* conv;
1011	uint32 i;
1012	int ok;
1013	conv = _TIFFmalloc(count*sizeof(double));
1014	if (conv == NULL)
1015	{
1016		TIFFErrorExt(tif->tif_clientdata, module, "Out of memory");
1017		return (0);
1018	}
1019
1020	switch (tif->tif_dir.td_sampleformat)
1021	{
1022		case SAMPLEFORMAT_IEEEFP:
1023			if (tif->tif_dir.td_bitspersample<=32)
1024			{
1025				for (i = 0; i < count; ++i)
1026					((float*)conv)[i] = TIFFClampDoubleToFloat(value[i]);
1027				ok = TIFFWriteDirectoryTagFloatArray(tif,ndir,dir,tag,count,(float*)conv);
1028			}
1029			else
1030			{
1031				ok = TIFFWriteDirectoryTagDoubleArray(tif,ndir,dir,tag,count,value);
1032			}
1033			break;
1034		case SAMPLEFORMAT_INT:
1035			if (tif->tif_dir.td_bitspersample<=8)
1036			{
1037				for (i = 0; i < count; ++i)
1038					((int8*)conv)[i] = TIFFClampDoubleToInt8(value[i]);
1039				ok = TIFFWriteDirectoryTagSbyteArray(tif,ndir,dir,tag,count,(int8*)conv);
1040			}
1041			else if (tif->tif_dir.td_bitspersample<=16)
1042			{
1043				for (i = 0; i < count; ++i)
1044					((int16*)conv)[i] = TIFFClampDoubleToInt16(value[i]);
1045				ok = TIFFWriteDirectoryTagSshortArray(tif,ndir,dir,tag,count,(int16*)conv);
1046			}
1047			else
1048			{
1049				for (i = 0; i < count; ++i)
1050					((int32*)conv)[i] = TIFFClampDoubleToInt32(value[i]);
1051				ok = TIFFWriteDirectoryTagSlongArray(tif,ndir,dir,tag,count,(int32*)conv);
1052			}
1053			break;
1054		case SAMPLEFORMAT_UINT:
1055			if (tif->tif_dir.td_bitspersample<=8)
1056			{
1057				for (i = 0; i < count; ++i)
1058					((uint8*)conv)[i] = TIFFClampDoubleToUInt8(value[i]);
1059				ok = TIFFWriteDirectoryTagByteArray(tif,ndir,dir,tag,count,(uint8*)conv);
1060			}
1061			else if (tif->tif_dir.td_bitspersample<=16)
1062			{
1063				for (i = 0; i < count; ++i)
1064					((uint16*)conv)[i] = TIFFClampDoubleToUInt16(value[i]);
1065				ok = TIFFWriteDirectoryTagShortArray(tif,ndir,dir,tag,count,(uint16*)conv);
1066			}
1067			else
1068			{
1069				for (i = 0; i < count; ++i)
1070					((uint32*)conv)[i] = TIFFClampDoubleToUInt32(value[i]);
1071				ok = TIFFWriteDirectoryTagLongArray(tif,ndir,dir,tag,count,(uint32*)conv);
1072			}
1073			break;
1074		default:
1075			ok = 0;
1076	}
1077
1078	_TIFFfree(conv);
1079	return (ok);
1080}
1081
1082#if 0
1083static int
1084TIFFWriteDirectoryTagSampleformatPerSample(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, double value)
1085{
1086	switch (tif->tif_dir.td_sampleformat)
1087	{
1088		case SAMPLEFORMAT_IEEEFP:
1089			if (tif->tif_dir.td_bitspersample<=32)
1090				return(TIFFWriteDirectoryTagFloatPerSample(tif,ndir,dir,tag,(float)value));
1091			else
1092				return(TIFFWriteDirectoryTagDoublePerSample(tif,ndir,dir,tag,value));
1093		case SAMPLEFORMAT_INT:
1094			if (tif->tif_dir.td_bitspersample<=8)
1095				return(TIFFWriteDirectoryTagSbytePerSample(tif,ndir,dir,tag,(int8)value));
1096			else if (tif->tif_dir.td_bitspersample<=16)
1097				return(TIFFWriteDirectoryTagSshortPerSample(tif,ndir,dir,tag,(int16)value));
1098			else
1099				return(TIFFWriteDirectoryTagSlongPerSample(tif,ndir,dir,tag,(int32)value));
1100		case SAMPLEFORMAT_UINT:
1101			if (tif->tif_dir.td_bitspersample<=8)
1102				return(TIFFWriteDirectoryTagBytePerSample(tif,ndir,dir,tag,(uint8)value));
1103			else if (tif->tif_dir.td_bitspersample<=16)
1104				return(TIFFWriteDirectoryTagShortPerSample(tif,ndir,dir,tag,(uint16)value));
1105			else
1106				return(TIFFWriteDirectoryTagLongPerSample(tif,ndir,dir,tag,(uint32)value));
1107		default:
1108			return(1);
1109	}
1110}
1111#endif
1112
1113static int
1114TIFFWriteDirectoryTagAscii(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, char* value)
1115{
1116	if (dir==NULL)
1117	{
1118		(*ndir)++;
1119		return(1);
1120	}
1121	return(TIFFWriteDirectoryTagCheckedAscii(tif,ndir,dir,tag,count,value));
1122}
1123
1124static int
1125TIFFWriteDirectoryTagUndefinedArray(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, uint8* value)
1126{
1127	if (dir==NULL)
1128	{
1129		(*ndir)++;
1130		return(1);
1131	}
1132	return(TIFFWriteDirectoryTagCheckedUndefinedArray(tif,ndir,dir,tag,count,value));
1133}
1134
1135#ifdef notdef
1136static int
1137TIFFWriteDirectoryTagByte(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint8 value)
1138{
1139	if (dir==NULL)
1140	{
1141		(*ndir)++;
1142		return(1);
1143	}
1144	return(TIFFWriteDirectoryTagCheckedByte(tif,ndir,dir,tag,value));
1145}
1146#endif
1147
1148static int
1149TIFFWriteDirectoryTagByteArray(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, uint8* value)
1150{
1151	if (dir==NULL)
1152	{
1153		(*ndir)++;
1154		return(1);
1155	}
1156	return(TIFFWriteDirectoryTagCheckedByteArray(tif,ndir,dir,tag,count,value));
1157}
1158
1159#if 0
1160static int
1161TIFFWriteDirectoryTagBytePerSample(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint8 value)
1162{
1163	static const char module[] = "TIFFWriteDirectoryTagBytePerSample";
1164	uint8* m;
1165	uint8* na;
1166	uint16 nb;
1167	int o;
1168	if (dir==NULL)
1169	{
1170		(*ndir)++;
1171		return(1);
1172	}
1173	m=_TIFFmalloc(tif->tif_dir.td_samplesperpixel*sizeof(uint8));
1174	if (m==NULL)
1175	{
1176		TIFFErrorExt(tif->tif_clientdata,module,"Out of memory");
1177		return(0);
1178	}
1179	for (na=m, nb=0; nb<tif->tif_dir.td_samplesperpixel; na++, nb++)
1180		*na=value;
1181	o=TIFFWriteDirectoryTagCheckedByteArray(tif,ndir,dir,tag,tif->tif_dir.td_samplesperpixel,m);
1182	_TIFFfree(m);
1183	return(o);
1184}
1185#endif
1186
1187#ifdef notdef
1188static int
1189TIFFWriteDirectoryTagSbyte(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, int8 value)
1190{
1191	if (dir==NULL)
1192	{
1193		(*ndir)++;
1194		return(1);
1195	}
1196	return(TIFFWriteDirectoryTagCheckedSbyte(tif,ndir,dir,tag,value));
1197}
1198#endif
1199
1200static int
1201TIFFWriteDirectoryTagSbyteArray(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, int8* value)
1202{
1203	if (dir==NULL)
1204	{
1205		(*ndir)++;
1206		return(1);
1207	}
1208	return(TIFFWriteDirectoryTagCheckedSbyteArray(tif,ndir,dir,tag,count,value));
1209}
1210
1211#if 0
1212static int
1213TIFFWriteDirectoryTagSbytePerSample(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, int8 value)
1214{
1215	static const char module[] = "TIFFWriteDirectoryTagSbytePerSample";
1216	int8* m;
1217	int8* na;
1218	uint16 nb;
1219	int o;
1220	if (dir==NULL)
1221	{
1222		(*ndir)++;
1223		return(1);
1224	}
1225	m=_TIFFmalloc(tif->tif_dir.td_samplesperpixel*sizeof(int8));
1226	if (m==NULL)
1227	{
1228		TIFFErrorExt(tif->tif_clientdata,module,"Out of memory");
1229		return(0);
1230	}
1231	for (na=m, nb=0; nb<tif->tif_dir.td_samplesperpixel; na++, nb++)
1232		*na=value;
1233	o=TIFFWriteDirectoryTagCheckedSbyteArray(tif,ndir,dir,tag,tif->tif_dir.td_samplesperpixel,m);
1234	_TIFFfree(m);
1235	return(o);
1236}
1237#endif
1238
1239static int
1240TIFFWriteDirectoryTagShort(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint16 value)
1241{
1242	if (dir==NULL)
1243	{
1244		(*ndir)++;
1245		return(1);
1246	}
1247	return(TIFFWriteDirectoryTagCheckedShort(tif,ndir,dir,tag,value));
1248}
1249
1250static int
1251TIFFWriteDirectoryTagShortArray(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, uint16* value)
1252{
1253	if (dir==NULL)
1254	{
1255		(*ndir)++;
1256		return(1);
1257	}
1258	return(TIFFWriteDirectoryTagCheckedShortArray(tif,ndir,dir,tag,count,value));
1259}
1260
1261static int
1262TIFFWriteDirectoryTagShortPerSample(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint16 value)
1263{
1264	static const char module[] = "TIFFWriteDirectoryTagShortPerSample";
1265	uint16* m;
1266	uint16* na;
1267	uint16 nb;
1268	int o;
1269	if (dir==NULL)
1270	{
1271		(*ndir)++;
1272		return(1);
1273	}
1274	m=_TIFFmalloc(tif->tif_dir.td_samplesperpixel*sizeof(uint16));
1275	if (m==NULL)
1276	{
1277		TIFFErrorExt(tif->tif_clientdata,module,"Out of memory");
1278		return(0);
1279	}
1280	for (na=m, nb=0; nb<tif->tif_dir.td_samplesperpixel; na++, nb++)
1281		*na=value;
1282	o=TIFFWriteDirectoryTagCheckedShortArray(tif,ndir,dir,tag,tif->tif_dir.td_samplesperpixel,m);
1283	_TIFFfree(m);
1284	return(o);
1285}
1286
1287#ifdef notdef
1288static int
1289TIFFWriteDirectoryTagSshort(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, int16 value)
1290{
1291	if (dir==NULL)
1292	{
1293		(*ndir)++;
1294		return(1);
1295	}
1296	return(TIFFWriteDirectoryTagCheckedSshort(tif,ndir,dir,tag,value));
1297}
1298#endif
1299
1300static int
1301TIFFWriteDirectoryTagSshortArray(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, int16* value)
1302{
1303	if (dir==NULL)
1304	{
1305		(*ndir)++;
1306		return(1);
1307	}
1308	return(TIFFWriteDirectoryTagCheckedSshortArray(tif,ndir,dir,tag,count,value));
1309}
1310
1311#if 0
1312static int
1313TIFFWriteDirectoryTagSshortPerSample(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, int16 value)
1314{
1315	static const char module[] = "TIFFWriteDirectoryTagSshortPerSample";
1316	int16* m;
1317	int16* na;
1318	uint16 nb;
1319	int o;
1320	if (dir==NULL)
1321	{
1322		(*ndir)++;
1323		return(1);
1324	}
1325	m=_TIFFmalloc(tif->tif_dir.td_samplesperpixel*sizeof(int16));
1326	if (m==NULL)
1327	{
1328		TIFFErrorExt(tif->tif_clientdata,module,"Out of memory");
1329		return(0);
1330	}
1331	for (na=m, nb=0; nb<tif->tif_dir.td_samplesperpixel; na++, nb++)
1332		*na=value;
1333	o=TIFFWriteDirectoryTagCheckedSshortArray(tif,ndir,dir,tag,tif->tif_dir.td_samplesperpixel,m);
1334	_TIFFfree(m);
1335	return(o);
1336}
1337#endif
1338
1339static int
1340TIFFWriteDirectoryTagLong(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 value)
1341{
1342	if (dir==NULL)
1343	{
1344		(*ndir)++;
1345		return(1);
1346	}
1347	return(TIFFWriteDirectoryTagCheckedLong(tif,ndir,dir,tag,value));
1348}
1349
1350static int
1351TIFFWriteDirectoryTagLongArray(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, uint32* value)
1352{
1353	if (dir==NULL)
1354	{
1355		(*ndir)++;
1356		return(1);
1357	}
1358	return(TIFFWriteDirectoryTagCheckedLongArray(tif,ndir,dir,tag,count,value));
1359}
1360
1361#if 0
1362static int
1363TIFFWriteDirectoryTagLongPerSample(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 value)
1364{
1365	static const char module[] = "TIFFWriteDirectoryTagLongPerSample";
1366	uint32* m;
1367	uint32* na;
1368	uint16 nb;
1369	int o;
1370	if (dir==NULL)
1371	{
1372		(*ndir)++;
1373		return(1);
1374	}
1375	m=_TIFFmalloc(tif->tif_dir.td_samplesperpixel*sizeof(uint32));
1376	if (m==NULL)
1377	{
1378		TIFFErrorExt(tif->tif_clientdata,module,"Out of memory");
1379		return(0);
1380	}
1381	for (na=m, nb=0; nb<tif->tif_dir.td_samplesperpixel; na++, nb++)
1382		*na=value;
1383	o=TIFFWriteDirectoryTagCheckedLongArray(tif,ndir,dir,tag,tif->tif_dir.td_samplesperpixel,m);
1384	_TIFFfree(m);
1385	return(o);
1386}
1387#endif
1388
1389#ifdef notdef
1390static int
1391TIFFWriteDirectoryTagSlong(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, int32 value)
1392{
1393	if (dir==NULL)
1394	{
1395		(*ndir)++;
1396		return(1);
1397	}
1398	return(TIFFWriteDirectoryTagCheckedSlong(tif,ndir,dir,tag,value));
1399}
1400#endif
1401
1402static int
1403TIFFWriteDirectoryTagSlongArray(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, int32* value)
1404{
1405	if (dir==NULL)
1406	{
1407		(*ndir)++;
1408		return(1);
1409	}
1410	return(TIFFWriteDirectoryTagCheckedSlongArray(tif,ndir,dir,tag,count,value));
1411}
1412
1413#if 0
1414static int
1415TIFFWriteDirectoryTagSlongPerSample(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, int32 value)
1416{
1417	static const char module[] = "TIFFWriteDirectoryTagSlongPerSample";
1418	int32* m;
1419	int32* na;
1420	uint16 nb;
1421	int o;
1422	if (dir==NULL)
1423	{
1424		(*ndir)++;
1425		return(1);
1426	}
1427	m=_TIFFmalloc(tif->tif_dir.td_samplesperpixel*sizeof(int32));
1428	if (m==NULL)
1429	{
1430		TIFFErrorExt(tif->tif_clientdata,module,"Out of memory");
1431		return(0);
1432	}
1433	for (na=m, nb=0; nb<tif->tif_dir.td_samplesperpixel; na++, nb++)
1434		*na=value;
1435	o=TIFFWriteDirectoryTagCheckedSlongArray(tif,ndir,dir,tag,tif->tif_dir.td_samplesperpixel,m);
1436	_TIFFfree(m);
1437	return(o);
1438}
1439#endif
1440
1441#ifdef notdef
1442static int
1443TIFFWriteDirectoryTagLong8(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint64 value)
1444{
1445	if (dir==NULL)
1446	{
1447		(*ndir)++;
1448		return(1);
1449	}
1450	return(TIFFWriteDirectoryTagCheckedLong8(tif,ndir,dir,tag,value));
1451}
1452#endif
1453
1454static int
1455TIFFWriteDirectoryTagLong8Array(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, uint64* value)
1456{
1457	if (dir==NULL)
1458	{
1459		(*ndir)++;
1460		return(1);
1461	}
1462	return(TIFFWriteDirectoryTagCheckedLong8Array(tif,ndir,dir,tag,count,value));
1463}
1464
1465#ifdef notdef
1466static int
1467TIFFWriteDirectoryTagSlong8(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, int64 value)
1468{
1469	if (dir==NULL)
1470	{
1471		(*ndir)++;
1472		return(1);
1473	}
1474	return(TIFFWriteDirectoryTagCheckedSlong8(tif,ndir,dir,tag,value));
1475}
1476#endif
1477
1478static int
1479TIFFWriteDirectoryTagSlong8Array(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, int64* value)
1480{
1481	if (dir==NULL)
1482	{
1483		(*ndir)++;
1484		return(1);
1485	}
1486	return(TIFFWriteDirectoryTagCheckedSlong8Array(tif,ndir,dir,tag,count,value));
1487}
1488
1489static int
1490TIFFWriteDirectoryTagRational(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, double value)
1491{
1492	if (dir==NULL)
1493	{
1494		(*ndir)++;
1495		return(1);
1496	}
1497	return(TIFFWriteDirectoryTagCheckedRational(tif,ndir,dir,tag,value));
1498}
1499
1500static int
1501TIFFWriteDirectoryTagRationalArray(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, float* value)
1502{
1503	if (dir==NULL)
1504	{
1505		(*ndir)++;
1506		return(1);
1507	}
1508	return(TIFFWriteDirectoryTagCheckedRationalArray(tif,ndir,dir,tag,count,value));
1509}
1510
1511static int
1512TIFFWriteDirectoryTagSrationalArray(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, float* value)
1513{
1514	if (dir==NULL)
1515	{
1516		(*ndir)++;
1517		return(1);
1518	}
1519	return(TIFFWriteDirectoryTagCheckedSrationalArray(tif,ndir,dir,tag,count,value));
1520}
1521
1522#ifdef notdef
1523static int TIFFWriteDirectoryTagFloat(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, float value)
1524{
1525	if (dir==NULL)
1526	{
1527		(*ndir)++;
1528		return(1);
1529	}
1530	return(TIFFWriteDirectoryTagCheckedFloat(tif,ndir,dir,tag,value));
1531}
1532#endif
1533
1534static int TIFFWriteDirectoryTagFloatArray(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, float* value)
1535{
1536	if (dir==NULL)
1537	{
1538		(*ndir)++;
1539		return(1);
1540	}
1541	return(TIFFWriteDirectoryTagCheckedFloatArray(tif,ndir,dir,tag,count,value));
1542}
1543
1544#if 0
1545static int TIFFWriteDirectoryTagFloatPerSample(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, float value)
1546{
1547	static const char module[] = "TIFFWriteDirectoryTagFloatPerSample";
1548	float* m;
1549	float* na;
1550	uint16 nb;
1551	int o;
1552	if (dir==NULL)
1553	{
1554		(*ndir)++;
1555		return(1);
1556	}
1557	m=_TIFFmalloc(tif->tif_dir.td_samplesperpixel*sizeof(float));
1558	if (m==NULL)
1559	{
1560		TIFFErrorExt(tif->tif_clientdata,module,"Out of memory");
1561		return(0);
1562	}
1563	for (na=m, nb=0; nb<tif->tif_dir.td_samplesperpixel; na++, nb++)
1564		*na=value;
1565	o=TIFFWriteDirectoryTagCheckedFloatArray(tif,ndir,dir,tag,tif->tif_dir.td_samplesperpixel,m);
1566	_TIFFfree(m);
1567	return(o);
1568}
1569#endif
1570
1571#ifdef notdef
1572static int TIFFWriteDirectoryTagDouble(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, double value)
1573{
1574	if (dir==NULL)
1575	{
1576		(*ndir)++;
1577		return(1);
1578	}
1579	return(TIFFWriteDirectoryTagCheckedDouble(tif,ndir,dir,tag,value));
1580}
1581#endif
1582
1583static int TIFFWriteDirectoryTagDoubleArray(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, double* value)
1584{
1585	if (dir==NULL)
1586	{
1587		(*ndir)++;
1588		return(1);
1589	}
1590	return(TIFFWriteDirectoryTagCheckedDoubleArray(tif,ndir,dir,tag,count,value));
1591}
1592
1593#if 0
1594static int TIFFWriteDirectoryTagDoublePerSample(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, double value)
1595{
1596	static const char module[] = "TIFFWriteDirectoryTagDoublePerSample";
1597	double* m;
1598	double* na;
1599	uint16 nb;
1600	int o;
1601	if (dir==NULL)
1602	{
1603		(*ndir)++;
1604		return(1);
1605	}
1606	m=_TIFFmalloc(tif->tif_dir.td_samplesperpixel*sizeof(double));
1607	if (m==NULL)
1608	{
1609		TIFFErrorExt(tif->tif_clientdata,module,"Out of memory");
1610		return(0);
1611	}
1612	for (na=m, nb=0; nb<tif->tif_dir.td_samplesperpixel; na++, nb++)
1613		*na=value;
1614	o=TIFFWriteDirectoryTagCheckedDoubleArray(tif,ndir,dir,tag,tif->tif_dir.td_samplesperpixel,m);
1615	_TIFFfree(m);
1616	return(o);
1617}
1618#endif
1619
1620static int
1621TIFFWriteDirectoryTagIfdArray(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, uint32* value)
1622{
1623	if (dir==NULL)
1624	{
1625		(*ndir)++;
1626		return(1);
1627	}
1628	return(TIFFWriteDirectoryTagCheckedIfdArray(tif,ndir,dir,tag,count,value));
1629}
1630
1631#ifdef notdef
1632static int
1633TIFFWriteDirectoryTagIfd8Array(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, uint64* value)
1634{
1635	if (dir==NULL)
1636	{
1637		(*ndir)++;
1638		return(1);
1639	}
1640	return(TIFFWriteDirectoryTagCheckedIfd8Array(tif,ndir,dir,tag,count,value));
1641}
1642#endif
1643
1644static int
1645TIFFWriteDirectoryTagShortLong(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 value)
1646{
1647	if (dir==NULL)
1648	{
1649		(*ndir)++;
1650		return(1);
1651	}
1652	if (value<=0xFFFF)
1653		return(TIFFWriteDirectoryTagCheckedShort(tif,ndir,dir,tag,(uint16)value));
1654	else
1655		return(TIFFWriteDirectoryTagCheckedLong(tif,ndir,dir,tag,value));
1656}
1657
1658/************************************************************************/
1659/*                TIFFWriteDirectoryTagLongLong8Array()                 */
1660/*                                                                      */
1661/*      Write out LONG8 array as LONG8 for BigTIFF or LONG for          */
1662/*      Classic TIFF with some checking.                                */
1663/************************************************************************/
1664
1665static int
1666TIFFWriteDirectoryTagLongLong8Array(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, uint64* value)
1667{
1668    static const char module[] = "TIFFWriteDirectoryTagLongLong8Array";
1669    uint64* ma;
1670    uint32 mb;
1671    uint32* p;
1672    uint32* q;
1673    int o;
1674
1675    /* is this just a counting pass? */
1676    if (dir==NULL)
1677    {
1678        (*ndir)++;
1679        return(1);
1680    }
1681
1682    /* We always write LONG8 for BigTIFF, no checking needed. */
1683    if( tif->tif_flags&TIFF_BIGTIFF )
1684        return TIFFWriteDirectoryTagCheckedLong8Array(tif,ndir,dir,
1685                                                      tag,count,value);
1686
1687    /*
1688    ** For classic tiff we want to verify everything is in range for LONG
1689    ** and convert to long format.
1690    */
1691
1692    p = _TIFFmalloc(count*sizeof(uint32));
1693    if (p==NULL)
1694    {
1695        TIFFErrorExt(tif->tif_clientdata,module,"Out of memory");
1696        return(0);
1697    }
1698
1699    for (q=p, ma=value, mb=0; mb<count; ma++, mb++, q++)
1700    {
1701        if (*ma>0xFFFFFFFF)
1702        {
1703            TIFFErrorExt(tif->tif_clientdata,module,
1704                         "Attempt to write value larger than 0xFFFFFFFF in Classic TIFF file.");
1705            _TIFFfree(p);
1706            return(0);
1707        }
1708        *q= (uint32)(*ma);
1709    }
1710
1711    o=TIFFWriteDirectoryTagCheckedLongArray(tif,ndir,dir,tag,count,p);
1712    _TIFFfree(p);
1713
1714    return(o);
1715}
1716
1717/************************************************************************/
1718/*                 TIFFWriteDirectoryTagIfdIfd8Array()                  */
1719/*                                                                      */
1720/*      Write either IFD8 or IFD array depending on file type.          */
1721/************************************************************************/
1722
1723static int
1724TIFFWriteDirectoryTagIfdIfd8Array(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, uint64* value)
1725{
1726    static const char module[] = "TIFFWriteDirectoryTagIfdIfd8Array";
1727    uint64* ma;
1728    uint32 mb;
1729    uint32* p;
1730    uint32* q;
1731    int o;
1732
1733    /* is this just a counting pass? */
1734    if (dir==NULL)
1735    {
1736        (*ndir)++;
1737        return(1);
1738    }
1739
1740    /* We always write IFD8 for BigTIFF, no checking needed. */
1741    if( tif->tif_flags&TIFF_BIGTIFF )
1742        return TIFFWriteDirectoryTagCheckedIfd8Array(tif,ndir,dir,
1743                                                     tag,count,value);
1744
1745    /*
1746    ** For classic tiff we want to verify everything is in range for IFD
1747    ** and convert to long format.
1748    */
1749
1750    p = _TIFFmalloc(count*sizeof(uint32));
1751    if (p==NULL)
1752    {
1753        TIFFErrorExt(tif->tif_clientdata,module,"Out of memory");
1754        return(0);
1755    }
1756
1757    for (q=p, ma=value, mb=0; mb<count; ma++, mb++, q++)
1758    {
1759        if (*ma>0xFFFFFFFF)
1760        {
1761            TIFFErrorExt(tif->tif_clientdata,module,
1762                         "Attempt to write value larger than 0xFFFFFFFF in Classic TIFF file.");
1763            _TIFFfree(p);
1764            return(0);
1765        }
1766        *q= (uint32)(*ma);
1767    }
1768
1769    o=TIFFWriteDirectoryTagCheckedIfdArray(tif,ndir,dir,tag,count,p);
1770    _TIFFfree(p);
1771
1772    return(o);
1773}
1774
1775#ifdef notdef
1776static int
1777TIFFWriteDirectoryTagShortLongLong8Array(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, uint64* value)
1778{
1779	static const char module[] = "TIFFWriteDirectoryTagShortLongLong8Array";
1780	uint64* ma;
1781	uint32 mb;
1782	uint8 n;
1783	int o;
1784	if (dir==NULL)
1785	{
1786		(*ndir)++;
1787		return(1);
1788	}
1789	n=0;
1790	for (ma=value, mb=0; mb<count; ma++, mb++)
1791	{
1792		if ((n==0)&&(*ma>0xFFFF))
1793			n=1;
1794		if ((n==1)&&(*ma>0xFFFFFFFF))
1795		{
1796			n=2;
1797			break;
1798		}
1799	}
1800	if (n==0)
1801	{
1802		uint16* p;
1803		uint16* q;
1804		p=_TIFFmalloc(count*sizeof(uint16));
1805		if (p==NULL)
1806		{
1807			TIFFErrorExt(tif->tif_clientdata,module,"Out of memory");
1808			return(0);
1809		}
1810		for (ma=value, mb=0, q=p; mb<count; ma++, mb++, q++)
1811			*q=(uint16)(*ma);
1812		o=TIFFWriteDirectoryTagCheckedShortArray(tif,ndir,dir,tag,count,p);
1813		_TIFFfree(p);
1814	}
1815	else if (n==1)
1816	{
1817		uint32* p;
1818		uint32* q;
1819		p=_TIFFmalloc(count*sizeof(uint32));
1820		if (p==NULL)
1821		{
1822			TIFFErrorExt(tif->tif_clientdata,module,"Out of memory");
1823			return(0);
1824		}
1825		for (ma=value, mb=0, q=p; mb<count; ma++, mb++, q++)
1826			*q=(uint32)(*ma);
1827		o=TIFFWriteDirectoryTagCheckedLongArray(tif,ndir,dir,tag,count,p);
1828		_TIFFfree(p);
1829	}
1830	else
1831	{
1832		assert(n==2);
1833		o=TIFFWriteDirectoryTagCheckedLong8Array(tif,ndir,dir,tag,count,value);
1834	}
1835	return(o);
1836}
1837#endif
1838static int
1839TIFFWriteDirectoryTagColormap(TIFF* tif, uint32* ndir, TIFFDirEntry* dir)
1840{
1841	static const char module[] = "TIFFWriteDirectoryTagColormap";
1842	uint32 m;
1843	uint16* n;
1844	int o;
1845	if (dir==NULL)
1846	{
1847		(*ndir)++;
1848		return(1);
1849	}
1850	m=(1<<tif->tif_dir.td_bitspersample);
1851	n=_TIFFmalloc(3*m*sizeof(uint16));
1852	if (n==NULL)
1853	{
1854		TIFFErrorExt(tif->tif_clientdata,module,"Out of memory");
1855		return(0);
1856	}
1857	_TIFFmemcpy(&n[0],tif->tif_dir.td_colormap[0],m*sizeof(uint16));
1858	_TIFFmemcpy(&n[m],tif->tif_dir.td_colormap[1],m*sizeof(uint16));
1859	_TIFFmemcpy(&n[2*m],tif->tif_dir.td_colormap[2],m*sizeof(uint16));
1860	o=TIFFWriteDirectoryTagCheckedShortArray(tif,ndir,dir,TIFFTAG_COLORMAP,3*m,n);
1861	_TIFFfree(n);
1862	return(o);
1863}
1864
1865static int
1866TIFFWriteDirectoryTagTransferfunction(TIFF* tif, uint32* ndir, TIFFDirEntry* dir)
1867{
1868	static const char module[] = "TIFFWriteDirectoryTagTransferfunction";
1869	uint32 m;
1870	uint16 n;
1871	uint16* o;
1872	int p;
1873	if (dir==NULL)
1874	{
1875		(*ndir)++;
1876		return(1);
1877	}
1878	m=(1<<tif->tif_dir.td_bitspersample);
1879	n=tif->tif_dir.td_samplesperpixel-tif->tif_dir.td_extrasamples;
1880	/*
1881	 * Check if the table can be written as a single column,
1882	 * or if it must be written as 3 columns.  Note that we
1883	 * write a 3-column tag if there are 2 samples/pixel and
1884	 * a single column of data won't suffice--hmm.
1885	 */
1886	if (n>3)
1887		n=3;
1888	if (n==3)
1889	{
1890		if (!_TIFFmemcmp(tif->tif_dir.td_transferfunction[0],tif->tif_dir.td_transferfunction[2],m*sizeof(uint16)))
1891			n=2;
1892	}
1893	if (n==2)
1894	{
1895		if (!_TIFFmemcmp(tif->tif_dir.td_transferfunction[0],tif->tif_dir.td_transferfunction[1],m*sizeof(uint16)))
1896			n=1;
1897	}
1898	if (n==0)
1899		n=1;
1900	o=_TIFFmalloc(n*m*sizeof(uint16));
1901	if (o==NULL)
1902	{
1903		TIFFErrorExt(tif->tif_clientdata,module,"Out of memory");
1904		return(0);
1905	}
1906	_TIFFmemcpy(&o[0],tif->tif_dir.td_transferfunction[0],m*sizeof(uint16));
1907	if (n>1)
1908		_TIFFmemcpy(&o[m],tif->tif_dir.td_transferfunction[1],m*sizeof(uint16));
1909	if (n>2)
1910		_TIFFmemcpy(&o[2*m],tif->tif_dir.td_transferfunction[2],m*sizeof(uint16));
1911	p=TIFFWriteDirectoryTagCheckedShortArray(tif,ndir,dir,TIFFTAG_TRANSFERFUNCTION,n*m,o);
1912	_TIFFfree(o);
1913	return(p);
1914}
1915
1916static int
1917TIFFWriteDirectoryTagSubifd(TIFF* tif, uint32* ndir, TIFFDirEntry* dir)
1918{
1919	static const char module[] = "TIFFWriteDirectoryTagSubifd";
1920	uint64 m;
1921	int n;
1922	if (tif->tif_dir.td_nsubifd==0)
1923		return(1);
1924	if (dir==NULL)
1925	{
1926		(*ndir)++;
1927		return(1);
1928	}
1929	m=tif->tif_dataoff;
1930	if (!(tif->tif_flags&TIFF_BIGTIFF))
1931	{
1932		uint32* o;
1933		uint64* pa;
1934		uint32* pb;
1935		uint16 p;
1936		o=_TIFFmalloc(tif->tif_dir.td_nsubifd*sizeof(uint32));
1937		if (o==NULL)
1938		{
1939			TIFFErrorExt(tif->tif_clientdata,module,"Out of memory");
1940			return(0);
1941		}
1942		pa=tif->tif_dir.td_subifd;
1943		pb=o;
1944		for (p=0; p < tif->tif_dir.td_nsubifd; p++)
1945		{
1946                        assert(pa != 0);
1947			assert(*pa <= 0xFFFFFFFFUL);
1948			*pb++=(uint32)(*pa++);
1949		}
1950		n=TIFFWriteDirectoryTagCheckedIfdArray(tif,ndir,dir,TIFFTAG_SUBIFD,tif->tif_dir.td_nsubifd,o);
1951		_TIFFfree(o);
1952	}
1953	else
1954		n=TIFFWriteDirectoryTagCheckedIfd8Array(tif,ndir,dir,TIFFTAG_SUBIFD,tif->tif_dir.td_nsubifd,tif->tif_dir.td_subifd);
1955	if (!n)
1956		return(0);
1957	/*
1958	 * Total hack: if this directory includes a SubIFD
1959	 * tag then force the next <n> directories to be
1960	 * written as ``sub directories'' of this one.  This
1961	 * is used to write things like thumbnails and
1962	 * image masks that one wants to keep out of the
1963	 * normal directory linkage access mechanism.
1964	 */
1965	tif->tif_flags|=TIFF_INSUBIFD;
1966	tif->tif_nsubifd=tif->tif_dir.td_nsubifd;
1967	if (tif->tif_dir.td_nsubifd==1)
1968		tif->tif_subifdoff=0;
1969	else
1970		tif->tif_subifdoff=m;
1971	return(1);
1972}
1973
1974static int
1975TIFFWriteDirectoryTagCheckedAscii(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, char* value)
1976{
1977	assert(sizeof(char)==1);
1978	return(TIFFWriteDirectoryTagData(tif,ndir,dir,tag,TIFF_ASCII,count,count,value));
1979}
1980
1981static int
1982TIFFWriteDirectoryTagCheckedUndefinedArray(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, uint8* value)
1983{
1984	assert(sizeof(uint8)==1);
1985	return(TIFFWriteDirectoryTagData(tif,ndir,dir,tag,TIFF_UNDEFINED,count,count,value));
1986}
1987
1988#ifdef notdef
1989static int
1990TIFFWriteDirectoryTagCheckedByte(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint8 value)
1991{
1992	assert(sizeof(uint8)==1);
1993	return(TIFFWriteDirectoryTagData(tif,ndir,dir,tag,TIFF_BYTE,1,1,&value));
1994}
1995#endif
1996
1997static int
1998TIFFWriteDirectoryTagCheckedByteArray(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, uint8* value)
1999{
2000	assert(sizeof(uint8)==1);
2001	return(TIFFWriteDirectoryTagData(tif,ndir,dir,tag,TIFF_BYTE,count,count,value));
2002}
2003
2004#ifdef notdef
2005static int
2006TIFFWriteDirectoryTagCheckedSbyte(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, int8 value)
2007{
2008	assert(sizeof(int8)==1);
2009	return(TIFFWriteDirectoryTagData(tif,ndir,dir,tag,TIFF_SBYTE,1,1,&value));
2010}
2011#endif
2012
2013static int
2014TIFFWriteDirectoryTagCheckedSbyteArray(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, int8* value)
2015{
2016	assert(sizeof(int8)==1);
2017	return(TIFFWriteDirectoryTagData(tif,ndir,dir,tag,TIFF_SBYTE,count,count,value));
2018}
2019
2020static int
2021TIFFWriteDirectoryTagCheckedShort(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint16 value)
2022{
2023	uint16 m;
2024	assert(sizeof(uint16)==2);
2025	m=value;
2026	if (tif->tif_flags&TIFF_SWAB)
2027		TIFFSwabShort(&m);
2028	return(TIFFWriteDirectoryTagData(tif,ndir,dir,tag,TIFF_SHORT,1,2,&m));
2029}
2030
2031static int
2032TIFFWriteDirectoryTagCheckedShortArray(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, uint16* value)
2033{
2034	assert(count<0x80000000);
2035	assert(sizeof(uint16)==2);
2036	if (tif->tif_flags&TIFF_SWAB)
2037		TIFFSwabArrayOfShort(value,count);
2038	return(TIFFWriteDirectoryTagData(tif,ndir,dir,tag,TIFF_SHORT,count,count*2,value));
2039}
2040
2041#ifdef notdef
2042static int
2043TIFFWriteDirectoryTagCheckedSshort(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, int16 value)
2044{
2045	int16 m;
2046	assert(sizeof(int16)==2);
2047	m=value;
2048	if (tif->tif_flags&TIFF_SWAB)
2049		TIFFSwabShort((uint16*)(&m));
2050	return(TIFFWriteDirectoryTagData(tif,ndir,dir,tag,TIFF_SSHORT,1,2,&m));
2051}
2052#endif
2053
2054static int
2055TIFFWriteDirectoryTagCheckedSshortArray(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, int16* value)
2056{
2057	assert(count<0x80000000);
2058	assert(sizeof(int16)==2);
2059	if (tif->tif_flags&TIFF_SWAB)
2060		TIFFSwabArrayOfShort((uint16*)value,count);
2061	return(TIFFWriteDirectoryTagData(tif,ndir,dir,tag,TIFF_SSHORT,count,count*2,value));
2062}
2063
2064static int
2065TIFFWriteDirectoryTagCheckedLong(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 value)
2066{
2067	uint32 m;
2068	assert(sizeof(uint32)==4);
2069	m=value;
2070	if (tif->tif_flags&TIFF_SWAB)
2071		TIFFSwabLong(&m);
2072	return(TIFFWriteDirectoryTagData(tif,ndir,dir,tag,TIFF_LONG,1,4,&m));
2073}
2074
2075static int
2076TIFFWriteDirectoryTagCheckedLongArray(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, uint32* value)
2077{
2078	assert(count<0x40000000);
2079	assert(sizeof(uint32)==4);
2080	if (tif->tif_flags&TIFF_SWAB)
2081		TIFFSwabArrayOfLong(value,count);
2082	return(TIFFWriteDirectoryTagData(tif,ndir,dir,tag,TIFF_LONG,count,count*4,value));
2083}
2084
2085#ifdef notdef
2086static int
2087TIFFWriteDirectoryTagCheckedSlong(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, int32 value)
2088{
2089	int32 m;
2090	assert(sizeof(int32)==4);
2091	m=value;
2092	if (tif->tif_flags&TIFF_SWAB)
2093		TIFFSwabLong((uint32*)(&m));
2094	return(TIFFWriteDirectoryTagData(tif,ndir,dir,tag,TIFF_SLONG,1,4,&m));
2095}
2096#endif
2097
2098static int
2099TIFFWriteDirectoryTagCheckedSlongArray(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, int32* value)
2100{
2101	assert(count<0x40000000);
2102	assert(sizeof(int32)==4);
2103	if (tif->tif_flags&TIFF_SWAB)
2104		TIFFSwabArrayOfLong((uint32*)value,count);
2105	return(TIFFWriteDirectoryTagData(tif,ndir,dir,tag,TIFF_SLONG,count,count*4,value));
2106}
2107
2108#ifdef notdef
2109static int
2110TIFFWriteDirectoryTagCheckedLong8(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint64 value)
2111{
2112	uint64 m;
2113	assert(sizeof(uint64)==8);
2114	assert(tif->tif_flags&TIFF_BIGTIFF);
2115	m=value;
2116	if (tif->tif_flags&TIFF_SWAB)
2117		TIFFSwabLong8(&m);
2118	return(TIFFWriteDirectoryTagData(tif,ndir,dir,tag,TIFF_LONG8,1,8,&m));
2119}
2120#endif
2121
2122static int
2123TIFFWriteDirectoryTagCheckedLong8Array(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, uint64* value)
2124{
2125	assert(count<0x20000000);
2126	assert(sizeof(uint64)==8);
2127	assert(tif->tif_flags&TIFF_BIGTIFF);
2128	if (tif->tif_flags&TIFF_SWAB)
2129		TIFFSwabArrayOfLong8(value,count);
2130	return(TIFFWriteDirectoryTagData(tif,ndir,dir,tag,TIFF_LONG8,count,count*8,value));
2131}
2132
2133#ifdef notdef
2134static int
2135TIFFWriteDirectoryTagCheckedSlong8(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, int64 value)
2136{
2137	int64 m;
2138	assert(sizeof(int64)==8);
2139	assert(tif->tif_flags&TIFF_BIGTIFF);
2140	m=value;
2141	if (tif->tif_flags&TIFF_SWAB)
2142		TIFFSwabLong8((uint64*)(&m));
2143	return(TIFFWriteDirectoryTagData(tif,ndir,dir,tag,TIFF_SLONG8,1,8,&m));
2144}
2145#endif
2146
2147static int
2148TIFFWriteDirectoryTagCheckedSlong8Array(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, int64* value)
2149{
2150	assert(count<0x20000000);
2151	assert(sizeof(int64)==8);
2152	assert(tif->tif_flags&TIFF_BIGTIFF);
2153	if (tif->tif_flags&TIFF_SWAB)
2154		TIFFSwabArrayOfLong8((uint64*)value,count);
2155	return(TIFFWriteDirectoryTagData(tif,ndir,dir,tag,TIFF_SLONG8,count,count*8,value));
2156}
2157
2158static int
2159TIFFWriteDirectoryTagCheckedRational(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, double value)
2160{
2161        static const char module[] = "TIFFWriteDirectoryTagCheckedRational";
2162	uint32 m[2];
2163	assert(sizeof(uint32)==4);
2164        if( value < 0 )
2165        {
2166            TIFFErrorExt(tif->tif_clientdata,module,"Negative value is illegal");
2167            return 0;
2168        }
2169        else if( value != value )
2170        {
2171            TIFFErrorExt(tif->tif_clientdata,module,"Not-a-number value is illegal");
2172            return 0;
2173        }
2174	else if (value==0.0)
2175	{
2176		m[0]=0;
2177		m[1]=1;
2178	}
2179	else if (value <= 0xFFFFFFFFU && value==(double)(uint32)value)
2180	{
2181		m[0]=(uint32)value;
2182		m[1]=1;
2183	}
2184	else if (value<1.0)
2185	{
2186		m[0]=(uint32)(value*0xFFFFFFFF);
2187		m[1]=0xFFFFFFFF;
2188	}
2189	else
2190	{
2191		m[0]=0xFFFFFFFF;
2192		m[1]=(uint32)(0xFFFFFFFF/value);
2193	}
2194	if (tif->tif_flags&TIFF_SWAB)
2195	{
2196		TIFFSwabLong(&m[0]);
2197		TIFFSwabLong(&m[1]);
2198	}
2199	return(TIFFWriteDirectoryTagData(tif,ndir,dir,tag,TIFF_RATIONAL,1,8,&m[0]));
2200}
2201
2202static int
2203TIFFWriteDirectoryTagCheckedRationalArray(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, float* value)
2204{
2205	static const char module[] = "TIFFWriteDirectoryTagCheckedRationalArray";
2206	uint32* m;
2207	float* na;
2208	uint32* nb;
2209	uint32 nc;
2210	int o;
2211	assert(sizeof(uint32)==4);
2212	m=_TIFFmalloc(count*2*sizeof(uint32));
2213	if (m==NULL)
2214	{
2215		TIFFErrorExt(tif->tif_clientdata,module,"Out of memory");
2216		return(0);
2217	}
2218	for (na=value, nb=m, nc=0; nc<count; na++, nb+=2, nc++)
2219	{
2220		if (*na<=0.0 || *na != *na)
2221		{
2222			nb[0]=0;
2223			nb[1]=1;
2224		}
2225		else if (*na >= 0 && *na <= (float)0xFFFFFFFFU &&
2226                         *na==(float)(uint32)(*na))
2227		{
2228			nb[0]=(uint32)(*na);
2229			nb[1]=1;
2230		}
2231		else if (*na<1.0)
2232		{
2233			nb[0]=(uint32)((double)(*na)*0xFFFFFFFF);
2234			nb[1]=0xFFFFFFFF;
2235		}
2236		else
2237		{
2238			nb[0]=0xFFFFFFFF;
2239			nb[1]=(uint32)((double)0xFFFFFFFF/(*na));
2240		}
2241	}
2242	if (tif->tif_flags&TIFF_SWAB)
2243		TIFFSwabArrayOfLong(m,count*2);
2244	o=TIFFWriteDirectoryTagData(tif,ndir,dir,tag,TIFF_RATIONAL,count,count*8,&m[0]);
2245	_TIFFfree(m);
2246	return(o);
2247}
2248
2249static int
2250TIFFWriteDirectoryTagCheckedSrationalArray(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, float* value)
2251{
2252	static const char module[] = "TIFFWriteDirectoryTagCheckedSrationalArray";
2253	int32* m;
2254	float* na;
2255	int32* nb;
2256	uint32 nc;
2257	int o;
2258	assert(sizeof(int32)==4);
2259	m=_TIFFmalloc(count*2*sizeof(int32));
2260	if (m==NULL)
2261	{
2262		TIFFErrorExt(tif->tif_clientdata,module,"Out of memory");
2263		return(0);
2264	}
2265	for (na=value, nb=m, nc=0; nc<count; na++, nb+=2, nc++)
2266	{
2267		if (*na<0.0)
2268		{
2269			if (*na==(int32)(*na))
2270			{
2271				nb[0]=(int32)(*na);
2272				nb[1]=1;
2273			}
2274			else if (*na>-1.0)
2275			{
2276				nb[0]=-(int32)((double)(-*na)*0x7FFFFFFF);
2277				nb[1]=0x7FFFFFFF;
2278			}
2279			else
2280			{
2281				nb[0]=-0x7FFFFFFF;
2282				nb[1]=(int32)((double)0x7FFFFFFF/(-*na));
2283			}
2284		}
2285		else
2286		{
2287			if (*na==(int32)(*na))
2288			{
2289				nb[0]=(int32)(*na);
2290				nb[1]=1;
2291			}
2292			else if (*na<1.0)
2293			{
2294				nb[0]=(int32)((double)(*na)*0x7FFFFFFF);
2295				nb[1]=0x7FFFFFFF;
2296			}
2297			else
2298			{
2299				nb[0]=0x7FFFFFFF;
2300				nb[1]=(int32)((double)0x7FFFFFFF/(*na));
2301			}
2302		}
2303	}
2304	if (tif->tif_flags&TIFF_SWAB)
2305		TIFFSwabArrayOfLong((uint32*)m,count*2);
2306	o=TIFFWriteDirectoryTagData(tif,ndir,dir,tag,TIFF_SRATIONAL,count,count*8,&m[0]);
2307	_TIFFfree(m);
2308	return(o);
2309}
2310
2311#ifdef notdef
2312static int
2313TIFFWriteDirectoryTagCheckedFloat(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, float value)
2314{
2315	float m;
2316	assert(sizeof(float)==4);
2317	m=value;
2318	TIFFCvtNativeToIEEEFloat(tif,1,&m);
2319	if (tif->tif_flags&TIFF_SWAB)
2320		TIFFSwabFloat(&m);
2321	return(TIFFWriteDirectoryTagData(tif,ndir,dir,tag,TIFF_FLOAT,1,4,&m));
2322}
2323#endif
2324
2325static int
2326TIFFWriteDirectoryTagCheckedFloatArray(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, float* value)
2327{
2328	assert(count<0x40000000);
2329	assert(sizeof(float)==4);
2330	TIFFCvtNativeToIEEEFloat(tif,count,&value);
2331	if (tif->tif_flags&TIFF_SWAB)
2332		TIFFSwabArrayOfFloat(value,count);
2333	return(TIFFWriteDirectoryTagData(tif,ndir,dir,tag,TIFF_FLOAT,count,count*4,value));
2334}
2335
2336#ifdef notdef
2337static int
2338TIFFWriteDirectoryTagCheckedDouble(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, double value)
2339{
2340	double m;
2341	assert(sizeof(double)==8);
2342	m=value;
2343	TIFFCvtNativeToIEEEDouble(tif,1,&m);
2344	if (tif->tif_flags&TIFF_SWAB)
2345		TIFFSwabDouble(&m);
2346	return(TIFFWriteDirectoryTagData(tif,ndir,dir,tag,TIFF_DOUBLE,1,8,&m));
2347}
2348#endif
2349
2350static int
2351TIFFWriteDirectoryTagCheckedDoubleArray(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, double* value)
2352{
2353	assert(count<0x20000000);
2354	assert(sizeof(double)==8);
2355	TIFFCvtNativeToIEEEDouble(tif,count,&value);
2356	if (tif->tif_flags&TIFF_SWAB)
2357		TIFFSwabArrayOfDouble(value,count);
2358	return(TIFFWriteDirectoryTagData(tif,ndir,dir,tag,TIFF_DOUBLE,count,count*8,value));
2359}
2360
2361static int
2362TIFFWriteDirectoryTagCheckedIfdArray(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, uint32* value)
2363{
2364	assert(count<0x40000000);
2365	assert(sizeof(uint32)==4);
2366	if (tif->tif_flags&TIFF_SWAB)
2367		TIFFSwabArrayOfLong(value,count);
2368	return(TIFFWriteDirectoryTagData(tif,ndir,dir,tag,TIFF_IFD,count,count*4,value));
2369}
2370
2371static int
2372TIFFWriteDirectoryTagCheckedIfd8Array(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, uint64* value)
2373{
2374	assert(count<0x20000000);
2375	assert(sizeof(uint64)==8);
2376	assert(tif->tif_flags&TIFF_BIGTIFF);
2377	if (tif->tif_flags&TIFF_SWAB)
2378		TIFFSwabArrayOfLong8(value,count);
2379	return(TIFFWriteDirectoryTagData(tif,ndir,dir,tag,TIFF_IFD8,count,count*8,value));
2380}
2381
2382static int
2383TIFFWriteDirectoryTagData(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint16 datatype, uint32 count, uint32 datalength, void* data)
2384{
2385	static const char module[] = "TIFFWriteDirectoryTagData";
2386	uint32 m;
2387	m=0;
2388	while (m<(*ndir))
2389	{
2390		assert(dir[m].tdir_tag!=tag);
2391		if (dir[m].tdir_tag>tag)
2392			break;
2393		m++;
2394	}
2395	if (m<(*ndir))
2396	{
2397		uint32 n;
2398		for (n=*ndir; n>m; n--)
2399			dir[n]=dir[n-1];
2400	}
2401	dir[m].tdir_tag=tag;
2402	dir[m].tdir_type=datatype;
2403	dir[m].tdir_count=count;
2404	dir[m].tdir_offset.toff_long8 = 0;
2405	if (datalength<=((tif->tif_flags&TIFF_BIGTIFF)?0x8U:0x4U))
2406		_TIFFmemcpy(&dir[m].tdir_offset,data,datalength);
2407	else
2408	{
2409		uint64 na,nb;
2410		na=tif->tif_dataoff;
2411		nb=na+datalength;
2412		if (!(tif->tif_flags&TIFF_BIGTIFF))
2413			nb=(uint32)nb;
2414		if ((nb<na)||(nb<datalength))
2415		{
2416			TIFFErrorExt(tif->tif_clientdata,module,"Maximum TIFF file size exceeded");
2417			return(0);
2418		}
2419		if (!SeekOK(tif,na))
2420		{
2421			TIFFErrorExt(tif->tif_clientdata,module,"IO error writing tag data");
2422			return(0);
2423		}
2424		assert(datalength<0x80000000UL);
2425		if (!WriteOK(tif,data,(tmsize_t)datalength))
2426		{
2427			TIFFErrorExt(tif->tif_clientdata,module,"IO error writing tag data");
2428			return(0);
2429		}
2430		tif->tif_dataoff=nb;
2431		if (tif->tif_dataoff&1)
2432			tif->tif_dataoff++;
2433		if (!(tif->tif_flags&TIFF_BIGTIFF))
2434		{
2435			uint32 o;
2436			o=(uint32)na;
2437			if (tif->tif_flags&TIFF_SWAB)
2438				TIFFSwabLong(&o);
2439			_TIFFmemcpy(&dir[m].tdir_offset,&o,4);
2440		}
2441		else
2442		{
2443			dir[m].tdir_offset.toff_long8 = na;
2444			if (tif->tif_flags&TIFF_SWAB)
2445				TIFFSwabLong8(&dir[m].tdir_offset.toff_long8);
2446		}
2447	}
2448	(*ndir)++;
2449	return(1);
2450}
2451
2452/*
2453 * Link the current directory into the directory chain for the file.
2454 */
2455static int
2456TIFFLinkDirectory(TIFF* tif)
2457{
2458	static const char module[] = "TIFFLinkDirectory";
2459
2460	tif->tif_diroff = (TIFFSeekFile(tif,0,SEEK_END)+1) & (~((toff_t)1));
2461
2462	/*
2463	 * Handle SubIFDs
2464	 */
2465	if (tif->tif_flags & TIFF_INSUBIFD)
2466	{
2467		if (!(tif->tif_flags&TIFF_BIGTIFF))
2468		{
2469			uint32 m;
2470			m = (uint32)tif->tif_diroff;
2471			if (tif->tif_flags & TIFF_SWAB)
2472				TIFFSwabLong(&m);
2473			(void) TIFFSeekFile(tif, tif->tif_subifdoff, SEEK_SET);
2474			if (!WriteOK(tif, &m, 4)) {
2475				TIFFErrorExt(tif->tif_clientdata, module,
2476				     "Error writing SubIFD directory link");
2477				return (0);
2478			}
2479			/*
2480			 * Advance to the next SubIFD or, if this is
2481			 * the last one configured, revert back to the
2482			 * normal directory linkage.
2483			 */
2484			if (--tif->tif_nsubifd)
2485				tif->tif_subifdoff += 4;
2486			else
2487				tif->tif_flags &= ~TIFF_INSUBIFD;
2488			return (1);
2489		}
2490		else
2491		{
2492			uint64 m;
2493			m = tif->tif_diroff;
2494			if (tif->tif_flags & TIFF_SWAB)
2495				TIFFSwabLong8(&m);
2496			(void) TIFFSeekFile(tif, tif->tif_subifdoff, SEEK_SET);
2497			if (!WriteOK(tif, &m, 8)) {
2498				TIFFErrorExt(tif->tif_clientdata, module,
2499				     "Error writing SubIFD directory link");
2500				return (0);
2501			}
2502			/*
2503			 * Advance to the next SubIFD or, if this is
2504			 * the last one configured, revert back to the
2505			 * normal directory linkage.
2506			 */
2507			if (--tif->tif_nsubifd)
2508				tif->tif_subifdoff += 8;
2509			else
2510				tif->tif_flags &= ~TIFF_INSUBIFD;
2511			return (1);
2512		}
2513	}
2514
2515	if (!(tif->tif_flags&TIFF_BIGTIFF))
2516	{
2517		uint32 m;
2518		uint32 nextdir;
2519		m = (uint32)(tif->tif_diroff);
2520		if (tif->tif_flags & TIFF_SWAB)
2521			TIFFSwabLong(&m);
2522		if (tif->tif_header.classic.tiff_diroff == 0) {
2523			/*
2524			 * First directory, overwrite offset in header.
2525			 */
2526			tif->tif_header.classic.tiff_diroff = (uint32) tif->tif_diroff;
2527			(void) TIFFSeekFile(tif,4, SEEK_SET);
2528			if (!WriteOK(tif, &m, 4)) {
2529				TIFFErrorExt(tif->tif_clientdata, tif->tif_name,
2530					     "Error writing TIFF header");
2531				return (0);
2532			}
2533			return (1);
2534		}
2535		/*
2536		 * Not the first directory, search to the last and append.
2537		 */
2538		nextdir = tif->tif_header.classic.tiff_diroff;
2539		while(1) {
2540			uint16 dircount;
2541			uint32 nextnextdir;
2542
2543			if (!SeekOK(tif, nextdir) ||
2544			    !ReadOK(tif, &dircount, 2)) {
2545				TIFFErrorExt(tif->tif_clientdata, module,
2546					     "Error fetching directory count");
2547				return (0);
2548			}
2549			if (tif->tif_flags & TIFF_SWAB)
2550				TIFFSwabShort(&dircount);
2551			(void) TIFFSeekFile(tif,
2552			    nextdir+2+dircount*12, SEEK_SET);
2553			if (!ReadOK(tif, &nextnextdir, 4)) {
2554				TIFFErrorExt(tif->tif_clientdata, module,
2555					     "Error fetching directory link");
2556				return (0);
2557			}
2558			if (tif->tif_flags & TIFF_SWAB)
2559				TIFFSwabLong(&nextnextdir);
2560			if (nextnextdir==0)
2561			{
2562				(void) TIFFSeekFile(tif,
2563				    nextdir+2+dircount*12, SEEK_SET);
2564				if (!WriteOK(tif, &m, 4)) {
2565					TIFFErrorExt(tif->tif_clientdata, module,
2566					     "Error writing directory link");
2567					return (0);
2568				}
2569				break;
2570			}
2571			nextdir=nextnextdir;
2572		}
2573	}
2574	else
2575	{
2576		uint64 m;
2577		uint64 nextdir;
2578		m = tif->tif_diroff;
2579		if (tif->tif_flags & TIFF_SWAB)
2580			TIFFSwabLong8(&m);
2581		if (tif->tif_header.big.tiff_diroff == 0) {
2582			/*
2583			 * First directory, overwrite offset in header.
2584			 */
2585			tif->tif_header.big.tiff_diroff = tif->tif_diroff;
2586			(void) TIFFSeekFile(tif,8, SEEK_SET);
2587			if (!WriteOK(tif, &m, 8)) {
2588				TIFFErrorExt(tif->tif_clientdata, tif->tif_name,
2589					     "Error writing TIFF header");
2590				return (0);
2591			}
2592			return (1);
2593		}
2594		/*
2595		 * Not the first directory, search to the last and append.
2596		 */
2597		nextdir = tif->tif_header.big.tiff_diroff;
2598		while(1) {
2599			uint64 dircount64;
2600			uint16 dircount;
2601			uint64 nextnextdir;
2602
2603			if (!SeekOK(tif, nextdir) ||
2604			    !ReadOK(tif, &dircount64, 8)) {
2605				TIFFErrorExt(tif->tif_clientdata, module,
2606					     "Error fetching directory count");
2607				return (0);
2608			}
2609			if (tif->tif_flags & TIFF_SWAB)
2610				TIFFSwabLong8(&dircount64);
2611			if (dircount64>0xFFFF)
2612			{
2613				TIFFErrorExt(tif->tif_clientdata, module,
2614					     "Sanity check on tag count failed, likely corrupt TIFF");
2615				return (0);
2616			}
2617			dircount=(uint16)dircount64;
2618			(void) TIFFSeekFile(tif,
2619			    nextdir+8+dircount*20, SEEK_SET);
2620			if (!ReadOK(tif, &nextnextdir, 8)) {
2621				TIFFErrorExt(tif->tif_clientdata, module,
2622					     "Error fetching directory link");
2623				return (0);
2624			}
2625			if (tif->tif_flags & TIFF_SWAB)
2626				TIFFSwabLong8(&nextnextdir);
2627			if (nextnextdir==0)
2628			{
2629				(void) TIFFSeekFile(tif,
2630				    nextdir+8+dircount*20, SEEK_SET);
2631				if (!WriteOK(tif, &m, 8)) {
2632					TIFFErrorExt(tif->tif_clientdata, module,
2633					     "Error writing directory link");
2634					return (0);
2635				}
2636				break;
2637			}
2638			nextdir=nextnextdir;
2639		}
2640	}
2641	return (1);
2642}
2643
2644/************************************************************************/
2645/*                          TIFFRewriteField()                          */
2646/*                                                                      */
2647/*      Rewrite a field in the directory on disk without regard to      */
2648/*      updating the TIFF directory structure in memory.  Currently     */
2649/*      only supported for field that already exist in the on-disk      */
2650/*      directory.  Mainly used for updating stripoffset /              */
2651/*      stripbytecount values after the directory is already on         */
2652/*      disk.                                                           */
2653/*                                                                      */
2654/*      Returns zero on failure, and one on success.                    */
2655/************************************************************************/
2656
2657int
2658_TIFFRewriteField(TIFF* tif, uint16 tag, TIFFDataType in_datatype,
2659                  tmsize_t count, void* data)
2660{
2661    static const char module[] = "TIFFResetField";
2662    /* const TIFFField* fip = NULL; */
2663    uint16 dircount;
2664    tmsize_t dirsize;
2665    uint8 direntry_raw[20];
2666    uint16 entry_tag = 0;
2667    uint16 entry_type = 0;
2668    uint64 entry_count = 0;
2669    uint64 entry_offset = 0;
2670    int    value_in_entry = 0;
2671    uint64 read_offset;
2672    uint8 *buf_to_write = NULL;
2673    TIFFDataType datatype;
2674
2675/* -------------------------------------------------------------------- */
2676/*      Find field definition.                                          */
2677/* -------------------------------------------------------------------- */
2678    /*fip =*/ TIFFFindField(tif, tag, TIFF_ANY);
2679
2680/* -------------------------------------------------------------------- */
2681/*      Do some checking this is a straight forward case.               */
2682/* -------------------------------------------------------------------- */
2683    if( isMapped(tif) )
2684    {
2685        TIFFErrorExt( tif->tif_clientdata, module,
2686                      "Memory mapped files not currently supported for this operation." );
2687        return 0;
2688    }
2689
2690    if( tif->tif_diroff == 0 )
2691    {
2692        TIFFErrorExt( tif->tif_clientdata, module,
2693                      "Attempt to reset field on directory not already on disk." );
2694        return 0;
2695    }
2696
2697/* -------------------------------------------------------------------- */
2698/*      Read the directory entry count.                                 */
2699/* -------------------------------------------------------------------- */
2700    if (!SeekOK(tif, tif->tif_diroff)) {
2701        TIFFErrorExt(tif->tif_clientdata, module,
2702                     "%s: Seek error accessing TIFF directory",
2703                     tif->tif_name);
2704        return 0;
2705    }
2706
2707    read_offset = tif->tif_diroff;
2708
2709    if (!(tif->tif_flags&TIFF_BIGTIFF))
2710    {
2711        if (!ReadOK(tif, &dircount, sizeof (uint16))) {
2712            TIFFErrorExt(tif->tif_clientdata, module,
2713                         "%s: Can not read TIFF directory count",
2714                         tif->tif_name);
2715            return 0;
2716        }
2717        if (tif->tif_flags & TIFF_SWAB)
2718            TIFFSwabShort(&dircount);
2719        dirsize = 12;
2720        read_offset += 2;
2721    } else {
2722        uint64 dircount64;
2723        if (!ReadOK(tif, &dircount64, sizeof (uint64))) {
2724            TIFFErrorExt(tif->tif_clientdata, module,
2725                         "%s: Can not read TIFF directory count",
2726                         tif->tif_name);
2727            return 0;
2728        }
2729        if (tif->tif_flags & TIFF_SWAB)
2730            TIFFSwabLong8(&dircount64);
2731        dircount = (uint16)dircount64;
2732        dirsize = 20;
2733        read_offset += 8;
2734    }
2735
2736/* -------------------------------------------------------------------- */
2737/*      Read through directory to find target tag.                      */
2738/* -------------------------------------------------------------------- */
2739    while( dircount > 0 )
2740    {
2741        if (!ReadOK(tif, direntry_raw, dirsize)) {
2742            TIFFErrorExt(tif->tif_clientdata, module,
2743                         "%s: Can not read TIFF directory entry.",
2744                         tif->tif_name);
2745            return 0;
2746        }
2747
2748        memcpy( &entry_tag, direntry_raw + 0, sizeof(uint16) );
2749        if (tif->tif_flags&TIFF_SWAB)
2750            TIFFSwabShort( &entry_tag );
2751
2752        if( entry_tag == tag )
2753            break;
2754
2755        read_offset += dirsize;
2756    }
2757
2758    if( entry_tag != tag )
2759    {
2760        TIFFErrorExt(tif->tif_clientdata, module,
2761                     "%s: Could not find tag %d.",
2762                     tif->tif_name, tag );
2763        return 0;
2764    }
2765
2766/* -------------------------------------------------------------------- */
2767/*      Extract the type, count and offset for this entry.              */
2768/* -------------------------------------------------------------------- */
2769    memcpy( &entry_type, direntry_raw + 2, sizeof(uint16) );
2770    if (tif->tif_flags&TIFF_SWAB)
2771        TIFFSwabShort( &entry_type );
2772
2773    if (!(tif->tif_flags&TIFF_BIGTIFF))
2774    {
2775        uint32 value;
2776
2777        memcpy( &value, direntry_raw + 4, sizeof(uint32) );
2778        if (tif->tif_flags&TIFF_SWAB)
2779            TIFFSwabLong( &value );
2780        entry_count = value;
2781
2782        memcpy( &value, direntry_raw + 8, sizeof(uint32) );
2783        if (tif->tif_flags&TIFF_SWAB)
2784            TIFFSwabLong( &value );
2785        entry_offset = value;
2786    }
2787    else
2788    {
2789        memcpy( &entry_count, direntry_raw + 4, sizeof(uint64) );
2790        if (tif->tif_flags&TIFF_SWAB)
2791            TIFFSwabLong8( &entry_count );
2792
2793        memcpy( &entry_offset, direntry_raw + 12, sizeof(uint64) );
2794        if (tif->tif_flags&TIFF_SWAB)
2795            TIFFSwabLong8( &entry_offset );
2796    }
2797
2798/* -------------------------------------------------------------------- */
2799/*      What data type do we want to write this as?                     */
2800/* -------------------------------------------------------------------- */
2801    if( TIFFDataWidth(in_datatype) == 8 && !(tif->tif_flags&TIFF_BIGTIFF) )
2802    {
2803        if( in_datatype == TIFF_LONG8 )
2804            datatype = TIFF_LONG;
2805        else if( in_datatype == TIFF_SLONG8 )
2806            datatype = TIFF_SLONG;
2807        else if( in_datatype == TIFF_IFD8 )
2808            datatype = TIFF_IFD;
2809        else
2810            datatype = in_datatype;
2811    }
2812    else
2813        datatype = in_datatype;
2814
2815/* -------------------------------------------------------------------- */
2816/*      Prepare buffer of actual data to write.  This includes          */
2817/*      swabbing as needed.                                             */
2818/* -------------------------------------------------------------------- */
2819    buf_to_write =
2820	    (uint8 *)_TIFFCheckMalloc(tif, count, TIFFDataWidth(datatype),
2821				      "for field buffer.");
2822    if (!buf_to_write)
2823        return 0;
2824
2825    if( datatype == in_datatype )
2826        memcpy( buf_to_write, data, count * TIFFDataWidth(datatype) );
2827    else if( datatype == TIFF_SLONG && in_datatype == TIFF_SLONG8 )
2828    {
2829	tmsize_t i;
2830
2831        for( i = 0; i < count; i++ )
2832        {
2833            ((int32 *) buf_to_write)[i] =
2834                (int32) ((int64 *) data)[i];
2835            if( (int64) ((int32 *) buf_to_write)[i] != ((int64 *) data)[i] )
2836            {
2837                _TIFFfree( buf_to_write );
2838                TIFFErrorExt( tif->tif_clientdata, module,
2839                              "Value exceeds 32bit range of output type." );
2840                return 0;
2841            }
2842        }
2843    }
2844    else if( (datatype == TIFF_LONG && in_datatype == TIFF_LONG8)
2845             || (datatype == TIFF_IFD && in_datatype == TIFF_IFD8) )
2846    {
2847	tmsize_t i;
2848
2849        for( i = 0; i < count; i++ )
2850        {
2851            ((uint32 *) buf_to_write)[i] =
2852                (uint32) ((uint64 *) data)[i];
2853            if( (uint64) ((uint32 *) buf_to_write)[i] != ((uint64 *) data)[i] )
2854            {
2855                _TIFFfree( buf_to_write );
2856                TIFFErrorExt( tif->tif_clientdata, module,
2857                              "Value exceeds 32bit range of output type." );
2858                return 0;
2859            }
2860        }
2861    }
2862
2863    if( TIFFDataWidth(datatype) > 1 && (tif->tif_flags&TIFF_SWAB) )
2864    {
2865        if( TIFFDataWidth(datatype) == 2 )
2866            TIFFSwabArrayOfShort( (uint16 *) buf_to_write, count );
2867        else if( TIFFDataWidth(datatype) == 4 )
2868            TIFFSwabArrayOfLong( (uint32 *) buf_to_write, count );
2869        else if( TIFFDataWidth(datatype) == 8 )
2870            TIFFSwabArrayOfLong8( (uint64 *) buf_to_write, count );
2871    }
2872
2873/* -------------------------------------------------------------------- */
2874/*      Is this a value that fits into the directory entry?             */
2875/* -------------------------------------------------------------------- */
2876    if (!(tif->tif_flags&TIFF_BIGTIFF))
2877    {
2878        if( TIFFDataWidth(datatype) * count <= 4 )
2879        {
2880            entry_offset = read_offset + 8;
2881            value_in_entry = 1;
2882        }
2883    }
2884    else
2885    {
2886        if( TIFFDataWidth(datatype) * count <= 8 )
2887        {
2888            entry_offset = read_offset + 12;
2889            value_in_entry = 1;
2890        }
2891    }
2892
2893/* -------------------------------------------------------------------- */
2894/*      If the tag type, and count match, then we just write it out     */
2895/*      over the old values without altering the directory entry at     */
2896/*      all.                                                            */
2897/* -------------------------------------------------------------------- */
2898    if( entry_count == (uint64)count && entry_type == (uint16) datatype )
2899    {
2900        if (!SeekOK(tif, entry_offset)) {
2901            _TIFFfree( buf_to_write );
2902            TIFFErrorExt(tif->tif_clientdata, module,
2903                         "%s: Seek error accessing TIFF directory",
2904                         tif->tif_name);
2905            return 0;
2906        }
2907        if (!WriteOK(tif, buf_to_write, count*TIFFDataWidth(datatype))) {
2908            _TIFFfree( buf_to_write );
2909            TIFFErrorExt(tif->tif_clientdata, module,
2910                         "Error writing directory link");
2911            return (0);
2912        }
2913
2914        _TIFFfree( buf_to_write );
2915        return 1;
2916    }
2917
2918/* -------------------------------------------------------------------- */
2919/*      Otherwise, we write the new tag data at the end of the file.    */
2920/* -------------------------------------------------------------------- */
2921    if( !value_in_entry )
2922    {
2923        entry_offset = TIFFSeekFile(tif,0,SEEK_END);
2924
2925        if (!WriteOK(tif, buf_to_write, count*TIFFDataWidth(datatype))) {
2926            _TIFFfree( buf_to_write );
2927            TIFFErrorExt(tif->tif_clientdata, module,
2928                         "Error writing directory link");
2929            return (0);
2930        }
2931    }
2932    else
2933    {
2934        memcpy( &entry_offset, buf_to_write, count*TIFFDataWidth(datatype));
2935    }
2936
2937    _TIFFfree( buf_to_write );
2938    buf_to_write = 0;
2939
2940/* -------------------------------------------------------------------- */
2941/*      Adjust the directory entry.                                     */
2942/* -------------------------------------------------------------------- */
2943    entry_type = datatype;
2944    memcpy( direntry_raw + 2, &entry_type, sizeof(uint16) );
2945    if (tif->tif_flags&TIFF_SWAB)
2946        TIFFSwabShort( (uint16 *) (direntry_raw + 2) );
2947
2948    if (!(tif->tif_flags&TIFF_BIGTIFF))
2949    {
2950        uint32 value;
2951
2952        value = (uint32) entry_count;
2953        memcpy( direntry_raw + 4, &value, sizeof(uint32) );
2954        if (tif->tif_flags&TIFF_SWAB)
2955            TIFFSwabLong( (uint32 *) (direntry_raw + 4) );
2956
2957        value = (uint32) entry_offset;
2958        memcpy( direntry_raw + 8, &value, sizeof(uint32) );
2959        if (tif->tif_flags&TIFF_SWAB)
2960            TIFFSwabLong( (uint32 *) (direntry_raw + 8) );
2961    }
2962    else
2963    {
2964        memcpy( direntry_raw + 4, &entry_count, sizeof(uint64) );
2965        if (tif->tif_flags&TIFF_SWAB)
2966            TIFFSwabLong8( (uint64 *) (direntry_raw + 4) );
2967
2968        memcpy( direntry_raw + 12, &entry_offset, sizeof(uint64) );
2969        if (tif->tif_flags&TIFF_SWAB)
2970            TIFFSwabLong8( (uint64 *) (direntry_raw + 12) );
2971    }
2972
2973/* -------------------------------------------------------------------- */
2974/*      Write the directory entry out to disk.                          */
2975/* -------------------------------------------------------------------- */
2976    if (!SeekOK(tif, read_offset )) {
2977        TIFFErrorExt(tif->tif_clientdata, module,
2978                     "%s: Seek error accessing TIFF directory",
2979                     tif->tif_name);
2980        return 0;
2981    }
2982
2983    if (!WriteOK(tif, direntry_raw,dirsize))
2984    {
2985        TIFFErrorExt(tif->tif_clientdata, module,
2986                     "%s: Can not write TIFF directory entry.",
2987                     tif->tif_name);
2988        return 0;
2989    }
2990
2991    return 1;
2992}
2993/* vim: set ts=8 sts=8 sw=8 noet: */
2994/*
2995 * Local Variables:
2996 * mode: c
2997 * c-basic-offset: 8
2998 * fill-column: 78
2999 * End:
3000 */
3001