diff options
author | erdgeist <erdgeist@erdgeist.org> | 2025-08-15 12:42:40 +0200 |
---|---|---|
committer | erdgeist <erdgeist@erdgeist.org> | 2025-08-15 12:42:40 +0200 |
commit | 30325d24d107dbf133da39f7c96d1510fd1c9449 (patch) | |
tree | 932baa5b2a4475821f16dccf9e3e05011daa6d92 /pack.c | |
parent | 9022d768021bbe15c7815cc6f8b64218b46f0e10 (diff) |
Bump to codec2 version 1.2.0erdgeist-bump-to-1.2.0
Diffstat (limited to 'pack.c')
-rw-r--r-- | pack.c | 104 |
1 files changed, 47 insertions, 57 deletions
@@ -15,19 +15,20 @@ | |||
15 | along with this program; if not, see <http://www.gnu.org/licenses/>. | 15 | along with this program; if not, see <http://www.gnu.org/licenses/>. |
16 | */ | 16 | */ |
17 | 17 | ||
18 | #include <stdio.h> | ||
19 | |||
18 | #include "defines.h" | 20 | #include "defines.h" |
19 | #include "quantise.h" | 21 | #include "quantise.h" |
20 | #include <stdio.h> | ||
21 | 22 | ||
22 | /* Compile-time constants */ | 23 | /* Compile-time constants */ |
23 | /* Size of unsigned char in bits. Assumes 8 bits-per-char. */ | 24 | /* Size of unsigned char in bits. Assumes 8 bits-per-char. */ |
24 | static const unsigned int WordSize = 8; | 25 | static const unsigned int WordSize = 8; |
25 | 26 | ||
26 | /* Mask to pick the bit component out of bitIndex. */ | 27 | /* Mask to pick the bit component out of bitIndex. */ |
27 | static const unsigned int IndexMask = 0x7; | 28 | static const unsigned int IndexMask = 0x7; |
28 | 29 | ||
29 | /* Used to pick the word component out of bitIndex. */ | 30 | /* Used to pick the word component out of bitIndex. */ |
30 | static const unsigned int ShiftRight = 3; | 31 | static const unsigned int ShiftRight = 3; |
31 | 32 | ||
32 | /** Pack a bit field into a bit string, encoding the field in Gray code. | 33 | /** Pack a bit field into a bit string, encoding the field in Gray code. |
33 | * | 34 | * |
@@ -44,86 +45,76 @@ static const unsigned int ShiftRight = 3; | |||
44 | * compatibility with the rest of the code, indices are always expected to | 45 | * compatibility with the rest of the code, indices are always expected to |
45 | * be >= 0. | 46 | * be >= 0. |
46 | */ | 47 | */ |
47 | void | 48 | void pack(unsigned char* bitArray, /* The output bit string. */ |
48 | pack( | 49 | unsigned int* bitIndex, /* Index into the string in BITS, not bytes.*/ |
49 | unsigned char * bitArray, /* The output bit string. */ | 50 | int field, /* The bit field to be packed. */ |
50 | unsigned int * bitIndex, /* Index into the string in BITS, not bytes.*/ | 51 | unsigned int fieldWidth /* Width of the field in BITS, not bytes. */ |
51 | int field, /* The bit field to be packed. */ | 52 | ) { |
52 | unsigned int fieldWidth/* Width of the field in BITS, not bytes. */ | 53 | pack_natural_or_gray(bitArray, bitIndex, field, fieldWidth, 1); |
53 | ) | ||
54 | { | ||
55 | pack_natural_or_gray(bitArray, bitIndex, field, fieldWidth, 1); | ||
56 | } | 54 | } |
57 | 55 | ||
58 | void | 56 | void pack_natural_or_gray( |
59 | pack_natural_or_gray( | 57 | unsigned char* bitArray, /* The output bit string. */ |
60 | unsigned char * bitArray, /* The output bit string. */ | 58 | unsigned int* bitIndex, /* Index into the string in BITS, not bytes.*/ |
61 | unsigned int * bitIndex, /* Index into the string in BITS, not bytes.*/ | 59 | int field, /* The bit field to be packed. */ |
62 | int field, /* The bit field to be packed. */ | 60 | unsigned int fieldWidth, /* Width of the field in BITS, not bytes. */ |
63 | unsigned int fieldWidth,/* Width of the field in BITS, not bytes. */ | 61 | unsigned int gray /* non-zero for gray coding */ |
64 | unsigned int gray /* non-zero for gray coding */ | 62 | ) { |
65 | ) | ||
66 | { | ||
67 | if (gray) { | 63 | if (gray) { |
68 | /* Convert the field to Gray code */ | 64 | /* Convert the field to Gray code */ |
69 | field = (field >> 1) ^ field; | 65 | field = (field >> 1) ^ field; |
70 | } | 66 | } |
71 | 67 | ||
72 | do { | 68 | do { |
73 | unsigned int bI = *bitIndex; | 69 | unsigned int bI = *bitIndex; |
74 | unsigned int bitsLeft = WordSize - (bI & IndexMask); | 70 | unsigned int bitsLeft = WordSize - (bI & IndexMask); |
75 | unsigned int sliceWidth = | 71 | unsigned int sliceWidth = bitsLeft < fieldWidth ? bitsLeft : fieldWidth; |
76 | bitsLeft < fieldWidth ? bitsLeft : fieldWidth; | 72 | unsigned int wordIndex = bI >> ShiftRight; |
77 | unsigned int wordIndex = bI >> ShiftRight; | ||
78 | 73 | ||
79 | bitArray[wordIndex] |= | 74 | bitArray[wordIndex] |= ((unsigned char)((field >> (fieldWidth - sliceWidth)) |
80 | ((unsigned char)((field >> (fieldWidth - sliceWidth)) | 75 | << (bitsLeft - sliceWidth))); |
81 | << (bitsLeft - sliceWidth))); | ||
82 | 76 | ||
83 | *bitIndex = bI + sliceWidth; | 77 | *bitIndex = bI + sliceWidth; |
84 | fieldWidth -= sliceWidth; | 78 | fieldWidth -= sliceWidth; |
85 | } while ( fieldWidth != 0 ); | 79 | } while (fieldWidth != 0); |
86 | } | 80 | } |
87 | 81 | ||
88 | /** Unpack a field from a bit string, converting from Gray code to binary. | 82 | /** Unpack a field from a bit string, converting from Gray code to binary. |
89 | * | 83 | * |
90 | */ | 84 | */ |
91 | int | 85 | int unpack( |
92 | unpack( | 86 | const unsigned char* bitArray, /* The input bit string. */ |
93 | const unsigned char * bitArray, /* The input bit string. */ | 87 | unsigned int* bitIndex, /* Index into the string in BITS, not bytes.*/ |
94 | unsigned int * bitIndex, /* Index into the string in BITS, not bytes.*/ | 88 | unsigned int fieldWidth /* Width of the field in BITS, not bytes. */ |
95 | unsigned int fieldWidth/* Width of the field in BITS, not bytes. */ | 89 | ) { |
96 | ) | 90 | return unpack_natural_or_gray(bitArray, bitIndex, fieldWidth, 1); |
97 | { | ||
98 | return unpack_natural_or_gray(bitArray, bitIndex, fieldWidth, 1); | ||
99 | } | 91 | } |
100 | 92 | ||
101 | /** Unpack a field from a bit string, to binary, optionally using | 93 | /** Unpack a field from a bit string, to binary, optionally using |
102 | * natural or Gray code. | 94 | * natural or Gray code. |
103 | * | 95 | * |
104 | */ | 96 | */ |
105 | int | 97 | int unpack_natural_or_gray( |
106 | unpack_natural_or_gray( | 98 | const unsigned char* bitArray, /* The input bit string. */ |
107 | const unsigned char * bitArray, /* The input bit string. */ | 99 | unsigned int* bitIndex, /* Index into the string in BITS, not bytes.*/ |
108 | unsigned int * bitIndex, /* Index into the string in BITS, not bytes.*/ | 100 | unsigned int fieldWidth, /* Width of the field in BITS, not bytes. */ |
109 | unsigned int fieldWidth,/* Width of the field in BITS, not bytes. */ | 101 | unsigned int gray /* non-zero for Gray coding */ |
110 | unsigned int gray /* non-zero for Gray coding */ | 102 | ) { |
111 | ) | 103 | unsigned int field = 0; |
112 | { | 104 | unsigned int t; |
113 | unsigned int field = 0; | ||
114 | unsigned int t; | ||
115 | 105 | ||
116 | do { | 106 | do { |
117 | unsigned int bI = *bitIndex; | 107 | unsigned int bI = *bitIndex; |
118 | unsigned int bitsLeft = WordSize - (bI & IndexMask); | 108 | unsigned int bitsLeft = WordSize - (bI & IndexMask); |
119 | unsigned int sliceWidth = | 109 | unsigned int sliceWidth = bitsLeft < fieldWidth ? bitsLeft : fieldWidth; |
120 | bitsLeft < fieldWidth ? bitsLeft : fieldWidth; | ||
121 | 110 | ||
122 | field |= (((bitArray[bI >> ShiftRight] >> (bitsLeft - sliceWidth)) & ((1 << sliceWidth) - 1)) << (fieldWidth - sliceWidth)); | 111 | field |= (((bitArray[bI >> ShiftRight] >> (bitsLeft - sliceWidth)) & |
112 | ((1 << sliceWidth) - 1)) | ||
113 | << (fieldWidth - sliceWidth)); | ||
123 | 114 | ||
124 | *bitIndex = bI + sliceWidth; | 115 | *bitIndex = bI + sliceWidth; |
125 | fieldWidth -= sliceWidth; | 116 | fieldWidth -= sliceWidth; |
126 | } while ( fieldWidth != 0 ); | 117 | } while (fieldWidth != 0); |
127 | 118 | ||
128 | if (gray) { | 119 | if (gray) { |
129 | /* Convert from Gray code to binary. Works for maximum 8-bit fields. */ | 120 | /* Convert from Gray code to binary. Works for maximum 8-bit fields. */ |
@@ -131,8 +122,7 @@ unpack_natural_or_gray( | |||
131 | t ^= (t >> 4); | 122 | t ^= (t >> 4); |
132 | t ^= (t >> 2); | 123 | t ^= (t >> 2); |
133 | t ^= (t >> 1); | 124 | t ^= (t >> 1); |
134 | } | 125 | } else { |
135 | else { | ||
136 | t = field; | 126 | t = field; |
137 | } | 127 | } |
138 | 128 | ||