summaryrefslogtreecommitdiff
path: root/pack.c
diff options
context:
space:
mode:
authorerdgeist <erdgeist@erdgeist.org>2025-08-15 12:42:40 +0200
committererdgeist <erdgeist@erdgeist.org>2025-08-15 12:42:40 +0200
commit30325d24d107dbf133da39f7c96d1510fd1c9449 (patch)
tree932baa5b2a4475821f16dccf9e3e05011daa6d92 /pack.c
parent9022d768021bbe15c7815cc6f8b64218b46f0e10 (diff)
Bump to codec2 version 1.2.0erdgeist-bump-to-1.2.0
Diffstat (limited to 'pack.c')
-rw-r--r--pack.c104
1 files changed, 47 insertions, 57 deletions
diff --git a/pack.c b/pack.c
index 1c07230..3181223 100644
--- a/pack.c
+++ b/pack.c
@@ -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. */
24static const unsigned int WordSize = 8; 25static 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. */
27static const unsigned int IndexMask = 0x7; 28static 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. */
30static const unsigned int ShiftRight = 3; 31static 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 */
47void 48void pack(unsigned char* bitArray, /* The output bit string. */
48pack( 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
58void 56void pack_natural_or_gray(
59pack_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 */
91int 85int unpack(
92unpack( 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 */
105int 97int unpack_natural_or_gray(
106unpack_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