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