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