/* * libzvbi - Error correction functions * * Copyright (C) 2001, 2002, 2003, 2004 Michael H. Schimek * * Based on code from AleVT 1.5.1 * Copyright (C) 1998, 1999 Edgar Toernig * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program 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 General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ /* $Id: hamm.h,v 1.9 2006/05/22 09:04:07 mschimek Exp $ */ #ifndef __ZVBI_HAMM_H__ #define __ZVBI_HAMM_H__ #include /* uintN_t */ #include "misc.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 LowDec * @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) { #ifdef __GNUC__ #if #cpu (i686) 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 #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 incorrectable 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 incorrectable 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 int vbi_unham24p (const uint8_t * p) __attribute__ ((_vbi_pure)); /** @} */ /* Private */ VBI_END_DECLS #endif /* __ZVBI_HAMM_H__ */