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