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 IMAGE_SOURCE_H 17 #define IMAGE_SOURCE_H 18 19 #include <cstdint> 20 #include <iostream> 21 #include <map> 22 #include <memory> 23 #include <mutex> 24 #include <set> 25 26 #include "decode_listener.h" 27 #include "image_type.h" 28 #include "incremental_pixel_map.h" 29 #include "peer_listener.h" 30 #include "pixel_map.h" 31 32 namespace OHOS { 33 namespace MultimediaPlugin { 34 constexpr float EPSILON = 1e-6; 35 36 class PluginServer; 37 } // namespace MultimediaPlugin 38 } // namespace OHOS 39 40 namespace OHOS { 41 namespace ImagePlugin { 42 class AbsImageFormatAgent; 43 class AbsImageDecoder; 44 struct PixelDecodeOptions; 45 struct PlImageInfo; 46 } // namespace ImagePlugin 47 } // namespace OHOS 48 49 namespace OHOS { 50 namespace Media { 51 struct SourceOptions { 52 std::string formatHint; 53 int32_t baseDensity = 0; 54 }; 55 56 struct IncrementalSourceOptions { 57 SourceOptions sourceOptions; 58 IncrementalMode incrementalMode = IncrementalMode::FULL_DATA; 59 }; 60 61 struct NinePatchInfo { 62 void *ninePatch = nullptr; 63 size_t patchSize = 0; 64 }; 65 66 enum class DecodeEvent : int32_t { 67 EVENT_COMPLETE_DECODE = 0, 68 EVENT_PARTIAL_DECODE = 1, 69 EVENT_HEADER_DECODE = 2, 70 EVENT_LAST = 3 71 }; 72 73 enum class ImageDecodingState : int32_t { 74 UNRESOLVED = 0, 75 BASE_INFO_ERROR = 1, 76 BASE_INFO_PARSED = 2, 77 IMAGE_DECODING = 3, 78 IMAGE_ERROR = 4, 79 PARTIAL_IMAGE = 5, 80 IMAGE_DECODED = 6 81 }; 82 83 enum class SourceDecodingState : int32_t { 84 UNRESOLVED = 0, 85 SOURCE_ERROR = 1, 86 UNKNOWN_FORMAT = 2, 87 FORMAT_RECOGNIZED = 3, 88 UNSUPPORTED_FORMAT = 4, 89 FILE_INFO_ERROR = 5, 90 FILE_INFO_DECODED = 6, 91 IMAGE_DECODING = 7, 92 ALL_IMAGES_ERROR = 8 93 }; 94 95 enum class SourceInfoState : int32_t { 96 SOURCE_ERROR = 0, 97 SOURCE_INCOMPLETE = 1, 98 UNKNOWN_FORMAT = 2, 99 UNSUPPORTED_FORMAT = 3, 100 FILE_INFO_ERROR = 4, 101 FILE_INFO_PARSED = 5 102 }; 103 104 struct ImageDecodingStatus { 105 ImageInfo imageInfo; 106 ImageDecodingState imageState = ImageDecodingState::UNRESOLVED; 107 }; 108 109 struct SourceInfo { 110 int32_t baseDensity = 0; 111 uint32_t topLevelImageNum = 0; 112 std::string encodedFormat; 113 SourceInfoState state = SourceInfoState::SOURCE_ERROR; 114 }; 115 116 struct IncrementalDecodingContext { 117 std::unique_ptr<ImagePlugin::AbsImageDecoder> decoder; 118 ImageDecodingState IncrementalState = ImageDecodingState::UNRESOLVED; 119 uint8_t decodingProgress = 0; 120 }; 121 122 class SourceStream; 123 124 class ImageSource { 125 public: 126 ~ImageSource(); 127 NATIVEEXPORT static uint32_t GetSupportedFormats(std::set<std::string> &formats); 128 NATIVEEXPORT static std::unique_ptr<ImageSource> CreateImageSource(std::unique_ptr<std::istream> is, 129 const SourceOptions &opts, uint32_t &errorCode); 130 NATIVEEXPORT static std::unique_ptr<ImageSource> CreateImageSource(const uint8_t *data, uint32_t size, 131 const SourceOptions &opts, uint32_t &errorCode); 132 NATIVEEXPORT static std::unique_ptr<ImageSource> CreateImageSource(const std::string &pathName, 133 const SourceOptions &opts, uint32_t &errorCode); 134 NATIVEEXPORT static std::unique_ptr<ImageSource> CreateImageSource(const int fd, const SourceOptions &opts, 135 uint32_t &errorCode); 136 NATIVEEXPORT static std::unique_ptr<ImageSource> CreateIncrementalImageSource(const IncrementalSourceOptions &opts, 137 uint32_t &errorCode); 138 CreatePixelMap(const DecodeOptions & opts,uint32_t & errorCode)139 NATIVEEXPORT std::unique_ptr<PixelMap> CreatePixelMap(const DecodeOptions &opts, uint32_t &errorCode) 140 { 141 return CreatePixelMap(0, opts, errorCode); 142 } 143 NATIVEEXPORT std::unique_ptr<PixelMap> CreatePixelMap(uint32_t index, const DecodeOptions &opts, 144 uint32_t &errorCode); 145 NATIVEEXPORT std::unique_ptr<IncrementalPixelMap> CreateIncrementalPixelMap(uint32_t index, 146 const DecodeOptions &opts, 147 uint32_t &errorCode); 148 // for incremental source. 149 NATIVEEXPORT uint32_t UpdateData(const uint8_t *data, uint32_t size, bool isCompleted); 150 // for obtaining basic image information without decoding image data. GetImageInfo(ImageInfo & imageInfo)151 NATIVEEXPORT uint32_t GetImageInfo(ImageInfo &imageInfo) 152 { 153 return GetImageInfo(0, imageInfo); 154 } 155 NATIVEEXPORT uint32_t GetImageInfo(uint32_t index, ImageInfo &imageInfo); 156 NATIVEEXPORT const SourceInfo &GetSourceInfo(uint32_t &errorCode); 157 NATIVEEXPORT void RegisterListener(PeerListener *listener); 158 NATIVEEXPORT void UnRegisterListener(PeerListener *listener); 159 NATIVEEXPORT DecodeEvent GetDecodeEvent(); 160 NATIVEEXPORT void AddDecodeListener(DecodeListener *listener); 161 NATIVEEXPORT void RemoveDecodeListener(DecodeListener *listener); 162 NATIVEEXPORT bool IsIncrementalSource(); 163 NATIVEEXPORT uint32_t GetImagePropertyInt(uint32_t index, const std::string &key, int32_t &value); 164 NATIVEEXPORT uint32_t GetImagePropertyString(uint32_t index, const std::string &key, std::string &value); 165 NATIVEEXPORT uint32_t ModifyImageProperty(uint32_t index, const std::string &key, const std::string &value, 166 const std::string &path); 167 NATIVEEXPORT const NinePatchInfo &GetNinePatchInfo() const; 168 NATIVEEXPORT void SetMemoryUsagePreference(const MemoryUsagePreference preference); 169 NATIVEEXPORT MemoryUsagePreference GetMemoryUsagePreference(); 170 171 private: 172 DISALLOW_COPY_AND_MOVE(ImageSource); 173 using FormatAgentMap = std::map<std::string, ImagePlugin::AbsImageFormatAgent *>; 174 using ImageStatusMap = std::map<uint32_t, ImageDecodingStatus>; 175 using IncrementalRecordMap = std::map<PixelMap *, IncrementalDecodingContext>; 176 ImageSource(std::unique_ptr<SourceStream> &&stream, const SourceOptions &opts); 177 uint32_t CheckEncodedFormat(ImagePlugin::AbsImageFormatAgent &agent); 178 static FormatAgentMap InitClass(); 179 uint32_t GetEncodedFormat(const std::string &formatHint, std::string &format); 180 uint32_t DecodeImageInfo(uint32_t index, ImageStatusMap::iterator &iter); 181 uint32_t DecodeSourceInfo(bool isAcquiredImageNum); 182 uint32_t InitMainDecoder(); 183 ImagePlugin::AbsImageDecoder *CreateDecoder(uint32_t &errorCode); 184 void CopyOptionsToPlugin(const DecodeOptions &opts, ImagePlugin::PixelDecodeOptions &plOpts); 185 void CopyOptionsToProcOpts(const DecodeOptions &opts, DecodeOptions &procOpts, PixelMap &pixelMap); 186 uint32_t CheckFormatHint(const std::string &formatHint, FormatAgentMap::iterator &formatIter); 187 uint32_t GetSourceInfo(); 188 uint32_t OnSourceRecognized(bool isAcquiredImageNum); 189 uint32_t OnSourceUnresolved(); 190 uint32_t SetDecodeOptions(std::unique_ptr<ImagePlugin::AbsImageDecoder> &decoder, uint32_t index, 191 const DecodeOptions &opts, ImagePlugin::PlImageInfo &plInfo); 192 uint32_t UpdatePixelMapInfo(const DecodeOptions &opts, ImagePlugin::PlImageInfo &plInfo, PixelMap &pixelMap); 193 // declare friend class, only IncrementalPixelMap can call PromoteDecoding function. 194 friend class IncrementalPixelMap; 195 uint32_t PromoteDecoding(uint32_t index, const DecodeOptions &opts, PixelMap &pixelMap, ImageDecodingState &state, 196 uint8_t &decodeProgress); 197 void DetachIncrementalDecoding(PixelMap &pixelMap); 198 ImageStatusMap::iterator GetValidImageStatus(uint32_t index, uint32_t &errorCode); 199 uint32_t AddIncrementalContext(PixelMap &pixelMap, IncrementalRecordMap::iterator &iterator); 200 uint32_t DoIncrementalDecoding(uint32_t index, const DecodeOptions &opts, PixelMap &pixelMap, 201 IncrementalDecodingContext &recordContext); 202 void SetIncrementalSource(const bool isIncrementalSource); 203 bool IsStreamCompleted(); 204 FinalOutputStep GetFinalOutputStep(const DecodeOptions &opts, PixelMap &pixelMap, bool hasNinePatch); 205 bool HasDensityChange(const DecodeOptions &opts, ImageInfo &srcImageInfo, bool hasNinePatch); 206 bool ImageSizeChange(int32_t width, int32_t height, int32_t desiredWidth, int32_t desiredHeight); 207 bool ImageConverChange(const Rect &cropRect, ImageInfo &dstImageInfo, ImageInfo &srcImageInfo); 208 void Reset(); 209 210 const std::string NINE_PATCH = "ninepatch"; 211 const std::string SKIA_DECODER = "SKIA_DECODER"; 212 static MultimediaPlugin::PluginServer &pluginServer_; 213 static FormatAgentMap formatAgentMap_; 214 std::unique_ptr<SourceStream> sourceStreamPtr_; 215 SourceDecodingState decodeState_ = SourceDecodingState::UNRESOLVED; 216 SourceInfo sourceInfo_; 217 NinePatchInfo ninePatchInfo_; 218 ImageStatusMap imageStatusMap_; 219 IncrementalRecordMap incDecodingMap_; 220 // The main decoder is responsible for ordinary decoding (non-Incremental decoding), 221 // as well as decoding SourceInfo and ImageInfo. 222 std::unique_ptr<ImagePlugin::AbsImageDecoder> mainDecoder_; 223 DecodeOptions opts_; 224 std::set<PeerListener *> listeners_; 225 DecodeEvent decodeEvent_ = DecodeEvent::EVENT_COMPLETE_DECODE; 226 std::map<int32_t, int32_t> decodeEventMap_; 227 std::set<DecodeListener *> decodeListeners_; 228 std::mutex listenerMutex_; 229 std::mutex decodingMutex_; 230 bool isIncrementalSource_ = false; 231 bool isIncrementalCompleted_ = false; 232 MemoryUsagePreference preference_ = MemoryUsagePreference::DEFAULT; 233 }; 234 } // namespace Media 235 } // namespace OHOS 236 237 #endif // IMAGE_SOURCE_H 238