home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 11 Util / 11-Util.zip / xloadimg.zip / xloadimage.4.1 / tiff / tif_read.c < prev    next >
C/C++ Source or Header  |  1993-10-21  |  16KB  |  595 lines

  1. #ifndef lint
  2. static char rcsid[] = "$Header: /usr/people/sam/tiff/libtiff/RCS/tif_read.c,v 1.43 92/02/10 19:06:41 sam Exp $";
  3. #endif
  4.  
  5. /*
  6.  * Copyright (c) 1988, 1989, 1990, 1991, 1992 Sam Leffler
  7.  * Copyright (c) 1991, 1992 Silicon Graphics, Inc.
  8.  *
  9.  * Permission to use, copy, modify, distribute, and sell this software and 
  10.  * its documentation for any purpose is hereby granted without fee, provided
  11.  * that (i) the above copyright notices and this permission notice appear in
  12.  * all copies of the software and related documentation, and (ii) the names of
  13.  * Sam Leffler and Silicon Graphics may not be used in any advertising or
  14.  * publicity relating to the software without the specific, prior written
  15.  * permission of Sam Leffler and Silicon Graphics.
  16.  * 
  17.  * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, 
  18.  * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY 
  19.  * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.  
  20.  * 
  21.  * IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR
  22.  * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND,
  23.  * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
  24.  * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF 
  25.  * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE 
  26.  * OF THIS SOFTWARE.
  27.  */
  28.  
  29. /*
  30.  * TIFF Library.
  31.  * Scanline-oriented Read Support
  32.  */
  33. #include "tiffioP.h"
  34.  
  35. #if USE_PROTOTYPES
  36. static    TIFFSeek(TIFF *, u_int, u_int);
  37. static    int TIFFReadRawStrip1(TIFF *, u_int, u_char *, u_int, char []);
  38. static    int TIFFReadRawTile1(TIFF *, u_int, u_char *, u_int, char []);
  39. static    TIFFFillStrip(TIFF *, u_int);
  40. static    TIFFFillTile(TIFF *, u_int);
  41. static    TIFFStartStrip(TIFF *, u_int);
  42. static    TIFFStartTile(TIFF *, u_int);
  43. static    TIFFCheckRead(TIFF *, int);
  44. #else
  45. static    TIFFSeek();
  46. static    int TIFFReadRawStrip1();
  47. static    int TIFFReadRawTile1();
  48. static    TIFFFillStrip();
  49. static    TIFFFillTile();
  50. static    TIFFStartStrip();
  51. static    TIFFStartTile();
  52. static    TIFFCheckRead();
  53. #endif
  54.  
  55. /*VARARGS3*/
  56. TIFFReadScanline(tif, buf, row, sample)
  57.     register TIFF *tif;
  58.     u_char *buf;
  59.     u_int row, sample;
  60. {
  61.     int e;
  62.  
  63.     if (!TIFFCheckRead(tif, 0))
  64.         return (-1);
  65.     if (e = TIFFSeek(tif, row, sample)) {
  66.         /*
  67.          * Decompress desired row into user buffer.
  68.          */
  69.         e = (*tif->tif_decoderow)(tif, buf, tif->tif_scanlinesize, sample);
  70.         tif->tif_row++;
  71.     }
  72.     return (e ? 1 : -1);
  73. }
  74.  
  75. /*
  76.  * Seek to a random row+sample in a file.
  77.  */
  78. static
  79. /*VARARGS2*/
  80. TIFFSeek(tif, row, sample)
  81.     register TIFF *tif;
  82.     u_int row, sample;
  83. {
  84.     register TIFFDirectory *td = &tif->tif_dir;
  85.     int strip;
  86.  
  87.     if (row >= td->td_imagelength) {    /* out of range */
  88.         TIFFError(tif->tif_name, "%d: Row out of range, max %d",
  89.             row, td->td_imagelength);
  90.         return (0);
  91.     }
  92.     if (td->td_planarconfig == PLANARCONFIG_SEPARATE) {
  93.         if (sample >= td->td_samplesperpixel) {
  94.             TIFFError(tif->tif_name,
  95.                 "%d: Sample out of range, max %d",
  96.                 sample, td->td_samplesperpixel);
  97.             return (0);
  98.         }
  99.         strip = sample*td->td_stripsperimage + row/td->td_rowsperstrip;
  100.     } else
  101.         strip = row / td->td_rowsperstrip;
  102.     if (strip != tif->tif_curstrip) {     /* different strip, refill */
  103.         if (!TIFFFillStrip(tif, strip))
  104.             return (0);
  105.     } else if (row < tif->tif_row) {
  106.         /*
  107.          * Moving backwards within the same strip: backup
  108.          * to the start and then decode forward (below).
  109.          *
  110.          * NB: If you're planning on lots of random access within a
  111.          * strip, it's better to just read and decode the entire
  112.          * strip, and then access the decoded data in a random fashion.
  113.          */
  114.         if (!TIFFStartStrip(tif, strip))
  115.             return (0);
  116.     }
  117.     if (row != tif->tif_row) {
  118.         if (tif->tif_seek) {
  119.             /*
  120.              * Seek forward to the desired row.
  121.              */
  122.             if (!(*tif->tif_seek)(tif, row - tif->tif_row))
  123.                 return (0);
  124.             tif->tif_row = row;
  125.         } else {
  126.             TIFFError(tif->tif_name,
  127.             "Compression algorithm does not support random access");
  128.             return (0);
  129.         }
  130.     }
  131.     return (1);
  132. }
  133.  
  134. /*
  135.  * Read a strip of data and decompress the specified
  136.  * amount into the user-supplied buffer.
  137.  */
  138. TIFFReadEncodedStrip(tif, strip, buf, size)
  139.     TIFF *tif;
  140.     u_int strip;
  141.     u_char *buf;
  142.     u_int size;
  143. {
  144.     TIFFDirectory *td = &tif->tif_dir;
  145.     u_int stripsize = TIFFStripSize(tif);
  146.  
  147.     if (!TIFFCheckRead(tif, 0))
  148.         return (-1);
  149.     if (strip >= td->td_nstrips) {
  150.         TIFFError(tif->tif_name, "%d: Strip out of range, max %d",
  151.             strip, td->td_nstrips);
  152.         return (-1);
  153.     }
  154.     /*
  155.      * Calculate the strip size according to the number of
  156.      * rows in the strip (check for truncated last strip).
  157.      */
  158.     if (size == (u_int)-1)
  159.         size = stripsize;
  160.     else if (size > stripsize)
  161.         size = stripsize;
  162.     return (TIFFFillStrip(tif, strip) && 
  163.     (*tif->tif_decodestrip)(tif, buf, size, strip / td->td_stripsperimage) ?
  164.         size : -1);
  165. }
  166.  
  167. /*
  168.  * Read a strip of data from the file.
  169.  */
  170. TIFFReadRawStrip(tif, strip, buf, size)
  171.     TIFF *tif;
  172.     u_int strip;
  173.     u_char *buf;
  174.     u_int size;
  175. {
  176.     static char module[] = "TIFFReadRawStrip";
  177.     TIFFDirectory *td = &tif->tif_dir;
  178.     u_long bytecount;
  179.  
  180.     if (!TIFFCheckRead(tif, 0))
  181.         return (-1);
  182.     if (strip >= td->td_nstrips) {
  183.         TIFFError(tif->tif_name, "%d: Strip out of range, max %d",
  184.             strip, td->td_nstrips);
  185.         return (-1);
  186.     }
  187.     bytecount = td->td_stripbytecount[strip];
  188.     if (size != (u_int)-1 && size < bytecount)
  189.         bytecount = size;
  190.     return (TIFFReadRawStrip1(tif, strip, buf, bytecount, module));
  191. }
  192.  
  193. static int
  194. TIFFReadRawStrip1(tif, strip, buf, size, module)
  195.     TIFF *tif;
  196.     u_int strip;
  197.     u_char *buf;
  198.     u_int size;
  199.     char module[];
  200. {
  201.     TIFFDirectory *td = &tif->tif_dir;
  202.  
  203.     if (!isMapped(tif)) {
  204.         if (!SeekOK(tif->tif_fd, td->td_stripoffset[strip])) {
  205.             TIFFError(module,
  206.                 "%s: Seek error at scanline %d, strip %d",
  207.                 tif->tif_name, tif->tif_row, strip);
  208.             return (-1);
  209.         }
  210.         if (!ReadOK(tif->tif_fd, buf, size)) {
  211.             TIFFError(module, "%s: Read error at scanline %d",
  212.                 tif->tif_name, tif->tif_row);
  213.             return (-1);
  214.         }
  215. #ifdef MMAP_SUPPORT
  216.     } else {
  217.         if (td->td_stripoffset[strip] + size > tif->tif_size) {
  218.             TIFFError(module,
  219.                 "%s: Seek error at scanline %d, strip %d",
  220.                 tif->tif_name, tif->tif_row, strip);
  221.             return (-1);
  222.         }
  223.         bcopy(tif->tif_base + td->td_stripoffset[strip], buf, size);
  224. #endif
  225.     }
  226.     return (size);
  227. }
  228.  
  229. /*
  230.  * Read the specified strip and setup for decoding. 
  231.  * The data buffer is expanded, as necessary, to
  232.  * hold the strip's data.
  233.  */
  234. static
  235. TIFFFillStrip(tif, strip)
  236.     TIFF *tif;
  237.     u_int strip;
  238. {
  239.     static char module[] = "TIFFFillStrip";
  240.     TIFFDirectory *td = &tif->tif_dir;
  241.     u_long bytecount;
  242.  
  243.     bytecount = td->td_stripbytecount[strip];
  244. #ifdef MMAP_SUPPORT
  245.     if (isMapped(tif) &&
  246.         (td->td_fillorder == tif->tif_fillorder || (tif->tif_flags & TIFF_NOBITREV))) {
  247.         /*
  248.          * The image is mapped into memory and we either don't
  249.          * need to flip bits or the compression routine is going
  250.          * to handle this operation itself.  In this case, avoid
  251.          * copying the raw data and instead just reference the
  252.          * data from the memory mapped file image.  This assumes
  253.          * that the decompression routines do not modify the
  254.          * contents of the raw data buffer (if they try to,
  255.          * the application will get a fault since the file is
  256.          * mapped read-only).
  257.          */
  258.         if ((tif->tif_flags & TIFF_MYBUFFER) && tif->tif_rawdata)
  259.             free(tif->tif_rawdata);
  260.         tif->tif_flags &= ~TIFF_MYBUFFER;
  261.         if (td->td_stripoffset[strip] + bytecount > tif->tif_size) {
  262.             /*
  263.              * This error message might seem strange, but it's
  264.              * what would happen if a read were done instead.
  265.              */
  266.             TIFFError(module, "%s: Read error on strip %d",
  267.                 tif->tif_name, strip);
  268.             tif->tif_curstrip = -1;        /* unknown state */
  269.             return (0);
  270.         }
  271.         tif->tif_rawdatasize = bytecount;
  272.         tif->tif_rawdata = tif->tif_base + td->td_stripoffset[strip];
  273.     } else {
  274. #endif
  275.         /*
  276.          * Expand raw data buffer, if needed, to
  277.          * hold data strip coming from file
  278.          * (perhaps should set upper bound on
  279.          *  the size of a buffer we'll use?).
  280.          */
  281.         if (bytecount > tif->tif_rawdatasize) {
  282.             tif->tif_curstrip = -1;        /* unknown state */
  283.             if ((tif->tif_flags & TIFF_MYBUFFER) == 0) {
  284.                 TIFFError(module,
  285.                 "%s: Data buffer too small to hold strip %d",
  286.                     tif->tif_name, strip);
  287.                 return (0);
  288.             }
  289.             if (!TIFFReadBufferSetup(tif, 0,
  290.                 roundup(bytecount, 1024)))
  291.                 return (0);
  292.         }
  293.         if (TIFFReadRawStrip1(tif, strip, (u_char *)tif->tif_rawdata,
  294.             bytecount, module) != bytecount)
  295.             return (0);
  296.         if (td->td_fillorder != tif->tif_fillorder &&
  297.             (tif->tif_flags & TIFF_NOBITREV) == 0)
  298.             TIFFReverseBits((u_char *)tif->tif_rawdata, bytecount);
  299. #ifdef MMAP_SUPPORT
  300.     }
  301. #endif
  302.     return (TIFFStartStrip(tif, strip));
  303. }
  304.  
  305. /*
  306.  * Tile-oriented Read Support
  307.  * Contributed by Nancy Cam (Silicon Graphics).
  308.  */
  309.  
  310. /*
  311.  * Read and decompress a tile of data.  The
  312.  * tile is selected by the (x,y,z,s) coordinates.
  313.  */
  314. TIFFReadTile(tif, buf, x, y, z, s)
  315.     TIFF *tif;
  316.     u_char *buf;
  317.     u_long x, y, z;
  318.     u_int s;
  319. {
  320.     u_int tile;
  321.  
  322.     if (!TIFFCheckRead(tif, 1) || !TIFFCheckTile(tif, x, y, z, s))
  323.         return (-1);
  324.     tile = TIFFComputeTile(tif, x, y, z, s);
  325.     if (tile >= tif->tif_dir.td_nstrips) {
  326.         TIFFError(tif->tif_name, "%d: Tile out of range, max %d",
  327.             tile, tif->tif_dir.td_nstrips);
  328.         return (-1);
  329.     }
  330.     return (TIFFFillTile(tif, tile) &&
  331.         (*tif->tif_decodetile)(tif, buf, tif->tif_tilesize, s) ?
  332.         tif->tif_tilesize : -1);
  333. }
  334.  
  335. /*
  336.  * Read a tile of data and decompress the specified
  337.  * amount into the user-supplied buffer.
  338.  */
  339. TIFFReadEncodedTile(tif, tile, buf, size)
  340.     TIFF *tif;
  341.     u_int tile;
  342.     u_char *buf;
  343.     u_int size;
  344. {
  345.     TIFFDirectory *td = &tif->tif_dir;
  346.     int tilesize = tif->tif_tilesize;
  347.  
  348.     if (!TIFFCheckRead(tif, 1))
  349.         return (-1);
  350.     if (tile >= td->td_nstrips) {
  351.         TIFFError(tif->tif_name, "%d: Tile out of range, max %d",
  352.             tile, td->td_nstrips);
  353.         return (-1);
  354.     }
  355.     if (size == (u_int)-1)
  356.         size = tilesize;
  357.     else if (size > tilesize )
  358.         size = tilesize;
  359.     return (TIFFFillTile(tif, tile) && 
  360.         (*tif->tif_decodetile)(tif, buf, size, tile/td->td_stripsperimage) ?
  361.         size : -1);
  362. }
  363.  
  364. /*
  365.  * Read a tile of data from the file.
  366.  */
  367. TIFFReadRawTile(tif, tile, buf, size)
  368.     TIFF *tif;
  369.     u_int tile;
  370.     u_char *buf;
  371.     u_int size;
  372. {
  373.     static char module[] = "TIFFReadRawTile";
  374.     TIFFDirectory *td = &tif->tif_dir;
  375.     u_long bytecount;
  376.  
  377.     if (!TIFFCheckRead(tif, 1))
  378.         return (-1);
  379.     if (tile >= td->td_nstrips) {
  380.         TIFFError(tif->tif_name, "%d: Tile out of range, max %d",
  381.             tile, td->td_nstrips);
  382.         return (-1);
  383.     }
  384.     bytecount = td->td_stripbytecount[tile];
  385.     if (size != (u_int)-1 && size < bytecount)
  386.         bytecount = size;
  387.     return (TIFFReadRawTile1(tif, tile, buf, bytecount, module));
  388. }
  389.  
  390. static int
  391. TIFFReadRawTile1(tif, tile, buf, size, module)
  392.     TIFF *tif;
  393.     u_int tile;
  394.     u_char *buf;
  395.     u_int size;
  396.     char module[];
  397. {
  398.     TIFFDirectory *td = &tif->tif_dir;
  399.  
  400.     if (!isMapped(tif)) {
  401.         if (!SeekOK(tif->tif_fd, td->td_stripoffset[tile])) {
  402.             TIFFError(module,
  403.                 "%s: Seek error at row %d, col %d, tile %d",
  404.                 tif->tif_name, tif->tif_row, tif->tif_col, tile);
  405.             return (-1);
  406.         }
  407.         if (!ReadOK(tif->tif_fd, buf, size)) {
  408.             TIFFError(module, "%s: Read error at row %d, col %d",
  409.                 tif->tif_name, tif->tif_row, tif->tif_col);
  410.             return (-1);
  411.         }
  412. #ifdef MMAP_SUPPORT
  413.     } else {
  414.         if (td->td_stripoffset[tile] + size > tif->tif_size) {
  415.             TIFFError(module,
  416.                 "%s: Seek error at row %d, col %d, tile %d",
  417.                 tif->tif_name, tif->tif_row, tif->tif_col, tile);
  418.             return (-1);
  419.         }
  420.         bcopy(tif->tif_base + td->td_stripoffset[tile], buf, size);
  421. #endif
  422.     }
  423.     return (size);
  424. }
  425.  
  426. /*
  427.  * Read the specified tile and setup for decoding. 
  428.  * The data buffer is expanded, as necessary, to
  429.  * hold the tile's data.
  430.  */
  431. static
  432. TIFFFillTile(tif, tile)
  433.     TIFF *tif;
  434.     u_int tile;
  435. {
  436.     static char module[] = "TIFFFillTile";
  437.     TIFFDirectory *td = &tif->tif_dir;
  438.     u_long bytecount;
  439.  
  440.     bytecount = td->td_stripbytecount[tile];
  441. #ifdef MMAP_SUPPORT
  442.     if (isMapped(tif) &&
  443.         (td->td_fillorder == tif->tif_fillorder || (tif->tif_flags & TIFF_NOBITREV))) {
  444.         /*
  445.          * The image is mapped into memory and we either don't
  446.          * need to flip bits or the compression routine is going
  447.          * to handle this operation itself.  In this case, avoid
  448.          * copying the raw data and instead just reference the
  449.          * data from the memory mapped file image.  This assumes
  450.          * that the decompression routines do not modify the
  451.          * contents of the raw data buffer (if they try to,
  452.          * the application will get a fault since the file is
  453.          * mapped read-only).
  454.          */
  455.         if ((tif->tif_flags & TIFF_MYBUFFER) && tif->tif_rawdata)
  456.             free(tif->tif_rawdata);
  457.         tif->tif_flags &= ~TIFF_MYBUFFER;
  458.         if (td->td_stripoffset[tile] + bytecount > tif->tif_size) {
  459.             tif->tif_curtile = -1;        /* unknown state */
  460.             return (0);
  461.         }
  462.         tif->tif_rawdatasize = bytecount;
  463.         tif->tif_rawdata = tif->tif_base + td->td_stripoffset[tile];
  464.     } else {
  465. #endif
  466.         /*
  467.          * Expand raw data buffer, if needed, to
  468.          * hold data tile coming from file
  469.          * (perhaps should set upper bound on
  470.          *  the size of a buffer we'll use?).
  471.          */
  472.         if (bytecount > tif->tif_rawdatasize) {
  473.             tif->tif_curtile = -1;        /* unknown state */
  474.             if ((tif->tif_flags & TIFF_MYBUFFER) == 0) {
  475.                 TIFFError(module,
  476.                 "%s: Data buffer too small to hold tile %d",
  477.                     tif->tif_name, tile);
  478.                 return (0);
  479.             }
  480.             if (!TIFFReadBufferSetup(tif, 0,
  481.                 roundup(bytecount, 1024)))
  482.                 return (0);
  483.         }
  484.         if (TIFFReadRawTile1(tif, tile, (u_char *)tif->tif_rawdata,
  485.             bytecount, module) != bytecount)
  486.             return (0);
  487.         if (td->td_fillorder != tif->tif_fillorder &&
  488.             (tif->tif_flags & TIFF_NOBITREV) == 0)
  489.             TIFFReverseBits((u_char *)tif->tif_rawdata, bytecount);
  490. #ifdef MMAP_SUPPORT
  491.     }
  492. #endif
  493.     return (TIFFStartTile(tif, tile));
  494. }
  495.  
  496. /*
  497.  * Setup the raw data buffer in preparation for
  498.  * reading a strip of raw data.  If the buffer
  499.  * is specified as zero, then a buffer of appropriate
  500.  * size is allocated by the library.  Otherwise,
  501.  * the client must guarantee that the buffer is
  502.  * large enough to hold any individual strip of
  503.  * raw data.
  504.  */
  505. int
  506. TIFFReadBufferSetup(tif, bp, size)
  507.     TIFF *tif;
  508.     char *bp;
  509.     u_int size;
  510. {
  511.     static char module[] = "TIFFReadBufferSetup";
  512.  
  513.     if (tif->tif_rawdata) {
  514.         if (tif->tif_flags & TIFF_MYBUFFER)
  515.             free(tif->tif_rawdata);
  516.         tif->tif_rawdata = NULL;
  517.     }
  518.     if (bp) {
  519.         tif->tif_rawdatasize = size;
  520.         tif->tif_rawdata = bp;
  521.         tif->tif_flags &= ~TIFF_MYBUFFER;
  522.     } else {
  523.         tif->tif_rawdatasize = roundup(size, 1024);
  524.         tif->tif_rawdata = malloc(tif->tif_rawdatasize);
  525.         tif->tif_flags |= TIFF_MYBUFFER;
  526.     }
  527.     if (tif->tif_rawdata == NULL) {
  528.         TIFFError(module,
  529.             "%s: No space for data buffer at scanline %d",
  530.             tif->tif_name, tif->tif_row);
  531.         tif->tif_rawdatasize = 0;
  532.         return (0);
  533.     }
  534.     return (1);
  535. }
  536.  
  537. /*
  538.  * Set state to appear as if a
  539.  * strip has just been read in.
  540.  */
  541. static
  542. TIFFStartStrip(tif, strip)
  543.     register TIFF *tif;
  544.     u_int strip;
  545. {
  546.     TIFFDirectory *td = &tif->tif_dir;
  547.  
  548.     tif->tif_curstrip = strip;
  549.     tif->tif_row = (strip % td->td_stripsperimage) * td->td_rowsperstrip;
  550.     tif->tif_rawcp = tif->tif_rawdata;
  551.     tif->tif_rawcc = td->td_stripbytecount[strip];
  552.     return (tif->tif_predecode == NULL || (*tif->tif_predecode)(tif));
  553. }
  554.  
  555. /*
  556.  * Set state to appear as if a
  557.  * tile has just been read in.
  558.  */
  559. static
  560. TIFFStartTile(tif, tile)
  561.     register TIFF *tif;
  562.     u_int tile;
  563. {
  564.     TIFFDirectory *td = &tif->tif_dir;
  565.  
  566.     tif->tif_curtile = tile;
  567.     tif->tif_row =
  568.         (tile % howmany(td->td_imagewidth, td->td_tilewidth)) *
  569.         td->td_tilelength;
  570.     tif->tif_col =
  571.         (tile % howmany(td->td_imagelength, td->td_tilelength)) *
  572.         td->td_tilewidth;
  573.     tif->tif_rawcp = tif->tif_rawdata;
  574.     tif->tif_rawcc = td->td_stripbytecount[tile];
  575.     return (tif->tif_predecode == NULL || (*tif->tif_predecode)(tif));
  576. }
  577.  
  578. static
  579. TIFFCheckRead(tif, tiles)
  580.     TIFF *tif;
  581.     int tiles;
  582. {
  583.     if (tif->tif_mode == O_WRONLY) {
  584.         TIFFError(tif->tif_name, "File not open for reading");
  585.         return (0);
  586.     }
  587.     if (tiles ^ isTiled(tif)) {
  588.         TIFFError(tif->tif_name, tiles ?
  589.             "Can not read tiles from a stripped image" :
  590.             "Can not read scanlines from a tiled image");
  591.         return (0);
  592.     }
  593.     return (1);
  594. }
  595.