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