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