2 * Copyright (c) 1991-1997 Sam Leffler
3 * Copyright (c) 1991-1997 Silicon Graphics, Inc.
5 * Permission to use, copy, modify, distribute, and sell this software and
6 * its documentation for any purpose is hereby granted without fee, provided
7 * that (i) the above copyright notices and this permission notice appear in
8 * all copies of the software and related documentation, and (ii) the names of
9 * Sam Leffler and Silicon Graphics may not be used in any advertising or
10 * publicity relating to the software without the specific, prior written
11 * permission of Sam Leffler and Silicon Graphics.
13 * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND,
14 * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY
15 * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
17 * IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR
18 * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND,
19 * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
20 * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF
21 * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
28 * Strip-organized Image Support Routines.
33 * Compute which strip a (row,sample) value is in.
35 uint32_t TIFFComputeStrip(TIFF
*tif
, uint32_t row
, uint16_t sample
)
37 static const char module
[] = "TIFFComputeStrip";
38 TIFFDirectory
*td
= &tif
->tif_dir
;
41 strip
= row
/ td
->td_rowsperstrip
;
42 if (td
->td_planarconfig
== PLANARCONFIG_SEPARATE
)
44 if (sample
>= td
->td_samplesperpixel
)
46 TIFFErrorExtR(tif
, module
, "%lu: Sample out of range, max %lu",
47 (unsigned long)sample
,
48 (unsigned long)td
->td_samplesperpixel
);
51 strip
+= (uint32_t)sample
* td
->td_stripsperimage
;
57 * Compute how many strips are in an image.
59 uint32_t TIFFNumberOfStrips(TIFF
*tif
)
61 TIFFDirectory
*td
= &tif
->tif_dir
;
64 nstrips
= (td
->td_rowsperstrip
== (uint32_t)-1
66 : TIFFhowmany_32(td
->td_imagelength
, td
->td_rowsperstrip
));
67 if (td
->td_planarconfig
== PLANARCONFIG_SEPARATE
)
69 _TIFFMultiply32(tif
, nstrips
, (uint32_t)td
->td_samplesperpixel
,
70 "TIFFNumberOfStrips");
75 * Compute the # bytes in a variable height, row-aligned strip.
77 uint64_t TIFFVStripSize64(TIFF
*tif
, uint32_t nrows
)
79 static const char module
[] = "TIFFVStripSize64";
80 TIFFDirectory
*td
= &tif
->tif_dir
;
81 if (nrows
== (uint32_t)(-1))
82 nrows
= td
->td_imagelength
;
83 if ((td
->td_planarconfig
== PLANARCONFIG_CONTIG
) &&
84 (td
->td_photometric
== PHOTOMETRIC_YCBCR
) && (!isUpSampled(tif
)))
87 * Packed YCbCr data contain one Cb+Cr for every
88 * HorizontalSampling*VerticalSampling Y values.
89 * Must also roundup width and height when calculating
90 * since images that are not a multiple of the
91 * horizontal/vertical subsampling area include
92 * YCbCr data for the extended image.
94 uint16_t ycbcrsubsampling
[2];
95 uint16_t samplingblock_samples
;
96 uint32_t samplingblocks_hor
;
97 uint32_t samplingblocks_ver
;
98 uint64_t samplingrow_samples
;
99 uint64_t samplingrow_size
;
100 if (td
->td_samplesperpixel
!= 3)
102 TIFFErrorExtR(tif
, module
, "Invalid td_samplesperpixel value");
105 TIFFGetFieldDefaulted(tif
, TIFFTAG_YCBCRSUBSAMPLING
,
106 ycbcrsubsampling
+ 0, ycbcrsubsampling
+ 1);
107 if ((ycbcrsubsampling
[0] != 1 && ycbcrsubsampling
[0] != 2 &&
108 ycbcrsubsampling
[0] != 4) ||
109 (ycbcrsubsampling
[1] != 1 && ycbcrsubsampling
[1] != 2 &&
110 ycbcrsubsampling
[1] != 4))
112 TIFFErrorExtR(tif
, module
, "Invalid YCbCr subsampling (%dx%d)",
113 ycbcrsubsampling
[0], ycbcrsubsampling
[1]);
116 samplingblock_samples
= ycbcrsubsampling
[0] * ycbcrsubsampling
[1] + 2;
118 TIFFhowmany_32(td
->td_imagewidth
, ycbcrsubsampling
[0]);
119 samplingblocks_ver
= TIFFhowmany_32(nrows
, ycbcrsubsampling
[1]);
120 samplingrow_samples
= _TIFFMultiply64(tif
, samplingblocks_hor
,
121 samplingblock_samples
, module
);
122 samplingrow_size
= TIFFhowmany8_64(_TIFFMultiply64(
123 tif
, samplingrow_samples
, td
->td_bitspersample
, module
));
125 _TIFFMultiply64(tif
, samplingrow_size
, samplingblocks_ver
, module
));
128 return (_TIFFMultiply64(tif
, nrows
, TIFFScanlineSize64(tif
), module
));
130 tmsize_t
TIFFVStripSize(TIFF
*tif
, uint32_t nrows
)
132 static const char module
[] = "TIFFVStripSize";
134 m
= TIFFVStripSize64(tif
, nrows
);
135 return _TIFFCastUInt64ToSSize(tif
, m
, module
);
139 * Compute the # bytes in a raw strip.
141 uint64_t TIFFRawStripSize64(TIFF
*tif
, uint32_t strip
)
143 static const char module
[] = "TIFFRawStripSize64";
144 uint64_t bytecount
= TIFFGetStrileByteCount(tif
, strip
);
148 TIFFErrorExtR(tif
, module
,
149 "%" PRIu64
": Invalid strip byte count, strip %lu",
150 (uint64_t)bytecount
, (unsigned long)strip
);
151 bytecount
= (uint64_t)-1;
156 tmsize_t
TIFFRawStripSize(TIFF
*tif
, uint32_t strip
)
158 static const char module
[] = "TIFFRawStripSize";
161 m
= TIFFRawStripSize64(tif
, strip
);
162 if (m
== (uint64_t)(-1))
167 if ((uint64_t)n
!= m
)
169 TIFFErrorExtR(tif
, module
, "Integer overflow");
177 * Compute the # bytes in a (row-aligned) strip.
179 * Note that if RowsPerStrip is larger than the
180 * recorded ImageLength, then the strip size is
181 * truncated to reflect the actual space required
184 uint64_t TIFFStripSize64(TIFF
*tif
)
186 TIFFDirectory
*td
= &tif
->tif_dir
;
187 uint32_t rps
= td
->td_rowsperstrip
;
188 if (rps
> td
->td_imagelength
)
189 rps
= td
->td_imagelength
;
190 return (TIFFVStripSize64(tif
, rps
));
192 tmsize_t
TIFFStripSize(TIFF
*tif
)
194 static const char module
[] = "TIFFStripSize";
196 m
= TIFFStripSize64(tif
);
197 return _TIFFCastUInt64ToSSize(tif
, m
, module
);
201 * Compute a default strip size based on the image
202 * characteristics and a requested value. If the
203 * request is <1 then we choose a strip size according
204 * to certain heuristics.
206 uint32_t TIFFDefaultStripSize(TIFF
*tif
, uint32_t request
)
208 return (*tif
->tif_defstripsize
)(tif
, request
);
211 uint32_t _TIFFDefaultStripSize(TIFF
*tif
, uint32_t s
)
216 * If RowsPerStrip is unspecified, try to break the
217 * image up into strips that are approximately
218 * STRIP_SIZE_DEFAULT bytes long.
220 uint64_t scanlinesize
;
222 scanlinesize
= TIFFScanlineSize64(tif
);
223 if (scanlinesize
== 0)
225 rows
= (uint64_t)STRIP_SIZE_DEFAULT
/ scanlinesize
;
228 else if (rows
> 0xFFFFFFFF)
236 * Return the number of bytes to read/write in a call to
237 * one of the scanline-oriented i/o routines. Note that
238 * this number may be 1/samples-per-pixel if data is
239 * stored as separate planes.
240 * The ScanlineSize in case of YCbCrSubsampling is defined as the
241 * strip size divided by the strip height, i.e. the size of a pack of vertical
242 * subsampling lines divided by vertical subsampling. It should thus make
243 * sense when multiplied by a multiple of vertical subsampling.
245 uint64_t TIFFScanlineSize64(TIFF
*tif
)
247 static const char module
[] = "TIFFScanlineSize64";
248 TIFFDirectory
*td
= &tif
->tif_dir
;
249 uint64_t scanline_size
;
250 if (td
->td_planarconfig
== PLANARCONFIG_CONTIG
)
252 if ((td
->td_photometric
== PHOTOMETRIC_YCBCR
) &&
253 (td
->td_samplesperpixel
== 3) && (!isUpSampled(tif
)))
255 uint16_t ycbcrsubsampling
[2];
256 uint16_t samplingblock_samples
;
257 uint32_t samplingblocks_hor
;
258 uint64_t samplingrow_samples
;
259 uint64_t samplingrow_size
;
260 if (td
->td_samplesperpixel
!= 3)
262 TIFFErrorExtR(tif
, module
, "Invalid td_samplesperpixel value");
265 TIFFGetFieldDefaulted(tif
, TIFFTAG_YCBCRSUBSAMPLING
,
266 ycbcrsubsampling
+ 0, ycbcrsubsampling
+ 1);
267 if (((ycbcrsubsampling
[0] != 1) && (ycbcrsubsampling
[0] != 2) &&
268 (ycbcrsubsampling
[0] != 4)) ||
269 ((ycbcrsubsampling
[1] != 1) && (ycbcrsubsampling
[1] != 2) &&
270 (ycbcrsubsampling
[1] != 4)))
272 TIFFErrorExtR(tif
, module
, "Invalid YCbCr subsampling");
275 samplingblock_samples
=
276 ycbcrsubsampling
[0] * ycbcrsubsampling
[1] + 2;
278 TIFFhowmany_32(td
->td_imagewidth
, ycbcrsubsampling
[0]);
279 samplingrow_samples
= _TIFFMultiply64(
280 tif
, samplingblocks_hor
, samplingblock_samples
, module
);
282 TIFFhowmany_64(_TIFFMultiply64(tif
, samplingrow_samples
,
283 td
->td_bitspersample
, module
),
285 scanline_size
= (samplingrow_size
/ ycbcrsubsampling
[1]);
289 uint64_t scanline_samples
;
290 scanline_samples
= _TIFFMultiply64(tif
, td
->td_imagewidth
,
291 td
->td_samplesperpixel
, module
);
293 TIFFhowmany_64(_TIFFMultiply64(tif
, scanline_samples
,
294 td
->td_bitspersample
, module
),
301 TIFFhowmany_64(_TIFFMultiply64(tif
, td
->td_imagewidth
,
302 td
->td_bitspersample
, module
),
305 if (scanline_size
== 0)
307 TIFFErrorExtR(tif
, module
, "Computed scanline size is zero");
310 return (scanline_size
);
312 tmsize_t
TIFFScanlineSize(TIFF
*tif
)
314 static const char module
[] = "TIFFScanlineSize";
316 m
= TIFFScanlineSize64(tif
);
317 return _TIFFCastUInt64ToSSize(tif
, m
, module
);
321 * Return the number of bytes required to store a complete
322 * decoded and packed raster scanline (as opposed to the
323 * I/O size returned by TIFFScanlineSize which may be less
324 * if data is store as separate planes).
326 uint64_t TIFFRasterScanlineSize64(TIFF
*tif
)
328 static const char module
[] = "TIFFRasterScanlineSize64";
329 TIFFDirectory
*td
= &tif
->tif_dir
;
333 _TIFFMultiply64(tif
, td
->td_bitspersample
, td
->td_imagewidth
, module
);
334 if (td
->td_planarconfig
== PLANARCONFIG_CONTIG
)
337 _TIFFMultiply64(tif
, scanline
, td
->td_samplesperpixel
, module
);
338 return (TIFFhowmany8_64(scanline
));
341 return (_TIFFMultiply64(tif
, TIFFhowmany8_64(scanline
),
342 td
->td_samplesperpixel
, module
));
344 tmsize_t
TIFFRasterScanlineSize(TIFF
*tif
)
346 static const char module
[] = "TIFFRasterScanlineSize";
348 m
= TIFFRasterScanlineSize64(tif
);
349 return _TIFFCastUInt64ToSSize(tif
, m
, module
);