Česky
Kamil Dudka

Digital Watermarking (C++, Qt3, gnulib)

File detail

Name:Downloadhamming.c [Download]
Location: kry2 > kry2-1.0pre1 > hamming-0.3
Size:12.8 KB
Last modification:2009-07-12 01:46

Source code

/***************************************************************************
*               Hamming Encoding and Decoding Implementation
*
*   File    : hamming.c
*   Purpose : Implementation Hamming encode and decode routines.  Contains
*             different style functions for Hamming encoding and decoding.
*   Author  : Michael Dipperstein
*   Date    : December 29, 2004
*
****************************************************************************
*   UPDATES
*
*   $Id: hamming.c,v 1.4 2007/09/19 13:08:14 michael Exp $
*   $Log: hamming.c,v $
*   Revision 1.4  2007/09/19 13:08:14  michael
*   Licensed under LGPL V3.
*
*   Revision 1.3  2005/10/24 12:33:12  michael
*   corrected errors in decode matrices pointed out by Ivan Piasini
*   <furettoo@gmail.com>
*
*   Revision 1.2  2005/01/03 14:41:56  michael
*   Renamed code generator matrix G so that it matches documentation.
*
*   Revision 1.1.1.1  2005/01/02 05:06:45  michael
*   Initial version
*
*
****************************************************************************
*
* Hamming: A collection of ANSI C Hamming Encoding/Decoding routines
* Copyright (C) 2004, 2007 by Michael Dipperstein (mdipper@cs.ucsb.edu)
*
* This file is part of the Hamming library.
*
* The Hamming library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public License as
* published by the Free Software Foundation; either version 3 of the
* License, or (at your option) any later version.
*
* The Hamming 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 Lesser
* General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program.  If not, see <http://www.gnu.org/licenses/>.
*
***************************************************************************/
 
/***************************************************************************
*                             INCLUDED FILES
***************************************************************************/
#include <stdio.h>
#include "hamming.h"
 
/***************************************************************************
*                                CONSTANTS
***************************************************************************/
 
/* code matrix 2nd, 3rd, and 4th MSB define parity bits */
const unsigned char g[DATA_BITS] =
{
    0x38,   /* 0 1 1 | 1 0 0 0 */
    0x54,   /* 1 0 1 | 0 1 0 0 */
    0x62,   /* 1 1 0 | 0 0 1 0 */
    0x71    /* 1 1 1 | 0 0 0 1 */
};
 
/* code matrix trasposed for ease of use in routines */
const unsigned char gT[CODE_BITS] =
{
    0x07,   /* 0 1 1 1 */
    0x0B,   /* 1 0 1 1 */
    0x0D,   /* 1 1 0 1 */
            /* ------- */
    0x08,   /* 1 0 0 0 */
    0x04,   /* 0 1 0 0 */
    0x02,   /* 0 0 1 0 */
    0x01    /* 0 0 0 1 */
};
 
/* table of Hamming codes hammingCodes[x] is the x encoded */
const unsigned char hammingCodes[DATA_VALUES] =
{
    0x00,   /* 0 */
    0x71,   /* 1 */
    0x62,   /* 2 */
    0x13,   /* 3 */
    0x54,   /* 4 */
    0x25,   /* 5 */
    0x36,   /* 6 */
    0x47,   /* 7 */
    0x38,   /* 8 */
    0x49,   /* 9 */
    0x5A,   /* A */
    0x2B,   /* B */
    0x6C,   /* C */
    0x1D,   /* D */
    0x0E,   /* E */
    0x7F    /* F */
};
 
/* parity check matrix.  4 LSBs indicate which bits a parity bit represents */
const unsigned char h[PARITY_BITS] =
{
    0x47,   /* 1 0 0 | 0 1 1 1 */
    0x2B,   /* 0 1 0 | 1 0 1 1 */
    0x1D    /* 0 0 1 | 1 1 0 1 */
};
 
/* convert syndrome (H x data) to mask that corrects data error */
const unsigned char syndromeMask[PARITY_VALUES] =
{
    0x00,   /* syndrome = 0 0 0 */
    0x10,   /* syndrome = 0 0 1 */
    0x20,   /* syndrome = 0 1 0 */
    0x08,   /* syndrome = 0 1 1 */
    0x40,   /* syndrome = 1 0 0 */
    0x04,   /* syndrome = 1 0 1 */
    0x02,   /* syndrome = 1 1 0 */
    0x01    /* syndrome = 1 1 1 */
};
 
