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_ext_utils.h"
17
18 #include <cmath>
19 #include <cstring>
20 #include <iostream>
21 #include <map>
22 #include "hilog/log.h"
23 #include "image_convert_tools.h"
24 #include "image_log.h"
25 #include "log_tags.h"
26 #include "securec.h"
27
28 namespace {
29 constexpr uint32_t NUM_0 = 0;
30 constexpr uint32_t NUM_1 = 1;
31 constexpr uint32_t NUM_2 = 2;
32 constexpr uint32_t NUM_3 = 3;
33 constexpr uint32_t NUM_4 = 4;
34
35 constexpr uint32_t EVEN_ODD_DIVISOR = 2;
36 constexpr uint32_t TWO_SLICES = 2;
37 constexpr uint32_t BYTES_PER_PIXEL_RGB565 = 2;
38 constexpr uint32_t BYTES_PER_PIXEL_RGB = 3;
39 constexpr uint32_t BYTES_PER_PIXEL_RGBA = 4;
40 constexpr uint32_t BYTES_PER_PIXEL_BGRA = 4;
41 constexpr uint32_t STRIDES_PER_PLANE = 8;
42 constexpr int32_t PIXEL_MAP_MAX_RAM_SIZE = 600 * 1024 * 1024;
43 }
44
45 #undef LOG_TAG
46 #define LOG_TAG "ImageFormatConvertExt"
47 namespace OHOS {
48 namespace Media {
I010ToP010(I010Info & i010,DestConvertParam & destParam)49 static bool I010ToP010(I010Info &i010, DestConvertParam &destParam)
50 {
51 auto &converter = ConverterHandle::GetInstance().GetHandle();
52 switch (destParam.format) {
53 case PixelFormat::YCBCR_P010:
54 converter.I010ToP010(i010.I010Y, i010.yStride, i010.I010U, i010.uStride, i010.I010V, i010.vStride,
55 reinterpret_cast<uint16_t *>(destParam.slice[0]), destParam.stride[0],
56 reinterpret_cast<uint16_t *>(destParam.slice[1]), destParam.stride[1],
57 destParam.width, destParam.height);
58 break;
59 case PixelFormat::YCRCB_P010:
60 converter.I010ToP010(i010.I010Y, i010.yStride, i010.I010V, i010.vStride, i010.I010U, i010.uStride,
61 reinterpret_cast<uint16_t *>(destParam.slice[0]), destParam.stride[0],
62 reinterpret_cast<uint16_t *>(destParam.slice[1]), destParam.stride[1],
63 destParam.width, destParam.height);
64 break;
65 default:
66 return false;
67 }
68 return true;
69 }
70
I420ToI010(I420Info & i420,I010Info & i010)71 static bool I420ToI010(I420Info &i420, I010Info &i010)
72 {
73 auto &converter = ConverterHandle::GetInstance().GetHandle();
74 converter.I420ToI010(i420.I420Y, i420.yStride, i420.I420U, i420.uStride, i420.I420V, i420.vStride,
75 i010.I010Y, i010.yStride, i010.I010U, i010.uStride, i010.I010V, i010.vStride,
76 i420.width, i420.height);
77 return true;
78 }
79
RGBToI420(SrcConvertParam & srcParam,I420Info & i420)80 static bool RGBToI420(SrcConvertParam &srcParam, I420Info &i420)
81 {
82 auto &converter = ConverterHandle::GetInstance().GetHandle();
83 switch (srcParam.format) {
84 case PixelFormat::RGB_888:
85 converter.RGB24ToI420(srcParam.slice[0], srcParam.stride[0], i420.I420Y, i420.yStride, i420.I420U,
86 i420.uStride, i420.I420V, i420.vStride, srcParam.width, srcParam.height);
87 break;
88 case PixelFormat::RGB_565:
89 converter.RGB565ToI420(srcParam.slice[0], srcParam.stride[0], i420.I420Y, i420.yStride, i420.I420U,
90 i420.uStride, i420.I420V, i420.vStride, srcParam.width, srcParam.height);
91 break;
92 case PixelFormat::RGBA_8888:
93 converter.ABGRToJ420(srcParam.slice[0], srcParam.stride[0], i420.I420Y, i420.yStride, i420.I420U,
94 i420.uStride, i420.I420V, i420.vStride, srcParam.width, srcParam.height);
95 break;
96 case PixelFormat::BGRA_8888:
97 converter.ARGBToI420(srcParam.slice[0], srcParam.stride[0], i420.I420Y, i420.yStride, i420.I420U,
98 i420.uStride, i420.I420V, i420.vStride, srcParam.width, srcParam.height);
99 break;
100 default:
101 return false;
102 }
103 return true;
104 }
105
I420ToYuv(I420Info & i420,DestConvertParam & destParam)106 static bool I420ToYuv(I420Info &i420, DestConvertParam &destParam)
107 {
108 auto &converter = ConverterHandle::GetInstance().GetHandle();
109 switch (destParam.format) {
110 case PixelFormat::NV12:
111 converter.I420ToNV12(i420.I420Y, i420.yStride, i420.I420U, i420.uStride, i420.I420V, i420.vStride,
112 destParam.slice[0], destParam.stride[0], destParam.slice[1], destParam.stride[1],
113 destParam.width, destParam.height);
114 break;
115 case PixelFormat::NV21:
116 converter.I420ToNV21(i420.I420Y, i420.yStride, i420.I420U, i420.uStride, i420.I420V, i420.vStride,
117 destParam.slice[0], destParam.stride[0], destParam.slice[1], destParam.stride[1],
118 destParam.width, destParam.height);
119 break;
120 default:
121 return false;
122 }
123 return true;
124 }
125
RGBToYuvParam(const RGBDataInfo & rgbInfo,SrcConvertParam & srcParam,DestConvertParam & destParam,DestConvertInfo & destInfo)126 static void RGBToYuvParam(const RGBDataInfo &rgbInfo, SrcConvertParam &srcParam, DestConvertParam &destParam,
127 DestConvertInfo &destInfo)
128 {
129 srcParam.slice[0] = srcParam.buffer;
130 srcParam.stride[0] = static_cast<int>(rgbInfo.stride);
131 if (destInfo.allocType == AllocatorType::DMA_ALLOC) {
132 destParam.stride[0] = static_cast<int>(destInfo.yStride);
133 destParam.stride[1] = static_cast<int>(destInfo.uvStride);
134 destParam.slice[0] = destInfo.buffer + destInfo.yOffset;
135 destParam.slice[1] = destInfo.buffer + destInfo.uvOffset;
136 } else {
137 int uvStride = (rgbInfo.width + NUM_1) / NUM_2 * NUM_2;
138 destParam.stride[0] = static_cast<int>(destParam.width);
139 destParam.stride[1] = static_cast<int>(uvStride);
140 destParam.slice[0] = destInfo.buffer;
141 destParam.slice[1] = destInfo.buffer + destParam.width * destParam.height;
142 }
143 }
144
YuvToI420(SrcConvertParam & srcParam,I420Info & i420)145 static bool YuvToI420(SrcConvertParam &srcParam, I420Info &i420)
146 {
147 auto &converter = ConverterHandle::GetInstance().GetHandle();
148 switch (srcParam.format) {
149 case PixelFormat::NV12:
150 converter.NV12ToI420(srcParam.slice[0], srcParam.stride[0], srcParam.slice[1], srcParam.stride[1],
151 i420.I420Y, i420.yStride, i420.I420U, i420.uStride, i420.I420V, i420.vStride,
152 i420.width, i420.height);
153 break;
154 case PixelFormat::NV21:
155 converter.NV21ToI420(srcParam.slice[0], srcParam.stride[0], srcParam.slice[1], srcParam.stride[1],
156 i420.I420Y, i420.yStride, i420.I420U, i420.uStride, i420.I420V, i420.vStride,
157 i420.width, i420.height);
158 break;
159 default:
160 return false;
161 }
162 return true;
163 }
164
I420ToRGB(I420Info & i420,DestConvertParam & destParam,ColorSpace colorSpace)165 static bool I420ToRGB(I420Info &i420, DestConvertParam &destParam, [[maybe_unused]]ColorSpace colorSpace)
166 {
167 auto &converter = ConverterHandle::GetInstance().GetHandle();
168 switch (destParam.format) {
169 case PixelFormat::RGBA_8888:
170 converter.I420ToARGBMatrix(i420.I420Y, i420.yStride, i420.I420V, i420.vStride, i420.I420U, i420.uStride,
171 destParam.slice[0], destParam.stride[0], OHOS::OpenSourceLibyuv::YuvConstants::YvuJPEG,
172 destParam.width, destParam.height);
173 break;
174 case PixelFormat::RGB_565:
175 converter.I420ToRGB565Matrix(i420.I420Y, i420.yStride, i420.I420U, i420.uStride, i420.I420V, i420.vStride,
176 destParam.slice[0], destParam.stride[0], static_cast<OHOS::OpenSourceLibyuv::ColorSpace>(colorSpace),
177 destParam.width, destParam.height);
178 break;
179 case PixelFormat::BGRA_8888:
180 converter.I420ToARGB(i420.I420Y, i420.yStride, i420.I420U, i420.uStride, i420.I420V, i420.vStride,
181 destParam.slice[0], destParam.stride[0], destParam.width, destParam.height);
182 break;
183 case PixelFormat::RGB_888:
184 converter.I420ToRAW(i420.I420Y, i420.yStride, i420.I420U, i420.uStride, i420.I420V, i420.vStride,
185 destParam.slice[0], destParam.stride[0], destParam.width, destParam.height);
186 break;
187 default:
188 return false;
189 }
190 return true;
191 }
192
CalcRGBStride(PixelFormat format,uint32_t width,int & stride)193 static bool CalcRGBStride(PixelFormat format, uint32_t width, int &stride)
194 {
195 switch (format) {
196 case PixelFormat::RGB_565:
197 stride = static_cast<int>(width * BYTES_PER_PIXEL_RGB565);
198 break;
199 case PixelFormat::RGBA_8888:
200 stride = static_cast<int>(width * BYTES_PER_PIXEL_RGBA);
201 break;
202 case PixelFormat::RGBA_1010102:
203 stride = static_cast<int>(width * BYTES_PER_PIXEL_RGBA);
204 break;
205 case PixelFormat::RGBA_F16:
206 stride = static_cast<int>(width * STRIDES_PER_PLANE);
207 break;
208 case PixelFormat::BGRA_8888:
209 stride = static_cast<int>(width * BYTES_PER_PIXEL_BGRA);
210 break;
211 case PixelFormat::RGB_888:
212 stride = static_cast<int>(width * BYTES_PER_PIXEL_RGB);
213 break;
214 default:
215 return false;
216 }
217 return true;
218 }
219
YuvToRGBParam(const YUVDataInfo & yuvInfo,SrcConvertParam & srcParam,DestConvertParam & destParam,DestConvertInfo & destInfo)220 static void YuvToRGBParam(const YUVDataInfo &yuvInfo, SrcConvertParam &srcParam,
221 DestConvertParam &destParam, DestConvertInfo &destInfo)
222 {
223 srcParam.slice[0] = srcParam.buffer + yuvInfo.yOffset;
224 srcParam.slice[1] = srcParam.buffer + yuvInfo.uvOffset;
225 srcParam.stride[0] = static_cast<int>(yuvInfo.yStride);
226 srcParam.stride[1] = static_cast<int>(yuvInfo.uvStride);
227 int dstStride = 0;
228 if (destInfo.allocType == AllocatorType::DMA_ALLOC) {
229 dstStride = static_cast<int>(destInfo.yStride);
230 destParam.slice[0] = destInfo.buffer + destInfo.yOffset;
231 } else {
232 auto bRet = CalcRGBStride(destParam.format, destParam.width, dstStride);
233 CHECK_ERROR_RETURN(!bRet);
234 destParam.slice[0] = destInfo.buffer;
235 }
236 destParam.stride[0] = dstStride;
237 }
238
I420Param(uint32_t width,uint32_t height,I420Info & i420Info)239 static bool I420Param(uint32_t width, uint32_t height, I420Info &i420Info)
240 {
241 i420Info.yStride = width;
242 i420Info.uStride = (width + NUM_1) / NUM_2;
243 i420Info.vStride = (width + NUM_1) / NUM_2;
244 i420Info.uvHeight = (height + NUM_1) / NUM_2;
245
246 const uint32_t i420BufferSize = static_cast<size_t>(i420Info.yStride * i420Info.height +
247 i420Info.uStride * i420Info.uvHeight * NUM_2);
248 bool cond = i420BufferSize <= NUM_0 || i420BufferSize > PIXEL_MAP_MAX_RAM_SIZE;
249 CHECK_ERROR_RETURN_RET_LOG(cond, false, "Invalid destination buffer size calculation!");
250 uint8_t *i420Buffer = new (std::nothrow) uint8_t[i420BufferSize];
251 CHECK_ERROR_RETURN_RET_LOG(i420Buffer == nullptr, false, "apply space for I420 buffer failed!");
252 auto i420UOffset = height * i420Info.yStride;
253 auto i420VOffset = i420UOffset + i420Info.uStride * ((height + NUM_1) / NUM_2);
254 i420Info.I420Y = i420Buffer;
255 i420Info.I420U = i420Buffer + i420UOffset;
256 i420Info.I420V = i420Buffer + i420VOffset;
257 return true;
258 }
259
YuvToI420ToRGBParam(const YUVDataInfo & yuvInfo,SrcConvertParam & srcParam,I420Info & i420Info,DestConvertParam & destParam,DestConvertInfo & destInfo)260 static bool YuvToI420ToRGBParam(const YUVDataInfo &yuvInfo, SrcConvertParam &srcParam, I420Info &i420Info,
261 DestConvertParam &destParam, DestConvertInfo &destInfo)
262 {
263 YuvToRGBParam(yuvInfo, srcParam, destParam, destInfo);
264
265 return I420Param(yuvInfo.yWidth, yuvInfo.yHeight, i420Info);
266 }
267
YuvTo420ToRGB(const uint8_t * srcBuffer,const YUVDataInfo & yuvInfo,PixelFormat srcFormat,DestConvertInfo & destInfo,ColorSpace colorSpace)268 static bool YuvTo420ToRGB(const uint8_t *srcBuffer, const YUVDataInfo &yuvInfo, PixelFormat srcFormat,
269 DestConvertInfo &destInfo, [[maybe_unused]]ColorSpace colorSpace)
270 {
271 bool cond = srcBuffer == nullptr || destInfo.buffer == nullptr || yuvInfo.yWidth == 0 || yuvInfo.yHeight == 0 ||
272 destInfo.bufferSize == 0;
273 CHECK_ERROR_RETURN_RET(cond, false);
274 SrcConvertParam srcParam = {yuvInfo.yWidth, yuvInfo.yHeight};
275 srcParam.buffer = srcBuffer;
276 srcParam.format = srcFormat;
277
278 DestConvertParam destParam = {destInfo.width, destInfo.height};
279 destParam.format = destInfo.format;
280
281 I420Info i420Info = {yuvInfo.yWidth, yuvInfo.yHeight};
282
283 YuvToI420ToRGBParam(yuvInfo, srcParam, i420Info, destParam, destInfo);
284 auto bRet = YuvToI420(srcParam, i420Info);
285 if (!bRet) {
286 delete[] i420Info.I420Y;
287 return false;
288 }
289 bRet = I420ToRGB(i420Info, destParam, colorSpace);
290 delete[] i420Info.I420Y;
291 return bRet;
292 }
293
YuvToRGBConverter(SrcConvertParam & srcParam,DestConvertParam & destParam)294 static bool YuvToRGBConverter(SrcConvertParam &srcParam, DestConvertParam &destParam)
295 {
296 auto &converter = ConverterHandle::GetInstance().GetHandle();
297 if (srcParam.format == PixelFormat::NV21) {
298 switch (destParam.format) {
299 case PixelFormat::RGB_888:
300 converter.NV21ToRAW(srcParam.slice[0], srcParam.stride[0], srcParam.slice[1], srcParam.stride[1],
301 destParam.slice[0], destParam.stride[0], destParam.width, destParam.height);
302 break;
303 case PixelFormat::BGRA_8888:
304 converter.NV21ToARGB(srcParam.slice[0], srcParam.stride[0], srcParam.slice[1], srcParam.stride[1],
305 destParam.slice[0], destParam.stride[0], destParam.width, destParam.height);
306 break;
307 default:
308 return false;
309 }
310 } else if (srcParam.format == PixelFormat::NV12) {
311 switch (destParam.format) {
312 case PixelFormat::RGB_888:
313 converter.NV12ToRAW(srcParam.slice[0], srcParam.stride[0], srcParam.slice[1], srcParam.stride[1],
314 destParam.slice[0], destParam.stride[0], destParam.width, destParam.height);
315 break;
316 case PixelFormat::BGRA_8888:
317 converter.NV12ToARGB(srcParam.slice[0], srcParam.stride[0], srcParam.slice[1], srcParam.stride[1],
318 destParam.slice[0], destParam.stride[0], destParam.width, destParam.height);
319 break;
320 default:
321 return false;
322 }
323 }
324 return true;
325 }
326
YuvToRGB(const uint8_t * srcBuffer,const YUVDataInfo & yuvInfo,PixelFormat srcFormat,DestConvertInfo & destInfo,PixelFormat destFormat)327 static bool YuvToRGB(const uint8_t *srcBuffer, const YUVDataInfo &yuvInfo, PixelFormat srcFormat,
328 DestConvertInfo &destInfo, PixelFormat destFormat)
329 {
330 bool cond = srcBuffer == nullptr || destInfo.buffer == nullptr || yuvInfo.yWidth == 0 || yuvInfo.yHeight == 0 ||
331 destInfo.bufferSize == 0;
332 CHECK_ERROR_RETURN_RET(cond, false);
333 SrcConvertParam srcParam = {yuvInfo.yWidth, yuvInfo.yHeight};
334 srcParam.buffer = srcBuffer;
335 srcParam.format = srcFormat;
336
337 DestConvertParam destParam = {destInfo.width, destInfo.height};
338 destParam.format = destFormat;
339
340 YuvToRGBParam(yuvInfo, srcParam, destParam, destInfo);
341 return YuvToRGBConverter(srcParam, destParam);
342 }
343
I010Param(I010Info & i010Info)344 static bool I010Param(I010Info &i010Info)
345 {
346 i010Info.yStride = i010Info.width;
347 i010Info.uStride = (i010Info.width + NUM_1) / NUM_2;
348 i010Info.vStride = (i010Info.width + NUM_1) / NUM_2;
349 i010Info.uvHeight = ((i010Info.height + NUM_1) / NUM_2);
350 const uint32_t i010BufferSize = static_cast<size_t>(i010Info.yStride * i010Info.height +
351 i010Info.uStride * i010Info.uvHeight * NUM_2);
352 bool cond = i010BufferSize <= NUM_0 || i010BufferSize > PIXEL_MAP_MAX_RAM_SIZE;
353 CHECK_ERROR_RETURN_RET_LOG(cond, false, "Invalid destination buffer size calculation!");
354 uint16_t *i010Buffer = new (std::nothrow) uint16_t[i010BufferSize];
355 CHECK_ERROR_RETURN_RET_LOG(i010Buffer == nullptr, false, "apply space for I420 buffer failed!");
356 i010Info.I010Y = i010Buffer;
357 i010Info.I010U = i010Info.I010Y + i010Info.height * i010Info.yStride;
358 i010Info.I010V = i010Info.I010U + i010Info.uStride * ((i010Info.height + NUM_1) / NUM_2);
359 return true;
360 }
361
RGBToYuvP010Param(const RGBDataInfo & rgbInfo,SrcConvertParam & srcParam,DestConvertParam & destParam,DestConvertInfo & destInfo)362 static void RGBToYuvP010Param(const RGBDataInfo &rgbInfo, SrcConvertParam &srcParam, DestConvertParam &destParam,
363 DestConvertInfo &destInfo)
364 {
365 srcParam.slice[0] = srcParam.buffer;
366 srcParam.stride[0] = static_cast<int>(rgbInfo.stride);
367 if (destInfo.allocType == AllocatorType::DMA_ALLOC) {
368 destParam.stride[0] = static_cast<int>(destInfo.yStride);
369 destParam.stride[1] = static_cast<int>(destInfo.uvStride);
370 destParam.slice[0] = destInfo.buffer + destInfo.yOffset;
371 destParam.slice[1] = destInfo.buffer + destInfo.uvOffset * TWO_SLICES;
372 } else {
373 int uvStride = (destParam.width % EVEN_ODD_DIVISOR == 0) ?
374 static_cast<int>(destParam.width) : static_cast<int>(destParam.width + 1);
375 destParam.stride[0] = static_cast<int>(destParam.width);
376 destParam.stride[1] = static_cast<int>(uvStride);
377 destParam.slice[0] = destInfo.buffer;
378 destParam.slice[1] = destInfo.buffer + destParam.width * destParam.height * TWO_SLICES;
379 }
380 }
381
RGBToI420ToYuvP010Param(const RGBDataInfo & rgbInfo,SrcConvertParam & srcParam,I420Info & i420Info,DestConvertParam & destParam,DestConvertInfo & destInfo)382 static bool RGBToI420ToYuvP010Param(const RGBDataInfo &rgbInfo, SrcConvertParam &srcParam, I420Info &i420Info,
383 DestConvertParam &destParam, DestConvertInfo &destInfo)
384 {
385 RGBToYuvP010Param(rgbInfo, srcParam, destParam, destInfo);
386
387 i420Info.yStride = rgbInfo.width;
388 i420Info.uStride = (rgbInfo.width + NUM_1) / NUM_2;
389 i420Info.vStride = (rgbInfo.width + NUM_1) / NUM_2;
390 i420Info.uvHeight = ((i420Info.height + NUM_1) / NUM_2);
391 const uint32_t i420BufferSize = static_cast<size_t>(i420Info.yStride * i420Info.height +
392 i420Info.uStride * i420Info.uvHeight * NUM_2);
393 bool cond = i420BufferSize <= NUM_0 || i420BufferSize > PIXEL_MAP_MAX_RAM_SIZE;
394 CHECK_ERROR_RETURN_RET_LOG(cond, false, "Invalid destination buffer size calculation!");
395 uint8_t *i420Buffer = new (std::nothrow) uint8_t[i420BufferSize];
396 CHECK_ERROR_RETURN_RET_LOG(i420Buffer == nullptr, false, "apply space for I420 buffer failed!");
397 i420Info.I420Y = i420Buffer;
398 i420Info.I420U = i420Info.I420Y + rgbInfo.height * i420Info.yStride;
399 i420Info.I420V = i420Info.I420U + i420Info.uStride * ((rgbInfo.height + NUM_1) / NUM_2);
400 return true;
401 }
402
RGBToI420ToI010ToP010(const uint8_t * srcBuffer,const RGBDataInfo & rgbInfo,PixelFormat srcFormat,DestConvertInfo & destInfo,PixelFormat dstFormat)403 static bool RGBToI420ToI010ToP010(const uint8_t *srcBuffer, const RGBDataInfo &rgbInfo, PixelFormat srcFormat,
404 DestConvertInfo &destInfo, PixelFormat dstFormat)
405 {
406 SrcConvertParam srcParam = {rgbInfo.width, rgbInfo.height};
407 srcParam.buffer = srcBuffer;
408 srcParam.format = srcFormat;
409
410 DestConvertParam destParam = {rgbInfo.width, rgbInfo.height};
411 destParam.format = dstFormat;
412 I420Info i420Info = {rgbInfo.width, rgbInfo.height};
413
414 bool cond = RGBToI420ToYuvP010Param(rgbInfo, srcParam, i420Info, destParam, destInfo);
415 CHECK_ERROR_RETURN_RET_LOG(!cond, false, "RGB conversion to YUV failed!");
416 I010Info i010Info = {rgbInfo.width, rgbInfo.height};
417 if (!I010Param(i010Info)) {
418 IMAGE_LOGE("I010 Param failed!");
419 delete[] i420Info.I420Y;
420 return false;
421 }
422 auto bRet = RGBToI420(srcParam, i420Info);
423 if (!bRet) {
424 IMAGE_LOGE("RGB conversion to I420 failed!");
425 delete[] i420Info.I420Y;
426 delete[] i010Info.I010Y;
427 return false;
428 }
429 bRet = I420ToI010(i420Info, i010Info);
430 if (!bRet) {
431 IMAGE_LOGE("I420 conversion to I010 failed!");
432 delete[] i420Info.I420Y;
433 delete[] i010Info.I010Y;
434 return false;
435 }
436 bRet = I010ToP010(i010Info, destParam);
437 if (!bRet) {
438 IMAGE_LOGE("I010 conversion to P010 failed!");
439 delete[] i420Info.I420Y;
440 delete[] i010Info.I010Y;
441 return false;
442 }
443 delete[] i420Info.I420Y;
444 delete[] i010Info.I010Y;
445 return bRet;
446 }
447
RGB10ToI420ToYuv(SrcConvertParam & srcParam,DestConvertParam & midParam,I420Info & i420,DestConvertParam & destParam)448 static bool RGB10ToI420ToYuv(SrcConvertParam &srcParam, DestConvertParam &midParam,
449 I420Info &i420, DestConvertParam &destParam)
450 {
451 auto &converter = ConverterHandle::GetInstance().GetHandle();
452 switch (destParam.format) {
453 case PixelFormat::NV12:
454 converter.AR30ToARGB(srcParam.slice[0], srcParam.stride[0], midParam.slice[0], midParam.stride[0],
455 srcParam.width, srcParam.height);
456 converter.ABGRToI420(midParam.slice[0], midParam.stride[0], i420.I420Y, i420.yStride, i420.I420U,
457 i420.uStride, i420.I420V, i420.vStride, midParam.width, midParam.height);
458 converter.I420ToNV12(i420.I420Y, i420.yStride, i420.I420U, i420.uStride, i420.I420V, i420.vStride,
459 destParam.slice[0], destParam.stride[0], destParam.slice[1], destParam.stride[1],
460 destParam.width, destParam.height);
461 break;
462 case PixelFormat::NV21:
463 converter.AR30ToARGB(srcParam.slice[0], srcParam.stride[0], midParam.slice[0], midParam.stride[0],
464 srcParam.width, srcParam.height);
465 converter.ABGRToI420(midParam.slice[0], midParam.stride[0], i420.I420Y, i420.yStride, i420.I420U,
466 i420.uStride, i420.I420V, i420.vStride, midParam.width, midParam.height);
467 converter.I420ToNV21(i420.I420Y, i420.yStride, i420.I420U, i420.uStride, i420.I420V, i420.vStride,
468 destParam.slice[0], destParam.stride[0], destParam.slice[1], destParam.stride[1],
469 destParam.width, destParam.height);
470 break;
471 default:
472 return false;
473 }
474 return true;
475 }
476
RGBAParam(DestConvertParam & srcParam)477 static bool RGBAParam(DestConvertParam &srcParam)
478 {
479 const uint32_t midBufferSize = static_cast<size_t>(srcParam.width * srcParam.height * BYTES_PER_PIXEL_RGBA);
480 bool cond = midBufferSize <= NUM_0 || midBufferSize > PIXEL_MAP_MAX_RAM_SIZE;
481 CHECK_ERROR_RETURN_RET_LOG(cond, false, "Invalid destination buffer size calculation!");
482 uint8_t *midBuffer = new (std::nothrow) uint8_t[midBufferSize];
483 CHECK_ERROR_RETURN_RET_LOG(midBuffer == nullptr, false, "apply space for I420 buffer failed!");
484 srcParam.buffer = midBuffer;
485 srcParam.slice[0] = srcParam.buffer;
486 srcParam.stride[0] = static_cast<int>(srcParam.width * BYTES_PER_PIXEL_RGBA);
487 return true;
488 }
489
RGB10ToRGBToI420Param(const RGBDataInfo & rgbInfo,SrcConvertParam & srcParam,I420Info & i420Info,DestConvertParam & destParam,DestConvertInfo & destInfo)490 static bool RGB10ToRGBToI420Param(const RGBDataInfo &rgbInfo, SrcConvertParam &srcParam, I420Info &i420Info,
491 DestConvertParam &destParam, DestConvertInfo &destInfo)
492 {
493 RGBToYuvParam(rgbInfo, srcParam, destParam, destInfo);
494
495 i420Info.yStride = rgbInfo.width;
496 i420Info.uStride = (rgbInfo.width + NUM_1) / NUM_2;
497 i420Info.vStride = (rgbInfo.width + NUM_1) / NUM_2;
498 i420Info.uvHeight = ((i420Info.height + NUM_1) / NUM_2);
499 const uint32_t i420BufferSize = static_cast<size_t>(i420Info.yStride * i420Info.height +
500 i420Info.uStride * i420Info.uvHeight * NUM_2);
501 bool cond = i420BufferSize <= NUM_0 || i420BufferSize > PIXEL_MAP_MAX_RAM_SIZE;
502 CHECK_ERROR_RETURN_RET_LOG(cond, false, "Invalid destination buffer size calculation!");
503 uint8_t *i420Buffer = new (std::nothrow) uint8_t[i420BufferSize];
504 CHECK_ERROR_RETURN_RET_LOG(i420Buffer == nullptr, false, "apply space for I420 buffer failed!");
505 i420Info.I420Y = i420Buffer;
506 i420Info.I420U = i420Info.I420Y + rgbInfo.height * i420Info.yStride;
507 i420Info.I420V = i420Info.I420U + i420Info.uStride * ((rgbInfo.height + NUM_1) / NUM_2);
508 return true;
509 }
510
RGB10ToRGBToI420ToYuv(const uint8_t * srcBuffer,const RGBDataInfo & rgbInfo,PixelFormat srcFormat,DestConvertInfo & destInfo,PixelFormat dstFormat)511 static bool RGB10ToRGBToI420ToYuv(const uint8_t *srcBuffer, const RGBDataInfo &rgbInfo, PixelFormat srcFormat,
512 DestConvertInfo &destInfo, PixelFormat dstFormat)
513 {
514 SrcConvertParam srcParam = {rgbInfo.width, rgbInfo.height};
515 srcParam.buffer = srcBuffer;
516 srcParam.format = srcFormat;
517
518 DestConvertParam destParam = {rgbInfo.width, rgbInfo.height};
519 destParam.format = dstFormat;
520
521 I420Info i420Info = {rgbInfo.width, rgbInfo.height};
522
523 bool cond = RGB10ToRGBToI420Param(rgbInfo, srcParam, i420Info, destParam, destInfo);
524 CHECK_ERROR_RETURN_RET_LOG(!cond, false, "RGB conversion to YUV failed!");
525
526 DestConvertParam midParam = {rgbInfo.width, rgbInfo.height};
527 if (!RGBAParam(midParam)) {
528 IMAGE_LOGE("I010 Param failed!");
529 delete[] i420Info.I420Y;
530 return false;
531 }
532
533 auto bRet = RGB10ToI420ToYuv(srcParam, midParam, i420Info, destParam);
534 if (!bRet) {
535 IMAGE_LOGE("RGB10 conversion to YUV failed!");
536 delete[] i420Info.I420Y;
537 delete[] midParam.buffer;
538 return false;
539 }
540 delete[] i420Info.I420Y;
541 delete[] midParam.buffer;
542 return bRet;
543 }
544
I010ToRGB10(I010Info & i010,DestConvertParam & destParam)545 static bool I010ToRGB10(I010Info &i010, DestConvertParam &destParam)
546 {
547 auto &converter = ConverterHandle::GetInstance().GetHandle();
548 bool ret = converter.U010VUToAB30(i010.I010Y, i010.yStride, i010.I010U, i010.uStride, i010.I010V, i010.vStride,
549 destParam.slice[0], destParam.stride[0], destParam.width, destParam.height);
550 CHECK_ERROR_RETURN_RET_LOG(ret != 0, false, "I010ToAB30 failed, ret = %{public}d!", ret);
551 return true;
552 }
553
YuvToI420ToI010ToRGB10(const uint8_t * srcBuffer,const YUVDataInfo & yuvInfo,PixelFormat srcFormat,DestConvertInfo & destInfo,ColorSpace colorSpace)554 static bool YuvToI420ToI010ToRGB10(const uint8_t *srcBuffer, const YUVDataInfo &yuvInfo, PixelFormat srcFormat,
555 DestConvertInfo &destInfo, [[maybe_unused]]ColorSpace colorSpace)
556 {
557 SrcConvertParam srcParam = {yuvInfo.yWidth, yuvInfo.yHeight};
558 srcParam.buffer = srcBuffer;
559 srcParam.format = srcFormat;
560
561 DestConvertParam destParam = {yuvInfo.yWidth, yuvInfo.yHeight};
562 destParam.format = destInfo.format;
563
564 I420Info i420Info = {yuvInfo.yWidth, yuvInfo.yHeight};
565
566 YuvToI420ToRGBParam(yuvInfo, srcParam, i420Info, destParam, destInfo);
567
568 I010Info i010Info = {yuvInfo.yWidth, yuvInfo.yHeight};
569
570 if (!I010Param(i010Info)) {
571 IMAGE_LOGE("I010 Param failed!");
572 delete[] i420Info.I420Y;
573 return false;
574 }
575
576 auto bRet = YuvToI420(srcParam, i420Info);
577 if (!bRet) {
578 IMAGE_LOGE("Yuv conversion to I420 failed!");
579 delete[] i420Info.I420Y;
580 delete[] i010Info.I010Y;
581 return false;
582 }
583
584 bRet = I420ToI010(i420Info, i010Info);
585 if (!bRet) {
586 IMAGE_LOGE("I420 conversion to I010 failed!");
587 delete[] i420Info.I420Y;
588 delete[] i010Info.I010Y;
589 return false;
590 }
591
592 bRet = I010ToRGB10(i010Info, destParam);
593 if (!bRet) {
594 IMAGE_LOGE("I010 conversion to RGB10 failed!");
595 delete[] i420Info.I420Y;
596 delete[] i010Info.I010Y;
597 return false;
598 }
599 delete[] i420Info.I420Y;
600 delete[] i010Info.I010Y;
601 return bRet;
602 }
603
YuvToP010Param(const YUVDataInfo & yDInfo,SrcConvertParam & srcParam,DestConvertParam & destParam,DestConvertInfo & destInfo)604 static bool YuvToP010Param(const YUVDataInfo &yDInfo, SrcConvertParam &srcParam, DestConvertParam &destParam,
605 DestConvertInfo &destInfo)
606 {
607 srcParam.slice[0] = srcParam.buffer + yDInfo.yOffset;
608 srcParam.slice[1] = srcParam.buffer + yDInfo.uvOffset;
609
610 srcParam.stride[0] = static_cast<int>(yDInfo.yStride);
611 srcParam.stride[1] = static_cast<int>(yDInfo.uvStride);
612
613 uint32_t dstyStride = 0;
614 uint32_t dstuvStride = 0;
615 if (destInfo.allocType == AllocatorType::DMA_ALLOC) {
616 dstyStride = destInfo.yStride;
617 dstuvStride = destInfo.uvStride;
618 destParam.slice[0] = destInfo.buffer + destInfo.yOffset;
619 destParam.slice[1] = destInfo.buffer + destInfo.uvOffset * TWO_SLICES;
620 } else {
621 dstyStride = destParam.width;
622 dstuvStride = (destParam.width % EVEN_ODD_DIVISOR == 0) ?
623 destParam.width : (destParam.width + 1);
624 destParam.slice[0] = destInfo.buffer;
625 destParam.slice[1] = destInfo.buffer + dstyStride * destParam.height * TWO_SLICES;
626 }
627 destParam.stride[0] = static_cast<int>(dstyStride);
628 destParam.stride[1] = static_cast<int>(dstuvStride);
629 return true;
630 }
631
YuvToI420ToP010Param(const YUVDataInfo & yuvInfo,SrcConvertParam & srcParam,I420Info & i420Info,DestConvertParam & destParam,DestConvertInfo & destInfo)632 static bool YuvToI420ToP010Param(const YUVDataInfo &yuvInfo, SrcConvertParam &srcParam, I420Info &i420Info,
633 DestConvertParam &destParam, DestConvertInfo &destInfo)
634 {
635 YuvToP010Param(yuvInfo, srcParam, destParam, destInfo);
636 i420Info.yStride = yuvInfo.yWidth;
637 i420Info.uStride = (yuvInfo.yWidth + NUM_1) / NUM_2;
638 i420Info.vStride = (yuvInfo.yWidth + NUM_1) / NUM_2;
639 i420Info.uvHeight = ((i420Info.height + NUM_1) / NUM_2);
640 const uint32_t i420BufferSize = static_cast<size_t>(i420Info.yStride * i420Info.height +
641 i420Info.uStride * i420Info.uvHeight * NUM_2);
642 bool cond = i420BufferSize <= NUM_0 || i420BufferSize > PIXEL_MAP_MAX_RAM_SIZE;
643 CHECK_ERROR_RETURN_RET_LOG(cond, false, "Invalid destination buffer size calculation!");
644 uint8_t *i420Buffer = new (std::nothrow) uint8_t[i420BufferSize];
645 CHECK_ERROR_RETURN_RET_LOG(i420Buffer == nullptr, false, "apply space for I420 buffer failed!");
646 i420Info.I420Y = i420Buffer;
647 i420Info.I420U = i420Info.I420Y + yuvInfo.yHeight * i420Info.yStride;
648 i420Info.I420V = i420Info.I420U + i420Info.uStride * ((yuvInfo.yHeight + NUM_1) / NUM_2);
649 return true;
650 }
651
YuvToI420ToI010ToP010(const uint8_t * srcBuffer,const YUVDataInfo & yuvInfo,PixelFormat srcFormat,DestConvertInfo & destInfo,ColorSpace colorSpace)652 static bool YuvToI420ToI010ToP010(const uint8_t *srcBuffer, const YUVDataInfo &yuvInfo, PixelFormat srcFormat,
653 DestConvertInfo &destInfo, [[maybe_unused]]ColorSpace colorSpace)
654 {
655 SrcConvertParam srcParam = {yuvInfo.yWidth, yuvInfo.yHeight};
656 srcParam.buffer = srcBuffer;
657 srcParam.format = srcFormat;
658
659 DestConvertParam destParam = {yuvInfo.yWidth, yuvInfo.yHeight};
660 destParam.format = destInfo.format;
661
662 I420Info i420Info = {yuvInfo.yWidth, yuvInfo.yHeight};
663
664 YuvToI420ToP010Param(yuvInfo, srcParam, i420Info, destParam, destInfo);
665
666 I010Info i010Info = {yuvInfo.yWidth, yuvInfo.yHeight};
667
668 if (!I010Param(i010Info)) {
669 IMAGE_LOGE("I010 Param failed!");
670 delete[] i420Info.I420Y;
671 return false;
672 }
673
674 auto bRet = YuvToI420(srcParam, i420Info);
675 if (!bRet) {
676 IMAGE_LOGE("Yuv conversion to I420 failed!");
677 delete[] i420Info.I420Y;
678 delete[] i010Info.I010Y;
679 return false;
680 }
681
682 bRet = I420ToI010(i420Info, i010Info);
683 if (!bRet) {
684 IMAGE_LOGE("I420 conversion to I010 failed!");
685 delete[] i420Info.I420Y;
686 delete[] i010Info.I010Y;
687 return false;
688 }
689
690 bRet = I010ToP010(i010Info, destParam);
691 if (!bRet) {
692 IMAGE_LOGE("I010 conversion to P010 failed!");
693 delete[] i420Info.I420Y;
694 delete[] i010Info.I010Y;
695 return false;
696 }
697 delete[] i420Info.I420Y;
698 delete[] i010Info.I010Y;
699 return bRet;
700 }
701
P010ToI010(SrcConvertParam & srcParam,I010Info & i010)702 static bool P010ToI010(SrcConvertParam &srcParam, I010Info &i010)
703 {
704 auto &converter = ConverterHandle::GetInstance().GetHandle();
705 switch (srcParam.format) {
706 case PixelFormat::YCBCR_P010:
707 converter.P010ToI010(reinterpret_cast<const uint16_t *>(srcParam.slice[0]), srcParam.stride[0],
708 reinterpret_cast<const uint16_t *>(srcParam.slice[1]), srcParam.stride[1],
709 i010.I010Y, i010.yStride, i010.I010U, i010.uStride, i010.I010V, i010.vStride,
710 srcParam.width, srcParam.height);
711 break;
712 case PixelFormat::YCRCB_P010:
713 converter.P010ToI010(reinterpret_cast<const uint16_t *>(srcParam.slice[0]), srcParam.stride[0],
714 reinterpret_cast<const uint16_t *>(srcParam.slice[1]), srcParam.stride[1],
715 i010.I010Y, i010.yStride, i010.I010V, i010.vStride, i010.I010U, i010.uStride,
716 srcParam.width, srcParam.height);
717 break;
718 default:
719 return false;
720 }
721 return true;
722 }
723
YuvP010ToYuvParam(const YUVDataInfo & yDInfo,SrcConvertParam & srcParam,DestConvertParam & destParam,DestConvertInfo & destInfo)724 static bool YuvP010ToYuvParam(const YUVDataInfo &yDInfo, SrcConvertParam &srcParam, DestConvertParam &destParam,
725 DestConvertInfo &destInfo)
726 {
727 srcParam.slice[0] = srcParam.buffer + yDInfo.yOffset;
728 srcParam.slice[1] = srcParam.buffer + yDInfo.uvOffset * TWO_SLICES;
729
730 srcParam.stride[0] = static_cast<int>(yDInfo.yStride);
731 srcParam.stride[1] = static_cast<int>(yDInfo.uvStride);
732
733 uint32_t dstyStride = 0;
734 uint32_t dstuvStride = 0;
735 if (destInfo.allocType == AllocatorType::DMA_ALLOC) {
736 dstyStride = destInfo.yStride;
737 dstuvStride = destInfo.uvStride;
738 destParam.slice[0] = destInfo.buffer + destInfo.yOffset;
739 destParam.slice[1] = destInfo.buffer + destInfo.uvOffset;
740 } else {
741 dstyStride = destParam.width;
742 dstuvStride = (destParam.width % EVEN_ODD_DIVISOR == 0) ?
743 destParam.width : (destParam.width + 1);
744 destParam.slice[0] = destInfo.buffer;
745 destParam.slice[1] = destInfo.buffer + dstyStride * destParam.height;
746 }
747 destParam.stride[0] = static_cast<int>(dstyStride);
748 destParam.stride[1] = static_cast<int>(dstuvStride);
749 return true;
750 }
751
YuvP010ToI420ToYuvParam(const YUVDataInfo & yuvInfo,SrcConvertParam & srcParam,I420Info & i420Info,DestConvertParam & destParam,DestConvertInfo & destInfo)752 static bool YuvP010ToI420ToYuvParam(const YUVDataInfo &yuvInfo, SrcConvertParam &srcParam, I420Info &i420Info,
753 DestConvertParam &destParam, DestConvertInfo &destInfo)
754 {
755 YuvP010ToYuvParam(yuvInfo, srcParam, destParam, destInfo);
756 i420Info.yStride = yuvInfo.yWidth;
757 i420Info.uStride = (yuvInfo.yWidth + NUM_1) / NUM_2;
758 i420Info.vStride = (yuvInfo.yWidth + NUM_1) / NUM_2;
759 i420Info.uvHeight = ((i420Info.height + NUM_1) / NUM_2);
760 const uint32_t i420BufferSize = static_cast<size_t>(i420Info.yStride * i420Info.height +
761 i420Info.uStride * i420Info.uvHeight * NUM_2);
762 bool cond = i420BufferSize <= NUM_0 || i420BufferSize > PIXEL_MAP_MAX_RAM_SIZE;
763 CHECK_ERROR_RETURN_RET_LOG(cond, false, "Invalid destination buffer size calculation!");
764 uint8_t *i420Buffer = new (std::nothrow) uint8_t[i420BufferSize];
765 CHECK_ERROR_RETURN_RET_LOG(i420Buffer == nullptr, false, "apply space for I420 buffer failed!");
766 i420Info.I420Y = i420Buffer;
767 i420Info.I420U = i420Info.I420Y + yuvInfo.yHeight * i420Info.yStride;
768 i420Info.I420V = i420Info.I420U + i420Info.uStride * ((yuvInfo.yHeight + NUM_1) / NUM_2);
769 return true;
770 }
771
I010ToI420(I010Info & i010,I420Info & i420)772 static bool I010ToI420(I010Info &i010, I420Info &i420)
773 {
774 auto &converter = ConverterHandle::GetInstance().GetHandle();
775 converter.I010ToI420(i010.I010Y, i010.yStride, i010.I010U, i010.uStride, i010.I010V, i010.vStride,
776 i420.I420Y, i420.yStride, i420.I420U, i420.uStride, i420.I420V, i420.vStride,
777 i010.width, i010.height);
778 return true;
779 }
780
P010ToI010ToI420ToYuv(const uint8_t * srcBuffer,const YUVDataInfo & yuvInfo,PixelFormat srcFormat,DestConvertInfo & destInfo,ColorSpace colorSpace)781 static bool P010ToI010ToI420ToYuv(const uint8_t *srcBuffer, const YUVDataInfo &yuvInfo, PixelFormat srcFormat,
782 DestConvertInfo &destInfo, [[maybe_unused]]ColorSpace colorSpace)
783 {
784 SrcConvertParam srcParam = {yuvInfo.yWidth, yuvInfo.yHeight};
785 srcParam.buffer = srcBuffer;
786 srcParam.format = srcFormat;
787
788 DestConvertParam destParam = {yuvInfo.yWidth, yuvInfo.yHeight};
789 destParam.format = destInfo.format;
790
791 I420Info i420Info = {yuvInfo.yWidth, yuvInfo.yHeight};
792
793 YuvP010ToI420ToYuvParam(yuvInfo, srcParam, i420Info, destParam, destInfo);
794
795 I010Info i010Info = {yuvInfo.yWidth, yuvInfo.yHeight};
796
797 if (!I010Param(i010Info)) {
798 IMAGE_LOGE("I010 Param failed!");
799 delete[] i420Info.I420Y;
800 return false;
801 }
802
803 auto bRet = P010ToI010(srcParam, i010Info);
804 if (!bRet) {
805 IMAGE_LOGE("P010 conversion to I010 failed!");
806 delete[] i420Info.I420Y;
807 delete[] i010Info.I010Y;
808 return false;
809 }
810
811 bRet = I010ToI420(i010Info, i420Info);
812 if (!bRet) {
813 IMAGE_LOGE("I010 conversion to I420 failed!");
814 delete[] i420Info.I420Y;
815 delete[] i010Info.I010Y;
816 return false;
817 }
818 bRet = I420ToYuv(i420Info, destParam);
819 if (!bRet) {
820 IMAGE_LOGE("I420 conversion to Yuv failed!");
821 delete[] i420Info.I420Y;
822 delete[] i010Info.I010Y;
823 return false;
824 }
825 delete[] i420Info.I420Y;
826 delete[] i010Info.I010Y;
827 return bRet;
828 }
829
YuvP010ToRGBParam(const YUVDataInfo & yuvInfo,SrcConvertParam & srcParam,DestConvertParam & destParam,DestConvertInfo & destInfo)830 static void YuvP010ToRGBParam(const YUVDataInfo &yuvInfo, SrcConvertParam &srcParam,
831 DestConvertParam &destParam, DestConvertInfo &destInfo)
832 {
833 srcParam.slice[0] = srcParam.buffer + yuvInfo.yOffset;
834 srcParam.slice[1] = srcParam.buffer + yuvInfo.uvOffset * TWO_SLICES;
835 srcParam.stride[0] = static_cast<int>(yuvInfo.yStride);
836 srcParam.stride[1] = static_cast<int>(yuvInfo.uvStride);
837 int dstStride = 0;
838 if (destInfo.allocType == AllocatorType::DMA_ALLOC) {
839 dstStride = static_cast<int>(destInfo.yStride);
840 destParam.slice[0] = destInfo.buffer + destInfo.yOffset;
841 } else {
842 auto bRet = CalcRGBStride(destParam.format, destParam.width, dstStride);
843 if (!bRet) {
844 return;
845 }
846 destParam.slice[0] = destInfo.buffer;
847 }
848 destParam.stride[0] = dstStride;
849 }
850
YuvP010ToI420ToRGBParam(const YUVDataInfo & yuvInfo,SrcConvertParam & srcParam,I420Info & i420Info,DestConvertParam & destParam,DestConvertInfo & destInfo)851 static bool YuvP010ToI420ToRGBParam(const YUVDataInfo &yuvInfo, SrcConvertParam &srcParam, I420Info &i420Info,
852 DestConvertParam &destParam, DestConvertInfo &destInfo)
853 {
854 YuvP010ToRGBParam(yuvInfo, srcParam, destParam, destInfo);
855 i420Info.yStride = yuvInfo.yWidth;
856 i420Info.uStride = (yuvInfo.yWidth + NUM_1) / NUM_2;
857 i420Info.vStride = (yuvInfo.yWidth + NUM_1) / NUM_2;
858 i420Info.uvHeight = ((i420Info.height + NUM_1) / NUM_2);
859 const uint32_t i420BufferSize = static_cast<size_t>(i420Info.yStride * i420Info.height +
860 i420Info.uStride * i420Info.uvHeight * NUM_2);
861 bool cond = i420BufferSize <= NUM_0 || i420BufferSize > PIXEL_MAP_MAX_RAM_SIZE;
862 CHECK_ERROR_RETURN_RET_LOG(cond, false, "Invalid destination buffer size calculation!");
863 uint8_t *i420Buffer = new (std::nothrow) uint8_t[i420BufferSize];
864 CHECK_ERROR_RETURN_RET_LOG(i420Buffer == nullptr, false, "apply space for I420 buffer failed!");
865 i420Info.I420Y = i420Buffer;
866 i420Info.I420U = i420Info.I420Y + yuvInfo.yHeight * i420Info.yStride;
867 i420Info.I420V = i420Info.I420U + i420Info.uStride * ((yuvInfo.yHeight + NUM_1) / NUM_2);
868 return true;
869 }
870
P010ToI010ToI420ToRGB(const uint8_t * srcBuffer,const YUVDataInfo & yuvInfo,PixelFormat srcFormat,DestConvertInfo & destInfo,ColorSpace colorSpace)871 static bool P010ToI010ToI420ToRGB(const uint8_t *srcBuffer, const YUVDataInfo &yuvInfo, PixelFormat srcFormat,
872 DestConvertInfo &destInfo, [[maybe_unused]]ColorSpace colorSpace)
873 {
874 SrcConvertParam srcParam = {yuvInfo.yWidth, yuvInfo.yHeight};
875 srcParam.buffer = srcBuffer;
876 srcParam.format = srcFormat;
877
878 DestConvertParam destParam = {yuvInfo.yWidth, yuvInfo.yHeight};
879 destParam.format = destInfo.format;
880
881 I420Info i420Info = {yuvInfo.yWidth, yuvInfo.yHeight};
882
883 YuvP010ToI420ToRGBParam(yuvInfo, srcParam, i420Info, destParam, destInfo);
884
885 I010Info i010Info = {yuvInfo.yWidth, yuvInfo.yHeight};
886
887 if (!I010Param(i010Info)) {
888 IMAGE_LOGE("I010 Param failed!");
889 delete[] i420Info.I420Y;
890 return false;
891 }
892
893 auto bRet = P010ToI010(srcParam, i010Info);
894 if (!bRet) {
895 IMAGE_LOGE("P010 conversion to I010 failed!");
896 delete[] i420Info.I420Y;
897 delete[] i010Info.I010Y;
898 return false;
899 }
900
901 bRet = I010ToI420(i010Info, i420Info);
902 if (!bRet) {
903 IMAGE_LOGE("I010 conversion to I420 failed!");
904 delete[] i420Info.I420Y;
905 delete[] i010Info.I010Y;
906 return false;
907 }
908 bRet = I420ToRGB(i420Info, destParam, colorSpace);
909 if (!bRet) {
910 IMAGE_LOGE("I420 conversion to RGB failed!");
911 delete[] i420Info.I420Y;
912 delete[] i010Info.I010Y;
913 return false;
914 }
915 delete[] i420Info.I420Y;
916 delete[] i010Info.I010Y;
917 return bRet;
918 }
919
P010ToI010ToRGB10Param(const YUVDataInfo & yuvInfo,SrcConvertParam & srcParam,I010Info & i010Info,DestConvertParam & destParam,DestConvertInfo & destInfo)920 static bool P010ToI010ToRGB10Param(const YUVDataInfo &yuvInfo, SrcConvertParam &srcParam, I010Info &i010Info,
921 DestConvertParam &destParam, DestConvertInfo &destInfo)
922 {
923 YuvP010ToRGBParam(yuvInfo, srcParam, destParam, destInfo);
924 i010Info.yStride = yuvInfo.yWidth;
925 i010Info.uStride = (yuvInfo.yWidth + NUM_1) / NUM_2;
926 i010Info.vStride = (yuvInfo.yWidth + NUM_1) / NUM_2;
927 i010Info.uvHeight = ((i010Info.height + NUM_1) / NUM_2);
928 const uint32_t i010BufferSize = static_cast<size_t>(i010Info.yStride * i010Info.height +
929 i010Info.uStride * i010Info.uvHeight * NUM_2);
930 bool cond = i010BufferSize <= NUM_0 || i010BufferSize > PIXEL_MAP_MAX_RAM_SIZE;
931 CHECK_ERROR_RETURN_RET_LOG(cond, false, "Invalid destination buffer size calculation!");
932 uint16_t *i010Buffer = new (std::nothrow) uint16_t[i010BufferSize];
933 CHECK_ERROR_RETURN_RET_LOG(i010Buffer == nullptr, false, "apply space for I420 buffer failed!");
934 i010Info.I010Y = i010Buffer;
935 i010Info.I010U = i010Info.I010Y + yuvInfo.yHeight * i010Info.yStride;
936 i010Info.I010V = i010Info.I010U + i010Info.uStride * ((yuvInfo.yHeight + NUM_1) / NUM_2);
937 return true;
938 }
939
P010ToI010ToRGB10(const uint8_t * srcBuffer,const YUVDataInfo & yuvInfo,PixelFormat srcFormat,DestConvertInfo & destInfo,ColorSpace colorSpace)940 static bool P010ToI010ToRGB10(const uint8_t *srcBuffer, const YUVDataInfo &yuvInfo, PixelFormat srcFormat,
941 DestConvertInfo &destInfo, [[maybe_unused]]ColorSpace colorSpace)
942 {
943 SrcConvertParam srcParam = {yuvInfo.yWidth, yuvInfo.yHeight};
944 srcParam.buffer = srcBuffer;
945 srcParam.format = srcFormat;
946
947 DestConvertParam destParam = {yuvInfo.yWidth, yuvInfo.yHeight};
948 destParam.format = destInfo.format;
949
950 I010Info i010Info = {yuvInfo.yWidth, yuvInfo.yHeight};
951
952 P010ToI010ToRGB10Param(yuvInfo, srcParam, i010Info, destParam, destInfo);
953
954 auto bRet = P010ToI010(srcParam, i010Info);
955 if (!bRet) {
956 IMAGE_LOGE("P010 conversion to I010 failed!");
957 delete[] i010Info.I010Y;
958 return false;
959 }
960
961 bRet = I010ToRGB10(i010Info, destParam);
962 if (!bRet) {
963 IMAGE_LOGE("I010 conversion to RGB10 failed!");
964 delete[] i010Info.I010Y;
965 return false;
966 }
967 delete[] i010Info.I010Y;
968 return bRet;
969 }
970
RGB565ToNV12P010(const uint8_t * srcBuffer,const RGBDataInfo & rgbInfo,DestConvertInfo & destInfo,ColorSpace colorSpace)971 bool ImageFormatConvertExtUtils::RGB565ToNV12P010(const uint8_t *srcBuffer, const RGBDataInfo &rgbInfo,
972 DestConvertInfo &destInfo, [[maybe_unused]]ColorSpace colorSpace)
973 {
974 return RGBToI420ToI010ToP010(srcBuffer, rgbInfo, PixelFormat::RGB_565, destInfo, PixelFormat::YCBCR_P010);
975 }
976
RGB565ToNV21P010(const uint8_t * srcBuffer,const RGBDataInfo & rgbInfo,DestConvertInfo & destInfo,ColorSpace colorSpace)977 bool ImageFormatConvertExtUtils::RGB565ToNV21P010(const uint8_t *srcBuffer, const RGBDataInfo &rgbInfo,
978 DestConvertInfo &destInfo, [[maybe_unused]]ColorSpace colorSpace)
979 {
980 return RGBToI420ToI010ToP010(srcBuffer, rgbInfo, PixelFormat::RGB_565, destInfo, PixelFormat::YCRCB_P010);
981 }
982
RGBAToNV12P010(const uint8_t * srcBuffer,const RGBDataInfo & rgbInfo,DestConvertInfo & destInfo,ColorSpace colorSpace)983 bool ImageFormatConvertExtUtils::RGBAToNV12P010(const uint8_t *srcBuffer, const RGBDataInfo &rgbInfo,
984 DestConvertInfo &destInfo, [[maybe_unused]]ColorSpace colorSpace)
985 {
986 return RGBToI420ToI010ToP010(srcBuffer, rgbInfo, PixelFormat::RGBA_8888, destInfo, PixelFormat::YCBCR_P010);
987 }
988
RGBAToNV21P010(const uint8_t * srcBuffer,const RGBDataInfo & rgbInfo,DestConvertInfo & destInfo,ColorSpace colorSpace)989 bool ImageFormatConvertExtUtils::RGBAToNV21P010(const uint8_t *srcBuffer, const RGBDataInfo &rgbInfo,
990 DestConvertInfo &destInfo, [[maybe_unused]]ColorSpace colorSpace)
991 {
992 return RGBToI420ToI010ToP010(srcBuffer, rgbInfo, PixelFormat::RGBA_8888, destInfo, PixelFormat::YCRCB_P010);
993 }
994
BGRAToNV12P010(const uint8_t * srcBuffer,const RGBDataInfo & rgbInfo,DestConvertInfo & destInfo,ColorSpace colorSpace)995 bool ImageFormatConvertExtUtils::BGRAToNV12P010(const uint8_t *srcBuffer, const RGBDataInfo &rgbInfo,
996 DestConvertInfo &destInfo, [[maybe_unused]]ColorSpace colorSpace)
997 {
998 return RGBToI420ToI010ToP010(srcBuffer, rgbInfo, PixelFormat::RGBA_8888, destInfo, PixelFormat::YCBCR_P010);
999 }
1000
BGRAToNV21P010(const uint8_t * srcBuffer,const RGBDataInfo & rgbInfo,DestConvertInfo & destInfo,ColorSpace colorSpace)1001 bool ImageFormatConvertExtUtils::BGRAToNV21P010(const uint8_t *srcBuffer, const RGBDataInfo &rgbInfo,
1002 DestConvertInfo &destInfo, [[maybe_unused]]ColorSpace colorSpace)
1003 {
1004 return RGBToI420ToI010ToP010(srcBuffer, rgbInfo, PixelFormat::RGBA_8888, destInfo, PixelFormat::YCRCB_P010);
1005 }
1006
RGBToNV12P010(const uint8_t * srcBuffer,const RGBDataInfo & rgbInfo,DestConvertInfo & destInfo,ColorSpace colorSpace)1007 bool ImageFormatConvertExtUtils::RGBToNV12P010(const uint8_t *srcBuffer, const RGBDataInfo &rgbInfo,
1008 DestConvertInfo &destInfo, [[maybe_unused]]ColorSpace colorSpace)
1009 {
1010 return RGBToI420ToI010ToP010(srcBuffer, rgbInfo, PixelFormat::RGB_888, destInfo, PixelFormat::YCBCR_P010);
1011 }
1012
RGBToNV21P010(const uint8_t * srcBuffer,const RGBDataInfo & rgbInfo,DestConvertInfo & destInfo,ColorSpace colorSpace)1013 bool ImageFormatConvertExtUtils::RGBToNV21P010(const uint8_t *srcBuffer, const RGBDataInfo &rgbInfo,
1014 DestConvertInfo &destInfo, [[maybe_unused]]ColorSpace colorSpace)
1015 {
1016 return RGBToI420ToI010ToP010(srcBuffer, rgbInfo, PixelFormat::RGB_888, destInfo, PixelFormat::YCRCB_P010);
1017 }
1018
RGBA1010102ToNV12(const uint8_t * srcBuffer,const RGBDataInfo & rgbInfo,DestConvertInfo & destInfo,ColorSpace colorSpace)1019 bool ImageFormatConvertExtUtils::RGBA1010102ToNV12(const uint8_t *srcBuffer, const RGBDataInfo &rgbInfo,
1020 DestConvertInfo &destInfo, [[maybe_unused]]ColorSpace colorSpace)
1021 {
1022 return RGB10ToRGBToI420ToYuv(srcBuffer, rgbInfo, PixelFormat::RGBA_1010102, destInfo, PixelFormat::NV12);
1023 }
1024
RGBA1010102ToNV21(const uint8_t * srcBuffer,const RGBDataInfo & rgbInfo,DestConvertInfo & destInfo,ColorSpace colorSpace)1025 bool ImageFormatConvertExtUtils::RGBA1010102ToNV21(const uint8_t *srcBuffer, const RGBDataInfo &rgbInfo,
1026 DestConvertInfo &destInfo, [[maybe_unused]]ColorSpace colorSpace)
1027 {
1028 return RGB10ToRGBToI420ToYuv(srcBuffer, rgbInfo, PixelFormat::RGBA_1010102, destInfo, PixelFormat::NV21);
1029 }
1030
NV12ToRGBA1010102(const uint8_t * srcBuffer,const YUVDataInfo & yDInfo,DestConvertInfo & destInfo,ColorSpace colorSpace)1031 bool ImageFormatConvertExtUtils::NV12ToRGBA1010102(const uint8_t *srcBuffer, const YUVDataInfo &yDInfo,
1032 DestConvertInfo &destInfo, [[maybe_unused]]ColorSpace colorSpace)
1033 {
1034 return YuvToI420ToI010ToRGB10(srcBuffer, yDInfo, PixelFormat::NV12, destInfo, colorSpace);
1035 }
1036
NV21ToRGBA1010102(const uint8_t * srcBuffer,const YUVDataInfo & yDInfo,DestConvertInfo & destInfo,ColorSpace colorSpace)1037 bool ImageFormatConvertExtUtils::NV21ToRGBA1010102(const uint8_t *srcBuffer, const YUVDataInfo &yDInfo,
1038 DestConvertInfo &destInfo, [[maybe_unused]]ColorSpace colorSpace)
1039 {
1040 return YuvToI420ToI010ToRGB10(srcBuffer, yDInfo, PixelFormat::NV21, destInfo, colorSpace);
1041 }
1042
NV12ToNV12P010(const uint8_t * srcBuffer,const YUVDataInfo & yDInfo,DestConvertInfo & destInfo,ColorSpace colorSpace)1043 bool ImageFormatConvertExtUtils::NV12ToNV12P010(const uint8_t *srcBuffer, const YUVDataInfo &yDInfo,
1044 DestConvertInfo &destInfo, [[maybe_unused]]ColorSpace colorSpace)
1045 {
1046 return YuvToI420ToI010ToP010(srcBuffer, yDInfo, PixelFormat::NV12, destInfo, colorSpace);
1047 }
1048
NV12ToNV21P010(const uint8_t * srcBuffer,const YUVDataInfo & yDInfo,DestConvertInfo & destInfo,ColorSpace colorSpace)1049 bool ImageFormatConvertExtUtils::NV12ToNV21P010(const uint8_t *srcBuffer, const YUVDataInfo &yDInfo,
1050 DestConvertInfo &destInfo, [[maybe_unused]]ColorSpace colorSpace)
1051 {
1052 return YuvToI420ToI010ToP010(srcBuffer, yDInfo, PixelFormat::NV12, destInfo, colorSpace);
1053 }
1054
NV21ToNV12P010(const uint8_t * srcBuffer,const YUVDataInfo & yDInfo,DestConvertInfo & destInfo,ColorSpace colorSpace)1055 bool ImageFormatConvertExtUtils::NV21ToNV12P010(const uint8_t *srcBuffer, const YUVDataInfo &yDInfo,
1056 DestConvertInfo &destInfo, [[maybe_unused]]ColorSpace colorSpace)
1057 {
1058 return YuvToI420ToI010ToP010(srcBuffer, yDInfo, PixelFormat::NV21, destInfo, colorSpace);
1059 }
1060
NV21ToNV21P010(const uint8_t * srcBuffer,const YUVDataInfo & yDInfo,DestConvertInfo & destInfo,ColorSpace colorSpace)1061 bool ImageFormatConvertExtUtils::NV21ToNV21P010(const uint8_t *srcBuffer, const YUVDataInfo &yDInfo,
1062 DestConvertInfo &destInfo, [[maybe_unused]]ColorSpace colorSpace)
1063 {
1064 return YuvToI420ToI010ToP010(srcBuffer, yDInfo, PixelFormat::NV21, destInfo, colorSpace);
1065 }
1066
NV12P010ToNV12(const uint8_t * srcBuffer,const YUVDataInfo & yDInfo,DestConvertInfo & destInfo,ColorSpace colorSpace)1067 bool ImageFormatConvertExtUtils::NV12P010ToNV12(const uint8_t *srcBuffer, const YUVDataInfo &yDInfo,
1068 DestConvertInfo &destInfo, [[maybe_unused]]ColorSpace colorSpace)
1069 {
1070 return P010ToI010ToI420ToYuv(srcBuffer, yDInfo, PixelFormat::YCBCR_P010, destInfo, colorSpace);
1071 }
1072
NV12P010ToNV21(const uint8_t * srcBuffer,const YUVDataInfo & yDInfo,DestConvertInfo & destInfo,ColorSpace colorSpace)1073 bool ImageFormatConvertExtUtils::NV12P010ToNV21(const uint8_t *srcBuffer, const YUVDataInfo &yDInfo,
1074 DestConvertInfo &destInfo, [[maybe_unused]]ColorSpace colorSpace)
1075 {
1076 return P010ToI010ToI420ToYuv(srcBuffer, yDInfo, PixelFormat::YCBCR_P010, destInfo, colorSpace);
1077 }
1078
NV12P010ToRGB565(const uint8_t * srcBuffer,const YUVDataInfo & yDInfo,DestConvertInfo & destInfo,ColorSpace colorSpace)1079 bool ImageFormatConvertExtUtils::NV12P010ToRGB565(const uint8_t *srcBuffer, const YUVDataInfo &yDInfo,
1080 DestConvertInfo &destInfo, [[maybe_unused]]ColorSpace colorSpace)
1081 {
1082 return P010ToI010ToI420ToRGB(srcBuffer, yDInfo, PixelFormat::YCBCR_P010, destInfo, colorSpace);
1083 }
1084
NV12P010ToRGBA8888(const uint8_t * srcBuffer,const YUVDataInfo & yDInfo,DestConvertInfo & destInfo,ColorSpace colorSpace)1085 bool ImageFormatConvertExtUtils::NV12P010ToRGBA8888(const uint8_t *srcBuffer, const YUVDataInfo &yDInfo,
1086 DestConvertInfo &destInfo, [[maybe_unused]]ColorSpace colorSpace)
1087 {
1088 return P010ToI010ToI420ToRGB(srcBuffer, yDInfo, PixelFormat::YCBCR_P010, destInfo, colorSpace);
1089 }
1090
NV12P010ToBGRA8888(const uint8_t * srcBuffer,const YUVDataInfo & yDInfo,DestConvertInfo & destInfo,ColorSpace colorSpace)1091 bool ImageFormatConvertExtUtils::NV12P010ToBGRA8888(const uint8_t *srcBuffer, const YUVDataInfo &yDInfo,
1092 DestConvertInfo &destInfo, [[maybe_unused]]ColorSpace colorSpace)
1093 {
1094 return P010ToI010ToI420ToRGB(srcBuffer, yDInfo, PixelFormat::YCBCR_P010, destInfo, colorSpace);
1095 }
1096
NV12P010ToRGB888(const uint8_t * srcBuffer,const YUVDataInfo & yDInfo,DestConvertInfo & destInfo,ColorSpace colorSpace)1097 bool ImageFormatConvertExtUtils::NV12P010ToRGB888(const uint8_t *srcBuffer, const YUVDataInfo &yDInfo,
1098 DestConvertInfo &destInfo, [[maybe_unused]]ColorSpace colorSpace)
1099 {
1100 return P010ToI010ToI420ToRGB(srcBuffer, yDInfo, PixelFormat::YCBCR_P010, destInfo, colorSpace);
1101 }
1102
NV21P010ToNV12(const uint8_t * srcBuffer,const YUVDataInfo & yDInfo,DestConvertInfo & destInfo,ColorSpace colorSpace)1103 bool ImageFormatConvertExtUtils::NV21P010ToNV12(const uint8_t *srcBuffer, const YUVDataInfo &yDInfo,
1104 DestConvertInfo &destInfo, [[maybe_unused]]ColorSpace colorSpace)
1105 {
1106 return P010ToI010ToI420ToYuv(srcBuffer, yDInfo, PixelFormat::YCRCB_P010, destInfo, colorSpace);
1107 }
1108
NV21P010ToNV21(const uint8_t * srcBuffer,const YUVDataInfo & yDInfo,DestConvertInfo & destInfo,ColorSpace colorSpace)1109 bool ImageFormatConvertExtUtils::NV21P010ToNV21(const uint8_t *srcBuffer, const YUVDataInfo &yDInfo,
1110 DestConvertInfo &destInfo, [[maybe_unused]]ColorSpace colorSpace)
1111 {
1112 return P010ToI010ToI420ToYuv(srcBuffer, yDInfo, PixelFormat::YCRCB_P010, destInfo, colorSpace);
1113 }
1114
NV12P010ToRGBA1010102(const uint8_t * srcBuffer,const YUVDataInfo & yDInfo,DestConvertInfo & destInfo,ColorSpace colorSpace)1115 bool ImageFormatConvertExtUtils::NV12P010ToRGBA1010102(const uint8_t *srcBuffer, const YUVDataInfo &yDInfo,
1116 DestConvertInfo &destInfo,
1117 [[maybe_unused]]ColorSpace colorSpace)
1118 {
1119 return P010ToI010ToRGB10(srcBuffer, yDInfo, PixelFormat::YCBCR_P010, destInfo, colorSpace);
1120 }
1121
NV21P010ToRGB565(const uint8_t * srcBuffer,const YUVDataInfo & yDInfo,DestConvertInfo & destInfo,ColorSpace colorSpace)1122 bool ImageFormatConvertExtUtils::NV21P010ToRGB565(const uint8_t *srcBuffer, const YUVDataInfo &yDInfo,
1123 DestConvertInfo &destInfo, [[maybe_unused]]ColorSpace colorSpace)
1124 {
1125 return P010ToI010ToI420ToRGB(srcBuffer, yDInfo, PixelFormat::YCRCB_P010, destInfo, colorSpace);
1126 }
1127
NV21P010ToRGBA8888(const uint8_t * srcBuffer,const YUVDataInfo & yDInfo,DestConvertInfo & destInfo,ColorSpace colorSpace)1128 bool ImageFormatConvertExtUtils::NV21P010ToRGBA8888(const uint8_t *srcBuffer, const YUVDataInfo &yDInfo,
1129 DestConvertInfo &destInfo, [[maybe_unused]]ColorSpace colorSpace)
1130 {
1131 return P010ToI010ToI420ToRGB(srcBuffer, yDInfo, PixelFormat::YCRCB_P010, destInfo, colorSpace);
1132 }
1133
NV21P010ToBGRA8888(const uint8_t * srcBuffer,const YUVDataInfo & yDInfo,DestConvertInfo & destInfo,ColorSpace colorSpace)1134 bool ImageFormatConvertExtUtils::NV21P010ToBGRA8888(const uint8_t *srcBuffer, const YUVDataInfo &yDInfo,
1135 DestConvertInfo &destInfo, [[maybe_unused]]ColorSpace colorSpace)
1136 {
1137 return P010ToI010ToI420ToRGB(srcBuffer, yDInfo, PixelFormat::YCRCB_P010, destInfo, colorSpace);
1138 }
1139
NV21P010ToRGB888(const uint8_t * srcBuffer,const YUVDataInfo & yDInfo,DestConvertInfo & destInfo,ColorSpace colorSpace)1140 bool ImageFormatConvertExtUtils::NV21P010ToRGB888(const uint8_t *srcBuffer, const YUVDataInfo &yDInfo,
1141 DestConvertInfo &destInfo, [[maybe_unused]]ColorSpace colorSpace)
1142 {
1143 return P010ToI010ToI420ToRGB(srcBuffer, yDInfo, PixelFormat::YCRCB_P010, destInfo, colorSpace);
1144 }
1145
NV21P010ToRGBA1010102(const uint8_t * srcBuffer,const YUVDataInfo & yDInfo,DestConvertInfo & destInfo,ColorSpace colorSpace)1146 bool ImageFormatConvertExtUtils::NV21P010ToRGBA1010102(const uint8_t *srcBuffer, const YUVDataInfo &yDInfo,
1147 DestConvertInfo &destInfo,
1148 [[maybe_unused]]ColorSpace colorSpace)
1149 {
1150 return P010ToI010ToRGB10(srcBuffer, yDInfo, PixelFormat::YCRCB_P010, destInfo, colorSpace);
1151 }
1152
RGBToI420ToYuv(const uint8_t * srcBuffer,const RGBDataInfo & rgbInfo,PixelFormat srcFormat,DestConvertInfo & destInfo,PixelFormat destFormat)1153 static bool RGBToI420ToYuv(const uint8_t *srcBuffer, const RGBDataInfo &rgbInfo, PixelFormat srcFormat,
1154 DestConvertInfo &destInfo, PixelFormat destFormat)
1155 {
1156 bool cond = srcBuffer == nullptr || destInfo.buffer == nullptr || rgbInfo.width == 0 || rgbInfo.height == 0 ||
1157 destInfo.bufferSize == 0;
1158 CHECK_ERROR_RETURN_RET(cond, false);
1159 SrcConvertParam srcParam = {rgbInfo.width, rgbInfo.height};
1160 srcParam.buffer = srcBuffer;
1161 srcParam.format = srcFormat;
1162
1163 DestConvertParam destParam = {destInfo.width, destInfo.height};
1164 destParam.format = destFormat;
1165
1166 I420Info i420Info = {rgbInfo.width, rgbInfo.height};
1167 cond = RGBToI420ToYuvParam(rgbInfo, srcParam, i420Info, destParam, destInfo);
1168 CHECK_ERROR_RETURN_RET_LOG(!cond, false, "RGB conversion to YUV failed!");
1169 auto bRet = RGBToI420(srcParam, i420Info);
1170 if (!bRet) {
1171 delete[] i420Info.I420Y;
1172 return false;
1173 }
1174 bRet = I420ToYuv(i420Info, destParam);
1175 delete[] i420Info.I420Y;
1176 return bRet;
1177 }
1178
RGBToYuvConverter(SrcConvertParam & srcParam,DestConvertParam & destParam)1179 static bool RGBToYuvConverter(SrcConvertParam &srcParam, DestConvertParam &destParam)
1180 {
1181 CHECK_ERROR_RETURN_RET(srcParam.format != PixelFormat::BGRA_8888, false);
1182 auto &converter = ConverterHandle::GetInstance().GetHandle();
1183 switch (destParam.format) {
1184 case PixelFormat::NV12:
1185 converter.ARGBToNV12(srcParam.slice[0], srcParam.stride[0],
1186 destParam.slice[0], destParam.stride[0], destParam.slice[1], destParam.stride[1],
1187 destParam.width, destParam.height);
1188 break;
1189 case PixelFormat::NV21:
1190 converter.ARGBToNV21(srcParam.slice[0], srcParam.stride[0],
1191 destParam.slice[0], destParam.stride[0], destParam.slice[1], destParam.stride[1],
1192 destParam.width, destParam.height);
1193 break;
1194 default:
1195 return false;
1196 }
1197 return true;
1198 }
1199
RGBToYuv(const uint8_t * srcBuffer,const RGBDataInfo & rgbInfo,PixelFormat srcFormat,DestConvertInfo & destInfo,PixelFormat destFormat)1200 static bool RGBToYuv(const uint8_t *srcBuffer, const RGBDataInfo &rgbInfo, PixelFormat srcFormat,
1201 DestConvertInfo &destInfo, PixelFormat destFormat)
1202 {
1203 bool cond = srcBuffer == nullptr || destInfo.buffer == nullptr || rgbInfo.width == 0 || rgbInfo.height == 0 ||
1204 destInfo.bufferSize == 0;
1205 CHECK_ERROR_RETURN_RET(cond, false);
1206 SrcConvertParam srcParam = {rgbInfo.width, rgbInfo.height};
1207 srcParam.buffer = srcBuffer;
1208 srcParam.format = srcFormat;
1209
1210 DestConvertParam destParam = {destInfo.width, destInfo.height};
1211 destParam.format = destFormat;
1212
1213 RGBToYuvParam(rgbInfo, srcParam, destParam, destInfo);
1214 return RGBToYuvConverter(srcParam, destParam);
1215 }
1216
BGRAToNV21(const uint8_t * srcBuffer,const RGBDataInfo & rgbInfo,DestConvertInfo & destInfo,ColorSpace colorSpace)1217 bool ImageFormatConvertExtUtils::BGRAToNV21(const uint8_t *srcBuffer, const RGBDataInfo &rgbInfo,
1218 DestConvertInfo &destInfo,
1219 [[maybe_unused]] ColorSpace colorSpace)
1220 {
1221 return RGBToYuv(srcBuffer, rgbInfo, PixelFormat::BGRA_8888, destInfo, PixelFormat::NV21);
1222 }
1223
BGRAToNV12(const uint8_t * srcBuffer,const RGBDataInfo & rgbInfo,DestConvertInfo & destInfo,ColorSpace colorSpace)1224 bool ImageFormatConvertExtUtils::BGRAToNV12(const uint8_t *srcBuffer, const RGBDataInfo &rgbInfo,
1225 DestConvertInfo &destInfo,
1226 [[maybe_unused]] ColorSpace colorSpace)
1227 {
1228 return RGBToYuv(srcBuffer, rgbInfo, PixelFormat::BGRA_8888, destInfo, PixelFormat::NV12);
1229 }
1230
RGB565ToNV21(const uint8_t * srcBuffer,const RGBDataInfo & rgbInfo,DestConvertInfo & destInfo,ColorSpace colorSpace)1231 bool ImageFormatConvertExtUtils::RGB565ToNV21(const uint8_t *srcBuffer, const RGBDataInfo &rgbInfo,
1232 DestConvertInfo &destInfo,
1233 [[maybe_unused]] ColorSpace colorSpace)
1234 {
1235 return RGBToI420ToYuv(srcBuffer, rgbInfo, PixelFormat::RGB_565, destInfo, PixelFormat::NV21);
1236 }
1237
RGB565ToNV12(const uint8_t * srcBuffer,const RGBDataInfo & rgbInfo,DestConvertInfo & destInfo,ColorSpace colorSpace)1238 bool ImageFormatConvertExtUtils::RGB565ToNV12(const uint8_t *srcBuffer, const RGBDataInfo &rgbInfo,
1239 DestConvertInfo &destInfo,
1240 [[maybe_unused]] ColorSpace colorSpace)
1241 {
1242 return RGBToI420ToYuv(srcBuffer, rgbInfo, PixelFormat::RGB_565, destInfo, PixelFormat::NV12);
1243 }
1244
RGBToNV21(const uint8_t * srcBuffer,const RGBDataInfo & rgbInfo,DestConvertInfo & destInfo,ColorSpace colorSpace)1245 bool ImageFormatConvertExtUtils::RGBToNV21(const uint8_t *srcBuffer, const RGBDataInfo &rgbInfo,
1246 DestConvertInfo &destInfo,
1247 [[maybe_unused]] ColorSpace colorSpace)
1248 {
1249 return RGBToI420ToYuv(srcBuffer, rgbInfo, PixelFormat::RGB_888, destInfo, PixelFormat::NV21);
1250 }
1251
RGBToNV12(const uint8_t * srcBuffer,const RGBDataInfo & rgbInfo,DestConvertInfo & destInfo,ColorSpace colorSpace)1252 bool ImageFormatConvertExtUtils::RGBToNV12(const uint8_t *srcBuffer, const RGBDataInfo &rgbInfo,
1253 DestConvertInfo &destInfo,
1254 [[maybe_unused]] ColorSpace colorSpace)
1255 {
1256 return RGBToI420ToYuv(srcBuffer, rgbInfo, PixelFormat::RGB_888, destInfo, PixelFormat::NV12);
1257 }
1258
RGBAToNV21(const uint8_t * srcBuffer,const RGBDataInfo & rgbInfo,DestConvertInfo & destInfo,ColorSpace colorSpace)1259 bool ImageFormatConvertExtUtils::RGBAToNV21(const uint8_t *srcBuffer, const RGBDataInfo &rgbInfo,
1260 DestConvertInfo &destInfo,
1261 [[maybe_unused]] ColorSpace colorSpace)
1262 {
1263 return RGBToI420ToYuv(srcBuffer, rgbInfo, PixelFormat::RGBA_8888, destInfo, PixelFormat::NV21);
1264 }
1265
RGBAToNV12(const uint8_t * srcBuffer,const RGBDataInfo & rgbInfo,DestConvertInfo & destInfo,ColorSpace colorSpace)1266 bool ImageFormatConvertExtUtils::RGBAToNV12(const uint8_t *srcBuffer, const RGBDataInfo &rgbInfo,
1267 DestConvertInfo &destInfo,
1268 [[maybe_unused]] ColorSpace colorSpace)
1269 {
1270 return RGBToI420ToYuv(srcBuffer, rgbInfo, PixelFormat::RGBA_8888, destInfo, PixelFormat::NV12);
1271 }
1272
NV21ToRGB(const uint8_t * srcBuffer,const YUVDataInfo & yDInfo,DestConvertInfo & destInfo,ColorSpace colorSpace)1273 bool ImageFormatConvertExtUtils::NV21ToRGB(const uint8_t *srcBuffer, const YUVDataInfo &yDInfo,
1274 DestConvertInfo &destInfo,
1275 [[maybe_unused]]ColorSpace colorSpace)
1276 {
1277 return YuvToRGB(srcBuffer, yDInfo, PixelFormat::NV21, destInfo, PixelFormat::RGB_888);
1278 }
1279
NV12ToRGB(const uint8_t * srcBuffer,const YUVDataInfo & yDInfo,DestConvertInfo & destInfo,ColorSpace colorSpace)1280 bool ImageFormatConvertExtUtils::NV12ToRGB(const uint8_t *srcBuffer, const YUVDataInfo &yDInfo,
1281 DestConvertInfo &destInfo,
1282 [[maybe_unused]]ColorSpace colorSpace)
1283 {
1284 return YuvToRGB(srcBuffer, yDInfo, PixelFormat::NV12, destInfo, PixelFormat::RGB_888);
1285 }
1286
NV21ToRGBA(const uint8_t * srcBuffer,const YUVDataInfo & yDInfo,DestConvertInfo & destInfo,ColorSpace colorSpace)1287 bool ImageFormatConvertExtUtils::NV21ToRGBA(const uint8_t *srcBuffer, const YUVDataInfo &yDInfo,
1288 DestConvertInfo &destInfo,
1289 [[maybe_unused]]ColorSpace colorSpace)
1290 {
1291 destInfo.format = PixelFormat::RGBA_8888;
1292 return YuvTo420ToRGB(srcBuffer, yDInfo, PixelFormat::NV21, destInfo, colorSpace);
1293 }
1294
NV12ToRGBA(const uint8_t * srcBuffer,const YUVDataInfo & yDInfo,DestConvertInfo & destInfo,ColorSpace colorSpace)1295 bool ImageFormatConvertExtUtils::NV12ToRGBA(const uint8_t *srcBuffer, const YUVDataInfo &yDInfo,
1296 DestConvertInfo &destInfo,
1297 [[maybe_unused]]ColorSpace colorSpace)
1298 {
1299 destInfo.format = PixelFormat::RGBA_8888;
1300 return YuvTo420ToRGB(srcBuffer, yDInfo, PixelFormat::NV12, destInfo, colorSpace);
1301 }
1302
NV21ToBGRA(const uint8_t * srcBuffer,const YUVDataInfo & yDInfo,DestConvertInfo & destInfo,ColorSpace colorSpace)1303 bool ImageFormatConvertExtUtils::NV21ToBGRA(const uint8_t *srcBuffer, const YUVDataInfo &yDInfo,
1304 DestConvertInfo &destInfo,
1305 [[maybe_unused]]ColorSpace colorSpace)
1306 {
1307 return YuvToRGB(srcBuffer, yDInfo, PixelFormat::NV21, destInfo, PixelFormat::BGRA_8888);
1308 }
1309
NV12ToBGRA(const uint8_t * srcBuffer,const YUVDataInfo & yDInfo,DestConvertInfo & destInfo,ColorSpace colorSpace)1310 bool ImageFormatConvertExtUtils::NV12ToBGRA(const uint8_t *srcBuffer, const YUVDataInfo &yDInfo,
1311 DestConvertInfo &destInfo,
1312 [[maybe_unused]]ColorSpace colorSpace)
1313 {
1314 return YuvToRGB(srcBuffer, yDInfo, PixelFormat::NV12, destInfo, PixelFormat::BGRA_8888);
1315 }
1316
NV21ToRGB565(const uint8_t * srcBuffer,const YUVDataInfo & yDInfo,DestConvertInfo & destInfo,ColorSpace colorSpace)1317 bool ImageFormatConvertExtUtils::NV21ToRGB565(const uint8_t *srcBuffer, const YUVDataInfo &yDInfo,
1318 DestConvertInfo &destInfo,
1319 [[maybe_unused]]ColorSpace colorSpace)
1320 {
1321 destInfo.format = PixelFormat::RGB_565;
1322 return YuvTo420ToRGB(srcBuffer, yDInfo, PixelFormat::NV21, destInfo, colorSpace);
1323 }
1324
NV12ToRGB565(const uint8_t * srcBuffer,const YUVDataInfo & yDInfo,DestConvertInfo & destInfo,ColorSpace colorSpace)1325 bool ImageFormatConvertExtUtils::NV12ToRGB565(const uint8_t *srcBuffer, const YUVDataInfo &yDInfo,
1326 DestConvertInfo &destInfo,
1327 [[maybe_unused]]ColorSpace colorSpace)
1328 {
1329 destInfo.format = PixelFormat::RGB_565;
1330 return YuvTo420ToRGB(srcBuffer, yDInfo, PixelFormat::NV12, destInfo, colorSpace);
1331 }
1332 } // namespace Media
1333 } // namespace OHOS