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