image/src/FrameBlender.h

Wed, 31 Dec 2014 06:09:35 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Wed, 31 Dec 2014 06:09:35 +0100
changeset 0
6474c204b198
permissions
-rw-r--r--

Cloned upstream origin tor-browser at tor-browser-31.3.0esr-4.5-1-build1
revision ID fc1c9ff7c1b2defdbc039f12214767608f46423f for hacking purpose.

     1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
     2  *
     3  * This Source Code Form is subject to the terms of the Mozilla Public
     4  * License, v. 2.0. If a copy of the MPL was not distributed with this
     5  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
     7 #ifndef mozilla_imagelib_FrameBlender_h_
     8 #define mozilla_imagelib_FrameBlender_h_
    10 #include "mozilla/MemoryReporting.h"
    11 #include "gfxTypes.h"
    12 #include "FrameSequence.h"
    13 #include "nsCOMPtr.h"
    15 class imgFrame;
    17 namespace mozilla {
    18 namespace image {
    20 /**
    21  * FrameBlender stores and gives access to imgFrames. It also knows how to
    22  * blend frames from previous to next, looping if necessary.
    23  *
    24  * All logic about when and whether to blend are external to FrameBlender.
    25  */
    26 class FrameBlender
    27 {
    28 public:
    30   /**
    31    * Create a new FrameBlender with a given frame sequence.
    32    *
    33    * If aSequenceToUse is not specified, it will be allocated automatically.
    34    */
    35   FrameBlender(FrameSequence* aSequenceToUse = nullptr);
    36   ~FrameBlender();
    38   bool DoBlend(nsIntRect* aDirtyRect, uint32_t aPrevFrameIndex,
    39                uint32_t aNextFrameIndex);
    41   already_AddRefed<FrameSequence> GetFrameSequence();
    43   /**
    44    * Get the @aIndex-th frame, including (if applicable) any results of
    45    * blending.
    46    */
    47   imgFrame* GetFrame(uint32_t aIndex) const;
    49   /**
    50    * Get the @aIndex-th frame in the frame index, ignoring results of blending.
    51    */
    52   imgFrame* RawGetFrame(uint32_t aIndex) const;
    54   void InsertFrame(uint32_t framenum, imgFrame* aFrame);
    55   void RemoveFrame(uint32_t framenum);
    56   imgFrame* SwapFrame(uint32_t framenum, imgFrame* aFrame);
    57   void ClearFrames();
    59   /* The total number of frames in this image. */
    60   uint32_t GetNumFrames() const;
    62   /*
    63    * Returns the frame's adjusted timeout. If the animation loops and the timeout
    64    * falls in between a certain range then the timeout is adjusted so that
    65    * it's never 0. If the animation does not loop then no adjustments are made.
    66    */
    67   int32_t GetTimeoutForFrame(uint32_t framenum) const;
    69   /*
    70    * Set number of times to loop the image.
    71    * @note -1 means loop forever.
    72    */
    73   void SetLoopCount(int32_t aLoopCount);
    74   int32_t GetLoopCount() const;
    76   void Discard();
    78   void SetSize(nsIntSize aSize) { mSize = aSize; }
    80   size_t SizeOfDecodedWithComputedFallbackIfHeap(gfxMemoryLocation aLocation,
    81                                                  mozilla::MallocSizeOf aMallocSizeOf) const;
    83   void ResetAnimation();
    85   // "Blend" method indicates how the current image is combined with the
    86   // previous image.
    87   enum FrameBlendMethod {
    88     // All color components of the frame, including alpha, overwrite the current
    89     // contents of the frame's output buffer region
    90     kBlendSource =  0,
    92     // The frame should be composited onto the output buffer based on its alpha,
    93     // using a simple OVER operation
    94     kBlendOver
    95   };
    97   enum FrameDisposalMethod {
    98     kDisposeClearAll         = -1, // Clear the whole image, revealing
    99                                    // what was there before the gif displayed
   100     kDisposeNotSpecified,   // Leave frame, let new frame draw on top
   101     kDisposeKeep,           // Leave frame, let new frame draw on top
   102     kDisposeClear,          // Clear the frame's area, revealing bg
   103     kDisposeRestorePrevious // Restore the previous (composited) frame
   104   };
   106   // A hint as to whether an individual frame is entirely opaque, or requires
   107   // alpha blending.
   108   enum FrameAlpha {
   109     kFrameHasAlpha,
   110     kFrameOpaque
   111   };
   113 private:
   115   struct Anim
   116   {
   117     //! Track the last composited frame for Optimizations (See DoComposite code)
   118     int32_t lastCompositedFrameIndex;
   120     /** For managing blending of frames
   121      *
   122      * Some animations will use the compositingFrame to composite images
   123      * and just hand this back to the caller when it is time to draw the frame.
   124      * NOTE: When clearing compositingFrame, remember to set
   125      *       lastCompositedFrameIndex to -1.  Code assume that if
   126      *       lastCompositedFrameIndex >= 0 then compositingFrame exists.
   127      */
   128     FrameDataPair compositingFrame;
   130     /** the previous composited frame, for DISPOSE_RESTORE_PREVIOUS
   131      *
   132      * The Previous Frame (all frames composited up to the current) needs to be
   133      * stored in cases where the image specifies it wants the last frame back
   134      * when it's done with the current frame.
   135      */
   136     FrameDataPair compositingPrevFrame;
   138     Anim() :
   139       lastCompositedFrameIndex(-1)
   140     {}
   141   };
   143   void EnsureAnimExists();
   145   /** Clears an area of <aFrame> with transparent black.
   146    *
   147    * @param aFrameData Target Frame data
   148    * @param aFrameRect The rectangle of the data pointed ot by aFrameData
   149    *
   150    * @note Does also clears the transparancy mask
   151    */
   152   static void ClearFrame(uint8_t* aFrameData, const nsIntRect& aFrameRect);
   154   //! @overload
   155   static void ClearFrame(uint8_t* aFrameData, const nsIntRect& aFrameRect, const nsIntRect &aRectToClear);
   157   //! Copy one frames's image and mask into another
   158   static bool CopyFrameImage(const uint8_t *aDataSrc, const nsIntRect& aRectSrc,
   159                              uint8_t *aDataDest, const nsIntRect& aRectDest);
   161   /**
   162    * Draws one frames's image to into another, at the position specified by
   163    * aSrcRect.
   164    *
   165    * @aSrcData the raw data of the current frame being drawn
   166    * @aSrcRect the size of the source frame, and the position of that frame in
   167    *           the composition frame
   168    * @aSrcPaletteLength the length (in bytes) of the palette at the beginning
   169    *                    of the source data (0 if image is not paletted)
   170    * @aSrcHasAlpha whether the source data represents an image with alpha
   171    * @aDstPixels the raw data of the composition frame where the current frame
   172    *             is drawn into (32-bit ARGB)
   173    * @aDstRect the size of the composition frame
   174    * @aBlendMethod the blend method for how to blend src on the composition frame.
   175    */
   176   static nsresult DrawFrameTo(const uint8_t *aSrcData, const nsIntRect& aSrcRect,
   177                               uint32_t aSrcPaletteLength, bool aSrcHasAlpha,
   178                               uint8_t *aDstPixels, const nsIntRect& aDstRect,
   179                               FrameBlendMethod aBlendMethod);
   181 private: // data
   182   //! All the frames of the image
   183   nsRefPtr<FrameSequence> mFrames;
   184   nsIntSize mSize;
   185   Anim* mAnim;
   186   int32_t mLoopCount;
   187 };
   189 } // namespace image
   190 } // namespace mozilla
   192 #endif /* mozilla_imagelib_FrameBlender_h_ */

mercurial