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