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