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 #include "image_log.h"
17 #include "file_source_stream.h"
18 #include "image_source.h"
19 #include "media_errors.h"
20 #include "string_ex.h"
21 #include "pixel_map_impl.h"
22 #include "image_ffi.h"
23 
24 namespace OHOS {
25 namespace Media {
26 const uint32_t NUM_2 = 2;
27 const uint32_t NUM_3 = 3;
28 const long int NUM_8 = 8;
29 const int DECIMAL_BASE = 10;
30 
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(std::string uri, SourceOptions &opts,
40     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(int fd, SourceOptions &opts,
54     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(uint8_t *data, uint32_t size,
68     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(const int fd, int32_t offset,
75     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,
79         offset, fileSize, opts, errorCode);
80     return imageSource;
81 }
82 
CreateIncrementalSource(const uint8_t * data,uint32_t size,SourceOptions & opts,uint32_t & errorCode)83 std::tuple<std::unique_ptr<ImageSource>, std::unique_ptr<IncrementalPixelMap>> ImageSourceImpl::CreateIncrementalSource(
84     const uint8_t *data, uint32_t size, SourceOptions &opts, uint32_t &errorCode)
85 {
86     IncrementalSourceOptions incOpts;
87     incOpts.sourceOptions = opts;
88     incOpts.incrementalMode = IncrementalMode::INCREMENTAL_DATA;
89     std::unique_ptr<ImageSource> imageSource = ImageSource::CreateIncrementalImageSource(incOpts, errorCode);
90 
91     DecodeOptions decodeOpts;
92     std::unique_ptr<IncrementalPixelMap> incPixelMap = imageSource->CreateIncrementalPixelMap(0, decodeOpts,
93         errorCode);
94     if (errorCode != SUCCESS) {
95         IMAGE_LOGE("CreateIncrementalImageSource error.");
96         return std::make_tuple(nullptr, nullptr);
97     }
98     return std::make_tuple(move(imageSource), move(incPixelMap));
99 }
100 
ImageSourceImpl(std::unique_ptr<ImageSource> imageSource)101 ImageSourceImpl::ImageSourceImpl(std::unique_ptr<ImageSource> imageSource)
102 {
103     nativeImgSrc = move(imageSource);
104 }
105 
ImageSourceImpl(std::unique_ptr<ImageSource> imageSource,std::unique_ptr<IncrementalPixelMap> pixelMap)106 ImageSourceImpl::ImageSourceImpl(std::unique_ptr<ImageSource> imageSource,
107     std::unique_ptr<IncrementalPixelMap> pixelMap)
108 {
109     nativeImgSrc = move(imageSource);
110     navIncPixelMap_ = move(pixelMap);
111 }
112 
GetImageInfo(uint32_t index,ImageInfo & imageInfo)113 uint32_t ImageSourceImpl::GetImageInfo(uint32_t index, ImageInfo &imageInfo)
114 {
115     if (nativeImgSrc == nullptr) {
116         return ERR_IMAGE_INIT_ABNORMAL;
117     }
118     IMAGE_LOGD("[ImageSourceImpl] GetImageInfo start.");
119     return nativeImgSrc->GetImageInfo(index, imageInfo);
120 }
121 
GetSupportedFormats(std::set<std::string> & formats)122 uint32_t ImageSourceImpl::GetSupportedFormats(std::set<std::string> &formats)
123 {
124     if (nativeImgSrc == nullptr) {
125         return ERR_IMAGE_INIT_ABNORMAL;
126     }
127     IMAGE_LOGD("[ImageSourceImpl] GetSupportedFormats start.");
128     return nativeImgSrc->GetSupportedFormats(formats);
129 }
130 
GetImageProperty(std::string key,uint32_t index,std::string & defaultValue)131 uint32_t ImageSourceImpl::GetImageProperty(std::string key, uint32_t index, std::string &defaultValue)
132 {
133     if (nativeImgSrc == nullptr) {
134         return ERR_IMAGE_INIT_ABNORMAL;
135     }
136     IMAGE_LOGD("[ImageSourceImpl] GetImageProperty start.");
137     index_ = index;
138     return nativeImgSrc->GetImagePropertyString(index, key, defaultValue);
139 }
140 
CheckExifDataValue(const std::string & value)141 static bool CheckExifDataValue(const std::string &value)
142 {
143     std::vector<std::string> bitsVec;
144     SplitStr(value, ",", bitsVec);
145     if (bitsVec.size() > NUM_3) {
146         return false;
147     }
148     for (size_t i = 0; i < bitsVec.size(); i++) {
149         if (!IsNumericStr(bitsVec[i])) {
150             return false;
151         }
152     }
153     return true;
154 }
155 
CheckOrientation(const std::string & value)156 static bool CheckOrientation(const std::string &value)
157 {
158     long int num;
159     char *endptr;
160     num = strtol(value.c_str(), &endptr, DECIMAL_BASE);
161     if (*endptr != '\0') {
162         return false;
163     }
164     if (!IsNumericStr(value) || num < 1 || num > NUM_8) {
165         return false;
166     }
167     return true;
168 }
169 
CheckGPS(const std::string & value)170 static bool CheckGPS(const std::string &value)
171 {
172     std::vector<std::string> gpsVec;
173     SplitStr(value, ",", gpsVec);
174     if (gpsVec.size() != NUM_2) {
175         return false;
176     }
177 
178     for (size_t i = 0; i < gpsVec.size(); i++) {
179         if (!IsNumericStr(gpsVec[i])) {
180             return false;
181         }
182     }
183     return true;
184 }
185 
CheckExifDataValue(const std::string & key,const std::string & value)186 static bool CheckExifDataValue(const std::string &key, const std::string &value)
187 {
188     if (IsSameTextStr(key, "BitsPerSample")) {
189         return CheckExifDataValue(value);
190     } else if (IsSameTextStr(key, "Orientation")) {
191         return CheckOrientation(value);
192     } else if (IsSameTextStr(key, "ImageLength") || IsSameTextStr(key, "ImageWidth")) {
193         if (!IsNumericStr(value)) {
194             return false;
195         }
196     } else if (IsSameTextStr(key, "GPSLatitude") || IsSameTextStr(key, "GPSLongitude")) {
197         return CheckGPS(value);
198     } else if (IsSameTextStr(key, "GPSLatitudeRef")) {
199         if (!IsSameTextStr(value, "N") && !IsSameTextStr(value, "S")) {
200             return false;
201         }
202     } else if (IsSameTextStr(key, "GPSLongitudeRef")) {
203         if (!IsSameTextStr(value, "W") && !IsSameTextStr(value, "E")) {
204             return false;
205         }
206     }
207     return true;
208 }
209 
ModifyImageProperty(std::string key,std::string value)210 uint32_t ImageSourceImpl::ModifyImageProperty(std::string key, std::string value)
211 {
212     if (nativeImgSrc == nullptr) {
213         return ERR_IMAGE_INIT_ABNORMAL;
214     }
215     IMAGE_LOGD("[ImageSourceImpl] ModifyImageProperty start.");
216     uint32_t ret = ERR_MEDIA_INVALID_VALUE;
217     if (!CheckExifDataValue(key, value)) {
218         IMAGE_LOGE("There is invalid exif data parameter");
219         ret = ERR_MEDIA_VALUE_INVALID;
220         return ret;
221     }
222     if (!IsSameTextStr(pathName_, "")) {
223         ret = nativeImgSrc->ModifyImageProperty(index_, key, value, pathName_);
224     } else if (fd_ != -1) {
225         ret = nativeImgSrc->ModifyImageProperty(index_, key, value, fd_);
226     } else if (buffer_ != nullptr) {
227         ret = nativeImgSrc->ModifyImageProperty(index_, key, value, buffer_, bufferSize_);
228     } else {
229         IMAGE_LOGE("[ImageSourceImpl] There is no image source!");
230     }
231     return ret;
232 }
233 
GetFrameCount(uint32_t & errorCode)234 uint32_t ImageSourceImpl::GetFrameCount(uint32_t &errorCode)
235 {
236     if (nativeImgSrc == nullptr) {
237         errorCode = ERR_IMAGE_INIT_ABNORMAL;
238         return 0;
239     }
240     IMAGE_LOGD("[ImageSourceImpl] GetFrameCount start.");
241     return nativeImgSrc->GetFrameCount(errorCode);
242 }
243 
UpdateData(uint8_t * data,uint32_t size,bool isCompleted)244 uint32_t ImageSourceImpl::UpdateData(uint8_t *data, uint32_t size, bool isCompleted)
245 {
246     if (nativeImgSrc == nullptr) {
247         return ERR_IMAGE_INIT_ABNORMAL;
248     }
249     IMAGE_LOGD("[ImageSourceImpl] UpdateData start.");
250     return nativeImgSrc->UpdateData(data, size, isCompleted);
251 }
252 
CreatePixelMap(uint32_t index,DecodeOptions & opts,uint32_t & errorCode)253 int64_t ImageSourceImpl::CreatePixelMap(uint32_t index, DecodeOptions &opts, uint32_t &errorCode)
254 {
255     if (nativeImgSrc == nullptr) {
256         errorCode = ERR_IMAGE_INIT_ABNORMAL;
257         return 0;
258     }
259     IMAGE_LOGD("[ImageSourceImpl] CreatePixelMap start.");
260     std::shared_ptr<PixelMap> incPixelMap;
261     incPixelMap = GetIncrementalPixelMap();
262     if (incPixelMap != nullptr) {
263         errorCode = 0;
264         IMAGE_LOGD("Get Incremental PixelMap!!!");
265     } else {
266         IMAGE_LOGD("Create PixelMap!!!");
267         incPixelMap = nativeImgSrc->CreatePixelMapEx(index, opts, errorCode);
268         if (incPixelMap == nullptr) {
269             IMAGE_LOGE("[ImageSourceImpl] Create PixelMap error.");
270         }
271     }
272 
273     auto nativeImage = FFIData::Create<PixelMapImpl>(move(incPixelMap));
274     IMAGE_LOGD("[ImageSourceImpl] CreatePixelMap success.");
275     return nativeImage->GetID();
276 }
277 
CreatePixelMapList(uint32_t index,DecodeOptions opts,uint32_t * errorCode)278 std::vector<int64_t> ImageSourceImpl::CreatePixelMapList(uint32_t index, DecodeOptions opts, uint32_t* errorCode)
279 {
280     std::vector<int64_t> ret;
281     if (nativeImgSrc == nullptr) {
282         *errorCode = ERR_IMAGE_INIT_ABNORMAL;
283         return ret;
284     }
285     IMAGE_LOGD("[ImageSourceImpl] CreatePixelMapList start.");
286     uint32_t frameCount = nativeImgSrc->GetFrameCount(*errorCode);
287 
288     std::unique_ptr<std::vector<std::unique_ptr<PixelMap>>> pixelMaps;
289     if ((*errorCode == SUCCESS) && (index >= 0) && (index < frameCount)) {
290         pixelMaps = nativeImgSrc->CreatePixelMapList(opts, *errorCode);
291     }
292     for (size_t i = 0; i < pixelMaps->size(); i++) {
293         std::unique_ptr<PixelMap> pixelmap = move(pixelMaps->operator[](i));
294         auto nativeImage = FFIData::Create<PixelMapImpl>(move(pixelmap));
295         ret.push_back(nativeImage->GetID());
296     }
297     IMAGE_LOGD("[ImageSourceImpl] CreatePixelMapList success.");
298     return ret;
299 }
300 
GetDelayTime(uint32_t * errorCode)301 std::unique_ptr<std::vector<int32_t>> ImageSourceImpl::GetDelayTime(uint32_t* errorCode)
302 {
303     std::unique_ptr<std::vector<int32_t>> delayTimes;
304     if (nativeImgSrc == nullptr) {
305         *errorCode = ERR_IMAGE_INIT_ABNORMAL;
306         return delayTimes;
307     }
308     IMAGE_LOGD("[ImageSourceImpl] GetDelayTime start.");
309     delayTimes = nativeImgSrc->GetDelayTime(*errorCode);
310     IMAGE_LOGD("[ImageSourceImpl] GetDelayTime success.");
311     return delayTimes;
312 }
313 
SetPathName(std::string pathName)314 void ImageSourceImpl::SetPathName(std::string pathName)
315 {
316     pathName_ = pathName;
317 }
318 
SetFd(int fd)319 void ImageSourceImpl::SetFd(int fd)
320 {
321     fd_ = fd;
322 }
323 
SetBuffer(uint8_t * data,uint32_t size)324 void ImageSourceImpl::SetBuffer(uint8_t *data, uint32_t size)
325 {
326     buffer_ = data;
327     bufferSize_ = size;
328 }
329 }
330 }