1 : /* $Id: tif_tile.c,v 1.23 2012-06-06 05:33:55 fwarmerdam 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 1 : TIFFComputeTile(TIFF* tif, uint32 x, uint32 y, uint32 z, uint16 s)
39 : {
40 1 : TIFFDirectory *td = &tif->tif_dir;
41 1 : uint32 dx = td->td_tilewidth;
42 1 : uint32 dy = td->td_tilelength;
43 1 : uint32 dz = td->td_tiledepth;
44 1 : uint32 tile = 1;
45 :
46 1 : if (td->td_imagedepth == 1)
47 1 : z = 0;
48 1 : if (dx == (uint32) -1)
49 0 : dx = td->td_imagewidth;
50 1 : if (dy == (uint32) -1)
51 0 : dy = td->td_imagelength;
52 1 : if (dz == (uint32) -1)
53 0 : dz = td->td_imagedepth;
54 1 : if (dx != 0 && dy != 0 && dz != 0) {
55 1 : uint32 xpt = TIFFhowmany_32(td->td_imagewidth, dx);
56 1 : uint32 ypt = TIFFhowmany_32(td->td_imagelength, dy);
57 1 : uint32 zpt = TIFFhowmany_32(td->td_imagedepth, dz);
58 :
59 1 : if (td->td_planarconfig == PLANARCONFIG_SEPARATE)
60 0 : tile = (xpt*ypt*zpt)*s +
61 0 : (xpt*ypt)*(z/dz) +
62 0 : xpt*(y/dy) +
63 0 : x/dx;
64 : else
65 1 : tile = (xpt*ypt)*(z/dz) + xpt*(y/dy) + x/dx;
66 : }
67 1 : return (tile);
68 : }
69 :
70 : /*
71 : * Check an (x,y,z,s) coordinate
72 : * against the image bounds.
73 : */
74 : int
75 1 : TIFFCheckTile(TIFF* tif, uint32 x, uint32 y, uint32 z, uint16 s)
76 : {
77 1 : TIFFDirectory *td = &tif->tif_dir;
78 :
79 1 : if (x >= td->td_imagewidth) {
80 0 : TIFFErrorExt(tif->tif_clientdata, tif->tif_name,
81 : "%lu: Col out of range, max %lu",
82 : (unsigned long) x,
83 0 : (unsigned long) (td->td_imagewidth - 1));
84 0 : return (0);
85 : }
86 1 : if (y >= td->td_imagelength) {
87 0 : TIFFErrorExt(tif->tif_clientdata, tif->tif_name,
88 : "%lu: Row out of range, max %lu",
89 : (unsigned long) y,
90 0 : (unsigned long) (td->td_imagelength - 1));
91 0 : return (0);
92 : }
93 1 : if (z >= td->td_imagedepth) {
94 0 : TIFFErrorExt(tif->tif_clientdata, tif->tif_name,
95 : "%lu: Depth out of range, max %lu",
96 : (unsigned long) z,
97 0 : (unsigned long) (td->td_imagedepth - 1));
98 0 : return (0);
99 : }
100 1 : if (td->td_planarconfig == PLANARCONFIG_SEPARATE &&
101 0 : s >= td->td_samplesperpixel) {
102 0 : TIFFErrorExt(tif->tif_clientdata, tif->tif_name,
103 : "%lu: Sample out of range, max %lu",
104 : (unsigned long) s,
105 0 : (unsigned long) (td->td_samplesperpixel - 1));
106 0 : return (0);
107 : }
108 1 : return (1);
109 : }
110 :
111 : /*
112 : * Compute how many tiles are in an image.
113 : */
114 : uint32
115 2434 : TIFFNumberOfTiles(TIFF* tif)
116 : {
117 2434 : TIFFDirectory *td = &tif->tif_dir;
118 2434 : uint32 dx = td->td_tilewidth;
119 2434 : uint32 dy = td->td_tilelength;
120 2434 : uint32 dz = td->td_tiledepth;
121 : uint32 ntiles;
122 :
123 2434 : if (dx == (uint32) -1)
124 0 : dx = td->td_imagewidth;
125 2434 : if (dy == (uint32) -1)
126 0 : dy = td->td_imagelength;
127 2434 : if (dz == (uint32) -1)
128 0 : dz = td->td_imagedepth;
129 4868 : ntiles = (dx == 0 || dy == 0 || dz == 0) ? 0 :
130 9736 : _TIFFMultiply32(tif, _TIFFMultiply32(tif, TIFFhowmany_32(td->td_imagewidth, dx),
131 4868 : TIFFhowmany_32(td->td_imagelength, dy),
132 : "TIFFNumberOfTiles"),
133 4868 : TIFFhowmany_32(td->td_imagedepth, dz), "TIFFNumberOfTiles");
134 2434 : if (td->td_planarconfig == PLANARCONFIG_SEPARATE)
135 420 : ntiles = _TIFFMultiply32(tif, ntiles, td->td_samplesperpixel,
136 : "TIFFNumberOfTiles");
137 2434 : return (ntiles);
138 : }
139 :
140 : /*
141 : * Compute the # bytes in each row of a tile.
142 : */
143 : uint64
144 31362 : TIFFTileRowSize64(TIFF* tif)
145 : {
146 31362 : TIFFDirectory *td = &tif->tif_dir;
147 : uint64 rowsize;
148 :
149 31362 : if (td->td_tilelength == 0 || td->td_tilewidth == 0)
150 0 : return (0);
151 31362 : rowsize = _TIFFMultiply64(tif, td->td_bitspersample, td->td_tilewidth,
152 : "TIFFTileRowSize");
153 31362 : if (td->td_planarconfig == PLANARCONFIG_CONTIG)
154 28967 : rowsize = _TIFFMultiply64(tif, rowsize, td->td_samplesperpixel,
155 : "TIFFTileRowSize");
156 31362 : return (TIFFhowmany8_64(rowsize));
157 : }
158 : tmsize_t
159 657 : TIFFTileRowSize(TIFF* tif)
160 : {
161 : static const char module[] = "TIFFTileRowSize";
162 : uint64 m;
163 : tmsize_t n;
164 657 : m=TIFFTileRowSize64(tif);
165 657 : n=(tmsize_t)m;
166 657 : if ((uint64)n!=m)
167 : {
168 0 : TIFFErrorExt(tif->tif_clientdata,module,"Integer overflow");
169 0 : n=0;
170 : }
171 657 : return(n);
172 : }
173 :
174 : /*
175 : * Compute the # bytes in a variable length, row-aligned tile.
176 : */
177 : uint64
178 31176 : TIFFVTileSize64(TIFF* tif, uint32 nrows)
179 : {
180 : static const char module[] = "TIFFVTileSize64";
181 31176 : TIFFDirectory *td = &tif->tif_dir;
182 62352 : if (td->td_tilelength == 0 || td->td_tilewidth == 0 ||
183 31176 : td->td_tiledepth == 0)
184 0 : return (0);
185 65513 : if ((td->td_planarconfig==PLANARCONFIG_CONTIG)&&
186 28821 : (td->td_photometric==PHOTOMETRIC_YCBCR)&&
187 2758 : (td->td_samplesperpixel==3)&&
188 2758 : (!isUpSampled(tif)))
189 : {
190 : /*
191 : * Packed YCbCr data contain one Cb+Cr for every
192 : * HorizontalSampling*VerticalSampling Y values.
193 : * Must also roundup width and height when calculating
194 : * since images that are not a multiple of the
195 : * horizontal/vertical subsampling area include
196 : * YCbCr data for the extended image.
197 : */
198 : uint16 ycbcrsubsampling[2];
199 : uint16 samplingblock_samples;
200 : uint32 samplingblocks_hor;
201 : uint32 samplingblocks_ver;
202 : uint64 samplingrow_samples;
203 : uint64 samplingrow_size;
204 471 : TIFFGetFieldDefaulted(tif,TIFFTAG_YCBCRSUBSAMPLING,ycbcrsubsampling+0,
205 : ycbcrsubsampling+1);
206 1413 : if ((ycbcrsubsampling[0] != 1 && ycbcrsubsampling[0] != 2 && ycbcrsubsampling[0] != 4)
207 942 : ||(ycbcrsubsampling[1] != 1 && ycbcrsubsampling[1] != 2 && ycbcrsubsampling[1] != 4))
208 : {
209 0 : TIFFErrorExt(tif->tif_clientdata,module,
210 : "Invalid YCbCr subsampling (%dx%d)",
211 0 : ycbcrsubsampling[0],
212 0 : ycbcrsubsampling[1] );
213 0 : return 0;
214 : }
215 471 : samplingblock_samples=ycbcrsubsampling[0]*ycbcrsubsampling[1]+2;
216 471 : samplingblocks_hor=TIFFhowmany_32(td->td_tilewidth,ycbcrsubsampling[0]);
217 471 : samplingblocks_ver=TIFFhowmany_32(nrows,ycbcrsubsampling[1]);
218 471 : samplingrow_samples=_TIFFMultiply64(tif,samplingblocks_hor,samplingblock_samples,module);
219 471 : samplingrow_size=TIFFhowmany8_64(_TIFFMultiply64(tif,samplingrow_samples,td->td_bitspersample,module));
220 471 : return(_TIFFMultiply64(tif,samplingrow_size,samplingblocks_ver,module));
221 : }
222 : else
223 30705 : return(_TIFFMultiply64(tif,nrows,TIFFTileRowSize64(tif),module));
224 : }
225 : tmsize_t
226 0 : TIFFVTileSize(TIFF* tif, uint32 nrows)
227 : {
228 : static const char module[] = "TIFFVTileSize";
229 : uint64 m;
230 : tmsize_t n;
231 0 : m=TIFFVTileSize64(tif,nrows);
232 0 : n=(tmsize_t)m;
233 0 : if ((uint64)n!=m)
234 : {
235 0 : TIFFErrorExt(tif->tif_clientdata,module,"Integer overflow");
236 0 : n=0;
237 : }
238 0 : return(n);
239 : }
240 :
241 : /*
242 : * Compute the # bytes in a row-aligned tile.
243 : */
244 : uint64
245 27759 : TIFFTileSize64(TIFF* tif)
246 : {
247 27759 : return (TIFFVTileSize64(tif, tif->tif_dir.td_tilelength));
248 : }
249 : tmsize_t
250 27759 : TIFFTileSize(TIFF* tif)
251 : {
252 : static const char module[] = "TIFFTileSize";
253 : uint64 m;
254 : tmsize_t n;
255 27759 : m=TIFFTileSize64(tif);
256 27759 : n=(tmsize_t)m;
257 27759 : if ((uint64)n!=m)
258 : {
259 0 : TIFFErrorExt(tif->tif_clientdata,module,"Integer overflow");
260 0 : n=0;
261 : }
262 27759 : return(n);
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
272 0 : TIFFDefaultTileSize(TIFF* tif, uint32* tw, uint32* th)
273 : {
274 0 : (*tif->tif_deftilesize)(tif, tw, th);
275 0 : }
276 :
277 : void
278 0 : _TIFFDefaultTileSize(TIFF* tif, uint32* tw, uint32* th)
279 : {
280 : (void) tif;
281 0 : if (*(int32*) tw < 1)
282 0 : *tw = 256;
283 0 : if (*(int32*) th < 1)
284 0 : *th = 256;
285 : /* roundup to a multiple of 16 per the spec */
286 0 : if (*tw & 0xf)
287 0 : *tw = TIFFroundup_32(*tw, 16);
288 0 : if (*th & 0xf)
289 0 : *th = TIFFroundup_32(*th, 16);
290 0 : }
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 : */
|