Switch SkCodec to int for counts and indices
This matches other Skia APIs. size_t was adopted from blink/ GIFImageReader. Change-Id: Ic83e59f0942f597c4fb834e623acd9886ad483fe Reviewed-on: https://skia-review.googlesource.com/13274 Reviewed-by: Mike Reed <reed@google.com> Reviewed-by: Matt Sarett <msarett@google.com> Reviewed-by: Chris Blume <cblume@google.com> Commit-Queue: Leon Scroggins <scroggo@google.com>
This commit is contained in:
parent
cd11c809f2
commit
249b8e3a2b
@ -465,11 +465,11 @@ Error CodecSrc::draw(SkCanvas* canvas) const {
|
||||
|
||||
// Used to cache a frame that future frames will depend on.
|
||||
SkAutoMalloc priorFramePixels;
|
||||
size_t cachedFrame = SkCodec::kNone;
|
||||
for (size_t i = 0; i < frameInfos.size(); i++) {
|
||||
int cachedFrame = SkCodec::kNone;
|
||||
for (int i = 0; static_cast<size_t>(i) < frameInfos.size(); i++) {
|
||||
options.fFrameIndex = i;
|
||||
// Check for a prior frame
|
||||
const size_t reqFrame = frameInfos[i].fRequiredFrame;
|
||||
const int reqFrame = frameInfos[i].fRequiredFrame;
|
||||
if (reqFrame != SkCodec::kNone && reqFrame == cachedFrame
|
||||
&& priorFramePixels.get()) {
|
||||
// Copy into pixels
|
||||
@ -514,7 +514,8 @@ Error CodecSrc::draw(SkCanvas* canvas) const {
|
||||
|
||||
// If a future frame depends on this one, store it in priorFrame.
|
||||
// (Note that if i+1 does *not* depend on i, then no future frame can.)
|
||||
if (i+1 < frameInfos.size() && frameInfos[i+1].fRequiredFrame == i) {
|
||||
if (static_cast<size_t>(i+1) < frameInfos.size()
|
||||
&& frameInfos[i+1].fRequiredFrame == i) {
|
||||
memcpy(priorFramePixels.reset(safeSize), pixels.get(), safeSize);
|
||||
cachedFrame = i;
|
||||
}
|
||||
|
@ -34,9 +34,9 @@ namespace {
|
||||
class AnimatedGifGM : public skiagm::GM {
|
||||
private:
|
||||
std::unique_ptr<SkCodec> fCodec;
|
||||
size_t fFrame;
|
||||
int fFrame;
|
||||
double fNextUpdate;
|
||||
size_t fTotalFrames;
|
||||
int fTotalFrames;
|
||||
std::vector<SkCodec::FrameInfo> fFrameInfos;
|
||||
std::vector<SkBitmap> fFrames;
|
||||
|
||||
@ -53,9 +53,10 @@ private:
|
||||
SkCodec::Options opts;
|
||||
opts.fFrameIndex = frameIndex;
|
||||
opts.fHasPriorFrame = false;
|
||||
const size_t requiredFrame = fFrameInfos[frameIndex].fRequiredFrame;
|
||||
const int requiredFrame = fFrameInfos[frameIndex].fRequiredFrame;
|
||||
if (requiredFrame != SkCodec::kNone) {
|
||||
SkASSERT(requiredFrame < fFrames.size());
|
||||
SkASSERT(requiredFrame >= 0
|
||||
&& static_cast<size_t>(requiredFrame) < fFrames.size());
|
||||
SkBitmap& requiredBitmap = fFrames[requiredFrame];
|
||||
// For simplicity, do not try to cache old frames
|
||||
if (requiredBitmap.getPixels() && requiredBitmap.copyTo(&bm)) {
|
||||
@ -101,7 +102,7 @@ private:
|
||||
canvas->clear(SK_ColorWHITE);
|
||||
if (this->initCodec()) {
|
||||
SkAutoCanvasRestore acr(canvas, true);
|
||||
for (size_t frameIndex = 0; frameIndex < fTotalFrames; frameIndex++) {
|
||||
for (int frameIndex = 0; frameIndex < fTotalFrames; frameIndex++) {
|
||||
this->drawFrame(canvas, frameIndex);
|
||||
canvas->translate(SkIntToScalar(fCodec->getInfo().width()), 0);
|
||||
}
|
||||
|
@ -277,7 +277,7 @@ public:
|
||||
*
|
||||
* Only meaningful for multi-frame images.
|
||||
*/
|
||||
size_t fFrameIndex;
|
||||
int fFrameIndex;
|
||||
|
||||
/**
|
||||
* If true, the dst already contains the prior frame.
|
||||
@ -598,13 +598,13 @@ public:
|
||||
*
|
||||
* May require reading through the stream.
|
||||
*/
|
||||
size_t getFrameCount() {
|
||||
int getFrameCount() {
|
||||
return this->onGetFrameCount();
|
||||
}
|
||||
|
||||
// The required frame for an independent frame is marked as
|
||||
// kNone.
|
||||
static constexpr size_t kNone = static_cast<size_t>(-1);
|
||||
static constexpr int kNone = -1;
|
||||
|
||||
/**
|
||||
* Information about individual frames in a multi-framed image.
|
||||
@ -614,12 +614,12 @@ public:
|
||||
* The frame that this frame needs to be blended with, or
|
||||
* kNone.
|
||||
*/
|
||||
size_t fRequiredFrame;
|
||||
int fRequiredFrame;
|
||||
|
||||
/**
|
||||
* Number of milliseconds to show this frame.
|
||||
*/
|
||||
size_t fDuration;
|
||||
int fDuration;
|
||||
|
||||
/**
|
||||
* Whether the end marker for this frame is contained in the stream.
|
||||
@ -643,7 +643,7 @@ public:
|
||||
* so it should be called after getFrameCount() to parse any frames that
|
||||
* have not already been parsed.
|
||||
*/
|
||||
bool getFrameInfo(size_t index, FrameInfo* info) const {
|
||||
bool getFrameInfo(int index, FrameInfo* info) const {
|
||||
return this->onGetFrameInfo(index, info);
|
||||
}
|
||||
|
||||
@ -818,11 +818,11 @@ protected:
|
||||
SkTransferFunctionBehavior premulBehavior);
|
||||
SkColorSpaceXform* colorXform() const { return fColorXform.get(); }
|
||||
|
||||
virtual size_t onGetFrameCount() {
|
||||
virtual int onGetFrameCount() {
|
||||
return 1;
|
||||
}
|
||||
|
||||
virtual bool onGetFrameInfo(size_t, FrameInfo*) const {
|
||||
virtual bool onGetFrameInfo(int, FrameInfo*) const {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -491,22 +491,20 @@ bool SkCodec::initializeColorXform(const SkImageInfo& dstInfo,
|
||||
}
|
||||
|
||||
std::vector<SkCodec::FrameInfo> SkCodec::getFrameInfo() {
|
||||
const size_t frameCount = this->getFrameCount();
|
||||
switch (frameCount) {
|
||||
case 0:
|
||||
return std::vector<FrameInfo>{};
|
||||
case 1:
|
||||
if (!this->onGetFrameInfo(0, nullptr)) {
|
||||
// Not animated.
|
||||
return std::vector<FrameInfo>{};
|
||||
}
|
||||
// fall through
|
||||
default: {
|
||||
std::vector<FrameInfo> result(frameCount);
|
||||
for (size_t i = 0; i < frameCount; ++i) {
|
||||
SkAssertResult(this->onGetFrameInfo(i, &result[i]));
|
||||
}
|
||||
return result;
|
||||
}
|
||||
const int frameCount = this->getFrameCount();
|
||||
SkASSERT(frameCount >= 0);
|
||||
if (frameCount <= 0) {
|
||||
return std::vector<FrameInfo>{};
|
||||
}
|
||||
|
||||
if (frameCount == 1 && !this->onGetFrameInfo(0, nullptr)) {
|
||||
// Not animated.
|
||||
return std::vector<FrameInfo>{};
|
||||
}
|
||||
|
||||
std::vector<FrameInfo> result(frameCount);
|
||||
for (int i = 0; i < frameCount; ++i) {
|
||||
SkAssertResult(this->onGetFrameInfo(i, &result[i]));
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
@ -132,12 +132,12 @@ SkGifCodec::SkGifCodec(const SkEncodedInfo& encodedInfo, const SkImageInfo& imag
|
||||
reader->setClient(this);
|
||||
}
|
||||
|
||||
size_t SkGifCodec::onGetFrameCount() {
|
||||
int SkGifCodec::onGetFrameCount() {
|
||||
fReader->parse(SkGifImageReader::SkGIFFrameCountQuery);
|
||||
return fReader->imagesCount();
|
||||
}
|
||||
|
||||
bool SkGifCodec::onGetFrameInfo(size_t i, SkCodec::FrameInfo* frameInfo) const {
|
||||
bool SkGifCodec::onGetFrameInfo(int i, SkCodec::FrameInfo* frameInfo) const {
|
||||
if (i >= fReader->imagesCount()) {
|
||||
return false;
|
||||
}
|
||||
@ -164,7 +164,7 @@ int SkGifCodec::onGetRepetitionCount() {
|
||||
|
||||
static const SkColorType kXformSrcColorType = kRGBA_8888_SkColorType;
|
||||
|
||||
void SkGifCodec::initializeColorTable(const SkImageInfo& dstInfo, size_t frameIndex) {
|
||||
void SkGifCodec::initializeColorTable(const SkImageInfo& dstInfo, int frameIndex) {
|
||||
SkColorType colorTableColorType = dstInfo.colorType();
|
||||
if (this->colorXform()) {
|
||||
colorTableColorType = kXformSrcColorType;
|
||||
@ -215,7 +215,7 @@ SkCodec::Result SkGifCodec::prepareToDecode(const SkImageInfo& dstInfo, SkPMColo
|
||||
return gif_error("Subsets not supported.\n", kUnimplemented);
|
||||
}
|
||||
|
||||
const size_t frameIndex = opts.fFrameIndex;
|
||||
const int frameIndex = opts.fFrameIndex;
|
||||
if (frameIndex > 0) {
|
||||
switch (dstInfo.colorType()) {
|
||||
case kIndex_8_SkColorType:
|
||||
@ -276,7 +276,7 @@ SkCodec::Result SkGifCodec::prepareToDecode(const SkImageInfo& dstInfo, SkPMColo
|
||||
return kSuccess;
|
||||
}
|
||||
|
||||
void SkGifCodec::initializeSwizzler(const SkImageInfo& dstInfo, size_t frameIndex) {
|
||||
void SkGifCodec::initializeSwizzler(const SkImageInfo& dstInfo, int frameIndex) {
|
||||
const SkGIFFrameContext* frame = fReader->frameContext(frameIndex);
|
||||
// This is only called by prepareToDecode, which ensures frameIndex is in range.
|
||||
SkASSERT(frame);
|
||||
@ -365,7 +365,7 @@ SkCodec::Result SkGifCodec::onStartIncrementalDecode(const SkImageInfo& dstInfo,
|
||||
SkCodec::Result SkGifCodec::onIncrementalDecode(int* rowsDecoded) {
|
||||
// It is possible the client has appended more data. Parse, if needed.
|
||||
const auto& options = this->options();
|
||||
const size_t frameIndex = options.fFrameIndex;
|
||||
const int frameIndex = options.fFrameIndex;
|
||||
fReader->parse((SkGifImageReader::SkGIFParseQuery) frameIndex);
|
||||
|
||||
const bool firstCallToIncrementalDecode = fFirstCallToIncrementalDecode;
|
||||
@ -375,7 +375,7 @@ SkCodec::Result SkGifCodec::onIncrementalDecode(int* rowsDecoded) {
|
||||
|
||||
SkCodec::Result SkGifCodec::decodeFrame(bool firstAttempt, const Options& opts, int* rowsDecoded) {
|
||||
const SkImageInfo& dstInfo = this->dstInfo();
|
||||
const size_t frameIndex = opts.fFrameIndex;
|
||||
const int frameIndex = opts.fFrameIndex;
|
||||
SkASSERT(frameIndex < fReader->imagesCount());
|
||||
const SkGIFFrameContext* frameContext = fReader->frameContext(frameIndex);
|
||||
if (firstAttempt) {
|
||||
@ -500,8 +500,8 @@ uint64_t SkGifCodec::onGetFillValue(const SkImageInfo& dstInfo) const {
|
||||
// compatibity on Android, so we are using the color table for the first frame.
|
||||
SkASSERT(this->options().fFrameIndex == 0);
|
||||
// Use the transparent index for the first frame.
|
||||
const size_t transPixel = fReader->frameContext(0)->transparentPixel();
|
||||
if (transPixel < (size_t) fCurrColorTable->count()) {
|
||||
const int transPixel = fReader->frameContext(0)->transparentPixel();
|
||||
if (transPixel >= 0 && transPixel < fCurrColorTable->count()) {
|
||||
return transPixel;
|
||||
}
|
||||
// Fall through to return SK_ColorTRANSPARENT (i.e. 0). This choice is arbitrary,
|
||||
@ -532,8 +532,8 @@ void SkGifCodec::applyXformRow(const SkImageInfo& dstInfo, void* dst, const uint
|
||||
}
|
||||
}
|
||||
|
||||
bool SkGifCodec::haveDecodedRow(size_t frameIndex, const unsigned char* rowBegin,
|
||||
size_t rowNumber, unsigned repeatCount, bool writeTransparentPixels)
|
||||
bool SkGifCodec::haveDecodedRow(int frameIndex, const unsigned char* rowBegin,
|
||||
int rowNumber, int repeatCount, bool writeTransparentPixels)
|
||||
{
|
||||
const SkGIFFrameContext* frameContext = fReader->frameContext(frameIndex);
|
||||
// The pixel data and coordinates supplied to us are relative to the frame's
|
||||
@ -542,13 +542,11 @@ bool SkGifCodec::haveDecodedRow(size_t frameIndex, const unsigned char* rowBegin
|
||||
// that width == (size().width() - frameContext->xOffset), so
|
||||
// we must ensure we don't run off the end of either the source data or the
|
||||
// row's X-coordinates.
|
||||
const size_t width = frameContext->width();
|
||||
const int width = frameContext->width();
|
||||
const int xBegin = frameContext->xOffset();
|
||||
const int yBegin = frameContext->yOffset() + rowNumber;
|
||||
const int xEnd = std::min(static_cast<int>(frameContext->xOffset() + width),
|
||||
this->getInfo().width());
|
||||
const int yEnd = std::min(static_cast<int>(frameContext->yOffset() + rowNumber + repeatCount),
|
||||
this->getInfo().height());
|
||||
const int xEnd = std::min(xBegin + width, this->getInfo().width());
|
||||
const int yEnd = std::min(yBegin + rowNumber + repeatCount, this->getInfo().height());
|
||||
// FIXME: No need to make the checks on width/xBegin/xEnd for every row. We could instead do
|
||||
// this once in prepareToDecode.
|
||||
if (!width || (xBegin < 0) || (yBegin < 0) || (xEnd <= xBegin) || (yEnd <= yBegin))
|
||||
@ -563,7 +561,7 @@ bool SkGifCodec::haveDecodedRow(size_t frameIndex, const unsigned char* rowBegin
|
||||
// Check to see whether this row or one that falls in the repeatCount is needed in the
|
||||
// output.
|
||||
bool foundNecessaryRow = false;
|
||||
for (unsigned i = 0; i < repeatCount; i++) {
|
||||
for (int i = 0; i < repeatCount; i++) {
|
||||
const int potentialRow = yBegin + i;
|
||||
if (fSwizzler->rowNeeded(potentialRow)) {
|
||||
dstRow = potentialRow / sampleY;
|
||||
@ -578,7 +576,7 @@ bool SkGifCodec::haveDecodedRow(size_t frameIndex, const unsigned char* rowBegin
|
||||
repeatCount = (repeatCount - 1) / sampleY + 1;
|
||||
|
||||
// Make sure the repeatCount does not take us beyond the end of the dst
|
||||
if (dstRow + (int) repeatCount > scaledHeight) {
|
||||
if (dstRow + repeatCount > scaledHeight) {
|
||||
repeatCount = scaledHeight - dstRow;
|
||||
SkASSERT(repeatCount >= 1);
|
||||
}
|
||||
@ -592,7 +590,7 @@ bool SkGifCodec::haveDecodedRow(size_t frameIndex, const unsigned char* rowBegin
|
||||
} else {
|
||||
// Make sure the repeatCount does not take us beyond the end of the dst
|
||||
SkASSERT(this->dstInfo().height() >= yBegin);
|
||||
repeatCount = SkTMin(repeatCount, (unsigned) (this->dstInfo().height() - yBegin));
|
||||
repeatCount = SkTMin(repeatCount, this->dstInfo().height() - yBegin);
|
||||
}
|
||||
|
||||
if (!fFilledBackground) {
|
||||
@ -665,7 +663,7 @@ bool SkGifCodec::haveDecodedRow(size_t frameIndex, const unsigned char* rowBegin
|
||||
const size_t bytesToCopy = fSwizzler->swizzleWidth() * bytesPerPixel;
|
||||
void* copiedLine = SkTAddOffset<void>(dstLine, fSwizzler->swizzleOffsetBytes());
|
||||
void* dst = copiedLine;
|
||||
for (unsigned i = 1; i < repeatCount; i++) {
|
||||
for (int i = 1; i < repeatCount; i++) {
|
||||
dst = SkTAddOffset<void>(dst, fDstRowBytes);
|
||||
memcpy(dst, copiedLine, bytesToCopy);
|
||||
}
|
||||
|
@ -33,8 +33,8 @@ public:
|
||||
static SkCodec* NewFromStream(SkStream*);
|
||||
|
||||
// Callback for SkGifImageReader when a row is available.
|
||||
bool haveDecodedRow(size_t frameIndex, const unsigned char* rowBegin,
|
||||
size_t rowNumber, unsigned repeatCount, bool writeTransparentPixels);
|
||||
bool haveDecodedRow(int frameIndex, const unsigned char* rowBegin,
|
||||
int rowNumber, int repeatCount, bool writeTransparentPixels);
|
||||
protected:
|
||||
/*
|
||||
* Performs the full gif decode
|
||||
@ -50,8 +50,8 @@ protected:
|
||||
|
||||
uint64_t onGetFillValue(const SkImageInfo&) const override;
|
||||
|
||||
size_t onGetFrameCount() override;
|
||||
bool onGetFrameInfo(size_t, FrameInfo*) const override;
|
||||
int onGetFrameCount() override;
|
||||
bool onGetFrameInfo(int, FrameInfo*) const override;
|
||||
int onGetRepetitionCount() override;
|
||||
|
||||
Result onStartIncrementalDecode(const SkImageInfo& /*dstInfo*/, void*, size_t,
|
||||
@ -67,7 +67,7 @@ private:
|
||||
* @param dstInfo Contains the requested dst color type.
|
||||
* @param frameIndex Frame whose color table to use.
|
||||
*/
|
||||
void initializeColorTable(const SkImageInfo& dstInfo, size_t frameIndex);
|
||||
void initializeColorTable(const SkImageInfo& dstInfo, int frameIndex);
|
||||
|
||||
/*
|
||||
* Does necessary setup, including setting up the color table and swizzler,
|
||||
@ -85,7 +85,7 @@ private:
|
||||
* @param frameIndex Which frame we are decoding. This determines the frameRect
|
||||
* to use.
|
||||
*/
|
||||
void initializeSwizzler(const SkImageInfo& dstInfo, size_t frameIndex);
|
||||
void initializeSwizzler(const SkImageInfo& dstInfo, int frameIndex);
|
||||
|
||||
SkSampler* getSampler(bool createIfNecessary) override {
|
||||
SkASSERT(fSwizzler);
|
||||
|
@ -43,15 +43,15 @@ DEF_TEST(Codec_frames, r) {
|
||||
#define kUnpremul kUnpremul_SkAlphaType
|
||||
static const struct {
|
||||
const char* fName;
|
||||
size_t fFrameCount;
|
||||
int fFrameCount;
|
||||
// One less than fFramecount, since the first frame is always
|
||||
// independent.
|
||||
std::vector<size_t> fRequiredFrames;
|
||||
std::vector<int> fRequiredFrames;
|
||||
// Same, since the first frame should match getInfo.
|
||||
std::vector<SkAlphaType> fAlphaTypes;
|
||||
// The size of this one should match fFrameCount for animated, empty
|
||||
// otherwise.
|
||||
std::vector<size_t> fDurations;
|
||||
std::vector<int> fDurations;
|
||||
int fRepetitionCount;
|
||||
} gRecs[] = {
|
||||
{ "alphabetAnim.gif", 13,
|
||||
@ -126,14 +126,14 @@ DEF_TEST(Codec_frames, r) {
|
||||
rec.fName, rec.fRepetitionCount, repetitionCount);
|
||||
}
|
||||
|
||||
const size_t expected = rec.fFrameCount;
|
||||
if (rec.fRequiredFrames.size() + 1 != expected) {
|
||||
const int expected = rec.fFrameCount;
|
||||
if (rec.fRequiredFrames.size() + 1 != static_cast<size_t>(expected)) {
|
||||
ERRORF(r, "'%s' has wrong number entries in fRequiredFrames; expected: %i\tactual: %i",
|
||||
rec.fName, expected, rec.fRequiredFrames.size() + 1);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (rec.fDurations.size() != expected) {
|
||||
if (rec.fDurations.size() != static_cast<size_t>(expected)) {
|
||||
ERRORF(r, "'%s' has wrong number entries in fDurations; expected: %i\tactual: %i",
|
||||
rec.fName, expected, rec.fDurations.size());
|
||||
continue;
|
||||
@ -148,7 +148,7 @@ DEF_TEST(Codec_frames, r) {
|
||||
// Re-create the codec to reset state and test parsing.
|
||||
codec.reset(SkCodec::NewFromData(data));
|
||||
|
||||
size_t frameCount;
|
||||
int frameCount;
|
||||
std::vector<SkCodec::FrameInfo> frameInfos;
|
||||
switch (mode) {
|
||||
case TestMode::kVector:
|
||||
@ -172,7 +172,7 @@ DEF_TEST(Codec_frames, r) {
|
||||
continue;
|
||||
}
|
||||
|
||||
for (size_t i = 0; i < frameCount; i++) {
|
||||
for (int i = 0; i < frameCount; i++) {
|
||||
SkCodec::FrameInfo frameInfo;
|
||||
switch (mode) {
|
||||
case TestMode::kVector:
|
||||
@ -233,11 +233,11 @@ DEF_TEST(Codec_frames, r) {
|
||||
std::vector<SkBitmap> cachedFrames(frameCount);
|
||||
const auto& info = codec->getInfo().makeColorType(kN32_SkColorType);
|
||||
|
||||
auto decode = [&](SkBitmap* bm, bool cached, size_t index) {
|
||||
auto decode = [&](SkBitmap* bm, bool cached, int index) {
|
||||
bm->allocPixels(info);
|
||||
if (cached) {
|
||||
// First copy the pixels from the cached frame
|
||||
const size_t requiredFrame = frameInfos[index].fRequiredFrame;
|
||||
const int requiredFrame = frameInfos[index].fRequiredFrame;
|
||||
if (requiredFrame != SkCodec::kNone) {
|
||||
const bool success = cachedFrames[requiredFrame].copyTo(bm);
|
||||
REPORTER_ASSERT(r, success);
|
||||
@ -251,7 +251,7 @@ DEF_TEST(Codec_frames, r) {
|
||||
REPORTER_ASSERT(r, result == SkCodec::kSuccess);
|
||||
};
|
||||
|
||||
for (size_t i = 0; i < frameCount; i++) {
|
||||
for (int i = 0; i < frameCount; i++) {
|
||||
SkBitmap& cachedFrame = cachedFrames[i];
|
||||
decode(&cachedFrame, true, i);
|
||||
SkBitmap uncachedFrame;
|
||||
|
@ -1508,7 +1508,7 @@ DEF_TEST(Codec_InvalidAnimated, r) {
|
||||
|
||||
auto frameInfos = codec->getFrameInfo();
|
||||
SkCodec::Options opts;
|
||||
for (size_t i = 0; i < frameInfos.size(); i++) {
|
||||
for (int i = 0; static_cast<size_t>(i) < frameInfos.size(); i++) {
|
||||
opts.fFrameIndex = i;
|
||||
opts.fHasPriorFrame = frameInfos[i].fRequiredFrame == i - 1;
|
||||
auto result = codec->startIncrementalDecode(info, bm.getPixels(), bm.rowBytes(), &opts);
|
||||
|
49
third_party/gif/SkGifImageReader.cpp
vendored
49
third_party/gif/SkGifImageReader.cpp
vendored
@ -202,7 +202,7 @@ bool SkGIFLZWContext::outputRow(const unsigned char* rowBegin)
|
||||
// Otherwise, decoding failed; returns false in this case, which will always cause the SkGifImageReader to set the "decode failed" flag.
|
||||
bool SkGIFLZWContext::doLZW(const unsigned char* block, size_t bytesInBlock)
|
||||
{
|
||||
const size_t width = m_frameContext->width();
|
||||
const int width = m_frameContext->width();
|
||||
|
||||
if (rowIter == rowBuffer.end())
|
||||
return true;
|
||||
@ -306,14 +306,14 @@ bool SkGIFLZWContext::doLZW(const unsigned char* block, size_t bytesInBlock)
|
||||
}
|
||||
|
||||
sk_sp<SkColorTable> SkGIFColorMap::buildTable(SkStreamBuffer* streamBuffer, SkColorType colorType,
|
||||
size_t transparentPixel) const
|
||||
int transparentPixel) const
|
||||
{
|
||||
if (!m_isDefined)
|
||||
return nullptr;
|
||||
|
||||
const PackColorProc proc = choose_pack_color_proc(false, colorType);
|
||||
if (m_table && proc == m_packColorProc && m_transPixel == transparentPixel) {
|
||||
SkASSERT(transparentPixel > (unsigned) m_table->count()
|
||||
SkASSERT(transparentPixel == kNotFound || transparentPixel > m_table->count()
|
||||
|| m_table->operator[](transparentPixel) == SK_ColorTRANSPARENT);
|
||||
// This SkColorTable has already been built with the same transparent color and
|
||||
// packing proc. Reuse it.
|
||||
@ -331,7 +331,7 @@ sk_sp<SkColorTable> SkGIFColorMap::buildTable(SkStreamBuffer* streamBuffer, SkCo
|
||||
SkASSERT(m_colors <= SK_MAX_COLORS);
|
||||
const uint8_t* srcColormap = rawData->bytes();
|
||||
SkPMColor colorStorage[SK_MAX_COLORS];
|
||||
for (size_t i = 0; i < m_colors; i++) {
|
||||
for (int i = 0; i < m_colors; i++) {
|
||||
if (i == transparentPixel) {
|
||||
colorStorage[i] = SK_ColorTRANSPARENT;
|
||||
} else {
|
||||
@ -339,21 +339,21 @@ sk_sp<SkColorTable> SkGIFColorMap::buildTable(SkStreamBuffer* streamBuffer, SkCo
|
||||
}
|
||||
srcColormap += SK_BYTES_PER_COLORMAP_ENTRY;
|
||||
}
|
||||
for (size_t i = m_colors; i < SK_MAX_COLORS; i++) {
|
||||
for (int i = m_colors; i < SK_MAX_COLORS; i++) {
|
||||
colorStorage[i] = SK_ColorTRANSPARENT;
|
||||
}
|
||||
m_table = sk_sp<SkColorTable>(new SkColorTable(colorStorage, SK_MAX_COLORS));
|
||||
return m_table;
|
||||
}
|
||||
|
||||
sk_sp<SkColorTable> SkGifImageReader::getColorTable(SkColorType colorType, size_t index) {
|
||||
if (index >= m_frames.size()) {
|
||||
sk_sp<SkColorTable> SkGifImageReader::getColorTable(SkColorType colorType, int index) {
|
||||
if (index < 0 || static_cast<size_t>(index) >= m_frames.size()) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
const SkGIFFrameContext* frameContext = m_frames[index].get();
|
||||
const SkGIFColorMap& localColorMap = frameContext->localColorMap();
|
||||
const size_t transPix = frameContext->transparentPixel();
|
||||
const int transPix = frameContext->transparentPixel();
|
||||
if (localColorMap.isDefined()) {
|
||||
return localColorMap.buildTable(&m_streamBuffer, colorType, transPix);
|
||||
}
|
||||
@ -385,7 +385,8 @@ bool SkGIFFrameContext::decode(SkStreamBuffer* streamBuffer, SkGifCodec* client,
|
||||
}
|
||||
|
||||
// Some bad GIFs have extra blocks beyond the last row, which we don't want to decode.
|
||||
while (m_currentLzwBlock < m_lzwBlocks.size() && m_lzwContext->hasRemainingRows()) {
|
||||
while (static_cast<size_t>(m_currentLzwBlock) < m_lzwBlocks.size()
|
||||
&& m_lzwContext->hasRemainingRows()) {
|
||||
const auto& block = m_lzwBlocks[m_currentLzwBlock];
|
||||
const size_t len = block.blockSize;
|
||||
|
||||
@ -411,7 +412,7 @@ bool SkGIFFrameContext::decode(SkStreamBuffer* streamBuffer, SkGifCodec* client,
|
||||
// Decode a frame.
|
||||
// This method uses SkGIFFrameContext:decode() to decode the frame; decoding error is reported to client as a critical failure.
|
||||
// Return true if decoding has progressed. Return false if an error has occurred.
|
||||
bool SkGifImageReader::decode(size_t frameIndex, bool* frameComplete)
|
||||
bool SkGifImageReader::decode(int frameIndex, bool* frameComplete)
|
||||
{
|
||||
SkGIFFrameContext* currentFrame = m_frames[frameIndex].get();
|
||||
|
||||
@ -493,7 +494,7 @@ bool SkGifImageReader::parse(SkGifImageReader::SkGIFParseQuery query)
|
||||
m_screenWidth = GETINT16(currentComponent);
|
||||
m_screenHeight = GETINT16(currentComponent + 2);
|
||||
|
||||
const size_t globalColorMapColors = 2 << (currentComponent[4] & 0x07);
|
||||
const int globalColorMapColors = 2 << (currentComponent[4] & 0x07);
|
||||
|
||||
if ((currentComponent[4] & 0x80) && globalColorMapColors > 0) { /* global map */
|
||||
m_globalColorMap.setNumColors(globalColorMapColors);
|
||||
@ -753,7 +754,7 @@ bool SkGifImageReader::parse(SkGifImageReader::SkGIFParseQuery query)
|
||||
|
||||
const bool isLocalColormapDefined = SkToBool(currentComponent[8] & 0x80);
|
||||
// The three low-order bits of currentComponent[8] specify the bits per pixel.
|
||||
const size_t numColors = 2 << (currentComponent[8] & 0x7);
|
||||
const int numColors = 2 << (currentComponent[8] & 0x7);
|
||||
if (currentFrameIsFirstFrame()) {
|
||||
if (hasTransparentPixel(0, isLocalColormapDefined, numColors)) {
|
||||
m_firstFrameHasAlpha = true;
|
||||
@ -851,9 +852,10 @@ bool SkGifImageReader::parse(SkGifImageReader::SkGIFParseQuery query)
|
||||
return true;
|
||||
}
|
||||
|
||||
bool SkGifImageReader::hasTransparentPixel(size_t i, bool isLocalColormapDefined,
|
||||
size_t localColors) {
|
||||
if (m_frames.size() <= i) {
|
||||
bool SkGifImageReader::hasTransparentPixel(int i, bool isLocalColormapDefined,
|
||||
int localColors) {
|
||||
SkASSERT(i >= 0);
|
||||
if (m_frames.size() <= static_cast<size_t>(i)) {
|
||||
// This should only happen when parsing the first frame.
|
||||
SkASSERT(0 == i);
|
||||
|
||||
@ -863,12 +865,17 @@ bool SkGifImageReader::hasTransparentPixel(size_t i, bool isLocalColormapDefined
|
||||
return !isLocalColormapDefined && m_globalColorMap.numColors() == 0;
|
||||
}
|
||||
|
||||
const size_t transparentPixel = m_frames[i]->transparentPixel();
|
||||
const int transparentPixel = m_frames[i]->transparentPixel();
|
||||
if (transparentPixel < 0) {
|
||||
SkASSERT(SkGIFColorMap::kNotFound == transparentPixel);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (isLocalColormapDefined) {
|
||||
return transparentPixel < localColors;
|
||||
}
|
||||
|
||||
const size_t globalColors = m_globalColorMap.numColors();
|
||||
const int globalColors = m_globalColorMap.numColors();
|
||||
if (!globalColors) {
|
||||
// No color table for this frame, so the frame is empty.
|
||||
// This is technically different from having a transparent
|
||||
@ -886,7 +893,7 @@ void SkGifImageReader::addFrameIfNecessary()
|
||||
{
|
||||
if (m_frames.empty() || m_frames.back()->isComplete()) {
|
||||
const size_t i = m_frames.size();
|
||||
std::unique_ptr<SkGIFFrameContext> frame(new SkGIFFrameContext(i));
|
||||
std::unique_ptr<SkGIFFrameContext> frame(new SkGIFFrameContext(static_cast<int>(i)));
|
||||
m_frames.push_back(std::move(frame));
|
||||
}
|
||||
}
|
||||
@ -909,7 +916,7 @@ static bool restore_bg(const SkGIFFrameContext& frame) {
|
||||
}
|
||||
|
||||
void SkGifImageReader::setAlphaAndRequiredFrame(SkGIFFrameContext* frame) {
|
||||
const size_t i = frame->frameId();
|
||||
const int i = frame->frameId();
|
||||
if (0 == i) {
|
||||
frame->setHasAlpha(m_firstFrameHasAlpha);
|
||||
frame->setRequiredFrame(SkCodec::kNone);
|
||||
@ -933,7 +940,7 @@ void SkGifImageReader::setAlphaAndRequiredFrame(SkGIFFrameContext* frame) {
|
||||
|
||||
const SkGIFFrameContext* prevFrame = m_frames[i - 1].get();
|
||||
while (prevFrame->getDisposalMethod() == SkCodecAnimation::RestorePrevious_DisposalMethod) {
|
||||
const size_t prevId = prevFrame->frameId();
|
||||
const int prevId = prevFrame->frameId();
|
||||
if (0 == prevId) {
|
||||
frame->setHasAlpha(true);
|
||||
frame->setRequiredFrame(SkCodec::kNone);
|
||||
@ -965,7 +972,7 @@ void SkGifImageReader::setAlphaAndRequiredFrame(SkGIFFrameContext* frame) {
|
||||
}
|
||||
|
||||
while (frameRect.contains(prevFrameRect)) {
|
||||
const size_t prevRequiredFrame = prevFrame->getRequiredFrame();
|
||||
const int prevRequiredFrame = prevFrame->getRequiredFrame();
|
||||
if (prevRequiredFrame == SkCodec::kNone) {
|
||||
frame->setRequiredFrame(SkCodec::kNone);
|
||||
frame->setHasAlpha(true);
|
||||
|
45
third_party/gif/SkGifImageReader.h
vendored
45
third_party/gif/SkGifImageReader.h
vendored
@ -148,7 +148,7 @@ struct SkGIFLZWBlock {
|
||||
|
||||
class SkGIFColorMap final {
|
||||
public:
|
||||
static constexpr size_t kNotFound = static_cast<size_t>(-1);
|
||||
static constexpr int kNotFound = -1;
|
||||
|
||||
SkGIFColorMap()
|
||||
: m_isDefined(false)
|
||||
@ -159,7 +159,7 @@ public:
|
||||
{
|
||||
}
|
||||
|
||||
void setNumColors(size_t colors) {
|
||||
void setNumColors(int colors) {
|
||||
SkASSERT(!m_colors);
|
||||
SkASSERT(!m_position);
|
||||
|
||||
@ -173,20 +173,20 @@ public:
|
||||
m_isDefined = true;
|
||||
}
|
||||
|
||||
size_t numColors() const { return m_colors; }
|
||||
int numColors() const { return m_colors; }
|
||||
|
||||
bool isDefined() const { return m_isDefined; }
|
||||
|
||||
// Build RGBA table using the data stream.
|
||||
sk_sp<SkColorTable> buildTable(SkStreamBuffer*, SkColorType dstColorType,
|
||||
size_t transparentPixel) const;
|
||||
int transparentPixel) const;
|
||||
|
||||
private:
|
||||
bool m_isDefined;
|
||||
size_t m_position;
|
||||
size_t m_colors;
|
||||
int m_colors;
|
||||
// Cached values. If these match on a new request, we can reuse m_table.
|
||||
mutable size_t m_transPixel;
|
||||
mutable int m_transPixel;
|
||||
mutable PackColorProc m_packColorProc;
|
||||
mutable sk_sp<SkColorTable> m_table;
|
||||
};
|
||||
@ -239,18 +239,18 @@ public:
|
||||
unsigned yOffset() const { return m_yOffset; }
|
||||
unsigned width() const { return m_width; }
|
||||
unsigned height() const { return m_height; }
|
||||
size_t transparentPixel() const { return m_transparentPixel; }
|
||||
void setTransparentPixel(size_t pixel) { m_transparentPixel = pixel; }
|
||||
int transparentPixel() const { return m_transparentPixel; }
|
||||
void setTransparentPixel(int pixel) { m_transparentPixel = pixel; }
|
||||
bool hasAlpha() const { return m_hasAlpha; }
|
||||
void setHasAlpha(bool alpha) { m_hasAlpha = alpha; }
|
||||
SkCodecAnimation::DisposalMethod getDisposalMethod() const { return m_disposalMethod; }
|
||||
void setDisposalMethod(SkCodecAnimation::DisposalMethod disposalMethod) { m_disposalMethod = disposalMethod; }
|
||||
|
||||
size_t getRequiredFrame() const {
|
||||
int getRequiredFrame() const {
|
||||
SkASSERT(this->reachedStartOfData());
|
||||
return m_requiredFrame;
|
||||
}
|
||||
void setRequiredFrame(size_t req) { m_requiredFrame = req; }
|
||||
void setRequiredFrame(int req) { m_requiredFrame = req; }
|
||||
|
||||
unsigned delayTime() const { return m_delayTime; }
|
||||
void setDelayTime(unsigned delay) { m_delayTime = delay; }
|
||||
@ -277,21 +277,21 @@ public:
|
||||
bool reachedStartOfData() const { return m_requiredFrame != kUninitialized; }
|
||||
|
||||
private:
|
||||
static constexpr size_t kUninitialized = static_cast<size_t>(-2);
|
||||
static constexpr int kUninitialized = -2;
|
||||
|
||||
int m_frameId;
|
||||
unsigned m_xOffset;
|
||||
unsigned m_yOffset; // With respect to "screen" origin.
|
||||
unsigned m_width;
|
||||
unsigned m_height;
|
||||
size_t m_transparentPixel; // Index of transparent pixel. Value is kNotFound if there is no transparent pixel.
|
||||
int m_transparentPixel; // Index of transparent pixel. Value is kNotFound if there is no transparent pixel.
|
||||
// Cached value, taking into account:
|
||||
// - m_transparentPixel
|
||||
// - frameRect
|
||||
// - previous required frame
|
||||
bool m_hasAlpha;
|
||||
SkCodecAnimation::DisposalMethod m_disposalMethod; // Restore to background, leave in place, etc.
|
||||
size_t m_requiredFrame;
|
||||
int m_requiredFrame;
|
||||
int m_dataSize;
|
||||
|
||||
bool m_progressiveDisplay; // If true, do Haeberli interlace hack.
|
||||
@ -305,7 +305,7 @@ private:
|
||||
|
||||
SkGIFColorMap m_localColorMap;
|
||||
|
||||
size_t m_currentLzwBlock;
|
||||
int m_currentLzwBlock;
|
||||
bool m_isComplete;
|
||||
bool m_isHeaderDefined;
|
||||
bool m_isDataSizeDefined;
|
||||
@ -359,15 +359,15 @@ public:
|
||||
// Decode the frame indicated by frameIndex.
|
||||
// frameComplete will be set to true if the frame is completely decoded.
|
||||
// The method returns false if there is an error.
|
||||
bool decode(size_t frameIndex, bool* frameComplete);
|
||||
bool decode(int frameIndex, bool* frameComplete);
|
||||
|
||||
size_t imagesCount() const
|
||||
int imagesCount() const
|
||||
{
|
||||
// Report the first frame immediately, so the parser can stop when it
|
||||
// sees the size on a SizeQuery.
|
||||
const size_t frames = m_frames.size();
|
||||
if (frames <= 1) {
|
||||
return frames;
|
||||
return static_cast<int>(frames);
|
||||
}
|
||||
|
||||
// This avoids counting an empty frame when the file is truncated (or
|
||||
@ -375,7 +375,7 @@ public:
|
||||
// possibly SkGIFImageHeader) but before reading the color table. This
|
||||
// ensures that we do not count a frame before we know its required
|
||||
// frame.
|
||||
return m_frames.back()->reachedStartOfData() ? frames : frames - 1;
|
||||
return static_cast<int>(m_frames.back()->reachedStartOfData() ? frames : frames - 1);
|
||||
}
|
||||
int loopCount() const {
|
||||
if (cLoopCountNotSeen == m_loopCount) {
|
||||
@ -389,9 +389,10 @@ public:
|
||||
return m_globalColorMap;
|
||||
}
|
||||
|
||||
const SkGIFFrameContext* frameContext(size_t index) const
|
||||
const SkGIFFrameContext* frameContext(int index) const
|
||||
{
|
||||
return index < m_frames.size() ? m_frames[index].get() : 0;
|
||||
return index >= 0 && index < static_cast<int>(m_frames.size())
|
||||
? m_frames[index].get() : 0;
|
||||
}
|
||||
|
||||
void clearDecodeState() {
|
||||
@ -401,7 +402,7 @@ public:
|
||||
}
|
||||
|
||||
// Return the color table for frame index (which may be the global color table).
|
||||
sk_sp<SkColorTable> getColorTable(SkColorType dstColorType, size_t index);
|
||||
sk_sp<SkColorTable> getColorTable(SkColorType dstColorType, int index);
|
||||
|
||||
bool firstFrameHasAlpha() const { return m_firstFrameHasAlpha; }
|
||||
|
||||
@ -418,7 +419,7 @@ private:
|
||||
void setAlphaAndRequiredFrame(SkGIFFrameContext*);
|
||||
// This method is sometimes called before creating a SkGIFFrameContext, so it cannot rely
|
||||
// on SkGIFFrameContext::localColorMap().
|
||||
bool hasTransparentPixel(size_t frameIndex, bool hasLocalColorMap, size_t localMapColors);
|
||||
bool hasTransparentPixel(int frameIndex, bool hasLocalColorMap, int localMapColors);
|
||||
bool currentFrameIsFirstFrame() const
|
||||
{
|
||||
return m_frames.empty() || (m_frames.size() == 1u && !m_frames[0]->isComplete());
|
||||
|
Loading…
Reference in New Issue
Block a user