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