source: trunk/third/tiff/libtiff/tif_open.c @ 18174

Revision 18174, 13.1 KB checked in by ghudson, 22 years ago (diff)
This commit was generated by cvs2svn to compensate for changes in r18173, which included commits to RCS files with non-trunk default branches.
Line 
1/* $Header: /afs/dev.mit.edu/source/repository/third/tiff/libtiff/tif_open.c,v 1.1.1.1 2002-12-26 02:39:04 ghudson 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
32void _TIFFSetDefaultCompressionState(TIFF* tif);
33
34static const long typemask[13] = {
35        0L,             /* TIFF_NOTYPE */
36        0x000000ffL,    /* TIFF_BYTE */
37        0xffffffffL,    /* TIFF_ASCII */
38        0x0000ffffL,    /* TIFF_SHORT */
39        0xffffffffL,    /* TIFF_LONG */
40        0xffffffffL,    /* TIFF_RATIONAL */
41        0x000000ffL,    /* TIFF_SBYTE */
42        0x000000ffL,    /* TIFF_UNDEFINED */
43        0x0000ffffL,    /* TIFF_SSHORT */
44        0xffffffffL,    /* TIFF_SLONG */
45        0xffffffffL,    /* TIFF_SRATIONAL */
46        0xffffffffL,    /* TIFF_FLOAT */
47        0xffffffffL,    /* TIFF_DOUBLE */
48};
49static 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};
64static 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 */
85static void
86TIFFInitOrder(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
100int
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
124TIFF*
125TIFFClientOpen(
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        tif->tif_readproc = readproc;
160        tif->tif_writeproc = writeproc;
161        tif->tif_seekproc = seekproc;
162        tif->tif_closeproc = closeproc;
163        tif->tif_sizeproc = sizeproc;
164        tif->tif_mapproc = mapproc;
165        tif->tif_unmapproc = unmapproc;
166        _TIFFSetDefaultCompressionState(tif);   /* setup default state */
167        /*
168         * Default is to return data MSB2LSB and enable the
169         * use of memory-mapped files and strip chopping when
170         * a file is opened read-only.
171         */
172        tif->tif_flags = FILLORDER_MSB2LSB;
173        if (m == O_RDONLY )
174            tif->tif_flags |= TIFF_MAPPED;
175
176#ifdef STRIPCHOP_DEFAULT
177        if (m == O_RDONLY || m == O_RDWR)
178                tif->tif_flags |= STRIPCHOP_DEFAULT;
179#endif
180
181        { union { int32 i; char c[4]; } u; u.i = 1; bigendian = u.c[0] == 0; }
182        /*
183         * Process library-specific flags in the open mode string.
184         * The following flags may be used to control intrinsic library
185         * behaviour that may or may not be desirable (usually for
186         * compatibility with some application that claims to support
187         * TIFF but only supports some braindead idea of what the
188         * vendor thinks TIFF is):
189         *
190         * 'l'          use little-endian byte order for creating a file
191         * 'b'          use big-endian byte order for creating a file
192         * 'L'          read/write information using LSB2MSB bit order
193         * 'B'          read/write information using MSB2LSB bit order
194         * 'H'          read/write information using host bit order
195         * 'M'          enable use of memory-mapped files when supported
196         * 'm'          disable use of memory-mapped files
197         * 'C'          enable strip chopping support when reading
198         * 'c'          disable strip chopping support
199         *
200         * The use of the 'l' and 'b' flags is strongly discouraged.
201         * These flags are provided solely because numerous vendors,
202         * typically on the PC, do not correctly support TIFF; they
203         * only support the Intel little-endian byte order.  This
204         * support is not configured by default because it supports
205         * the violation of the TIFF spec that says that readers *MUST*
206         * support both byte orders.  It is strongly recommended that
207         * you not use this feature except to deal with busted apps
208         * that write invalid TIFF.  And even in those cases you should
209         * bang on the vendors to fix their software.
210         *
211         * The 'L', 'B', and 'H' flags are intended for applications
212         * that can optimize operations on data by using a particular
213         * bit order.  By default the library returns data in MSB2LSB
214         * bit order for compatibiltiy with older versions of this
215         * library.  Returning data in the bit order of the native cpu
216         * makes the most sense but also requires applications to check
217         * the value of the FillOrder tag; something they probabyl do
218         * not do right now.
219         *
220         * The 'M' and 'm' flags are provided because some virtual memory
221         * systems exhibit poor behaviour when large images are mapped.
222         * These options permit clients to control the use of memory-mapped
223         * files on a per-file basis.
224         *
225         * The 'C' and 'c' flags are provided because the library support
226         * for chopping up large strips into multiple smaller strips is not
227         * application-transparent and as such can cause problems.  The 'c'
228         * option permits applications that only want to look at the tags,
229         * for example, to get the unadulterated TIFF tag information.
230         */
231        for (cp = mode; *cp; cp++)
232                switch (*cp) {
233                case 'b':
234                        if ((m&O_CREAT) && !bigendian)
235                                tif->tif_flags |= TIFF_SWAB;
236                        break;
237                case 'l':
238                        if ((m&O_CREAT) && bigendian)
239                                tif->tif_flags |= TIFF_SWAB;
240                        break;
241                case 'B':
242                        tif->tif_flags = (tif->tif_flags &~ TIFF_FILLORDER) |
243                            FILLORDER_MSB2LSB;
244                        break;
245                case 'L':
246                        tif->tif_flags = (tif->tif_flags &~ TIFF_FILLORDER) |
247                            FILLORDER_LSB2MSB;
248                        break;
249                case 'H':
250                        tif->tif_flags = (tif->tif_flags &~ TIFF_FILLORDER) |
251                            HOST_FILLORDER;
252                        break;
253                case 'M':
254                        if (m == O_RDONLY)
255                                tif->tif_flags |= TIFF_MAPPED;
256                        break;
257                case 'm':
258                        if (m == O_RDONLY)
259                                tif->tif_flags &= ~TIFF_MAPPED;
260                        break;
261                case 'C':
262                        if (m == O_RDONLY)
263                                tif->tif_flags |= TIFF_STRIPCHOP;
264                        break;
265                case 'c':
266                        if (m == O_RDONLY)
267                                tif->tif_flags &= ~TIFF_STRIPCHOP;
268                        break;
269                }
270        /*
271         * Read in TIFF header.
272         */
273        if (!ReadOK(tif, &tif->tif_header, sizeof (TIFFHeader))) {
274                if (tif->tif_mode == O_RDONLY) {
275                        TIFFError(name, "Cannot read TIFF header");
276                        goto bad;
277                }
278                /*
279                 * Setup header and write.
280                 */
281                tif->tif_header.tiff_magic = tif->tif_flags & TIFF_SWAB
282                    ? (bigendian ? TIFF_LITTLEENDIAN : TIFF_BIGENDIAN)
283                    : (bigendian ? TIFF_BIGENDIAN : TIFF_LITTLEENDIAN);
284                tif->tif_header.tiff_version = TIFF_VERSION;
285                if (tif->tif_flags & TIFF_SWAB)
286                        TIFFSwabShort(&tif->tif_header.tiff_version);
287                tif->tif_header.tiff_diroff = 0;        /* filled in later */
288
289                /*
290                 * This seek shouldn't be necessary, but I have had some
291                 * crazy problems with a failed fseek() on Solaris leaving
292                 * the current file pointer out of whack when an fwrite()
293                 * is done.
294                 */
295                TIFFSeekFile( tif, 0, SEEK_SET );
296
297                if (!WriteOK(tif, &tif->tif_header, sizeof (TIFFHeader))) {
298                        TIFFError(name, "Error writing TIFF header");
299                        goto bad;
300                }
301                /*
302                 * Setup the byte order handling.
303                 */
304                TIFFInitOrder(tif, tif->tif_header.tiff_magic, bigendian);
305                /*
306                 * Setup default directory.
307                 */
308                if (!TIFFDefaultDirectory(tif))
309                        goto bad;
310                tif->tif_diroff = 0;
311                return (tif);
312        }
313        /*
314         * Setup the byte order handling.
315         */
316        if (tif->tif_header.tiff_magic != TIFF_BIGENDIAN &&
317            tif->tif_header.tiff_magic != TIFF_LITTLEENDIAN) {
318                TIFFError(name,  "Not a TIFF file, bad magic number %d (0x%x)",
319                    tif->tif_header.tiff_magic,
320                    tif->tif_header.tiff_magic);
321                goto bad;
322        }
323        TIFFInitOrder(tif, tif->tif_header.tiff_magic, bigendian);
324        /*
325         * Swap header if required.
326         */
327        if (tif->tif_flags & TIFF_SWAB) {
328                TIFFSwabShort(&tif->tif_header.tiff_version);
329                TIFFSwabLong(&tif->tif_header.tiff_diroff);
330        }
331        /*
332         * Now check version (if needed, it's been byte-swapped).
333         * Note that this isn't actually a version number, it's a
334         * magic number that doesn't change (stupid).
335         */
336        if (tif->tif_header.tiff_version != TIFF_VERSION) {
337                TIFFError(name,
338                    "Not a TIFF file, bad version number %d (0x%x)",
339                    tif->tif_header.tiff_version,
340                    tif->tif_header.tiff_version);
341                goto bad;
342        }
343        tif->tif_flags |= TIFF_MYBUFFER;
344        tif->tif_rawcp = tif->tif_rawdata = 0;
345        tif->tif_rawdatasize = 0;
346        /*
347         * Setup initial directory.
348         */
349        switch (mode[0]) {
350        case 'r':
351                tif->tif_nextdiroff = tif->tif_header.tiff_diroff;
352                /*
353                 * Try to use a memory-mapped file if the client
354                 * has not explicitly suppressed usage with the
355                 * 'm' flag in the open mode (see above).
356                 */
357                if ((tif->tif_flags & TIFF_MAPPED) &&
358        !TIFFMapFileContents(tif, (tdata_t*) &tif->tif_base, &tif->tif_size))
359                        tif->tif_flags &= ~TIFF_MAPPED;
360                if (TIFFReadDirectory(tif)) {
361                        if( m != O_RDONLY
362                          && tif->tif_dir.td_compression != COMPRESSION_NONE )
363                        {
364                            TIFFError( name,
365                                       "Can't open a compressed TIFF file"
366                                       " with compression for update." );
367                            goto bad;
368                        }
369                        tif->tif_rawcc = -1;
370                        tif->tif_flags |= TIFF_BUFFERSETUP;
371                        return (tif);
372                }
373                break;
374        case 'a':
375                /*
376                 * New directories are automatically append
377                 * to the end of the directory chain when they
378                 * are written out (see TIFFWriteDirectory).
379                 */
380                if (!TIFFDefaultDirectory(tif))
381                        goto bad;
382                return (tif);
383        }
384bad:
385        tif->tif_mode = O_RDONLY;       /* XXX avoid flush */
386        TIFFClose(tif);
387        return ((TIFF*)0);
388bad2:
389        (void) (*closeproc)(clientdata);
390        return ((TIFF*)0);
391}
392
393/*
394 * Query functions to access private data.
395 */
396
397/*
398 * Return open file's name.
399 */
400const char *
401TIFFFileName(TIFF* tif)
402{
403        return (tif->tif_name);
404}
405
406/*
407 * Return open file's I/O descriptor.
408 */
409int
410TIFFFileno(TIFF* tif)
411{
412        return (tif->tif_fd);
413}
414
415/*
416 * Return read/write mode.
417 */
418int
419TIFFGetMode(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 */
428int
429TIFFIsTiled(TIFF* tif)
430{
431        return (isTiled(tif));
432}
433
434/*
435 * Return current row being read/written.
436 */
437uint32
438TIFFCurrentRow(TIFF* tif)
439{
440        return (tif->tif_row);
441}
442
443/*
444 * Return index of the current directory.
445 */
446tdir_t
447TIFFCurrentDirectory(TIFF* tif)
448{
449        return (tif->tif_curdir);
450}
451
452/*
453 * Return current strip.
454 */
455tstrip_t
456TIFFCurrentStrip(TIFF* tif)
457{
458        return (tif->tif_curstrip);
459}
460
461/*
462 * Return current tile.
463 */
464ttile_t
465TIFFCurrentTile(TIFF* tif)
466{
467        return (tif->tif_curtile);
468}
469
470/*
471 * Return nonzero if the file has byte-swapped data.
472 */
473int
474TIFFIsByteSwapped(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 */
482int
483TIFFIsUpSampled(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 */
491int
492TIFFIsMSB2LSB(TIFF* tif)
493{
494        return (isFillOrder(tif, FILLORDER_MSB2LSB));
495}
Note: See TracBrowser for help on using the repository browser.