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