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