| /* | |
| * libzvbi -- Error correction functions | |
| * | |
| * Copyright (C) 2001, 2002, 2003, 2004, 2007 Michael H. Schimek | |
| * | |
| * This library is free software; you can redistribute it and/or | |
| * modify it under the terms of the GNU Library General Public | |
| * License as published by the Free Software Foundation; either | |
| * version 2 of the License, or (at your option) any later version. | |
| * | |
| * This library is distributed in the hope that it will be useful, | |
| * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
| * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
| * Library General Public License for more details. | |
| * | |
| * You should have received a copy of the GNU Library General Public | |
| * License along with this library; if not, write to the | |
| * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, | |
| * Boston, MA 02110-1301 USA. | |
| */ | |
| /* $Id: hamm.h,v 1.16 2013-07-10 11:37:13 mschimek Exp $ */ | |
| #ifndef __ZVBI_HAMM_H__ | |
| #define __ZVBI_HAMM_H__ | |
| #include <inttypes.h> /* uintN_t */ | |
| #include "macros.h" | |
| VBI_BEGIN_DECLS | |
| /* Public */ | |
| extern const uint8_t _vbi_bit_reverse [256]; | |
| extern const uint8_t _vbi_hamm8_fwd [16]; | |
| extern const int8_t _vbi_hamm8_inv [256]; | |
| extern const int8_t _vbi_hamm24_inv_par [3][256]; | |
| /** | |
| * @addtogroup Error Error correction functions | |
| * @ingroup Raw | |
| * @brief Helper functions to decode sliced VBI data. | |
| * @{ | |
| */ | |
| /** | |
| * @param c Unsigned byte. | |
| * | |
| * Reverses the bits of the argument. | |
| * | |
| * @returns | |
| * Data bits 0 [msb] ... 7 [lsb]. | |
| * | |
| * @since 0.2.12 | |
| */ | |
| _vbi_inline unsigned int | |
| vbi_rev8 (unsigned int c) | |
| { | |
| return _vbi_bit_reverse[(uint8_t) c]; | |
| } | |
| /** | |
| * @param c Unsigned 16 bit word. | |
| * | |
| * Reverses (or "reflects") the bits of the argument. | |
| * | |
| * @returns | |
| * Data bits 0 [msb] ... 15 [lsb]. | |
| * | |
| * @since 0.2.12 | |
| */ | |
| _vbi_inline unsigned int | |
| vbi_rev16 (unsigned int c) | |
| { | |
| return _vbi_bit_reverse[(uint8_t) c] * 256 | |
| + _vbi_bit_reverse[(uint8_t)(c >> 8)]; | |
| } | |
| /** | |
| * @param p Pointer to a 16 bit word, last significant | |
| * byte first. | |
| * | |
| * Reverses (or "reflects") the bits of the argument. | |
| * | |
| * @returns | |
| * Data bits 0 [msb] ... 15 [lsb]. | |
| * | |
| * @since 0.2.12 | |
| */ | |
| _vbi_inline unsigned int | |
| vbi_rev16p (const uint8_t * p) | |
| { | |
| return _vbi_bit_reverse[p[0]] * 256 | |
| + _vbi_bit_reverse[p[1]]; | |
| } | |
| /** | |
| * @param c Unsigned byte. | |
| * | |
| * @returns | |
| * Changes the most significant bit of the byte | |
| * to make the number of set bits odd. | |
| * | |
| * @since 0.2.12 | |
| */ | |
| _vbi_inline unsigned int | |
| vbi_par8 (unsigned int c) | |
| { | |
| c &= 255; | |
| /* if 0 == (inv_par[] & 32) change bit 7 of c. */ | |
| c ^= 128 & ~(_vbi_hamm24_inv_par[0][c] << 2); | |
| return c; | |
| } | |
| /** | |
| * @param c Unsigned byte. | |
| * | |
| * @returns | |
| * If the byte has odd parity (sum of bits modulo 2 is 1) the | |
| * byte AND 127, otherwise a negative value. | |
| * | |
| * @since 0.2.12 | |
| */ | |
| _vbi_inline int | |
| vbi_unpar8 (unsigned int c) | |
| { | |
| /* Disabled until someone finds a reliable way | |
| to test for cmov support at compile time. */ | |
| #if 0 | |
| int r = c & 127; | |
| /* This saves cache flushes and an explicit branch. */ | |
| __asm__ (" testb %1,%1\n" | |
| " cmovp %2,%0\n" | |
| : "+&a" (r) : "c" (c), "rm" (-1)); | |
| return r; | |
| #endif | |
| if (_vbi_hamm24_inv_par[0][(uint8_t) c] & 32) { | |
| return c & 127; | |
| } else { | |
| /* The idea is to OR results together to find a parity | |
| error in a sequence, rather than a test and branch on | |
| each byte. */ | |
| return -1; | |
| } | |
| } | |
| extern void | |
| vbi_par (uint8_t * p, | |
| unsigned int n); | |
| extern int | |
| vbi_unpar (uint8_t * p, | |
| unsigned int n); | |
| /** | |
| * @param c Integer between 0 ... 15. | |
| * | |
| * Encodes a nibble with Hamming 8/4 protection | |
| * as specified in EN 300 706, Section 8.2. | |
| * | |
| * @returns | |
| * Hamming encoded unsigned byte, lsb first transmitted. | |
| * | |
| * @since 0.2.12 | |
| */ | |
| _vbi_inline unsigned int | |
| vbi_ham8 (unsigned int c) | |
| { | |
| return _vbi_hamm8_fwd[c & 15]; | |
| } | |
| /** | |
| * @param c Hamming 8/4 protected byte, lsb first transmitted. | |
| * | |
| * Decodes a Hamming 8/4 protected byte | |
| * as specified in EN 300 706, Section 8.2. | |
| * | |
| * @returns | |
| * Data bits (D4 [msb] ... D1 [lsb]) or a negative | |
| * value if the byte contained uncorrectable errors. | |
| * | |
| * @since 0.2.12 | |
| */ | |
| _vbi_inline int | |
| vbi_unham8 (unsigned int c) | |
| { | |
| return _vbi_hamm8_inv[(uint8_t) c]; | |
| } | |
| /** | |
| * @param p Pointer to a Hamming 8/4 protected 16 bit word, | |
| * last significant byte first, lsb first transmitted. | |
| * | |
| * Decodes a Hamming 8/4 protected byte pair | |
| * as specified in EN 300 706, Section 8.2. | |
| * | |
| * @returns | |
| * Data bits D4 [msb] ... D1 of first byte and D4 ... D1 [lsb] | |
| * of second byte, or a negative value if any of the bytes | |
| * contained uncorrectable errors. | |
| * | |
| * @since 0.2.12 | |
| */ | |
| _vbi_inline int | |
| vbi_unham16p (const uint8_t * p) | |
| { | |
| return ((int) _vbi_hamm8_inv[p[0]]) | |
| | (((int) _vbi_hamm8_inv[p[1]]) << 4); | |
| } | |
| extern void | |
| vbi_ham24p (uint8_t * p, | |
| unsigned int c); | |
| extern int | |
| vbi_unham24p (const uint8_t * p) | |
| _vbi_pure; | |
| /** @} */ | |
| /* Private */ | |
| VBI_END_DECLS | |
| #endif /* __ZVBI_HAMM_H__ */ | |
| /* | |
| Local variables: | |
| c-set-style: K&R | |
| c-basic-offset: 8 | |
| End: | |
| */ |