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