• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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