1 /* $Id: tif_tile.c,v 1.21 2010-03-10 18:56:49 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 * Tiled Image Support Routines. 31 */ 32 #include "tiffiop.h" 33 34 static uint32 35 multiply_32(TIFF* tif, uint32 nmemb, uint32 elem_size, const char* where) 36 { 37 uint32 bytes = nmemb * elem_size; 38 39 if (elem_size && bytes / elem_size != nmemb) { 40 TIFFErrorExt(tif->tif_clientdata, where, "Integer overflow in %s", where); 41 bytes = 0; 42 } 43 44 return (bytes); 45 } 46 47 static uint64 48 multiply_64(TIFF* tif, uint64 nmemb, uint64 elem_size, const char* where) 49 { 50 uint64 bytes = nmemb * elem_size; 51 52 if (elem_size && bytes / elem_size != nmemb) { 53 TIFFErrorExt(tif->tif_clientdata, where, "Integer overflow in %s", where); 54 bytes = 0; 55 } 56 57 return (bytes); 58 } 59 60 /* 61 * Compute which tile an (x,y,z,s) value is in. 62 */ 63 uint32 64 TIFFComputeTile(TIFF* tif, uint32 x, uint32 y, uint32 z, uint16 s) 65 { 66 TIFFDirectory *td = &tif->tif_dir; 67 uint32 dx = td->td_tilewidth; 68 uint32 dy = td->td_tilelength; 69 uint32 dz = td->td_tiledepth; 70 uint32 tile = 1; 71 72 if (td->td_imagedepth == 1) 73 z = 0; 74 if (dx == (uint32) -1) 75 dx = td->td_imagewidth; 76 if (dy == (uint32) -1) 77 dy = td->td_imagelength; 78 if (dz == (uint32) -1) 79 dz = td->td_imagedepth; 80 if (dx != 0 && dy != 0 && dz != 0) { 81 uint32 xpt = TIFFhowmany_32(td->td_imagewidth, dx); 82 uint32 ypt = TIFFhowmany_32(td->td_imagelength, dy); 83 uint32 zpt = TIFFhowmany_32(td->td_imagedepth, dz); 84 85 if (td->td_planarconfig == PLANARCONFIG_SEPARATE) 86 tile = (xpt*ypt*zpt)*s + 87 (xpt*ypt)*(z/dz) + 88 xpt*(y/dy) + 89 x/dx; 90 else 91 tile = (xpt*ypt)*(z/dz) + xpt*(y/dy) + x/dx; 92 } 93 return (tile); 94 } 95 96 /* 97 * Check an (x,y,z,s) coordinate 98 * against the image bounds. 99 */ 100 int 101 TIFFCheckTile(TIFF* tif, uint32 x, uint32 y, uint32 z, uint16 s) 102 { 103 TIFFDirectory *td = &tif->tif_dir; 104 105 if (x >= td->td_imagewidth) { 106 TIFFErrorExt(tif->tif_clientdata, tif->tif_name, 107 "%lu: Col out of range, max %lu", 108 (unsigned long) x, 109 (unsigned long) (td->td_imagewidth - 1)); 110 return (0); 111 } 112 if (y >= td->td_imagelength) { 113 TIFFErrorExt(tif->tif_clientdata, tif->tif_name, 114 "%lu: Row out of range, max %lu", 115 (unsigned long) y, 116 (unsigned long) (td->td_imagelength - 1)); 117 return (0); 118 } 119 if (z >= td->td_imagedepth) { 120 TIFFErrorExt(tif->tif_clientdata, tif->tif_name, 121 "%lu: Depth out of range, max %lu", 122 (unsigned long) z, 123 (unsigned long) (td->td_imagedepth - 1)); 124 return (0); 125 } 126 if (td->td_planarconfig == PLANARCONFIG_SEPARATE && 127 s >= td->td_samplesperpixel) { 128 TIFFErrorExt(tif->tif_clientdata, tif->tif_name, 129 "%lu: Sample out of range, max %lu", 130 (unsigned long) s, 131 (unsigned long) (td->td_samplesperpixel - 1)); 132 return (0); 133 } 134 return (1); 135 } 136 137 /* 138 * Compute how many tiles are in an image. 139 */ 140 uint32 141 TIFFNumberOfTiles(TIFF* tif) 142 { 143 TIFFDirectory *td = &tif->tif_dir; 144 uint32 dx = td->td_tilewidth; 145 uint32 dy = td->td_tilelength; 146 uint32 dz = td->td_tiledepth; 147 uint32 ntiles; 148 149 if (dx == (uint32) -1) 150 dx = td->td_imagewidth; 151 if (dy == (uint32) -1) 152 dy = td->td_imagelength; 153 if (dz == (uint32) -1) 154 dz = td->td_imagedepth; 155 ntiles = (dx == 0 || dy == 0 || dz == 0) ? 0 : 156 multiply_32(tif, multiply_32(tif, TIFFhowmany_32(td->td_imagewidth, dx), 157 TIFFhowmany_32(td->td_imagelength, dy), 158 "TIFFNumberOfTiles"), 159 TIFFhowmany_32(td->td_imagedepth, dz), "TIFFNumberOfTiles"); 160 if (td->td_planarconfig == PLANARCONFIG_SEPARATE) 161 ntiles = multiply_32(tif, ntiles, td->td_samplesperpixel, 162 "TIFFNumberOfTiles"); 163 return (ntiles); 164 } 165 166 /* 167 * Compute the # bytes in each row of a tile. 168 */ 169 uint64 170 TIFFTileRowSize64(TIFF* tif) 171 { 172 TIFFDirectory *td = &tif->tif_dir; 173 uint64 rowsize; 174 175 if (td->td_tilelength == 0 || td->td_tilewidth == 0) 176 return (0); 177 rowsize = multiply_64(tif, td->td_bitspersample, td->td_tilewidth, 178 "TIFFTileRowSize"); 179 if (td->td_planarconfig == PLANARCONFIG_CONTIG) 180 rowsize = multiply_64(tif, rowsize, td->td_samplesperpixel, 181 "TIFFTileRowSize"); 182 return (TIFFhowmany8_64(rowsize)); 183 } 184 tmsize_t 185 TIFFTileRowSize(TIFF* tif) 186 { 187 static const char module[] = "TIFFTileRowSize"; 188 uint64 m; 189 tmsize_t n; 190 m=TIFFTileRowSize64(tif); 191 n=(tmsize_t)m; 192 if ((uint64)n!=m) 193 { 194 TIFFErrorExt(tif->tif_clientdata,module,"Integer overflow"); 195 n=0; 196 } 197 return(n); 198 } 199 200 /* 201 * Compute the # bytes in a variable length, row-aligned tile. 202 */ 203 uint64 204 TIFFVTileSize64(TIFF* tif, uint32 nrows) 205 { 206 static const char module[] = "TIFFVTileSize64"; 207 TIFFDirectory *td = &tif->tif_dir; 208 if (td->td_tilelength == 0 || td->td_tilewidth == 0 || 209 td->td_tiledepth == 0) 210 return (0); 211 if ((td->td_planarconfig==PLANARCONFIG_CONTIG)&& 212 (td->td_photometric==PHOTOMETRIC_YCBCR)&& 213 (td->td_samplesperpixel==3)&& 214 (!isUpSampled(tif))) 215 { 216 /* 217 * Packed YCbCr data contain one Cb+Cr for every 218 * HorizontalSampling*VerticalSampling Y values. 219 * Must also roundup width and height when calculating 220 * since images that are not a multiple of the 221 * horizontal/vertical subsampling area include 222 * YCbCr data for the extended image. 223 */ 224 uint16 ycbcrsubsampling[2]; 225 uint16 samplingblock_samples; 226 uint32 samplingblocks_hor; 227 uint32 samplingblocks_ver; 228 uint64 samplingrow_samples; 229 uint64 samplingrow_size; 230 TIFFGetFieldDefaulted(tif,TIFFTAG_YCBCRSUBSAMPLING,ycbcrsubsampling+0, 231 ycbcrsubsampling+1); 232 assert((ycbcrsubsampling[0]==1)||(ycbcrsubsampling[0]==2)||(ycbcrsubsampling[0]==4)); 233 assert((ycbcrsubsampling[1]==1)||(ycbcrsubsampling[1]==2)||(ycbcrsubsampling[1]==4)); 234 if (ycbcrsubsampling[0]*ycbcrsubsampling[1]==0) 235 { 236 TIFFErrorExt(tif->tif_clientdata,module, 237 "Invalid YCbCr subsampling"); 238 return 0; 239 } 240 samplingblock_samples=ycbcrsubsampling[0]*ycbcrsubsampling[1]+2; 241 samplingblocks_hor=TIFFhowmany_32(td->td_tilewidth,ycbcrsubsampling[0]); 242 samplingblocks_ver=TIFFhowmany_32(nrows,ycbcrsubsampling[1]); 243 samplingrow_samples=multiply_64(tif,samplingblocks_hor,samplingblock_samples,module); 244 samplingrow_size=TIFFhowmany8_64(multiply_64(tif,samplingrow_samples,td->td_bitspersample,module)); 245 return(multiply_64(tif,samplingrow_size,samplingblocks_ver,module)); 246 } 247 else 248 return(multiply_64(tif,nrows,TIFFTileRowSize64(tif),module)); 249 } 250 tmsize_t 251 TIFFVTileSize(TIFF* tif, uint32 nrows) 252 { 253 static const char module[] = "TIFFVTileSize"; 254 uint64 m; 255 tmsize_t n; 256 m=TIFFVTileSize64(tif,nrows); 257 n=(tmsize_t)m; 258 if ((uint64)n!=m) 259 { 260 TIFFErrorExt(tif->tif_clientdata,module,"Integer overflow"); 261 n=0; 262 } 263 return(n); 264 } 265 266 /* 267 * Compute the # bytes in a row-aligned tile. 268 */ 269 uint64 270 TIFFTileSize64(TIFF* tif) 271 { 272 return (TIFFVTileSize64(tif, tif->tif_dir.td_tilelength)); 273 } 274 tmsize_t 275 TIFFTileSize(TIFF* tif) 276 { 277 static const char module[] = "TIFFTileSize"; 278 uint64 m; 279 tmsize_t n; 280 m=TIFFTileSize64(tif); 281 n=(tmsize_t)m; 282 if ((uint64)n!=m) 283 { 284 TIFFErrorExt(tif->tif_clientdata,module,"Integer overflow"); 285 n=0; 286 } 287 return(n); 288 } 289 290 /* 291 * Compute a default tile size based on the image 292 * characteristics and a requested value. If a 293 * request is <1 then we choose a size according 294 * to certain heuristics. 295 */ 296 void 297 TIFFDefaultTileSize(TIFF* tif, uint32* tw, uint32* th) 298 { 299 (*tif->tif_deftilesize)(tif, tw, th); 300 } 301 302 void 303 _TIFFDefaultTileSize(TIFF* tif, uint32* tw, uint32* th) 304 { 305 (void) tif; 306 if (*(int32*) tw < 1) 307 *tw = 256; 308 if (*(int32*) th < 1) 309 *th = 256; 310 /* roundup to a multiple of 16 per the spec */ 311 if (*tw & 0xf) 312 *tw = TIFFroundup_32(*tw, 16); 313 if (*th & 0xf) 314 *th = TIFFroundup_32(*th, 16); 315 } 316 317 /* vim: set ts=8 sts=8 sw=8 noet: */ 318 /* 319 * Local Variables: 320 * mode: c 321 * c-basic-offset: 8 322 * fill-column: 78 323 * End: 324 */ 325