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