diff options
author | Leon Scroggins III <scroggo@google.com> | 2017-04-17 12:46:33 -0400 |
---|---|---|
committer | Skia Commit-Bot <skia-commit-bot@chromium.org> | 2017-04-17 17:38:35 +0000 |
commit | 249b8e3a2b6450be2e2315f8f9496eec03cfd1c1 (patch) | |
tree | 4c857c72d3716f13658e52dde2afe93b5d07cb70 | |
parent | cd11c809f206af0da3ce1779dee3c91193baa7b0 (diff) |
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>
-rw-r--r-- | dm/DMSrcSink.cpp | 9 | ||||
-rw-r--r-- | gm/animatedGif.cpp | 11 | ||||
-rw-r--r-- | include/codec/SkCodec.h | 16 | ||||
-rw-r--r-- | src/codec/SkCodec.cpp | 32 | ||||
-rw-r--r-- | src/codec/SkGifCodec.cpp | 38 | ||||
-rw-r--r-- | src/codec/SkGifCodec.h | 12 | ||||
-rw-r--r-- | tests/CodecAnimTest.cpp | 22 | ||||
-rw-r--r-- | tests/CodecTest.cpp | 2 | ||||
-rw-r--r-- | third_party/gif/SkGifImageReader.cpp | 49 | ||||
-rw-r--r-- | third_party/gif/SkGifImageReader.h | 45 |
10 files changed, 121 insertions, 115 deletions
diff --git a/dm/DMSrcSink.cpp b/dm/DMSrcSink.cpp index b223c97f56..ebcda38584 100644 --- a/dm/DMSrcSink.cpp +++ b/dm/DMSrcSink.cpp @@ -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; } diff --git a/gm/animatedGif.cpp b/gm/animatedGif.cpp index 03bf66c526..c7871e0d12 100644 --- a/gm/animatedGif.cpp +++ b/gm/animatedGif.cpp @@ -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); } diff --git a/include/codec/SkCodec.h b/include/codec/SkCodec.h index aadcb059fe..7f88fc6117 100644 --- a/include/codec/SkCodec.h +++ b/include/codec/SkCodec.h @@ -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; } diff --git a/src/codec/SkCodec.cpp b/src/codec/SkCodec.cpp index 6a6fdc78c9..9e693b1dfa 100644 --- a/src/codec/SkCodec.cpp +++ b/src/codec/SkCodec.cpp @@ -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; } diff --git a/src/codec/SkGifCodec.cpp b/src/codec/SkGifCodec.cpp index 2e0ec3057d..2584ee57c7 100644 --- a/src/codec/SkGifCodec.cpp +++ b/src/codec/SkGifCodec.cpp @@ -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); } diff --git a/src/codec/SkGifCodec.h b/src/codec/SkGifCodec.h index 11714eb39e..9cb663289a 100644 --- a/src/codec/SkGifCodec.h +++ b/src/codec/SkGifCodec.h @@ -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); diff --git a/tests/CodecAnimTest.cpp b/tests/CodecAnimTest.cpp index 3d7080e35d..79e03bdef8 100644 --- a/tests/CodecAnimTest.cpp +++ b/tests/CodecAnimTest.cpp @@ -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; diff --git a/tests/CodecTest.cpp b/tests/CodecTest.cpp index ceafa15cb1..52240542c6 100644 --- a/tests/CodecTest.cpp +++ b/tests/CodecTest.cpp @@ -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); diff --git a/third_party/gif/SkGifImageReader.cpp b/third_party/gif/SkGifImageReader.cpp index 86768e301c..8c5cfa1ea8 100644 --- a/third_party/gif/SkGifImageReader.cpp +++ b/third_party/gif/SkGifImageReader.cpp @@ -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); diff --git a/third_party/gif/SkGifImageReader.h b/third_party/gif/SkGifImageReader.h index 9d69e48823..4667f7963f 100644 --- a/third_party/gif/SkGifImageReader.h +++ b/third_party/gif/SkGifImageReader.h @@ -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()); |