diff options
author | scroggo <scroggo@google.com> | 2015-10-02 13:14:46 -0700 |
---|---|---|
committer | Commit bot <commit-bot@chromium.org> | 2015-10-02 13:14:46 -0700 |
commit | e7fc14b55bb8c41ba054abf0bfa09cdd6ec84671 (patch) | |
tree | 81525743c2c436a60f4127cf04f0f96d5dc3bed5 /src/codec/SkBmpRLECodec.cpp | |
parent | 65f7c9fa7ed028159a4a2c792ccc1dcdf718eed2 (diff) |
Move all knowledge of X sampling into SkScaledCodec
Prior to this CL, each SkCodec subclass that allows sampling does an
extra check in onStartScanlineDecode to determine whether the X dimension
is supported for sampling. Remove this check, and provide a way for
SkScaledCodec to directly access the SkSwizzler, and update it to do
sampling. This way, the SkCodec knows nothing of sampling, but we can
still save the extra step of sampling afterwards.
FIXME: SkBmpRLECodec still calls SkScaledCodec::DimensionsSupported. It
seems like it could directly support sampling, rather than dealing with
SkScaledCodec (partially).
Add a new base class for SkSwizzler. It allows updating the swizzler
after it was created, which is done by SkScaledCodec. Modify SkSwizzler's
constructor/factory function to stop taking any info about sampling,
assume the sample size is one, and move modifying that into a virtual
function overridden from the base class.
BUG=skia:4284
Review URL: https://codereview.chromium.org/1372973002
Diffstat (limited to 'src/codec/SkBmpRLECodec.cpp')
-rw-r--r-- | src/codec/SkBmpRLECodec.cpp | 46 |
1 files changed, 38 insertions, 8 deletions
diff --git a/src/codec/SkBmpRLECodec.cpp b/src/codec/SkBmpRLECodec.cpp index e76a23ed14..fe499c6a6d 100644 --- a/src/codec/SkBmpRLECodec.cpp +++ b/src/codec/SkBmpRLECodec.cpp @@ -43,10 +43,6 @@ SkCodec::Result SkBmpRLECodec::onGetPixels(const SkImageInfo& dstInfo, // Subsets are not supported. return kUnimplemented; } - if (dstInfo.dimensions() != this->getInfo().dimensions()) { - SkCodecPrintf("Error: scaling not supported.\n"); - return kInvalidScale; - } if (!conversion_possible(dstInfo, this->getInfo())) { SkCodecPrintf("Error: cannot convert input type to output type.\n"); return kInvalidConversion; @@ -253,6 +249,9 @@ void SkBmpRLECodec::setRGBPixel(void* dst, size_t dstRowBytes, SkCodec::Result SkBmpRLECodec::prepareToDecode(const SkImageInfo& dstInfo, const SkCodec::Options& options, SkPMColor inputColorPtr[], int* inputColorCount) { + // Reset fSampleX. If it needs to be a value other than 1, it will get modified by + // the sampler. + fSampleX = 1; // Create the color table if necessary and prepare the stream for decode // Note that if it is non-NULL, inputColorCount will be modified if (!this->createColorTable(inputColorCount)) { @@ -269,8 +268,6 @@ SkCodec::Result SkBmpRLECodec::prepareToDecode(const SkImageInfo& dstInfo, return SkCodec::kInvalidConversion; } - SkScaledCodec::ComputeSampleSize(dstInfo, this->getInfo(), &fSampleX, NULL); - return SkCodec::kSuccess; } @@ -278,7 +275,7 @@ SkCodec::Result SkBmpRLECodec::prepareToDecode(const SkImageInfo& dstInfo, * Performs the bitmap decoding for RLE input format * RLE decoding is performed all at once, rather than a one row at a time */ -SkCodec::Result SkBmpRLECodec::decodeRows(const SkImageInfo& dstInfo, +SkCodec::Result SkBmpRLECodec::decodeRows(const SkImageInfo& info, void* dst, size_t dstRowBytes, const Options& opts) { // Set RLE flags @@ -289,7 +286,10 @@ SkCodec::Result SkBmpRLECodec::decodeRows(const SkImageInfo& dstInfo, // Set constant values const int width = this->getInfo().width(); - const int height = dstInfo.height(); + const int height = info.height(); + + // Account for sampling. + SkImageInfo dstInfo = info.makeWH(get_scaled_dimension(width, fSampleX), height); // Destination parameters int x = 0; @@ -466,3 +466,33 @@ SkCodec::Result SkBmpRLECodec::decodeRows(const SkImageInfo& dstInfo, } } } + +class SkBmpRLESampler : public SkSampler { +public: + SkBmpRLESampler(SkBmpRLECodec* codec) + : fCodec(codec) + { + SkASSERT(fCodec); + } + +private: + int onSetSampleX(int sampleX) { + return fCodec->setSampleX(sampleX); + } + + // Unowned pointer. fCodec will delete this class in its destructor. + SkBmpRLECodec* fCodec; +}; + +SkSampler* SkBmpRLECodec::getSampler() { + if (!fSampler) { + fSampler.reset(new SkBmpRLESampler(this)); + } + + return fSampler; +} + +int SkBmpRLECodec::setSampleX(int sampleX) { + fSampleX = sampleX; + return get_scaled_dimension(this->getInfo().width(), sampleX); +} |