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