| Index: src/codec/SkCodec.cpp
|
| diff --git a/src/codec/SkCodec.cpp b/src/codec/SkCodec.cpp
|
| index d12de21f515e45c861f6793cdd0b73b4bcc8055f..97bcf3e1d84403f776900be5e9965500fa481291 100644
|
| --- a/src/codec/SkCodec.cpp
|
| +++ b/src/codec/SkCodec.cpp
|
| @@ -76,9 +76,12 @@ SkCodec* SkCodec::NewFromData(SkData* data) {
|
| }
|
|
|
| SkCodec::SkCodec(const SkImageInfo& info, SkStream* stream)
|
| - : fInfo(info)
|
| + : fSrcInfo(info)
|
| , fStream(stream)
|
| , fNeedsRewind(false)
|
| + , fDstInfo()
|
| + , fOptions()
|
| + , fCurrScanline(-1)
|
| {}
|
|
|
| SkCodec::~SkCodec() {}
|
| @@ -92,6 +95,9 @@ bool SkCodec::rewindIfNeeded() {
|
| return true;
|
| }
|
|
|
| + // startScanlineDecode will need to be called before decoding scanlines.
|
| + fCurrScanline = -1;
|
| +
|
| if (!fStream->rewind()) {
|
| return false;
|
| }
|
| @@ -148,3 +154,75 @@ SkCodec::Result SkCodec::getPixels(const SkImageInfo& info, void* pixels, size_t
|
| SkCodec::Result SkCodec::getPixels(const SkImageInfo& info, void* pixels, size_t rowBytes) {
|
| return this->getPixels(info, pixels, rowBytes, nullptr, nullptr, nullptr);
|
| }
|
| +
|
| +SkCodec::Result SkCodec::startScanlineDecode(const SkImageInfo& dstInfo,
|
| + const SkCodec::Options* options, SkPMColor ctable[], int* ctableCount) {
|
| + // Reset fCurrScanline in case of failure.
|
| + fCurrScanline = -1;
|
| + // Ensure that valid color ptrs are passed in for kIndex8 color type
|
| + if (kIndex_8_SkColorType == dstInfo.colorType()) {
|
| + if (nullptr == ctable || nullptr == ctableCount) {
|
| + return SkCodec::kInvalidParameters;
|
| + }
|
| + } else {
|
| + if (ctableCount) {
|
| + *ctableCount = 0;
|
| + }
|
| + ctableCount = nullptr;
|
| + ctable = nullptr;
|
| + }
|
| +
|
| + // Set options.
|
| + Options optsStorage;
|
| + if (nullptr == options) {
|
| + options = &optsStorage;
|
| + }
|
| +
|
| + const Result result = this->onStartScanlineDecode(dstInfo, *options, ctable, ctableCount);
|
| + if (result != SkCodec::kSuccess) {
|
| + return result;
|
| + }
|
| +
|
| + fCurrScanline = 0;
|
| + fDstInfo = dstInfo;
|
| + fOptions = *options;
|
| + return kSuccess;
|
| +}
|
| +
|
| +SkCodec::Result SkCodec::startScanlineDecode(const SkImageInfo& dstInfo) {
|
| + return this->startScanlineDecode(dstInfo, nullptr, nullptr, nullptr);
|
| +}
|
| +
|
| +SkCodec::Result SkCodec::getScanlines(void* dst, int countLines, size_t rowBytes) {
|
| + if (fCurrScanline < 0) {
|
| + return kScanlineDecodingNotStarted;
|
| + }
|
| +
|
| + SkASSERT(!fDstInfo.isEmpty());
|
| + if ((rowBytes < fDstInfo.minRowBytes() && countLines > 1 ) || countLines <= 0
|
| + || fCurrScanline + countLines > fDstInfo.height()) {
|
| + return kInvalidParameters;
|
| + }
|
| +
|
| + const Result result = this->onGetScanlines(dst, countLines, rowBytes);
|
| + fCurrScanline += countLines;
|
| + return result;
|
| +}
|
| +
|
| +SkCodec::Result SkCodec::skipScanlines(int countLines) {
|
| + if (fCurrScanline < 0) {
|
| + return kScanlineDecodingNotStarted;
|
| + }
|
| +
|
| + SkASSERT(!fDstInfo.isEmpty());
|
| + if (fCurrScanline + countLines > fDstInfo.height()) {
|
| + // Arguably, we could just skip the scanlines which are remaining,
|
| + // and return kSuccess. We choose to return invalid so the client
|
| + // can catch their bug.
|
| + return SkCodec::kInvalidParameters;
|
| + }
|
| +
|
| + const Result result = this->onSkipScanlines(countLines);
|
| + fCurrScanline += countLines;
|
| + return result;
|
| +}
|
|
|