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