Implement SkGifCodec::onSkipScanlines()
This should give a performance improvment because we are able to skip swizzling pixels. This should also fix valgrind failures caused by color table lookups with uninitialized memory. BUG=skia:4270 Review URL: https://codereview.chromium.org/1460073002
This commit is contained in:
parent
da707bf563
commit
72261c0afd
@ -506,10 +506,36 @@ SkCodec::Result SkGifCodec::onStartScanlineDecode(const SkImageInfo& dstInfo,
|
||||
return this->prepareToDecode(dstInfo, inputColorPtr, inputColorCount, this->options());
|
||||
}
|
||||
|
||||
void SkGifCodec::handleScanlineFrame(int count, int* rowsBeforeFrame, int* rowsInFrame) {
|
||||
if (fFrameIsSubset) {
|
||||
const int currRow = this->INHERITED::nextScanline();
|
||||
|
||||
// The number of rows that remain to be skipped before reaching rows that we
|
||||
// actually must decode into.
|
||||
// This must be at least zero. We also make sure that it is less than or
|
||||
// equal to count, since we will skip at most count rows.
|
||||
*rowsBeforeFrame = SkTMin(count, SkTMax(0, fFrameRect.top() - currRow));
|
||||
|
||||
// Rows left to decode once we reach the start of the frame.
|
||||
const int rowsLeft = count - *rowsBeforeFrame;
|
||||
|
||||
// Count the number of that extend beyond the bottom of the frame. We do not
|
||||
// need to decode into these rows.
|
||||
const int rowsAfterFrame = SkTMax(0, currRow + rowsLeft - fFrameRect.bottom());
|
||||
|
||||
// Set the actual number of source rows that we need to decode.
|
||||
*rowsInFrame = rowsLeft - rowsAfterFrame;
|
||||
} else {
|
||||
*rowsBeforeFrame = 0;
|
||||
*rowsInFrame = count;
|
||||
}
|
||||
}
|
||||
|
||||
int SkGifCodec::onGetScanlines(void* dst, int count, size_t rowBytes) {
|
||||
int rowsBeforeFrame = 0;
|
||||
int rowsAfterFrame = 0;
|
||||
int rowsInFrame = count;
|
||||
int rowsBeforeFrame;
|
||||
int rowsInFrame;
|
||||
this->handleScanlineFrame(count, &rowsBeforeFrame, &rowsInFrame);
|
||||
|
||||
if (fFrameIsSubset) {
|
||||
// Fill the requested rows
|
||||
SkImageInfo fillInfo = this->dstInfo().makeWH(this->dstInfo().width(), count);
|
||||
@ -517,15 +543,8 @@ int SkGifCodec::onGetScanlines(void* dst, int count, size_t rowBytes) {
|
||||
this->dstInfo().alphaType());
|
||||
fSwizzler->fill(fillInfo, dst, rowBytes, fillValue, this->options().fZeroInitialized);
|
||||
|
||||
// Do nothing for rows before the image frame
|
||||
rowsBeforeFrame = SkTMax(0, fFrameRect.top() - this->INHERITED::nextScanline());
|
||||
rowsInFrame = SkTMax(0, rowsInFrame - rowsBeforeFrame);
|
||||
// Start to write pixels at the start of the image frame
|
||||
dst = SkTAddOffset<void>(dst, rowBytes * rowsBeforeFrame);
|
||||
|
||||
// Do nothing for rows after the image frame
|
||||
rowsAfterFrame = SkTMax(0,
|
||||
this->INHERITED::nextScanline() + rowsInFrame - fFrameRect.bottom());
|
||||
rowsInFrame = SkTMax(0, rowsInFrame - rowsAfterFrame);
|
||||
}
|
||||
|
||||
for (int i = 0; i < rowsInFrame; i++) {
|
||||
@ -539,6 +558,20 @@ int SkGifCodec::onGetScanlines(void* dst, int count, size_t rowBytes) {
|
||||
return count;
|
||||
}
|
||||
|
||||
bool SkGifCodec::onSkipScanlines(int count) {
|
||||
int rowsBeforeFrame;
|
||||
int rowsInFrame;
|
||||
this->handleScanlineFrame(count, &rowsBeforeFrame, &rowsInFrame);
|
||||
|
||||
for (int i = 0; i < rowsInFrame; i++) {
|
||||
if (!this->readRow()) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
SkCodec::SkScanlineOrder SkGifCodec::onGetScanlineOrder() const {
|
||||
if (fGif->Image.Interlace) {
|
||||
return kOutOfOrder_SkScanlineOrder;
|
||||
|
@ -150,6 +150,22 @@ private:
|
||||
|
||||
int onGetScanlines(void* dst, int count, size_t rowBytes) override;
|
||||
|
||||
bool onSkipScanlines(int count) override;
|
||||
|
||||
/*
|
||||
* For a scanline decode of "count" lines, this function indicates how
|
||||
* many of the "count" lines should be skipped until we reach the top of
|
||||
* the image frame and how many of the "count" lines are actually inside
|
||||
* the image frame.
|
||||
*
|
||||
* @param count The number of scanlines requested.
|
||||
* @param rowsBeforeFrame Output variable. The number of lines before
|
||||
* we reach the top of the image frame.
|
||||
* @param rowsInFrame Output variable. The number of lines to decode
|
||||
* inside the image frame.
|
||||
*/
|
||||
void handleScanlineFrame(int count, int* rowsBeforeFrame, int* rowsInFrame);
|
||||
|
||||
SkScanlineOrder onGetScanlineOrder() const override;
|
||||
|
||||
/*
|
||||
|
Loading…
Reference in New Issue
Block a user