34cf4058 |
1 | #ifndef CONVERT_H |
2 | #define CONVERT_H |
3 | |
4 | #include "Types.h" |
5 | |
6 | const volatile unsigned char Five2Eight[32] = |
7 | { |
8 | 0, // 00000 = 00000000 |
9 | 8, // 00001 = 00001000 |
10 | 16, // 00010 = 00010000 |
11 | 25, // 00011 = 00011001 |
12 | 33, // 00100 = 00100001 |
13 | 41, // 00101 = 00101001 |
14 | 49, // 00110 = 00110001 |
15 | 58, // 00111 = 00111010 |
16 | 66, // 01000 = 01000010 |
17 | 74, // 01001 = 01001010 |
18 | 82, // 01010 = 01010010 |
19 | 90, // 01011 = 01011010 |
20 | 99, // 01100 = 01100011 |
21 | 107, // 01101 = 01101011 |
22 | 115, // 01110 = 01110011 |
23 | 123, // 01111 = 01111011 |
24 | 132, // 10000 = 10000100 |
25 | 140, // 10001 = 10001100 |
26 | 148, // 10010 = 10010100 |
27 | 156, // 10011 = 10011100 |
28 | 165, // 10100 = 10100101 |
29 | 173, // 10101 = 10101101 |
30 | 181, // 10110 = 10110101 |
31 | 189, // 10111 = 10111101 |
32 | 197, // 11000 = 11000101 |
33 | 206, // 11001 = 11001110 |
34 | 214, // 11010 = 11010110 |
35 | 222, // 11011 = 11011110 |
36 | 230, // 11100 = 11100110 |
37 | 239, // 11101 = 11101111 |
38 | 247, // 11110 = 11110111 |
39 | 255 // 11111 = 11111111 |
40 | }; |
41 | |
42 | const volatile unsigned char Four2Eight[16] = |
43 | { |
44 | 0, // 0000 = 00000000 |
45 | 17, // 0001 = 00010001 |
46 | 34, // 0010 = 00100010 |
47 | 51, // 0011 = 00110011 |
48 | 68, // 0100 = 01000100 |
49 | 85, // 0101 = 01010101 |
50 | 102, // 0110 = 01100110 |
51 | 119, // 0111 = 01110111 |
52 | 136, // 1000 = 10001000 |
53 | 153, // 1001 = 10011001 |
54 | 170, // 1010 = 10101010 |
55 | 187, // 1011 = 10111011 |
56 | 204, // 1100 = 11001100 |
57 | 221, // 1101 = 11011101 |
58 | 238, // 1110 = 11101110 |
59 | 255 // 1111 = 11111111 |
60 | }; |
61 | |
62 | const volatile unsigned char Three2Four[8] = |
63 | { |
64 | 0, // 000 = 0000 |
65 | 2, // 001 = 0010 |
66 | 4, // 010 = 0100 |
67 | 6, // 011 = 0110 |
68 | 9, // 100 = 1001 |
69 | 11, // 101 = 1011 |
70 | 13, // 110 = 1101 |
71 | 15, // 111 = 1111 |
72 | }; |
73 | |
74 | const volatile unsigned char Three2Eight[8] = |
75 | { |
76 | 0, // 000 = 00000000 |
77 | 36, // 001 = 00100100 |
78 | 73, // 010 = 01001001 |
79 | 109, // 011 = 01101101 |
80 | 146, // 100 = 10010010 |
81 | 182, // 101 = 10110110 |
82 | 219, // 110 = 11011011 |
83 | 255, // 111 = 11111111 |
84 | }; |
85 | const volatile unsigned char Two2Eight[4] = |
86 | { |
87 | 0, // 00 = 00000000 |
88 | 85, // 01 = 01010101 |
89 | 170, // 10 = 10101010 |
90 | 255 // 11 = 11111111 |
91 | }; |
92 | |
93 | const volatile unsigned char One2Four[2] = |
94 | { |
95 | 0, // 0 = 0000 |
96 | 15, // 1 = 1111 |
97 | }; |
98 | |
99 | const volatile unsigned char One2Eight[2] = |
100 | { |
101 | 0, // 0 = 00000000 |
102 | 255, // 1 = 11111111 |
103 | }; |
104 | |
105 | static inline void UnswapCopy( void *src, void *dest, u32 numBytes ) |
106 | { |
107 | // copy leading bytes |
108 | int leadingBytes = ((long)src) & 3; |
109 | if (leadingBytes != 0) |
110 | { |
111 | leadingBytes = 4-leadingBytes; |
112 | if ((unsigned int)leadingBytes > numBytes) |
113 | leadingBytes = numBytes; |
114 | numBytes -= leadingBytes; |
115 | |
116 | src = (void *)((long)src ^ 3); |
117 | for (int i = 0; i < leadingBytes; i++) |
118 | { |
119 | *(u8 *)(dest) = *(u8 *)(src); |
120 | dest = (void *)((long)dest+1); |
121 | src = (void *)((long)src -1); |
122 | } |
123 | src = (void *)((long)src+5); |
124 | } |
125 | |
126 | // copy dwords |
127 | int numDWords = numBytes >> 2; |
128 | while (numDWords--) |
129 | { |
130 | u32 dword = *(u32 *)src; |
131 | #ifdef ARM_ASM |
132 | asm("rev %0, %0" : "+r"(dword)::); |
133 | #else |
134 | dword = ((dword<<24)|((dword<<8)&0x00FF0000)|((dword>>8)&0x0000FF00)|(dword>>24)); |
135 | #endif |
136 | *(u32 *)dest = dword; |
137 | dest = (void *)((long)dest+4); |
138 | src = (void *)((long)src +4); |
139 | } |
140 | |
141 | // copy trailing bytes |
142 | int trailingBytes = numBytes & 3; |
143 | if (trailingBytes) |
144 | { |
145 | src = (void *)((long)src ^ 3); |
146 | for (int i = 0; i < trailingBytes; i++) |
147 | { |
148 | *(u8 *)(dest) = *(u8 *)(src); |
149 | dest = (void *)((long)dest+1); |
150 | src = (void *)((long)src -1); |
151 | } |
152 | } |
153 | } |
154 | |
155 | static inline void DWordInterleave( void *mem, u32 numDWords ) |
156 | { |
157 | int tmp; |
158 | while( numDWords-- ) |
159 | { |
160 | tmp = *(int *)((long)mem + 0); |
161 | *(int *)((long)mem + 0) = *(int *)((long)mem + 4); |
162 | *(int *)((long)mem + 4) = tmp; |
163 | mem = (void *)((long)mem + 8); |
164 | } |
165 | } |
166 | |
167 | inline void QWordInterleave( void *mem, u32 numDWords ) |
168 | { |
169 | numDWords >>= 1; // qwords |
170 | while( numDWords-- ) |
171 | { |
172 | int tmp0, tmp1; |
173 | tmp0 = *(int *)((long)mem + 0); |
174 | tmp1 = *(int *)((long)mem + 4); |
175 | *(int *)((long)mem + 0) = *(int *)((long)mem + 8); |
176 | *(int *)((long)mem + 8) = tmp0; |
177 | *(int *)((long)mem + 4) = *(int *)((long)mem + 12); |
178 | *(int *)((long)mem + 12) = tmp1; |
179 | mem = (void *)((long)mem + 16); |
180 | } |
181 | } |
182 | |
183 | |
184 | inline u32 swapdword( u32 value ) |
185 | { |
186 | #ifdef ARM_ASM |
187 | asm("rev %0, %0" : "+r"(value)::); |
188 | return value; |
189 | #else |
190 | return ((value & 0xff000000) >> 24) | |
191 | ((value & 0x00ff0000) >> 8) | |
192 | ((value & 0x0000ff00) << 8) | |
193 | ((value & 0x000000ff) << 24); |
194 | #endif |
195 | } |
196 | |
197 | inline u16 swapword( u16 value ) |
198 | { |
199 | #ifdef ARM_ASM |
200 | asm("rev16 %0, %0" : "+r"(value)::); |
201 | return value; |
202 | #else |
203 | return (value << 8) | (value >> 8); |
204 | #endif |
205 | } |
206 | |
207 | inline u16 RGBA8888_RGBA4444( u32 color ) |
208 | { |
209 | return ((color & 0x000000f0) << 8) | // r |
210 | ((color & 0x0000f000) >> 4) | // g |
211 | ((color & 0x00f00000) >> 16) | // b |
212 | ((color & 0xf0000000) >> 28); // a |
213 | } |
214 | |
215 | inline u32 RGBA5551_RGBA8888( u16 color ) |
216 | { |
217 | color = swapword( color ); |
218 | u8 r, g, b, a; |
219 | r = Five2Eight[color >> 11]; |
220 | g = Five2Eight[(color >> 6) & 0x001f]; |
221 | b = Five2Eight[(color >> 1) & 0x001f]; |
222 | a = One2Eight [(color ) & 0x0001]; |
223 | return (a << 24) | (b << 16) | (g << 8) | r; |
224 | } |
225 | |
226 | // Just swaps the word |
227 | inline u16 RGBA5551_RGBA5551( u16 color ) |
228 | { |
229 | return swapword( color ); |
230 | } |
231 | |
232 | inline u32 IA88_RGBA8888( u16 color ) |
233 | { |
234 | u8 a = color >> 8; |
235 | u8 i = color & 0x00FF; |
236 | return (a << 24) | (i << 16) | (i << 8) | i; |
237 | } |
238 | |
239 | inline u16 IA88_RGBA4444( u16 color ) |
240 | { |
241 | u8 i = color >> 12; |
242 | u8 a = (color >> 4) & 0x000F; |
243 | return (i << 12) | (i << 8) | (i << 4) | a; |
244 | } |
245 | |
246 | inline u16 IA44_RGBA4444( u8 color ) |
247 | { |
248 | return ((color & 0xf0) << 8) | ((color & 0xf0) << 4) | (color); |
249 | } |
250 | |
251 | inline u32 IA44_RGBA8888( u8 color ) |
252 | { |
253 | u8 i = Four2Eight[color >> 4]; |
254 | u8 a = Four2Eight[color & 0x0F]; |
255 | return (a << 24) | (i << 16) | (i << 8) | i; |
256 | } |
257 | |
258 | inline u16 IA44_IA88( u8 color ) |
259 | { |
260 | u8 i = Four2Eight[color >> 4]; |
261 | u8 a = Four2Eight[color & 0x0F]; |
262 | return (a << 8) | i; |
263 | } |
264 | |
265 | inline u16 IA31_RGBA4444( u8 color ) |
266 | { |
267 | u8 i = Three2Four[color >> 1]; |
268 | u8 a = One2Four[color & 0x01]; |
269 | return (i << 12) | (i << 8) | (i << 4) | a; |
270 | } |
271 | |
272 | inline u16 IA31_IA88( u8 color ) |
273 | { |
274 | u8 i = Three2Eight[color >> 1]; |
275 | u8 a = One2Eight[color & 0x01]; |
276 | return (a << 8) | i; |
277 | } |
278 | |
279 | inline u32 IA31_RGBA8888( u8 color ) |
280 | { |
281 | u8 i = Three2Eight[color >> 1]; |
282 | u8 a = One2Eight[color & 0x01]; |
283 | return (i << 24) | (i << 16) | (i << 8) | a; |
284 | } |
285 | |
286 | inline u16 I8_RGBA4444( u8 color ) |
287 | { |
288 | u8 c = color >> 4; |
289 | return (c << 12) | (c << 8) | (c << 4) | c; |
290 | } |
291 | |
292 | inline u32 I8_RGBA8888( u8 color ) |
293 | { |
294 | return (color << 24) | (color << 16) | (color << 8) | color; |
295 | } |
296 | |
297 | inline u16 I4_RGBA4444( u8 color ) |
298 | { |
299 | u16 ret = color & 0x0f; |
300 | ret |= ret << 4; |
301 | ret |= ret << 8; |
302 | return ret; |
303 | } |
304 | |
305 | inline u8 I4_I8( u8 color ) |
306 | { |
307 | return Four2Eight[color & 0x0f]; |
308 | } |
309 | |
310 | inline u16 I4_IA88( u8 color ) |
311 | { |
312 | u32 c = Four2Eight[color & 0x0f]; |
313 | return (c << 8) | c; |
314 | } |
315 | |
316 | inline u16 I8_IA88( u8 color ) |
317 | { |
318 | return (color << 8) | color; |
319 | } |
320 | |
321 | |
322 | inline u16 IA88_IA88( u16 color ) |
323 | { |
324 | u8 a = (color&0xFF); |
325 | u8 i = (color>>8); |
326 | return (i << 8) | a; |
327 | } |
328 | |
329 | |
330 | inline u32 I4_RGBA8888( u8 color ) |
331 | { |
332 | u8 c = Four2Eight[color]; |
333 | c |= c << 4; |
334 | return (c << 24) | (c << 16) | (c << 8) | c; |
335 | } |
336 | |
337 | #endif // CONVERT_H |
338 | |