1 /*
2 * Copyright (c) 2025 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 "dfx_report.h"
17 #include "picture_adapter.h"
18 #include "camera_log.h"
19 #include "image_format.h"
20 #include "image_mime_type.h"
21 #include "image_type.h"
22 #include "ipc_skeleton.h"
23 #include "picture.h"
24 #include "pixel_map.h"
25 #include "surface_buffer.h"
26 #include "securec.h"
27 #include <algorithm>
28 #include <cstdint>
29 namespace OHOS {
30 namespace CameraStandard {
31 std::unordered_map<std::string, float> exifOrientationDegree = {
32 {"Top-left", 0},
33 {"Top-right", 90},
34 {"Bottom-right", 180},
35 {"Right-top", 90},
36 {"Left-bottom", 270},
37 };
38
TransExifOrientationToDegree(const std::string & orientation)39 float TransExifOrientationToDegree(const std::string& orientation)
40 {
41 float degree = .0;
42 if (exifOrientationDegree.count(orientation)) {
43 degree = exifOrientationDegree[orientation];
44 }
45 return degree;
46 }
47
RotatePixelMap(std::shared_ptr<Media::PixelMap> pixelMap,const std::string & exifOrientation)48 inline void RotatePixelMap(std::shared_ptr<Media::PixelMap> pixelMap, const std::string& exifOrientation)
49 {
50 float degree = TransExifOrientationToDegree(exifOrientation);
51 if (pixelMap) {
52 DECORATOR_HILOG(HILOG_INFO, "RotatePicture degree is %{public}f", degree);
53 pixelMap->rotate(degree);
54 } else {
55 DECORATOR_HILOG(HILOG_ERROR, "RotatePicture degree is %{public}f", degree);
56 }
57 }
58
GetAndSetExifOrientation(OHOS::Media::ImageMetadata * exifData)59 std::string GetAndSetExifOrientation(OHOS::Media::ImageMetadata* exifData)
60 {
61 std::string orientation = "";
62 if (exifData != nullptr) {
63 exifData->GetValue("Orientation", orientation);
64 std::string defalutExifOrientation = "1";
65 exifData->SetValue("Orientation", defalutExifOrientation);
66 DECORATOR_HILOG(HILOG_INFO, "GetExifOrientation orientation:%{public}s", orientation.c_str());
67 exifData->RemoveExifThumbnail();
68 MEDIA_INFO_LOG("RemoveExifThumbnail");
69 } else {
70 DECORATOR_HILOG(HILOG_ERROR, "GetExifOrientation exifData is nullptr");
71 }
72 return orientation;
73 }
74
PictureAdapter()75 PictureAdapter::PictureAdapter() : picture_(nullptr)
76 {
77 MEDIA_INFO_LOG("PictureAdapter ctor");
78 }
79
~PictureAdapter()80 PictureAdapter::~PictureAdapter()
81 {
82 MEDIA_INFO_LOG("PictureAdapter dctor");
83 }
84
Create(sptr<SurfaceBuffer> & surfaceBuffer)85 void PictureAdapter::Create(sptr<SurfaceBuffer> &surfaceBuffer)
86 {
87 MEDIA_INFO_LOG("PictureAdapter ctor");
88 picture_ = Media::Picture::Create(surfaceBuffer);
89 CHECK_EXECUTE(!picture_,
90 CameraReportUtils::GetInstance().ReportCameraCreateNullptr(
91 "PictureAdapter::Create", "Media::Picture::Create"));
92 }
93
SetAuxiliaryPicture(sptr<SurfaceBuffer> & surfaceBuffer,CameraAuxiliaryPictureType type)94 void PictureAdapter::SetAuxiliaryPicture(sptr<SurfaceBuffer> &surfaceBuffer, CameraAuxiliaryPictureType type)
95 {
96 MEDIA_INFO_LOG("PictureAdapter::SetAuxiliaryPicture enter");
97 std::shared_ptr<Media::Picture> picture = GetPicture();
98 CHECK_RETURN_ELOG(!picture, "PictureAdapter::SetAuxiliaryPicture picture is nullptr");
99 std::unique_ptr<Media::AuxiliaryPicture> uniptr = Media::AuxiliaryPicture::Create(
100 surfaceBuffer, static_cast<Media::AuxiliaryPictureType>(type));
101 std::shared_ptr<Media::AuxiliaryPicture> picturePtr = std::move(uniptr);
102 picture->SetAuxiliaryPicture(picturePtr);
103 }
104
CopyMetaData(sptr<SurfaceBuffer> & inBuffer,sptr<SurfaceBuffer> & outBuffer)105 void CopyMetaData(sptr<SurfaceBuffer> &inBuffer, sptr<SurfaceBuffer> &outBuffer)
106 {
107 std::vector<uint32_t> keys = {};
108 CHECK_RETURN_ELOG(inBuffer == nullptr, "CopyMetaData: inBuffer is nullptr");
109 auto ret = inBuffer->ListMetadataKeys(keys);
110 CHECK_RETURN_ELOG(ret != GSError::GSERROR_OK,
111 "CopyMetaData: ListMetadataKeys fail! res=%{public}d", ret);
112 for (uint32_t key : keys) {
113 std::vector<uint8_t> values;
114 ret = inBuffer->GetMetadata(key, values);
115 CHECK_CONTINUE_ILOG(ret != 0, "GetMetadata fail! key = %{public}d res = %{public}d", key, ret);
116 ret = outBuffer->SetMetadata(key, values);
117 CHECK_CONTINUE_ILOG(ret != 0, "SetMetadata fail! key = %{public}d res = %{public}d", key, ret);
118 }
119 }
120
CreateWithDeepCopySurfaceBuffer(sptr<SurfaceBuffer> & surfaceBuffer)121 void PictureAdapter::CreateWithDeepCopySurfaceBuffer(sptr<SurfaceBuffer> &surfaceBuffer)
122 {
123 MEDIA_INFO_LOG("PictureAdapter CreateWithDeepCopySurfaceBuffer");
124 BufferRequestConfig requestConfig = {
125 .width = surfaceBuffer->GetWidth(),
126 .height = surfaceBuffer->GetHeight(),
127 .strideAlignment = surfaceBuffer->GetStride(),
128 .format = surfaceBuffer->GetFormat(),
129 .usage = surfaceBuffer->GetUsage(),
130 .timeout = 0,
131 .colorGamut = surfaceBuffer->GetSurfaceBufferColorGamut(),
132 .transform = surfaceBuffer->GetSurfaceBufferTransform(),
133 };
134 sptr<SurfaceBuffer> newSurfaceBuffer = SurfaceBuffer::Create();
135 CHECK_RETURN_ELOG(!newSurfaceBuffer,
136 "PictureAdapter::CreateWithDeepCopySurfaceBuffer newSurfaceBuffer is nullptr");
137 auto allocErrorCode = newSurfaceBuffer->Alloc(requestConfig);
138 MEDIA_INFO_LOG("PictureAdapter::CreateWithDeepCopySurfaceBuffer SurfaceBuffer alloc ret: %{public}d",
139 allocErrorCode);
140 unsigned char* dst = static_cast<unsigned char*>(newSurfaceBuffer->GetVirAddr());
141 unsigned char* src = static_cast<unsigned char*>(surfaceBuffer->GetVirAddr());
142 for (int32_t i = 0; i < surfaceBuffer->GetHeight() * PIXEL_SIZE_HDR_YUV / HDR_PIXEL_SIZE; i++) {
143 errno_t errNo = memcpy_s(dst, surfaceBuffer->GetWidth(), src, surfaceBuffer->GetWidth());
144 if (errNo != EOK) {
145 MEDIA_ERR_LOG("PictureAdapter memcpy_s failed, errNo = %{public}d", static_cast<int32_t>(errNo));
146 return;
147 }
148 dst += surfaceBuffer->GetWidth();
149 src += surfaceBuffer->GetStride();
150 }
151 CopyMetaData(surfaceBuffer, newSurfaceBuffer);
152 picture_ = Media::Picture::Create(newSurfaceBuffer);
153 }
154
Marshalling(Parcel & data) const155 bool PictureAdapter::Marshalling(Parcel &data) const
156 {
157 MEDIA_INFO_LOG("PictureAdapter::Marshalling enter");
158 std::shared_ptr<Media::Picture> picture = GetPicture();
159 CHECK_RETURN_RET_ELOG(!picture, false, "PictureAdapter::Marshalling picture is nullptr");
160 bool isMarshalling = picture->Marshalling(data);
161 CHECK_EXECUTE(isMarshalling == false, CameraReportUtils::GetInstance().ReportCameraFalse(
162 "PictureAdapter::Marshalling", "Media::Picture::Marshalling"));
163 return isMarshalling;
164 }
165
UnmarshallingPicture(Parcel & data)166 void PictureAdapter::UnmarshallingPicture(Parcel &data)
167 {
168 MEDIA_INFO_LOG("PictureAdapter::Unmarshalling enter");
169 picture_.reset(Media::Picture::Unmarshalling(data));
170 }
171
SetExifMetadata(sptr<SurfaceBuffer> & surfaceBuffer)172 int32_t PictureAdapter::SetExifMetadata(sptr<SurfaceBuffer> &surfaceBuffer)
173 {
174 MEDIA_DEBUG_LOG("PictureAdapter::SetExifMetadata enter");
175 int32_t retCode = -1;
176 std::shared_ptr<Media::Picture> picture = GetPicture();
177 CHECK_RETURN_RET_ELOG(!picture, retCode, "PictureAdapter::SetExifMetadata picture is nullptr");
178 retCode = static_cast<int32_t>(picture->SetExifMetadata(surfaceBuffer));
179 CHECK_EXECUTE(retCode != 0, CameraReportUtils::GetInstance().ReportCameraError<int32_t>(
180 "PictureAdapter::SetExifMetadata", "Media::Picture::SetExifMetadata", retCode));
181 MEDIA_INFO_LOG("PictureAdapter::SetExifMetadata retCode:%{public}d", retCode);
182 return retCode;
183 }
184
SetMaintenanceData(sptr<SurfaceBuffer> & surfaceBuffer)185 bool PictureAdapter::SetMaintenanceData(sptr<SurfaceBuffer> &surfaceBuffer)
186 {
187 bool retCode = false;
188 std::shared_ptr<Media::Picture> picture = GetPicture();
189 CHECK_RETURN_RET_ELOG(!picture, retCode, "PictureAdapter::SetMaintenanceData picture is nullptr");
190 retCode = picture->SetMaintenanceData(surfaceBuffer);
191 CHECK_EXECUTE(retCode == false, CameraReportUtils::GetInstance().ReportCameraFalse(
192 "PictureAdapter::SetMaintenanceData", "Media::Picture::SetMaintenanceData"));
193 return retCode;
194 }
195
RotatePicture()196 void PictureAdapter::RotatePicture()
197 {
198 MEDIA_DEBUG_LOG("PictureAdapter::RotatePicture E");
199 std::shared_ptr<Media::Picture> picture = GetPicture();
200 CHECK_RETURN_ELOG(!picture, "PictureAdapter::RotatePicture picture is nullptr");
201 std::string orientation = GetAndSetExifOrientation(
202 reinterpret_cast<OHOS::Media::ImageMetadata*>(picture->GetExifMetadata().get()));
203 RotatePixelMap(picture->GetMainPixel(), orientation);
204 MEDIA_INFO_LOG("PictureAdapter::RotatePicture orientation:%{public}s", orientation.c_str());
205 auto gainMap = picture->GetAuxiliaryPicture(Media::AuxiliaryPictureType::GAINMAP);
206 if (gainMap) {
207 RotatePixelMap(gainMap->GetContentPixel(), orientation);
208 }
209 auto depthMap = picture->GetAuxiliaryPicture(Media::AuxiliaryPictureType::DEPTH_MAP);
210 if (depthMap) {
211 RotatePixelMap(depthMap->GetContentPixel(), orientation);
212 }
213 auto unrefocusMap = picture->GetAuxiliaryPicture(Media::AuxiliaryPictureType::UNREFOCUS_MAP);
214 if (unrefocusMap) {
215 RotatePixelMap(unrefocusMap->GetContentPixel(), orientation);
216 }
217 auto linearMap = picture->GetAuxiliaryPicture(Media::AuxiliaryPictureType::LINEAR_MAP);
218 if (linearMap) {
219 RotatePixelMap(linearMap->GetContentPixel(), orientation);
220 }
221 MEDIA_INFO_LOG("PictureAdapter::RotatePicture X");
222 }
223
GetPicture() const224 std::shared_ptr<Media::Picture> PictureAdapter::GetPicture() const
225 {
226 return picture_;
227 }
228
createPictureAdapterIntf()229 extern "C" PictureIntf *createPictureAdapterIntf()
230 {
231 return new PictureAdapter();
232 }
233
234 } // namespace AVSession
235 } // namespace OHOS