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