1/* PDFlib GmbH cvsid: $Id: tif_tile.c 14574 2005-10-29 16:27:43Z bonefish $ */
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 */
37ttile_t
38TIFFComputeTile(TIFF* tif, uint32 x, uint32 y, uint32 z, tsample_t 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	ttile_t 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(td->td_imagewidth, dx);
56		uint32 ypt = TIFFhowmany(td->td_imagelength, dy);
57		uint32 zpt = TIFFhowmany(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 + s;
66	}
67	return (tile);
68}
69
70/*
71 * Check an (x,y,z,s) coordinate
72 * against the image bounds.
73 */
74int
75TIFFCheckTile(TIFF* tif, uint32 x, uint32 y, uint32 z, tsample_t s)
76{
77	TIFFDirectory *td = &tif->tif_dir;
78
79	if (x >= td->td_imagewidth) {
80		TIFFError(tif->tif_name, "Col %ld out of range, max %lu",
81		    (long) x, (tif_long) td->td_imagewidth);
82		return (0);
83	}
84	if (y >= td->td_imagelength) {
85		TIFFError(tif->tif_name, "Row %ld out of range, max %lu",
86		    (long) y, (tif_long) td->td_imagelength);
87		return (0);
88	}
89	if (z >= td->td_imagedepth) {
90		TIFFError(tif->tif_name, "Depth %ld out of range, max %lu",
91		    (long) z, (tif_long) td->td_imagedepth);
92		return (0);
93	}
94	if (td->td_planarconfig == PLANARCONFIG_SEPARATE &&
95	    s >= td->td_samplesperpixel) {
96		TIFFError(tif->tif_name, "Sample %d out of range, max %u",
97		    (int) s, td->td_samplesperpixel);
98		return (0);
99	}
100	return (1);
101}
102
103/*
104 * Compute how many tiles are in an image.
105 */
106ttile_t
107TIFFNumberOfTiles(TIFF* tif)
108{
109	TIFFDirectory *td = &tif->tif_dir;
110	uint32 dx = td->td_tilewidth;
111	uint32 dy = td->td_tilelength;
112	uint32 dz = td->td_tiledepth;
113	ttile_t ntiles;
114
115	if (dx == (uint32) -1)
116		dx = td->td_imagewidth;
117	if (dy == (uint32) -1)
118		dy = td->td_imagelength;
119	if (dz == (uint32) -1)
120		dz = td->td_imagedepth;
121	ntiles = (dx == 0 || dy == 0 || dz == 0) ? 0 :
122	    (TIFFhowmany(td->td_imagewidth, dx) *
123	     TIFFhowmany(td->td_imagelength, dy) *
124	     TIFFhowmany(td->td_imagedepth, dz));
125	if (td->td_planarconfig == PLANARCONFIG_SEPARATE)
126		ntiles *= td->td_samplesperpixel;
127	return (ntiles);
128}
129
130/*
131 * Compute the # bytes in each row of a tile.
132 */
133tsize_t
134TIFFTileRowSize(TIFF* tif)
135{
136	TIFFDirectory *td = &tif->tif_dir;
137	tsize_t rowsize;
138
139	if (td->td_tilelength == 0 || td->td_tilewidth == 0)
140		return ((tsize_t) 0);
141	rowsize = td->td_bitspersample * td->td_tilewidth;
142	if (td->td_planarconfig == PLANARCONFIG_CONTIG)
143		rowsize *= td->td_samplesperpixel;
144	return ((tsize_t) TIFFhowmany(rowsize, 8));
145}
146
147/*
148 * Compute the # bytes in a variable length, row-aligned tile.
149 */
150tsize_t
151TIFFVTileSize(TIFF* tif, uint32 nrows)
152{
153	TIFFDirectory *td = &tif->tif_dir;
154	tsize_t tilesize;
155
156	if (td->td_tilelength == 0 || td->td_tilewidth == 0 ||
157	    td->td_tiledepth == 0)
158		return ((tsize_t) 0);
159#ifdef YCBCR_SUPPORT
160	if (td->td_planarconfig == PLANARCONFIG_CONTIG &&
161	    td->td_photometric == PHOTOMETRIC_YCBCR &&
162	    !isUpSampled(tif)) {
163		/*
164		 * Packed YCbCr data contain one Cb+Cr for every
165		 * HorizontalSampling*VerticalSampling Y values.
166		 * Must also roundup width and height when calculating
167		 * since images that are not a multiple of the
168		 * horizontal/vertical subsampling area include
169		 * YCbCr data for the extended image.
170		 */
171		tsize_t w =
172		    TIFFroundup(td->td_tilewidth, td->td_ycbcrsubsampling[0]);
173		tsize_t rowsize = TIFFhowmany(w*td->td_bitspersample, 8);
174		tsize_t samplingarea =
175		    td->td_ycbcrsubsampling[0]*td->td_ycbcrsubsampling[1];
176		nrows = TIFFroundup(nrows, td->td_ycbcrsubsampling[1]);
177		/* NB: don't need TIFFhowmany here 'cuz everything is rounded */
178		tilesize = nrows*rowsize + 2*(nrows*rowsize / samplingarea);
179	} else
180#endif
181		tilesize = nrows * TIFFTileRowSize(tif);
182	return ((tsize_t)(tilesize * td->td_tiledepth));
183}
184
185/*
186 * Compute the # bytes in a row-aligned tile.
187 */
188tsize_t
189TIFFTileSize(TIFF* tif)
190{
191	return (TIFFVTileSize(tif, tif->tif_dir.td_tilelength));
192}
193
194/*
195 * Compute a default tile size based on the image
196 * characteristics and a requested value.  If a
197 * request is <1 then we choose a size according
198 * to certain heuristics.
199 */
200void
201TIFFDefaultTileSize(TIFF* tif, uint32* tw, uint32* th)
202{
203	(*tif->tif_deftilesize)(tif, tw, th);
204}
205
206void
207_TIFFDefaultTileSize(TIFF* tif, uint32* tw, uint32* th)
208{
209	(void) tif;
210	if (*(int32*) tw < 1)
211		*tw = 256;
212	if (*(int32*) th < 1)
213		*th = 256;
214	/* roundup to a multiple of 16 per the spec */
215	if (*tw & 0xf)
216		*tw = TIFFroundup(*tw, 16);
217	if (*th & 0xf)
218		*th = TIFFroundup(*th, 16);
219}
220