/* * 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.c,v 1.10 2008/02/19 00:35:20 mschimek Exp $ */ #ifdef HAVE_CONFIG_H # include "config.h" #endif #include /* CHAR_BIT */ #include "hamm.h" #include "hamm-tables.h" /** * @ingroup Error * * @param p Array of unsigned bytes. * @param n Size of array. * * Of each byte of the array, changes the most significant * bit to make the number of set bits odd. * * @since 0.2.12 */ void vbi_par (uint8_t * p, unsigned int n) { while (n-- > 0) { uint8_t c = *p; /* if 0 == (inv_par[] & 32) change msb of *p. */ *p++ = c ^ (128 & ~(_vbi_hamm24_inv_par[0][c] << 2)); } } /** * @ingroup Error * @param p Array of unsigned bytes. * @param n Size of array. * * Tests the parity and clears the most significant bit of * each byte of the array. * * @return * A negative value if any byte of the array had even * parity (sum of bits modulo 2 is 0). * * @since 0.2.12 */ int vbi_unpar (uint8_t * p, unsigned int n) { int r = 0; while (n-- > 0) { uint8_t c = *p; /* if 0 == (inv_par[] & 32) set msb of r. */ r |= ~ _vbi_hamm24_inv_par[0][c] << (sizeof (int) * CHAR_BIT - 1 - 5); *p++ = c & 127; } return r; } /** * @ingroup Error * @param p A Hamming 24/18 protected 24 bit word will be stored here, * last significant byte first, lsb first transmitted. * @param c Integer between 0 ... 1 << 18 - 1. * * Encodes an 18 bit word with Hamming 24/18 protection * as specified in ETS 300 706, Section 8.3. * * @since 0.2.27 */ void vbi_ham24p (uint8_t * p, unsigned int c) { unsigned int D5_D11; unsigned int D12_D18; unsigned int P5, P6; unsigned int Byte_0; Byte_0 = (_vbi_hamm24_fwd_0 [(c >> 0) & 0xFF] ^ _vbi_hamm24_fwd_1 [(c >> 8) & 0xFF] ^ _vbi_hamm24_fwd_2 [(c >> 16) & 0x03]); p[0] = Byte_0; D5_D11 = (c >> 4) & 0x7F; D12_D18 = (c >> 11) & 0x7F; P5 = 0x80 & ~(_vbi_hamm24_inv_par[0][D12_D18] << 2); p[1] = D5_D11 | P5; P6 = 0x80 & ((_vbi_hamm24_inv_par[0][Byte_0] ^ _vbi_hamm24_inv_par[0][D5_D11]) << 2); p[2] = D12_D18 | P6; } /** * @ingroup Error * @param p Pointer to a Hamming 24/18 protected 24 bit word, * last significant byte first, lsb first transmitted. * * Decodes a Hamming 24/18 protected byte triplet * as specified in ETS 300 706, Section 8.3. * * @return * Triplet data bits D18 [msb] ... D1 [lsb] or a negative value * if the triplet contained incorrectable errors. * * @since 0.2.12 */ int vbi_unham24p (const uint8_t * p) { unsigned int D1_D4; unsigned int D5_D11; unsigned int D12_D18; unsigned int ABCDEF; int32_t d; D1_D4 = _vbi_hamm24_inv_d1_d4[p[0] >> 2]; D5_D11 = p[1] & 0x7F; D12_D18 = p[2] & 0x7F; d = D1_D4 | (D5_D11 << 4) | (D12_D18 << 11); ABCDEF = (_vbi_hamm24_inv_par[0][p[0]] ^ _vbi_hamm24_inv_par[1][p[1]] ^ _vbi_hamm24_inv_par[2][p[2]]); /* Correct single bit error, set MSB on double bit error. */ return d ^ (int) _vbi_hamm24_inv_err[ABCDEF]; } /* Local variables: c-set-style: K&R c-basic-offset: 8 End: */