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