• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2021 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 "image_format_convert.h"
17 #ifdef EXT_PIXEL
18 #include "pixel_yuv_ext.h"
19 #endif
20 
21 #include <map>
22 #include <memory>
23 #include "hilog/log.h"
24 #include "image_format_convert_ext_utils.h"
25 #include "image_log.h"
26 #include "image_source.h"
27 #include "log_tags.h"
28 #include "media_errors.h"
29 #include "pixel_yuv.h"
30 #if !defined(_WIN32) && !defined(_APPLE) && !defined(IOS_PLATFORM) && !defined(ANDROID_PLATFORM)
31 #include "v1_0/buffer_handle_meta_key_type.h"
32 #include "v1_0/cm_color_space.h"
33 #include "v1_0/hdr_static_metadata.h"
34 #include "surface_buffer.h"
35 #endif
36 #include "vpe_utils.h"
37 #include "image_utils.h"
38 
39 namespace {
40     constexpr uint8_t NUM_0 = 0;
41     constexpr uint8_t NUM_1 = 1;
42     constexpr uint8_t NUM_2 = 2;
43     constexpr uint8_t NUM_3 = 3;
44     constexpr uint8_t NUM_4 = 4;
45     constexpr uint8_t NUM_8 = 8;
46     constexpr uint8_t PLANE_Y = 0;
47     constexpr uint8_t PLANE_U = 1;
48     constexpr uint8_t PLANE_V = 2;
49     constexpr uint32_t BYTES_PER_PIXEL_RGB565 = 2;
50     constexpr uint32_t BYTES_PER_PIXEL_RGB = 3;
51     constexpr uint32_t BYTES_PER_PIXEL_RGBA = 4;
52     constexpr uint32_t BYTES_PER_PIXEL_BGRA = 4;
53     constexpr uint32_t STRIDES_PER_PLANE = 8;
54 }
55 
56 #undef LOG_DOMAIN
57 #define LOG_DOMAIN LOG_TAG_DOMAIN_ID_IMAGE
58 
59 #undef LOG_TAG
60 #define LOG_TAG "ImageFormatConvert"
61 
62 namespace OHOS {
63 namespace Media {
64 #if !defined(_WIN32) && !defined(_APPLE) && !defined(IOS_PLATFORM) && !defined(ANDROID_PLATFORM)
65 using namespace HDI::Display::Graphic::Common::V1_0;
66 #endif
67 
__anon6e213fcc0202() 68 static const std::map<std::pair<PixelFormat, PixelFormat>, ConvertFunction> g_cvtFuncMap = []() {
69 #ifndef EXT_PIXEL
70     static const std::map<std::pair<PixelFormat, PixelFormat>, ConvertFunction> cvtFuncMap = {
71         {std::make_pair(PixelFormat::RGB_565, PixelFormat::NV21), ImageFormatConvertUtils::RGB565ToNV21},
72         {std::make_pair(PixelFormat::RGB_565, PixelFormat::NV12), ImageFormatConvertUtils::RGB565ToNV12},
73         {std::make_pair(PixelFormat::RGBA_8888, PixelFormat::NV21), ImageFormatConvertUtils::RGBAToNV21},
74         {std::make_pair(PixelFormat::RGBA_8888, PixelFormat::NV12), ImageFormatConvertUtils::RGBAToNV12},
75         {std::make_pair(PixelFormat::BGRA_8888, PixelFormat::NV21), ImageFormatConvertUtils::BGRAToNV21},
76         {std::make_pair(PixelFormat::BGRA_8888, PixelFormat::NV12), ImageFormatConvertUtils::BGRAToNV12},
77         {std::make_pair(PixelFormat::RGB_888, PixelFormat::NV21), ImageFormatConvertUtils::RGBToNV21},
78         {std::make_pair(PixelFormat::RGB_888, PixelFormat::NV12), ImageFormatConvertUtils::RGBToNV12},
79         {std::make_pair(PixelFormat::RGBA_F16, PixelFormat::NV21), ImageFormatConvertUtils::RGBAF16ToNV21},
80         {std::make_pair(PixelFormat::RGBA_F16, PixelFormat::NV12), ImageFormatConvertUtils::RGBAF16ToNV12},
81         {std::make_pair(PixelFormat::RGB_565, PixelFormat::YCBCR_P010), ImageFormatConvertUtils::RGB565ToNV12P010},
82         {std::make_pair(PixelFormat::RGB_565, PixelFormat::YCRCB_P010), ImageFormatConvertUtils::RGB565ToNV21P010},
83         {std::make_pair(PixelFormat::RGBA_8888, PixelFormat::YCBCR_P010), ImageFormatConvertUtils::RGBAToNV12P010},
84         {std::make_pair(PixelFormat::RGBA_8888, PixelFormat::YCRCB_P010), ImageFormatConvertUtils::RGBAToNV21P010},
85         {std::make_pair(PixelFormat::BGRA_8888, PixelFormat::YCBCR_P010), ImageFormatConvertUtils::BGRAToNV12P010},
86         {std::make_pair(PixelFormat::BGRA_8888, PixelFormat::YCRCB_P010), ImageFormatConvertUtils::BGRAToNV21P010},
87         {std::make_pair(PixelFormat::RGB_888, PixelFormat::YCBCR_P010), ImageFormatConvertUtils::RGBToNV12P010},
88         {std::make_pair(PixelFormat::RGB_888, PixelFormat::YCRCB_P010), ImageFormatConvertUtils::RGBToNV21P010},
89         {std::make_pair(PixelFormat::RGBA_F16, PixelFormat::YCBCR_P010), ImageFormatConvertUtils::RGBAF16ToNV12P010},
90         {std::make_pair(PixelFormat::RGBA_F16, PixelFormat::YCRCB_P010), ImageFormatConvertUtils::RGBAF16ToNV21P010},
91         {std::make_pair(PixelFormat::RGBA_1010102, PixelFormat::NV12), ImageFormatConvertUtils::RGBA1010102ToNV12},
92         {std::make_pair(PixelFormat::RGBA_1010102, PixelFormat::NV21), ImageFormatConvertUtils::RGBA1010102ToNV21},
93         {std::make_pair(PixelFormat::RGBA_1010102, PixelFormat::YCBCR_P010),
94             ImageFormatConvertUtils::RGBA1010102ToNV12P010},
95         {std::make_pair(PixelFormat::RGBA_1010102, PixelFormat::YCRCB_P010),
96             ImageFormatConvertUtils::RGBA1010102ToNV21P010},
97     };
98 #else
99     static const std::map<std::pair<PixelFormat, PixelFormat>, ConvertFunction> cvtFuncMap = {
100         {std::make_pair(PixelFormat::RGB_565, PixelFormat::NV21), ImageFormatConvertExtUtils::RGB565ToNV21},
101         {std::make_pair(PixelFormat::RGB_565, PixelFormat::NV12), ImageFormatConvertExtUtils::RGB565ToNV12},
102         {std::make_pair(PixelFormat::RGBA_8888, PixelFormat::NV21), ImageFormatConvertExtUtils::RGBAToNV21},
103         {std::make_pair(PixelFormat::RGBA_8888, PixelFormat::NV12), ImageFormatConvertExtUtils::RGBAToNV12},
104         {std::make_pair(PixelFormat::BGRA_8888, PixelFormat::NV21), ImageFormatConvertExtUtils::BGRAToNV21},
105         {std::make_pair(PixelFormat::BGRA_8888, PixelFormat::NV12), ImageFormatConvertExtUtils::BGRAToNV12},
106         {std::make_pair(PixelFormat::RGB_888, PixelFormat::NV21), ImageFormatConvertUtils::RGBToNV21},
107         {std::make_pair(PixelFormat::RGB_888, PixelFormat::NV12), ImageFormatConvertUtils::RGBToNV12},
108         {std::make_pair(PixelFormat::RGBA_F16, PixelFormat::NV21), ImageFormatConvertUtils::RGBAF16ToNV21},
109         {std::make_pair(PixelFormat::RGBA_F16, PixelFormat::NV12), ImageFormatConvertUtils::RGBAF16ToNV12},
110         {std::make_pair(PixelFormat::RGB_565, PixelFormat::YCBCR_P010), ImageFormatConvertExtUtils::RGB565ToNV12P010},
111         {std::make_pair(PixelFormat::RGB_565, PixelFormat::YCRCB_P010), ImageFormatConvertExtUtils::RGB565ToNV21P010},
112         {std::make_pair(PixelFormat::RGBA_8888, PixelFormat::YCBCR_P010), ImageFormatConvertExtUtils::RGBAToNV12P010},
113         {std::make_pair(PixelFormat::RGBA_8888, PixelFormat::YCRCB_P010), ImageFormatConvertExtUtils::RGBAToNV21P010},
114         {std::make_pair(PixelFormat::BGRA_8888, PixelFormat::YCBCR_P010), ImageFormatConvertExtUtils::BGRAToNV12P010},
115         {std::make_pair(PixelFormat::BGRA_8888, PixelFormat::YCRCB_P010), ImageFormatConvertExtUtils::BGRAToNV21P010},
116         {std::make_pair(PixelFormat::RGB_888, PixelFormat::YCBCR_P010), ImageFormatConvertExtUtils::RGBToNV12P010},
117         {std::make_pair(PixelFormat::RGB_888, PixelFormat::YCRCB_P010), ImageFormatConvertExtUtils::RGBToNV21P010},
118         {std::make_pair(PixelFormat::RGBA_1010102, PixelFormat::NV12), ImageFormatConvertExtUtils::RGBA1010102ToNV12},
119         {std::make_pair(PixelFormat::RGBA_1010102, PixelFormat::NV21), ImageFormatConvertExtUtils::RGBA1010102ToNV21},
120         {std::make_pair(PixelFormat::RGBA_1010102, PixelFormat::YCBCR_P010),
121             ImageFormatConvertUtils::RGBA1010102ToNV12P010},
122         {std::make_pair(PixelFormat::RGBA_1010102, PixelFormat::YCRCB_P010),
123             ImageFormatConvertUtils::RGBA1010102ToNV21P010},
124         {std::make_pair(PixelFormat::RGBA_F16, PixelFormat::YCBCR_P010), ImageFormatConvertUtils::RGBAF16ToNV12P010},
125         {std::make_pair(PixelFormat::RGBA_F16, PixelFormat::YCRCB_P010), ImageFormatConvertUtils::RGBAF16ToNV21P010},
126     };
127 #endif
128     return cvtFuncMap;
129 }();
130 
__anon6e213fcc0302() 131 static const std::map<std::pair<PixelFormat, PixelFormat>, YUVConvertFunction> g_yuvCvtFuncMap = []() {
132 #ifndef EXT_PIXEL
133     std::map<std::pair<PixelFormat, PixelFormat>, YUVConvertFunction> yuvCvtFuncMap = {
134         {std::make_pair(PixelFormat::NV12, PixelFormat::NV21), ImageFormatConvertUtils::NV12ToNV21},
135         {std::make_pair(PixelFormat::NV12, PixelFormat::RGB_888), ImageFormatConvertUtils::NV12ToRGB},
136         {std::make_pair(PixelFormat::NV12, PixelFormat::RGB_565), ImageFormatConvertUtils::NV12ToRGB565},
137         {std::make_pair(PixelFormat::NV12, PixelFormat::RGBA_F16), ImageFormatConvertUtils::NV12ToRGBAF16},
138         {std::make_pair(PixelFormat::NV12, PixelFormat::RGBA_8888), ImageFormatConvertUtils::NV12ToRGBA},
139         {std::make_pair(PixelFormat::NV12, PixelFormat::BGRA_8888), ImageFormatConvertUtils::NV12ToBGRA},
140         {std::make_pair(PixelFormat::NV21, PixelFormat::NV12), ImageFormatConvertUtils::NV21ToNV12},
141         {std::make_pair(PixelFormat::NV21, PixelFormat::RGB_888), ImageFormatConvertUtils::NV21ToRGB},
142         {std::make_pair(PixelFormat::NV21, PixelFormat::RGB_565), ImageFormatConvertUtils::NV21ToRGB565},
143         {std::make_pair(PixelFormat::NV21, PixelFormat::RGBA_F16), ImageFormatConvertUtils::NV21ToRGBAF16},
144         {std::make_pair(PixelFormat::NV21, PixelFormat::RGBA_8888), ImageFormatConvertUtils::NV21ToRGBA},
145         {std::make_pair(PixelFormat::NV21, PixelFormat::BGRA_8888), ImageFormatConvertUtils::NV21ToBGRA},
146         {std::make_pair(PixelFormat::NV12, PixelFormat::YCBCR_P010), ImageFormatConvertUtils::NV12ToNV12P010},
147         {std::make_pair(PixelFormat::NV12, PixelFormat::YCRCB_P010), ImageFormatConvertUtils::NV12ToNV21P010},
148         {std::make_pair(PixelFormat::NV21, PixelFormat::YCBCR_P010), ImageFormatConvertUtils::NV21ToNV12P010},
149         {std::make_pair(PixelFormat::NV21, PixelFormat::YCRCB_P010), ImageFormatConvertUtils::NV21ToNV21P010},
150         {std::make_pair(PixelFormat::NV12, PixelFormat::RGBA_1010102), ImageFormatConvertUtils::NV12ToRGBA1010102},
151         {std::make_pair(PixelFormat::NV21, PixelFormat::RGBA_1010102), ImageFormatConvertUtils::NV21ToRGBA1010102},
152         {std::make_pair(PixelFormat::YCBCR_P010, PixelFormat::NV12), ImageFormatConvertUtils::NV12P010ToNV12},
153         {std::make_pair(PixelFormat::YCBCR_P010, PixelFormat::NV21), ImageFormatConvertUtils::NV12P010ToNV21},
154         {std::make_pair(PixelFormat::YCBCR_P010, PixelFormat::YCRCB_P010),
155             ImageFormatConvertUtils::NV12P010ToNV21P010},
156         {std::make_pair(PixelFormat::YCBCR_P010, PixelFormat::RGB_565), ImageFormatConvertUtils::NV12P010ToRGB565},
157         {std::make_pair(PixelFormat::YCBCR_P010, PixelFormat::RGBA_8888), ImageFormatConvertUtils::NV12P010ToRGBA8888},
158         {std::make_pair(PixelFormat::YCBCR_P010, PixelFormat::BGRA_8888), ImageFormatConvertUtils::NV12P010ToBGRA8888},
159         {std::make_pair(PixelFormat::YCBCR_P010, PixelFormat::RGB_888), ImageFormatConvertUtils::NV12P010ToRGB888},
160         {std::make_pair(PixelFormat::YCBCR_P010, PixelFormat::RGBA_F16), ImageFormatConvertUtils::NV12P010ToRGBAF16},
161         {std::make_pair(PixelFormat::YCRCB_P010, PixelFormat::NV12), ImageFormatConvertUtils::NV21P010ToNV12},
162         {std::make_pair(PixelFormat::YCRCB_P010, PixelFormat::NV21), ImageFormatConvertUtils::NV21P010ToNV21},
163         {std::make_pair(PixelFormat::YCRCB_P010, PixelFormat::YCBCR_P010),
164             ImageFormatConvertUtils::NV21P010ToNV12P010},
165         {std::make_pair(PixelFormat::YCBCR_P010, PixelFormat::RGBA_1010102),
166             ImageFormatConvertUtils::NV12P010ToRGBA1010102},
167         {std::make_pair(PixelFormat::YCRCB_P010, PixelFormat::RGB_565), ImageFormatConvertUtils::NV21P010ToRGB565},
168         {std::make_pair(PixelFormat::YCRCB_P010, PixelFormat::RGBA_8888), ImageFormatConvertUtils::NV21P010ToRGBA8888},
169         {std::make_pair(PixelFormat::YCRCB_P010, PixelFormat::BGRA_8888), ImageFormatConvertUtils::NV21P010ToBGRA8888},
170         {std::make_pair(PixelFormat::YCRCB_P010, PixelFormat::RGB_888), ImageFormatConvertUtils::NV21P010ToRGB888},
171         {std::make_pair(PixelFormat::YCRCB_P010, PixelFormat::RGBA_F16), ImageFormatConvertUtils::NV21P010ToRGBAF16},
172         {std::make_pair(PixelFormat::YCRCB_P010, PixelFormat::RGBA_1010102),
173             ImageFormatConvertUtils::NV21P010ToRGBA1010102},
174     };
175 #else
176     std::map<std::pair<PixelFormat, PixelFormat>, YUVConvertFunction> yuvCvtFuncMap = {
177         {std::make_pair(PixelFormat::NV21, PixelFormat::RGB_888), ImageFormatConvertExtUtils::NV21ToRGB},
178         {std::make_pair(PixelFormat::NV21, PixelFormat::RGBA_8888), ImageFormatConvertExtUtils::NV21ToRGBA},
179         {std::make_pair(PixelFormat::NV21, PixelFormat::BGRA_8888), ImageFormatConvertExtUtils::NV21ToBGRA},
180         {std::make_pair(PixelFormat::NV21, PixelFormat::RGB_565), ImageFormatConvertExtUtils::NV21ToRGB565},
181         {std::make_pair(PixelFormat::NV12, PixelFormat::RGB_565), ImageFormatConvertExtUtils::NV12ToRGB565},
182         {std::make_pair(PixelFormat::NV21, PixelFormat::NV12), ImageFormatConvertUtils::NV21ToNV12},
183         {std::make_pair(PixelFormat::NV21, PixelFormat::RGBA_F16), ImageFormatConvertUtils::NV21ToRGBAF16},
184         {std::make_pair(PixelFormat::NV12, PixelFormat::NV21), ImageFormatConvertUtils::NV12ToNV21},
185         {std::make_pair(PixelFormat::NV12, PixelFormat::RGBA_F16), ImageFormatConvertUtils::NV12ToRGBAF16},
186         {std::make_pair(PixelFormat::NV12, PixelFormat::RGBA_8888), ImageFormatConvertExtUtils::NV12ToRGBA},
187         {std::make_pair(PixelFormat::NV12, PixelFormat::BGRA_8888), ImageFormatConvertExtUtils::NV12ToBGRA},
188         {std::make_pair(PixelFormat::NV12, PixelFormat::RGB_888), ImageFormatConvertExtUtils::NV12ToRGB},
189         {std::make_pair(PixelFormat::NV12, PixelFormat::RGBA_1010102), ImageFormatConvertExtUtils::NV12ToRGBA1010102},
190         {std::make_pair(PixelFormat::NV21, PixelFormat::RGBA_1010102), ImageFormatConvertExtUtils::NV21ToRGBA1010102},
191         {std::make_pair(PixelFormat::NV12, PixelFormat::YCBCR_P010), ImageFormatConvertExtUtils::NV12ToNV12P010},
192         {std::make_pair(PixelFormat::NV12, PixelFormat::YCRCB_P010), ImageFormatConvertExtUtils::NV12ToNV21P010},
193         {std::make_pair(PixelFormat::NV21, PixelFormat::YCBCR_P010), ImageFormatConvertExtUtils::NV21ToNV12P010},
194         {std::make_pair(PixelFormat::NV21, PixelFormat::YCRCB_P010), ImageFormatConvertExtUtils::NV21ToNV21P010},
195         {std::make_pair(PixelFormat::YCBCR_P010, PixelFormat::NV12), ImageFormatConvertExtUtils::NV12P010ToNV12},
196         {std::make_pair(PixelFormat::YCBCR_P010, PixelFormat::NV21), ImageFormatConvertExtUtils::NV12P010ToNV21},
197         {std::make_pair(PixelFormat::YCBCR_P010, PixelFormat::YCRCB_P010),
198             ImageFormatConvertUtils::NV12P010ToNV21P010},
199         {std::make_pair(PixelFormat::YCBCR_P010, PixelFormat::RGB_565), ImageFormatConvertExtUtils::NV12P010ToRGB565},
200         {std::make_pair(PixelFormat::YCBCR_P010, PixelFormat::RGBA_8888),
201             ImageFormatConvertExtUtils::NV12P010ToRGBA8888},
202         {std::make_pair(PixelFormat::YCBCR_P010, PixelFormat::BGRA_8888),
203             ImageFormatConvertExtUtils::NV12P010ToBGRA8888},
204         {std::make_pair(PixelFormat::YCBCR_P010, PixelFormat::RGB_888), ImageFormatConvertExtUtils::NV12P010ToRGB888},
205         {std::make_pair(PixelFormat::YCBCR_P010, PixelFormat::RGBA_F16), ImageFormatConvertUtils::NV12P010ToRGBAF16},
206         {std::make_pair(PixelFormat::YCRCB_P010, PixelFormat::NV12), ImageFormatConvertExtUtils::NV21P010ToNV12},
207         {std::make_pair(PixelFormat::YCRCB_P010, PixelFormat::NV21), ImageFormatConvertExtUtils::NV21P010ToNV21},
208         {std::make_pair(PixelFormat::YCRCB_P010, PixelFormat::YCBCR_P010),
209             ImageFormatConvertUtils::NV21P010ToNV12P010},
210         {std::make_pair(PixelFormat::YCBCR_P010, PixelFormat::RGBA_1010102),
211             ImageFormatConvertExtUtils::NV12P010ToRGBA1010102},
212         {std::make_pair(PixelFormat::YCRCB_P010, PixelFormat::RGB_565), ImageFormatConvertExtUtils::NV21P010ToRGB565},
213         {std::make_pair(PixelFormat::YCRCB_P010, PixelFormat::RGBA_8888),
214             ImageFormatConvertExtUtils::NV21P010ToRGBA8888},
215         {std::make_pair(PixelFormat::YCRCB_P010, PixelFormat::BGRA_8888),
216             ImageFormatConvertExtUtils::NV21P010ToBGRA8888},
217         {std::make_pair(PixelFormat::YCRCB_P010, PixelFormat::RGB_888), ImageFormatConvertExtUtils::NV21P010ToRGB888},
218         {std::make_pair(PixelFormat::YCRCB_P010, PixelFormat::RGBA_F16), ImageFormatConvertUtils::NV21P010ToRGBAF16},
219         {std::make_pair(PixelFormat::YCRCB_P010, PixelFormat::RGBA_1010102),
220             ImageFormatConvertExtUtils::NV21P010ToRGBA1010102},
221     };
222 #endif
223     return yuvCvtFuncMap;
224 }();
225 
226 static const std::set<std::pair<PixelFormat, PixelFormat>> conversions = {
227     {PixelFormat::NV12, PixelFormat::RGBA_1010102},
228     {PixelFormat::NV21, PixelFormat::RGBA_1010102},
229     {PixelFormat::RGB_565, PixelFormat::YCBCR_P010},
230     {PixelFormat::RGBA_8888, PixelFormat::YCBCR_P010},
231     {PixelFormat::BGRA_8888, PixelFormat::YCBCR_P010},
232     {PixelFormat::RGB_888, PixelFormat::YCBCR_P010},
233     {PixelFormat::RGBA_F16, PixelFormat::YCBCR_P010},
234     {PixelFormat::RGB_565, PixelFormat::YCRCB_P010},
235     {PixelFormat::RGBA_8888, PixelFormat::YCRCB_P010},
236     {PixelFormat::BGRA_8888, PixelFormat::YCRCB_P010},
237     {PixelFormat::RGB_888, PixelFormat::YCRCB_P010},
238     {PixelFormat::RGBA_F16, PixelFormat::YCRCB_P010}
239 };
240 
CalcRGBStride(PixelFormat format,uint32_t width,uint32_t & stride)241 static void CalcRGBStride(PixelFormat format, uint32_t width, uint32_t &stride)
242 {
243     switch (format) {
244         case PixelFormat::RGB_565:
245             stride = static_cast<uint32_t>(width * BYTES_PER_PIXEL_RGB565);
246             break;
247         case PixelFormat::RGBA_8888:
248             stride = static_cast<uint32_t>(width * BYTES_PER_PIXEL_RGBA);
249             break;
250         case PixelFormat::BGRA_8888:
251             stride = static_cast<uint32_t>(width * BYTES_PER_PIXEL_BGRA);
252             break;
253         case PixelFormat::RGB_888:
254             stride = static_cast<uint32_t>(width * BYTES_PER_PIXEL_RGB);
255             break;
256         case PixelFormat::RGBA_F16:
257             stride = static_cast<uint32_t>(width * STRIDES_PER_PLANE);
258             break;
259         default:
260             stride = static_cast<uint32_t>(width * BYTES_PER_PIXEL_RGBA);
261     }
262 }
263 
IsYUVConvert(PixelFormat srcFormat)264 static bool IsYUVConvert(PixelFormat srcFormat)
265 {
266     bool ret = srcFormat == PixelFormat::NV21 || srcFormat == PixelFormat::NV12 ||
267                srcFormat == PixelFormat::YCBCR_P010 || srcFormat == PixelFormat::YCRCB_P010;
268     return ret;
269 }
270 
YUVConvert(const OHOS::Media::ConvertDataInfo & srcDataInfo,OHOS::Media::DestConvertInfo & destInfo)271 uint32_t ImageFormatConvert::YUVConvert(const OHOS::Media::ConvertDataInfo &srcDataInfo,
272                                         OHOS::Media::DestConvertInfo &destInfo)
273 {
274     YUVConvertFunction yuvConvertFunction = YUVGetConvertFuncByFormat(srcDataInfo.pixelFormat, destInfo.format);
275     CHECK_ERROR_RETURN_RET_LOG(yuvConvertFunction == nullptr, ERR_IMAGE_INVALID_PARAMETER,
276         "YUVConvert get convert function by format failed!");
277     YUVDataInfo yuvDataInfo = srcDataInfo.yuvDataInfo;
278     int32_t width = srcDataInfo.imageSize.width;
279     int32_t height = srcDataInfo.imageSize.height;
280     if (destInfo.width == 0 || destInfo.height == 0) {
281         destInfo.width = static_cast<uint32_t>(width);
282         destInfo.height = static_cast<uint32_t>(height);
283     }
284     if (yuvDataInfo.yWidth == 0 || yuvDataInfo.yHeight == 0 || yuvDataInfo.uvWidth == 0 || yuvDataInfo.uvHeight == 0) {
285         yuvDataInfo.yWidth = static_cast<uint32_t>(width);
286         yuvDataInfo.yHeight = static_cast<uint32_t>(height);
287         yuvDataInfo.uvWidth = static_cast<uint32_t>((width + 1) / NUM_2);
288         yuvDataInfo.uvHeight = static_cast<uint32_t>((height + 1) / NUM_2);
289     }
290     YUVStrideInfo dstStrides;
291     auto m = CreateMemory(destInfo.format, destInfo.allocType, {destInfo.width, destInfo.height}, dstStrides);
292     CHECK_ERROR_RETURN_RET_LOG(m == nullptr, ERR_IMAGE_INVALID_PARAMETER, "YUVConvert create memory failed!");
293     destInfo.context = m->extend.data;
294     destInfo.yStride = dstStrides.yStride;
295     destInfo.uvStride = dstStrides.uvStride;
296     destInfo.yOffset = dstStrides.yOffset;
297     destInfo.uvOffset = dstStrides.uvOffset;
298     destInfo.buffer = reinterpret_cast<uint8_t *>(m->data.data);
299     destInfo.bufferSize = GetBufferSizeByFormat(destInfo.format, {destInfo.width, destInfo.height});
300 
301     if (!yuvConvertFunction(srcDataInfo.buffer, yuvDataInfo, destInfo, srcDataInfo.colorSpace)) {
302         IMAGE_LOGE("YUVConvert format convert failed!");
303         m->Release();
304         return IMAGE_RESULT_FORMAT_CONVERT_FAILED;
305     }
306     return SUCCESS;
307 }
308 
RGBConvert(const OHOS::Media::ConvertDataInfo & srcDataInfo,OHOS::Media::DestConvertInfo & destInfo)309 uint32_t ImageFormatConvert::RGBConvert(const OHOS::Media::ConvertDataInfo &srcDataInfo,
310                                         OHOS::Media::DestConvertInfo &destInfo)
311 {
312     ConvertFunction cvtFunc = GetConvertFuncByFormat(srcDataInfo.pixelFormat, destInfo.format);
313     CHECK_ERROR_RETURN_RET_LOG(cvtFunc == nullptr, ERR_IMAGE_INVALID_PARAMETER,
314         "RGBConvert get convert function by format failed!");
315     YUVStrideInfo dstStrides;
316     auto m = CreateMemory(destInfo.format, destInfo.allocType, {destInfo.width, destInfo.height}, dstStrides);
317     CHECK_ERROR_RETURN_RET_LOG(m == nullptr, ERR_IMAGE_INVALID_PARAMETER, "RGBConvert create memory failed!");
318     destInfo.context = m->extend.data;
319     destInfo.yStride = dstStrides.yStride;
320     destInfo.uvStride = dstStrides.uvStride;
321     destInfo.yOffset = dstStrides.yOffset;
322     destInfo.uvOffset = dstStrides.uvOffset;
323     destInfo.buffer = reinterpret_cast<uint8_t *>(m->data.data);
324     destInfo.bufferSize = GetBufferSizeByFormat(destInfo.format, {destInfo.width, destInfo.height});
325     uint32_t srcStride = 0;
326     CalcRGBStride(srcDataInfo.pixelFormat, srcDataInfo.imageSize.width, srcStride);
327     RGBDataInfo rgbDataInfo = {srcDataInfo.imageSize.width, srcDataInfo.imageSize.height, srcStride};
328     if (!cvtFunc(srcDataInfo.buffer, rgbDataInfo, destInfo, srcDataInfo.colorSpace)) {
329         IMAGE_LOGE("RGBConvert format convert failed!");
330         m->Release();
331         return IMAGE_RESULT_FORMAT_CONVERT_FAILED;
332     }
333     return SUCCESS;
334 }
335 
ConvertImageFormat(const ConvertDataInfo & srcDataInfo,DestConvertInfo & destInfo)336 uint32_t ImageFormatConvert::ConvertImageFormat(const ConvertDataInfo &srcDataInfo, DestConvertInfo &destInfo)
337 {
338     if (!CheckConvertDataInfo(srcDataInfo)) {
339         IMAGE_LOGE("source convert data info is invalid");
340         return ERR_IMAGE_INVALID_PARAMETER;
341     }
342     if (!IsSupport(destInfo.format)) {
343         IMAGE_LOGE("destination format is not support or invalid");
344         return ERR_IMAGE_INVALID_PARAMETER;
345     }
346     if (IsYUVConvert(srcDataInfo.pixelFormat)) {
347         return YUVConvert(srcDataInfo, destInfo);
348     }
349     return RGBConvert(srcDataInfo, destInfo);
350 }
351 
ConvertImageFormat(std::shared_ptr<PixelMap> & srcPiexlMap,PixelFormat destFormat)352 uint32_t ImageFormatConvert::ConvertImageFormat(std::shared_ptr<PixelMap> &srcPiexlMap, PixelFormat destFormat)
353 {
354     if (srcPiexlMap == nullptr) {
355         IMAGE_LOGE("source pixel map is null");
356         return ERR_IMAGE_INVALID_PARAMETER;
357     }
358     if (!IsSupport(destFormat)) {
359         IMAGE_LOGE("destination format not support");
360         return ERR_MEDIA_FORMAT_UNSUPPORT;
361     }
362     PixelFormat srcFormat = srcPiexlMap->GetPixelFormat();
363     if (IsYUVConvert(srcFormat)) {
364         uint32_t ret = 0;
365         ret = YUVConvertImageFormatOption(srcPiexlMap, srcFormat, destFormat);
366         if (ret != SUCCESS) {
367             IMAGE_LOGE("convert yuv format failed!");
368         }
369         return ret;
370     }
371     if (srcPiexlMap->IsAstc()) {
372         uint32_t ret = 0;
373         std::unique_ptr<PixelMap> resultPixelMap = PixelMap::ConvertFromAstc(srcPiexlMap.get(), ret,
374             destFormat);
375         srcPiexlMap = std::move(resultPixelMap);
376         if (ret != SUCCESS) {
377             IMAGE_LOGE("convert astc format failed!");
378         }
379         return ret;
380     }
381     uint32_t ret = RGBConvertImageFormatOption(srcPiexlMap, srcFormat, destFormat);
382     if (ret != SUCCESS) {
383         IMAGE_LOGE("convert rgb format failed!");
384         return ret;
385     }
386     ImageUtils::DumpPixelMapIfDumpEnabled(*srcPiexlMap, __func__);
387     return SUCCESS;
388 }
389 
IsValidSize(const Size & size)390 bool ImageFormatConvert::IsValidSize(const Size &size)
391 {
392     return size.width > 0 && size.height > 0;
393 }
394 
CheckConvertDataInfo(const ConvertDataInfo & convertDataInfo)395 bool ImageFormatConvert::CheckConvertDataInfo(const ConvertDataInfo &convertDataInfo)
396 {
397     if (convertDataInfo.buffer == nullptr) {
398         IMAGE_LOGE("buffer is null");
399         return false;
400     }
401 
402     if (!IsSupport(convertDataInfo.pixelFormat)) {
403         IMAGE_LOGE("format is not support or invalid");
404         return false;
405     }
406 
407     if (!IsValidSize(convertDataInfo.imageSize)) {
408         IMAGE_LOGE("image size is invalid");
409         return false;
410     }
411 
412     if (GetBufferSizeByFormat(convertDataInfo.pixelFormat, convertDataInfo.imageSize) != convertDataInfo.bufferSize) {
413         IMAGE_LOGE("buffer size is wrong");
414         return false;
415     }
416 
417     return true;
418 }
419 
GetBufferSizeByFormat(PixelFormat format,const Size & size)420 size_t ImageFormatConvert::GetBufferSizeByFormat(PixelFormat format, const Size &size)
421 {
422     switch (format) {
423         case PixelFormat::RGB_565:{
424             return size.width * size.height * NUM_2;
425         }
426         case PixelFormat::RGB_888:{
427             return size.width * size.height * NUM_3;
428         }
429         case PixelFormat::ARGB_8888:
430         case PixelFormat::RGBA_8888:
431         case PixelFormat::BGRA_8888:
432         case PixelFormat::RGBA_1010102:{
433             return size.width * size.height * NUM_4;
434         }
435         case PixelFormat::RGBA_F16:{
436             return (((size.width + NUM_1) / NUM_2) * NUM_2) * size.height * NUM_8;
437         }
438         case PixelFormat::NV21:
439         case PixelFormat::NV12:{
440             return size.width * size.height + ((size.width + NUM_1) / NUM_2) *
441                 ((size.height + NUM_1) / NUM_2) * NUM_2;
442         }
443         case PixelFormat::YCBCR_P010:
444         case PixelFormat::YCRCB_P010: {
445             return (size.width * size.height + ((size.width + NUM_1) / NUM_2) *
446                 ((size.height + NUM_1) / NUM_2) * NUM_2) * NUM_2;
447         }
448         default:{
449             return NUM_0;
450         }
451     }
452 }
453 
GetConvertFuncByFormat(PixelFormat srcFormat,PixelFormat destFormat)454 ConvertFunction ImageFormatConvert::GetConvertFuncByFormat(PixelFormat srcFormat, PixelFormat destFormat)
455 {
456     auto iter = g_cvtFuncMap.find(std::make_pair(srcFormat, destFormat));
457     if (iter == g_cvtFuncMap.end()) {
458         IMAGE_LOGE("current format is not supported or format is wrong");
459         return nullptr;
460     }
461     return iter->second;
462 }
463 
YUVGetConvertFuncByFormat(PixelFormat srcFormat,PixelFormat destFormat)464 YUVConvertFunction ImageFormatConvert::YUVGetConvertFuncByFormat(PixelFormat srcFormat, PixelFormat destFormat)
465 {
466     auto iter = g_yuvCvtFuncMap.find(std::make_pair(srcFormat, destFormat));
467     if (iter == g_yuvCvtFuncMap.end()) {
468         IMAGE_LOGE("current format is not supported or format is wrong");
469         return nullptr;
470     }
471     return iter->second;
472 }
473 
IsSupport(PixelFormat format)474 bool ImageFormatConvert::IsSupport(PixelFormat format)
475 {
476     switch (format) {
477         case PixelFormat::ARGB_8888:
478         case PixelFormat::RGB_565:
479         case PixelFormat::RGBA_8888:
480         case PixelFormat::BGRA_8888:
481         case PixelFormat::RGB_888:
482         case PixelFormat::RGBA_F16:
483         case PixelFormat::RGBA_1010102:
484         case PixelFormat::YCBCR_P010:
485         case PixelFormat::YCRCB_P010:
486         case PixelFormat::NV21:
487         case PixelFormat::NV12:{
488             return true;
489         }
490         default:{
491             return false;
492         }
493     }
494 }
495 
496 #if !defined(_WIN32) && !defined(_APPLE) && !defined(IOS_PLATFORM) && !defined(ANDROID_PLATFORM)
GetYUVStrideInfo(int32_t pixelFmt,OH_NativeBuffer_Planes * planes,YUVStrideInfo & dstStrides)497 static void GetYUVStrideInfo(int32_t pixelFmt, OH_NativeBuffer_Planes *planes, YUVStrideInfo &dstStrides)
498 {
499     if (pixelFmt == GRAPHIC_PIXEL_FMT_YCBCR_420_SP) {
500         auto yStride = planes->planes[PLANE_Y].columnStride;
501         auto uvStride = planes->planes[PLANE_U].columnStride;
502         auto yOffset = planes->planes[PLANE_Y].offset;
503         auto uvOffset = planes->planes[PLANE_U].offset;
504         dstStrides = {yStride, uvStride, yOffset, uvOffset};
505     } else if (pixelFmt == GRAPHIC_PIXEL_FMT_YCRCB_420_SP) {
506         auto yStride = planes->planes[PLANE_Y].columnStride;
507         auto uvStride = planes->planes[PLANE_V].columnStride;
508         auto yOffset = planes->planes[PLANE_Y].offset;
509         auto uvOffset = planes->planes[PLANE_V].offset;
510         dstStrides = {yStride, uvStride, yOffset, uvOffset};
511     } else if (pixelFmt == GRAPHIC_PIXEL_FMT_YCBCR_P010) {
512         auto yStride = planes->planes[PLANE_Y].columnStride / 2;
513         auto uvStride = planes->planes[PLANE_U].columnStride / 2;
514         auto yOffset = planes->planes[PLANE_Y].offset / 2;
515         auto uvOffset = planes->planes[PLANE_U].offset / 2;
516         dstStrides = {yStride, uvStride, yOffset, uvOffset};
517     } else if (pixelFmt == GRAPHIC_PIXEL_FMT_YCRCB_P010) {
518         auto yStride = planes->planes[PLANE_Y].columnStride / 2;
519         auto uvStride = planes->planes[PLANE_V].columnStride / 2;
520         auto yOffset = planes->planes[PLANE_Y].offset / 2;
521         auto uvOffset = planes->planes[PLANE_V].offset / 2;
522         dstStrides = {yStride, uvStride, yOffset, uvOffset};
523     }
524 }
525 #endif
526 
CreateMemory(PixelFormat pixelFormat,AllocatorType allocatorType,Size size,YUVStrideInfo & strides,uint64_t usage)527 std::unique_ptr<AbsMemory> ImageFormatConvert::CreateMemory(PixelFormat pixelFormat, AllocatorType allocatorType,
528     Size size, YUVStrideInfo &strides, uint64_t usage)
529 {
530     if (size.width == 0 || size.height == 0 || pixelFormat == PixelFormat::UNKNOWN) {
531         IMAGE_LOGE("CreateMemory err ERR_IMAGE_INVALID_PARAMETER!");
532         return nullptr;
533     }
534     uint32_t pictureSize = GetBufferSizeByFormat(pixelFormat, size);
535     if (IsYUVConvert(pixelFormat)) {
536         strides = {size.width, (size.width + 1) / NUM_2 * NUM_2, 0, size.width * size.height};
537     } else {
538         uint32_t stride = 0;
539         CalcRGBStride(pixelFormat, size.width, stride);
540         strides = {stride, 0, 0, 0};
541     }
542     MemoryData memoryData = {nullptr, pictureSize, "PixelConvert", size, pixelFormat};
543     memoryData.usage = usage;
544     auto m = MemoryManager::CreateMemory(allocatorType, memoryData);
545     CHECK_ERROR_RETURN_RET_LOG(m == nullptr, m, "CreateMemory failed");
546 #if !defined(_WIN32) && !defined(_APPLE) && !defined(IOS_PLATFORM) && !defined(ANDROID_PLATFORM)
547     if (allocatorType != AllocatorType::DMA_ALLOC) {
548         return m;
549     }
550     CHECK_ERROR_RETURN_RET_LOG(m->extend.data == nullptr, m, "CreateMemory get surfacebuffer failed");
551     auto sb = reinterpret_cast<SurfaceBuffer*>(m->extend.data);
552     OH_NativeBuffer_Planes *planes = nullptr;
553     GSError retVal = sb->GetPlanesInfo(reinterpret_cast<void**>(&planes));
554     auto stride = sb->GetStride();
555     strides = {stride, 0, 0, 0};
556     if (retVal != OHOS::GSERROR_OK || planes == nullptr) {
557         IMAGE_LOGE("CreateMemory Get planesInfo failed, retVal:%{public}d", retVal);
558     } else if (planes->planeCount >= NUM_2) {
559         int32_t pixelFmt = sb->GetFormat();
560         GetYUVStrideInfo(pixelFmt, planes, strides);
561     }
562 #endif
563     return m;
564 }
565 
RGBConvertImageFormatOption(std::shared_ptr<PixelMap> & srcPiexlMap,const PixelFormat & srcFormat,PixelFormat destFormat)566 uint32_t ImageFormatConvert::RGBConvertImageFormatOption(std::shared_ptr<PixelMap> &srcPiexlMap,
567                                                          const PixelFormat &srcFormat, PixelFormat destFormat)
568 {
569     ConvertFunction cvtFunc = GetConvertFuncByFormat(srcFormat, destFormat);
570     if (cvtFunc == nullptr) {
571         IMAGE_LOGE("get convert function by format failed!");
572         return ERR_IMAGE_INVALID_PARAMETER;
573     }
574     const_uint8_buffer_type srcBuffer = srcPiexlMap->GetPixels();
575     ImageInfo imageInfo;
576     srcPiexlMap->GetImageInfo(imageInfo);
577 
578     int32_t width = imageInfo.size.width;
579     int32_t height = imageInfo.size.height;
580     YUVStrideInfo dstStrides;
581     auto allocType = srcPiexlMap->GetAllocatorType();
582     auto m = CreateMemory(destFormat, allocType, imageInfo.size, dstStrides, srcPiexlMap->GetNoPaddingUsage());
583     if (m == nullptr) {
584         IMAGE_LOGE("CreateMemory failed");
585         return ERR_IMAGE_INVALID_PARAMETER;
586     }
587     int32_t stride = srcPiexlMap->GetRowStride();
588     #if !defined(_WIN32) && !defined(_APPLE) && !defined(IOS_PLATFORM) && !defined(ANDROID_PLATFORM)
589     if (allocType == AllocatorType::DMA_ALLOC) {
590         auto sb = reinterpret_cast<SurfaceBuffer*>(srcPiexlMap->GetFd());
591         stride = sb->GetStride();
592         sptr<SurfaceBuffer> sourceSurfaceBuffer(sb);
593         sptr<SurfaceBuffer> dstSurfaceBuffer(reinterpret_cast<SurfaceBuffer*>(m->extend.data));
594         VpeUtils::CopySurfaceBufferInfo(sourceSurfaceBuffer, dstSurfaceBuffer);
595     }
596     #endif
597     RGBDataInfo rgbDataInfo = {width, height, static_cast<uint32_t>(stride)};
598     DestConvertInfo destInfo = {width, height, destFormat, allocType};
599     destInfo.buffer = reinterpret_cast<uint8_t *>(m->data.data);
600     destInfo.bufferSize = GetBufferSizeByFormat(destFormat, {destInfo.width, destInfo.height});
601     destInfo.yStride = dstStrides.yStride;
602     destInfo.uvStride = dstStrides.uvStride;
603     destInfo.yOffset = dstStrides.yOffset;
604     destInfo.uvOffset = dstStrides.uvOffset;
605     if (!cvtFunc(srcBuffer, rgbDataInfo, destInfo, srcPiexlMap->GetColorSpace())) {
606         IMAGE_LOGE("format convert failed!");
607         m->Release();
608         return IMAGE_RESULT_FORMAT_CONVERT_FAILED;
609     }
610     auto ret = MakeDestPixelMap(srcPiexlMap, imageInfo, destInfo, m->extend.data);
611     if (ret == ERR_IMAGE_PIXELMAP_CREATE_FAILED) {
612         m->Release();
613     }
614     return ret;
615 }
616 
RGBConvertImageFormatOptionUnique(std::unique_ptr<PixelMap> & srcPiexlMap,const PixelFormat & srcFormat,PixelFormat destFormat)617 uint32_t ImageFormatConvert::RGBConvertImageFormatOptionUnique(
618     std::unique_ptr<PixelMap> &srcPiexlMap, const PixelFormat &srcFormat, PixelFormat destFormat)
619 {
620     ConvertFunction cvtFunc = GetConvertFuncByFormat(srcFormat, destFormat);
621     bool cond = cvtFunc == nullptr;
622     CHECK_ERROR_RETURN_RET_LOG(cond, ERR_IMAGE_INVALID_PARAMETER, "get convert function by format failed!");
623     const_uint8_buffer_type srcBuffer = srcPiexlMap->GetPixels();
624     ImageInfo imageInfo;
625     srcPiexlMap->GetImageInfo(imageInfo);
626 
627     int32_t width = imageInfo.size.width;
628     int32_t height = imageInfo.size.height;
629     YUVStrideInfo dstStrides;
630     auto allocType = srcPiexlMap->GetAllocatorType();
631     auto memory = CreateMemory(destFormat, allocType, imageInfo.size, dstStrides, srcPiexlMap->GetNoPaddingUsage());
632     cond = memory == nullptr;
633     CHECK_ERROR_RETURN_RET_LOG(cond, ERR_IMAGE_INVALID_PARAMETER, "CreateMemory failed");
634     int32_t stride = srcPiexlMap->GetRowStride();
635     #if !defined(_WIN32) && !defined(_APPLE) && !defined(IOS_PLATFORM) && !defined(ANDROID_PLATFORM)
636     if (allocType == AllocatorType::DMA_ALLOC) {
637         auto sb = reinterpret_cast<SurfaceBuffer*>(srcPiexlMap->GetFd());
638         stride = sb->GetStride();
639         sptr<SurfaceBuffer> sourceSurfaceBuffer(sb);
640         sptr<SurfaceBuffer> dstSurfaceBuffer(reinterpret_cast<SurfaceBuffer*>(memory->extend.data));
641         VpeUtils::CopySurfaceBufferInfo(sourceSurfaceBuffer, dstSurfaceBuffer);
642     }
643     #endif
644     RGBDataInfo rgbDataInfo = {width, height, static_cast<uint32_t>(stride)};
645     DestConvertInfo destInfo = {width, height, destFormat, allocType};
646     destInfo.buffer = reinterpret_cast<uint8_t *>(memory->data.data);
647     destInfo.bufferSize = GetBufferSizeByFormat(destFormat, {destInfo.width, destInfo.height});
648     destInfo.yStride = dstStrides.yStride;
649     destInfo.uvStride = dstStrides.uvStride;
650     destInfo.yOffset = dstStrides.yOffset;
651     destInfo.uvOffset = dstStrides.uvOffset;
652     if (!cvtFunc(srcBuffer, rgbDataInfo, destInfo, srcPiexlMap->GetColorSpace())) {
653         IMAGE_LOGE("format convert failed!");
654         memory->Release();
655         return IMAGE_RESULT_FORMAT_CONVERT_FAILED;
656     }
657     auto ret = MakeDestPixelMapUnique(srcPiexlMap, imageInfo, destInfo, memory->extend.data);
658     if (ret == ERR_IMAGE_PIXELMAP_CREATE_FAILED) {
659         memory->Release();
660     }
661     return ret;
662 }
663 
SetConvertImageMetaData(std::unique_ptr<PixelMap> & srcPixelMap,std::unique_ptr<PixelMap> & dstPixelMap)664 bool ImageFormatConvert::SetConvertImageMetaData(std::unique_ptr<PixelMap> &srcPixelMap,
665                                                  std::unique_ptr<PixelMap> &dstPixelMap)
666 {
667     CHECK_ERROR_RETURN_RET(srcPixelMap == nullptr || dstPixelMap == nullptr, false);
668     auto HdrMetadata = srcPixelMap->GetHdrMetadata();
669     if (HdrMetadata != nullptr) {
670         dstPixelMap->SetHdrMetadata(HdrMetadata);
671     }
672     auto exifData = srcPixelMap->GetExifMetadata();
673     if (exifData != nullptr) {
674         dstPixelMap->SetExifMetadata(exifData);
675     }
676     return true;
677 }
678 
SetConvertImageMetaData(std::shared_ptr<PixelMap> & srcPixelMap,std::unique_ptr<PixelMap> & dstPixelMap)679 bool ImageFormatConvert::SetConvertImageMetaData(std::shared_ptr<PixelMap> &srcPixelMap,
680                                                  std::unique_ptr<PixelMap> &dstPixelMap)
681 {
682     if (srcPixelMap == nullptr || dstPixelMap == nullptr) {
683         return false;
684     }
685     auto HdrMetadata = srcPixelMap->GetHdrMetadata();
686     if (HdrMetadata != nullptr) {
687         dstPixelMap->SetHdrMetadata(HdrMetadata);
688     }
689     auto exifData = srcPixelMap->GetExifMetadata();
690     if (exifData != nullptr) {
691         dstPixelMap->SetExifMetadata(exifData);
692     }
693     return true;
694 }
695 
GetAllocatorType(std::shared_ptr<PixelMap> & srcPiexlMap,PixelFormat destFormat)696 static AllocatorType GetAllocatorType(std::shared_ptr<PixelMap> &srcPiexlMap, PixelFormat destFormat)
697 {
698     auto allocType = srcPiexlMap->GetAllocatorType();
699     if (destFormat == PixelFormat::RGB_888 || destFormat == PixelFormat::RGB_565 ||
700         destFormat == PixelFormat::RGBA_F16) {
701         allocType = AllocatorType::SHARE_MEM_ALLOC;
702     }
703     return allocType;
704 }
705 
YUVConvertImageFormatOption(std::shared_ptr<PixelMap> & srcPiexlMap,const PixelFormat & srcFormat,PixelFormat destFormat)706 uint32_t ImageFormatConvert::YUVConvertImageFormatOption(std::shared_ptr<PixelMap> &srcPiexlMap,
707                                                          const PixelFormat &srcFormat, PixelFormat destFormat)
708 {
709     YUVConvertFunction yuvCvtFunc = YUVGetConvertFuncByFormat(srcFormat, destFormat);
710     if (yuvCvtFunc == nullptr) {
711         return ERR_IMAGE_INVALID_PARAMETER;
712     }
713     const_uint8_buffer_type data = srcPiexlMap->GetPixels();
714     YUVDataInfo yDInfo;
715     srcPiexlMap->GetImageYUVInfo(yDInfo);
716     ImageInfo imageInfo;
717     srcPiexlMap->GetImageInfo(imageInfo);
718     if ((srcFormat == PixelFormat::NV21 || srcFormat == PixelFormat::YCBCR_P010 ||
719         srcFormat == PixelFormat::YCRCB_P010) &&
720         (yDInfo.yWidth == 0 || yDInfo.yHeight == 0 || yDInfo.uvWidth == 0 || yDInfo.uvHeight == 0)) {
721         yDInfo.yWidth = static_cast<uint32_t>(imageInfo.size.width);
722         yDInfo.yHeight = static_cast<uint32_t>(imageInfo.size.height);
723         yDInfo.uvWidth = static_cast<uint32_t>((imageInfo.size.width + 1) / NUM_2);
724         yDInfo.uvHeight = static_cast<uint32_t>((imageInfo.size.height + 1) / NUM_2);
725     }
726     YUVStrideInfo dstStrides;
727     auto allocType = GetAllocatorType(srcPiexlMap, destFormat);
728     DestConvertInfo destInfo = {imageInfo.size.width, imageInfo.size.height, destFormat, allocType};
729     auto m = CreateMemory(destFormat, allocType, imageInfo.size, dstStrides,
730         srcPiexlMap->GetNoPaddingUsage());
731     if (m == nullptr) {
732         return ERR_IMAGE_INVALID_PARAMETER;
733     }
734 #if !defined(_WIN32) && !defined(_APPLE) && !defined(IOS_PLATFORM) && !defined(ANDROID_PLATFORM)
735     if (allocType == AllocatorType::DMA_ALLOC) {
736         sptr<SurfaceBuffer> sourceSurfaceBuffer(reinterpret_cast<SurfaceBuffer*>(srcPiexlMap->GetFd()));
737         sptr<SurfaceBuffer> dstSurfaceBuffer(reinterpret_cast<SurfaceBuffer*>(m->extend.data));
738         VpeUtils::CopySurfaceBufferInfo(sourceSurfaceBuffer, dstSurfaceBuffer);
739     }
740 #endif
741     destInfo.buffer = reinterpret_cast<uint8_t *>(m->data.data);
742     destInfo.bufferSize = GetBufferSizeByFormat(destFormat, {destInfo.width, destInfo.height});
743     destInfo.yStride = dstStrides.yStride;
744     destInfo.uvStride = dstStrides.uvStride;
745     destInfo.yOffset = dstStrides.yOffset;
746     destInfo.uvOffset = dstStrides.uvOffset;
747     if (!yuvCvtFunc(data, yDInfo, destInfo, srcPiexlMap->GetColorSpace())) {
748         m->Release();
749         return IMAGE_RESULT_FORMAT_CONVERT_FAILED;
750     }
751     auto ret = MakeDestPixelMap(srcPiexlMap, imageInfo, destInfo, m->extend.data);
752     if (ret == ERR_IMAGE_PIXELMAP_CREATE_FAILED) {
753         m->Release();
754     }
755     return ret;
756 }
757 
NeedProtectionConversion(const PixelFormat inputFormat,const PixelFormat outputFormat)758 bool NeedProtectionConversion(const PixelFormat inputFormat, const PixelFormat outputFormat)
759 {
760     if (conversions.find({inputFormat, outputFormat}) != conversions.end()) {
761         return true;
762     }
763     return false;
764 }
765 
SetImageInfo(ImageInfo & srcImageinfo,DestConvertInfo & destInfo)766 ImageInfo SetImageInfo(ImageInfo &srcImageinfo, DestConvertInfo &destInfo)
767 {
768     ImageInfo info;
769     info.alphaType = srcImageinfo.alphaType;
770     info.baseDensity = srcImageinfo.baseDensity;
771     info.colorSpace = srcImageinfo.colorSpace;
772     info.pixelFormat = destInfo.format;
773     info.size = {destInfo.width, destInfo.height};
774     return info;
775 }
776 
MakeDestPixelMap(std::shared_ptr<PixelMap> & destPixelMap,ImageInfo & srcImageinfo,DestConvertInfo & destInfo,void * context)777 uint32_t ImageFormatConvert::MakeDestPixelMap(std::shared_ptr<PixelMap> &destPixelMap, ImageInfo &srcImageinfo,
778                                               DestConvertInfo &destInfo, void *context)
779 {
780     if (srcImageinfo.size.width == 0 || srcImageinfo.size.height == 0 || destInfo.width == 0
781         || destInfo.height == 0 || destInfo.format == PixelFormat::UNKNOWN) {
782         return ERR_IMAGE_INVALID_PARAMETER;
783     }
784     ImageInfo info = SetImageInfo(srcImageinfo, destInfo);
785     auto allcatorType = destInfo.allocType;
786     std::unique_ptr<PixelMap> pixelMap;
787     if (info.pixelFormat == PixelFormat::NV21 || info.pixelFormat == PixelFormat::NV12 ||
788         info.pixelFormat == PixelFormat::YCBCR_P010 || info.pixelFormat == PixelFormat::YCRCB_P010) {
789 #ifdef EXT_PIXEL
790         pixelMap = std::make_unique<PixelYuvExt>();
791 #else
792         pixelMap = std::make_unique<PixelYuv>();
793 #endif
794         CHECK_ERROR_RETURN_RET(pixelMap == nullptr, ERR_IMAGE_PIXELMAP_CREATE_FAILED);
795         if (allcatorType != AllocatorType::DMA_ALLOC) {
796             pixelMap->AssignYuvDataOnType(info.pixelFormat, info.size.width, info.size.height);
797         } else {
798             YUVStrideInfo strides = {destInfo.yStride, destInfo.uvStride, destInfo.yOffset, destInfo.uvOffset};
799             pixelMap->UpdateYUVDataInfo(info.pixelFormat, info.size.width, info.size.height, strides);
800         }
801     } else {
802         pixelMap = std::make_unique<PixelMap>();
803         CHECK_ERROR_RETURN_RET(pixelMap == nullptr, ERR_IMAGE_PIXELMAP_CREATE_FAILED);
804     }
805     pixelMap->SetPixelsAddr(destInfo.buffer, context, destInfo.bufferSize, allcatorType, nullptr);
806     auto ret = pixelMap->SetImageInfo(info, true);
807     bool isSetMetaData = SetConvertImageMetaData(destPixelMap, pixelMap);
808     CHECK_ERROR_RETURN_RET_LOG(ret != SUCCESS || isSetMetaData == false, ret, "set imageInfo failed");
809 #ifdef IMAGE_COLORSPACE_FLAG
810     if (NeedProtectionConversion(srcImageinfo.pixelFormat, info.pixelFormat)) {
811         pixelMap->InnerSetColorSpace(OHOS::ColorManager::ColorSpace(ColorManager::ColorSpaceName::BT2020_HLG));
812     } else {
813         pixelMap->InnerSetColorSpace(destPixelMap->InnerGetGrColorSpace());
814     }
815 #endif
816     destPixelMap = std::move(pixelMap);
817     return SUCCESS;
818 }
819 
MakeDestPixelMapUnique(std::unique_ptr<PixelMap> & destPixelMap,ImageInfo & srcImageinfo,DestConvertInfo & destInfo,void * context)820 uint32_t ImageFormatConvert::MakeDestPixelMapUnique(std::unique_ptr<PixelMap> &destPixelMap, ImageInfo &srcImageinfo,
821     DestConvertInfo &destInfo, void *context)
822 {
823     bool cond = srcImageinfo.size.width == 0 || srcImageinfo.size.height == 0 || destInfo.width == 0 ||
824                 destInfo.height == 0 || destInfo.format == PixelFormat::UNKNOWN;
825     CHECK_ERROR_RETURN_RET(cond, ERR_IMAGE_INVALID_PARAMETER);
826     ImageInfo info = SetImageInfo(srcImageinfo, destInfo);
827     auto allcatorType = destInfo.allocType;
828     std::unique_ptr<PixelMap> pixelMap;
829     if (info.pixelFormat == PixelFormat::NV21 || info.pixelFormat == PixelFormat::NV12 ||
830         info.pixelFormat == PixelFormat::YCBCR_P010 || info.pixelFormat == PixelFormat::YCRCB_P010) {
831 #ifdef EXT_PIXEL
832         pixelMap = std::make_unique<PixelYuvExt>();
833 #else
834         pixelMap = std::make_unique<PixelYuv>();
835 #endif
836         CHECK_ERROR_RETURN_RET(pixelMap == nullptr, ERR_IMAGE_PIXELMAP_CREATE_FAILED);
837         if (allcatorType != AllocatorType::DMA_ALLOC) {
838             pixelMap->AssignYuvDataOnType(info.pixelFormat, info.size.width, info.size.height);
839         } else {
840             YUVStrideInfo strides = {destInfo.yStride, destInfo.uvStride, destInfo.yOffset, destInfo.uvOffset};
841             pixelMap->UpdateYUVDataInfo(info.pixelFormat, info.size.width, info.size.height, strides);
842         }
843     } else {
844         pixelMap = std::make_unique<PixelMap>();
845         CHECK_ERROR_RETURN_RET(pixelMap == nullptr, ERR_IMAGE_PIXELMAP_CREATE_FAILED);
846     }
847     pixelMap->SetPixelsAddr(destInfo.buffer, context, destInfo.bufferSize, allcatorType, nullptr);
848     auto ret = pixelMap->SetImageInfo(info, true);
849     bool isSetMetaData = SetConvertImageMetaData(destPixelMap, pixelMap);
850     cond = ret != SUCCESS || isSetMetaData == false;
851     CHECK_ERROR_RETURN_RET_LOG(cond, ret, "set imageInfo failed");
852 #ifdef IMAGE_COLORSPACE_FLAG
853     if (NeedProtectionConversion(srcImageinfo.pixelFormat, info.pixelFormat)) {
854         pixelMap->InnerSetColorSpace(OHOS::ColorManager::ColorSpace(ColorManager::ColorSpaceName::BT2020_HLG));
855     } else {
856         pixelMap->InnerSetColorSpace(destPixelMap->InnerGetGrColorSpace());
857     }
858 #endif
859     destPixelMap = std::move(pixelMap);
860     return SUCCESS;
861 }
862 } // namespace Media
863 } // namespace OHOS