1 : /* $Id: tif_strip.c,v 1.35 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 : * 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 9270 : TIFFNumberOfStrips(TIFF* tif)
62 : {
63 9270 : TIFFDirectory *td = &tif->tif_dir;
64 : uint32 nstrips;
65 :
66 18498 : nstrips = (td->td_rowsperstrip == (uint32) -1 ? 1 :
67 9228 : TIFFhowmany_32(td->td_imagelength, td->td_rowsperstrip));
68 9270 : if (td->td_planarconfig == PLANARCONFIG_SEPARATE)
69 110 : nstrips = _TIFFMultiply32(tif, nstrips, (uint32)td->td_samplesperpixel,
70 : "TIFFNumberOfStrips");
71 9270 : return (nstrips);
72 : }
73 :
74 : /*
75 : * Compute the # bytes in a variable height, row-aligned strip.
76 : */
77 : uint64
78 204274 : TIFFVStripSize64(TIFF* tif, uint32 nrows)
79 : {
80 : static const char module[] = "TIFFVStripSize64";
81 204274 : TIFFDirectory *td = &tif->tif_dir;
82 204274 : if (nrows==(uint32)(-1))
83 0 : nrows=td->td_imagelength;
84 347345 : if ((td->td_planarconfig==PLANARCONFIG_CONTIG)&&
85 137968 : (td->td_photometric == PHOTOMETRIC_YCBCR)&&
86 5103 : (!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 114 : if(td->td_samplesperpixel!=3)
103 : {
104 0 : TIFFErrorExt(tif->tif_clientdata,module,
105 : "Invalid td_samplesperpixel value");
106 0 : return 0;
107 : }
108 114 : TIFFGetFieldDefaulted(tif,TIFFTAG_YCBCRSUBSAMPLING,ycbcrsubsampling+0,
109 : ycbcrsubsampling+1);
110 342 : if ((ycbcrsubsampling[0] != 1 && ycbcrsubsampling[0] != 2 && ycbcrsubsampling[0] != 4)
111 228 : ||(ycbcrsubsampling[1] != 1 && ycbcrsubsampling[1] != 2 && ycbcrsubsampling[1] != 4))
112 : {
113 0 : TIFFErrorExt(tif->tif_clientdata,module,
114 : "Invalid YCbCr subsampling (%dx%d)",
115 0 : ycbcrsubsampling[0],
116 0 : ycbcrsubsampling[1] );
117 0 : return 0;
118 : }
119 114 : samplingblock_samples=ycbcrsubsampling[0]*ycbcrsubsampling[1]+2;
120 114 : samplingblocks_hor=TIFFhowmany_32(td->td_imagewidth,ycbcrsubsampling[0]);
121 114 : samplingblocks_ver=TIFFhowmany_32(nrows,ycbcrsubsampling[1]);
122 114 : samplingrow_samples=_TIFFMultiply64(tif,samplingblocks_hor,samplingblock_samples,module);
123 114 : samplingrow_size=TIFFhowmany8_64(_TIFFMultiply64(tif,samplingrow_samples,td->td_bitspersample,module));
124 114 : return(_TIFFMultiply64(tif,samplingrow_size,samplingblocks_ver,module));
125 : }
126 : else
127 204160 : return(_TIFFMultiply64(tif,nrows,TIFFScanlineSize64(tif),module));
128 : }
129 : tmsize_t
130 7106 : TIFFVStripSize(TIFF* tif, uint32 nrows)
131 : {
132 : static const char module[] = "TIFFVStripSize";
133 : uint64 m;
134 : tmsize_t n;
135 7106 : m=TIFFVStripSize64(tif,nrows);
136 7106 : n=(tmsize_t)m;
137 7106 : if ((uint64)n!=m)
138 : {
139 0 : TIFFErrorExt(tif->tif_clientdata,module,"Integer overflow");
140 0 : n=0;
141 : }
142 7106 : return(n);
143 : }
144 :
145 : /*
146 : * Compute the # bytes in a raw strip.
147 : */
148 : uint64
149 0 : TIFFRawStripSize64(TIFF* tif, uint32 strip)
150 : {
151 : static const char module[] = "TIFFRawStripSize64";
152 0 : TIFFDirectory* td = &tif->tif_dir;
153 0 : uint64 bytecount = td->td_stripbytecount[strip];
154 :
155 0 : if (bytecount == 0)
156 : {
157 : #if defined(__WIN32__) && (defined(_MSC_VER) || defined(__MINGW32__))
158 : TIFFErrorExt(tif->tif_clientdata, module,
159 : "%I64u: Invalid strip byte count, strip %lu",
160 : (unsigned __int64) bytecount,
161 : (unsigned long) strip);
162 : #else
163 0 : TIFFErrorExt(tif->tif_clientdata, module,
164 : "%llu: Invalid strip byte count, strip %lu",
165 : (unsigned long long) bytecount,
166 : (unsigned long) strip);
167 : #endif
168 0 : bytecount = (uint64) -1;
169 : }
170 :
171 0 : return bytecount;
172 : }
173 : tmsize_t
174 0 : TIFFRawStripSize(TIFF* tif, uint32 strip)
175 : {
176 : static const char module[] = "TIFFRawStripSize";
177 : uint64 m;
178 : tmsize_t n;
179 0 : m=TIFFRawStripSize64(tif,strip);
180 0 : if (m==(uint64)(-1))
181 0 : n=(tmsize_t)(-1);
182 : else
183 : {
184 0 : n=(tmsize_t)m;
185 0 : if ((uint64)n!=m)
186 : {
187 0 : TIFFErrorExt(tif->tif_clientdata,module,"Integer overflow");
188 0 : n=0;
189 : }
190 : }
191 0 : return(n);
192 : }
193 :
194 : /*
195 : * Compute the # bytes in a (row-aligned) strip.
196 : *
197 : * Note that if RowsPerStrip is larger than the
198 : * recorded ImageLength, then the strip size is
199 : * truncated to reflect the actual space required
200 : * to hold the strip.
201 : */
202 : uint64
203 197168 : TIFFStripSize64(TIFF* tif)
204 : {
205 197168 : TIFFDirectory* td = &tif->tif_dir;
206 197168 : uint32 rps = td->td_rowsperstrip;
207 197168 : if (rps > td->td_imagelength)
208 77 : rps = td->td_imagelength;
209 197168 : return (TIFFVStripSize64(tif, rps));
210 : }
211 : tmsize_t
212 197168 : TIFFStripSize(TIFF* tif)
213 : {
214 : static const char module[] = "TIFFStripSize";
215 : uint64 m;
216 : tmsize_t n;
217 197168 : m=TIFFStripSize64(tif);
218 197168 : n=(tmsize_t)m;
219 197168 : if ((uint64)n!=m)
220 : {
221 0 : TIFFErrorExt(tif->tif_clientdata,module,"Integer overflow");
222 0 : n=0;
223 : }
224 197168 : return(n);
225 : }
226 :
227 : /*
228 : * Compute a default strip size based on the image
229 : * characteristics and a requested value. If the
230 : * request is <1 then we choose a strip size according
231 : * to certain heuristics.
232 : */
233 : uint32
234 1395 : TIFFDefaultStripSize(TIFF* tif, uint32 request)
235 : {
236 1395 : return (*tif->tif_defstripsize)(tif, request);
237 : }
238 :
239 : uint32
240 1395 : _TIFFDefaultStripSize(TIFF* tif, uint32 s)
241 : {
242 1395 : if ((int32) s < 1) {
243 : /*
244 : * If RowsPerStrip is unspecified, try to break the
245 : * image up into strips that are approximately
246 : * STRIP_SIZE_DEFAULT bytes long.
247 : */
248 : uint64 scanlinesize;
249 : uint64 rows;
250 1395 : scanlinesize=TIFFScanlineSize64(tif);
251 1395 : if (scanlinesize==0)
252 0 : scanlinesize=1;
253 1395 : rows=(uint64)STRIP_SIZE_DEFAULT/scanlinesize;
254 1395 : if (rows==0)
255 24 : rows=1;
256 1371 : else if (rows>0xFFFFFFFF)
257 0 : rows=0xFFFFFFFF;
258 1395 : s=(uint32)rows;
259 : }
260 1395 : return (s);
261 : }
262 :
263 : /*
264 : * Return the number of bytes to read/write in a call to
265 : * one of the scanline-oriented i/o routines. Note that
266 : * this number may be 1/samples-per-pixel if data is
267 : * stored as separate planes.
268 : * The ScanlineSize in case of YCbCrSubsampling is defined as the
269 : * strip size divided by the strip height, i.e. the size of a pack of vertical
270 : * subsampling lines divided by vertical subsampling. It should thus make
271 : * sense when multiplied by a multiple of vertical subsampling.
272 : */
273 : uint64
274 256959 : TIFFScanlineSize64(TIFF* tif)
275 : {
276 : static const char module[] = "TIFFScanlineSize64";
277 256959 : TIFFDirectory *td = &tif->tif_dir;
278 : uint64 scanline_size;
279 256959 : if (td->td_planarconfig==PLANARCONFIG_CONTIG)
280 : {
281 176025 : if ((td->td_photometric==PHOTOMETRIC_YCBCR)&&
282 7650 : (td->td_samplesperpixel==3)&&
283 7650 : (!isUpSampled(tif)))
284 : {
285 : uint16 ycbcrsubsampling[2];
286 : uint16 samplingblock_samples;
287 : uint32 samplingblocks_hor;
288 : uint64 samplingrow_samples;
289 : uint64 samplingrow_size;
290 744 : if(td->td_samplesperpixel!=3)
291 : {
292 0 : TIFFErrorExt(tif->tif_clientdata,module,
293 : "Invalid td_samplesperpixel value");
294 0 : return 0;
295 : }
296 744 : TIFFGetFieldDefaulted(tif,TIFFTAG_YCBCRSUBSAMPLING,
297 : ycbcrsubsampling+0,
298 : ycbcrsubsampling+1);
299 2232 : if (((ycbcrsubsampling[0]!=1)&&(ycbcrsubsampling[0]!=2)&&(ycbcrsubsampling[0]!=4)) ||
300 1488 : ((ycbcrsubsampling[1]!=1)&&(ycbcrsubsampling[1]!=2)&&(ycbcrsubsampling[1]!=4)))
301 : {
302 0 : TIFFErrorExt(tif->tif_clientdata,module,
303 : "Invalid YCbCr subsampling");
304 0 : return 0;
305 : }
306 744 : samplingblock_samples = ycbcrsubsampling[0]*ycbcrsubsampling[1]+2;
307 744 : samplingblocks_hor = TIFFhowmany_32(td->td_imagewidth,ycbcrsubsampling[0]);
308 744 : samplingrow_samples = _TIFFMultiply64(tif,samplingblocks_hor,samplingblock_samples,module);
309 744 : samplingrow_size = TIFFhowmany_64(_TIFFMultiply64(tif,samplingrow_samples,td->td_bitspersample,module),8);
310 744 : scanline_size = (samplingrow_size/ycbcrsubsampling[1]);
311 : }
312 : else
313 : {
314 : uint64 scanline_samples;
315 159237 : scanline_samples=_TIFFMultiply64(tif,td->td_imagewidth,td->td_samplesperpixel,module);
316 159237 : scanline_size=TIFFhowmany_64(_TIFFMultiply64(tif,scanline_samples,td->td_bitspersample,module),8);
317 : }
318 : }
319 : else
320 96978 : scanline_size=TIFFhowmany_64(_TIFFMultiply64(tif,td->td_imagewidth,td->td_bitspersample,module),8);
321 256959 : return(scanline_size);
322 : }
323 : tmsize_t
324 45595 : TIFFScanlineSize(TIFF* tif)
325 : {
326 : static const char module[] = "TIFFScanlineSize";
327 : uint64 m;
328 : tmsize_t n;
329 45595 : m=TIFFScanlineSize64(tif);
330 45595 : n=(tmsize_t)m;
331 45595 : if ((uint64)n!=m)
332 : {
333 0 : TIFFErrorExt(tif->tif_clientdata,module,"Integer arithmetic overflow");
334 0 : n=0;
335 : }
336 45595 : return(n);
337 : }
338 :
339 : /*
340 : * Return the number of bytes required to store a complete
341 : * decoded and packed raster scanline (as opposed to the
342 : * I/O size returned by TIFFScanlineSize which may be less
343 : * if data is store as separate planes).
344 : */
345 : uint64
346 0 : TIFFRasterScanlineSize64(TIFF* tif)
347 : {
348 : static const char module[] = "TIFFRasterScanlineSize64";
349 0 : TIFFDirectory *td = &tif->tif_dir;
350 : uint64 scanline;
351 :
352 0 : scanline = _TIFFMultiply64(tif, td->td_bitspersample, td->td_imagewidth, module);
353 0 : if (td->td_planarconfig == PLANARCONFIG_CONTIG) {
354 0 : scanline = _TIFFMultiply64(tif, scanline, td->td_samplesperpixel, module);
355 0 : return (TIFFhowmany8_64(scanline));
356 : } else
357 0 : return (_TIFFMultiply64(tif, TIFFhowmany8_64(scanline),
358 0 : td->td_samplesperpixel, module));
359 : }
360 : tmsize_t
361 0 : TIFFRasterScanlineSize(TIFF* tif)
362 : {
363 : static const char module[] = "TIFFRasterScanlineSize";
364 : uint64 m;
365 : tmsize_t n;
366 0 : m=TIFFRasterScanlineSize64(tif);
367 0 : n=(tmsize_t)m;
368 0 : if ((uint64)n!=m)
369 : {
370 0 : TIFFErrorExt(tif->tif_clientdata,module,"Integer arithmetic overflow");
371 0 : n=0;
372 : }
373 0 : return(n);
374 : }
375 :
376 : /* vim: set ts=8 sts=8 sw=8 noet: */
377 : /*
378 : * Local Variables:
379 : * mode: c
380 : * c-basic-offset: 8
381 : * fill-column: 78
382 : * End:
383 : */
|