1 /* This Source Code Form is subject to the terms of the Mozilla Public
2  * License, v. 2.0. If a copy of the MPL was not distributed with this
3  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
4 
5 #ifndef mozilla_image_encoders_ico_nsICOEncoder_h
6 #define mozilla_image_encoders_ico_nsICOEncoder_h
7 
8 #include "mozilla/Attributes.h"
9 #include "mozilla/ReentrantMonitor.h"
10 #include "mozilla/image/ICOFileHeaders.h"
11 
12 #include "imgIEncoder.h"
13 
14 #include "nsCOMPtr.h"
15 
16 #define NS_ICOENCODER_CID                            \
17   { /*92AE3AB2-8968-41B1-8709-B6123BCEAF21 */        \
18     0x92ae3ab2, 0x8968, 0x41b1, {                    \
19       0x87, 0x09, 0xb6, 0x12, 0x3b, 0Xce, 0xaf, 0x21 \
20     }                                                \
21   }
22 
23 // Provides ICO encoding functionality. Use InitFromData() to do the
24 // encoding. See that function definition for encoding options.
25 
26 class nsICOEncoder final : public imgIEncoder {
27   typedef mozilla::ReentrantMonitor ReentrantMonitor;
28 
29  public:
30   NS_DECL_THREADSAFE_ISUPPORTS
31   NS_DECL_IMGIENCODER
32   NS_DECL_NSIINPUTSTREAM
33   NS_DECL_NSIASYNCINPUTSTREAM
34 
35   nsICOEncoder();
36 
37   // Obtains the width of the icon directory entry
GetRealWidth()38   uint32_t GetRealWidth() const {
39     return mICODirEntry.mWidth == 0 ? 256 : mICODirEntry.mWidth;
40   }
41 
42   // Obtains the height of the icon directory entry
GetRealHeight()43   uint32_t GetRealHeight() const {
44     return mICODirEntry.mHeight == 0 ? 256 : mICODirEntry.mHeight;
45   }
46 
47  protected:
48   ~nsICOEncoder();
49 
50   nsresult ParseOptions(const nsAString& aOptions, uint16_t& aBppOut,
51                         bool& aUsePNGOut);
52   void NotifyListener();
53 
54   // Initializes the icon file header mICOFileHeader
55   void InitFileHeader();
56   // Initializes the icon directory info header mICODirEntry
57   void InitInfoHeader(uint16_t aBPP, uint8_t aWidth, uint8_t aHeight);
58   // Encodes the icon file header mICOFileHeader
59   void EncodeFileHeader();
60   // Encodes the icon directory info header mICODirEntry
61   void EncodeInfoHeader();
62   // Obtains the current offset filled up to for the image buffer
GetCurrentImageBufferOffset()63   inline int32_t GetCurrentImageBufferOffset() {
64     return static_cast<int32_t>(mImageBufferCurr - mImageBufferStart);
65   }
66 
67   // Holds either a PNG or a BMP depending on the encoding options specified
68   // or if no encoding options specified will use the default (PNG)
69   nsCOMPtr<imgIEncoder> mContainedEncoder;
70 
71   // These headers will always contain endian independent stuff.
72   // Don't trust the width and height of mICODirEntry directly,
73   // instead use the accessors GetRealWidth() and GetRealHeight().
74   mozilla::image::IconFileHeader mICOFileHeader;
75   mozilla::image::IconDirEntry mICODirEntry;
76 
77   // Keeps track of the start of the image buffer
78   uint8_t* mImageBufferStart;
79   // Keeps track of the current position in the image buffer
80   uint8_t* mImageBufferCurr;
81   // Keeps track of the image buffer size
82   uint32_t mImageBufferSize;
83   // Keeps track of the number of bytes in the image buffer which are read
84   uint32_t mImageBufferReadPoint;
85   // Stores true if the image is done being encoded
86   bool mFinished;
87   // Stores true if the contained image is a PNG
88   bool mUsePNG;
89 
90   nsCOMPtr<nsIInputStreamCallback> mCallback;
91   nsCOMPtr<nsIEventTarget> mCallbackTarget;
92   uint32_t mNotifyThreshold;
93 };
94 
95 #endif  // mozilla_image_encoders_ico_nsICOEncoder_h
96