image/src/FrameBlender.h

changeset 0
6474c204b198
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/image/src/FrameBlender.h	Wed Dec 31 06:09:35 2014 +0100
     1.3 @@ -0,0 +1,192 @@
     1.4 +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
     1.5 + *
     1.6 + * This Source Code Form is subject to the terms of the Mozilla Public
     1.7 + * License, v. 2.0. If a copy of the MPL was not distributed with this
     1.8 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
     1.9 +
    1.10 +#ifndef mozilla_imagelib_FrameBlender_h_
    1.11 +#define mozilla_imagelib_FrameBlender_h_
    1.12 +
    1.13 +#include "mozilla/MemoryReporting.h"
    1.14 +#include "gfxTypes.h"
    1.15 +#include "FrameSequence.h"
    1.16 +#include "nsCOMPtr.h"
    1.17 +
    1.18 +class imgFrame;
    1.19 +
    1.20 +namespace mozilla {
    1.21 +namespace image {
    1.22 +
    1.23 +/**
    1.24 + * FrameBlender stores and gives access to imgFrames. It also knows how to
    1.25 + * blend frames from previous to next, looping if necessary.
    1.26 + *
    1.27 + * All logic about when and whether to blend are external to FrameBlender.
    1.28 + */
    1.29 +class FrameBlender
    1.30 +{
    1.31 +public:
    1.32 +
    1.33 +  /**
    1.34 +   * Create a new FrameBlender with a given frame sequence.
    1.35 +   *
    1.36 +   * If aSequenceToUse is not specified, it will be allocated automatically.
    1.37 +   */
    1.38 +  FrameBlender(FrameSequence* aSequenceToUse = nullptr);
    1.39 +  ~FrameBlender();
    1.40 +
    1.41 +  bool DoBlend(nsIntRect* aDirtyRect, uint32_t aPrevFrameIndex,
    1.42 +               uint32_t aNextFrameIndex);
    1.43 +
    1.44 +  already_AddRefed<FrameSequence> GetFrameSequence();
    1.45 +
    1.46 +  /**
    1.47 +   * Get the @aIndex-th frame, including (if applicable) any results of
    1.48 +   * blending.
    1.49 +   */
    1.50 +  imgFrame* GetFrame(uint32_t aIndex) const;
    1.51 +
    1.52 +  /**
    1.53 +   * Get the @aIndex-th frame in the frame index, ignoring results of blending.
    1.54 +   */
    1.55 +  imgFrame* RawGetFrame(uint32_t aIndex) const;
    1.56 +
    1.57 +  void InsertFrame(uint32_t framenum, imgFrame* aFrame);
    1.58 +  void RemoveFrame(uint32_t framenum);
    1.59 +  imgFrame* SwapFrame(uint32_t framenum, imgFrame* aFrame);
    1.60 +  void ClearFrames();
    1.61 +
    1.62 +  /* The total number of frames in this image. */
    1.63 +  uint32_t GetNumFrames() const;
    1.64 +
    1.65 +  /*
    1.66 +   * Returns the frame's adjusted timeout. If the animation loops and the timeout
    1.67 +   * falls in between a certain range then the timeout is adjusted so that
    1.68 +   * it's never 0. If the animation does not loop then no adjustments are made.
    1.69 +   */
    1.70 +  int32_t GetTimeoutForFrame(uint32_t framenum) const;
    1.71 +
    1.72 +  /*
    1.73 +   * Set number of times to loop the image.
    1.74 +   * @note -1 means loop forever.
    1.75 +   */
    1.76 +  void SetLoopCount(int32_t aLoopCount);
    1.77 +  int32_t GetLoopCount() const;
    1.78 +
    1.79 +  void Discard();
    1.80 +
    1.81 +  void SetSize(nsIntSize aSize) { mSize = aSize; }
    1.82 +
    1.83 +  size_t SizeOfDecodedWithComputedFallbackIfHeap(gfxMemoryLocation aLocation,
    1.84 +                                                 mozilla::MallocSizeOf aMallocSizeOf) const;
    1.85 +
    1.86 +  void ResetAnimation();
    1.87 +
    1.88 +  // "Blend" method indicates how the current image is combined with the
    1.89 +  // previous image.
    1.90 +  enum FrameBlendMethod {
    1.91 +    // All color components of the frame, including alpha, overwrite the current
    1.92 +    // contents of the frame's output buffer region
    1.93 +    kBlendSource =  0,
    1.94 +
    1.95 +    // The frame should be composited onto the output buffer based on its alpha,
    1.96 +    // using a simple OVER operation
    1.97 +    kBlendOver
    1.98 +  };
    1.99 +
   1.100 +  enum FrameDisposalMethod {
   1.101 +    kDisposeClearAll         = -1, // Clear the whole image, revealing
   1.102 +                                   // what was there before the gif displayed
   1.103 +    kDisposeNotSpecified,   // Leave frame, let new frame draw on top
   1.104 +    kDisposeKeep,           // Leave frame, let new frame draw on top
   1.105 +    kDisposeClear,          // Clear the frame's area, revealing bg
   1.106 +    kDisposeRestorePrevious // Restore the previous (composited) frame
   1.107 +  };
   1.108 +
   1.109 +  // A hint as to whether an individual frame is entirely opaque, or requires
   1.110 +  // alpha blending.
   1.111 +  enum FrameAlpha {
   1.112 +    kFrameHasAlpha,
   1.113 +    kFrameOpaque
   1.114 +  };
   1.115 +
   1.116 +private:
   1.117 +
   1.118 +  struct Anim
   1.119 +  {
   1.120 +    //! Track the last composited frame for Optimizations (See DoComposite code)
   1.121 +    int32_t lastCompositedFrameIndex;
   1.122 +
   1.123 +    /** For managing blending of frames
   1.124 +     *
   1.125 +     * Some animations will use the compositingFrame to composite images
   1.126 +     * and just hand this back to the caller when it is time to draw the frame.
   1.127 +     * NOTE: When clearing compositingFrame, remember to set
   1.128 +     *       lastCompositedFrameIndex to -1.  Code assume that if
   1.129 +     *       lastCompositedFrameIndex >= 0 then compositingFrame exists.
   1.130 +     */
   1.131 +    FrameDataPair compositingFrame;
   1.132 +
   1.133 +    /** the previous composited frame, for DISPOSE_RESTORE_PREVIOUS
   1.134 +     *
   1.135 +     * The Previous Frame (all frames composited up to the current) needs to be
   1.136 +     * stored in cases where the image specifies it wants the last frame back
   1.137 +     * when it's done with the current frame.
   1.138 +     */
   1.139 +    FrameDataPair compositingPrevFrame;
   1.140 +
   1.141 +    Anim() :
   1.142 +      lastCompositedFrameIndex(-1)
   1.143 +    {}
   1.144 +  };
   1.145 +
   1.146 +  void EnsureAnimExists();
   1.147 +
   1.148 +  /** Clears an area of <aFrame> with transparent black.
   1.149 +   *
   1.150 +   * @param aFrameData Target Frame data
   1.151 +   * @param aFrameRect The rectangle of the data pointed ot by aFrameData
   1.152 +   *
   1.153 +   * @note Does also clears the transparancy mask
   1.154 +   */
   1.155 +  static void ClearFrame(uint8_t* aFrameData, const nsIntRect& aFrameRect);
   1.156 +
   1.157 +  //! @overload
   1.158 +  static void ClearFrame(uint8_t* aFrameData, const nsIntRect& aFrameRect, const nsIntRect &aRectToClear);
   1.159 +
   1.160 +  //! Copy one frames's image and mask into another
   1.161 +  static bool CopyFrameImage(const uint8_t *aDataSrc, const nsIntRect& aRectSrc,
   1.162 +                             uint8_t *aDataDest, const nsIntRect& aRectDest);
   1.163 +
   1.164 +  /**
   1.165 +   * Draws one frames's image to into another, at the position specified by
   1.166 +   * aSrcRect.
   1.167 +   *
   1.168 +   * @aSrcData the raw data of the current frame being drawn
   1.169 +   * @aSrcRect the size of the source frame, and the position of that frame in
   1.170 +   *           the composition frame
   1.171 +   * @aSrcPaletteLength the length (in bytes) of the palette at the beginning
   1.172 +   *                    of the source data (0 if image is not paletted)
   1.173 +   * @aSrcHasAlpha whether the source data represents an image with alpha
   1.174 +   * @aDstPixels the raw data of the composition frame where the current frame
   1.175 +   *             is drawn into (32-bit ARGB)
   1.176 +   * @aDstRect the size of the composition frame
   1.177 +   * @aBlendMethod the blend method for how to blend src on the composition frame.
   1.178 +   */
   1.179 +  static nsresult DrawFrameTo(const uint8_t *aSrcData, const nsIntRect& aSrcRect,
   1.180 +                              uint32_t aSrcPaletteLength, bool aSrcHasAlpha,
   1.181 +                              uint8_t *aDstPixels, const nsIntRect& aDstRect,
   1.182 +                              FrameBlendMethod aBlendMethod);
   1.183 +
   1.184 +private: // data
   1.185 +  //! All the frames of the image
   1.186 +  nsRefPtr<FrameSequence> mFrames;
   1.187 +  nsIntSize mSize;
   1.188 +  Anim* mAnim;
   1.189 +  int32_t mLoopCount;
   1.190 +};
   1.191 +
   1.192 +} // namespace image
   1.193 +} // namespace mozilla
   1.194 +
   1.195 +#endif /* mozilla_imagelib_FrameBlender_h_ */

mercurial