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