Skip to content
This repository was archived by the owner on Feb 25, 2025. It is now read-only.

Commit b3e9642

Browse files
authored
Add Animated PNG demuxer (#31098)
1 parent 5203b6f commit b3e9642

14 files changed

Lines changed: 891 additions & 26 deletions

ci/licenses_golden/licenses_flutter

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1799,6 +1799,8 @@ ORIGIN: ../../../flutter/lib/ui/painting/image_filter.cc + ../../../flutter/LICE
17991799
ORIGIN: ../../../flutter/lib/ui/painting/image_filter.h + ../../../flutter/LICENSE
18001800
ORIGIN: ../../../flutter/lib/ui/painting/image_generator.cc + ../../../flutter/LICENSE
18011801
ORIGIN: ../../../flutter/lib/ui/painting/image_generator.h + ../../../flutter/LICENSE
1802+
ORIGIN: ../../../flutter/lib/ui/painting/image_generator_apng.cc + ../../../flutter/LICENSE
1803+
ORIGIN: ../../../flutter/lib/ui/painting/image_generator_apng.h + ../../../flutter/LICENSE
18021804
ORIGIN: ../../../flutter/lib/ui/painting/image_generator_registry.cc + ../../../flutter/LICENSE
18031805
ORIGIN: ../../../flutter/lib/ui/painting/image_generator_registry.h + ../../../flutter/LICENSE
18041806
ORIGIN: ../../../flutter/lib/ui/painting/image_shader.cc + ../../../flutter/LICENSE
@@ -4286,6 +4288,8 @@ FILE: ../../../flutter/lib/ui/painting/image_filter.cc
42864288
FILE: ../../../flutter/lib/ui/painting/image_filter.h
42874289
FILE: ../../../flutter/lib/ui/painting/image_generator.cc
42884290
FILE: ../../../flutter/lib/ui/painting/image_generator.h
4291+
FILE: ../../../flutter/lib/ui/painting/image_generator_apng.cc
4292+
FILE: ../../../flutter/lib/ui/painting/image_generator_apng.h
42894293
FILE: ../../../flutter/lib/ui/painting/image_generator_registry.cc
42904294
FILE: ../../../flutter/lib/ui/painting/image_generator_registry.h
42914295
FILE: ../../../flutter/lib/ui/painting/image_shader.cc

fml/endianness.h

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -26,9 +26,17 @@
2626

2727
namespace fml {
2828

29+
template <typename T>
30+
struct IsByteSwappable
31+
: public std::
32+
integral_constant<bool, std::is_integral_v<T> || std::is_enum_v<T>> {
33+
};
34+
template <typename T>
35+
constexpr bool IsByteSwappableV = IsByteSwappable<T>::value;
36+
2937
/// @brief Flips the endianness of the given value.
3038
/// The given value must be an integral type of size 1, 2, 4, or 8.
31-
template <typename T, class = std::enable_if_t<std::is_integral_v<T>>>
39+
template <typename T, class = std::enable_if_t<IsByteSwappableV<T>>>
3240
constexpr T ByteSwap(T n) {
3341
if constexpr (sizeof(T) == 1) {
3442
return n;
@@ -47,7 +55,7 @@ constexpr T ByteSwap(T n) {
4755
/// current architecture. This is effectively a cross platform
4856
/// ntohl/ntohs (as network byte order is always Big Endian).
4957
/// The given value must be an integral type of size 1, 2, 4, or 8.
50-
template <typename T, class = std::enable_if_t<std::is_integral_v<T>>>
58+
template <typename T, class = std::enable_if_t<IsByteSwappableV<T>>>
5159
constexpr T BigEndianToArch(T n) {
5260
#if FML_ARCH_CPU_LITTLE_ENDIAN
5361
return ByteSwap<T>(n);
@@ -59,7 +67,7 @@ constexpr T BigEndianToArch(T n) {
5967
/// @brief Convert a known little endian value to match the endianness of the
6068
/// current architecture.
6169
/// The given value must be an integral type of size 1, 2, 4, or 8.
62-
template <typename T, class = std::enable_if_t<std::is_integral_v<T>>>
70+
template <typename T, class = std::enable_if_t<IsByteSwappableV<T>>>
6371
constexpr T LittleEndianToArch(T n) {
6472
#if !FML_ARCH_CPU_LITTLE_ENDIAN
6573
return ByteSwap<T>(n);

lib/ui/BUILD.gn

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,8 @@ source_set("ui") {
5959
"painting/image_filter.h",
6060
"painting/image_generator.cc",
6161
"painting/image_generator.h",
62+
"painting/image_generator_apng.cc",
63+
"painting/image_generator_apng.h",
6264
"painting/image_generator_registry.cc",
6365
"painting/image_generator_registry.h",
6466
"painting/image_shader.cc",
@@ -161,6 +163,7 @@ source_set("ui") {
161163
"//third_party/dart/runtime/bin:dart_io_api",
162164
"//third_party/rapidjson",
163165
"//third_party/skia",
166+
"//third_party/zlib:zlib",
164167
]
165168

166169
if (impeller_supports_rendering) {

lib/ui/painting/image_decoder_unittests.cc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -162,7 +162,7 @@ class UnknownImageGenerator : public ImageGenerator {
162162

163163
unsigned int GetPlayCount() const { return 1; }
164164

165-
const ImageGenerator::FrameInfo GetFrameInfo(unsigned int frame_index) const {
165+
const ImageGenerator::FrameInfo GetFrameInfo(unsigned int frame_index) {
166166
return {std::nullopt, 0, SkCodecAnimation::DisposalMethod::kKeep};
167167
}
168168

lib/ui/painting/image_generator.cc

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ unsigned int BuiltinSkiaImageGenerator::GetPlayCount() const {
5151
}
5252

5353
const ImageGenerator::FrameInfo BuiltinSkiaImageGenerator::GetFrameInfo(
54-
unsigned int frame_index) const {
54+
unsigned int frame_index) {
5555
return {.required_frame = std::nullopt,
5656
.duration = 0,
5757
.disposal_method = SkCodecAnimation::DisposalMethod::kKeep};
@@ -105,7 +105,7 @@ unsigned int BuiltinSkiaCodecImageGenerator::GetPlayCount() const {
105105
}
106106

107107
const ImageGenerator::FrameInfo BuiltinSkiaCodecImageGenerator::GetFrameInfo(
108-
unsigned int frame_index) const {
108+
unsigned int frame_index) {
109109
SkCodec::FrameInfo info = {};
110110
codec_generator_->getFrameInfo(frame_index, &info);
111111
return {

lib/ui/painting/image_generator.h

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -37,11 +37,15 @@ class ImageGenerator {
3737
/// blended with.
3838
std::optional<unsigned int> required_frame;
3939

40-
/// Number of milliseconds to show this frame.
40+
/// Number of milliseconds to show this frame. 0 means only show it for one
41+
/// frame.
4142
unsigned int duration;
4243

4344
/// How this frame should be modified before decoding the next one.
4445
SkCodecAnimation::DisposalMethod disposal_method;
46+
47+
/// How this frame should be blended with the previous frame.
48+
SkCodecAnimation::Blend blend_mode;
4549
};
4650

4751
virtual ~ImageGenerator();
@@ -80,7 +84,7 @@ class ImageGenerator {
8084
/// @return Information about the given frame. If the image is
8185
/// single-frame, a default result is returned.
8286
/// @see `GetFrameCount`
83-
virtual const FrameInfo GetFrameInfo(unsigned int frame_index) const = 0;
87+
virtual const FrameInfo GetFrameInfo(unsigned int frame_index) = 0;
8488

8589
/// @brief Given a scale value, find the closest image size that can be
8690
/// used for efficiently decoding the image. If subpixel image
@@ -152,7 +156,7 @@ class BuiltinSkiaImageGenerator : public ImageGenerator {
152156

153157
// |ImageGenerator|
154158
const ImageGenerator::FrameInfo GetFrameInfo(
155-
unsigned int frame_index) const override;
159+
unsigned int frame_index) override;
156160

157161
// |ImageGenerator|
158162
SkISize GetScaledDimensions(float desired_scale) override;
@@ -192,7 +196,7 @@ class BuiltinSkiaCodecImageGenerator : public ImageGenerator {
192196

193197
// |ImageGenerator|
194198
const ImageGenerator::FrameInfo GetFrameInfo(
195-
unsigned int frame_index) const override;
199+
unsigned int frame_index) override;
196200

197201
// |ImageGenerator|
198202
SkISize GetScaledDimensions(float desired_scale) override;

0 commit comments

Comments
 (0)