Home | History | Annotate | Download | only in codec
      1 /*
      2  * Copyright 2017 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 SkFrameHolder_DEFINED
      9 #define SkFrameHolder_DEFINED
     10 
     11 #include "SkTypes.h"
     12 #include "SkCodecAnimation.h"
     13 #include "SkCodecAnimationPriv.h"
     14 #include "SkRect.h"
     15 
     16 /**
     17  *  Base class for a single frame of an animated image.
     18  *
     19  *  Separate from SkCodec::FrameInfo, which is a pared down
     20  *  interface that only contains the info the client needs.
     21  */
     22 class SkFrame : public SkNoncopyable {
     23 public:
     24     SkFrame(int id)
     25         : fId(id)
     26         , fHasAlpha(false)
     27         , fRequiredFrame(kUninitialized)
     28         , fDisposalMethod(SkCodecAnimation::DisposalMethod::kKeep)
     29         , fDuration(0)
     30         , fBlend(SkCodecAnimation::Blend::kPriorFrame)
     31     {
     32         fRect.setEmpty();
     33     }
     34 
     35     virtual ~SkFrame() {}
     36 
     37     /**
     38      *  0-based index of the frame in the image sequence.
     39      */
     40     int frameId() const { return fId; }
     41 
     42     /**
     43      *  How this frame reports its alpha.
     44      *
     45      *  This only considers the rectangle of this frame, and
     46      *  considers it to have alpha even if it is opaque once
     47      *  blended with the frame behind it.
     48      */
     49     SkEncodedInfo::Alpha reportedAlpha() const {
     50         return this->onReportedAlpha();
     51     }
     52 
     53     /**
     54      *  Cached value representing whether the frame has alpha,
     55      *  after compositing with the prior frame.
     56      */
     57     bool hasAlpha() const { return fHasAlpha; }
     58 
     59     /**
     60      *  Cache whether the finished frame has alpha.
     61      */
     62     void setHasAlpha(bool alpha) { fHasAlpha = alpha; }
     63 
     64     /**
     65      *  Whether enough of the frame has been read to determine
     66      *  fRequiredFrame and fHasAlpha.
     67      */
     68     bool reachedStartOfData() const { return fRequiredFrame != kUninitialized; }
     69 
     70     /**
     71      *  The frame this one depends on.
     72      *
     73      *  Must not be called until fRequiredFrame has been set properly.
     74      */
     75     int getRequiredFrame() const {
     76         SkASSERT(this->reachedStartOfData());
     77         return fRequiredFrame;
     78     }
     79 
     80     /**
     81      *  Set the frame that this frame depends on.
     82      */
     83     void setRequiredFrame(int req) { fRequiredFrame = req; }
     84 
     85     /**
     86      *  Set the rectangle that is updated by this frame.
     87      */
     88     void setXYWH(int x, int y, int width, int height) {
     89         fRect.setXYWH(x, y, width, height);
     90     }
     91 
     92     /**
     93      *  The rectangle that is updated by this frame.
     94      */
     95     SkIRect frameRect() const { return fRect; }
     96 
     97     int xOffset() const { return fRect.x(); }
     98     int yOffset() const { return fRect.y(); }
     99     int width()   const { return fRect.width(); }
    100     int height()  const { return fRect.height(); }
    101 
    102     SkCodecAnimation::DisposalMethod getDisposalMethod() const {
    103         return fDisposalMethod;
    104     }
    105 
    106     void setDisposalMethod(SkCodecAnimation::DisposalMethod disposalMethod) {
    107         fDisposalMethod = disposalMethod;
    108     }
    109 
    110     /**
    111      * Set the duration (in ms) to show this frame.
    112      */
    113     void setDuration(int duration) {
    114         fDuration = duration;
    115     }
    116 
    117     /**
    118      *  Duration in ms to show this frame.
    119      */
    120     int getDuration() const {
    121         return fDuration;
    122     }
    123 
    124     void setBlend(SkCodecAnimation::Blend blend) {
    125         fBlend = blend;
    126     }
    127 
    128     SkCodecAnimation::Blend getBlend() const {
    129         return fBlend;
    130     }
    131 
    132 protected:
    133     virtual SkEncodedInfo::Alpha onReportedAlpha() const = 0;
    134 
    135 private:
    136     static constexpr int kUninitialized = -2;
    137 
    138     const int                           fId;
    139     bool                                fHasAlpha;
    140     int                                 fRequiredFrame;
    141     SkIRect                             fRect;
    142     SkCodecAnimation::DisposalMethod    fDisposalMethod;
    143     int                                 fDuration;
    144     SkCodecAnimation::Blend             fBlend;
    145 };
    146 
    147 /**
    148  *  Base class for an object which holds the SkFrames of an
    149  *  image sequence.
    150  */
    151 class SkFrameHolder : public SkNoncopyable {
    152 public:
    153     SkFrameHolder()
    154         : fScreenWidth(0)
    155         , fScreenHeight(0)
    156     {}
    157 
    158     virtual ~SkFrameHolder() {}
    159 
    160     /**
    161      *  Size of the image. Each frame will be contained in
    162      *  these dimensions (possibly after clipping).
    163      */
    164     int screenWidth() const { return fScreenWidth; }
    165     int screenHeight() const { return fScreenHeight; }
    166 
    167     /**
    168      *  Compute the opacity and required frame, based on
    169      *  the frame's reportedAlpha and how it blends
    170      *  with prior frames.
    171      */
    172     void setAlphaAndRequiredFrame(SkFrame*);
    173 
    174     /**
    175      *  Return the frame with frameId i.
    176      */
    177     const SkFrame* getFrame(int i) const {
    178         return this->onGetFrame(i);
    179     }
    180 
    181 protected:
    182     int fScreenWidth;
    183     int fScreenHeight;
    184 
    185     virtual const SkFrame* onGetFrame(int i) const = 0;
    186 };
    187 
    188 #endif // SkFrameHolder_DEFINED
    189