| /* | |
| * Copyright 2022 Google LLC | |
| * | |
| * Use of this source code is governed by a BSD-style license that can be | |
| * found in the LICENSE file. | |
| */ | |
| #include "include/core/SkTypes.h" | |
| #ifdef SK_CODEC_DECODES_AVIF | |
| #include "include/codec/SkCodec.h" | |
| #include "include/core/SkBitmap.h" | |
| #include "tests/Test.h" | |
| #include "tools/Resources.h" | |
| #include "tools/ToolUtils.h" | |
| struct AvifTestCase { | |
| const char* path; | |
| int imageWidth; | |
| int imageHeight; | |
| int bitmapWidth; | |
| int bitmapHeight; | |
| int expectedFrameCount; | |
| int expectedFrameDuration; | |
| SkColorType color_type; | |
| SkAlphaType alpha_type; | |
| }; | |
| static void run_avif_test(skiatest::Reporter* r, const AvifTestCase& t) { | |
| auto data = GetResourceAsData(t.path); | |
| if (!data) { | |
| ERRORF(r, "failed to find %s", t.path); | |
| return; | |
| } | |
| auto codec = SkCodec::MakeFromData(std::move(data)); | |
| if (!codec) { | |
| ERRORF(r, "Could not create codec from %s", t.path); | |
| return; | |
| } | |
| REPORTER_ASSERT(r, codec->getFrameCount() == t.expectedFrameCount); | |
| auto info = codec->getInfo(); | |
| REPORTER_ASSERT(r, info.width() == t.imageWidth); | |
| REPORTER_ASSERT(r, info.height() == t.imageHeight); | |
| SkImageInfo imageInfo = | |
| SkImageInfo::Make(t.bitmapWidth, t.bitmapHeight, t.color_type, t.alpha_type); | |
| SkBitmap bm; | |
| bm.allocPixels(imageInfo); | |
| for (int i = 0; i < codec->getFrameCount(); i++) { | |
| SkCodec::Options options; | |
| options.fFrameIndex = i; | |
| auto result = codec->getPixels(imageInfo, bm.getPixels(), bm.rowBytes(), &options); | |
| if (result != SkCodec::kSuccess) { | |
| ERRORF(r, | |
| "Failed to decode %s frame %i - error %s", | |
| t.path, | |
| i, | |
| SkCodec::ResultToString(result)); | |
| return; | |
| } | |
| if (codec->getFrameCount() > 1) { | |
| SkCodec::FrameInfo frameInfo; | |
| if (!codec->getFrameInfo(i, &frameInfo)) { | |
| ERRORF(r, "Failed to getFrameInfo for %s frame %i", t.path, i); | |
| return; | |
| } | |
| REPORTER_ASSERT(r, frameInfo.fAlphaType == t.alpha_type); | |
| REPORTER_ASSERT(r, frameInfo.fDuration == t.expectedFrameDuration); | |
| } | |
| } | |
| } | |
| DEF_TEST(AvifDecodeBasic, r) { | |
| AvifTestCase t = {.path = "images/dog.avif", | |
| .imageWidth = 180, | |
| .imageHeight = 180, | |
| .bitmapWidth = 180, | |
| .bitmapHeight = 180, | |
| .expectedFrameCount = 1, | |
| .expectedFrameDuration = 0, | |
| .color_type = kRGBA_8888_SkColorType, | |
| .alpha_type = kOpaque_SkAlphaType}; | |
| run_avif_test(r, t); | |
| } | |
| DEF_TEST(AvifDecodeOddDimensions, r) { | |
| AvifTestCase t = {.path = "images/ducky.avif", | |
| .imageWidth = 489, | |
| .imageHeight = 537, | |
| .bitmapWidth = 489, | |
| .bitmapHeight = 537, | |
| .expectedFrameCount = 1, | |
| .expectedFrameDuration = 0, | |
| .color_type = kRGBA_8888_SkColorType, | |
| .alpha_type = kOpaque_SkAlphaType}; | |
| run_avif_test(r, t); | |
| } | |
| DEF_TEST(AvifDecodeScaleDown, r) { | |
| AvifTestCase t = {.path = "images/dog.avif", | |
| .imageWidth = 180, | |
| .imageHeight = 180, | |
| .bitmapWidth = 20, | |
| .bitmapHeight = 20, | |
| .expectedFrameCount = 1, | |
| .expectedFrameDuration = 0, | |
| .color_type = kRGBA_8888_SkColorType, | |
| .alpha_type = kOpaque_SkAlphaType}; | |
| run_avif_test(r, t); | |
| } | |
| DEF_TEST(AvifDecode10BitToRGBA8888Bitmap, r) { | |
| AvifTestCase t = {.path = "images/example_3_10bit.avif", | |
| .imageWidth = 512, | |
| .imageHeight = 512, | |
| .bitmapWidth = 512, | |
| .bitmapHeight = 512, | |
| .expectedFrameCount = 1, | |
| .expectedFrameDuration = 0, | |
| .color_type = kRGBA_8888_SkColorType, | |
| .alpha_type = kOpaque_SkAlphaType}; | |
| run_avif_test(r, t); | |
| } | |
| DEF_TEST(AvifDecode10BitToRGBAF16Bitmap, r) { | |
| AvifTestCase t = {.path = "images/example_3_10bit.avif", | |
| .imageWidth = 512, | |
| .imageHeight = 512, | |
| .bitmapWidth = 512, | |
| .bitmapHeight = 512, | |
| .expectedFrameCount = 1, | |
| .expectedFrameDuration = 0, | |
| .color_type = kRGBA_F16_SkColorType, | |
| .alpha_type = kOpaque_SkAlphaType}; | |
| run_avif_test(r, t); | |
| } | |
| DEF_TEST(AvifDecode10BitToRGBAF16BitmapDownscale, r) { | |
| AvifTestCase t = {.path = "images/example_3_10bit.avif", | |
| .imageWidth = 512, | |
| .imageHeight = 512, | |
| .bitmapWidth = 100, | |
| .bitmapHeight = 100, | |
| .expectedFrameCount = 1, | |
| .expectedFrameDuration = 0, | |
| .color_type = kRGBA_F16_SkColorType, | |
| .alpha_type = kOpaque_SkAlphaType}; | |
| run_avif_test(r, t); | |
| } | |
| DEF_TEST(AvifDecode12BitToRGBA8888Bitmap, r) { | |
| AvifTestCase t = {.path = "images/example_3_12bit.avif", | |
| .imageWidth = 512, | |
| .imageHeight = 512, | |
| .bitmapWidth = 512, | |
| .bitmapHeight = 512, | |
| .expectedFrameCount = 1, | |
| .expectedFrameDuration = 0, | |
| .color_type = kRGBA_8888_SkColorType, | |
| .alpha_type = kOpaque_SkAlphaType}; | |
| run_avif_test(r, t); | |
| } | |
| DEF_TEST(AvifDecode12BitToRGBAF16Bitmap, r) { | |
| AvifTestCase t = {.path = "images/example_3_12bit.avif", | |
| .imageWidth = 512, | |
| .imageHeight = 512, | |
| .bitmapWidth = 512, | |
| .bitmapHeight = 512, | |
| .expectedFrameCount = 1, | |
| .expectedFrameDuration = 0, | |
| .color_type = kRGBA_F16_SkColorType, | |
| .alpha_type = kOpaque_SkAlphaType}; | |
| run_avif_test(r, t); | |
| } | |
| DEF_TEST(AvifDecode12BitToRGBAF16BitmapDownscale, r) { | |
| AvifTestCase t = {.path = "images/example_3_12bit.avif", | |
| .imageWidth = 512, | |
| .imageHeight = 512, | |
| .bitmapWidth = 100, | |
| .bitmapHeight = 100, | |
| .expectedFrameCount = 1, | |
| .expectedFrameDuration = 0, | |
| .color_type = kRGBA_F16_SkColorType, | |
| .alpha_type = kOpaque_SkAlphaType}; | |
| run_avif_test(r, t); | |
| } | |
| DEF_TEST(AvifDecodeImageWithAlpha, r) { | |
| AvifTestCase t = {.path = "images/baby_tux.avif", | |
| .imageWidth = 240, | |
| .imageHeight = 246, | |
| .bitmapWidth = 240, | |
| .bitmapHeight = 246, | |
| .expectedFrameCount = 1, | |
| .expectedFrameDuration = 0, | |
| .color_type = kRGBA_8888_SkColorType, | |
| .alpha_type = kUnpremul_SkAlphaType}; | |
| run_avif_test(r, t); | |
| } | |
| DEF_TEST(AvifDecodeAnimation, r) { | |
| AvifTestCase t = {.path = "images/alphabetAnim.avif", | |
| .imageWidth = 100, | |
| .imageHeight = 100, | |
| .bitmapWidth = 100, | |
| .bitmapHeight = 100, | |
| .expectedFrameCount = 13, | |
| .expectedFrameDuration = 100, | |
| .color_type = kRGBA_8888_SkColorType, | |
| .alpha_type = kOpaque_SkAlphaType}; | |
| run_avif_test(r, t); | |
| } | |
| DEF_TEST(AvifDecodeAnimationWithAlpha, r) { | |
| AvifTestCase t = {.path = "images/example_1_animated.avif", | |
| .imageWidth = 256, | |
| .imageHeight = 256, | |
| .bitmapWidth = 256, | |
| .bitmapHeight = 256, | |
| .expectedFrameCount = 8, | |
| .expectedFrameDuration = 33, | |
| .color_type = kRGBA_8888_SkColorType, | |
| .alpha_type = kUnpremul_SkAlphaType}; | |
| run_avif_test(r, t); | |
| } | |
| #endif // SK_CODEC_DECODES_AVIF |