/* table convering encoded value (with error) to original data */
/* hammingDecodeValues[code] = original data */
const unsigned char hammingDecodeValues[CODE_VALUES] =
{
    0x00, 0x00, 0x00, 0x03, 0x00, 0x05, 0x0E, 0x07,     /* 0x00 to 0x07 */
    0x00, 0x09, 0x0E, 0x0B, 0x0E, 0x0D, 0x0E, 0x0E,     /* 0x08 to 0x0F */
    0x00, 0x03, 0x03, 0x03, 0x04, 0x0D, 0x06, 0x03,     /* 0x10 to 0x17 */
    0x08, 0x0D, 0x0A, 0x03, 0x0D, 0x0D, 0x0E, 0x0D,     /* 0x18 to 0x1F */
    0x00, 0x05, 0x02, 0x0B, 0x05, 0x05, 0x06, 0x05,     /* 0x20 to 0x27 */
    0x08, 0x0B, 0x0B, 0x0B, 0x0C, 0x05, 0x0E, 0x0B,     /* 0x28 to 0x2F */
    0x08, 0x01, 0x06, 0x03, 0x06, 0x05, 0x06, 0x06,     /* 0x30 to 0x37 */
    0x08, 0x08, 0x08, 0x0B, 0x08, 0x0D, 0x06, 0x0F,     /* 0x38 to 0x3F */
    0x00, 0x09, 0x02, 0x07, 0x04, 0x07, 0x07, 0x07,     /* 0x40 to 0x47 */
    0x09, 0x09, 0x0A, 0x09, 0x0C, 0x09, 0x0E, 0x07,     /* 0x48 to 0x4F */
    0x04, 0x01, 0x0A, 0x03, 0x04, 0x04, 0x04, 0x07,     /* 0x50 to 0x57 */
    0x0A, 0x09, 0x0A, 0x0A, 0x04, 0x0D, 0x0A, 0x0F,     /* 0x58 to 0x5F */
    0x02, 0x01, 0x02, 0x02, 0x0C, 0x05, 0x02, 0x07,     /* 0x60 to 0x67 */
    0x0C, 0x09, 0x02, 0x0B, 0x0C, 0x0C, 0x0C, 0x0F,     /* 0x68 to 0x6F */
    0x01, 0x01, 0x02, 0x01, 0x04, 0x01, 0x06, 0x0F,     /* 0x70 to 0x77 */
    0x08, 0x01, 0x0A, 0x0F, 0x0C, 0x0F, 0x0F, 0x0F      /* 0x78 to 0x7F */
};
 
/* packed table convering encoded value (with error) to original data */
/* hammingPackedDecodeValues[code / 2] & 0x0F = original data for odd codes */
/* hammingPackedDecodeValues[code / 2] >> 4 = original data for even codes */
const unsigned char hammingPackedDecodeValues[CODE_VALUES] =
{
    0x00, 0x03, 0x05, 0xE7,     /* 0x00 to 0x07 */
    0x09, 0xEB, 0xED, 0xEE,     /* 0x08 to 0x0F */
    0x03, 0x33, 0x4D, 0x63,     /* 0x10 to 0x17 */
    0x8D, 0xA3, 0xDD, 0xED,     /* 0x18 to 0x1F */
    0x05, 0x2B, 0x55, 0x65,     /* 0x20 to 0x27 */
    0x8B, 0xBB, 0xC5, 0xEB,     /* 0x28 to 0x2F */
    0x81, 0x63, 0x65, 0x66,     /* 0x30 to 0x37 */
    0x88, 0x8B, 0x8D, 0x6F,     /* 0x38 to 0x3F */
    0x09, 0x27, 0x47, 0x77,     /* 0x40 to 0x47 */
    0x99, 0xA9, 0xC9, 0xE7,     /* 0x48 to 0x4F */
    0x41, 0xA3, 0x44, 0x47,     /* 0x50 to 0x57 */
    0xA9, 0xAA, 0x4D, 0xAF,     /* 0x58 to 0x5F */
    0x21, 0x22, 0xC5, 0x27,     /* 0x60 to 0x67 */
    0xC9, 0x2B, 0xCC, 0xCF,     /* 0x68 to 0x6F */
    0x11, 0x21, 0x41, 0x6F,     /* 0x70 to 0x77 */
    0x81, 0xAF, 0xCF, 0xFF      /* 0x78 to 0x7F */
};
 
/***************************************************************************
*                                FUNCTIONS
***************************************************************************/
 
/***************************************************************************
*   Function   : SumBitsModulo2
*   Description: This function performs a modulo 2 sum of the least
*                significant CODE_BITS bits in an unsigned char.
*   Parameters : bits - right justified array of CODE_BITS bits to be
*                       summed modulo 2.
*   Effects    : None
*   Returned   : 0 if even number of bits set to 1.
*                1 if odd number of bits set to 1.
***************************************************************************/
unsigned char SumBitsModulo2(unsigned char bits)
{
    unsigned char sum, mask;
 
    sum = 0;
 
    for (mask = 0x01; mask < (0x01 << CODE_BITS); mask <<=1 )
    {
        if (bits & mask)
        {
            sum++;
        }
    }
 
    return (sum & 0x01);
}
 
