blob: 0ff7e85352ddd1755561989081be7faad8627c24
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 | TIFFComputeTile(TIFF* tif, uint32 x, uint32 y, uint32 z, uint16 s) |
39 | { |
40 | TIFFDirectory *td = &tif->tif_dir; |
41 | uint32 dx = td->td_tilewidth; |
42 | uint32 dy = td->td_tilelength; |
43 | uint32 dz = td->td_tiledepth; |
44 | uint32 tile = 1; |
45 | |
46 | if (td->td_imagedepth == 1) |
47 | z = 0; |
48 | if (dx == (uint32) -1) |
49 | dx = td->td_imagewidth; |
50 | if (dy == (uint32) -1) |
51 | dy = td->td_imagelength; |
52 | if (dz == (uint32) -1) |
53 | dz = td->td_imagedepth; |
54 | if (dx != 0 && dy != 0 && dz != 0) { |
55 | uint32 xpt = TIFFhowmany_32(td->td_imagewidth, dx); |
56 | uint32 ypt = TIFFhowmany_32(td->td_imagelength, dy); |
57 | uint32 zpt = TIFFhowmany_32(td->td_imagedepth, dz); |
58 | |
59 | if (td->td_planarconfig == PLANARCONFIG_SEPARATE) |
60 | tile = (xpt*ypt*zpt)*s + |
61 | (xpt*ypt)*(z/dz) + |
62 | xpt*(y/dy) + |
63 | x/dx; |
64 | else |
65 | tile = (xpt*ypt)*(z/dz) + xpt*(y/dy) + x/dx; |
66 | } |
67 | return (tile); |
68 | } |
69 | |
70 | /* |
71 | * Check an (x,y,z,s) coordinate |
72 | * against the image bounds. |
73 | */ |
74 | int |
75 | TIFFCheckTile(TIFF* tif, uint32 x, uint32 y, uint32 z, uint16 s) |
76 | { |
77 | TIFFDirectory *td = &tif->tif_dir; |
78 | |
79 | if (x >= td->td_imagewidth) { |
80 | TIFFErrorExt(tif->tif_clientdata, tif->tif_name, |
81 | "%lu: Col out of range, max %lu", |
82 | (unsigned long) x, |
83 | (unsigned long) (td->td_imagewidth - 1)); |
84 | return (0); |
85 | } |
86 | if (y >= td->td_imagelength) { |
87 | TIFFErrorExt(tif->tif_clientdata, tif->tif_name, |
88 | "%lu: Row out of range, max %lu", |
89 | (unsigned long) y, |
90 | (unsigned long) (td->td_imagelength - 1)); |
91 | return (0); |
92 | } |
93 | if (z >= td->td_imagedepth) { |
94 | TIFFErrorExt(tif->tif_clientdata, tif->tif_name, |
95 | "%lu: Depth out of range, max %lu", |
96 | (unsigned long) z, |
97 | (unsigned long) (td->td_imagedepth - 1)); |
98 | return (0); |
99 | } |
100 | if (td->td_planarconfig == PLANARCONFIG_SEPARATE && |
101 | s >= td->td_samplesperpixel) { |
102 | TIFFErrorExt(tif->tif_clientdata, tif->tif_name, |
103 | "%lu: Sample out of range, max %lu", |
104 | (unsigned long) s, |
105 | (unsigned long) (td->td_samplesperpixel - 1)); |
106 | return (0); |
107 | } |
108 | return (1); |
109 | } |
110 | |
111 | /* |
112 | * Compute how many tiles are in an image. |
113 | */ |
114 | uint32 |
115 | TIFFNumberOfTiles(TIFF* tif) |
116 | { |
117 | TIFFDirectory *td = &tif->tif_dir; |
118 | uint32 dx = td->td_tilewidth; |
119 | uint32 dy = td->td_tilelength; |
120 | uint32 dz = td->td_tiledepth; |
121 | uint32 ntiles; |
122 | |
123 | if (dx == (uint32) -1) |
124 | dx = td->td_imagewidth; |
125 | if (dy == (uint32) -1) |
126 | dy = td->td_imagelength; |
127 | if (dz == (uint32) -1) |
128 | dz = td->td_imagedepth; |
129 | ntiles = (dx == 0 || dy == 0 || dz == 0) ? 0 : |
130 | _TIFFMultiply32(tif, _TIFFMultiply32(tif, TIFFhowmany_32(td->td_imagewidth, dx), |
131 | TIFFhowmany_32(td->td_imagelength, dy), |
132 | "TIFFNumberOfTiles"), |
133 | TIFFhowmany_32(td->td_imagedepth, dz), "TIFFNumberOfTiles"); |
134 | if (td->td_planarconfig == PLANARCONFIG_SEPARATE) |
135 | ntiles = _TIFFMultiply32(tif, ntiles, td->td_samplesperpixel, |
136 | "TIFFNumberOfTiles"); |
137 | return (ntiles); |
138 | } |
139 | |
140 | /* |
141 | * Compute the # bytes in each row of a tile. |
142 | */ |
143 | uint64 |
144 | TIFFTileRowSize64(TIFF* tif) |
145 | { |
146 | TIFFDirectory *td = &tif->tif_dir; |
147 | uint64 rowsize; |
148 | |
149 | if (td->td_tilelength == 0 || td->td_tilewidth == 0) |
150 | return (0); |
151 | rowsize = _TIFFMultiply64(tif, td->td_bitspersample, td->td_tilewidth, |
152 | "TIFFTileRowSize"); |
153 | if (td->td_planarconfig == PLANARCONFIG_CONTIG) |
154 | rowsize = _TIFFMultiply64(tif, rowsize, td->td_samplesperpixel, |
155 | "TIFFTileRowSize"); |
156 | return (TIFFhowmany8_64(rowsize)); |
157 | } |
158 | tmsize_t |
159 | TIFFTileRowSize(TIFF* tif) |
160 | { |
161 | static const char module[] = "TIFFTileRowSize"; |
162 | uint64 m; |
163 | tmsize_t n; |
164 | m=TIFFTileRowSize64(tif); |
165 | n=(tmsize_t)m; |
166 | if ((uint64)n!=m) |
167 | { |
168 | TIFFErrorExt(tif->tif_clientdata,module,"Integer overflow"); |
169 | n=0; |
170 | } |
171 | return(n); |
172 | } |
173 | |
174 | /* |
175 | * Compute the # bytes in a variable length, row-aligned tile. |
176 | */ |
177 | uint64 |
178 | TIFFVTileSize64(TIFF* tif, uint32 nrows) |
179 | { |
180 | static const char module[] = "TIFFVTileSize64"; |
181 | TIFFDirectory *td = &tif->tif_dir; |
182 | if (td->td_tilelength == 0 || td->td_tilewidth == 0 || |
183 | td->td_tiledepth == 0) |
184 | return (0); |
185 | if ((td->td_planarconfig==PLANARCONFIG_CONTIG)&& |
186 | (td->td_photometric==PHOTOMETRIC_YCBCR)&& |
187 | (td->td_samplesperpixel==3)&& |
188 | (!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 | TIFFGetFieldDefaulted(tif,TIFFTAG_YCBCRSUBSAMPLING,ycbcrsubsampling+0, |
205 | ycbcrsubsampling+1); |
206 | if ((ycbcrsubsampling[0] != 1 && ycbcrsubsampling[0] != 2 && ycbcrsubsampling[0] != 4) |
207 | ||(ycbcrsubsampling[1] != 1 && ycbcrsubsampling[1] != 2 && ycbcrsubsampling[1] != 4)) |
208 | { |
209 | TIFFErrorExt(tif->tif_clientdata,module, |
210 | "Invalid YCbCr subsampling (%dx%d)", |
211 | ycbcrsubsampling[0], |
212 | ycbcrsubsampling[1] ); |
213 | return 0; |
214 | } |
215 | samplingblock_samples=ycbcrsubsampling[0]*ycbcrsubsampling[1]+2; |
216 | samplingblocks_hor=TIFFhowmany_32(td->td_tilewidth,ycbcrsubsampling[0]); |
217 | samplingblocks_ver=TIFFhowmany_32(nrows,ycbcrsubsampling[1]); |
218 | samplingrow_samples=_TIFFMultiply64(tif,samplingblocks_hor,samplingblock_samples,module); |
219 | samplingrow_size=TIFFhowmany8_64(_TIFFMultiply64(tif,samplingrow_samples,td->td_bitspersample,module)); |
220 | return(_TIFFMultiply64(tif,samplingrow_size,samplingblocks_ver,module)); |
221 | } |
222 | else |
223 | return(_TIFFMultiply64(tif,nrows,TIFFTileRowSize64(tif),module)); |
224 | } |
225 | tmsize_t |
226 | TIFFVTileSize(TIFF* tif, uint32 nrows) |
227 | { |
228 | static const char module[] = "TIFFVTileSize"; |
229 | uint64 m; |
230 | tmsize_t n; |
231 | m=TIFFVTileSize64(tif,nrows); |
232 | n=(tmsize_t)m; |
233 | if ((uint64)n!=m) |
234 | { |
235 | TIFFErrorExt(tif->tif_clientdata,module,"Integer overflow"); |
236 | n=0; |
237 | } |
238 | return(n); |
239 | } |
240 | |
241 | /* |
242 | * Compute the # bytes in a row-aligned tile. |
243 | */ |
244 | uint64 |
245 | TIFFTileSize64(TIFF* tif) |
246 | { |
247 | return (TIFFVTileSize64(tif, tif->tif_dir.td_tilelength)); |
248 | } |
249 | tmsize_t |
250 | TIFFTileSize(TIFF* tif) |
251 | { |
252 | static const char module[] = "TIFFTileSize"; |
253 | uint64 m; |
254 | tmsize_t n; |
255 | m=TIFFTileSize64(tif); |
256 | n=(tmsize_t)m; |
257 | if ((uint64)n!=m) |
258 | { |
259 | TIFFErrorExt(tif->tif_clientdata,module,"Integer overflow"); |
260 | n=0; |
261 | } |
262 | 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 | TIFFDefaultTileSize(TIFF* tif, uint32* tw, uint32* th) |
273 | { |
274 | (*tif->tif_deftilesize)(tif, tw, th); |
275 | } |
276 | |
277 | void |
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 |