"Fossies" - the Fresh Open Source Software Archive

Member "PDFlib-Lite-7.0.5p3/libs/tiff/tif_strip.c" (6 Jun 2012, 7839 Bytes) of package /linux/misc/old/PDFlib-Lite-7.0.5p3.tar.gz:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file. For more information about "tif_strip.c" see the Fossies "Dox" file reference documentation.

    1 /* PDFlib GmbH cvsid:
    2  * $Id: tif_strip.c,v 1.9.2.1 2007/06/25 17:19:30 rjs Exp $ */
    3 
    4 /*
    5  * Copyright (c) 1991-1997 Sam Leffler
    6  * Copyright (c) 1991-1997 Silicon Graphics, Inc.
    7  *
    8  * Permission to use, copy, modify, distribute, and sell this software and 
    9  * its documentation for any purpose is hereby granted without fee, provided
   10  * that (i) the above copyright notices and this permission notice appear in
   11  * all copies of the software and related documentation, and (ii) the names of
   12  * Sam Leffler and Silicon Graphics may not be used in any advertising or
   13  * publicity relating to the software without the specific, prior written
   14  * permission of Sam Leffler and Silicon Graphics.
   15  * 
   16  * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, 
   17  * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY 
   18  * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.  
   19  * 
   20  * IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR
   21  * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND,
   22  * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
   23  * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF 
   24  * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE 
   25  * OF THIS SOFTWARE.
   26  */
   27 
   28 /*
   29  * TIFF Library.
   30  *
   31  * Strip-organized Image Support Routines.
   32  */
   33 #include "tiffiop.h"
   34 
   35 static uint32
   36 summarize(TIFF* tif, size_t summand1, size_t summand2, const char* where)
   37 {
   38     /*
   39      * XXX: We are using casting to uint32 here, bacause sizeof(size_t)
   40      * may be larger than sizeof(uint32) on 64-bit architectures.
   41      */
   42     uint32  bytes = summand1 + summand2;
   43 
   44     if (bytes - summand1 != summand2) {
   45         _TIFFError(tif, tif->tif_name, "Integer overflow in %s", where);
   46         bytes = 0;
   47     }
   48 
   49     return (bytes);
   50 }
   51 
   52 static uint32
   53 multiply(TIFF* tif, size_t nmemb, size_t elem_size, const char* where)
   54 {
   55     uint32  bytes = nmemb * elem_size;
   56 
   57     if (elem_size && bytes / elem_size != nmemb) {
   58         _TIFFError(tif, tif->tif_name, "Integer overflow in %s", where);
   59         bytes = 0;
   60     }
   61 
   62     return (bytes);
   63 }
   64 
   65 /*
   66  * Compute which strip a (row,sample) value is in.
   67  */
   68 tstrip_t
   69 TIFFComputeStrip(TIFF* tif, uint32 row, tsample_t sample)
   70 {
   71     TIFFDirectory *td = &tif->tif_dir;
   72     tstrip_t strip;
   73 
   74     strip = row / td->td_rowsperstrip;
   75     if (td->td_planarconfig == PLANARCONFIG_SEPARATE) {
   76         if (sample >= td->td_samplesperpixel) {
   77             _TIFFError(tif, tif->tif_name,
   78                 "%lu: Sample out of range, max %lu",
   79                 (unsigned long) sample,
   80                 (unsigned long) td->td_samplesperpixel);
   81             return ((tstrip_t) 0);
   82         }
   83         strip += sample*td->td_stripsperimage;
   84     }
   85     return (strip);
   86 }
   87 
   88 /*
   89  * Compute how many strips are in an image.
   90  */
   91 tstrip_t
   92 TIFFNumberOfStrips(TIFF* tif)
   93 {
   94     TIFFDirectory *td = &tif->tif_dir;
   95     tstrip_t nstrips;
   96 
   97     nstrips = (td->td_rowsperstrip == (uint32) -1 ? 1 :
   98          TIFFhowmany(td->td_imagelength, td->td_rowsperstrip));
   99     if (td->td_planarconfig == PLANARCONFIG_SEPARATE)
  100         nstrips = multiply(tif, nstrips, td->td_samplesperpixel,
  101                    "TIFFNumberOfStrips");
  102     return (nstrips);
  103 }
  104 
  105 /*
  106  * Compute the # bytes in a variable height, row-aligned strip.
  107  */
  108 tsize_t
  109 TIFFVStripSize(TIFF* tif, uint32 nrows)
  110 {
  111     TIFFDirectory *td = &tif->tif_dir;
  112 
  113     if (nrows == (uint32) -1)
  114         nrows = td->td_imagelength;
  115     if (td->td_planarconfig == PLANARCONFIG_CONTIG &&
  116         td->td_photometric == PHOTOMETRIC_YCBCR &&
  117         !isUpSampled(tif)) {
  118         /*
  119          * Packed YCbCr data contain one Cb+Cr for every
  120          * HorizontalSampling*VerticalSampling Y values.
  121          * Must also roundup width and height when calculating
  122          * since images that are not a multiple of the
  123          * horizontal/vertical subsampling area include
  124          * YCbCr data for the extended image.
  125          */
  126                 uint16 ycbcrsubsampling[2];
  127                 tsize_t w, scanline, samplingarea;
  128         ycbcrsubsampling[0] = 0;
  129         ycbcrsubsampling[1] = 0;
  130 
  131                 TIFFGetField( tif, TIFFTAG_YCBCRSUBSAMPLING, 
  132                               ycbcrsubsampling + 0, 
  133                               ycbcrsubsampling + 1 );
  134         /* make sure we dont get division by 0 due to bad tiffs */
  135         if (!ycbcrsubsampling[0]) ycbcrsubsampling[0] = 1;
  136         if (!ycbcrsubsampling[1]) ycbcrsubsampling[1] = 1;
  137 
  138         samplingarea = ycbcrsubsampling[0]*ycbcrsubsampling[1];
  139         if (samplingarea == 0) {
  140             _TIFFError(tif, tif->tif_name,
  141                 "Invalid YCbCr subsampling");
  142             return 0;
  143         }
  144 
  145         w = TIFFroundup(td->td_imagewidth, ycbcrsubsampling[0]);
  146         scanline = TIFFhowmany8(multiply(tif, w, td->td_bitspersample,
  147                          "TIFFVStripSize"));
  148         nrows = TIFFroundup(nrows, ycbcrsubsampling[1]);
  149         /* NB: don't need TIFFhowmany here 'cuz everything is rounded */
  150         scanline = multiply(tif, nrows, scanline, "TIFFVStripSize");
  151         return ((tsize_t)
  152             summarize(tif, scanline,
  153                   multiply(tif, 2, scanline / samplingarea,
  154                        "TIFFVStripSize"), "TIFFVStripSize"));
  155     } else
  156         return ((tsize_t) multiply(tif, nrows, TIFFScanlineSize(tif),
  157                        "TIFFVStripSize"));
  158 }
  159 
  160 
  161 /*
  162  * Compute the # bytes in a raw strip.
  163  */
  164 tsize_t
  165 TIFFRawStripSize(TIFF* tif, tstrip_t strip)
  166 {
  167     TIFFDirectory* td = &tif->tif_dir;
  168     tsize_t bytecount = td->td_stripbytecount[strip];
  169 
  170     if (bytecount <= 0) {
  171         _TIFFError(tif, tif->tif_name,
  172               "%lu: Invalid strip byte count, strip %lu",
  173               (unsigned long) bytecount, (unsigned long) strip);
  174         bytecount = (tsize_t) -1;
  175     }
  176 
  177     return bytecount;
  178 }
  179 
  180 /*
  181  * Compute the # bytes in a (row-aligned) strip.
  182  *
  183  * Note that if RowsPerStrip is larger than the
  184  * recorded ImageLength, then the strip size is
  185  * truncated to reflect the actual space required
  186  * to hold the strip.
  187  */
  188 tsize_t
  189 TIFFStripSize(TIFF* tif)
  190 {
  191     TIFFDirectory* td = &tif->tif_dir;
  192     uint32 rps = td->td_rowsperstrip;
  193     if (rps > td->td_imagelength)
  194         rps = td->td_imagelength;
  195     return (TIFFVStripSize(tif, rps));
  196 }
  197 
  198 /*
  199  * Compute a default strip size based on the image
  200  * characteristics and a requested value.  If the
  201  * request is <1 then we choose a strip size according
  202  * to certain heuristics.
  203  */
  204 uint32
  205 TIFFDefaultStripSize(TIFF* tif, uint32 request)
  206 {
  207     return (*tif->tif_defstripsize)(tif, request);
  208 }
  209 
  210 uint32
  211 _TIFFDefaultStripSize(TIFF* tif, uint32 s)
  212 {
  213     if ((int32) s < 1) {
  214         /*
  215          * If RowsPerStrip is unspecified, try to break the
  216          * image up into strips that are approximately 8Kbytes.
  217          */
  218         tsize_t scanline = TIFFScanlineSize(tif);
  219         s = (uint32)(8*1024) / (scanline == 0 ? 1 : scanline);
  220         if (s == 0)     /* very wide images */
  221             s = 1;
  222     }
  223     return (s);
  224 }
  225 
  226 /*
  227  * Return the number of bytes to read/write in a call to
  228  * one of the scanline-oriented i/o routines.  Note that
  229  * this number may be 1/samples-per-pixel if data is
  230  * stored as separate planes.
  231  */
  232 tsize_t
  233 TIFFScanlineSize(TIFF* tif)
  234 {
  235     TIFFDirectory *td = &tif->tif_dir;
  236     tsize_t scanline;
  237     
  238     scanline = multiply (tif, td->td_bitspersample, td->td_imagewidth,
  239                  "TIFFScanlineSize");
  240     if (td->td_planarconfig == PLANARCONFIG_CONTIG)
  241         scanline = multiply (tif, scanline, td->td_samplesperpixel,
  242                      "TIFFScanlineSize");
  243     return ((tsize_t) TIFFhowmany8(scanline));
  244 }
  245 
  246 /*
  247  * Return the number of bytes required to store a complete
  248  * decoded and packed raster scanline (as opposed to the
  249  * I/O size returned by TIFFScanlineSize which may be less
  250  * if data is store as separate planes).
  251  */
  252 tsize_t
  253 TIFFRasterScanlineSize(TIFF* tif)
  254 {
  255     TIFFDirectory *td = &tif->tif_dir;
  256     tsize_t scanline;
  257     
  258     scanline = multiply (tif, td->td_bitspersample, td->td_imagewidth,
  259                  "TIFFRasterScanlineSize");
  260     if (td->td_planarconfig == PLANARCONFIG_CONTIG) {
  261         scanline = multiply (tif, scanline, td->td_samplesperpixel,
  262                      "TIFFRasterScanlineSize");
  263         return ((tsize_t) TIFFhowmany8(scanline));
  264     } else
  265         return ((tsize_t) multiply (tif, TIFFhowmany8(scanline),
  266                         td->td_samplesperpixel,
  267                         "TIFFRasterScanlineSize"));
  268 }
  269 
  270 /* vim: set ts=8 sts=8 sw=8 noet: */