1 /* $Id: tif_strip.c,v 1.38 2016-12-03 11:02:15 erouault Exp $ */
4 * Copyright (c) 1991-1997 Sam Leffler
5 * Copyright (c) 1991-1997 Silicon Graphics, Inc.
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.
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.
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
30 * Strip-organized Image Support Routines.
36 * Compute which strip a (row,sample) value is in.
39 TIFFComputeStrip(TIFF
* tif
, uint32 row
, uint16 sample
)
41 static const char module
[] = "TIFFComputeStrip";
42 TIFFDirectory
*td
= &tif
->tif_dir
;
45 strip
= row
/ td
->td_rowsperstrip
;
46 if (td
->td_planarconfig
== PLANARCONFIG_SEPARATE
) {
47 if (sample
>= td
->td_samplesperpixel
) {
48 TIFFErrorExt(tif
->tif_clientdata
, module
,
49 "%lu: Sample out of range, max %lu",
50 (unsigned long) sample
, (unsigned long) td
->td_samplesperpixel
);
53 strip
+= (uint32
)sample
*td
->td_stripsperimage
;
59 * Compute how many strips are in an image.
62 TIFFNumberOfStrips(TIFF
* tif
)
64 TIFFDirectory
*td
= &tif
->tif_dir
;
67 nstrips
= (td
->td_rowsperstrip
== (uint32
) -1 ? 1 :
68 TIFFhowmany_32(td
->td_imagelength
, td
->td_rowsperstrip
));
69 if (td
->td_planarconfig
== PLANARCONFIG_SEPARATE
)
70 nstrips
= _TIFFMultiply32(tif
, nstrips
, (uint32
)td
->td_samplesperpixel
,
71 "TIFFNumberOfStrips");
76 * Compute the # bytes in a variable height, row-aligned strip.
79 TIFFVStripSize64(TIFF
* tif
, uint32 nrows
)
81 static const char module
[] = "TIFFVStripSize64";
82 TIFFDirectory
*td
= &tif
->tif_dir
;
83 if (nrows
==(uint32
)(-1))
84 nrows
=td
->td_imagelength
;
85 if ((td
->td_planarconfig
==PLANARCONFIG_CONTIG
)&&
86 (td
->td_photometric
== PHOTOMETRIC_YCBCR
)&&
90 * Packed YCbCr data contain one Cb+Cr for every
91 * HorizontalSampling*VerticalSampling Y values.
92 * Must also roundup width and height when calculating
93 * since images that are not a multiple of the
94 * horizontal/vertical subsampling area include
95 * YCbCr data for the extended image.
97 uint16 ycbcrsubsampling
[2];
98 uint16 samplingblock_samples
;
99 uint32 samplingblocks_hor
;
100 uint32 samplingblocks_ver
;
101 uint64 samplingrow_samples
;
102 uint64 samplingrow_size
;
103 if(td
->td_samplesperpixel
!=3)
105 TIFFErrorExt(tif
->tif_clientdata
,module
,
106 "Invalid td_samplesperpixel value");
109 TIFFGetFieldDefaulted(tif
,TIFFTAG_YCBCRSUBSAMPLING
,ycbcrsubsampling
+0,
111 if ((ycbcrsubsampling
[0] != 1 && ycbcrsubsampling
[0] != 2 && ycbcrsubsampling
[0] != 4)
112 ||(ycbcrsubsampling
[1] != 1 && ycbcrsubsampling
[1] != 2 && ycbcrsubsampling
[1] != 4))
114 TIFFErrorExt(tif
->tif_clientdata
,module
,
115 "Invalid YCbCr subsampling (%dx%d)",
117 ycbcrsubsampling
[1] );
120 samplingblock_samples
=ycbcrsubsampling
[0]*ycbcrsubsampling
[1]+2;
121 samplingblocks_hor
=TIFFhowmany_32(td
->td_imagewidth
,ycbcrsubsampling
[0]);
122 samplingblocks_ver
=TIFFhowmany_32(nrows
,ycbcrsubsampling
[1]);
123 samplingrow_samples
=_TIFFMultiply64(tif
,samplingblocks_hor
,samplingblock_samples
,module
);
124 samplingrow_size
=TIFFhowmany8_64(_TIFFMultiply64(tif
,samplingrow_samples
,td
->td_bitspersample
,module
));
125 return(_TIFFMultiply64(tif
,samplingrow_size
,samplingblocks_ver
,module
));
128 return(_TIFFMultiply64(tif
,nrows
,TIFFScanlineSize64(tif
),module
));
131 TIFFVStripSize(TIFF
* tif
, uint32 nrows
)
133 static const char module
[] = "TIFFVStripSize";
136 m
=TIFFVStripSize64(tif
,nrows
);
140 TIFFErrorExt(tif
->tif_clientdata
,module
,"Integer overflow");
147 * Compute the # bytes in a raw strip.
150 TIFFRawStripSize64(TIFF
* tif
, uint32 strip
)
152 static const char module
[] = "TIFFRawStripSize64";
153 TIFFDirectory
* td
= &tif
->tif_dir
;
154 uint64 bytecount
= td
->td_stripbytecount
[strip
];
158 #if defined(__WIN32__) && (defined(_MSC_VER) || defined(__MINGW32__))
159 TIFFErrorExt(tif
->tif_clientdata
, module
,
160 "%I64u: Invalid strip byte count, strip %lu",
161 (unsigned __int64
) bytecount
,
162 (unsigned long) strip
);
164 TIFFErrorExt(tif
->tif_clientdata
, module
,
165 "%llu: Invalid strip byte count, strip %lu",
166 (unsigned long long) bytecount
,
167 (unsigned long) strip
);
169 bytecount
= (uint64
) -1;
175 TIFFRawStripSize(TIFF
* tif
, uint32 strip
)
177 static const char module
[] = "TIFFRawStripSize";
180 m
=TIFFRawStripSize64(tif
,strip
);
188 TIFFErrorExt(tif
->tif_clientdata
,module
,"Integer overflow");
196 * Compute the # bytes in a (row-aligned) strip.
198 * Note that if RowsPerStrip is larger than the
199 * recorded ImageLength, then the strip size is
200 * truncated to reflect the actual space required
204 TIFFStripSize64(TIFF
* tif
)
206 TIFFDirectory
* td
= &tif
->tif_dir
;
207 uint32 rps
= td
->td_rowsperstrip
;
208 if (rps
> td
->td_imagelength
)
209 rps
= td
->td_imagelength
;
210 return (TIFFVStripSize64(tif
, rps
));
213 TIFFStripSize(TIFF
* tif
)
215 static const char module
[] = "TIFFStripSize";
218 m
=TIFFStripSize64(tif
);
222 TIFFErrorExt(tif
->tif_clientdata
,module
,"Integer overflow");
229 * Compute a default strip size based on the image
230 * characteristics and a requested value. If the
231 * request is <1 then we choose a strip size according
232 * to certain heuristics.
235 TIFFDefaultStripSize(TIFF
* tif
, uint32 request
)
237 return (*tif
->tif_defstripsize
)(tif
, request
);
241 _TIFFDefaultStripSize(TIFF
* tif
, uint32 s
)
245 * If RowsPerStrip is unspecified, try to break the
246 * image up into strips that are approximately
247 * STRIP_SIZE_DEFAULT bytes long.
251 scanlinesize
=TIFFScanlineSize64(tif
);
254 rows
=(uint64
)STRIP_SIZE_DEFAULT
/scanlinesize
;
257 else if (rows
>0xFFFFFFFF)
265 * Return the number of bytes to read/write in a call to
266 * one of the scanline-oriented i/o routines. Note that
267 * this number may be 1/samples-per-pixel if data is
268 * stored as separate planes.
269 * The ScanlineSize in case of YCbCrSubsampling is defined as the
270 * strip size divided by the strip height, i.e. the size of a pack of vertical
271 * subsampling lines divided by vertical subsampling. It should thus make
272 * sense when multiplied by a multiple of vertical subsampling.
275 TIFFScanlineSize64(TIFF
* tif
)
277 static const char module
[] = "TIFFScanlineSize64";
278 TIFFDirectory
*td
= &tif
->tif_dir
;
279 uint64 scanline_size
;
280 if (td
->td_planarconfig
==PLANARCONFIG_CONTIG
)
282 if ((td
->td_photometric
==PHOTOMETRIC_YCBCR
)&&
283 (td
->td_samplesperpixel
==3)&&
286 uint16 ycbcrsubsampling
[2];
287 uint16 samplingblock_samples
;
288 uint32 samplingblocks_hor
;
289 uint64 samplingrow_samples
;
290 uint64 samplingrow_size
;
291 if(td
->td_samplesperpixel
!=3)
293 TIFFErrorExt(tif
->tif_clientdata
,module
,
294 "Invalid td_samplesperpixel value");
297 TIFFGetFieldDefaulted(tif
,TIFFTAG_YCBCRSUBSAMPLING
,
300 if (((ycbcrsubsampling
[0]!=1)&&(ycbcrsubsampling
[0]!=2)&&(ycbcrsubsampling
[0]!=4)) ||
301 ((ycbcrsubsampling
[1]!=1)&&(ycbcrsubsampling
[1]!=2)&&(ycbcrsubsampling
[1]!=4)))
303 TIFFErrorExt(tif
->tif_clientdata
,module
,
304 "Invalid YCbCr subsampling");
307 samplingblock_samples
= ycbcrsubsampling
[0]*ycbcrsubsampling
[1]+2;
308 samplingblocks_hor
= TIFFhowmany_32(td
->td_imagewidth
,ycbcrsubsampling
[0]);
309 samplingrow_samples
= _TIFFMultiply64(tif
,samplingblocks_hor
,samplingblock_samples
,module
);
310 samplingrow_size
= TIFFhowmany_64(_TIFFMultiply64(tif
,samplingrow_samples
,td
->td_bitspersample
,module
),8);
311 scanline_size
= (samplingrow_size
/ycbcrsubsampling
[1]);
315 uint64 scanline_samples
;
316 scanline_samples
=_TIFFMultiply64(tif
,td
->td_imagewidth
,td
->td_samplesperpixel
,module
);
317 scanline_size
=TIFFhowmany_64(_TIFFMultiply64(tif
,scanline_samples
,td
->td_bitspersample
,module
),8);
322 scanline_size
=TIFFhowmany_64(_TIFFMultiply64(tif
,td
->td_imagewidth
,td
->td_bitspersample
,module
),8);
324 if (scanline_size
== 0)
326 TIFFErrorExt(tif
->tif_clientdata
,module
,"Computed scanline size is zero");
329 return(scanline_size
);
332 TIFFScanlineSize(TIFF
* tif
)
334 static const char module
[] = "TIFFScanlineSize";
337 m
=TIFFScanlineSize64(tif
);
340 TIFFErrorExt(tif
->tif_clientdata
,module
,"Integer arithmetic overflow");
347 * Return the number of bytes required to store a complete
348 * decoded and packed raster scanline (as opposed to the
349 * I/O size returned by TIFFScanlineSize which may be less
350 * if data is store as separate planes).
353 TIFFRasterScanlineSize64(TIFF
* tif
)
355 static const char module
[] = "TIFFRasterScanlineSize64";
356 TIFFDirectory
*td
= &tif
->tif_dir
;
359 scanline
= _TIFFMultiply64(tif
, td
->td_bitspersample
, td
->td_imagewidth
, module
);
360 if (td
->td_planarconfig
== PLANARCONFIG_CONTIG
) {
361 scanline
= _TIFFMultiply64(tif
, scanline
, td
->td_samplesperpixel
, module
);
362 return (TIFFhowmany8_64(scanline
));
364 return (_TIFFMultiply64(tif
, TIFFhowmany8_64(scanline
),
365 td
->td_samplesperpixel
, module
));
368 TIFFRasterScanlineSize(TIFF
* tif
)
370 static const char module
[] = "TIFFRasterScanlineSize";
373 m
=TIFFRasterScanlineSize64(tif
);
377 TIFFErrorExt(tif
->tif_clientdata
,module
,"Integer arithmetic overflow");
383 /* vim: set ts=8 sts=8 sw=8 noet: */