blob: 983a57bd5cb6aa1995dabc31a4c90eecea8c160f [file] [log] [blame]
Leon Scroggins III7a10b332018-01-12 11:24:30 -05001/*
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 "SkBitmap.h"
12#include "SkCodecAnimation.h"
13#include "SkDrawable.h"
Leon Scroggins IIIb1b7f7012018-01-16 15:26:35 -050014#include "SkMatrix.h"
15#include "SkRect.h"
Leon Scroggins III7a10b332018-01-12 11:24:30 -050016
Leon Scroggins III42ee2842018-01-14 14:46:51 -050017class SkAndroidCodec;
Leon Scroggins IIIb1b7f7012018-01-16 15:26:35 -050018class SkPicture;
Leon Scroggins III7a10b332018-01-12 11:24:30 -050019
20/**
21 * Thread unsafe drawable for drawing animated images (e.g. GIF).
22 */
23class SK_API SkAnimatedImage : public SkDrawable {
24public:
25 /**
Leon Scroggins III42ee2842018-01-14 14:46:51 -050026 * Create an SkAnimatedImage from the SkAndroidCodec.
Leon Scroggins III7a10b332018-01-12 11:24:30 -050027 *
28 * Returns null on failure to allocate pixels. On success, this will
Leon Scroggins III495e0f02018-01-29 19:35:55 -050029 * decode the first frame.
Leon Scroggins IIIb1b7f7012018-01-16 15:26:35 -050030 *
31 * @param scaledSize Size to draw the image, possibly requiring scaling.
32 * @param cropRect Rectangle to crop to after scaling.
33 * @param postProcess Picture to apply after scaling and cropping.
34 */
35 static sk_sp<SkAnimatedImage> Make(std::unique_ptr<SkAndroidCodec>,
36 SkISize scaledSize, SkIRect cropRect, sk_sp<SkPicture> postProcess);
37
38 /**
39 * Simpler version that uses the default size, no cropping, and no postProcess.
Leon Scroggins III7a10b332018-01-12 11:24:30 -050040 */
Leon Scroggins III42ee2842018-01-14 14:46:51 -050041 static sk_sp<SkAnimatedImage> Make(std::unique_ptr<SkAndroidCodec>);
Leon Scroggins III7a10b332018-01-12 11:24:30 -050042
43 ~SkAnimatedImage() override;
44
45 /**
Leon Scroggins III7a10b332018-01-12 11:24:30 -050046 * Reset the animation to the beginning.
47 */
48 void reset();
49
50 /**
Leon Scroggins III2cb6cb12018-01-21 15:50:12 -050051 * Whether the animation completed.
52 *
53 * Returns true after all repetitions are complete, or an error stops the
54 * animation. Gets reset to false if the animation is restarted.
55 */
56 bool isFinished() const { return fFinished; }
57
58 /**
Leon Scroggins III495e0f02018-01-29 19:35:55 -050059 * Returned by decodeNextFrame and currentFrameDuration if the animation
60 * is not running.
Leon Scroggins III8524c302018-01-22 12:31:21 -050061 */
Leon Scroggins III495e0f02018-01-29 19:35:55 -050062 static constexpr int kFinished = -1;
Leon Scroggins III8524c302018-01-22 12:31:21 -050063
64 /**
Leon Scroggins III495e0f02018-01-29 19:35:55 -050065 * Decode the next frame.
Leon Scroggins III7a10b332018-01-12 11:24:30 -050066 *
Leon Scroggins III495e0f02018-01-29 19:35:55 -050067 * If the animation is on the last frame or has hit an error, returns
68 * kFinished.
Leon Scroggins III7a10b332018-01-12 11:24:30 -050069 */
Leon Scroggins III495e0f02018-01-29 19:35:55 -050070 int decodeNextFrame();
71
72 /**
73 * How long to display the current frame.
74 *
75 * Useful for the first frame, for which decodeNextFrame is called
76 * internally.
77 */
78 int currentFrameDuration() {
79 return fCurrentFrameDuration;
80 }
Leon Scroggins III7a10b332018-01-12 11:24:30 -050081
Leon Scroggins III4c119452018-01-20 10:33:24 -050082 /**
83 * Change the repetition count.
84 *
85 * By default, the image will repeat the number of times indicated in the
86 * encoded data.
87 *
88 * Use SkCodec::kRepetitionCountInfinite for infinite, and 0 to show all
89 * frames once and then stop.
90 */
91 void setRepetitionCount(int count);
92
Leon Scroggins IIIabe639c2018-01-26 11:06:12 -050093 /**
94 * Return the currently set repetition count.
95 */
96 int getRepetitionCount() const {
97 return fRepetitionCount;
98 }
99
Leon Scroggins III7a10b332018-01-12 11:24:30 -0500100protected:
101 SkRect onGetBounds() override;
102 void onDraw(SkCanvas*) override;
103
104private:
105 struct Frame {
106 SkBitmap fBitmap;
107 int fIndex;
108 SkCodecAnimation::DisposalMethod fDisposalMethod;
109
Leon Scroggins III4aafb3a2018-05-23 16:15:09 -0400110 // init() may have to create a new SkPixelRef, if the
111 // current one is already in use by another owner (e.g.
112 // an SkPicture). This determines whether to copy the
113 // existing one to the new one.
114 enum class OnInit {
115 // Restore the image from the old SkPixelRef to the
116 // new one.
117 kRestoreIfNecessary,
118 // No need to restore.
119 kNoRestore,
120 };
121
Leon Scroggins III7a10b332018-01-12 11:24:30 -0500122 Frame();
Leon Scroggins III4aafb3a2018-05-23 16:15:09 -0400123 bool init(const SkImageInfo& info, OnInit);
Leon Scroggins III7a10b332018-01-12 11:24:30 -0500124 bool copyTo(Frame*) const;
125 };
126
Leon Scroggins III42ee2842018-01-14 14:46:51 -0500127 std::unique_ptr<SkAndroidCodec> fCodec;
Leon Scroggins IIIb1b7f7012018-01-16 15:26:35 -0500128 const SkISize fScaledSize;
129 const SkImageInfo fDecodeInfo;
130 const SkIRect fCropRect;
131 const sk_sp<SkPicture> fPostProcess;
Leon Scroggins III4c119452018-01-20 10:33:24 -0500132 const int fFrameCount;
Leon Scroggins IIIb1b7f7012018-01-16 15:26:35 -0500133 const bool fSimple; // no crop, scale, or postprocess
134 SkMatrix fMatrix; // used only if !fSimple
135
Leon Scroggins III42ee2842018-01-14 14:46:51 -0500136 bool fFinished;
Leon Scroggins III495e0f02018-01-29 19:35:55 -0500137 int fCurrentFrameDuration;
Leon Scroggins III4aafb3a2018-05-23 16:15:09 -0400138 Frame fDisplayFrame;
139 Frame fDecodingFrame;
Leon Scroggins III42ee2842018-01-14 14:46:51 -0500140 Frame fRestoreFrame;
Leon Scroggins III4c119452018-01-20 10:33:24 -0500141 int fRepetitionCount;
142 int fRepetitionsCompleted;
Leon Scroggins III7a10b332018-01-12 11:24:30 -0500143
Leon Scroggins IIIb1b7f7012018-01-16 15:26:35 -0500144 SkAnimatedImage(std::unique_ptr<SkAndroidCodec>, SkISize scaledSize,
145 SkImageInfo decodeInfo, SkIRect cropRect, sk_sp<SkPicture> postProcess);
Leon Scroggins III4c119452018-01-20 10:33:24 -0500146 SkAnimatedImage(std::unique_ptr<SkAndroidCodec>);
147
148 int computeNextFrame(int current, bool* animationEnded);
149 double finish();
Leon Scroggins III7a10b332018-01-12 11:24:30 -0500150
151 typedef SkDrawable INHERITED;
152};
153
154#endif // SkAnimatedImage_DEFINED