home *** CD-ROM | disk | FTP | other *** search
/ Crawly Crypt Collection 1 / crawlyvol1.bin / program / grfx_snd / tifflib / source / tif_read.c < prev    next >
C/C++ Source or Header  |  1993-01-13  |  9KB  |  249 lines

  1. #pragma warn -use
  2. static char     *sccsid = "@(#)TIFF/tif_read.c 1.23, Copyright (c) Sam Leffler, Dieter Linde, "__DATE__;
  3. #pragma warn .use
  4. /*
  5.  * Copyright (c) 1988, 1990 by Sam Leffler, Oct 8 1990
  6.  * All rights reserved.
  7.  *
  8.  * This file is provided for unrestricted use provided that this legend is included on all tape media and as a part of the
  9.  * software program in whole or part.  Users may copy, modify or distribute this file at will.
  10.  *
  11.  * TIFF Library.
  12.  *
  13.  * Scanline-oriented Read Support
  14.  */
  15. #include <stdlib.h>
  16. #include "tiffio.h"
  17.  
  18. #define roundup(x, y)    ((((x) + ((y) - 1)) / (y)) * (y))
  19.  
  20. /****************************************************************************
  21.  *
  22.  */
  23. static long
  24. TIFFReadRawStrip1(
  25.         TIFF     *tif,
  26.         u_int     strip,
  27.         void     *buf,
  28.         u_long    size,
  29.         char     *module
  30.         )
  31. {
  32.         if (!SeekOK(tif->tif_fd, tif->tif_dir.td_stripoffset[strip])) {
  33.                    TIFFError(module, "seek error at scanline %ld, strip %u", tif->tif_row, strip);
  34.                 return(-1);
  35.         }
  36.         if (!ReadOK(tif->tif_fd, buf, size)) {
  37.                    TIFFError(module, "read error at scanline %ld", tif->tif_row);
  38.                 return(-1);
  39.         }
  40.         return(size);
  41. }
  42.  
  43.  
  44. /****************************************************************************
  45.  * Read a strip of data from the file.
  46.  */
  47. long
  48. TIFFReadRawStrip(
  49.         TIFF     *tif,
  50.         u_int     strip,
  51.         void     *buf,
  52.         u_long     size
  53.         )
  54. {
  55.         static char    *module = "TIFFReadRawStrip";
  56.         TIFFDirectory     *td = &tif->tif_dir;
  57.         u_long         bytecount;
  58.  
  59.         if (tif->tif_mode == O_WRONLY) {
  60.                    TIFFError(module, "file \"%s\" not opened for reading", tif->tif_name);
  61.                 return(-1);
  62.         }
  63.         if (strip >= td->td_nstrips) {
  64.                 TIFFError(module, "strip %u out of range, max %ul", strip, td->td_nstrips);
  65.                 return(-1);
  66.         }
  67.         bytecount = td->td_stripbytecount[strip];
  68.         if (size == (u_int)-1)
  69.                 size = bytecount;
  70.         else if (bytecount > size)
  71.                 bytecount = size;
  72.         return(TIFFReadRawStrip1(tif, strip, buf, bytecount, module));
  73. }
  74.  
  75. /****************************************************************************
  76.  * Set state to appear as if a strip has just been read in.
  77.  */
  78. static int
  79. TIFFStartStrip(
  80.         register TIFF    *tif,
  81.         u_int         strip
  82.         )
  83. {
  84.         TIFFDirectory    *td = &tif->tif_dir;
  85.  
  86.         tif->tif_curstrip = strip;
  87.         tif->tif_row = (strip % td->td_stripsperimage) * td->td_rowsperstrip;
  88.         tif->tif_rawcp = tif->tif_rawdata;
  89.         tif->tif_rawcc = td->td_stripbytecount[strip];
  90.         return(tif->tif_stripdecode == NULL || (*tif->tif_stripdecode)(tif));
  91. }
  92. /****************************************************************************
  93.  * Read the specified strip and setup for decoding.  The data buffer is expanded, as necessary, to
  94.  * hold the strip's data.
  95.  */
  96. static int
  97. TIFFFillStrip(
  98.         TIFF     *tif,
  99.         u_int     strip
  100.         )
  101. {
  102.         static char    *module = "TIFFFillStrip";
  103.         TIFFDirectory     *td = &tif->tif_dir;
  104.         u_long         bytecount;
  105.  
  106.         /*
  107.          * Expand raw data buffer, if needed, to hold data strip coming from file
  108.          * (perhaps should set upper bound on the size of a buffer we'll use?).
  109.          */
  110.         bytecount = td->td_stripbytecount[strip];
  111.         if (bytecount > tif->tif_rawdatasize) {
  112.                 tif->tif_curstrip = -1;            /* unknown state */
  113.                 if (tif->tif_rawdata) {
  114.                         free(tif->tif_rawdata);
  115.                         tif->tif_rawdata = NULL;
  116.                 }
  117.                 tif->tif_rawdatasize = roundup(bytecount, 1024);
  118.                 tif->tif_rawdata = malloc(tif->tif_rawdatasize);
  119.                 if (tif->tif_rawdata == NULL) {
  120.                            TIFFError(module, "out of memory allocating data buffer at scanline %ld", tif->tif_row);
  121.                         tif->tif_rawdatasize = 0;
  122.                         return(0);
  123.                 }
  124.         }
  125.         if (TIFFReadRawStrip1(tif, strip, tif->tif_rawdata, bytecount, module) != bytecount)
  126.                 return(0);
  127.         if (td->td_fillorder != tif->tif_fillorder && (tif->tif_flags & TIFF_NOBITREV) == 0)
  128.                 TIFFReverseBits((u_char *)tif->tif_rawdata, bytecount);
  129.         return(TIFFStartStrip(tif, strip));
  130. }
  131.  
  132. /****************************************************************************
  133.  * Seek to a random row + sample in a file.
  134.  */
  135. static int
  136. TIFFSeek(
  137.         register TIFF    *tif,
  138.         u_int         row, 
  139.         u_int        sample
  140.         )
  141. {
  142.     static char        *module = "TIFFSeek";
  143.         register TIFFDirectory    *td = &tif->tif_dir;
  144.         long             strip;
  145.  
  146.         if (row >= td->td_imagelength) {           /* out of range */
  147.                    TIFFError(module, "row %u out of range, max %u", row, td->td_imagelength);
  148.                 return(0);
  149.         }
  150.         if (td->td_planarconfig == PLANARCONFIG_SEPARATE) {
  151.                    if (sample >= td->td_samplesperpixel) {
  152.                            TIFFError(module, "sample %u out of range, max %u", sample, td->td_samplesperpixel);
  153.                         return(0);
  154.                 }
  155.                 strip = sample * td->td_stripsperimage + row / td->td_rowsperstrip;
  156.         } 
  157.         else
  158.                 strip = row / td->td_rowsperstrip;
  159.         if (strip != tif->tif_curstrip) {          /* different strip, refill */
  160.                 if (!TIFFFillStrip(tif, (u_int)strip))
  161.                            return(0);
  162.         } 
  163.         else if (row < tif->tif_row) {
  164.  
  165.     /*
  166.          * Moving backwards within the same strip: backup to the start and then decode forward (below).
  167.          *
  168.          * NB: If you're planning on lots of random access within a strip, it's better to just read and decode the entire
  169.          * strip, and then access the decoded data in a random fashion.
  170.          */
  171.                    if (!TIFFStartStrip(tif, (u_int)strip))
  172.                         return(0);
  173.         }
  174.         if (row != tif->tif_row) {
  175.                    if (tif->tif_seek) {
  176.  
  177.     /*
  178.          * Seek forward to the desired row.
  179.          */
  180.                            if (!(*tif->tif_seek)(tif, row - tif->tif_row))
  181.                                    return(0);
  182.                         tif->tif_row = row;
  183.                 } 
  184.                 else {
  185.                            TIFFError(module, "compression algorithm does not support random access");
  186.                         return(0);
  187.                 }
  188.         }
  189.         return(1);
  190. }
  191.  
  192. /****************************************************************************
  193.  *
  194.  */
  195. int
  196. TIFFReadScanline(
  197.         register TIFF    *tif,
  198.         void         *buf,
  199.         u_int         row, 
  200.         u_int        sample
  201.         )
  202. {
  203.     static char    *module = "TIFFReadScanline";
  204.         int         e;
  205.  
  206.         if (tif->tif_mode == O_WRONLY) {
  207.                 TIFFError(module, "file \"%s\" not opened for reading", tif->tif_name);
  208.                 return(-1);
  209.         }
  210.         if ((e = TIFFSeek(tif, row, sample)) != 0) {
  211.  
  212.     /*
  213.          * Decompress desired row into user buffer
  214.          */
  215.                 e = (*tif->tif_decoderow)(tif, buf, tif->tif_scanlinesize);
  216.                 tif->tif_row++;
  217.         }
  218.         return(e ? 1 : -1);
  219. }
  220.  
  221. /****************************************************************************
  222.  * Read a strip of data and decompress the specified amount into the user-supplied buffer.
  223.  */
  224. int
  225. TIFFReadEncodedStrip(
  226.         TIFF     *tif,
  227.         u_int     strip,
  228.         void     *buf,
  229.         u_int     size
  230.         )
  231. {
  232.     static char    *module = "TIFFReadEncodedStrip";
  233.         TIFFDirectory    *td = &tif->tif_dir;
  234.  
  235.         if (tif->tif_mode == O_WRONLY) {
  236.                    TIFFError(module, "file \"%s\" not opened for reading", tif->tif_name);
  237.                 return(-1);
  238.         }
  239.         if (strip >= td->td_nstrips) {
  240.                    TIFFError(module, "strip %u out of range, max %ul", strip, td->td_nstrips);
  241.                 return(-1);
  242.         }
  243.         if (size == (u_int)-1)
  244.                    size = (u_int)(td->td_rowsperstrip * tif->tif_scanlinesize);
  245.         else if (size > td->td_rowsperstrip * tif->tif_scanlinesize)
  246.                    size = (u_int)(td->td_rowsperstrip * tif->tif_scanlinesize);
  247.         return(TIFFFillStrip(tif, strip) && (*tif->tif_decoderow)(tif, buf, size) ? size : -1);
  248. }
  249.