• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2021 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #include "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