1 /* $Id: tif_tile.c,v 1.12.2.1 2010-06-08 18:50:43 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 summarize(TIFF* tif, size_t summand1, size_t summand2, const char* where) 36 { 37 /* 38 * XXX: We are using casting to uint32 here, because sizeof(size_t) 39 * may be larger than sizeof(uint32) on 64-bit architectures. 40 */ 41 uint32 bytes = summand1 + summand2; 42 43 if (bytes - summand1 != summand2) { 44 TIFFErrorExt(tif->tif_clientdata, tif->tif_name, "Integer overflow in %s", where); 45 bytes = 0; 46 } 47 48 return (bytes); 49 } 50 51 static uint32 52 multiply(TIFF* tif, size_t nmemb, size_t elem_size, const char* where) 53 { 54 uint32 bytes = nmemb * elem_size; 55 56 if (elem_size && bytes / elem_size != nmemb) { 57 TIFFErrorExt(tif->tif_clientdata, tif->tif_name, "Integer overflow in %s", where); 58 bytes = 0; 59 } 60 61 return (bytes); 62 } 63 64 /* 65 * Compute which tile an (x,y,z,s) value is in. 66 */ 67 ttile_t 68 TIFFComputeTile(TIFF* tif, uint32 x, uint32 y, uint32 z, tsample_t s) 69 { 70 TIFFDirectory *td = &tif->tif_dir; 71 uint32 dx = td->td_tilewidth; 72 uint32 dy = td->td_tilelength; 73 uint32 dz = td->td_tiledepth; 74 ttile_t tile = 1; 75 76 if (td->td_imagedepth == 1) 77 z = 0; 78 if (dx == (uint32) -1) 79 dx = td->td_imagewidth; 80 if (dy == (uint32) -1) 81 dy = td->td_imagelength; 82 if (dz == (uint32) -1) 83 dz = td->td_imagedepth; 84 if (dx != 0 && dy != 0 && dz != 0) { 85 uint32 xpt = TIFFhowmany(td->td_imagewidth, dx); 86 uint32 ypt = TIFFhowmany(td->td_imagelength, dy); 87 uint32 zpt = TIFFhowmany(td->td_imagedepth, dz); 88 89 if (td->td_planarconfig == PLANARCONFIG_SEPARATE) 90 tile = (xpt*ypt*zpt)*s + 91 (xpt*ypt)*(z/dz) + 92 xpt*(y/dy) + 93 x/dx; 94 else 95 tile = (xpt*ypt)*(z/dz) + xpt*(y/dy) + x/dx; 96 } 97 return (tile); 98 } 99 100 /* 101 * Check an (x,y,z,s) coordinate 102 * against the image bounds. 103 */ 104 int 105 TIFFCheckTile(TIFF* tif, uint32 x, uint32 y, uint32 z, tsample_t s) 106 { 107 TIFFDirectory *td = &tif->tif_dir; 108 109 if (x >= td->td_imagewidth) { 110 TIFFErrorExt(tif->tif_clientdata, tif->tif_name, 111 "%lu: Col out of range, max %lu", 112 (unsigned long) x, 113 (unsigned long) (td->td_imagewidth - 1)); 114 return (0); 115 } 116 if (y >= td->td_imagelength) { 117 TIFFErrorExt(tif->tif_clientdata, tif->tif_name, 118 "%lu: Row out of range, max %lu", 119 (unsigned long) y, 120 (unsigned long) (td->td_imagelength - 1)); 121 return (0); 122 } 123 if (z >= td->td_imagedepth) { 124 TIFFErrorExt(tif->tif_clientdata, tif->tif_name, 125 "%lu: Depth out of range, max %lu", 126 (unsigned long) z, 127 (unsigned long) (td->td_imagedepth - 1)); 128 return (0); 129 } 130 if (td->td_planarconfig == PLANARCONFIG_SEPARATE && 131 s >= td->td_samplesperpixel) { 132 TIFFErrorExt(tif->tif_clientdata, tif->tif_name, 133 "%lu: Sample out of range, max %lu", 134 (unsigned long) s, 135 (unsigned long) (td->td_samplesperpixel - 1)); 136 return (0); 137 } 138 return (1); 139 } 140 141 /* 142 * Compute how many tiles are in an image. 143 */ 144 ttile_t 145 TIFFNumberOfTiles(TIFF* tif) 146 { 147 TIFFDirectory *td = &tif->tif_dir; 148 uint32 dx = td->td_tilewidth; 149 uint32 dy = td->td_tilelength; 150 uint32 dz = td->td_tiledepth; 151 ttile_t ntiles; 152 153 if (dx == (uint32) -1) 154 dx = td->td_imagewidth; 155 if (dy == (uint32) -1) 156 dy = td->td_imagelength; 157 if (dz == (uint32) -1) 158 dz = td->td_imagedepth; 159 ntiles = (dx == 0 || dy == 0 || dz == 0) ? 0 : 160 multiply(tif, multiply(tif, TIFFhowmany(td->td_imagewidth, dx), 161 TIFFhowmany(td->td_imagelength, dy), 162 "TIFFNumberOfTiles"), 163 TIFFhowmany(td->td_imagedepth, dz), "TIFFNumberOfTiles"); 164 if (td->td_planarconfig == PLANARCONFIG_SEPARATE) 165 ntiles = multiply(tif, ntiles, td->td_samplesperpixel, 166 "TIFFNumberOfTiles"); 167 return (ntiles); 168 } 169 170 /* 171 * Compute the # bytes in each row of a tile. 172 */ 173 tsize_t 174 TIFFTileRowSize(TIFF* tif) 175 { 176 TIFFDirectory *td = &tif->tif_dir; 177 tsize_t rowsize; 178 179 if (td->td_tilelength == 0 || td->td_tilewidth == 0) 180 return ((tsize_t) 0); 181 rowsize = multiply(tif, td->td_bitspersample, td->td_tilewidth, 182 "TIFFTileRowSize"); 183 if (td->td_planarconfig == PLANARCONFIG_CONTIG) 184 rowsize = multiply(tif, rowsize, td->td_samplesperpixel, 185 "TIFFTileRowSize"); 186 return ((tsize_t) TIFFhowmany8(rowsize)); 187 } 188 189 /* 190 * Compute the # bytes in a variable length, row-aligned tile. 191 */ 192 tsize_t 193 TIFFVTileSize(TIFF* tif, uint32 nrows) 194 { 195 TIFFDirectory *td = &tif->tif_dir; 196 tsize_t tilesize; 197 198 if (td->td_tilelength == 0 || td->td_tilewidth == 0 || 199 td->td_tiledepth == 0) 200 return ((tsize_t) 0); 201 if (td->td_planarconfig == PLANARCONFIG_CONTIG && 202 td->td_photometric == PHOTOMETRIC_YCBCR && 203 !isUpSampled(tif)) { 204 /* 205 * Packed YCbCr data contain one Cb+Cr for every 206 * HorizontalSampling*VerticalSampling Y values. 207 * Must also roundup width and height when calculating 208 * since images that are not a multiple of the 209 * horizontal/vertical subsampling area include 210 * YCbCr data for the extended image. 211 */ 212 tsize_t w = 213 TIFFroundup(td->td_tilewidth, td->td_ycbcrsubsampling[0]); 214 tsize_t rowsize = 215 TIFFhowmany8(multiply(tif, w, td->td_bitspersample, 216 "TIFFVTileSize")); 217 tsize_t samplingarea = 218 td->td_ycbcrsubsampling[0]*td->td_ycbcrsubsampling[1]; 219 if (samplingarea == 0) { 220 TIFFErrorExt(tif->tif_clientdata, tif->tif_name, "Invalid YCbCr subsampling"); 221 return 0; 222 } 223 nrows = TIFFroundup(nrows, td->td_ycbcrsubsampling[1]); 224 /* NB: don't need TIFFhowmany here 'cuz everything is rounded */ 225 tilesize = multiply(tif, nrows, rowsize, "TIFFVTileSize"); 226 tilesize = summarize(tif, tilesize, 227 multiply(tif, 2, tilesize / samplingarea, 228 "TIFFVTileSize"), 229 "TIFFVTileSize"); 230 } else 231 tilesize = multiply(tif, nrows, TIFFTileRowSize(tif), 232 "TIFFVTileSize"); 233 return ((tsize_t) 234 multiply(tif, tilesize, td->td_tiledepth, "TIFFVTileSize")); 235 } 236 237 /* 238 * Compute the # bytes in a row-aligned tile. 239 */ 240 tsize_t 241 TIFFTileSize(TIFF* tif) 242 { 243 return (TIFFVTileSize(tif, tif->tif_dir.td_tilelength)); 244 } 245 246 /* 247 * Compute a default tile size based on the image 248 * characteristics and a requested value. If a 249 * request is <1 then we choose a size according 250 * to certain heuristics. 251 */ 252 void 253 TIFFDefaultTileSize(TIFF* tif, uint32* tw, uint32* th) 254 { 255 (*tif->tif_deftilesize)(tif, tw, th); 256 } 257 258 void 259 _TIFFDefaultTileSize(TIFF* tif, uint32* tw, uint32* th) 260 { 261 (void) tif; 262 if (*(int32*) tw < 1) 263 *tw = 256; 264 if (*(int32*) th < 1) 265 *th = 256; 266 /* roundup to a multiple of 16 per the spec */ 267 if (*tw & 0xf) 268 *tw = TIFFroundup(*tw, 16); 269 if (*th & 0xf) 270 *th = TIFFroundup(*th, 16); 271 } 272 273 /* vim: set ts=8 sts=8 sw=8 noet: */ 274 /* 275 * Local Variables: 276 * mode: c 277 * c-basic-offset: 8 278 * fill-column: 78 279 * End: 280 */ 281