home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / wxos2240.zip / wxWindows-2.4.0 / src / tiff / tif_open.c < prev    next >
C/C++ Source or Header  |  2002-11-10  |  13KB  |  478 lines

  1. /* $Header: /pack/cvsroots/wxwindows/wxWindows/src/tiff/tif_open.c,v 1.2.6.1 2002/11/10 13:13:57 JS 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 LINKAGEMODE _TIFFSetDefaultCompressionState(TIFF* tif);
  33.  
  34. static 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. };
  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.  * Initialize the shift & mask tables, and the
  82.  * byte swapping state according to the file
  83.  * contents and the machine architecture.
  84.  */
  85. static void
  86. TIFFInitOrder(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.  
  100. int
  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.  
  124. TIFF*
  125. TIFFClientOpen(
  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. #ifdef STRIPCHOP_DEFAULT
  175.         tif->tif_flags |= TIFF_MAPPED|STRIPCHOP_DEFAULT;
  176. #else
  177.         tif->tif_flags |= TIFF_MAPPED;
  178. #endif
  179.  
  180.     { union { int32 i; char c[4]; } u; u.i = 1; bigendian = u.c[0] == 0; }
  181.     /*
  182.      * Process library-specific flags in the open mode string.
  183.      * The following flags may be used to control intrinsic library
  184.      * behaviour that may or may not be desirable (usually for
  185.      * compatibility with some application that claims to support
  186.      * TIFF but only supports some braindead idea of what the
  187.      * vendor thinks TIFF is):
  188.      *
  189.      * 'l'        use little-endian byte order for creating a file
  190.      * 'b'        use big-endian byte order for creating a file
  191.      * 'L'        read/write information using LSB2MSB bit order
  192.      * 'B'        read/write information using MSB2LSB bit order
  193.      * 'H'        read/write information using host bit order
  194.      * 'M'        enable use of memory-mapped files when supported
  195.      * 'm'        disable use of memory-mapped files
  196.      * 'C'        enable strip chopping support when reading
  197.      * 'c'        disable strip chopping support
  198.      *
  199.      * The use of the 'l' and 'b' flags is strongly discouraged.
  200.      * These flags are provided solely because numerous vendors,
  201.      * typically on the PC, do not correctly support TIFF; they
  202.      * only support the Intel little-endian byte order.  This
  203.      * support is not configured by default because it supports
  204.      * the violation of the TIFF spec that says that readers *MUST*
  205.      * support both byte orders.  It is strongly recommended that
  206.      * you not use this feature except to deal with busted apps
  207.      * that write invalid TIFF.  And even in those cases you should
  208.      * bang on the vendors to fix their software.
  209.      *
  210.      * The 'L', 'B', and 'H' flags are intended for applications
  211.      * that can optimize operations on data by using a particular
  212.      * bit order.  By default the library returns data in MSB2LSB
  213.      * bit order for compatibiltiy with older versions of this
  214.      * library.  Returning data in the bit order of the native cpu
  215.      * makes the most sense but also requires applications to check
  216.      * the value of the FillOrder tag; something they probabyl do
  217.      * not do right now.
  218.      *
  219.      * The 'M' and 'm' flags are provided because some virtual memory
  220.      * systems exhibit poor behaviour when large images are mapped.
  221.      * These options permit clients to control the use of memory-mapped
  222.      * files on a per-file basis.
  223.      *
  224.      * The 'C' and 'c' flags are provided because the library support
  225.      * for chopping up large strips into multiple smaller strips is not
  226.      * application-transparent and as such can cause problems.  The 'c'
  227.      * option permits applications that only want to look at the tags,
  228.      * for example, to get the unadulterated TIFF tag information.
  229.      */
  230.     for (cp = mode; *cp; cp++)
  231.         switch (*cp) {
  232.         case 'b':
  233.             if ((m&O_CREAT) && !bigendian)
  234.                 tif->tif_flags |= TIFF_SWAB;
  235.             break;
  236.         case 'l':
  237.             if ((m&O_CREAT) && bigendian)
  238.                 tif->tif_flags |= TIFF_SWAB;
  239.             break;
  240.         case 'B':
  241.             tif->tif_flags = (tif->tif_flags &~ TIFF_FILLORDER) |
  242.                 FILLORDER_MSB2LSB;
  243.             break;
  244.         case 'L':
  245.             tif->tif_flags = (tif->tif_flags &~ TIFF_FILLORDER) |
  246.                 FILLORDER_LSB2MSB;
  247.             break;
  248.         case 'H':
  249.             tif->tif_flags = (tif->tif_flags &~ TIFF_FILLORDER) |
  250.                 HOST_FILLORDER;
  251.             break;
  252.         case 'M':
  253.             if (m == O_RDONLY)
  254.                 tif->tif_flags |= TIFF_MAPPED;
  255.             break;
  256.         case 'm':
  257.             if (m == O_RDONLY)
  258.                 tif->tif_flags &= ~TIFF_MAPPED;
  259.             break;
  260.         case 'C':
  261.             if (m == O_RDONLY)
  262.                 tif->tif_flags |= TIFF_STRIPCHOP;
  263.             break;
  264.         case 'c':
  265.             if (m == O_RDONLY)
  266.                 tif->tif_flags &= ~TIFF_STRIPCHOP;
  267.             break;
  268.         }
  269.     /*
  270.      * Read in TIFF header.
  271.      */
  272.     if (!ReadOK(tif, &tif->tif_header, sizeof (TIFFHeader))) {
  273.         if (tif->tif_mode == O_RDONLY) {
  274.             TIFFError(name, "Cannot read TIFF header");
  275.             goto bad;
  276.         }
  277.         /*
  278.          * Setup header and write.
  279.          */
  280.         tif->tif_header.tiff_magic = tif->tif_flags & TIFF_SWAB
  281.             ? (bigendian ? TIFF_LITTLEENDIAN : TIFF_BIGENDIAN)
  282.             : (bigendian ? TIFF_BIGENDIAN : TIFF_LITTLEENDIAN);
  283.         tif->tif_header.tiff_version = TIFF_VERSION;
  284.         if (tif->tif_flags & TIFF_SWAB)
  285.             TIFFSwabShort(&tif->tif_header.tiff_version);
  286.         tif->tif_header.tiff_diroff = 0;    /* filled in later */
  287.         if (!WriteOK(tif, &tif->tif_header, sizeof (TIFFHeader))) {
  288.             TIFFError(name, "Error writing TIFF header");
  289.             goto bad;
  290.         }
  291.         /*
  292.          * Setup the byte order handling.
  293.          */
  294.         TIFFInitOrder(tif, tif->tif_header.tiff_magic, bigendian);
  295.         /*
  296.          * Setup default directory.
  297.          */
  298.         if (!TIFFDefaultDirectory(tif))
  299.             goto bad;
  300.         tif->tif_diroff = 0;
  301.         return (tif);
  302.     }
  303.     /*
  304.      * Setup the byte order handling.
  305.      */
  306.     if (tif->tif_header.tiff_magic != TIFF_BIGENDIAN &&
  307.         tif->tif_header.tiff_magic != TIFF_LITTLEENDIAN) {
  308.         TIFFError(name,  "Not a TIFF file, bad magic number %d (0x%x)",
  309.             tif->tif_header.tiff_magic,
  310.             tif->tif_header.tiff_magic);
  311.         goto bad;
  312.     }
  313.     TIFFInitOrder(tif, tif->tif_header.tiff_magic, bigendian);
  314.     /*
  315.      * Swap header if required.
  316.      */
  317.     if (tif->tif_flags & TIFF_SWAB) {
  318.         TIFFSwabShort(&tif->tif_header.tiff_version);
  319.         TIFFSwabLong(&tif->tif_header.tiff_diroff);
  320.     }
  321.     /*
  322.      * Now check version (if needed, it's been byte-swapped).
  323.      * Note that this isn't actually a version number, it's a
  324.      * magic number that doesn't change (stupid).
  325.      */
  326.     if (tif->tif_header.tiff_version != TIFF_VERSION) {
  327.         TIFFError(name,
  328.             "Not a TIFF file, bad version number %d (0x%x)",
  329.             tif->tif_header.tiff_version,
  330.             tif->tif_header.tiff_version);
  331.         goto bad;
  332.     }
  333.     tif->tif_flags |= TIFF_MYBUFFER;
  334.     tif->tif_rawcp = tif->tif_rawdata = 0;
  335.     tif->tif_rawdatasize = 0;
  336.     /*
  337.      * Setup initial directory.
  338.      */
  339.     switch (mode[0]) {
  340.     case 'r':
  341.         tif->tif_nextdiroff = tif->tif_header.tiff_diroff;
  342.         /*
  343.          * Try to use a memory-mapped file if the client
  344.          * has not explicitly suppressed usage with the
  345.          * 'm' flag in the open mode (see above).
  346.          */
  347.         if ((tif->tif_flags & TIFF_MAPPED) &&
  348.     !TIFFMapFileContents(tif, (tdata_t*) &tif->tif_base, &tif->tif_size))
  349.             tif->tif_flags &= ~TIFF_MAPPED;
  350.         if (TIFFReadDirectory(tif)) {
  351.             tif->tif_rawcc = -1;
  352.             tif->tif_flags |= TIFF_BUFFERSETUP;
  353.             return (tif);
  354.         }
  355.         break;
  356.     case 'a':
  357.         /*
  358.          * New directories are automatically append
  359.          * to the end of the directory chain when they
  360.          * are written out (see TIFFWriteDirectory).
  361.          */
  362.         if (!TIFFDefaultDirectory(tif))
  363.             goto bad;
  364.         return (tif);
  365.     }
  366. bad:
  367.     tif->tif_mode = O_RDONLY;    /* XXX avoid flush */
  368.     TIFFClose(tif);
  369.     return ((TIFF*)0);
  370. bad2:
  371.     (void) (*closeproc)(clientdata);
  372.     return ((TIFF*)0);
  373. }
  374.  
  375. /*
  376.  * Query functions to access private data.
  377.  */
  378.  
  379. /*
  380.  * Return open file's name.
  381.  */
  382. const char *
  383. TIFFFileName(TIFF* tif)
  384. {
  385.     return (tif->tif_name);
  386. }
  387.  
  388. /*
  389.  * Return open file's I/O descriptor.
  390.  */
  391. int
  392. TIFFFileno(TIFF* tif)
  393. {
  394.     return (tif->tif_fd);
  395. }
  396.  
  397. /*
  398.  * Return read/write mode.
  399.  */
  400. int
  401. TIFFGetMode(TIFF* tif)
  402. {
  403.     return (tif->tif_mode);
  404. }
  405.  
  406. /*
  407.  * Return nonzero if file is organized in
  408.  * tiles; zero if organized as strips.
  409.  */
  410. int
  411. TIFFIsTiled(TIFF* tif)
  412. {
  413.     return (isTiled(tif));
  414. }
  415.  
  416. /*
  417.  * Return current row being read/written.
  418.  */
  419. uint32
  420. TIFFCurrentRow(TIFF* tif)
  421. {
  422.     return (tif->tif_row);
  423. }
  424.  
  425. /*
  426.  * Return index of the current directory.
  427.  */
  428. tdir_t
  429. TIFFCurrentDirectory(TIFF* tif)
  430. {
  431.     return (tif->tif_curdir);
  432. }
  433.  
  434. /*
  435.  * Return current strip.
  436.  */
  437. tstrip_t
  438. TIFFCurrentStrip(TIFF* tif)
  439. {
  440.     return (tif->tif_curstrip);
  441. }
  442.  
  443. /*
  444.  * Return current tile.
  445.  */
  446. ttile_t
  447. TIFFCurrentTile(TIFF* tif)
  448. {
  449.     return (tif->tif_curtile);
  450. }
  451.  
  452. /*
  453.  * Return nonzero if the file has byte-swapped data.
  454.  */
  455. int
  456. TIFFIsByteSwapped(TIFF* tif)
  457. {
  458.     return ((tif->tif_flags & TIFF_SWAB) != 0);
  459. }
  460.  
  461. /*
  462.  * Return nonzero if the data is returned up-sampled.
  463.  */
  464. int
  465. TIFFIsUpSampled(TIFF* tif)
  466. {
  467.     return (isUpSampled(tif));
  468. }
  469.  
  470. /*
  471.  * Return nonzero if the data is returned in MSB-to-LSB bit order.
  472.  */
  473. int
  474. TIFFIsMSB2LSB(TIFF* tif)
  475. {
  476.     return (isFillOrder(tif, FILLORDER_MSB2LSB));
  477. }
  478.