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