10#include "include/core/SkColorType.h"
11#include "third_party/skia/include/codec/SkPngDecoder.h"
17#if defined(OS_FUCHSIA)
18#pragma GCC diagnostic ignored "-Wunreachable-code"
23bool IsPngWithPLTE(
const uint8_t* bytes,
size_t size) {
24 constexpr std::string_view kPngMagic =
"\x89PNG\x0d\x0a\x1a\x0a";
25 constexpr std::string_view kPngPlte =
"PLTE";
26 constexpr uint32_t kLengthBytes = 4;
27 constexpr uint32_t kTypeBytes = 4;
28 constexpr uint32_t kCrcBytes = 4;
30 if (
size < kPngMagic.size()) {
34 if (memcmp(bytes, kPngMagic.data(), kPngMagic.size()) != 0) {
38 const uint8_t*
end = bytes +
size;
39 const uint8_t* loc = bytes + kPngMagic.size();
40 while (loc + kLengthBytes + kTypeBytes <=
end) {
41 uint32_t chunk_length =
44 if (memcmp(loc + kLengthBytes, kPngPlte.data(), kPngPlte.size()) == 0) {
48 loc += kLengthBytes + kTypeBytes + chunk_length + kCrcBytes;
59 return std::numeric_limits<float>::infinity();
61 return -std::numeric_limits<float>::infinity();
63 bool negative = half >> 15;
64 uint16_t exponent = (half >> 10) & 0x1f;
65 uint16_t fraction = half & 0x3ff;
66 float fExponent = exponent - 15.0f;
67 float fFraction =
static_cast<float>(fraction) / 1024.f;
68 float pow_value = powf(2.0f, fExponent);
69 return (negative ? -1.f : 1.f) * pow_value * (1.0f + fFraction);
73 const float max = 1.25098f;
74 const float min = -0.752941f;
75 const float intercept = min;
76 const float slope = (max - min) / 1024.0f;
77 return (
x * slope) + intercept;
80TEST(ImageDecoderNoGLTest, ImpellerWideGamutDisplayP3) {
81#if defined(OS_FUCHSIA)
82 GTEST_SKIP() <<
"Fuchsia can't load the test fixtures.";
84 SkCodecs::Register(SkPngDecoder::Decoder());
86 auto image = SkImages::DeferredFromEncodedData(
data);
87 std::shared_ptr<impeller::Capabilities> capabilities =
91 ASSERT_TRUE(
image !=
nullptr);
92 ASSERT_EQ(SkISize::Make(100, 100),
image->dimensions());
95 std::shared_ptr<ImageGenerator> generator =
97 ASSERT_TRUE(generator);
99 auto descriptor = fml::MakeRefCounted<ImageDescriptor>(std::move(
data),
100 std::move(generator));
103 IsPngWithPLTE(descriptor->data()->bytes(), descriptor->data()->size()));
105#if IMPELLER_SUPPORTS_RENDERING
106 std::shared_ptr<impeller::Allocator>
allocator =
107 std::make_shared<impeller::TestImpellerAllocator>();
108 absl::StatusOr<ImageDecoderImpeller::DecompressResult> wide_result =
110 descriptor.get(), {.target_width = 100, .target_height = 100},
113 ASSERT_TRUE(wide_result.ok());
114 ASSERT_EQ(wide_result->image_info.format,
117 const uint16_t* half_ptr =
reinterpret_cast<const uint16_t*
>(
118 wide_result->device_buffer->OnGetContents());
119 bool found_deep_red =
false;
120 for (
int i = 0;
i < wide_result->image_info.size.width *
121 wide_result->image_info.size.height;
127 if (fabsf(red - 1.0931f) < 0.01f && fabsf(green - -0.2268f) < 0.01f &&
128 fabsf(blue - -0.1501f) < 0.01f) {
129 found_deep_red =
true;
134 ASSERT_TRUE(found_deep_red);
135 absl::StatusOr<ImageDecoderImpeller::DecompressResult> narrow_result =
137 descriptor.get(), {.target_width = 100, .target_height = 100},
141 ASSERT_TRUE(narrow_result.ok());
142 ASSERT_EQ(narrow_result->image_info.format,
147TEST(ImageDecoderNoGLTest, ImpellerWideGamutIndexedPng) {
148#if defined(OS_FUCHSIA)
149 GTEST_SKIP() <<
"Fuchsia can't load the test fixtures.";
151 SkCodecs::Register(SkPngDecoder::Decoder());
153 auto image = SkImages::DeferredFromEncodedData(
data);
154 std::shared_ptr<impeller::Capabilities> capabilities =
158 ASSERT_TRUE(
image !=
nullptr);
159 ASSERT_EQ(SkISize::Make(100, 100),
image->dimensions());
162 std::shared_ptr<ImageGenerator> generator =
164 ASSERT_TRUE(generator);
166 auto descriptor = fml::MakeRefCounted<ImageDescriptor>(std::move(
data),
167 std::move(generator));
170 IsPngWithPLTE(descriptor->data()->bytes(), descriptor->data()->size()));
172#if IMPELLER_SUPPORTS_RENDERING
173 std::shared_ptr<impeller::Allocator>
allocator =
174 std::make_shared<impeller::TestImpellerAllocator>();
175 absl::StatusOr<ImageDecoderImpeller::DecompressResult> wide_result =
177 descriptor.get(), {.target_width = 100, .target_height = 100},
180 ASSERT_TRUE(wide_result.ok());
181 ASSERT_EQ(wide_result->image_info.format,
184 const uint32_t* pixel_ptr =
reinterpret_cast<const uint32_t*
>(
185 wide_result->device_buffer->OnGetContents());
186 bool found_deep_red =
false;
187 for (
int i = 0;
i < wide_result->image_info.size.width *
188 wide_result->image_info.size.height;
190 uint32_t pixel = *pixel_ptr++;
194 if (fabsf(red - 1.0931f) < 0.01f && fabsf(green - -0.2268f) < 0.01f &&
195 fabsf(blue - -0.1501f) < 0.01f) {
196 found_deep_red =
true;
201 ASSERT_TRUE(found_deep_red);
202 absl::StatusOr<ImageDecoderImpeller::DecompressResult> narrow_result =
204 descriptor.get(), {.target_width = 100, .target_height = 100},
208 ASSERT_TRUE(narrow_result.ok());
209 ASSERT_EQ(narrow_result->image_info.format,
214TEST(ImageDecoderNoGLTest, ImpellerRGBA32FDecode) {
215#if defined(OS_FUCHSIA)
216 GTEST_SKIP() <<
"Fuchsia can't load the test fixtures.";
219#if IMPELLER_SUPPORTS_RENDERING
221 float pixel_data[] = {1.0f, 0.5f, 0.25f, 1.0f};
222 sk_sp<SkData> sk_data = SkData::MakeWithCopy(pixel_data,
sizeof(pixel_data));
223 auto immutable_buffer =
224 fml::MakeRefCounted<ImmutableBuffer>(std::move(sk_data));
231 .alpha_type = kUnpremul_SkAlphaType,
233 auto descriptor = fml::MakeRefCounted<ImageDescriptor>(
234 immutable_buffer->data(), image_info,
sizeof(pixel_data));
237 std::shared_ptr<impeller::Capabilities> capabilities =
241 std::shared_ptr<impeller::Allocator>
allocator =
242 std::make_shared<impeller::TestImpellerAllocator>();
245 absl::StatusOr<ImageDecoderImpeller::DecompressResult> result =
252 ImageDecoder::TargetPixelFormat::kR32G32B32A32Float},
258 ASSERT_TRUE(result.ok());
259 ASSERT_EQ(result->image_info.format,
263 const float* decompressed_pixel_ptr =
264 reinterpret_cast<const float*
>(result->device_buffer->OnGetContents());
265 ASSERT_NE(decompressed_pixel_ptr,
nullptr);
266 EXPECT_EQ(decompressed_pixel_ptr[0], 1.0f);
267 EXPECT_EQ(decompressed_pixel_ptr[1], 0.5f);
268 EXPECT_EQ(decompressed_pixel_ptr[2], 0.25f);
269 EXPECT_EQ(decompressed_pixel_ptr[3], 1.0f);
274TEST(ImageDecoderNoGLTest, ImpellerR32FDecode) {
275#if defined(OS_FUCHSIA)
276 GTEST_SKIP() <<
"Fuchsia can't load the test fixtures.";
279#if !IMPELLER_SUPPORTS_RENDERING
280 GTEST_SKIP() <<
"test only supported on impeller";
283 float pixel_data[] = {1.0f};
284 sk_sp<SkData> sk_data = SkData::MakeWithCopy(pixel_data,
sizeof(pixel_data));
285 auto immutable_buffer =
286 fml::MakeRefCounted<ImmutableBuffer>(std::move(sk_data));
293 .alpha_type = kUnpremul_SkAlphaType,
295 auto descriptor = fml::MakeRefCounted<ImageDescriptor>(
296 immutable_buffer->data(), image_info,
sizeof(pixel_data));
299 std::shared_ptr<impeller::Capabilities> capabilities =
303 std::shared_ptr<impeller::Allocator>
allocator =
304 std::make_shared<impeller::TestImpellerAllocator>();
307 absl::StatusOr<ImageDecoderImpeller::DecompressResult> result =
313 .target_format = ImageDecoder::TargetPixelFormat::kR32Float},
319 ASSERT_TRUE(result.ok());
323 const float* decompressed_pixel_ptr =
324 reinterpret_cast<const float*
>(result->device_buffer->OnGetContents());
325 ASSERT_NE(decompressed_pixel_ptr,
nullptr);
326 EXPECT_EQ(decompressed_pixel_ptr[0], 1.0f);
331TEST(ImageDecoderNoGLTest, ImpellerUnmultipliedAlphaPng) {
332#if defined(OS_FUCHSIA)
333 GTEST_SKIP() <<
"Fuchsia can't load the test fixtures.";
335 SkCodecs::Register(SkPngDecoder::Decoder());
337 auto image = SkImages::DeferredFromEncodedData(
data);
338 std::shared_ptr<impeller::Capabilities> capabilities =
342 ASSERT_TRUE(
image !=
nullptr);
343 ASSERT_EQ(SkISize::Make(11, 11),
image->dimensions());
346 std::shared_ptr<ImageGenerator> generator =
348 ASSERT_TRUE(generator);
350 auto descriptor = fml::MakeRefCounted<ImageDescriptor>(std::move(
data),
351 std::move(generator));
353#if IMPELLER_SUPPORTS_RENDERING
354 std::shared_ptr<impeller::Allocator>
allocator =
355 std::make_shared<impeller::TestImpellerAllocator>();
356 absl::StatusOr<ImageDecoderImpeller::DecompressResult> result =
358 descriptor.get(), {.target_width = 11, .target_height = 11}, {11, 11},
360 ASSERT_TRUE(result.ok());
361 ASSERT_EQ(result->image_info.format,
364 const uint32_t* pixel_ptr =
365 reinterpret_cast<const uint32_t*
>(result->device_buffer->OnGetContents());
367 ASSERT_EQ(*pixel_ptr, (uint32_t)0x1000001);
369 ASSERT_EQ(*(pixel_ptr + 11 * 4 + 4), (uint32_t)0xFF00FF00);
static absl::StatusOr< DecompressResult > DecompressTexture(ImageDescriptor *descriptor, const ImageDecoder::Options &options, impeller::ISize max_texture_size, bool supports_wide_gamut, const std::shared_ptr< const impeller::Capabilities > &capabilities, const std::shared_ptr< impeller::Allocator > &allocator)
Keeps a priority-ordered registry of image generator builders to be used when decoding images....
std::shared_ptr< ImageGenerator > CreateCompatibleGenerator(const sk_sp< SkData > &buffer)
Walks the list of image generator builders in descending priority order until a compatible ImageGener...
CapabilitiesBuilder & SetSupportsTextureToTextureBlits(bool value)
std::unique_ptr< Capabilities > Build()
FlutterVulkanImage * image
std::shared_ptr< ImpellerAllocator > allocator
float DecodeBGR10(uint32_t x)
sk_sp< SkData > OpenFixtureAsSkData(const std::string &fixture_name)
Opens a fixture of the given file name and returns a Skia SkData holding its contents.
TEST(NativeAssetsManagerTest, NoAvailableAssets)
float HalfToFloat(uint16_t half)
it will be possible to load the file into Perfetto s trace viewer use test Running tests that layout and measure text will not yield consistent results across various platforms Enabling this option will make font resolution default to the Ahem test font on all disable asset Prevents usage of any non test fonts unless they were explicitly Loaded via prefetched default font Indicates whether the embedding started a prefetch of the default font manager before creating the engine run In non interactive keep the shell running after the Dart script has completed enable serial On low power devices with low core running concurrent GC tasks on threads can cause them to contend with the UI thread which could potentially lead to jank This option turns off all concurrent GC activities domain network JSON encoded network policy per domain This overrides the DisallowInsecureConnections switch Embedder can specify whether to allow or disallow insecure connections at a domain level old gen heap size
DEF_SWITCHES_START aot vmservice shared library Name of the *so containing AOT compiled Dart assets for launching the service isolate vm snapshot data
constexpr T BigEndianToArch(T n)
Convert a known big endian value to match the endianness of the current architecture....