| OLD | NEW | 
|---|
| 1 /* | 1 /* | 
| 2  * Copyright 2016 Google Inc. | 2  * Copyright 2016 Google Inc. | 
| 3  * | 3  * | 
| 4  * Use of this source code is governed by a BSD-style license that can be | 4  * Use of this source code is governed by a BSD-style license that can be | 
| 5  * found in the LICENSE file. | 5  * found in the LICENSE file. | 
| 6  */ | 6  */ | 
| 7 | 7 | 
| 8 #include "SkBitmap.h" | 8 #include "SkBitmap.h" | 
| 9 #include "SkCodec.h" | 9 #include "SkCodec.h" | 
| 10 #include "SkStream.h" | 10 #include "SkStream.h" | 
| 11 | 11 | 
| 12 #include "Resources.h" | 12 #include "Resources.h" | 
| 13 #include "Test.h" | 13 #include "Test.h" | 
| 14 | 14 | 
| 15 #include <initializer_list> | 15 #include <initializer_list> | 
| 16 #include <vector> | 16 #include <vector> | 
| 17 | 17 | 
| 18 DEF_TEST(Codec_frames, r) { | 18 DEF_TEST(Codec_frames, r) { | 
| 19     static const struct { | 19     static const struct { | 
| 20         const char*         fName; | 20         const char*         fName; | 
| 21         size_t              fFrameCount; | 21         size_t              fFrameCount; | 
| 22         // One less than fFramecount, since the first frame is always | 22         // One less than fFramecount, since the first frame is always | 
| 23         // independent. | 23         // independent. | 
| 24         std::vector<size_t> fRequiredFrames; | 24         std::vector<size_t> fRequiredFrames; | 
| 25         // The size of this one should match fFrameCount for animated, empty | 25         // The size of this one should match fFrameCount for animated, empty | 
| 26         // otherwise. | 26         // otherwise. | 
| 27         std::vector<size_t> fDurations; | 27         std::vector<size_t> fDurations; | 
|  | 28         int                 fRepetitionCount; | 
| 28     } gRecs[] = { | 29     } gRecs[] = { | 
| 29         { "box.gif", 1, {}, {} }, | 30         { "box.gif", 1, {}, {}, 0 }, | 
| 30         { "color_wheel.gif", 1, {}, {} }, | 31         { "color_wheel.gif", 1, {}, {}, 0 }, | 
| 31         { "test640x479.gif", 4, { 0, 1, 2 }, { 200, 200, 200, 200 } }, | 32         { "test640x479.gif", 4, { 0, 1, 2 }, { 200, 200, 200, 200 }, | 
|  | 33                 SkCodec::kRepetitionCountInfinite }, | 
| 32 | 34 | 
| 33         { "arrow.png",  1, {}, {} }, | 35         { "arrow.png",  1, {}, {}, 0 }, | 
| 34         { "google_chrome.ico", 1, {}, {} }, | 36         { "google_chrome.ico", 1, {}, {}, 0 }, | 
| 35         { "brickwork-texture.jpg", 1, {}, {} }, | 37         { "brickwork-texture.jpg", 1, {}, {}, 0 }, | 
| 36 #if defined(SK_CODEC_DECODES_RAW) && (!defined(_WIN32)) | 38 #if defined(SK_CODEC_DECODES_RAW) && (!defined(_WIN32)) | 
| 37         { "dng_with_preview.dng", 1, {}, {} }, | 39         { "dng_with_preview.dng", 1, {}, {}, 0 }, | 
| 38 #endif | 40 #endif | 
| 39         { "mandrill.wbmp", 1, {}, {} }, | 41         { "mandrill.wbmp", 1, {}, {}, 0 }, | 
| 40         { "randPixels.bmp", 1, {}, {} }, | 42         { "randPixels.bmp", 1, {}, {}, 0 }, | 
| 41         { "yellow_rose.webp", 1, {}, {} }, | 43         { "yellow_rose.webp", 1, {}, {}, 0 }, | 
| 42     }; | 44     }; | 
| 43 | 45 | 
| 44     for (auto rec : gRecs) { | 46     for (const auto& rec : gRecs) { | 
| 45         std::unique_ptr<SkStream> stream(GetResourceAsStream(rec.fName)); | 47         std::unique_ptr<SkStream> stream(GetResourceAsStream(rec.fName)); | 
| 46         if (!stream) { | 48         if (!stream) { | 
| 47             // Useful error statement, but sometimes people run tests without | 49             // Useful error statement, but sometimes people run tests without | 
| 48             // resources, and they do not want to see these messages. | 50             // resources, and they do not want to see these messages. | 
| 49             //ERRORF(r, "Missing resources? Could not find '%s'", rec.fName); | 51             //ERRORF(r, "Missing resources? Could not find '%s'", rec.fName); | 
| 50             continue; | 52             continue; | 
| 51         } | 53         } | 
| 52 | 54 | 
| 53         std::unique_ptr<SkCodec> codec(SkCodec::NewFromStream(stream.release()))
     ; | 55         std::unique_ptr<SkCodec> codec(SkCodec::NewFromStream(stream.release()))
     ; | 
| 54         if (!codec) { | 56         if (!codec) { | 
| 55             ERRORF(r, "Failed to create an SkCodec from '%s'", rec.fName); | 57             ERRORF(r, "Failed to create an SkCodec from '%s'", rec.fName); | 
| 56             continue; | 58             continue; | 
| 57         } | 59         } | 
| 58 | 60 | 
|  | 61         std::vector<SkCodec::FrameInfo> frameInfos; | 
|  | 62         int repetitionCount; | 
|  | 63         const bool isAnimated = codec->getFrameInfo(&frameInfos, &repetitionCoun
     t); | 
|  | 64         if (!isAnimated) { | 
|  | 65             REPORTER_ASSERT(r, rec.fFrameCount == 1); | 
|  | 66             continue; | 
|  | 67         } | 
|  | 68 | 
|  | 69         if (rec.fFrameCount == 1) { | 
|  | 70             // SkGifCodec still returns true even if there is only one frame. | 
|  | 71             continue; | 
|  | 72         } | 
|  | 73 | 
|  | 74         // From here on, we are only concerned with animated images. | 
| 59         const size_t expected = rec.fFrameCount; | 75         const size_t expected = rec.fFrameCount; | 
| 60         const auto frameInfos = codec->getFrameInfo(); | 76         const size_t frameCount = frameInfos.size(); | 
| 61         // getFrameInfo returns empty set for non-animated. |  | 
| 62         const size_t frameCount = frameInfos.size() == 0 ? 1 : frameInfos.size()
     ; |  | 
| 63         if (frameCount != expected) { | 77         if (frameCount != expected) { | 
| 64             ERRORF(r, "'%s' expected frame count: %i\tactual: %i", rec.fName, ex
     pected, frameCount); | 78             ERRORF(r, "'%s' expected frame count: %i\tactual: %i", rec.fName, ex
     pected, frameCount); | 
| 65             continue; | 79             continue; | 
| 66         } | 80         } | 
| 67 | 81 | 
| 68         if (rec.fRequiredFrames.size() + 1 != expected) { | 82         if (rec.fRequiredFrames.size() + 1 != expected) { | 
| 69             ERRORF(r, "'%s' has wrong number entries in fRequiredFrames; expecte
     d: %i\tactual: %i", | 83             ERRORF(r, "'%s' has wrong number entries in fRequiredFrames; expecte
     d: %i\tactual: %i", | 
| 70                    rec.fName, expected, rec.fRequiredFrames.size()); | 84                    rec.fName, expected, rec.fRequiredFrames.size()); | 
| 71             continue; | 85             continue; | 
| 72         } | 86         } | 
| 73 | 87 | 
| 74         if (1 == frameCount) { | 88         REPORTER_ASSERT(r, repetitionCount == rec.fRepetitionCount); | 
| 75             continue; |  | 
| 76         } |  | 
| 77 |  | 
| 78         // From here on, we are only concerned with animated images. |  | 
| 79         REPORTER_ASSERT(r, frameInfos[0].fRequiredFrame == SkCodec::kNone); | 89         REPORTER_ASSERT(r, frameInfos[0].fRequiredFrame == SkCodec::kNone); | 
| 80         for (size_t i = 1; i < frameCount; i++) { | 90         for (size_t i = 1; i < frameCount; i++) { | 
| 81             REPORTER_ASSERT(r, rec.fRequiredFrames[i-1] == frameInfos[i].fRequir
     edFrame); | 91             REPORTER_ASSERT(r, rec.fRequiredFrames[i-1] == frameInfos[i].fRequir
     edFrame); | 
| 82         } | 92         } | 
| 83 | 93 | 
| 84         // Compare decoding in two ways: | 94         // Compare decoding in two ways: | 
| 85         // 1. Provide the frame that a frame depends on, so the codec just has t
     o blend. | 95         // 1. Provide the frame that a frame depends on, so the codec just has t
     o blend. | 
| 86         //    (in the array cachedFrames) | 96         //    (in the array cachedFrames) | 
| 87         // 2. Do not provide the frame that a frame depends on, so the codec has
      to decode all the | 97         // 2. Do not provide the frame that a frame depends on, so the codec has
      to decode all the | 
| 88         //    way back to a key-frame. (in a local variable uncachedFrame) | 98         //    way back to a key-frame. (in a local variable uncachedFrame) | 
| (...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 133             ERRORF(r, "'%s' has wrong number entries in fDurations; expected: %i
     \tactual: %i", | 143             ERRORF(r, "'%s' has wrong number entries in fDurations; expected: %i
     \tactual: %i", | 
| 134                    rec.fName, expected, rec.fDurations.size()); | 144                    rec.fName, expected, rec.fDurations.size()); | 
| 135             continue; | 145             continue; | 
| 136         } | 146         } | 
| 137 | 147 | 
| 138         for (size_t i = 0; i < frameCount; i++) { | 148         for (size_t i = 0; i < frameCount; i++) { | 
| 139             REPORTER_ASSERT(r, rec.fDurations[i] == frameInfos[i].fDuration); | 149             REPORTER_ASSERT(r, rec.fDurations[i] == frameInfos[i].fDuration); | 
| 140         } | 150         } | 
| 141     } | 151     } | 
| 142 } | 152 } | 
| OLD | NEW | 
|---|