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