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