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