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