1 /*
2 * libzvbi -- Error correction functions
3 *
4 * Copyright (C) 2001, 2002, 2003, 2004, 2007 Michael H. Schimek
5 *
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Library General Public
8 * License as published by the Free Software Foundation; either
9 * version 2 of the License, or (at your option) any later version.
10 *
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Library General Public License for more details.
15 *
16 * You should have received a copy of the GNU Library General Public
17 * License along with this library; if not, write to the
18 * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
19 * Boston, MA 02110-1301 USA.
20 */
21
22 /* $Id: hamm.h,v 1.16 2013-07-10 11:37:13 mschimek Exp $ */
23
24 #ifndef __ZVBI_HAMM_H__
25 #define __ZVBI_HAMM_H__
26
27 #include <inttypes.h> /* uintN_t */
28 #include "macros.h"
29
30 VBI_BEGIN_DECLS
31
32 /* Public */
33
34 extern const uint8_t _vbi_bit_reverse [256];
35 extern const uint8_t _vbi_hamm8_fwd [16];
36 extern const int8_t _vbi_hamm8_inv [256];
37 extern const int8_t _vbi_hamm24_inv_par [3][256];
38
39 /**
40 * @addtogroup Error Error correction functions
41 * @ingroup Raw
42 * @brief Helper functions to decode sliced VBI data.
43 * @{
44 */
45
46 /**
47 * @param c Unsigned byte.
48 *
49 * Reverses the bits of the argument.
50 *
51 * @returns
52 * Data bits 0 [msb] ... 7 [lsb].
53 *
54 * @since 0.2.12
55 */
56 _vbi_inline unsigned int
vbi_rev8(unsigned int c)57 vbi_rev8 (unsigned int c)
58 {
59 return _vbi_bit_reverse[(uint8_t) c];
60 }
61
62 /**
63 * @param c Unsigned 16 bit word.
64 *
65 * Reverses (or "reflects") the bits of the argument.
66 *
67 * @returns
68 * Data bits 0 [msb] ... 15 [lsb].
69 *
70 * @since 0.2.12
71 */
72 _vbi_inline unsigned int
vbi_rev16(unsigned int c)73 vbi_rev16 (unsigned int c)
74 {
75 return _vbi_bit_reverse[(uint8_t) c] * 256
76 + _vbi_bit_reverse[(uint8_t)(c >> 8)];
77 }
78
79 /**
80 * @param p Pointer to a 16 bit word, last significant
81 * byte first.
82 *
83 * Reverses (or "reflects") the bits of the argument.
84 *
85 * @returns
86 * Data bits 0 [msb] ... 15 [lsb].
87 *
88 * @since 0.2.12
89 */
90 _vbi_inline unsigned int
vbi_rev16p(const uint8_t * p)91 vbi_rev16p (const uint8_t * p)
92 {
93 return _vbi_bit_reverse[p[0]] * 256
94 + _vbi_bit_reverse[p[1]];
95 }
96
97 /**
98 * @param c Unsigned byte.
99 *
100 * @returns
101 * Changes the most significant bit of the byte
102 * to make the number of set bits odd.
103 *
104 * @since 0.2.12
105 */
106 _vbi_inline unsigned int
vbi_par8(unsigned int c)107 vbi_par8 (unsigned int c)
108 {
109 c &= 255;
110
111 /* if 0 == (inv_par[] & 32) change bit 7 of c. */
112 c ^= 128 & ~(_vbi_hamm24_inv_par[0][c] << 2);
113
114 return c;
115 }
116
117 /**
118 * @param c Unsigned byte.
119 *
120 * @returns
121 * If the byte has odd parity (sum of bits modulo 2 is 1) the
122 * byte AND 127, otherwise a negative value.
123 *
124 * @since 0.2.12
125 */
126 _vbi_inline int
vbi_unpar8(unsigned int c)127 vbi_unpar8 (unsigned int c)
128 {
129 /* Disabled until someone finds a reliable way
130 to test for cmov support at compile time. */
131 #if 0
132 int r = c & 127;
133
134 /* This saves cache flushes and an explicit branch. */
135 __asm__ (" testb %1,%1\n"
136 " cmovp %2,%0\n"
137 : "+&a" (r) : "c" (c), "rm" (-1));
138 return r;
139 #endif
140 if (_vbi_hamm24_inv_par[0][(uint8_t) c] & 32) {
141 return c & 127;
142 } else {
143 /* The idea is to OR results together to find a parity
144 error in a sequence, rather than a test and branch on
145 each byte. */
146 return -1;
147 }
148 }
149
150 extern void
151 vbi_par (uint8_t * p,
152 unsigned int n);
153 extern int
154 vbi_unpar (uint8_t * p,
155 unsigned int n);
156
157 /**
158 * @param c Integer between 0 ... 15.
159 *
160 * Encodes a nibble with Hamming 8/4 protection
161 * as specified in EN 300 706, Section 8.2.
162 *
163 * @returns
164 * Hamming encoded unsigned byte, lsb first transmitted.
165 *
166 * @since 0.2.12
167 */
168 _vbi_inline unsigned int
vbi_ham8(unsigned int c)169 vbi_ham8 (unsigned int c)
170 {
171 return _vbi_hamm8_fwd[c & 15];
172 }
173
174 /**
175 * @param c Hamming 8/4 protected byte, lsb first transmitted.
176 *
177 * Decodes a Hamming 8/4 protected byte
178 * as specified in EN 300 706, Section 8.2.
179 *
180 * @returns
181 * Data bits (D4 [msb] ... D1 [lsb]) or a negative
182 * value if the byte contained uncorrectable errors.
183 *
184 * @since 0.2.12
185 */
186 _vbi_inline int
vbi_unham8(unsigned int c)187 vbi_unham8 (unsigned int c)
188 {
189 return _vbi_hamm8_inv[(uint8_t) c];
190 }
191
192 /**
193 * @param p Pointer to a Hamming 8/4 protected 16 bit word,
194 * last significant byte first, lsb first transmitted.
195 *
196 * Decodes a Hamming 8/4 protected byte pair
197 * as specified in EN 300 706, Section 8.2.
198 *
199 * @returns
200 * Data bits D4 [msb] ... D1 of first byte and D4 ... D1 [lsb]
201 * of second byte, or a negative value if any of the bytes
202 * contained uncorrectable errors.
203 *
204 * @since 0.2.12
205 */
206 _vbi_inline int
vbi_unham16p(const uint8_t * p)207 vbi_unham16p (const uint8_t * p)
208 {
209 return ((int) _vbi_hamm8_inv[p[0]])
210 | (((int) _vbi_hamm8_inv[p[1]]) << 4);
211 }
212
213 extern void
214 vbi_ham24p (uint8_t * p,
215 unsigned int c);
216 extern int
217 vbi_unham24p (const uint8_t * p)
218 _vbi_pure;
219
220 /** @} */
221
222 /* Private */
223
224 VBI_END_DECLS
225
226 #endif /* __ZVBI_HAMM_H__ */
227
228 /*
229 Local variables:
230 c-set-style: K&R
231 c-basic-offset: 8
232 End:
233 */
234