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
12 #include "StreamingLexer.h"
13 #include "SurfacePipe.h"
14 #include "mozilla/gfx/Swizzle.h"
20 class nsPNGDecoder
: public Decoder
{
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
; }
30 nsresult
InitInternal() override
;
31 nsresult
FinishInternal() override
;
32 LexerResult
DoDecode(SourceBufferIterator
& aIterator
,
33 IResumable
* aOnResume
) override
;
35 Maybe
<glean::impl::MemoryDistributionMetric
> SpeedMetric() const override
;
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.
45 OrientedIntRect mFrameRect
;
49 nsresult
CreateFrame(const FrameInfo
& aFrameInfo
);
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
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
;
95 OrientedIntRect mFrameRect
;
97 uint8_t* interlacebuf
;
98 gfx::SurfaceFormat mFormat
;
103 bool mDisablePremultipliedAlpha
;
104 bool mGotInfoCallback
;
105 bool mUsePipeTransform
;
106 bool mErrorIsRecoverable
;
108 struct AnimFrameInfo
{
110 #ifdef PNG_APNG_SUPPORTED
111 AnimFrameInfo(png_structp aPNG
, png_infop aInfo
);
114 DisposalMethod mDispose
;
119 AnimFrameInfo mAnimInfo
;
121 SurfacePipe mPipe
; /// The SurfacePipe used to write to the output surface.
123 // The number of frames we've finished.
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
);
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
[];
147 } // namespace mozilla
149 #endif // mozilla_image_decoders_nsPNGDecoder_h