Line data Source code
1 : /* vim:set tw=80 expandtab softtabstop=4 ts=4 sw=4: */
2 : /* This Source Code Form is subject to the terms of the Mozilla Public
3 : * License, v. 2.0. If a copy of the MPL was not distributed with this
4 : * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
5 :
6 :
7 : #ifndef mozilla_image_decoders_nsICODecoder_h
8 : #define mozilla_image_decoders_nsICODecoder_h
9 :
10 : #include "StreamingLexer.h"
11 : #include "Decoder.h"
12 : #include "imgFrame.h"
13 : #include "mozilla/gfx/2D.h"
14 : #include "nsBMPDecoder.h"
15 : #include "nsPNGDecoder.h"
16 : #include "ICOFileHeaders.h"
17 :
18 : namespace mozilla {
19 : namespace image {
20 :
21 : class RasterImage;
22 :
23 : enum class ICOState
24 : {
25 : HEADER,
26 : DIR_ENTRY,
27 : SKIP_TO_RESOURCE,
28 : FOUND_RESOURCE,
29 : SNIFF_RESOURCE,
30 : READ_PNG,
31 : READ_BIH,
32 : READ_BMP,
33 : PREPARE_FOR_MASK,
34 : READ_MASK_ROW,
35 : FINISH_MASK,
36 : SKIP_MASK,
37 : FINISHED_RESOURCE
38 : };
39 :
40 : class nsICODecoder : public Decoder
41 : {
42 : public:
43 0 : virtual ~nsICODecoder() { }
44 :
45 : /// @return the width of the icon directory entry @aEntry.
46 0 : static uint32_t GetRealWidth(const IconDirEntry& aEntry)
47 : {
48 0 : return aEntry.mWidth == 0 ? 256 : aEntry.mWidth;
49 : }
50 :
51 : /// @return the width of the selected directory entry (mDirEntry).
52 0 : uint32_t GetRealWidth() const { return GetRealWidth(mDirEntry); }
53 :
54 : /// @return the height of the icon directory entry @aEntry.
55 0 : static uint32_t GetRealHeight(const IconDirEntry& aEntry)
56 : {
57 0 : return aEntry.mHeight == 0 ? 256 : aEntry.mHeight;
58 : }
59 :
60 : /// @return the height of the selected directory entry (mDirEntry).
61 0 : uint32_t GetRealHeight() const { return GetRealHeight(mDirEntry); }
62 :
63 : /// @return the size of the selected directory entry (mDirEntry).
64 0 : gfx::IntSize GetRealSize() const
65 : {
66 0 : return gfx::IntSize(GetRealWidth(), GetRealHeight());
67 : }
68 :
69 : /// @return The offset from the beginning of the ICO to the first resource.
70 : size_t FirstResourceOffset() const;
71 :
72 : LexerResult DoDecode(SourceBufferIterator& aIterator,
73 : IResumable* aOnResume) override;
74 : nsresult FinishInternal() override;
75 : nsresult FinishWithErrorInternal() override;
76 :
77 : private:
78 : friend class DecoderFactory;
79 :
80 : // Decoders should only be instantiated via DecoderFactory.
81 : explicit nsICODecoder(RasterImage* aImage);
82 :
83 : // Writes to the contained decoder and sets the appropriate errors
84 : // Returns true if there are no errors.
85 : bool WriteToContainedDecoder(const char* aBuffer, uint32_t aCount);
86 :
87 : // Gets decoder state from the contained decoder so it's visible externally.
88 : nsresult GetFinalStateFromContainedDecoder();
89 :
90 : /**
91 : * Verifies that the width and height values in @aBIH are valid and match the
92 : * values we read from the ICO directory entry. If everything looks OK, the
93 : * height value in @aBIH is updated to compensate for the AND mask, which the
94 : * underlying BMP decoder doesn't know about.
95 : *
96 : * @return true if the width and height values in @aBIH are valid and correct.
97 : */
98 : bool CheckAndFixBitmapSize(int8_t* aBIH);
99 :
100 : // Obtains the number of colors from the BPP, mBPP must be filled in
101 : uint16_t GetNumColors();
102 :
103 : LexerTransition<ICOState> ReadHeader(const char* aData);
104 : LexerTransition<ICOState> ReadDirEntry(const char* aData);
105 : LexerTransition<ICOState> SniffResource(const char* aData);
106 : LexerTransition<ICOState> ReadPNG(const char* aData, uint32_t aLen);
107 : LexerTransition<ICOState> ReadBIH(const char* aData);
108 : LexerTransition<ICOState> ReadBMP(const char* aData, uint32_t aLen);
109 : LexerTransition<ICOState> PrepareForMask();
110 : LexerTransition<ICOState> ReadMaskRow(const char* aData);
111 : LexerTransition<ICOState> FinishMask();
112 : LexerTransition<ICOState> FinishResource();
113 :
114 : StreamingLexer<ICOState, 32> mLexer; // The lexer.
115 : RefPtr<Decoder> mContainedDecoder; // Either a BMP or PNG decoder.
116 : RefPtr<SourceBuffer> mContainedSourceBuffer; // SourceBuffer for mContainedDecoder.
117 : UniquePtr<uint8_t[]> mMaskBuffer; // A temporary buffer for the alpha mask.
118 : char mBIHraw[bmp::InfoHeaderLength::WIN_ICO]; // The bitmap information header.
119 : IconDirEntry mDirEntry; // The dir entry for the selected resource.
120 : gfx::IntSize mBiggestResourceSize; // Used to select the intrinsic size.
121 : gfx::IntSize mBiggestResourceHotSpot; // Used to select the intrinsic size.
122 : uint16_t mBiggestResourceColorDepth; // Used to select the intrinsic size.
123 : int32_t mBestResourceDelta; // Used to select the best resource.
124 : uint16_t mBestResourceColorDepth; // Used to select the best resource.
125 : uint16_t mNumIcons; // Stores the number of icons in the ICO file.
126 : uint16_t mCurrIcon; // Stores the current dir entry index we are processing.
127 : uint16_t mBPP; // The BPP of the resource we're decoding.
128 : uint32_t mMaskRowSize; // The size in bytes of each row in the BMP alpha mask.
129 : uint32_t mCurrMaskLine; // The line of the BMP alpha mask we're processing.
130 : bool mIsCursor; // Is this ICO a cursor?
131 : bool mHasMaskAlpha; // Did the BMP alpha mask have any transparency?
132 : };
133 :
134 : } // namespace image
135 : } // namespace mozilla
136 :
137 : #endif // mozilla_image_decoders_nsICODecoder_h
|