| 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 | |