diff options
Diffstat (limited to 'v17tcm.c')
-rw-r--r-- | v17tcm.c | 109 |
1 files changed, 109 insertions, 0 deletions
diff --git a/v17tcm.c b/v17tcm.c new file mode 100644 index 0000000..0edaefe --- /dev/null +++ b/v17tcm.c @@ -0,0 +1,109 @@ +#include <assert.h> +#include <string.h> +#include <stdio.h> +#include <inttypes.h> + +#include "v17tcm.h" + +static const uint8_t v17tcm_table[] = { + 0, 1, 2, 3, + 1, 2, 3, 0, + 2, 3, 0, 1, + 3, 0, 1, 2 +}; + +static const uint8_t v17tcm_table_reverse[] = { + 0, 1, 2, 3, + 3, 0, 1, 2, + 2, 3, 0, 1, + 1, 2, 3, 0 +}; + +void v17tcm_init(struct v17tcm_state *s) { + assert(s); + memset(s, 0, sizeof(*s)); +} + +static uint8_t conv_encode(struct v17tcm_state* s, uint8_t y) { + uint8_t x, a, b, c, d, e; + + /* + fprintf(stderr, "conv_encode(..., %u)\n", y); + */ + a = (y&1) ^ (y>>1); + b = (a ^ s->c1); + d = s->c2 ^ (s->c2 ^ (y>>1)); + c = b ^ (s->c3 & d); + e = d ^ ((y&1) & s->c3); + + x = s->c3; + + s->c1 = s->c3; + s->c2 = c; + s->c3 = e; + + return x; +} + +uint8_t v17tcm_encode(struct v17tcm_state* s, uint8_t input) { + uint8_t y, c; + + y = s->y = v17tcm_table[((input & 3) << 2) | (s->y & 3)]; + + /*fprintf(stderr, "tcm = %u\n", y);*/ + + c = conv_encode(s, y); + + /*fprintf(stderr, "c:%u von %u\n", c, y);*/ + + return c | ((y | (input & ~3)) << 1); +} + +uint8_t v17tcm_decode(struct v17tcm_state *s, uint8_t input) { + uint8_t y, py; + + if (conv_encode(s, (input >> 1) & 3) != (input & 1)) + fprintf(stderr, "Invalid TCM code, ignoring\n"); + + y = v17tcm_table_reverse[((s->y&3) << 2) | (py = ((input >> 1) & 3))]; + + s->y = py; + + return (input >> 3 << 2) | y; +} + +#ifdef TEST1 +int main() { + uint8_t c; + + for (c = 0; c <= 0xF; c++) { + if (v17tcm_table_reverse[v17tcm_table[c] | ((c&3) << 2)] != (c >> 2)) + fprintf(stderr, "%u: FEHLER\n", c); + else + fprintf(stderr, "%u: OK\n", c); + } + return 0; +} +#endif + +#ifdef TEST2 +int main() { + struct v17tcm_state s1, s2; + int c, n; + + v17tcm_init(&s1); + v17tcm_init(&s2); + + n = 0; + while ((c = getchar()) >= 0) { + uint8_t b = ((uint8_t) c) & 63; + uint8_t u = v17tcm_encode(&s1, b); + uint8_t e = v17tcm_decode(&s2, u); + + fprintf(stderr, "%i) %u %s %u (encoded: %u)\n", n++, b, b == e ? "==" : "!=", e, u); + } + + return 0; +} + +#endif |