/src/mozilla-central/image/decoders/nsPNGDecoder.h
Line | Count | Source (jump to first uncovered line) |
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_image_decoders_nsPNGDecoder_h |
8 | | #define mozilla_image_decoders_nsPNGDecoder_h |
9 | | |
10 | | #include "Decoder.h" |
11 | | #include "png.h" |
12 | | #include "qcms.h" |
13 | | #include "StreamingLexer.h" |
14 | | #include "SurfacePipe.h" |
15 | | |
16 | | namespace mozilla { |
17 | | namespace image { |
18 | | class RasterImage; |
19 | | |
20 | | class nsPNGDecoder : public Decoder |
21 | | { |
22 | | public: |
23 | | virtual ~nsPNGDecoder(); |
24 | | |
25 | | /// @return true if this PNG is a valid ICO resource. |
26 | | bool IsValidICOResource() const override; |
27 | | |
28 | 0 | DecoderType GetType() const override { return DecoderType::PNG; } |
29 | | |
30 | | protected: |
31 | | nsresult InitInternal() override; |
32 | | nsresult FinishInternal() override; |
33 | | LexerResult DoDecode(SourceBufferIterator& aIterator, |
34 | | IResumable* aOnResume) override; |
35 | | |
36 | | Maybe<Telemetry::HistogramID> SpeedHistogram() const override; |
37 | | |
38 | | private: |
39 | | friend class DecoderFactory; |
40 | | |
41 | | // Decoders should only be instantiated via DecoderFactory. |
42 | | explicit nsPNGDecoder(RasterImage* aImage); |
43 | | |
44 | | /// The information necessary to create a frame. |
45 | | struct FrameInfo |
46 | | { |
47 | | gfx::IntRect mFrameRect; |
48 | | bool mIsInterlaced; |
49 | | }; |
50 | | |
51 | | nsresult CreateFrame(const FrameInfo& aFrameInfo); |
52 | | void EndImageFrame(); |
53 | | |
54 | | bool HasAlphaChannel() const |
55 | 0 | { |
56 | 0 | return mChannels == 2 || mChannels == 4; |
57 | 0 | } |
58 | | |
59 | | enum class TransparencyType |
60 | | { |
61 | | eNone, |
62 | | eAlpha, |
63 | | eFrameRect |
64 | | }; |
65 | | |
66 | | TransparencyType GetTransparencyType(const gfx::IntRect& aFrameRect); |
67 | | void PostHasTransparencyIfNeeded(TransparencyType aTransparencyType); |
68 | | |
69 | | void PostInvalidationIfNeeded(); |
70 | | |
71 | | void WriteRow(uint8_t* aRow); |
72 | | |
73 | | // Convenience methods to make interacting with StreamingLexer from inside |
74 | | // a libpng callback easier. |
75 | | void DoTerminate(png_structp aPNGStruct, TerminalState aState); |
76 | | void DoYield(png_structp aPNGStruct); |
77 | | |
78 | | enum class State |
79 | | { |
80 | | PNG_DATA, |
81 | | FINISHED_PNG_DATA |
82 | | }; |
83 | | |
84 | | LexerTransition<State> ReadPNGData(const char* aData, size_t aLength); |
85 | | LexerTransition<State> FinishedPNGData(); |
86 | | |
87 | | StreamingLexer<State> mLexer; |
88 | | |
89 | | // The next lexer state transition. We need to store it here because we can't |
90 | | // directly return arbitrary values from libpng callbacks. |
91 | | LexerTransition<State> mNextTransition; |
92 | | |
93 | | // We yield to the caller every time we finish decoding a frame. When this |
94 | | // happens, we need to allocate the next frame after returning from the yield. |
95 | | // |mNextFrameInfo| is used to store the information needed to allocate the |
96 | | // next frame. |
97 | | Maybe<FrameInfo> mNextFrameInfo; |
98 | | |
99 | | // The length of the last chunk of data passed to ReadPNGData(). We use this |
100 | | // to arrange to arrive back at the correct spot in the data after yielding. |
101 | | size_t mLastChunkLength; |
102 | | |
103 | | public: |
104 | | png_structp mPNG; |
105 | | png_infop mInfo; |
106 | | nsIntRect mFrameRect; |
107 | | uint8_t* mCMSLine; |
108 | | uint8_t* interlacebuf; |
109 | | qcms_profile* mInProfile; |
110 | | qcms_transform* mTransform; |
111 | | gfx::SurfaceFormat mFormat; |
112 | | |
113 | | // whether CMS or premultiplied alpha are forced off |
114 | | uint32_t mCMSMode; |
115 | | |
116 | | uint8_t mChannels; |
117 | | uint8_t mPass; |
118 | | bool mFrameIsHidden; |
119 | | bool mDisablePremultipliedAlpha; |
120 | | |
121 | | struct AnimFrameInfo |
122 | | { |
123 | | AnimFrameInfo(); |
124 | | #ifdef PNG_APNG_SUPPORTED |
125 | | AnimFrameInfo(png_structp aPNG, png_infop aInfo); |
126 | | #endif |
127 | | |
128 | | DisposalMethod mDispose; |
129 | | BlendMethod mBlend; |
130 | | int32_t mTimeout; |
131 | | }; |
132 | | |
133 | | AnimFrameInfo mAnimInfo; |
134 | | |
135 | | SurfacePipe mPipe; /// The SurfacePipe used to write to the output surface. |
136 | | |
137 | | // The number of frames we've finished. |
138 | | uint32_t mNumFrames; |
139 | | |
140 | | // libpng callbacks |
141 | | // We put these in the class so that they can access protected members. |
142 | | static void PNGAPI info_callback(png_structp png_ptr, png_infop info_ptr); |
143 | | static void PNGAPI row_callback(png_structp png_ptr, png_bytep new_row, |
144 | | png_uint_32 row_num, int pass); |
145 | | #ifdef PNG_APNG_SUPPORTED |
146 | | static void PNGAPI frame_info_callback(png_structp png_ptr, |
147 | | png_uint_32 frame_num); |
148 | | #endif |
149 | | static void PNGAPI end_callback(png_structp png_ptr, png_infop info_ptr); |
150 | | static void PNGAPI error_callback(png_structp png_ptr, |
151 | | png_const_charp error_msg); |
152 | | static void PNGAPI warning_callback(png_structp png_ptr, |
153 | | png_const_charp warning_msg); |
154 | | |
155 | | // This is defined in the PNG spec as an invariant. We use it to |
156 | | // do manual validation without libpng. |
157 | | static const uint8_t pngSignatureBytes[]; |
158 | | }; |
159 | | |
160 | | } // namespace image |
161 | | } // namespace mozilla |
162 | | |
163 | | #endif // mozilla_image_decoders_nsPNGDecoder_h |