|
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_FrameSequence_h_ |
|
8 #define mozilla_imagelib_FrameSequence_h_ |
|
9 |
|
10 #include "nsTArray.h" |
|
11 #include "mozilla/MemoryReporting.h" |
|
12 #include "gfxTypes.h" |
|
13 #include "imgFrame.h" |
|
14 |
|
15 namespace mozilla { |
|
16 namespace image { |
|
17 |
|
18 /** |
|
19 * FrameDataPair is a slightly-smart tuple of (frame, raw frame data) where the |
|
20 * raw frame data is allowed to be (and is, initially) null. |
|
21 * |
|
22 * If you call LockAndGetData, you will be able to call GetFrameData() on that |
|
23 * instance, and when the FrameDataPair is destructed, the imgFrame lock will |
|
24 * be unlocked. |
|
25 */ |
|
26 class FrameDataPair |
|
27 { |
|
28 public: |
|
29 explicit FrameDataPair(imgFrame* frame) |
|
30 : mFrame(frame) |
|
31 , mFrameData(nullptr) |
|
32 {} |
|
33 |
|
34 FrameDataPair() |
|
35 : mFrame(nullptr) |
|
36 , mFrameData(nullptr) |
|
37 {} |
|
38 |
|
39 FrameDataPair(FrameDataPair& other) |
|
40 { |
|
41 mFrame = other.mFrame; |
|
42 mFrameData = other.mFrameData; |
|
43 |
|
44 // since mFrame is an nsAutoPtr, the assignment operator above actually |
|
45 // nulls out other.mFrame. In order to fully assume ownership over the |
|
46 // frame, we also null out the other's mFrameData. |
|
47 other.mFrameData = nullptr; |
|
48 } |
|
49 |
|
50 ~FrameDataPair() |
|
51 { |
|
52 if (mFrameData) { |
|
53 mFrame->UnlockImageData(); |
|
54 } |
|
55 } |
|
56 |
|
57 // Lock the frame and store its mFrameData. The frame will be unlocked (and |
|
58 // deleted) when this FrameDataPair is deleted. |
|
59 void LockAndGetData() |
|
60 { |
|
61 if (mFrame) { |
|
62 if (NS_SUCCEEDED(mFrame->LockImageData())) { |
|
63 if (mFrame->GetIsPaletted()) { |
|
64 mFrameData = reinterpret_cast<uint8_t*>(mFrame->GetPaletteData()); |
|
65 } else { |
|
66 mFrameData = mFrame->GetImageData(); |
|
67 } |
|
68 } |
|
69 } |
|
70 } |
|
71 |
|
72 // Null out this FrameDataPair and return its frame. You must ensure the |
|
73 // frame will be deleted separately. |
|
74 imgFrame* Forget() |
|
75 { |
|
76 if (mFrameData) { |
|
77 mFrame->UnlockImageData(); |
|
78 } |
|
79 |
|
80 imgFrame* frame = mFrame.forget(); |
|
81 mFrameData = nullptr; |
|
82 return frame; |
|
83 } |
|
84 |
|
85 bool HasFrameData() const |
|
86 { |
|
87 if (mFrameData) { |
|
88 MOZ_ASSERT(!!mFrame); |
|
89 } |
|
90 return !!mFrameData; |
|
91 } |
|
92 |
|
93 uint8_t* GetFrameData() const |
|
94 { |
|
95 return mFrameData; |
|
96 } |
|
97 |
|
98 imgFrame* GetFrame() const |
|
99 { |
|
100 return mFrame; |
|
101 } |
|
102 |
|
103 // Resets this FrameDataPair to work with a different frame. Takes ownership |
|
104 // of the frame, deleting the old frame (if any). |
|
105 void SetFrame(imgFrame* frame) |
|
106 { |
|
107 if (mFrameData) { |
|
108 mFrame->UnlockImageData(); |
|
109 } |
|
110 |
|
111 mFrame = frame; |
|
112 mFrameData = nullptr; |
|
113 } |
|
114 |
|
115 operator imgFrame*() const |
|
116 { |
|
117 return GetFrame(); |
|
118 } |
|
119 |
|
120 imgFrame* operator->() const |
|
121 { |
|
122 return GetFrame(); |
|
123 } |
|
124 |
|
125 bool operator==(imgFrame* other) const |
|
126 { |
|
127 return mFrame == other; |
|
128 } |
|
129 |
|
130 private: |
|
131 nsAutoPtr<imgFrame> mFrame; |
|
132 uint8_t* mFrameData; |
|
133 }; |
|
134 |
|
135 /** |
|
136 * FrameSequence stores image frames (and their associated raw data pointers). |
|
137 * It is little more than a smart array. |
|
138 */ |
|
139 class FrameSequence |
|
140 { |
|
141 public: |
|
142 |
|
143 ~FrameSequence(); |
|
144 |
|
145 NS_INLINE_DECL_THREADSAFE_REFCOUNTING(FrameSequence) |
|
146 |
|
147 /** |
|
148 * Get the read-only (frame, data) pair at index aIndex. |
|
149 */ |
|
150 const FrameDataPair& GetFrame(uint32_t aIndex) const; |
|
151 |
|
152 /** |
|
153 * Insert a frame into the array. FrameSequence takes ownership of the frame. |
|
154 */ |
|
155 void InsertFrame(uint32_t framenum, imgFrame* aFrame); |
|
156 |
|
157 /** |
|
158 * Remove (and delete) the frame at index framenum. |
|
159 */ |
|
160 void RemoveFrame(uint32_t framenum); |
|
161 |
|
162 /** |
|
163 * Swap aFrame with the frame at sequence framenum, and return that frame. |
|
164 * You take ownership over the frame returned. |
|
165 */ |
|
166 imgFrame* SwapFrame(uint32_t framenum, imgFrame* aFrame); |
|
167 |
|
168 /** |
|
169 * Remove (and delete) all frames. |
|
170 */ |
|
171 void ClearFrames(); |
|
172 |
|
173 /* The total number of frames in this image. */ |
|
174 uint32_t GetNumFrames() const; |
|
175 |
|
176 size_t SizeOfDecodedWithComputedFallbackIfHeap(gfxMemoryLocation aLocation, |
|
177 mozilla::MallocSizeOf aMallocSizeOf) const; |
|
178 |
|
179 private: // data |
|
180 //! All the frames of the image |
|
181 nsTArray<FrameDataPair> mFrames; |
|
182 }; |
|
183 |
|
184 } // namespace image |
|
185 } // namespace mozilla |
|
186 |
|
187 #endif /* mozilla_imagelib_FrameSequence_h_ */ |