diff options
author | scroggo <scroggo@chromium.org> | 2016-06-02 14:16:43 -0700 |
---|---|---|
committer | Commit bot <commit-bot@chromium.org> | 2016-06-02 14:16:43 -0700 |
commit | 6fb2391b2cc83ee2160b4e994faa8128975acc1f (patch) | |
tree | c27833e424302058ef076f50a0b6760079bc1cea /src/codec/SkPngCodec.h | |
parent | 3965825b97a5809454f5810f7e603cbd02daa036 (diff) |
Make SkPngCodec decode progressively.
This is a step towards using SkCodec in Chromium, where progressive
decoding is necessary.
Switch from using png_read_row (which expects all the data to be
available) to png_process_data, which uses callbacks when rows are
available.
Create a new API for SkCodec, which supports progressive decoding and
scanline decoding. Future changes will switch the other clients off of
startScanlineDecode and get/skip-Scanlines to the new API.
Remove SkCodec::kNone_ScanlineOrder, which was only used for interlaced
PNG images. In the new API, interlaced PNG fits kTopDown. Also remove
updateCurrScanline(), which was only used by the old implementation for
interlaced PNG.
DMSrcSink:
- In CodecSrc::kScanline_Mode, use the new method for scanline decoding
for the supported formats (just PNG and PNG-in-ICO for now).
fuzz.cpp:
- Remove reference to kNone_ScanlineOrder
SkCodec:
- Add new APIs:
- startIncrementalDecode
- incrementalDecode
- Remove kNone_SkScanlineOrder and updateCurrScanline()
SkPngCodec:
- Implement new APIs
- Switch from sk_read_fn/png_read_row etc to png_process_data
- Expand AutoCleanPng's role to decode the header and create the
SkPngCodec
- Make the interlaced PNG decoder report how many lines were
initialized during an incomplete decode
- Make initializeSwizzler return a bool instead of an SkCodec::Result
(It only returned kSuccess or kInvalidInput anyway)
SkIcoCodec:
- Implement the new APIs; supported for PNG in ICO
SkSampledCodec:
- Call the new method for decoding scanlines, and fall back to the old
method if the new version is unimplemented
- Remove references to kNone_SkScanlineOrder
tests/CodecPartial:
- Add a test which decodes part of an image, then finishes the decode,
and compares it to the straightforward method
tests/CodecTest:
- Add a test which decodes all scanlines using the new method
- Repurpose the Codec_stripes test to decode using the new method in
sections rather than all at once
- In the method check(), add a parameter for whether the image supports
the new method of scanline decoding, and be explicit about whether an
image supports incomplete
- Test incomplete PNG decodes. We should have been doing it anyway for
non-interlaced (except for an image that is too small - one row), but
the new method supports interlaced incomplete as well
- Make test_invalid_parameters test the new method
- Add a test to ensure that it's safe to fall back to scanline decoding without
rewinding
BUG=skia:4211
The new version was generally faster than the old version (but not significantly so).
Some raw performance differences can be found at https://docs.google.com/a/google.com/spreadsheets/d/1Gis3aRCEa72qBNDRMgGDg3jD-pMgO-FXldlNF9ejo4o/
Design doc can be found at https://docs.google.com/a/google.com/document/d/11Mn8-ePDKwVEMCjs3nWwSjxcSpJ_Cu8DF57KNtUmgLM/
GOLD_TRYBOT_URL= https://gold.skia.org/search2?unt=true&query=source_type%3Dgm&master=false&issue=1997703003
Committed: https://skia.googlesource.com/skia/+/a4b09a117d4d1ba5dda372e6a2323e653766539e
Committed: https://skia.googlesource.com/skia/+/30e78c9737ff4861dc4e3fa1e4cd010680ed6965
Review-Url: https://codereview.chromium.org/1997703003
Diffstat (limited to 'src/codec/SkPngCodec.h')
-rw-r--r-- | src/codec/SkPngCodec.h | 33 |
1 files changed, 24 insertions, 9 deletions
diff --git a/src/codec/SkPngCodec.h b/src/codec/SkPngCodec.h index 0a8878395a..51d8978199 100644 --- a/src/codec/SkPngCodec.h +++ b/src/codec/SkPngCodec.h @@ -27,6 +27,9 @@ public: virtual ~SkPngCodec(); protected: + SkPngCodec(int width, int height, const SkEncodedInfo&, SkStream*, SkPngChunkReader*, + png_structp, png_infop, int bitDepth, sk_sp<SkColorSpace>); + Result onGetPixels(const SkImageInfo&, void*, size_t, const Options&, SkPMColor*, int*, int*) override; SkEncodedFormat onGetEncodedFormat() const override { return kPNG_SkEncodedFormat; } @@ -34,34 +37,46 @@ protected: uint32_t onGetFillValue(SkColorType) const override; // Helper to set up swizzler and color table. Also calls png_read_update_info. - Result initializeSwizzler(const SkImageInfo& requestedInfo, const Options&, - SkPMColor*, int* ctableCount); + bool initializeSwizzler(const SkImageInfo& requestedInfo, const Options&, + SkPMColor*, int* ctableCount); SkSampler* getSampler(bool createIfNecessary) override { SkASSERT(fSwizzler); return fSwizzler; } - SkPngCodec(int width, int height, const SkEncodedInfo&, SkStream*, SkPngChunkReader*, - png_structp, png_infop, int, int, sk_sp<SkColorSpace>); - png_structp png_ptr() { return fPng_ptr; } + png_infop info_ptr() { return fInfo_ptr; } SkSwizzler* swizzler() { return fSwizzler; } - int numberPasses() const { return fNumberPasses; } + + /** + * Pass available input to libpng to process it. + * + * libpng will call any relevant callbacks installed. This will continue decoding + * until it reaches the end of the file, or until a callback tells libpng to stop. + */ + void processData(); + + Result onStartIncrementalDecode(const SkImageInfo& dstInfo, void* pixels, size_t rowBytes, + const SkCodec::Options&, + SkPMColor* ctable, int* ctableCount) override; + Result onIncrementalDecode(int*) override; private: SkAutoTUnref<SkPngChunkReader> fPngChunkReader; png_structp fPng_ptr; png_infop fInfo_ptr; - // These are stored here so they can be used both by normal decoding and scanline decoding. SkAutoTUnref<SkColorTable> fColorTable; // May be unpremul. SkAutoTDelete<SkSwizzler> fSwizzler; - const int fNumberPasses; - int fBitDepth; + const int fBitDepth; bool createColorTable(SkColorType dstColorType, bool premultiply, int* ctableCount); void destroyReadStruct(); + virtual Result decodeAllRows(void* dst, size_t rowBytes, int* rowsDecoded) = 0; + virtual void setRange(int firstRow, int lastRow, void* dst, size_t rowBytes) = 0; + virtual Result decode(int* rowsDecoded) = 0; + typedef SkCodec INHERITED; }; |