Coverage Report

Created: 2024-05-20 07:14

/src/skia/include/android/SkAnimatedImage.h
Line
Count
Source (jump to first uncovered line)
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
11
#include "include/codec/SkCodecAnimation.h"
12
#include "include/core/SkBitmap.h"
13
#include "include/core/SkDrawable.h"
14
#include "include/core/SkMatrix.h"
15
#include "include/core/SkRect.h"
16
17
class SkAndroidCodec;
18
class SkImage;
19
class SkPicture;
20
21
/**
22
 *  Thread unsafe drawable for drawing animated images (e.g. GIF).
23
 */
24
class SK_API SkAnimatedImage : public SkDrawable {
25
public:
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
57.4k
    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
     */
86
0
    int currentFrameDuration() {
87
0
        return fCurrentFrameDuration;
88
0
    }
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
0
    int getRepetitionCount() const {
105
0
        return fRepetitionCount;
106
0
    }
107
108
    /**
109
     *  Return the total number of frames in the animation.
110
     */
111
0
    int getFrameCount() const { return fFrameCount; }
112
113
protected:
114
    SkRect onGetBounds() override;
115
    void onDraw(SkCanvas*) override;
116
117
private:
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
55.0k
    bool simple() const { return fMatrix.isIdentity() && !fPostProcess
166
55.0k
                                 && 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