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 
16 #include "picture.h"
17 #include "auxiliary_picture.h"
18 #include "media_errors.h"
19 #include "image_log.h"
20 #include "image_utils.h"
21 #include "exif_metadata.h"
22 #include "fragment_metadata.h"
23 
24 namespace OHOS {
25 namespace Media {
26 
27 const static uint64_t MAX_PICTURE_META_TYPE_COUNT = 64;
28 const static uint64_t MAX_JPEG_TAG_NAME_LENGTH = 100;
~AuxiliaryPicture()29 AuxiliaryPicture::~AuxiliaryPicture() {}
Create(std::shared_ptr<PixelMap> & content,AuxiliaryPictureType type,Size size)30 std::unique_ptr<AuxiliaryPicture> AuxiliaryPicture::Create(std::shared_ptr<PixelMap> &content,
31                                                            AuxiliaryPictureType type, Size size)
32 {
33     if (content == nullptr) {
34         return nullptr;
35     }
36     std::unique_ptr<AuxiliaryPicture> dstAuxPicture = std::make_unique<AuxiliaryPicture>();
37     dstAuxPicture->content_ = content;
38     dstAuxPicture->SetType(type);
39     dstAuxPicture->SetSize(size);
40     return dstAuxPicture;
41 }
42 
Create(sptr<SurfaceBuffer> & surfaceBuffer,AuxiliaryPictureType type,Size size)43 std::unique_ptr<AuxiliaryPicture> AuxiliaryPicture::Create(sptr<SurfaceBuffer> &surfaceBuffer,
44                                                            AuxiliaryPictureType type, Size size)
45 {
46     std::shared_ptr<PixelMap> pixelMap = Picture::SurfaceBuffer2PixelMap(surfaceBuffer);
47     return Create(pixelMap, type, size);
48 }
49 
GetType()50 AuxiliaryPictureType AuxiliaryPicture::GetType()
51 {
52     return auxiliaryPictureInfo_.auxiliaryPictureType;
53 }
54 
SetType(AuxiliaryPictureType type)55 void AuxiliaryPicture::SetType(AuxiliaryPictureType type)
56 {
57     auxiliaryPictureInfo_.auxiliaryPictureType = type;
58 }
59 
GetSize()60 Size AuxiliaryPicture::GetSize()
61 {
62     return auxiliaryPictureInfo_.size;
63 }
64 
SetSize(Size size)65 void AuxiliaryPicture::SetSize(Size size)
66 {
67     auxiliaryPictureInfo_.size = size;
68 }
69 
GetContentPixel()70 std::shared_ptr<PixelMap> AuxiliaryPicture::GetContentPixel()
71 {
72     return content_;
73 }
74 
SetContentPixel(std::shared_ptr<PixelMap> content)75 void AuxiliaryPicture::SetContentPixel(std::shared_ptr<PixelMap> content)
76 {
77     content_ = content;
78 }
79 
ReadPixels(const uint64_t & bufferSize,uint8_t * dst)80 uint32_t AuxiliaryPicture::ReadPixels(const uint64_t &bufferSize, uint8_t *dst)
81 {
82     if (content_ == nullptr) {
83         return ERR_MEDIA_NULL_POINTER;
84     }
85     return content_->ReadPixels(bufferSize, dst);
86 }
87 
WritePixels(const uint8_t * source,const uint64_t & bufferSize)88 uint32_t AuxiliaryPicture::WritePixels(const uint8_t *source, const uint64_t &bufferSize)
89 {
90     if (content_ == nullptr) {
91         return ERR_MEDIA_NULL_POINTER;
92     }
93     return content_->WritePixels(source, bufferSize);
94 }
95 
GetMetadata(MetadataType type)96 std::shared_ptr<ImageMetadata> AuxiliaryPicture::GetMetadata(MetadataType type)
97 {
98     auto iter = metadatas_.find(type);
99     if (iter == metadatas_.end()) {
100         return nullptr;
101     }
102     return iter->second;
103 }
104 
SetMetadata(MetadataType type,std::shared_ptr<ImageMetadata> metadata)105 void AuxiliaryPicture::SetMetadata(MetadataType type, std::shared_ptr<ImageMetadata> metadata)
106 {
107     if (metadatas_.size() >= MAX_PICTURE_META_TYPE_COUNT) {
108         IMAGE_LOGE("Failed to set metadata, the size of metadata exceeds the maximum limit %{public}llu.",
109             static_cast<unsigned long long>(MAX_PICTURE_META_TYPE_COUNT));
110         return;
111     }
112     if (metadata != nullptr) {
113         metadatas_[type] = metadata;
114     }
115 }
116 
HasMetadata(MetadataType type)117 bool AuxiliaryPicture::HasMetadata(MetadataType type)
118 {
119     auto item = metadatas_.find(type);
120     return item != metadatas_.end() && item->second != nullptr;
121 }
122 
WriteAuxPictureInfoToParcel(Parcel & data) const123 bool AuxiliaryPicture::WriteAuxPictureInfoToParcel(Parcel &data) const
124 {
125     if (!data.WriteInt32(static_cast<int32_t>(auxiliaryPictureInfo_.auxiliaryPictureType))) {
126         IMAGE_LOGE("Failed to write type of auxiliary pictures.");
127         return false;
128     }
129 
130     if (!data.WriteInt32(static_cast<int32_t>(auxiliaryPictureInfo_.colorSpace))) {
131         IMAGE_LOGE("Failed to write color space of auxiliary pictures.");
132         return false;
133     }
134 
135     if (!data.WriteInt32(static_cast<int32_t>(auxiliaryPictureInfo_.pixelFormat))) {
136         IMAGE_LOGE("Failed to write pixel format of auxiliary pictures.");
137         return false;
138     }
139 
140     if (!data.WriteUint32(auxiliaryPictureInfo_.rowStride)) {
141         IMAGE_LOGE("Failed to write row stride of auxiliary pictures.");
142         return false;
143     }
144 
145     if (!data.WriteInt32(auxiliaryPictureInfo_.size.height) || !data.WriteInt32(auxiliaryPictureInfo_.size.width)) {
146         IMAGE_LOGE("Failed to write size of auxiliary pictures.");
147         return false;
148     }
149 
150     if (auxiliaryPictureInfo_.jpegTagName.length() > MAX_JPEG_TAG_NAME_LENGTH) {
151         IMAGE_LOGE("The length of jpeg tag name exceeds the maximum limit.");
152         return false;
153     }
154 
155     if (!data.WriteString(auxiliaryPictureInfo_.jpegTagName)) {
156         IMAGE_LOGE("Failed to write jpegTagName of auxiliary pictures.");
157         return false;
158     }
159 
160     return true;
161 }
162 
Marshalling(Parcel & data) const163 bool AuxiliaryPicture::Marshalling(Parcel &data) const
164 {
165     if (content_ == nullptr) {
166         IMAGE_LOGE("Auxiliary picture is null.");
167         return false;
168     }
169 
170     if (!content_->Marshalling(data)) {
171         IMAGE_LOGE("Failed to marshal auxiliary picture.");
172         return false;
173     }
174 
175     if (!WriteAuxPictureInfoToParcel(data)) {
176         IMAGE_LOGE("write auxiliary picture info to parcel failed.");
177         return false;
178     }
179 
180     if (metadatas_.size() > MAX_PICTURE_META_TYPE_COUNT) {
181         IMAGE_LOGE("The number of metadatas exceeds the maximum limit.");
182         return false;
183     }
184 
185     if (!data.WriteUint64(static_cast<uint64_t>(metadatas_.size()))) {
186         return false;
187     }
188 
189     for (const auto &[type, metadata] : metadatas_) {
190         int32_t typeInt32 = static_cast<int32_t>(type);
191         if (metadata == nullptr) {
192             IMAGE_LOGE("Metadata %{public}d is nullptr.", typeInt32);
193             return false;
194         }
195         if (!(data.WriteInt32(typeInt32) && metadata->Marshalling(data))) {
196             IMAGE_LOGE("Failed to marshal metadatas.");
197             return false;
198         }
199     }
200 
201     return true;
202 }
203 
Unmarshalling(Parcel & data)204 AuxiliaryPicture *AuxiliaryPicture::Unmarshalling(Parcel &data)
205 {
206     PICTURE_ERR error;
207     AuxiliaryPicture* dstAuxiliaryPicture = AuxiliaryPicture::Unmarshalling(data, error);
208     if (dstAuxiliaryPicture == nullptr || error.errorCode != SUCCESS) {
209         IMAGE_LOGE("unmarshalling failed errorCode:%{public}d, errorInfo:%{public}s",
210             error.errorCode, error.errorInfo.c_str());
211     }
212     return dstAuxiliaryPicture;
213 }
214 
Unmarshalling(Parcel & parcel,PICTURE_ERR & error)215 AuxiliaryPicture *AuxiliaryPicture::Unmarshalling(Parcel &parcel, PICTURE_ERR &error)
216 {
217     std::unique_ptr<AuxiliaryPicture> auxPtr = std::make_unique<AuxiliaryPicture>();
218 
219     std::shared_ptr<PixelMap> contentPtr(PixelMap::Unmarshalling(parcel));
220     if (!contentPtr) {
221         return nullptr;
222     }
223     auxPtr->SetContentPixel(contentPtr);
224     AuxiliaryPictureInfo auxiliaryPictureInfo;
225     auxiliaryPictureInfo.auxiliaryPictureType = static_cast<AuxiliaryPictureType>(parcel.ReadInt32());
226     auxiliaryPictureInfo.colorSpace = static_cast<ColorSpace>(parcel.ReadInt32());
227     auxiliaryPictureInfo.pixelFormat = static_cast<PixelFormat>(parcel.ReadInt32());
228     auxiliaryPictureInfo.rowStride = parcel.ReadUint32();
229     auxiliaryPictureInfo.size.height = parcel.ReadInt32();
230     auxiliaryPictureInfo.size.width = parcel.ReadInt32();
231     auxiliaryPictureInfo.jpegTagName = parcel.ReadString();
232     auxPtr->SetAuxiliaryPictureInfo(auxiliaryPictureInfo);
233 
234     std::map<MetadataType, std::shared_ptr<ImageMetadata>> metadatas;
235 
236     uint64_t size = parcel.ReadUint64();
237     if (size > MAX_PICTURE_META_TYPE_COUNT) {
238         return nullptr;
239     }
240 
241     for (size_t i = 0; i < size; ++i) {
242         MetadataType type = static_cast<MetadataType>(parcel.ReadInt32());
243         std::shared_ptr<ImageMetadata> imagedataPtr(nullptr);
244 
245         if (type == MetadataType::EXIF) {
246             imagedataPtr.reset(ExifMetadata::Unmarshalling(parcel));
247             if (!imagedataPtr) {
248                 return nullptr;
249             }
250         } else if (type == MetadataType::FRAGMENT) {
251             imagedataPtr.reset(FragmentMetadata::Unmarshalling(parcel));
252             if (!imagedataPtr) {
253                 return nullptr;
254             }
255         } else {
256             IMAGE_LOGE("Unsupported metadata type.");
257             return nullptr;
258         }
259         auxPtr->SetMetadata(type, imagedataPtr);
260     }
261 
262     return auxPtr.release();
263 }
264 
GetAuxiliaryPictureInfo()265 AuxiliaryPictureInfo AuxiliaryPicture::GetAuxiliaryPictureInfo()
266 {
267     return auxiliaryPictureInfo_;
268 }
269 
SetAuxiliaryPictureInfo(const AuxiliaryPictureInfo & auxiliaryPictureInfo)270 uint32_t AuxiliaryPicture::SetAuxiliaryPictureInfo(const AuxiliaryPictureInfo &auxiliaryPictureInfo)
271 {
272     int32_t apiVersion = ImageUtils::GetAPIVersion();
273     IMAGE_LOGI("%{public}s current apiVersion: %{public}d", __func__, apiVersion);
274     if (apiVersion > APIVERSION_13) {
275         if (content_ == nullptr) {
276             IMAGE_LOGE("%{public}s pixelmap is nullptr", __func__);
277             return ERR_MEDIA_NULL_POINTER;
278         }
279         if (!ImageUtils::IsValidAuxiliaryInfo(content_, auxiliaryPictureInfo)) {
280             IMAGE_LOGE("%{public}s invalid auxiliary picture info", __func__);
281             return ERR_IMAGE_INVALID_PARAMETER;
282         }
283         ImageInfo imageInfo;
284         content_->GetImageInfo(imageInfo);
285         imageInfo.size = auxiliaryPictureInfo.size;
286         imageInfo.pixelFormat = auxiliaryPictureInfo.pixelFormat;
287         imageInfo.colorSpace = auxiliaryPictureInfo.colorSpace;
288         uint32_t err = content_->SetImageInfo(imageInfo, true);
289         if (err != SUCCESS) {
290             IMAGE_LOGE("%{public}s sync info to pixelmap failed", __func__);
291             return err;
292         }
293     }
294     auxiliaryPictureInfo_ = auxiliaryPictureInfo;
295     return SUCCESS;
296 }
297 
298 } // namespace Media
299 } // namespace OHOS