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