Chromium Code Reviews| Index: src/codec/SkCodec.cpp |
| diff --git a/src/codec/SkCodec.cpp b/src/codec/SkCodec.cpp |
| index 8468f8a09996d1c7e79363970f9103e106049c7a..fd0cda0c66a69004e7461c6cd319612203b10b56 100644 |
| --- a/src/codec/SkCodec.cpp |
| +++ b/src/codec/SkCodec.cpp |
| @@ -228,6 +228,66 @@ SkCodec::Result SkCodec::getPixels(const SkImageInfo& info, void* pixels, size_t |
| return this->getPixels(info, pixels, rowBytes, nullptr, nullptr, nullptr); |
| } |
| +SkCodec::Result SkCodec::startIncrementalDecode(const SkImageInfo& dstInfo, |
| + const SkCodec::Options* options, SkPMColor* ctable, int* ctableCount) { |
| + fStartedIncrementalDecode = false; |
| + |
| + // FIXME: Share more code with getPixels/startScanlineDecode? |
|
msarett
2016/05/20 15:04:40
I think this would be a good chance to share the c
scroggo_chromium
2016/05/20 16:51:59
I moved the checks for index8, colortables, etc in
|
| + // Ensure that valid color ptrs are passed in for kIndex8 color type |
| + if (kIndex_8_SkColorType == dstInfo.colorType()) { |
| + if (nullptr == ctable || nullptr == ctableCount) { |
| + return kInvalidParameters; |
| + } |
| + } else { |
| + if (ctableCount) { |
| + *ctableCount = 0; |
| + } |
| + ctableCount = nullptr; |
| + ctable = nullptr; |
| + } |
| + |
| + // FIXME: If the rows come after the rows of a previous incremental decode, |
| + // we might be able to skip the rewind, but only the implementation knows |
| + // that. (e.g. PNG will always need to rewind, since we called longjmp, but |
| + // a bottom-up BMP could skip rewinding if the new rows are above the old |
| + // rows.) |
| + if (!this->rewindIfNeeded()) { |
| + return kCouldNotRewind; |
| + } |
| + |
| + // Set options. |
| + Options optsStorage; |
| + if (nullptr == options) { |
| + options = &optsStorage; |
| + } else if (options->fSubset) { |
| + SkIRect size = SkIRect::MakeSize(dstInfo.dimensions()); |
| + if (!size.contains(*options->fSubset)) { |
| + return kInvalidParameters; |
| + } |
| + |
| + const int top = options->fSubset->top(); |
| + const int bottom = options->fSubset->bottom(); |
| + if (top < 0 || top >= dstInfo.height() || top >= bottom || bottom > dstInfo.height()) { |
| + return kInvalidParameters; |
| + } |
| + } |
| + |
| + if (!this->dimensionsSupported(dstInfo.dimensions())) { |
| + return kInvalidScale; |
| + } |
| + |
| + fDstInfo = dstInfo; |
| + fOptions = *options; |
| + |
| + const Result result = this->onStartIncrementalDecode(dstInfo, fOptions, ctable, |
| + ctableCount); |
| + if (kSuccess == result) { |
| + fStartedIncrementalDecode = true; |
| + } |
| + return result; |
| +} |
| + |
| + |
| SkCodec::Result SkCodec::startScanlineDecode(const SkImageInfo& dstInfo, |
| const SkCodec::Options* options, SkPMColor ctable[], int* ctableCount) { |
| // Reset fCurrScanline in case of failure. |
| @@ -331,7 +391,6 @@ int SkCodec::outputScanline(int inputScanline) const { |
| int SkCodec::onOutputScanline(int inputScanline) const { |
| switch (this->getScanlineOrder()) { |
| case kTopDown_SkScanlineOrder: |
| - case kNone_SkScanlineOrder: |
| return inputScanline; |
| case kBottomUp_SkScanlineOrder: |
| return this->getInfo().height() - inputScanline - 1; |
| @@ -365,8 +424,7 @@ void SkCodec::fillIncompleteImage(const SkImageInfo& info, void* dst, size_t row |
| } |
| switch (this->getScanlineOrder()) { |
| - case kTopDown_SkScanlineOrder: |
| - case kNone_SkScanlineOrder: { |
| + case kTopDown_SkScanlineOrder: { |
| const SkImageInfo fillInfo = info.makeWH(fillWidth, linesRemaining); |
| fillDst = SkTAddOffset<void>(dst, linesDecoded * rowBytes); |
| fill_proc(fillInfo, fillDst, rowBytes, fillValue, zeroInit, sampler); |