Implement onSkipScanlines() for bmp and wbmp
TBR=reed@google.com BUG=skia:4270 GOLD_TRYBOT_URL= https://gold.skia.org/search2?unt=true&query=source_type%3Dgm&master=false&issue=1691083002 Review URL: https://codereview.chromium.org/1691083002
This commit is contained in:
parent
f8289d9bd1
commit
9b9497ef14
@ -657,18 +657,7 @@ private:
|
|||||||
return kUnimplemented;
|
return kUnimplemented;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Naive default version just calls onGetScanlines on temp memory.
|
virtual bool onSkipScanlines(int /*countLines*/) { return false; }
|
||||||
virtual bool onSkipScanlines(int countLines) {
|
|
||||||
// FIXME (msarett): Make this a pure virtual and always override this.
|
|
||||||
SkAutoMalloc storage(fDstInfo.minRowBytes());
|
|
||||||
|
|
||||||
// Note that we pass 0 to rowBytes so we continue to use the same memory.
|
|
||||||
// Also note that while getScanlines checks that rowBytes is big enough,
|
|
||||||
// onGetScanlines bypasses that check.
|
|
||||||
// Calling the virtual method also means we do not double count
|
|
||||||
// countLines.
|
|
||||||
return countLines == this->onGetScanlines(storage.get(), countLines, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
virtual int onGetScanlines(void* /*dst*/, int /*countLines*/, size_t /*rowBytes*/) { return 0; }
|
virtual int onGetScanlines(void* /*dst*/, int /*countLines*/, size_t /*rowBytes*/) { return 0; }
|
||||||
|
|
||||||
|
@ -546,6 +546,7 @@ SkBmpCodec::SkBmpCodec(const SkImageInfo& info, SkStream* stream,
|
|||||||
: INHERITED(info, stream)
|
: INHERITED(info, stream)
|
||||||
, fBitsPerPixel(bitsPerPixel)
|
, fBitsPerPixel(bitsPerPixel)
|
||||||
, fRowOrder(rowOrder)
|
, fRowOrder(rowOrder)
|
||||||
|
, fSrcRowBytes(SkAlign4(compute_row_bytes(info.width(), fBitsPerPixel)))
|
||||||
{}
|
{}
|
||||||
|
|
||||||
bool SkBmpCodec::onRewind() {
|
bool SkBmpCodec::onRewind() {
|
||||||
@ -577,3 +578,12 @@ int SkBmpCodec::onGetScanlines(void* dst, int count, size_t rowBytes) {
|
|||||||
// Decode the requested rows
|
// Decode the requested rows
|
||||||
return this->decodeRows(rowInfo, dst, rowBytes, this->options());
|
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);
|
||||||
|
}
|
||||||
|
@ -81,6 +81,7 @@ protected:
|
|||||||
*/
|
*/
|
||||||
uint16_t bitsPerPixel() const { return fBitsPerPixel; }
|
uint16_t bitsPerPixel() const { return fBitsPerPixel; }
|
||||||
SkScanlineOrder onGetScanlineOrder() const override { return fRowOrder; }
|
SkScanlineOrder onGetScanlineOrder() const override { return fRowOrder; }
|
||||||
|
size_t srcRowBytes() const { return fSrcRowBytes; }
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* To be overriden by bmp subclasses, which provide unique implementations.
|
* 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,
|
virtual int decodeRows(const SkImageInfo& dstInfo, void* dst, size_t dstRowBytes,
|
||||||
const Options& opts) = 0;
|
const Options& opts) = 0;
|
||||||
|
|
||||||
|
virtual bool skipRows(int count);
|
||||||
|
|
||||||
Result onStartScanlineDecode(const SkImageInfo& dstInfo, const SkCodec::Options&,
|
Result onStartScanlineDecode(const SkImageInfo& dstInfo, const SkCodec::Options&,
|
||||||
SkPMColor inputColorPtr[], int* inputColorCount) override;
|
SkPMColor inputColorPtr[], int* inputColorCount) override;
|
||||||
|
|
||||||
int onGetScanlines(void* dst, int count, size_t rowBytes) 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 uint16_t fBitsPerPixel;
|
||||||
const SkScanlineOrder fRowOrder;
|
const SkScanlineOrder fRowOrder;
|
||||||
|
const size_t fSrcRowBytes;
|
||||||
|
|
||||||
typedef SkCodec INHERITED;
|
typedef SkCodec INHERITED;
|
||||||
};
|
};
|
||||||
|
@ -18,8 +18,7 @@ SkBmpMaskCodec::SkBmpMaskCodec(const SkImageInfo& info, SkStream* stream,
|
|||||||
: INHERITED(info, stream, bitsPerPixel, rowOrder)
|
: INHERITED(info, stream, bitsPerPixel, rowOrder)
|
||||||
, fMasks(masks)
|
, fMasks(masks)
|
||||||
, fMaskSwizzler(nullptr)
|
, fMaskSwizzler(nullptr)
|
||||||
, fSrcRowBytes(SkAlign4(compute_row_bytes(this->getInfo().width(), this->bitsPerPixel())))
|
, fSrcBuffer(new uint8_t [this->srcRowBytes()])
|
||||||
, fSrcBuffer(new uint8_t [fSrcRowBytes])
|
|
||||||
{}
|
{}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -92,7 +91,7 @@ int SkBmpMaskCodec::decodeRows(const SkImageInfo& dstInfo,
|
|||||||
const int height = dstInfo.height();
|
const int height = dstInfo.height();
|
||||||
for (int y = 0; y < height; y++) {
|
for (int y = 0; y < height; y++) {
|
||||||
// Read a row of the input
|
// 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");
|
SkCodecPrintf("Warning: incomplete input stream.\n");
|
||||||
return y;
|
return y;
|
||||||
}
|
}
|
||||||
|
@ -55,7 +55,6 @@ private:
|
|||||||
|
|
||||||
SkAutoTDelete<SkMasks> fMasks; // owned
|
SkAutoTDelete<SkMasks> fMasks; // owned
|
||||||
SkAutoTDelete<SkMaskSwizzler> fMaskSwizzler;
|
SkAutoTDelete<SkMaskSwizzler> fMaskSwizzler;
|
||||||
const size_t fSrcRowBytes;
|
|
||||||
SkAutoTDeleteArray<uint8_t> fSrcBuffer;
|
SkAutoTDeleteArray<uint8_t> fSrcBuffer;
|
||||||
|
|
||||||
typedef SkBmpCodec INHERITED;
|
typedef SkBmpCodec INHERITED;
|
||||||
|
@ -201,7 +201,7 @@ size_t SkBmpRLECodec::checkForMoreData() {
|
|||||||
void SkBmpRLECodec::setPixel(void* dst, size_t dstRowBytes,
|
void SkBmpRLECodec::setPixel(void* dst, size_t dstRowBytes,
|
||||||
const SkImageInfo& dstInfo, uint32_t x, uint32_t y,
|
const SkImageInfo& dstInfo, uint32_t x, uint32_t y,
|
||||||
uint8_t index) {
|
uint8_t index) {
|
||||||
if (is_coord_necessary(x, fSampleX, dstInfo.width())) {
|
if (dst && is_coord_necessary(x, fSampleX, dstInfo.width())) {
|
||||||
// Set the row
|
// Set the row
|
||||||
uint32_t row = this->getDstRow(y, dstInfo.height());
|
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,
|
const SkImageInfo& dstInfo, uint32_t x,
|
||||||
uint32_t y, uint8_t red, uint8_t green,
|
uint32_t y, uint8_t red, uint8_t green,
|
||||||
uint8_t blue) {
|
uint8_t blue) {
|
||||||
if (is_coord_necessary(x, fSampleX, dstInfo.width())) {
|
if (dst && is_coord_necessary(x, fSampleX, dstInfo.width())) {
|
||||||
// Set the row
|
// Set the row
|
||||||
uint32_t row = this->getDstRow(y, dstInfo.height());
|
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
|
// Because of the need for transparent pixels, kN32 is the only color
|
||||||
// type that makes sense for the destination format.
|
// type that makes sense for the destination format.
|
||||||
SkASSERT(kN32_SkColorType == dstInfo.colorType());
|
SkASSERT(kN32_SkColorType == dstInfo.colorType());
|
||||||
|
if (dst) {
|
||||||
SkSampler::Fill(dstInfo, dst, dstRowBytes, SK_ColorTRANSPARENT, opts.fZeroInitialized);
|
SkSampler::Fill(dstInfo, dst, dstRowBytes, SK_ColorTRANSPARENT, opts.fZeroInitialized);
|
||||||
|
}
|
||||||
|
|
||||||
// Adjust the height and the dst if the previous call to decodeRows() left us
|
// Adjust the height and the dst if the previous call to decodeRows() left us
|
||||||
// with lines that need to be skipped.
|
// 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.
|
// FIXME: Make SkBmpRLECodec have no knowledge of sampling.
|
||||||
// Or it should do all sampling natively.
|
// Or it should do all sampling natively.
|
||||||
// It currently is a hybrid that needs to know what SkScaledCodec is doing.
|
// It currently is a hybrid that needs to know what SkScaledCodec is doing.
|
||||||
|
@ -84,9 +84,14 @@ private:
|
|||||||
const SkImageInfo& dstInfo, uint32_t x, uint32_t y,
|
const SkImageInfo& dstInfo, uint32_t x, uint32_t y,
|
||||||
uint8_t red, uint8_t green, uint8_t blue);
|
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,
|
int decodeRows(const SkImageInfo& dstInfo, void* dst, size_t dstRowBytes,
|
||||||
const Options& opts) override;
|
const Options& opts) override;
|
||||||
|
|
||||||
|
bool skipRows(int count) override;
|
||||||
|
|
||||||
SkSampler* getSampler(bool createIfNecessary) override;
|
SkSampler* getSampler(bool createIfNecessary) override;
|
||||||
|
|
||||||
SkAutoTUnref<SkColorTable> fColorTable; // owned
|
SkAutoTUnref<SkColorTable> fColorTable; // owned
|
||||||
|
@ -25,8 +25,7 @@ SkBmpStandardCodec::SkBmpStandardCodec(const SkImageInfo& info, SkStream* stream
|
|||||||
, fBytesPerColor(bytesPerColor)
|
, fBytesPerColor(bytesPerColor)
|
||||||
, fOffset(offset)
|
, fOffset(offset)
|
||||||
, fSwizzler(nullptr)
|
, fSwizzler(nullptr)
|
||||||
, fSrcRowBytes(SkAlign4(compute_row_bytes(this->getInfo().width(), this->bitsPerPixel())))
|
, fSrcBuffer(new uint8_t [this->srcRowBytes()])
|
||||||
, fSrcBuffer(new uint8_t [fSrcRowBytes])
|
|
||||||
, fIsOpaque(isOpaque)
|
, fIsOpaque(isOpaque)
|
||||||
, fInIco(inIco)
|
, fInIco(inIco)
|
||||||
, fAndMaskRowBytes(fInIco ? SkAlign4(compute_row_bytes(this->getInfo().width(), 1)) : 0)
|
, 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();
|
const int height = dstInfo.height();
|
||||||
for (int y = 0; y < height; y++) {
|
for (int y = 0; y < height; y++) {
|
||||||
// Read a row of the input
|
// 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");
|
SkCodecPrintf("Warning: incomplete input stream.\n");
|
||||||
return y;
|
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.
|
// Calculate how many bytes we must skip to reach the AND mask.
|
||||||
const int remainingScanlines = this->getInfo().height() - startScanline - height;
|
const int remainingScanlines = this->getInfo().height() - startScanline - height;
|
||||||
const size_t bytesToSkip = remainingScanlines * fSrcRowBytes +
|
const size_t bytesToSkip = remainingScanlines * this->srcRowBytes() +
|
||||||
startScanline * fAndMaskRowBytes;
|
startScanline * fAndMaskRowBytes;
|
||||||
const size_t subStreamStartPosition = currPosition + bytesToSkip;
|
const size_t subStreamStartPosition = currPosition + bytesToSkip;
|
||||||
if (subStreamStartPosition >= length) {
|
if (subStreamStartPosition >= length) {
|
||||||
|
@ -90,7 +90,6 @@ private:
|
|||||||
const uint32_t fBytesPerColor;
|
const uint32_t fBytesPerColor;
|
||||||
const uint32_t fOffset;
|
const uint32_t fOffset;
|
||||||
SkAutoTDelete<SkSwizzler> fSwizzler;
|
SkAutoTDelete<SkSwizzler> fSwizzler;
|
||||||
const size_t fSrcRowBytes;
|
|
||||||
SkAutoTDeleteArray<uint8_t> fSrcBuffer;
|
SkAutoTDeleteArray<uint8_t> fSrcBuffer;
|
||||||
const bool fIsOpaque;
|
const bool fIsOpaque;
|
||||||
const bool fInIco;
|
const bool fInIco;
|
||||||
|
@ -181,6 +181,11 @@ int SkWbmpCodec::onGetScanlines(void* dst, int count, size_t dstRowBytes) {
|
|||||||
return count;
|
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,
|
SkCodec::Result SkWbmpCodec::onStartScanlineDecode(const SkImageInfo& dstInfo,
|
||||||
const Options& options, SkPMColor inputColorTable[], int* inputColorCount) {
|
const Options& options, SkPMColor inputColorTable[], int* inputColorCount) {
|
||||||
if (options.fSubset) {
|
if (options.fSubset) {
|
||||||
|
@ -52,8 +52,8 @@ private:
|
|||||||
SkAutoTUnref<SkColorTable> fColorTable;
|
SkAutoTUnref<SkColorTable> fColorTable;
|
||||||
SkAutoTMalloc<uint8_t> fSrcBuffer;
|
SkAutoTMalloc<uint8_t> fSrcBuffer;
|
||||||
|
|
||||||
// FIXME: Override onSkipScanlines to avoid swizzling.
|
|
||||||
int onGetScanlines(void* dst, int count, size_t dstRowBytes) override;
|
int onGetScanlines(void* dst, int count, size_t dstRowBytes) override;
|
||||||
|
bool onSkipScanlines(int count) override;
|
||||||
Result onStartScanlineDecode(const SkImageInfo& dstInfo, const Options& options,
|
Result onStartScanlineDecode(const SkImageInfo& dstInfo, const Options& options,
|
||||||
SkPMColor inputColorTable[], int* inputColorCount) override;
|
SkPMColor inputColorTable[], int* inputColorCount) override;
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user