Commit | Line | Data |
---|---|---|
fcfbc150 | 1 | /* |
8a322796 DB |
2 | * software RGB to RGB converter |
3 | * pluralize by software PAL8 to RGB converter | |
4 | * software YUV to YUV converter | |
5 | * software YUV to RGB converter | |
6 | * Written by Nick Kurshev. | |
7 | * palette & YUV & runtime CPU stuff by Michael (michaelni@gmx.at) | |
4fadc2b4 | 8 | * |
d026b45e DB |
9 | * This file is part of FFmpeg. |
10 | * | |
819ee683 DB |
11 | * FFmpeg is free software; you can redistribute it and/or |
12 | * modify it under the terms of the GNU Lesser General Public | |
13 | * License as published by the Free Software Foundation; either | |
14 | * version 2.1 of the License, or (at your option) any later version. | |
4fadc2b4 | 15 | * |
d026b45e | 16 | * FFmpeg is distributed in the hope that it will be useful, |
4fadc2b4 | 17 | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
819ee683 DB |
18 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
19 | * Lesser General Public License for more details. | |
4fadc2b4 | 20 | * |
819ee683 DB |
21 | * You should have received a copy of the GNU Lesser General Public |
22 | * License along with FFmpeg; if not, write to the Free Software | |
b19bcbaa | 23 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA |
a3aece93 | 24 | */ |
b234ae81 | 25 | #include <inttypes.h> |
b2d374c9 | 26 | #include "config.h" |
83da2c6f DB |
27 | #include "libavutil/x86_cpu.h" |
28 | #include "libavutil/bswap.h" | |
b234ae81 | 29 | #include "rgb2rgb.h" |
700490a4 | 30 | #include "swscale.h" |
94c4def2 | 31 | #include "swscale_internal.h" |
a3aece93 | 32 | |
8a322796 | 33 | #define FAST_BGR2YV12 // use 7-bit instead of 15-bit coefficients |
21316f3c | 34 | |
6107059c MN |
35 | void (*rgb24tobgr32)(const uint8_t *src, uint8_t *dst, long src_size); |
36 | void (*rgb24tobgr16)(const uint8_t *src, uint8_t *dst, long src_size); | |
37 | void (*rgb24tobgr15)(const uint8_t *src, uint8_t *dst, long src_size); | |
38 | void (*rgb32tobgr24)(const uint8_t *src, uint8_t *dst, long src_size); | |
30c48a0a BF |
39 | void (*rgb32to16)(const uint8_t *src, uint8_t *dst, long src_size); |
40 | void (*rgb32to15)(const uint8_t *src, uint8_t *dst, long src_size); | |
41 | void (*rgb15to16)(const uint8_t *src, uint8_t *dst, long src_size); | |
6107059c | 42 | void (*rgb15tobgr24)(const uint8_t *src, uint8_t *dst, long src_size); |
30c48a0a BF |
43 | void (*rgb15to32)(const uint8_t *src, uint8_t *dst, long src_size); |
44 | void (*rgb16to15)(const uint8_t *src, uint8_t *dst, long src_size); | |
6107059c | 45 | void (*rgb16tobgr24)(const uint8_t *src, uint8_t *dst, long src_size); |
30c48a0a | 46 | void (*rgb16to32)(const uint8_t *src, uint8_t *dst, long src_size); |
7f526efd | 47 | void (*rgb24tobgr24)(const uint8_t *src, uint8_t *dst, long src_size); |
6107059c MN |
48 | void (*rgb24to16)(const uint8_t *src, uint8_t *dst, long src_size); |
49 | void (*rgb24to15)(const uint8_t *src, uint8_t *dst, long src_size); | |
7f526efd | 50 | void (*rgb32tobgr32)(const uint8_t *src, uint8_t *dst, long src_size); |
7f526efd RD |
51 | void (*rgb32tobgr16)(const uint8_t *src, uint8_t *dst, long src_size); |
52 | void (*rgb32tobgr15)(const uint8_t *src, uint8_t *dst, long src_size); | |
700490a4 MN |
53 | |
54 | void (*yv12toyuy2)(const uint8_t *ysrc, const uint8_t *usrc, const uint8_t *vsrc, uint8_t *dst, | |
6e42e6c4 DB |
55 | long width, long height, |
56 | long lumStride, long chromStride, long dstStride); | |
caeaabe7 | 57 | void (*yv12touyvy)(const uint8_t *ysrc, const uint8_t *usrc, const uint8_t *vsrc, uint8_t *dst, |
6e42e6c4 DB |
58 | long width, long height, |
59 | long lumStride, long chromStride, long dstStride); | |
700490a4 | 60 | void (*yuv422ptoyuy2)(const uint8_t *ysrc, const uint8_t *usrc, const uint8_t *vsrc, uint8_t *dst, |
6e42e6c4 DB |
61 | long width, long height, |
62 | long lumStride, long chromStride, long dstStride); | |
a6100f39 BC |
63 | void (*yuv422ptouyvy)(const uint8_t *ysrc, const uint8_t *usrc, const uint8_t *vsrc, uint8_t *dst, |
64 | long width, long height, | |
65 | long lumStride, long chromStride, long dstStride); | |
700490a4 | 66 | void (*yuy2toyv12)(const uint8_t *src, uint8_t *ydst, uint8_t *udst, uint8_t *vdst, |
6e42e6c4 DB |
67 | long width, long height, |
68 | long lumStride, long chromStride, long srcStride); | |
700490a4 | 69 | void (*rgb24toyv12)(const uint8_t *src, uint8_t *ydst, uint8_t *udst, uint8_t *vdst, |
6e42e6c4 DB |
70 | long width, long height, |
71 | long lumStride, long chromStride, long srcStride); | |
7f526efd | 72 | void (*planar2x)(const uint8_t *src, uint8_t *dst, long width, long height, |
6e42e6c4 | 73 | long srcStride, long dstStride); |
a959e247 | 74 | void (*interleaveBytes)(const uint8_t *src1, const uint8_t *src2, uint8_t *dst, |
6e42e6c4 DB |
75 | long width, long height, long src1Stride, |
76 | long src2Stride, long dstStride); | |
700490a4 | 77 | void (*vu9_to_vu12)(const uint8_t *src1, const uint8_t *src2, |
6e42e6c4 DB |
78 | uint8_t *dst1, uint8_t *dst2, |
79 | long width, long height, | |
80 | long srcStride1, long srcStride2, | |
81 | long dstStride1, long dstStride2); | |
700490a4 | 82 | void (*yvu9_to_yuy2)(const uint8_t *src1, const uint8_t *src2, const uint8_t *src3, |
6e42e6c4 DB |
83 | uint8_t *dst, |
84 | long width, long height, | |
85 | long srcStride1, long srcStride2, | |
86 | long srcStride3, long dstStride); | |
0411072e | 87 | void (*uyvytoyuv420)(uint8_t *ydst, uint8_t *udst, uint8_t *vdst, const uint8_t *src, |
9b734d44 RP |
88 | long width, long height, |
89 | long lumStride, long chromStride, long srcStride); | |
0411072e | 90 | void (*uyvytoyuv422)(uint8_t *ydst, uint8_t *udst, uint8_t *vdst, const uint8_t *src, |
9b734d44 RP |
91 | long width, long height, |
92 | long lumStride, long chromStride, long srcStride); | |
0411072e | 93 | void (*yuyvtoyuv420)(uint8_t *ydst, uint8_t *udst, uint8_t *vdst, const uint8_t *src, |
9b734d44 RP |
94 | long width, long height, |
95 | long lumStride, long chromStride, long srcStride); | |
0411072e | 96 | void (*yuyvtoyuv422)(uint8_t *ydst, uint8_t *udst, uint8_t *vdst, const uint8_t *src, |
9b734d44 RP |
97 | long width, long height, |
98 | long lumStride, long chromStride, long srcStride); | |
0411072e | 99 | |
700490a4 | 100 | |
819ee683 | 101 | #if ARCH_X86 |
d334c7c2 RD |
102 | DECLARE_ASM_CONST(8, uint64_t, mmx_null) = 0x0000000000000000ULL; |
103 | DECLARE_ASM_CONST(8, uint64_t, mmx_one) = 0xFFFFFFFFFFFFFFFFULL; | |
104 | DECLARE_ASM_CONST(8, uint64_t, mask32b) = 0x000000FF000000FFULL; | |
105 | DECLARE_ASM_CONST(8, uint64_t, mask32g) = 0x0000FF000000FF00ULL; | |
106 | DECLARE_ASM_CONST(8, uint64_t, mask32r) = 0x00FF000000FF0000ULL; | |
f8a138be | 107 | DECLARE_ASM_CONST(8, uint64_t, mask32a) = 0xFF000000FF000000ULL; |
d334c7c2 RD |
108 | DECLARE_ASM_CONST(8, uint64_t, mask32) = 0x00FFFFFF00FFFFFFULL; |
109 | DECLARE_ASM_CONST(8, uint64_t, mask3216br) = 0x00F800F800F800F8ULL; | |
110 | DECLARE_ASM_CONST(8, uint64_t, mask3216g) = 0x0000FC000000FC00ULL; | |
111 | DECLARE_ASM_CONST(8, uint64_t, mask3215g) = 0x0000F8000000F800ULL; | |
112 | DECLARE_ASM_CONST(8, uint64_t, mul3216) = 0x2000000420000004ULL; | |
113 | DECLARE_ASM_CONST(8, uint64_t, mul3215) = 0x2000000820000008ULL; | |
114 | DECLARE_ASM_CONST(8, uint64_t, mask24b) = 0x00FF0000FF0000FFULL; | |
115 | DECLARE_ASM_CONST(8, uint64_t, mask24g) = 0xFF0000FF0000FF00ULL; | |
116 | DECLARE_ASM_CONST(8, uint64_t, mask24r) = 0x0000FF0000FF0000ULL; | |
117 | DECLARE_ASM_CONST(8, uint64_t, mask24l) = 0x0000000000FFFFFFULL; | |
118 | DECLARE_ASM_CONST(8, uint64_t, mask24h) = 0x0000FFFFFF000000ULL; | |
119 | DECLARE_ASM_CONST(8, uint64_t, mask24hh) = 0xffff000000000000ULL; | |
120 | DECLARE_ASM_CONST(8, uint64_t, mask24hhh) = 0xffffffff00000000ULL; | |
121 | DECLARE_ASM_CONST(8, uint64_t, mask24hhhh) = 0xffffffffffff0000ULL; | |
122 | DECLARE_ASM_CONST(8, uint64_t, mask15b) = 0x001F001F001F001FULL; /* 00000000 00011111 xxB */ | |
123 | DECLARE_ASM_CONST(8, uint64_t, mask15rg) = 0x7FE07FE07FE07FE0ULL; /* 01111111 11100000 RGx */ | |
124 | DECLARE_ASM_CONST(8, uint64_t, mask15s) = 0xFFE0FFE0FFE0FFE0ULL; | |
125 | DECLARE_ASM_CONST(8, uint64_t, mask15g) = 0x03E003E003E003E0ULL; | |
126 | DECLARE_ASM_CONST(8, uint64_t, mask15r) = 0x7C007C007C007C00ULL; | |
0d9f3d85 | 127 | #define mask16b mask15b |
d334c7c2 RD |
128 | DECLARE_ASM_CONST(8, uint64_t, mask16g) = 0x07E007E007E007E0ULL; |
129 | DECLARE_ASM_CONST(8, uint64_t, mask16r) = 0xF800F800F800F800ULL; | |
130 | DECLARE_ASM_CONST(8, uint64_t, red_16mask) = 0x0000f8000000f800ULL; | |
131 | DECLARE_ASM_CONST(8, uint64_t, green_16mask) = 0x000007e0000007e0ULL; | |
132 | DECLARE_ASM_CONST(8, uint64_t, blue_16mask) = 0x0000001f0000001fULL; | |
133 | DECLARE_ASM_CONST(8, uint64_t, red_15mask) = 0x00007c0000007c00ULL; | |
134 | DECLARE_ASM_CONST(8, uint64_t, green_15mask) = 0x000003e0000003e0ULL; | |
135 | DECLARE_ASM_CONST(8, uint64_t, blue_15mask) = 0x0000001f0000001fULL; | |
b63f641e | 136 | #endif /* ARCH_X86 */ |
79811694 | 137 | |
1de97d84 MN |
138 | #define RGB2YUV_SHIFT 8 |
139 | #define BY ((int)( 0.098*(1<<RGB2YUV_SHIFT)+0.5)) | |
140 | #define BV ((int)(-0.071*(1<<RGB2YUV_SHIFT)+0.5)) | |
141 | #define BU ((int)( 0.439*(1<<RGB2YUV_SHIFT)+0.5)) | |
142 | #define GY ((int)( 0.504*(1<<RGB2YUV_SHIFT)+0.5)) | |
143 | #define GV ((int)(-0.368*(1<<RGB2YUV_SHIFT)+0.5)) | |
144 | #define GU ((int)(-0.291*(1<<RGB2YUV_SHIFT)+0.5)) | |
145 | #define RY ((int)( 0.257*(1<<RGB2YUV_SHIFT)+0.5)) | |
146 | #define RV ((int)( 0.439*(1<<RGB2YUV_SHIFT)+0.5)) | |
147 | #define RU ((int)(-0.148*(1<<RGB2YUV_SHIFT)+0.5)) | |
148 | ||
8a322796 DB |
149 | //Note: We have C, MMX, MMX2, 3DNOW versions, there is no 3DNOW + MMX2 one. |
150 | //plain C versions | |
1de97d84 MN |
151 | #undef HAVE_MMX |
152 | #undef HAVE_MMX2 | |
f4406ec1 | 153 | #undef HAVE_AMD3DNOW |
52075cde | 154 | #undef HAVE_SSE2 |
b63f641e AJ |
155 | #define HAVE_MMX 0 |
156 | #define HAVE_MMX2 0 | |
f4406ec1 | 157 | #define HAVE_AMD3DNOW 0 |
b63f641e | 158 | #define HAVE_SSE2 0 |
1de97d84 MN |
159 | #define RENAME(a) a ## _C |
160 | #include "rgb2rgb_template.c" | |
161 | ||
819ee683 | 162 | #if ARCH_X86 |
1de97d84 MN |
163 | |
164 | //MMX versions | |
165 | #undef RENAME | |
b63f641e AJ |
166 | #undef HAVE_MMX |
167 | #define HAVE_MMX 1 | |
1de97d84 MN |
168 | #define RENAME(a) a ## _MMX |
169 | #include "rgb2rgb_template.c" | |
170 | ||
171 | //MMX2 versions | |
172 | #undef RENAME | |
b63f641e AJ |
173 | #undef HAVE_MMX2 |
174 | #define HAVE_MMX2 1 | |
1de97d84 MN |
175 | #define RENAME(a) a ## _MMX2 |
176 | #include "rgb2rgb_template.c" | |
177 | ||
178 | //3DNOW versions | |
179 | #undef RENAME | |
1de97d84 | 180 | #undef HAVE_MMX2 |
f4406ec1 | 181 | #undef HAVE_AMD3DNOW |
b63f641e | 182 | #define HAVE_MMX2 0 |
f4406ec1 | 183 | #define HAVE_AMD3DNOW 1 |
abdcd337 | 184 | #define RENAME(a) a ## _3DNOW |
1de97d84 MN |
185 | #include "rgb2rgb_template.c" |
186 | ||
6e1c66bc | 187 | #endif //ARCH_X86 || ARCH_X86_64 |
b238eb2e | 188 | |
a3aece93 | 189 | /* |
8a322796 | 190 | RGB15->RGB16 original by Strepto/Astral |
a3aece93 | 191 | ported to gcc & bugfixed : A'rpi |
51da31f1 | 192 | MMX2, 3DNOW optimization by Nick Kurshev |
8a322796 | 193 | 32-bit C version, and and&add trick by Michael Niedermayer |
a3aece93 | 194 | */ |
fcfbc150 | 195 | |
dd68318c RP |
196 | void sws_rgb2rgb_init(int flags) |
197 | { | |
819ee683 | 198 | #if HAVE_MMX2 || HAVE_AMD3DNOW || HAVE_MMX |
6e42e6c4 DB |
199 | if (flags & SWS_CPU_CAPS_MMX2) |
200 | rgb2rgb_init_MMX2(); | |
201 | else if (flags & SWS_CPU_CAPS_3DNOW) | |
202 | rgb2rgb_init_3DNOW(); | |
203 | else if (flags & SWS_CPU_CAPS_MMX) | |
204 | rgb2rgb_init_MMX(); | |
205 | else | |
f4406ec1 | 206 | #endif /* HAVE_MMX2 || HAVE_AMD3DNOW || HAVE_MMX */ |
6e42e6c4 | 207 | rgb2rgb_init_C(); |
ac4d0aea | 208 | } |
700490a4 | 209 | |
fcfbc150 | 210 | /** |
522ce957 | 211 | * Convert the palette to the same packet 32-bit format as the palette |
fcfbc150 | 212 | */ |
522ce957 | 213 | void palette8topacked32(const uint8_t *src, uint8_t *dst, long num_pixels, const uint8_t *palette) |
fcfbc150 | 214 | { |
6e42e6c4 | 215 | long i; |
9780c7ff | 216 | |
6e42e6c4 | 217 | for (i=0; i<num_pixels; i++) |
522ce957 | 218 | ((uint32_t *) dst)[i] = ((const uint32_t *) palette)[src[i]]; |
6c1baeb0 | 219 | } |
6c1baeb0 | 220 | |
9ce6584e | 221 | /** |
522ce957 | 222 | * Palette format: ABCD -> dst format: ABC |
9ce6584e | 223 | */ |
522ce957 | 224 | void palette8topacked24(const uint8_t *src, uint8_t *dst, long num_pixels, const uint8_t *palette) |
9ce6584e | 225 | { |
6e42e6c4 | 226 | long i; |
9ce6584e | 227 | |
dd68318c | 228 | for (i=0; i<num_pixels; i++) { |
6e42e6c4 | 229 | //FIXME slow? |
30c48a0a BF |
230 | dst[0]= palette[src[i]*4+0]; |
231 | dst[1]= palette[src[i]*4+1]; | |
232 | dst[2]= palette[src[i]*4+2]; | |
6e42e6c4 DB |
233 | dst+= 3; |
234 | } | |
6c1baeb0 AB |
235 | } |
236 | ||
fcfbc150 | 237 | /** |
8a322796 | 238 | * Palette is assumed to contain BGR16, see rgb32to16 to convert the palette. |
fcfbc150 | 239 | */ |
7f526efd | 240 | void palette8torgb16(const uint8_t *src, uint8_t *dst, long num_pixels, const uint8_t *palette) |
fcfbc150 | 241 | { |
6e42e6c4 DB |
242 | long i; |
243 | for (i=0; i<num_pixels; i++) | |
774c386a | 244 | ((uint16_t *)dst)[i] = ((const uint16_t *)palette)[src[i]]; |
fcfbc150 | 245 | } |
7f526efd | 246 | void palette8tobgr16(const uint8_t *src, uint8_t *dst, long num_pixels, const uint8_t *palette) |
6c1baeb0 | 247 | { |
6e42e6c4 DB |
248 | long i; |
249 | for (i=0; i<num_pixels; i++) | |
774c386a | 250 | ((uint16_t *)dst)[i] = bswap_16(((const uint16_t *)palette)[src[i]]); |
6c1baeb0 | 251 | } |
fcfbc150 | 252 | |
6107059c | 253 | void rgb32to24(const uint8_t *src, uint8_t *dst, long src_size) |
ac4d0aea | 254 | { |
6e42e6c4 DB |
255 | long i; |
256 | long num_pixels = src_size >> 2; | |
dd68318c | 257 | for (i=0; i<num_pixels; i++) { |
7d73d1c3 RP |
258 | #if HAVE_BIGENDIAN |
259 | /* RGB32 (= A,B,G,R) -> BGR24 (= B,G,R) */ | |
260 | dst[3*i + 0] = src[4*i + 1]; | |
261 | dst[3*i + 1] = src[4*i + 2]; | |
262 | dst[3*i + 2] = src[4*i + 3]; | |
263 | #else | |
264 | dst[3*i + 0] = src[4*i + 2]; | |
265 | dst[3*i + 1] = src[4*i + 1]; | |
266 | dst[3*i + 2] = src[4*i + 0]; | |
267 | #endif | |
6e42e6c4 | 268 | } |
ac4d0aea MN |
269 | } |
270 | ||
6107059c | 271 | void rgb24to32(const uint8_t *src, uint8_t *dst, long src_size) |
ac4d0aea | 272 | { |
6e42e6c4 | 273 | long i; |
dd68318c | 274 | for (i=0; 3*i<src_size; i++) { |
7d73d1c3 RP |
275 | #if HAVE_BIGENDIAN |
276 | /* RGB24 (= R,G,B) -> BGR32 (= A,R,G,B) */ | |
277 | dst[4*i + 0] = 255; | |
278 | dst[4*i + 1] = src[3*i + 0]; | |
279 | dst[4*i + 2] = src[3*i + 1]; | |
280 | dst[4*i + 3] = src[3*i + 2]; | |
281 | #else | |
282 | dst[4*i + 0] = src[3*i + 2]; | |
283 | dst[4*i + 1] = src[3*i + 1]; | |
284 | dst[4*i + 2] = src[3*i + 0]; | |
285 | dst[4*i + 3] = 255; | |
286 | #endif | |
6e42e6c4 | 287 | } |
ac4d0aea MN |
288 | } |
289 | ||
7f526efd | 290 | void rgb16tobgr32(const uint8_t *src, uint8_t *dst, long src_size) |
ac4d0aea | 291 | { |
6e42e6c4 | 292 | const uint16_t *end; |
72d6b610 | 293 | uint8_t *d = dst; |
774c386a | 294 | const uint16_t *s = (const uint16_t *)src; |
6e42e6c4 | 295 | end = s + src_size/2; |
dd68318c | 296 | while (s < end) { |
6e42e6c4 DB |
297 | register uint16_t bgr; |
298 | bgr = *s++; | |
7d73d1c3 RP |
299 | #if HAVE_BIGENDIAN |
300 | *d++ = 255; | |
301 | *d++ = (bgr&0x1F)<<3; | |
302 | *d++ = (bgr&0x7E0)>>3; | |
303 | *d++ = (bgr&0xF800)>>8; | |
304 | #else | |
305 | *d++ = (bgr&0xF800)>>8; | |
306 | *d++ = (bgr&0x7E0)>>3; | |
307 | *d++ = (bgr&0x1F)<<3; | |
308 | *d++ = 255; | |
309 | #endif | |
6e42e6c4 | 310 | } |
ac4d0aea MN |
311 | } |
312 | ||
6107059c | 313 | void rgb16to24(const uint8_t *src, uint8_t *dst, long src_size) |
ac4d0aea | 314 | { |
6e42e6c4 | 315 | const uint16_t *end; |
72d6b610 | 316 | uint8_t *d = dst; |
6e42e6c4 DB |
317 | const uint16_t *s = (const uint16_t *)src; |
318 | end = s + src_size/2; | |
dd68318c | 319 | while (s < end) { |
6e42e6c4 DB |
320 | register uint16_t bgr; |
321 | bgr = *s++; | |
322 | *d++ = (bgr&0xF800)>>8; | |
323 | *d++ = (bgr&0x7E0)>>3; | |
324 | *d++ = (bgr&0x1F)<<3; | |
325 | } | |
ac4d0aea MN |
326 | } |
327 | ||
7f526efd | 328 | void rgb16tobgr16(const uint8_t *src, uint8_t *dst, long src_size) |
ac4d0aea | 329 | { |
6e42e6c4 DB |
330 | long i; |
331 | long num_pixels = src_size >> 1; | |
332 | ||
dd68318c | 333 | for (i=0; i<num_pixels; i++) { |
7372e9bb MN |
334 | unsigned rgb = ((const uint16_t*)src)[i]; |
335 | ((uint16_t*)dst)[i] = (rgb>>11) | (rgb&0x7E0) | (rgb<<11); | |
6e42e6c4 | 336 | } |
ac4d0aea MN |
337 | } |
338 | ||
7f526efd | 339 | void rgb16tobgr15(const uint8_t *src, uint8_t *dst, long src_size) |
ac4d0aea | 340 | { |
6e42e6c4 DB |
341 | long i; |
342 | long num_pixels = src_size >> 1; | |
343 | ||
dd68318c | 344 | for (i=0; i<num_pixels; i++) { |
7372e9bb MN |
345 | unsigned rgb = ((const uint16_t*)src)[i]; |
346 | ((uint16_t*)dst)[i] = (rgb>>11) | ((rgb&0x7C0)>>1) | ((rgb&0x1F)<<10); | |
6e42e6c4 | 347 | } |
ac4d0aea MN |
348 | } |
349 | ||
7f526efd | 350 | void rgb15tobgr32(const uint8_t *src, uint8_t *dst, long src_size) |
ac4d0aea | 351 | { |
6e42e6c4 | 352 | const uint16_t *end; |
72d6b610 | 353 | uint8_t *d = dst; |
6e42e6c4 DB |
354 | const uint16_t *s = (const uint16_t *)src; |
355 | end = s + src_size/2; | |
dd68318c | 356 | while (s < end) { |
6e42e6c4 DB |
357 | register uint16_t bgr; |
358 | bgr = *s++; | |
7d73d1c3 RP |
359 | #if HAVE_BIGENDIAN |
360 | *d++ = 255; | |
361 | *d++ = (bgr&0x1F)<<3; | |
362 | *d++ = (bgr&0x3E0)>>2; | |
363 | *d++ = (bgr&0x7C00)>>7; | |
364 | #else | |
365 | *d++ = (bgr&0x7C00)>>7; | |
366 | *d++ = (bgr&0x3E0)>>2; | |
367 | *d++ = (bgr&0x1F)<<3; | |
368 | *d++ = 255; | |
369 | #endif | |
6e42e6c4 | 370 | } |
ac4d0aea MN |
371 | } |
372 | ||
6107059c | 373 | void rgb15to24(const uint8_t *src, uint8_t *dst, long src_size) |
ac4d0aea | 374 | { |
6e42e6c4 | 375 | const uint16_t *end; |
72d6b610 | 376 | uint8_t *d = dst; |
774c386a | 377 | const uint16_t *s = (const uint16_t *)src; |
6e42e6c4 | 378 | end = s + src_size/2; |
dd68318c | 379 | while (s < end) { |
6e42e6c4 DB |
380 | register uint16_t bgr; |
381 | bgr = *s++; | |
382 | *d++ = (bgr&0x7C00)>>7; | |
383 | *d++ = (bgr&0x3E0)>>2; | |
384 | *d++ = (bgr&0x1F)<<3; | |
385 | } | |
ac4d0aea MN |
386 | } |
387 | ||
7f526efd | 388 | void rgb15tobgr16(const uint8_t *src, uint8_t *dst, long src_size) |
ac4d0aea | 389 | { |
6e42e6c4 DB |
390 | long i; |
391 | long num_pixels = src_size >> 1; | |
392 | ||
dd68318c | 393 | for (i=0; i<num_pixels; i++) { |
7372e9bb MN |
394 | unsigned rgb = ((const uint16_t*)src)[i]; |
395 | ((uint16_t*)dst)[i] = ((rgb&0x7C00)>>10) | ((rgb&0x3E0)<<1) | (rgb<<11); | |
6e42e6c4 | 396 | } |
ac4d0aea MN |
397 | } |
398 | ||
7f526efd | 399 | void rgb15tobgr15(const uint8_t *src, uint8_t *dst, long src_size) |
ac4d0aea | 400 | { |
6e42e6c4 DB |
401 | long i; |
402 | long num_pixels = src_size >> 1; | |
403 | ||
dd68318c | 404 | for (i=0; i<num_pixels; i++) { |
7372e9bb MN |
405 | unsigned br; |
406 | unsigned rgb = ((const uint16_t*)src)[i]; | |
407 | br = rgb&0x7c1F; | |
408 | ((uint16_t*)dst)[i] = (br>>10) | (rgb&0x3E0) | (br<<10); | |
6e42e6c4 | 409 | } |
ac4d0aea MN |
410 | } |
411 | ||
6107059c | 412 | void bgr8torgb8(const uint8_t *src, uint8_t *dst, long src_size) |
ac4d0aea | 413 | { |
6e42e6c4 DB |
414 | long i; |
415 | long num_pixels = src_size; | |
dd68318c | 416 | for (i=0; i<num_pixels; i++) { |
6e42e6c4 DB |
417 | unsigned b,g,r; |
418 | register uint8_t rgb; | |
419 | rgb = src[i]; | |
420 | r = (rgb&0x07); | |
421 | g = (rgb&0x38)>>3; | |
422 | b = (rgb&0xC0)>>6; | |
423 | dst[i] = ((b<<1)&0x07) | ((g&0x07)<<3) | ((r&0x03)<<6); | |
424 | } | |
ac4d0aea | 425 | } |
82e5f86b SS |
426 | |
427 | #define DEFINE_SHUFFLE_BYTES(a, b, c, d) \ | |
428 | void shuffle_bytes_##a##b##c##d(const uint8_t *src, uint8_t *dst, long src_size) \ | |
429 | { \ | |
430 | long i; \ | |
431 | \ | |
432 | for (i = 0; i < src_size; i+=4) { \ | |
433 | dst[i + 0] = src[i + a]; \ | |
434 | dst[i + 1] = src[i + b]; \ | |
435 | dst[i + 2] = src[i + c]; \ | |
436 | dst[i + 3] = src[i + d]; \ | |
437 | } \ | |
438 | } | |
439 | ||
440 | DEFINE_SHUFFLE_BYTES(0, 3, 2, 1); | |
441 | DEFINE_SHUFFLE_BYTES(1, 2, 3, 0); | |
442 | DEFINE_SHUFFLE_BYTES(2, 1, 0, 3); | |
443 | DEFINE_SHUFFLE_BYTES(3, 0, 1, 2); | |
444 | DEFINE_SHUFFLE_BYTES(3, 2, 1, 0); | |
445 |