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