Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(745)

Side by Side Diff: include/codec/SkScanlineDecoder.h

Issue 1365313002: Merge SkCodec with SkScanlineDecoder (Closed) Base URL: https://skia.googlesource.com/skia.git@master
Patch Set: Skip ICO in SkScaledCodec for now Created 5 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « include/codec/SkScaledCodec.h ('k') | resources/plane_interlaced.png » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 /*
2 * Copyright 2015 Google Inc.
3 *
4 * Use of this source code is governed by a BSD-style license that can be
5 * found in the LICENSE file.
6 */
7
8 #ifndef SkScanlineDecoder_DEFINED
9 #define SkScanlineDecoder_DEFINED
10
11 #include "../private/SkTemplates.h"
12 #include "SkCodec.h"
13 #include "SkImageInfo.h"
14 #include "SkTypes.h"
15
16 class SkScanlineDecoder : public SkNoncopyable {
17 public:
18 /**
19 * If this stream represents an encoded image that we know how to decode
20 * in scanlines, return an SkScanlineDecoder that can decode it. Otherwise
21 * return NULL.
22 *
23 * start() must be called in order to decode any scanlines.
24 *
25 * If NULL is returned, the stream is deleted immediately. Otherwise, the
26 * SkScanlineDecoder takes ownership of it, and will delete it when done
27 * with it.
28 */
29 static SkScanlineDecoder* NewFromStream(SkStream*);
30
31 /**
32 * Similar to NewFromStream, but reads from an SkData.
33 *
34 * Will take a ref if it returns a scanline decoder, else will not affect
35 * the data.
36 */
37 static SkScanlineDecoder* NewFromData(SkData*);
38
39 /**
40 * Clean up after reading/skipping scanlines.
41 *
42 * It is possible that not all scanlines will have been read/skipped. In
43 * fact, in the case of subset decodes, it is likely that there will be
44 * scanlines at the bottom of the image that have been ignored.
45 */
46 virtual ~SkScanlineDecoder() {}
47
48 /**
49 * Return a size that approximately supports the desired scale factor.
50 * The codec may not be able to scale efficiently to the exact scale
51 * factor requested, so return a size that approximates that scale.
52 * The returned value is the codec's suggestion for the closest valid
53 * scale that it can natively support
54 * FIXME: share this with SkCodec
55 */
56 SkISize getScaledDimensions(float desiredScale) {
57 return this->onGetScaledDimensions(desiredScale);
58 }
59
60 /**
61 * Returns the default info, corresponding to the encoded data.
62 */
63 const SkImageInfo& getInfo() { return fSrcInfo; }
64
65 /**
66 * Initialize on the first scanline, with the specified options.
67 *
68 * This must be called in order to call getScanlnies or skipScanlines. If
69 * it has been called before, this will require rewinding the stream.
70 *
71 * @param dstInfo Info of the destination. If the dimensions do not match
72 * those of getInfo, this implies a scale.
73 * @param options Contains decoding options, including if memory is zero
74 * initialized.
75 * @param ctable A pointer to a color table. When dstInfo.colorType() is
76 * kIndex8, this should be non-NULL and have enough storage for 256
77 * colors. The color table will be populated after decoding the palett e.
78 * @param ctableCount A pointer to the size of the color table. When
79 * dstInfo.colorType() is kIndex8, this should be non-NULL. It will
80 * be modified to the true size of the color table (<= 256) after
81 * decoding the palette.
82 * @return Enum representing success or reason for failure.
83 */
84 SkCodec::Result start(const SkImageInfo& dstInfo, const SkCodec::Options* op tions,
85 SkPMColor ctable[], int* ctableCount);
86
87 /**
88 * Simplified version of start() that asserts that info is NOT
89 * kIndex8_SkColorType and uses the default Options.
90 */
91 SkCodec::Result start(const SkImageInfo& dstInfo);
92
93 /**
94 * Write the next countLines scanlines into dst.
95 *
96 * Not valid to call before calling start().
97 *
98 * @param dst Must be non-null, and large enough to hold countLines
99 * scanlines of size rowBytes.
100 * @param countLines Number of lines to write.
101 * @param rowBytes Number of bytes per row. Must be large enough to hold
102 * a scanline based on the SkImageInfo used to create this object.
103 */
104 SkCodec::Result getScanlines(void* dst, int countLines, size_t rowBytes) {
105 SkASSERT(!fDstInfo.isEmpty());
106 if ((rowBytes < fDstInfo.minRowBytes() && countLines > 1 ) || countLines <= 0
107 || fCurrScanline + countLines > fDstInfo.height()) {
108 return SkCodec::kInvalidParameters;
109 }
110 const SkCodec::Result result = this->onGetScanlines(dst, countLines, row Bytes);
111 fCurrScanline += countLines;
112 return result;
113 }
114
115 /**
116 * Skip count scanlines.
117 *
118 * Not valid to call before calling start().
119 *
120 * The default version just calls onGetScanlines and discards the dst.
121 * NOTE: If skipped lines are the only lines with alpha, this default
122 * will make reallyHasAlpha return true, when it could have returned
123 * false.
124 */
125 SkCodec::Result skipScanlines(int countLines) {
126 SkASSERT(!fDstInfo.isEmpty());
127 if (fCurrScanline + countLines > fDstInfo.height()) {
128 // Arguably, we could just skip the scanlines which are remaining,
129 // and return kSuccess. We choose to return invalid so the client
130 // can catch their bug.
131 return SkCodec::kInvalidParameters;
132 }
133 const SkCodec::Result result = this->onSkipScanlines(countLines);
134 fCurrScanline += countLines;
135 return result;
136 }
137
138 /**
139 * Some images may initially report that they have alpha due to the format
140 * of the encoded data, but then never use any colors which have alpha
141 * less than 100%. This function can be called *after* decoding to
142 * determine if such an image truly had alpha. Calling it before decoding
143 * is undefined.
144 * FIXME: see skbug.com/3582.
145 */
146 bool reallyHasAlpha() const {
147 return this->onReallyHasAlpha();
148 }
149
150 /**
151 * Format of the encoded data.
152 */
153 SkEncodedFormat getEncodedFormat() const { return this->onGetEncodedFormat() ; }
154
155 /**
156 * The order in which rows are output from the scanline decoder is not the
157 * same for all variations of all image types. This explains the possible
158 * output row orderings.
159 */
160 enum SkScanlineOrder {
161 /*
162 * By far the most common, this indicates that the image can be decoded
163 * reliably using the scanline decoder, and that rows will be output in
164 * the logical order.
165 */
166 kTopDown_SkScanlineOrder,
167
168 /*
169 * This indicates that the scanline decoder reliably outputs rows, but
170 * they will be returned in reverse order. If the scanline format is
171 * kBottomUp, the getY() API can be used to determine the actual
172 * y-coordinate of the next output row, but the client is not forced
173 * to take advantage of this, given that it's not too tough to keep
174 * track independently.
175 *
176 * For full image decodes, it is safe to get all of the scanlines at
177 * once, since the decoder will handle inverting the rows as it
178 * decodes.
179 *
180 * For subset decodes and sampling, it is simplest to get and skip
181 * scanlines one at a time, using the getY() API. It is possible to
182 * ask for larger chunks at a time, but this should be used with
183 * caution. As with full image decodes, the decoder will handle
184 * inverting the requested rows, but rows will still be delivered
185 * starting from the bottom of the image.
186 *
187 * Upside down bmps are an example.
188 */
189 kBottomUp_SkScanlineOrder,
190
191 /*
192 * This indicates that the scanline decoder reliably outputs rows, but
193 * they will not be in logical order. If the scanline format is
194 * kOutOfOrder, the getY() API should be used to determine the actual
195 * y-coordinate of the next output row.
196 *
197 * For this scanline ordering, it is advisable to get and skip
198 * scanlines one at a time.
199 *
200 * Interlaced gifs are an example.
201 */
202 kOutOfOrder_SkScanlineOrder,
203
204 /*
205 * Indicates that the entire image must be decoded in order to output
206 * any amount of scanlines. In this case, it is a REALLY BAD IDEA to
207 * request scanlines 1-by-1 or in small chunks. The client should
208 * determine which scanlines are needed and ask for all of them in
209 * a single call to getScanlines().
210 *
211 * Interlaced pngs are an example.
212 */
213 kNone_SkScanlineOrder,
214 };
215
216 /**
217 * An enum representing the order in which scanlines will be returned by
218 * the scanline decoder.
219 */
220 SkScanlineOrder getScanlineOrder() const { return this->onGetScanlineOrder() ; }
221
222 /**
223 * Returns the y-coordinate of the next row to be returned by the scanline
224 * decoder. This will be overridden in the case of
225 * kOutOfOrder_SkScanlineOrder and should be unnecessary in the case of
226 * kNone_SkScanlineOrder.
227 */
228 int getY() const {
229 SkASSERT(kNone_SkScanlineOrder != this->getScanlineOrder());
230 return this->onGetY();
231 }
232
233 protected:
234 SkScanlineDecoder(const SkImageInfo& srcInfo)
235 : fSrcInfo(srcInfo)
236 , fDstInfo()
237 , fOptions()
238 , fCurrScanline(0) {}
239
240 virtual SkISize onGetScaledDimensions(float /* desiredScale */) {
241 // By default, scaling is not supported.
242 return this->getInfo().dimensions();
243 }
244
245 virtual SkEncodedFormat onGetEncodedFormat() const = 0;
246
247 virtual bool onReallyHasAlpha() const { return false; }
248
249 /**
250 * Most images types will be kTopDown and will not need to override this fu nction.
251 */
252 virtual SkScanlineOrder onGetScanlineOrder() const { return kTopDown_SkScanl ineOrder; }
253
254 /**
255 * Most images will be kTopDown and will not need to override this function .
256 */
257 virtual int onGetY() const { return fCurrScanline; }
258
259 const SkImageInfo& dstInfo() const { return fDstInfo; }
260
261 const SkCodec::Options& options() const { return fOptions; }
262
263 private:
264 const SkImageInfo fSrcInfo;
265 SkImageInfo fDstInfo;
266 SkCodec::Options fOptions;
267 int fCurrScanline;
268
269 virtual SkCodec::Result onStart(const SkImageInfo& dstInfo,
270 const SkCodec::Options& options,
271 SkPMColor ctable[], int* ctableCount) = 0;
272
273 // Naive default version just calls onGetScanlines on temp memory.
274 virtual SkCodec::Result onSkipScanlines(int countLines) {
275 SkAutoMalloc storage(fDstInfo.minRowBytes());
276 // Note that we pass 0 to rowBytes so we continue to use the same memory .
277 // Also note that while getScanlines checks that rowBytes is big enough,
278 // onGetScanlines bypasses that check.
279 // Calling the virtual method also means we do not double count
280 // countLines.
281 return this->onGetScanlines(storage.get(), countLines, 0);
282 }
283
284 virtual SkCodec::Result onGetScanlines(void* dst, int countLines,
285 size_t rowBytes) = 0;
286
287 };
288 #endif // SkScanlineDecoder_DEFINED
OLDNEW
« no previous file with comments | « include/codec/SkScaledCodec.h ('k') | resources/plane_interlaced.png » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698