]>
Commit | Line | Data |
---|---|---|
1 | /* $Header$ */ | |
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 | tstrip_t | |
38 | TIFFComputeStrip(TIFF* tif, uint32 row, tsample_t sample) | |
39 | { | |
40 | TIFFDirectory *td = &tif->tif_dir; | |
41 | tstrip_t strip; | |
42 | ||
43 | strip = row / td->td_rowsperstrip; | |
44 | if (td->td_planarconfig == PLANARCONFIG_SEPARATE) { | |
45 | if (sample >= td->td_samplesperpixel) { | |
46 | TIFFError(tif->tif_name, | |
47 | "%u: Sample out of range, max %u", | |
48 | sample, td->td_samplesperpixel); | |
49 | return ((tstrip_t) 0); | |
50 | } | |
51 | strip += sample*td->td_stripsperimage; | |
52 | } | |
53 | return (strip); | |
54 | } | |
55 | ||
56 | /* | |
57 | * Compute how many strips are in an image. | |
58 | */ | |
59 | tstrip_t | |
60 | TIFFNumberOfStrips(TIFF* tif) | |
61 | { | |
62 | TIFFDirectory *td = &tif->tif_dir; | |
63 | tstrip_t nstrips; | |
64 | ||
65 | nstrips = (td->td_rowsperstrip == (uint32) -1 ? | |
66 | (td->td_imagelength != 0 ? 1 : 0) : | |
67 | TIFFhowmany(td->td_imagelength, td->td_rowsperstrip)); | |
68 | if (td->td_planarconfig == PLANARCONFIG_SEPARATE) | |
69 | nstrips *= td->td_samplesperpixel; | |
70 | return (nstrips); | |
71 | } | |
72 | ||
73 | /* | |
74 | * Compute the # bytes in a variable height, row-aligned strip. | |
75 | */ | |
76 | tsize_t | |
77 | TIFFVStripSize(TIFF* tif, uint32 nrows) | |
78 | { | |
79 | TIFFDirectory *td = &tif->tif_dir; | |
80 | ||
81 | if (nrows == (uint32) -1) | |
82 | nrows = td->td_imagelength; | |
83 | #ifdef YCBCR_SUPPORT | |
84 | if (td->td_planarconfig == PLANARCONFIG_CONTIG && | |
85 | td->td_photometric == PHOTOMETRIC_YCBCR && | |
86 | !isUpSampled(tif)) { | |
87 | /* | |
88 | * Packed YCbCr data contain one Cb+Cr for every | |
89 | * HorizontalSampling*VerticalSampling Y values. | |
90 | * Must also roundup width and height when calculating | |
91 | * since images that are not a multiple of the | |
92 | * horizontal/vertical subsampling area include | |
93 | * YCbCr data for the extended image. | |
94 | */ | |
95 | tsize_t w = | |
96 | TIFFroundup(td->td_imagewidth, td->td_ycbcrsubsampling[0]); | |
97 | tsize_t scanline = TIFFhowmany(w*td->td_bitspersample, 8); | |
98 | tsize_t samplingarea = | |
99 | td->td_ycbcrsubsampling[0]*td->td_ycbcrsubsampling[1]; | |
100 | nrows = TIFFroundup(nrows, td->td_ycbcrsubsampling[1]); | |
101 | /* NB: don't need TIFFhowmany here 'cuz everything is rounded */ | |
102 | return ((tsize_t) | |
103 | (nrows*scanline + 2*(nrows*scanline / samplingarea))); | |
104 | } else | |
105 | #endif | |
106 | return ((tsize_t)(nrows * TIFFScanlineSize(tif))); | |
107 | } | |
108 | ||
109 | /* | |
110 | * Compute the # bytes in a (row-aligned) strip. | |
111 | * | |
112 | * Note that if RowsPerStrip is larger than the | |
113 | * recorded ImageLength, then the strip size is | |
114 | * truncated to reflect the actual space required | |
115 | * to hold the strip. | |
116 | */ | |
117 | tsize_t | |
118 | TIFFStripSize(TIFF* tif) | |
119 | { | |
120 | TIFFDirectory* td = &tif->tif_dir; | |
121 | uint32 rps = td->td_rowsperstrip; | |
122 | if (rps > td->td_imagelength) | |
123 | rps = td->td_imagelength; | |
124 | return (TIFFVStripSize(tif, rps)); | |
125 | } | |
126 | ||
127 | /* | |
128 | * Compute a default strip size based on the image | |
129 | * characteristics and a requested value. If the | |
130 | * request is <1 then we choose a strip size according | |
131 | * to certain heuristics. | |
132 | */ | |
133 | uint32 | |
134 | TIFFDefaultStripSize(TIFF* tif, uint32 request) | |
135 | { | |
136 | return (*tif->tif_defstripsize)(tif, request); | |
137 | } | |
138 | ||
139 | uint32 | |
140 | _TIFFDefaultStripSize(TIFF* tif, uint32 s) | |
141 | { | |
142 | if ((int32) s < 1) { | |
143 | /* | |
144 | * If RowsPerStrip is unspecified, try to break the | |
145 | * image up into strips that are approximately 8Kbytes. | |
146 | */ | |
147 | tsize_t scanline = TIFFScanlineSize(tif); | |
148 | s = (uint32)(8*1024) / (scanline == 0 ? 1 : scanline); | |
149 | if (s == 0) /* very wide images */ | |
150 | s = 1; | |
151 | } | |
152 | return (s); | |
153 | } | |
154 | ||
155 | /* | |
156 | * Return the number of bytes to read/write in a call to | |
157 | * one of the scanline-oriented i/o routines. Note that | |
158 | * this number may be 1/samples-per-pixel if data is | |
159 | * stored as separate planes. | |
160 | */ | |
161 | tsize_t | |
162 | TIFFScanlineSize(TIFF* tif) | |
163 | { | |
164 | TIFFDirectory *td = &tif->tif_dir; | |
165 | tsize_t scanline; | |
166 | ||
167 | scanline = td->td_bitspersample * td->td_imagewidth; | |
168 | if (td->td_planarconfig == PLANARCONFIG_CONTIG) | |
169 | scanline *= td->td_samplesperpixel; | |
170 | return ((tsize_t) TIFFhowmany(scanline, 8)); | |
171 | } | |
172 | ||
173 | /* | |
174 | * Return the number of bytes required to store a complete | |
175 | * decoded and packed raster scanline (as opposed to the | |
176 | * I/O size returned by TIFFScanlineSize which may be less | |
177 | * if data is store as separate planes). | |
178 | */ | |
179 | tsize_t | |
180 | TIFFRasterScanlineSize(TIFF* tif) | |
181 | { | |
182 | TIFFDirectory *td = &tif->tif_dir; | |
183 | tsize_t scanline; | |
184 | ||
185 | scanline = td->td_bitspersample * td->td_imagewidth; | |
186 | if (td->td_planarconfig == PLANARCONFIG_CONTIG) { | |
187 | scanline *= td->td_samplesperpixel; | |
188 | return ((tsize_t) TIFFhowmany(scanline, 8)); | |
189 | } else | |
190 | return ((tsize_t) | |
191 | TIFFhowmany(scanline, 8)*td->td_samplesperpixel); | |
192 | } |