michael@0: /* This Source Code Form is subject to the terms of the Mozilla Public michael@0: * License, v. 2.0. If a copy of the MPL was not distributed with this michael@0: * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ michael@0: michael@0: #include "mozilla/Attributes.h" michael@0: #include "mozilla/ReentrantMonitor.h" michael@0: michael@0: #include "imgIEncoder.h" michael@0: michael@0: #include "nsAutoPtr.h" michael@0: #include "nsCOMPtr.h" michael@0: #include "ICOFileHeaders.h" michael@0: michael@0: class nsBMPEncoder; michael@0: class nsPNGEncoder; michael@0: michael@0: #define NS_ICOENCODER_CID \ michael@0: { /*92AE3AB2-8968-41B1-8709-B6123BCEAF21 */ \ michael@0: 0x92ae3ab2, \ michael@0: 0x8968, \ michael@0: 0x41b1, \ michael@0: {0x87, 0x09, 0xb6, 0x12, 0x3b, 0Xce, 0xaf, 0x21} \ michael@0: } michael@0: michael@0: // Provides ICO encoding functionality. Use InitFromData() to do the michael@0: // encoding. See that function definition for encoding options. michael@0: michael@0: class nsICOEncoder MOZ_FINAL : public imgIEncoder michael@0: { michael@0: typedef mozilla::ReentrantMonitor ReentrantMonitor; michael@0: public: michael@0: NS_DECL_THREADSAFE_ISUPPORTS michael@0: NS_DECL_IMGIENCODER michael@0: NS_DECL_NSIINPUTSTREAM michael@0: NS_DECL_NSIASYNCINPUTSTREAM michael@0: michael@0: nsICOEncoder(); michael@0: ~nsICOEncoder(); michael@0: michael@0: // Obtains the width of the icon directory entry michael@0: uint32_t GetRealWidth() const michael@0: { michael@0: return mICODirEntry.mWidth == 0 ? 256 : mICODirEntry.mWidth; michael@0: } michael@0: michael@0: // Obtains the height of the icon directory entry michael@0: uint32_t GetRealHeight() const michael@0: { michael@0: return mICODirEntry.mHeight == 0 ? 256 : mICODirEntry.mHeight; michael@0: } michael@0: michael@0: protected: michael@0: nsresult ParseOptions(const nsAString& aOptions, uint32_t* bpp, michael@0: bool *usePNG); michael@0: void NotifyListener(); michael@0: michael@0: // Initializes the icon file header mICOFileHeader michael@0: void InitFileHeader(); michael@0: // Initializes the icon directory info header mICODirEntry michael@0: void InitInfoHeader(uint32_t aBPP, uint8_t aWidth, uint8_t aHeight); michael@0: // Encodes the icon file header mICOFileHeader michael@0: void EncodeFileHeader(); michael@0: // Encodes the icon directory info header mICODirEntry michael@0: void EncodeInfoHeader(); michael@0: // Obtains the current offset filled up to for the image buffer michael@0: inline int32_t GetCurrentImageBufferOffset() michael@0: { michael@0: return static_cast(mImageBufferCurr - mImageBufferStart); michael@0: } michael@0: michael@0: // Holds either a PNG or a BMP depending on the encoding options specified michael@0: // or if no encoding options specified will use the default (PNG) michael@0: nsCOMPtr mContainedEncoder; michael@0: michael@0: // These headers will always contain endian independent stuff. michael@0: // Don't trust the width and height of mICODirEntry directly, michael@0: // instead use the accessors GetRealWidth() and GetRealHeight(). michael@0: mozilla::image::IconFileHeader mICOFileHeader; michael@0: mozilla::image::IconDirEntry mICODirEntry; michael@0: michael@0: // Keeps track of the start of the image buffer michael@0: uint8_t* mImageBufferStart; michael@0: // Keeps track of the current position in the image buffer michael@0: uint8_t* mImageBufferCurr; michael@0: // Keeps track of the image buffer size michael@0: uint32_t mImageBufferSize; michael@0: // Keeps track of the number of bytes in the image buffer which are read michael@0: uint32_t mImageBufferReadPoint; michael@0: // Stores true if the image is done being encoded michael@0: bool mFinished; michael@0: // Stores true if the contained image is a PNG michael@0: bool mUsePNG; michael@0: michael@0: nsCOMPtr mCallback; michael@0: nsCOMPtr mCallbackTarget; michael@0: uint32_t mNotifyThreshold; michael@0: };