Flutter Engine
The Flutter Engine
Loading...
Searching...
No Matches
SkAnimatedImage.h
Go to the documentation of this file.
1/*
2 * Copyright 2018 Google Inc.
3 *
4 * Use of this source code is governed by a BSD-style license that can be
5 * found in the LICENSE file.
6 */
7
8#ifndef SkAnimatedImage_DEFINED
9#define SkAnimatedImage_DEFINED
10
15#include "include/core/SkRect.h"
16
17class SkAndroidCodec;
18class SkImage;
19class SkPicture;
20
21/**
22 * Thread unsafe drawable for drawing animated images (e.g. GIF).
23 */
25public:
26 /**
27 * Create an SkAnimatedImage from the SkAndroidCodec.
28 *
29 * Returns null on failure to allocate pixels. On success, this will
30 * decode the first frame.
31 *
32 * @param info Width and height may require scaling.
33 * @param cropRect Rectangle to crop to after scaling.
34 * @param postProcess Picture to apply after scaling and cropping.
35 */
36 static sk_sp<SkAnimatedImage> Make(std::unique_ptr<SkAndroidCodec>,
37 const SkImageInfo& info, SkIRect cropRect, sk_sp<SkPicture> postProcess);
38
39 /**
40 * Simpler version that uses the default size, no cropping, and no postProcess.
41 */
42 static sk_sp<SkAnimatedImage> Make(std::unique_ptr<SkAndroidCodec>);
43
44 ~SkAnimatedImage() override;
45
46 /**
47 * Reset the animation to the beginning.
48 */
49 void reset();
50
51 /**
52 * Whether the animation completed.
53 *
54 * Returns true after all repetitions are complete, or an error stops the
55 * animation. Gets reset to false if the animation is restarted.
56 */
57 bool isFinished() const { return fFinished; }
58
59 /**
60 * Returned by decodeNextFrame and currentFrameDuration if the animation
61 * is not running.
62 */
63 static constexpr int kFinished = -1;
64
65 /**
66 * Decode the next frame.
67 *
68 * If the animation is on the last frame or has hit an error, returns
69 * kFinished.
70 */
71 int decodeNextFrame();
72
73 /**
74 * Returns the current frame as an SkImage. The SkImage will not change
75 * after it has been returned.
76 * If there is no current frame, nullptr will be returned.
77 */
78 sk_sp<SkImage> getCurrentFrame();
79
80 /**
81 * How long to display the current frame.
82 *
83 * Useful for the first frame, for which decodeNextFrame is called
84 * internally.
85 */
87 return fCurrentFrameDuration;
88 }
89
90 /**
91 * Change the repetition count.
92 *
93 * By default, the image will repeat the number of times indicated in the
94 * encoded data.
95 *
96 * Use SkCodec::kRepetitionCountInfinite for infinite, and 0 to show all
97 * frames once and then stop.
98 */
99 void setRepetitionCount(int count);
100
101 /**
102 * Return the currently set repetition count.
103 */
104 int getRepetitionCount() const {
105 return fRepetitionCount;
106 }
107
108 /**
109 * Return the total number of frames in the animation.
110 */
111 int getFrameCount() const { return fFrameCount; }
112
113protected:
114 SkRect onGetBounds() override;
115 void onDraw(SkCanvas*) override;
116
117private:
118 struct Frame {
119 SkBitmap fBitmap;
120 int fIndex;
121 SkCodecAnimation::DisposalMethod fDisposalMethod;
122
123 // init() may have to create a new SkPixelRef, if the
124 // current one is already in use by another owner (e.g.
125 // an SkPicture). This determines whether to copy the
126 // existing one to the new one.
127 enum class OnInit {
128 // Restore the image from the old SkPixelRef to the
129 // new one.
130 kRestoreIfNecessary,
131 // No need to restore.
132 kNoRestore,
133 };
134
135 Frame();
136 bool init(const SkImageInfo& info, OnInit);
137 bool copyTo(Frame*) const;
138 };
139
140 std::unique_ptr<SkAndroidCodec> fCodec;
141 SkImageInfo fDecodeInfo;
142 const SkIRect fCropRect;
143 const sk_sp<SkPicture> fPostProcess;
144 const int fFrameCount;
145 SkMatrix fMatrix;
146 int fSampleSize;
147
148 bool fFinished;
149 int fCurrentFrameDuration;
150 Frame fDisplayFrame;
151 Frame fDecodingFrame;
152 Frame fRestoreFrame;
153 int fRepetitionCount;
154 int fRepetitionsCompleted;
155
156 SkAnimatedImage(std::unique_ptr<SkAndroidCodec>, const SkImageInfo& requestedInfo,
157 SkIRect cropRect, sk_sp<SkPicture> postProcess);
158
159 int computeNextFrame(int current, bool* animationEnded);
160 double finish();
161
162 /**
163 * True if there is no crop, orientation, or post decoding scaling.
164 */
165 bool simple() const { return fMatrix.isIdentity() && !fPostProcess
166 && fCropRect == fDecodeInfo.bounds(); }
167
168 /**
169 * Returns the current frame as an SkImage.
170 *
171 * Like getCurrentFrame, but only returns the raw data from the internal SkBitmap. (i.e. no
172 * scaling, orientation-correction or cropping.) If simple(), this is the final output.
173 */
174 sk_sp<SkImage> getCurrentFrameSimple();
175
176 using INHERITED = SkDrawable;
177};
178
179#endif // SkAnimatedImage_DEFINED
static void info(const char *fmt,...) SK_PRINTF_LIKE(1
Definition DM.cpp:213
m reset()
int count
#define SK_API
Definition SkAPI.h:35
static std::unique_ptr< SkEncoder > Make(SkWStream *dst, const SkPixmap *src, const SkYUVAPixmaps *srcYUVA, const SkColorSpace *srcYUVAColorSpace, const SkJpegEncoder::Options &options)
#define INHERITED(method,...)
int getFrameCount() const
bool isFinished() const
int getRepetitionCount() const
virtual SkRect onGetBounds()=0
virtual void onDraw(SkCanvas *)=0
bool isIdentity() const
Definition SkMatrix.h:223
init(device_serial, adb_binary)
Definition _adb_path.py:12
SkIRect bounds() const