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