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