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 "SkBitmap.h" 12 #include "SkCodecAnimation.h" 13 #include "SkDrawable.h" 14 #include "SkMatrix.h" 15 #include "SkRect.h" 16 17 class SkAndroidCodec; 18 class SkPicture; 19 20 /** 21 * Thread unsafe drawable for drawing animated images (e.g. GIF). 22 */ 23 class SK_API SkAnimatedImage : public SkDrawable { 24 public: 25 /** 26 * Create an SkAnimatedImage from the SkAndroidCodec. 27 * 28 * Returns null on failure to allocate pixels. On success, this will 29 * decode the first frame. 30 * 31 * @param info Width and height may require 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 const SkImageInfo& info, SkIRect cropRect, sk_sp<SkPicture> postProcess); 37 38 /** 39 * Create an SkAnimatedImage from the SkAndroidCodec. 40 * 41 * Returns null on failure to allocate pixels. On success, this will 42 * decode the first frame. 43 * 44 * @param scaledSize Size to draw the image, possibly requiring scaling. 45 * @param cropRect Rectangle to crop to after scaling. 46 * @param postProcess Picture to apply after scaling and cropping. 47 */ 48 static sk_sp<SkAnimatedImage> Make(std::unique_ptr<SkAndroidCodec>, 49 SkISize scaledSize, SkIRect cropRect, sk_sp<SkPicture> postProcess); 50 51 /** 52 * Simpler version that uses the default size, no cropping, and no postProcess. 53 */ 54 static sk_sp<SkAnimatedImage> Make(std::unique_ptr<SkAndroidCodec>); 55 56 ~SkAnimatedImage() override; 57 58 /** 59 * Reset the animation to the beginning. 60 */ 61 void reset(); 62 63 /** 64 * Whether the animation completed. 65 * 66 * Returns true after all repetitions are complete, or an error stops the 67 * animation. Gets reset to false if the animation is restarted. 68 */ isFinished()69 bool isFinished() const { return fFinished; } 70 71 /** 72 * Returned by decodeNextFrame and currentFrameDuration if the animation 73 * is not running. 74 */ 75 static constexpr int kFinished = -1; 76 77 /** 78 * Decode the next frame. 79 * 80 * If the animation is on the last frame or has hit an error, returns 81 * kFinished. 82 */ 83 int decodeNextFrame(); 84 85 /** 86 * How long to display the current frame. 87 * 88 * Useful for the first frame, for which decodeNextFrame is called 89 * internally. 90 */ currentFrameDuration()91 int currentFrameDuration() { 92 return fCurrentFrameDuration; 93 } 94 95 /** 96 * Change the repetition count. 97 * 98 * By default, the image will repeat the number of times indicated in the 99 * encoded data. 100 * 101 * Use SkCodec::kRepetitionCountInfinite for infinite, and 0 to show all 102 * frames once and then stop. 103 */ 104 void setRepetitionCount(int count); 105 106 /** 107 * Return the currently set repetition count. 108 */ getRepetitionCount()109 int getRepetitionCount() const { 110 return fRepetitionCount; 111 } 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 const SkISize fScaledSize; 142 const SkImageInfo fDecodeInfo; 143 const SkIRect fCropRect; 144 const sk_sp<SkPicture> fPostProcess; 145 const int fFrameCount; 146 const bool fSimple; // no crop, scale, or postprocess 147 SkMatrix fMatrix; // used only if !fSimple 148 149 bool fFinished; 150 int fCurrentFrameDuration; 151 Frame fDisplayFrame; 152 Frame fDecodingFrame; 153 Frame fRestoreFrame; 154 int fRepetitionCount; 155 int fRepetitionsCompleted; 156 157 SkAnimatedImage(std::unique_ptr<SkAndroidCodec>, SkISize scaledSize, 158 SkImageInfo decodeInfo, SkIRect cropRect, sk_sp<SkPicture> postProcess); 159 SkAnimatedImage(std::unique_ptr<SkAndroidCodec>); 160 161 int computeNextFrame(int current, bool* animationEnded); 162 double finish(); 163 164 typedef SkDrawable INHERITED; 165 }; 166 167 #endif // SkAnimatedImage_DEFINED 168