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