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