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_ */