image/src/FrameBlender.h

branch
TOR_BUG_9701
changeset 10
ac0c01689b40
equal deleted inserted replaced
-1:000000000000 0:d4680d066b81
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/. */
6
7 #ifndef mozilla_imagelib_FrameBlender_h_
8 #define mozilla_imagelib_FrameBlender_h_
9
10 #include "mozilla/MemoryReporting.h"
11 #include "gfxTypes.h"
12 #include "FrameSequence.h"
13 #include "nsCOMPtr.h"
14
15 class imgFrame;
16
17 namespace mozilla {
18 namespace image {
19
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:
29
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();
37
38 bool DoBlend(nsIntRect* aDirtyRect, uint32_t aPrevFrameIndex,
39 uint32_t aNextFrameIndex);
40
41 already_AddRefed<FrameSequence> GetFrameSequence();
42
43 /**
44 * Get the @aIndex-th frame, including (if applicable) any results of
45 * blending.
46 */
47 imgFrame* GetFrame(uint32_t aIndex) const;
48
49 /**
50 * Get the @aIndex-th frame in the frame index, ignoring results of blending.
51 */
52 imgFrame* RawGetFrame(uint32_t aIndex) const;
53
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();
58
59 /* The total number of frames in this image. */
60 uint32_t GetNumFrames() const;
61
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;
68
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;
75
76 void Discard();
77
78 void SetSize(nsIntSize aSize) { mSize = aSize; }
79
80 size_t SizeOfDecodedWithComputedFallbackIfHeap(gfxMemoryLocation aLocation,
81 mozilla::MallocSizeOf aMallocSizeOf) const;
82
83 void ResetAnimation();
84
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,
91
92 // The frame should be composited onto the output buffer based on its alpha,
93 // using a simple OVER operation
94 kBlendOver
95 };
96
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 };
105
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 };
112
113 private:
114
115 struct Anim
116 {
117 //! Track the last composited frame for Optimizations (See DoComposite code)
118 int32_t lastCompositedFrameIndex;
119
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;
129
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;
137
138 Anim() :
139 lastCompositedFrameIndex(-1)
140 {}
141 };
142
143 void EnsureAnimExists();
144
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);
153
154 //! @overload
155 static void ClearFrame(uint8_t* aFrameData, const nsIntRect& aFrameRect, const nsIntRect &aRectToClear);
156
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);
160
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);
180
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 };
188
189 } // namespace image
190 } // namespace mozilla
191
192 #endif /* mozilla_imagelib_FrameBlender_h_ */

mercurial