aboutsummaryrefslogtreecommitdiffhomepage
path: root/include/codec
diff options
context:
space:
mode:
authorGravatar emmaleer <emmaleer@google.com>2015-08-13 11:26:57 -0700
committerGravatar Commit bot <commit-bot@chromium.org>2015-08-13 11:26:57 -0700
commit0944100ac89f797714eeae0cf2875e2335ff52ee (patch)
tree4eecdf5aa0aa3c0285b319c63b148fd672c2508b /include/codec
parente516e4fa2b681dc97775c1581eef38d7559f33d1 (diff)
SkScaledCodec class
This class does scaling by using a scanlineDecoder. getScanlines and skipScanlines are used for y sampling, the swizzler is used for x sampling this class is currently only working for png and jpeg images I will update other Codec types to work soon For SkJpegCodec to implement width wise swizzling it now uses a swizzler. I ran performance tests on this change. Here are the performance test results: https://docs.google.com/a/google.com/spreadsheets/d/1D7-Q_GXD_dI68LZO005NNvb8Wq2Ee0wEBEPG72671yw/edit?usp=sharing BUG=skia: Review URL: https://codereview.chromium.org/1260673002
Diffstat (limited to 'include/codec')
-rw-r--r--include/codec/SkCodec.h2
-rw-r--r--include/codec/SkScaledCodec.h70
-rw-r--r--include/codec/SkScanlineDecoder.h42
3 files changed, 114 insertions, 0 deletions
diff --git a/include/codec/SkCodec.h b/include/codec/SkCodec.h
index a0bd18a8e5..3465c1df5b 100644
--- a/include/codec/SkCodec.h
+++ b/include/codec/SkCodec.h
@@ -51,6 +51,8 @@ public:
* Return a size that approximately supports the desired scale factor.
* The codec may not be able to scale efficiently to the exact scale
* factor requested, so return a size that approximates that scale.
+ * The returned value is the codec's suggestion for the closest valid
+ * scale that it can natively support
*/
SkISize getScaledDimensions(float desiredScale) const {
return this->onGetScaledDimensions(desiredScale);
diff --git a/include/codec/SkScaledCodec.h b/include/codec/SkScaledCodec.h
new file mode 100644
index 0000000000..1bcdf085b2
--- /dev/null
+++ b/include/codec/SkScaledCodec.h
@@ -0,0 +1,70 @@
+/*
+ * Copyright 2015 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+#ifndef SkScaledCodec_DEFINED
+#define SkScaledCodec_DEFINED
+
+#include "SkCodec.h"
+#include "SkScanlineDecoder.h"
+
+class SkScanlineDecoder;
+class SkStream;
+
+/**
+ * This class implements scaling, by sampling scanlines in the y direction.
+ * x-wise sampling is implemented in the swizzler, when getScanlines() is called.
+ */
+class SkScaledCodec : public SkCodec {
+public:
+ static SkCodec* NewFromStream(SkStream*);
+ static SkCodec* NewFromData(SkData*);
+
+ virtual ~SkScaledCodec();
+
+ /**
+ * returns whether a destination's dimensions are supported for down sampling
+ */
+ static bool DimensionsSupportedForSampling(const SkImageInfo& srcInfo,
+ const SkImageInfo& dstInfo) {
+ // heights must be equal as no native y sampling is supported
+ if (dstInfo.height() != srcInfo.height()) {
+ return false;
+ }
+ // only support down sampling, dstWidth cannot be larger that srcWidth
+ if(dstInfo.width() > srcInfo.width()) {
+ return false;
+ }
+ return true;
+ }
+
+ static void ComputeSampleSize(const SkImageInfo& dstInfo, const SkImageInfo& srcInfo,
+ int* sampleSizeX, int* sampleSizeY);
+
+protected:
+ /**
+ * Recommend a set of destination dimensions given a requested scale
+ */
+ SkISize onGetScaledDimensions(float desiredScale) const override;
+
+ Result onGetPixels(const SkImageInfo&, void*, size_t, const Options&, SkPMColor*, int*)
+ override;
+ SkEncodedFormat onGetEncodedFormat() const override {
+ return fScanlineDecoder->getEncodedFormat();
+ }
+
+ bool onReallyHasAlpha() const override {
+ return fScanlineDecoder->reallyHasAlpha();
+ }
+
+private:
+
+ SkAutoTDelete<SkScanlineDecoder> fScanlineDecoder;
+
+ explicit SkScaledCodec(SkScanlineDecoder*);
+
+ typedef SkCodec INHERITED;
+};
+#endif // SkScaledCodec_DEFINED
diff --git a/include/codec/SkScanlineDecoder.h b/include/codec/SkScanlineDecoder.h
index c233663dbd..c547f6701f 100644
--- a/include/codec/SkScanlineDecoder.h
+++ b/include/codec/SkScanlineDecoder.h
@@ -46,6 +46,18 @@ public:
virtual ~SkScanlineDecoder() {}
/**
+ * Return a size that approximately supports the desired scale factor.
+ * The codec may not be able to scale efficiently to the exact scale
+ * factor requested, so return a size that approximates that scale.
+ * The returned value is the codec's suggestion for the closest valid
+ * scale that it can natively support
+ * FIXME: share this with SkCodec
+ */
+ SkISize getScaledDimensions(float desiredScale) {
+ return this->onGetScaledDimensions(desiredScale);
+ }
+
+ /**
* Returns the default info, corresponding to the encoded data.
*/
const SkImageInfo& getInfo() { return fSrcInfo; }
@@ -135,14 +147,44 @@ public:
return this->onReallyHasAlpha();
}
+ /**
+ * Format of the encoded data.
+ */
+ SkEncodedFormat getEncodedFormat() const { return this->onGetEncodedFormat(); }
+
+ /**
+ * returns true if the image must be scaled, in the y direction, after reading, not during.
+ * To scale afterwards, we first decode every line and then sample the lines we want afterwards.
+ * An example is interlaced pngs, where calling getScanlines once (regardless of the count
+ * used) needs to read the entire image, therefore it is inefficient to call
+ * getScanlines more than once. Instead, it should only ever be called with all the
+ * rows needed.
+ */
+ bool requiresPostYSampling() {
+ return this->onRequiresPostYSampling();
+ }
+
protected:
SkScanlineDecoder(const SkImageInfo& srcInfo)
: fSrcInfo(srcInfo)
, fDstInfo()
, fCurrScanline(0) {}
+ virtual SkISize onGetScaledDimensions(float /* desiredScale */) {
+ // By default, scaling is not supported.
+ return this->getInfo().dimensions();
+ }
+
+ virtual SkEncodedFormat onGetEncodedFormat() const = 0;
+
virtual bool onReallyHasAlpha() const { return false; }
+ /**
+ * returns true if the image type is hard to sample and must be scaled after reading, not during
+ * An example is interlaced pngs, where the entire image must be read for each decode
+ */
+ virtual bool onRequiresPostYSampling() { return false; }
+
const SkImageInfo& dstInfo() const { return fDstInfo; }
private: