/src/mpg123/src/common/swap_bytes_impl.h
Line | Count | Source |
1 | | /* |
2 | | swap_bytes: Swap byte order of samples in a buffer. |
3 | | |
4 | | copyright 2018 by the mpg123 project |
5 | | licensed under the terms of the LGPL 2.1 |
6 | | see COPYING and AUTHORS files in distribution or http://mpg123.org |
7 | | |
8 | | initially written by Thomas Orgis |
9 | | |
10 | | This is C source to include in your code to get the function named |
11 | | swap_bytes. It is serves intentional duplication in libmpg123 and |
12 | | libsyn123 to avoid introducing a dependency between them. This function |
13 | | is too small for that. |
14 | | */ |
15 | | |
16 | | /* Other headers are already included! */ |
17 | | |
18 | | /* Optionally use platform-specific byteswap macros. */ |
19 | | #ifdef HAVE_BYTESWAP_H |
20 | | #include <byteswap.h> |
21 | | #endif |
22 | | |
23 | | /* Plain stupid swapping of elements in a byte array. */ |
24 | | /* This is the fallback when there is no native bswap macro. */ |
25 | 0 | #define SWAP(a,b) tmp = p[a]; p[a] = p[b]; p[b] = tmp; |
26 | | |
27 | | /* Convert samplecount elements of samplesize bytes each in buffer buf. */ |
28 | | static void swap_bytes(void *buf, size_t samplesize, size_t samplecount) |
29 | 0 | { |
30 | 0 | unsigned char *p = buf; |
31 | 0 | unsigned char *pend = (unsigned char*)buf+samplesize*samplecount; |
32 | 0 | unsigned char tmp; |
33 | |
|
34 | 0 | if(samplesize < 2) |
35 | 0 | return; |
36 | 0 | switch(samplesize) |
37 | 0 | { |
38 | 0 | case 2: /* AB -> BA */ |
39 | 0 | #ifdef HAVE_BYTESWAP_H |
40 | 0 | { |
41 | 0 | uint16_t* pp = (uint16_t*)p; |
42 | 0 | for(; pp<(uint16_t*)pend; ++pp) |
43 | 0 | *pp = bswap_16(*pp); |
44 | 0 | } |
45 | | #else |
46 | | for(; p<pend; p+=2) |
47 | | { |
48 | | SWAP(0,1) |
49 | | } |
50 | | #endif |
51 | 0 | break; |
52 | 0 | case 3: /* ABC -> CBA */ |
53 | 0 | for(; p<pend; p+=3) |
54 | 0 | { |
55 | 0 | SWAP(0,2) |
56 | 0 | } |
57 | 0 | break; |
58 | 0 | case 4: /* ABCD -> DCBA */ |
59 | 0 | #ifdef HAVE_BYTESWAP_H |
60 | 0 | { |
61 | 0 | uint32_t* pp = (uint32_t*)p; |
62 | 0 | for(; pp<(uint32_t*)pend; ++pp) |
63 | 0 | *pp = bswap_32(*pp); |
64 | 0 | } |
65 | | #else |
66 | | for(; p<pend; p+=4) |
67 | | { |
68 | | SWAP(0,3) |
69 | | SWAP(1,2) |
70 | | } |
71 | | #endif |
72 | 0 | break; |
73 | 0 | case 8: /* ABCDEFGH -> HGFEDCBA */ |
74 | 0 | #ifdef HAVE_BYTESWAP_H |
75 | 0 | { |
76 | 0 | uint64_t* pp = (uint64_t*)p; |
77 | 0 | for(; pp<(uint64_t*)pend; ++pp) |
78 | 0 | *pp = bswap_64(*pp); |
79 | 0 | } |
80 | | #else |
81 | | for(; p<pend; p+=8) |
82 | | { |
83 | | SWAP(0,7) |
84 | | SWAP(1,6) |
85 | | SWAP(2,5) |
86 | | SWAP(3,4) |
87 | | } |
88 | | #endif |
89 | 0 | break; |
90 | | /* All the weird choices with the full nested loop. */ |
91 | 0 | default: |
92 | 0 | for(; p<pend; p+=samplesize) |
93 | 0 | { |
94 | 0 | size_t j; |
95 | 0 | for(j=0; j<samplesize/2; ++j) |
96 | 0 | { |
97 | 0 | SWAP(j, samplesize-j-1) |
98 | 0 | } |
99 | 0 | } |
100 | 0 | } |
101 | 0 | } |
102 | | |
103 | | #undef SWAP |