/***************************************************************************
*   Function   : HammingMatrixEncode
*   Description: This function uses a generator matrix G (above) to
*                determine the Hamming code for a DATA_BITS long value.
*                Actually, G Transpose is used in the calculation, because
*                it makes the C code a little easier.
*                Notice that '&' is used for modulo 2 multiplication.
*   Parameters : data - DATA_BITS long series of data bits to encode.
*   Effects    : None
*   Returned   : Hamming code used to represent data
***************************************************************************/
unsigned char HammingMatrixEncode(unsigned char data)
{
    unsigned char i, code;
    unsigned char rowBits;
 
    code = 0;
 
    for (i = 0; i < CODE_BITS; i++)
    {
        code <<= 1;     /* code bits are accumlated from right to left */
 
        /* each component of data row times column c[i] */
        rowBits = (gT[i] & data);       /* mod 2 multiplication of vectors */
 
        /* determine modulo 2 sum of compoments */
        if (SumBitsModulo2(rowBits))
        {
            code |= 1;
        }
    }
 
    return code;
}
 
/***************************************************************************
*   Function   : HammingTableEncode
*   Description: This function uses a lookup table to determine the
*                Hamming code for a DATA_BITS long value.  The lookup table
*                is based on the codes generated by the matrix G (above).
*   Parameters : data - DATA_BITS long series of data bits to encode.
*   Effects    : None
*   Returned   : Hamming code used to represent data
***************************************************************************/
unsigned char HammingTableEncode(unsigned char data)
{
    return hammingCodes[data];
}
 
/***************************************************************************
*   Function   : HammingMatrixDecode
*   Description: This function uses the matrix H (above) to determine the
*                value encoded by a CODE_BITS long code.  H is a parity
*                check matrix based on the encoding matrix G.  The result
*                of multiplying the code by H is called the syndrome.  If
*                there are no errors in the code, the syndrome will be a 0
*                vector.  If the syndrome is not 0, it will match a column
*                in H.  The column it matches is likely the errored bit.
*                Toggle the errored bit and the resulting code is the
*                nearest matching correct code.
*   Parameters : code - CODE_BITS long series of code bits to decode.
*   Effects    : None
*   Returned   : Nearest value to encoded data
***************************************************************************/
unsigned char HammingMatrixDecode(unsigned char code)
{
    unsigned char i, syndromeVal;
    unsigned char syndromeColBits;  /* sum of bits is bit in syndrome */
 
    syndromeVal = 0;
 
    for (i = 0; i < PARITY_BITS; i++)
    {
        syndromeVal <<= 1;
 
        /* components of row h[i] times column code */
        syndromeColBits = (h[i] & code);
 
        /* determine modulo 2 sum of compoments */
        if (SumBitsModulo2(syndromeColBits))
        {
            syndromeVal |= 1;
        }
    }
 
    /* return the data corrected for error */
    return ((code ^ syndromeMask[syndromeVal]) & (0xFF >> DATA_BITS));
}
 
/***************************************************************************
*   Function   : HammingTableDecode
*   Description: This function uses a lookup table to determine the value
*                encoded by a CODE_BITS long code.  It assumes that the
*                code is based on the codes generated by the matrix G
*                (above), but errors are allowed.  The value returned is
*                the value with the code nearest (with the least error) to
*                the code passed as a parameter.
*   Parameters : code - CODE_BITS long series of code bits to decode.
*   Effects    : None
*   Returned   : Nearest value to encoded data
***************************************************************************/
unsigned char HammingTableDecode(unsigned char code)
{
    return hammingDecodeValues[code];
}
 
/***************************************************************************
*   Function   : HammingPackedTableDecode
*   Description: This function uses a packed lookup table to determine the
*                value encoded by a CODE_BITS long code.  It assumes that
*                the code is based on the codes generated by the matrix G
*                (above), but errors are allowed.  The value returned is
*                the value with the code nearest (with the least error) to
*                the code passed as a parameter.
*                NOTE: The table packing will only work if the size of a
*                      table entry is larger than 2 * DATA_BITS.
*   Parameters : code - CODE_BITS long series of code bits to decode.
*   Effects    : None
*   Returned   : Nearest value to encoded data
***************************************************************************/
unsigned char HammingPackedTableDecode(unsigned char code)
{
    unsigned char decoded;
 
    decoded = hammingPackedDecodeValues[code / 2];
 
    if (code % 2)
    {
        /* even value.  keep LS nibble */
        decoded &= (0xFF >> DATA_BITS);
    }
    else
    {
        /* odd value.  move MS nibble to LS half */
        decoded >>= DATA_BITS;
    }
 
    return decoded;
}