1 /* Id */
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 static const long typemask[13] = {
33 (long)0L, /* TIFF_NOTYPE */
34 (long)0x000000ffL, /* TIFF_BYTE */
35 (long)0xffffffffL, /* TIFF_ASCII */
36 (long)0x0000ffffL, /* TIFF_SHORT */
37 (long)0xffffffffL, /* TIFF_LONG */
38 (long)0xffffffffL, /* TIFF_RATIONAL */
39 (long)0x000000ffL, /* TIFF_SBYTE */
40 (long)0x000000ffL, /* TIFF_UNDEFINED */
41 (long)0x0000ffffL, /* TIFF_SSHORT */
42 (long)0xffffffffL, /* TIFF_SLONG */
43 (long)0xffffffffL, /* TIFF_SRATIONAL */
44 (long)0xffffffffL, /* TIFF_FLOAT */
45 (long)0xffffffffL, /* TIFF_DOUBLE */
46 };
47 static const int bigTypeshift[13] = {
48 0, /* TIFF_NOTYPE */
49 24, /* TIFF_BYTE */
50 0, /* TIFF_ASCII */
51 16, /* TIFF_SHORT */
52 0, /* TIFF_LONG */
53 0, /* TIFF_RATIONAL */
54 24, /* TIFF_SBYTE */
55 24, /* TIFF_UNDEFINED */
56 16, /* TIFF_SSHORT */
57 0, /* TIFF_SLONG */
58 0, /* TIFF_SRATIONAL */
59 0, /* TIFF_FLOAT */
60 0, /* TIFF_DOUBLE */
61 };
62 static const int litTypeshift[13] = {
63 0, /* TIFF_NOTYPE */
64 0, /* TIFF_BYTE */
65 0, /* TIFF_ASCII */
66 0, /* TIFF_SHORT */
67 0, /* TIFF_LONG */
68 0, /* TIFF_RATIONAL */
69 0, /* TIFF_SBYTE */
70 0, /* TIFF_UNDEFINED */
71 0, /* TIFF_SSHORT */
72 0, /* TIFF_SLONG */
73 0, /* TIFF_SRATIONAL */
74 0, /* TIFF_FLOAT */
75 0, /* TIFF_DOUBLE */
76 };
77
78 /*
79 * Dummy functions to fill the omitted client procedures.
80 */
81 static int
_tiffDummyMapProc(thandle_t fd,tdata_t * pbase,toff_t * psize)82 _tiffDummyMapProc(thandle_t fd, tdata_t* pbase, toff_t* psize)
83 {
84 (void) fd; (void) pbase; (void) psize;
85 return (0);
86 }
87
88 static void
_tiffDummyUnmapProc(thandle_t fd,tdata_t base,toff_t size)89 _tiffDummyUnmapProc(thandle_t fd, tdata_t base, toff_t size)
90 {
91 (void) fd; (void) base; (void) size;
92 }
93
94 /*
95 * Initialize the shift & mask tables, and the
96 * byte swapping state according to the file
97 * contents and the machine architecture.
98 */
99 static void
TIFFInitOrder(TIFF * tif,int magic)100 TIFFInitOrder(TIFF* tif, int magic)
101 {
102 tif->tif_typemask = typemask;
103 if (magic == TIFF_BIGENDIAN) {
104 tif->tif_typeshift = bigTypeshift;
105 #ifndef WORDS_BIGENDIAN
106 tif->tif_flags |= TIFF_SWAB;
107 #endif
108 } else {
109 tif->tif_typeshift = litTypeshift;
110 #ifdef WORDS_BIGENDIAN
111 tif->tif_flags |= TIFF_SWAB;
112 #endif
113 }
114 }
115
116 int
_TIFFgetMode(const char * mode,const char * module)117 _TIFFgetMode(const char* mode, const char* module)
118 {
119 int m = -1;
120
121 switch (mode[0]) {
122 case 'r':
123 m = O_RDONLY;
124 if (mode[1] == '+')
125 m = O_RDWR;
126 break;
127 case 'w':
128 case 'a':
129 m = O_RDWR|O_CREAT;
130 if (mode[0] == 'w')
131 m |= O_TRUNC;
132 break;
133 default:
134 TIFFErrorExt(0, module, "\"%s\": Bad mode", mode);
135 break;
136 }
137 return (m);
138 }
139
140 TIFF*
141 TEXPORT
TIFFClientOpen(const char * name,const char * mode,thandle_t clientdata,TIFFReadWriteProc readproc,TIFFReadWriteProc writeproc,TIFFSeekProc seekproc,TIFFCloseProc closeproc,TIFFSizeProc sizeproc,TIFFMapFileProc mapproc,TIFFUnmapFileProc unmapproc)142 TIFFClientOpen(
143 const char* name, const char* mode,
144 thandle_t clientdata,
145 TIFFReadWriteProc readproc,
146 TIFFReadWriteProc writeproc,
147 TIFFSeekProc seekproc,
148 TIFFCloseProc closeproc,
149 TIFFSizeProc sizeproc,
150 TIFFMapFileProc mapproc,
151 TIFFUnmapFileProc unmapproc
152 )
153 {
154 static const char module[] = "TIFFClientOpen";
155 TIFF *tif;
156 int m;
157 const char* cp;
158
159 m = _TIFFgetMode(mode, module);
160 if (m == -1)
161 goto bad2;
162 tif = (TIFF *)_TIFFmalloc(sizeof (TIFF) + strlen(name) + 1);
163 if (tif == NULL) {
164 TIFFErrorExt(clientdata, module, "%s: Out of memory (TIFF structure)", name);
165 goto bad2;
166 }
167 _TIFFmemset(tif, 0, sizeof (*tif));
168 tif->tif_name = (char *)tif + sizeof (TIFF);
169 strcpy(tif->tif_name, name);
170 tif->tif_mode = m &~ (O_CREAT|O_TRUNC);
171 tif->tif_curdir = (tdir_t) -1; /* non-existent directory */
172 tif->tif_curoff = 0;
173 tif->tif_curstrip = (tstrip_t) -1; /* invalid strip */
174 tif->tif_row = (uint32) -1; /* read/write pre-increment */
175 tif->tif_clientdata = clientdata;
176 if (!readproc || !writeproc || !seekproc || !closeproc || !sizeproc) {
177 TIFFErrorExt(clientdata, module,
178 "One of the client procedures is NULL pointer.");
179 goto bad2;
180 }
181 tif->tif_readproc = readproc;
182 tif->tif_writeproc = writeproc;
183 tif->tif_seekproc = seekproc;
184 tif->tif_closeproc = closeproc;
185 tif->tif_sizeproc = sizeproc;
186 if (mapproc)
187 tif->tif_mapproc = mapproc;
188 else
189 tif->tif_mapproc = _tiffDummyMapProc;
190 if (unmapproc)
191 tif->tif_unmapproc = unmapproc;
192 else
193 tif->tif_unmapproc = _tiffDummyUnmapProc;
194 _TIFFSetDefaultCompressionState(tif); /* setup default state */
195 /*
196 * Default is to return data MSB2LSB and enable the
197 * use of memory-mapped files and strip chopping when
198 * a file is opened read-only.
199 */
200 tif->tif_flags = FILLORDER_MSB2LSB;
201 if (m == O_RDONLY )
202 tif->tif_flags |= TIFF_MAPPED;
203
204 #ifdef STRIPCHOP_DEFAULT
205 if (m == O_RDONLY || m == O_RDWR)
206 tif->tif_flags |= STRIPCHOP_DEFAULT;
207 #endif
208
209 /*
210 * Process library-specific flags in the open mode string.
211 * The following flags may be used to control intrinsic library
212 * behaviour that may or may not be desirable (usually for
213 * compatibility with some application that claims to support
214 * TIFF but only supports some braindead idea of what the
215 * vendor thinks TIFF is):
216 *
217 * 'l' use little-endian byte order for creating a file
218 * 'b' use big-endian byte order for creating a file
219 * 'L' read/write information using LSB2MSB bit order
220 * 'B' read/write information using MSB2LSB bit order
221 * 'H' read/write information using host bit order
222 * 'M' enable use of memory-mapped files when supported
223 * 'm' disable use of memory-mapped files
224 * 'C' enable strip chopping support when reading
225 * 'c' disable strip chopping support
226 * 'h' read TIFF header only, do not load the first IFD
227 *
228 * The use of the 'l' and 'b' flags is strongly discouraged.
229 * These flags are provided solely because numerous vendors,
230 * typically on the PC, do not correctly support TIFF; they
231 * only support the Intel little-endian byte order. This
232 * support is not configured by default because it supports
233 * the violation of the TIFF spec that says that readers *MUST*
234 * support both byte orders. It is strongly recommended that
235 * you not use this feature except to deal with busted apps
236 * that write invalid TIFF. And even in those cases you should
237 * bang on the vendors to fix their software.
238 *
239 * The 'L', 'B', and 'H' flags are intended for applications
240 * that can optimize operations on data by using a particular
241 * bit order. By default the library returns data in MSB2LSB
242 * bit order for compatibiltiy with older versions of this
243 * library. Returning data in the bit order of the native cpu
244 * makes the most sense but also requires applications to check
245 * the value of the FillOrder tag; something they probably do
246 * not do right now.
247 *
248 * The 'M' and 'm' flags are provided because some virtual memory
249 * systems exhibit poor behaviour when large images are mapped.
250 * These options permit clients to control the use of memory-mapped
251 * files on a per-file basis.
252 *
253 * The 'C' and 'c' flags are provided because the library support
254 * for chopping up large strips into multiple smaller strips is not
255 * application-transparent and as such can cause problems. The 'c'
256 * option permits applications that only want to look at the tags,
257 * for example, to get the unadulterated TIFF tag information.
258 */
259 for (cp = mode; *cp; cp++)
260 switch (*cp) {
261 case 'b':
262 #ifndef WORDS_BIGENDIAN
263 if (m&O_CREAT)
264 tif->tif_flags |= TIFF_SWAB;
265 #endif
266 break;
267 case 'l':
268 #ifdef WORDS_BIGENDIAN
269 if ((m&O_CREAT))
270 tif->tif_flags |= TIFF_SWAB;
271 #endif
272 break;
273 case 'B':
274 tif->tif_flags = (tif->tif_flags &~ TIFF_FILLORDER) |
275 FILLORDER_MSB2LSB;
276 break;
277 case 'L':
278 tif->tif_flags = (tif->tif_flags &~ TIFF_FILLORDER) |
279 FILLORDER_LSB2MSB;
280 break;
281 case 'H':
282 tif->tif_flags = (tif->tif_flags &~ TIFF_FILLORDER) |
283 HOST_FILLORDER;
284 break;
285 case 'M':
286 if (m == O_RDONLY)
287 tif->tif_flags |= TIFF_MAPPED;
288 break;
289 case 'm':
290 if (m == O_RDONLY)
291 tif->tif_flags &= ~TIFF_MAPPED;
292 break;
293 case 'C':
294 if (m == O_RDONLY)
295 tif->tif_flags |= TIFF_STRIPCHOP;
296 break;
297 case 'c':
298 if (m == O_RDONLY)
299 tif->tif_flags &= ~TIFF_STRIPCHOP;
300 break;
301 case 'h':
302 tif->tif_flags |= TIFF_HEADERONLY;
303 break;
304 }
305 /*
306 * Read in TIFF header.
307 */
308 if (tif->tif_mode & O_TRUNC ||
309 !ReadOK(tif, &tif->tif_header, sizeof (TIFFHeader))) {
310 if (tif->tif_mode == O_RDONLY) {
311 TIFFErrorExt(tif->tif_clientdata, name, "Cannot read TIFF header");
312 goto bad;
313 }
314 /*
315 * Setup header and write.
316 */
317 #ifdef WORDS_BIGENDIAN
318 tif->tif_header.tiff_magic = tif->tif_flags & TIFF_SWAB
319 ? TIFF_LITTLEENDIAN : TIFF_BIGENDIAN;
320 #else
321 tif->tif_header.tiff_magic = tif->tif_flags & TIFF_SWAB
322 ? TIFF_BIGENDIAN : TIFF_LITTLEENDIAN;
323 #endif
324 tif->tif_header.tiff_version = TIFF_VERSION;
325 if (tif->tif_flags & TIFF_SWAB)
326 TIFFSwabShort(&tif->tif_header.tiff_version);
327 tif->tif_header.tiff_diroff = 0; /* filled in later */
328
329
330 /*
331 * The doc for "fopen" for some STD_C_LIBs says that if you
332 * open a file for modify ("+"), then you must fseek (or
333 * fflush?) between any freads and fwrites. This is not
334 * necessary on most systems, but has been shown to be needed
335 * on Solaris.
336 */
337 TIFFSeekFile( tif, 0, SEEK_SET );
338
339 if (!WriteOK(tif, &tif->tif_header, sizeof (TIFFHeader))) {
340 TIFFErrorExt(tif->tif_clientdata, name, "Error writing TIFF header");
341 goto bad;
342 }
343 /*
344 * Setup the byte order handling.
345 */
346 TIFFInitOrder(tif, tif->tif_header.tiff_magic);
347 /*
348 * Setup default directory.
349 */
350 if (!TIFFDefaultDirectory(tif))
351 goto bad;
352 tif->tif_diroff = 0;
353 tif->tif_dirlist = NULL;
354 tif->tif_dirnumber = 0;
355 return (tif);
356 }
357 /*
358 * Setup the byte order handling.
359 */
360 if (tif->tif_header.tiff_magic != TIFF_BIGENDIAN &&
361 tif->tif_header.tiff_magic != TIFF_LITTLEENDIAN
362 #if MDI_SUPPORT
363 &&
364 #if HOST_BIGENDIAN
365 tif->tif_header.tiff_magic != MDI_BIGENDIAN
366 #else
367 tif->tif_header.tiff_magic != MDI_LITTLEENDIAN
368 #endif
369 ) {
370 TIFFErrorExt(tif->tif_clientdata, name, "Not a TIFF or MDI file, bad magic number %d (0x%x)",
371 #else
372 ) {
373 TIFFErrorExt(tif->tif_clientdata, name, "Not a TIFF file, bad magic number %d (0x%x)",
374 #endif
375 tif->tif_header.tiff_magic,
376 tif->tif_header.tiff_magic);
377 goto bad;
378 }
379 TIFFInitOrder(tif, tif->tif_header.tiff_magic);
380 /*
381 * Swap header if required.
382 */
383 if (tif->tif_flags & TIFF_SWAB) {
384 TIFFSwabShort(&tif->tif_header.tiff_version);
385 TIFFSwabLong(&tif->tif_header.tiff_diroff);
386 }
387 /*
388 * Now check version (if needed, it's been byte-swapped).
389 * Note that this isn't actually a version number, it's a
390 * magic number that doesn't change (stupid).
391 */
392 if (tif->tif_header.tiff_version == TIFF_BIGTIFF_VERSION) {
393 TIFFErrorExt(tif->tif_clientdata, name,
394 "This is a BigTIFF file. This format not supported\n"
395 "by this version of libtiff." );
396 goto bad;
397 }
398 if (tif->tif_header.tiff_version != TIFF_VERSION) {
399 TIFFErrorExt(tif->tif_clientdata, name,
400 "Not a TIFF file, bad version number %d (0x%x)",
401 tif->tif_header.tiff_version,
402 tif->tif_header.tiff_version);
403 goto bad;
404 }
405 tif->tif_flags |= TIFF_MYBUFFER;
406 tif->tif_rawcp = tif->tif_rawdata = 0;
407 tif->tif_rawdatasize = 0;
408
409 /*
410 * Sometimes we do not want to read the first directory (for example,
411 * it may be broken) and want to proceed to other directories. I this
412 * case we use the TIFF_HEADERONLY flag to open file and return
413 * immediately after reading TIFF header.
414 */
415 if (tif->tif_flags & TIFF_HEADERONLY)
416 return (tif);
417
418 /*
419 * Setup initial directory.
420 */
421 switch (mode[0]) {
422 case 'r':
423 tif->tif_nextdiroff = tif->tif_header.tiff_diroff;
424 /*
425 * Try to use a memory-mapped file if the client
426 * has not explicitly suppressed usage with the
427 * 'm' flag in the open mode (see above).
428 */
429 if ((tif->tif_flags & TIFF_MAPPED) &&
430 !TIFFMapFileContents(tif, (tdata_t*) &tif->tif_base, &tif->tif_size))
431 tif->tif_flags &= ~TIFF_MAPPED;
432 if (TIFFReadDirectory(tif)) {
433 tif->tif_rawcc = -1;
434 tif->tif_flags |= TIFF_BUFFERSETUP;
435 return (tif);
436 }
437 break;
438 case 'a':
439 /*
440 * New directories are automatically append
441 * to the end of the directory chain when they
442 * are written out (see TIFFWriteDirectory).
443 */
444 if (!TIFFDefaultDirectory(tif))
445 goto bad;
446 return (tif);
447 }
448 bad:
449 tif->tif_mode = O_RDONLY; /* XXX avoid flush */
450 TIFFCleanup(tif);
451 bad2:
452 return ((TIFF*)0);
453 }
454
455 /*
456 * Query functions to access private data.
457 */
458
459 /*
460 * Return open file's name.
461 */
462 const char *
463 TIFFFileName(TIFF* tif)
464 {
465 return (tif->tif_name);
466 }
467
468 /*
469 * Set the file name.
470 */
471 const char *
472 TIFFSetFileName(TIFF* tif, const char *name)
473 {
474 const char* old_name = tif->tif_name;
475 tif->tif_name = (char *)name;
476 return (old_name);
477 }
478
479 /*
480 * Return open file's I/O descriptor.
481 */
482 int
483 TIFFFileno(TIFF* tif)
484 {
485 return (tif->tif_fd);
486 }
487
488 /*
489 * Set open file's I/O descriptor, and return previous value.
490 */
491 int
492 TIFFSetFileno(TIFF* tif, int fd)
493 {
494 int old_fd = tif->tif_fd;
495 tif->tif_fd = fd;
496 return old_fd;
497 }
498
499 /*
500 * Return open file's clientdata.
501 */
502 thandle_t
503 TIFFClientdata(TIFF* tif)
504 {
505 return (tif->tif_clientdata);
506 }
507
508 /*
509 * Set open file's clientdata, and return previous value.
510 */
511 thandle_t
512 TIFFSetClientdata(TIFF* tif, thandle_t newvalue)
513 {
514 thandle_t m = tif->tif_clientdata;
515 tif->tif_clientdata = newvalue;
516 return m;
517 }
518
519 /*
520 * Return read/write mode.
521 */
522 int
523 TIFFGetMode(TIFF* tif)
524 {
525 return (tif->tif_mode);
526 }
527
528 /*
529 * Return read/write mode.
530 */
531 int
532 TIFFSetMode(TIFF* tif, int mode)
533 {
534 int old_mode = tif->tif_mode;
535 tif->tif_mode = mode;
536 return (old_mode);
537 }
538
539 /*
540 * Return nonzero if file is organized in
541 * tiles; zero if organized as strips.
542 */
543 int
544 TEXPORT
545 TIFFIsTiled(TIFF* tif)
546 {
547 return (isTiled(tif));
548 }
549
550 /*
551 * Return current row being read/written.
552 */
553 uint32
554 TIFFCurrentRow(TIFF* tif)
555 {
556 return (tif->tif_row);
557 }
558
559 /*
560 * Return index of the current directory.
561 */
562 tdir_t
563 TIFFCurrentDirectory(TIFF* tif)
564 {
565 return (tif->tif_curdir);
566 }
567
568 /*
569 * Return current strip.
570 */
571 tstrip_t
572 TIFFCurrentStrip(TIFF* tif)
573 {
574 return (tif->tif_curstrip);
575 }
576
577 /*
578 * Return current tile.
579 */
580 ttile_t
581 TIFFCurrentTile(TIFF* tif)
582 {
583 return (tif->tif_curtile);
584 }
585
586 /*
587 * Return nonzero if the file has byte-swapped data.
588 */
589 int
590 TIFFIsByteSwapped(TIFF* tif)
591 {
592 return ((tif->tif_flags & TIFF_SWAB) != 0);
593 }
594
595 /*
596 * Return nonzero if the data is returned up-sampled.
597 */
598 int
599 TIFFIsUpSampled(TIFF* tif)
600 {
601 return (isUpSampled(tif));
602 }
603
604 /*
605 * Return nonzero if the data is returned in MSB-to-LSB bit order.
606 */
607 int
608 TIFFIsMSB2LSB(TIFF* tif)
609 {
610 return (isFillOrder(tif, FILLORDER_MSB2LSB));
611 }
612
613 /*
614 * Return nonzero if given file was written in big-endian order.
615 */
616 int
617 TIFFIsBigEndian(TIFF* tif)
618 {
619 return (tif->tif_header.tiff_magic == TIFF_BIGENDIAN);
620 }
621
622 /*
623 * Return pointer to file read method.
624 */
625 TIFFReadWriteProc
626 TIFFGetReadProc(TIFF* tif)
627 {
628 return (tif->tif_readproc);
629 }
630
631 /*
632 * Return pointer to file write method.
633 */
634 TIFFReadWriteProc
635 TIFFGetWriteProc(TIFF* tif)
636 {
637 return (tif->tif_writeproc);
638 }
639
640 /*
641 * Return pointer to file seek method.
642 */
643 TIFFSeekProc
644 TIFFGetSeekProc(TIFF* tif)
645 {
646 return (tif->tif_seekproc);
647 }
648
649 /*
650 * Return pointer to file close method.
651 */
652 TIFFCloseProc
653 TIFFGetCloseProc(TIFF* tif)
654 {
655 return (tif->tif_closeproc);
656 }
657
658 /*
659 * Return pointer to file size requesting method.
660 */
661 TIFFSizeProc
662 TIFFGetSizeProc(TIFF* tif)
663 {
664 return (tif->tif_sizeproc);
665 }
666
667 /*
668 * Return pointer to memory mapping method.
669 */
670 TIFFMapFileProc
671 TIFFGetMapFileProc(TIFF* tif)
672 {
673 return (tif->tif_mapproc);
674 }
675
676 /*
677 * Return pointer to memory unmapping method.
678 */
679 TIFFUnmapFileProc
680 TIFFGetUnmapFileProc(TIFF* tif)
681 {
682 return (tif->tif_unmapproc);
683 }
684
685 /* vim: set ts=8 sts=8 sw=8 noet: */
686