no bug - Bumping Firefox l10n changesets r=release a=l10n-bump DONTBUILD CLOSED TREE
[gecko.git] / image / decoders / nsPNGDecoder.h
blob4627302b873fba2e6195cdc639a9a708a572f978
1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 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/. */
7 #ifndef mozilla_image_decoders_nsPNGDecoder_h
8 #define mozilla_image_decoders_nsPNGDecoder_h
10 #include "Decoder.h"
11 #include "png.h"
12 #include "StreamingLexer.h"
13 #include "SurfacePipe.h"
14 #include "mozilla/gfx/Swizzle.h"
16 namespace mozilla {
17 namespace image {
18 class RasterImage;
20 class nsPNGDecoder : public Decoder {
21 public:
22 virtual ~nsPNGDecoder();
24 /// @return true if this PNG is a valid ICO resource.
25 bool IsValidICOResource() const override;
27 DecoderType GetType() const override { return DecoderType::PNG; }
29 protected:
30 nsresult InitInternal() override;
31 nsresult FinishInternal() override;
32 LexerResult DoDecode(SourceBufferIterator& aIterator,
33 IResumable* aOnResume) override;
35 Maybe<Telemetry::HistogramID> SpeedHistogram() const override;
37 private:
38 friend class DecoderFactory;
40 // Decoders should only be instantiated via DecoderFactory.
41 explicit nsPNGDecoder(RasterImage* aImage);
43 /// The information necessary to create a frame.
44 struct FrameInfo {
45 OrientedIntRect mFrameRect;
46 bool mIsInterlaced;
49 nsresult CreateFrame(const FrameInfo& aFrameInfo);
50 void EndImageFrame();
52 uint32_t ReadColorProfile(png_structp png_ptr, png_infop info_ptr,
53 int color_type, bool* sRGBTag);
55 bool HasAlphaChannel() const { return mChannels == 2 || mChannels == 4; }
57 enum class TransparencyType { eNone, eAlpha, eFrameRect };
59 TransparencyType GetTransparencyType(const OrientedIntRect& aFrameRect);
60 void PostHasTransparencyIfNeeded(TransparencyType aTransparencyType);
62 void PostInvalidationIfNeeded();
64 void WriteRow(uint8_t* aRow);
66 // Convenience methods to make interacting with StreamingLexer from inside
67 // a libpng callback easier.
68 void DoTerminate(png_structp aPNGStruct, TerminalState aState);
69 void DoYield(png_structp aPNGStruct);
71 enum class State { PNG_DATA, FINISHED_PNG_DATA };
73 LexerTransition<State> ReadPNGData(const char* aData, size_t aLength);
74 LexerTransition<State> FinishedPNGData();
76 StreamingLexer<State> mLexer;
78 // The next lexer state transition. We need to store it here because we can't
79 // directly return arbitrary values from libpng callbacks.
80 LexerTransition<State> mNextTransition;
82 // We yield to the caller every time we finish decoding a frame. When this
83 // happens, we need to allocate the next frame after returning from the yield.
84 // |mNextFrameInfo| is used to store the information needed to allocate the
85 // next frame.
86 Maybe<FrameInfo> mNextFrameInfo;
88 // The length of the last chunk of data passed to ReadPNGData(). We use this
89 // to arrange to arrive back at the correct spot in the data after yielding.
90 size_t mLastChunkLength;
92 public:
93 png_structp mPNG;
94 png_infop mInfo;
95 OrientedIntRect mFrameRect;
96 uint8_t* mCMSLine;
97 uint8_t* interlacebuf;
98 gfx::SurfaceFormat mFormat;
100 uint8_t mChannels;
101 uint8_t mPass;
102 bool mFrameIsHidden;
103 bool mDisablePremultipliedAlpha;
104 bool mGotInfoCallback;
105 bool mUsePipeTransform;
106 bool mErrorIsRecoverable;
108 struct AnimFrameInfo {
109 AnimFrameInfo();
110 #ifdef PNG_APNG_SUPPORTED
111 AnimFrameInfo(png_structp aPNG, png_infop aInfo);
112 #endif
114 DisposalMethod mDispose;
115 BlendMethod mBlend;
116 int32_t mTimeout;
119 AnimFrameInfo mAnimInfo;
121 SurfacePipe mPipe; /// The SurfacePipe used to write to the output surface.
123 // The number of frames we've finished.
124 uint32_t mNumFrames;
126 // libpng callbacks
127 // We put these in the class so that they can access protected members.
128 static void PNGAPI info_callback(png_structp png_ptr, png_infop info_ptr);
129 static void PNGAPI row_callback(png_structp png_ptr, png_bytep new_row,
130 png_uint_32 row_num, int pass);
131 #ifdef PNG_APNG_SUPPORTED
132 static void PNGAPI frame_info_callback(png_structp png_ptr,
133 png_uint_32 frame_num);
134 #endif
135 static void PNGAPI end_callback(png_structp png_ptr, png_infop info_ptr);
136 static void PNGAPI error_callback(png_structp png_ptr,
137 png_const_charp error_msg);
138 static void PNGAPI warning_callback(png_structp png_ptr,
139 png_const_charp warning_msg);
141 // This is defined in the PNG spec as an invariant. We use it to
142 // do manual validation without libpng.
143 static const uint8_t pngSignatureBytes[];
146 } // namespace image
147 } // namespace mozilla
149 #endif // mozilla_image_decoders_nsPNGDecoder_h