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