aboutsummaryrefslogtreecommitdiffhomepage
path: root/src
diff options
context:
space:
mode:
authorGravatar msarett <msarett@google.com>2016-02-11 13:29:36 -0800
committerGravatar Commit bot <commit-bot@chromium.org>2016-02-11 13:29:36 -0800
commit9b9497ef14f23562a95afe989d1efe41c603a6f6 (patch)
tree73bcf52cd5174899c13c816d02092faccdc8453d /src
parentf8289d9bd1faff400728cb8e1ac0b1aa68bfbc32 (diff)
Implement onSkipScanlines() for bmp and wbmp
Diffstat (limited to 'src')
-rw-r--r--src/codec/SkBmpCodec.cpp10
-rw-r--r--src/codec/SkBmpCodec.h6
-rw-r--r--src/codec/SkBmpMaskCodec.cpp5
-rw-r--r--src/codec/SkBmpMaskCodec.h1
-rw-r--r--src/codec/SkBmpRLECodec.cpp15
-rw-r--r--src/codec/SkBmpRLECodec.h5
-rw-r--r--src/codec/SkBmpStandardCodec.cpp7
-rw-r--r--src/codec/SkBmpStandardCodec.h1
-rw-r--r--src/codec/SkWbmpCodec.cpp5
-rw-r--r--src/codec/SkWbmpCodec.h2
10 files changed, 43 insertions, 14 deletions
diff --git a/src/codec/SkBmpCodec.cpp b/src/codec/SkBmpCodec.cpp
index cbba28c172..babb17d32e 100644
--- a/src/codec/SkBmpCodec.cpp
+++ b/src/codec/SkBmpCodec.cpp
@@ -546,6 +546,7 @@ SkBmpCodec::SkBmpCodec(const SkImageInfo& info, SkStream* stream,
: INHERITED(info, stream)
, fBitsPerPixel(bitsPerPixel)
, fRowOrder(rowOrder)
+ , fSrcRowBytes(SkAlign4(compute_row_bytes(info.width(), fBitsPerPixel)))
{}
bool SkBmpCodec::onRewind() {
@@ -577,3 +578,12 @@ int SkBmpCodec::onGetScanlines(void* dst, int count, size_t rowBytes) {
// Decode the requested rows
return this->decodeRows(rowInfo, dst, rowBytes, this->options());
}
+
+bool SkBmpCodec::skipRows(int count) {
+ const size_t bytesToSkip = count * fSrcRowBytes;
+ return this->stream()->skip(bytesToSkip) == bytesToSkip;
+}
+
+bool SkBmpCodec::onSkipScanlines(int count) {
+ return this->skipRows(count);
+}
diff --git a/src/codec/SkBmpCodec.h b/src/codec/SkBmpCodec.h
index 5d77ca3fc8..a54734f431 100644
--- a/src/codec/SkBmpCodec.h
+++ b/src/codec/SkBmpCodec.h
@@ -81,6 +81,7 @@ protected:
*/
uint16_t bitsPerPixel() const { return fBitsPerPixel; }
SkScanlineOrder onGetScanlineOrder() const override { return fRowOrder; }
+ size_t srcRowBytes() const { return fSrcRowBytes; }
/*
* To be overriden by bmp subclasses, which provide unique implementations.
@@ -127,15 +128,18 @@ private:
virtual int decodeRows(const SkImageInfo& dstInfo, void* dst, size_t dstRowBytes,
const Options& opts) = 0;
+ virtual bool skipRows(int count);
+
Result onStartScanlineDecode(const SkImageInfo& dstInfo, const SkCodec::Options&,
SkPMColor inputColorPtr[], int* inputColorCount) override;
int onGetScanlines(void* dst, int count, size_t rowBytes) override;
- // TODO(msarett): Override default skipping with something more clever.
+ bool onSkipScanlines(int count) override;
const uint16_t fBitsPerPixel;
const SkScanlineOrder fRowOrder;
+ const size_t fSrcRowBytes;
typedef SkCodec INHERITED;
};
diff --git a/src/codec/SkBmpMaskCodec.cpp b/src/codec/SkBmpMaskCodec.cpp
index b173317c10..b603de9a03 100644
--- a/src/codec/SkBmpMaskCodec.cpp
+++ b/src/codec/SkBmpMaskCodec.cpp
@@ -18,8 +18,7 @@ SkBmpMaskCodec::SkBmpMaskCodec(const SkImageInfo& info, SkStream* stream,
: INHERITED(info, stream, bitsPerPixel, rowOrder)
, fMasks(masks)
, fMaskSwizzler(nullptr)
- , fSrcRowBytes(SkAlign4(compute_row_bytes(this->getInfo().width(), this->bitsPerPixel())))
- , fSrcBuffer(new uint8_t [fSrcRowBytes])
+ , fSrcBuffer(new uint8_t [this->srcRowBytes()])
{}
/*
@@ -92,7 +91,7 @@ int SkBmpMaskCodec::decodeRows(const SkImageInfo& dstInfo,
const int height = dstInfo.height();
for (int y = 0; y < height; y++) {
// Read a row of the input
- if (this->stream()->read(srcRow, fSrcRowBytes) != fSrcRowBytes) {
+ if (this->stream()->read(srcRow, this->srcRowBytes()) != this->srcRowBytes()) {
SkCodecPrintf("Warning: incomplete input stream.\n");
return y;
}
diff --git a/src/codec/SkBmpMaskCodec.h b/src/codec/SkBmpMaskCodec.h
index 4ec868db0e..73a8b3799d 100644
--- a/src/codec/SkBmpMaskCodec.h
+++ b/src/codec/SkBmpMaskCodec.h
@@ -55,7 +55,6 @@ private:
SkAutoTDelete<SkMasks> fMasks; // owned
SkAutoTDelete<SkMaskSwizzler> fMaskSwizzler;
- const size_t fSrcRowBytes;
SkAutoTDeleteArray<uint8_t> fSrcBuffer;
typedef SkBmpCodec INHERITED;
diff --git a/src/codec/SkBmpRLECodec.cpp b/src/codec/SkBmpRLECodec.cpp
index 05691cc079..1b95acc830 100644
--- a/src/codec/SkBmpRLECodec.cpp
+++ b/src/codec/SkBmpRLECodec.cpp
@@ -201,7 +201,7 @@ size_t SkBmpRLECodec::checkForMoreData() {
void SkBmpRLECodec::setPixel(void* dst, size_t dstRowBytes,
const SkImageInfo& dstInfo, uint32_t x, uint32_t y,
uint8_t index) {
- if (is_coord_necessary(x, fSampleX, dstInfo.width())) {
+ if (dst && is_coord_necessary(x, fSampleX, dstInfo.width())) {
// Set the row
uint32_t row = this->getDstRow(y, dstInfo.height());
@@ -234,7 +234,7 @@ void SkBmpRLECodec::setRGBPixel(void* dst, size_t dstRowBytes,
const SkImageInfo& dstInfo, uint32_t x,
uint32_t y, uint8_t red, uint8_t green,
uint8_t blue) {
- if (is_coord_necessary(x, fSampleX, dstInfo.width())) {
+ if (dst && is_coord_necessary(x, fSampleX, dstInfo.width())) {
// Set the row
uint32_t row = this->getDstRow(y, dstInfo.height());
@@ -316,7 +316,9 @@ int SkBmpRLECodec::decodeRows(const SkImageInfo& info, void* dst, size_t dstRowB
// Because of the need for transparent pixels, kN32 is the only color
// type that makes sense for the destination format.
SkASSERT(kN32_SkColorType == dstInfo.colorType());
- SkSampler::Fill(dstInfo, dst, dstRowBytes, SK_ColorTRANSPARENT, opts.fZeroInitialized);
+ if (dst) {
+ SkSampler::Fill(dstInfo, dst, dstRowBytes, SK_ColorTRANSPARENT, opts.fZeroInitialized);
+ }
// Adjust the height and the dst if the previous call to decodeRows() left us
// with lines that need to be skipped.
@@ -500,6 +502,13 @@ int SkBmpRLECodec::decodeRows(const SkImageInfo& info, void* dst, size_t dstRowB
}
}
+bool SkBmpRLECodec::skipRows(int count) {
+ const SkImageInfo rowInfo = SkImageInfo::Make(this->getInfo().width(), count, kN32_SkColorType,
+ kUnpremul_SkAlphaType);
+
+ return count == this->decodeRows(rowInfo, nullptr, 0, this->options());
+}
+
// FIXME: Make SkBmpRLECodec have no knowledge of sampling.
// Or it should do all sampling natively.
// It currently is a hybrid that needs to know what SkScaledCodec is doing.
diff --git a/src/codec/SkBmpRLECodec.h b/src/codec/SkBmpRLECodec.h
index e319a71052..2ddf8d8b90 100644
--- a/src/codec/SkBmpRLECodec.h
+++ b/src/codec/SkBmpRLECodec.h
@@ -84,9 +84,14 @@ private:
const SkImageInfo& dstInfo, uint32_t x, uint32_t y,
uint8_t red, uint8_t green, uint8_t blue);
+ /*
+ * If dst is NULL, this is a signal to skip the rows.
+ */
int decodeRows(const SkImageInfo& dstInfo, void* dst, size_t dstRowBytes,
const Options& opts) override;
+ bool skipRows(int count) override;
+
SkSampler* getSampler(bool createIfNecessary) override;
SkAutoTUnref<SkColorTable> fColorTable; // owned
diff --git a/src/codec/SkBmpStandardCodec.cpp b/src/codec/SkBmpStandardCodec.cpp
index 66a8c9a12a..47b10701d3 100644
--- a/src/codec/SkBmpStandardCodec.cpp
+++ b/src/codec/SkBmpStandardCodec.cpp
@@ -25,8 +25,7 @@ SkBmpStandardCodec::SkBmpStandardCodec(const SkImageInfo& info, SkStream* stream
, fBytesPerColor(bytesPerColor)
, fOffset(offset)
, fSwizzler(nullptr)
- , fSrcRowBytes(SkAlign4(compute_row_bytes(this->getInfo().width(), this->bitsPerPixel())))
- , fSrcBuffer(new uint8_t [fSrcRowBytes])
+ , fSrcBuffer(new uint8_t [this->srcRowBytes()])
, fIsOpaque(isOpaque)
, fInIco(inIco)
, fAndMaskRowBytes(fInIco ? SkAlign4(compute_row_bytes(this->getInfo().width(), 1)) : 0)
@@ -225,7 +224,7 @@ int SkBmpStandardCodec::decodeRows(const SkImageInfo& dstInfo, void* dst, size_t
const int height = dstInfo.height();
for (int y = 0; y < height; y++) {
// Read a row of the input
- if (this->stream()->read(fSrcBuffer.get(), fSrcRowBytes) != fSrcRowBytes) {
+ if (this->stream()->read(fSrcBuffer.get(), this->srcRowBytes()) != this->srcRowBytes()) {
SkCodecPrintf("Warning: incomplete input stream.\n");
return y;
}
@@ -262,7 +261,7 @@ int SkBmpStandardCodec::decodeRows(const SkImageInfo& dstInfo, void* dst, size_t
// Calculate how many bytes we must skip to reach the AND mask.
const int remainingScanlines = this->getInfo().height() - startScanline - height;
- const size_t bytesToSkip = remainingScanlines * fSrcRowBytes +
+ const size_t bytesToSkip = remainingScanlines * this->srcRowBytes() +
startScanline * fAndMaskRowBytes;
const size_t subStreamStartPosition = currPosition + bytesToSkip;
if (subStreamStartPosition >= length) {
diff --git a/src/codec/SkBmpStandardCodec.h b/src/codec/SkBmpStandardCodec.h
index 725b7bb68f..d3e2ed3e4f 100644
--- a/src/codec/SkBmpStandardCodec.h
+++ b/src/codec/SkBmpStandardCodec.h
@@ -90,7 +90,6 @@ private:
const uint32_t fBytesPerColor;
const uint32_t fOffset;
SkAutoTDelete<SkSwizzler> fSwizzler;
- const size_t fSrcRowBytes;
SkAutoTDeleteArray<uint8_t> fSrcBuffer;
const bool fIsOpaque;
const bool fInIco;
diff --git a/src/codec/SkWbmpCodec.cpp b/src/codec/SkWbmpCodec.cpp
index 4dd0f2544d..af1ab46f73 100644
--- a/src/codec/SkWbmpCodec.cpp
+++ b/src/codec/SkWbmpCodec.cpp
@@ -181,6 +181,11 @@ int SkWbmpCodec::onGetScanlines(void* dst, int count, size_t dstRowBytes) {
return count;
}
+bool SkWbmpCodec::onSkipScanlines(int count) {
+ const size_t bytesToSkip = count * fSrcRowBytes;
+ return this->stream()->skip(bytesToSkip) == bytesToSkip;
+}
+
SkCodec::Result SkWbmpCodec::onStartScanlineDecode(const SkImageInfo& dstInfo,
const Options& options, SkPMColor inputColorTable[], int* inputColorCount) {
if (options.fSubset) {
diff --git a/src/codec/SkWbmpCodec.h b/src/codec/SkWbmpCodec.h
index fb062c94d5..ceeadd4cc8 100644
--- a/src/codec/SkWbmpCodec.h
+++ b/src/codec/SkWbmpCodec.h
@@ -52,8 +52,8 @@ private:
SkAutoTUnref<SkColorTable> fColorTable;
SkAutoTMalloc<uint8_t> fSrcBuffer;
- // FIXME: Override onSkipScanlines to avoid swizzling.
int onGetScanlines(void* dst, int count, size_t dstRowBytes) override;
+ bool onSkipScanlines(int count) override;
Result onStartScanlineDecode(const SkImageInfo& dstInfo, const Options& options,
SkPMColor inputColorTable[], int* inputColorCount) override;