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