1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
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
|