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 "pixel_convert.h"
17
18 #include <map>
19 #include <mutex>
20 #if !defined(IOS_PLATFORM) && !defined(ANDROID_PLATFORM)
21 #include "astcenc.h"
22 #endif
23 #ifndef _WIN32
24 #include "securec.h"
25 #else
26 #include "memory.h"
27 #endif
28 #include "pixel_convert_adapter.h"
29 #include "image_utils.h"
30 #include "pixel_map.h"
31
32 #include "image_log.h"
33 #include "media_errors.h"
34 #include "memory_manager.h"
35 #if !defined(_WIN32) && !defined(_APPLE) && !defined(IOS_PLATFORM) && !defined(ANDROID_PLATFORM)
36 #include "surface_buffer.h"
37 #endif
38
39 #ifdef __cplusplus
40 extern "C" {
41 #endif
42 #include "libswscale/swscale.h"
43 #include "libavutil/opt.h"
44 #include "libavutil/imgutils.h"
45 #include "libavcodec/avcodec.h"
46 #ifdef __cplusplus
47 }
48 #endif
49
50 #undef LOG_DOMAIN
51 #define LOG_DOMAIN LOG_TAG_DOMAIN_ID_IMAGE
52
53 #undef LOG_TAG
54 #define LOG_TAG "PixelConvert"
55
56 namespace OHOS {
57 namespace Media {
58 using namespace std;
59 #if __BYTE_ORDER == __LITTLE_ENDIAN
60 constexpr bool IS_LITTLE_ENDIAN = true;
61 #else
62 constexpr bool IS_LITTLE_ENDIAN = false;
63 #endif
64 constexpr int32_t DMA_LINE_SIZE = 256;
65 static const uint8_t NUM_2 = 2;
66 constexpr uint8_t YUV420_P010_BYTES = 2;
67
68 constexpr uint8_t BYTE_POS_0 = 0;
69 constexpr uint8_t BYTE_POS_1 = 1;
70 constexpr uint8_t BYTE_POS_2 = 2;
71 constexpr uint8_t BYTE_POS_3 = 3;
72 constexpr uint8_t BYTE_POS_4 = 4;
73 constexpr uint8_t BYTE_POS_5 = 5;
74 constexpr uint8_t BYTE_POS_6 = 6;
75 constexpr uint8_t BYTE_POS_7 = 7;
76 constexpr uint8_t BYTE_POS_8 = 8;
77 constexpr uint8_t BYTE_POS_9 = 9;
78 constexpr uint8_t BYTE_POS_10 = 10;
79 constexpr uint8_t BYTE_POS_11 = 11;
80 constexpr uint8_t BYTE_POS_12 = 12;
81 constexpr uint8_t BYTE_POS_13 = 13;
82 constexpr uint8_t BYTE_POS_14 = 14;
83 constexpr uint8_t BYTE_POS_15 = 15;
84 constexpr uint32_t ASTC_BLOCK_SIZE_4 = 4;
85 constexpr uint32_t ASTC_MAGIC_ID = 0x5CA1AB13;
86 constexpr uint32_t UNPACK_SHIFT_1 = 8;
87 constexpr uint32_t UNPACK_SHIFT_2 = 16;
88 constexpr uint32_t UNPACK_SHIFT_3 = 24;
89 constexpr uint32_t ASTC_UNIT_BYTES = 16;
90 constexpr uint32_t ASTC_DIM_MAX = 8192;
91 constexpr uint32_t BYTES_PER_PIXEL = 4;
92 constexpr uint32_t BIT_SHIFT_16BITS = 16;
93 constexpr uint32_t EVEN_ALIGNMENT = 2;
94 constexpr int32_t CONVERT_ERROR = -1;
95 constexpr uint32_t UV_PLANES_COUNT = 2;
96 constexpr uint8_t RGB565_EXTRA_BYTES = 2;
97
98 static const std::map<YuvConversion, const int> SWS_CS_COEFFICIENT = {
99 {YuvConversion::BT601, SWS_CS_DEFAULT},
100 {YuvConversion::BT709, SWS_CS_ITU709},
101 {YuvConversion::BT2020, SWS_CS_BT2020},
102 {YuvConversion::BT240, SWS_CS_SMPTE240M},
103 {YuvConversion::BTFCC, SWS_CS_FCC}
104 };
105
106 struct AstcInfo {
107 uint32_t astcBufSize;
108 uint8_t *astcBuf;
109 PixelFormat format;
110 Size astcSize;
111 unsigned int dimX;
112 unsigned int dimY;
113 };
114
AlphaTypeConvertOnRGB(uint32_t & A,uint32_t & R,uint32_t & G,uint32_t & B,const ProcFuncExtension & extension)115 static void AlphaTypeConvertOnRGB(uint32_t &A, uint32_t &R, uint32_t &G, uint32_t &B,
116 const ProcFuncExtension &extension)
117 {
118 switch (extension.alphaConvertType) {
119 case AlphaConvertType::PREMUL_CONVERT_UNPREMUL:
120 R = Unpremul255(R, A);
121 G = Unpremul255(G, A);
122 B = Unpremul255(B, A);
123 break;
124 case AlphaConvertType::PREMUL_CONVERT_OPAQUE:
125 R = Unpremul255(R, A);
126 G = Unpremul255(G, A);
127 B = Unpremul255(B, A);
128 A = ALPHA_OPAQUE;
129 break;
130 case AlphaConvertType::UNPREMUL_CONVERT_PREMUL:
131 R = Premul255(R, A);
132 G = Premul255(G, A);
133 B = Premul255(B, A);
134 break;
135 case AlphaConvertType::UNPREMUL_CONVERT_OPAQUE:
136 A = ALPHA_OPAQUE;
137 break;
138 default:
139 break;
140 }
141 }
142
FillARGB8888(uint32_t A,uint32_t R,uint32_t G,uint32_t B)143 static uint32_t FillARGB8888(uint32_t A, uint32_t R, uint32_t G, uint32_t B)
144 {
145 if (IS_LITTLE_ENDIAN) {
146 return ((B << SHIFT_24_BIT) | (G << SHIFT_16_BIT) | (R << SHIFT_8_BIT) | A);
147 }
148 return ((A << SHIFT_24_BIT) | (R << SHIFT_16_BIT) | (G << SHIFT_8_BIT) | B);
149 }
150
FillABGR8888(uint32_t A,uint32_t B,uint32_t G,uint32_t R)151 static uint32_t FillABGR8888(uint32_t A, uint32_t B, uint32_t G, uint32_t R)
152 {
153 if (IS_LITTLE_ENDIAN) {
154 return ((R << SHIFT_24_BIT) | (G << SHIFT_16_BIT) | (B << SHIFT_8_BIT) | A);
155 }
156 return ((A << SHIFT_24_BIT) | (B << SHIFT_16_BIT) | (G << SHIFT_8_BIT) | R);
157 }
158
FillRGBA8888(uint32_t R,uint32_t G,uint32_t B,uint32_t A)159 static uint32_t FillRGBA8888(uint32_t R, uint32_t G, uint32_t B, uint32_t A)
160 {
161 if (IS_LITTLE_ENDIAN) {
162 return ((A << SHIFT_24_BIT) | (B << SHIFT_16_BIT) | (G << SHIFT_8_BIT) | R);
163 }
164 return ((R << SHIFT_24_BIT) | (G << SHIFT_16_BIT) | (B << SHIFT_8_BIT) | A);
165 }
166
FillBGRA8888(uint32_t B,uint32_t G,uint32_t R,uint32_t A)167 static uint32_t FillBGRA8888(uint32_t B, uint32_t G, uint32_t R, uint32_t A)
168 {
169 if (IS_LITTLE_ENDIAN) {
170 return ((A << SHIFT_24_BIT) | (R << SHIFT_16_BIT) | (G << SHIFT_8_BIT) | B);
171 }
172 return ((B << SHIFT_24_BIT) | (G << SHIFT_16_BIT) | (R << SHIFT_8_BIT) | A);
173 }
174
FillRGB565(uint32_t R,uint32_t G,uint32_t B)175 static uint16_t FillRGB565(uint32_t R, uint32_t G, uint32_t B)
176 {
177 if (IS_LITTLE_ENDIAN) {
178 return ((B << SHIFT_11_BIT) | (G << SHIFT_5_BIT) | R);
179 }
180 return ((R << SHIFT_11_BIT) | (G << SHIFT_5_BIT) | B);
181 }
182
FillRGBAF16(float R,float G,float B,float A)183 static uint64_t FillRGBAF16(float R, float G, float B, float A)
184 {
185 uint64_t R16 = FloatToHalf(R);
186 uint64_t G16 = FloatToHalf(G);
187 uint64_t B16 = FloatToHalf(B);
188 uint64_t A16 = FloatToHalf(A);
189 if (IS_LITTLE_ENDIAN) {
190 return ((A16 << SHIFT_48_BIT) | (R16 << SHIFT_32_BIT) | (G16 << SHIFT_16_BIT) | B16);
191 }
192 return ((B16 << SHIFT_48_BIT) | (G16 << SHIFT_32_BIT) | (R16 << SHIFT_16_BIT) | A16);
193 }
194
195 constexpr uint8_t BYTE_BITS = 8;
196 constexpr uint8_t BYTE_BITS_MAX_INDEX = 7;
197 template<typename T>
BitConvert(T * destinationRow,const uint8_t * sourceRow,uint32_t sourceWidth,uint32_t white,uint32_t black)198 static void BitConvert(T *destinationRow, const uint8_t *sourceRow, uint32_t sourceWidth, uint32_t white,
199 uint32_t black)
200 {
201 destinationRow[0] = (*sourceRow & GET_8_BIT) ? white : black;
202 uint32_t bitIndex = 0;
203 uint8_t currentSource = 0;
204 /*
205 * 1 byte = 8 bit
206 * 7: 8 bit index
207 */
208 for (uint32_t i = 1; i < sourceWidth; i++) {
209 bitIndex = i % BYTE_BITS;
210 currentSource = *(sourceRow + i / BYTE_BITS);
211 if (bitIndex > BYTE_BITS_MAX_INDEX) {
212 continue;
213 }
214 destinationRow[i] = ((currentSource >> (BYTE_BITS_MAX_INDEX - bitIndex)) & GET_1_BIT) ? white : black;
215 }
216 }
217
BitConvertGray(void * destinationRow,const uint8_t * sourceRow,uint32_t sourceWidth,const ProcFuncExtension & extension)218 static void BitConvertGray(void *destinationRow, const uint8_t *sourceRow, uint32_t sourceWidth,
219 const ProcFuncExtension &extension)
220 {
221 uint8_t *newDestinationRow = static_cast<uint8_t *>(destinationRow);
222 BitConvert(newDestinationRow, sourceRow, sourceWidth, GRAYSCALE_WHITE, GRAYSCALE_BLACK);
223 }
224
BitConvertARGB8888(void * destinationRow,const uint8_t * sourceRow,uint32_t sourceWidth,const ProcFuncExtension & extension)225 static void BitConvertARGB8888(void *destinationRow, const uint8_t *sourceRow, uint32_t sourceWidth,
226 const ProcFuncExtension &extension)
227 {
228 uint32_t *newDestinationRow = static_cast<uint32_t *>(destinationRow);
229 BitConvert(newDestinationRow, sourceRow, sourceWidth, ARGB_WHITE, ARGB_BLACK);
230 }
231
BitConvertRGB565(void * destinationRow,const uint8_t * sourceRow,uint32_t sourceWidth,const ProcFuncExtension & extension)232 static void BitConvertRGB565(void *destinationRow, const uint8_t *sourceRow, uint32_t sourceWidth,
233 const ProcFuncExtension &extension)
234 {
235 uint16_t *newDestinationRow = static_cast<uint16_t *>(destinationRow);
236 BitConvert(newDestinationRow, sourceRow, sourceWidth, RGB_WHITE, RGB_BLACK);
237 }
238
239 constexpr uint32_t BRANCH_GRAY_TO_ARGB8888 = 0x00000001;
240 constexpr uint32_t BRANCH_GRAY_TO_RGB565 = 0x00000002;
241 template<typename T>
GrayConvert(T * destinationRow,const uint8_t * sourceRow,uint32_t sourceWidth,uint32_t branch)242 static void GrayConvert(T *destinationRow, const uint8_t *sourceRow, uint32_t sourceWidth, uint32_t branch)
243 {
244 for (uint32_t i = 0; i < sourceWidth; i++) {
245 uint32_t R = sourceRow[i];
246 uint32_t G = sourceRow[i];
247 uint32_t B = sourceRow[i];
248 if (branch == BRANCH_GRAY_TO_ARGB8888) {
249 uint32_t A = ALPHA_OPAQUE;
250 destinationRow[i] = ((A << SHIFT_24_BIT) | (R << SHIFT_16_BIT) | (G << SHIFT_8_BIT) | B);
251 } else if (branch == BRANCH_GRAY_TO_RGB565) {
252 R = R >> SHIFT_3_BIT;
253 G = G >> SHIFT_2_BIT;
254 B = B >> SHIFT_3_BIT;
255 destinationRow[i] = ((R << SHIFT_11_BIT) | (G << SHIFT_5_BIT) | B);
256 } else {
257 break;
258 }
259 }
260 }
261
GrayConvertARGB8888(void * destinationRow,const uint8_t * sourceRow,uint32_t sourceWidth,const ProcFuncExtension & extension)262 static void GrayConvertARGB8888(void *destinationRow, const uint8_t *sourceRow, uint32_t sourceWidth,
263 const ProcFuncExtension &extension)
264 {
265 uint32_t *newDestinationRow = static_cast<uint32_t *>(destinationRow);
266 GrayConvert(newDestinationRow, sourceRow, sourceWidth, BRANCH_GRAY_TO_ARGB8888);
267 }
268
GrayConvertRGB565(void * destinationRow,const uint8_t * sourceRow,uint32_t sourceWidth,const ProcFuncExtension & extension)269 static void GrayConvertRGB565(void *destinationRow, const uint8_t *sourceRow, uint32_t sourceWidth,
270 const ProcFuncExtension &extension)
271 {
272 uint16_t *newDestinationRow = static_cast<uint16_t *>(destinationRow);
273 GrayConvert(newDestinationRow, sourceRow, sourceWidth, BRANCH_GRAY_TO_RGB565);
274 }
275
276 constexpr uint32_t BRANCH_ARGB8888 = 0x10000001;
277 constexpr uint32_t BRANCH_ALPHA = 0x10000002;
278 template<typename T>
GrayAlphaConvert(T * destinationRow,const uint8_t * sourceRow,uint32_t sourceWidth,uint32_t branch,const ProcFuncExtension & extension)279 static void GrayAlphaConvert(T *destinationRow, const uint8_t *sourceRow, uint32_t sourceWidth, uint32_t branch,
280 const ProcFuncExtension &extension)
281 {
282 for (uint32_t i = 0; i < sourceWidth; i++) {
283 uint32_t A = sourceRow[1];
284 uint32_t R = sourceRow[0];
285 uint32_t G = sourceRow[0];
286 uint32_t B = sourceRow[0];
287 AlphaTypeConvertOnRGB(A, R, G, B, extension);
288 if (branch == BRANCH_ARGB8888) {
289 destinationRow[i] = FillARGB8888(A, R, G, B);
290 } else if (branch == BRANCH_ALPHA) {
291 destinationRow[i] = A;
292 } else {
293 break;
294 }
295 sourceRow += SIZE_2_BYTE;
296 }
297 }
298
GrayAlphaConvertARGB8888(void * destinationRow,const uint8_t * sourceRow,uint32_t sourceWidth,const ProcFuncExtension & extension)299 static void GrayAlphaConvertARGB8888(void *destinationRow, const uint8_t *sourceRow, uint32_t sourceWidth,
300 const ProcFuncExtension &extension)
301 {
302 uint32_t *newDestinationRow = static_cast<uint32_t *>(destinationRow);
303 GrayAlphaConvert(newDestinationRow, sourceRow, sourceWidth, BRANCH_ARGB8888, extension);
304 }
305
GrayAlphaConvertAlpha(void * destinationRow,const uint8_t * sourceRow,uint32_t sourceWidth,const ProcFuncExtension & extension)306 static void GrayAlphaConvertAlpha(void *destinationRow, const uint8_t *sourceRow, uint32_t sourceWidth,
307 const ProcFuncExtension &extension)
308 {
309 uint8_t *newDestinationRow = static_cast<uint8_t *>(destinationRow);
310 GrayAlphaConvert(newDestinationRow, sourceRow, sourceWidth, BRANCH_ALPHA, extension);
311 }
312
313 constexpr uint32_t BRANCH_BGR888_TO_ARGB8888 = 0x20000001;
314 constexpr uint32_t BRANCH_BGR888_TO_RGBA8888 = 0x20000002;
315 constexpr uint32_t BRANCH_BGR888_TO_BGRA8888 = 0x20000003;
316 constexpr uint32_t BRANCH_BGR888_TO_RGB565 = 0x20000004;
317 constexpr uint32_t BRANCH_BGR888_TO_RGBAF16 = 0x20000005;
318 template<typename T>
BGR888Convert(T * destinationRow,const uint8_t * sourceRow,uint32_t sourceWidth,uint32_t branch)319 static void BGR888Convert(T *destinationRow, const uint8_t *sourceRow, uint32_t sourceWidth, uint32_t branch)
320 {
321 for (uint32_t i = 0; i < sourceWidth; i++) {
322 uint32_t R = sourceRow[2];
323 uint32_t G = sourceRow[1];
324 uint32_t B = sourceRow[0];
325 uint32_t A = ALPHA_OPAQUE;
326 if (branch == BRANCH_BGR888_TO_ARGB8888) {
327 destinationRow[i] = FillARGB8888(A, R, G, B);
328 } else if (branch == BRANCH_BGR888_TO_RGBA8888) {
329 destinationRow[i] = FillRGBA8888(R, G, B, A);
330 } else if (branch == BRANCH_BGR888_TO_BGRA8888) {
331 destinationRow[i] = FillBGRA8888(B, G, R, A);
332 } else if (branch == BRANCH_BGR888_TO_RGB565) {
333 R = R >> SHIFT_3_BIT;
334 G = G >> SHIFT_2_BIT;
335 B = B >> SHIFT_3_BIT;
336 destinationRow[i] = ((B << SHIFT_11_BIT) | (G << SHIFT_5_BIT) | R);
337 } else if (branch == BRANCH_BGR888_TO_RGBAF16) {
338 destinationRow[i] = FillRGBAF16(R, G, B, A);
339 } else {
340 break;
341 }
342 sourceRow += SIZE_3_BYTE;
343 }
344 }
345
BGR888ConvertARGB8888(void * destinationRow,const uint8_t * sourceRow,uint32_t sourceWidth,const ProcFuncExtension & extension)346 static void BGR888ConvertARGB8888(void *destinationRow, const uint8_t *sourceRow, uint32_t sourceWidth,
347 const ProcFuncExtension &extension)
348 {
349 uint32_t *newDestinationRow = static_cast<uint32_t *>(destinationRow);
350 BGR888Convert(newDestinationRow, sourceRow, sourceWidth, BRANCH_BGR888_TO_ARGB8888);
351 }
352
BGR888ConvertRGBA8888(void * destinationRow,const uint8_t * sourceRow,uint32_t sourceWidth,const ProcFuncExtension & extension)353 static void BGR888ConvertRGBA8888(void *destinationRow, const uint8_t *sourceRow, uint32_t sourceWidth,
354 const ProcFuncExtension &extension)
355 {
356 uint32_t *newDestinationRow = static_cast<uint32_t *>(destinationRow);
357 BGR888Convert(newDestinationRow, sourceRow, sourceWidth, BRANCH_BGR888_TO_RGBA8888);
358 }
359
BGR888ConvertBGRA8888(void * destinationRow,const uint8_t * sourceRow,uint32_t sourceWidth,const ProcFuncExtension & extension)360 static void BGR888ConvertBGRA8888(void *destinationRow, const uint8_t *sourceRow, uint32_t sourceWidth,
361 const ProcFuncExtension &extension)
362 {
363 uint32_t *newDestinationRow = static_cast<uint32_t *>(destinationRow);
364 BGR888Convert(newDestinationRow, sourceRow, sourceWidth, BRANCH_BGR888_TO_BGRA8888);
365 }
366
BGR888ConvertRGB565(void * destinationRow,const uint8_t * sourceRow,uint32_t sourceWidth,const ProcFuncExtension & extension)367 static void BGR888ConvertRGB565(void *destinationRow, const uint8_t *sourceRow, uint32_t sourceWidth,
368 const ProcFuncExtension &extension)
369 {
370 uint16_t *newDestinationRow = static_cast<uint16_t *>(destinationRow);
371 BGR888Convert(newDestinationRow, sourceRow, sourceWidth, BRANCH_BGR888_TO_RGB565);
372 }
373
BGR888ConvertRGBAF16(uint8_t * destinationRow,const uint8_t * sourceRow,uint32_t sourceWidth,const ProcFuncExtension & extension)374 static void BGR888ConvertRGBAF16(uint8_t *destinationRow, const uint8_t *sourceRow, uint32_t sourceWidth,
375 const ProcFuncExtension &extension)
376 {
377 void* tmp = static_cast<void *>(destinationRow);
378 uint64_t *newDestinationRow = static_cast<uint64_t *>(tmp);
379 BGR888Convert(newDestinationRow, sourceRow, sourceWidth, BRANCH_BGR888_TO_RGBAF16);
380 }
381
382 constexpr uint32_t BRANCH_RGB888_TO_ARGB8888 = 0x30000001;
383 constexpr uint32_t BRANCH_RGB888_TO_RGBA8888 = 0x30000002;
384 constexpr uint32_t BRANCH_RGB888_TO_BGRA8888 = 0x30000003;
385 constexpr uint32_t BRANCH_RGB888_TO_RGB565 = 0x30000004;
386 constexpr uint32_t BRANCH_RGB888_TO_RGBAF16 = 0x30000005;
387 template<typename T>
RGB888Convert(T * destinationRow,const uint8_t * sourceRow,uint32_t sourceWidth,uint32_t branch)388 static void RGB888Convert(T *destinationRow, const uint8_t *sourceRow, uint32_t sourceWidth, uint32_t branch)
389 {
390 for (uint32_t i = 0; i < sourceWidth; i++) {
391 uint32_t R = sourceRow[0];
392 uint32_t G = sourceRow[1];
393 uint32_t B = sourceRow[2];
394 uint32_t A = ALPHA_OPAQUE;
395 if (branch == BRANCH_RGB888_TO_ARGB8888) {
396 destinationRow[i] = FillARGB8888(A, R, G, B);
397 } else if (branch == BRANCH_RGB888_TO_RGBA8888) {
398 destinationRow[i] = FillRGBA8888(R, G, B, A);
399 } else if (branch == BRANCH_RGB888_TO_BGRA8888) {
400 destinationRow[i] = FillBGRA8888(B, G, R, A);
401 } else if (branch == BRANCH_RGB888_TO_RGB565) {
402 R = R >> SHIFT_3_BIT;
403 G = G >> SHIFT_2_BIT;
404 B = B >> SHIFT_3_BIT;
405 destinationRow[i] = FillRGB565(R, G, B);
406 } else if (branch == BRANCH_RGB888_TO_RGBAF16) {
407 destinationRow[i] = FillRGBAF16(R, G, B, A);
408 } else {
409 break;
410 }
411 sourceRow += SIZE_3_BYTE;
412 }
413 }
RGB888ConvertARGB8888(void * destinationRow,const uint8_t * sourceRow,uint32_t sourceWidth,const ProcFuncExtension & extension)414 static void RGB888ConvertARGB8888(void *destinationRow, const uint8_t *sourceRow, uint32_t sourceWidth,
415 const ProcFuncExtension &extension)
416 {
417 uint32_t *newDestinationRow = static_cast<uint32_t *>(destinationRow);
418 RGB888Convert(newDestinationRow, sourceRow, sourceWidth, BRANCH_RGB888_TO_ARGB8888);
419 }
420
RGB888ConvertRGBA8888(void * destinationRow,const uint8_t * sourceRow,uint32_t sourceWidth,const ProcFuncExtension & extension)421 static void RGB888ConvertRGBA8888(void *destinationRow, const uint8_t *sourceRow, uint32_t sourceWidth,
422 const ProcFuncExtension &extension)
423 {
424 uint32_t *newDestinationRow = static_cast<uint32_t *>(destinationRow);
425 RGB888Convert(newDestinationRow, sourceRow, sourceWidth, BRANCH_RGB888_TO_RGBA8888);
426 }
427
RGB888ConvertBGRA8888(void * destinationRow,const uint8_t * sourceRow,uint32_t sourceWidth,const ProcFuncExtension & extension)428 static void RGB888ConvertBGRA8888(void *destinationRow, const uint8_t *sourceRow, uint32_t sourceWidth,
429 const ProcFuncExtension &extension)
430 {
431 uint32_t *newDestinationRow = static_cast<uint32_t *>(destinationRow);
432 RGB888Convert(newDestinationRow, sourceRow, sourceWidth, BRANCH_RGB888_TO_BGRA8888);
433 }
434
RGB888ConvertRGB565(void * destinationRow,const uint8_t * sourceRow,uint32_t sourceWidth,const ProcFuncExtension & extension)435 static void RGB888ConvertRGB565(void *destinationRow, const uint8_t *sourceRow, uint32_t sourceWidth,
436 const ProcFuncExtension &extension)
437 {
438 uint16_t *newDestinationRow = static_cast<uint16_t *>(destinationRow);
439 RGB888Convert(newDestinationRow, sourceRow, sourceWidth, BRANCH_RGB888_TO_RGB565);
440 }
441
RGB888ConvertRGBAF16(uint8_t * destinationRow,const uint8_t * sourceRow,uint32_t sourceWidth,const ProcFuncExtension & extension)442 static void RGB888ConvertRGBAF16(uint8_t *destinationRow, const uint8_t *sourceRow, uint32_t sourceWidth,
443 const ProcFuncExtension &extension)
444 {
445 void* tmp = static_cast<void *>(destinationRow);
446 uint64_t *newDestinationRow = static_cast<uint64_t *>(tmp);
447 RGB888Convert(newDestinationRow, sourceRow, sourceWidth, BRANCH_RGB888_TO_RGBAF16);
448 }
449 constexpr uint32_t BRANCH_RGBA8888_TO_RGBA8888_ALPHA = 0x40000001;
450 constexpr uint32_t BRANCH_RGBA8888_TO_ARGB8888 = 0x40000002;
451 constexpr uint32_t BRANCH_RGBA8888_TO_BGRA8888 = 0x40000003;
452 constexpr uint32_t BRANCH_RGBA8888_TO_RGB565 = 0x40000004;
453 constexpr uint32_t BRANCH_RGBA8888_TO_RGBAF16 = 0x40000005;
454 template<typename T>
RGBA8888Convert(T * destinationRow,const uint8_t * sourceRow,uint32_t sourceWidth,uint32_t branch,const ProcFuncExtension & extension)455 static void RGBA8888Convert(T *destinationRow, const uint8_t *sourceRow, uint32_t sourceWidth, uint32_t branch,
456 const ProcFuncExtension &extension)
457 {
458 for (uint32_t i = 0; i < sourceWidth; i++) {
459 uint32_t R = sourceRow[0];
460 uint32_t G = sourceRow[1];
461 uint32_t B = sourceRow[2];
462 uint32_t A = sourceRow[3];
463 AlphaTypeConvertOnRGB(A, R, G, B, extension);
464 if (branch == BRANCH_RGBA8888_TO_RGBA8888_ALPHA) {
465 destinationRow[i] = FillRGBA8888(R, G, B, A);
466 } else if (branch == BRANCH_RGBA8888_TO_ARGB8888) {
467 destinationRow[i] = FillARGB8888(A, R, G, B);
468 } else if (branch == BRANCH_RGBA8888_TO_BGRA8888) {
469 destinationRow[i] = FillBGRA8888(B, G, R, A);
470 } else if (branch == BRANCH_RGBA8888_TO_RGB565) {
471 R = R >> SHIFT_3_BIT;
472 G = G >> SHIFT_2_BIT;
473 B = B >> SHIFT_3_BIT;
474 destinationRow[i] = FillRGB565(R, G, B);
475 } else if (branch == BRANCH_RGBA8888_TO_RGBAF16) {
476 destinationRow[i] = FillRGBAF16(R, G, B, A);
477 } else {
478 break;
479 }
480 sourceRow += SIZE_4_BYTE;
481 }
482 }
483
RGBA8888ConvertRGBA8888Alpha(void * destinationRow,const uint8_t * sourceRow,uint32_t sourceWidth,const ProcFuncExtension & extension)484 static void RGBA8888ConvertRGBA8888Alpha(void *destinationRow, const uint8_t *sourceRow, uint32_t sourceWidth,
485 const ProcFuncExtension &extension)
486 {
487 uint32_t *newDestinationRow = static_cast<uint32_t *>(destinationRow);
488 RGBA8888Convert(newDestinationRow, sourceRow, sourceWidth, BRANCH_RGBA8888_TO_RGBA8888_ALPHA, extension);
489 }
490
RGBA8888ConvertARGB8888(void * destinationRow,const uint8_t * sourceRow,uint32_t sourceWidth,const ProcFuncExtension & extension)491 static void RGBA8888ConvertARGB8888(void *destinationRow, const uint8_t *sourceRow, uint32_t sourceWidth,
492 const ProcFuncExtension &extension)
493 {
494 uint32_t *newDestinationRow = static_cast<uint32_t *>(destinationRow);
495 RGBA8888Convert(newDestinationRow, sourceRow, sourceWidth, BRANCH_RGBA8888_TO_ARGB8888, extension);
496 }
RGBA8888ConvertBGRA8888(void * destinationRow,const uint8_t * sourceRow,uint32_t sourceWidth,const ProcFuncExtension & extension)497 static void RGBA8888ConvertBGRA8888(void *destinationRow, const uint8_t *sourceRow, uint32_t sourceWidth,
498 const ProcFuncExtension &extension)
499 {
500 uint32_t *newDestinationRow = static_cast<uint32_t *>(destinationRow);
501 RGBA8888Convert(newDestinationRow, sourceRow, sourceWidth, BRANCH_RGBA8888_TO_BGRA8888, extension);
502 }
503
RGBA8888ConvertRGB565(void * destinationRow,const uint8_t * sourceRow,uint32_t sourceWidth,const ProcFuncExtension & extension)504 static void RGBA8888ConvertRGB565(void *destinationRow, const uint8_t *sourceRow, uint32_t sourceWidth,
505 const ProcFuncExtension &extension)
506 {
507 uint16_t *newDestinationRow = static_cast<uint16_t *>(destinationRow);
508 RGBA8888Convert(newDestinationRow, sourceRow, sourceWidth, BRANCH_RGBA8888_TO_RGB565, extension);
509 }
510
RGBA8888ConvertRGBAF16(uint8_t * destinationRow,const uint8_t * sourceRow,uint32_t sourceWidth,const ProcFuncExtension & extension)511 static void RGBA8888ConvertRGBAF16(uint8_t *destinationRow, const uint8_t *sourceRow, uint32_t sourceWidth,
512 const ProcFuncExtension &extension)
513 {
514 void* tmp = static_cast<void *>(destinationRow);
515 uint64_t *newDestinationRow = static_cast<uint64_t *>(tmp);
516 RGBA8888Convert(newDestinationRow, sourceRow, sourceWidth, BRANCH_RGBA8888_TO_RGBAF16, extension);
517 }
518 constexpr uint32_t BRANCH_BGRA8888_TO_BGRA8888_ALPHA = 0x80000001;
519 constexpr uint32_t BRANCH_BGRA8888_TO_ARGB8888 = 0x80000002;
520 constexpr uint32_t BRANCH_BGRA8888_TO_RGBA8888 = 0x80000003;
521 constexpr uint32_t BRANCH_BGRA8888_TO_RGB565 = 0x80000004;
522 constexpr uint32_t BRANCH_BGRA8888_TO_RGBAF16 = 0x80000005;
523 template<typename T>
BGRA8888Convert(T * destinationRow,const uint8_t * sourceRow,uint32_t sourceWidth,uint32_t branch,const ProcFuncExtension & extension)524 static void BGRA8888Convert(T *destinationRow, const uint8_t *sourceRow, uint32_t sourceWidth, uint32_t branch,
525 const ProcFuncExtension &extension)
526 {
527 for (uint32_t i = 0; i < sourceWidth; i++) {
528 uint32_t B = sourceRow[0];
529 uint32_t G = sourceRow[1];
530 uint32_t R = sourceRow[2];
531 uint32_t A = sourceRow[3];
532 AlphaTypeConvertOnRGB(A, R, G, B, extension);
533 if (branch == BRANCH_BGRA8888_TO_BGRA8888_ALPHA) {
534 destinationRow[i] = FillBGRA8888(B, G, R, A);
535 } else if (branch == BRANCH_BGRA8888_TO_ARGB8888) {
536 destinationRow[i] = FillARGB8888(A, R, G, B);
537 } else if (branch == BRANCH_BGRA8888_TO_RGBA8888) {
538 destinationRow[i] = FillRGBA8888(R, G, B, A);
539 } else if (branch == BRANCH_BGRA8888_TO_RGB565) {
540 R = R >> SHIFT_3_BIT;
541 G = G >> SHIFT_2_BIT;
542 B = B >> SHIFT_3_BIT;
543 destinationRow[i] = FillRGB565(R, G, B);
544 } else if (branch == BRANCH_BGRA8888_TO_RGBAF16) {
545 destinationRow[i] = FillRGBAF16(R, G, B, A);
546 } else {
547 break;
548 }
549 sourceRow += SIZE_4_BYTE;
550 }
551 }
552
BGRA8888ConvertBGRA8888Alpha(void * destinationRow,const uint8_t * sourceRow,uint32_t sourceWidth,const ProcFuncExtension & extension)553 static void BGRA8888ConvertBGRA8888Alpha(void *destinationRow, const uint8_t *sourceRow, uint32_t sourceWidth,
554 const ProcFuncExtension &extension)
555 {
556 uint32_t *newDestinationRow = static_cast<uint32_t *>(destinationRow);
557 BGRA8888Convert(newDestinationRow, sourceRow, sourceWidth, BRANCH_BGRA8888_TO_BGRA8888_ALPHA, extension);
558 }
559
BGRA8888ConvertARGB8888(void * destinationRow,const uint8_t * sourceRow,uint32_t sourceWidth,const ProcFuncExtension & extension)560 static void BGRA8888ConvertARGB8888(void *destinationRow, const uint8_t *sourceRow, uint32_t sourceWidth,
561 const ProcFuncExtension &extension)
562 {
563 uint32_t *newDestinationRow = static_cast<uint32_t *>(destinationRow);
564 BGRA8888Convert(newDestinationRow, sourceRow, sourceWidth, BRANCH_BGRA8888_TO_ARGB8888, extension);
565 }
566
BGRA8888ConvertRGBA8888(void * destinationRow,const uint8_t * sourceRow,uint32_t sourceWidth,const ProcFuncExtension & extension)567 static void BGRA8888ConvertRGBA8888(void *destinationRow, const uint8_t *sourceRow, uint32_t sourceWidth,
568 const ProcFuncExtension &extension)
569 {
570 uint32_t *newDestinationRow = static_cast<uint32_t *>(destinationRow);
571 BGRA8888Convert(newDestinationRow, sourceRow, sourceWidth, BRANCH_BGRA8888_TO_RGBA8888, extension);
572 }
573
BGRA8888ConvertRGB565(void * destinationRow,const uint8_t * sourceRow,uint32_t sourceWidth,const ProcFuncExtension & extension)574 static void BGRA8888ConvertRGB565(void *destinationRow, const uint8_t *sourceRow, uint32_t sourceWidth,
575 const ProcFuncExtension &extension)
576 {
577 uint16_t *newDestinationRow = static_cast<uint16_t *>(destinationRow);
578 BGRA8888Convert(newDestinationRow, sourceRow, sourceWidth, BRANCH_BGRA8888_TO_RGB565, extension);
579 }
580
BGRA8888ConvertRGBAF16(uint8_t * destinationRow,const uint8_t * sourceRow,uint32_t sourceWidth,const ProcFuncExtension & extension)581 static void BGRA8888ConvertRGBAF16(uint8_t *destinationRow, const uint8_t *sourceRow, uint32_t sourceWidth,
582 const ProcFuncExtension &extension)
583 {
584 void* tmp = static_cast<void *>(destinationRow);
585 uint64_t *newDestinationRow = static_cast<uint64_t *>(tmp);
586 BGRA8888Convert(newDestinationRow, sourceRow, sourceWidth, BRANCH_BGRA8888_TO_RGBAF16, extension);
587 }
588
589 constexpr uint32_t BRANCH_ARGB8888_TO_ARGB8888_ALPHA = 0x90000001;
590 constexpr uint32_t BRANCH_ARGB8888_TO_RGBA8888 = 0x90000002;
591 constexpr uint32_t BRANCH_ARGB8888_TO_BGRA8888 = 0x90000003;
592 constexpr uint32_t BRANCH_ARGB8888_TO_RGB565 = 0x90000004;
593 constexpr uint32_t BRANCH_ARGB8888_TO_RGBAF16 = 0x90000005;
594 template<typename T>
ARGB8888Convert(T * destinationRow,const uint8_t * sourceRow,uint32_t sourceWidth,uint32_t branch,const ProcFuncExtension & extension)595 static void ARGB8888Convert(T *destinationRow, const uint8_t *sourceRow, uint32_t sourceWidth, uint32_t branch,
596 const ProcFuncExtension &extension)
597 {
598 for (uint32_t i = 0; i < sourceWidth; i++) {
599 uint32_t A = sourceRow[0];
600 uint32_t R = sourceRow[1];
601 uint32_t G = sourceRow[2];
602 uint32_t B = sourceRow[3];
603 AlphaTypeConvertOnRGB(A, R, G, B, extension);
604 if (branch == BRANCH_ARGB8888_TO_ARGB8888_ALPHA) {
605 destinationRow[i] = FillARGB8888(A, R, G, B);
606 } else if (branch == BRANCH_ARGB8888_TO_RGBA8888) {
607 destinationRow[i] = FillRGBA8888(R, G, B, A);
608 } else if (branch == BRANCH_ARGB8888_TO_BGRA8888) {
609 destinationRow[i] = FillBGRA8888(B, G, R, A);
610 } else if (branch == BRANCH_ARGB8888_TO_RGB565) {
611 R = R >> SHIFT_3_BIT;
612 G = G >> SHIFT_2_BIT;
613 B = B >> SHIFT_3_BIT;
614 destinationRow[i] = FillRGB565(R, G, B);
615 } else if (branch == BRANCH_ARGB8888_TO_RGBAF16) {
616 destinationRow[i] = FillRGBAF16(R, G, B, A);
617 } else {
618 break;
619 }
620 sourceRow += SIZE_4_BYTE;
621 }
622 }
623
ARGB8888ConvertARGB8888Alpha(void * destinationRow,const uint8_t * sourceRow,uint32_t sourceWidth,const ProcFuncExtension & extension)624 static void ARGB8888ConvertARGB8888Alpha(void *destinationRow, const uint8_t *sourceRow, uint32_t sourceWidth,
625 const ProcFuncExtension &extension)
626 {
627 uint32_t *newDestinationRow = static_cast<uint32_t *>(destinationRow);
628 ARGB8888Convert(newDestinationRow, sourceRow, sourceWidth, BRANCH_ARGB8888_TO_ARGB8888_ALPHA, extension);
629 }
630
ARGB8888ConvertRGBA8888(void * destinationRow,const uint8_t * sourceRow,uint32_t sourceWidth,const ProcFuncExtension & extension)631 static void ARGB8888ConvertRGBA8888(void *destinationRow, const uint8_t *sourceRow, uint32_t sourceWidth,
632 const ProcFuncExtension &extension)
633 {
634 uint32_t *newDestinationRow = static_cast<uint32_t *>(destinationRow);
635 ARGB8888Convert(newDestinationRow, sourceRow, sourceWidth, BRANCH_ARGB8888_TO_RGBA8888, extension);
636 }
637
ARGB8888ConvertBGRA8888(void * destinationRow,const uint8_t * sourceRow,uint32_t sourceWidth,const ProcFuncExtension & extension)638 static void ARGB8888ConvertBGRA8888(void *destinationRow, const uint8_t *sourceRow, uint32_t sourceWidth,
639 const ProcFuncExtension &extension)
640 {
641 uint32_t *newDestinationRow = static_cast<uint32_t *>(destinationRow);
642 ARGB8888Convert(newDestinationRow, sourceRow, sourceWidth, BRANCH_ARGB8888_TO_BGRA8888, extension);
643 }
644
ARGB8888ConvertRGB565(void * destinationRow,const uint8_t * sourceRow,uint32_t sourceWidth,const ProcFuncExtension & extension)645 static void ARGB8888ConvertRGB565(void *destinationRow, const uint8_t *sourceRow, uint32_t sourceWidth,
646 const ProcFuncExtension &extension)
647 {
648 uint16_t *newDestinationRow = static_cast<uint16_t *>(destinationRow);
649 ARGB8888Convert(newDestinationRow, sourceRow, sourceWidth, BRANCH_ARGB8888_TO_RGB565, extension);
650 }
651
ARGB8888ConvertRGBAF16(uint8_t * destinationRow,const uint8_t * sourceRow,uint32_t sourceWidth,const ProcFuncExtension & extension)652 static void ARGB8888ConvertRGBAF16(uint8_t *destinationRow, const uint8_t *sourceRow, uint32_t sourceWidth,
653 const ProcFuncExtension &extension)
654 {
655 void* tmp = static_cast<void *>(destinationRow);
656 uint64_t *newDestinationRow = static_cast<uint64_t *>(tmp);
657 ARGB8888Convert(newDestinationRow, sourceRow, sourceWidth, BRANCH_ARGB8888_TO_RGBAF16, extension);
658 }
659
660 constexpr uint32_t BRANCH_RGB161616_TO_ARGB8888 = 0x50000001;
661 constexpr uint32_t BRANCH_RGB161616_TO_ABGR8888 = 0x50000002;
662 constexpr uint32_t BRANCH_RGB161616_TO_RGBA8888 = 0x50000003;
663 constexpr uint32_t BRANCH_RGB161616_TO_BGRA8888 = 0x50000004;
664 constexpr uint32_t BRANCH_RGB161616_TO_RGB565 = 0x50000005;
665 constexpr uint32_t BRANCH_RGB161616_TO_RGBAF16 = 0x50000006;
666 template<typename T>
RGB161616Convert(T * destinationRow,const uint8_t * sourceRow,uint32_t sourceWidth,uint32_t branch)667 static void RGB161616Convert(T *destinationRow, const uint8_t *sourceRow, uint32_t sourceWidth, uint32_t branch)
668 {
669 for (uint32_t i = 0; i < sourceWidth; i++) {
670 uint32_t R = sourceRow[0];
671 uint32_t G = sourceRow[2];
672 uint32_t B = sourceRow[4];
673 uint32_t A = ALPHA_OPAQUE;
674 if (branch == BRANCH_RGB161616_TO_ARGB8888) {
675 destinationRow[i] = FillARGB8888(A, R, G, B);
676 } else if (branch == BRANCH_RGB161616_TO_ABGR8888) {
677 destinationRow[i] = FillABGR8888(A, B, G, R);
678 } else if (branch == BRANCH_RGB161616_TO_RGBA8888) {
679 destinationRow[i] = FillRGBA8888(R, G, B, A);
680 } else if (branch == BRANCH_RGB161616_TO_BGRA8888) {
681 destinationRow[i] = FillBGRA8888(B, G, R, A);
682 } else if (branch == BRANCH_RGB161616_TO_RGB565) {
683 R = R >> SHIFT_3_BIT;
684 G = G >> SHIFT_2_BIT;
685 B = B >> SHIFT_3_BIT;
686 destinationRow[i] = FillRGB565(R, G, B);
687 } else if (branch == BRANCH_RGB161616_TO_RGBAF16) {
688 destinationRow[i] = FillRGBAF16(R, G, B, A);
689 } else {
690 break;
691 }
692 sourceRow += SIZE_6_BYTE;
693 }
694 }
695
RGB161616ConvertARGB8888(void * destinationRow,const uint8_t * sourceRow,uint32_t sourceWidth,const ProcFuncExtension & extension)696 static void RGB161616ConvertARGB8888(void *destinationRow, const uint8_t *sourceRow, uint32_t sourceWidth,
697 const ProcFuncExtension &extension)
698 {
699 uint32_t *newDestinationRow = static_cast<uint32_t *>(destinationRow);
700 RGB161616Convert(newDestinationRow, sourceRow, sourceWidth, BRANCH_RGB161616_TO_ARGB8888);
701 }
702
RGB161616ConvertABGR8888(void * destinationRow,const uint8_t * sourceRow,uint32_t sourceWidth,const ProcFuncExtension & extension)703 static void RGB161616ConvertABGR8888(void *destinationRow, const uint8_t *sourceRow, uint32_t sourceWidth,
704 const ProcFuncExtension &extension)
705 {
706 uint32_t *newDestinationRow = static_cast<uint32_t *>(destinationRow);
707 RGB161616Convert(newDestinationRow, sourceRow, sourceWidth, BRANCH_RGB161616_TO_ABGR8888);
708 }
709
RGB161616ConvertRGBA8888(void * destinationRow,const uint8_t * sourceRow,uint32_t sourceWidth,const ProcFuncExtension & extension)710 static void RGB161616ConvertRGBA8888(void *destinationRow, const uint8_t *sourceRow, uint32_t sourceWidth,
711 const ProcFuncExtension &extension)
712 {
713 uint32_t *newDestinationRow = static_cast<uint32_t *>(destinationRow);
714 RGB161616Convert(newDestinationRow, sourceRow, sourceWidth, BRANCH_RGB161616_TO_RGBA8888);
715 }
716
RGB161616ConvertBGRA8888(void * destinationRow,const uint8_t * sourceRow,uint32_t sourceWidth,const ProcFuncExtension & extension)717 static void RGB161616ConvertBGRA8888(void *destinationRow, const uint8_t *sourceRow, uint32_t sourceWidth,
718 const ProcFuncExtension &extension)
719 {
720 uint32_t *newDestinationRow = static_cast<uint32_t *>(destinationRow);
721 RGB161616Convert(newDestinationRow, sourceRow, sourceWidth, BRANCH_RGB161616_TO_BGRA8888);
722 }
723
RGB161616ConvertRGB565(void * destinationRow,const uint8_t * sourceRow,uint32_t sourceWidth,const ProcFuncExtension & extension)724 static void RGB161616ConvertRGB565(void *destinationRow, const uint8_t *sourceRow, uint32_t sourceWidth,
725 const ProcFuncExtension &extension)
726 {
727 uint16_t *newDestinationRow = static_cast<uint16_t *>(destinationRow);
728 RGB161616Convert(newDestinationRow, sourceRow, sourceWidth, BRANCH_RGB161616_TO_RGB565);
729 }
730
RGB161616ConvertRGBAF16(uint8_t * destinationRow,const uint8_t * sourceRow,uint32_t sourceWidth,const ProcFuncExtension & extension)731 static void RGB161616ConvertRGBAF16(uint8_t *destinationRow, const uint8_t *sourceRow, uint32_t sourceWidth,
732 const ProcFuncExtension &extension)
733 {
734 void* tmp = static_cast<void *>(destinationRow);
735 uint64_t *newDestinationRow = static_cast<uint64_t *>(tmp);
736 RGB161616Convert(newDestinationRow, sourceRow, sourceWidth, BRANCH_RGB161616_TO_RGBAF16);
737 }
738
739 constexpr uint32_t BRANCH_RGBA16161616_TO_ARGB8888 = 0x60000001;
740 constexpr uint32_t BRANCH_RGBA16161616_TO_ABGR8888 = 0x60000002;
741 constexpr uint32_t BRANCH_RGBA16161616_TO_RGBA8888 = 0x60000003;
742 constexpr uint32_t BRANCH_RGBA16161616_TO_BGRA8888 = 0x60000004;
743 constexpr uint32_t BRANCH_RGBA16161616_TO_RGBAF16 = 0x60000005;
744 template<typename T>
RGBA16161616Convert(T * destinationRow,const uint8_t * sourceRow,uint32_t sourceWidth,uint32_t branch,const ProcFuncExtension & extension)745 static void RGBA16161616Convert(T *destinationRow, const uint8_t *sourceRow, uint32_t sourceWidth, uint32_t branch,
746 const ProcFuncExtension &extension)
747 {
748 for (uint32_t i = 0; i < sourceWidth; i++) {
749 uint32_t R = sourceRow[0];
750 uint32_t G = sourceRow[2];
751 uint32_t B = sourceRow[4];
752 uint32_t A = sourceRow[6];
753 AlphaTypeConvertOnRGB(A, R, G, B, extension);
754 if (branch == BRANCH_RGBA16161616_TO_ARGB8888) {
755 destinationRow[i] = FillARGB8888(A, R, G, B);
756 } else if (branch == BRANCH_RGBA16161616_TO_ABGR8888) {
757 destinationRow[i] = FillABGR8888(A, B, G, R);
758 } else if (branch == BRANCH_RGBA16161616_TO_RGBA8888) {
759 destinationRow[i] = FillRGBA8888(A, B, G, R);
760 } else if (branch == BRANCH_RGBA16161616_TO_BGRA8888) {
761 destinationRow[i] = FillBGRA8888(A, B, G, R);
762 } else if (branch == BRANCH_RGBA16161616_TO_RGBAF16) {
763 destinationRow[i] = FillRGBAF16(R, G, B, A);
764 } else {
765 break;
766 }
767 sourceRow += SIZE_8_BYTE;
768 }
769 }
770
RGBA16161616ConvertARGB8888(void * destinationRow,const uint8_t * sourceRow,uint32_t sourceWidth,const ProcFuncExtension & extension)771 static void RGBA16161616ConvertARGB8888(void *destinationRow, const uint8_t *sourceRow, uint32_t sourceWidth,
772 const ProcFuncExtension &extension)
773 {
774 uint32_t *newDestinationRow = static_cast<uint32_t *>(destinationRow);
775 RGBA16161616Convert(newDestinationRow, sourceRow, sourceWidth, BRANCH_RGBA16161616_TO_ARGB8888, extension);
776 }
777
RGBA16161616ConvertABGR8888(void * destinationRow,const uint8_t * sourceRow,uint32_t sourceWidth,const ProcFuncExtension & extension)778 static void RGBA16161616ConvertABGR8888(void *destinationRow, const uint8_t *sourceRow, uint32_t sourceWidth,
779 const ProcFuncExtension &extension)
780 {
781 uint32_t *newDestinationRow = static_cast<uint32_t *>(destinationRow);
782 RGBA16161616Convert(newDestinationRow, sourceRow, sourceWidth, BRANCH_RGBA16161616_TO_ABGR8888, extension);
783 }
784
RGBA16161616ConvertRGBA8888(void * destinationRow,const uint8_t * sourceRow,uint32_t sourceWidth,const ProcFuncExtension & extension)785 static void RGBA16161616ConvertRGBA8888(void *destinationRow, const uint8_t *sourceRow, uint32_t sourceWidth,
786 const ProcFuncExtension &extension)
787 {
788 uint32_t *newDestinationRow = static_cast<uint32_t *>(destinationRow);
789 RGBA16161616Convert(newDestinationRow, sourceRow, sourceWidth, BRANCH_RGBA16161616_TO_RGBA8888, extension);
790 }
791
RGBA16161616ConvertBGRA8888(void * destinationRow,const uint8_t * sourceRow,uint32_t sourceWidth,const ProcFuncExtension & extension)792 static void RGBA16161616ConvertBGRA8888(void *destinationRow, const uint8_t *sourceRow, uint32_t sourceWidth,
793 const ProcFuncExtension &extension)
794 {
795 uint32_t *newDestinationRow = static_cast<uint32_t *>(destinationRow);
796 RGBA16161616Convert(newDestinationRow, sourceRow, sourceWidth, BRANCH_RGBA16161616_TO_BGRA8888, extension);
797 }
798
RGBA16161616ConvertRGBAF16(uint8_t * destinationRow,const uint8_t * sourceRow,uint32_t sourceWidth,const ProcFuncExtension & extension)799 static void RGBA16161616ConvertRGBAF16(uint8_t *destinationRow, const uint8_t *sourceRow, uint32_t sourceWidth,
800 const ProcFuncExtension &extension)
801 {
802 void* tmp = static_cast<void *>(destinationRow);
803 uint64_t *newDestinationRow = static_cast<uint64_t *>(tmp);
804 RGBA16161616Convert(newDestinationRow, sourceRow, sourceWidth, BRANCH_RGBA16161616_TO_RGBAF16, extension);
805 }
806
807 constexpr uint32_t BRANCH_CMYK_TO_ARGB8888 = 0x70000001;
808 constexpr uint32_t BRANCH_CMYK_TO_ABGR8888 = 0x70000002;
809 constexpr uint32_t BRANCH_CMYK_TO_RGBA8888 = 0x70000003;
810 constexpr uint32_t BRANCH_CMYK_TO_BGRA8888 = 0x70000004;
811 constexpr uint32_t BRANCH_CMYK_TO_RGB565 = 0x70000005;
812 template<typename T>
CMYKConvert(T * destinationRow,const uint8_t * sourceRow,uint32_t sourceWidth,uint32_t branch)813 static void CMYKConvert(T *destinationRow, const uint8_t *sourceRow, uint32_t sourceWidth, uint32_t branch)
814 {
815 for (uint32_t i = 0; i < sourceWidth; i++) {
816 uint8_t C = sourceRow[0];
817 uint8_t M = sourceRow[1];
818 uint8_t Y = sourceRow[2];
819 uint8_t K = sourceRow[3];
820 uint32_t R = Premul255(C, K);
821 uint32_t G = Premul255(M, K);
822 uint32_t B = Premul255(Y, K);
823 uint32_t A = ALPHA_OPAQUE;
824 if (branch == BRANCH_CMYK_TO_ARGB8888) {
825 destinationRow[i] = FillARGB8888(A, R, G, B);
826 } else if (branch == BRANCH_CMYK_TO_ABGR8888) {
827 destinationRow[i] = FillABGR8888(A, B, G, R);
828 } else if (branch == BRANCH_CMYK_TO_RGBA8888) {
829 destinationRow[i] = FillRGBA8888(R, G, B, A);
830 } else if (branch == BRANCH_CMYK_TO_BGRA8888) {
831 destinationRow[i] = FillBGRA8888(B, G, R, A);
832 } else if (branch == BRANCH_CMYK_TO_RGB565) {
833 R = R >> SHIFT_3_BIT;
834 G = R >> SHIFT_2_BIT;
835 B = B >> SHIFT_3_BIT;
836 destinationRow[i] = FillRGB565(R, G, B);
837 } else {
838 break;
839 }
840 sourceRow += SIZE_4_BYTE;
841 }
842 }
843
CMYKConvertARGB8888(void * destinationRow,const uint8_t * sourceRow,uint32_t sourceWidth,const ProcFuncExtension & extension)844 static void CMYKConvertARGB8888(void *destinationRow, const uint8_t *sourceRow, uint32_t sourceWidth,
845 const ProcFuncExtension &extension)
846 {
847 uint32_t *newDestinationRow = static_cast<uint32_t *>(destinationRow);
848 CMYKConvert(newDestinationRow, sourceRow, sourceWidth, BRANCH_CMYK_TO_ARGB8888);
849 }
850
CMYKConvertABGR8888(void * destinationRow,const uint8_t * sourceRow,uint32_t sourceWidth,const ProcFuncExtension & extension)851 static void CMYKConvertABGR8888(void *destinationRow, const uint8_t *sourceRow, uint32_t sourceWidth,
852 const ProcFuncExtension &extension)
853 {
854 uint32_t *newDestinationRow = static_cast<uint32_t *>(destinationRow);
855 CMYKConvert(newDestinationRow, sourceRow, sourceWidth, BRANCH_CMYK_TO_ABGR8888);
856 }
857
CMYKConvertRGBA8888(void * destinationRow,const uint8_t * sourceRow,uint32_t sourceWidth,const ProcFuncExtension & extension)858 static void CMYKConvertRGBA8888(void *destinationRow, const uint8_t *sourceRow, uint32_t sourceWidth,
859 const ProcFuncExtension &extension)
860 {
861 uint32_t *newDestinationRow = static_cast<uint32_t *>(destinationRow);
862 CMYKConvert(newDestinationRow, sourceRow, sourceWidth, BRANCH_CMYK_TO_RGBA8888);
863 }
864
CMYKConvertBGRA8888(void * destinationRow,const uint8_t * sourceRow,uint32_t sourceWidth,const ProcFuncExtension & extension)865 static void CMYKConvertBGRA8888(void *destinationRow, const uint8_t *sourceRow, uint32_t sourceWidth,
866 const ProcFuncExtension &extension)
867 {
868 uint32_t *newDestinationRow = static_cast<uint32_t *>(destinationRow);
869 CMYKConvert(newDestinationRow, sourceRow, sourceWidth, BRANCH_CMYK_TO_BGRA8888);
870 }
871
CMYKConvertRGB565(void * destinationRow,const uint8_t * sourceRow,uint32_t sourceWidth,const ProcFuncExtension & extension)872 static void CMYKConvertRGB565(void *destinationRow, const uint8_t *sourceRow, uint32_t sourceWidth,
873 const ProcFuncExtension &extension)
874 {
875 uint32_t *newDestinationRow = static_cast<uint32_t *>(destinationRow);
876 CMYKConvert(newDestinationRow, sourceRow, sourceWidth, BRANCH_CMYK_TO_RGB565);
877 }
878
879 constexpr uint32_t BRANCH_RGB565_TO_ARGB8888 = 0x11000001;
880 constexpr uint32_t BRANCH_RGB565_TO_RGBA8888 = 0x11000002;
881 constexpr uint32_t BRANCH_RGB565_TO_BGRA8888 = 0x11000003;
882 constexpr uint32_t BRANCH_RGB565_TO_RGBAF16 = 0x11000004;
883 template<typename T>
RGB565Convert(T * destinationRow,const uint8_t * sourceRow,uint32_t sourceWidth,uint32_t branch)884 static void RGB565Convert(T *destinationRow, const uint8_t *sourceRow, uint32_t sourceWidth, uint32_t branch)
885 {
886 for (uint32_t i = 0; i < sourceWidth; i++) {
887 uint32_t R = (sourceRow[0] >> SHIFT_3_BIT) & SHIFT_5_MASK;
888 uint32_t G = ((sourceRow[0] & SHIFT_3_MASK) << SHIFT_3_BIT) | ((sourceRow[1] >> SHIFT_5_BIT) & SHIFT_3_MASK);
889 uint32_t B = sourceRow[1] & SHIFT_5_MASK;
890 uint32_t A = ALPHA_OPAQUE;
891 if (branch == BRANCH_RGB565_TO_ARGB8888) {
892 destinationRow[i] = FillARGB8888(A, R, G, B);
893 } else if (branch == BRANCH_RGB565_TO_RGBA8888) {
894 destinationRow[i] = FillRGBA8888(R, G, B, A);
895 } else if (branch == BRANCH_RGB565_TO_BGRA8888) {
896 destinationRow[i] = FillBGRA8888(B, G, R, A);
897 } else if (branch == BRANCH_RGB565_TO_RGBAF16) {
898 destinationRow[i] = FillRGBAF16(R, G, B, A);
899 } else {
900 break;
901 }
902 sourceRow += SIZE_2_BYTE;
903 }
904 }
905
RGB565ConvertARGB8888(void * destinationRow,const uint8_t * sourceRow,uint32_t sourceWidth,const ProcFuncExtension & extension)906 static void RGB565ConvertARGB8888(void *destinationRow, const uint8_t *sourceRow, uint32_t sourceWidth,
907 const ProcFuncExtension &extension)
908 {
909 uint32_t *newDestinationRow = static_cast<uint32_t *>(destinationRow);
910 RGB565Convert(newDestinationRow, sourceRow, sourceWidth, BRANCH_RGB565_TO_ARGB8888);
911 }
912
RGB565ConvertRGBA8888(void * destinationRow,const uint8_t * sourceRow,uint32_t sourceWidth,const ProcFuncExtension & extension)913 static void RGB565ConvertRGBA8888(void *destinationRow, const uint8_t *sourceRow, uint32_t sourceWidth,
914 const ProcFuncExtension &extension)
915 {
916 uint32_t *newDestinationRow = static_cast<uint32_t *>(destinationRow);
917 RGB565Convert(newDestinationRow, sourceRow, sourceWidth, BRANCH_RGB565_TO_RGBA8888);
918 }
919
RGB565ConvertBGRA8888(void * destinationRow,const uint8_t * sourceRow,uint32_t sourceWidth,const ProcFuncExtension & extension)920 static void RGB565ConvertBGRA8888(void *destinationRow, const uint8_t *sourceRow, uint32_t sourceWidth,
921 const ProcFuncExtension &extension)
922 {
923 uint32_t *newDestinationRow = static_cast<uint32_t *>(destinationRow);
924 RGB565Convert(newDestinationRow, sourceRow, sourceWidth, BRANCH_RGB565_TO_BGRA8888);
925 }
926
RGB565ConvertRGBAF16(uint8_t * destinationRow,const uint8_t * sourceRow,uint32_t sourceWidth,const ProcFuncExtension & extension)927 static void RGB565ConvertRGBAF16(uint8_t *destinationRow, const uint8_t *sourceRow, uint32_t sourceWidth,
928 const ProcFuncExtension &extension)
929 {
930 void* tmp = static_cast<void *>(destinationRow);
931 uint64_t *newDestinationRow = static_cast<uint64_t *>(tmp);
932 RGB565Convert(newDestinationRow, sourceRow, sourceWidth, BRANCH_RGB565_TO_RGBAF16);
933 }
934
935 constexpr uint32_t BRANCH_RGBAF16_TO_ARGB8888 = 0x13000001;
936 constexpr uint32_t BRANCH_RGBAF16_TO_RGBA8888 = 0x13000002;
937 constexpr uint32_t BRANCH_RGBAF16_TO_BGRA8888 = 0x13000003;
938 constexpr uint32_t BRANCH_RGBAF16_TO_ABGR8888 = 0x13000004;
939 constexpr uint32_t BRANCH_RGBAF16_TO_RGB565 = 0x13000005;
940 template<typename T>
RGBAF16Convert(T * destinationRow,const uint8_t * sourceRow,uint32_t sourceWidth,uint32_t branch,const ProcFuncExtension & extension)941 static void RGBAF16Convert(T *destinationRow, const uint8_t *sourceRow, uint32_t sourceWidth, uint32_t branch,
942 const ProcFuncExtension &extension)
943 {
944 for (uint32_t i = 0; i < sourceWidth; i++) {
945 uint32_t R = HalfToUint32(sourceRow, IS_LITTLE_ENDIAN);
946 uint32_t G = HalfToUint32(sourceRow + 2, IS_LITTLE_ENDIAN);
947 uint32_t B = HalfToUint32(sourceRow + 4, IS_LITTLE_ENDIAN);
948 uint32_t A = HalfToUint32(sourceRow + 6, IS_LITTLE_ENDIAN);
949 AlphaTypeConvertOnRGB(A, R, G, B, extension);
950 if (branch == BRANCH_RGBAF16_TO_ARGB8888) {
951 destinationRow[i] = FillARGB8888(A, R, G, B);
952 } else if (branch == BRANCH_RGBAF16_TO_RGBA8888) {
953 destinationRow[i] = FillRGBA8888(R, G, B, A);
954 } else if (branch == BRANCH_RGBAF16_TO_BGRA8888) {
955 destinationRow[i] = FillBGRA8888(B, G, R, A);
956 } else if (branch == BRANCH_RGBAF16_TO_ABGR8888) {
957 destinationRow[i] = FillABGR8888(A, B, G, R);
958 } else if (branch == BRANCH_RGBAF16_TO_RGB565) {
959 R = R >> SHIFT_3_BIT;
960 G = G >> SHIFT_2_BIT;
961 B = B >> SHIFT_3_BIT;
962 destinationRow[i] = FillRGB565(R, G, B);
963 } else {
964 break;
965 }
966 sourceRow += SIZE_8_BYTE;
967 }
968 }
969
RGBAF16ConvertARGB8888(uint8_t * destinationRow,const uint8_t * sourceRow,uint32_t sourceWidth,const ProcFuncExtension & extension)970 static void RGBAF16ConvertARGB8888(uint8_t *destinationRow, const uint8_t *sourceRow, uint32_t sourceWidth,
971 const ProcFuncExtension &extension)
972 {
973 void* tmp = static_cast<void *>(destinationRow);
974 uint32_t *newDestinationRow = static_cast<uint32_t *>(tmp);
975 RGBAF16Convert(newDestinationRow, sourceRow, sourceWidth, BRANCH_RGBAF16_TO_ARGB8888, extension);
976 }
977
RGBAF16ConvertRGBA8888(uint8_t * destinationRow,const uint8_t * sourceRow,uint32_t sourceWidth,const ProcFuncExtension & extension)978 static void RGBAF16ConvertRGBA8888(uint8_t *destinationRow, const uint8_t *sourceRow, uint32_t sourceWidth,
979 const ProcFuncExtension &extension)
980 {
981 void* tmp = static_cast<void *>(destinationRow);
982 uint32_t *newDestinationRow = static_cast<uint32_t *>(tmp);
983 RGBAF16Convert(newDestinationRow, sourceRow, sourceWidth, BRANCH_RGBAF16_TO_RGBA8888, extension);
984 }
985
RGBAF16ConvertBGRA8888(uint8_t * destinationRow,const uint8_t * sourceRow,uint32_t sourceWidth,const ProcFuncExtension & extension)986 static void RGBAF16ConvertBGRA8888(uint8_t *destinationRow, const uint8_t *sourceRow, uint32_t sourceWidth,
987 const ProcFuncExtension &extension)
988 {
989 void* tmp = static_cast<void *>(destinationRow);
990 uint32_t *newDestinationRow = static_cast<uint32_t *>(tmp);
991 RGBAF16Convert(newDestinationRow, sourceRow, sourceWidth, BRANCH_RGBAF16_TO_BGRA8888, extension);
992 }
993
RGBAF16ConvertABGR8888(uint8_t * destinationRow,const uint8_t * sourceRow,uint32_t sourceWidth,const ProcFuncExtension & extension)994 static void RGBAF16ConvertABGR8888(uint8_t *destinationRow, const uint8_t *sourceRow, uint32_t sourceWidth,
995 const ProcFuncExtension &extension)
996 {
997 void* tmp = static_cast<void *>(destinationRow);
998 uint32_t *newDestinationRow = static_cast<uint32_t *>(tmp);
999 RGBAF16Convert(newDestinationRow, sourceRow, sourceWidth, BRANCH_RGBAF16_TO_ABGR8888, extension);
1000 }
1001
RGBAF16ConvertRGB565(uint8_t * destinationRow,const uint8_t * sourceRow,uint32_t sourceWidth,const ProcFuncExtension & extension)1002 static void RGBAF16ConvertRGB565(uint8_t *destinationRow, const uint8_t *sourceRow, uint32_t sourceWidth,
1003 const ProcFuncExtension &extension)
1004 {
1005 void* tmp = static_cast<void *>(destinationRow);
1006 uint16_t *newDestinationRow = static_cast<uint16_t *>(tmp);
1007 RGBAF16Convert(newDestinationRow, sourceRow, sourceWidth, BRANCH_RGBAF16_TO_RGB565, extension);
1008 }
1009
1010 static map<string, ProcFuncType> g_procMapping;
1011 static mutex g_procMutex;
1012
MakeKey(uint32_t srcFormat,uint32_t dstFormat)1013 static string MakeKey(uint32_t srcFormat, uint32_t dstFormat)
1014 {
1015 return to_string(srcFormat) + ("_") + to_string(dstFormat);
1016 }
1017
InitGrayProc()1018 static void InitGrayProc()
1019 {
1020 g_procMapping.emplace(MakeKey(GRAY_BIT, ARGB_8888), &BitConvertARGB8888);
1021 g_procMapping.emplace(MakeKey(GRAY_BIT, RGB_565), &BitConvertRGB565);
1022 g_procMapping.emplace(MakeKey(GRAY_BIT, ALPHA_8), &BitConvertGray);
1023
1024 g_procMapping.emplace(MakeKey(ALPHA_8, ARGB_8888), &GrayConvertARGB8888);
1025 g_procMapping.emplace(MakeKey(ALPHA_8, RGB_565), &GrayConvertRGB565);
1026
1027 g_procMapping.emplace(MakeKey(GRAY_ALPHA, ARGB_8888), &GrayAlphaConvertARGB8888);
1028 g_procMapping.emplace(MakeKey(GRAY_ALPHA, ALPHA_8), &GrayAlphaConvertAlpha);
1029 }
1030
InitRGBProc()1031 static void InitRGBProc()
1032 {
1033 g_procMapping.emplace(MakeKey(RGB_888, ARGB_8888), &RGB888ConvertARGB8888);
1034 g_procMapping.emplace(MakeKey(RGB_888, RGBA_8888), &RGB888ConvertRGBA8888);
1035 g_procMapping.emplace(MakeKey(RGB_888, BGRA_8888), &RGB888ConvertBGRA8888);
1036 g_procMapping.emplace(MakeKey(RGB_888, RGB_565), &RGB888ConvertRGB565);
1037
1038 g_procMapping.emplace(MakeKey(BGR_888, ARGB_8888), &BGR888ConvertARGB8888);
1039 g_procMapping.emplace(MakeKey(BGR_888, RGBA_8888), &BGR888ConvertRGBA8888);
1040 g_procMapping.emplace(MakeKey(BGR_888, BGRA_8888), &BGR888ConvertBGRA8888);
1041 g_procMapping.emplace(MakeKey(BGR_888, RGB_565), &BGR888ConvertRGB565);
1042
1043 g_procMapping.emplace(MakeKey(RGB_161616, ARGB_8888), &RGB161616ConvertARGB8888);
1044 g_procMapping.emplace(MakeKey(RGB_161616, ABGR_8888), &RGB161616ConvertABGR8888);
1045 g_procMapping.emplace(MakeKey(RGB_161616, RGBA_8888), &RGB161616ConvertRGBA8888);
1046 g_procMapping.emplace(MakeKey(RGB_161616, BGRA_8888), &RGB161616ConvertBGRA8888);
1047 g_procMapping.emplace(MakeKey(RGB_161616, RGB_565), &RGB161616ConvertRGB565);
1048
1049 g_procMapping.emplace(MakeKey(RGB_565, ARGB_8888), &RGB565ConvertARGB8888);
1050 g_procMapping.emplace(MakeKey(RGB_565, RGBA_8888), &RGB565ConvertRGBA8888);
1051 g_procMapping.emplace(MakeKey(RGB_565, BGRA_8888), &RGB565ConvertBGRA8888);
1052 }
1053
InitRGBAProc()1054 static void InitRGBAProc()
1055 {
1056 g_procMapping.emplace(MakeKey(RGBA_8888, RGBA_8888), &RGBA8888ConvertRGBA8888Alpha);
1057 g_procMapping.emplace(MakeKey(RGBA_8888, ARGB_8888), &RGBA8888ConvertARGB8888);
1058 g_procMapping.emplace(MakeKey(RGBA_8888, BGRA_8888), &RGBA8888ConvertBGRA8888);
1059 g_procMapping.emplace(MakeKey(RGBA_8888, RGB_565), &RGBA8888ConvertRGB565);
1060
1061 g_procMapping.emplace(MakeKey(BGRA_8888, RGBA_8888), &BGRA8888ConvertRGBA8888);
1062 g_procMapping.emplace(MakeKey(BGRA_8888, ARGB_8888), &BGRA8888ConvertARGB8888);
1063 g_procMapping.emplace(MakeKey(BGRA_8888, BGRA_8888), &BGRA8888ConvertBGRA8888Alpha);
1064 g_procMapping.emplace(MakeKey(BGRA_8888, RGB_565), &BGRA8888ConvertRGB565);
1065
1066 g_procMapping.emplace(MakeKey(ARGB_8888, RGBA_8888), &ARGB8888ConvertRGBA8888);
1067 g_procMapping.emplace(MakeKey(ARGB_8888, ARGB_8888), &ARGB8888ConvertARGB8888Alpha);
1068 g_procMapping.emplace(MakeKey(ARGB_8888, BGRA_8888), &ARGB8888ConvertBGRA8888);
1069 g_procMapping.emplace(MakeKey(ARGB_8888, RGB_565), &ARGB8888ConvertRGB565);
1070
1071 g_procMapping.emplace(MakeKey(RGBA_16161616, ARGB_8888), &RGBA16161616ConvertARGB8888);
1072 g_procMapping.emplace(MakeKey(RGBA_16161616, RGBA_8888), &RGBA16161616ConvertRGBA8888);
1073 g_procMapping.emplace(MakeKey(RGBA_16161616, BGRA_8888), &RGBA16161616ConvertBGRA8888);
1074 g_procMapping.emplace(MakeKey(RGBA_16161616, ABGR_8888), &RGBA16161616ConvertABGR8888);
1075 }
1076
InitCMYKProc()1077 static void InitCMYKProc()
1078 {
1079 g_procMapping.emplace(MakeKey(CMKY, ARGB_8888), &CMYKConvertARGB8888);
1080 g_procMapping.emplace(MakeKey(CMKY, RGBA_8888), &CMYKConvertRGBA8888);
1081 g_procMapping.emplace(MakeKey(CMKY, BGRA_8888), &CMYKConvertBGRA8888);
1082 g_procMapping.emplace(MakeKey(CMKY, ABGR_8888), &CMYKConvertABGR8888);
1083 g_procMapping.emplace(MakeKey(CMKY, RGB_565), &CMYKConvertRGB565);
1084 }
1085
InitF16Proc()1086 static void InitF16Proc()
1087 {
1088 g_procMapping.emplace(MakeKey(RGBA_F16, ARGB_8888),
1089 reinterpret_cast<ProcFuncType>(&RGBAF16ConvertARGB8888));
1090 g_procMapping.emplace(MakeKey(RGBA_F16, RGBA_8888),
1091 reinterpret_cast<ProcFuncType>(&RGBAF16ConvertRGBA8888));
1092 g_procMapping.emplace(MakeKey(RGBA_F16, BGRA_8888),
1093 reinterpret_cast<ProcFuncType>(&RGBAF16ConvertBGRA8888));
1094 g_procMapping.emplace(MakeKey(RGBA_F16, ABGR_8888),
1095 reinterpret_cast<ProcFuncType>(&RGBAF16ConvertABGR8888));
1096 g_procMapping.emplace(MakeKey(RGBA_F16, RGB_565),
1097 reinterpret_cast<ProcFuncType>(&RGBAF16ConvertRGB565));
1098
1099 g_procMapping.emplace(MakeKey(BGR_888, RGBA_F16),
1100 reinterpret_cast<ProcFuncType>(&BGR888ConvertRGBAF16));
1101 g_procMapping.emplace(MakeKey(RGB_888, RGBA_F16),
1102 reinterpret_cast<ProcFuncType>(&RGB888ConvertRGBAF16));
1103 g_procMapping.emplace(MakeKey(RGB_161616, RGBA_F16),
1104 reinterpret_cast<ProcFuncType>(&RGB161616ConvertRGBAF16));
1105 g_procMapping.emplace(MakeKey(ARGB_8888, RGBA_F16),
1106 reinterpret_cast<ProcFuncType>(&ARGB8888ConvertRGBAF16));
1107 g_procMapping.emplace(MakeKey(RGBA_8888, RGBA_F16),
1108 reinterpret_cast<ProcFuncType>(&RGBA8888ConvertRGBAF16));
1109 g_procMapping.emplace(MakeKey(BGRA_8888, RGBA_F16),
1110 reinterpret_cast<ProcFuncType>(&BGRA8888ConvertRGBAF16));
1111 g_procMapping.emplace(MakeKey(RGB_565, RGBA_F16),
1112 reinterpret_cast<ProcFuncType>(&RGB565ConvertRGBAF16));
1113 g_procMapping.emplace(MakeKey(RGBA_16161616, RGBA_F16),
1114 reinterpret_cast<ProcFuncType>(&RGBA16161616ConvertRGBAF16));
1115 }
1116
GetProcFuncType(uint32_t srcPixelFormat,uint32_t dstPixelFormat)1117 static ProcFuncType GetProcFuncType(uint32_t srcPixelFormat, uint32_t dstPixelFormat)
1118 {
1119 unique_lock<mutex> guard(g_procMutex);
1120 if (g_procMapping.empty()) {
1121 InitGrayProc();
1122 InitRGBProc();
1123 InitRGBAProc();
1124 InitCMYKProc();
1125 InitF16Proc();
1126 }
1127 guard.unlock();
1128 string procKey = MakeKey(srcPixelFormat, dstPixelFormat);
1129 map<string, ProcFuncType>::iterator iter = g_procMapping.find(procKey);
1130 if (iter != g_procMapping.end()) {
1131 return iter->second;
1132 }
1133 return nullptr;
1134 }
1135
PixelFormatToAVPixelFormat(const PixelFormat & pixelFormat)1136 static AVPixelFormat PixelFormatToAVPixelFormat(const PixelFormat &pixelFormat)
1137 {
1138 auto formatSearch = PixelConvertAdapter::FFMPEG_PIXEL_FORMAT_MAP.find(pixelFormat);
1139 return (formatSearch != PixelConvertAdapter::FFMPEG_PIXEL_FORMAT_MAP.end()) ?
1140 formatSearch->second : AVPixelFormat::AV_PIX_FMT_NONE;
1141 }
1142
1143 typedef struct FFMpegConvertInfo {
1144 AVPixelFormat format = AVPixelFormat::AV_PIX_FMT_NONE;
1145 int32_t width = 0;
1146 int32_t height = 0;
1147 int32_t alignSize = 1;
1148 } FFMPEG_CONVERT_INFO;
1149
FFMpegConvert(const void * srcPixels,const FFMPEG_CONVERT_INFO & srcInfo,void * dstPixels,const FFMPEG_CONVERT_INFO & dstInfo,YUVConvertColorSpaceDetails & colorSpaceDetails)1150 static bool FFMpegConvert(const void *srcPixels, const FFMPEG_CONVERT_INFO& srcInfo,
1151 void *dstPixels, const FFMPEG_CONVERT_INFO& dstInfo, YUVConvertColorSpaceDetails &colorSpaceDetails)
1152 {
1153 bool ret = true;
1154 AVFrame *inputFrame = nullptr;
1155 AVFrame *outputFrame = nullptr;
1156
1157 CHECK_ERROR_RETURN_RET_LOG(srcInfo.format == AVPixelFormat::AV_PIX_FMT_NONE ||
1158 dstInfo.format == AVPixelFormat::AV_PIX_FMT_NONE, false, "unsupport src/dst pixel format!");
1159 CHECK_ERROR_RETURN_RET_LOG((srcInfo.width <= 0 || srcInfo.height <= 0 ||
1160 dstInfo.width <= 0 || dstInfo.height <= 0 ||
1161 (SWS_CS_COEFFICIENT.find(colorSpaceDetails.srcYuvConversion) == SWS_CS_COEFFICIENT.end()) ||
1162 (SWS_CS_COEFFICIENT.find(colorSpaceDetails.dstYuvConversion) == SWS_CS_COEFFICIENT.end())),
1163 false, "src/dst width/height colorTableCoefficients error!");
1164
1165 inputFrame = av_frame_alloc();
1166 outputFrame = av_frame_alloc();
1167 if (inputFrame != nullptr && outputFrame != nullptr) {
1168 struct SwsContext *ctx = sws_getContext(srcInfo.width, srcInfo.height, srcInfo.format,
1169 dstInfo.width, dstInfo.height, dstInfo.format, SWS_POINT, nullptr, nullptr, nullptr);
1170 IMAGE_LOGE("srcInfo.width:%{public}d, srcInfo.height:%{public}d", srcInfo.width, srcInfo.height);
1171 if (ctx != nullptr) {
1172 //if need applu colorspace in scale, change defult table;
1173 auto srcColorTable = sws_getCoefficients(SWS_CS_COEFFICIENT.at(colorSpaceDetails.srcYuvConversion));
1174 auto dstColorTable = sws_getCoefficients(SWS_CS_COEFFICIENT.at(colorSpaceDetails.dstYuvConversion));
1175 sws_setColorspaceDetails(ctx,
1176 // src convert matrix(YUV2RGB), Range: 0 means limit range, 1 means full range.
1177 srcColorTable, colorSpaceDetails.srcRange,
1178 // dst convert matrix(RGB2YUV, not used here).
1179 dstColorTable, colorSpaceDetails.dstRange,
1180 // brightness, contrast, saturation not adjusted.
1181 0, 1 << BIT_SHIFT_16BITS, 1 << BIT_SHIFT_16BITS);
1182
1183 av_image_fill_arrays(inputFrame->data, inputFrame->linesize, (uint8_t *)srcPixels,
1184 srcInfo.format, srcInfo.width, srcInfo.height, srcInfo.alignSize);
1185 av_image_fill_arrays(outputFrame->data, outputFrame->linesize, (uint8_t *)dstPixels,
1186 dstInfo.format, dstInfo.width, dstInfo.height, dstInfo.alignSize);
1187
1188 sws_scale(ctx, (uint8_t const **)inputFrame->data, inputFrame->linesize, 0, srcInfo.height,
1189 outputFrame->data, outputFrame->linesize);
1190 sws_freeContext(ctx);
1191 } else {
1192 IMAGE_LOGE("FFMpeg: sws_getContext failed!");
1193 ret = false;
1194 }
1195 } else {
1196 IMAGE_LOGE("FFMpeg: av_frame_alloc failed!");
1197 ret = false;
1198 }
1199 av_frame_free(&inputFrame);
1200 av_frame_free(&outputFrame);
1201 return ret;
1202 }
1203
FFMpegConvert(const void * srcPixels,const FFMPEG_CONVERT_INFO & srcInfo,void * dstPixels,const FFMPEG_CONVERT_INFO & dstInfo)1204 static bool FFMpegConvert(const void *srcPixels, const FFMPEG_CONVERT_INFO& srcInfo,
1205 void *dstPixels, const FFMPEG_CONVERT_INFO& dstInfo)
1206 {
1207 YUVConvertColorSpaceDetails colorSpaceDetails = { 0, 0 };
1208 return FFMpegConvert(srcPixels, srcInfo, dstPixels, dstInfo, colorSpaceDetails);
1209 }
1210
NV12P010ToNV21P010(const uint16_t * srcBuffer,const ImageInfo & info,uint16_t * destBuffer)1211 static bool NV12P010ToNV21P010(const uint16_t *srcBuffer, const ImageInfo &info, uint16_t *destBuffer)
1212 {
1213 if (info.size.width <= 0 || info.size.height <= 0) {
1214 IMAGE_LOGE("Invalid Pixelmap size: width = %{public}d, height = %{public}d", info.size.width, info.size.height);
1215 return false;
1216 }
1217 uint32_t width = static_cast<uint32_t>(info.size.width);
1218 uint32_t height = static_cast<uint32_t>(info.size.height);
1219 if (width > UINT32_MAX / height) {
1220 IMAGE_LOGE("Image size too large: width = %{public}u, height = %{public}u", width, height);
1221 return false;
1222 }
1223 uint32_t ysize = width * height;
1224 uint32_t sizeUV = ysize / NUM_2;
1225 const uint16_t *srcUV = srcBuffer + ysize;
1226 uint16_t *dstVU = destBuffer + ysize;
1227 for (uint32_t i = 0; i < ysize; i++) {
1228 destBuffer[i] = srcBuffer[i];
1229 }
1230 for (uint32_t i = 0; i < sizeUV / UV_PLANES_COUNT; i++) {
1231 dstVU[UV_PLANES_COUNT * i] = srcUV[UV_PLANES_COUNT * i + 1];
1232 dstVU[UV_PLANES_COUNT * i + 1] = srcUV[UV_PLANES_COUNT * i];
1233 }
1234 return true;
1235 }
1236
IsYUVP010Format(PixelFormat format)1237 bool IsYUVP010Format(PixelFormat format)
1238 {
1239 return (format == PixelFormat::YCBCR_P010) || (format == PixelFormat::YCRCB_P010);
1240 }
1241
ConvertForFFMPEG(const void * srcPixels,PixelFormat srcpixelmap,ImageInfo srcInfo,void * dstPixels,PixelFormat dstpixelmap)1242 static bool ConvertForFFMPEG(const void *srcPixels, PixelFormat srcpixelmap, ImageInfo srcInfo,
1243 void *dstPixels, PixelFormat dstpixelmap)
1244 {
1245 FFMPEG_CONVERT_INFO srcFFmpegInfo = {PixelFormatToAVPixelFormat(srcpixelmap),
1246 srcInfo.size.width, srcInfo.size.height, 1};
1247 FFMPEG_CONVERT_INFO dstFFmpegInfo = {PixelFormatToAVPixelFormat(dstpixelmap),
1248 srcInfo.size.width, srcInfo.size.height, 1};
1249
1250 CHECK_ERROR_RETURN_RET_LOG((!FFMpegConvert(srcPixels, srcFFmpegInfo, dstPixels, dstFFmpegInfo)),
1251 false, "[PixelMap]Convert: ffmpeg convert failed!");
1252
1253 return true;
1254 }
1255
GetValidBufferSize(const ImageInfo & dstInfo)1256 static int64_t GetValidBufferSize(const ImageInfo &dstInfo)
1257 {
1258 int64_t rowDataSize = ImageUtils::GetRowDataSizeByPixelFormat(dstInfo.size.width, dstInfo.pixelFormat);
1259 CHECK_ERROR_RETURN_RET_LOG(rowDataSize <= 0, CONVERT_ERROR,
1260 "[PixelMap] AllocPixelMapMemory: get row data size failed");
1261
1262 int64_t bufferSize = rowDataSize * dstInfo.size.height;
1263 CHECK_ERROR_RETURN_RET_LOG(bufferSize > UINT32_MAX, CONVERT_ERROR,
1264 "[PixelMap]Create: Pixelmap size too large: width = %{public}d, height = %{public}d",
1265 dstInfo.size.width, dstInfo.size.height);
1266 return bufferSize;
1267 }
1268
IsRGBFormat(PixelFormat format)1269 static bool IsRGBFormat(PixelFormat format)
1270 {
1271 return (format == PixelFormat::RGB_888) || (format == PixelFormat::RGB_565);
1272 }
1273
1274 // Convert and collapse pixels by removing line paddings if any
ConvertAndCollapseByFFMpeg(const void * srcPixels,const ImageInfo & srcInfo,void * dstPixels,const ImageInfo & dstInfo,bool useDMA)1275 static bool ConvertAndCollapseByFFMpeg(const void *srcPixels, const ImageInfo &srcInfo, void *dstPixels,
1276 const ImageInfo &dstInfo, bool useDMA)
1277 {
1278 FFMPEG_CONVERT_INFO srcFFMpegInfo = {PixelFormatToAVPixelFormat(srcInfo.pixelFormat),
1279 srcInfo.size.width, srcInfo.size.height, useDMA ? DMA_LINE_SIZE : 1};
1280 FFMPEG_CONVERT_INFO dstFFMpegInfo = {PixelFormatToAVPixelFormat(dstInfo.pixelFormat),
1281 dstInfo.size.width, dstInfo.size.height, 1};
1282
1283 std::unique_ptr<uint8_t[]> tmpBuffer = nullptr;
1284 bool needTmpBuffer = false;
1285 int64_t bufferSize = 0;
1286 if (IsRGBFormat(srcInfo.pixelFormat) && dstInfo.pixelFormat == PixelFormat::ARGB_8888) {
1287 bufferSize = GetValidBufferSize(dstInfo);
1288 CHECK_ERROR_RETURN_RET(bufferSize <= 0, false);
1289
1290 tmpBuffer = std::make_unique<uint8_t[]>(bufferSize + 1); // avoid ffmpeg out-bounds-write
1291 CHECK_ERROR_RETURN_RET_LOG(tmpBuffer == nullptr, false,
1292 "[PixelMap] ConvertAndCollapseByFFMpeg: alloc memory failed!");
1293 needTmpBuffer = true;
1294 }
1295 void* conversionTarget = needTmpBuffer ? static_cast<void*>(tmpBuffer.get()) : dstPixels;
1296 bool cond = FFMpegConvert(srcPixels, srcFFMpegInfo, conversionTarget, dstFFMpegInfo);
1297 CHECK_ERROR_RETURN_RET_LOG(!cond, false, "[PixelMap] ConvertAndCollapseByFFMpeg: FFMpeg convert failed!");
1298 if (needTmpBuffer) {
1299 CHECK_ERROR_RETURN_RET_LOG(memcpy_s(dstPixels, bufferSize, conversionTarget, bufferSize) != 0, false,
1300 "[PixelMap] ConvertAndCollapseByFFMpeg: memcpy_s failed!");
1301 }
1302 return true;
1303 }
1304
P010ConvertRGBA1010102(const void * srcPixels,ImageInfo srcInfo,void * dstPixels,ImageInfo dstInfo)1305 static bool P010ConvertRGBA1010102(const void *srcPixels, ImageInfo srcInfo,
1306 void *dstPixels, ImageInfo dstInfo)
1307 {
1308 FFMPEG_CONVERT_INFO srcFFmpegInfo = {PixelFormatToAVPixelFormat(srcInfo.pixelFormat),
1309 srcInfo.size.width, srcInfo.size.height, 1};
1310 FFMPEG_CONVERT_INFO tmpFFmpegInfo = {PixelFormatToAVPixelFormat(PixelFormat::RGBA_F16),
1311 srcInfo.size.width, srcInfo.size.height, 1};
1312 int tmpPixelsLen = av_image_get_buffer_size(tmpFFmpegInfo.format, tmpFFmpegInfo.width, tmpFFmpegInfo.height,
1313 tmpFFmpegInfo.alignSize);
1314
1315 CHECK_ERROR_RETURN_RET_LOG((tmpPixelsLen <= 0), false, "[PixelMap]Convert: Get tmp pixels length failed!");
1316
1317 uint8_t* tmpPixels = new(std::nothrow) uint8_t[tmpPixelsLen];
1318 CHECK_ERROR_RETURN_RET_LOG(tmpPixels == nullptr, false, "[PixelMap]Convert: alloc memory failed!");
1319 memset_s(tmpPixels, tmpPixelsLen, 0, tmpPixelsLen);
1320 if (!FFMpegConvert(srcPixels, srcFFmpegInfo, tmpPixels, tmpFFmpegInfo)) {
1321 IMAGE_LOGE("[PixelMap]Convert: ffmpeg convert failed!");
1322 delete[] tmpPixels;
1323 tmpPixels = nullptr;
1324 return false;
1325 }
1326 ImageInfo tmpInfo = srcInfo;
1327 tmpInfo.pixelFormat = PixelFormat::RGBA_U16;
1328 tmpInfo.alphaType = AlphaType::IMAGE_ALPHA_TYPE_PREMUL;
1329 Position pos;
1330 if (!PixelConvertAdapter::WritePixelsConvert(tmpPixels, PixelMap::GetRGBxRowDataSize(tmpInfo), tmpInfo,
1331 dstPixels, pos, PixelMap::GetRGBxRowDataSize(dstInfo), dstInfo)) {
1332 IMAGE_LOGE("[PixelMap]Convert: ConvertFromYUV: pixel convert in adapter failed.");
1333 delete[] tmpPixels;
1334 tmpPixels = nullptr;
1335 return false;
1336 }
1337 delete[] tmpPixels;
1338 tmpPixels = nullptr;
1339 return true;
1340 }
1341
P010ConvertRGB565(const uint8_t * srcP010,const ImageInfo & srcInfo,void * dstPixels,const ImageInfo & dstInfo)1342 static bool P010ConvertRGB565(const uint8_t* srcP010, const ImageInfo& srcInfo,
1343 void* dstPixels, const ImageInfo& dstInfo)
1344 {
1345 int64_t bufferSize = GetValidBufferSize(dstInfo);
1346 if (bufferSize <= 0) {
1347 return false;
1348 }
1349
1350 std::unique_ptr<uint8_t[]> tmpBuffer =
1351 std::make_unique<uint8_t[]>(bufferSize + RGB565_EXTRA_BYTES); // avoid ffmpeg out-bounds-write
1352 if (tmpBuffer == nullptr) {
1353 IMAGE_LOGE("P010ConvertRGB565: alloc temp buffer failed");
1354 return false;
1355 }
1356 if (!ConvertForFFMPEG(srcP010, srcInfo.pixelFormat, srcInfo, tmpBuffer.get(), dstInfo.pixelFormat)) {
1357 IMAGE_LOGE("P010ConvertRGB565: FFMpeg convert failed");
1358 return false;
1359 }
1360 if (memcpy_s(dstPixels, bufferSize, tmpBuffer.get(), bufferSize) != 0) {
1361 IMAGE_LOGE("P010ConvertRGB565: memcpy_s dstPixels failed!");
1362 return false;
1363 }
1364 return true;
1365 }
1366
ConvertRGBA1010102ToYUV(const void * srcPixels,ImageInfo srcInfo,void * dstPixels,ImageInfo dstInfo)1367 static bool ConvertRGBA1010102ToYUV(const void *srcPixels, ImageInfo srcInfo,
1368 void *dstPixels, ImageInfo dstInfo)
1369 {
1370 ImageInfo copySrcInfo = srcInfo;
1371 copySrcInfo.pixelFormat = PixelFormat::RGBA_U16;
1372 bool cond = ImageUtils::GetAlignedNumber(copySrcInfo.size.width, EVEN_ALIGNMENT) &&
1373 ImageUtils::GetAlignedNumber(copySrcInfo.size.height, EVEN_ALIGNMENT);
1374 CHECK_ERROR_RETURN_RET(!cond, false);
1375
1376 int copySrcLen = PixelMap::GetRGBxByteCount(copySrcInfo);
1377 CHECK_ERROR_RETURN_RET_LOG(copySrcLen <= 0, false, "[PixelMap]Convert: Get copySrc pixels length failed!");
1378 std::unique_ptr<uint8_t[]> copySrcBuffer = std::make_unique<uint8_t[]>(copySrcLen);
1379 CHECK_ERROR_RETURN_RET_LOG(copySrcBuffer == nullptr, false, "[PixelMap]Convert: alloc memory failed!");
1380 uint8_t* copySrcPixels = copySrcBuffer.get();
1381 memset_s(copySrcPixels, copySrcLen, 0, copySrcLen);
1382
1383 Position pos;
1384 cond = PixelConvertAdapter::WritePixelsConvert(srcPixels, PixelMap::GetRGBxRowDataSize(srcInfo), srcInfo,
1385 copySrcPixels, pos, PixelMap::GetRGBxRowDataSize(copySrcInfo), copySrcInfo);
1386 CHECK_ERROR_RETURN_RET_LOG(!cond, false, "[PixelMap]Convert: ConvertToYUV: pixel convert in adapter failed.");
1387
1388 FFMPEG_CONVERT_INFO srcFFmpegInfo = {PixelFormatToAVPixelFormat(PixelFormat::RGBA_F16),
1389 copySrcInfo.size.width, copySrcInfo.size.height, 1};
1390 FFMPEG_CONVERT_INFO dstFFmpegInfo = {PixelFormatToAVPixelFormat(dstInfo.pixelFormat),
1391 dstInfo.size.width, dstInfo.size.height, 1};
1392 cond = FFMpegConvert(copySrcPixels, srcFFmpegInfo, dstPixels, dstFFmpegInfo);
1393 CHECK_ERROR_RETURN_RET_LOG(!cond, false, "[PixelMap]Convert: ffmpeg convert failed!");
1394 return true;
1395 }
1396
YUVConvertRGB(const void * srcPixels,const ImageInfo & srcInfo,void * dstPixels,const ImageInfo & dstInfo,YUVConvertColorSpaceDetails & colorSpaceDetails)1397 static int32_t YUVConvertRGB(const void *srcPixels, const ImageInfo &srcInfo,
1398 void *dstPixels, const ImageInfo &dstInfo, YUVConvertColorSpaceDetails &colorSpaceDetails)
1399 {
1400 FFMPEG_CONVERT_INFO srcFFmpegInfo = {PixelFormatToAVPixelFormat(srcInfo.pixelFormat),
1401 srcInfo.size.width, srcInfo.size.height, 1};
1402 FFMPEG_CONVERT_INFO tmpFFmpegInfo = {PixelFormatToAVPixelFormat(PixelFormat::RGB_888),
1403 srcInfo.size.width, srcInfo.size.height, 1};
1404 int tmpPixelsLen = av_image_get_buffer_size(tmpFFmpegInfo.format, tmpFFmpegInfo.width, tmpFFmpegInfo.height,
1405 tmpFFmpegInfo.alignSize);
1406
1407 CHECK_ERROR_RETURN_RET_LOG((tmpPixelsLen <= 0), -1, "[PixelMap]Convert: Get tmp pixels length failed!");
1408
1409 uint8_t* tmpPixels = new(std::nothrow) uint8_t[tmpPixelsLen];
1410 CHECK_ERROR_RETURN_RET_LOG(tmpPixels == nullptr, -1, "[PixelMap]Convert: alloc memory failed!");
1411
1412 memset_s(tmpPixels, tmpPixelsLen, 0, tmpPixelsLen);
1413 if (!FFMpegConvert(srcPixels, srcFFmpegInfo, (void *)tmpPixels, tmpFFmpegInfo, colorSpaceDetails)) {
1414 IMAGE_LOGE("[PixelMap]Convert: ffmpeg convert failed!");
1415 delete[] tmpPixels;
1416 tmpPixels = nullptr;
1417 return -1;
1418 }
1419
1420 ImageInfo tmpInfo = srcInfo;
1421 tmpInfo.pixelFormat = PixelFormat::RGB_888;
1422 Position pos;
1423 if (!PixelConvertAdapter::WritePixelsConvert(tmpPixels, PixelMap::GetRGBxRowDataSize(tmpInfo), tmpInfo,
1424 dstPixels, pos, PixelMap::GetRGBxRowDataSize(dstInfo), dstInfo)) {
1425 IMAGE_LOGE("[PixelMap]Convert: ConvertFromYUV: pixel convert in adapter failed.");
1426 delete[] tmpPixels;
1427 tmpPixels = nullptr;
1428 return -1;
1429 }
1430
1431 delete[] tmpPixels;
1432 tmpPixels = nullptr;
1433 return PixelMap::GetRGBxByteCount(dstInfo);
1434 }
1435
ConvertFromYUV(const BufferInfo & srcBufferInfo,const int32_t srcLength,BufferInfo & dstBufferInfo)1436 static int32_t ConvertFromYUV(const BufferInfo &srcBufferInfo, const int32_t srcLength, BufferInfo &dstBufferInfo)
1437 {
1438 bool cond = srcBufferInfo.pixels == nullptr || dstBufferInfo.pixels == nullptr || srcLength <= 0;
1439 CHECK_ERROR_RETURN_RET_LOG(cond, CONVERT_ERROR,
1440 "[PixelMap]Convert: src pixels or dst pixels or src pixels length invalid.");
1441
1442 const ImageInfo &srcInfo = srcBufferInfo.imageInfo;
1443 const ImageInfo &dstInfo = dstBufferInfo.imageInfo;
1444 YUVConvertColorSpaceDetails colorSpaceDetails = {
1445 srcBufferInfo.range,
1446 dstBufferInfo.range,
1447 srcBufferInfo.yuvConversion,
1448 dstBufferInfo.yuvConversion
1449 };
1450
1451 cond = (srcInfo.pixelFormat != PixelFormat::NV21 && srcInfo.pixelFormat != PixelFormat::NV12) ||
1452 (dstInfo.pixelFormat == PixelFormat::NV21 || dstInfo.pixelFormat == PixelFormat::NV12);
1453 CHECK_ERROR_RETURN_RET_LOG(cond, CONVERT_ERROR, "[PixelMap]Convert: src or dst pixel format invalid.");
1454
1455 ImageInfo copySrcInfo = srcInfo;
1456 cond = ImageUtils::GetAlignedNumber(copySrcInfo.size.width, EVEN_ALIGNMENT) &&
1457 ImageUtils::GetAlignedNumber(copySrcInfo.size.height, EVEN_ALIGNMENT);
1458 CHECK_ERROR_RETURN_RET(!cond, CONVERT_ERROR);
1459
1460 int32_t copySrcLen = PixelMap::GetAllocatedByteCount(copySrcInfo);
1461 CHECK_ERROR_RETURN_RET_LOG((copySrcLen <= 0), -1, "[PixelMap]Convert: Get copySrcLen pixels length failed!");
1462 std::unique_ptr<uint8_t[]> copySrcBuffer = std::make_unique<uint8_t[]>(copySrcLen);
1463 CHECK_ERROR_RETURN_RET_LOG((copySrcBuffer == nullptr), -1, "[PixelMap]Convert: alloc memory failed!");
1464 uint8_t* copySrcPixels = copySrcBuffer.get();
1465 memset_s(copySrcPixels, copySrcLen, 0, copySrcLen);
1466 cond = memcpy_s(copySrcPixels, copySrcLen, srcBufferInfo.pixels, std::min(srcLength, copySrcLen)) != EOK;
1467 CHECK_ERROR_RETURN_RET(cond, -1);
1468 if ((srcInfo.pixelFormat == PixelFormat::NV12 && dstInfo.pixelFormat == PixelFormat::YCBCR_P010) ||
1469 (srcInfo.pixelFormat == PixelFormat::NV21 && dstInfo.pixelFormat == PixelFormat::YCRCB_P010)) {
1470 return ConvertForFFMPEG(copySrcPixels, PixelFormat::NV12, srcInfo, dstBufferInfo.pixels,
1471 PixelFormat::YCBCR_P010) == true ? PixelMap::GetYUVByteCount(dstInfo) : -1;
1472 }
1473 if ((srcInfo.pixelFormat == PixelFormat::NV12 && dstInfo.pixelFormat == PixelFormat::YCRCB_P010) ||
1474 (srcInfo.pixelFormat == PixelFormat::NV21 && dstInfo.pixelFormat == PixelFormat::YCBCR_P010)) {
1475 return ConvertForFFMPEG(copySrcPixels, PixelFormat::NV21, srcInfo, dstBufferInfo.pixels,
1476 PixelFormat::YCBCR_P010) == true ? PixelMap::GetYUVByteCount(dstInfo) : -1;
1477 }
1478
1479 return YUVConvertRGB(copySrcPixels, srcInfo, dstBufferInfo.pixels, dstInfo, colorSpaceDetails);
1480 }
1481
ConvertFromP010(const void * srcPixels,const int32_t srcLength,const ImageInfo & srcInfo,void * dstPixels,const ImageInfo & dstInfo)1482 static int32_t ConvertFromP010(const void *srcPixels, const int32_t srcLength, const ImageInfo &srcInfo,
1483 void *dstPixels, const ImageInfo &dstInfo)
1484 {
1485 bool cond = srcPixels == nullptr || dstPixels == nullptr || srcLength <= 0;
1486 CHECK_ERROR_RETURN_RET_LOG(cond, CONVERT_ERROR,
1487 "[PixelMap]Convert: src pixels or dst pixels or src pixels length invalid.");
1488
1489 cond = (srcInfo.pixelFormat != PixelFormat::YCRCB_P010 && srcInfo.pixelFormat != PixelFormat::YCBCR_P010) ||
1490 IsYUVP010Format(dstInfo.pixelFormat);
1491 CHECK_ERROR_RETURN_RET_LOG(cond, CONVERT_ERROR, "[PixelMap]Convert: src or dst pixel format invalid.");
1492
1493 ImageInfo copySrcInfo = srcInfo;
1494 cond = ImageUtils::GetAlignedNumber(copySrcInfo.size.width, EVEN_ALIGNMENT) &&
1495 ImageUtils::GetAlignedNumber(copySrcInfo.size.height, EVEN_ALIGNMENT);
1496 CHECK_ERROR_RETURN_RET(!cond, CONVERT_ERROR);
1497
1498 int32_t srcP010Length = PixelMap::GetAllocatedByteCount(copySrcInfo);
1499 std::unique_ptr<uint8_t[]> srcP010Buffer = std::make_unique<uint8_t[]>(srcP010Length);
1500 CHECK_ERROR_RETURN_RET_LOG(srcP010Buffer == nullptr, CONVERT_ERROR, "[PixelMap]Convert: alloc memory failed!");
1501
1502 uint8_t* srcP010 = srcP010Buffer.get();
1503 memset_s(srcP010, srcP010Length, 0, srcP010Length);
1504 if (srcInfo.pixelFormat == PixelFormat::YCRCB_P010) {
1505 NV12P010ToNV21P010((uint16_t *)srcPixels, srcInfo, (uint16_t *)srcP010);
1506 } else {
1507 CHECK_ERROR_RETURN_RET(memcpy_s(srcP010, srcP010Length, srcPixels, srcLength) != 0, CONVERT_ERROR);
1508 }
1509 if (dstInfo.pixelFormat == PixelFormat::RGBA_1010102) {
1510 if (P010ConvertRGBA1010102(srcP010, srcInfo, dstPixels, dstInfo)) {
1511 return PixelMap::GetRGBxByteCount(dstInfo);
1512 }
1513 return -1;
1514 } else if (dstInfo.pixelFormat == PixelFormat::RGB_565) {
1515 if (P010ConvertRGB565(srcP010, srcInfo, dstPixels, dstInfo)) {
1516 return PixelMap::GetRGBxByteCount(dstInfo);
1517 }
1518 return -1;
1519 } else {
1520 if (ConvertForFFMPEG(srcP010, srcInfo.pixelFormat, srcInfo, dstPixels, dstInfo.pixelFormat)) {
1521 return PixelMap::GetRGBxByteCount(dstInfo);
1522 }
1523 return -1;
1524 }
1525 }
1526
RGBConvertYUV(const void * srcPixels,const ImageInfo & srcInfo,void * dstPixels,const ImageInfo & dstInfo)1527 static int32_t RGBConvertYUV(const void *srcPixels, const ImageInfo &srcInfo,
1528 void *dstPixels, const ImageInfo &dstInfo)
1529 {
1530 ImageInfo tmpInfo = srcInfo;
1531 tmpInfo.pixelFormat = PixelFormat::RGB_888;
1532 uint32_t tmpWidth = (static_cast<uint32_t>(tmpInfo.size.width) & 1) == 1 ?
1533 static_cast<uint32_t>(tmpInfo.size.width) + 1 : static_cast<uint32_t>(tmpInfo.size.width);
1534 size_t tmpPixelsLen = static_cast<size_t>(tmpWidth) * static_cast<size_t>(tmpInfo.size.height) *
1535 static_cast<size_t>(ImageUtils::GetPixelBytes(tmpInfo.pixelFormat));
1536 CHECK_ERROR_RETURN_RET_LOG(tmpPixelsLen == 0 || tmpPixelsLen > INT32_MAX, CONVERT_ERROR,
1537 "[PixelMap]Convert: Get tmp pixels length failed!");
1538 uint8_t* tmpPixels = new(std::nothrow) uint8_t[tmpPixelsLen];
1539
1540 CHECK_ERROR_RETURN_RET_LOG((tmpPixels == nullptr), -1, "[PixelMap]Convert: alloc memory failed!");
1541
1542 memset_s(tmpPixels, tmpPixelsLen, 0, tmpPixelsLen);
1543 Position pos;
1544 if (!PixelConvertAdapter::WritePixelsConvert(srcPixels, PixelMap::GetRGBxRowDataSize(srcInfo), srcInfo,
1545 tmpPixels, pos, PixelMap::GetRGBxRowDataSize(tmpInfo), tmpInfo)) {
1546 IMAGE_LOGE("[PixelMap]Convert: ConvertToYUV: pixel convert in adapter failed.");
1547 delete[] tmpPixels;
1548 tmpPixels = nullptr;
1549 return -1;
1550 }
1551 FFMPEG_CONVERT_INFO srcFFmpegInfo = {PixelFormatToAVPixelFormat(PixelFormat::RGB_888),
1552 tmpInfo.size.width, tmpInfo.size.height, 1};
1553 FFMPEG_CONVERT_INFO dstFFmpegInfo = {PixelFormatToAVPixelFormat(dstInfo.pixelFormat),
1554 dstInfo.size.width, dstInfo.size.height, 1};
1555 if (!FFMpegConvert(tmpPixels, srcFFmpegInfo, (void *)dstPixels, dstFFmpegInfo)) {
1556 IMAGE_LOGE("[PixelMap]Convert: ffmpeg convert failed!");
1557 delete[] tmpPixels;
1558 tmpPixels = nullptr;
1559 return -1;
1560 }
1561 delete[] tmpPixels;
1562 tmpPixels = nullptr;
1563 return av_image_get_buffer_size(dstFFmpegInfo.format, dstFFmpegInfo.width, dstFFmpegInfo.height,
1564 dstFFmpegInfo.alignSize);
1565 }
1566
ConvertToYUV(const void * srcPixels,const int32_t srcLength,const ImageInfo & srcInfo,void * dstPixels,const ImageInfo & dstInfo)1567 static int32_t ConvertToYUV(const void *srcPixels, const int32_t srcLength, const ImageInfo &srcInfo,
1568 void *dstPixels, const ImageInfo &dstInfo)
1569 {
1570 bool cond = srcPixels == nullptr || dstPixels == nullptr || srcLength <= 0;
1571 CHECK_ERROR_RETURN_RET_LOG(cond, CONVERT_ERROR,
1572 "[PixelMap]Convert: src pixels or dst pixels or src pixel length invalid");
1573
1574 cond = (srcInfo.pixelFormat == PixelFormat::NV21 || srcInfo.pixelFormat == PixelFormat::NV12) ||
1575 (dstInfo.pixelFormat != PixelFormat::NV21 && dstInfo.pixelFormat != PixelFormat::NV12);
1576 CHECK_ERROR_RETURN_RET_LOG(cond, CONVERT_ERROR, "[PixelMap]Convert: src or dst pixel format invalid.");
1577
1578 ImageInfo copySrcInfo = srcInfo;
1579 cond = ImageUtils::GetAlignedNumber(copySrcInfo.size.width, EVEN_ALIGNMENT) &&
1580 ImageUtils::GetAlignedNumber(copySrcInfo.size.height, EVEN_ALIGNMENT);
1581 CHECK_ERROR_RETURN_RET(!cond, CONVERT_ERROR);
1582
1583 int32_t copySrcLen = PixelMap::GetAllocatedByteCount(copySrcInfo);
1584 CHECK_ERROR_RETURN_RET_LOG((copySrcLen <= 0), -1, "[PixelMap]Convert: Get copySrcLen pixels length failed!");
1585 std::unique_ptr<uint8_t[]> copySrcBuffer = std::make_unique<uint8_t[]>(copySrcLen);
1586 CHECK_ERROR_RETURN_RET_LOG((copySrcBuffer == nullptr), -1, "[PixelMap]Convert: alloc memory failed!");
1587 uint8_t* copySrcPixels = copySrcBuffer.get();
1588 memset_s(copySrcPixels, copySrcLen, 0, copySrcLen);
1589 cond = memcpy_s(copySrcPixels, copySrcLen, srcPixels, std::min(srcLength, copySrcLen)) != EOK;
1590 CHECK_ERROR_RETURN_RET(cond, -1);
1591 if ((srcInfo.pixelFormat == PixelFormat::YCBCR_P010 && dstInfo.pixelFormat == PixelFormat::NV12) ||
1592 (srcInfo.pixelFormat == PixelFormat::YCRCB_P010 && dstInfo.pixelFormat == PixelFormat::NV21)) {
1593 return ConvertForFFMPEG(copySrcPixels, PixelFormat::YCBCR_P010, srcInfo, dstPixels,
1594 PixelFormat::NV12) == true ? PixelMap::GetYUVByteCount(dstInfo) : -1;
1595 }
1596 if ((srcInfo.pixelFormat == PixelFormat::YCBCR_P010 && dstInfo.pixelFormat == PixelFormat::NV21) ||
1597 (srcInfo.pixelFormat == PixelFormat::YCRCB_P010 && dstInfo.pixelFormat == PixelFormat::NV12)) {
1598 return ConvertForFFMPEG(copySrcPixels, PixelFormat::YCBCR_P010, srcInfo, dstPixels,
1599 PixelFormat::NV21) == true ? PixelMap::GetYUVByteCount(dstInfo) : -1;
1600 }
1601 return RGBConvertYUV(copySrcPixels, srcInfo, dstPixels, dstInfo);
1602 }
1603
ConvertToP010(const BufferInfo & src,BufferInfo & dst)1604 static int32_t ConvertToP010(const BufferInfo &src, BufferInfo &dst)
1605 {
1606 const void *srcPixels = src.pixels;
1607 const int32_t srcLength = src.length;
1608 const ImageInfo &srcInfo = src.imageInfo;
1609 void *dstPixels = dst.pixels;
1610 const ImageInfo &dstInfo = dst.imageInfo;
1611
1612 CHECK_ERROR_RETURN_RET_LOG((srcPixels == nullptr || dstPixels == nullptr || srcLength <= 0), -1,
1613 "[PixelMap]Convert: src pixels or dst pixels or src pixel length invalid");
1614 CHECK_ERROR_RETURN_RET_LOG((IsYUVP010Format(srcInfo.pixelFormat) ||
1615 (dstInfo.pixelFormat != PixelFormat::YCRCB_P010 && dstInfo.pixelFormat != PixelFormat::YCBCR_P010)),
1616 -1, "[PixelMap]Convert: src or dst pixel format invalid.");
1617 int32_t dstLength = PixelMap::GetYUVByteCount(dstInfo);
1618
1619 CHECK_ERROR_RETURN_RET_LOG(dstLength <= 0, -1, "[PixelMap]Convert: Get dstP010 length failed!");
1620
1621 std::unique_ptr<uint8_t[]> dstP010Buffer = std::make_unique<uint8_t[]>(dstLength);
1622 CHECK_ERROR_RETURN_RET_LOG(dstP010Buffer == nullptr, CONVERT_ERROR, "[PixelMap]Convert: alloc memory failed!");
1623 uint8_t* dstP010 = dstP010Buffer.get();
1624 memset_s(dstP010, dstLength, 0, dstLength);
1625
1626 bool cond = false;
1627 if (srcInfo.pixelFormat == PixelFormat::RGBA_1010102) {
1628 cond = ConvertRGBA1010102ToYUV(srcPixels, srcInfo, dstP010, dstInfo);
1629 CHECK_ERROR_RETURN_RET(!cond, CONVERT_ERROR);
1630 } else {
1631 ImageInfo copySrcInfo = srcInfo;
1632 cond = ImageUtils::GetAlignedNumber(copySrcInfo.size.width, EVEN_ALIGNMENT) &&
1633 ImageUtils::GetAlignedNumber(copySrcInfo.size.height, EVEN_ALIGNMENT);
1634 CHECK_ERROR_RETURN_RET(!cond, CONVERT_ERROR);
1635 int32_t copySrcLength = PixelMap::GetAllocatedByteCount(copySrcInfo);
1636 std::unique_ptr<uint8_t[]> copySrcBuffer = std::make_unique<uint8_t[]>(copySrcLength);
1637 cond = copySrcBuffer == nullptr || EOK != memcpy_s(copySrcBuffer.get(), copySrcLength, srcPixels, srcLength);
1638 CHECK_ERROR_RETURN_RET_LOG(cond, CONVERT_ERROR, "alloc memory or memcpy_s failed!");
1639 cond = ConvertForFFMPEG(copySrcBuffer.get(), srcInfo.pixelFormat, srcInfo, dstP010, dstInfo.pixelFormat);
1640 CHECK_ERROR_RETURN_RET(!cond, CONVERT_ERROR);
1641 }
1642 if (dstInfo.pixelFormat == PixelFormat::YCRCB_P010) {
1643 NV12P010ToNV21P010((uint16_t *)dstP010, dstInfo, (uint16_t *)dstPixels);
1644 } else {
1645 CHECK_ERROR_RETURN_RET(memcpy_s(dstPixels, dst.length, dstP010, dstLength) != 0, CONVERT_ERROR);
1646 }
1647 return dstLength;
1648 }
1649
YUVConvert(const BufferInfo & src,const int32_t srcLength,BufferInfo & dst)1650 static int32_t YUVConvert(const BufferInfo &src, const int32_t srcLength, BufferInfo &dst)
1651 {
1652 ImageInfo srcInfo = src.imageInfo;
1653 ImageInfo dstInfo = dst.imageInfo;
1654 const void *srcPixels = src.pixels;
1655 void* dstPixels = dst.pixels;
1656 if (srcInfo.pixelFormat == dstInfo.pixelFormat &&
1657 srcInfo.size.width == dstInfo.size.width && srcInfo.size.height == dstInfo.size.height) {
1658 IMAGE_LOGE("src pixel format is equal dst pixel format. no need to convert.");
1659 int32_t minLength = static_cast<int32_t>(dst.length) < srcLength ?
1660 static_cast<int32_t>(dst.length) : srcLength;
1661 auto result = memcpy_s(dstPixels, dst.length, srcPixels, minLength);
1662 return result == 0 ? minLength : -1;
1663 }
1664 if (IsYUVP010Format(srcInfo.pixelFormat) && IsYUVP010Format(dstInfo.pixelFormat)) {
1665 if (srcInfo.size.width == dstInfo.size.width && srcInfo.size.height == dstInfo.size.height) {
1666 return NV12P010ToNV21P010((uint16_t *)srcPixels, dstInfo, (uint16_t *)dstPixels) == true ?
1667 srcLength : -1;
1668 }
1669 }
1670 ImageInfo copySrcInfo = srcInfo;
1671 bool cond = ImageUtils::GetAlignedNumber(copySrcInfo.size.width, EVEN_ALIGNMENT) &&
1672 ImageUtils::GetAlignedNumber(copySrcInfo.size.height, EVEN_ALIGNMENT);
1673 CHECK_ERROR_RETURN_RET(!cond, CONVERT_ERROR);
1674
1675 int32_t copySrcLen = PixelMap::GetAllocatedByteCount(copySrcInfo);
1676 CHECK_ERROR_RETURN_RET_LOG((copySrcLen <= 0), -1, "[PixelMap]Convert: Get copySrcLen pixels length failed!");
1677 std::unique_ptr<uint8_t[]> copySrcBuffer = std::make_unique<uint8_t[]>(copySrcLen);
1678 CHECK_ERROR_RETURN_RET_LOG((copySrcBuffer == nullptr), -1, "[PixelMap]Convert: alloc memory failed!");
1679 uint8_t* copySrcPixels = copySrcBuffer.get();
1680 memset_s(copySrcPixels, copySrcLen, 0, copySrcLen);
1681 cond = memcpy_s(copySrcPixels, copySrcLen, srcPixels, std::min(srcLength, copySrcLen)) != EOK;
1682 CHECK_ERROR_RETURN_RET(cond, -1);
1683 FFMPEG_CONVERT_INFO srcFFmpegInfo = {PixelFormatToAVPixelFormat(srcInfo.pixelFormat), srcInfo.size.width,
1684 srcInfo.size.height, 1};
1685 FFMPEG_CONVERT_INFO dstFFmpegInfo = {PixelFormatToAVPixelFormat(dstInfo.pixelFormat), dstInfo.size.width,
1686 dstInfo.size.height, 1};
1687
1688 CHECK_ERROR_RETURN_RET_LOG(!FFMpegConvert(copySrcPixels, srcFFmpegInfo, dstPixels, dstFFmpegInfo),
1689 -1, "[PixelMap]Convert: ffmpeg convert failed!");
1690
1691 return av_image_get_buffer_size(dstFFmpegInfo.format, dstFFmpegInfo.width, dstFFmpegInfo.height,
1692 dstFFmpegInfo.alignSize);
1693 }
1694
IsInterYUVConvert(PixelFormat srcPixelFormat,PixelFormat dstPixelFormat)1695 static bool IsInterYUVConvert(PixelFormat srcPixelFormat, PixelFormat dstPixelFormat)
1696 {
1697 return (srcPixelFormat == PixelFormat::NV12 || srcPixelFormat == PixelFormat::NV21) &&
1698 (dstPixelFormat == PixelFormat::NV12 || dstPixelFormat == PixelFormat::NV21);
1699 }
1700
PixelsConvert(const BufferInfo & src,BufferInfo & dst,bool useDMA)1701 int32_t PixelConvert::PixelsConvert(const BufferInfo &src, BufferInfo &dst, bool useDMA)
1702 {
1703 CHECK_ERROR_RETURN_RET_LOG(!(IsValidBufferInfo(src) && IsValidBufferInfo(dst)), CONVERT_ERROR,
1704 "[PixelMap]Convert: pixels or image info or row stride or src pixels length invalid.");
1705 return ConvertAndCollapseByFFMpeg(src.pixels, src.imageInfo, dst.pixels, dst.imageInfo, useDMA) ?
1706 PixelMap::GetRGBxByteCount(dst.imageInfo) : -1;
1707 }
1708
CopySrcBufferAndConvert(const BufferInfo & src,BufferInfo & dst,int32_t srcLength,bool useDMA)1709 int32_t PixelConvert::CopySrcBufferAndConvert(const BufferInfo &src, BufferInfo &dst, int32_t srcLength, bool useDMA)
1710 {
1711 bool cond = src.pixels == nullptr || dst.pixels == nullptr || srcLength <= 0;
1712 CHECK_ERROR_RETURN_RET_LOG(cond, CONVERT_ERROR,
1713 "[PixelMap]Convert: src pixels or dst pixels or src pixels length invalid.");
1714
1715 ImageInfo copySrcInfo = src.imageInfo;
1716 cond = ImageUtils::GetAlignedNumber(copySrcInfo.size.width, EVEN_ALIGNMENT) &&
1717 ImageUtils::GetAlignedNumber(copySrcInfo.size.height, EVEN_ALIGNMENT);
1718 CHECK_ERROR_RETURN_RET(!cond, CONVERT_ERROR);
1719 int32_t copySrcLen = PixelMap::GetAllocatedByteCount(copySrcInfo);
1720 std::unique_ptr<uint8_t[]> copySrcBuffer = std::make_unique<uint8_t[]>(copySrcLen);
1721 CHECK_ERROR_RETURN_RET_LOG(copySrcBuffer == nullptr, CONVERT_ERROR, "[PixelMap]Convert: alloc memory failed!");
1722
1723 uint8_t* copySrcPixels = copySrcBuffer.get();
1724 memset_s(copySrcPixels, copySrcLen, 0, copySrcLen);
1725 CHECK_ERROR_RETURN_RET(memcpy_s(copySrcPixels, copySrcLen, src.pixels, srcLength) != 0, CONVERT_ERROR);
1726 return ConvertAndCollapseByFFMpeg(copySrcPixels, src.imageInfo, dst.pixels, dst.imageInfo, useDMA) ?
1727 PixelMap::GetRGBxByteCount(dst.imageInfo) : CONVERT_ERROR;
1728 }
1729
PixelsConvert(const BufferInfo & src,BufferInfo & dst,int32_t srcLength,bool useDMA)1730 int32_t PixelConvert::PixelsConvert(const BufferInfo &src, BufferInfo &dst, int32_t srcLength, bool useDMA)
1731 {
1732 bool cond = IsValidBufferInfo(src) && IsValidBufferInfo(dst) && srcLength > 0;
1733 CHECK_ERROR_RETURN_RET_LOG(!cond, CONVERT_ERROR,
1734 "[PixelMap]Convert: pixels or image info or row stride or src pixels length invalid.");
1735
1736 if (dst.imageInfo.pixelFormat == PixelFormat::ARGB_8888) {
1737 if (useDMA || (src.imageInfo.size.width % EVEN_ALIGNMENT == 0 &&
1738 src.imageInfo.size.height % EVEN_ALIGNMENT == 0)) {
1739 return ConvertAndCollapseByFFMpeg(src.pixels, src.imageInfo, dst.pixels, dst.imageInfo, useDMA) ?
1740 PixelMap::GetRGBxByteCount(dst.imageInfo) : CONVERT_ERROR;
1741 } else {
1742 return CopySrcBufferAndConvert(src, dst, srcLength, useDMA);
1743 }
1744 }
1745 if (IsInterYUVConvert(src.imageInfo.pixelFormat, dst.imageInfo.pixelFormat) ||
1746 (IsYUVP010Format(src.imageInfo.pixelFormat) && IsYUVP010Format(dst.imageInfo.pixelFormat))) {
1747 return YUVConvert(src, srcLength, dst);
1748 }
1749 if (src.imageInfo.pixelFormat == PixelFormat::NV12 || src.imageInfo.pixelFormat == PixelFormat::NV21) {
1750 return ConvertFromYUV(src, srcLength, dst);
1751 } else if (dst.imageInfo.pixelFormat == PixelFormat::NV12 || dst.imageInfo.pixelFormat == PixelFormat::NV21) {
1752 return ConvertToYUV(src.pixels, srcLength, src.imageInfo, dst.pixels, dst.imageInfo);
1753 } else if (IsYUVP010Format(src.imageInfo.pixelFormat)) {
1754 return ConvertFromP010(src.pixels, srcLength, src.imageInfo, dst.pixels, dst.imageInfo);
1755 } else if (IsYUVP010Format(dst.imageInfo.pixelFormat)) {
1756 return ConvertToP010(src, dst);
1757 }
1758
1759 Position pos;
1760 IMAGE_LOGI("%{public}s: colorLength = %{public}d, width = %{public}d, height = %{public}d,", __func__,
1761 srcLength, src.imageInfo.size.width, src.imageInfo.size.height);
1762 cond = PixelConvertAdapter::WritePixelsConvert(src.pixels,
1763 src.rowStride == 0 ? PixelMap::GetRGBxRowDataSize(src.imageInfo) : src.rowStride, src.imageInfo,
1764 dst.pixels, pos, useDMA ? dst.rowStride : PixelMap::GetRGBxRowDataSize(dst.imageInfo), dst.imageInfo);
1765 CHECK_ERROR_RETURN_RET_LOG(!cond, CONVERT_ERROR,
1766 "[PixelMap]Convert: PixelsConvert: pixel convert in adapter failed.");
1767
1768 return PixelMap::GetRGBxByteCount(dst.imageInfo);
1769 }
1770
PixelConvert(ProcFuncType funcPtr,ProcFuncExtension extension,bool isNeedConvert)1771 PixelConvert::PixelConvert(ProcFuncType funcPtr, ProcFuncExtension extension, bool isNeedConvert)
1772 : procFunc_(funcPtr), procFuncExtension_(extension), isNeedConvert_(isNeedConvert)
1773 {}
1774
1775 // caller need setting the correct pixelFormat and alphaType
Create(const ImageInfo & srcInfo,const ImageInfo & dstInfo)1776 std::unique_ptr<PixelConvert> PixelConvert::Create(const ImageInfo &srcInfo, const ImageInfo &dstInfo)
1777 {
1778 if (srcInfo.pixelFormat == PixelFormat::UNKNOWN || dstInfo.pixelFormat == PixelFormat::UNKNOWN) {
1779 IMAGE_LOGE("source or destination pixel format unknown");
1780 return nullptr;
1781 }
1782 uint32_t srcFormat = static_cast<uint32_t>(srcInfo.pixelFormat);
1783 uint32_t dstFormat = static_cast<uint32_t>(dstInfo.pixelFormat);
1784 ProcFuncType funcPtr = GetProcFuncType(srcFormat, dstFormat);
1785 if (funcPtr == nullptr) {
1786 IMAGE_LOGE("not found convert function. pixelFormat %{public}u -> %{public}u", srcFormat, dstFormat);
1787 return nullptr;
1788 }
1789 ProcFuncExtension extension;
1790 extension.alphaConvertType = GetAlphaConvertType(srcInfo.alphaType, dstInfo.alphaType);
1791 bool isNeedConvert = true;
1792 if ((srcInfo.pixelFormat == dstInfo.pixelFormat) && (extension.alphaConvertType == AlphaConvertType::NO_CONVERT)) {
1793 isNeedConvert = false;
1794 }
1795 return make_unique<PixelConvert>(funcPtr, extension, isNeedConvert);
1796 }
1797
GetAlphaConvertType(const AlphaType & srcType,const AlphaType & dstType)1798 AlphaConvertType PixelConvert::GetAlphaConvertType(const AlphaType &srcType, const AlphaType &dstType)
1799 {
1800 if (srcType == AlphaType::IMAGE_ALPHA_TYPE_UNKNOWN || dstType == AlphaType::IMAGE_ALPHA_TYPE_UNKNOWN) {
1801 IMAGE_LOGD("source or destination alpha type unknown");
1802 return AlphaConvertType::NO_CONVERT;
1803 }
1804 if ((srcType == AlphaType::IMAGE_ALPHA_TYPE_PREMUL) && (dstType == AlphaType::IMAGE_ALPHA_TYPE_UNPREMUL)) {
1805 return AlphaConvertType::PREMUL_CONVERT_UNPREMUL;
1806 }
1807 if ((srcType == AlphaType::IMAGE_ALPHA_TYPE_PREMUL) && (dstType == AlphaType::IMAGE_ALPHA_TYPE_OPAQUE)) {
1808 return AlphaConvertType::PREMUL_CONVERT_OPAQUE;
1809 }
1810 if ((srcType == AlphaType::IMAGE_ALPHA_TYPE_UNPREMUL) && (dstType == AlphaType::IMAGE_ALPHA_TYPE_PREMUL)) {
1811 return AlphaConvertType::UNPREMUL_CONVERT_PREMUL;
1812 }
1813 if ((srcType == AlphaType::IMAGE_ALPHA_TYPE_UNPREMUL) && (dstType == AlphaType::IMAGE_ALPHA_TYPE_OPAQUE)) {
1814 return AlphaConvertType::UNPREMUL_CONVERT_OPAQUE;
1815 }
1816 return AlphaConvertType::NO_CONVERT;
1817 }
1818
IsValidRowStride(int32_t rowStride,const ImageInfo & imageInfo)1819 bool PixelConvert::IsValidRowStride(int32_t rowStride, const ImageInfo &imageInfo)
1820 {
1821 if (imageInfo.pixelFormat == PixelFormat::YCBCR_P010 ||
1822 imageInfo.pixelFormat == PixelFormat::YCRCB_P010) {
1823 return rowStride == 0 || rowStride >= imageInfo.size.width * YUV420_P010_BYTES;
1824 }
1825 return rowStride == 0 || rowStride >= imageInfo.size.width * ImageUtils::GetPixelBytes(imageInfo.pixelFormat);
1826 }
1827
IsValidBufferInfo(const BufferInfo & bufferInfo)1828 bool PixelConvert::IsValidBufferInfo(const BufferInfo &bufferInfo)
1829 {
1830 return bufferInfo.pixels != nullptr && IsValidRowStride(bufferInfo.rowStride, bufferInfo.imageInfo);
1831 }
1832
Convert(void * destinationPixels,const uint8_t * sourcePixels,uint32_t sourcePixelsNum)1833 void PixelConvert::Convert(void *destinationPixels, const uint8_t *sourcePixels, uint32_t sourcePixelsNum)
1834 {
1835 if ((destinationPixels == nullptr) || (sourcePixels == nullptr)) {
1836 IMAGE_LOGE("destinationPixel or sourcePixel is null");
1837 return;
1838 }
1839 if (!isNeedConvert_) {
1840 IMAGE_LOGD("no need convert");
1841 return;
1842 }
1843 procFunc_(destinationPixels, sourcePixels, sourcePixelsNum, procFuncExtension_);
1844 }
1845
1846 #if !defined(IOS_PLATFORM) && !defined(ANDROID_PLATFORM)
UnpackBytes(uint8_t a,uint8_t b,uint8_t c,uint8_t d)1847 static unsigned int UnpackBytes(uint8_t a, uint8_t b, uint8_t c, uint8_t d)
1848 {
1849 return static_cast<unsigned int>(a) +
1850 (static_cast<unsigned int>(b) << UNPACK_SHIFT_1) +
1851 (static_cast<unsigned int>(c) << UNPACK_SHIFT_2) +
1852 (static_cast<unsigned int>(d) << UNPACK_SHIFT_3);
1853 }
1854
CheckAstcHead(uint8_t * astcBuf,unsigned int & blockX,unsigned int & blockY,uint32_t astcBufSize)1855 static bool CheckAstcHead(uint8_t *astcBuf, unsigned int &blockX, unsigned int &blockY, uint32_t astcBufSize)
1856 {
1857 CHECK_ERROR_RETURN_RET_LOG(astcBufSize < ASTC_UNIT_BYTES + ASTC_UNIT_BYTES, false,
1858 "DecAstc astcBufSize: %{public}d is invalid", astcBufSize);
1859
1860 unsigned int magicVal = UnpackBytes(astcBuf[BYTE_POS_0], astcBuf[BYTE_POS_1], astcBuf[BYTE_POS_2],
1861 astcBuf[BYTE_POS_3]);
1862 CHECK_ERROR_RETURN_RET_LOG(magicVal != ASTC_MAGIC_ID, false, "DecAstc magicVal: %{public}d is invalid", magicVal);
1863 blockX = static_cast<unsigned int>(astcBuf[BYTE_POS_4]);
1864 blockY = static_cast<unsigned int>(astcBuf[BYTE_POS_5]);
1865 CHECK_ERROR_RETURN_RET_LOG(blockX != ASTC_BLOCK_SIZE_4 || blockY != blockX, false,
1866 "DecAstc blockX: %{public}d blockY: %{public}d not 4x4 or w!=h", blockX, blockY);
1867 CHECK_ERROR_RETURN_RET_LOG(astcBuf[BYTE_POS_6] != 1, false, "DecAstc astc buffer is not 1d");
1868
1869 // dimZ = 1
1870 bool cond = UnpackBytes(astcBuf[BYTE_POS_13], astcBuf[BYTE_POS_14], astcBuf[BYTE_POS_15], 0) != 1;
1871 CHECK_ERROR_RETURN_RET_LOG(cond, false, "DecAstc astc buffer is not 1d");
1872
1873 CHECK_ERROR_RETURN_RET(blockX == 0 || blockY == 0, false);
1874 return true;
1875 }
1876
InitAstcOutImage(astcenc_image & outImage,uint8_t * astcBuf,uint8_t * recRgba,uint32_t stride)1877 static bool InitAstcOutImage(astcenc_image &outImage, uint8_t *astcBuf, uint8_t *recRgba, uint32_t stride)
1878 {
1879 outImage.dim_x = UnpackBytes(astcBuf[BYTE_POS_7], astcBuf[BYTE_POS_8], astcBuf[BYTE_POS_9], 0);
1880 outImage.dim_y = UnpackBytes(astcBuf[BYTE_POS_10], astcBuf[BYTE_POS_11], astcBuf[BYTE_POS_12], 0);
1881 outImage.dim_z = 1;
1882 outImage.dim_stride = stride;
1883 outImage.data_type = ASTCENC_TYPE_U8;
1884 outImage.data = new void* [1];
1885 CHECK_ERROR_RETURN_RET_LOG(outImage.data == nullptr, false, "DecAstc outImage.data is null");
1886 outImage.data[0] = recRgba;
1887 return true;
1888 }
1889
FreeAstcMem(astcenc_image & outImage,astcenc_context * codec_context)1890 static void FreeAstcMem(astcenc_image &outImage, astcenc_context *codec_context)
1891 {
1892 if (outImage.data != nullptr) {
1893 delete[] outImage.data;
1894 }
1895 if (codec_context != nullptr) {
1896 astcenc_context_free(codec_context);
1897 }
1898 }
1899
DecAstc(uint8_t * recRgba,uint32_t stride,AstcInfo astcInfo)1900 static bool DecAstc(uint8_t *recRgba, uint32_t stride, AstcInfo astcInfo)
1901 {
1902 unsigned int blockX = 0;
1903 unsigned int blockY = 0;
1904
1905 bool cond = CheckAstcHead(astcInfo.astcBuf, blockX, blockY, astcInfo.astcBufSize);
1906 CHECK_ERROR_RETURN_RET(!cond, false);
1907
1908 unsigned int xblocks = (astcInfo.dimX + blockX - 1) / blockX;
1909 unsigned int yblocks = (astcInfo.dimY + blockY - 1) / blockY;
1910 size_t dataSize = xblocks * yblocks * ASTC_UNIT_BYTES;
1911 CHECK_ERROR_RETURN_RET_LOG(dataSize + ASTC_UNIT_BYTES > astcInfo.astcBufSize, false,
1912 "DecAstc astc buffer is invalid, dataSize: %{public}zu, astcBufSize: %{public}d",
1913 dataSize, astcInfo.astcBufSize);
1914
1915 astcenc_config config = {};
1916 astcenc_error status = astcenc_config_init(ASTCENC_PRF_LDR_SRGB, blockX, blockY, 1, 0, 0x10, &config);
1917 CHECK_ERROR_RETURN_RET_LOG(status != ASTCENC_SUCCESS, false,
1918 "DecAstc init config failed with %{public}s", astcenc_get_error_string(status));
1919 config.flags = 0x12;
1920 astcenc_context *codec_context = nullptr;
1921 status = astcenc_context_alloc(&config, 1, &codec_context);
1922
1923 CHECK_ERROR_RETURN_RET_LOG(status != ASTCENC_SUCCESS, false,
1924 "DecAstc codec context alloc failed: %{public}s", astcenc_get_error_string(status));
1925 astcenc_image outImage;
1926 if (!InitAstcOutImage(outImage, astcInfo.astcBuf, recRgba, stride)) {
1927 FreeAstcMem(outImage, codec_context);
1928 return false;
1929 }
1930
1931 astcenc_swizzle swz_decode {ASTCENC_SWZ_R, ASTCENC_SWZ_G, ASTCENC_SWZ_B, ASTCENC_SWZ_A};
1932 status = astcenc_decompress_image(codec_context, astcInfo.astcBuf + ASTC_UNIT_BYTES, dataSize, &outImage,
1933 &swz_decode, 0);
1934 if (status != ASTCENC_SUCCESS) {
1935 IMAGE_LOGE("DecAstc codec decompress failed: %{public}s", astcenc_get_error_string(status));
1936 FreeAstcMem(outImage, codec_context);
1937 return false;
1938 }
1939 FreeAstcMem(outImage, codec_context);
1940 return true;
1941 }
1942
CheckInputValid(AstcInfo & astcInfo,PixelFormat destFormat)1943 static bool CheckInputValid(AstcInfo &astcInfo, PixelFormat destFormat)
1944 {
1945 bool isInvalidInput = (astcInfo.astcBufSize < ASTC_UNIT_BYTES || astcInfo.astcBuf == nullptr ||
1946 astcInfo.format != PixelFormat::ASTC_4x4 || destFormat != PixelFormat::RGBA_8888);
1947 if (isInvalidInput) {
1948 IMAGE_LOGE("DecAstc input astcBuf is null or src is not astc_4x4 or dst is not rgba_8888");
1949 return false;
1950 }
1951 unsigned int dimX = UnpackBytes(astcInfo.astcBuf[BYTE_POS_7], astcInfo.astcBuf[BYTE_POS_8],
1952 astcInfo.astcBuf[BYTE_POS_9], 0);
1953 unsigned int dimY = UnpackBytes(astcInfo.astcBuf[BYTE_POS_10], astcInfo.astcBuf[BYTE_POS_11],
1954 astcInfo.astcBuf[BYTE_POS_12], 0);
1955 bool cond = dimX > ASTC_DIM_MAX || dimY > ASTC_DIM_MAX ||
1956 dimX != static_cast<unsigned int>(astcInfo.astcSize.width) ||
1957 dimY != static_cast<unsigned int>(astcInfo.astcSize.height);
1958 CHECK_ERROR_RETURN_RET_LOG(cond, false, "DecAstc dimX: %{public}d dimY: %{public}d overflow", dimX, dimY);
1959 astcInfo.dimX = dimX;
1960 astcInfo.dimY = dimY;
1961 return true;
1962 }
1963
GetStride(AllocatorType allocatorType,void * data,uint32_t & stride,Size astcSize)1964 static void GetStride(AllocatorType allocatorType, void *data, uint32_t &stride, Size astcSize)
1965 {
1966 if (allocatorType == AllocatorType::DMA_ALLOC) {
1967 SurfaceBuffer *surfaceBuffer = reinterpret_cast<SurfaceBuffer *>(data);
1968 stride = static_cast<uint32_t>(surfaceBuffer->GetStride()) >> NUM_2;
1969 } else {
1970 stride = static_cast<uint32_t>(astcSize.width);
1971 }
1972 }
1973
InitAstcInfo(AstcInfo & astcInfo,PixelMap * source)1974 static void InitAstcInfo(AstcInfo &astcInfo, PixelMap *source)
1975 {
1976 astcInfo.astcBufSize = source->GetCapacity();
1977 astcInfo.astcBuf = const_cast<uint8_t *>(source->GetPixels());
1978 astcInfo.format = source->GetPixelFormat();
1979 source->GetAstcRealSize(astcInfo.astcSize);
1980 }
1981 #endif
1982
AstcToRgba(PixelMap * source,uint32_t & errorCode,PixelFormat destFormat)1983 std::unique_ptr<PixelMap> PixelConvert::AstcToRgba(PixelMap *source, uint32_t &errorCode, PixelFormat destFormat)
1984 {
1985 #if !defined(IOS_PLATFORM) && !defined(ANDROID_PLATFORM)
1986 auto colorSpace = source->InnerGetGrColorSpace();
1987 AstcInfo astcInfo;
1988 if (memset_s(&astcInfo, sizeof(AstcInfo), 0, sizeof(AstcInfo)) != 0) {
1989 IMAGE_LOGE("DecAstc memset failed");
1990 errorCode = ERR_IMAGE_INIT_ABNORMAL;
1991 return nullptr;
1992 }
1993 InitAstcInfo(astcInfo, source);
1994 if (!CheckInputValid(astcInfo, destFormat)) {
1995 errorCode = ERR_IMAGE_INVALID_PARAMETER;
1996 return nullptr;
1997 }
1998 uint32_t byteCount = static_cast<uint32_t>(astcInfo.astcSize.width * astcInfo.astcSize.height * BYTES_PER_PIXEL);
1999 MemoryData memoryData = {nullptr, byteCount, "Create PixelMap", astcInfo.astcSize, PixelFormat::RGBA_8888};
2000 memoryData.usage = source->GetNoPaddingUsage();
2001 AllocatorType allocatorType = ImageUtils::GetPixelMapAllocatorType(astcInfo.astcSize, PixelFormat::RGBA_8888, true);
2002 std::unique_ptr<AbsMemory> dstMemory = MemoryManager::CreateMemory(allocatorType, memoryData);
2003 if (dstMemory == nullptr) {
2004 IMAGE_LOGE("DecAstc malloc failed");
2005 errorCode = ERR_IMAGE_MALLOC_ABNORMAL;
2006 return nullptr;
2007 }
2008 uint8_t *recRgba = static_cast<uint8_t *>(dstMemory->data.data);
2009 uint32_t stride = 0;
2010 GetStride(allocatorType, dstMemory->extend.data, stride, astcInfo.astcSize);
2011 if (!DecAstc(recRgba, stride, astcInfo)) {
2012 IMAGE_LOGE("DecAstc failed");
2013 dstMemory->Release();
2014 errorCode = ERR_IMAGE_DECODE_FAILED;
2015 return nullptr;
2016 }
2017
2018 InitializationOptions opts = { astcInfo.astcSize, PixelFormat::RGBA_8888 };
2019 std::unique_ptr<PixelMap> result = PixelMap::Create(opts);
2020 if (result == nullptr) {
2021 IMAGE_LOGE("DecAstc create pixelmap failed");
2022 dstMemory->Release();
2023 errorCode = ERR_IMAGE_DECODE_FAILED;
2024 return nullptr;
2025 }
2026 result->SetPixelsAddr(static_cast<void *>(recRgba), dstMemory->extend.data, byteCount, allocatorType, nullptr);
2027 result->InnerSetColorSpace(colorSpace);
2028 return result;
2029 #else
2030 errorCode = ERR_IMAGE_DECODE_FAILED;
2031 return nullptr;
2032 #endif
2033 }
2034 } // namespace Media
2035 } // namespace OHOS
2036