• 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 "hilog/log.h"
21 #include "input_data_stream.h"
22 #include "log_tags.h"
23 #include "nine_patch_listener.h"
24 #include "plugin_class_base.h"
25 #include "png.h"
26 
27 namespace OHOS {
28 namespace ImagePlugin {
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, PlSize &size) override;
60     bool HasProperty(std::string key) override;
61 
62 private:
63     uint32_t GetDecodeFormat(PlPixelFormat format, PlPixelFormat &outputFormat, PlAlphaType &alphaType);
64     void ChooseFormat(PlPixelFormat format, PlPixelFormat &outputFormat, png_byte destType);
65     static void PngErrorExit(png_structp pngPtr, png_const_charp message);
66     static void PngWarning(png_structp pngPtr, png_const_charp message);
67     static void PngWarningMessage(png_structp pngPtr, png_const_charp message);
68     static void PngErrorMessage(png_structp pngPtr, png_const_charp message);
69     // incremental private interface
70     uint32_t PushCurrentToDecode(InputDataStream *stream);
71     uint32_t IncrementalReadRows(InputDataStream *stream);
72     uint32_t PushAllToDecode(InputDataStream *stream, size_t bufferSize, size_t length);
73     static void GetAllRows(png_structp pngPtr, png_bytep row, png_uint_32 rowNum, int pass);
74     static void GetInterlacedRows(png_structp pngPtr, png_bytep row, png_uint_32 rowNum, int pass);
75     static int32_t ReadUserChunk(png_structp png_ptr, png_unknown_chunkp chunk);
76     void SaveRows(png_bytep row, png_uint_32 rowNum);
77     void SaveInterlacedRows(png_bytep row, png_uint_32 rowNum, int pass);
78     uint32_t ReadIncrementalHead(InputDataStream *stream, PngImageInfo &info);
79     bool GetImageInfo(PngImageInfo &info);
80     bool IsChunk(const png_byte *chunk, const char *flag);
81     uint32_t ProcessData(png_structp pngPtr, png_infop infoPtr, InputDataStream *sourceStream,
82                          DataStreamBuffer streamData, size_t bufferSize, size_t totalSize);
83     bool ConvertOriginalFormat(png_byte source, png_byte &destination);
84     uint8_t *AllocOutputHeapBuffer(DecodeContext &context);
85     uint32_t IncrementalRead(InputDataStream *stream, uint32_t desiredSize, DataStreamBuffer &outData);
86     uint32_t DecodeHeader();
87     uint32_t ConfigInfo(const PixelDecodeOptions &opts);
88     uint32_t DoOneTimeDecode(DecodeContext &context);
89     bool FinishOldDecompress();
90     bool InitPnglib();
91     uint32_t GetImageIdatSize(InputDataStream *stream);
92     void DealNinePatch(const PixelDecodeOptions &opts);
93     // local private parameter
94     const std::string NINE_PATCH = "ninepatch";
95     png_structp pngStructPtr_ = nullptr;
96     png_infop pngInfoPtr_ = nullptr;
97     InputDataStream *inputStreamPtr_ = nullptr;
98     PngImageInfo pngImageInfo_;
99     bool decodedIdat_ = false;
100     size_t idatLength_ = 0;
101     size_t incrementalLength_ = 0;
102     uint8_t *pixelsData_ = nullptr;
103     uint32_t outputRowsNum_ = 0;
104     PngDecodingState state_ = PngDecodingState::UNDECIDED;
105     uint32_t streamPosition_ = 0;  // may be changed by other decoders, record it and restore if needed.
106     PlPixelFormat outputFormat_ = PlPixelFormat::UNKNOWN;
107     PlAlphaType alphaType_ = PlAlphaType::IMAGE_ALPHA_TYPE_UNKNOWN;
108     PixelDecodeOptions opts_;
109     bool decodeHeadFlag_ = false;
110     uint32_t firstRow_ = 0;
111     uint32_t lastRow_ = 0;
112     bool interlacedComplete_ = false;
113     NinePatchListener ninePatch_;
114 };
115 } // namespace ImagePlugin
116 } // namespace OHOS
117 
118 #endif // PNG_DECODER_H
119