1 : /* $Id: tif_strip.c,v 1.34 2011-04-02 20:54:09 bfriesen 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 : * Strip-organized Image Support Routines.
31 : */
32 : #include "tiffiop.h"
33 :
34 : /*
35 : * Compute which strip a (row,sample) value is in.
36 : */
37 : uint32
38 3 : TIFFComputeStrip(TIFF* tif, uint32 row, uint16 sample)
39 : {
40 : static const char module[] = "TIFFComputeStrip";
41 3 : TIFFDirectory *td = &tif->tif_dir;
42 : uint32 strip;
43 :
44 3 : strip = row / td->td_rowsperstrip;
45 3 : if (td->td_planarconfig == PLANARCONFIG_SEPARATE) {
46 0 : if (sample >= td->td_samplesperpixel) {
47 0 : TIFFErrorExt(tif->tif_clientdata, module,
48 : "%lu: Sample out of range, max %lu",
49 : (unsigned long) sample, (unsigned long) td->td_samplesperpixel);
50 0 : return (0);
51 : }
52 0 : strip += (uint32)sample*td->td_stripsperimage;
53 : }
54 3 : return (strip);
55 : }
56 :
57 : /*
58 : * Compute how many strips are in an image.
59 : */
60 : uint32
61 6022 : TIFFNumberOfStrips(TIFF* tif)
62 : {
63 6022 : TIFFDirectory *td = &tif->tif_dir;
64 : uint32 nstrips;
65 :
66 12013 : nstrips = (td->td_rowsperstrip == (uint32) -1 ? 1 :
67 5991 : TIFFhowmany_32(td->td_imagelength, td->td_rowsperstrip));
68 6022 : if (td->td_planarconfig == PLANARCONFIG_SEPARATE)
69 101 : nstrips = _TIFFMultiply32(tif, nstrips, (uint32)td->td_samplesperpixel,
70 : "TIFFNumberOfStrips");
71 6022 : return (nstrips);
72 : }
73 :
74 : /*
75 : * Compute the # bytes in a variable height, row-aligned strip.
76 : */
77 : uint64
78 195061 : TIFFVStripSize64(TIFF* tif, uint32 nrows)
79 : {
80 : static const char module[] = "TIFFVStripSize64";
81 195061 : TIFFDirectory *td = &tif->tif_dir;
82 195061 : if (nrows==(uint32)(-1))
83 0 : nrows=td->td_imagelength;
84 328986 : if ((td->td_planarconfig==PLANARCONFIG_CONTIG)&&
85 128916 : (td->td_photometric == PHOTOMETRIC_YCBCR)&&
86 5009 : (!isUpSampled(tif)))
87 : {
88 : /*
89 : * Packed YCbCr data contain one Cb+Cr for every
90 : * HorizontalSampling*VerticalSampling Y values.
91 : * Must also roundup width and height when calculating
92 : * since images that are not a multiple of the
93 : * horizontal/vertical subsampling area include
94 : * YCbCr data for the extended image.
95 : */
96 : uint16 ycbcrsubsampling[2];
97 : uint16 samplingblock_samples;
98 : uint32 samplingblocks_hor;
99 : uint32 samplingblocks_ver;
100 : uint64 samplingrow_samples;
101 : uint64 samplingrow_size;
102 110 : if(td->td_samplesperpixel!=3)
103 : {
104 0 : TIFFErrorExt(tif->tif_clientdata,module,
105 : "Invalid td_samplesperpixel value");
106 0 : return 0;
107 : }
108 110 : TIFFGetFieldDefaulted(tif,TIFFTAG_YCBCRSUBSAMPLING,ycbcrsubsampling+0,
109 : ycbcrsubsampling+1);
110 330 : if (((ycbcrsubsampling[0]!=1)&&(ycbcrsubsampling[0]!=2)&&(ycbcrsubsampling[0]!=4)) ||
111 220 : ((ycbcrsubsampling[1]!=1)&&(ycbcrsubsampling[1]!=2)&&(ycbcrsubsampling[1]!=4)))
112 : {
113 0 : TIFFErrorExt(tif->tif_clientdata,module,
114 : "Invalid YCbCr subsampling");
115 0 : return 0;
116 : }
117 110 : samplingblock_samples=ycbcrsubsampling[0]*ycbcrsubsampling[1]+2;
118 110 : samplingblocks_hor=TIFFhowmany_32(td->td_imagewidth,ycbcrsubsampling[0]);
119 110 : samplingblocks_ver=TIFFhowmany_32(nrows,ycbcrsubsampling[1]);
120 110 : samplingrow_samples=_TIFFMultiply64(tif,samplingblocks_hor,samplingblock_samples,module);
121 110 : samplingrow_size=TIFFhowmany8_64(_TIFFMultiply64(tif,samplingrow_samples,td->td_bitspersample,module));
122 110 : return(_TIFFMultiply64(tif,samplingrow_size,samplingblocks_ver,module));
123 : }
124 : else
125 194951 : return(_TIFFMultiply64(tif,nrows,TIFFScanlineSize64(tif),module));
126 : }
127 : tmsize_t
128 5959 : TIFFVStripSize(TIFF* tif, uint32 nrows)
129 : {
130 : static const char module[] = "TIFFVStripSize";
131 : uint64 m;
132 : tmsize_t n;
133 5959 : m=TIFFVStripSize64(tif,nrows);
134 5959 : n=(tmsize_t)m;
135 5959 : if ((uint64)n!=m)
136 : {
137 0 : TIFFErrorExt(tif->tif_clientdata,module,"Integer overflow");
138 0 : n=0;
139 : }
140 5959 : return(n);
141 : }
142 :
143 : /*
144 : * Compute the # bytes in a raw strip.
145 : */
146 : uint64
147 0 : TIFFRawStripSize64(TIFF* tif, uint32 strip)
148 : {
149 : static const char module[] = "TIFFRawStripSize64";
150 0 : TIFFDirectory* td = &tif->tif_dir;
151 0 : uint64 bytecount = td->td_stripbytecount[strip];
152 :
153 0 : if (bytecount == 0)
154 : {
155 : #if defined(__WIN32__) && (defined(_MSC_VER) || defined(__MINGW32__))
156 : TIFFErrorExt(tif->tif_clientdata, module,
157 : "%I64u: Invalid strip byte count, strip %lu",
158 : (unsigned __int64) bytecount,
159 : (unsigned long) strip);
160 : #else
161 0 : TIFFErrorExt(tif->tif_clientdata, module,
162 : "%llu: Invalid strip byte count, strip %lu",
163 : (unsigned long long) bytecount,
164 : (unsigned long) strip);
165 : #endif
166 0 : bytecount = (uint64) -1;
167 : }
168 :
169 0 : return bytecount;
170 : }
171 : tmsize_t
172 0 : TIFFRawStripSize(TIFF* tif, uint32 strip)
173 : {
174 : static const char module[] = "TIFFRawStripSize";
175 : uint64 m;
176 : tmsize_t n;
177 0 : m=TIFFRawStripSize64(tif,strip);
178 0 : if (m==(uint64)(-1))
179 0 : n=(tmsize_t)(-1);
180 : else
181 : {
182 0 : n=(tmsize_t)m;
183 0 : if ((uint64)n!=m)
184 : {
185 0 : TIFFErrorExt(tif->tif_clientdata,module,"Integer overflow");
186 0 : n=0;
187 : }
188 : }
189 0 : return(n);
190 : }
191 :
192 : /*
193 : * Compute the # bytes in a (row-aligned) strip.
194 : *
195 : * Note that if RowsPerStrip is larger than the
196 : * recorded ImageLength, then the strip size is
197 : * truncated to reflect the actual space required
198 : * to hold the strip.
199 : */
200 : uint64
201 189102 : TIFFStripSize64(TIFF* tif)
202 : {
203 189102 : TIFFDirectory* td = &tif->tif_dir;
204 189102 : uint32 rps = td->td_rowsperstrip;
205 189102 : if (rps > td->td_imagelength)
206 47 : rps = td->td_imagelength;
207 189102 : return (TIFFVStripSize64(tif, rps));
208 : }
209 : tmsize_t
210 189102 : TIFFStripSize(TIFF* tif)
211 : {
212 : static const char module[] = "TIFFStripSize";
213 : uint64 m;
214 : tmsize_t n;
215 189102 : m=TIFFStripSize64(tif);
216 189102 : n=(tmsize_t)m;
217 189102 : if ((uint64)n!=m)
218 : {
219 0 : TIFFErrorExt(tif->tif_clientdata,module,"Integer overflow");
220 0 : n=0;
221 : }
222 189102 : return(n);
223 : }
224 :
225 : /*
226 : * Compute a default strip size based on the image
227 : * characteristics and a requested value. If the
228 : * request is <1 then we choose a strip size according
229 : * to certain heuristics.
230 : */
231 : uint32
232 1329 : TIFFDefaultStripSize(TIFF* tif, uint32 request)
233 : {
234 1329 : return (*tif->tif_defstripsize)(tif, request);
235 : }
236 :
237 : uint32
238 1329 : _TIFFDefaultStripSize(TIFF* tif, uint32 s)
239 : {
240 1329 : if ((int32) s < 1) {
241 : /*
242 : * If RowsPerStrip is unspecified, try to break the
243 : * image up into strips that are approximately
244 : * STRIP_SIZE_DEFAULT bytes long.
245 : */
246 : uint64 scanlinesize;
247 : uint64 rows;
248 1329 : scanlinesize=TIFFScanlineSize64(tif);
249 1329 : if (scanlinesize==0)
250 0 : scanlinesize=1;
251 1329 : rows=(uint64)STRIP_SIZE_DEFAULT/scanlinesize;
252 1329 : if (rows==0)
253 24 : rows=1;
254 1305 : else if (rows>0xFFFFFFFF)
255 0 : rows=0xFFFFFFFF;
256 1329 : s=(uint32)rows;
257 : }
258 1329 : return (s);
259 : }
260 :
261 : /*
262 : * Return the number of bytes to read/write in a call to
263 : * one of the scanline-oriented i/o routines. Note that
264 : * this number may be 1/samples-per-pixel if data is
265 : * stored as separate planes.
266 : * The ScanlineSize in case of YCbCrSubsampling is defined as the
267 : * strip size divided by the strip height, i.e. the size of a pack of vertical
268 : * subsampling lines divided by vertical subsampling. It should thus make
269 : * sense when multiplied by a multiple of vertical subsampling.
270 : */
271 : uint64
272 241219 : TIFFScanlineSize64(TIFF* tif)
273 : {
274 : static const char module[] = "TIFFScanlineSize64";
275 241219 : TIFFDirectory *td = &tif->tif_dir;
276 : uint64 scanline_size;
277 241219 : if (td->td_planarconfig==PLANARCONFIG_CONTIG)
278 : {
279 160264 : if ((td->td_photometric==PHOTOMETRIC_YCBCR)&&
280 7522 : (td->td_samplesperpixel==3)&&
281 7522 : (!isUpSampled(tif)))
282 : {
283 : uint16 ycbcrsubsampling[2];
284 : uint16 samplingblock_samples;
285 : uint32 samplingblocks_hor;
286 : uint64 samplingrow_samples;
287 : uint64 samplingrow_size;
288 736 : if(td->td_samplesperpixel!=3)
289 : {
290 0 : TIFFErrorExt(tif->tif_clientdata,module,
291 : "Invalid td_samplesperpixel value");
292 0 : return 0;
293 : }
294 736 : TIFFGetFieldDefaulted(tif,TIFFTAG_YCBCRSUBSAMPLING,
295 : ycbcrsubsampling+0,
296 : ycbcrsubsampling+1);
297 2208 : if (((ycbcrsubsampling[0]!=1)&&(ycbcrsubsampling[0]!=2)&&(ycbcrsubsampling[0]!=4)) ||
298 1472 : ((ycbcrsubsampling[1]!=1)&&(ycbcrsubsampling[1]!=2)&&(ycbcrsubsampling[1]!=4)))
299 : {
300 0 : TIFFErrorExt(tif->tif_clientdata,module,
301 : "Invalid YCbCr subsampling");
302 0 : return 0;
303 : }
304 736 : samplingblock_samples = ycbcrsubsampling[0]*ycbcrsubsampling[1]+2;
305 736 : samplingblocks_hor = TIFFhowmany_32(td->td_imagewidth,ycbcrsubsampling[0]);
306 736 : samplingrow_samples = _TIFFMultiply64(tif,samplingblocks_hor,samplingblock_samples,module);
307 736 : samplingrow_size = TIFFhowmany_64(_TIFFMultiply64(tif,samplingrow_samples,td->td_bitspersample,module),8);
308 736 : scanline_size = (samplingrow_size/ycbcrsubsampling[1]);
309 : }
310 : else
311 : {
312 : uint64 scanline_samples;
313 143748 : scanline_samples=_TIFFMultiply64(tif,td->td_imagewidth,td->td_samplesperpixel,module);
314 143748 : scanline_size=TIFFhowmany_64(_TIFFMultiply64(tif,scanline_samples,td->td_bitspersample,module),8);
315 : }
316 : }
317 : else
318 96735 : scanline_size=TIFFhowmany_64(_TIFFMultiply64(tif,td->td_imagewidth,td->td_bitspersample,module),8);
319 241219 : return(scanline_size);
320 : }
321 : tmsize_t
322 41993 : TIFFScanlineSize(TIFF* tif)
323 : {
324 : static const char module[] = "TIFFScanlineSize";
325 : uint64 m;
326 : tmsize_t n;
327 41993 : m=TIFFScanlineSize64(tif);
328 41993 : n=(tmsize_t)m;
329 41993 : if ((uint64)n!=m)
330 : {
331 0 : TIFFErrorExt(tif->tif_clientdata,module,"Integer arithmetic overflow");
332 0 : n=0;
333 : }
334 41993 : return(n);
335 : }
336 :
337 : /*
338 : * Return the number of bytes required to store a complete
339 : * decoded and packed raster scanline (as opposed to the
340 : * I/O size returned by TIFFScanlineSize which may be less
341 : * if data is store as separate planes).
342 : */
343 : uint64
344 0 : TIFFRasterScanlineSize64(TIFF* tif)
345 : {
346 : static const char module[] = "TIFFRasterScanlineSize64";
347 0 : TIFFDirectory *td = &tif->tif_dir;
348 : uint64 scanline;
349 :
350 0 : scanline = _TIFFMultiply64(tif, td->td_bitspersample, td->td_imagewidth, module);
351 0 : if (td->td_planarconfig == PLANARCONFIG_CONTIG) {
352 0 : scanline = _TIFFMultiply64(tif, scanline, td->td_samplesperpixel, module);
353 0 : return (TIFFhowmany8_64(scanline));
354 : } else
355 0 : return (_TIFFMultiply64(tif, TIFFhowmany8_64(scanline),
356 0 : td->td_samplesperpixel, module));
357 : }
358 : tmsize_t
359 0 : TIFFRasterScanlineSize(TIFF* tif)
360 : {
361 : static const char module[] = "TIFFRasterScanlineSize";
362 : uint64 m;
363 : tmsize_t n;
364 0 : m=TIFFRasterScanlineSize64(tif);
365 0 : n=(tmsize_t)m;
366 0 : if ((uint64)n!=m)
367 : {
368 0 : TIFFErrorExt(tif->tif_clientdata,module,"Integer arithmetic overflow");
369 0 : n=0;
370 : }
371 0 : return(n);
372 : }
373 :
374 : /* vim: set ts=8 sts=8 sw=8 noet: */
375 : /*
376 : * Local Variables:
377 : * mode: c
378 : * c-basic-offset: 8
379 : * fill-column: 78
380 : * End:
381 : */
|