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