]>
Commit | Line | Data |
---|---|---|
1 | /* $Header$ */ | |
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 | #include "tiffiop.h" | |
31 | ||
32 | void _TIFFSetDefaultCompressionState(TIFF* tif); | |
33 | ||
34 | static const long typemask[13] = { | |
35 | (long)0L, /* TIFF_NOTYPE */ | |
36 | (long)0x000000ffL, /* TIFF_BYTE */ | |
37 | (long)0xffffffffL, /* TIFF_ASCII */ | |
38 | (long)0x0000ffffL, /* TIFF_SHORT */ | |
39 | (long)0xffffffffL, /* TIFF_LONG */ | |
40 | (long)0xffffffffL, /* TIFF_RATIONAL */ | |
41 | (long)0x000000ffL, /* TIFF_SBYTE */ | |
42 | (long)0x000000ffL, /* TIFF_UNDEFINED */ | |
43 | (long)0x0000ffffL, /* TIFF_SSHORT */ | |
44 | (long)0xffffffffL, /* TIFF_SLONG */ | |
45 | (long)0xffffffffL, /* TIFF_SRATIONAL */ | |
46 | (long)0xffffffffL, /* TIFF_FLOAT */ | |
47 | (long)0xffffffffL, /* TIFF_DOUBLE */ | |
48 | }; | |
49 | static const int bigTypeshift[13] = { | |
50 | 0, /* TIFF_NOTYPE */ | |
51 | 24, /* TIFF_BYTE */ | |
52 | 0, /* TIFF_ASCII */ | |
53 | 16, /* TIFF_SHORT */ | |
54 | 0, /* TIFF_LONG */ | |
55 | 0, /* TIFF_RATIONAL */ | |
56 | 24, /* TIFF_SBYTE */ | |
57 | 24, /* TIFF_UNDEFINED */ | |
58 | 16, /* TIFF_SSHORT */ | |
59 | 0, /* TIFF_SLONG */ | |
60 | 0, /* TIFF_SRATIONAL */ | |
61 | 0, /* TIFF_FLOAT */ | |
62 | 0, /* TIFF_DOUBLE */ | |
63 | }; | |
64 | static const int litTypeshift[13] = { | |
65 | 0, /* TIFF_NOTYPE */ | |
66 | 0, /* TIFF_BYTE */ | |
67 | 0, /* TIFF_ASCII */ | |
68 | 0, /* TIFF_SHORT */ | |
69 | 0, /* TIFF_LONG */ | |
70 | 0, /* TIFF_RATIONAL */ | |
71 | 0, /* TIFF_SBYTE */ | |
72 | 0, /* TIFF_UNDEFINED */ | |
73 | 0, /* TIFF_SSHORT */ | |
74 | 0, /* TIFF_SLONG */ | |
75 | 0, /* TIFF_SRATIONAL */ | |
76 | 0, /* TIFF_FLOAT */ | |
77 | 0, /* TIFF_DOUBLE */ | |
78 | }; | |
79 | ||
80 | /* | |
81 | * Initialize the shift & mask tables, and the | |
82 | * byte swapping state according to the file | |
83 | * contents and the machine architecture. | |
84 | */ | |
85 | static void | |
86 | TIFFInitOrder(TIFF* tif, int magic, int bigendian) | |
87 | { | |
88 | tif->tif_typemask = typemask; | |
89 | if (magic == TIFF_BIGENDIAN) { | |
90 | tif->tif_typeshift = bigTypeshift; | |
91 | if (!bigendian) | |
92 | tif->tif_flags |= TIFF_SWAB; | |
93 | } else { | |
94 | tif->tif_typeshift = litTypeshift; | |
95 | if (bigendian) | |
96 | tif->tif_flags |= TIFF_SWAB; | |
97 | } | |
98 | } | |
99 | ||
100 | int | |
101 | _TIFFgetMode(const char* mode, const char* module) | |
102 | { | |
103 | int m = -1; | |
104 | ||
105 | switch (mode[0]) { | |
106 | case 'r': | |
107 | m = O_RDONLY; | |
108 | if (mode[1] == '+') | |
109 | m = O_RDWR; | |
110 | break; | |
111 | case 'w': | |
112 | case 'a': | |
113 | m = O_RDWR|O_CREAT; | |
114 | if (mode[0] == 'w') | |
115 | m |= O_TRUNC; | |
116 | break; | |
117 | default: | |
118 | TIFFError(module, "\"%s\": Bad mode", mode); | |
119 | break; | |
120 | } | |
121 | return (m); | |
122 | } | |
123 | ||
124 | TIFF* | |
125 | TIFFClientOpen( | |
126 | const char* name, const char* mode, | |
127 | thandle_t clientdata, | |
128 | TIFFReadWriteProc readproc, | |
129 | TIFFReadWriteProc writeproc, | |
130 | TIFFSeekProc seekproc, | |
131 | TIFFCloseProc closeproc, | |
132 | TIFFSizeProc sizeproc, | |
133 | TIFFMapFileProc mapproc, | |
134 | TIFFUnmapFileProc unmapproc | |
135 | ) | |
136 | { | |
137 | static const char module[] = "TIFFClientOpen"; | |
138 | TIFF *tif; | |
139 | int m, bigendian; | |
140 | const char* cp; | |
141 | ||
142 | m = _TIFFgetMode(mode, module); | |
143 | if (m == -1) | |
144 | goto bad2; | |
145 | tif = (TIFF *)_TIFFmalloc(sizeof (TIFF) + strlen(name) + 1); | |
146 | if (tif == NULL) { | |
147 | TIFFError(module, "%s: Out of memory (TIFF structure)", name); | |
148 | goto bad2; | |
149 | } | |
150 | _TIFFmemset(tif, 0, sizeof (*tif)); | |
151 | tif->tif_name = (char *)tif + sizeof (TIFF); | |
152 | strcpy(tif->tif_name, name); | |
153 | tif->tif_mode = m &~ (O_CREAT|O_TRUNC); | |
154 | tif->tif_curdir = (tdir_t) -1; /* non-existent directory */ | |
155 | tif->tif_curoff = 0; | |
156 | tif->tif_curstrip = (tstrip_t) -1; /* invalid strip */ | |
157 | tif->tif_row = (uint32) -1; /* read/write pre-increment */ | |
158 | tif->tif_clientdata = clientdata; | |
159 | if (!readproc || !writeproc || !seekproc || !closeproc | |
160 | || !sizeproc || !mapproc || !unmapproc) { | |
161 | TIFFError(module, "One of the client procedures are NULL pointer"); | |
162 | goto bad3; | |
163 | } | |
164 | tif->tif_readproc = readproc; | |
165 | tif->tif_writeproc = writeproc; | |
166 | tif->tif_seekproc = seekproc; | |
167 | tif->tif_closeproc = closeproc; | |
168 | tif->tif_sizeproc = sizeproc; | |
169 | tif->tif_mapproc = mapproc; | |
170 | tif->tif_unmapproc = unmapproc; | |
171 | _TIFFSetDefaultCompressionState(tif); /* setup default state */ | |
172 | /* | |
173 | * Default is to return data MSB2LSB and enable the | |
174 | * use of memory-mapped files and strip chopping when | |
175 | * a file is opened read-only. | |
176 | */ | |
177 | tif->tif_flags = FILLORDER_MSB2LSB; | |
178 | if (m == O_RDONLY ) | |
179 | tif->tif_flags |= TIFF_MAPPED; | |
180 | ||
181 | #ifdef STRIPCHOP_DEFAULT | |
182 | if (m == O_RDONLY || m == O_RDWR) | |
183 | tif->tif_flags |= STRIPCHOP_DEFAULT; | |
184 | #endif | |
185 | ||
186 | { union { int32 i; char c[4]; } u; u.i = 1; bigendian = u.c[0] == 0; } | |
187 | /* | |
188 | * Process library-specific flags in the open mode string. | |
189 | * The following flags may be used to control intrinsic library | |
190 | * behaviour that may or may not be desirable (usually for | |
191 | * compatibility with some application that claims to support | |
192 | * TIFF but only supports some braindead idea of what the | |
193 | * vendor thinks TIFF is): | |
194 | * | |
195 | * 'l' use little-endian byte order for creating a file | |
196 | * 'b' use big-endian byte order for creating a file | |
197 | * 'L' read/write information using LSB2MSB bit order | |
198 | * 'B' read/write information using MSB2LSB bit order | |
199 | * 'H' read/write information using host bit order | |
200 | * 'M' enable use of memory-mapped files when supported | |
201 | * 'm' disable use of memory-mapped files | |
202 | * 'C' enable strip chopping support when reading | |
203 | * 'c' disable strip chopping support | |
204 | * | |
205 | * The use of the 'l' and 'b' flags is strongly discouraged. | |
206 | * These flags are provided solely because numerous vendors, | |
207 | * typically on the PC, do not correctly support TIFF; they | |
208 | * only support the Intel little-endian byte order. This | |
209 | * support is not configured by default because it supports | |
210 | * the violation of the TIFF spec that says that readers *MUST* | |
211 | * support both byte orders. It is strongly recommended that | |
212 | * you not use this feature except to deal with busted apps | |
213 | * that write invalid TIFF. And even in those cases you should | |
214 | * bang on the vendors to fix their software. | |
215 | * | |
216 | * The 'L', 'B', and 'H' flags are intended for applications | |
217 | * that can optimize operations on data by using a particular | |
218 | * bit order. By default the library returns data in MSB2LSB | |
219 | * bit order for compatibiltiy with older versions of this | |
220 | * library. Returning data in the bit order of the native cpu | |
221 | * makes the most sense but also requires applications to check | |
222 | * the value of the FillOrder tag; something they probabyl do | |
223 | * not do right now. | |
224 | * | |
225 | * The 'M' and 'm' flags are provided because some virtual memory | |
226 | * systems exhibit poor behaviour when large images are mapped. | |
227 | * These options permit clients to control the use of memory-mapped | |
228 | * files on a per-file basis. | |
229 | * | |
230 | * The 'C' and 'c' flags are provided because the library support | |
231 | * for chopping up large strips into multiple smaller strips is not | |
232 | * application-transparent and as such can cause problems. The 'c' | |
233 | * option permits applications that only want to look at the tags, | |
234 | * for example, to get the unadulterated TIFF tag information. | |
235 | */ | |
236 | for (cp = mode; *cp; cp++) | |
237 | switch (*cp) { | |
238 | case 'b': | |
239 | if ((m&O_CREAT) && !bigendian) | |
240 | tif->tif_flags |= TIFF_SWAB; | |
241 | break; | |
242 | case 'l': | |
243 | if ((m&O_CREAT) && bigendian) | |
244 | tif->tif_flags |= TIFF_SWAB; | |
245 | break; | |
246 | case 'B': | |
247 | tif->tif_flags = (tif->tif_flags &~ TIFF_FILLORDER) | | |
248 | FILLORDER_MSB2LSB; | |
249 | break; | |
250 | case 'L': | |
251 | tif->tif_flags = (tif->tif_flags &~ TIFF_FILLORDER) | | |
252 | FILLORDER_LSB2MSB; | |
253 | break; | |
254 | case 'H': | |
255 | tif->tif_flags = (tif->tif_flags &~ TIFF_FILLORDER) | | |
256 | HOST_FILLORDER; | |
257 | break; | |
258 | case 'M': | |
259 | if (m == O_RDONLY) | |
260 | tif->tif_flags |= TIFF_MAPPED; | |
261 | break; | |
262 | case 'm': | |
263 | if (m == O_RDONLY) | |
264 | tif->tif_flags &= ~TIFF_MAPPED; | |
265 | break; | |
266 | case 'C': | |
267 | if (m == O_RDONLY) | |
268 | tif->tif_flags |= TIFF_STRIPCHOP; | |
269 | break; | |
270 | case 'c': | |
271 | if (m == O_RDONLY) | |
272 | tif->tif_flags &= ~TIFF_STRIPCHOP; | |
273 | break; | |
274 | } | |
275 | /* | |
276 | * Read in TIFF header. | |
277 | */ | |
278 | if (!ReadOK(tif, &tif->tif_header, sizeof (TIFFHeader))) { | |
279 | if (tif->tif_mode == O_RDONLY) { | |
280 | TIFFError(name, "Cannot read TIFF header"); | |
281 | goto bad; | |
282 | } | |
283 | /* | |
284 | * Setup header and write. | |
285 | */ | |
286 | tif->tif_header.tiff_magic = tif->tif_flags & TIFF_SWAB | |
287 | ? (bigendian ? TIFF_LITTLEENDIAN : TIFF_BIGENDIAN) | |
288 | : (bigendian ? TIFF_BIGENDIAN : TIFF_LITTLEENDIAN); | |
289 | tif->tif_header.tiff_version = TIFF_VERSION; | |
290 | if (tif->tif_flags & TIFF_SWAB) | |
291 | TIFFSwabShort(&tif->tif_header.tiff_version); | |
292 | tif->tif_header.tiff_diroff = 0; /* filled in later */ | |
293 | ||
294 | /* | |
295 | * This seek shouldn't be necessary, but I have had some | |
296 | * crazy problems with a failed fseek() on Solaris leaving | |
297 | * the current file pointer out of whack when an fwrite() | |
298 | * is done. | |
299 | */ | |
300 | TIFFSeekFile( tif, 0, SEEK_SET ); | |
301 | ||
302 | if (!WriteOK(tif, &tif->tif_header, sizeof (TIFFHeader))) { | |
303 | TIFFError(name, "Error writing TIFF header"); | |
304 | goto bad; | |
305 | } | |
306 | /* | |
307 | * Setup the byte order handling. | |
308 | */ | |
309 | TIFFInitOrder(tif, tif->tif_header.tiff_magic, bigendian); | |
310 | /* | |
311 | * Setup default directory. | |
312 | */ | |
313 | if (!TIFFDefaultDirectory(tif)) | |
314 | goto bad; | |
315 | tif->tif_diroff = 0; | |
316 | tif->tif_dirlist = NULL; | |
317 | tif->tif_dirnumber = 0; | |
318 | return (tif); | |
319 | } | |
320 | /* | |
321 | * Setup the byte order handling. | |
322 | */ | |
323 | if (tif->tif_header.tiff_magic != TIFF_BIGENDIAN && | |
324 | tif->tif_header.tiff_magic != TIFF_LITTLEENDIAN) { | |
325 | TIFFError(name, "Not a TIFF file, bad magic number %d (0x%x)", | |
326 | tif->tif_header.tiff_magic, | |
327 | tif->tif_header.tiff_magic); | |
328 | goto bad; | |
329 | } | |
330 | TIFFInitOrder(tif, tif->tif_header.tiff_magic, bigendian); | |
331 | /* | |
332 | * Swap header if required. | |
333 | */ | |
334 | if (tif->tif_flags & TIFF_SWAB) { | |
335 | TIFFSwabShort(&tif->tif_header.tiff_version); | |
336 | TIFFSwabLong(&tif->tif_header.tiff_diroff); | |
337 | } | |
338 | /* | |
339 | * Now check version (if needed, it's been byte-swapped). | |
340 | * Note that this isn't actually a version number, it's a | |
341 | * magic number that doesn't change (stupid). | |
342 | */ | |
343 | if (tif->tif_header.tiff_version != TIFF_VERSION) { | |
344 | TIFFError(name, | |
345 | "Not a TIFF file, bad version number %d (0x%x)", | |
346 | tif->tif_header.tiff_version, | |
347 | tif->tif_header.tiff_version); | |
348 | goto bad; | |
349 | } | |
350 | tif->tif_flags |= TIFF_MYBUFFER; | |
351 | tif->tif_rawcp = tif->tif_rawdata = 0; | |
352 | tif->tif_rawdatasize = 0; | |
353 | /* | |
354 | * Setup initial directory. | |
355 | */ | |
356 | switch (mode[0]) { | |
357 | case 'r': | |
358 | tif->tif_nextdiroff = tif->tif_header.tiff_diroff; | |
359 | /* | |
360 | * Try to use a memory-mapped file if the client | |
361 | * has not explicitly suppressed usage with the | |
362 | * 'm' flag in the open mode (see above). | |
363 | */ | |
364 | if ((tif->tif_flags & TIFF_MAPPED) && | |
365 | !TIFFMapFileContents(tif, (tdata_t*) &tif->tif_base, &tif->tif_size)) | |
366 | tif->tif_flags &= ~TIFF_MAPPED; | |
367 | if (TIFFReadDirectory(tif)) { | |
368 | tif->tif_rawcc = -1; | |
369 | tif->tif_flags |= TIFF_BUFFERSETUP; | |
370 | return (tif); | |
371 | } | |
372 | break; | |
373 | case 'a': | |
374 | /* | |
375 | * New directories are automatically append | |
376 | * to the end of the directory chain when they | |
377 | * are written out (see TIFFWriteDirectory). | |
378 | */ | |
379 | if (!TIFFDefaultDirectory(tif)) | |
380 | goto bad; | |
381 | return (tif); | |
382 | } | |
383 | bad: | |
384 | tif->tif_mode = O_RDONLY; /* XXX avoid flush */ | |
385 | TIFFClose(tif); | |
386 | return ((TIFF*)0); | |
387 | bad2: | |
388 | (void) (*closeproc)(clientdata); | |
389 | bad3: | |
390 | return ((TIFF*)0); | |
391 | } | |
392 | ||
393 | /* | |
394 | * Query functions to access private data. | |
395 | */ | |
396 | ||
397 | /* | |
398 | * Return open file's name. | |
399 | */ | |
400 | const char * | |
401 | TIFFFileName(TIFF* tif) | |
402 | { | |
403 | return (tif->tif_name); | |
404 | } | |
405 | ||
406 | /* | |
407 | * Return open file's I/O descriptor. | |
408 | */ | |
409 | int | |
410 | TIFFFileno(TIFF* tif) | |
411 | { | |
412 | return (tif->tif_fd); | |
413 | } | |
414 | ||
415 | /* | |
416 | * Return read/write mode. | |
417 | */ | |
418 | int | |
419 | TIFFGetMode(TIFF* tif) | |
420 | { | |
421 | return (tif->tif_mode); | |
422 | } | |
423 | ||
424 | /* | |
425 | * Return nonzero if file is organized in | |
426 | * tiles; zero if organized as strips. | |
427 | */ | |
428 | int | |
429 | TIFFIsTiled(TIFF* tif) | |
430 | { | |
431 | return (isTiled(tif)); | |
432 | } | |
433 | ||
434 | /* | |
435 | * Return current row being read/written. | |
436 | */ | |
437 | uint32 | |
438 | TIFFCurrentRow(TIFF* tif) | |
439 | { | |
440 | return (tif->tif_row); | |
441 | } | |
442 | ||
443 | /* | |
444 | * Return index of the current directory. | |
445 | */ | |
446 | tdir_t | |
447 | TIFFCurrentDirectory(TIFF* tif) | |
448 | { | |
449 | return (tif->tif_curdir); | |
450 | } | |
451 | ||
452 | /* | |
453 | * Return current strip. | |
454 | */ | |
455 | tstrip_t | |
456 | TIFFCurrentStrip(TIFF* tif) | |
457 | { | |
458 | return (tif->tif_curstrip); | |
459 | } | |
460 | ||
461 | /* | |
462 | * Return current tile. | |
463 | */ | |
464 | ttile_t | |
465 | TIFFCurrentTile(TIFF* tif) | |
466 | { | |
467 | return (tif->tif_curtile); | |
468 | } | |
469 | ||
470 | /* | |
471 | * Return nonzero if the file has byte-swapped data. | |
472 | */ | |
473 | int | |
474 | TIFFIsByteSwapped(TIFF* tif) | |
475 | { | |
476 | return ((tif->tif_flags & TIFF_SWAB) != 0); | |
477 | } | |
478 | ||
479 | /* | |
480 | * Return nonzero if the data is returned up-sampled. | |
481 | */ | |
482 | int | |
483 | TIFFIsUpSampled(TIFF* tif) | |
484 | { | |
485 | return (isUpSampled(tif)); | |
486 | } | |
487 | ||
488 | /* | |
489 | * Return nonzero if the data is returned in MSB-to-LSB bit order. | |
490 | */ | |
491 | int | |
492 | TIFFIsMSB2LSB(TIFF* tif) | |
493 | { | |
494 | return (isFillOrder(tif, FILLORDER_MSB2LSB)); | |
495 | } |