/*
* 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 <froese@gmx.de>
*
* 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 <inttypes.h> /* 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__ */
syntax highlighted by Code2HTML, v. 0.9.1