| Index: src/codec/SkBmpCodec.cpp
|
| diff --git a/src/codec/SkBmpCodec.cpp b/src/codec/SkBmpCodec.cpp
|
| index 20af2da06fe0db122b86b49bef63b5c7ba6da8bc..18db3d99cb4be4e2c716916b0f57a9e1314262f1 100644
|
| --- a/src/codec/SkBmpCodec.cpp
|
| +++ b/src/codec/SkBmpCodec.cpp
|
| @@ -11,6 +11,7 @@
|
| #include "SkBmpStandardCodec.h"
|
| #include "SkCodecPriv.h"
|
| #include "SkColorPriv.h"
|
| +#include "SkScaledCodec.h"
|
| #include "SkStream.h"
|
|
|
| /*
|
| @@ -540,6 +541,14 @@ bool SkBmpCodec::onRewind() {
|
| return SkBmpCodec::ReadHeader(this->stream(), this->inIco(), NULL);
|
| }
|
|
|
| +int32_t SkBmpCodec::getDstRow(int32_t y, int32_t height) {
|
| + if (SkBmpCodec::kTopDown_RowOrder == fRowOrder) {
|
| + return y;
|
| + } else {
|
| + return height - y - 1;
|
| + }
|
| +}
|
| +
|
| /*
|
| * Get the destination row to start filling from
|
| * Used to fill the remainder of the image on incomplete input for bmps
|
| @@ -563,3 +572,77 @@ uint32_t SkBmpCodec::computeNumColors(uint32_t numColors) {
|
| }
|
| return numColors;
|
| }
|
| +
|
| +/*
|
| + * Scanline decoder for bmps
|
| + */
|
| +class SkBmpScanlineDecoder : public SkScanlineDecoder {
|
| +public:
|
| + SkBmpScanlineDecoder(SkBmpCodec* codec)
|
| + : INHERITED(codec->getInfo())
|
| + , fCodec(codec)
|
| + {}
|
| +
|
| + SkEncodedFormat onGetEncodedFormat() const override {
|
| + return kBMP_SkEncodedFormat;
|
| + }
|
| +
|
| + SkCodec::Result onStart(const SkImageInfo& dstInfo, const SkCodec::Options& options,
|
| + SkPMColor inputColorPtr[], int* inputColorCount) override {
|
| + if (!fCodec->rewindIfNeeded()) {
|
| + return SkCodec::kCouldNotRewind;
|
| + }
|
| + if (options.fSubset) {
|
| + // Subsets are not supported.
|
| + return SkCodec::kUnimplemented;
|
| + }
|
| + if (dstInfo.dimensions() != this->getInfo().dimensions()) {
|
| + if (!SkScaledCodec::DimensionsSupportedForSampling(this->getInfo(), dstInfo)) {
|
| + return SkCodec::kInvalidScale;
|
| + }
|
| + }
|
| + if (!conversion_possible(dstInfo, this->getInfo())) {
|
| + SkCodecPrintf("Error: cannot convert input type to output type.\n");
|
| + return SkCodec::kInvalidConversion;
|
| + }
|
| +
|
| + return fCodec->prepareToDecode(dstInfo, options, inputColorPtr, inputColorCount);
|
| + }
|
| +
|
| + SkCodec::Result onGetScanlines(void* dst, int count, size_t rowBytes) override {
|
| + // Create a new image info representing the portion of the image to decode
|
| + SkImageInfo rowInfo = this->dstInfo().makeWH(this->dstInfo().width(), count);
|
| +
|
| + // Decode the requested rows
|
| + return fCodec->decodeRows(rowInfo, dst, rowBytes, this->options());
|
| + }
|
| +
|
| + SkScanlineOrder onGetScanlineOrder() const override {
|
| + if (SkBmpCodec::kTopDown_RowOrder == fCodec->fRowOrder) {
|
| + return kTopDown_SkScanlineOrder;
|
| + } else {
|
| + return kOutOfOrder_SkScanlineOrder;
|
| + }
|
| + }
|
| +
|
| + int onGetY() const override {
|
| + return fCodec->getDstRow(INHERITED::onGetY(), this->dstInfo().height());
|
| + }
|
| +
|
| + // TODO(msarett): Override default skipping with something more clever.
|
| + // TODO(msarett): Consider other optimizations for this codec.
|
| +
|
| +private:
|
| + SkAutoTDelete<SkBmpCodec> fCodec;
|
| +
|
| + typedef SkScanlineDecoder INHERITED;
|
| +};
|
| +
|
| +SkScanlineDecoder* SkBmpCodec::NewSDFromStream(SkStream* stream) {
|
| + SkAutoTDelete<SkBmpCodec> codec(static_cast<SkBmpCodec*>(SkBmpCodec::NewFromStream(stream)));
|
| + if (!codec) {
|
| + return NULL;
|
| + }
|
| +
|
| + return SkNEW_ARGS(SkBmpScanlineDecoder, (codec.detach()));
|
| +}
|
|
|