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