1 #ifndef _IMAGE_CONVERT_H
2 #define _IMAGE_CONVERT_H
3
4 #include <stdint.h>
5 #include <retro_inline.h>
6
7 #ifdef __cplusplus
8 extern "C" {
9 #endif
10
11 #define RGB565_RSHIFT 11
12 #define RGB565_GSHIFT 5
13 #define RGB565_BSHIFT 0
14
15 #define RGB5551_RSHIFT 11
16 #define RGB5551_GSHIFT 6
17 #define RGB5551_BSHIFT 1
18 #define RGB5551_ASHIFT 0
19
20
21 union RGBA {
22 struct {
23 uint8_t r, g, b, a;
24 };
25 uint32_t raw;
26 };
27
YUVtoRGBA16(uint8_t y,uint8_t u,uint8_t v)28 static INLINE uint16_t YUVtoRGBA16(uint8_t y, uint8_t u, uint8_t v)
29 {
30 float r = y + (1.370705f * (v-128));
31 float g = y - (0.698001f * (v-128)) - (0.337633f * (u-128));
32 float b = y + (1.732446f * (u-128));
33 r *= 0.125f;
34 g *= 0.125f;
35 b *= 0.125f;
36
37 /* clipping the result */
38 if (r > 32)
39 r = 32;
40 if (g > 32)
41 g = 32;
42 if (b > 32)
43 b = 32;
44 if (r < 0)
45 r = 0;
46 if (g < 0)
47 g = 0;
48 if (b < 0)
49 b = 0;
50
51 return (uint16_t)(
52 ((uint16_t)(r) << RGB5551_RSHIFT) |
53 ((uint16_t)(g) << RGB5551_GSHIFT) |
54 ((uint16_t)(b) << RGB5551_BSHIFT) |
55 1);
56 }
57
YUVtoRGBA8888(uint8_t y,uint8_t u,uint8_t v)58 static INLINE uint32_t YUVtoRGBA8888(uint8_t y, uint8_t u, uint8_t v)
59 {
60 int32_t r = (int32_t)(y + (1.370705f * (v - 128)));
61 int32_t g = (int32_t)((y - (0.698001f * (v - 128)) - (0.337633f * (u - 128))));
62 int32_t b = (int32_t)(y + (1.732446f * (u - 128)));
63 //clipping the result
64 if (r > 255) r = 255;
65 if (g > 255) g = 255;
66 if (b > 255) b = 255;
67 if (r < 0) r = 0;
68 if (g < 0) g = 0;
69 if (b < 0) b = 0;
70
71 return (0xff << 24) | (b << 16) | (g << 8) | r;
72 }
73
YUVtoRGB565(uint8_t y,uint8_t u,uint8_t v)74 static uint16_t YUVtoRGB565(uint8_t y, uint8_t u, uint8_t v)
75 {
76 float r = y + (1.370705f * (v-128));
77 float g = y - (0.698001f * (v-128)) - (0.337633f * (u-128));
78 float b = y + (1.732446f * (u-128));
79
80 r *= 0.125f;
81 g *= 0.25f;
82 b *= 0.125f;
83
84 /* clipping the result */
85 if (r > 31) r = 31;
86 if (g > 63) g = 63;
87 if (b > 31) b = 31;
88 if (r < 0) r = 0;
89 if (g < 0) g = 0;
90 if (b < 0) b = 0;
91 return(uint16_t)(
92 ((uint16_t)(r) << RGB565_RSHIFT) |
93 ((uint16_t)(g) << RGB565_GSHIFT) |
94 ((uint16_t)(b) << RGB565_BSHIFT )
95 );
96 }
97
PAL8toR4G4B4A4(uint8_t r,uint8_t g,uint8_t b,uint8_t a)98 static INLINE uint16_t PAL8toR4G4B4A4(uint8_t r, uint8_t g, uint8_t b, uint8_t a)
99 {
100 return (uint16_t)((a << 12) | (r << 8) | (g <<4) | (b));
101 }
102
PAL8toRGBA16(uint8_t r,uint8_t g,uint8_t b,uint8_t a)103 static INLINE uint16_t PAL8toRGBA16(uint8_t r, uint8_t g, uint8_t b, uint8_t a)
104 {
105 return (uint16_t)(
106 ((uint16_t)(r >> 3) << RGB5551_RSHIFT) |
107 ((uint16_t)(g >> 3) << RGB5551_GSHIFT) |
108 ((uint16_t)(b >> 3) << RGB5551_BSHIFT) |
109 ((uint16_t)(a ) << RGB5551_ASHIFT));
110 }
111
PAL8toRGB565(uint8_t r,uint8_t g,uint8_t b,uint8_t a)112 static INLINE uint16_t PAL8toRGB565(uint8_t r, uint8_t g, uint8_t b, uint8_t a)
113 {
114 return (uint16_t)(
115 ((uint16_t)(r >> 3) << RGB565_RSHIFT) |
116 ((uint16_t)(g >> 2) << RGB565_GSHIFT) |
117 ((uint16_t)(b >> 3) << RGB565_BSHIFT));
118 }
119
RGBA32toRGBA16(uint32_t _c)120 static INLINE uint16_t RGBA32toRGBA16(uint32_t _c)
121 {
122 union RGBA c;
123 c.raw = _c;
124 return (
125 (c.r >> 3) << RGB5551_RSHIFT) |
126 ((c.g >> 3) << RGB5551_GSHIFT) |
127 ((c.b >> 3) << RGB5551_BSHIFT) |
128 ((c.a == 0) ? 0 : 1);
129 }
130
RGBA8toR8(uint8_t _c)131 static INLINE uint8_t RGBA8toR8(uint8_t _c)
132 {
133 return _c;
134 }
135
RGBA16toRGBA32(uint32_t _c)136 static INLINE uint32_t RGBA16toRGBA32(uint32_t _c)
137 {
138 union RGBA c;
139 c.raw = _c;
140 return (c.r << 24) | (c.g << 16) | (c.b << 8) | c.a;
141 }
142
UnswapCopyWrap(const uint8_t * src,uint32_t srcIdx,uint8_t * dest,uint32_t destIdx,uint32_t destMask,uint32_t numBytes)143 static INLINE void UnswapCopyWrap(const uint8_t *src, uint32_t srcIdx, uint8_t *dest, uint32_t destIdx, uint32_t destMask, uint32_t numBytes)
144 {
145 int numDWords;
146 int trailingBytes;
147 // copy leading bytes
148 uint32_t leadingBytes = srcIdx & 3;
149 if (leadingBytes != 0)
150 {
151 unsigned i;
152
153 leadingBytes = 4 - leadingBytes;
154 if ((uint32_t)leadingBytes > numBytes)
155 leadingBytes = numBytes;
156 numBytes -= leadingBytes;
157
158 srcIdx ^= 3;
159 for (i = 0; i < leadingBytes; i++)
160 {
161 dest[destIdx&destMask] = src[srcIdx];
162 ++destIdx;
163 --srcIdx;
164 }
165 srcIdx += 5;
166 }
167
168 // copy dwords
169 numDWords = numBytes >> 2;
170 while (numDWords--) {
171 dest[(destIdx + 3) & destMask] = src[srcIdx++];
172 dest[(destIdx + 2) & destMask] = src[srcIdx++];
173 dest[(destIdx + 1) & destMask] = src[srcIdx++];
174 dest[(destIdx + 0) & destMask] = src[srcIdx++];
175 destIdx += 4;
176 }
177
178 // copy trailing bytes
179 trailingBytes = numBytes & 3;
180 if (trailingBytes)
181 {
182 unsigned i;
183
184 srcIdx ^= 3;
185 for (i = 0; i < trailingBytes; i++)
186 {
187 dest[destIdx&destMask] = src[srcIdx];
188 ++destIdx;
189 --srcIdx;
190 }
191 }
192 }
193
DWordInterleaveWrap(uint32_t * src,uint32_t srcIdx,uint32_t srcMask,uint32_t numQWords)194 static INLINE void DWordInterleaveWrap(uint32_t *src, uint32_t srcIdx, uint32_t srcMask, uint32_t numQWords)
195 {
196 uint32_t tmp;
197 while (numQWords--) {
198 tmp = src[srcIdx & srcMask];
199 src[srcIdx & srcMask] = src[(srcIdx + 1) & srcMask];
200 ++srcIdx;
201 src[srcIdx & srcMask] = tmp;
202 ++srcIdx;
203 }
204 }
205
swapdword(uint32_t * a,uint32_t * b)206 static INLINE void swapdword(uint32_t *a, uint32_t *b)
207 {
208 uint32_t temp = *a;
209 *a = *b;
210 *b = temp;
211 }
212
swapbyte(uint8_t * a,uint8_t * b)213 static INLINE void swapbyte(uint8_t *a, uint8_t *b)
214 {
215 uint8_t temp = *a;
216 *a = *b;
217 *b = temp;
218 }
219
swapword(uint16_t value)220 static INLINE uint16_t swapword( uint16_t value )
221 {
222 return (value << 8) | (value >> 8);
223 }
224
225 #ifdef __cplusplus
226 }
227 #endif
228
229 #endif
230