• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2021 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #ifndef PNG_DECODER_H
17 #define PNG_DECODER_H
18 
19 #include "abs_image_decoder.h"
20 #include "input_data_stream.h"
21 #include "nine_patch_listener.h"
22 #include "plugin_class_base.h"
23 #include "png.h"
24 
25 namespace OHOS {
26 namespace ImagePlugin {
27 using namespace Media;
28 
29 enum class PngDecodingState : int32_t {
30     UNDECIDED = 0,
31     SOURCE_INITED = 1,
32     BASE_INFO_PARSING = 2,
33     BASE_INFO_PARSED = 3,
34     IMAGE_DECODING = 4,
35     IMAGE_ERROR = 5,
36     IMAGE_PARTIAL = 6,
37     IMAGE_DECODED = 7
38 };
39 
40 struct PngImageInfo {
41     uint32_t width = 0;
42     uint32_t height = 0;
43     uint8_t bitDepth = 0;
44     uint32_t rowDataSize = 0;
45     int32_t numberPasses = 0;  // interlace is 7 otherwise is 1.
46 };
47 
48 class PngDecoder : public AbsImageDecoder, public OHOS::MultimediaPlugin::PluginClassBase {
49 public:
50     PngDecoder();
51     ~PngDecoder() override;
52     PngDecoder(const PngDecoder &) = delete;
53     PngDecoder &operator=(const PngDecoder &) = delete;
54     void SetSource(InputDataStream &sourceStream) override;
55     void Reset() override;
56     uint32_t SetDecodeOptions(uint32_t index, const PixelDecodeOptions &opts, PlImageInfo &info) override;
57     uint32_t Decode(uint32_t index, DecodeContext &context) override;
58     uint32_t PromoteIncrementalDecode(uint32_t index, ProgDecodeContext &context) override;
59     uint32_t GetImageSize(uint32_t index, Size &size) override;
60     bool HasProperty(std::string key) override;
GetPluginType()61     std::string GetPluginType() override
62     {
63         return "png";
64     }
65 #ifdef IMAGE_COLORSPACE_FLAG
IsSupportICCProfile()66     bool IsSupportICCProfile() override
67     {
68         return false;
69     }
70 #endif
71 
72 private:
73     uint32_t GetDecodeFormat(PixelFormat format, PixelFormat &outputFormat, AlphaType &alphaType);
74     bool ChooseFormat(PixelFormat format, PixelFormat &outputFormat, png_byte destType);
75     static void PngErrorExit(png_structp pngPtr, png_const_charp message);
76     static void PngWarning(png_structp pngPtr, png_const_charp message);
77     static void PngWarningMessage(png_structp pngPtr, png_const_charp message);
78     static void PngErrorMessage(png_structp pngPtr, png_const_charp message);
79     // incremental private interface
80     uint32_t PushCurrentToDecode(InputDataStream *stream);
81     uint32_t IncrementalReadRows(InputDataStream *stream);
82     uint32_t PushAllToDecode(InputDataStream *stream, size_t bufferSize, size_t length);
83     static void GetAllRows(png_structp pngPtr, png_bytep row, png_uint_32 rowNum, int pass);
84     static void GetInterlacedRows(png_structp pngPtr, png_bytep row, png_uint_32 rowNum, int pass);
85     static int32_t ReadUserChunk(png_structp png_ptr, png_unknown_chunkp chunk);
86     void SaveRows(png_bytep row, png_uint_32 rowNum);
87     void SaveInterlacedRows(png_bytep row, png_uint_32 rowNum, int pass);
88     uint32_t ReadIncrementalHead(InputDataStream *stream, PngImageInfo &info);
89     bool GetImageInfo(PngImageInfo &info);
90     bool IsChunk(const png_byte *chunk, const char *flag);
91     uint32_t ProcessData(png_structp pngPtr, png_infop infoPtr, InputDataStream *sourceStream,
92                          DataStreamBuffer streamData, size_t bufferSize, size_t totalSize);
93     bool ConvertOriginalFormat(png_byte source, png_byte &destination);
94     uint8_t *AllocOutputBuffer(DecodeContext &context);
95     uint32_t IncrementalRead(InputDataStream *stream, uint32_t desiredSize, DataStreamBuffer &outData);
96     uint32_t DecodeHeader();
97     uint32_t ConfigInfo(const PixelDecodeOptions &opts);
98     uint32_t DoOneTimeDecode(DecodeContext &context);
99     bool FinishOldDecompress();
100     bool InitPnglib();
101     uint32_t GetImageIdatSize(InputDataStream *stream);
102     void DealNinePatch(const PixelDecodeOptions &opts);
103     // local private parameter
104     const std::string NINE_PATCH = "ninepatch";
105     png_structp pngStructPtr_ = nullptr;
106     png_infop pngInfoPtr_ = nullptr;
107     InputDataStream *inputStreamPtr_ = nullptr;
108     PngImageInfo pngImageInfo_;
109     bool decodedIdat_ = false;
110     size_t idatLength_ = 0;
111     size_t incrementalLength_ = 0;
112     uint8_t *pixelsData_ = nullptr;
113     uint32_t outputRowsNum_ = 0;
114     PngDecodingState state_ = PngDecodingState::UNDECIDED;
115     uint32_t streamPosition_ = 0;  // may be changed by other decoders, record it and restore if needed.
116     PixelFormat outputFormat_ = PixelFormat::UNKNOWN;
117     AlphaType alphaType_ = AlphaType::IMAGE_ALPHA_TYPE_UNKNOWN;
118     PixelDecodeOptions opts_;
119     bool decodeHeadFlag_ = false;
120     uint32_t firstRow_ = 0;
121     uint32_t lastRow_ = 0;
122     bool interlacedComplete_ = false;
123     NinePatchListener ninePatch_;
124 };
125 } // namespace ImagePlugin
126 } // namespace OHOS
127 
128 #endif // PNG_DECODER_H
129