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 (bitIndex > BYTE_BITS_MAX_INDEX) {
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         if (ctx != nullptr) {
1118             av_image_fill_arrays(inputFrame->data, inputFrame->linesize, (uint8_t *)srcPixels,
1119                 srcInfo.format, srcInfo.width, srcInfo.height, srcInfo.alignSize);
1120             av_image_fill_arrays(outputFrame->data, outputFrame->linesize, (uint8_t *)dstPixels,
1121                 dstInfo.format, dstInfo.width, dstInfo.height, dstInfo.alignSize);
1122 
1123             sws_scale(ctx, (uint8_t const **)inputFrame->data, inputFrame->linesize, 0, srcInfo.height,
1124                 outputFrame->data, outputFrame->linesize);
1125             sws_freeContext(ctx);
1126         } else {
1127             IMAGE_LOGE("FFMpeg: sws_getContext failed!");
1128             ret = false;
1129         }
1130     } else {
1131         IMAGE_LOGE("FFMpeg: av_frame_alloc failed!");
1132         ret = false;
1133     }
1134     av_frame_free(&inputFrame);
1135     av_frame_free(&outputFrame);
1136     return ret;
1137 }
1138 
NV12P010ToNV21P010(const uint16_t * srcBuffer,const ImageInfo & info,uint16_t * destBuffer)1139 static bool NV12P010ToNV21P010(const uint16_t *srcBuffer, const ImageInfo &info, uint16_t *destBuffer)
1140 {
1141     const uint16_t *srcUV = srcBuffer + info.size.width * info.size.height;
1142     uint16_t *dstVU = destBuffer + info.size.width * info.size.height;
1143     uint32_t sizeUV = info.size.width * info.size.height / NUM_2;
1144     for (uint32_t i = 0; i < static_cast<uint32_t>(info.size.width * info.size.height); i++) {
1145         destBuffer[i] = srcBuffer[i];
1146     }
1147     for (uint32_t i = 0; i < sizeUV; i += NUM_2) {
1148         dstVU[i] = srcUV[i + 1];
1149         dstVU[i + 1] = srcUV[i];
1150     }
1151     return true;
1152 }
1153 
IsYUVP010Format(PixelFormat format)1154 bool IsYUVP010Format(PixelFormat format)
1155 {
1156     return (format == PixelFormat::YCBCR_P010) || (format == PixelFormat::YCRCB_P010);
1157 }
1158 
ConvertForFFMPEG(const void * srcPixels,PixelFormat srcpixelmap,ImageInfo srcInfo,void * dstPixels,PixelFormat dstpixelmap)1159 static bool ConvertForFFMPEG(const void *srcPixels, PixelFormat srcpixelmap, ImageInfo srcInfo,
1160     void *dstPixels, PixelFormat dstpixelmap)
1161 {
1162     FFMPEG_CONVERT_INFO srcFFmpegInfo = {PixelFormatToAVPixelFormat(srcpixelmap),
1163         srcInfo.size.width, srcInfo.size.height, 1};
1164     FFMPEG_CONVERT_INFO dstFFmpegInfo = {PixelFormatToAVPixelFormat(dstpixelmap),
1165         srcInfo.size.width, srcInfo.size.height, 1};
1166     if (!FFMpegConvert(srcPixels, srcFFmpegInfo, dstPixels, dstFFmpegInfo)) {
1167         IMAGE_LOGE("[PixelMap]Convert: ffmpeg convert failed!");
1168         return false;
1169     }
1170     return true;
1171 }
1172 
1173 // Convert and collapse pixels by removing line paddings if any
ConvertAndCollapseByFFMpeg(const void * srcPixels,const ImageInfo & srcInfo,void * dstPixels,const ImageInfo & dstInfo,bool useDMA)1174 static bool ConvertAndCollapseByFFMpeg(const void *srcPixels, const ImageInfo &srcInfo, void *dstPixels,
1175     const ImageInfo &dstInfo, bool useDMA)
1176 {
1177     FFMPEG_CONVERT_INFO srcFFMpegInfo = {PixelFormatToAVPixelFormat(srcInfo.pixelFormat),
1178         srcInfo.size.width, srcInfo.size.height, useDMA ? DMA_LINE_SIZE : 1};
1179     FFMPEG_CONVERT_INFO dstFFMpegInfo = {PixelFormatToAVPixelFormat(dstInfo.pixelFormat),
1180         dstInfo.size.width, dstInfo.size.height, 1};
1181     if (!FFMpegConvert(srcPixels, srcFFMpegInfo, dstPixels, dstFFMpegInfo)) {
1182         IMAGE_LOGE("[PixelMap] ConvertAndCollapseByFFMpeg: FFMpeg convert failed!");
1183         return false;
1184     }
1185     return true;
1186 }
1187 
P010ConvertRGBA1010102(const void * srcPixels,ImageInfo srcInfo,void * dstPixels,ImageInfo dstInfo)1188 static bool P010ConvertRGBA1010102(const void *srcPixels, ImageInfo srcInfo,
1189     void *dstPixels, ImageInfo dstInfo)
1190 {
1191     FFMPEG_CONVERT_INFO srcFFmpegInfo = {PixelFormatToAVPixelFormat(srcInfo.pixelFormat),
1192         srcInfo.size.width, srcInfo.size.height, 1};
1193     FFMPEG_CONVERT_INFO tmpFFmpegInfo = {PixelFormatToAVPixelFormat(PixelFormat::RGBA_F16),
1194         srcInfo.size.width, srcInfo.size.height, 1};
1195     int tmpPixelsLen = av_image_get_buffer_size(tmpFFmpegInfo.format, tmpFFmpegInfo.width, tmpFFmpegInfo.height,
1196         tmpFFmpegInfo.alignSize);
1197     if (tmpPixelsLen <= 0) {
1198         IMAGE_LOGE("[PixelMap]Convert: Get tmp pixels length failed!");
1199         return false;
1200     }
1201     uint8_t* tmpPixels = new(std::nothrow) uint8_t[tmpPixelsLen];
1202     if (tmpPixels == nullptr) {
1203         IMAGE_LOGE("[PixelMap]Convert: alloc memory failed!");
1204         return false;
1205     }
1206     memset_s(tmpPixels, tmpPixelsLen, 0, tmpPixelsLen);
1207     if (!FFMpegConvert(srcPixels, srcFFmpegInfo, tmpPixels, tmpFFmpegInfo)) {
1208         IMAGE_LOGE("[PixelMap]Convert: ffmpeg convert failed!");
1209         delete[] tmpPixels;
1210         tmpPixels = nullptr;
1211         return false;
1212     }
1213     ImageInfo tmpInfo = srcInfo;
1214     tmpInfo.pixelFormat = PixelFormat::RGBA_U16;
1215     tmpInfo.alphaType = AlphaType::IMAGE_ALPHA_TYPE_PREMUL;
1216     Position pos;
1217     if (!PixelConvertAdapter::WritePixelsConvert(tmpPixels, PixelMap::GetRGBxRowDataSize(tmpInfo), tmpInfo,
1218         dstPixels, pos, PixelMap::GetRGBxRowDataSize(dstInfo), dstInfo)) {
1219         IMAGE_LOGE("[PixelMap]Convert: ConvertFromYUV: pixel convert in adapter failed.");
1220         delete[] tmpPixels;
1221         tmpPixels = nullptr;
1222         return false;
1223     }
1224     delete[] tmpPixels;
1225     tmpPixels = nullptr;
1226     return true;
1227 }
1228 
ConvertRGBA1010102ToYUV(const void * srcPixels,ImageInfo srcInfo,void * dstPixels,ImageInfo dstInfo)1229 static bool ConvertRGBA1010102ToYUV(const void *srcPixels, ImageInfo srcInfo,
1230     void *dstPixels, ImageInfo dstInfo)
1231 {
1232     ImageInfo tmpInfo = srcInfo;
1233     tmpInfo.pixelFormat = PixelFormat::RGBA_U16;
1234     int tmpPixelsLen = PixelMap::GetRGBxByteCount(tmpInfo);
1235     if (tmpPixelsLen <= 0) {
1236         IMAGE_LOGE("[PixelMap]Convert: Get tmp pixels length failed!");
1237         return false;
1238     }
1239     uint8_t* tmpPixels = new(std::nothrow) uint8_t[tmpPixelsLen];
1240     if (tmpPixels == nullptr) {
1241         IMAGE_LOGE("[PixelMap]Convert: alloc memory failed!");
1242         return false;
1243     }
1244     memset_s(tmpPixels, tmpPixelsLen, 0, tmpPixelsLen);
1245 
1246     Position pos;
1247     if (!PixelConvertAdapter::WritePixelsConvert(srcPixels, PixelMap::GetRGBxRowDataSize(srcInfo), srcInfo,
1248         tmpPixels, pos, PixelMap::GetRGBxRowDataSize(tmpInfo), tmpInfo)) {
1249         IMAGE_LOGE("[PixelMap]Convert: ConvertToYUV: pixel convert in adapter failed.");
1250         delete[] tmpPixels;
1251         tmpPixels = nullptr;
1252         return false;
1253     }
1254 
1255     FFMPEG_CONVERT_INFO srcFFmpegInfo = {PixelFormatToAVPixelFormat(PixelFormat::RGBA_F16),
1256         tmpInfo.size.width, tmpInfo.size.height, 1};
1257     FFMPEG_CONVERT_INFO dstFFmpegInfo = {PixelFormatToAVPixelFormat(dstInfo.pixelFormat),
1258         dstInfo.size.width, dstInfo.size.height, 1};
1259     if (!FFMpegConvert(tmpPixels, srcFFmpegInfo, dstPixels, dstFFmpegInfo)) {
1260         IMAGE_LOGE("[PixelMap]Convert: ffmpeg convert failed!");
1261         delete[] tmpPixels;
1262         tmpPixels = nullptr;
1263         return false;
1264     }
1265     delete[] tmpPixels;
1266     tmpPixels = nullptr;
1267     return true;
1268 }
1269 
YUVConvertRGB(const void * srcPixels,const ImageInfo & srcInfo,void * dstPixels,const ImageInfo & dstInfo)1270 static int32_t YUVConvertRGB(const void *srcPixels, const ImageInfo &srcInfo,
1271     void *dstPixels, const ImageInfo &dstInfo)
1272 {
1273     FFMPEG_CONVERT_INFO srcFFmpegInfo = {PixelFormatToAVPixelFormat(srcInfo.pixelFormat),
1274         srcInfo.size.width, srcInfo.size.height, 1};
1275     FFMPEG_CONVERT_INFO tmpFFmpegInfo = {PixelFormatToAVPixelFormat(PixelFormat::RGB_888),
1276         srcInfo.size.width, srcInfo.size.height, 1};
1277     int tmpPixelsLen = av_image_get_buffer_size(tmpFFmpegInfo.format, tmpFFmpegInfo.width, tmpFFmpegInfo.height,
1278         tmpFFmpegInfo.alignSize);
1279     if (tmpPixelsLen <= 0) {
1280         IMAGE_LOGE("[PixelMap]Convert: Get tmp pixels length failed!");
1281         return -1;
1282     }
1283     uint8_t* tmpPixels = new(std::nothrow) uint8_t[tmpPixelsLen];
1284     if (tmpPixels == nullptr) {
1285         IMAGE_LOGE("[PixelMap]Convert: alloc memory failed!");
1286         return -1;
1287     }
1288     memset_s(tmpPixels, tmpPixelsLen, 0, tmpPixelsLen);
1289     if (!FFMpegConvert(srcPixels, srcFFmpegInfo, reinterpret_cast<void *>(tmpPixels), tmpFFmpegInfo)) {
1290         IMAGE_LOGE("[PixelMap]Convert: ffmpeg convert failed!");
1291         delete[] tmpPixels;
1292         tmpPixels = nullptr;
1293         return -1;
1294     }
1295 
1296     ImageInfo tmpInfo = srcInfo;
1297     tmpInfo.pixelFormat = PixelFormat::RGB_888;
1298     Position pos;
1299     if (!PixelConvertAdapter::WritePixelsConvert(tmpPixels, PixelMap::GetRGBxRowDataSize(tmpInfo), tmpInfo,
1300         dstPixels, pos, PixelMap::GetRGBxRowDataSize(dstInfo), dstInfo)) {
1301         IMAGE_LOGE("[PixelMap]Convert: ConvertFromYUV: pixel convert in adapter failed.");
1302         delete[] tmpPixels;
1303         tmpPixels = nullptr;
1304         return -1;
1305     }
1306 
1307     delete[] tmpPixels;
1308     tmpPixels = nullptr;
1309     return PixelMap::GetRGBxByteCount(dstInfo);
1310 }
1311 
ConvertFromYUV(const void * srcPixels,const int32_t srcLength,const ImageInfo & srcInfo,void * dstPixels,const ImageInfo & dstInfo)1312 static int32_t ConvertFromYUV(const void *srcPixels, const int32_t srcLength, const ImageInfo &srcInfo,
1313     void *dstPixels, const ImageInfo &dstInfo)
1314 {
1315     if (srcPixels == nullptr || dstPixels == nullptr || srcLength <= 0) {
1316         IMAGE_LOGE("[PixelMap]Convert: src pixels or dst pixels or src pixels length invalid.");
1317         return -1;
1318     }
1319     if ((srcInfo.pixelFormat != PixelFormat::NV21 && srcInfo.pixelFormat != PixelFormat::NV12) ||
1320         (dstInfo.pixelFormat == PixelFormat::NV21 || dstInfo.pixelFormat == PixelFormat::NV12)) {
1321         IMAGE_LOGE("[PixelMap]Convert: src or dst pixel format invalid.");
1322         return -1;
1323     }
1324     if ((srcInfo.pixelFormat == PixelFormat::NV12 && dstInfo.pixelFormat == PixelFormat::YCBCR_P010) ||
1325         (srcInfo.pixelFormat == PixelFormat::NV21 && dstInfo.pixelFormat == PixelFormat::YCRCB_P010)) {
1326         return ConvertForFFMPEG(srcPixels, PixelFormat::NV12, srcInfo, dstPixels,
1327             PixelFormat::YCBCR_P010) == true ? PixelMap::GetYUVByteCount(dstInfo) : -1;
1328     }
1329     if ((srcInfo.pixelFormat == PixelFormat::NV12 && dstInfo.pixelFormat == PixelFormat::YCRCB_P010) ||
1330         (srcInfo.pixelFormat == PixelFormat::NV21 && dstInfo.pixelFormat == PixelFormat::YCBCR_P010)) {
1331         return ConvertForFFMPEG(srcPixels, PixelFormat::NV21, srcInfo, dstPixels,
1332             PixelFormat::YCBCR_P010) == true ? PixelMap::GetYUVByteCount(dstInfo) : -1;
1333     }
1334 
1335     return YUVConvertRGB(srcPixels, srcInfo, dstPixels, dstInfo);
1336 }
1337 
ConvertFromP010(const void * srcPixels,const int32_t srcLength,const ImageInfo & srcInfo,void * dstPixels,const ImageInfo & dstInfo)1338 static int32_t ConvertFromP010(const void *srcPixels, const int32_t srcLength, const ImageInfo &srcInfo,
1339     void *dstPixels, const ImageInfo &dstInfo)
1340 {
1341     if (srcPixels == nullptr || dstPixels == nullptr || srcLength <= 0) {
1342         IMAGE_LOGE("[PixelMap]Convert: src pixels or dst pixels or src pixels length invalid.");
1343         return -1;
1344     }
1345     if ((srcInfo.pixelFormat != PixelFormat::YCRCB_P010 && srcInfo.pixelFormat != PixelFormat::YCBCR_P010) ||
1346         IsYUVP010Format(dstInfo.pixelFormat)) {
1347         IMAGE_LOGE("[PixelMap]Convert: src or dst pixel format invalid.");
1348         return -1;
1349     }
1350     uint8_t* srcP010 = new(std::nothrow) uint8_t[srcLength];
1351     if (srcP010 == nullptr) {
1352         IMAGE_LOGE("[PixelMap]Convert: alloc memory failed!");
1353         return -1;
1354     }
1355     memset_s(srcP010, srcLength, 0, srcLength);
1356     if (srcInfo.pixelFormat == PixelFormat::YCRCB_P010) {
1357         NV12P010ToNV21P010((uint16_t *)srcPixels, srcInfo, (uint16_t *)srcP010);
1358     } else {
1359         if (memcpy_s(srcP010, srcLength, srcPixels, srcLength) != 0) {
1360             delete[] srcP010;
1361             srcP010 = nullptr;
1362             return -1;
1363         }
1364     }
1365     if (dstInfo.pixelFormat == PixelFormat::RGBA_1010102) {
1366         if (P010ConvertRGBA1010102(srcP010, srcInfo, dstPixels, dstInfo)) {
1367             delete[] srcP010;
1368             srcP010 = nullptr;
1369             return PixelMap::GetRGBxByteCount(dstInfo);
1370         }
1371         delete[] srcP010;
1372         srcP010 = nullptr;
1373         return -1;
1374     } else {
1375         if (ConvertForFFMPEG(srcP010, srcInfo.pixelFormat, srcInfo, dstPixels, dstInfo.pixelFormat)) {
1376             delete[] srcP010;
1377             srcP010 = nullptr;
1378             return PixelMap::GetRGBxByteCount(dstInfo);
1379         }
1380         delete[] srcP010;
1381         srcP010 = nullptr;
1382         return -1;
1383     }
1384 }
1385 
RGBConvertYUV(const void * srcPixels,const ImageInfo & srcInfo,void * dstPixels,const ImageInfo & dstInfo)1386 static int32_t RGBConvertYUV(const void *srcPixels, const ImageInfo &srcInfo,
1387     void *dstPixels, const ImageInfo &dstInfo)
1388 {
1389     ImageInfo tmpInfo = srcInfo;
1390     tmpInfo.pixelFormat = PixelFormat::RGB_888;
1391     int tmpPixelsLen = PixelMap::GetRGBxByteCount(tmpInfo);
1392     if (tmpPixelsLen <= 0) {
1393         IMAGE_LOGE("[PixelMap]Convert: Get tmp pixels length failed!");
1394         return -1;
1395     }
1396     uint8_t* tmpPixels = new(std::nothrow) uint8_t[tmpPixelsLen];
1397     if (tmpPixels == nullptr) {
1398         IMAGE_LOGE("[PixelMap]Convert: alloc memory failed!");
1399         return -1;
1400     }
1401     memset_s(tmpPixels, tmpPixelsLen, 0, tmpPixelsLen);
1402     Position pos;
1403     if (!PixelConvertAdapter::WritePixelsConvert(srcPixels, PixelMap::GetRGBxRowDataSize(srcInfo), srcInfo,
1404         tmpPixels, pos, PixelMap::GetRGBxRowDataSize(tmpInfo), tmpInfo)) {
1405         IMAGE_LOGE("[PixelMap]Convert: ConvertToYUV: pixel convert in adapter failed.");
1406         delete[] tmpPixels;
1407         tmpPixels = nullptr;
1408         return -1;
1409     }
1410     FFMPEG_CONVERT_INFO srcFFmpegInfo = {PixelFormatToAVPixelFormat(PixelFormat::RGB_888),
1411         tmpInfo.size.width, tmpInfo.size.height, 1};
1412     FFMPEG_CONVERT_INFO dstFFmpegInfo = {PixelFormatToAVPixelFormat(dstInfo.pixelFormat),
1413         dstInfo.size.width, dstInfo.size.height, 1};
1414     if (!FFMpegConvert(tmpPixels, srcFFmpegInfo, reinterpret_cast<void *>(dstPixels), dstFFmpegInfo)) {
1415         IMAGE_LOGE("[PixelMap]Convert: ffmpeg convert failed!");
1416         delete[] tmpPixels;
1417         tmpPixels = nullptr;
1418         return -1;
1419     }
1420     delete[] tmpPixels;
1421     tmpPixels = nullptr;
1422     return av_image_get_buffer_size(dstFFmpegInfo.format, dstFFmpegInfo.width, dstFFmpegInfo.height,
1423         dstFFmpegInfo.alignSize);
1424 }
1425 
ConvertToYUV(const void * srcPixels,const int32_t srcLength,const ImageInfo & srcInfo,void * dstPixels,const ImageInfo & dstInfo)1426 static int32_t ConvertToYUV(const void *srcPixels, const int32_t srcLength, const ImageInfo &srcInfo,
1427     void *dstPixels, const ImageInfo &dstInfo)
1428 {
1429     if (srcPixels == nullptr || dstPixels == nullptr || srcLength <= 0) {
1430         IMAGE_LOGE("[PixelMap]Convert: src pixels or dst pixels or src pixel length invalid");
1431         return -1;
1432     }
1433     if ((srcInfo.pixelFormat == PixelFormat::NV21 || srcInfo.pixelFormat == PixelFormat::NV12) ||
1434         (dstInfo.pixelFormat != PixelFormat::NV21 && dstInfo.pixelFormat != PixelFormat::NV12)) {
1435         IMAGE_LOGE("[PixelMap]Convert: src or dst pixel format invalid.");
1436         return -1;
1437     }
1438     if ((srcInfo.pixelFormat == PixelFormat::YCBCR_P010 && dstInfo.pixelFormat == PixelFormat::NV12) ||
1439         (srcInfo.pixelFormat == PixelFormat::YCRCB_P010 && dstInfo.pixelFormat == PixelFormat::NV21)) {
1440         return ConvertForFFMPEG(srcPixels, PixelFormat::YCBCR_P010, srcInfo, dstPixels,
1441             PixelFormat::NV12) == true ? PixelMap::GetYUVByteCount(dstInfo) : -1;
1442     }
1443     if ((srcInfo.pixelFormat == PixelFormat::YCBCR_P010 && dstInfo.pixelFormat == PixelFormat::NV21) ||
1444         (srcInfo.pixelFormat == PixelFormat::YCRCB_P010 && dstInfo.pixelFormat == PixelFormat::NV12)) {
1445         return ConvertForFFMPEG(srcPixels, PixelFormat::YCBCR_P010, srcInfo, dstPixels,
1446             PixelFormat::NV21) == true ? PixelMap::GetYUVByteCount(dstInfo) : -1;
1447     }
1448     return RGBConvertYUV(srcPixels, srcInfo, dstPixels, dstInfo);
1449 }
1450 
ConvertToP010(const void * srcPixels,const int32_t srcLength,const ImageInfo & srcInfo,void * dstPixels,const ImageInfo & dstInfo)1451 static int32_t ConvertToP010(const void *srcPixels, const int32_t srcLength, const ImageInfo &srcInfo,
1452     void *dstPixels, const ImageInfo &dstInfo)
1453 {
1454     if (srcPixels == nullptr || dstPixels == nullptr || srcLength <= 0) {
1455         IMAGE_LOGE("[PixelMap]Convert: src pixels or dst pixels or src pixel length invalid");
1456         return -1;
1457     }
1458     if (IsYUVP010Format(srcInfo.pixelFormat) ||
1459         (dstInfo.pixelFormat != PixelFormat::YCRCB_P010 && dstInfo.pixelFormat != PixelFormat::YCBCR_P010)) {
1460         IMAGE_LOGE("[PixelMap]Convert: src or dst pixel format invalid.");
1461         return -1;
1462     }
1463     int32_t dstLength = PixelMap::GetYUVByteCount(dstInfo);
1464     if (dstLength <= 0) {
1465         IMAGE_LOGE("[PixelMap]Convert: Get dstP010 length failed!");
1466         return -1;
1467     }
1468     uint8_t* dstP010 = new(std::nothrow) uint8_t[dstLength];
1469     if (dstP010 == nullptr) {
1470         IMAGE_LOGE("[PixelMap]Convert: alloc memory failed!");
1471         return -1;
1472     }
1473     memset_s(dstP010, dstLength, 0, dstLength);
1474 
1475     if (srcInfo.pixelFormat == PixelFormat::RGBA_1010102) {
1476         if (!ConvertRGBA1010102ToYUV(srcPixels, srcInfo, dstP010, dstInfo)) {
1477             delete[] dstP010;
1478             dstP010 = nullptr;
1479             return -1;
1480         }
1481     } else {
1482         if (!ConvertForFFMPEG(srcPixels, srcInfo.pixelFormat, srcInfo, dstP010, dstInfo.pixelFormat)) {
1483             delete[] dstP010;
1484             dstP010 = nullptr;
1485             return -1;
1486         }
1487     }
1488     if (dstInfo.pixelFormat == PixelFormat::YCRCB_P010) {
1489         NV12P010ToNV21P010((uint16_t *)dstP010, dstInfo, (uint16_t *)dstPixels);
1490     } else {
1491         if (memcpy_s(dstPixels, dstLength, dstP010, dstLength) != 0) {
1492             delete[] dstP010;
1493             dstP010 = nullptr;
1494             return -1;
1495         }
1496     }
1497     delete[] dstP010;
1498     dstP010 = nullptr;
1499     return dstLength;
1500 }
1501 
YUVConvert(const void * srcPixels,const int32_t srcLength,const ImageInfo & srcInfo,void * dstPixels,const ImageInfo & dstInfo)1502 static int32_t YUVConvert(const void *srcPixels, const int32_t srcLength, const ImageInfo &srcInfo,
1503     void *dstPixels, const ImageInfo &dstInfo)
1504 {
1505     if (srcInfo.pixelFormat == dstInfo.pixelFormat &&
1506         srcInfo.size.width == dstInfo.size.width && srcInfo.size.height == dstInfo.size.height) {
1507             IMAGE_LOGE("src pixel format is equal dst pixel format. no need to convert.");
1508             auto result = memcpy_s(dstPixels, srcLength, srcPixels, srcLength);
1509             return result == 0 ? srcLength : -1;
1510     }
1511     if (IsYUVP010Format(srcInfo.pixelFormat) && IsYUVP010Format(dstInfo.pixelFormat)) {
1512         if (srcInfo.size.width == dstInfo.size.width && srcInfo.size.height == dstInfo.size.height) {
1513             return NV12P010ToNV21P010((uint16_t *)srcPixels, dstInfo, (uint16_t *)dstPixels) == true ?
1514                 srcLength : -1;
1515         }
1516     }
1517     FFMPEG_CONVERT_INFO srcFFmpegInfo = {PixelFormatToAVPixelFormat(srcInfo.pixelFormat), srcInfo.size.width,
1518         srcInfo.size.height, 1};
1519     FFMPEG_CONVERT_INFO dstFFmpegInfo = {PixelFormatToAVPixelFormat(dstInfo.pixelFormat), dstInfo.size.width,
1520         dstInfo.size.height, 1};
1521     if (!FFMpegConvert(srcPixels, srcFFmpegInfo, dstPixels, dstFFmpegInfo)) {
1522         IMAGE_LOGE("[PixelMap]Convert: ffmpeg convert failed!");
1523         return -1;
1524     }
1525     return av_image_get_buffer_size(dstFFmpegInfo.format, dstFFmpegInfo.width, dstFFmpegInfo.height,
1526         dstFFmpegInfo.alignSize);
1527 }
1528 
IsInterYUVConvert(PixelFormat srcPixelFormat,PixelFormat dstPixelFormat)1529 static bool IsInterYUVConvert(PixelFormat srcPixelFormat, PixelFormat dstPixelFormat)
1530 {
1531     return (srcPixelFormat == PixelFormat::NV12 || srcPixelFormat == PixelFormat::NV21) &&
1532         (dstPixelFormat == PixelFormat::NV12 || dstPixelFormat == PixelFormat::NV21);
1533 }
1534 
PixelsConvert(const BufferInfo & srcInfo,BufferInfo & dstInfo,int32_t srcLength,bool useDMA)1535 int32_t PixelConvert::PixelsConvert(const BufferInfo &srcInfo, BufferInfo &dstInfo, int32_t srcLength, bool useDMA)
1536 {
1537     if (!IsValidBufferInfo(srcInfo) || !IsValidBufferInfo(dstInfo) || srcLength <= 0) {
1538         IMAGE_LOGE("[PixelMap]Convert: pixels or image info or row stride or src pixels length invalid.");
1539         return -1;
1540     }
1541 
1542     const ImageInfo srcImageInfo = srcInfo.imageInfo;
1543     const ImageInfo dstImageInfo = dstInfo.imageInfo;
1544     if (dstImageInfo.pixelFormat == PixelFormat::ARGB_8888) {
1545         return ConvertAndCollapseByFFMpeg(srcInfo.pixels, srcImageInfo, dstInfo.pixels, dstImageInfo, useDMA) ?
1546             PixelMap::GetRGBxByteCount(dstImageInfo) : -1;
1547     }
1548     if (IsInterYUVConvert(srcImageInfo.pixelFormat, dstImageInfo.pixelFormat) ||
1549         (IsYUVP010Format(srcImageInfo.pixelFormat) && IsYUVP010Format(dstImageInfo.pixelFormat))) {
1550         return YUVConvert(srcInfo.pixels, srcLength, srcImageInfo, dstInfo.pixels, dstImageInfo);
1551     }
1552     if (srcImageInfo.pixelFormat == PixelFormat::NV12 || srcImageInfo.pixelFormat == PixelFormat::NV21) {
1553         return ConvertFromYUV(srcInfo.pixels, srcLength, srcImageInfo, dstInfo.pixels, dstImageInfo);
1554     } else if (dstImageInfo.pixelFormat == PixelFormat::NV12 || dstImageInfo.pixelFormat == PixelFormat::NV21) {
1555         return ConvertToYUV(srcInfo.pixels, srcLength, srcImageInfo, dstInfo.pixels, dstImageInfo);
1556     } else if (IsYUVP010Format(srcImageInfo.pixelFormat)) {
1557         return ConvertFromP010(srcInfo.pixels, srcLength, srcImageInfo, dstInfo.pixels, dstImageInfo);
1558     } else if (IsYUVP010Format(dstImageInfo.pixelFormat)) {
1559         return ConvertToP010(srcInfo.pixels, srcLength, srcImageInfo, dstInfo.pixels, dstImageInfo);
1560     }
1561 
1562     Position pos;
1563     if (!PixelConvertAdapter::WritePixelsConvert(srcInfo.pixels,
1564         srcInfo.rowStride == 0 ? PixelMap::GetRGBxRowDataSize(srcImageInfo) : srcInfo.rowStride, srcImageInfo,
1565         dstInfo.pixels, pos, useDMA ? dstInfo.rowStride : PixelMap::GetRGBxRowDataSize(dstImageInfo), dstImageInfo)) {
1566         IMAGE_LOGE("[PixelMap]Convert: PixelsConvert: pixel convert in adapter failed.");
1567         return -1;
1568     }
1569 
1570     return PixelMap::GetRGBxByteCount(dstImageInfo);
1571 }
1572 
PixelConvert(ProcFuncType funcPtr,ProcFuncExtension extension,bool isNeedConvert)1573 PixelConvert::PixelConvert(ProcFuncType funcPtr, ProcFuncExtension extension, bool isNeedConvert)
1574     : procFunc_(funcPtr), procFuncExtension_(extension), isNeedConvert_(isNeedConvert)
1575 {}
1576 
1577 // caller need setting the correct pixelFormat and alphaType
Create(const ImageInfo & srcInfo,const ImageInfo & dstInfo)1578 std::unique_ptr<PixelConvert> PixelConvert::Create(const ImageInfo &srcInfo, const ImageInfo &dstInfo)
1579 {
1580     if (srcInfo.pixelFormat == PixelFormat::UNKNOWN || dstInfo.pixelFormat == PixelFormat::UNKNOWN) {
1581         IMAGE_LOGE("source or destination pixel format unknown");
1582         return nullptr;
1583     }
1584     uint32_t srcFormat = static_cast<uint32_t>(srcInfo.pixelFormat);
1585     uint32_t dstFormat = static_cast<uint32_t>(dstInfo.pixelFormat);
1586     ProcFuncType funcPtr = GetProcFuncType(srcFormat, dstFormat);
1587     if (funcPtr == nullptr) {
1588         IMAGE_LOGE("not found convert function. pixelFormat %{public}u -> %{public}u", srcFormat, dstFormat);
1589         return nullptr;
1590     }
1591     ProcFuncExtension extension;
1592     extension.alphaConvertType = GetAlphaConvertType(srcInfo.alphaType, dstInfo.alphaType);
1593     bool isNeedConvert = true;
1594     if ((srcInfo.pixelFormat == dstInfo.pixelFormat) && (extension.alphaConvertType == AlphaConvertType::NO_CONVERT)) {
1595         isNeedConvert = false;
1596     }
1597     return make_unique<PixelConvert>(funcPtr, extension, isNeedConvert);
1598 }
1599 
GetAlphaConvertType(const AlphaType & srcType,const AlphaType & dstType)1600 AlphaConvertType PixelConvert::GetAlphaConvertType(const AlphaType &srcType, const AlphaType &dstType)
1601 {
1602     if (srcType == AlphaType::IMAGE_ALPHA_TYPE_UNKNOWN || dstType == AlphaType::IMAGE_ALPHA_TYPE_UNKNOWN) {
1603         IMAGE_LOGD("source or destination alpha type unknown");
1604         return AlphaConvertType::NO_CONVERT;
1605     }
1606     if ((srcType == AlphaType::IMAGE_ALPHA_TYPE_PREMUL) && (dstType == AlphaType::IMAGE_ALPHA_TYPE_UNPREMUL)) {
1607         return AlphaConvertType::PREMUL_CONVERT_UNPREMUL;
1608     }
1609     if ((srcType == AlphaType::IMAGE_ALPHA_TYPE_PREMUL) && (dstType == AlphaType::IMAGE_ALPHA_TYPE_OPAQUE)) {
1610         return AlphaConvertType::PREMUL_CONVERT_OPAQUE;
1611     }
1612     if ((srcType == AlphaType::IMAGE_ALPHA_TYPE_UNPREMUL) && (dstType == AlphaType::IMAGE_ALPHA_TYPE_PREMUL)) {
1613         return AlphaConvertType::UNPREMUL_CONVERT_PREMUL;
1614     }
1615     if ((srcType == AlphaType::IMAGE_ALPHA_TYPE_UNPREMUL) && (dstType == AlphaType::IMAGE_ALPHA_TYPE_OPAQUE)) {
1616         return AlphaConvertType::UNPREMUL_CONVERT_OPAQUE;
1617     }
1618     return AlphaConvertType::NO_CONVERT;
1619 }
1620 
IsValidRowStride(int32_t rowStride,const ImageInfo & imageInfo)1621 bool PixelConvert::IsValidRowStride(int32_t rowStride, const ImageInfo &imageInfo)
1622 {
1623     if (imageInfo.pixelFormat == PixelFormat::YCBCR_P010 ||
1624         imageInfo.pixelFormat == PixelFormat::YCRCB_P010) {
1625         return rowStride == 0 || rowStride >= imageInfo.size.width * YUV420_P010_BYTES;
1626     }
1627     return rowStride == 0 || rowStride >= imageInfo.size.width * ImageUtils::GetPixelBytes(imageInfo.pixelFormat);
1628 }
1629 
IsValidBufferInfo(const BufferInfo & bufferInfo)1630 bool PixelConvert::IsValidBufferInfo(const BufferInfo &bufferInfo)
1631 {
1632     return bufferInfo.pixels != nullptr && IsValidRowStride(bufferInfo.rowStride, bufferInfo.imageInfo);
1633 }
1634 
Convert(void * destinationPixels,const uint8_t * sourcePixels,uint32_t sourcePixelsNum)1635 void PixelConvert::Convert(void *destinationPixels, const uint8_t *sourcePixels, uint32_t sourcePixelsNum)
1636 {
1637     if ((destinationPixels == nullptr) || (sourcePixels == nullptr)) {
1638         IMAGE_LOGE("destinationPixel or sourcePixel is null");
1639         return;
1640     }
1641     if (!isNeedConvert_) {
1642         IMAGE_LOGD("no need convert");
1643         return;
1644     }
1645     procFunc_(destinationPixels, sourcePixels, sourcePixelsNum, procFuncExtension_);
1646 }
1647 } // namespace Media
1648 } // namespace OHOS
1649