diff options
author | Leon Scroggins III <scroggo@google.com> | 2017-04-11 10:32:02 -0400 |
---|---|---|
committer | Skia Commit-Bot <skia-commit-bot@chromium.org> | 2017-04-11 15:05:05 +0000 |
commit | a4db9be6a28c3a2c24c31e721ac804aec47ad379 (patch) | |
tree | c57209e4f3ce29e137ad228d4ad9c65f0f6e6657 /tests | |
parent | 0f3fdfacf32261f943dcac5cdfd14475011f40db (diff) |
Correct GIF frame dependencies and track alpha
Add SkCodec::FrameInfo::fAlphaType. The SkImageInfo for the SkCodec
specifies the SkAlphaType for the first frame, but the opacity can vary
from frame to frame.
When determining the required frame, also compute whether a frame has
alpha. Update how we determine the required frame, which had bugs.
(Update a test that had an incorrect required frame as a result.)
Add new test images covering cases that have been fixed:
- randPixelsAnim2.gif
It has the following frames:
A (keep)
B (keep) (subset)
C (disposePrevious) (covers B)
D (any) (does *not* cover B)
B and C depend on A, but D depends on B, since after disposing C, B
should be visible again.
- alphabetAnim.gif
Includes frames which fill the image size, with different disposal
methods and transparencies.
Change-Id: Ie086167711c4cac4931ed8c4ddaeb9c9b0b91fdb
Reviewed-on: https://skia-review.googlesource.com/9810
Commit-Queue: Leon Scroggins <scroggo@google.com>
Reviewed-by: Mike Reed <reed@google.com>
Reviewed-by: Matt Sarett <msarett@google.com>
Diffstat (limited to 'tests')
-rw-r--r-- | tests/CodecAnimTest.cpp | 79 |
1 files changed, 61 insertions, 18 deletions
diff --git a/tests/CodecAnimTest.cpp b/tests/CodecAnimTest.cpp index 9f9a160bbb..dea4adbfd2 100644 --- a/tests/CodecAnimTest.cpp +++ b/tests/CodecAnimTest.cpp @@ -32,42 +32,68 @@ static void write_bm(const char* name, const SkBitmap& bm) { } DEF_TEST(Codec_frames, r) { + #define kOpaque kOpaque_SkAlphaType + #define kUnpremul kUnpremul_SkAlphaType static const struct { - const char* fName; - size_t fFrameCount; + const char* fName; + size_t fFrameCount; // One less than fFramecount, since the first frame is always // independent. - std::vector<size_t> fRequiredFrames; + std::vector<size_t> 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; - int fRepetitionCount; + std::vector<size_t> fDurations; + int fRepetitionCount; } gRecs[] = { + { "alphabetAnim.gif", 13, + { SkCodec::kNone, 0, 0, 0, 0, 5, 6, SkCodec::kNone, + SkCodec::kNone, SkCodec::kNone, 10, 11 }, + { kUnpremul, kUnpremul, kUnpremul, kUnpremul, kUnpremul, kUnpremul, + kUnpremul, kUnpremul, kUnpremul, kOpaque, kOpaque, kUnpremul }, + { 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100 }, + 0 }, + { "randPixelsAnim2.gif", 4, + // required frames + { 0, 0, 1 }, + // alphas + { kOpaque, kOpaque, kOpaque }, + // durations + { 0, 1000, 170, 40 }, + // repetition count + 0 }, { "randPixelsAnim.gif", 13, // required frames - { SkCodec::kNone, 1, 2, 3, 4, 4, 6, 7, 7, 7, 7, 7 }, + { SkCodec::kNone, 1, 2, 3, 4, 3, 6, 7, 7, 7, 9, 9 }, + { kUnpremul, kUnpremul, kUnpremul, kUnpremul, kUnpremul, kUnpremul, + kUnpremul, kUnpremul, kUnpremul, kUnpremul, kUnpremul, kUnpremul }, // durations { 0, 1000, 170, 40, 220, 7770, 90, 90, 90, 90, 90, 90, 90 }, // repetition count 0 }, - { "box.gif", 1, {}, {}, 0 }, - { "color_wheel.gif", 1, {}, {}, 0 }, - { "test640x479.gif", 4, { 0, 1, 2 }, { 200, 200, 200, 200 }, + { "box.gif", 1, {}, {}, {}, 0 }, + { "color_wheel.gif", 1, {}, {}, {}, 0 }, + { "test640x479.gif", 4, { 0, 1, 2 }, + { kOpaque, kOpaque, kOpaque }, + { 200, 200, 200, 200 }, SkCodec::kRepetitionCountInfinite }, - { "colorTables.gif", 2, { 0 }, { 1000, 1000 }, 5 }, + { "colorTables.gif", 2, { 0 }, { kOpaque }, { 1000, 1000 }, 5 }, - { "arrow.png", 1, {}, {}, 0 }, - { "google_chrome.ico", 1, {}, {}, 0 }, - { "brickwork-texture.jpg", 1, {}, {}, 0 }, + { "arrow.png", 1, {}, {}, {}, 0 }, + { "google_chrome.ico", 1, {}, {}, {}, 0 }, + { "brickwork-texture.jpg", 1, {}, {}, {}, 0 }, #if defined(SK_CODEC_DECODES_RAW) && (!defined(_WIN32)) - { "dng_with_preview.dng", 1, {}, {}, 0 }, + { "dng_with_preview.dng", 1, {}, {}, {}, 0 }, #endif - { "mandrill.wbmp", 1, {}, {}, 0 }, - { "randPixels.bmp", 1, {}, {}, 0 }, - { "yellow_rose.webp", 1, {}, {}, 0 }, + { "mandrill.wbmp", 1, {}, {}, {}, 0 }, + { "randPixels.bmp", 1, {}, {}, {}, 0 }, + { "yellow_rose.webp", 1, {}, {}, {}, 0 }, }; + #undef kOpaque + #undef kUnpremul - for (auto rec : gRecs) { + for (const auto& rec : gRecs) { std::unique_ptr<SkStream> stream(GetResourceAsStream(rec.fName)); if (!stream) { // Useful error statement, but sometimes people run tests without @@ -107,13 +133,30 @@ DEF_TEST(Codec_frames, r) { continue; } + auto to_string = [](SkAlphaType type) { + switch (type) { + case kUnpremul_SkAlphaType: + return "unpremul"; + case kOpaque_SkAlphaType: + return "opaque"; + default: + return "other"; + } + }; // From here on, we are only concerned with animated images. REPORTER_ASSERT(r, frameInfos[0].fRequiredFrame == SkCodec::kNone); + REPORTER_ASSERT(r, frameInfos[0].fAlphaType == codec->getInfo().alphaType()); for (size_t i = 1; i < frameCount; i++) { if (rec.fRequiredFrames[i-1] != frameInfos[i].fRequiredFrame) { ERRORF(r, "%s's frame %i has wrong dependency! expected: %i\tactual: %i", rec.fName, i, rec.fRequiredFrames[i-1], frameInfos[i].fRequiredFrame); } + auto expectedAlpha = rec.fAlphaTypes[i-1]; + auto alpha = frameInfos[i].fAlphaType; + if (expectedAlpha != alpha) { + ERRORF(r, "%s's frame %i has wrong alpha type! expected: %s\tactual: %s", + rec.fName, i, to_string(expectedAlpha), to_string(alpha)); + } } // Compare decoding in two ways: |