ReactOS Fundraising Campaign 2012
 
€ 4,410 / € 30,000

Information | Donate

Home | Info | Community | Development | myReactOS | Contact Us

  1. Home
  2. Community
  3. Development
  4. myReactOS
  5. Fundraiser 2012

  1. Main Page
  2. Alphabetical List
  3. Data Structures
  4. Directories
  5. File List
  6. Data Fields
  7. Globals
  8. Related Pages

ReactOS Development > Doxygen

tif_strip.c
Go to the documentation of this file.
00001 /* $Id: tif_strip.c,v 1.19.2.1 2010-06-08 18:50:43 bfriesen Exp $ */
00002 
00003 /*
00004  * Copyright (c) 1991-1997 Sam Leffler
00005  * Copyright (c) 1991-1997 Silicon Graphics, Inc.
00006  *
00007  * Permission to use, copy, modify, distribute, and sell this software and 
00008  * its documentation for any purpose is hereby granted without fee, provided
00009  * that (i) the above copyright notices and this permission notice appear in
00010  * all copies of the software and related documentation, and (ii) the names of
00011  * Sam Leffler and Silicon Graphics may not be used in any advertising or
00012  * publicity relating to the software without the specific, prior written
00013  * permission of Sam Leffler and Silicon Graphics.
00014  * 
00015  * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, 
00016  * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY 
00017  * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.  
00018  * 
00019  * IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR
00020  * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND,
00021  * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
00022  * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF 
00023  * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE 
00024  * OF THIS SOFTWARE.
00025  */
00026 
00027 /*
00028  * TIFF Library.
00029  *
00030  * Strip-organized Image Support Routines.
00031  */
00032 #include "tiffiop.h"
00033 
00034 static uint32
00035 summarize(TIFF* tif, size_t summand1, size_t summand2, const char* where)
00036 {
00037     /*
00038      * XXX: We are using casting to uint32 here, bacause sizeof(size_t)
00039      * may be larger than sizeof(uint32) on 64-bit architectures.
00040      */
00041     uint32  bytes = summand1 + summand2;
00042 
00043     if (bytes - summand1 != summand2) {
00044         TIFFErrorExt(tif->tif_clientdata, tif->tif_name, "Integer overflow in %s", where);
00045         bytes = 0;
00046     }
00047 
00048     return (bytes);
00049 }
00050 
00051 static uint32
00052 multiply(TIFF* tif, size_t nmemb, size_t elem_size, const char* where)
00053 {
00054     uint32  bytes = nmemb * elem_size;
00055 
00056     if (elem_size && bytes / elem_size != nmemb) {
00057         TIFFErrorExt(tif->tif_clientdata, tif->tif_name, "Integer overflow in %s", where);
00058         bytes = 0;
00059     }
00060 
00061     return (bytes);
00062 }
00063 
00064 /*
00065  * Compute which strip a (row,sample) value is in.
00066  */
00067 tstrip_t
00068 TIFFComputeStrip(TIFF* tif, uint32 row, tsample_t sample)
00069 {
00070     TIFFDirectory *td = &tif->tif_dir;
00071     tstrip_t strip;
00072 
00073     strip = row / td->td_rowsperstrip;
00074     if (td->td_planarconfig == PLANARCONFIG_SEPARATE) {
00075         if (sample >= td->td_samplesperpixel) {
00076             TIFFErrorExt(tif->tif_clientdata, tif->tif_name,
00077                 "%lu: Sample out of range, max %lu",
00078                 (unsigned long) sample, (unsigned long) td->td_samplesperpixel);
00079             return ((tstrip_t) 0);
00080         }
00081         strip += sample*td->td_stripsperimage;
00082     }
00083     return (strip);
00084 }
00085 
00086 /*
00087  * Compute how many strips are in an image.
00088  */
00089 tstrip_t
00090 TIFFNumberOfStrips(TIFF* tif)
00091 {
00092     TIFFDirectory *td = &tif->tif_dir;
00093     tstrip_t nstrips;
00094 
00095     nstrips = (td->td_rowsperstrip == (uint32) -1 ? 1 :
00096          TIFFhowmany(td->td_imagelength, td->td_rowsperstrip));
00097     if (td->td_planarconfig == PLANARCONFIG_SEPARATE)
00098         nstrips = multiply(tif, nstrips, td->td_samplesperpixel,
00099                    "TIFFNumberOfStrips");
00100     return (nstrips);
00101 }
00102 
00103 /*
00104  * Compute the # bytes in a variable height, row-aligned strip.
00105  */
00106 tsize_t
00107 TIFFVStripSize(TIFF* tif, uint32 nrows)
00108 {
00109     TIFFDirectory *td = &tif->tif_dir;
00110 
00111     if (nrows == (uint32) -1)
00112         nrows = td->td_imagelength;
00113     if (td->td_planarconfig == PLANARCONFIG_CONTIG &&
00114         td->td_photometric == PHOTOMETRIC_YCBCR &&
00115         !isUpSampled(tif)) {
00116         /*
00117          * Packed YCbCr data contain one Cb+Cr for every
00118          * HorizontalSampling*VerticalSampling Y values.
00119          * Must also roundup width and height when calculating
00120          * since images that are not a multiple of the
00121          * horizontal/vertical subsampling area include
00122          * YCbCr data for the extended image.
00123          */
00124         uint16 ycbcrsubsampling[2];
00125         tsize_t w, scanline, samplingarea;
00126 
00127         TIFFGetField( tif, TIFFTAG_YCBCRSUBSAMPLING,
00128                   ycbcrsubsampling + 0,
00129                   ycbcrsubsampling + 1 );
00130 
00131         samplingarea = ycbcrsubsampling[0]*ycbcrsubsampling[1];
00132         if (samplingarea == 0) {
00133             TIFFErrorExt(tif->tif_clientdata, tif->tif_name,
00134                      "Invalid YCbCr subsampling");
00135             return 0;
00136         }
00137 
00138         w = TIFFroundup(td->td_imagewidth, ycbcrsubsampling[0]);
00139         scanline = TIFFhowmany8(multiply(tif, w, td->td_bitspersample,
00140                          "TIFFVStripSize"));
00141         nrows = TIFFroundup(nrows, ycbcrsubsampling[1]);
00142         /* NB: don't need TIFFhowmany here 'cuz everything is rounded */
00143         scanline = multiply(tif, nrows, scanline, "TIFFVStripSize");
00144         return ((tsize_t)
00145             summarize(tif, scanline,
00146                   multiply(tif, 2, scanline / samplingarea,
00147                        "TIFFVStripSize"), "TIFFVStripSize"));
00148     } else
00149         return ((tsize_t) multiply(tif, nrows, TIFFScanlineSize(tif),
00150                        "TIFFVStripSize"));
00151 }
00152 
00153 
00154 /*
00155  * Compute the # bytes in a raw strip.
00156  */
00157 tsize_t
00158 TIFFRawStripSize(TIFF* tif, tstrip_t strip)
00159 {
00160     TIFFDirectory* td = &tif->tif_dir;
00161     tsize_t bytecount = td->td_stripbytecount[strip];
00162 
00163     if (bytecount <= 0) {
00164         TIFFErrorExt(tif->tif_clientdata, tif->tif_name,
00165               "%lu: Invalid strip byte count, strip %lu",
00166               (unsigned long) bytecount, (unsigned long) strip);
00167         bytecount = (tsize_t) -1;
00168     }
00169 
00170     return bytecount;
00171 }
00172 
00173 /*
00174  * Compute the # bytes in a (row-aligned) strip.
00175  *
00176  * Note that if RowsPerStrip is larger than the
00177  * recorded ImageLength, then the strip size is
00178  * truncated to reflect the actual space required
00179  * to hold the strip.
00180  */
00181 tsize_t
00182 TIFFStripSize(TIFF* tif)
00183 {
00184     TIFFDirectory* td = &tif->tif_dir;
00185     uint32 rps = td->td_rowsperstrip;
00186     if (rps > td->td_imagelength)
00187         rps = td->td_imagelength;
00188     return (TIFFVStripSize(tif, rps));
00189 }
00190 
00191 /*
00192  * Compute a default strip size based on the image
00193  * characteristics and a requested value.  If the
00194  * request is <1 then we choose a strip size according
00195  * to certain heuristics.
00196  */
00197 uint32
00198 TIFFDefaultStripSize(TIFF* tif, uint32 request)
00199 {
00200     return (*tif->tif_defstripsize)(tif, request);
00201 }
00202 
00203 uint32
00204 _TIFFDefaultStripSize(TIFF* tif, uint32 s)
00205 {
00206     if ((int32) s < 1) {
00207         /*
00208          * If RowsPerStrip is unspecified, try to break the
00209          * image up into strips that are approximately
00210          * STRIP_SIZE_DEFAULT bytes long.
00211          */
00212         tsize_t scanline = TIFFScanlineSize(tif);
00213         s = (uint32)STRIP_SIZE_DEFAULT / (scanline == 0 ? 1 : scanline);
00214         if (s == 0)     /* very wide images */
00215             s = 1;
00216     }
00217     return (s);
00218 }
00219 
00220 /*
00221  * Return the number of bytes to read/write in a call to
00222  * one of the scanline-oriented i/o routines.  Note that
00223  * this number may be 1/samples-per-pixel if data is
00224  * stored as separate planes.
00225  */
00226 tsize_t
00227 TIFFScanlineSize(TIFF* tif)
00228 {
00229     TIFFDirectory *td = &tif->tif_dir;
00230     tsize_t scanline;
00231 
00232     if (td->td_planarconfig == PLANARCONFIG_CONTIG) {
00233         if (td->td_photometric == PHOTOMETRIC_YCBCR
00234             && !isUpSampled(tif)) {
00235             uint16 ycbcrsubsampling[2];
00236 
00237             TIFFGetField(tif, TIFFTAG_YCBCRSUBSAMPLING,
00238                      ycbcrsubsampling + 0,
00239                      ycbcrsubsampling + 1);
00240 
00241             if (ycbcrsubsampling[0] == 0) {
00242                 TIFFErrorExt(tif->tif_clientdata, tif->tif_name,
00243                          "Invalid YCbCr subsampling");
00244                 return 0;
00245             }
00246 
00247             scanline = TIFFroundup(td->td_imagewidth,
00248                            ycbcrsubsampling[0]);
00249             scanline = TIFFhowmany8(multiply(tif, scanline,
00250                              td->td_bitspersample,
00251                              "TIFFScanlineSize"));
00252             return ((tsize_t)
00253                 summarize(tif, scanline,
00254                       multiply(tif, 2,
00255                         scanline / ycbcrsubsampling[0],
00256                         "TIFFVStripSize"),
00257                       "TIFFVStripSize"));
00258         } else {
00259             scanline = multiply(tif, td->td_imagewidth,
00260                         td->td_samplesperpixel,
00261                         "TIFFScanlineSize");
00262         }
00263     } else
00264         scanline = td->td_imagewidth;
00265     return ((tsize_t) TIFFhowmany8(multiply(tif, scanline,
00266                         td->td_bitspersample,
00267                         "TIFFScanlineSize")));
00268 }
00269 
00270 /*
00271  * Some stuff depends on this older version of TIFFScanlineSize
00272  * TODO: resolve this
00273  */
00274 tsize_t
00275 TIFFOldScanlineSize(TIFF* tif)
00276 {
00277     TIFFDirectory *td = &tif->tif_dir;
00278     tsize_t scanline;
00279 
00280     scanline = multiply (tif, td->td_bitspersample, td->td_imagewidth,
00281                  "TIFFScanlineSize");
00282     if (td->td_planarconfig == PLANARCONFIG_CONTIG)
00283         scanline = multiply (tif, scanline, td->td_samplesperpixel,
00284                      "TIFFScanlineSize");
00285     return ((tsize_t) TIFFhowmany8(scanline));
00286 }
00287 
00288 /*
00289  * Return the number of bytes to read/write in a call to
00290  * one of the scanline-oriented i/o routines.  Note that
00291  * this number may be 1/samples-per-pixel if data is
00292  * stored as separate planes.
00293  * The ScanlineSize in case of YCbCrSubsampling is defined as the
00294  * strip size divided by the strip height, i.e. the size of a pack of vertical
00295  * subsampling lines divided by vertical subsampling. It should thus make
00296  * sense when multiplied by a multiple of vertical subsampling.
00297  * Some stuff depends on this newer version of TIFFScanlineSize
00298  * TODO: resolve this
00299  */
00300 tsize_t
00301 TIFFNewScanlineSize(TIFF* tif)
00302 {
00303     TIFFDirectory *td = &tif->tif_dir;
00304     tsize_t scanline;
00305 
00306     if (td->td_planarconfig == PLANARCONFIG_CONTIG) {
00307         if (td->td_photometric == PHOTOMETRIC_YCBCR
00308             && !isUpSampled(tif)) {
00309             uint16 ycbcrsubsampling[2];
00310 
00311             TIFFGetField(tif, TIFFTAG_YCBCRSUBSAMPLING,
00312                      ycbcrsubsampling + 0,
00313                      ycbcrsubsampling + 1);
00314 
00315             if (ycbcrsubsampling[0]*ycbcrsubsampling[1] == 0) {
00316                 TIFFErrorExt(tif->tif_clientdata, tif->tif_name,
00317                          "Invalid YCbCr subsampling");
00318                 return 0;
00319             }
00320 
00321             return((tsize_t) ((((td->td_imagewidth+ycbcrsubsampling[0]-1)
00322                         /ycbcrsubsampling[0])
00323                        *(ycbcrsubsampling[0]*ycbcrsubsampling[1]+2)
00324                        *td->td_bitspersample+7)
00325                       /8)/ycbcrsubsampling[1]);
00326 
00327         } else {
00328             scanline = multiply(tif, td->td_imagewidth,
00329                         td->td_samplesperpixel,
00330                         "TIFFScanlineSize");
00331         }
00332     } else
00333         scanline = td->td_imagewidth;
00334     return ((tsize_t) TIFFhowmany8(multiply(tif, scanline,
00335                         td->td_bitspersample,
00336                         "TIFFScanlineSize")));
00337 }
00338 
00339 /*
00340  * Return the number of bytes required to store a complete
00341  * decoded and packed raster scanline (as opposed to the
00342  * I/O size returned by TIFFScanlineSize which may be less
00343  * if data is store as separate planes).
00344  */
00345 tsize_t
00346 TIFFRasterScanlineSize(TIFF* tif)
00347 {
00348     TIFFDirectory *td = &tif->tif_dir;
00349     tsize_t scanline;
00350     
00351     scanline = multiply (tif, td->td_bitspersample, td->td_imagewidth,
00352                  "TIFFRasterScanlineSize");
00353     if (td->td_planarconfig == PLANARCONFIG_CONTIG) {
00354         scanline = multiply (tif, scanline, td->td_samplesperpixel,
00355                      "TIFFRasterScanlineSize");
00356         return ((tsize_t) TIFFhowmany8(scanline));
00357     } else
00358         return ((tsize_t) multiply (tif, TIFFhowmany8(scanline),
00359                         td->td_samplesperpixel,
00360                         "TIFFRasterScanlineSize"));
00361 }
00362 
00363 /* vim: set ts=8 sts=8 sw=8 noet: */
00364 /*
00365  * Local Variables:
00366  * mode: c
00367  * c-basic-offset: 8
00368  * fill-column: 78
00369  * End:
00370  */

Generated on Sun May 27 2012 04:19:35 for ReactOS by doxygen 1.7.6.1

ReactOS is a registered trademark or a trademark of ReactOS Foundation in the United States and other countries.