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:
Leon Scroggins III 2017-04-17 12:46:33 -04:00 committed by Skia Commit-Bot
parent cd11c809f2
commit 249b8e3a2b
10 changed files with 121 additions and 115 deletions

View File

@ -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;
}

View File

@ -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);
}

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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);
}

View File

@ -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);

View File

@ -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;

View File

@ -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);

View File

@ -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);

View File

@ -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());