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 #ifndef _WIN32
21 #include "securec.h"
22 #else
23 #include "memory.h"
24 #endif
25 #include "pixel_convert_adapter.h"
26 #include "image_utils.h"
27 #include "pixel_map.h"
28 
29 #include "image_log.h"
30 
31 #ifdef __cplusplus
32 extern "C" {
33 #endif
34 #include "libswscale/swscale.h"
35 #include "libavutil/opt.h"
36 #include "libavutil/imgutils.h"
37 #include "libavcodec/avcodec.h"
38 #ifdef __cplusplus
39 }
40 #endif
41 
42 #undef LOG_DOMAIN
43 #define LOG_DOMAIN LOG_TAG_DOMAIN_ID_IMAGE
44 
45 #undef LOG_TAG
46 #define LOG_TAG "PixelConvert"
47 
48 namespace OHOS {
49 namespace Media {
50 using namespace std;
51 #if __BYTE_ORDER == __LITTLE_ENDIAN
52 constexpr bool IS_LITTLE_ENDIAN = true;
53 #else
54 constexpr bool IS_LITTLE_ENDIAN = false;
55 #endif
56 constexpr int32_t DMA_LINE_SIZE = 256;
57 static const uint8_t NUM_2 = 2;
58 constexpr uint8_t YUV420_P010_BYTES = 2;
59 
AlphaTypeConvertOnRGB(uint32_t &A, uint32_t &R, uint32_t &G, uint32_t &B, const ProcFuncExtension &extension)60 static void AlphaTypeConvertOnRGB(uint32_t &A, uint32_t &R, uint32_t &G, uint32_t &B,
61                                   const ProcFuncExtension &extension)
62 {
63     switch (extension.alphaConvertType) {
64         case AlphaConvertType::PREMUL_CONVERT_UNPREMUL:
65             R = Unpremul255(R, A);
66             G = Unpremul255(G, A);
67             B = Unpremul255(B, A);
68             break;
69         case AlphaConvertType::PREMUL_CONVERT_OPAQUE:
70             R = Unpremul255(R, A);
71             G = Unpremul255(G, A);
72             B = Unpremul255(B, A);
73             A = ALPHA_OPAQUE;
74             break;
75         case AlphaConvertType::UNPREMUL_CONVERT_PREMUL:
76             R = Premul255(R, A);
77             G = Premul255(G, A);
78             B = Premul255(B, A);
79             break;
80         case AlphaConvertType::UNPREMUL_CONVERT_OPAQUE:
81             A = ALPHA_OPAQUE;
82             break;
83         default:
84             break;
85     }
86 }
87 
FillARGB8888(uint32_t A, uint32_t R, uint32_t G, uint32_t B)88 static uint32_t FillARGB8888(uint32_t A, uint32_t R, uint32_t G, uint32_t B)
89 {
90     if (IS_LITTLE_ENDIAN) {
91         return ((B << SHIFT_24_BIT) | (G << SHIFT_16_BIT) | (R << SHIFT_8_BIT) | A);
92     }
93     return ((A << SHIFT_24_BIT) | (R << SHIFT_16_BIT) | (G << SHIFT_8_BIT) | B);
94 }
95 
FillABGR8888(uint32_t A, uint32_t B, uint32_t G, uint32_t R)96 static uint32_t FillABGR8888(uint32_t A, uint32_t B, uint32_t G, uint32_t R)
97 {
98     if (IS_LITTLE_ENDIAN) {
99         return ((R << SHIFT_24_BIT) | (G << SHIFT_16_BIT) | (B << SHIFT_8_BIT) | A);
100     }
101     return ((A << SHIFT_24_BIT) | (B << SHIFT_16_BIT) | (G << SHIFT_8_BIT) | R);
102 }
103 
FillRGBA8888(uint32_t R, uint32_t G, uint32_t B, uint32_t A)104 static uint32_t FillRGBA8888(uint32_t R, uint32_t G, uint32_t B, uint32_t A)
105 {
106     if (IS_LITTLE_ENDIAN) {
107         return ((A << SHIFT_24_BIT) | (B << SHIFT_16_BIT) | (G << SHIFT_8_BIT) | R);
108     }
109     return ((R << SHIFT_24_BIT) | (G << SHIFT_16_BIT) | (B << SHIFT_8_BIT) | A);
110 }
111 
FillBGRA8888(uint32_t B, uint32_t G, uint32_t R, uint32_t A)112 static uint32_t FillBGRA8888(uint32_t B, uint32_t G, uint32_t R, uint32_t A)
113 {
114     if (IS_LITTLE_ENDIAN) {
115         return ((A << SHIFT_24_BIT) | (R << SHIFT_16_BIT) | (G << SHIFT_8_BIT) | B);
116     }
117     return ((B << SHIFT_24_BIT) | (G << SHIFT_16_BIT) | (R << SHIFT_8_BIT) | A);
118 }
119 
FillRGB565(uint32_t R, uint32_t G, uint32_t B)120 static uint16_t FillRGB565(uint32_t R, uint32_t G, uint32_t B)
121 {
122     if (IS_LITTLE_ENDIAN) {
123         return ((B << SHIFT_11_BIT) | (G << SHIFT_5_BIT) | R);
124     }
125     return ((R << SHIFT_11_BIT) | (G << SHIFT_5_BIT) | B);
126 }
127 
FillRGBAF16(float R, float G, float B, float A)128 static uint64_t FillRGBAF16(float R, float G, float B, float A)
129 {
130     uint64_t R16 = FloatToHalf(R);
131     uint64_t G16 = FloatToHalf(G);
132     uint64_t B16 = FloatToHalf(B);
133     uint64_t A16 = FloatToHalf(A);
134     if (IS_LITTLE_ENDIAN) {
135         return ((A16 << SHIFT_48_BIT) | (R16 << SHIFT_32_BIT) | (G16 << SHIFT_16_BIT) | B16);
136     }
137     return ((B16 << SHIFT_48_BIT) | (G16 << SHIFT_32_BIT) | (R16 << SHIFT_16_BIT) | A16);
138 }
139 
140 constexpr uint8_t BYTE_BITS = 8;
141 constexpr uint8_t BYTE_BITS_MAX_INDEX = 7;
142 template<typename T>
BitConvert(T *destinationRow, const uint8_t *sourceRow, uint32_t sourceWidth, uint32_t white, uint32_t black)143 static void BitConvert(T *destinationRow, const uint8_t *sourceRow, uint32_t sourceWidth, uint32_t white,
144                        uint32_t black)
145 {
146     destinationRow[0] = (*sourceRow & GET_8_BIT) ? white : black;
147     uint32_t bitIndex = 0;
148     uint8_t currentSource = 0;
149     /*
150      * 1 byte = 8 bit
151      * 7: 8 bit index
152      */
153     for (uint32_t i = 1; i < sourceWidth; i++) {
154         bitIndex = i % BYTE_BITS;
155         currentSource = *(sourceRow + i / BYTE_BITS);
156         if (BYTE_BITS_MAX_INDEX < bitIndex) {
157             continue;
158         }
159         destinationRow[i] = ((currentSource >> (BYTE_BITS_MAX_INDEX - bitIndex)) & GET_1_BIT) ? white : black;
160     }
161 }
162 
BitConvertGray(void *destinationRow, const uint8_t *sourceRow, uint32_t sourceWidth, const ProcFuncExtension &extension)163 static void BitConvertGray(void *destinationRow, const uint8_t *sourceRow, uint32_t sourceWidth,
164                            const ProcFuncExtension &extension)
165 {
166     uint8_t *newDestinationRow = static_cast<uint8_t *>(destinationRow);
167     BitConvert(newDestinationRow, sourceRow, sourceWidth, GRAYSCALE_WHITE, GRAYSCALE_BLACK);
168 }
169 
BitConvertARGB8888(void *destinationRow, const uint8_t *sourceRow, uint32_t sourceWidth, const ProcFuncExtension &extension)170 static void BitConvertARGB8888(void *destinationRow, const uint8_t *sourceRow, uint32_t sourceWidth,
171                                const ProcFuncExtension &extension)
172 {
173     uint32_t *newDestinationRow = static_cast<uint32_t *>(destinationRow);
174     BitConvert(newDestinationRow, sourceRow, sourceWidth, ARGB_WHITE, ARGB_BLACK);
175 }
176 
BitConvertRGB565(void *destinationRow, const uint8_t *sourceRow, uint32_t sourceWidth, const ProcFuncExtension &extension)177 static void BitConvertRGB565(void *destinationRow, const uint8_t *sourceRow, uint32_t sourceWidth,
178                              const ProcFuncExtension &extension)
179 {
180     uint16_t *newDestinationRow = static_cast<uint16_t *>(destinationRow);
181     BitConvert(newDestinationRow, sourceRow, sourceWidth, RGB_WHITE, RGB_BLACK);
182 }
183 
184 constexpr uint32_t BRANCH_GRAY_TO_ARGB8888 = 0x00000001;
185 constexpr uint32_t BRANCH_GRAY_TO_RGB565 = 0x00000002;
186 template<typename T>
GrayConvert(T *destinationRow, const uint8_t *sourceRow, uint32_t sourceWidth, uint32_t branch)187 static void GrayConvert(T *destinationRow, const uint8_t *sourceRow, uint32_t sourceWidth, uint32_t branch)
188 {
189     for (uint32_t i = 0; i < sourceWidth; i++) {
190         uint32_t R = sourceRow[i];
191         uint32_t G = sourceRow[i];
192         uint32_t B = sourceRow[i];
193         if (branch == BRANCH_GRAY_TO_ARGB8888) {
194             uint32_t A = ALPHA_OPAQUE;
195             destinationRow[i] = ((A << SHIFT_24_BIT) | (R << SHIFT_16_BIT) | (G << SHIFT_8_BIT) | B);
196         } else if (branch == BRANCH_GRAY_TO_RGB565) {
197             R = R >> SHIFT_3_BIT;
198             G = G >> SHIFT_2_BIT;
199             B = B >> SHIFT_3_BIT;
200             destinationRow[i] = ((R << SHIFT_11_BIT) | (G << SHIFT_5_BIT) | B);
201         } else {
202             break;
203         }
204     }
205 }
206 
GrayConvertARGB8888(void *destinationRow, const uint8_t *sourceRow, uint32_t sourceWidth, const ProcFuncExtension &extension)207 static void GrayConvertARGB8888(void *destinationRow, const uint8_t *sourceRow, uint32_t sourceWidth,
208                                 const ProcFuncExtension &extension)
209 {
210     uint32_t *newDestinationRow = static_cast<uint32_t *>(destinationRow);
211     GrayConvert(newDestinationRow, sourceRow, sourceWidth, BRANCH_GRAY_TO_ARGB8888);
212 }
213 
GrayConvertRGB565(void *destinationRow, const uint8_t *sourceRow, uint32_t sourceWidth, const ProcFuncExtension &extension)214 static void GrayConvertRGB565(void *destinationRow, const uint8_t *sourceRow, uint32_t sourceWidth,
215                               const ProcFuncExtension &extension)
216 {
217     uint16_t *newDestinationRow = static_cast<uint16_t *>(destinationRow);
218     GrayConvert(newDestinationRow, sourceRow, sourceWidth, BRANCH_GRAY_TO_RGB565);
219 }
220 
221 constexpr uint32_t BRANCH_ARGB8888 = 0x10000001;
222 constexpr uint32_t BRANCH_ALPHA = 0x10000002;
223 template<typename T>
GrayAlphaConvert(T *destinationRow, const uint8_t *sourceRow, uint32_t sourceWidth, uint32_t branch, const ProcFuncExtension &extension)224 static void GrayAlphaConvert(T *destinationRow, const uint8_t *sourceRow, uint32_t sourceWidth, uint32_t branch,
225                              const ProcFuncExtension &extension)
226 {
227     for (uint32_t i = 0; i < sourceWidth; i++) {
228         uint32_t A = sourceRow[1];
229         uint32_t R = sourceRow[0];
230         uint32_t G = sourceRow[0];
231         uint32_t B = sourceRow[0];
232         AlphaTypeConvertOnRGB(A, R, G, B, extension);
233         if (branch == BRANCH_ARGB8888) {
234             destinationRow[i] = FillARGB8888(A, R, G, B);
235         } else if (branch == BRANCH_ALPHA) {
236             destinationRow[i] = A;
237         } else {
238             break;
239         }
240         sourceRow += SIZE_2_BYTE;
241     }
242 }
243 
GrayAlphaConvertARGB8888(void *destinationRow, const uint8_t *sourceRow, uint32_t sourceWidth, const ProcFuncExtension &extension)244 static void GrayAlphaConvertARGB8888(void *destinationRow, const uint8_t *sourceRow, uint32_t sourceWidth,
245                                      const ProcFuncExtension &extension)
246 {
247     uint32_t *newDestinationRow = static_cast<uint32_t *>(destinationRow);
248     GrayAlphaConvert(newDestinationRow, sourceRow, sourceWidth, BRANCH_ARGB8888, extension);
249 }
250 
GrayAlphaConvertAlpha(void *destinationRow, const uint8_t *sourceRow, uint32_t sourceWidth, const ProcFuncExtension &extension)251 static void GrayAlphaConvertAlpha(void *destinationRow, const uint8_t *sourceRow, uint32_t sourceWidth,
252                                   const ProcFuncExtension &extension)
253 {
254     uint8_t *newDestinationRow = static_cast<uint8_t *>(destinationRow);
255     GrayAlphaConvert(newDestinationRow, sourceRow, sourceWidth, BRANCH_ALPHA, extension);
256 }
257 
258 constexpr uint32_t BRANCH_BGR888_TO_ARGB8888 = 0x20000001;
259 constexpr uint32_t BRANCH_BGR888_TO_RGBA8888 = 0x20000002;
260 constexpr uint32_t BRANCH_BGR888_TO_BGRA8888 = 0x20000003;
261 constexpr uint32_t BRANCH_BGR888_TO_RGB565 = 0x20000004;
262 constexpr uint32_t BRANCH_BGR888_TO_RGBAF16 = 0x20000005;
263 template<typename T>
BGR888Convert(T *destinationRow, const uint8_t *sourceRow, uint32_t sourceWidth, uint32_t branch)264 static void BGR888Convert(T *destinationRow, const uint8_t *sourceRow, uint32_t sourceWidth, uint32_t branch)
265 {
266     for (uint32_t i = 0; i < sourceWidth; i++) {
267         uint32_t R = sourceRow[2];
268         uint32_t G = sourceRow[1];
269         uint32_t B = sourceRow[0];
270         uint32_t A = ALPHA_OPAQUE;
271         if (branch == BRANCH_BGR888_TO_ARGB8888) {
272             destinationRow[i] = FillARGB8888(A, R, G, B);
273         } else if (branch == BRANCH_BGR888_TO_RGBA8888) {
274             destinationRow[i] = FillRGBA8888(R, G, B, A);
275         } else if (branch == BRANCH_BGR888_TO_BGRA8888) {
276             destinationRow[i] = FillBGRA8888(B, G, R, A);
277         } else if (branch == BRANCH_BGR888_TO_RGB565) {
278             R = R >> SHIFT_3_BIT;
279             G = G >> SHIFT_2_BIT;
280             B = B >> SHIFT_3_BIT;
281             destinationRow[i] = ((B << SHIFT_11_BIT) | (G << SHIFT_5_BIT) | R);
282         } else if (branch == BRANCH_BGR888_TO_RGBAF16) {
283             destinationRow[i] = FillRGBAF16(R, G, B, A);
284         } else {
285             break;
286         }
287         sourceRow += SIZE_3_BYTE;
288     }
289 }
290 
BGR888ConvertARGB8888(void *destinationRow, const uint8_t *sourceRow, uint32_t sourceWidth, const ProcFuncExtension &extension)291 static void BGR888ConvertARGB8888(void *destinationRow, const uint8_t *sourceRow, uint32_t sourceWidth,
292                                   const ProcFuncExtension &extension)
293 {
294     uint32_t *newDestinationRow = static_cast<uint32_t *>(destinationRow);
295     BGR888Convert(newDestinationRow, sourceRow, sourceWidth, BRANCH_BGR888_TO_ARGB8888);
296 }
297 
BGR888ConvertRGBA8888(void *destinationRow, const uint8_t *sourceRow, uint32_t sourceWidth, const ProcFuncExtension &extension)298 static void BGR888ConvertRGBA8888(void *destinationRow, const uint8_t *sourceRow, uint32_t sourceWidth,
299                                   const ProcFuncExtension &extension)
300 {
301     uint32_t *newDestinationRow = static_cast<uint32_t *>(destinationRow);
302     BGR888Convert(newDestinationRow, sourceRow, sourceWidth, BRANCH_BGR888_TO_RGBA8888);
303 }
304 
BGR888ConvertBGRA8888(void *destinationRow, const uint8_t *sourceRow, uint32_t sourceWidth, const ProcFuncExtension &extension)305 static void BGR888ConvertBGRA8888(void *destinationRow, const uint8_t *sourceRow, uint32_t sourceWidth,
306                                   const ProcFuncExtension &extension)
307 {
308     uint32_t *newDestinationRow = static_cast<uint32_t *>(destinationRow);
309     BGR888Convert(newDestinationRow, sourceRow, sourceWidth, BRANCH_BGR888_TO_BGRA8888);
310 }
311 
BGR888ConvertRGB565(void *destinationRow, const uint8_t *sourceRow, uint32_t sourceWidth, const ProcFuncExtension &extension)312 static void BGR888ConvertRGB565(void *destinationRow, const uint8_t *sourceRow, uint32_t sourceWidth,
313                                 const ProcFuncExtension &extension)
314 {
315     uint16_t *newDestinationRow = static_cast<uint16_t *>(destinationRow);
316     BGR888Convert(newDestinationRow, sourceRow, sourceWidth, BRANCH_BGR888_TO_RGB565);
317 }
318 
BGR888ConvertRGBAF16(uint8_t *destinationRow, const uint8_t *sourceRow, uint32_t sourceWidth, const ProcFuncExtension &extension)319 static void BGR888ConvertRGBAF16(uint8_t *destinationRow, const uint8_t *sourceRow, uint32_t sourceWidth,
320     const ProcFuncExtension &extension)
321 {
322     void* tmp = static_cast<void *>(destinationRow);
323     uint64_t *newDestinationRow = static_cast<uint64_t *>(tmp);
324     BGR888Convert(newDestinationRow, sourceRow, sourceWidth, BRANCH_BGR888_TO_RGBAF16);
325 }
326 
327 constexpr uint32_t BRANCH_RGB888_TO_ARGB8888 = 0x30000001;
328 constexpr uint32_t BRANCH_RGB888_TO_RGBA8888 = 0x30000002;
329 constexpr uint32_t BRANCH_RGB888_TO_BGRA8888 = 0x30000003;
330 constexpr uint32_t BRANCH_RGB888_TO_RGB565 = 0x30000004;
331 constexpr uint32_t BRANCH_RGB888_TO_RGBAF16 = 0x30000005;
332 template<typename T>
RGB888Convert(T *destinationRow, const uint8_t *sourceRow, uint32_t sourceWidth, uint32_t branch)333 static void RGB888Convert(T *destinationRow, const uint8_t *sourceRow, uint32_t sourceWidth, uint32_t branch)
334 {
335     for (uint32_t i = 0; i < sourceWidth; i++) {
336         uint32_t R = sourceRow[0];
337         uint32_t G = sourceRow[1];
338         uint32_t B = sourceRow[2];
339         uint32_t A = ALPHA_OPAQUE;
340         if (branch == BRANCH_RGB888_TO_ARGB8888) {
341             destinationRow[i] = FillARGB8888(A, R, G, B);
342         } else if (branch == BRANCH_RGB888_TO_RGBA8888) {
343             destinationRow[i] = FillRGBA8888(R, G, B, A);
344         } else if (branch == BRANCH_RGB888_TO_BGRA8888) {
345             destinationRow[i] = FillBGRA8888(B, G, R, A);
346         } else if (branch == BRANCH_RGB888_TO_RGB565) {
347             R = R >> SHIFT_3_BIT;
348             G = G >> SHIFT_2_BIT;
349             B = B >> SHIFT_3_BIT;
350             destinationRow[i] = FillRGB565(R, G, B);
351         } else if (branch == BRANCH_RGB888_TO_RGBAF16) {
352             destinationRow[i] = FillRGBAF16(R, G, B, A);
353         } else {
354             break;
355         }
356         sourceRow += SIZE_3_BYTE;
357     }
358 }
RGB888ConvertARGB8888(void *destinationRow, const uint8_t *sourceRow, uint32_t sourceWidth, const ProcFuncExtension &extension)359 static void RGB888ConvertARGB8888(void *destinationRow, const uint8_t *sourceRow, uint32_t sourceWidth,
360                                   const ProcFuncExtension &extension)
361 {
362     uint32_t *newDestinationRow = static_cast<uint32_t *>(destinationRow);
363     RGB888Convert(newDestinationRow, sourceRow, sourceWidth, BRANCH_RGB888_TO_ARGB8888);
364 }
365 
RGB888ConvertRGBA8888(void *destinationRow, const uint8_t *sourceRow, uint32_t sourceWidth, const ProcFuncExtension &extension)366 static void RGB888ConvertRGBA8888(void *destinationRow, const uint8_t *sourceRow, uint32_t sourceWidth,
367                                   const ProcFuncExtension &extension)
368 {
369     uint32_t *newDestinationRow = static_cast<uint32_t *>(destinationRow);
370     RGB888Convert(newDestinationRow, sourceRow, sourceWidth, BRANCH_RGB888_TO_RGBA8888);
371 }
372 
RGB888ConvertBGRA8888(void *destinationRow, const uint8_t *sourceRow, uint32_t sourceWidth, const ProcFuncExtension &extension)373 static void RGB888ConvertBGRA8888(void *destinationRow, const uint8_t *sourceRow, uint32_t sourceWidth,
374                                   const ProcFuncExtension &extension)
375 {
376     uint32_t *newDestinationRow = static_cast<uint32_t *>(destinationRow);
377     RGB888Convert(newDestinationRow, sourceRow, sourceWidth, BRANCH_RGB888_TO_BGRA8888);
378 }
379 
RGB888ConvertRGB565(void *destinationRow, const uint8_t *sourceRow, uint32_t sourceWidth, const ProcFuncExtension &extension)380 static void RGB888ConvertRGB565(void *destinationRow, const uint8_t *sourceRow, uint32_t sourceWidth,
381                                 const ProcFuncExtension &extension)
382 {
383     uint16_t *newDestinationRow = static_cast<uint16_t *>(destinationRow);
384     RGB888Convert(newDestinationRow, sourceRow, sourceWidth, BRANCH_RGB888_TO_RGB565);
385 }
386 
RGB888ConvertRGBAF16(uint8_t *destinationRow, const uint8_t *sourceRow, uint32_t sourceWidth, const ProcFuncExtension &extension)387 static void RGB888ConvertRGBAF16(uint8_t *destinationRow, const uint8_t *sourceRow, uint32_t sourceWidth,
388     const ProcFuncExtension &extension)
389 {
390     void* tmp = static_cast<void *>(destinationRow);
391     uint64_t *newDestinationRow = static_cast<uint64_t *>(tmp);
392     RGB888Convert(newDestinationRow, sourceRow, sourceWidth, BRANCH_RGB888_TO_RGBAF16);
393 }
394 constexpr uint32_t BRANCH_RGBA8888_TO_RGBA8888_ALPHA = 0x40000001;
395 constexpr uint32_t BRANCH_RGBA8888_TO_ARGB8888 = 0x40000002;
396 constexpr uint32_t BRANCH_RGBA8888_TO_BGRA8888 = 0x40000003;
397 constexpr uint32_t BRANCH_RGBA8888_TO_RGB565 = 0x40000004;
398 constexpr uint32_t BRANCH_RGBA8888_TO_RGBAF16 = 0x40000005;
399 template<typename T>
RGBA8888Convert(T *destinationRow, const uint8_t *sourceRow, uint32_t sourceWidth, uint32_t branch, const ProcFuncExtension &extension)400 static void RGBA8888Convert(T *destinationRow, const uint8_t *sourceRow, uint32_t sourceWidth, uint32_t branch,
401                             const ProcFuncExtension &extension)
402 {
403     for (uint32_t i = 0; i < sourceWidth; i++) {
404         uint32_t R = sourceRow[0];
405         uint32_t G = sourceRow[1];
406         uint32_t B = sourceRow[2];
407         uint32_t A = sourceRow[3];
408         AlphaTypeConvertOnRGB(A, R, G, B, extension);
409         if (branch == BRANCH_RGBA8888_TO_RGBA8888_ALPHA) {
410             destinationRow[i] = FillRGBA8888(R, G, B, A);
411         } else if (branch == BRANCH_RGBA8888_TO_ARGB8888) {
412             destinationRow[i] = FillARGB8888(A, R, G, B);
413         } else if (branch == BRANCH_RGBA8888_TO_BGRA8888) {
414             destinationRow[i] = FillBGRA8888(B, G, R, A);
415         } else if (branch == BRANCH_RGBA8888_TO_RGB565) {
416             R = R >> SHIFT_3_BIT;
417             G = G >> SHIFT_2_BIT;
418             B = B >> SHIFT_3_BIT;
419             destinationRow[i] = FillRGB565(R, G, B);
420         } else if (branch == BRANCH_RGBA8888_TO_RGBAF16) {
421             destinationRow[i] = FillRGBAF16(R, G, B, A);
422         } else {
423             break;
424         }
425         sourceRow += SIZE_4_BYTE;
426     }
427 }
428 
RGBA8888ConvertRGBA8888Alpha(void *destinationRow, const uint8_t *sourceRow, uint32_t sourceWidth, const ProcFuncExtension &extension)429 static void RGBA8888ConvertRGBA8888Alpha(void *destinationRow, const uint8_t *sourceRow, uint32_t sourceWidth,
430                                          const ProcFuncExtension &extension)
431 {
432     uint32_t *newDestinationRow = static_cast<uint32_t *>(destinationRow);
433     RGBA8888Convert(newDestinationRow, sourceRow, sourceWidth, BRANCH_RGBA8888_TO_RGBA8888_ALPHA, extension);
434 }
435 
RGBA8888ConvertARGB8888(void *destinationRow, const uint8_t *sourceRow, uint32_t sourceWidth, const ProcFuncExtension &extension)436 static void RGBA8888ConvertARGB8888(void *destinationRow, const uint8_t *sourceRow, uint32_t sourceWidth,
437                                     const ProcFuncExtension &extension)
438 {
439     uint32_t *newDestinationRow = static_cast<uint32_t *>(destinationRow);
440     RGBA8888Convert(newDestinationRow, sourceRow, sourceWidth, BRANCH_RGBA8888_TO_ARGB8888, extension);
441 }
RGBA8888ConvertBGRA8888(void *destinationRow, const uint8_t *sourceRow, uint32_t sourceWidth, const ProcFuncExtension &extension)442 static void RGBA8888ConvertBGRA8888(void *destinationRow, const uint8_t *sourceRow, uint32_t sourceWidth,
443                                     const ProcFuncExtension &extension)
444 {
445     uint32_t *newDestinationRow = static_cast<uint32_t *>(destinationRow);
446     RGBA8888Convert(newDestinationRow, sourceRow, sourceWidth, BRANCH_RGBA8888_TO_BGRA8888, extension);
447 }
448 
RGBA8888ConvertRGB565(void *destinationRow, const uint8_t *sourceRow, uint32_t sourceWidth, const ProcFuncExtension &extension)449 static void RGBA8888ConvertRGB565(void *destinationRow, const uint8_t *sourceRow, uint32_t sourceWidth,
450                                   const ProcFuncExtension &extension)
451 {
452     uint16_t *newDestinationRow = static_cast<uint16_t *>(destinationRow);
453     RGBA8888Convert(newDestinationRow, sourceRow, sourceWidth, BRANCH_RGBA8888_TO_RGB565, extension);
454 }
455 
RGBA8888ConvertRGBAF16(uint8_t *destinationRow, const uint8_t *sourceRow, uint32_t sourceWidth, const ProcFuncExtension &extension)456 static void RGBA8888ConvertRGBAF16(uint8_t *destinationRow, const uint8_t *sourceRow, uint32_t sourceWidth,
457     const ProcFuncExtension &extension)
458 {
459     void* tmp = static_cast<void *>(destinationRow);
460     uint64_t *newDestinationRow = static_cast<uint64_t *>(tmp);
461     RGBA8888Convert(newDestinationRow, sourceRow, sourceWidth, BRANCH_RGBA8888_TO_RGBAF16, extension);
462 }
463 constexpr uint32_t BRANCH_BGRA8888_TO_BGRA8888_ALPHA = 0x80000001;
464 constexpr uint32_t BRANCH_BGRA8888_TO_ARGB8888 = 0x80000002;
465 constexpr uint32_t BRANCH_BGRA8888_TO_RGBA8888 = 0x80000003;
466 constexpr uint32_t BRANCH_BGRA8888_TO_RGB565 = 0x80000004;
467 constexpr uint32_t BRANCH_BGRA8888_TO_RGBAF16 = 0x80000005;
468 template<typename T>
BGRA8888Convert(T *destinationRow, const uint8_t *sourceRow, uint32_t sourceWidth, uint32_t branch, const ProcFuncExtension &extension)469 static void BGRA8888Convert(T *destinationRow, const uint8_t *sourceRow, uint32_t sourceWidth, uint32_t branch,
470                             const ProcFuncExtension &extension)
471 {
472     for (uint32_t i = 0; i < sourceWidth; i++) {
473         uint32_t B = sourceRow[0];
474         uint32_t G = sourceRow[1];
475         uint32_t R = sourceRow[2];
476         uint32_t A = sourceRow[3];
477         AlphaTypeConvertOnRGB(A, R, G, B, extension);
478         if (branch == BRANCH_BGRA8888_TO_BGRA8888_ALPHA) {
479             destinationRow[i] = FillBGRA8888(B, G, R, A);
480         } else if (branch == BRANCH_BGRA8888_TO_ARGB8888) {
481             destinationRow[i] = FillARGB8888(A, R, G, B);
482         } else if (branch == BRANCH_BGRA8888_TO_RGBA8888) {
483             destinationRow[i] = FillRGBA8888(R, G, B, A);
484         } else if (branch == BRANCH_BGRA8888_TO_RGB565) {
485             R = R >> SHIFT_3_BIT;
486             G = G >> SHIFT_2_BIT;
487             B = B >> SHIFT_3_BIT;
488             destinationRow[i] = FillRGB565(R, G, B);
489         } else if (branch == BRANCH_BGRA8888_TO_RGBAF16) {
490             destinationRow[i] = FillRGBAF16(R, G, B, A);
491         } else {
492             break;
493         }
494         sourceRow += SIZE_4_BYTE;
495     }
496 }
497 
BGRA8888ConvertBGRA8888Alpha(void *destinationRow, const uint8_t *sourceRow, uint32_t sourceWidth, const ProcFuncExtension &extension)498 static void BGRA8888ConvertBGRA8888Alpha(void *destinationRow, const uint8_t *sourceRow, uint32_t sourceWidth,
499                                          const ProcFuncExtension &extension)
500 {
501     uint32_t *newDestinationRow = static_cast<uint32_t *>(destinationRow);
502     BGRA8888Convert(newDestinationRow, sourceRow, sourceWidth, BRANCH_BGRA8888_TO_BGRA8888_ALPHA, extension);
503 }
504 
BGRA8888ConvertARGB8888(void *destinationRow, const uint8_t *sourceRow, uint32_t sourceWidth, const ProcFuncExtension &extension)505 static void BGRA8888ConvertARGB8888(void *destinationRow, const uint8_t *sourceRow, uint32_t sourceWidth,
506                                     const ProcFuncExtension &extension)
507 {
508     uint32_t *newDestinationRow = static_cast<uint32_t *>(destinationRow);
509     BGRA8888Convert(newDestinationRow, sourceRow, sourceWidth, BRANCH_BGRA8888_TO_ARGB8888, extension);
510 }
511 
BGRA8888ConvertRGBA8888(void *destinationRow, const uint8_t *sourceRow, uint32_t sourceWidth, const ProcFuncExtension &extension)512 static void BGRA8888ConvertRGBA8888(void *destinationRow, const uint8_t *sourceRow, uint32_t sourceWidth,
513                                     const ProcFuncExtension &extension)
514 {
515     uint32_t *newDestinationRow = static_cast<uint32_t *>(destinationRow);
516     BGRA8888Convert(newDestinationRow, sourceRow, sourceWidth, BRANCH_BGRA8888_TO_RGBA8888, extension);
517 }
518 
BGRA8888ConvertRGB565(void *destinationRow, const uint8_t *sourceRow, uint32_t sourceWidth, const ProcFuncExtension &extension)519 static void BGRA8888ConvertRGB565(void *destinationRow, const uint8_t *sourceRow, uint32_t sourceWidth,
520                                   const ProcFuncExtension &extension)
521 {
522     uint16_t *newDestinationRow = static_cast<uint16_t *>(destinationRow);
523     BGRA8888Convert(newDestinationRow, sourceRow, sourceWidth, BRANCH_BGRA8888_TO_RGB565, extension);
524 }
525 
BGRA8888ConvertRGBAF16(uint8_t *destinationRow, const uint8_t *sourceRow, uint32_t sourceWidth, const ProcFuncExtension &extension)526 static void BGRA8888ConvertRGBAF16(uint8_t *destinationRow, const uint8_t *sourceRow, uint32_t sourceWidth,
527     const ProcFuncExtension &extension)
528 {
529     void* tmp = static_cast<void *>(destinationRow);
530     uint64_t *newDestinationRow = static_cast<uint64_t *>(tmp);
531     BGRA8888Convert(newDestinationRow, sourceRow, sourceWidth, BRANCH_BGRA8888_TO_RGBAF16, extension);
532 }
533 
534 constexpr uint32_t BRANCH_ARGB8888_TO_ARGB8888_ALPHA = 0x90000001;
535 constexpr uint32_t BRANCH_ARGB8888_TO_RGBA8888 = 0x90000002;
536 constexpr uint32_t BRANCH_ARGB8888_TO_BGRA8888 = 0x90000003;
537 constexpr uint32_t BRANCH_ARGB8888_TO_RGB565 = 0x90000004;
538 constexpr uint32_t BRANCH_ARGB8888_TO_RGBAF16 = 0x90000005;
539 template<typename T>
ARGB8888Convert(T *destinationRow, const uint8_t *sourceRow, uint32_t sourceWidth, uint32_t branch, const ProcFuncExtension &extension)540 static void ARGB8888Convert(T *destinationRow, const uint8_t *sourceRow, uint32_t sourceWidth, uint32_t branch,
541                             const ProcFuncExtension &extension)
542 {
543     for (uint32_t i = 0; i < sourceWidth; i++) {
544         uint32_t A = sourceRow[0];
545         uint32_t R = sourceRow[1];
546         uint32_t G = sourceRow[2];
547         uint32_t B = sourceRow[3];
548         AlphaTypeConvertOnRGB(A, R, G, B, extension);
549         if (branch == BRANCH_ARGB8888_TO_ARGB8888_ALPHA) {
550             destinationRow[i] = FillARGB8888(A, R, G, B);
551         } else if (branch == BRANCH_ARGB8888_TO_RGBA8888) {
552             destinationRow[i] = FillRGBA8888(R, G, B, A);
553         } else if (branch == BRANCH_ARGB8888_TO_BGRA8888) {
554             destinationRow[i] = FillBGRA8888(B, G, R, A);
555         } else if (branch == BRANCH_ARGB8888_TO_RGB565) {
556             R = R >> SHIFT_3_BIT;
557             G = G >> SHIFT_2_BIT;
558             B = B >> SHIFT_3_BIT;
559             destinationRow[i] = FillRGB565(R, G, B);
560         } else if (branch == BRANCH_ARGB8888_TO_RGBAF16) {
561             destinationRow[i] = FillRGBAF16(R, G, B, A);
562         } else {
563             break;
564         }
565         sourceRow += SIZE_4_BYTE;
566     }
567 }
568 
ARGB8888ConvertARGB8888Alpha(void *destinationRow, const uint8_t *sourceRow, uint32_t sourceWidth, const ProcFuncExtension &extension)569 static void ARGB8888ConvertARGB8888Alpha(void *destinationRow, const uint8_t *sourceRow, uint32_t sourceWidth,
570                                          const ProcFuncExtension &extension)
571 {
572     uint32_t *newDestinationRow = static_cast<uint32_t *>(destinationRow);
573     ARGB8888Convert(newDestinationRow, sourceRow, sourceWidth, BRANCH_ARGB8888_TO_ARGB8888_ALPHA, extension);
574 }
575 
ARGB8888ConvertRGBA8888(void *destinationRow, const uint8_t *sourceRow, uint32_t sourceWidth, const ProcFuncExtension &extension)576 static void ARGB8888ConvertRGBA8888(void *destinationRow, const uint8_t *sourceRow, uint32_t sourceWidth,
577                                     const ProcFuncExtension &extension)
578 {
579     uint32_t *newDestinationRow = static_cast<uint32_t *>(destinationRow);
580     ARGB8888Convert(newDestinationRow, sourceRow, sourceWidth, BRANCH_ARGB8888_TO_RGBA8888, extension);
581 }
582 
ARGB8888ConvertBGRA8888(void *destinationRow, const uint8_t *sourceRow, uint32_t sourceWidth, const ProcFuncExtension &extension)583 static void ARGB8888ConvertBGRA8888(void *destinationRow, const uint8_t *sourceRow, uint32_t sourceWidth,
584                                     const ProcFuncExtension &extension)
585 {
586     uint32_t *newDestinationRow = static_cast<uint32_t *>(destinationRow);
587     ARGB8888Convert(newDestinationRow, sourceRow, sourceWidth, BRANCH_ARGB8888_TO_BGRA8888, extension);
588 }
589 
ARGB8888ConvertRGB565(void *destinationRow, const uint8_t *sourceRow, uint32_t sourceWidth, const ProcFuncExtension &extension)590 static void ARGB8888ConvertRGB565(void *destinationRow, const uint8_t *sourceRow, uint32_t sourceWidth,
591                                   const ProcFuncExtension &extension)
592 {
593     uint16_t *newDestinationRow = static_cast<uint16_t *>(destinationRow);
594     ARGB8888Convert(newDestinationRow, sourceRow, sourceWidth, BRANCH_ARGB8888_TO_RGB565, extension);
595 }
596 
ARGB8888ConvertRGBAF16(uint8_t *destinationRow, const uint8_t *sourceRow, uint32_t sourceWidth, const ProcFuncExtension &extension)597 static void ARGB8888ConvertRGBAF16(uint8_t *destinationRow, const uint8_t *sourceRow, uint32_t sourceWidth,
598     const ProcFuncExtension &extension)
599 {
600     void* tmp = static_cast<void *>(destinationRow);
601     uint64_t *newDestinationRow = static_cast<uint64_t *>(tmp);
602     ARGB8888Convert(newDestinationRow, sourceRow, sourceWidth, BRANCH_ARGB8888_TO_RGBAF16, extension);
603 }
604 
605 constexpr uint32_t BRANCH_RGB161616_TO_ARGB8888 = 0x50000001;
606 constexpr uint32_t BRANCH_RGB161616_TO_ABGR8888 = 0x50000002;
607 constexpr uint32_t BRANCH_RGB161616_TO_RGBA8888 = 0x50000003;
608 constexpr uint32_t BRANCH_RGB161616_TO_BGRA8888 = 0x50000004;
609 constexpr uint32_t BRANCH_RGB161616_TO_RGB565 = 0x50000005;
610 constexpr uint32_t BRANCH_RGB161616_TO_RGBAF16 = 0x50000006;
611 template<typename T>
RGB161616Convert(T *destinationRow, const uint8_t *sourceRow, uint32_t sourceWidth, uint32_t branch)612 static void RGB161616Convert(T *destinationRow, const uint8_t *sourceRow, uint32_t sourceWidth, uint32_t branch)
613 {
614     for (uint32_t i = 0; i < sourceWidth; i++) {
615         uint32_t R = sourceRow[0];
616         uint32_t G = sourceRow[2];
617         uint32_t B = sourceRow[4];
618         uint32_t A = ALPHA_OPAQUE;
619         if (branch == BRANCH_RGB161616_TO_ARGB8888) {
620             destinationRow[i] = FillARGB8888(A, R, G, B);
621         } else if (branch == BRANCH_RGB161616_TO_ABGR8888) {
622             destinationRow[i] = FillABGR8888(A, B, G, R);
623         } else if (branch == BRANCH_RGB161616_TO_RGBA8888) {
624             destinationRow[i] = FillRGBA8888(R, G, B, A);
625         } else if (branch == BRANCH_RGB161616_TO_BGRA8888) {
626             destinationRow[i] = FillBGRA8888(B, G, R, A);
627         } else if (branch == BRANCH_RGB161616_TO_RGB565) {
628             R = R >> SHIFT_3_BIT;
629             G = G >> SHIFT_2_BIT;
630             B = B >> SHIFT_3_BIT;
631             destinationRow[i] = FillRGB565(R, G, B);
632         } else if (branch == BRANCH_RGB161616_TO_RGBAF16) {
633             destinationRow[i] = FillRGBAF16(R, G, B, A);
634         } else {
635             break;
636         }
637         sourceRow += SIZE_6_BYTE;
638     }
639 }
640 
RGB161616ConvertARGB8888(void *destinationRow, const uint8_t *sourceRow, uint32_t sourceWidth, const ProcFuncExtension &extension)641 static void RGB161616ConvertARGB8888(void *destinationRow, const uint8_t *sourceRow, uint32_t sourceWidth,
642                                      const ProcFuncExtension &extension)
643 {
644     uint32_t *newDestinationRow = static_cast<uint32_t *>(destinationRow);
645     RGB161616Convert(newDestinationRow, sourceRow, sourceWidth, BRANCH_RGB161616_TO_ARGB8888);
646 }
647 
RGB161616ConvertABGR8888(void *destinationRow, const uint8_t *sourceRow, uint32_t sourceWidth, const ProcFuncExtension &extension)648 static void RGB161616ConvertABGR8888(void *destinationRow, const uint8_t *sourceRow, uint32_t sourceWidth,
649                                      const ProcFuncExtension &extension)
650 {
651     uint32_t *newDestinationRow = static_cast<uint32_t *>(destinationRow);
652     RGB161616Convert(newDestinationRow, sourceRow, sourceWidth, BRANCH_RGB161616_TO_ABGR8888);
653 }
654 
RGB161616ConvertRGBA8888(void *destinationRow, const uint8_t *sourceRow, uint32_t sourceWidth, const ProcFuncExtension &extension)655 static void RGB161616ConvertRGBA8888(void *destinationRow, const uint8_t *sourceRow, uint32_t sourceWidth,
656                                      const ProcFuncExtension &extension)
657 {
658     uint32_t *newDestinationRow = static_cast<uint32_t *>(destinationRow);
659     RGB161616Convert(newDestinationRow, sourceRow, sourceWidth, BRANCH_RGB161616_TO_RGBA8888);
660 }
661 
RGB161616ConvertBGRA8888(void *destinationRow, const uint8_t *sourceRow, uint32_t sourceWidth, const ProcFuncExtension &extension)662 static void RGB161616ConvertBGRA8888(void *destinationRow, const uint8_t *sourceRow, uint32_t sourceWidth,
663                                      const ProcFuncExtension &extension)
664 {
665     uint32_t *newDestinationRow = static_cast<uint32_t *>(destinationRow);
666     RGB161616Convert(newDestinationRow, sourceRow, sourceWidth, BRANCH_RGB161616_TO_BGRA8888);
667 }
668 
RGB161616ConvertRGB565(void *destinationRow, const uint8_t *sourceRow, uint32_t sourceWidth, const ProcFuncExtension &extension)669 static void RGB161616ConvertRGB565(void *destinationRow, const uint8_t *sourceRow, uint32_t sourceWidth,
670                                    const ProcFuncExtension &extension)
671 {
672     uint16_t *newDestinationRow = static_cast<uint16_t *>(destinationRow);
673     RGB161616Convert(newDestinationRow, sourceRow, sourceWidth, BRANCH_RGB161616_TO_RGB565);
674 }
675 
RGB161616ConvertRGBAF16(uint8_t *destinationRow, const uint8_t *sourceRow, uint32_t sourceWidth, const ProcFuncExtension &extension)676 static void RGB161616ConvertRGBAF16(uint8_t *destinationRow, const uint8_t *sourceRow, uint32_t sourceWidth,
677     const ProcFuncExtension &extension)
678 {
679     void* tmp = static_cast<void *>(destinationRow);
680     uint64_t *newDestinationRow = static_cast<uint64_t *>(tmp);
681     RGB161616Convert(newDestinationRow, sourceRow, sourceWidth, BRANCH_RGB161616_TO_RGBAF16);
682 }
683 
684 constexpr uint32_t BRANCH_RGBA16161616_TO_ARGB8888 = 0x60000001;
685 constexpr uint32_t BRANCH_RGBA16161616_TO_ABGR8888 = 0x60000002;
686 constexpr uint32_t BRANCH_RGBA16161616_TO_RGBA8888 = 0x60000003;
687 constexpr uint32_t BRANCH_RGBA16161616_TO_BGRA8888 = 0x60000004;
688 constexpr uint32_t BRANCH_RGBA16161616_TO_RGBAF16 = 0x60000005;
689 template<typename T>
RGBA16161616Convert(T *destinationRow, const uint8_t *sourceRow, uint32_t sourceWidth, uint32_t branch, const ProcFuncExtension &extension)690 static void RGBA16161616Convert(T *destinationRow, const uint8_t *sourceRow, uint32_t sourceWidth, uint32_t branch,
691                                 const ProcFuncExtension &extension)
692 {
693     for (uint32_t i = 0; i < sourceWidth; i++) {
694         uint32_t R = sourceRow[0];
695         uint32_t G = sourceRow[2];
696         uint32_t B = sourceRow[4];
697         uint32_t A = sourceRow[6];
698         AlphaTypeConvertOnRGB(A, R, G, B, extension);
699         if (branch == BRANCH_RGBA16161616_TO_ARGB8888) {
700             destinationRow[i] = FillARGB8888(A, R, G, B);
701         } else if (branch == BRANCH_RGBA16161616_TO_ABGR8888) {
702             destinationRow[i] = FillABGR8888(A, B, G, R);
703         } else if (branch == BRANCH_RGBA16161616_TO_RGBA8888) {
704             destinationRow[i] = FillRGBA8888(A, B, G, R);
705         } else if (branch == BRANCH_RGBA16161616_TO_BGRA8888) {
706             destinationRow[i] = FillBGRA8888(A, B, G, R);
707         } else if (branch == BRANCH_RGBA16161616_TO_RGBAF16) {
708             destinationRow[i] = FillRGBAF16(R, G, B, A);
709         } else {
710             break;
711         }
712         sourceRow += SIZE_8_BYTE;
713     }
714 }
715 
RGBA16161616ConvertARGB8888(void *destinationRow, const uint8_t *sourceRow, uint32_t sourceWidth, const ProcFuncExtension &extension)716 static void RGBA16161616ConvertARGB8888(void *destinationRow, const uint8_t *sourceRow, uint32_t sourceWidth,
717                                         const ProcFuncExtension &extension)
718 {
719     uint32_t *newDestinationRow = static_cast<uint32_t *>(destinationRow);
720     RGBA16161616Convert(newDestinationRow, sourceRow, sourceWidth, BRANCH_RGBA16161616_TO_ARGB8888, extension);
721 }
722 
RGBA16161616ConvertABGR8888(void *destinationRow, const uint8_t *sourceRow, uint32_t sourceWidth, const ProcFuncExtension &extension)723 static void RGBA16161616ConvertABGR8888(void *destinationRow, const uint8_t *sourceRow, uint32_t sourceWidth,
724                                         const ProcFuncExtension &extension)
725 {
726     uint32_t *newDestinationRow = static_cast<uint32_t *>(destinationRow);
727     RGBA16161616Convert(newDestinationRow, sourceRow, sourceWidth, BRANCH_RGBA16161616_TO_ABGR8888, extension);
728 }
729 
RGBA16161616ConvertRGBA8888(void *destinationRow, const uint8_t *sourceRow, uint32_t sourceWidth, const ProcFuncExtension &extension)730 static void RGBA16161616ConvertRGBA8888(void *destinationRow, const uint8_t *sourceRow, uint32_t sourceWidth,
731                                         const ProcFuncExtension &extension)
732 {
733     uint32_t *newDestinationRow = static_cast<uint32_t *>(destinationRow);
734     RGBA16161616Convert(newDestinationRow, sourceRow, sourceWidth, BRANCH_RGBA16161616_TO_RGBA8888, extension);
735 }
736 
RGBA16161616ConvertBGRA8888(void *destinationRow, const uint8_t *sourceRow, uint32_t sourceWidth, const ProcFuncExtension &extension)737 static void RGBA16161616ConvertBGRA8888(void *destinationRow, const uint8_t *sourceRow, uint32_t sourceWidth,
738                                         const ProcFuncExtension &extension)
739 {
740     uint32_t *newDestinationRow = static_cast<uint32_t *>(destinationRow);
741     RGBA16161616Convert(newDestinationRow, sourceRow, sourceWidth, BRANCH_RGBA16161616_TO_BGRA8888, extension);
742 }
743 
RGBA16161616ConvertRGBAF16(uint8_t *destinationRow, const uint8_t *sourceRow, uint32_t sourceWidth, const ProcFuncExtension &extension)744 static void RGBA16161616ConvertRGBAF16(uint8_t *destinationRow, const uint8_t *sourceRow, uint32_t sourceWidth,
745     const ProcFuncExtension &extension)
746 {
747     void* tmp = static_cast<void *>(destinationRow);
748     uint64_t *newDestinationRow = static_cast<uint64_t *>(tmp);
749     RGBA16161616Convert(newDestinationRow, sourceRow, sourceWidth, BRANCH_RGBA16161616_TO_RGBAF16, extension);
750 }
751 
752 constexpr uint32_t BRANCH_CMYK_TO_ARGB8888 = 0x70000001;
753 constexpr uint32_t BRANCH_CMYK_TO_ABGR8888 = 0x70000002;
754 constexpr uint32_t BRANCH_CMYK_TO_RGBA8888 = 0x70000003;
755 constexpr uint32_t BRANCH_CMYK_TO_BGRA8888 = 0x70000004;
756 constexpr uint32_t BRANCH_CMYK_TO_RGB565 = 0x70000005;
757 template<typename T>
CMYKConvert(T *destinationRow, const uint8_t *sourceRow, uint32_t sourceWidth, uint32_t branch)758 static void CMYKConvert(T *destinationRow, const uint8_t *sourceRow, uint32_t sourceWidth, uint32_t branch)
759 {
760     for (uint32_t i = 0; i < sourceWidth; i++) {
761         uint8_t C = sourceRow[0];
762         uint8_t M = sourceRow[1];
763         uint8_t Y = sourceRow[2];
764         uint8_t K = sourceRow[3];
765         uint32_t R = Premul255(C, K);
766         uint32_t G = Premul255(M, K);
767         uint32_t B = Premul255(Y, K);
768         uint32_t A = ALPHA_OPAQUE;
769         if (branch == BRANCH_CMYK_TO_ARGB8888) {
770             destinationRow[i] = FillARGB8888(A, R, G, B);
771         } else if (branch == BRANCH_CMYK_TO_ABGR8888) {
772             destinationRow[i] = FillABGR8888(A, B, G, R);
773         } else if (branch == BRANCH_CMYK_TO_RGBA8888) {
774             destinationRow[i] = FillRGBA8888(R, G, B, A);
775         } else if (branch == BRANCH_CMYK_TO_BGRA8888) {
776             destinationRow[i] = FillBGRA8888(B, G, R, A);
777         } else if (branch == BRANCH_CMYK_TO_RGB565) {
778             R = R >> SHIFT_3_BIT;
779             G = R >> SHIFT_2_BIT;
780             B = B >> SHIFT_3_BIT;
781             destinationRow[i] = FillRGB565(R, G, B);
782         } else {
783             break;
784         }
785         sourceRow += SIZE_4_BYTE;
786     }
787 }
788 
CMYKConvertARGB8888(void *destinationRow, const uint8_t *sourceRow, uint32_t sourceWidth, const ProcFuncExtension &extension)789 static void CMYKConvertARGB8888(void *destinationRow, const uint8_t *sourceRow, uint32_t sourceWidth,
790                                 const ProcFuncExtension &extension)
791 {
792     uint32_t *newDestinationRow = static_cast<uint32_t *>(destinationRow);
793     CMYKConvert(newDestinationRow, sourceRow, sourceWidth, BRANCH_CMYK_TO_ARGB8888);
794 }
795 
CMYKConvertABGR8888(void *destinationRow, const uint8_t *sourceRow, uint32_t sourceWidth, const ProcFuncExtension &extension)796 static void CMYKConvertABGR8888(void *destinationRow, const uint8_t *sourceRow, uint32_t sourceWidth,
797                                 const ProcFuncExtension &extension)
798 {
799     uint32_t *newDestinationRow = static_cast<uint32_t *>(destinationRow);
800     CMYKConvert(newDestinationRow, sourceRow, sourceWidth, BRANCH_CMYK_TO_ABGR8888);
801 }
802 
CMYKConvertRGBA8888(void *destinationRow, const uint8_t *sourceRow, uint32_t sourceWidth, const ProcFuncExtension &extension)803 static void CMYKConvertRGBA8888(void *destinationRow, const uint8_t *sourceRow, uint32_t sourceWidth,
804                                 const ProcFuncExtension &extension)
805 {
806     uint32_t *newDestinationRow = static_cast<uint32_t *>(destinationRow);
807     CMYKConvert(newDestinationRow, sourceRow, sourceWidth, BRANCH_CMYK_TO_RGBA8888);
808 }
809 
CMYKConvertBGRA8888(void *destinationRow, const uint8_t *sourceRow, uint32_t sourceWidth, const ProcFuncExtension &extension)810 static void CMYKConvertBGRA8888(void *destinationRow, const uint8_t *sourceRow, uint32_t sourceWidth,
811                                 const ProcFuncExtension &extension)
812 {
813     uint32_t *newDestinationRow = static_cast<uint32_t *>(destinationRow);
814     CMYKConvert(newDestinationRow, sourceRow, sourceWidth, BRANCH_CMYK_TO_BGRA8888);
815 }
816 
CMYKConvertRGB565(void *destinationRow, const uint8_t *sourceRow, uint32_t sourceWidth, const ProcFuncExtension &extension)817 static void CMYKConvertRGB565(void *destinationRow, const uint8_t *sourceRow, uint32_t sourceWidth,
818                               const ProcFuncExtension &extension)
819 {
820     uint32_t *newDestinationRow = static_cast<uint32_t *>(destinationRow);
821     CMYKConvert(newDestinationRow, sourceRow, sourceWidth, BRANCH_CMYK_TO_RGB565);
822 }
823 
824 constexpr uint32_t BRANCH_RGB565_TO_ARGB8888 = 0x11000001;
825 constexpr uint32_t BRANCH_RGB565_TO_RGBA8888 = 0x11000002;
826 constexpr uint32_t BRANCH_RGB565_TO_BGRA8888 = 0x11000003;
827 constexpr uint32_t BRANCH_RGB565_TO_RGBAF16 = 0x11000004;
828 template<typename T>
RGB565Convert(T *destinationRow, const uint8_t *sourceRow, uint32_t sourceWidth, uint32_t branch)829 static void RGB565Convert(T *destinationRow, const uint8_t *sourceRow, uint32_t sourceWidth, uint32_t branch)
830 {
831     for (uint32_t i = 0; i < sourceWidth; i++) {
832         uint32_t R = (sourceRow[0] >> SHIFT_3_BIT) & SHIFT_5_MASK;
833         uint32_t G = ((sourceRow[0] & SHIFT_3_MASK) << SHIFT_3_BIT) | ((sourceRow[1] >> SHIFT_5_BIT) & SHIFT_3_MASK);
834         uint32_t B = sourceRow[1] & SHIFT_5_MASK;
835         uint32_t A = ALPHA_OPAQUE;
836         if (branch == BRANCH_RGB565_TO_ARGB8888) {
837             destinationRow[i] = FillARGB8888(A, R, G, B);
838         } else if (branch == BRANCH_RGB565_TO_RGBA8888) {
839             destinationRow[i] = FillRGBA8888(R, G, B, A);
840         } else if (branch == BRANCH_RGB565_TO_BGRA8888) {
841             destinationRow[i] = FillBGRA8888(B, G, R, A);
842         } else if (branch == BRANCH_RGB565_TO_RGBAF16) {
843             destinationRow[i] = FillRGBAF16(R, G, B, A);
844         } else {
845             break;
846         }
847         sourceRow += SIZE_2_BYTE;
848     }
849 }
850 
RGB565ConvertARGB8888(void *destinationRow, const uint8_t *sourceRow, uint32_t sourceWidth, const ProcFuncExtension &extension)851 static void RGB565ConvertARGB8888(void *destinationRow, const uint8_t *sourceRow, uint32_t sourceWidth,
852                                   const ProcFuncExtension &extension)
853 {
854     uint32_t *newDestinationRow = static_cast<uint32_t *>(destinationRow);
855     RGB565Convert(newDestinationRow, sourceRow, sourceWidth, BRANCH_RGB565_TO_ARGB8888);
856 }
857 
RGB565ConvertRGBA8888(void *destinationRow, const uint8_t *sourceRow, uint32_t sourceWidth, const ProcFuncExtension &extension)858 static void RGB565ConvertRGBA8888(void *destinationRow, const uint8_t *sourceRow, uint32_t sourceWidth,
859                                   const ProcFuncExtension &extension)
860 {
861     uint32_t *newDestinationRow = static_cast<uint32_t *>(destinationRow);
862     RGB565Convert(newDestinationRow, sourceRow, sourceWidth, BRANCH_RGB565_TO_RGBA8888);
863 }
864 
RGB565ConvertBGRA8888(void *destinationRow, const uint8_t *sourceRow, uint32_t sourceWidth, const ProcFuncExtension &extension)865 static void RGB565ConvertBGRA8888(void *destinationRow, const uint8_t *sourceRow, uint32_t sourceWidth,
866                                   const ProcFuncExtension &extension)
867 {
868     uint32_t *newDestinationRow = static_cast<uint32_t *>(destinationRow);
869     RGB565Convert(newDestinationRow, sourceRow, sourceWidth, BRANCH_RGB565_TO_BGRA8888);
870 }
871 
RGB565ConvertRGBAF16(uint8_t *destinationRow, const uint8_t *sourceRow, uint32_t sourceWidth, const ProcFuncExtension &extension)872 static void RGB565ConvertRGBAF16(uint8_t *destinationRow, const uint8_t *sourceRow, uint32_t sourceWidth,
873     const ProcFuncExtension &extension)
874 {
875     void* tmp = static_cast<void *>(destinationRow);
876     uint64_t *newDestinationRow = static_cast<uint64_t *>(tmp);
877     RGB565Convert(newDestinationRow, sourceRow, sourceWidth, BRANCH_RGB565_TO_RGBAF16);
878 }
879 
880 constexpr uint32_t BRANCH_RGBAF16_TO_ARGB8888 = 0x13000001;
881 constexpr uint32_t BRANCH_RGBAF16_TO_RGBA8888 = 0x13000002;
882 constexpr uint32_t BRANCH_RGBAF16_TO_BGRA8888 = 0x13000003;
883 constexpr uint32_t BRANCH_RGBAF16_TO_ABGR8888 = 0x13000004;
884 constexpr uint32_t BRANCH_RGBAF16_TO_RGB565 = 0x13000005;
885 template<typename T>
RGBAF16Convert(T *destinationRow, const uint8_t *sourceRow, uint32_t sourceWidth, uint32_t branch, const ProcFuncExtension &extension)886 static void RGBAF16Convert(T *destinationRow, const uint8_t *sourceRow, uint32_t sourceWidth, uint32_t branch,
887                            const ProcFuncExtension &extension)
888 {
889     for (uint32_t i = 0; i < sourceWidth; i++) {
890         uint32_t R = HalfToUint32(sourceRow, IS_LITTLE_ENDIAN);
891         uint32_t G = HalfToUint32(sourceRow + 2, IS_LITTLE_ENDIAN);
892         uint32_t B = HalfToUint32(sourceRow + 4, IS_LITTLE_ENDIAN);
893         uint32_t A = HalfToUint32(sourceRow + 6, IS_LITTLE_ENDIAN);
894         AlphaTypeConvertOnRGB(A, R, G, B, extension);
895         if (branch == BRANCH_RGBAF16_TO_ARGB8888) {
896             destinationRow[i] = FillARGB8888(A, R, G, B);
897         } else if (branch == BRANCH_RGBAF16_TO_RGBA8888) {
898             destinationRow[i] = FillRGBA8888(R, G, B, A);
899         } else if (branch == BRANCH_RGBAF16_TO_BGRA8888) {
900             destinationRow[i] = FillBGRA8888(B, G, R, A);
901         } else if (branch == BRANCH_RGBAF16_TO_ABGR8888) {
902             destinationRow[i] = FillABGR8888(A, B, G, R);
903         } else if (branch == BRANCH_RGBAF16_TO_RGB565) {
904             R = R >> SHIFT_3_BIT;
905             G = G >> SHIFT_2_BIT;
906             B = B >> SHIFT_3_BIT;
907             destinationRow[i] = FillRGB565(R, G, B);
908         } else {
909             break;
910         }
911         sourceRow += SIZE_8_BYTE;
912     }
913 }
914 
RGBAF16ConvertARGB8888(uint8_t *destinationRow, const uint8_t *sourceRow, uint32_t sourceWidth, const ProcFuncExtension &extension)915 static void RGBAF16ConvertARGB8888(uint8_t *destinationRow, const uint8_t *sourceRow, uint32_t sourceWidth,
916     const ProcFuncExtension &extension)
917 {
918     void* tmp = static_cast<void *>(destinationRow);
919     uint32_t *newDestinationRow = static_cast<uint32_t *>(tmp);
920     RGBAF16Convert(newDestinationRow, sourceRow, sourceWidth, BRANCH_RGBAF16_TO_ARGB8888, extension);
921 }
922 
RGBAF16ConvertRGBA8888(uint8_t *destinationRow, const uint8_t *sourceRow, uint32_t sourceWidth, const ProcFuncExtension &extension)923 static void RGBAF16ConvertRGBA8888(uint8_t *destinationRow, const uint8_t *sourceRow, uint32_t sourceWidth,
924     const ProcFuncExtension &extension)
925 {
926     void* tmp = static_cast<void *>(destinationRow);
927     uint32_t *newDestinationRow = static_cast<uint32_t *>(tmp);
928     RGBAF16Convert(newDestinationRow, sourceRow, sourceWidth, BRANCH_RGBAF16_TO_RGBA8888, extension);
929 }
930 
RGBAF16ConvertBGRA8888(uint8_t *destinationRow, const uint8_t *sourceRow, uint32_t sourceWidth, const ProcFuncExtension &extension)931 static void RGBAF16ConvertBGRA8888(uint8_t *destinationRow, const uint8_t *sourceRow, uint32_t sourceWidth,
932     const ProcFuncExtension &extension)
933 {
934     void* tmp = static_cast<void *>(destinationRow);
935     uint32_t *newDestinationRow = static_cast<uint32_t *>(tmp);
936     RGBAF16Convert(newDestinationRow, sourceRow, sourceWidth, BRANCH_RGBAF16_TO_BGRA8888, extension);
937 }
938 
RGBAF16ConvertABGR8888(uint8_t *destinationRow, const uint8_t *sourceRow, uint32_t sourceWidth, const ProcFuncExtension &extension)939 static void RGBAF16ConvertABGR8888(uint8_t *destinationRow, const uint8_t *sourceRow, uint32_t sourceWidth,
940     const ProcFuncExtension &extension)
941 {
942     void* tmp = static_cast<void *>(destinationRow);
943     uint32_t *newDestinationRow = static_cast<uint32_t *>(tmp);
944     RGBAF16Convert(newDestinationRow, sourceRow, sourceWidth, BRANCH_RGBAF16_TO_ABGR8888, extension);
945 }
946 
RGBAF16ConvertRGB565(uint8_t *destinationRow, const uint8_t *sourceRow, uint32_t sourceWidth, const ProcFuncExtension &extension)947 static void RGBAF16ConvertRGB565(uint8_t *destinationRow, const uint8_t *sourceRow, uint32_t sourceWidth,
948     const ProcFuncExtension &extension)
949 {
950     void* tmp = static_cast<void *>(destinationRow);
951     uint16_t *newDestinationRow = static_cast<uint16_t *>(tmp);
952     RGBAF16Convert(newDestinationRow, sourceRow, sourceWidth, BRANCH_RGBAF16_TO_RGB565, extension);
953 }
954 
955 static map<string, ProcFuncType> g_procMapping;
956 static mutex g_procMutex;
957 
MakeKey(uint32_t srcFormat, uint32_t dstFormat)958 static string MakeKey(uint32_t srcFormat, uint32_t dstFormat)
959 {
960     return to_string(srcFormat) + ("_") + to_string(dstFormat);
961 }
962 
InitGrayProc()963 static void InitGrayProc()
964 {
965     g_procMapping.emplace(MakeKey(GRAY_BIT, ARGB_8888), &BitConvertARGB8888);
966     g_procMapping.emplace(MakeKey(GRAY_BIT, RGB_565), &BitConvertRGB565);
967     g_procMapping.emplace(MakeKey(GRAY_BIT, ALPHA_8), &BitConvertGray);
968 
969     g_procMapping.emplace(MakeKey(ALPHA_8, ARGB_8888), &GrayConvertARGB8888);
970     g_procMapping.emplace(MakeKey(ALPHA_8, RGB_565), &GrayConvertRGB565);
971 
972     g_procMapping.emplace(MakeKey(GRAY_ALPHA, ARGB_8888), &GrayAlphaConvertARGB8888);
973     g_procMapping.emplace(MakeKey(GRAY_ALPHA, ALPHA_8), &GrayAlphaConvertAlpha);
974 }
975 
InitRGBProc()976 static void InitRGBProc()
977 {
978     g_procMapping.emplace(MakeKey(RGB_888, ARGB_8888), &RGB888ConvertARGB8888);
979     g_procMapping.emplace(MakeKey(RGB_888, RGBA_8888), &RGB888ConvertRGBA8888);
980     g_procMapping.emplace(MakeKey(RGB_888, BGRA_8888), &RGB888ConvertBGRA8888);
981     g_procMapping.emplace(MakeKey(RGB_888, RGB_565), &RGB888ConvertRGB565);
982 
983     g_procMapping.emplace(MakeKey(BGR_888, ARGB_8888), &BGR888ConvertARGB8888);
984     g_procMapping.emplace(MakeKey(BGR_888, RGBA_8888), &BGR888ConvertRGBA8888);
985     g_procMapping.emplace(MakeKey(BGR_888, BGRA_8888), &BGR888ConvertBGRA8888);
986     g_procMapping.emplace(MakeKey(BGR_888, RGB_565), &BGR888ConvertRGB565);
987 
988     g_procMapping.emplace(MakeKey(RGB_161616, ARGB_8888), &RGB161616ConvertARGB8888);
989     g_procMapping.emplace(MakeKey(RGB_161616, ABGR_8888), &RGB161616ConvertABGR8888);
990     g_procMapping.emplace(MakeKey(RGB_161616, RGBA_8888), &RGB161616ConvertRGBA8888);
991     g_procMapping.emplace(MakeKey(RGB_161616, BGRA_8888), &RGB161616ConvertBGRA8888);
992     g_procMapping.emplace(MakeKey(RGB_161616, RGB_565), &RGB161616ConvertRGB565);
993 
994     g_procMapping.emplace(MakeKey(RGB_565, ARGB_8888), &RGB565ConvertARGB8888);
995     g_procMapping.emplace(MakeKey(RGB_565, RGBA_8888), &RGB565ConvertRGBA8888);
996     g_procMapping.emplace(MakeKey(RGB_565, BGRA_8888), &RGB565ConvertBGRA8888);
997 }
998 
InitRGBAProc()999 static void InitRGBAProc()
1000 {
1001     g_procMapping.emplace(MakeKey(RGBA_8888, RGBA_8888), &RGBA8888ConvertRGBA8888Alpha);
1002     g_procMapping.emplace(MakeKey(RGBA_8888, ARGB_8888), &RGBA8888ConvertARGB8888);
1003     g_procMapping.emplace(MakeKey(RGBA_8888, BGRA_8888), &RGBA8888ConvertBGRA8888);
1004     g_procMapping.emplace(MakeKey(RGBA_8888, RGB_565), &RGBA8888ConvertRGB565);
1005 
1006     g_procMapping.emplace(MakeKey(BGRA_8888, RGBA_8888), &BGRA8888ConvertRGBA8888);
1007     g_procMapping.emplace(MakeKey(BGRA_8888, ARGB_8888), &BGRA8888ConvertARGB8888);
1008     g_procMapping.emplace(MakeKey(BGRA_8888, BGRA_8888), &BGRA8888ConvertBGRA8888Alpha);
1009     g_procMapping.emplace(MakeKey(BGRA_8888, RGB_565), &BGRA8888ConvertRGB565);
1010 
1011     g_procMapping.emplace(MakeKey(ARGB_8888, RGBA_8888), &ARGB8888ConvertRGBA8888);
1012     g_procMapping.emplace(MakeKey(ARGB_8888, ARGB_8888), &ARGB8888ConvertARGB8888Alpha);
1013     g_procMapping.emplace(MakeKey(ARGB_8888, BGRA_8888), &ARGB8888ConvertBGRA8888);
1014     g_procMapping.emplace(MakeKey(ARGB_8888, RGB_565), &ARGB8888ConvertRGB565);
1015 
1016     g_procMapping.emplace(MakeKey(RGBA_16161616, ARGB_8888), &RGBA16161616ConvertARGB8888);
1017     g_procMapping.emplace(MakeKey(RGBA_16161616, RGBA_8888), &RGBA16161616ConvertRGBA8888);
1018     g_procMapping.emplace(MakeKey(RGBA_16161616, BGRA_8888), &RGBA16161616ConvertBGRA8888);
1019     g_procMapping.emplace(MakeKey(RGBA_16161616, ABGR_8888), &RGBA16161616ConvertABGR8888);
1020 }
1021 
InitCMYKProc()1022 static void InitCMYKProc()
1023 {
1024     g_procMapping.emplace(MakeKey(CMKY, ARGB_8888), &CMYKConvertARGB8888);
1025     g_procMapping.emplace(MakeKey(CMKY, RGBA_8888), &CMYKConvertRGBA8888);
1026     g_procMapping.emplace(MakeKey(CMKY, BGRA_8888), &CMYKConvertBGRA8888);
1027     g_procMapping.emplace(MakeKey(CMKY, ABGR_8888), &CMYKConvertABGR8888);
1028     g_procMapping.emplace(MakeKey(CMKY, RGB_565), &CMYKConvertRGB565);
1029 }
1030 
InitF16Proc()1031 static void InitF16Proc()
1032 {
1033     g_procMapping.emplace(MakeKey(RGBA_F16, ARGB_8888),
1034         reinterpret_cast<ProcFuncType>(&RGBAF16ConvertARGB8888));
1035     g_procMapping.emplace(MakeKey(RGBA_F16, RGBA_8888),
1036         reinterpret_cast<ProcFuncType>(&RGBAF16ConvertRGBA8888));
1037     g_procMapping.emplace(MakeKey(RGBA_F16, BGRA_8888),
1038         reinterpret_cast<ProcFuncType>(&RGBAF16ConvertBGRA8888));
1039     g_procMapping.emplace(MakeKey(RGBA_F16, ABGR_8888),
1040         reinterpret_cast<ProcFuncType>(&RGBAF16ConvertABGR8888));
1041     g_procMapping.emplace(MakeKey(RGBA_F16, RGB_565),
1042         reinterpret_cast<ProcFuncType>(&RGBAF16ConvertRGB565));
1043 
1044     g_procMapping.emplace(MakeKey(BGR_888, RGBA_F16),
1045         reinterpret_cast<ProcFuncType>(&BGR888ConvertRGBAF16));
1046     g_procMapping.emplace(MakeKey(RGB_888, RGBA_F16),
1047         reinterpret_cast<ProcFuncType>(&RGB888ConvertRGBAF16));
1048     g_procMapping.emplace(MakeKey(RGB_161616, RGBA_F16),
1049         reinterpret_cast<ProcFuncType>(&RGB161616ConvertRGBAF16));
1050     g_procMapping.emplace(MakeKey(ARGB_8888, RGBA_F16),
1051         reinterpret_cast<ProcFuncType>(&ARGB8888ConvertRGBAF16));
1052     g_procMapping.emplace(MakeKey(RGBA_8888, RGBA_F16),
1053         reinterpret_cast<ProcFuncType>(&RGBA8888ConvertRGBAF16));
1054     g_procMapping.emplace(MakeKey(BGRA_8888, RGBA_F16),
1055         reinterpret_cast<ProcFuncType>(&BGRA8888ConvertRGBAF16));
1056     g_procMapping.emplace(MakeKey(RGB_565, RGBA_F16),
1057         reinterpret_cast<ProcFuncType>(&RGB565ConvertRGBAF16));
1058     g_procMapping.emplace(MakeKey(RGBA_16161616, RGBA_F16),
1059         reinterpret_cast<ProcFuncType>(&RGBA16161616ConvertRGBAF16));
1060 }
1061 
GetProcFuncType(uint32_t srcPixelFormat, uint32_t dstPixelFormat)1062 static ProcFuncType GetProcFuncType(uint32_t srcPixelFormat, uint32_t dstPixelFormat)
1063 {
1064     unique_lock<mutex> guard(g_procMutex);
1065     if (g_procMapping.empty()) {
1066         InitGrayProc();
1067         InitRGBProc();
1068         InitRGBAProc();
1069         InitCMYKProc();
1070         InitF16Proc();
1071     }
1072     guard.unlock();
1073     string procKey = MakeKey(srcPixelFormat, dstPixelFormat);
1074     map<string, ProcFuncType>::iterator iter = g_procMapping.find(procKey);
1075     if (iter != g_procMapping.end()) {
1076         return iter->second;
1077     }
1078     return nullptr;
1079 }
1080 
PixelFormatToAVPixelFormat(const PixelFormat &pixelFormat)1081 static AVPixelFormat PixelFormatToAVPixelFormat(const PixelFormat &pixelFormat)
1082 {
1083     auto formatSearch = PixelConvertAdapter::FFMPEG_PIXEL_FORMAT_MAP.find(pixelFormat);
1084     return (formatSearch != PixelConvertAdapter::FFMPEG_PIXEL_FORMAT_MAP.end()) ?
1085         formatSearch->second : AVPixelFormat::AV_PIX_FMT_NONE;
1086 }
1087 
1088 typedef struct FFMpegConvertInfo {
1089     AVPixelFormat format = AVPixelFormat::AV_PIX_FMT_NONE;
1090     int32_t width = 0;
1091     int32_t height = 0;
1092     int32_t alignSize = 1;
1093 } FFMPEG_CONVERT_INFO;
1094 
FFMpegConvert(const void *srcPixels, const FFMPEG_CONVERT_INFO& srcInfo, void *dstPixels, const FFMPEG_CONVERT_INFO& dstInfo)1095 static bool FFMpegConvert(const void *srcPixels, const FFMPEG_CONVERT_INFO& srcInfo,
1096     void *dstPixels, const FFMPEG_CONVERT_INFO& dstInfo)
1097 {
1098     bool ret = true;
1099     AVFrame *inputFrame = nullptr;
1100     AVFrame *outputFrame = nullptr;
1101 
1102     if (srcInfo.format == AVPixelFormat::AV_PIX_FMT_NONE ||
1103         dstInfo.format == AVPixelFormat::AV_PIX_FMT_NONE) {
1104         IMAGE_LOGE("unsupport src/dst pixel format!");
1105         return false;
1106     }
1107     if (srcInfo.width <= 0 || srcInfo.height <= 0 || dstInfo.width <= 0 || dstInfo.height <= 0) {
1108         IMAGE_LOGE("src/dst width/height error!");
1109         return false;
1110     }
1111 
1112     inputFrame = av_frame_alloc();
1113     outputFrame = av_frame_alloc();
1114     if (inputFrame != nullptr && outputFrame != nullptr) {
1115         struct SwsContext *ctx = sws_getContext(srcInfo.width, srcInfo.height, srcInfo.format,
1116             dstInfo.width, dstInfo.height, dstInfo.format, SWS_POINT, nullptr, nullptr, nullptr);
1117         IMAGE_LOGE("srcInfo.width:%{public}d, srcInfo.height:%{public}d", srcInfo.width, srcInfo.height);
1118         if (ctx != nullptr) {
1119             av_image_fill_arrays(inputFrame->data, inputFrame->linesize, (uint8_t *)srcPixels,
1120                 srcInfo.format, srcInfo.width, srcInfo.height, srcInfo.alignSize);
1121             av_image_fill_arrays(outputFrame->data, outputFrame->linesize, (uint8_t *)dstPixels,
1122                 dstInfo.format, dstInfo.width, dstInfo.height, dstInfo.alignSize);
1123 
1124             sws_scale(ctx, (uint8_t const **)inputFrame->data, inputFrame->linesize, 0, srcInfo.height,
1125                 outputFrame->data, outputFrame->linesize);
1126             sws_freeContext(ctx);
1127         } else {
1128             IMAGE_LOGE("FFMpeg: sws_getContext failed!");
1129             ret = false;
1130         }
1131     } else {
1132         IMAGE_LOGE("FFMpeg: av_frame_alloc failed!");
1133         ret = false;
1134     }
1135     av_frame_free(&inputFrame);
1136     av_frame_free(&outputFrame);
1137     return ret;
1138 }
1139 
NV12P010ToNV21P010(const uint16_t *srcBuffer, const ImageInfo &info, uint16_t *destBuffer)1140 static bool NV12P010ToNV21P010(const uint16_t *srcBuffer, const ImageInfo &info, uint16_t *destBuffer)
1141 {
1142     const uint16_t *srcUV = srcBuffer + info.size.width * info.size.height;
1143     uint16_t *dstVU = destBuffer + info.size.width * info.size.height;
1144     uint32_t sizeUV = info.size.width * info.size.height / NUM_2;
1145     for (uint32_t i = 0; i < info.size.width * info.size.height; i++) {
1146         destBuffer[i] = srcBuffer[i];
1147     }
1148     for (uint32_t i = 0; i < sizeUV; i += NUM_2) {
1149         dstVU[i] = srcUV[i + 1];
1150         dstVU[i + 1] = srcUV[i];
1151     }
1152     return true;
1153 }
1154 
IsYUVP010Format(PixelFormat format)1155 bool IsYUVP010Format(PixelFormat format)
1156 {
1157     return (format == PixelFormat::YCBCR_P010) || (format == PixelFormat::YCRCB_P010);
1158 }
1159 
ConvertForFFMPEG(const void *srcPixels, PixelFormat srcpixelmap, ImageInfo srcInfo, void *dstPixels, PixelFormat dstpixelmap)1160 static bool ConvertForFFMPEG(const void *srcPixels, PixelFormat srcpixelmap, ImageInfo srcInfo,
1161     void *dstPixels, PixelFormat dstpixelmap)
1162 {
1163     FFMPEG_CONVERT_INFO srcFFmpegInfo = {PixelFormatToAVPixelFormat(srcpixelmap),
1164         srcInfo.size.width, srcInfo.size.height, 1};
1165     FFMPEG_CONVERT_INFO dstFFmpegInfo = {PixelFormatToAVPixelFormat(dstpixelmap),
1166         srcInfo.size.width, srcInfo.size.height, 1};
1167     if (!FFMpegConvert(srcPixels, srcFFmpegInfo, dstPixels, dstFFmpegInfo)) {
1168         IMAGE_LOGE("[PixelMap]Convert: ffmpeg convert failed!");
1169         return false;
1170     }
1171     return true;
1172 }
1173 
1174 // Convert and collapse pixels by removing line paddings if any
ConvertAndCollapseByFFMpeg(const void *srcPixels, const ImageInfo &srcInfo, void *dstPixels, const ImageInfo &dstInfo, bool useDMA)1175 static bool ConvertAndCollapseByFFMpeg(const void *srcPixels, const ImageInfo &srcInfo, void *dstPixels,
1176     const ImageInfo &dstInfo, bool useDMA)
1177 {
1178     FFMPEG_CONVERT_INFO srcFFMpegInfo = {PixelFormatToAVPixelFormat(srcInfo.pixelFormat),
1179         srcInfo.size.width, srcInfo.size.height, useDMA ? DMA_LINE_SIZE : 1};
1180     FFMPEG_CONVERT_INFO dstFFMpegInfo = {PixelFormatToAVPixelFormat(dstInfo.pixelFormat),
1181         dstInfo.size.width, dstInfo.size.height, 1};
1182     if (!FFMpegConvert(srcPixels, srcFFMpegInfo, dstPixels, dstFFMpegInfo)) {
1183         IMAGE_LOGE("[PixelMap] ConvertAndCollapseByFFMpeg: FFMpeg convert failed!");
1184         return false;
1185     }
1186     return true;
1187 }
1188 
P010ConvertRGBA1010102(const void *srcPixels, ImageInfo srcInfo, void *dstPixels, ImageInfo dstInfo)1189 static bool P010ConvertRGBA1010102(const void *srcPixels, ImageInfo srcInfo,
1190     void *dstPixels, ImageInfo dstInfo)
1191 {
1192     FFMPEG_CONVERT_INFO srcFFmpegInfo = {PixelFormatToAVPixelFormat(srcInfo.pixelFormat),
1193         srcInfo.size.width, srcInfo.size.height, 1};
1194     FFMPEG_CONVERT_INFO tmpFFmpegInfo = {PixelFormatToAVPixelFormat(PixelFormat::RGBA_F16),
1195         srcInfo.size.width, srcInfo.size.height, 1};
1196     int tmpPixelsLen = av_image_get_buffer_size(tmpFFmpegInfo.format, tmpFFmpegInfo.width, tmpFFmpegInfo.height,
1197         tmpFFmpegInfo.alignSize);
1198     if (tmpPixelsLen <= 0) {
1199         IMAGE_LOGE("[PixelMap]Convert: Get tmp pixels length failed!");
1200         return false;
1201     }
1202     uint8_t* tmpPixels = new(std::nothrow) uint8_t[tmpPixelsLen];
1203     if (tmpPixels == nullptr) {
1204         IMAGE_LOGE("[PixelMap]Convert: alloc memory failed!");
1205         return false;
1206     }
1207     memset_s(tmpPixels, tmpPixelsLen, 0, tmpPixelsLen);
1208     if (!FFMpegConvert(srcPixels, srcFFmpegInfo, tmpPixels, tmpFFmpegInfo)) {
1209         IMAGE_LOGE("[PixelMap]Convert: ffmpeg convert failed!");
1210         delete[] tmpPixels;
1211         tmpPixels = nullptr;
1212         return false;
1213     }
1214     ImageInfo tmpInfo = srcInfo;
1215     tmpInfo.pixelFormat = PixelFormat::RGBA_U16;
1216     tmpInfo.alphaType = AlphaType::IMAGE_ALPHA_TYPE_PREMUL;
1217     Position pos;
1218     if (!PixelConvertAdapter::WritePixelsConvert(tmpPixels, PixelMap::GetRGBxRowDataSize(tmpInfo), tmpInfo,
1219         dstPixels, pos, PixelMap::GetRGBxRowDataSize(dstInfo), dstInfo)) {
1220         IMAGE_LOGE("[PixelMap]Convert: ConvertFromYUV: pixel convert in adapter failed.");
1221         delete[] tmpPixels;
1222         tmpPixels = nullptr;
1223         return false;
1224     }
1225     delete[] tmpPixels;
1226     tmpPixels = nullptr;
1227     return true;
1228 }
1229 
ConvertRGBA1010102ToYUV(const void *srcPixels, ImageInfo srcInfo, void *dstPixels, ImageInfo dstInfo)1230 static bool ConvertRGBA1010102ToYUV(const void *srcPixels, ImageInfo srcInfo,
1231     void *dstPixels, ImageInfo dstInfo)
1232 {
1233     ImageInfo tmpInfo = srcInfo;
1234     tmpInfo.pixelFormat = PixelFormat::RGBA_U16;
1235     int tmpPixelsLen = PixelMap::GetRGBxByteCount(tmpInfo);
1236     if (tmpPixelsLen <= 0) {
1237         IMAGE_LOGE("[PixelMap]Convert: Get tmp pixels length failed!");
1238         return false;
1239     }
1240     uint8_t* tmpPixels = new(std::nothrow) uint8_t[tmpPixelsLen];
1241     if (tmpPixels == nullptr) {
1242         IMAGE_LOGE("[PixelMap]Convert: alloc memory failed!");
1243         return false;
1244     }
1245     memset_s(tmpPixels, tmpPixelsLen, 0, tmpPixelsLen);
1246 
1247     Position pos;
1248     if (!PixelConvertAdapter::WritePixelsConvert(srcPixels, PixelMap::GetRGBxRowDataSize(srcInfo), srcInfo,
1249         tmpPixels, pos, PixelMap::GetRGBxRowDataSize(tmpInfo), tmpInfo)) {
1250         IMAGE_LOGE("[PixelMap]Convert: ConvertToYUV: pixel convert in adapter failed.");
1251         delete[] tmpPixels;
1252         tmpPixels = nullptr;
1253         return false;
1254     }
1255 
1256     FFMPEG_CONVERT_INFO srcFFmpegInfo = {PixelFormatToAVPixelFormat(PixelFormat::RGBA_F16),
1257         tmpInfo.size.width, tmpInfo.size.height, 1};
1258     FFMPEG_CONVERT_INFO dstFFmpegInfo = {PixelFormatToAVPixelFormat(dstInfo.pixelFormat),
1259         dstInfo.size.width, dstInfo.size.height, 1};
1260     if (!FFMpegConvert(tmpPixels, srcFFmpegInfo, dstPixels, dstFFmpegInfo)) {
1261         IMAGE_LOGE("[PixelMap]Convert: ffmpeg convert failed!");
1262         delete[] tmpPixels;
1263         tmpPixels = nullptr;
1264         return false;
1265     }
1266     delete[] tmpPixels;
1267     tmpPixels = nullptr;
1268     return true;
1269 }
1270 
YUVConvertRGB(const void *srcPixels, const ImageInfo &srcInfo, void *dstPixels, const ImageInfo &dstInfo)1271 static int32_t YUVConvertRGB(const void *srcPixels, const ImageInfo &srcInfo,
1272     void *dstPixels, const ImageInfo &dstInfo)
1273 {
1274     FFMPEG_CONVERT_INFO srcFFmpegInfo = {PixelFormatToAVPixelFormat(srcInfo.pixelFormat),
1275         srcInfo.size.width, srcInfo.size.height, 1};
1276     FFMPEG_CONVERT_INFO tmpFFmpegInfo = {PixelFormatToAVPixelFormat(PixelFormat::RGB_888),
1277         srcInfo.size.width, srcInfo.size.height, 1};
1278     int tmpPixelsLen = av_image_get_buffer_size(tmpFFmpegInfo.format, tmpFFmpegInfo.width, tmpFFmpegInfo.height,
1279         tmpFFmpegInfo.alignSize);
1280     if (tmpPixelsLen <= 0) {
1281         IMAGE_LOGE("[PixelMap]Convert: Get tmp pixels length failed!");
1282         return -1;
1283     }
1284     uint8_t* tmpPixels = new(std::nothrow) uint8_t[tmpPixelsLen];
1285     if (tmpPixels == nullptr) {
1286         IMAGE_LOGE("[PixelMap]Convert: alloc memory failed!");
1287         return -1;
1288     }
1289     memset_s(tmpPixels, tmpPixelsLen, 0, tmpPixelsLen);
1290     if (!FFMpegConvert(srcPixels, srcFFmpegInfo, (void *)tmpPixels, tmpFFmpegInfo)) {
1291         IMAGE_LOGE("[PixelMap]Convert: ffmpeg convert failed!");
1292         delete[] tmpPixels;
1293         tmpPixels = nullptr;
1294         return -1;
1295     }
1296 
1297     ImageInfo tmpInfo = srcInfo;
1298     tmpInfo.pixelFormat = PixelFormat::RGB_888;
1299     Position pos;
1300     if (!PixelConvertAdapter::WritePixelsConvert(tmpPixels, PixelMap::GetRGBxRowDataSize(tmpInfo), tmpInfo,
1301         dstPixels, pos, PixelMap::GetRGBxRowDataSize(dstInfo), dstInfo)) {
1302         IMAGE_LOGE("[PixelMap]Convert: ConvertFromYUV: pixel convert in adapter failed.");
1303         delete[] tmpPixels;
1304         tmpPixels = nullptr;
1305         return -1;
1306     }
1307 
1308     delete[] tmpPixels;
1309     tmpPixels = nullptr;
1310     return PixelMap::GetRGBxByteCount(dstInfo);
1311 }
1312 
ConvertFromYUV(const void *srcPixels, const int32_t srcLength, const ImageInfo &srcInfo, void *dstPixels, const ImageInfo &dstInfo)1313 static int32_t ConvertFromYUV(const void *srcPixels, const int32_t srcLength, const ImageInfo &srcInfo,
1314     void *dstPixels, const ImageInfo &dstInfo)
1315 {
1316     if (srcPixels == nullptr || dstPixels == nullptr || srcLength <= 0) {
1317         IMAGE_LOGE("[PixelMap]Convert: src pixels or dst pixels or src pixels length invalid.");
1318         return -1;
1319     }
1320     if ((srcInfo.pixelFormat != PixelFormat::NV21 && srcInfo.pixelFormat != PixelFormat::NV12) ||
1321         (dstInfo.pixelFormat == PixelFormat::NV21 || dstInfo.pixelFormat == PixelFormat::NV12)) {
1322         IMAGE_LOGE("[PixelMap]Convert: src or dst pixel format invalid.");
1323         return -1;
1324     }
1325     if ((srcInfo.pixelFormat == PixelFormat::NV12 && dstInfo.pixelFormat == PixelFormat::YCBCR_P010) ||
1326         (srcInfo.pixelFormat == PixelFormat::NV21 && dstInfo.pixelFormat == PixelFormat::YCRCB_P010)) {
1327         return ConvertForFFMPEG(srcPixels, PixelFormat::NV12, srcInfo, dstPixels,
1328             PixelFormat::YCBCR_P010) == true ? PixelMap::GetYUVByteCount(dstInfo) : -1;
1329     }
1330     if ((srcInfo.pixelFormat == PixelFormat::NV12 && dstInfo.pixelFormat == PixelFormat::YCRCB_P010) ||
1331         (srcInfo.pixelFormat == PixelFormat::NV21 && dstInfo.pixelFormat == PixelFormat::YCBCR_P010)) {
1332         return ConvertForFFMPEG(srcPixels, PixelFormat::NV21, srcInfo, dstPixels,
1333             PixelFormat::YCBCR_P010) == true ? PixelMap::GetYUVByteCount(dstInfo) : -1;
1334     }
1335 
1336     return YUVConvertRGB(srcPixels, srcInfo, dstPixels, dstInfo);
1337 }
1338 
ConvertFromP010(const void *srcPixels, const int32_t srcLength, const ImageInfo &srcInfo, void *dstPixels, const ImageInfo &dstInfo)1339 static int32_t ConvertFromP010(const void *srcPixels, const int32_t srcLength, const ImageInfo &srcInfo,
1340     void *dstPixels, const ImageInfo &dstInfo)
1341 {
1342     if (srcPixels == nullptr || dstPixels == nullptr || srcLength <= 0) {
1343         IMAGE_LOGE("[PixelMap]Convert: src pixels or dst pixels or src pixels length invalid.");
1344         return -1;
1345     }
1346     if ((srcInfo.pixelFormat != PixelFormat::YCRCB_P010 && srcInfo.pixelFormat != PixelFormat::YCBCR_P010) ||
1347         IsYUVP010Format(dstInfo.pixelFormat)) {
1348         IMAGE_LOGE("[PixelMap]Convert: src or dst pixel format invalid.");
1349         return -1;
1350     }
1351     uint8_t* srcP010 = new(std::nothrow) uint8_t[srcLength];
1352     if (srcP010 == nullptr) {
1353         IMAGE_LOGE("[PixelMap]Convert: alloc memory failed!");
1354         return -1;
1355     }
1356     memset_s(srcP010, srcLength, 0, srcLength);
1357     if (srcInfo.pixelFormat == PixelFormat::YCRCB_P010) {
1358         NV12P010ToNV21P010((uint16_t *)srcPixels, srcInfo, (uint16_t *)srcP010);
1359     } else {
1360         if (memcpy_s(srcP010, srcLength, srcPixels, srcLength) != 0) {
1361             delete[] srcP010;
1362             srcP010 = nullptr;
1363             return -1;
1364         }
1365     }
1366     if (dstInfo.pixelFormat == PixelFormat::RGBA_1010102) {
1367         if (P010ConvertRGBA1010102(srcP010, srcInfo, dstPixels, dstInfo)) {
1368             delete[] srcP010;
1369             srcP010 = nullptr;
1370             return PixelMap::GetRGBxByteCount(dstInfo);
1371         }
1372         delete[] srcP010;
1373         srcP010 = nullptr;
1374         return -1;
1375     } else {
1376         if (ConvertForFFMPEG(srcP010, srcInfo.pixelFormat, srcInfo, dstPixels, dstInfo.pixelFormat)) {
1377             delete[] srcP010;
1378             srcP010 = nullptr;
1379             return PixelMap::GetRGBxByteCount(dstInfo);
1380         }
1381         delete[] srcP010;
1382         srcP010 = nullptr;
1383         return -1;
1384     }
1385 }
1386 
RGBConvertYUV(const void *srcPixels, const ImageInfo &srcInfo, void *dstPixels, const ImageInfo &dstInfo)1387 static int32_t RGBConvertYUV(const void *srcPixels, const ImageInfo &srcInfo,
1388     void *dstPixels, const ImageInfo &dstInfo)
1389 {
1390     ImageInfo tmpInfo = srcInfo;
1391     tmpInfo.pixelFormat = PixelFormat::RGB_888;
1392     int tmpPixelsLen = PixelMap::GetRGBxByteCount(tmpInfo);
1393     if (tmpPixelsLen <= 0) {
1394         IMAGE_LOGE("[PixelMap]Convert: Get tmp pixels length failed!");
1395         return -1;
1396     }
1397     uint8_t* tmpPixels = new(std::nothrow) uint8_t[tmpPixelsLen];
1398     if (tmpPixels == nullptr) {
1399         IMAGE_LOGE("[PixelMap]Convert: alloc memory failed!");
1400         return -1;
1401     }
1402     memset_s(tmpPixels, tmpPixelsLen, 0, tmpPixelsLen);
1403     Position pos;
1404     if (!PixelConvertAdapter::WritePixelsConvert(srcPixels, PixelMap::GetRGBxRowDataSize(srcInfo), srcInfo,
1405         tmpPixels, pos, PixelMap::GetRGBxRowDataSize(tmpInfo), tmpInfo)) {
1406         IMAGE_LOGE("[PixelMap]Convert: ConvertToYUV: pixel convert in adapter failed.");
1407         delete[] tmpPixels;
1408         tmpPixels = nullptr;
1409         return -1;
1410     }
1411     FFMPEG_CONVERT_INFO srcFFmpegInfo = {PixelFormatToAVPixelFormat(PixelFormat::RGB_888),
1412         tmpInfo.size.width, tmpInfo.size.height, 1};
1413     FFMPEG_CONVERT_INFO dstFFmpegInfo = {PixelFormatToAVPixelFormat(dstInfo.pixelFormat),
1414         dstInfo.size.width, dstInfo.size.height, 1};
1415     if (!FFMpegConvert(tmpPixels, srcFFmpegInfo, (void *)dstPixels, dstFFmpegInfo)) {
1416         IMAGE_LOGE("[PixelMap]Convert: ffmpeg convert failed!");
1417         delete[] tmpPixels;
1418         tmpPixels = nullptr;
1419         return -1;
1420     }
1421     delete[] tmpPixels;
1422     tmpPixels = nullptr;
1423     return av_image_get_buffer_size(dstFFmpegInfo.format, dstFFmpegInfo.width, dstFFmpegInfo.height,
1424         dstFFmpegInfo.alignSize);
1425 }
1426 
ConvertToYUV(const void *srcPixels, const int32_t srcLength, const ImageInfo &srcInfo, void *dstPixels, const ImageInfo &dstInfo)1427 static int32_t ConvertToYUV(const void *srcPixels, const int32_t srcLength, const ImageInfo &srcInfo,
1428     void *dstPixels, const ImageInfo &dstInfo)
1429 {
1430     if (srcPixels == nullptr || dstPixels == nullptr || srcLength <= 0) {
1431         IMAGE_LOGE("[PixelMap]Convert: src pixels or dst pixels or src pixel length invalid");
1432         return -1;
1433     }
1434     if ((srcInfo.pixelFormat == PixelFormat::NV21 || srcInfo.pixelFormat == PixelFormat::NV12) ||
1435         (dstInfo.pixelFormat != PixelFormat::NV21 && dstInfo.pixelFormat != PixelFormat::NV12)) {
1436         IMAGE_LOGE("[PixelMap]Convert: src or dst pixel format invalid.");
1437         return -1;
1438     }
1439     if ((srcInfo.pixelFormat == PixelFormat::YCBCR_P010 && dstInfo.pixelFormat == PixelFormat::NV12) ||
1440         (srcInfo.pixelFormat == PixelFormat::YCRCB_P010 && dstInfo.pixelFormat == PixelFormat::NV21)) {
1441         return ConvertForFFMPEG(srcPixels, PixelFormat::YCBCR_P010, srcInfo, dstPixels,
1442             PixelFormat::NV12) == true ? PixelMap::GetYUVByteCount(dstInfo) : -1;
1443     }
1444     if ((srcInfo.pixelFormat == PixelFormat::YCBCR_P010 && dstInfo.pixelFormat == PixelFormat::NV21) ||
1445         (srcInfo.pixelFormat == PixelFormat::YCRCB_P010 && dstInfo.pixelFormat == PixelFormat::NV12)) {
1446         return ConvertForFFMPEG(srcPixels, PixelFormat::YCBCR_P010, srcInfo, dstPixels,
1447             PixelFormat::NV21) == true ? PixelMap::GetYUVByteCount(dstInfo) : -1;
1448     }
1449     return RGBConvertYUV(srcPixels, srcInfo, dstPixels, dstInfo);
1450 }
1451 
ConvertToP010(const void *srcPixels, const int32_t srcLength, const ImageInfo &srcInfo, void *dstPixels, const ImageInfo &dstInfo)1452 static int32_t ConvertToP010(const void *srcPixels, const int32_t srcLength, const ImageInfo &srcInfo,
1453     void *dstPixels, const ImageInfo &dstInfo)
1454 {
1455     if (srcPixels == nullptr || dstPixels == nullptr || srcLength <= 0) {
1456         IMAGE_LOGE("[PixelMap]Convert: src pixels or dst pixels or src pixel length invalid");
1457         return -1;
1458     }
1459     if (IsYUVP010Format(srcInfo.pixelFormat) ||
1460         (dstInfo.pixelFormat != PixelFormat::YCRCB_P010 && dstInfo.pixelFormat != PixelFormat::YCBCR_P010)) {
1461         IMAGE_LOGE("[PixelMap]Convert: src or dst pixel format invalid.");
1462         return -1;
1463     }
1464     int32_t dstLength = PixelMap::GetYUVByteCount(dstInfo);
1465     if (dstLength <= 0) {
1466         IMAGE_LOGE("[PixelMap]Convert: Get dstP010 length failed!");
1467         return -1;
1468     }
1469     uint8_t* dstP010 = new(std::nothrow) uint8_t[dstLength];
1470     if (dstP010 == nullptr) {
1471         IMAGE_LOGE("[PixelMap]Convert: alloc memory failed!");
1472         return -1;
1473     }
1474     memset_s(dstP010, dstLength, 0, dstLength);
1475 
1476     if (srcInfo.pixelFormat == PixelFormat::RGBA_1010102) {
1477         if (!ConvertRGBA1010102ToYUV(srcPixels, srcInfo, dstP010, dstInfo)) {
1478             delete[] dstP010;
1479             dstP010 = nullptr;
1480             return -1;
1481         }
1482     } else {
1483         if (!ConvertForFFMPEG(srcPixels, srcInfo.pixelFormat, srcInfo, dstP010, dstInfo.pixelFormat)) {
1484             delete[] dstP010;
1485             dstP010 = nullptr;
1486             return -1;
1487         }
1488     }
1489     if (dstInfo.pixelFormat == PixelFormat::YCRCB_P010) {
1490         NV12P010ToNV21P010((uint16_t *)dstP010, dstInfo, (uint16_t *)dstPixels);
1491     } else {
1492         if (memcpy_s(dstPixels, dstLength, dstP010, dstLength) != 0) {
1493             delete[] dstP010;
1494             dstP010 = nullptr;
1495             return -1;
1496         }
1497     }
1498     delete[] dstP010;
1499     dstP010 = nullptr;
1500     return dstLength;
1501 }
1502 
YUVConvert(const void *srcPixels, const int32_t srcLength, const ImageInfo &srcInfo, void *dstPixels, const ImageInfo &dstInfo)1503 static int32_t YUVConvert(const void *srcPixels, const int32_t srcLength, const ImageInfo &srcInfo,
1504     void *dstPixels, const ImageInfo &dstInfo)
1505 {
1506     if (srcInfo.pixelFormat == dstInfo.pixelFormat &&
1507         srcInfo.size.width == dstInfo.size.width && srcInfo.size.height == dstInfo.size.height) {
1508             IMAGE_LOGE("src pixel format is equal dst pixel format. no need to convert.");
1509             auto result = memcpy_s(dstPixels, srcLength, srcPixels, srcLength);
1510             return result == 0 ? srcLength : -1;
1511     }
1512     if (IsYUVP010Format(srcInfo.pixelFormat) && IsYUVP010Format(dstInfo.pixelFormat)) {
1513         if (srcInfo.size.width == dstInfo.size.width && srcInfo.size.height == dstInfo.size.height) {
1514             return NV12P010ToNV21P010((uint16_t *)srcPixels, dstInfo, (uint16_t *)dstPixels) == true ?
1515                 srcLength : -1;
1516         }
1517     }
1518     FFMPEG_CONVERT_INFO srcFFmpegInfo = {PixelFormatToAVPixelFormat(srcInfo.pixelFormat), srcInfo.size.width,
1519         srcInfo.size.height, 1};
1520     FFMPEG_CONVERT_INFO dstFFmpegInfo = {PixelFormatToAVPixelFormat(dstInfo.pixelFormat), dstInfo.size.width,
1521         dstInfo.size.height, 1};
1522     if (!FFMpegConvert(srcPixels, srcFFmpegInfo, dstPixels, dstFFmpegInfo)) {
1523         IMAGE_LOGE("[PixelMap]Convert: ffmpeg convert failed!");
1524         return -1;
1525     }
1526     return av_image_get_buffer_size(dstFFmpegInfo.format, dstFFmpegInfo.width, dstFFmpegInfo.height,
1527         dstFFmpegInfo.alignSize);
1528 }
1529 
IsInterYUVConvert(PixelFormat srcPixelFormat, PixelFormat dstPixelFormat)1530 static bool IsInterYUVConvert(PixelFormat srcPixelFormat, PixelFormat dstPixelFormat)
1531 {
1532     return (srcPixelFormat == PixelFormat::NV12 || srcPixelFormat == PixelFormat::NV21) &&
1533         (dstPixelFormat == PixelFormat::NV12 || dstPixelFormat == PixelFormat::NV21);
1534 }
1535 
PixelsConvert(const BufferInfo &src, BufferInfo &dst, int32_t srcLength, bool useDMA)1536 int32_t PixelConvert::PixelsConvert(const BufferInfo &src, BufferInfo &dst, int32_t srcLength, bool useDMA)
1537 {
1538     if (!IsValidBufferInfo(src) || !IsValidBufferInfo(dst) || srcLength <= 0) {
1539         IMAGE_LOGE("[PixelMap]Convert: pixels or image info or row stride or src pixels length invalid.");
1540         return -1;
1541     }
1542 
1543     if (dst.imageInfo.pixelFormat == PixelFormat::ARGB_8888) {
1544         return ConvertAndCollapseByFFMpeg(src.pixels, src.imageInfo, dst.pixels, dst.imageInfo, useDMA) ?
1545             PixelMap::GetRGBxByteCount(dst.imageInfo) : -1;
1546     }
1547     if (IsInterYUVConvert(src.imageInfo.pixelFormat, dst.imageInfo.pixelFormat) ||
1548         (IsYUVP010Format(src.imageInfo.pixelFormat) && IsYUVP010Format(dst.imageInfo.pixelFormat))) {
1549         return YUVConvert(src.pixels, srcLength, src.imageInfo, dst.pixels, dst.imageInfo);
1550     }
1551     if (src.imageInfo.pixelFormat == PixelFormat::NV12 || src.imageInfo.pixelFormat == PixelFormat::NV21) {
1552         return ConvertFromYUV(src.pixels, srcLength, src.imageInfo, dst.pixels, dst.imageInfo);
1553     } else if (dst.imageInfo.pixelFormat == PixelFormat::NV12 || dst.imageInfo.pixelFormat == PixelFormat::NV21) {
1554         return ConvertToYUV(src.pixels, srcLength, src.imageInfo, dst.pixels, dst.imageInfo);
1555     } else if (IsYUVP010Format(src.imageInfo.pixelFormat)) {
1556         return ConvertFromP010(src.pixels, srcLength, src.imageInfo, dst.pixels, dst.imageInfo);
1557     } else if (IsYUVP010Format(dst.imageInfo.pixelFormat)) {
1558         return ConvertToP010(src.pixels, srcLength, src.imageInfo, dst.pixels, dst.imageInfo);
1559     }
1560 
1561     Position pos;
1562     if (!PixelConvertAdapter::WritePixelsConvert(src.pixels,
1563         src.rowStride == 0 ? PixelMap::GetRGBxRowDataSize(src.imageInfo) : src.rowStride, src.imageInfo,
1564         dst.pixels, pos, useDMA ? dst.rowStride : PixelMap::GetRGBxRowDataSize(dst.imageInfo), dst.imageInfo)) {
1565         IMAGE_LOGE("[PixelMap]Convert: PixelsConvert: pixel convert in adapter failed.");
1566         return -1;
1567     }
1568 
1569     return PixelMap::GetRGBxByteCount(dst.imageInfo);
1570 }
1571 
PixelConvert(ProcFuncType funcPtr, ProcFuncExtension extension, bool isNeedConvert)1572 PixelConvert::PixelConvert(ProcFuncType funcPtr, ProcFuncExtension extension, bool isNeedConvert)
1573     : procFunc_(funcPtr), procFuncExtension_(extension), isNeedConvert_(isNeedConvert)
1574 {}
1575 
1576 // caller need setting the correct pixelFormat and alphaType
Create(const ImageInfo &srcInfo, const ImageInfo &dstInfo)1577 std::unique_ptr<PixelConvert> PixelConvert::Create(const ImageInfo &srcInfo, const ImageInfo &dstInfo)
1578 {
1579     if (srcInfo.pixelFormat == PixelFormat::UNKNOWN || dstInfo.pixelFormat == PixelFormat::UNKNOWN) {
1580         IMAGE_LOGE("source or destination pixel format unknown");
1581         return nullptr;
1582     }
1583     uint32_t srcFormat = static_cast<uint32_t>(srcInfo.pixelFormat);
1584     uint32_t dstFormat = static_cast<uint32_t>(dstInfo.pixelFormat);
1585     ProcFuncType funcPtr = GetProcFuncType(srcFormat, dstFormat);
1586     if (funcPtr == nullptr) {
1587         IMAGE_LOGE("not found convert function. pixelFormat %{public}u -> %{public}u", srcFormat, dstFormat);
1588         return nullptr;
1589     }
1590     ProcFuncExtension extension;
1591     extension.alphaConvertType = GetAlphaConvertType(srcInfo.alphaType, dstInfo.alphaType);
1592     bool isNeedConvert = true;
1593     if ((srcInfo.pixelFormat == dstInfo.pixelFormat) && (extension.alphaConvertType == AlphaConvertType::NO_CONVERT)) {
1594         isNeedConvert = false;
1595     }
1596     return make_unique<PixelConvert>(funcPtr, extension, isNeedConvert);
1597 }
1598 
GetAlphaConvertType(const AlphaType &srcType, const AlphaType &dstType)1599 AlphaConvertType PixelConvert::GetAlphaConvertType(const AlphaType &srcType, const AlphaType &dstType)
1600 {
1601     if (srcType == AlphaType::IMAGE_ALPHA_TYPE_UNKNOWN || dstType == AlphaType::IMAGE_ALPHA_TYPE_UNKNOWN) {
1602         IMAGE_LOGD("source or destination alpha type unknown");
1603         return AlphaConvertType::NO_CONVERT;
1604     }
1605     if ((srcType == AlphaType::IMAGE_ALPHA_TYPE_PREMUL) && (dstType == AlphaType::IMAGE_ALPHA_TYPE_UNPREMUL)) {
1606         return AlphaConvertType::PREMUL_CONVERT_UNPREMUL;
1607     }
1608     if ((srcType == AlphaType::IMAGE_ALPHA_TYPE_PREMUL) && (dstType == AlphaType::IMAGE_ALPHA_TYPE_OPAQUE)) {
1609         return AlphaConvertType::PREMUL_CONVERT_OPAQUE;
1610     }
1611     if ((srcType == AlphaType::IMAGE_ALPHA_TYPE_UNPREMUL) && (dstType == AlphaType::IMAGE_ALPHA_TYPE_PREMUL)) {
1612         return AlphaConvertType::UNPREMUL_CONVERT_PREMUL;
1613     }
1614     if ((srcType == AlphaType::IMAGE_ALPHA_TYPE_UNPREMUL) && (dstType == AlphaType::IMAGE_ALPHA_TYPE_OPAQUE)) {
1615         return AlphaConvertType::UNPREMUL_CONVERT_OPAQUE;
1616     }
1617     return AlphaConvertType::NO_CONVERT;
1618 }
1619 
IsValidRowStride(int32_t rowStride, const ImageInfo &imageInfo)1620 bool PixelConvert::IsValidRowStride(int32_t rowStride, const ImageInfo &imageInfo)
1621 {
1622     if (imageInfo.pixelFormat == PixelFormat::YCBCR_P010 ||
1623         imageInfo.pixelFormat == PixelFormat::YCRCB_P010) {
1624         return rowStride == 0 || rowStride >= imageInfo.size.width * YUV420_P010_BYTES;
1625     }
1626     return rowStride == 0 || rowStride >= imageInfo.size.width * ImageUtils::GetPixelBytes(imageInfo.pixelFormat);
1627 }
1628 
IsValidBufferInfo(const BufferInfo &bufferInfo)1629 bool PixelConvert::IsValidBufferInfo(const BufferInfo &bufferInfo)
1630 {
1631     return bufferInfo.pixels != nullptr && IsValidRowStride(bufferInfo.rowStride, bufferInfo.imageInfo);
1632 }
1633 
Convert(void *destinationPixels, const uint8_t *sourcePixels, uint32_t sourcePixelsNum)1634 void PixelConvert::Convert(void *destinationPixels, const uint8_t *sourcePixels, uint32_t sourcePixelsNum)
1635 {
1636     if ((destinationPixels == nullptr) || (sourcePixels == nullptr)) {
1637         IMAGE_LOGE("destinationPixel or sourcePixel is null");
1638         return;
1639     }
1640     if (!isNeedConvert_) {
1641         IMAGE_LOGD("no need convert");
1642         return;
1643     }
1644     procFunc_(destinationPixels, sourcePixels, sourcePixelsNum, procFuncExtension_);
1645 }
1646 } // namespace Media
1647 } // namespace OHOS
1648