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