1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/image/src/FrameSequence.h Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,187 @@ 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_FrameSequence_h_ 1.11 +#define mozilla_imagelib_FrameSequence_h_ 1.12 + 1.13 +#include "nsTArray.h" 1.14 +#include "mozilla/MemoryReporting.h" 1.15 +#include "gfxTypes.h" 1.16 +#include "imgFrame.h" 1.17 + 1.18 +namespace mozilla { 1.19 +namespace image { 1.20 + 1.21 +/** 1.22 + * FrameDataPair is a slightly-smart tuple of (frame, raw frame data) where the 1.23 + * raw frame data is allowed to be (and is, initially) null. 1.24 + * 1.25 + * If you call LockAndGetData, you will be able to call GetFrameData() on that 1.26 + * instance, and when the FrameDataPair is destructed, the imgFrame lock will 1.27 + * be unlocked. 1.28 + */ 1.29 +class FrameDataPair 1.30 +{ 1.31 +public: 1.32 + explicit FrameDataPair(imgFrame* frame) 1.33 + : mFrame(frame) 1.34 + , mFrameData(nullptr) 1.35 + {} 1.36 + 1.37 + FrameDataPair() 1.38 + : mFrame(nullptr) 1.39 + , mFrameData(nullptr) 1.40 + {} 1.41 + 1.42 + FrameDataPair(FrameDataPair& other) 1.43 + { 1.44 + mFrame = other.mFrame; 1.45 + mFrameData = other.mFrameData; 1.46 + 1.47 + // since mFrame is an nsAutoPtr, the assignment operator above actually 1.48 + // nulls out other.mFrame. In order to fully assume ownership over the 1.49 + // frame, we also null out the other's mFrameData. 1.50 + other.mFrameData = nullptr; 1.51 + } 1.52 + 1.53 + ~FrameDataPair() 1.54 + { 1.55 + if (mFrameData) { 1.56 + mFrame->UnlockImageData(); 1.57 + } 1.58 + } 1.59 + 1.60 + // Lock the frame and store its mFrameData. The frame will be unlocked (and 1.61 + // deleted) when this FrameDataPair is deleted. 1.62 + void LockAndGetData() 1.63 + { 1.64 + if (mFrame) { 1.65 + if (NS_SUCCEEDED(mFrame->LockImageData())) { 1.66 + if (mFrame->GetIsPaletted()) { 1.67 + mFrameData = reinterpret_cast<uint8_t*>(mFrame->GetPaletteData()); 1.68 + } else { 1.69 + mFrameData = mFrame->GetImageData(); 1.70 + } 1.71 + } 1.72 + } 1.73 + } 1.74 + 1.75 + // Null out this FrameDataPair and return its frame. You must ensure the 1.76 + // frame will be deleted separately. 1.77 + imgFrame* Forget() 1.78 + { 1.79 + if (mFrameData) { 1.80 + mFrame->UnlockImageData(); 1.81 + } 1.82 + 1.83 + imgFrame* frame = mFrame.forget(); 1.84 + mFrameData = nullptr; 1.85 + return frame; 1.86 + } 1.87 + 1.88 + bool HasFrameData() const 1.89 + { 1.90 + if (mFrameData) { 1.91 + MOZ_ASSERT(!!mFrame); 1.92 + } 1.93 + return !!mFrameData; 1.94 + } 1.95 + 1.96 + uint8_t* GetFrameData() const 1.97 + { 1.98 + return mFrameData; 1.99 + } 1.100 + 1.101 + imgFrame* GetFrame() const 1.102 + { 1.103 + return mFrame; 1.104 + } 1.105 + 1.106 + // Resets this FrameDataPair to work with a different frame. Takes ownership 1.107 + // of the frame, deleting the old frame (if any). 1.108 + void SetFrame(imgFrame* frame) 1.109 + { 1.110 + if (mFrameData) { 1.111 + mFrame->UnlockImageData(); 1.112 + } 1.113 + 1.114 + mFrame = frame; 1.115 + mFrameData = nullptr; 1.116 + } 1.117 + 1.118 + operator imgFrame*() const 1.119 + { 1.120 + return GetFrame(); 1.121 + } 1.122 + 1.123 + imgFrame* operator->() const 1.124 + { 1.125 + return GetFrame(); 1.126 + } 1.127 + 1.128 + bool operator==(imgFrame* other) const 1.129 + { 1.130 + return mFrame == other; 1.131 + } 1.132 + 1.133 +private: 1.134 + nsAutoPtr<imgFrame> mFrame; 1.135 + uint8_t* mFrameData; 1.136 +}; 1.137 + 1.138 +/** 1.139 + * FrameSequence stores image frames (and their associated raw data pointers). 1.140 + * It is little more than a smart array. 1.141 + */ 1.142 +class FrameSequence 1.143 +{ 1.144 +public: 1.145 + 1.146 + ~FrameSequence(); 1.147 + 1.148 + NS_INLINE_DECL_THREADSAFE_REFCOUNTING(FrameSequence) 1.149 + 1.150 + /** 1.151 + * Get the read-only (frame, data) pair at index aIndex. 1.152 + */ 1.153 + const FrameDataPair& GetFrame(uint32_t aIndex) const; 1.154 + 1.155 + /** 1.156 + * Insert a frame into the array. FrameSequence takes ownership of the frame. 1.157 + */ 1.158 + void InsertFrame(uint32_t framenum, imgFrame* aFrame); 1.159 + 1.160 + /** 1.161 + * Remove (and delete) the frame at index framenum. 1.162 + */ 1.163 + void RemoveFrame(uint32_t framenum); 1.164 + 1.165 + /** 1.166 + * Swap aFrame with the frame at sequence framenum, and return that frame. 1.167 + * You take ownership over the frame returned. 1.168 + */ 1.169 + imgFrame* SwapFrame(uint32_t framenum, imgFrame* aFrame); 1.170 + 1.171 + /** 1.172 + * Remove (and delete) all frames. 1.173 + */ 1.174 + void ClearFrames(); 1.175 + 1.176 + /* The total number of frames in this image. */ 1.177 + uint32_t GetNumFrames() const; 1.178 + 1.179 + size_t SizeOfDecodedWithComputedFallbackIfHeap(gfxMemoryLocation aLocation, 1.180 + mozilla::MallocSizeOf aMallocSizeOf) const; 1.181 + 1.182 +private: // data 1.183 + //! All the frames of the image 1.184 + nsTArray<FrameDataPair> mFrames; 1.185 +}; 1.186 + 1.187 +} // namespace image 1.188 +} // namespace mozilla 1.189 + 1.190 +#endif /* mozilla_imagelib_FrameSequence_h_ */