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

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

Issue 1287423002: Scanline decoding for bmp (Closed) Base URL: https://skia.googlesource.com/skia.git@master
Patch Set: Use SkScanlineOrder instead of RowOrder Created 5 years, 3 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') | src/codec/SkBmpCodec.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 /* 1 /*
2 * Copyright 2015 Google Inc. 2 * Copyright 2015 Google Inc.
3 * 3 *
4 * Use of this source code is governed by a BSD-style license that can be 4 * Use of this source code is governed by a BSD-style license that can be
5 * found in the LICENSE file. 5 * found in the LICENSE file.
6 */ 6 */
7 7
8 #ifndef SkScanlineDecoder_DEFINED 8 #ifndef SkScanlineDecoder_DEFINED
9 #define SkScanlineDecoder_DEFINED 9 #define SkScanlineDecoder_DEFINED
10 10
(...skipping 135 matching lines...) Expand 10 before | Expand all | Expand 10 after
146 bool reallyHasAlpha() const { 146 bool reallyHasAlpha() const {
147 return this->onReallyHasAlpha(); 147 return this->onReallyHasAlpha();
148 } 148 }
149 149
150 /** 150 /**
151 * Format of the encoded data. 151 * Format of the encoded data.
152 */ 152 */
153 SkEncodedFormat getEncodedFormat() const { return this->onGetEncodedFormat() ; } 153 SkEncodedFormat getEncodedFormat() const { return this->onGetEncodedFormat() ; }
154 154
155 /** 155 /**
156 * returns true if the image must be scaled, in the y direction, after readi ng, not during. 156 * The order in which rows are output from the scanline decoder is not the
157 * To scale afterwards, we first decode every line and then sample the lines we want afterwards. 157 * same for all variations of all image types. This explains the possible
158 * An example is interlaced pngs, where calling getScanlines once (regardles s of the count 158 * output row orderings.
159 * used) needs to read the entire image, therefore it is inefficient to call
160 * getScanlines more than once. Instead, it should only ever be called with all the
161 * rows needed.
162 */ 159 */
163 bool requiresPostYSampling() { 160 enum SkScanlineOrder {
164 return this->onRequiresPostYSampling(); 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-coordinates of the output rows, but the client is not forced to
173 * take advantage of this, given that it's not too tough to keep track
174 * independently.
175 *
176 * For this scanline ordering, it may be advisable to get and skip
scroggo 2015/08/28 13:28:47 Why do they need to skip scanlines one at a time?
msarett 2015/08/28 14:05:57 They can skip more, but it's a bit a risky, they n
177 * scanlines one at a time. If multiple scanlines are requested, we
178 * will in fact invert them to be top-down in the provided memory.
179 * However, this capability should be used carefully, as it can lead
180 * to strange behavior if the client requests multiple chunks of
181 * scanlines where count > 1.
scroggo 2015/08/28 13:28:47 It seems like we *could* make this work, in at lea
msarett 2015/08/28 14:05:57 So we do invert the rows if they ask for more than
182 *
183 * Upside down bmps are an example.
184 */
185 kBottomUp_SkScanlineOrder,
186
187 /*
188 * This indicates that the scanline decoder reliably outputs rows, but
189 * they will not be in logical order. If the scanline format is
190 * kOutOfOrder, the getY() API should be used to determine the actual
191 * y-coordinates of the output rows.
192 *
193 * For this scanline ordering, it is advisable to get and skip
194 * scanlines one at a time.
195 *
196 * Interlaced gifs are an example.
197 */
198 kOutOfOrder_SkScanlineOrder,
199
200 /*
201 * Indicates that the entire image must be decoded in order to output
202 * any amount of scanlines. In this case, it is a REALLY BAD IDEA to
203 * request scanlines 1-by-1 or in small chunks. The client should
204 * determine which scanlines are needed and ask for all of them in
205 * a single call to getScanlines().
206 *
207 * Interlaced pngs are an example.
208 */
209 kNone_SkScanlineOrder,
210 };
211
212 /**
213 * An enum representing the order in which scanlines will be returned by
214 * the scanline decoder.
215 */
216 SkScanlineOrder getScanlineOrder() const { return this->onGetScanlineOrder() ; }
217
218 /**
219 * Returns the y-coordinate of the next row to be returned by the scanline
220 * decoder. This will be overridden in the case of
221 * kOutOfOrder_SkScanlineOrder and should be unnecessary in the case of
222 * kNone_SkScanlineOrder.
223 */
224 int getY() const {
225 SkASSERT(kNone_SkScanlineOrder != this->getScanlineOrder());
226 return this->onGetY();
165 } 227 }
166 228
167 protected: 229 protected:
168 SkScanlineDecoder(const SkImageInfo& srcInfo) 230 SkScanlineDecoder(const SkImageInfo& srcInfo)
169 : fSrcInfo(srcInfo) 231 : fSrcInfo(srcInfo)
170 , fDstInfo() 232 , fDstInfo()
233 , fOptions()
171 , fCurrScanline(0) {} 234 , fCurrScanline(0) {}
172 235
173 virtual SkISize onGetScaledDimensions(float /* desiredScale */) { 236 virtual SkISize onGetScaledDimensions(float /* desiredScale */) {
174 // By default, scaling is not supported. 237 // By default, scaling is not supported.
175 return this->getInfo().dimensions(); 238 return this->getInfo().dimensions();
176 } 239 }
177 240
178 virtual SkEncodedFormat onGetEncodedFormat() const = 0; 241 virtual SkEncodedFormat onGetEncodedFormat() const = 0;
179 242
180 virtual bool onReallyHasAlpha() const { return false; } 243 virtual bool onReallyHasAlpha() const { return false; }
181 244
182 /** 245 /**
183 * returns true if the image type is hard to sample and must be scaled after reading, not during 246 * Most images types will be kTopDown and will not need to override this fu nction.
184 * An example is interlaced pngs, where the entire image must be read for ea ch decode
185 */ 247 */
186 virtual bool onRequiresPostYSampling() { return false; } 248 virtual SkScanlineOrder onGetScanlineOrder() const { return kTopDown_SkScanl ineOrder; }
249
250 /**
251 * Most images will be kTopDown and will not need to override this function .
252 */
253 virtual int onGetY() const { return fCurrScanline; }
187 254
188 const SkImageInfo& dstInfo() const { return fDstInfo; } 255 const SkImageInfo& dstInfo() const { return fDstInfo; }
189 256
257 const SkCodec::Options& options() const { return fOptions; }
258
190 private: 259 private:
191 const SkImageInfo fSrcInfo; 260 const SkImageInfo fSrcInfo;
192 SkImageInfo fDstInfo; 261 SkImageInfo fDstInfo;
262 SkCodec::Options fOptions;
193 int fCurrScanline; 263 int fCurrScanline;
194 264
195 virtual SkCodec::Result onStart(const SkImageInfo& dstInfo, 265 virtual SkCodec::Result onStart(const SkImageInfo& dstInfo,
196 const SkCodec::Options& options, 266 const SkCodec::Options& options,
197 SkPMColor ctable[], int* ctableCount) = 0; 267 SkPMColor ctable[], int* ctableCount) = 0;
198 268
199 // Naive default version just calls onGetScanlines on temp memory. 269 // Naive default version just calls onGetScanlines on temp memory.
200 virtual SkCodec::Result onSkipScanlines(int countLines) { 270 virtual SkCodec::Result onSkipScanlines(int countLines) {
201 SkAutoMalloc storage(fDstInfo.minRowBytes()); 271 SkAutoMalloc storage(fDstInfo.minRowBytes());
202 // Note that we pass 0 to rowBytes so we continue to use the same memory . 272 // Note that we pass 0 to rowBytes so we continue to use the same memory .
203 // Also note that while getScanlines checks that rowBytes is big enough, 273 // Also note that while getScanlines checks that rowBytes is big enough,
204 // onGetScanlines bypasses that check. 274 // onGetScanlines bypasses that check.
205 // Calling the virtual method also means we do not double count 275 // Calling the virtual method also means we do not double count
206 // countLines. 276 // countLines.
207 return this->onGetScanlines(storage.get(), countLines, 0); 277 return this->onGetScanlines(storage.get(), countLines, 0);
208 } 278 }
209 279
210 virtual SkCodec::Result onGetScanlines(void* dst, int countLines, 280 virtual SkCodec::Result onGetScanlines(void* dst, int countLines,
211 size_t rowBytes) = 0; 281 size_t rowBytes) = 0;
212 282
213 }; 283 };
214 #endif // SkScanlineDecoder_DEFINED 284 #endif // SkScanlineDecoder_DEFINED
OLDNEW
« no previous file with comments | « include/codec/SkScaledCodec.h ('k') | src/codec/SkBmpCodec.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698