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