1 /* $Id: tif_strip.c,v 1.36 2015-06-07 22:35:40 bfriesen Exp $ */ 2 3 /* 4 * Copyright (c) 1991-1997 Sam Leffler 5 * Copyright (c) 1991-1997 Silicon Graphics, Inc. 6 * 7 * Permission to use, copy, modify, distribute, and sell this software and 8 * its documentation for any purpose is hereby granted without fee, provided 9 * that (i) the above copyright notices and this permission notice appear in 10 * all copies of the software and related documentation, and (ii) the names of 11 * Sam Leffler and Silicon Graphics may not be used in any advertising or 12 * publicity relating to the software without the specific, prior written 13 * permission of Sam Leffler and Silicon Graphics. 14 * 15 * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, 16 * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY 17 * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. 18 * 19 * IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR 20 * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, 21 * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, 22 * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF 23 * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE 24 * OF THIS SOFTWARE. 25 */ 26 27 /* 28 * TIFF Library. 29 * 30 * Strip-organized Image Support Routines. 31 */ 32 #include "tiffiop.h" 33 34 /* 35 * Compute which strip a (row,sample) value is in. 36 */ 37 uint32 38 TIFFComputeStrip(TIFF* tif, uint32 row, uint16 sample) 39 { 40 static const char module[] = "TIFFComputeStrip"; 41 TIFFDirectory *td = &tif->tif_dir; 42 uint32 strip; 43 44 strip = row / td->td_rowsperstrip; 45 if (td->td_planarconfig == PLANARCONFIG_SEPARATE) { 46 if (sample >= td->td_samplesperpixel) { 47 TIFFErrorExt(tif->tif_clientdata, module, 48 "%lu: Sample out of range, max %lu", 49 (unsigned long) sample, (unsigned long) td->td_samplesperpixel); 50 return (0); 51 } 52 strip += (uint32)sample*td->td_stripsperimage; 53 } 54 return (strip); 55 } 56 57 /* 58 * Compute how many strips are in an image. 59 */ 60 uint32 61 TIFFNumberOfStrips(TIFF* tif) 62 { 63 TIFFDirectory *td = &tif->tif_dir; 64 uint32 nstrips; 65 66 nstrips = (td->td_rowsperstrip == (uint32) -1 ? 1 : 67 TIFFhowmany_32(td->td_imagelength, td->td_rowsperstrip)); 68 if (td->td_planarconfig == PLANARCONFIG_SEPARATE) 69 nstrips = _TIFFMultiply32(tif, nstrips, (uint32)td->td_samplesperpixel, 70 "TIFFNumberOfStrips"); 71 return (nstrips); 72 } 73 74 /* 75 * Compute the # bytes in a variable height, row-aligned strip. 76 */ 77 uint64 78 TIFFVStripSize64(TIFF* tif, uint32 nrows) 79 { 80 static const char module[] = "TIFFVStripSize64"; 81 TIFFDirectory *td = &tif->tif_dir; 82 if (nrows==(uint32)(-1)) 83 nrows=td->td_imagelength; 84 if ((td->td_planarconfig==PLANARCONFIG_CONTIG)&& 85 (td->td_photometric == PHOTOMETRIC_YCBCR)&& 86 (!isUpSampled(tif))) 87 { 88 /* 89 * Packed YCbCr data contain one Cb+Cr for every 90 * HorizontalSampling*VerticalSampling Y values. 91 * Must also roundup width and height when calculating 92 * since images that are not a multiple of the 93 * horizontal/vertical subsampling area include 94 * YCbCr data for the extended image. 95 */ 96 uint16 ycbcrsubsampling[2]; 97 uint16 samplingblock_samples; 98 uint32 samplingblocks_hor; 99 uint32 samplingblocks_ver; 100 uint64 samplingrow_samples; 101 uint64 samplingrow_size; 102 if(td->td_samplesperpixel!=3) 103 { 104 TIFFErrorExt(tif->tif_clientdata,module, 105 "Invalid td_samplesperpixel value"); 106 return 0; 107 } 108 TIFFGetFieldDefaulted(tif,TIFFTAG_YCBCRSUBSAMPLING,ycbcrsubsampling+0, 109 ycbcrsubsampling+1); 110 if ((ycbcrsubsampling[0] != 1 && ycbcrsubsampling[0] != 2 && ycbcrsubsampling[0] != 4) 111 ||(ycbcrsubsampling[1] != 1 && ycbcrsubsampling[1] != 2 && ycbcrsubsampling[1] != 4)) 112 { 113 TIFFErrorExt(tif->tif_clientdata,module, 114 "Invalid YCbCr subsampling (%dx%d)", 115 ycbcrsubsampling[0], 116 ycbcrsubsampling[1] ); 117 return 0; 118 } 119 samplingblock_samples=ycbcrsubsampling[0]*ycbcrsubsampling[1]+2; 120 samplingblocks_hor=TIFFhowmany_32(td->td_imagewidth,ycbcrsubsampling[0]); 121 samplingblocks_ver=TIFFhowmany_32(nrows,ycbcrsubsampling[1]); 122 samplingrow_samples=_TIFFMultiply64(tif,samplingblocks_hor,samplingblock_samples,module); 123 samplingrow_size=TIFFhowmany8_64(_TIFFMultiply64(tif,samplingrow_samples,td->td_bitspersample,module)); 124 return(_TIFFMultiply64(tif,samplingrow_size,samplingblocks_ver,module)); 125 } 126 else 127 return(_TIFFMultiply64(tif,nrows,TIFFScanlineSize64(tif),module)); 128 } 129 tmsize_t 130 TIFFVStripSize(TIFF* tif, uint32 nrows) 131 { 132 static const char module[] = "TIFFVStripSize"; 133 uint64 m; 134 tmsize_t n; 135 m=TIFFVStripSize64(tif,nrows); 136 n=(tmsize_t)m; 137 if ((uint64)n!=m) 138 { 139 TIFFErrorExt(tif->tif_clientdata,module,"Integer overflow"); 140 n=0; 141 } 142 return(n); 143 } 144 145 /* 146 * Compute the # bytes in a raw strip. 147 */ 148 uint64 149 TIFFRawStripSize64(TIFF* tif, uint32 strip) 150 { 151 static const char module[] = "TIFFRawStripSize64"; 152 TIFFDirectory* td = &tif->tif_dir; 153 uint64 bytecount = td->td_stripbytecount[strip]; 154 155 if (bytecount == 0) 156 { 157 #if defined(__WIN32__) && (defined(_MSC_VER) || defined(__MINGW32__)) 158 TIFFErrorExt(tif->tif_clientdata, module, 159 "%I64u: Invalid strip byte count, strip %lu", 160 (unsigned __int64) bytecount, 161 (unsigned long) strip); 162 #else 163 TIFFErrorExt(tif->tif_clientdata, module, 164 "%llu: Invalid strip byte count, strip %lu", 165 (unsigned long long) bytecount, 166 (unsigned long) strip); 167 #endif 168 bytecount = (uint64) -1; 169 } 170 171 return bytecount; 172 } 173 tmsize_t 174 TIFFRawStripSize(TIFF* tif, uint32 strip) 175 { 176 static const char module[] = "TIFFRawStripSize"; 177 uint64 m; 178 tmsize_t n; 179 m=TIFFRawStripSize64(tif,strip); 180 if (m==(uint64)(-1)) 181 n=(tmsize_t)(-1); 182 else 183 { 184 n=(tmsize_t)m; 185 if ((uint64)n!=m) 186 { 187 TIFFErrorExt(tif->tif_clientdata,module,"Integer overflow"); 188 n=0; 189 } 190 } 191 return(n); 192 } 193 194 /* 195 * Compute the # bytes in a (row-aligned) strip. 196 * 197 * Note that if RowsPerStrip is larger than the 198 * recorded ImageLength, then the strip size is 199 * truncated to reflect the actual space required 200 * to hold the strip. 201 */ 202 uint64 203 TIFFStripSize64(TIFF* tif) 204 { 205 TIFFDirectory* td = &tif->tif_dir; 206 uint32 rps = td->td_rowsperstrip; 207 if (rps > td->td_imagelength) 208 rps = td->td_imagelength; 209 return (TIFFVStripSize64(tif, rps)); 210 } 211 tmsize_t 212 TIFFStripSize(TIFF* tif) 213 { 214 static const char module[] = "TIFFStripSize"; 215 uint64 m; 216 tmsize_t n; 217 m=TIFFStripSize64(tif); 218 n=(tmsize_t)m; 219 if ((uint64)n!=m) 220 { 221 TIFFErrorExt(tif->tif_clientdata,module,"Integer overflow"); 222 n=0; 223 } 224 return(n); 225 } 226 227 /* 228 * Compute a default strip size based on the image 229 * characteristics and a requested value. If the 230 * request is <1 then we choose a strip size according 231 * to certain heuristics. 232 */ 233 uint32 234 TIFFDefaultStripSize(TIFF* tif, uint32 request) 235 { 236 return (*tif->tif_defstripsize)(tif, request); 237 } 238 239 uint32 240 _TIFFDefaultStripSize(TIFF* tif, uint32 s) 241 { 242 if ((int32) s < 1) { 243 /* 244 * If RowsPerStrip is unspecified, try to break the 245 * image up into strips that are approximately 246 * STRIP_SIZE_DEFAULT bytes long. 247 */ 248 uint64 scanlinesize; 249 uint64 rows; 250 scanlinesize=TIFFScanlineSize64(tif); 251 if (scanlinesize==0) 252 scanlinesize=1; 253 rows=(uint64)STRIP_SIZE_DEFAULT/scanlinesize; 254 if (rows==0) 255 rows=1; 256 else if (rows>0xFFFFFFFF) 257 rows=0xFFFFFFFF; 258 s=(uint32)rows; 259 } 260 return (s); 261 } 262 263 /* 264 * Return the number of bytes to read/write in a call to 265 * one of the scanline-oriented i/o routines. Note that 266 * this number may be 1/samples-per-pixel if data is 267 * stored as separate planes. 268 * The ScanlineSize in case of YCbCrSubsampling is defined as the 269 * strip size divided by the strip height, i.e. the size of a pack of vertical 270 * subsampling lines divided by vertical subsampling. It should thus make 271 * sense when multiplied by a multiple of vertical subsampling. 272 */ 273 uint64 274 TIFFScanlineSize64(TIFF* tif) 275 { 276 static const char module[] = "TIFFScanlineSize64"; 277 TIFFDirectory *td = &tif->tif_dir; 278 uint64 scanline_size; 279 if (td->td_planarconfig==PLANARCONFIG_CONTIG) 280 { 281 if ((td->td_photometric==PHOTOMETRIC_YCBCR)&& 282 (td->td_samplesperpixel==3)&& 283 (!isUpSampled(tif))) 284 { 285 uint16 ycbcrsubsampling[2]; 286 uint16 samplingblock_samples; 287 uint32 samplingblocks_hor; 288 uint64 samplingrow_samples; 289 uint64 samplingrow_size; 290 if(td->td_samplesperpixel!=3) 291 { 292 TIFFErrorExt(tif->tif_clientdata,module, 293 "Invalid td_samplesperpixel value"); 294 return 0; 295 } 296 TIFFGetFieldDefaulted(tif,TIFFTAG_YCBCRSUBSAMPLING, 297 ycbcrsubsampling+0, 298 ycbcrsubsampling+1); 299 if (((ycbcrsubsampling[0]!=1)&&(ycbcrsubsampling[0]!=2)&&(ycbcrsubsampling[0]!=4)) || 300 ((ycbcrsubsampling[1]!=1)&&(ycbcrsubsampling[1]!=2)&&(ycbcrsubsampling[1]!=4))) 301 { 302 TIFFErrorExt(tif->tif_clientdata,module, 303 "Invalid YCbCr subsampling"); 304 return 0; 305 } 306 samplingblock_samples = ycbcrsubsampling[0]*ycbcrsubsampling[1]+2; 307 samplingblocks_hor = TIFFhowmany_32(td->td_imagewidth,ycbcrsubsampling[0]); 308 samplingrow_samples = _TIFFMultiply64(tif,samplingblocks_hor,samplingblock_samples,module); 309 samplingrow_size = TIFFhowmany_64(_TIFFMultiply64(tif,samplingrow_samples,td->td_bitspersample,module),8); 310 scanline_size = (samplingrow_size/ycbcrsubsampling[1]); 311 } 312 else 313 { 314 uint64 scanline_samples; 315 scanline_samples=_TIFFMultiply64(tif,td->td_imagewidth,td->td_samplesperpixel,module); 316 scanline_size=TIFFhowmany_64(_TIFFMultiply64(tif,scanline_samples,td->td_bitspersample,module),8); 317 } 318 } 319 else 320 { 321 scanline_size=TIFFhowmany_64(_TIFFMultiply64(tif,td->td_imagewidth,td->td_bitspersample,module),8); 322 } 323 if (scanline_size == 0) 324 { 325 TIFFErrorExt(tif->tif_clientdata,module,"Computed scanline size is zero"); 326 return 0; 327 } 328 return(scanline_size); 329 } 330 tmsize_t 331 TIFFScanlineSize(TIFF* tif) 332 { 333 static const char module[] = "TIFFScanlineSize"; 334 uint64 m; 335 tmsize_t n; 336 m=TIFFScanlineSize64(tif); 337 n=(tmsize_t)m; 338 if ((uint64)n!=m) { 339 TIFFErrorExt(tif->tif_clientdata,module,"Integer arithmetic overflow"); 340 n=0; 341 } 342 return(n); 343 } 344 345 /* 346 * Return the number of bytes required to store a complete 347 * decoded and packed raster scanline (as opposed to the 348 * I/O size returned by TIFFScanlineSize which may be less 349 * if data is store as separate planes). 350 */ 351 uint64 352 TIFFRasterScanlineSize64(TIFF* tif) 353 { 354 static const char module[] = "TIFFRasterScanlineSize64"; 355 TIFFDirectory *td = &tif->tif_dir; 356 uint64 scanline; 357 358 scanline = _TIFFMultiply64(tif, td->td_bitspersample, td->td_imagewidth, module); 359 if (td->td_planarconfig == PLANARCONFIG_CONTIG) { 360 scanline = _TIFFMultiply64(tif, scanline, td->td_samplesperpixel, module); 361 return (TIFFhowmany8_64(scanline)); 362 } else 363 return (_TIFFMultiply64(tif, TIFFhowmany8_64(scanline), 364 td->td_samplesperpixel, module)); 365 } 366 tmsize_t 367 TIFFRasterScanlineSize(TIFF* tif) 368 { 369 static const char module[] = "TIFFRasterScanlineSize"; 370 uint64 m; 371 tmsize_t n; 372 m=TIFFRasterScanlineSize64(tif); 373 n=(tmsize_t)m; 374 if ((uint64)n!=m) 375 { 376 TIFFErrorExt(tif->tif_clientdata,module,"Integer arithmetic overflow"); 377 n=0; 378 } 379 return(n); 380 } 381 382 /* vim: set ts=8 sts=8 sw=8 noet: */ 383 /* 384 * Local Variables: 385 * mode: c 386 * c-basic-offset: 8 387 * fill-column: 78 388 * End: 389 */ 390