/src/freeimage-svn/FreeImage/trunk/Source/LibTIFF4/tif_open.c
Line | Count | Source (jump to first uncovered line) |
1 | | /* |
2 | | * Copyright (c) 1988-1997 Sam Leffler |
3 | | * Copyright (c) 1991-1997 Silicon Graphics, Inc. |
4 | | * |
5 | | * Permission to use, copy, modify, distribute, and sell this software and |
6 | | * its documentation for any purpose is hereby granted without fee, provided |
7 | | * that (i) the above copyright notices and this permission notice appear in |
8 | | * all copies of the software and related documentation, and (ii) the names of |
9 | | * Sam Leffler and Silicon Graphics may not be used in any advertising or |
10 | | * publicity relating to the software without the specific, prior written |
11 | | * permission of Sam Leffler and Silicon Graphics. |
12 | | * |
13 | | * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, |
14 | | * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY |
15 | | * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. |
16 | | * |
17 | | * IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR |
18 | | * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, |
19 | | * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, |
20 | | * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF |
21 | | * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE |
22 | | * OF THIS SOFTWARE. |
23 | | */ |
24 | | |
25 | | /* |
26 | | * TIFF Library. |
27 | | */ |
28 | | #include "tiffiop.h" |
29 | | #include <limits.h> |
30 | | |
31 | | /* |
32 | | * Dummy functions to fill the omitted client procedures. |
33 | | */ |
34 | | static int _tiffDummyMapProc(thandle_t fd, void **pbase, toff_t *psize) |
35 | 0 | { |
36 | 0 | (void)fd; |
37 | 0 | (void)pbase; |
38 | 0 | (void)psize; |
39 | 0 | return (0); |
40 | 0 | } |
41 | | |
42 | | static void _tiffDummyUnmapProc(thandle_t fd, void *base, toff_t size) |
43 | 0 | { |
44 | 0 | (void)fd; |
45 | 0 | (void)base; |
46 | 0 | (void)size; |
47 | 0 | } |
48 | | |
49 | | int _TIFFgetMode(TIFFOpenOptions *opts, thandle_t clientdata, const char *mode, |
50 | | const char *module) |
51 | 0 | { |
52 | 0 | int m = -1; |
53 | |
|
54 | 0 | switch (mode[0]) |
55 | 0 | { |
56 | 0 | case 'r': |
57 | 0 | m = O_RDONLY; |
58 | 0 | if (mode[1] == '+') |
59 | 0 | m = O_RDWR; |
60 | 0 | break; |
61 | 0 | case 'w': |
62 | 0 | case 'a': |
63 | 0 | m = O_RDWR | O_CREAT; |
64 | 0 | if (mode[0] == 'w') |
65 | 0 | m |= O_TRUNC; |
66 | 0 | break; |
67 | 0 | default: |
68 | 0 | _TIFFErrorEarly(opts, clientdata, module, "\"%s\": Bad mode", mode); |
69 | 0 | break; |
70 | 0 | } |
71 | 0 | return (m); |
72 | 0 | } |
73 | | |
74 | | TIFFOpenOptions *TIFFOpenOptionsAlloc() |
75 | 0 | { |
76 | 0 | TIFFOpenOptions *opts = |
77 | 0 | (TIFFOpenOptions *)_TIFFcalloc(1, sizeof(TIFFOpenOptions)); |
78 | 0 | return opts; |
79 | 0 | } |
80 | | |
81 | 0 | void TIFFOpenOptionsFree(TIFFOpenOptions *opts) { _TIFFfree(opts); } |
82 | | |
83 | | /** Define a limit in bytes for a single memory allocation done by libtiff. |
84 | | * If max_single_mem_alloc is set to 0, no other limit that the underlying |
85 | | * _TIFFmalloc() will be applied, which is the default. |
86 | | */ |
87 | | void TIFFOpenOptionsSetMaxSingleMemAlloc(TIFFOpenOptions *opts, |
88 | | tmsize_t max_single_mem_alloc) |
89 | 0 | { |
90 | 0 | opts->max_single_mem_alloc = max_single_mem_alloc; |
91 | 0 | } |
92 | | |
93 | | void TIFFOpenOptionsSetErrorHandlerExtR(TIFFOpenOptions *opts, |
94 | | TIFFErrorHandlerExtR handler, |
95 | | void *errorhandler_user_data) |
96 | 0 | { |
97 | 0 | opts->errorhandler = handler; |
98 | 0 | opts->errorhandler_user_data = errorhandler_user_data; |
99 | 0 | } |
100 | | |
101 | | void TIFFOpenOptionsSetWarningHandlerExtR(TIFFOpenOptions *opts, |
102 | | TIFFErrorHandlerExtR handler, |
103 | | void *warnhandler_user_data) |
104 | 0 | { |
105 | 0 | opts->warnhandler = handler; |
106 | 0 | opts->warnhandler_user_data = warnhandler_user_data; |
107 | 0 | } |
108 | | |
109 | | static void _TIFFEmitErrorAboveMaxSingleMemAlloc(TIFF *tif, |
110 | | const char *pszFunction, |
111 | | tmsize_t s) |
112 | 0 | { |
113 | 0 | TIFFErrorExtR(tif, pszFunction, |
114 | 0 | "Memory allocation of %" PRIu64 |
115 | 0 | " bytes is beyond the %" PRIu64 |
116 | 0 | " byte limit defined in open options", |
117 | 0 | (uint64_t)s, (uint64_t)tif->tif_max_single_mem_alloc); |
118 | 0 | } |
119 | | |
120 | | /** malloc() version that takes into account memory-specific open options */ |
121 | | void *_TIFFmallocExt(TIFF *tif, tmsize_t s) |
122 | 0 | { |
123 | 0 | if (tif != NULL && tif->tif_max_single_mem_alloc > 0 && |
124 | 0 | s > tif->tif_max_single_mem_alloc) |
125 | 0 | { |
126 | 0 | _TIFFEmitErrorAboveMaxSingleMemAlloc(tif, "_TIFFmallocExt", s); |
127 | 0 | return NULL; |
128 | 0 | } |
129 | 0 | return _TIFFmalloc(s); |
130 | 0 | } |
131 | | |
132 | | /** calloc() version that takes into account memory-specific open options */ |
133 | | void *_TIFFcallocExt(TIFF *tif, tmsize_t nmemb, tmsize_t siz) |
134 | 0 | { |
135 | 0 | if (tif != NULL && tif->tif_max_single_mem_alloc > 0) |
136 | 0 | { |
137 | 0 | if (nmemb <= 0 || siz <= 0 || nmemb > TIFF_TMSIZE_T_MAX / siz) |
138 | 0 | return NULL; |
139 | 0 | if (nmemb * siz > tif->tif_max_single_mem_alloc) |
140 | 0 | { |
141 | 0 | _TIFFEmitErrorAboveMaxSingleMemAlloc(tif, "_TIFFcallocExt", |
142 | 0 | nmemb * siz); |
143 | 0 | return NULL; |
144 | 0 | } |
145 | 0 | } |
146 | 0 | return _TIFFcalloc(nmemb, siz); |
147 | 0 | } |
148 | | |
149 | | /** realloc() version that takes into account memory-specific open options */ |
150 | | void *_TIFFreallocExt(TIFF *tif, void *p, tmsize_t s) |
151 | 0 | { |
152 | 0 | if (tif != NULL && tif->tif_max_single_mem_alloc > 0 && |
153 | 0 | s > tif->tif_max_single_mem_alloc) |
154 | 0 | { |
155 | 0 | _TIFFEmitErrorAboveMaxSingleMemAlloc(tif, "_TIFFreallocExt", s); |
156 | 0 | return NULL; |
157 | 0 | } |
158 | 0 | return _TIFFrealloc(p, s); |
159 | 0 | } |
160 | | |
161 | | /** free() version that takes into account memory-specific open options */ |
162 | | void _TIFFfreeExt(TIFF *tif, void *p) |
163 | 0 | { |
164 | 0 | (void)tif; |
165 | 0 | _TIFFfree(p); |
166 | 0 | } |
167 | | |
168 | | TIFF *TIFFClientOpen(const char *name, const char *mode, thandle_t clientdata, |
169 | | TIFFReadWriteProc readproc, TIFFReadWriteProc writeproc, |
170 | | TIFFSeekProc seekproc, TIFFCloseProc closeproc, |
171 | | TIFFSizeProc sizeproc, TIFFMapFileProc mapproc, |
172 | | TIFFUnmapFileProc unmapproc) |
173 | 0 | { |
174 | 0 | return TIFFClientOpenExt(name, mode, clientdata, readproc, writeproc, |
175 | 0 | seekproc, closeproc, sizeproc, mapproc, unmapproc, |
176 | 0 | NULL); |
177 | 0 | } |
178 | | |
179 | | TIFF *TIFFClientOpenExt(const char *name, const char *mode, |
180 | | thandle_t clientdata, TIFFReadWriteProc readproc, |
181 | | TIFFReadWriteProc writeproc, TIFFSeekProc seekproc, |
182 | | TIFFCloseProc closeproc, TIFFSizeProc sizeproc, |
183 | | TIFFMapFileProc mapproc, TIFFUnmapFileProc unmapproc, |
184 | | TIFFOpenOptions *opts) |
185 | 0 | { |
186 | 0 | static const char module[] = "TIFFClientOpenExt"; |
187 | 0 | TIFF *tif; |
188 | 0 | int m; |
189 | 0 | const char *cp; |
190 | | |
191 | | /* The following are configuration checks. They should be redundant, but |
192 | | * should not compile to any actual code in an optimised release build |
193 | | * anyway. If any of them fail, (makefile-based or other) configuration is |
194 | | * not correct */ |
195 | 0 | assert(sizeof(uint8_t) == 1); |
196 | 0 | assert(sizeof(int8_t) == 1); |
197 | 0 | assert(sizeof(uint16_t) == 2); |
198 | 0 | assert(sizeof(int16_t) == 2); |
199 | 0 | assert(sizeof(uint32_t) == 4); |
200 | 0 | assert(sizeof(int32_t) == 4); |
201 | 0 | assert(sizeof(uint64_t) == 8); |
202 | 0 | assert(sizeof(int64_t) == 8); |
203 | 0 | { |
204 | 0 | union |
205 | 0 | { |
206 | 0 | uint8_t a8[2]; |
207 | 0 | uint16_t a16; |
208 | 0 | } n; |
209 | 0 | n.a8[0] = 1; |
210 | 0 | n.a8[1] = 0; |
211 | 0 | (void)n; |
212 | | #ifdef WORDS_BIGENDIAN |
213 | | assert(n.a16 == 256); |
214 | | #else |
215 | 0 | assert(n.a16 == 1); |
216 | 0 | #endif |
217 | 0 | } |
218 | | |
219 | 0 | m = _TIFFgetMode(opts, clientdata, mode, module); |
220 | 0 | if (m == -1) |
221 | 0 | goto bad2; |
222 | 0 | tmsize_t size_to_alloc = (tmsize_t)(sizeof(TIFF) + strlen(name) + 1); |
223 | 0 | if (opts && opts->max_single_mem_alloc > 0 && |
224 | 0 | size_to_alloc > opts->max_single_mem_alloc) |
225 | 0 | { |
226 | 0 | _TIFFErrorEarly(opts, clientdata, module, |
227 | 0 | "%s: Memory allocation of %" PRIu64 |
228 | 0 | " bytes is beyond the %" PRIu64 |
229 | 0 | " byte limit defined in open options", |
230 | 0 | name, (uint64_t)size_to_alloc, |
231 | 0 | (uint64_t)opts->max_single_mem_alloc); |
232 | 0 | goto bad2; |
233 | 0 | } |
234 | 0 | tif = (TIFF *)_TIFFmallocExt(NULL, size_to_alloc); |
235 | 0 | if (tif == NULL) |
236 | 0 | { |
237 | 0 | _TIFFErrorEarly(opts, clientdata, module, |
238 | 0 | "%s: Out of memory (TIFF structure)", name); |
239 | 0 | goto bad2; |
240 | 0 | } |
241 | 0 | _TIFFmemset(tif, 0, sizeof(*tif)); |
242 | 0 | tif->tif_name = (char *)tif + sizeof(TIFF); |
243 | 0 | strcpy(tif->tif_name, name); |
244 | 0 | tif->tif_mode = m & ~(O_CREAT | O_TRUNC); |
245 | 0 | tif->tif_curdir = TIFF_NON_EXISTENT_DIR_NUMBER; /* non-existent directory */ |
246 | 0 | tif->tif_curoff = 0; |
247 | 0 | tif->tif_curstrip = (uint32_t)-1; /* invalid strip */ |
248 | 0 | tif->tif_row = (uint32_t)-1; /* read/write pre-increment */ |
249 | 0 | tif->tif_clientdata = clientdata; |
250 | 0 | tif->tif_readproc = readproc; |
251 | 0 | tif->tif_writeproc = writeproc; |
252 | 0 | tif->tif_seekproc = seekproc; |
253 | 0 | tif->tif_closeproc = closeproc; |
254 | 0 | tif->tif_sizeproc = sizeproc; |
255 | 0 | tif->tif_mapproc = mapproc ? mapproc : _tiffDummyMapProc; |
256 | 0 | tif->tif_unmapproc = unmapproc ? unmapproc : _tiffDummyUnmapProc; |
257 | 0 | if (opts) |
258 | 0 | { |
259 | 0 | tif->tif_errorhandler = opts->errorhandler; |
260 | 0 | tif->tif_errorhandler_user_data = opts->errorhandler_user_data; |
261 | 0 | tif->tif_warnhandler = opts->warnhandler; |
262 | 0 | tif->tif_warnhandler_user_data = opts->warnhandler_user_data; |
263 | 0 | tif->tif_max_single_mem_alloc = opts->max_single_mem_alloc; |
264 | 0 | } |
265 | |
|
266 | 0 | if (!readproc || !writeproc || !seekproc || !closeproc || !sizeproc) |
267 | 0 | { |
268 | 0 | TIFFErrorExtR(tif, module, |
269 | 0 | "One of the client procedures is NULL pointer."); |
270 | 0 | _TIFFfreeExt(NULL, tif); |
271 | 0 | goto bad2; |
272 | 0 | } |
273 | | |
274 | 0 | _TIFFSetDefaultCompressionState(tif); /* setup default state */ |
275 | | /* |
276 | | * Default is to return data MSB2LSB and enable the |
277 | | * use of memory-mapped files and strip chopping when |
278 | | * a file is opened read-only. |
279 | | */ |
280 | 0 | tif->tif_flags = FILLORDER_MSB2LSB; |
281 | 0 | if (m == O_RDONLY) |
282 | 0 | tif->tif_flags |= TIFF_MAPPED; |
283 | |
|
284 | 0 | #ifdef STRIPCHOP_DEFAULT |
285 | 0 | if (m == O_RDONLY || m == O_RDWR) |
286 | 0 | tif->tif_flags |= STRIPCHOP_DEFAULT; |
287 | 0 | #endif |
288 | | |
289 | | /* |
290 | | * Process library-specific flags in the open mode string. |
291 | | * The following flags may be used to control intrinsic library |
292 | | * behavior that may or may not be desirable (usually for |
293 | | * compatibility with some application that claims to support |
294 | | * TIFF but only supports some brain dead idea of what the |
295 | | * vendor thinks TIFF is): |
296 | | * |
297 | | * 'l' use little-endian byte order for creating a file |
298 | | * 'b' use big-endian byte order for creating a file |
299 | | * 'L' read/write information using LSB2MSB bit order |
300 | | * 'B' read/write information using MSB2LSB bit order |
301 | | * 'H' read/write information using host bit order |
302 | | * 'M' enable use of memory-mapped files when supported |
303 | | * 'm' disable use of memory-mapped files |
304 | | * 'C' enable strip chopping support when reading |
305 | | * 'c' disable strip chopping support |
306 | | * 'h' read TIFF header only, do not load the first IFD |
307 | | * '4' ClassicTIFF for creating a file (default) |
308 | | * '8' BigTIFF for creating a file |
309 | | * 'D' enable use of deferred strip/tile offset/bytecount array loading. |
310 | | * 'O' on-demand loading of values instead of whole array loading (implies |
311 | | * D) |
312 | | * |
313 | | * The use of the 'l' and 'b' flags is strongly discouraged. |
314 | | * These flags are provided solely because numerous vendors, |
315 | | * typically on the PC, do not correctly support TIFF; they |
316 | | * only support the Intel little-endian byte order. This |
317 | | * support is not configured by default because it supports |
318 | | * the violation of the TIFF spec that says that readers *MUST* |
319 | | * support both byte orders. It is strongly recommended that |
320 | | * you not use this feature except to deal with busted apps |
321 | | * that write invalid TIFF. And even in those cases you should |
322 | | * bang on the vendors to fix their software. |
323 | | * |
324 | | * The 'L', 'B', and 'H' flags are intended for applications |
325 | | * that can optimize operations on data by using a particular |
326 | | * bit order. By default the library returns data in MSB2LSB |
327 | | * bit order for compatibility with older versions of this |
328 | | * library. Returning data in the bit order of the native CPU |
329 | | * makes the most sense but also requires applications to check |
330 | | * the value of the FillOrder tag; something they probably do |
331 | | * not do right now. |
332 | | * |
333 | | * The 'M' and 'm' flags are provided because some virtual memory |
334 | | * systems exhibit poor behavior when large images are mapped. |
335 | | * These options permit clients to control the use of memory-mapped |
336 | | * files on a per-file basis. |
337 | | * |
338 | | * The 'C' and 'c' flags are provided because the library support |
339 | | * for chopping up large strips into multiple smaller strips is not |
340 | | * application-transparent and as such can cause problems. The 'c' |
341 | | * option permits applications that only want to look at the tags, |
342 | | * for example, to get the unadulterated TIFF tag information. |
343 | | */ |
344 | 0 | for (cp = mode; *cp; cp++) |
345 | 0 | switch (*cp) |
346 | 0 | { |
347 | 0 | case 'b': |
348 | 0 | #ifndef WORDS_BIGENDIAN |
349 | 0 | if (m & O_CREAT) |
350 | 0 | tif->tif_flags |= TIFF_SWAB; |
351 | 0 | #endif |
352 | 0 | break; |
353 | 0 | case 'l': |
354 | | #ifdef WORDS_BIGENDIAN |
355 | | if ((m & O_CREAT)) |
356 | | tif->tif_flags |= TIFF_SWAB; |
357 | | #endif |
358 | 0 | break; |
359 | 0 | case 'B': |
360 | 0 | tif->tif_flags = |
361 | 0 | (tif->tif_flags & ~TIFF_FILLORDER) | FILLORDER_MSB2LSB; |
362 | 0 | break; |
363 | 0 | case 'L': |
364 | 0 | tif->tif_flags = |
365 | 0 | (tif->tif_flags & ~TIFF_FILLORDER) | FILLORDER_LSB2MSB; |
366 | 0 | break; |
367 | 0 | case 'H': |
368 | 0 | TIFFWarningExtR(tif, name, |
369 | 0 | "H(ost) mode is deprecated. Since " |
370 | 0 | "libtiff 4.5.1, it is an alias of 'B' / " |
371 | 0 | "FILLORDER_MSB2LSB."); |
372 | 0 | tif->tif_flags = |
373 | 0 | (tif->tif_flags & ~TIFF_FILLORDER) | FILLORDER_MSB2LSB; |
374 | 0 | break; |
375 | 0 | case 'M': |
376 | 0 | if (m == O_RDONLY) |
377 | 0 | tif->tif_flags |= TIFF_MAPPED; |
378 | 0 | break; |
379 | 0 | case 'm': |
380 | 0 | if (m == O_RDONLY) |
381 | 0 | tif->tif_flags &= ~TIFF_MAPPED; |
382 | 0 | break; |
383 | 0 | case 'C': |
384 | 0 | if (m == O_RDONLY) |
385 | 0 | tif->tif_flags |= TIFF_STRIPCHOP; |
386 | 0 | break; |
387 | 0 | case 'c': |
388 | 0 | if (m == O_RDONLY) |
389 | 0 | tif->tif_flags &= ~TIFF_STRIPCHOP; |
390 | 0 | break; |
391 | 0 | case 'h': |
392 | 0 | tif->tif_flags |= TIFF_HEADERONLY; |
393 | 0 | break; |
394 | 0 | case '8': |
395 | 0 | if (m & O_CREAT) |
396 | 0 | tif->tif_flags |= TIFF_BIGTIFF; |
397 | 0 | break; |
398 | 0 | case 'D': |
399 | 0 | tif->tif_flags |= TIFF_DEFERSTRILELOAD; |
400 | 0 | break; |
401 | 0 | case 'O': |
402 | 0 | if (m == O_RDONLY) |
403 | 0 | tif->tif_flags |= |
404 | 0 | (TIFF_LAZYSTRILELOAD | TIFF_DEFERSTRILELOAD); |
405 | 0 | break; |
406 | 0 | } |
407 | | |
408 | | #ifdef DEFER_STRILE_LOAD |
409 | | /* Compatibility with old DEFER_STRILE_LOAD compilation flag */ |
410 | | /* Probably unneeded, since to the best of my knowledge (E. Rouault) */ |
411 | | /* GDAL was the only user of this, and will now use the new 'D' flag */ |
412 | | tif->tif_flags |= TIFF_DEFERSTRILELOAD; |
413 | | #endif |
414 | | |
415 | | /* |
416 | | * Read in TIFF header. |
417 | | */ |
418 | 0 | if ((m & O_TRUNC) || |
419 | 0 | !ReadOK(tif, &tif->tif_header, sizeof(TIFFHeaderClassic))) |
420 | 0 | { |
421 | 0 | if (tif->tif_mode == O_RDONLY) |
422 | 0 | { |
423 | 0 | TIFFErrorExtR(tif, name, "Cannot read TIFF header"); |
424 | 0 | goto bad; |
425 | 0 | } |
426 | | /* |
427 | | * Setup header and write. |
428 | | */ |
429 | | #ifdef WORDS_BIGENDIAN |
430 | | tif->tif_header.common.tiff_magic = |
431 | | (tif->tif_flags & TIFF_SWAB) ? TIFF_LITTLEENDIAN : TIFF_BIGENDIAN; |
432 | | #else |
433 | 0 | tif->tif_header.common.tiff_magic = |
434 | 0 | (tif->tif_flags & TIFF_SWAB) ? TIFF_BIGENDIAN : TIFF_LITTLEENDIAN; |
435 | 0 | #endif |
436 | 0 | if (!(tif->tif_flags & TIFF_BIGTIFF)) |
437 | 0 | { |
438 | 0 | tif->tif_header.common.tiff_version = TIFF_VERSION_CLASSIC; |
439 | 0 | tif->tif_header.classic.tiff_diroff = 0; |
440 | 0 | if (tif->tif_flags & TIFF_SWAB) |
441 | 0 | TIFFSwabShort(&tif->tif_header.common.tiff_version); |
442 | 0 | tif->tif_header_size = sizeof(TIFFHeaderClassic); |
443 | 0 | } |
444 | 0 | else |
445 | 0 | { |
446 | 0 | tif->tif_header.common.tiff_version = TIFF_VERSION_BIG; |
447 | 0 | tif->tif_header.big.tiff_offsetsize = 8; |
448 | 0 | tif->tif_header.big.tiff_unused = 0; |
449 | 0 | tif->tif_header.big.tiff_diroff = 0; |
450 | 0 | if (tif->tif_flags & TIFF_SWAB) |
451 | 0 | { |
452 | 0 | TIFFSwabShort(&tif->tif_header.common.tiff_version); |
453 | 0 | TIFFSwabShort(&tif->tif_header.big.tiff_offsetsize); |
454 | 0 | } |
455 | 0 | tif->tif_header_size = sizeof(TIFFHeaderBig); |
456 | 0 | } |
457 | | /* |
458 | | * The doc for "fopen" for some STD_C_LIBs says that if you |
459 | | * open a file for modify ("+"), then you must fseek (or |
460 | | * fflush?) between any freads and fwrites. This is not |
461 | | * necessary on most systems, but has been shown to be needed |
462 | | * on Solaris. |
463 | | */ |
464 | 0 | TIFFSeekFile(tif, 0, SEEK_SET); |
465 | 0 | if (!WriteOK(tif, &tif->tif_header, (tmsize_t)(tif->tif_header_size))) |
466 | 0 | { |
467 | 0 | TIFFErrorExtR(tif, name, "Error writing TIFF header"); |
468 | 0 | goto bad; |
469 | 0 | } |
470 | | /* |
471 | | * Setup the byte order handling. |
472 | | */ |
473 | 0 | if (tif->tif_header.common.tiff_magic == TIFF_BIGENDIAN) |
474 | 0 | { |
475 | 0 | #ifndef WORDS_BIGENDIAN |
476 | 0 | tif->tif_flags |= TIFF_SWAB; |
477 | 0 | #endif |
478 | 0 | } |
479 | 0 | else |
480 | 0 | { |
481 | | #ifdef WORDS_BIGENDIAN |
482 | | tif->tif_flags |= TIFF_SWAB; |
483 | | #endif |
484 | 0 | } |
485 | | /* |
486 | | * Setup default directory. |
487 | | */ |
488 | 0 | if (!TIFFDefaultDirectory(tif)) |
489 | 0 | goto bad; |
490 | 0 | tif->tif_diroff = 0; |
491 | 0 | tif->tif_lastdiroff = 0; |
492 | 0 | tif->tif_setdirectory_force_absolute = FALSE; |
493 | 0 | return (tif); |
494 | 0 | } |
495 | | /* |
496 | | * Setup the byte order handling. |
497 | | */ |
498 | 0 | if (tif->tif_header.common.tiff_magic != TIFF_BIGENDIAN && |
499 | 0 | tif->tif_header.common.tiff_magic != TIFF_LITTLEENDIAN |
500 | 0 | #if MDI_SUPPORT |
501 | 0 | && |
502 | | #if HOST_BIGENDIAN |
503 | | tif->tif_header.common.tiff_magic != MDI_BIGENDIAN |
504 | | #else |
505 | 0 | tif->tif_header.common.tiff_magic != MDI_LITTLEENDIAN |
506 | 0 | #endif |
507 | 0 | ) |
508 | 0 | { |
509 | 0 | TIFFErrorExtR(tif, name, |
510 | 0 | "Not a TIFF or MDI file, bad magic number %" PRIu16 |
511 | 0 | " (0x%" PRIx16 ")", |
512 | | #else |
513 | | ) |
514 | | { |
515 | | TIFFErrorExtR(tif, name, |
516 | | "Not a TIFF file, bad magic number %" PRIu16 |
517 | | " (0x%" PRIx16 ")", |
518 | | #endif |
519 | 0 | tif->tif_header.common.tiff_magic, |
520 | 0 | tif->tif_header.common.tiff_magic); |
521 | 0 | goto bad; |
522 | 0 | } |
523 | 0 | if (tif->tif_header.common.tiff_magic == TIFF_BIGENDIAN) |
524 | 0 | { |
525 | 0 | #ifndef WORDS_BIGENDIAN |
526 | 0 | tif->tif_flags |= TIFF_SWAB; |
527 | 0 | #endif |
528 | 0 | } |
529 | 0 | else |
530 | 0 | { |
531 | | #ifdef WORDS_BIGENDIAN |
532 | | tif->tif_flags |= TIFF_SWAB; |
533 | | #endif |
534 | 0 | } |
535 | 0 | if (tif->tif_flags & TIFF_SWAB) |
536 | 0 | TIFFSwabShort(&tif->tif_header.common.tiff_version); |
537 | 0 | if ((tif->tif_header.common.tiff_version != TIFF_VERSION_CLASSIC) && |
538 | 0 | (tif->tif_header.common.tiff_version != TIFF_VERSION_BIG)) |
539 | 0 | { |
540 | 0 | TIFFErrorExtR(tif, name, |
541 | 0 | "Not a TIFF file, bad version number %" PRIu16 |
542 | 0 | " (0x%" PRIx16 ")", |
543 | 0 | tif->tif_header.common.tiff_version, |
544 | 0 | tif->tif_header.common.tiff_version); |
545 | 0 | goto bad; |
546 | 0 | } |
547 | 0 | if (tif->tif_header.common.tiff_version == TIFF_VERSION_CLASSIC) |
548 | 0 | { |
549 | 0 | if (tif->tif_flags & TIFF_SWAB) |
550 | 0 | TIFFSwabLong(&tif->tif_header.classic.tiff_diroff); |
551 | 0 | tif->tif_header_size = sizeof(TIFFHeaderClassic); |
552 | 0 | } |
553 | 0 | else |
554 | 0 | { |
555 | 0 | if (!ReadOK(tif, |
556 | 0 | ((uint8_t *)(&tif->tif_header) + sizeof(TIFFHeaderClassic)), |
557 | 0 | (sizeof(TIFFHeaderBig) - sizeof(TIFFHeaderClassic)))) |
558 | 0 | { |
559 | 0 | TIFFErrorExtR(tif, name, "Cannot read TIFF header"); |
560 | 0 | goto bad; |
561 | 0 | } |
562 | 0 | if (tif->tif_flags & TIFF_SWAB) |
563 | 0 | { |
564 | 0 | TIFFSwabShort(&tif->tif_header.big.tiff_offsetsize); |
565 | 0 | TIFFSwabLong8(&tif->tif_header.big.tiff_diroff); |
566 | 0 | } |
567 | 0 | if (tif->tif_header.big.tiff_offsetsize != 8) |
568 | 0 | { |
569 | 0 | TIFFErrorExtR(tif, name, |
570 | 0 | "Not a TIFF file, bad BigTIFF offsetsize %" PRIu16 |
571 | 0 | " (0x%" PRIx16 ")", |
572 | 0 | tif->tif_header.big.tiff_offsetsize, |
573 | 0 | tif->tif_header.big.tiff_offsetsize); |
574 | 0 | goto bad; |
575 | 0 | } |
576 | 0 | if (tif->tif_header.big.tiff_unused != 0) |
577 | 0 | { |
578 | 0 | TIFFErrorExtR(tif, name, |
579 | 0 | "Not a TIFF file, bad BigTIFF unused %" PRIu16 |
580 | 0 | " (0x%" PRIx16 ")", |
581 | 0 | tif->tif_header.big.tiff_unused, |
582 | 0 | tif->tif_header.big.tiff_unused); |
583 | 0 | goto bad; |
584 | 0 | } |
585 | 0 | tif->tif_header_size = sizeof(TIFFHeaderBig); |
586 | 0 | tif->tif_flags |= TIFF_BIGTIFF; |
587 | 0 | } |
588 | 0 | tif->tif_flags |= TIFF_MYBUFFER; |
589 | 0 | tif->tif_rawcp = tif->tif_rawdata = 0; |
590 | 0 | tif->tif_rawdatasize = 0; |
591 | 0 | tif->tif_rawdataoff = 0; |
592 | 0 | tif->tif_rawdataloaded = 0; |
593 | |
|
594 | 0 | switch (mode[0]) |
595 | 0 | { |
596 | 0 | case 'r': |
597 | 0 | if (!(tif->tif_flags & TIFF_BIGTIFF)) |
598 | 0 | tif->tif_nextdiroff = tif->tif_header.classic.tiff_diroff; |
599 | 0 | else |
600 | 0 | tif->tif_nextdiroff = tif->tif_header.big.tiff_diroff; |
601 | | /* |
602 | | * Try to use a memory-mapped file if the client |
603 | | * has not explicitly suppressed usage with the |
604 | | * 'm' flag in the open mode (see above). |
605 | | */ |
606 | 0 | if (tif->tif_flags & TIFF_MAPPED) |
607 | 0 | { |
608 | 0 | toff_t n; |
609 | 0 | if (TIFFMapFileContents(tif, (void **)(&tif->tif_base), &n)) |
610 | 0 | { |
611 | 0 | tif->tif_size = (tmsize_t)n; |
612 | 0 | assert((toff_t)tif->tif_size == n); |
613 | 0 | } |
614 | 0 | else |
615 | 0 | tif->tif_flags &= ~TIFF_MAPPED; |
616 | 0 | } |
617 | | /* |
618 | | * Sometimes we do not want to read the first directory (for |
619 | | * example, it may be broken) and want to proceed to other |
620 | | * directories. I this case we use the TIFF_HEADERONLY flag to open |
621 | | * file and return immediately after reading TIFF header. |
622 | | */ |
623 | 0 | if (tif->tif_flags & TIFF_HEADERONLY) |
624 | 0 | return (tif); |
625 | | |
626 | | /* |
627 | | * Setup initial directory. |
628 | | */ |
629 | 0 | if (TIFFReadDirectory(tif)) |
630 | 0 | { |
631 | 0 | return (tif); |
632 | 0 | } |
633 | 0 | break; |
634 | 0 | case 'a': |
635 | | /* |
636 | | * New directories are automatically append |
637 | | * to the end of the directory chain when they |
638 | | * are written out (see TIFFWriteDirectory). |
639 | | */ |
640 | 0 | if (!TIFFDefaultDirectory(tif)) |
641 | 0 | goto bad; |
642 | 0 | return (tif); |
643 | 0 | } |
644 | 0 | bad: |
645 | 0 | tif->tif_mode = O_RDONLY; /* XXX avoid flush */ |
646 | 0 | TIFFCleanup(tif); |
647 | 0 | bad2: |
648 | 0 | return ((TIFF *)0); |
649 | 0 | } |
650 | | |
651 | | /* |
652 | | * Query functions to access private data. |
653 | | */ |
654 | | |
655 | | /* |
656 | | * Return open file's name. |
657 | | */ |
658 | 0 | const char *TIFFFileName(TIFF *tif) { return (tif->tif_name); } |
659 | | |
660 | | /* |
661 | | * Set the file name. |
662 | | */ |
663 | | const char *TIFFSetFileName(TIFF *tif, const char *name) |
664 | 0 | { |
665 | 0 | const char *old_name = tif->tif_name; |
666 | 0 | tif->tif_name = (char *)name; |
667 | 0 | return (old_name); |
668 | 0 | } |
669 | | |
670 | | /* |
671 | | * Return open file's I/O descriptor. |
672 | | */ |
673 | 0 | int TIFFFileno(TIFF *tif) { return (tif->tif_fd); } |
674 | | |
675 | | /* |
676 | | * Set open file's I/O descriptor, and return previous value. |
677 | | */ |
678 | | int TIFFSetFileno(TIFF *tif, int fd) |
679 | 0 | { |
680 | 0 | int old_fd = tif->tif_fd; |
681 | 0 | tif->tif_fd = fd; |
682 | 0 | return old_fd; |
683 | 0 | } |
684 | | |
685 | | /* |
686 | | * Return open file's clientdata. |
687 | | */ |
688 | 0 | thandle_t TIFFClientdata(TIFF *tif) { return (tif->tif_clientdata); } |
689 | | |
690 | | /* |
691 | | * Set open file's clientdata, and return previous value. |
692 | | */ |
693 | | thandle_t TIFFSetClientdata(TIFF *tif, thandle_t newvalue) |
694 | 0 | { |
695 | 0 | thandle_t m = tif->tif_clientdata; |
696 | 0 | tif->tif_clientdata = newvalue; |
697 | 0 | return m; |
698 | 0 | } |
699 | | |
700 | | /* |
701 | | * Return read/write mode. |
702 | | */ |
703 | 0 | int TIFFGetMode(TIFF *tif) { return (tif->tif_mode); } |
704 | | |
705 | | /* |
706 | | * Return read/write mode. |
707 | | */ |
708 | | int TIFFSetMode(TIFF *tif, int mode) |
709 | 0 | { |
710 | 0 | int old_mode = tif->tif_mode; |
711 | 0 | tif->tif_mode = mode; |
712 | 0 | return (old_mode); |
713 | 0 | } |
714 | | |
715 | | /* |
716 | | * Return nonzero if file is organized in |
717 | | * tiles; zero if organized as strips. |
718 | | */ |
719 | 0 | int TIFFIsTiled(TIFF *tif) { return (isTiled(tif)); } |
720 | | |
721 | | /* |
722 | | * Return current row being read/written. |
723 | | */ |
724 | 0 | uint32_t TIFFCurrentRow(TIFF *tif) { return (tif->tif_row); } |
725 | | |
726 | | /* |
727 | | * Return index of the current directory. |
728 | | */ |
729 | 0 | tdir_t TIFFCurrentDirectory(TIFF *tif) { return (tif->tif_curdir); } |
730 | | |
731 | | /* |
732 | | * Return current strip. |
733 | | */ |
734 | 0 | uint32_t TIFFCurrentStrip(TIFF *tif) { return (tif->tif_curstrip); } |
735 | | |
736 | | /* |
737 | | * Return current tile. |
738 | | */ |
739 | 0 | uint32_t TIFFCurrentTile(TIFF *tif) { return (tif->tif_curtile); } |
740 | | |
741 | | /* |
742 | | * Return nonzero if the file has byte-swapped data. |
743 | | */ |
744 | 0 | int TIFFIsByteSwapped(TIFF *tif) { return ((tif->tif_flags & TIFF_SWAB) != 0); } |
745 | | |
746 | | /* |
747 | | * Return nonzero if the data is returned up-sampled. |
748 | | */ |
749 | 0 | int TIFFIsUpSampled(TIFF *tif) { return (isUpSampled(tif)); } |
750 | | |
751 | | /* |
752 | | * Return nonzero if the data is returned in MSB-to-LSB bit order. |
753 | | */ |
754 | 0 | int TIFFIsMSB2LSB(TIFF *tif) { return (isFillOrder(tif, FILLORDER_MSB2LSB)); } |
755 | | |
756 | | /* |
757 | | * Return nonzero if given file was written in big-endian order. |
758 | | */ |
759 | | int TIFFIsBigEndian(TIFF *tif) |
760 | 0 | { |
761 | 0 | return (tif->tif_header.common.tiff_magic == TIFF_BIGENDIAN); |
762 | 0 | } |
763 | | |
764 | | /* |
765 | | * Return nonzero if given file is BigTIFF style. |
766 | | */ |
767 | | int TIFFIsBigTIFF(TIFF *tif) |
768 | 0 | { |
769 | 0 | return (tif->tif_header.common.tiff_version == TIFF_VERSION_BIG); |
770 | 0 | } |
771 | | |
772 | | /* |
773 | | * Return pointer to file read method. |
774 | | */ |
775 | 0 | TIFFReadWriteProc TIFFGetReadProc(TIFF *tif) { return (tif->tif_readproc); } |
776 | | |
777 | | /* |
778 | | * Return pointer to file write method. |
779 | | */ |
780 | 0 | TIFFReadWriteProc TIFFGetWriteProc(TIFF *tif) { return (tif->tif_writeproc); } |
781 | | |
782 | | /* |
783 | | * Return pointer to file seek method. |
784 | | */ |
785 | 0 | TIFFSeekProc TIFFGetSeekProc(TIFF *tif) { return (tif->tif_seekproc); } |
786 | | |
787 | | /* |
788 | | * Return pointer to file close method. |
789 | | */ |
790 | 0 | TIFFCloseProc TIFFGetCloseProc(TIFF *tif) { return (tif->tif_closeproc); } |
791 | | |
792 | | /* |
793 | | * Return pointer to file size requesting method. |
794 | | */ |
795 | 0 | TIFFSizeProc TIFFGetSizeProc(TIFF *tif) { return (tif->tif_sizeproc); } |
796 | | |
797 | | /* |
798 | | * Return pointer to memory mapping method. |
799 | | */ |
800 | 0 | TIFFMapFileProc TIFFGetMapFileProc(TIFF *tif) { return (tif->tif_mapproc); } |
801 | | |
802 | | /* |
803 | | * Return pointer to memory unmapping method. |
804 | | */ |
805 | | TIFFUnmapFileProc TIFFGetUnmapFileProc(TIFF *tif) |
806 | 0 | { |
807 | 0 | return (tif->tif_unmapproc); |
808 | 0 | } |