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