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