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