/* * 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: */