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