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 	m=TIFFTileRowSize64(tif);
185 	return _TIFFCastUInt64ToSSize(tif, m, module);
186 }
187 
188 /*
189  * Compute the # bytes in a variable length, row-aligned tile.
190  */
191 uint64
TIFFVTileSize64(TIFF * tif,uint32 nrows)192 TIFFVTileSize64(TIFF* tif, uint32 nrows)
193 {
194 	static const char module[] = "TIFFVTileSize64";
195 	TIFFDirectory *td = &tif->tif_dir;
196 	if (td->td_tilelength == 0 || td->td_tilewidth == 0 ||
197 	    td->td_tiledepth == 0)
198 		return (0);
199 	if ((td->td_planarconfig==PLANARCONFIG_CONTIG)&&
200 	    (td->td_photometric==PHOTOMETRIC_YCBCR)&&
201 	    (td->td_samplesperpixel==3)&&
202 	    (!isUpSampled(tif)))
203 	{
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 		uint16 ycbcrsubsampling[2];
213 		uint16 samplingblock_samples;
214 		uint32 samplingblocks_hor;
215 		uint32 samplingblocks_ver;
216 		uint64 samplingrow_samples;
217 		uint64 samplingrow_size;
218 		TIFFGetFieldDefaulted(tif,TIFFTAG_YCBCRSUBSAMPLING,ycbcrsubsampling+0,
219 		    ycbcrsubsampling+1);
220 		if ((ycbcrsubsampling[0] != 1 && ycbcrsubsampling[0] != 2 && ycbcrsubsampling[0] != 4)
221 		    ||(ycbcrsubsampling[1] != 1 && ycbcrsubsampling[1] != 2 && ycbcrsubsampling[1] != 4))
222 		{
223 			TIFFErrorExt(tif->tif_clientdata,module,
224 				     "Invalid YCbCr subsampling (%dx%d)",
225 				     ycbcrsubsampling[0],
226 				     ycbcrsubsampling[1] );
227 			return 0;
228 		}
229 		samplingblock_samples=ycbcrsubsampling[0]*ycbcrsubsampling[1]+2;
230 		samplingblocks_hor=TIFFhowmany_32(td->td_tilewidth,ycbcrsubsampling[0]);
231 		samplingblocks_ver=TIFFhowmany_32(nrows,ycbcrsubsampling[1]);
232 		samplingrow_samples=_TIFFMultiply64(tif,samplingblocks_hor,samplingblock_samples,module);
233 		samplingrow_size=TIFFhowmany8_64(_TIFFMultiply64(tif,samplingrow_samples,td->td_bitspersample,module));
234 		return(_TIFFMultiply64(tif,samplingrow_size,samplingblocks_ver,module));
235 	}
236 	else
237 		return(_TIFFMultiply64(tif,nrows,TIFFTileRowSize64(tif),module));
238 }
239 tmsize_t
TIFFVTileSize(TIFF * tif,uint32 nrows)240 TIFFVTileSize(TIFF* tif, uint32 nrows)
241 {
242 	static const char module[] = "TIFFVTileSize";
243 	uint64 m;
244 	m=TIFFVTileSize64(tif,nrows);
245 	return _TIFFCastUInt64ToSSize(tif, m, module);
246 }
247 
248 /*
249  * Compute the # bytes in a row-aligned tile.
250  */
251 uint64
TIFFTileSize64(TIFF * tif)252 TIFFTileSize64(TIFF* tif)
253 {
254 	return (TIFFVTileSize64(tif, tif->tif_dir.td_tilelength));
255 }
256 tmsize_t
TIFFTileSize(TIFF * tif)257 TIFFTileSize(TIFF* tif)
258 {
259 	static const char module[] = "TIFFTileSize";
260 	uint64 m;
261 	m=TIFFTileSize64(tif);
262 	return _TIFFCastUInt64ToSSize(tif, m, module);
263 }
264 
265 /*
266  * Compute a default tile size based on the image
267  * characteristics and a requested value.  If a
268  * request is <1 then we choose a size according
269  * to certain heuristics.
270  */
271 void
TIFFDefaultTileSize(TIFF * tif,uint32 * tw,uint32 * th)272 TIFFDefaultTileSize(TIFF* tif, uint32* tw, uint32* th)
273 {
274 	(*tif->tif_deftilesize)(tif, tw, th);
275 }
276 
277 void
_TIFFDefaultTileSize(TIFF * tif,uint32 * tw,uint32 * th)278 _TIFFDefaultTileSize(TIFF* tif, uint32* tw, uint32* th)
279 {
280 	(void) tif;
281 	if (*(int32*) tw < 1)
282 		*tw = 256;
283 	if (*(int32*) th < 1)
284 		*th = 256;
285 	/* roundup to a multiple of 16 per the spec */
286 	if (*tw & 0xf)
287 		*tw = TIFFroundup_32(*tw, 16);
288 	if (*th & 0xf)
289 		*th = TIFFroundup_32(*th, 16);
290 }
291 
292 /* vim: set ts=8 sts=8 sw=8 noet: */
293 /*
294  * Local Variables:
295  * mode: c
296  * c-basic-offset: 8
297  * fill-column: 78
298  * End:
299  */
300