Home | Info | Community | Development | myReactOS | Contact Us
ReactOS Development > Doxygentif_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
1.7.6.1
|