1 /* $Id$ */
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 					if (!TIFFWriteDirectoryTagLongLong8Array(tif,&ndir,dir,TIFFTAG_STRIPOFFSETS,tif->tif_dir.td_nstrips,tif->tif_dir.td_stripoffset))
546 						goto bad;
547 				}
548 				else
549 				{
550 					if (!TIFFWriteDirectoryTagLongLong8Array(tif,&ndir,dir,TIFFTAG_TILEOFFSETS,tif->tif_dir.td_nstrips,tif->tif_dir.td_stripoffset))
551 						goto bad;
552 				}
553 			}
554 			if (TIFFFieldSet(tif,FIELD_COLORMAP))
555 			{
556 				if (!TIFFWriteDirectoryTagColormap(tif,&ndir,dir))
557 					goto bad;
558 			}
559 			if (TIFFFieldSet(tif,FIELD_EXTRASAMPLES))
560 			{
561 				if (tif->tif_dir.td_extrasamples)
562 				{
563 					uint16 na;
564 					uint16* nb;
565 					TIFFGetFieldDefaulted(tif,TIFFTAG_EXTRASAMPLES,&na,&nb);
566 					if (!TIFFWriteDirectoryTagShortArray(tif,&ndir,dir,TIFFTAG_EXTRASAMPLES,na,nb))
567 						goto bad;
568 				}
569 			}
570 			if (TIFFFieldSet(tif,FIELD_SAMPLEFORMAT))
571 			{
572 				if (!TIFFWriteDirectoryTagShortPerSample(tif,&ndir,dir,TIFFTAG_SAMPLEFORMAT,tif->tif_dir.td_sampleformat))
573 					goto bad;
574 			}
575 			if (TIFFFieldSet(tif,FIELD_SMINSAMPLEVALUE))
576 			{
577 				if (!TIFFWriteDirectoryTagSampleformatArray(tif,&ndir,dir,TIFFTAG_SMINSAMPLEVALUE,tif->tif_dir.td_samplesperpixel,tif->tif_dir.td_sminsamplevalue))
578 					goto bad;
579 			}
580 			if (TIFFFieldSet(tif,FIELD_SMAXSAMPLEVALUE))
581 			{
582 				if (!TIFFWriteDirectoryTagSampleformatArray(tif,&ndir,dir,TIFFTAG_SMAXSAMPLEVALUE,tif->tif_dir.td_samplesperpixel,tif->tif_dir.td_smaxsamplevalue))
583 					goto bad;
584 			}
585 			if (TIFFFieldSet(tif,FIELD_IMAGEDEPTH))
586 			{
587 				if (!TIFFWriteDirectoryTagLong(tif,&ndir,dir,TIFFTAG_IMAGEDEPTH,tif->tif_dir.td_imagedepth))
588 					goto bad;
589 			}
590 			if (TIFFFieldSet(tif,FIELD_TILEDEPTH))
591 			{
592 				if (!TIFFWriteDirectoryTagLong(tif,&ndir,dir,TIFFTAG_TILEDEPTH,tif->tif_dir.td_tiledepth))
593 					goto bad;
594 			}
595 			if (TIFFFieldSet(tif,FIELD_HALFTONEHINTS))
596 			{
597 				if (!TIFFWriteDirectoryTagShortArray(tif,&ndir,dir,TIFFTAG_HALFTONEHINTS,2,&tif->tif_dir.td_halftonehints[0]))
598 					goto bad;
599 			}
600 			if (TIFFFieldSet(tif,FIELD_YCBCRSUBSAMPLING))
601 			{
602 				if (!TIFFWriteDirectoryTagShortArray(tif,&ndir,dir,TIFFTAG_YCBCRSUBSAMPLING,2,&tif->tif_dir.td_ycbcrsubsampling[0]))
603 					goto bad;
604 			}
605 			if (TIFFFieldSet(tif,FIELD_YCBCRPOSITIONING))
606 			{
607 				if (!TIFFWriteDirectoryTagShort(tif,&ndir,dir,TIFFTAG_YCBCRPOSITIONING,tif->tif_dir.td_ycbcrpositioning))
608 					goto bad;
609 			}
610 			if (TIFFFieldSet(tif,FIELD_REFBLACKWHITE))
611 			{
612 				if (!TIFFWriteDirectoryTagRationalArray(tif,&ndir,dir,TIFFTAG_REFERENCEBLACKWHITE,6,tif->tif_dir.td_refblackwhite))
613 					goto bad;
614 			}
615 			if (TIFFFieldSet(tif,FIELD_TRANSFERFUNCTION))
616 			{
617 				if (!TIFFWriteDirectoryTagTransferfunction(tif,&ndir,dir))
618 					goto bad;
619 			}
620 			if (TIFFFieldSet(tif,FIELD_INKNAMES))
621 			{
622 				if (!TIFFWriteDirectoryTagAscii(tif,&ndir,dir,TIFFTAG_INKNAMES,tif->tif_dir.td_inknameslen,tif->tif_dir.td_inknames))
623 					goto bad;
624 			}
625 			if (TIFFFieldSet(tif,FIELD_SUBIFD))
626 			{
627 				if (!TIFFWriteDirectoryTagSubifd(tif,&ndir,dir))
628 					goto bad;
629 			}
630 			{
631 				uint32 n;
632 				for (n=0; n<tif->tif_nfields; n++) {
633 					const TIFFField* o;
634 					o = tif->tif_fields[n];
635 					if ((o->field_bit>=FIELD_CODEC)&&(TIFFFieldSet(tif,o->field_bit)))
636 					{
637 						switch (o->get_field_type)
638 						{
639 							case TIFF_SETGET_ASCII:
640 								{
641 									uint32 pa;
642 									char* pb;
643 									assert(o->field_type==TIFF_ASCII);
644 									assert(o->field_readcount==TIFF_VARIABLE);
645 									assert(o->field_passcount==0);
646 									TIFFGetField(tif,o->field_tag,&pb);
647 									pa=(uint32)(strlen(pb));
648 									if (!TIFFWriteDirectoryTagAscii(tif,&ndir,dir,(uint16)o->field_tag,pa,pb))
649 										goto bad;
650 								}
651 								break;
652 							case TIFF_SETGET_UINT16:
653 								{
654 									uint16 p;
655 									assert(o->field_type==TIFF_SHORT);
656 									assert(o->field_readcount==1);
657 									assert(o->field_passcount==0);
658 									TIFFGetField(tif,o->field_tag,&p);
659 									if (!TIFFWriteDirectoryTagShort(tif,&ndir,dir,(uint16)o->field_tag,p))
660 										goto bad;
661 								}
662 								break;
663 							case TIFF_SETGET_UINT32:
664 								{
665 									uint32 p;
666 									assert(o->field_type==TIFF_LONG);
667 									assert(o->field_readcount==1);
668 									assert(o->field_passcount==0);
669 									TIFFGetField(tif,o->field_tag,&p);
670 									if (!TIFFWriteDirectoryTagLong(tif,&ndir,dir,(uint16)o->field_tag,p))
671 										goto bad;
672 								}
673 								break;
674 							case TIFF_SETGET_C32_UINT8:
675 								{
676 									uint32 pa;
677 									void* pb;
678 									assert(o->field_type==TIFF_UNDEFINED);
679 									assert(o->field_readcount==TIFF_VARIABLE2);
680 									assert(o->field_passcount==1);
681 									TIFFGetField(tif,o->field_tag,&pa,&pb);
682 									if (!TIFFWriteDirectoryTagUndefinedArray(tif,&ndir,dir,(uint16)o->field_tag,pa,pb))
683 										goto bad;
684 								}
685 								break;
686 							default:
687 								assert(0);   /* we should never get here */
688 								break;
689 						}
690 					}
691 				}
692 			}
693 		}
694 		for (m=0; m<(uint32)(tif->tif_dir.td_customValueCount); m++)
695 		{
696                         uint16 tag = (uint16)tif->tif_dir.td_customValues[m].info->field_tag;
697                         uint32 count = tif->tif_dir.td_customValues[m].count;
698 			switch (tif->tif_dir.td_customValues[m].info->field_type)
699 			{
700 				case TIFF_ASCII:
701 					if (!TIFFWriteDirectoryTagAscii(tif,&ndir,dir,tag,count,tif->tif_dir.td_customValues[m].value))
702 						goto bad;
703 					break;
704 				case TIFF_UNDEFINED:
705 					if (!TIFFWriteDirectoryTagUndefinedArray(tif,&ndir,dir,tag,count,tif->tif_dir.td_customValues[m].value))
706 						goto bad;
707 					break;
708 				case TIFF_BYTE:
709 					if (!TIFFWriteDirectoryTagByteArray(tif,&ndir,dir,tag,count,tif->tif_dir.td_customValues[m].value))
710 						goto bad;
711 					break;
712 				case TIFF_SBYTE:
713 					if (!TIFFWriteDirectoryTagSbyteArray(tif,&ndir,dir,tag,count,tif->tif_dir.td_customValues[m].value))
714 						goto bad;
715 					break;
716 				case TIFF_SHORT:
717 					if (!TIFFWriteDirectoryTagShortArray(tif,&ndir,dir,tag,count,tif->tif_dir.td_customValues[m].value))
718 						goto bad;
719 					break;
720 				case TIFF_SSHORT:
721 					if (!TIFFWriteDirectoryTagSshortArray(tif,&ndir,dir,tag,count,tif->tif_dir.td_customValues[m].value))
722 						goto bad;
723 					break;
724 				case TIFF_LONG:
725 					if (!TIFFWriteDirectoryTagLongArray(tif,&ndir,dir,tag,count,tif->tif_dir.td_customValues[m].value))
726 						goto bad;
727 					break;
728 				case TIFF_SLONG:
729 					if (!TIFFWriteDirectoryTagSlongArray(tif,&ndir,dir,tag,count,tif->tif_dir.td_customValues[m].value))
730 						goto bad;
731 					break;
732 				case TIFF_LONG8:
733 					if (!TIFFWriteDirectoryTagLong8Array(tif,&ndir,dir,tag,count,tif->tif_dir.td_customValues[m].value))
734 						goto bad;
735 					break;
736 				case TIFF_SLONG8:
737 					if (!TIFFWriteDirectoryTagSlong8Array(tif,&ndir,dir,tag,count,tif->tif_dir.td_customValues[m].value))
738 						goto bad;
739 					break;
740 				case TIFF_RATIONAL:
741 					if (!TIFFWriteDirectoryTagRationalArray(tif,&ndir,dir,tag,count,tif->tif_dir.td_customValues[m].value))
742 						goto bad;
743 					break;
744 				case TIFF_SRATIONAL:
745 					if (!TIFFWriteDirectoryTagSrationalArray(tif,&ndir,dir,tag,count,tif->tif_dir.td_customValues[m].value))
746 						goto bad;
747 					break;
748 				case TIFF_FLOAT:
749 					if (!TIFFWriteDirectoryTagFloatArray(tif,&ndir,dir,tag,count,tif->tif_dir.td_customValues[m].value))
750 						goto bad;
751 					break;
752 				case TIFF_DOUBLE:
753 					if (!TIFFWriteDirectoryTagDoubleArray(tif,&ndir,dir,tag,count,tif->tif_dir.td_customValues[m].value))
754 						goto bad;
755 					break;
756 				case TIFF_IFD:
757 					if (!TIFFWriteDirectoryTagIfdArray(tif,&ndir,dir,tag,count,tif->tif_dir.td_customValues[m].value))
758 						goto bad;
759 					break;
760 				case TIFF_IFD8:
761 					if (!TIFFWriteDirectoryTagIfdIfd8Array(tif,&ndir,dir,tag,count,tif->tif_dir.td_customValues[m].value))
762 						goto bad;
763 					break;
764 				default:
765 					assert(0);   /* we should never get here */
766 					break;
767 			}
768 		}
769 		if (dir!=NULL)
770 			break;
771 		dir=_TIFFmalloc(ndir*sizeof(TIFFDirEntry));
772 		if (dir==NULL)
773 		{
774 			TIFFErrorExt(tif->tif_clientdata,module,"Out of memory");
775 			goto bad;
776 		}
777 		if (isimage)
778 		{
779 			if ((tif->tif_diroff==0)&&(!TIFFLinkDirectory(tif)))
780 				goto bad;
781 		}
782 		else
783 			tif->tif_diroff=(TIFFSeekFile(tif,0,SEEK_END)+1)&(~((toff_t)1));
784 		if (pdiroff!=NULL)
785 			*pdiroff=tif->tif_diroff;
786 		if (!(tif->tif_flags&TIFF_BIGTIFF))
787 			dirsize=2+ndir*12+4;
788 		else
789 			dirsize=8+ndir*20+8;
790 		tif->tif_dataoff=tif->tif_diroff+dirsize;
791 		if (!(tif->tif_flags&TIFF_BIGTIFF))
792 			tif->tif_dataoff=(uint32)tif->tif_dataoff;
793 		if ((tif->tif_dataoff<tif->tif_diroff)||(tif->tif_dataoff<(uint64)dirsize))
794 		{
795 			TIFFErrorExt(tif->tif_clientdata,module,"Maximum TIFF file size exceeded");
796 			goto bad;
797 		}
798 		if (tif->tif_dataoff&1)
799 			tif->tif_dataoff++;
800 		if (isimage)
801 			tif->tif_curdir++;
802 	}
803 	if (isimage)
804 	{
805 		if (TIFFFieldSet(tif,FIELD_SUBIFD)&&(tif->tif_subifdoff==0))
806 		{
807 			uint32 na;
808 			TIFFDirEntry* nb;
809 			for (na=0, nb=dir; ; na++, nb++)
810 			{
811 				assert(na<ndir);
812 				if (nb->tdir_tag==TIFFTAG_SUBIFD)
813 					break;
814 			}
815 			if (!(tif->tif_flags&TIFF_BIGTIFF))
816 				tif->tif_subifdoff=tif->tif_diroff+2+na*12+8;
817 			else
818 				tif->tif_subifdoff=tif->tif_diroff+8+na*20+12;
819 		}
820 	}
821 	dirmem=_TIFFmalloc(dirsize);
822 	if (dirmem==NULL)
823 	{
824 		TIFFErrorExt(tif->tif_clientdata,module,"Out of memory");
825 		goto bad;
826 	}
827 	if (!(tif->tif_flags&TIFF_BIGTIFF))
828 	{
829 		uint8* n;
830 		uint32 nTmp;
831 		TIFFDirEntry* o;
832 		n=dirmem;
833 		*(uint16*)n=(uint16)ndir;
834 		if (tif->tif_flags&TIFF_SWAB)
835 			TIFFSwabShort((uint16*)n);
836 		n+=2;
837 		o=dir;
838 		for (m=0; m<ndir; m++)
839 		{
840 			*(uint16*)n=o->tdir_tag;
841 			if (tif->tif_flags&TIFF_SWAB)
842 				TIFFSwabShort((uint16*)n);
843 			n+=2;
844 			*(uint16*)n=o->tdir_type;
845 			if (tif->tif_flags&TIFF_SWAB)
846 				TIFFSwabShort((uint16*)n);
847 			n+=2;
848 			nTmp = (uint32)o->tdir_count;
849 			_TIFFmemcpy(n,&nTmp,4);
850 			if (tif->tif_flags&TIFF_SWAB)
851 				TIFFSwabLong((uint32*)n);
852 			n+=4;
853 			/* This is correct. The data has been */
854 			/* swabbed previously in TIFFWriteDirectoryTagData */
855 			_TIFFmemcpy(n,&o->tdir_offset,4);
856 			n+=4;
857 			o++;
858 		}
859 		nTmp = (uint32)tif->tif_nextdiroff;
860 		if (tif->tif_flags&TIFF_SWAB)
861 			TIFFSwabLong(&nTmp);
862 		_TIFFmemcpy(n,&nTmp,4);
863 	}
864 	else
865 	{
866 		uint8* n;
867 		TIFFDirEntry* o;
868 		n=dirmem;
869 		*(uint64*)n=ndir;
870 		if (tif->tif_flags&TIFF_SWAB)
871 			TIFFSwabLong8((uint64*)n);
872 		n+=8;
873 		o=dir;
874 		for (m=0; m<ndir; m++)
875 		{
876 			*(uint16*)n=o->tdir_tag;
877 			if (tif->tif_flags&TIFF_SWAB)
878 				TIFFSwabShort((uint16*)n);
879 			n+=2;
880 			*(uint16*)n=o->tdir_type;
881 			if (tif->tif_flags&TIFF_SWAB)
882 				TIFFSwabShort((uint16*)n);
883 			n+=2;
884 			_TIFFmemcpy(n,&o->tdir_count,8);
885 			if (tif->tif_flags&TIFF_SWAB)
886 				TIFFSwabLong8((uint64*)n);
887 			n+=8;
888 			_TIFFmemcpy(n,&o->tdir_offset,8);
889 			n+=8;
890 			o++;
891 		}
892 		_TIFFmemcpy(n,&tif->tif_nextdiroff,8);
893 		if (tif->tif_flags&TIFF_SWAB)
894 			TIFFSwabLong8((uint64*)n);
895 	}
896 	_TIFFfree(dir);
897 	dir=NULL;
898 	if (!SeekOK(tif,tif->tif_diroff))
899 	{
900 		TIFFErrorExt(tif->tif_clientdata,module,"IO error writing directory");
901 		goto bad;
902 	}
903 	if (!WriteOK(tif,dirmem,(tmsize_t)dirsize))
904 	{
905 		TIFFErrorExt(tif->tif_clientdata,module,"IO error writing directory");
906 		goto bad;
907 	}
908 	_TIFFfree(dirmem);
909 	if (imagedone)
910 	{
911 		TIFFFreeDirectory(tif);
912 		tif->tif_flags &= ~TIFF_DIRTYDIRECT;
913 		tif->tif_flags &= ~TIFF_DIRTYSTRIP;
914 		(*tif->tif_cleanup)(tif);
915 		/*
916 		* Reset directory-related state for subsequent
917 		* directories.
918 		*/
919 		TIFFCreateDirectory(tif);
920 	}
921 	return(1);
922 bad:
923 	if (dir!=NULL)
924 		_TIFFfree(dir);
925 	if (dirmem!=NULL)
926 		_TIFFfree(dirmem);
927 	return(0);
928 }
929 
930 static int
TIFFWriteDirectoryTagSampleformatArray(TIFF * tif,uint32 * ndir,TIFFDirEntry * dir,uint16 tag,uint32 count,double * value)931 TIFFWriteDirectoryTagSampleformatArray(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, double* value)
932 {
933 	static const char module[] = "TIFFWriteDirectoryTagSampleformatArray";
934 	void* conv;
935 	uint32 i;
936 	int ok;
937 	conv = _TIFFmalloc(count*sizeof(double));
938 	if (conv == NULL)
939 	{
940 		TIFFErrorExt(tif->tif_clientdata, module, "Out of memory");
941 		return (0);
942 	}
943 
944 	switch (tif->tif_dir.td_sampleformat)
945 	{
946 		case SAMPLEFORMAT_IEEEFP:
947 			if (tif->tif_dir.td_bitspersample<=32)
948 			{
949 				for (i = 0; i < count; ++i)
950 					((float*)conv)[i] = (float)value[i];
951 				ok = TIFFWriteDirectoryTagFloatArray(tif,ndir,dir,tag,count,(float*)conv);
952 			}
953 			else
954 			{
955 				ok = TIFFWriteDirectoryTagDoubleArray(tif,ndir,dir,tag,count,value);
956 			}
957 			break;
958 		case SAMPLEFORMAT_INT:
959 			if (tif->tif_dir.td_bitspersample<=8)
960 			{
961 				for (i = 0; i < count; ++i)
962 					((int8*)conv)[i] = (int8)value[i];
963 				ok = TIFFWriteDirectoryTagSbyteArray(tif,ndir,dir,tag,count,(int8*)conv);
964 			}
965 			else if (tif->tif_dir.td_bitspersample<=16)
966 			{
967 				for (i = 0; i < count; ++i)
968 					((int16*)conv)[i] = (int16)value[i];
969 				ok = TIFFWriteDirectoryTagSshortArray(tif,ndir,dir,tag,count,(int16*)conv);
970 			}
971 			else
972 			{
973 				for (i = 0; i < count; ++i)
974 					((int32*)conv)[i] = (int32)value[i];
975 				ok = TIFFWriteDirectoryTagSlongArray(tif,ndir,dir,tag,count,(int32*)conv);
976 			}
977 			break;
978 		case SAMPLEFORMAT_UINT:
979 			if (tif->tif_dir.td_bitspersample<=8)
980 			{
981 				for (i = 0; i < count; ++i)
982 					((uint8*)conv)[i] = (uint8)value[i];
983 				ok = TIFFWriteDirectoryTagByteArray(tif,ndir,dir,tag,count,(uint8*)conv);
984 			}
985 			else if (tif->tif_dir.td_bitspersample<=16)
986 			{
987 				for (i = 0; i < count; ++i)
988 					((uint16*)conv)[i] = (uint16)value[i];
989 				ok = TIFFWriteDirectoryTagShortArray(tif,ndir,dir,tag,count,(uint16*)conv);
990 			}
991 			else
992 			{
993 				for (i = 0; i < count; ++i)
994 					((uint32*)conv)[i] = (uint32)value[i];
995 				ok = TIFFWriteDirectoryTagLongArray(tif,ndir,dir,tag,count,(uint32*)conv);
996 			}
997 			break;
998 		default:
999 			ok = 0;
1000 	}
1001 
1002 	_TIFFfree(conv);
1003 	return (ok);
1004 }
1005 
1006 #if 0
1007 static int
1008 TIFFWriteDirectoryTagSampleformatPerSample(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, double value)
1009 {
1010 	switch (tif->tif_dir.td_sampleformat)
1011 	{
1012 		case SAMPLEFORMAT_IEEEFP:
1013 			if (tif->tif_dir.td_bitspersample<=32)
1014 				return(TIFFWriteDirectoryTagFloatPerSample(tif,ndir,dir,tag,(float)value));
1015 			else
1016 				return(TIFFWriteDirectoryTagDoublePerSample(tif,ndir,dir,tag,value));
1017 		case SAMPLEFORMAT_INT:
1018 			if (tif->tif_dir.td_bitspersample<=8)
1019 				return(TIFFWriteDirectoryTagSbytePerSample(tif,ndir,dir,tag,(int8)value));
1020 			else if (tif->tif_dir.td_bitspersample<=16)
1021 				return(TIFFWriteDirectoryTagSshortPerSample(tif,ndir,dir,tag,(int16)value));
1022 			else
1023 				return(TIFFWriteDirectoryTagSlongPerSample(tif,ndir,dir,tag,(int32)value));
1024 		case SAMPLEFORMAT_UINT:
1025 			if (tif->tif_dir.td_bitspersample<=8)
1026 				return(TIFFWriteDirectoryTagBytePerSample(tif,ndir,dir,tag,(uint8)value));
1027 			else if (tif->tif_dir.td_bitspersample<=16)
1028 				return(TIFFWriteDirectoryTagShortPerSample(tif,ndir,dir,tag,(uint16)value));
1029 			else
1030 				return(TIFFWriteDirectoryTagLongPerSample(tif,ndir,dir,tag,(uint32)value));
1031 		default:
1032 			return(1);
1033 	}
1034 }
1035 #endif
1036 
1037 static int
TIFFWriteDirectoryTagAscii(TIFF * tif,uint32 * ndir,TIFFDirEntry * dir,uint16 tag,uint32 count,char * value)1038 TIFFWriteDirectoryTagAscii(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, char* value)
1039 {
1040 	if (dir==NULL)
1041 	{
1042 		(*ndir)++;
1043 		return(1);
1044 	}
1045 	return(TIFFWriteDirectoryTagCheckedAscii(tif,ndir,dir,tag,count,value));
1046 }
1047 
1048 static int
TIFFWriteDirectoryTagUndefinedArray(TIFF * tif,uint32 * ndir,TIFFDirEntry * dir,uint16 tag,uint32 count,uint8 * value)1049 TIFFWriteDirectoryTagUndefinedArray(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, uint8* value)
1050 {
1051 	if (dir==NULL)
1052 	{
1053 		(*ndir)++;
1054 		return(1);
1055 	}
1056 	return(TIFFWriteDirectoryTagCheckedUndefinedArray(tif,ndir,dir,tag,count,value));
1057 }
1058 
1059 #ifdef notdef
1060 static int
TIFFWriteDirectoryTagByte(TIFF * tif,uint32 * ndir,TIFFDirEntry * dir,uint16 tag,uint8 value)1061 TIFFWriteDirectoryTagByte(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint8 value)
1062 {
1063 	if (dir==NULL)
1064 	{
1065 		(*ndir)++;
1066 		return(1);
1067 	}
1068 	return(TIFFWriteDirectoryTagCheckedByte(tif,ndir,dir,tag,value));
1069 }
1070 #endif
1071 
1072 static int
TIFFWriteDirectoryTagByteArray(TIFF * tif,uint32 * ndir,TIFFDirEntry * dir,uint16 tag,uint32 count,uint8 * value)1073 TIFFWriteDirectoryTagByteArray(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, uint8* value)
1074 {
1075 	if (dir==NULL)
1076 	{
1077 		(*ndir)++;
1078 		return(1);
1079 	}
1080 	return(TIFFWriteDirectoryTagCheckedByteArray(tif,ndir,dir,tag,count,value));
1081 }
1082 
1083 #if 0
1084 static int
1085 TIFFWriteDirectoryTagBytePerSample(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint8 value)
1086 {
1087 	static const char module[] = "TIFFWriteDirectoryTagBytePerSample";
1088 	uint8* m;
1089 	uint8* na;
1090 	uint16 nb;
1091 	int o;
1092 	if (dir==NULL)
1093 	{
1094 		(*ndir)++;
1095 		return(1);
1096 	}
1097 	m=_TIFFmalloc(tif->tif_dir.td_samplesperpixel*sizeof(uint8));
1098 	if (m==NULL)
1099 	{
1100 		TIFFErrorExt(tif->tif_clientdata,module,"Out of memory");
1101 		return(0);
1102 	}
1103 	for (na=m, nb=0; nb<tif->tif_dir.td_samplesperpixel; na++, nb++)
1104 		*na=value;
1105 	o=TIFFWriteDirectoryTagCheckedByteArray(tif,ndir,dir,tag,tif->tif_dir.td_samplesperpixel,m);
1106 	_TIFFfree(m);
1107 	return(o);
1108 }
1109 #endif
1110 
1111 #ifdef notdef
1112 static int
TIFFWriteDirectoryTagSbyte(TIFF * tif,uint32 * ndir,TIFFDirEntry * dir,uint16 tag,int8 value)1113 TIFFWriteDirectoryTagSbyte(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, int8 value)
1114 {
1115 	if (dir==NULL)
1116 	{
1117 		(*ndir)++;
1118 		return(1);
1119 	}
1120 	return(TIFFWriteDirectoryTagCheckedSbyte(tif,ndir,dir,tag,value));
1121 }
1122 #endif
1123 
1124 static int
TIFFWriteDirectoryTagSbyteArray(TIFF * tif,uint32 * ndir,TIFFDirEntry * dir,uint16 tag,uint32 count,int8 * value)1125 TIFFWriteDirectoryTagSbyteArray(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, int8* value)
1126 {
1127 	if (dir==NULL)
1128 	{
1129 		(*ndir)++;
1130 		return(1);
1131 	}
1132 	return(TIFFWriteDirectoryTagCheckedSbyteArray(tif,ndir,dir,tag,count,value));
1133 }
1134 
1135 #if 0
1136 static int
1137 TIFFWriteDirectoryTagSbytePerSample(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, int8 value)
1138 {
1139 	static const char module[] = "TIFFWriteDirectoryTagSbytePerSample";
1140 	int8* m;
1141 	int8* na;
1142 	uint16 nb;
1143 	int o;
1144 	if (dir==NULL)
1145 	{
1146 		(*ndir)++;
1147 		return(1);
1148 	}
1149 	m=_TIFFmalloc(tif->tif_dir.td_samplesperpixel*sizeof(int8));
1150 	if (m==NULL)
1151 	{
1152 		TIFFErrorExt(tif->tif_clientdata,module,"Out of memory");
1153 		return(0);
1154 	}
1155 	for (na=m, nb=0; nb<tif->tif_dir.td_samplesperpixel; na++, nb++)
1156 		*na=value;
1157 	o=TIFFWriteDirectoryTagCheckedSbyteArray(tif,ndir,dir,tag,tif->tif_dir.td_samplesperpixel,m);
1158 	_TIFFfree(m);
1159 	return(o);
1160 }
1161 #endif
1162 
1163 static int
TIFFWriteDirectoryTagShort(TIFF * tif,uint32 * ndir,TIFFDirEntry * dir,uint16 tag,uint16 value)1164 TIFFWriteDirectoryTagShort(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint16 value)
1165 {
1166 	if (dir==NULL)
1167 	{
1168 		(*ndir)++;
1169 		return(1);
1170 	}
1171 	return(TIFFWriteDirectoryTagCheckedShort(tif,ndir,dir,tag,value));
1172 }
1173 
1174 static int
TIFFWriteDirectoryTagShortArray(TIFF * tif,uint32 * ndir,TIFFDirEntry * dir,uint16 tag,uint32 count,uint16 * value)1175 TIFFWriteDirectoryTagShortArray(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, uint16* value)
1176 {
1177 	if (dir==NULL)
1178 	{
1179 		(*ndir)++;
1180 		return(1);
1181 	}
1182 	return(TIFFWriteDirectoryTagCheckedShortArray(tif,ndir,dir,tag,count,value));
1183 }
1184 
1185 static int
TIFFWriteDirectoryTagShortPerSample(TIFF * tif,uint32 * ndir,TIFFDirEntry * dir,uint16 tag,uint16 value)1186 TIFFWriteDirectoryTagShortPerSample(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint16 value)
1187 {
1188 	static const char module[] = "TIFFWriteDirectoryTagShortPerSample";
1189 	uint16* m;
1190 	uint16* na;
1191 	uint16 nb;
1192 	int o;
1193 	if (dir==NULL)
1194 	{
1195 		(*ndir)++;
1196 		return(1);
1197 	}
1198 	m=_TIFFmalloc(tif->tif_dir.td_samplesperpixel*sizeof(uint16));
1199 	if (m==NULL)
1200 	{
1201 		TIFFErrorExt(tif->tif_clientdata,module,"Out of memory");
1202 		return(0);
1203 	}
1204 	for (na=m, nb=0; nb<tif->tif_dir.td_samplesperpixel; na++, nb++)
1205 		*na=value;
1206 	o=TIFFWriteDirectoryTagCheckedShortArray(tif,ndir,dir,tag,tif->tif_dir.td_samplesperpixel,m);
1207 	_TIFFfree(m);
1208 	return(o);
1209 }
1210 
1211 #ifdef notdef
1212 static int
TIFFWriteDirectoryTagSshort(TIFF * tif,uint32 * ndir,TIFFDirEntry * dir,uint16 tag,int16 value)1213 TIFFWriteDirectoryTagSshort(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, int16 value)
1214 {
1215 	if (dir==NULL)
1216 	{
1217 		(*ndir)++;
1218 		return(1);
1219 	}
1220 	return(TIFFWriteDirectoryTagCheckedSshort(tif,ndir,dir,tag,value));
1221 }
1222 #endif
1223 
1224 static int
TIFFWriteDirectoryTagSshortArray(TIFF * tif,uint32 * ndir,TIFFDirEntry * dir,uint16 tag,uint32 count,int16 * value)1225 TIFFWriteDirectoryTagSshortArray(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, int16* value)
1226 {
1227 	if (dir==NULL)
1228 	{
1229 		(*ndir)++;
1230 		return(1);
1231 	}
1232 	return(TIFFWriteDirectoryTagCheckedSshortArray(tif,ndir,dir,tag,count,value));
1233 }
1234 
1235 #if 0
1236 static int
1237 TIFFWriteDirectoryTagSshortPerSample(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, int16 value)
1238 {
1239 	static const char module[] = "TIFFWriteDirectoryTagSshortPerSample";
1240 	int16* m;
1241 	int16* na;
1242 	uint16 nb;
1243 	int o;
1244 	if (dir==NULL)
1245 	{
1246 		(*ndir)++;
1247 		return(1);
1248 	}
1249 	m=_TIFFmalloc(tif->tif_dir.td_samplesperpixel*sizeof(int16));
1250 	if (m==NULL)
1251 	{
1252 		TIFFErrorExt(tif->tif_clientdata,module,"Out of memory");
1253 		return(0);
1254 	}
1255 	for (na=m, nb=0; nb<tif->tif_dir.td_samplesperpixel; na++, nb++)
1256 		*na=value;
1257 	o=TIFFWriteDirectoryTagCheckedSshortArray(tif,ndir,dir,tag,tif->tif_dir.td_samplesperpixel,m);
1258 	_TIFFfree(m);
1259 	return(o);
1260 }
1261 #endif
1262 
1263 static int
TIFFWriteDirectoryTagLong(TIFF * tif,uint32 * ndir,TIFFDirEntry * dir,uint16 tag,uint32 value)1264 TIFFWriteDirectoryTagLong(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 value)
1265 {
1266 	if (dir==NULL)
1267 	{
1268 		(*ndir)++;
1269 		return(1);
1270 	}
1271 	return(TIFFWriteDirectoryTagCheckedLong(tif,ndir,dir,tag,value));
1272 }
1273 
1274 static int
TIFFWriteDirectoryTagLongArray(TIFF * tif,uint32 * ndir,TIFFDirEntry * dir,uint16 tag,uint32 count,uint32 * value)1275 TIFFWriteDirectoryTagLongArray(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, uint32* value)
1276 {
1277 	if (dir==NULL)
1278 	{
1279 		(*ndir)++;
1280 		return(1);
1281 	}
1282 	return(TIFFWriteDirectoryTagCheckedLongArray(tif,ndir,dir,tag,count,value));
1283 }
1284 
1285 #if 0
1286 static int
1287 TIFFWriteDirectoryTagLongPerSample(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 value)
1288 {
1289 	static const char module[] = "TIFFWriteDirectoryTagLongPerSample";
1290 	uint32* m;
1291 	uint32* na;
1292 	uint16 nb;
1293 	int o;
1294 	if (dir==NULL)
1295 	{
1296 		(*ndir)++;
1297 		return(1);
1298 	}
1299 	m=_TIFFmalloc(tif->tif_dir.td_samplesperpixel*sizeof(uint32));
1300 	if (m==NULL)
1301 	{
1302 		TIFFErrorExt(tif->tif_clientdata,module,"Out of memory");
1303 		return(0);
1304 	}
1305 	for (na=m, nb=0; nb<tif->tif_dir.td_samplesperpixel; na++, nb++)
1306 		*na=value;
1307 	o=TIFFWriteDirectoryTagCheckedLongArray(tif,ndir,dir,tag,tif->tif_dir.td_samplesperpixel,m);
1308 	_TIFFfree(m);
1309 	return(o);
1310 }
1311 #endif
1312 
1313 #ifdef notdef
1314 static int
TIFFWriteDirectoryTagSlong(TIFF * tif,uint32 * ndir,TIFFDirEntry * dir,uint16 tag,int32 value)1315 TIFFWriteDirectoryTagSlong(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, int32 value)
1316 {
1317 	if (dir==NULL)
1318 	{
1319 		(*ndir)++;
1320 		return(1);
1321 	}
1322 	return(TIFFWriteDirectoryTagCheckedSlong(tif,ndir,dir,tag,value));
1323 }
1324 #endif
1325 
1326 static int
TIFFWriteDirectoryTagSlongArray(TIFF * tif,uint32 * ndir,TIFFDirEntry * dir,uint16 tag,uint32 count,int32 * value)1327 TIFFWriteDirectoryTagSlongArray(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, int32* value)
1328 {
1329 	if (dir==NULL)
1330 	{
1331 		(*ndir)++;
1332 		return(1);
1333 	}
1334 	return(TIFFWriteDirectoryTagCheckedSlongArray(tif,ndir,dir,tag,count,value));
1335 }
1336 
1337 #if 0
1338 static int
1339 TIFFWriteDirectoryTagSlongPerSample(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, int32 value)
1340 {
1341 	static const char module[] = "TIFFWriteDirectoryTagSlongPerSample";
1342 	int32* m;
1343 	int32* na;
1344 	uint16 nb;
1345 	int o;
1346 	if (dir==NULL)
1347 	{
1348 		(*ndir)++;
1349 		return(1);
1350 	}
1351 	m=_TIFFmalloc(tif->tif_dir.td_samplesperpixel*sizeof(int32));
1352 	if (m==NULL)
1353 	{
1354 		TIFFErrorExt(tif->tif_clientdata,module,"Out of memory");
1355 		return(0);
1356 	}
1357 	for (na=m, nb=0; nb<tif->tif_dir.td_samplesperpixel; na++, nb++)
1358 		*na=value;
1359 	o=TIFFWriteDirectoryTagCheckedSlongArray(tif,ndir,dir,tag,tif->tif_dir.td_samplesperpixel,m);
1360 	_TIFFfree(m);
1361 	return(o);
1362 }
1363 #endif
1364 
1365 #ifdef notdef
1366 static int
TIFFWriteDirectoryTagLong8(TIFF * tif,uint32 * ndir,TIFFDirEntry * dir,uint16 tag,uint64 value)1367 TIFFWriteDirectoryTagLong8(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint64 value)
1368 {
1369 	if (dir==NULL)
1370 	{
1371 		(*ndir)++;
1372 		return(1);
1373 	}
1374 	return(TIFFWriteDirectoryTagCheckedLong8(tif,ndir,dir,tag,value));
1375 }
1376 #endif
1377 
1378 static int
TIFFWriteDirectoryTagLong8Array(TIFF * tif,uint32 * ndir,TIFFDirEntry * dir,uint16 tag,uint32 count,uint64 * value)1379 TIFFWriteDirectoryTagLong8Array(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, uint64* value)
1380 {
1381 	if (dir==NULL)
1382 	{
1383 		(*ndir)++;
1384 		return(1);
1385 	}
1386 	return(TIFFWriteDirectoryTagCheckedLong8Array(tif,ndir,dir,tag,count,value));
1387 }
1388 
1389 #ifdef notdef
1390 static int
TIFFWriteDirectoryTagSlong8(TIFF * tif,uint32 * ndir,TIFFDirEntry * dir,uint16 tag,int64 value)1391 TIFFWriteDirectoryTagSlong8(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, int64 value)
1392 {
1393 	if (dir==NULL)
1394 	{
1395 		(*ndir)++;
1396 		return(1);
1397 	}
1398 	return(TIFFWriteDirectoryTagCheckedSlong8(tif,ndir,dir,tag,value));
1399 }
1400 #endif
1401 
1402 static int
TIFFWriteDirectoryTagSlong8Array(TIFF * tif,uint32 * ndir,TIFFDirEntry * dir,uint16 tag,uint32 count,int64 * value)1403 TIFFWriteDirectoryTagSlong8Array(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, int64* value)
1404 {
1405 	if (dir==NULL)
1406 	{
1407 		(*ndir)++;
1408 		return(1);
1409 	}
1410 	return(TIFFWriteDirectoryTagCheckedSlong8Array(tif,ndir,dir,tag,count,value));
1411 }
1412 
1413 static int
TIFFWriteDirectoryTagRational(TIFF * tif,uint32 * ndir,TIFFDirEntry * dir,uint16 tag,double value)1414 TIFFWriteDirectoryTagRational(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, double value)
1415 {
1416 	if (dir==NULL)
1417 	{
1418 		(*ndir)++;
1419 		return(1);
1420 	}
1421 	return(TIFFWriteDirectoryTagCheckedRational(tif,ndir,dir,tag,value));
1422 }
1423 
1424 static int
TIFFWriteDirectoryTagRationalArray(TIFF * tif,uint32 * ndir,TIFFDirEntry * dir,uint16 tag,uint32 count,float * value)1425 TIFFWriteDirectoryTagRationalArray(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, float* value)
1426 {
1427 	if (dir==NULL)
1428 	{
1429 		(*ndir)++;
1430 		return(1);
1431 	}
1432 	return(TIFFWriteDirectoryTagCheckedRationalArray(tif,ndir,dir,tag,count,value));
1433 }
1434 
1435 static int
TIFFWriteDirectoryTagSrationalArray(TIFF * tif,uint32 * ndir,TIFFDirEntry * dir,uint16 tag,uint32 count,float * value)1436 TIFFWriteDirectoryTagSrationalArray(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, float* value)
1437 {
1438 	if (dir==NULL)
1439 	{
1440 		(*ndir)++;
1441 		return(1);
1442 	}
1443 	return(TIFFWriteDirectoryTagCheckedSrationalArray(tif,ndir,dir,tag,count,value));
1444 }
1445 
1446 #ifdef notdef
TIFFWriteDirectoryTagFloat(TIFF * tif,uint32 * ndir,TIFFDirEntry * dir,uint16 tag,float value)1447 static int TIFFWriteDirectoryTagFloat(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, float value)
1448 {
1449 	if (dir==NULL)
1450 	{
1451 		(*ndir)++;
1452 		return(1);
1453 	}
1454 	return(TIFFWriteDirectoryTagCheckedFloat(tif,ndir,dir,tag,value));
1455 }
1456 #endif
1457 
TIFFWriteDirectoryTagFloatArray(TIFF * tif,uint32 * ndir,TIFFDirEntry * dir,uint16 tag,uint32 count,float * value)1458 static int TIFFWriteDirectoryTagFloatArray(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, float* value)
1459 {
1460 	if (dir==NULL)
1461 	{
1462 		(*ndir)++;
1463 		return(1);
1464 	}
1465 	return(TIFFWriteDirectoryTagCheckedFloatArray(tif,ndir,dir,tag,count,value));
1466 }
1467 
1468 #if 0
1469 static int TIFFWriteDirectoryTagFloatPerSample(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, float value)
1470 {
1471 	static const char module[] = "TIFFWriteDirectoryTagFloatPerSample";
1472 	float* m;
1473 	float* na;
1474 	uint16 nb;
1475 	int o;
1476 	if (dir==NULL)
1477 	{
1478 		(*ndir)++;
1479 		return(1);
1480 	}
1481 	m=_TIFFmalloc(tif->tif_dir.td_samplesperpixel*sizeof(float));
1482 	if (m==NULL)
1483 	{
1484 		TIFFErrorExt(tif->tif_clientdata,module,"Out of memory");
1485 		return(0);
1486 	}
1487 	for (na=m, nb=0; nb<tif->tif_dir.td_samplesperpixel; na++, nb++)
1488 		*na=value;
1489 	o=TIFFWriteDirectoryTagCheckedFloatArray(tif,ndir,dir,tag,tif->tif_dir.td_samplesperpixel,m);
1490 	_TIFFfree(m);
1491 	return(o);
1492 }
1493 #endif
1494 
1495 #ifdef notdef
TIFFWriteDirectoryTagDouble(TIFF * tif,uint32 * ndir,TIFFDirEntry * dir,uint16 tag,double value)1496 static int TIFFWriteDirectoryTagDouble(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, double value)
1497 {
1498 	if (dir==NULL)
1499 	{
1500 		(*ndir)++;
1501 		return(1);
1502 	}
1503 	return(TIFFWriteDirectoryTagCheckedDouble(tif,ndir,dir,tag,value));
1504 }
1505 #endif
1506 
TIFFWriteDirectoryTagDoubleArray(TIFF * tif,uint32 * ndir,TIFFDirEntry * dir,uint16 tag,uint32 count,double * value)1507 static int TIFFWriteDirectoryTagDoubleArray(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, double* value)
1508 {
1509 	if (dir==NULL)
1510 	{
1511 		(*ndir)++;
1512 		return(1);
1513 	}
1514 	return(TIFFWriteDirectoryTagCheckedDoubleArray(tif,ndir,dir,tag,count,value));
1515 }
1516 
1517 #if 0
1518 static int TIFFWriteDirectoryTagDoublePerSample(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, double value)
1519 {
1520 	static const char module[] = "TIFFWriteDirectoryTagDoublePerSample";
1521 	double* m;
1522 	double* na;
1523 	uint16 nb;
1524 	int o;
1525 	if (dir==NULL)
1526 	{
1527 		(*ndir)++;
1528 		return(1);
1529 	}
1530 	m=_TIFFmalloc(tif->tif_dir.td_samplesperpixel*sizeof(double));
1531 	if (m==NULL)
1532 	{
1533 		TIFFErrorExt(tif->tif_clientdata,module,"Out of memory");
1534 		return(0);
1535 	}
1536 	for (na=m, nb=0; nb<tif->tif_dir.td_samplesperpixel; na++, nb++)
1537 		*na=value;
1538 	o=TIFFWriteDirectoryTagCheckedDoubleArray(tif,ndir,dir,tag,tif->tif_dir.td_samplesperpixel,m);
1539 	_TIFFfree(m);
1540 	return(o);
1541 }
1542 #endif
1543 
1544 static int
TIFFWriteDirectoryTagIfdArray(TIFF * tif,uint32 * ndir,TIFFDirEntry * dir,uint16 tag,uint32 count,uint32 * value)1545 TIFFWriteDirectoryTagIfdArray(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, uint32* value)
1546 {
1547 	if (dir==NULL)
1548 	{
1549 		(*ndir)++;
1550 		return(1);
1551 	}
1552 	return(TIFFWriteDirectoryTagCheckedIfdArray(tif,ndir,dir,tag,count,value));
1553 }
1554 
1555 #ifdef notdef
1556 static int
TIFFWriteDirectoryTagIfd8Array(TIFF * tif,uint32 * ndir,TIFFDirEntry * dir,uint16 tag,uint32 count,uint64 * value)1557 TIFFWriteDirectoryTagIfd8Array(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, uint64* value)
1558 {
1559 	if (dir==NULL)
1560 	{
1561 		(*ndir)++;
1562 		return(1);
1563 	}
1564 	return(TIFFWriteDirectoryTagCheckedIfd8Array(tif,ndir,dir,tag,count,value));
1565 }
1566 #endif
1567 
1568 static int
TIFFWriteDirectoryTagShortLong(TIFF * tif,uint32 * ndir,TIFFDirEntry * dir,uint16 tag,uint32 value)1569 TIFFWriteDirectoryTagShortLong(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 value)
1570 {
1571 	if (dir==NULL)
1572 	{
1573 		(*ndir)++;
1574 		return(1);
1575 	}
1576 	if (value<=0xFFFF)
1577 		return(TIFFWriteDirectoryTagCheckedShort(tif,ndir,dir,tag,(uint16)value));
1578 	else
1579 		return(TIFFWriteDirectoryTagCheckedLong(tif,ndir,dir,tag,value));
1580 }
1581 
1582 /************************************************************************/
1583 /*                TIFFWriteDirectoryTagLongLong8Array()                 */
1584 /*                                                                      */
1585 /*      Write out LONG8 array as LONG8 for BigTIFF or LONG for          */
1586 /*      Classic TIFF with some checking.                                */
1587 /************************************************************************/
1588 
1589 static int
TIFFWriteDirectoryTagLongLong8Array(TIFF * tif,uint32 * ndir,TIFFDirEntry * dir,uint16 tag,uint32 count,uint64 * value)1590 TIFFWriteDirectoryTagLongLong8Array(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, uint64* value)
1591 {
1592     static const char module[] = "TIFFWriteDirectoryTagLongLong8Array";
1593     uint64* ma;
1594     uint32 mb;
1595     uint32* p;
1596     uint32* q;
1597     int o;
1598 
1599     /* is this just a counting pass? */
1600     if (dir==NULL)
1601     {
1602         (*ndir)++;
1603         return(1);
1604     }
1605 
1606     /* We always write LONG8 for BigTIFF, no checking needed. */
1607     if( tif->tif_flags&TIFF_BIGTIFF )
1608         return TIFFWriteDirectoryTagCheckedLong8Array(tif,ndir,dir,
1609                                                       tag,count,value);
1610 
1611     /*
1612     ** For classic tiff we want to verify everything is in range for LONG
1613     ** and convert to long format.
1614     */
1615 
1616     p = _TIFFmalloc(count*sizeof(uint32));
1617     if (p==NULL)
1618     {
1619         TIFFErrorExt(tif->tif_clientdata,module,"Out of memory");
1620         return(0);
1621     }
1622 
1623     for (q=p, ma=value, mb=0; mb<count; ma++, mb++, q++)
1624     {
1625         if (*ma>0xFFFFFFFF)
1626         {
1627             TIFFErrorExt(tif->tif_clientdata,module,
1628                          "Attempt to write value larger than 0xFFFFFFFF in Classic TIFF file.");
1629             _TIFFfree(p);
1630             return(0);
1631         }
1632         *q= (uint32)(*ma);
1633     }
1634 
1635     o=TIFFWriteDirectoryTagCheckedLongArray(tif,ndir,dir,tag,count,p);
1636     _TIFFfree(p);
1637 
1638     return(o);
1639 }
1640 
1641 /************************************************************************/
1642 /*                 TIFFWriteDirectoryTagIfdIfd8Array()                  */
1643 /*                                                                      */
1644 /*      Write either IFD8 or IFD array depending on file type.          */
1645 /************************************************************************/
1646 
1647 static int
TIFFWriteDirectoryTagIfdIfd8Array(TIFF * tif,uint32 * ndir,TIFFDirEntry * dir,uint16 tag,uint32 count,uint64 * value)1648 TIFFWriteDirectoryTagIfdIfd8Array(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, uint64* value)
1649 {
1650     static const char module[] = "TIFFWriteDirectoryTagIfdIfd8Array";
1651     uint64* ma;
1652     uint32 mb;
1653     uint32* p;
1654     uint32* q;
1655     int o;
1656 
1657     /* is this just a counting pass? */
1658     if (dir==NULL)
1659     {
1660         (*ndir)++;
1661         return(1);
1662     }
1663 
1664     /* We always write IFD8 for BigTIFF, no checking needed. */
1665     if( tif->tif_flags&TIFF_BIGTIFF )
1666         return TIFFWriteDirectoryTagCheckedIfd8Array(tif,ndir,dir,
1667                                                      tag,count,value);
1668 
1669     /*
1670     ** For classic tiff we want to verify everything is in range for IFD
1671     ** and convert to long format.
1672     */
1673 
1674     p = _TIFFmalloc(count*sizeof(uint32));
1675     if (p==NULL)
1676     {
1677         TIFFErrorExt(tif->tif_clientdata,module,"Out of memory");
1678         return(0);
1679     }
1680 
1681     for (q=p, ma=value, mb=0; mb<count; ma++, mb++, q++)
1682     {
1683         if (*ma>0xFFFFFFFF)
1684         {
1685             TIFFErrorExt(tif->tif_clientdata,module,
1686                          "Attempt to write value larger than 0xFFFFFFFF in Classic TIFF file.");
1687             _TIFFfree(p);
1688             return(0);
1689         }
1690         *q= (uint32)(*ma);
1691     }
1692 
1693     o=TIFFWriteDirectoryTagCheckedIfdArray(tif,ndir,dir,tag,count,p);
1694     _TIFFfree(p);
1695 
1696     return(o);
1697 }
1698 
1699 #ifdef notdef
1700 static int
TIFFWriteDirectoryTagShortLongLong8Array(TIFF * tif,uint32 * ndir,TIFFDirEntry * dir,uint16 tag,uint32 count,uint64 * value)1701 TIFFWriteDirectoryTagShortLongLong8Array(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, uint64* value)
1702 {
1703 	static const char module[] = "TIFFWriteDirectoryTagShortLongLong8Array";
1704 	uint64* ma;
1705 	uint32 mb;
1706 	uint8 n;
1707 	int o;
1708 	if (dir==NULL)
1709 	{
1710 		(*ndir)++;
1711 		return(1);
1712 	}
1713 	n=0;
1714 	for (ma=value, mb=0; mb<count; ma++, mb++)
1715 	{
1716 		if ((n==0)&&(*ma>0xFFFF))
1717 			n=1;
1718 		if ((n==1)&&(*ma>0xFFFFFFFF))
1719 		{
1720 			n=2;
1721 			break;
1722 		}
1723 	}
1724 	if (n==0)
1725 	{
1726 		uint16* p;
1727 		uint16* q;
1728 		p=_TIFFmalloc(count*sizeof(uint16));
1729 		if (p==NULL)
1730 		{
1731 			TIFFErrorExt(tif->tif_clientdata,module,"Out of memory");
1732 			return(0);
1733 		}
1734 		for (ma=value, mb=0, q=p; mb<count; ma++, mb++, q++)
1735 			*q=(uint16)(*ma);
1736 		o=TIFFWriteDirectoryTagCheckedShortArray(tif,ndir,dir,tag,count,p);
1737 		_TIFFfree(p);
1738 	}
1739 	else if (n==1)
1740 	{
1741 		uint32* p;
1742 		uint32* q;
1743 		p=_TIFFmalloc(count*sizeof(uint32));
1744 		if (p==NULL)
1745 		{
1746 			TIFFErrorExt(tif->tif_clientdata,module,"Out of memory");
1747 			return(0);
1748 		}
1749 		for (ma=value, mb=0, q=p; mb<count; ma++, mb++, q++)
1750 			*q=(uint32)(*ma);
1751 		o=TIFFWriteDirectoryTagCheckedLongArray(tif,ndir,dir,tag,count,p);
1752 		_TIFFfree(p);
1753 	}
1754 	else
1755 	{
1756 		assert(n==2);
1757 		o=TIFFWriteDirectoryTagCheckedLong8Array(tif,ndir,dir,tag,count,value);
1758 	}
1759 	return(o);
1760 }
1761 #endif
1762 static int
TIFFWriteDirectoryTagColormap(TIFF * tif,uint32 * ndir,TIFFDirEntry * dir)1763 TIFFWriteDirectoryTagColormap(TIFF* tif, uint32* ndir, TIFFDirEntry* dir)
1764 {
1765 	static const char module[] = "TIFFWriteDirectoryTagColormap";
1766 	uint32 m;
1767 	uint16* n;
1768 	int o;
1769 	if (dir==NULL)
1770 	{
1771 		(*ndir)++;
1772 		return(1);
1773 	}
1774 	m=(1<<tif->tif_dir.td_bitspersample);
1775 	n=_TIFFmalloc(3*m*sizeof(uint16));
1776 	if (n==NULL)
1777 	{
1778 		TIFFErrorExt(tif->tif_clientdata,module,"Out of memory");
1779 		return(0);
1780 	}
1781 	_TIFFmemcpy(&n[0],tif->tif_dir.td_colormap[0],m*sizeof(uint16));
1782 	_TIFFmemcpy(&n[m],tif->tif_dir.td_colormap[1],m*sizeof(uint16));
1783 	_TIFFmemcpy(&n[2*m],tif->tif_dir.td_colormap[2],m*sizeof(uint16));
1784 	o=TIFFWriteDirectoryTagCheckedShortArray(tif,ndir,dir,TIFFTAG_COLORMAP,3*m,n);
1785 	_TIFFfree(n);
1786 	return(o);
1787 }
1788 
1789 static int
TIFFWriteDirectoryTagTransferfunction(TIFF * tif,uint32 * ndir,TIFFDirEntry * dir)1790 TIFFWriteDirectoryTagTransferfunction(TIFF* tif, uint32* ndir, TIFFDirEntry* dir)
1791 {
1792 	static const char module[] = "TIFFWriteDirectoryTagTransferfunction";
1793 	uint32 m;
1794 	uint16 n;
1795 	uint16* o;
1796 	int p;
1797 	if (dir==NULL)
1798 	{
1799 		(*ndir)++;
1800 		return(1);
1801 	}
1802 	m=(1<<tif->tif_dir.td_bitspersample);
1803 	n=tif->tif_dir.td_samplesperpixel-tif->tif_dir.td_extrasamples;
1804 	/*
1805 	 * Check if the table can be written as a single column,
1806 	 * or if it must be written as 3 columns.  Note that we
1807 	 * write a 3-column tag if there are 2 samples/pixel and
1808 	 * a single column of data won't suffice--hmm.
1809 	 */
1810 	if (n>3)
1811 		n=3;
1812 	if (n==3)
1813 	{
1814 		if (!_TIFFmemcmp(tif->tif_dir.td_transferfunction[0],tif->tif_dir.td_transferfunction[2],m*sizeof(uint16)))
1815 			n=2;
1816 	}
1817 	if (n==2)
1818 	{
1819 		if (!_TIFFmemcmp(tif->tif_dir.td_transferfunction[0],tif->tif_dir.td_transferfunction[1],m*sizeof(uint16)))
1820 			n=1;
1821 	}
1822 	if (n==0)
1823 		n=1;
1824 	o=_TIFFmalloc(n*m*sizeof(uint16));
1825 	if (o==NULL)
1826 	{
1827 		TIFFErrorExt(tif->tif_clientdata,module,"Out of memory");
1828 		return(0);
1829 	}
1830 	_TIFFmemcpy(&o[0],tif->tif_dir.td_transferfunction[0],m*sizeof(uint16));
1831 	if (n>1)
1832 		_TIFFmemcpy(&o[m],tif->tif_dir.td_transferfunction[1],m*sizeof(uint16));
1833 	if (n>2)
1834 		_TIFFmemcpy(&o[2*m],tif->tif_dir.td_transferfunction[2],m*sizeof(uint16));
1835 	p=TIFFWriteDirectoryTagCheckedShortArray(tif,ndir,dir,TIFFTAG_TRANSFERFUNCTION,n*m,o);
1836 	_TIFFfree(o);
1837 	return(p);
1838 }
1839 
1840 static int
TIFFWriteDirectoryTagSubifd(TIFF * tif,uint32 * ndir,TIFFDirEntry * dir)1841 TIFFWriteDirectoryTagSubifd(TIFF* tif, uint32* ndir, TIFFDirEntry* dir)
1842 {
1843 	static const char module[] = "TIFFWriteDirectoryTagSubifd";
1844 	uint64 m;
1845 	int n;
1846 	if (tif->tif_dir.td_nsubifd==0)
1847 		return(1);
1848 	if (dir==NULL)
1849 	{
1850 		(*ndir)++;
1851 		return(1);
1852 	}
1853 	m=tif->tif_dataoff;
1854 	if (!(tif->tif_flags&TIFF_BIGTIFF))
1855 	{
1856 		uint32* o;
1857 		uint64* pa;
1858 		uint32* pb;
1859 		uint16 p;
1860 		o=_TIFFmalloc(tif->tif_dir.td_nsubifd*sizeof(uint32));
1861 		if (o==NULL)
1862 		{
1863 			TIFFErrorExt(tif->tif_clientdata,module,"Out of memory");
1864 			return(0);
1865 		}
1866 		pa=tif->tif_dir.td_subifd;
1867 		pb=o;
1868 		for (p=0; p < tif->tif_dir.td_nsubifd; p++)
1869 		{
1870                         assert(pa != 0);
1871 			assert(*pa <= 0xFFFFFFFFUL);
1872 			*pb++=(uint32)(*pa++);
1873 		}
1874 		n=TIFFWriteDirectoryTagCheckedIfdArray(tif,ndir,dir,TIFFTAG_SUBIFD,tif->tif_dir.td_nsubifd,o);
1875 		_TIFFfree(o);
1876 	}
1877 	else
1878 		n=TIFFWriteDirectoryTagCheckedIfd8Array(tif,ndir,dir,TIFFTAG_SUBIFD,tif->tif_dir.td_nsubifd,tif->tif_dir.td_subifd);
1879 	if (!n)
1880 		return(0);
1881 	/*
1882 	 * Total hack: if this directory includes a SubIFD
1883 	 * tag then force the next <n> directories to be
1884 	 * written as ``sub directories'' of this one.  This
1885 	 * is used to write things like thumbnails and
1886 	 * image masks that one wants to keep out of the
1887 	 * normal directory linkage access mechanism.
1888 	 */
1889 	tif->tif_flags|=TIFF_INSUBIFD;
1890 	tif->tif_nsubifd=tif->tif_dir.td_nsubifd;
1891 	if (tif->tif_dir.td_nsubifd==1)
1892 		tif->tif_subifdoff=0;
1893 	else
1894 		tif->tif_subifdoff=m;
1895 	return(1);
1896 }
1897 
1898 static int
TIFFWriteDirectoryTagCheckedAscii(TIFF * tif,uint32 * ndir,TIFFDirEntry * dir,uint16 tag,uint32 count,char * value)1899 TIFFWriteDirectoryTagCheckedAscii(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, char* value)
1900 {
1901 	assert(sizeof(char)==1);
1902 	return(TIFFWriteDirectoryTagData(tif,ndir,dir,tag,TIFF_ASCII,count,count,value));
1903 }
1904 
1905 static int
TIFFWriteDirectoryTagCheckedUndefinedArray(TIFF * tif,uint32 * ndir,TIFFDirEntry * dir,uint16 tag,uint32 count,uint8 * value)1906 TIFFWriteDirectoryTagCheckedUndefinedArray(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, uint8* value)
1907 {
1908 	assert(sizeof(uint8)==1);
1909 	return(TIFFWriteDirectoryTagData(tif,ndir,dir,tag,TIFF_UNDEFINED,count,count,value));
1910 }
1911 
1912 #ifdef notdef
1913 static int
TIFFWriteDirectoryTagCheckedByte(TIFF * tif,uint32 * ndir,TIFFDirEntry * dir,uint16 tag,uint8 value)1914 TIFFWriteDirectoryTagCheckedByte(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint8 value)
1915 {
1916 	assert(sizeof(uint8)==1);
1917 	return(TIFFWriteDirectoryTagData(tif,ndir,dir,tag,TIFF_BYTE,1,1,&value));
1918 }
1919 #endif
1920 
1921 static int
TIFFWriteDirectoryTagCheckedByteArray(TIFF * tif,uint32 * ndir,TIFFDirEntry * dir,uint16 tag,uint32 count,uint8 * value)1922 TIFFWriteDirectoryTagCheckedByteArray(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, uint8* value)
1923 {
1924 	assert(sizeof(uint8)==1);
1925 	return(TIFFWriteDirectoryTagData(tif,ndir,dir,tag,TIFF_BYTE,count,count,value));
1926 }
1927 
1928 #ifdef notdef
1929 static int
TIFFWriteDirectoryTagCheckedSbyte(TIFF * tif,uint32 * ndir,TIFFDirEntry * dir,uint16 tag,int8 value)1930 TIFFWriteDirectoryTagCheckedSbyte(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, int8 value)
1931 {
1932 	assert(sizeof(int8)==1);
1933 	return(TIFFWriteDirectoryTagData(tif,ndir,dir,tag,TIFF_SBYTE,1,1,&value));
1934 }
1935 #endif
1936 
1937 static int
TIFFWriteDirectoryTagCheckedSbyteArray(TIFF * tif,uint32 * ndir,TIFFDirEntry * dir,uint16 tag,uint32 count,int8 * value)1938 TIFFWriteDirectoryTagCheckedSbyteArray(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, int8* value)
1939 {
1940 	assert(sizeof(int8)==1);
1941 	return(TIFFWriteDirectoryTagData(tif,ndir,dir,tag,TIFF_SBYTE,count,count,value));
1942 }
1943 
1944 static int
TIFFWriteDirectoryTagCheckedShort(TIFF * tif,uint32 * ndir,TIFFDirEntry * dir,uint16 tag,uint16 value)1945 TIFFWriteDirectoryTagCheckedShort(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint16 value)
1946 {
1947 	uint16 m;
1948 	assert(sizeof(uint16)==2);
1949 	m=value;
1950 	if (tif->tif_flags&TIFF_SWAB)
1951 		TIFFSwabShort(&m);
1952 	return(TIFFWriteDirectoryTagData(tif,ndir,dir,tag,TIFF_SHORT,1,2,&m));
1953 }
1954 
1955 static int
TIFFWriteDirectoryTagCheckedShortArray(TIFF * tif,uint32 * ndir,TIFFDirEntry * dir,uint16 tag,uint32 count,uint16 * value)1956 TIFFWriteDirectoryTagCheckedShortArray(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, uint16* value)
1957 {
1958 	assert(count<0x80000000);
1959 	assert(sizeof(uint16)==2);
1960 	if (tif->tif_flags&TIFF_SWAB)
1961 		TIFFSwabArrayOfShort(value,count);
1962 	return(TIFFWriteDirectoryTagData(tif,ndir,dir,tag,TIFF_SHORT,count,count*2,value));
1963 }
1964 
1965 #ifdef notdef
1966 static int
TIFFWriteDirectoryTagCheckedSshort(TIFF * tif,uint32 * ndir,TIFFDirEntry * dir,uint16 tag,int16 value)1967 TIFFWriteDirectoryTagCheckedSshort(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, int16 value)
1968 {
1969 	int16 m;
1970 	assert(sizeof(int16)==2);
1971 	m=value;
1972 	if (tif->tif_flags&TIFF_SWAB)
1973 		TIFFSwabShort((uint16*)(&m));
1974 	return(TIFFWriteDirectoryTagData(tif,ndir,dir,tag,TIFF_SSHORT,1,2,&m));
1975 }
1976 #endif
1977 
1978 static int
TIFFWriteDirectoryTagCheckedSshortArray(TIFF * tif,uint32 * ndir,TIFFDirEntry * dir,uint16 tag,uint32 count,int16 * value)1979 TIFFWriteDirectoryTagCheckedSshortArray(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, int16* value)
1980 {
1981 	assert(count<0x80000000);
1982 	assert(sizeof(int16)==2);
1983 	if (tif->tif_flags&TIFF_SWAB)
1984 		TIFFSwabArrayOfShort((uint16*)value,count);
1985 	return(TIFFWriteDirectoryTagData(tif,ndir,dir,tag,TIFF_SSHORT,count,count*2,value));
1986 }
1987 
1988 static int
TIFFWriteDirectoryTagCheckedLong(TIFF * tif,uint32 * ndir,TIFFDirEntry * dir,uint16 tag,uint32 value)1989 TIFFWriteDirectoryTagCheckedLong(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 value)
1990 {
1991 	uint32 m;
1992 	assert(sizeof(uint32)==4);
1993 	m=value;
1994 	if (tif->tif_flags&TIFF_SWAB)
1995 		TIFFSwabLong(&m);
1996 	return(TIFFWriteDirectoryTagData(tif,ndir,dir,tag,TIFF_LONG,1,4,&m));
1997 }
1998 
1999 static int
TIFFWriteDirectoryTagCheckedLongArray(TIFF * tif,uint32 * ndir,TIFFDirEntry * dir,uint16 tag,uint32 count,uint32 * value)2000 TIFFWriteDirectoryTagCheckedLongArray(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, uint32* value)
2001 {
2002 	assert(count<0x40000000);
2003 	assert(sizeof(uint32)==4);
2004 	if (tif->tif_flags&TIFF_SWAB)
2005 		TIFFSwabArrayOfLong(value,count);
2006 	return(TIFFWriteDirectoryTagData(tif,ndir,dir,tag,TIFF_LONG,count,count*4,value));
2007 }
2008 
2009 #ifdef notdef
2010 static int
TIFFWriteDirectoryTagCheckedSlong(TIFF * tif,uint32 * ndir,TIFFDirEntry * dir,uint16 tag,int32 value)2011 TIFFWriteDirectoryTagCheckedSlong(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, int32 value)
2012 {
2013 	int32 m;
2014 	assert(sizeof(int32)==4);
2015 	m=value;
2016 	if (tif->tif_flags&TIFF_SWAB)
2017 		TIFFSwabLong((uint32*)(&m));
2018 	return(TIFFWriteDirectoryTagData(tif,ndir,dir,tag,TIFF_SLONG,1,4,&m));
2019 }
2020 #endif
2021 
2022 static int
TIFFWriteDirectoryTagCheckedSlongArray(TIFF * tif,uint32 * ndir,TIFFDirEntry * dir,uint16 tag,uint32 count,int32 * value)2023 TIFFWriteDirectoryTagCheckedSlongArray(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, int32* value)
2024 {
2025 	assert(count<0x40000000);
2026 	assert(sizeof(int32)==4);
2027 	if (tif->tif_flags&TIFF_SWAB)
2028 		TIFFSwabArrayOfLong((uint32*)value,count);
2029 	return(TIFFWriteDirectoryTagData(tif,ndir,dir,tag,TIFF_SLONG,count,count*4,value));
2030 }
2031 
2032 #ifdef notdef
2033 static int
TIFFWriteDirectoryTagCheckedLong8(TIFF * tif,uint32 * ndir,TIFFDirEntry * dir,uint16 tag,uint64 value)2034 TIFFWriteDirectoryTagCheckedLong8(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint64 value)
2035 {
2036 	uint64 m;
2037 	assert(sizeof(uint64)==8);
2038 	assert(tif->tif_flags&TIFF_BIGTIFF);
2039 	m=value;
2040 	if (tif->tif_flags&TIFF_SWAB)
2041 		TIFFSwabLong8(&m);
2042 	return(TIFFWriteDirectoryTagData(tif,ndir,dir,tag,TIFF_LONG8,1,8,&m));
2043 }
2044 #endif
2045 
2046 static int
TIFFWriteDirectoryTagCheckedLong8Array(TIFF * tif,uint32 * ndir,TIFFDirEntry * dir,uint16 tag,uint32 count,uint64 * value)2047 TIFFWriteDirectoryTagCheckedLong8Array(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, uint64* value)
2048 {
2049 	assert(count<0x20000000);
2050 	assert(sizeof(uint64)==8);
2051 	assert(tif->tif_flags&TIFF_BIGTIFF);
2052 	if (tif->tif_flags&TIFF_SWAB)
2053 		TIFFSwabArrayOfLong8(value,count);
2054 	return(TIFFWriteDirectoryTagData(tif,ndir,dir,tag,TIFF_LONG8,count,count*8,value));
2055 }
2056 
2057 #ifdef notdef
2058 static int
TIFFWriteDirectoryTagCheckedSlong8(TIFF * tif,uint32 * ndir,TIFFDirEntry * dir,uint16 tag,int64 value)2059 TIFFWriteDirectoryTagCheckedSlong8(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, int64 value)
2060 {
2061 	int64 m;
2062 	assert(sizeof(int64)==8);
2063 	assert(tif->tif_flags&TIFF_BIGTIFF);
2064 	m=value;
2065 	if (tif->tif_flags&TIFF_SWAB)
2066 		TIFFSwabLong8((uint64*)(&m));
2067 	return(TIFFWriteDirectoryTagData(tif,ndir,dir,tag,TIFF_SLONG8,1,8,&m));
2068 }
2069 #endif
2070 
2071 static int
TIFFWriteDirectoryTagCheckedSlong8Array(TIFF * tif,uint32 * ndir,TIFFDirEntry * dir,uint16 tag,uint32 count,int64 * value)2072 TIFFWriteDirectoryTagCheckedSlong8Array(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, int64* value)
2073 {
2074 	assert(count<0x20000000);
2075 	assert(sizeof(int64)==8);
2076 	assert(tif->tif_flags&TIFF_BIGTIFF);
2077 	if (tif->tif_flags&TIFF_SWAB)
2078 		TIFFSwabArrayOfLong8((uint64*)value,count);
2079 	return(TIFFWriteDirectoryTagData(tif,ndir,dir,tag,TIFF_SLONG8,count,count*8,value));
2080 }
2081 
2082 static int
TIFFWriteDirectoryTagCheckedRational(TIFF * tif,uint32 * ndir,TIFFDirEntry * dir,uint16 tag,double value)2083 TIFFWriteDirectoryTagCheckedRational(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, double value)
2084 {
2085 	uint32 m[2];
2086 	assert(value>=0.0);
2087 	assert(sizeof(uint32)==4);
2088 	if (value<=0.0)
2089 	{
2090 		m[0]=0;
2091 		m[1]=1;
2092 	}
2093 	else if (value==(double)(uint32)value)
2094 	{
2095 		m[0]=(uint32)value;
2096 		m[1]=1;
2097 	}
2098 	else if (value<1.0)
2099 	{
2100 		m[0]=(uint32)(value*0xFFFFFFFF);
2101 		m[1]=0xFFFFFFFF;
2102 	}
2103 	else
2104 	{
2105 		m[0]=0xFFFFFFFF;
2106 		m[1]=(uint32)(0xFFFFFFFF/value);
2107 	}
2108 	if (tif->tif_flags&TIFF_SWAB)
2109 	{
2110 		TIFFSwabLong(&m[0]);
2111 		TIFFSwabLong(&m[1]);
2112 	}
2113 	return(TIFFWriteDirectoryTagData(tif,ndir,dir,tag,TIFF_RATIONAL,1,8,&m[0]));
2114 }
2115 
2116 static int
TIFFWriteDirectoryTagCheckedRationalArray(TIFF * tif,uint32 * ndir,TIFFDirEntry * dir,uint16 tag,uint32 count,float * value)2117 TIFFWriteDirectoryTagCheckedRationalArray(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, float* value)
2118 {
2119 	static const char module[] = "TIFFWriteDirectoryTagCheckedRationalArray";
2120 	uint32* m;
2121 	float* na;
2122 	uint32* nb;
2123 	uint32 nc;
2124 	int o;
2125 	assert(sizeof(uint32)==4);
2126 	m=_TIFFmalloc(count*2*sizeof(uint32));
2127 	if (m==NULL)
2128 	{
2129 		TIFFErrorExt(tif->tif_clientdata,module,"Out of memory");
2130 		return(0);
2131 	}
2132 	for (na=value, nb=m, nc=0; nc<count; na++, nb+=2, nc++)
2133 	{
2134 		if (*na<=0.0)
2135 		{
2136 			nb[0]=0;
2137 			nb[1]=1;
2138 		}
2139 		else if (*na==(float)(uint32)(*na))
2140 		{
2141 			nb[0]=(uint32)(*na);
2142 			nb[1]=1;
2143 		}
2144 		else if (*na<1.0)
2145 		{
2146 			nb[0]=(uint32)((double)(*na)*0xFFFFFFFF);
2147 			nb[1]=0xFFFFFFFF;
2148 		}
2149 		else
2150 		{
2151 			nb[0]=0xFFFFFFFF;
2152 			nb[1]=(uint32)((double)0xFFFFFFFF/(*na));
2153 		}
2154 	}
2155 	if (tif->tif_flags&TIFF_SWAB)
2156 		TIFFSwabArrayOfLong(m,count*2);
2157 	o=TIFFWriteDirectoryTagData(tif,ndir,dir,tag,TIFF_RATIONAL,count,count*8,&m[0]);
2158 	_TIFFfree(m);
2159 	return(o);
2160 }
2161 
2162 static int
TIFFWriteDirectoryTagCheckedSrationalArray(TIFF * tif,uint32 * ndir,TIFFDirEntry * dir,uint16 tag,uint32 count,float * value)2163 TIFFWriteDirectoryTagCheckedSrationalArray(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, float* value)
2164 {
2165 	static const char module[] = "TIFFWriteDirectoryTagCheckedSrationalArray";
2166 	int32* m;
2167 	float* na;
2168 	int32* nb;
2169 	uint32 nc;
2170 	int o;
2171 	assert(sizeof(int32)==4);
2172 	m=_TIFFmalloc(count*2*sizeof(int32));
2173 	if (m==NULL)
2174 	{
2175 		TIFFErrorExt(tif->tif_clientdata,module,"Out of memory");
2176 		return(0);
2177 	}
2178 	for (na=value, nb=m, nc=0; nc<count; na++, nb+=2, nc++)
2179 	{
2180 		if (*na<0.0)
2181 		{
2182 			if (*na==(int32)(*na))
2183 			{
2184 				nb[0]=(int32)(*na);
2185 				nb[1]=1;
2186 			}
2187 			else if (*na>-1.0)
2188 			{
2189 				nb[0]=-(int32)((double)(-*na)*0x7FFFFFFF);
2190 				nb[1]=0x7FFFFFFF;
2191 			}
2192 			else
2193 			{
2194 				nb[0]=-0x7FFFFFFF;
2195 				nb[1]=(int32)((double)0x7FFFFFFF/(-*na));
2196 			}
2197 		}
2198 		else
2199 		{
2200 			if (*na==(int32)(*na))
2201 			{
2202 				nb[0]=(int32)(*na);
2203 				nb[1]=1;
2204 			}
2205 			else if (*na<1.0)
2206 			{
2207 				nb[0]=(int32)((double)(*na)*0x7FFFFFFF);
2208 				nb[1]=0x7FFFFFFF;
2209 			}
2210 			else
2211 			{
2212 				nb[0]=0x7FFFFFFF;
2213 				nb[1]=(int32)((double)0x7FFFFFFF/(*na));
2214 			}
2215 		}
2216 	}
2217 	if (tif->tif_flags&TIFF_SWAB)
2218 		TIFFSwabArrayOfLong((uint32*)m,count*2);
2219 	o=TIFFWriteDirectoryTagData(tif,ndir,dir,tag,TIFF_SRATIONAL,count,count*8,&m[0]);
2220 	_TIFFfree(m);
2221 	return(o);
2222 }
2223 
2224 #ifdef notdef
2225 static int
TIFFWriteDirectoryTagCheckedFloat(TIFF * tif,uint32 * ndir,TIFFDirEntry * dir,uint16 tag,float value)2226 TIFFWriteDirectoryTagCheckedFloat(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, float value)
2227 {
2228 	float m;
2229 	assert(sizeof(float)==4);
2230 	m=value;
2231 	TIFFCvtNativeToIEEEFloat(tif,1,&m);
2232 	if (tif->tif_flags&TIFF_SWAB)
2233 		TIFFSwabFloat(&m);
2234 	return(TIFFWriteDirectoryTagData(tif,ndir,dir,tag,TIFF_FLOAT,1,4,&m));
2235 }
2236 #endif
2237 
2238 static int
TIFFWriteDirectoryTagCheckedFloatArray(TIFF * tif,uint32 * ndir,TIFFDirEntry * dir,uint16 tag,uint32 count,float * value)2239 TIFFWriteDirectoryTagCheckedFloatArray(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, float* value)
2240 {
2241 	assert(count<0x40000000);
2242 	assert(sizeof(float)==4);
2243 	TIFFCvtNativeToIEEEFloat(tif,count,&value);
2244 	if (tif->tif_flags&TIFF_SWAB)
2245 		TIFFSwabArrayOfFloat(value,count);
2246 	return(TIFFWriteDirectoryTagData(tif,ndir,dir,tag,TIFF_FLOAT,count,count*4,value));
2247 }
2248 
2249 #ifdef notdef
2250 static int
TIFFWriteDirectoryTagCheckedDouble(TIFF * tif,uint32 * ndir,TIFFDirEntry * dir,uint16 tag,double value)2251 TIFFWriteDirectoryTagCheckedDouble(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, double value)
2252 {
2253 	double m;
2254 	assert(sizeof(double)==8);
2255 	m=value;
2256 	TIFFCvtNativeToIEEEDouble(tif,1,&m);
2257 	if (tif->tif_flags&TIFF_SWAB)
2258 		TIFFSwabDouble(&m);
2259 	return(TIFFWriteDirectoryTagData(tif,ndir,dir,tag,TIFF_DOUBLE,1,8,&m));
2260 }
2261 #endif
2262 
2263 static int
TIFFWriteDirectoryTagCheckedDoubleArray(TIFF * tif,uint32 * ndir,TIFFDirEntry * dir,uint16 tag,uint32 count,double * value)2264 TIFFWriteDirectoryTagCheckedDoubleArray(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, double* value)
2265 {
2266 	assert(count<0x20000000);
2267 	assert(sizeof(double)==8);
2268 	TIFFCvtNativeToIEEEDouble(tif,count,&value);
2269 	if (tif->tif_flags&TIFF_SWAB)
2270 		TIFFSwabArrayOfDouble(value,count);
2271 	return(TIFFWriteDirectoryTagData(tif,ndir,dir,tag,TIFF_DOUBLE,count,count*8,value));
2272 }
2273 
2274 static int
TIFFWriteDirectoryTagCheckedIfdArray(TIFF * tif,uint32 * ndir,TIFFDirEntry * dir,uint16 tag,uint32 count,uint32 * value)2275 TIFFWriteDirectoryTagCheckedIfdArray(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, uint32* value)
2276 {
2277 	assert(count<0x40000000);
2278 	assert(sizeof(uint32)==4);
2279 	if (tif->tif_flags&TIFF_SWAB)
2280 		TIFFSwabArrayOfLong(value,count);
2281 	return(TIFFWriteDirectoryTagData(tif,ndir,dir,tag,TIFF_IFD,count,count*4,value));
2282 }
2283 
2284 static int
TIFFWriteDirectoryTagCheckedIfd8Array(TIFF * tif,uint32 * ndir,TIFFDirEntry * dir,uint16 tag,uint32 count,uint64 * value)2285 TIFFWriteDirectoryTagCheckedIfd8Array(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, uint64* value)
2286 {
2287 	assert(count<0x20000000);
2288 	assert(sizeof(uint64)==8);
2289 	assert(tif->tif_flags&TIFF_BIGTIFF);
2290 	if (tif->tif_flags&TIFF_SWAB)
2291 		TIFFSwabArrayOfLong8(value,count);
2292 	return(TIFFWriteDirectoryTagData(tif,ndir,dir,tag,TIFF_IFD8,count,count*8,value));
2293 }
2294 
2295 static int
TIFFWriteDirectoryTagData(TIFF * tif,uint32 * ndir,TIFFDirEntry * dir,uint16 tag,uint16 datatype,uint32 count,uint32 datalength,void * data)2296 TIFFWriteDirectoryTagData(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint16 datatype, uint32 count, uint32 datalength, void* data)
2297 {
2298 	static const char module[] = "TIFFWriteDirectoryTagData";
2299 	uint32 m;
2300 	m=0;
2301 	while (m<(*ndir))
2302 	{
2303 		assert(dir[m].tdir_tag!=tag);
2304 		if (dir[m].tdir_tag>tag)
2305 			break;
2306 		m++;
2307 	}
2308 	if (m<(*ndir))
2309 	{
2310 		uint32 n;
2311 		for (n=*ndir; n>m; n--)
2312 			dir[n]=dir[n-1];
2313 	}
2314 	dir[m].tdir_tag=tag;
2315 	dir[m].tdir_type=datatype;
2316 	dir[m].tdir_count=count;
2317 	dir[m].tdir_offset.toff_long8 = 0;
2318 	if (datalength<=((tif->tif_flags&TIFF_BIGTIFF)?0x8U:0x4U))
2319 		_TIFFmemcpy(&dir[m].tdir_offset,data,datalength);
2320 	else
2321 	{
2322 		uint64 na,nb;
2323 		na=tif->tif_dataoff;
2324 		nb=na+datalength;
2325 		if (!(tif->tif_flags&TIFF_BIGTIFF))
2326 			nb=(uint32)nb;
2327 		if ((nb<na)||(nb<datalength))
2328 		{
2329 			TIFFErrorExt(tif->tif_clientdata,module,"Maximum TIFF file size exceeded");
2330 			return(0);
2331 		}
2332 		if (!SeekOK(tif,na))
2333 		{
2334 			TIFFErrorExt(tif->tif_clientdata,module,"IO error writing tag data");
2335 			return(0);
2336 		}
2337 		assert(datalength<0x80000000UL);
2338 		if (!WriteOK(tif,data,(tmsize_t)datalength))
2339 		{
2340 			TIFFErrorExt(tif->tif_clientdata,module,"IO error writing tag data");
2341 			return(0);
2342 		}
2343 		tif->tif_dataoff=nb;
2344 		if (tif->tif_dataoff&1)
2345 			tif->tif_dataoff++;
2346 		if (!(tif->tif_flags&TIFF_BIGTIFF))
2347 		{
2348 			uint32 o;
2349 			o=(uint32)na;
2350 			if (tif->tif_flags&TIFF_SWAB)
2351 				TIFFSwabLong(&o);
2352 			_TIFFmemcpy(&dir[m].tdir_offset,&o,4);
2353 		}
2354 		else
2355 		{
2356 			dir[m].tdir_offset.toff_long8 = na;
2357 			if (tif->tif_flags&TIFF_SWAB)
2358 				TIFFSwabLong8(&dir[m].tdir_offset.toff_long8);
2359 		}
2360 	}
2361 	(*ndir)++;
2362 	return(1);
2363 }
2364 
2365 /*
2366  * Link the current directory into the directory chain for the file.
2367  */
2368 static int
TIFFLinkDirectory(TIFF * tif)2369 TIFFLinkDirectory(TIFF* tif)
2370 {
2371 	static const char module[] = "TIFFLinkDirectory";
2372 
2373 	tif->tif_diroff = (TIFFSeekFile(tif,0,SEEK_END)+1) & (~((toff_t)1));
2374 
2375 	/*
2376 	 * Handle SubIFDs
2377 	 */
2378 	if (tif->tif_flags & TIFF_INSUBIFD)
2379 	{
2380 		if (!(tif->tif_flags&TIFF_BIGTIFF))
2381 		{
2382 			uint32 m;
2383 			m = (uint32)tif->tif_diroff;
2384 			if (tif->tif_flags & TIFF_SWAB)
2385 				TIFFSwabLong(&m);
2386 			(void) TIFFSeekFile(tif, tif->tif_subifdoff, SEEK_SET);
2387 			if (!WriteOK(tif, &m, 4)) {
2388 				TIFFErrorExt(tif->tif_clientdata, module,
2389 				     "Error writing SubIFD directory link");
2390 				return (0);
2391 			}
2392 			/*
2393 			 * Advance to the next SubIFD or, if this is
2394 			 * the last one configured, revert back to the
2395 			 * normal directory linkage.
2396 			 */
2397 			if (--tif->tif_nsubifd)
2398 				tif->tif_subifdoff += 4;
2399 			else
2400 				tif->tif_flags &= ~TIFF_INSUBIFD;
2401 			return (1);
2402 		}
2403 		else
2404 		{
2405 			uint64 m;
2406 			m = tif->tif_diroff;
2407 			if (tif->tif_flags & TIFF_SWAB)
2408 				TIFFSwabLong8(&m);
2409 			(void) TIFFSeekFile(tif, tif->tif_subifdoff, SEEK_SET);
2410 			if (!WriteOK(tif, &m, 8)) {
2411 				TIFFErrorExt(tif->tif_clientdata, module,
2412 				     "Error writing SubIFD directory link");
2413 				return (0);
2414 			}
2415 			/*
2416 			 * Advance to the next SubIFD or, if this is
2417 			 * the last one configured, revert back to the
2418 			 * normal directory linkage.
2419 			 */
2420 			if (--tif->tif_nsubifd)
2421 				tif->tif_subifdoff += 8;
2422 			else
2423 				tif->tif_flags &= ~TIFF_INSUBIFD;
2424 			return (1);
2425 		}
2426 	}
2427 
2428 	if (!(tif->tif_flags&TIFF_BIGTIFF))
2429 	{
2430 		uint32 m;
2431 		uint32 nextdir;
2432 		m = (uint32)(tif->tif_diroff);
2433 		if (tif->tif_flags & TIFF_SWAB)
2434 			TIFFSwabLong(&m);
2435 		if (tif->tif_header.classic.tiff_diroff == 0) {
2436 			/*
2437 			 * First directory, overwrite offset in header.
2438 			 */
2439 			tif->tif_header.classic.tiff_diroff = (uint32) tif->tif_diroff;
2440 			(void) TIFFSeekFile(tif,4, SEEK_SET);
2441 			if (!WriteOK(tif, &m, 4)) {
2442 				TIFFErrorExt(tif->tif_clientdata, tif->tif_name,
2443 					     "Error writing TIFF header");
2444 				return (0);
2445 			}
2446 			return (1);
2447 		}
2448 		/*
2449 		 * Not the first directory, search to the last and append.
2450 		 */
2451 		nextdir = tif->tif_header.classic.tiff_diroff;
2452 		while(1) {
2453 			uint16 dircount;
2454 			uint32 nextnextdir;
2455 
2456 			if (!SeekOK(tif, nextdir) ||
2457 			    !ReadOK(tif, &dircount, 2)) {
2458 				TIFFErrorExt(tif->tif_clientdata, module,
2459 					     "Error fetching directory count");
2460 				return (0);
2461 			}
2462 			if (tif->tif_flags & TIFF_SWAB)
2463 				TIFFSwabShort(&dircount);
2464 			(void) TIFFSeekFile(tif,
2465 			    nextdir+2+dircount*12, SEEK_SET);
2466 			if (!ReadOK(tif, &nextnextdir, 4)) {
2467 				TIFFErrorExt(tif->tif_clientdata, module,
2468 					     "Error fetching directory link");
2469 				return (0);
2470 			}
2471 			if (tif->tif_flags & TIFF_SWAB)
2472 				TIFFSwabLong(&nextnextdir);
2473 			if (nextnextdir==0)
2474 			{
2475 				(void) TIFFSeekFile(tif,
2476 				    nextdir+2+dircount*12, SEEK_SET);
2477 				if (!WriteOK(tif, &m, 4)) {
2478 					TIFFErrorExt(tif->tif_clientdata, module,
2479 					     "Error writing directory link");
2480 					return (0);
2481 				}
2482 				break;
2483 			}
2484 			nextdir=nextnextdir;
2485 		}
2486 	}
2487 	else
2488 	{
2489 		uint64 m;
2490 		uint64 nextdir;
2491 		m = tif->tif_diroff;
2492 		if (tif->tif_flags & TIFF_SWAB)
2493 			TIFFSwabLong8(&m);
2494 		if (tif->tif_header.big.tiff_diroff == 0) {
2495 			/*
2496 			 * First directory, overwrite offset in header.
2497 			 */
2498 			tif->tif_header.big.tiff_diroff = tif->tif_diroff;
2499 			(void) TIFFSeekFile(tif,8, SEEK_SET);
2500 			if (!WriteOK(tif, &m, 8)) {
2501 				TIFFErrorExt(tif->tif_clientdata, tif->tif_name,
2502 					     "Error writing TIFF header");
2503 				return (0);
2504 			}
2505 			return (1);
2506 		}
2507 		/*
2508 		 * Not the first directory, search to the last and append.
2509 		 */
2510 		nextdir = tif->tif_header.big.tiff_diroff;
2511 		while(1) {
2512 			uint64 dircount64;
2513 			uint16 dircount;
2514 			uint64 nextnextdir;
2515 
2516 			if (!SeekOK(tif, nextdir) ||
2517 			    !ReadOK(tif, &dircount64, 8)) {
2518 				TIFFErrorExt(tif->tif_clientdata, module,
2519 					     "Error fetching directory count");
2520 				return (0);
2521 			}
2522 			if (tif->tif_flags & TIFF_SWAB)
2523 				TIFFSwabLong8(&dircount64);
2524 			if (dircount64>0xFFFF)
2525 			{
2526 				TIFFErrorExt(tif->tif_clientdata, module,
2527 					     "Sanity check on tag count failed, likely corrupt TIFF");
2528 				return (0);
2529 			}
2530 			dircount=(uint16)dircount64;
2531 			(void) TIFFSeekFile(tif,
2532 			    nextdir+8+dircount*20, SEEK_SET);
2533 			if (!ReadOK(tif, &nextnextdir, 8)) {
2534 				TIFFErrorExt(tif->tif_clientdata, module,
2535 					     "Error fetching directory link");
2536 				return (0);
2537 			}
2538 			if (tif->tif_flags & TIFF_SWAB)
2539 				TIFFSwabLong8(&nextnextdir);
2540 			if (nextnextdir==0)
2541 			{
2542 				(void) TIFFSeekFile(tif,
2543 				    nextdir+8+dircount*20, SEEK_SET);
2544 				if (!WriteOK(tif, &m, 8)) {
2545 					TIFFErrorExt(tif->tif_clientdata, module,
2546 					     "Error writing directory link");
2547 					return (0);
2548 				}
2549 				break;
2550 			}
2551 			nextdir=nextnextdir;
2552 		}
2553 	}
2554 	return (1);
2555 }
2556 
2557 /************************************************************************/
2558 /*                          TIFFRewriteField()                          */
2559 /*                                                                      */
2560 /*      Rewrite a field in the directory on disk without regard to      */
2561 /*      updating the TIFF directory structure in memory.  Currently     */
2562 /*      only supported for field that already exist in the on-disk      */
2563 /*      directory.  Mainly used for updating stripoffset /              */
2564 /*      stripbytecount values after the directory is already on         */
2565 /*      disk.                                                           */
2566 /*                                                                      */
2567 /*      Returns zero on failure, and one on success.                    */
2568 /************************************************************************/
2569 
2570 int
_TIFFRewriteField(TIFF * tif,uint16 tag,TIFFDataType in_datatype,tmsize_t count,void * data)2571 _TIFFRewriteField(TIFF* tif, uint16 tag, TIFFDataType in_datatype,
2572                   tmsize_t count, void* data)
2573 {
2574     static const char module[] = "TIFFResetField";
2575     /* const TIFFField* fip = NULL; */
2576     uint16 dircount;
2577     tmsize_t dirsize;
2578     uint8 direntry_raw[20];
2579     uint16 entry_tag = 0;
2580     uint16 entry_type = 0;
2581     uint64 entry_count = 0;
2582     uint64 entry_offset = 0;
2583     int    value_in_entry = 0;
2584     uint64 read_offset;
2585     uint8 *buf_to_write = NULL;
2586     TIFFDataType datatype;
2587 
2588 /* -------------------------------------------------------------------- */
2589 /*      Find field definition.                                          */
2590 /* -------------------------------------------------------------------- */
2591     /*fip =*/ TIFFFindField(tif, tag, TIFF_ANY);
2592 
2593 /* -------------------------------------------------------------------- */
2594 /*      Do some checking this is a straight forward case.               */
2595 /* -------------------------------------------------------------------- */
2596     if( isMapped(tif) )
2597     {
2598         TIFFErrorExt( tif->tif_clientdata, module,
2599                       "Memory mapped files not currently supported for this operation." );
2600         return 0;
2601     }
2602 
2603     if( tif->tif_diroff == 0 )
2604     {
2605         TIFFErrorExt( tif->tif_clientdata, module,
2606                       "Attempt to reset field on directory not already on disk." );
2607         return 0;
2608     }
2609 
2610 /* -------------------------------------------------------------------- */
2611 /*      Read the directory entry count.                                 */
2612 /* -------------------------------------------------------------------- */
2613     if (!SeekOK(tif, tif->tif_diroff)) {
2614         TIFFErrorExt(tif->tif_clientdata, module,
2615                      "%s: Seek error accessing TIFF directory",
2616                      tif->tif_name);
2617         return 0;
2618     }
2619 
2620     read_offset = tif->tif_diroff;
2621 
2622     if (!(tif->tif_flags&TIFF_BIGTIFF))
2623     {
2624         if (!ReadOK(tif, &dircount, sizeof (uint16))) {
2625             TIFFErrorExt(tif->tif_clientdata, module,
2626                          "%s: Can not read TIFF directory count",
2627                          tif->tif_name);
2628             return 0;
2629         }
2630         if (tif->tif_flags & TIFF_SWAB)
2631             TIFFSwabShort(&dircount);
2632         dirsize = 12;
2633         read_offset += 2;
2634     } else {
2635         uint64 dircount64;
2636         if (!ReadOK(tif, &dircount64, sizeof (uint64))) {
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             TIFFSwabLong8(&dircount64);
2644         dircount = (uint16)dircount64;
2645         dirsize = 20;
2646         read_offset += 8;
2647     }
2648 
2649 /* -------------------------------------------------------------------- */
2650 /*      Read through directory to find target tag.                      */
2651 /* -------------------------------------------------------------------- */
2652     while( dircount > 0 )
2653     {
2654         if (!ReadOK(tif, direntry_raw, dirsize)) {
2655             TIFFErrorExt(tif->tif_clientdata, module,
2656                          "%s: Can not read TIFF directory entry.",
2657                          tif->tif_name);
2658             return 0;
2659         }
2660 
2661         memcpy( &entry_tag, direntry_raw + 0, sizeof(uint16) );
2662         if (tif->tif_flags&TIFF_SWAB)
2663             TIFFSwabShort( &entry_tag );
2664 
2665         if( entry_tag == tag )
2666             break;
2667 
2668         read_offset += dirsize;
2669     }
2670 
2671     if( entry_tag != tag )
2672     {
2673         TIFFErrorExt(tif->tif_clientdata, module,
2674                      "%s: Could not find tag %d.",
2675                      tif->tif_name, tag );
2676         return 0;
2677     }
2678 
2679 /* -------------------------------------------------------------------- */
2680 /*      Extract the type, count and offset for this entry.              */
2681 /* -------------------------------------------------------------------- */
2682     memcpy( &entry_type, direntry_raw + 2, sizeof(uint16) );
2683     if (tif->tif_flags&TIFF_SWAB)
2684         TIFFSwabShort( &entry_type );
2685 
2686     if (!(tif->tif_flags&TIFF_BIGTIFF))
2687     {
2688         uint32 value;
2689 
2690         memcpy( &value, direntry_raw + 4, sizeof(uint32) );
2691         if (tif->tif_flags&TIFF_SWAB)
2692             TIFFSwabLong( &value );
2693         entry_count = value;
2694 
2695         memcpy( &value, direntry_raw + 8, sizeof(uint32) );
2696         if (tif->tif_flags&TIFF_SWAB)
2697             TIFFSwabLong( &value );
2698         entry_offset = value;
2699     }
2700     else
2701     {
2702         memcpy( &entry_count, direntry_raw + 4, sizeof(uint64) );
2703         if (tif->tif_flags&TIFF_SWAB)
2704             TIFFSwabLong8( &entry_count );
2705 
2706         memcpy( &entry_offset, direntry_raw + 12, sizeof(uint64) );
2707         if (tif->tif_flags&TIFF_SWAB)
2708             TIFFSwabLong8( &entry_offset );
2709     }
2710 
2711 /* -------------------------------------------------------------------- */
2712 /*      What data type do we want to write this as?                     */
2713 /* -------------------------------------------------------------------- */
2714     if( TIFFDataWidth(in_datatype) == 8 && !(tif->tif_flags&TIFF_BIGTIFF) )
2715     {
2716         if( in_datatype == TIFF_LONG8 )
2717             datatype = TIFF_LONG;
2718         else if( in_datatype == TIFF_SLONG8 )
2719             datatype = TIFF_SLONG;
2720         else if( in_datatype == TIFF_IFD8 )
2721             datatype = TIFF_IFD;
2722         else
2723             datatype = in_datatype;
2724     }
2725     else
2726         datatype = in_datatype;
2727 
2728 /* -------------------------------------------------------------------- */
2729 /*      Prepare buffer of actual data to write.  This includes          */
2730 /*      swabbing as needed.                                             */
2731 /* -------------------------------------------------------------------- */
2732     buf_to_write =
2733 	    (uint8 *)_TIFFCheckMalloc(tif, count, TIFFDataWidth(datatype),
2734 				      "for field buffer.");
2735     if (!buf_to_write)
2736         return 0;
2737 
2738     if( datatype == in_datatype )
2739         memcpy( buf_to_write, data, count * TIFFDataWidth(datatype) );
2740     else if( datatype == TIFF_SLONG && in_datatype == TIFF_SLONG8 )
2741     {
2742 	tmsize_t i;
2743 
2744         for( i = 0; i < count; i++ )
2745         {
2746             ((int32 *) buf_to_write)[i] =
2747                 (int32) ((int64 *) data)[i];
2748             if( (int64) ((int32 *) buf_to_write)[i] != ((int64 *) data)[i] )
2749             {
2750                 _TIFFfree( buf_to_write );
2751                 TIFFErrorExt( tif->tif_clientdata, module,
2752                               "Value exceeds 32bit range of output type." );
2753                 return 0;
2754             }
2755         }
2756     }
2757     else if( (datatype == TIFF_LONG && in_datatype == TIFF_LONG8)
2758              || (datatype == TIFF_IFD && in_datatype == TIFF_IFD8) )
2759     {
2760 	tmsize_t i;
2761 
2762         for( i = 0; i < count; i++ )
2763         {
2764             ((uint32 *) buf_to_write)[i] =
2765                 (uint32) ((uint64 *) data)[i];
2766             if( (uint64) ((uint32 *) buf_to_write)[i] != ((uint64 *) data)[i] )
2767             {
2768                 _TIFFfree( buf_to_write );
2769                 TIFFErrorExt( tif->tif_clientdata, module,
2770                               "Value exceeds 32bit range of output type." );
2771                 return 0;
2772             }
2773         }
2774     }
2775 
2776     if( TIFFDataWidth(datatype) > 1 && (tif->tif_flags&TIFF_SWAB) )
2777     {
2778         if( TIFFDataWidth(datatype) == 2 )
2779             TIFFSwabArrayOfShort( (uint16 *) buf_to_write, count );
2780         else if( TIFFDataWidth(datatype) == 4 )
2781             TIFFSwabArrayOfLong( (uint32 *) buf_to_write, count );
2782         else if( TIFFDataWidth(datatype) == 8 )
2783             TIFFSwabArrayOfLong8( (uint64 *) buf_to_write, count );
2784     }
2785 
2786 /* -------------------------------------------------------------------- */
2787 /*      Is this a value that fits into the directory entry?             */
2788 /* -------------------------------------------------------------------- */
2789     if (!(tif->tif_flags&TIFF_BIGTIFF))
2790     {
2791         if( TIFFDataWidth(datatype) * count <= 4 )
2792         {
2793             entry_offset = read_offset + 8;
2794             value_in_entry = 1;
2795         }
2796     }
2797     else
2798     {
2799         if( TIFFDataWidth(datatype) * count <= 8 )
2800         {
2801             entry_offset = read_offset + 12;
2802             value_in_entry = 1;
2803         }
2804     }
2805 
2806 /* -------------------------------------------------------------------- */
2807 /*      If the tag type, and count match, then we just write it out     */
2808 /*      over the old values without altering the directory entry at     */
2809 /*      all.                                                            */
2810 /* -------------------------------------------------------------------- */
2811     if( entry_count == (uint64)count && entry_type == (uint16) datatype )
2812     {
2813         if (!SeekOK(tif, entry_offset)) {
2814             _TIFFfree( buf_to_write );
2815             TIFFErrorExt(tif->tif_clientdata, module,
2816                          "%s: Seek error accessing TIFF directory",
2817                          tif->tif_name);
2818             return 0;
2819         }
2820         if (!WriteOK(tif, buf_to_write, count*TIFFDataWidth(datatype))) {
2821             _TIFFfree( buf_to_write );
2822             TIFFErrorExt(tif->tif_clientdata, module,
2823                          "Error writing directory link");
2824             return (0);
2825         }
2826 
2827         _TIFFfree( buf_to_write );
2828         return 1;
2829     }
2830 
2831 /* -------------------------------------------------------------------- */
2832 /*      Otherwise, we write the new tag data at the end of the file.    */
2833 /* -------------------------------------------------------------------- */
2834     if( !value_in_entry )
2835     {
2836         entry_offset = TIFFSeekFile(tif,0,SEEK_END);
2837 
2838         if (!WriteOK(tif, buf_to_write, count*TIFFDataWidth(datatype))) {
2839             _TIFFfree( buf_to_write );
2840             TIFFErrorExt(tif->tif_clientdata, module,
2841                          "Error writing directory link");
2842             return (0);
2843         }
2844     }
2845     else
2846     {
2847         memcpy( &entry_offset, buf_to_write, count*TIFFDataWidth(datatype));
2848     }
2849 
2850     _TIFFfree( buf_to_write );
2851     buf_to_write = 0;
2852 
2853 /* -------------------------------------------------------------------- */
2854 /*      Adjust the directory entry.                                     */
2855 /* -------------------------------------------------------------------- */
2856     entry_type = datatype;
2857     memcpy( direntry_raw + 2, &entry_type, sizeof(uint16) );
2858     if (tif->tif_flags&TIFF_SWAB)
2859         TIFFSwabShort( (uint16 *) (direntry_raw + 2) );
2860 
2861     if (!(tif->tif_flags&TIFF_BIGTIFF))
2862     {
2863         uint32 value;
2864 
2865         value = (uint32) entry_count;
2866         memcpy( direntry_raw + 4, &value, sizeof(uint32) );
2867         if (tif->tif_flags&TIFF_SWAB)
2868             TIFFSwabLong( (uint32 *) (direntry_raw + 4) );
2869 
2870         value = (uint32) entry_offset;
2871         memcpy( direntry_raw + 8, &value, sizeof(uint32) );
2872         if (tif->tif_flags&TIFF_SWAB)
2873             TIFFSwabLong( (uint32 *) (direntry_raw + 8) );
2874     }
2875     else
2876     {
2877         memcpy( direntry_raw + 4, &entry_count, sizeof(uint64) );
2878         if (tif->tif_flags&TIFF_SWAB)
2879             TIFFSwabLong8( (uint64 *) (direntry_raw + 4) );
2880 
2881         memcpy( direntry_raw + 12, &entry_offset, sizeof(uint64) );
2882         if (tif->tif_flags&TIFF_SWAB)
2883             TIFFSwabLong8( (uint64 *) (direntry_raw + 12) );
2884     }
2885 
2886 /* -------------------------------------------------------------------- */
2887 /*      Write the directory entry out to disk.                          */
2888 /* -------------------------------------------------------------------- */
2889     if (!SeekOK(tif, read_offset )) {
2890         TIFFErrorExt(tif->tif_clientdata, module,
2891                      "%s: Seek error accessing TIFF directory",
2892                      tif->tif_name);
2893         return 0;
2894     }
2895 
2896     if (!WriteOK(tif, direntry_raw,dirsize))
2897     {
2898         TIFFErrorExt(tif->tif_clientdata, module,
2899                      "%s: Can not write TIFF directory entry.",
2900                      tif->tif_name);
2901         return 0;
2902     }
2903 
2904     return 1;
2905 }
2906 /* vim: set ts=8 sts=8 sw=8 noet: */
2907 /*
2908  * Local Variables:
2909  * mode: c
2910  * c-basic-offset: 8
2911  * fill-column: 78
2912  * End:
2913  */
2914