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 "exif_metadata.h"
21 #include "fragment_metadata.h"
22 
23 namespace OHOS {
24 namespace Media {
25 
26 const static uint64_t MAX_PICTURE_META_TYPE_COUNT = 64;
~AuxiliaryPicture()27 AuxiliaryPicture::~AuxiliaryPicture() {}
28 
Create(std::shared_ptr<PixelMap> &content, AuxiliaryPictureType type, Size size)29 std::unique_ptr<AuxiliaryPicture> AuxiliaryPicture::Create(std::shared_ptr<PixelMap> &content,
30                                                            AuxiliaryPictureType type, Size size)
31 {
32     if (content == nullptr) {
33         return nullptr;
34     }
35     std::unique_ptr<AuxiliaryPicture> dstAuxPicture = std::make_unique<AuxiliaryPicture>();
36     dstAuxPicture->content_ = content;
37     dstAuxPicture->SetType(type);
38     dstAuxPicture->SetSize(size);
39     return dstAuxPicture;
40 }
41 
Create(sptr<SurfaceBuffer> &surfaceBuffer, AuxiliaryPictureType type, Size size)42 std::unique_ptr<AuxiliaryPicture> AuxiliaryPicture::Create(sptr<SurfaceBuffer> &surfaceBuffer,
43                                                            AuxiliaryPictureType type, Size size)
44 {
45     std::shared_ptr<PixelMap> pixelMap = Picture::SurfaceBuffer2PixelMap(surfaceBuffer);
46     return Create(pixelMap, type, size);
47 }
48 
GetType()49 AuxiliaryPictureType AuxiliaryPicture::GetType()
50 {
51     return auxiliaryPictureInfo_.auxiliaryPictureType;
52 }
53 
SetType(AuxiliaryPictureType type)54 void AuxiliaryPicture::SetType(AuxiliaryPictureType type)
55 {
56     auxiliaryPictureInfo_.auxiliaryPictureType = type;
57 }
58 
GetSize()59 Size AuxiliaryPicture::GetSize()
60 {
61     return auxiliaryPictureInfo_.size;
62 }
63 
SetSize(Size size)64 void AuxiliaryPicture::SetSize(Size size)
65 {
66     auxiliaryPictureInfo_.size = size;
67 }
68 
GetContentPixel()69 std::shared_ptr<PixelMap> AuxiliaryPicture::GetContentPixel()
70 {
71     return content_;
72 }
73 
SetContentPixel(std::shared_ptr<PixelMap> content)74 void AuxiliaryPicture::SetContentPixel(std::shared_ptr<PixelMap> content)
75 {
76     content_ = content;
77 }
78 
ReadPixels(const uint64_t &bufferSize, uint8_t *dst)79 uint32_t AuxiliaryPicture::ReadPixels(const uint64_t &bufferSize, uint8_t *dst)
80 {
81     if (content_ == nullptr) {
82         return ERR_MEDIA_NULL_POINTER;
83     }
84     return content_->ReadPixels(bufferSize, dst);
85 }
86 
WritePixels(const uint8_t *source, const uint64_t &bufferSize)87 uint32_t AuxiliaryPicture::WritePixels(const uint8_t *source, const uint64_t &bufferSize)
88 {
89     if (content_ == nullptr) {
90         return ERR_MEDIA_NULL_POINTER;
91     }
92     return content_->WritePixels(source, bufferSize);
93 }
94 
GetMetadata(MetadataType type)95 std::shared_ptr<ImageMetadata> AuxiliaryPicture::GetMetadata(MetadataType type)
96 {
97     auto iter = metadatas_.find(type);
98     if (iter == metadatas_.end()) {
99         return nullptr;
100     }
101     return iter->second;
102 }
103 
SetMetadata(MetadataType type, std::shared_ptr<ImageMetadata> metadata)104 void AuxiliaryPicture::SetMetadata(MetadataType type, std::shared_ptr<ImageMetadata> metadata)
105 {
106     metadatas_[type] = metadata;
107 }
108 
HasMetadata(MetadataType type)109 bool AuxiliaryPicture::HasMetadata(MetadataType type)
110 {
111     return metadatas_.find(type) != metadatas_.end();
112 }
113 
Marshalling(Parcel &data) const114 bool AuxiliaryPicture::Marshalling(Parcel &data) const
115 {
116     if (content_ == nullptr) {
117         IMAGE_LOGE("Auxiliary picture is null.");
118         return false;
119     }
120 
121     if (!content_->Marshalling(data)) {
122         IMAGE_LOGE("Failed to marshal auxiliary picture.");
123         return false;
124     }
125 
126     if (!data.WriteInt32(static_cast<int32_t>(auxiliaryPictureInfo_.auxiliaryPictureType))) {
127         IMAGE_LOGE("Failed to write type of auxiliary pictures.");
128         return false;
129     }
130 
131     if (!data.WriteInt32(static_cast<int32_t>(auxiliaryPictureInfo_.colorSpace))) {
132         IMAGE_LOGE("Failed to write color space of auxiliary pictures.");
133         return false;
134     }
135 
136     if (!data.WriteInt32(static_cast<int32_t>(auxiliaryPictureInfo_.pixelFormat))) {
137         IMAGE_LOGE("Failed to write pixel format of auxiliary pictures.");
138         return false;
139     }
140 
141     if (!data.WriteInt32(auxiliaryPictureInfo_.rowStride)) {
142         IMAGE_LOGE("Failed to write row stride of auxiliary pictures.");
143         return false;
144     }
145 
146     if (!data.WriteInt32(auxiliaryPictureInfo_.size.height) || !data.WriteInt32(auxiliaryPictureInfo_.size.width)) {
147         IMAGE_LOGE("Failed to write size of auxiliary pictures.");
148         return false;
149     }
150 
151     if (!data.WriteString(auxiliaryPictureInfo_.jpegTagName)) {
152         IMAGE_LOGE("Failed to write jpegTagName of auxiliary pictures.");
153         return false;
154     }
155 
156     if (!data.WriteUint64(static_cast<uint64_t>(metadatas_.size()))) {
157         return false;
158     }
159 
160     for (const auto &metadata : metadatas_) {
161         if (!(data.WriteInt32(static_cast<int32_t>(metadata.first)) && metadata.second->Marshalling(data))) {
162             IMAGE_LOGE("Failed to marshal metadatas.");
163             return false;
164         }
165     }
166 
167     return true;
168 }
169 
Unmarshalling(Parcel &data)170 AuxiliaryPicture *AuxiliaryPicture::Unmarshalling(Parcel &data)
171 {
172     PICTURE_ERR error;
173     AuxiliaryPicture* dstAuxiliaryPicture = AuxiliaryPicture::Unmarshalling(data, error);
174     if (dstAuxiliaryPicture == nullptr || error.errorCode != SUCCESS) {
175         IMAGE_LOGE("unmarshalling failed errorCode:%{public}d, errorInfo:%{public}s",
176             error.errorCode, error.errorInfo.c_str());
177     }
178     return dstAuxiliaryPicture;
179 }
180 
Unmarshalling(Parcel &parcel, PICTURE_ERR &error)181 AuxiliaryPicture *AuxiliaryPicture::Unmarshalling(Parcel &parcel, PICTURE_ERR &error)
182 {
183     std::unique_ptr<AuxiliaryPicture> auxPtr = std::make_unique<AuxiliaryPicture>();
184 
185     std::shared_ptr<PixelMap> contentPtr(PixelMap::Unmarshalling(parcel));
186     if (!contentPtr) {
187         return nullptr;
188     }
189     auxPtr->SetContentPixel(contentPtr);
190     AuxiliaryPictureInfo auxiliaryPictureInfo;
191     auxiliaryPictureInfo.auxiliaryPictureType = static_cast<AuxiliaryPictureType>(parcel.ReadInt32());
192     auxiliaryPictureInfo.colorSpace = static_cast<ColorSpace>(parcel.ReadInt32());
193     auxiliaryPictureInfo.pixelFormat = static_cast<PixelFormat>(parcel.ReadInt32());
194     auxiliaryPictureInfo.rowStride = parcel.ReadUint32();
195     auxiliaryPictureInfo.size.height = parcel.ReadInt32();
196     auxiliaryPictureInfo.size.width = parcel.ReadInt32();
197     auxiliaryPictureInfo.jpegTagName = parcel.ReadString();
198     auxPtr->SetAuxiliaryPictureInfo(auxiliaryPictureInfo);
199 
200     std::map<MetadataType, std::shared_ptr<ImageMetadata>> metadatas;
201 
202     uint64_t size = parcel.ReadUint64();
203     if (size > MAX_PICTURE_META_TYPE_COUNT) {
204         return nullptr;
205     }
206     for (size_t i = 0; i < size; ++i) {
207         MetadataType type = static_cast<MetadataType>(parcel.ReadInt32());
208         std::shared_ptr<ImageMetadata> imagedataPtr(nullptr);
209 
210         if (type == MetadataType::EXIF) {
211             imagedataPtr.reset(ExifMetadata::Unmarshalling(parcel));
212             if (!imagedataPtr) {
213                 return nullptr;
214             }
215         } else if (type == MetadataType::FRAGMENT) {
216             imagedataPtr.reset(FragmentMetadata::Unmarshalling(parcel));
217             if (!imagedataPtr) {
218                 return nullptr;
219             }
220         } else {
221             IMAGE_LOGE("Unsupported metadata type.");
222             return nullptr;
223         }
224         auxPtr->SetMetadata(type, imagedataPtr);
225     }
226 
227     return auxPtr.release();
228 }
229 
GetAuxiliaryPictureInfo()230 AuxiliaryPictureInfo AuxiliaryPicture::GetAuxiliaryPictureInfo()
231 {
232     return auxiliaryPictureInfo_;
233 }
234 
SetAuxiliaryPictureInfo(const AuxiliaryPictureInfo &auxiliaryPictureInfo)235 void AuxiliaryPicture::SetAuxiliaryPictureInfo(const AuxiliaryPictureInfo &auxiliaryPictureInfo)
236 {
237     auxiliaryPictureInfo_ = auxiliaryPictureInfo;
238 }
239 
240 } // namespace Media
241 } // namespace OHOS