1 /*
2 * Copyright (c) 2024 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 #include "image_source_impl.h"
16
17 #include "file_source_stream.h"
18 #include "image_ffi.h"
19 #include "image_log.h"
20 #include "image_source.h"
21 #include "media_errors.h"
22 #include "pixel_map_impl.h"
23 #include "string_ex.h"
24
25 namespace OHOS {
26 namespace Media {
27 const uint32_t NUM_2 = 2;
28 const uint32_t NUM_3 = 3;
29 const long int NUM_8 = 8;
30 const int DECIMAL_BASE = 10;
31
CreateImageSource(std::string uri,uint32_t * errCode)32 std::unique_ptr<ImageSource> ImageSourceImpl::CreateImageSource(std::string uri, uint32_t* errCode)
33 {
34 SourceOptions opts;
35 std::unique_ptr<ImageSource> ptr_ = ImageSource::CreateImageSource(uri, opts, *errCode);
36 return ptr_;
37 }
38
CreateImageSourceWithOption(std::string uri,SourceOptions & opts,uint32_t * errCode)39 std::unique_ptr<ImageSource> ImageSourceImpl::CreateImageSourceWithOption(
40 std::string uri, SourceOptions& opts, uint32_t* errCode)
41 {
42 std::unique_ptr<ImageSource> ptr_ = ImageSource::CreateImageSource(uri, opts, *errCode);
43 return ptr_;
44 }
45
CreateImageSource(int fd,uint32_t * errCode)46 std::unique_ptr<ImageSource> ImageSourceImpl::CreateImageSource(int fd, uint32_t* errCode)
47 {
48 SourceOptions opts;
49 std::unique_ptr<ImageSource> ptr_ = ImageSource::CreateImageSource(fd, opts, *errCode);
50 return ptr_;
51 }
52
CreateImageSourceWithOption(int fd,SourceOptions & opts,uint32_t * errCode)53 std::unique_ptr<ImageSource> ImageSourceImpl::CreateImageSourceWithOption(
54 int fd, SourceOptions& opts, uint32_t* errCode)
55 {
56 std::unique_ptr<ImageSource> ptr_ = ImageSource::CreateImageSource(fd, opts, *errCode);
57 return ptr_;
58 }
59
CreateImageSource(uint8_t * data,uint32_t size,uint32_t * errCode)60 std::unique_ptr<ImageSource> ImageSourceImpl::CreateImageSource(uint8_t* data, uint32_t size, uint32_t* errCode)
61 {
62 SourceOptions opts;
63 std::unique_ptr<ImageSource> ptr_ = ImageSource::CreateImageSource(data, size, opts, *errCode);
64 return ptr_;
65 }
66
CreateImageSourceWithOption(uint8_t * data,uint32_t size,SourceOptions & opts,uint32_t * errCode)67 std::unique_ptr<ImageSource> ImageSourceImpl::CreateImageSourceWithOption(
68 uint8_t* data, uint32_t size, SourceOptions& opts, uint32_t* errCode)
69 {
70 std::unique_ptr<ImageSource> ptr_ = ImageSource::CreateImageSource(data, size, opts, *errCode);
71 return ptr_;
72 }
73
CreateImageSource(const int fd,int32_t offset,int32_t length,const SourceOptions & opts,uint32_t & errorCode)74 std::unique_ptr<ImageSource> ImageSourceImpl::CreateImageSource(
75 const int fd, int32_t offset, int32_t length, const SourceOptions& opts, uint32_t& errorCode)
76 {
77 int32_t fileSize = offset + length;
78 std::unique_ptr<ImageSource> imageSource = ImageSource::CreateImageSource(fd, offset, fileSize, opts, errorCode);
79 return imageSource;
80 }
81
CreateIncrementalSource(const uint8_t * data,uint32_t size,SourceOptions & opts,uint32_t & errorCode)82 std::tuple<std::unique_ptr<ImageSource>, std::unique_ptr<IncrementalPixelMap>> ImageSourceImpl::CreateIncrementalSource(
83 const uint8_t* data, uint32_t size, SourceOptions& opts, uint32_t& errorCode)
84 {
85 IncrementalSourceOptions incOpts;
86 incOpts.sourceOptions = opts;
87 incOpts.incrementalMode = IncrementalMode::INCREMENTAL_DATA;
88 std::unique_ptr<ImageSource> imageSource = ImageSource::CreateIncrementalImageSource(incOpts, errorCode);
89 if (imageSource == nullptr) {
90 IMAGE_LOGE("CreateIncrementalImageSource error.");
91 return std::make_tuple(nullptr, nullptr);
92 }
93 DecodeOptions decodeOpts;
94 std::unique_ptr<IncrementalPixelMap> incPixelMap = imageSource->CreateIncrementalPixelMap(0, decodeOpts, errorCode);
95 if (errorCode != SUCCESS) {
96 IMAGE_LOGE("CreateIncrementalImageSource error.");
97 return std::make_tuple(nullptr, nullptr);
98 }
99 return std::make_tuple(move(imageSource), move(incPixelMap));
100 }
101
ImageSourceImpl(std::unique_ptr<ImageSource> imageSource)102 ImageSourceImpl::ImageSourceImpl(std::unique_ptr<ImageSource> imageSource)
103 {
104 nativeImgSrc = move(imageSource);
105 }
106
ImageSourceImpl(std::unique_ptr<ImageSource> imageSource,std::unique_ptr<IncrementalPixelMap> pixelMap)107 ImageSourceImpl::ImageSourceImpl(
108 std::unique_ptr<ImageSource> imageSource, std::unique_ptr<IncrementalPixelMap> pixelMap)
109 {
110 nativeImgSrc = move(imageSource);
111 navIncPixelMap_ = move(pixelMap);
112 }
113
GetImageInfo(uint32_t index,ImageInfo & imageInfo)114 uint32_t ImageSourceImpl::GetImageInfo(uint32_t index, ImageInfo& imageInfo)
115 {
116 if (nativeImgSrc == nullptr) {
117 return ERR_IMAGE_INIT_ABNORMAL;
118 }
119 IMAGE_LOGD("[ImageSourceImpl] GetImageInfo start.");
120 return nativeImgSrc->GetImageInfo(index, imageInfo);
121 }
122
GetSupportedFormats(std::set<std::string> & formats)123 uint32_t ImageSourceImpl::GetSupportedFormats(std::set<std::string>& formats)
124 {
125 if (nativeImgSrc == nullptr) {
126 return ERR_IMAGE_INIT_ABNORMAL;
127 }
128 IMAGE_LOGD("[ImageSourceImpl] GetSupportedFormats start.");
129 return nativeImgSrc->GetSupportedFormats(formats);
130 }
131
GetImageProperty(std::string key,uint32_t index,std::string & defaultValue)132 uint32_t ImageSourceImpl::GetImageProperty(std::string key, uint32_t index, std::string& defaultValue)
133 {
134 if (nativeImgSrc == nullptr) {
135 return ERR_IMAGE_INIT_ABNORMAL;
136 }
137 IMAGE_LOGD("[ImageSourceImpl] GetImageProperty start.");
138 index_ = index;
139 return nativeImgSrc->GetImagePropertyString(index, key, defaultValue);
140 }
141
GetImageProperties(std::vector<std::string> keyStrArray,std::vector<std::string> & valueStrArray)142 uint32_t ImageSourceImpl::GetImageProperties(
143 std::vector<std::string> keyStrArray, std::vector<std::string>& valueStrArray)
144 {
145 if (nativeImgSrc == nullptr) {
146 return ERR_IMAGE_INIT_ABNORMAL;
147 }
148 for (auto keyStrIt = keyStrArray.begin(); keyStrIt != keyStrArray.end(); ++keyStrIt) {
149 std::string valueStr = "";
150 uint32_t status = nativeImgSrc->GetImagePropertyString(0, *keyStrIt, valueStr);
151 if (status == SUCCESS) {
152 valueStrArray.push_back(valueStr);
153 } else {
154 valueStrArray.push_back(valueStr);
155 IMAGE_LOGE("errCode: %{public}u , exif key: %{public}s", status, keyStrIt->c_str());
156 }
157 }
158 return SUCCESS;
159 }
160
CheckExifDataValue(const std::string & value)161 static bool CheckExifDataValue(const std::string& value)
162 {
163 std::vector<std::string> bitsVec;
164 SplitStr(value, ",", bitsVec);
165 if (bitsVec.size() > NUM_3) {
166 return false;
167 }
168 for (size_t i = 0; i < bitsVec.size(); i++) {
169 if (!IsNumericStr(bitsVec[i])) {
170 return false;
171 }
172 }
173 return true;
174 }
175
CheckOrientation(const std::string & value)176 static bool CheckOrientation(const std::string& value)
177 {
178 long int num;
179 char* endptr;
180 num = strtol(value.c_str(), &endptr, DECIMAL_BASE);
181 if (*endptr != '\0') {
182 return false;
183 }
184 if (!IsNumericStr(value) || num < 1 || num > NUM_8) {
185 return false;
186 }
187 return true;
188 }
189
CheckGPS(const std::string & value)190 static bool CheckGPS(const std::string& value)
191 {
192 std::vector<std::string> gpsVec;
193 SplitStr(value, ",", gpsVec);
194 if (gpsVec.size() != NUM_2) {
195 return false;
196 }
197
198 for (size_t i = 0; i < gpsVec.size(); i++) {
199 if (!IsNumericStr(gpsVec[i])) {
200 return false;
201 }
202 }
203 return true;
204 }
205
CheckExifDataValue(const std::string & key,const std::string & value)206 static bool CheckExifDataValue(const std::string& key, const std::string& value)
207 {
208 if (IsSameTextStr(key, "BitsPerSample")) {
209 return CheckExifDataValue(value);
210 } else if (IsSameTextStr(key, "Orientation")) {
211 return CheckOrientation(value);
212 } else if (IsSameTextStr(key, "ImageLength") || IsSameTextStr(key, "ImageWidth")) {
213 if (!IsNumericStr(value)) {
214 return false;
215 }
216 } else if (IsSameTextStr(key, "GPSLatitude") || IsSameTextStr(key, "GPSLongitude")) {
217 return CheckGPS(value);
218 } else if (IsSameTextStr(key, "GPSLatitudeRef")) {
219 if (!IsSameTextStr(value, "N") && !IsSameTextStr(value, "S")) {
220 return false;
221 }
222 } else if (IsSameTextStr(key, "GPSLongitudeRef")) {
223 if (!IsSameTextStr(value, "W") && !IsSameTextStr(value, "E")) {
224 return false;
225 }
226 }
227 return true;
228 }
229
ModifyImageProperty(std::string key,std::string value)230 uint32_t ImageSourceImpl::ModifyImageProperty(std::string key, std::string value)
231 {
232 if (nativeImgSrc == nullptr) {
233 return ERR_IMAGE_INIT_ABNORMAL;
234 }
235 IMAGE_LOGD("[ImageSourceImpl] ModifyImageProperty start.");
236 uint32_t ret = ERR_MEDIA_INVALID_VALUE;
237 if (!CheckExifDataValue(key, value)) {
238 IMAGE_LOGE("There is invalid exif data parameter");
239 ret = ERR_MEDIA_VALUE_INVALID;
240 return ret;
241 }
242 if (!IsSameTextStr(pathName_, "")) {
243 ret = nativeImgSrc->ModifyImageProperty(index_, key, value, pathName_);
244 } else if (fd_ != -1) {
245 ret = nativeImgSrc->ModifyImageProperty(index_, key, value, fd_);
246 } else if (buffer_ != nullptr) {
247 ret = nativeImgSrc->ModifyImageProperty(index_, key, value, buffer_, bufferSize_);
248 } else {
249 IMAGE_LOGE("[ImageSourceImpl] There is no image source!");
250 }
251 return ret;
252 }
253
ModifyImageProperties(char ** keyStrArray,char ** valueStrArray,int64_t arraySize)254 uint32_t ImageSourceImpl::ModifyImageProperties(char** keyStrArray, char** valueStrArray, int64_t arraySize)
255 {
256 if (nativeImgSrc == nullptr) {
257 return ERR_IMAGE_INIT_ABNORMAL;
258 }
259 for (int64_t i = 0; i < arraySize; i++) {
260 uint32_t ret = ModifyImageProperty(keyStrArray[i], valueStrArray[i]);
261 if (ret != SUCCESS) {
262 return ret;
263 }
264 }
265 return SUCCESS;
266 }
267
GetFrameCount(uint32_t & errorCode)268 uint32_t ImageSourceImpl::GetFrameCount(uint32_t& errorCode)
269 {
270 if (nativeImgSrc == nullptr) {
271 errorCode = ERR_IMAGE_INIT_ABNORMAL;
272 return 0;
273 }
274 IMAGE_LOGD("[ImageSourceImpl] GetFrameCount start.");
275 return nativeImgSrc->GetFrameCount(errorCode);
276 }
277
UpdateData(uint8_t * data,uint32_t size,bool isCompleted)278 uint32_t ImageSourceImpl::UpdateData(uint8_t* data, uint32_t size, bool isCompleted)
279 {
280 if (nativeImgSrc == nullptr) {
281 return ERR_IMAGE_INIT_ABNORMAL;
282 }
283 IMAGE_LOGD("[ImageSourceImpl] UpdateData start.");
284 return nativeImgSrc->UpdateData(data, size, isCompleted);
285 }
286
CreatePixelMap(uint32_t index,DecodeOptions & opts,uint32_t & errorCode)287 int64_t ImageSourceImpl::CreatePixelMap(uint32_t index, DecodeOptions& opts, uint32_t& errorCode)
288 {
289 if (nativeImgSrc == nullptr) {
290 errorCode = ERR_IMAGE_INIT_ABNORMAL;
291 return 0;
292 }
293 IMAGE_LOGD("[ImageSourceImpl] CreatePixelMap start.");
294 std::shared_ptr<PixelMap> incPixelMap;
295 incPixelMap = GetIncrementalPixelMap();
296 if (incPixelMap != nullptr) {
297 errorCode = 0;
298 IMAGE_LOGD("Get Incremental PixelMap!!!");
299 } else {
300 IMAGE_LOGD("Create PixelMap!!!");
301 incPixelMap = nativeImgSrc->CreatePixelMapEx(index, opts, errorCode);
302 if (incPixelMap == nullptr) {
303 IMAGE_LOGE("[ImageSourceImpl] Create PixelMap error.");
304 }
305 }
306
307 auto nativeImage = FFIData::Create<PixelMapImpl>(move(incPixelMap));
308 IMAGE_LOGD("[ImageSourceImpl] CreatePixelMap success.");
309 return nativeImage->GetID();
310 }
311
CreatePixelMapList(uint32_t index,DecodeOptions opts,uint32_t * errorCode)312 std::vector<int64_t> ImageSourceImpl::CreatePixelMapList(uint32_t index, DecodeOptions opts, uint32_t* errorCode)
313 {
314 std::vector<int64_t> ret;
315 if (nativeImgSrc == nullptr) {
316 *errorCode = ERR_IMAGE_INIT_ABNORMAL;
317 return ret;
318 }
319 IMAGE_LOGD("[ImageSourceImpl] CreatePixelMapList start.");
320 uint32_t frameCount = nativeImgSrc->GetFrameCount(*errorCode);
321
322 std::unique_ptr<std::vector<std::unique_ptr<PixelMap>>> pixelMaps;
323 if ((*errorCode == SUCCESS) && (index >= 0) && (index < frameCount)) {
324 pixelMaps = nativeImgSrc->CreatePixelMapList(opts, *errorCode);
325 }
326 if (*errorCode != SUCCESS || pixelMaps == nullptr) {
327 return ret;
328 }
329 for (size_t i = 0; i < pixelMaps->size(); i++) {
330 std::unique_ptr<PixelMap> pixelmap = move(pixelMaps->operator[](i));
331 auto nativeImage = FFIData::Create<PixelMapImpl>(move(pixelmap));
332 if (nativeImage == nullptr) {
333 *errorCode = ERR_IMAGE_INIT_ABNORMAL;
334 return ret;
335 }
336 ret.push_back(nativeImage->GetID());
337 }
338 IMAGE_LOGD("[ImageSourceImpl] CreatePixelMapList success.");
339 return ret;
340 }
341
GetDelayTime(uint32_t * errorCode)342 std::unique_ptr<std::vector<int32_t>> ImageSourceImpl::GetDelayTime(uint32_t* errorCode)
343 {
344 std::unique_ptr<std::vector<int32_t>> delayTimes;
345 if (nativeImgSrc == nullptr) {
346 *errorCode = ERR_IMAGE_INIT_ABNORMAL;
347 return delayTimes;
348 }
349 IMAGE_LOGD("[ImageSourceImpl] GetDelayTime start.");
350 delayTimes = nativeImgSrc->GetDelayTime(*errorCode);
351 IMAGE_LOGD("[ImageSourceImpl] GetDelayTime success.");
352 return delayTimes;
353 }
354
GetDisposalTypeList(uint32_t * errorCode)355 std::unique_ptr<std::vector<int32_t>> ImageSourceImpl::GetDisposalTypeList(uint32_t* errorCode)
356 {
357 std::unique_ptr<std::vector<int32_t>> disposalType;
358 if (nativeImgSrc == nullptr) {
359 *errorCode = ERR_IMAGE_INIT_ABNORMAL;
360 return disposalType;
361 }
362 disposalType = nativeImgSrc->GetDisposalType(*errorCode);
363 if ((*errorCode != SUCCESS) || disposalType == nullptr) {
364 *errorCode = ERROR;
365 }
366 return disposalType;
367 }
368
SetPathName(std::string pathName)369 void ImageSourceImpl::SetPathName(std::string pathName)
370 {
371 pathName_ = pathName;
372 }
373
SetFd(int fd)374 void ImageSourceImpl::SetFd(int fd)
375 {
376 fd_ = fd;
377 }
378
SetBuffer(uint8_t * data,uint32_t size)379 void ImageSourceImpl::SetBuffer(uint8_t* data, uint32_t size)
380 {
381 buffer_ = data;
382 bufferSize_ = size;
383 }
384 } // namespace Media
385 } // namespace OHOS