JPWL version 1.0 by Universita' degli Studi di Perugia
This commit is contained in:
parent
3d2f2b4048
commit
7fd2ae9786
|
@ -0,0 +1,160 @@
|
|||
/*
|
||||
* Copyright (c) 2001-2003, David Janssens
|
||||
* Copyright (c) 2002-2003, Yannick Verschueren
|
||||
* Copyright (c) 2003-2005, Francois Devaux and Antonin Descampe
|
||||
* Copyright (c) 2005, Hervé Drolon, FreeImage Team
|
||||
* Copyright (c) 2002-2005, Communications and remote sensing Laboratory, Universite catholique de Louvain, Belgium
|
||||
* Copyright (c) 2005-2006, Dept. of Electronic and Information Engineering, Universita' degli Studi di Perugia, Italy
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS `AS IS'
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
||||
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifdef USE_JPWL
|
||||
|
||||
#include "crc.h"
|
||||
|
||||
/**
|
||||
@file crc.c
|
||||
@brief Functions used to compute the 16- and 32-bit CRC of byte arrays
|
||||
|
||||
*/
|
||||
|
||||
/** file: CRC16.CPP
|
||||
*
|
||||
* CRC - Cyclic Redundancy Check (16-bit)
|
||||
*
|
||||
* A CRC-checksum is used to be sure, the data hasn't changed or is false.
|
||||
* To create a CRC-checksum, initialise a check-variable (unsigned short),
|
||||
* and set this to zero. Than call for every byte in the file (e.g.) the
|
||||
* procedure updateCRC16 with this check-variable as the first parameter,
|
||||
* and the byte as the second. At the end, the check-variable contains the
|
||||
* CRC-checksum.
|
||||
*
|
||||
* implemented by Michael Neumann, 14.06.1998
|
||||
*
|
||||
*/
|
||||
const unsigned short CRC16_table[256] = {
|
||||
0x0000, 0x1021, 0x2042, 0x3063, 0x4084, 0x50a5, 0x60c6, 0x70e7,
|
||||
0x8108, 0x9129, 0xa14a, 0xb16b, 0xc18c, 0xd1ad, 0xe1ce, 0xf1ef,
|
||||
0x1231, 0x0210, 0x3273, 0x2252, 0x52b5, 0x4294, 0x72f7, 0x62d6,
|
||||
0x9339, 0x8318, 0xb37b, 0xa35a, 0xd3bd, 0xc39c, 0xf3ff, 0xe3de,
|
||||
0x2462, 0x3443, 0x0420, 0x1401, 0x64e6, 0x74c7, 0x44a4, 0x5485,
|
||||
0xa56a, 0xb54b, 0x8528, 0x9509, 0xe5ee, 0xf5cf, 0xc5ac, 0xd58d,
|
||||
0x3653, 0x2672, 0x1611, 0x0630, 0x76d7, 0x66f6, 0x5695, 0x46b4,
|
||||
0xb75b, 0xa77a, 0x9719, 0x8738, 0xf7df, 0xe7fe, 0xd79d, 0xc7bc,
|
||||
0x48c4, 0x58e5, 0x6886, 0x78a7, 0x0840, 0x1861, 0x2802, 0x3823,
|
||||
0xc9cc, 0xd9ed, 0xe98e, 0xf9af, 0x8948, 0x9969, 0xa90a, 0xb92b,
|
||||
0x5af5, 0x4ad4, 0x7ab7, 0x6a96, 0x1a71, 0x0a50, 0x3a33, 0x2a12,
|
||||
0xdbfd, 0xcbdc, 0xfbbf, 0xeb9e, 0x9b79, 0x8b58, 0xbb3b, 0xab1a,
|
||||
0x6ca6, 0x7c87, 0x4ce4, 0x5cc5, 0x2c22, 0x3c03, 0x0c60, 0x1c41,
|
||||
0xedae, 0xfd8f, 0xcdec, 0xddcd, 0xad2a, 0xbd0b, 0x8d68, 0x9d49,
|
||||
0x7e97, 0x6eb6, 0x5ed5, 0x4ef4, 0x3e13, 0x2e32, 0x1e51, 0x0e70,
|
||||
0xff9f, 0xefbe, 0xdfdd, 0xcffc, 0xbf1b, 0xaf3a, 0x9f59, 0x8f78,
|
||||
0x9188, 0x81a9, 0xb1ca, 0xa1eb, 0xd10c, 0xc12d, 0xf14e, 0xe16f,
|
||||
0x1080, 0x00a1, 0x30c2, 0x20e3, 0x5004, 0x4025, 0x7046, 0x6067,
|
||||
0x83b9, 0x9398, 0xa3fb, 0xb3da, 0xc33d, 0xd31c, 0xe37f, 0xf35e,
|
||||
0x02b1, 0x1290, 0x22f3, 0x32d2, 0x4235, 0x5214, 0x6277, 0x7256,
|
||||
0xb5ea, 0xa5cb, 0x95a8, 0x8589, 0xf56e, 0xe54f, 0xd52c, 0xc50d,
|
||||
0x34e2, 0x24c3, 0x14a0, 0x0481, 0x7466, 0x6447, 0x5424, 0x4405,
|
||||
0xa7db, 0xb7fa, 0x8799, 0x97b8, 0xe75f, 0xf77e, 0xc71d, 0xd73c,
|
||||
0x26d3, 0x36f2, 0x0691, 0x16b0, 0x6657, 0x7676, 0x4615, 0x5634,
|
||||
0xd94c, 0xc96d, 0xf90e, 0xe92f, 0x99c8, 0x89e9, 0xb98a, 0xa9ab,
|
||||
0x5844, 0x4865, 0x7806, 0x6827, 0x18c0, 0x08e1, 0x3882, 0x28a3,
|
||||
0xcb7d, 0xdb5c, 0xeb3f, 0xfb1e, 0x8bf9, 0x9bd8, 0xabbb, 0xbb9a,
|
||||
0x4a75, 0x5a54, 0x6a37, 0x7a16, 0x0af1, 0x1ad0, 0x2ab3, 0x3a92,
|
||||
0xfd2e, 0xed0f, 0xdd6c, 0xcd4d, 0xbdaa, 0xad8b, 0x9de8, 0x8dc9,
|
||||
0x7c26, 0x6c07, 0x5c64, 0x4c45, 0x3ca2, 0x2c83, 0x1ce0, 0x0cc1,
|
||||
0xef1f, 0xff3e, 0xcf5d, 0xdf7c, 0xaf9b, 0xbfba, 0x8fd9, 0x9ff8,
|
||||
0x6e17, 0x7e36, 0x4e55, 0x5e74, 0x2e93, 0x3eb2, 0x0ed1, 0x1ef0
|
||||
};
|
||||
|
||||
void updateCRC16(unsigned short *crc, unsigned char data) {
|
||||
*crc = CRC16_table[(*crc >> 8) & 0xFF] ^ (*crc << 8) ^ data;
|
||||
};
|
||||
|
||||
|
||||
/** file: CRC32.CPP
|
||||
*
|
||||
* CRC - Cyclic Redundancy Check (32-bit)
|
||||
*
|
||||
* A CRC-checksum is used to be sure, the data hasn't changed or is false.
|
||||
* To create a CRC-checksum, initialise a check-variable (unsigned long),
|
||||
* and set this to zero. Than call for every byte in the file (e.g.) the
|
||||
* procedure updateCRC32 with this check-variable as the first parameter,
|
||||
* and the byte as the second. At the end, the check-variable contains the
|
||||
* CRC-checksum.
|
||||
*
|
||||
* implemented by Michael Neumann, 14.06.1998
|
||||
*
|
||||
*/
|
||||
const unsigned long CRC32_table[256] = {
|
||||
0x00000000, 0x77073096, 0xee0e612c, 0x990951ba, 0x076dc419, 0x706af48f,
|
||||
0xe963a535, 0x9e6495a3, 0x0edb8832, 0x79dcb8a4, 0xe0d5e91e, 0x97d2d988,
|
||||
0x09b64c2b, 0x7eb17cbd, 0xe7b82d07, 0x90bf1d91, 0x1db71064, 0x6ab020f2,
|
||||
0xf3b97148, 0x84be41de, 0x1adad47d, 0x6ddde4eb, 0xf4d4b551, 0x83d385c7,
|
||||
0x136c9856, 0x646ba8c0, 0xfd62f97a, 0x8a65c9ec, 0x14015c4f, 0x63066cd9,
|
||||
0xfa0f3d63, 0x8d080df5, 0x3b6e20c8, 0x4c69105e, 0xd56041e4, 0xa2677172,
|
||||
0x3c03e4d1, 0x4b04d447, 0xd20d85fd, 0xa50ab56b, 0x35b5a8fa, 0x42b2986c,
|
||||
0xdbbbc9d6, 0xacbcf940, 0x32d86ce3, 0x45df5c75, 0xdcd60dcf, 0xabd13d59,
|
||||
0x26d930ac, 0x51de003a, 0xc8d75180, 0xbfd06116, 0x21b4f4b5, 0x56b3c423,
|
||||
0xcfba9599, 0xb8bda50f, 0x2802b89e, 0x5f058808, 0xc60cd9b2, 0xb10be924,
|
||||
0x2f6f7c87, 0x58684c11, 0xc1611dab, 0xb6662d3d, 0x76dc4190, 0x01db7106,
|
||||
0x98d220bc, 0xefd5102a, 0x71b18589, 0x06b6b51f, 0x9fbfe4a5, 0xe8b8d433,
|
||||
0x7807c9a2, 0x0f00f934, 0x9609a88e, 0xe10e9818, 0x7f6a0dbb, 0x086d3d2d,
|
||||
0x91646c97, 0xe6635c01, 0x6b6b51f4, 0x1c6c6162, 0x856530d8, 0xf262004e,
|
||||
0x6c0695ed, 0x1b01a57b, 0x8208f4c1, 0xf50fc457, 0x65b0d9c6, 0x12b7e950,
|
||||
0x8bbeb8ea, 0xfcb9887c, 0x62dd1ddf, 0x15da2d49, 0x8cd37cf3, 0xfbd44c65,
|
||||
0x4db26158, 0x3ab551ce, 0xa3bc0074, 0xd4bb30e2, 0x4adfa541, 0x3dd895d7,
|
||||
0xa4d1c46d, 0xd3d6f4fb, 0x4369e96a, 0x346ed9fc, 0xad678846, 0xda60b8d0,
|
||||
0x44042d73, 0x33031de5, 0xaa0a4c5f, 0xdd0d7cc9, 0x5005713c, 0x270241aa,
|
||||
0xbe0b1010, 0xc90c2086, 0x5768b525, 0x206f85b3, 0xb966d409, 0xce61e49f,
|
||||
0x5edef90e, 0x29d9c998, 0xb0d09822, 0xc7d7a8b4, 0x59b33d17, 0x2eb40d81,
|
||||
0xb7bd5c3b, 0xc0ba6cad, 0xedb88320, 0x9abfb3b6, 0x03b6e20c, 0x74b1d29a,
|
||||
0xead54739, 0x9dd277af, 0x04db2615, 0x73dc1683, 0xe3630b12, 0x94643b84,
|
||||
0x0d6d6a3e, 0x7a6a5aa8, 0xe40ecf0b, 0x9309ff9d, 0x0a00ae27, 0x7d079eb1,
|
||||
0xf00f9344, 0x8708a3d2, 0x1e01f268, 0x6906c2fe, 0xf762575d, 0x806567cb,
|
||||
0x196c3671, 0x6e6b06e7, 0xfed41b76, 0x89d32be0, 0x10da7a5a, 0x67dd4acc,
|
||||
0xf9b9df6f, 0x8ebeeff9, 0x17b7be43, 0x60b08ed5, 0xd6d6a3e8, 0xa1d1937e,
|
||||
0x38d8c2c4, 0x4fdff252, 0xd1bb67f1, 0xa6bc5767, 0x3fb506dd, 0x48b2364b,
|
||||
0xd80d2bda, 0xaf0a1b4c, 0x36034af6, 0x41047a60, 0xdf60efc3, 0xa867df55,
|
||||
0x316e8eef, 0x4669be79, 0xcb61b38c, 0xbc66831a, 0x256fd2a0, 0x5268e236,
|
||||
0xcc0c7795, 0xbb0b4703, 0x220216b9, 0x5505262f, 0xc5ba3bbe, 0xb2bd0b28,
|
||||
0x2bb45a92, 0x5cb36a04, 0xc2d7ffa7, 0xb5d0cf31, 0x2cd99e8b, 0x5bdeae1d,
|
||||
0x9b64c2b0, 0xec63f226, 0x756aa39c, 0x026d930a, 0x9c0906a9, 0xeb0e363f,
|
||||
0x72076785, 0x05005713, 0x95bf4a82, 0xe2b87a14, 0x7bb12bae, 0x0cb61b38,
|
||||
0x92d28e9b, 0xe5d5be0d, 0x7cdcefb7, 0x0bdbdf21, 0x86d3d2d4, 0xf1d4e242,
|
||||
0x68ddb3f8, 0x1fda836e, 0x81be16cd, 0xf6b9265b, 0x6fb077e1, 0x18b74777,
|
||||
0x88085ae6, 0xff0f6a70, 0x66063bca, 0x11010b5c, 0x8f659eff, 0xf862ae69,
|
||||
0x616bffd3, 0x166ccf45, 0xa00ae278, 0xd70dd2ee, 0x4e048354, 0x3903b3c2,
|
||||
0xa7672661, 0xd06016f7, 0x4969474d, 0x3e6e77db, 0xaed16a4a, 0xd9d65adc,
|
||||
0x40df0b66, 0x37d83bf0, 0xa9bcae53, 0xdebb9ec5, 0x47b2cf7f, 0x30b5ffe9,
|
||||
0xbdbdf21c, 0xcabac28a, 0x53b39330, 0x24b4a3a6, 0xbad03605, 0xcdd70693,
|
||||
0x54de5729, 0x23d967bf, 0xb3667a2e, 0xc4614ab8, 0x5d681b02, 0x2a6f2b94,
|
||||
0xb40bbe37, 0xc30c8ea1, 0x5a05df1b, 0x2d02ef8d
|
||||
};
|
||||
|
||||
void updateCRC32(unsigned long *crc, unsigned char data) {
|
||||
*crc = CRC32_table[(unsigned char) *crc ^ data] ^ ((*crc >> 8) & 0x00FFFFFF);
|
||||
};
|
||||
|
||||
#endif /* USE_JPWL */
|
|
@ -0,0 +1,84 @@
|
|||
/*
|
||||
* Copyright (c) 2001-2003, David Janssens
|
||||
* Copyright (c) 2002-2003, Yannick Verschueren
|
||||
* Copyright (c) 2003-2005, Francois Devaux and Antonin Descampe
|
||||
* Copyright (c) 2005, Hervé Drolon, FreeImage Team
|
||||
* Copyright (c) 2002-2005, Communications and remote sensing Laboratory, Universite catholique de Louvain, Belgium
|
||||
* Copyright (c) 2005-2006, Dept. of Electronic and Information Engineering, Universita' degli Studi di Perugia, Italy
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS `AS IS'
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
||||
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifdef USE_JPWL
|
||||
|
||||
/**
|
||||
@file crc.h
|
||||
@brief Functions used to compute the 16- and 32-bit CRC of byte arrays
|
||||
|
||||
*/
|
||||
|
||||
#ifndef __CRC16_HEADER__
|
||||
#define __CRC16_HEADER__
|
||||
|
||||
/** file: CRC16.HPP
|
||||
*
|
||||
* CRC - Cyclic Redundancy Check (16-bit)
|
||||
*
|
||||
* A CRC-checksum is used to be sure, the data hasn't changed or is false.
|
||||
* To create a CRC-checksum, initialise a check-variable (unsigned short),
|
||||
* and set this to zero. Than call for every byte in the file (e.g.) the
|
||||
* procedure updateCRC16 with this check-variable as the first parameter,
|
||||
* and the byte as the second. At the end, the check-variable contains the
|
||||
* CRC-checksum.
|
||||
*
|
||||
* implemented by Michael Neumann, 14.06.1998
|
||||
*
|
||||
*/
|
||||
void updateCRC16(unsigned short *, unsigned char);
|
||||
|
||||
#endif /* __CRC16_HEADER__ */
|
||||
|
||||
|
||||
#ifndef __CRC32_HEADER__
|
||||
#define __CRC32_HEADER__
|
||||
|
||||
/** file: CRC32.HPP
|
||||
*
|
||||
* CRC - Cyclic Redundancy Check (32-bit)
|
||||
*
|
||||
* A CRC-checksum is used to be sure, the data hasn't changed or is false.
|
||||
* To create a CRC-checksum, initialise a check-variable (unsigned short),
|
||||
* and set this to zero. Than call for every byte in the file (e.g.) the
|
||||
* procedure updateCRC32 with this check-variable as the first parameter,
|
||||
* and the byte as the second. At the end, the check-variable contains the
|
||||
* CRC-checksum.
|
||||
*
|
||||
* implemented by Michael Neumann, 14.06.1998
|
||||
*
|
||||
*/
|
||||
void updateCRC32(unsigned long *, unsigned char);
|
||||
|
||||
#endif /* __CRC32_HEADER__ */
|
||||
|
||||
|
||||
#endif /* USE_JPWL */
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,372 @@
|
|||
/*
|
||||
* Copyright (c) 2001-2003, David Janssens
|
||||
* Copyright (c) 2002-2003, Yannick Verschueren
|
||||
* Copyright (c) 2003-2005, Francois Devaux and Antonin Descampe
|
||||
* Copyright (c) 2005, Hervé Drolon, FreeImage Team
|
||||
* Copyright (c) 2002-2005, Communications and remote sensing Laboratory, Universite catholique de Louvain, Belgium
|
||||
* Copyright (c) 2005-2006, Dept. of Electronic and Information Engineering, Universita' degli Studi di Perugia, Italy
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS `AS IS'
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
||||
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
#ifndef __JPWL_H
|
||||
#define __JPWL_H
|
||||
|
||||
#ifdef USE_JPWL
|
||||
|
||||
#include "crc.h"
|
||||
#include "rs.h"
|
||||
|
||||
/**
|
||||
@file jpwl.h
|
||||
@brief The JPEG-2000 Part11 (JPWL) marker segments manager
|
||||
|
||||
The functions in JPWL.C have for goal to read/write the markers added by JPWL.
|
||||
*/
|
||||
|
||||
/** @defgroup JPWL JPWL - JPEG-2000 Part11 (JPWL) codestream manager */
|
||||
/*@{*/
|
||||
|
||||
/**
|
||||
Assume a basic codestream structure, so you can resort better from uncorrected errors
|
||||
*/
|
||||
#define JPWL_ASSUME true
|
||||
|
||||
/**
|
||||
EPB (Error Protection Block) Marker segment
|
||||
*/
|
||||
typedef struct jpwl_epb_ms {
|
||||
/**@name Private fields set by epb_create */
|
||||
/*@{*/
|
||||
/** is the latest in header? */
|
||||
bool latest;
|
||||
/** is it in packed mode? */
|
||||
bool packed;
|
||||
/** TH where this marker has been placed (-1 means MH) */
|
||||
int tileno;
|
||||
/** index in current header (0-63) */
|
||||
unsigned char index;
|
||||
/** error protection method [-1=absent 0=none 1=predefined 16=CRC-16 32=CRC-32 37-128=RS] */
|
||||
int hprot;
|
||||
/** message word length of pre-data */
|
||||
int k_pre;
|
||||
/** code word length of pre-data */
|
||||
int n_pre;
|
||||
/** length of pre-data */
|
||||
int pre_len;
|
||||
/** message word length of post-data */
|
||||
int k_post;
|
||||
/** code word length of post-data */
|
||||
int n_post;
|
||||
/** length of post-data */
|
||||
int post_len;
|
||||
/*@}*/
|
||||
/**@name Marker segment fields */
|
||||
/*@{*/
|
||||
/** two bytes for the length of EPB MS, exluding the marker itself (11 to 65535 bytes) */
|
||||
unsigned short int Lepb;
|
||||
/** single byte for the style */
|
||||
unsigned char Depb;
|
||||
/** four bytes, from 0 to 2^31-1 */
|
||||
unsigned long int LDPepb;
|
||||
/** four bytes, next error management method */
|
||||
unsigned long int Pepb;
|
||||
/** EPB data, variable size */
|
||||
unsigned char *data;
|
||||
/*@}*/
|
||||
} jpwl_epb_ms_t;
|
||||
|
||||
/**
|
||||
EPC (Error Protection Capability) Marker segment
|
||||
*/
|
||||
typedef struct jpwl_epc_ms {
|
||||
/** is ESD active? */
|
||||
bool esd_on;
|
||||
/** is RED active? */
|
||||
bool red_on;
|
||||
/** is EPB active? */
|
||||
bool epb_on;
|
||||
/** are informative techniques active? */
|
||||
bool info_on;
|
||||
/**@name Marker segment fields */
|
||||
/*@{*/
|
||||
/** two bytes for the length of EPC MS, exluding the marker itself (9 to 65535 bytes) */
|
||||
unsigned short int Lepc;
|
||||
/** two bytes, CRC for the EPC, excluding Pcrc itself */
|
||||
unsigned short int Pcrc;
|
||||
/** four bytes, the codestream length from SOC to EOC */
|
||||
unsigned long int DL;
|
||||
/** one byte, signals JPWL techniques adoption */
|
||||
unsigned char Pepc;
|
||||
/** EPC data, variable length */
|
||||
unsigned char *data;
|
||||
/*@}*/
|
||||
} jpwl_epc_ms_t;
|
||||
|
||||
/**
|
||||
ESD (Error Sensitivity Descriptor) Marker segment
|
||||
*/
|
||||
typedef struct jpwl_esd_ms {
|
||||
/** codestream addressing mode [0=packet, 1=byte range, 2=packet range, 3=reserved] */
|
||||
unsigned char addrm;
|
||||
/** size of codestream addresses [2/4 bytes] */
|
||||
unsigned char ad_size;
|
||||
/** type of sensitivity
|
||||
[0=relative error, 1=MSE, 2=MSE reduction, 3=PSNR, 4=PSNR increment,
|
||||
5=MAXERR (absolute peak error), 6=TSE (total squared error), 7=reserved */
|
||||
unsigned char senst;
|
||||
/** size of sensitivity data (1/2 bytes) */
|
||||
unsigned char se_size;
|
||||
/**@name Marker segment fields */
|
||||
/*@{*/
|
||||
/** two bytes for the length of ESD MS, exluding the marker itself (4 to 65535 bytes) */
|
||||
unsigned short int Lesd;
|
||||
/** two bytes, component of error sensitivity */
|
||||
unsigned short int Cesd;
|
||||
/** one byte, signals JPWL techniques adoption */
|
||||
unsigned char Pesd;
|
||||
/** ESD data, variable length */
|
||||
unsigned char *data;
|
||||
/*@}*/
|
||||
/**@name Fields set by esd_create (only internal use) */
|
||||
/*@{*/
|
||||
/** number of components in the image */
|
||||
int numcomps;
|
||||
/** tile where this marker has been placed (-1 means MH) */
|
||||
int tileno;
|
||||
/** number of sensitivity values */
|
||||
unsigned long int svalnum;
|
||||
/** size of a single sensitivity pair (address+value) */
|
||||
size_t sensval_size;
|
||||
/*@}*/
|
||||
} jpwl_esd_ms_t;
|
||||
|
||||
/**
|
||||
RED (Residual Error Descriptor) Marker segment
|
||||
*/
|
||||
typedef struct jpwl_red_ms {
|
||||
/** two bytes for the length of RED MS, exluding the marker itself (3 to 65535 bytes) */
|
||||
unsigned short int Lred;
|
||||
/** one byte, signals JPWL techniques adoption */
|
||||
unsigned char Pred;
|
||||
/** RED data, variable length */
|
||||
unsigned char *data;
|
||||
} jpwl_red_ms_t;
|
||||
|
||||
/**
|
||||
Structure used to store JPWL markers temporary position and readyness
|
||||
*/
|
||||
typedef struct jpwl_marker {
|
||||
/** marker value (J2K_MS_EPC, etc.) */
|
||||
int id;
|
||||
/** union keeping the pointer to the real marker struct */
|
||||
union {
|
||||
/** pointer to EPB marker */
|
||||
jpwl_epb_ms_t *epbmark;
|
||||
/** pointer to EPC marker */
|
||||
jpwl_epc_ms_t *epcmark;
|
||||
/** pointer to ESD marker */
|
||||
jpwl_esd_ms_t *esdmark;
|
||||
/** pointer to RED marker */
|
||||
jpwl_red_ms_t *redmark;
|
||||
};
|
||||
/** position where the marker should go, in the pre-JPWL codestream */
|
||||
unsigned long int pos;
|
||||
/** same as before, only written as a double, so we can sort it better */
|
||||
double dpos;
|
||||
/** length of the marker segment (marker excluded) */
|
||||
unsigned short int len;
|
||||
/** the marker length is ready or not? */
|
||||
bool len_ready;
|
||||
/** the marker position is ready or not? */
|
||||
bool pos_ready;
|
||||
/** the marker parameters are ready or not? */
|
||||
bool parms_ready;
|
||||
/** are the written data ready or not */
|
||||
bool data_ready;
|
||||
} jpwl_marker_t;
|
||||
|
||||
/**
|
||||
Prepare the list of JPWL markers, after the Part 1 codestream
|
||||
has been finalized (index struct is full)
|
||||
@param j2k J2K handle
|
||||
@param cio codestream handle
|
||||
@param image image handle
|
||||
*/
|
||||
void jpwl_prepare_marks(opj_j2k_t *j2k, opj_cio_t *cio, opj_image_t *image);
|
||||
|
||||
/**
|
||||
Dump the list of JPWL markers, after it has been prepared
|
||||
@param j2k J2K handle
|
||||
@param cio codestream handle
|
||||
@param image image handle
|
||||
*/
|
||||
void jpwl_dump_marks(opj_j2k_t *j2k, opj_cio_t *cio, opj_image_t *image);
|
||||
|
||||
/**
|
||||
Read the EPC marker (Error Protection Capability)
|
||||
@param j2k J2K handle
|
||||
*/
|
||||
void j2k_read_epc(opj_j2k_t *j2k);
|
||||
/**
|
||||
Write the EPC marker (Error Protection Capability), BUT the DL field is always set to 0
|
||||
(this simplifies the management of EPBs and it is openly stated in the standard
|
||||
as a possible value, mening that the information is not available) and the informative techniques
|
||||
are not yet implemented
|
||||
@param j2k J2K handle
|
||||
*/
|
||||
void j2k_write_epc(opj_j2k_t *j2k);
|
||||
/**
|
||||
Read the EPB marker (Error Protection Block)
|
||||
@param j2k J2K handle
|
||||
*/
|
||||
void j2k_read_epb(opj_j2k_t *j2k);
|
||||
/**
|
||||
Write the EPB marker (Error Protection Block)
|
||||
@param j2k J2K handle
|
||||
*/
|
||||
void j2k_write_epb(opj_j2k_t *j2k);
|
||||
/**
|
||||
Read the ESD marker (Error Sensitivity Descriptor)
|
||||
@param j2k J2K handle
|
||||
*/
|
||||
void j2k_read_esd(opj_j2k_t *j2k);
|
||||
/**
|
||||
Read the RED marker (Residual Error Descriptor)
|
||||
@param j2k J2K handle
|
||||
*/
|
||||
void j2k_read_red(opj_j2k_t *j2k);
|
||||
|
||||
/** create an EPB marker segment
|
||||
@param j2k J2K compressor handle
|
||||
@param latest it is the latest EPB in the header
|
||||
@param packed EPB is in packed style
|
||||
@param tileno tile number where the marker has been placed (-1 means MH)
|
||||
@param idx current EPB running index
|
||||
@param hprot applied protection type (-1/0,1,16,32,37-128)
|
||||
@param pre_len length of pre-protected data
|
||||
@param post_len length of post-protected data
|
||||
@return returns the freshly created EPB
|
||||
*/
|
||||
jpwl_epb_ms_t *jpwl_epb_create(opj_j2k_t *j2k, bool latest, bool packed, int tileno, int idx, int hprot,
|
||||
unsigned long int pre_len, unsigned long int post_len);
|
||||
|
||||
/** add a number of EPB marker segments
|
||||
@param j2k J2K compressor handle
|
||||
@param jwmarker pointer to the JPWL markers list
|
||||
@param jwmarker_num pointer to the number of JPWL markers (gets updated)
|
||||
@param latest it is the latest group of EPBs in the header
|
||||
@param packed EPBs are in packed style
|
||||
@param insideMH it is in the MH
|
||||
@param idx pointer to the starting EPB running index (gets updated)
|
||||
@param hprot applied protection type (-1/0,1,16,32,37-128)
|
||||
@param place_pos place in original codestream where EPBs should go
|
||||
@param tileno tile number of these EPBs
|
||||
@param pre_len length of pre-protected data
|
||||
@param post_len length of post-protected data
|
||||
@return returns the length of all added markers
|
||||
*/
|
||||
int jpwl_epbs_add(opj_j2k_t *j2k, jpwl_marker_t *jwmarker, int *jwmarker_num,
|
||||
bool latest, bool packed, bool insideMH, int *idx, int hprot,
|
||||
double place_pos, int tileno,
|
||||
unsigned long int pre_len, unsigned long int post_len);
|
||||
|
||||
/** add a number of ESD marker segments
|
||||
@param j2k J2K compressor handle
|
||||
@param jwmarker pointer to the JPWL markers list
|
||||
@param jwmarker_num pointer to the number of JPWL markers (gets updated)
|
||||
@param comps considered component (-1=average, 0/1/2/...=component no.)
|
||||
@param addrm addressing mode (0=packet, 1=byte range, 2=packet range, 3=reserved)
|
||||
@param ad_size size of addresses (2/4 bytes)
|
||||
@param senst sensitivity type
|
||||
@param se_size sensitivity values size (1/2 bytes)
|
||||
@param place_pos place in original codestream where EPBs should go
|
||||
@param tileno tile number of these EPBs
|
||||
@return returns the length of all added markers
|
||||
*/
|
||||
int jpwl_esds_add(opj_j2k_t *j2k, jpwl_marker_t *jwmarker, int *jwmarker_num,
|
||||
int comps, unsigned char addrm, unsigned char ad_size,
|
||||
unsigned char senst, unsigned char se_size,
|
||||
double place_pos, int tileno);
|
||||
|
||||
/** updates the information structure by modifying the positions and lengths
|
||||
@param j2k J2K compressor handle
|
||||
@param jwmarker pointer to JPWL markers list
|
||||
@param jwmarker_num number of JPWL markers
|
||||
@return returns true in case of success
|
||||
*/
|
||||
bool jpwl_update_info(opj_j2k_t *j2k, jpwl_marker_t *jwmarker, int jwmarker_num);
|
||||
|
||||
|
||||
bool jpwl_esd_fill(opj_j2k_t *j2k, jpwl_esd_ms_t *esdmark, unsigned char *buf);
|
||||
|
||||
bool jpwl_epb_fill(opj_j2k_t *j2k, jpwl_epb_ms_t *epbmark, unsigned char *buf, unsigned char *post_buf);
|
||||
|
||||
/** corrects the data in the JPWL codestream
|
||||
@param j2k J2K compressor handle
|
||||
@return true if correction is performed correctly
|
||||
*/
|
||||
bool jpwl_correct(opj_j2k_t *j2k);
|
||||
|
||||
/** corrects the data protected by an EPB
|
||||
@param j2k J2K compressor handle
|
||||
@param buffer pointer to the EPB position
|
||||
@param type type of EPB: 0=MH, 1=TPH, 2=other, 3=auto
|
||||
@param pre_len length of pre-data
|
||||
@param post_len length of post_data
|
||||
@param conn is a pointer to the length of all connected (packed) EPBs
|
||||
@param L4_bufp is a pointer to the buffer pointer of redundancy data
|
||||
@return returns true if correction could be succesfully performed
|
||||
*/
|
||||
bool jpwl_epb_correct(opj_j2k_t *j2k, unsigned char *buffer, int type, int pre_len, int post_len, int *conn,
|
||||
unsigned char **L4_bufp);
|
||||
|
||||
/** check that a tile and its children have valid data
|
||||
@param j2k J2K decompressor handle
|
||||
@param tcd Tile decompressor handle
|
||||
@param tileno number of the tile to check
|
||||
*/
|
||||
bool jpwl_check_tile(opj_j2k_t *j2k, opj_tcd_t *tcd, int tileno);
|
||||
|
||||
/** Macro functions for CRC computation */
|
||||
|
||||
/**
|
||||
Computes the CRC-16, as stated in JPWL specs
|
||||
@param CRC two bytes containing the CRC value (must be initialized with 0x0000)
|
||||
@param DATA byte for which the CRC is computed; call this on every byte of the sequence
|
||||
and get the CRC at the end
|
||||
*/
|
||||
#define jpwl_updateCRC16(CRC, DATA) updateCRC16(CRC, DATA)
|
||||
|
||||
/**
|
||||
Computes the CRC-32, as stated in JPWL specs
|
||||
@param CRC four bytes containing the CRC value (must be initialized with 0x00000000)
|
||||
@param DATA byte for which the CRC is computed; call this on every byte of the sequence
|
||||
and get the CRC at the end
|
||||
*/
|
||||
#define jpwl_updateCRC32(CRC, DATA) updateCRC32(CRC, DATA)
|
||||
|
||||
/*@}*/
|
||||
|
||||
#endif /* USE_JPWL */
|
||||
|
||||
#endif /* __JPWL_H */
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,594 @@
|
|||
/*
|
||||
* Copyright (c) 2001-2003, David Janssens
|
||||
* Copyright (c) 2002-2003, Yannick Verschueren
|
||||
* Copyright (c) 2003-2005, Francois Devaux and Antonin Descampe
|
||||
* Copyright (c) 2005, Hervé Drolon, FreeImage Team
|
||||
* Copyright (c) 2002-2005, Communications and remote sensing Laboratory, Universite catholique de Louvain, Belgium
|
||||
* Copyright (c) 2005-2006, Dept. of Electronic and Information Engineering, Universita' degli Studi di Perugia, Italy
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS `AS IS'
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
||||
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifdef USE_JPWL
|
||||
|
||||
/**
|
||||
@file rs.c
|
||||
@brief Functions used to compute the Reed-Solomon parity and check of byte arrays
|
||||
|
||||
*/
|
||||
|
||||
/**
|
||||
* Reed-Solomon coding and decoding
|
||||
* Phil Karn (karn@ka9q.ampr.org) September 1996
|
||||
*
|
||||
* This file is derived from the program "new_rs_erasures.c" by Robert
|
||||
* Morelos-Zaragoza (robert@spectra.eng.hawaii.edu) and Hari Thirumoorthy
|
||||
* (harit@spectra.eng.hawaii.edu), Aug 1995
|
||||
*
|
||||
* I've made changes to improve performance, clean up the code and make it
|
||||
* easier to follow. Data is now passed to the encoding and decoding functions
|
||||
* through arguments rather than in global arrays. The decode function returns
|
||||
* the number of corrected symbols, or -1 if the word is uncorrectable.
|
||||
*
|
||||
* This code supports a symbol size from 2 bits up to 16 bits,
|
||||
* implying a block size of 3 2-bit symbols (6 bits) up to 65535
|
||||
* 16-bit symbols (1,048,560 bits). The code parameters are set in rs.h.
|
||||
*
|
||||
* Note that if symbols larger than 8 bits are used, the type of each
|
||||
* data array element switches from unsigned char to unsigned int. The
|
||||
* caller must ensure that elements larger than the symbol range are
|
||||
* not passed to the encoder or decoder.
|
||||
*
|
||||
*/
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include "rs.h"
|
||||
|
||||
/* This defines the type used to store an element of the Galois Field
|
||||
* used by the code. Make sure this is something larger than a char if
|
||||
* if anything larger than GF(256) is used.
|
||||
*
|
||||
* Note: unsigned char will work up to GF(256) but int seems to run
|
||||
* faster on the Pentium.
|
||||
*/
|
||||
typedef int gf;
|
||||
|
||||
/* Primitive polynomials - see Lin & Costello, Appendix A,
|
||||
* and Lee & Messerschmitt, p. 453.
|
||||
*/
|
||||
#if(MM == 2)/* Admittedly silly */
|
||||
int Pp[MM+1] = { 1, 1, 1 };
|
||||
|
||||
#elif(MM == 3)
|
||||
/* 1 + x + x^3 */
|
||||
int Pp[MM+1] = { 1, 1, 0, 1 };
|
||||
|
||||
#elif(MM == 4)
|
||||
/* 1 + x + x^4 */
|
||||
int Pp[MM+1] = { 1, 1, 0, 0, 1 };
|
||||
|
||||
#elif(MM == 5)
|
||||
/* 1 + x^2 + x^5 */
|
||||
int Pp[MM+1] = { 1, 0, 1, 0, 0, 1 };
|
||||
|
||||
#elif(MM == 6)
|
||||
/* 1 + x + x^6 */
|
||||
int Pp[MM+1] = { 1, 1, 0, 0, 0, 0, 1 };
|
||||
|
||||
#elif(MM == 7)
|
||||
/* 1 + x^3 + x^7 */
|
||||
int Pp[MM+1] = { 1, 0, 0, 1, 0, 0, 0, 1 };
|
||||
|
||||
#elif(MM == 8)
|
||||
/* 1+x^2+x^3+x^4+x^8 */
|
||||
int Pp[MM+1] = { 1, 0, 1, 1, 1, 0, 0, 0, 1 };
|
||||
|
||||
#elif(MM == 9)
|
||||
/* 1+x^4+x^9 */
|
||||
int Pp[MM+1] = { 1, 0, 0, 0, 1, 0, 0, 0, 0, 1 };
|
||||
|
||||
#elif(MM == 10)
|
||||
/* 1+x^3+x^10 */
|
||||
int Pp[MM+1] = { 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1 };
|
||||
|
||||
#elif(MM == 11)
|
||||
/* 1+x^2+x^11 */
|
||||
int Pp[MM+1] = { 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1 };
|
||||
|
||||
#elif(MM == 12)
|
||||
/* 1+x+x^4+x^6+x^12 */
|
||||
int Pp[MM+1] = { 1, 1, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 1 };
|
||||
|
||||
#elif(MM == 13)
|
||||
/* 1+x+x^3+x^4+x^13 */
|
||||
int Pp[MM+1] = { 1, 1, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1 };
|
||||
|
||||
#elif(MM == 14)
|
||||
/* 1+x+x^6+x^10+x^14 */
|
||||
int Pp[MM+1] = { 1, 1, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1 };
|
||||
|
||||
#elif(MM == 15)
|
||||
/* 1+x+x^15 */
|
||||
int Pp[MM+1] = { 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 };
|
||||
|
||||
#elif(MM == 16)
|
||||
/* 1+x+x^3+x^12+x^16 */
|
||||
int Pp[MM+1] = { 1, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1 };
|
||||
|
||||
#else
|
||||
#error "MM must be in range 2-16"
|
||||
#endif
|
||||
|
||||
/* Alpha exponent for the first root of the generator polynomial */
|
||||
#define B0 0 /* Different from the default 1 */
|
||||
|
||||
/* index->polynomial form conversion table */
|
||||
gf Alpha_to[NN + 1];
|
||||
|
||||
/* Polynomial->index form conversion table */
|
||||
gf Index_of[NN + 1];
|
||||
|
||||
/* No legal value in index form represents zero, so
|
||||
* we need a special value for this purpose
|
||||
*/
|
||||
#define A0 (NN)
|
||||
|
||||
/* Generator polynomial g(x)
|
||||
* Degree of g(x) = 2*TT
|
||||
* has roots @**B0, @**(B0+1), ... ,@^(B0+2*TT-1)
|
||||
*/
|
||||
/*gf Gg[NN - KK + 1];*/
|
||||
gf Gg[NN - 1];
|
||||
|
||||
/* Compute x % NN, where NN is 2**MM - 1,
|
||||
* without a slow divide
|
||||
*/
|
||||
static /*inline*/ gf
|
||||
modnn(int x)
|
||||
{
|
||||
while (x >= NN) {
|
||||
x -= NN;
|
||||
x = (x >> MM) + (x & NN);
|
||||
}
|
||||
return x;
|
||||
}
|
||||
|
||||
/*#define min(a,b) ((a) < (b) ? (a) : (b))*/
|
||||
|
||||
#define CLEAR(a,n) {\
|
||||
int ci;\
|
||||
for(ci=(n)-1;ci >=0;ci--)\
|
||||
(a)[ci] = 0;\
|
||||
}
|
||||
|
||||
#define COPY(a,b,n) {\
|
||||
int ci;\
|
||||
for(ci=(n)-1;ci >=0;ci--)\
|
||||
(a)[ci] = (b)[ci];\
|
||||
}
|
||||
#define COPYDOWN(a,b,n) {\
|
||||
int ci;\
|
||||
for(ci=(n)-1;ci >=0;ci--)\
|
||||
(a)[ci] = (b)[ci];\
|
||||
}
|
||||
|
||||
void init_rs(int k)
|
||||
{
|
||||
KK = k;
|
||||
if (KK >= NN) {
|
||||
printf("KK must be less than 2**MM - 1\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
generate_gf();
|
||||
gen_poly();
|
||||
}
|
||||
|
||||
/* generate GF(2**m) from the irreducible polynomial p(X) in p[0]..p[m]
|
||||
lookup tables: index->polynomial form alpha_to[] contains j=alpha**i;
|
||||
polynomial form -> index form index_of[j=alpha**i] = i
|
||||
alpha=2 is the primitive element of GF(2**m)
|
||||
HARI's COMMENT: (4/13/94) alpha_to[] can be used as follows:
|
||||
Let @ represent the primitive element commonly called "alpha" that
|
||||
is the root of the primitive polynomial p(x). Then in GF(2^m), for any
|
||||
0 <= i <= 2^m-2,
|
||||
@^i = a(0) + a(1) @ + a(2) @^2 + ... + a(m-1) @^(m-1)
|
||||
where the binary vector (a(0),a(1),a(2),...,a(m-1)) is the representation
|
||||
of the integer "alpha_to[i]" with a(0) being the LSB and a(m-1) the MSB. Thus for
|
||||
example the polynomial representation of @^5 would be given by the binary
|
||||
representation of the integer "alpha_to[5]".
|
||||
Similarily, index_of[] can be used as follows:
|
||||
As above, let @ represent the primitive element of GF(2^m) that is
|
||||
the root of the primitive polynomial p(x). In order to find the power
|
||||
of @ (alpha) that has the polynomial representation
|
||||
a(0) + a(1) @ + a(2) @^2 + ... + a(m-1) @^(m-1)
|
||||
we consider the integer "i" whose binary representation with a(0) being LSB
|
||||
and a(m-1) MSB is (a(0),a(1),...,a(m-1)) and locate the entry
|
||||
"index_of[i]". Now, @^index_of[i] is that element whose polynomial
|
||||
representation is (a(0),a(1),a(2),...,a(m-1)).
|
||||
NOTE:
|
||||
The element alpha_to[2^m-1] = 0 always signifying that the
|
||||
representation of "@^infinity" = 0 is (0,0,0,...,0).
|
||||
Similarily, the element index_of[0] = A0 always signifying
|
||||
that the power of alpha which has the polynomial representation
|
||||
(0,0,...,0) is "infinity".
|
||||
|
||||
*/
|
||||
|
||||
void
|
||||
generate_gf(void)
|
||||
{
|
||||
register int i, mask;
|
||||
|
||||
mask = 1;
|
||||
Alpha_to[MM] = 0;
|
||||
for (i = 0; i < MM; i++) {
|
||||
Alpha_to[i] = mask;
|
||||
Index_of[Alpha_to[i]] = i;
|
||||
/* If Pp[i] == 1 then, term @^i occurs in poly-repr of @^MM */
|
||||
if (Pp[i] != 0)
|
||||
Alpha_to[MM] ^= mask; /* Bit-wise EXOR operation */
|
||||
mask <<= 1; /* single left-shift */
|
||||
}
|
||||
Index_of[Alpha_to[MM]] = MM;
|
||||
/*
|
||||
* Have obtained poly-repr of @^MM. Poly-repr of @^(i+1) is given by
|
||||
* poly-repr of @^i shifted left one-bit and accounting for any @^MM
|
||||
* term that may occur when poly-repr of @^i is shifted.
|
||||
*/
|
||||
mask >>= 1;
|
||||
for (i = MM + 1; i < NN; i++) {
|
||||
if (Alpha_to[i - 1] >= mask)
|
||||
Alpha_to[i] = Alpha_to[MM] ^ ((Alpha_to[i - 1] ^ mask) << 1);
|
||||
else
|
||||
Alpha_to[i] = Alpha_to[i - 1] << 1;
|
||||
Index_of[Alpha_to[i]] = i;
|
||||
}
|
||||
Index_of[0] = A0;
|
||||
Alpha_to[NN] = 0;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Obtain the generator polynomial of the TT-error correcting, length
|
||||
* NN=(2**MM -1) Reed Solomon code from the product of (X+@**(B0+i)), i = 0,
|
||||
* ... ,(2*TT-1)
|
||||
*
|
||||
* Examples:
|
||||
*
|
||||
* If B0 = 1, TT = 1. deg(g(x)) = 2*TT = 2.
|
||||
* g(x) = (x+@) (x+@**2)
|
||||
*
|
||||
* If B0 = 0, TT = 2. deg(g(x)) = 2*TT = 4.
|
||||
* g(x) = (x+1) (x+@) (x+@**2) (x+@**3)
|
||||
*/
|
||||
void
|
||||
gen_poly(void)
|
||||
{
|
||||
register int i, j;
|
||||
|
||||
Gg[0] = Alpha_to[B0];
|
||||
Gg[1] = 1; /* g(x) = (X+@**B0) initially */
|
||||
for (i = 2; i <= NN - KK; i++) {
|
||||
Gg[i] = 1;
|
||||
/*
|
||||
* Below multiply (Gg[0]+Gg[1]*x + ... +Gg[i]x^i) by
|
||||
* (@**(B0+i-1) + x)
|
||||
*/
|
||||
for (j = i - 1; j > 0; j--)
|
||||
if (Gg[j] != 0)
|
||||
Gg[j] = Gg[j - 1] ^ Alpha_to[modnn((Index_of[Gg[j]]) + B0 + i - 1)];
|
||||
else
|
||||
Gg[j] = Gg[j - 1];
|
||||
/* Gg[0] can never be zero */
|
||||
Gg[0] = Alpha_to[modnn((Index_of[Gg[0]]) + B0 + i - 1)];
|
||||
}
|
||||
/* convert Gg[] to index form for quicker encoding */
|
||||
for (i = 0; i <= NN - KK; i++)
|
||||
Gg[i] = Index_of[Gg[i]];
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* take the string of symbols in data[i], i=0..(k-1) and encode
|
||||
* systematically to produce NN-KK parity symbols in bb[0]..bb[NN-KK-1] data[]
|
||||
* is input and bb[] is output in polynomial form. Encoding is done by using
|
||||
* a feedback shift register with appropriate connections specified by the
|
||||
* elements of Gg[], which was generated above. Codeword is c(X) =
|
||||
* data(X)*X**(NN-KK)+ b(X)
|
||||
*/
|
||||
int
|
||||
encode_rs(dtype *data, dtype *bb)
|
||||
{
|
||||
register int i, j;
|
||||
gf feedback;
|
||||
|
||||
CLEAR(bb,NN-KK);
|
||||
for (i = KK - 1; i >= 0; i--) {
|
||||
#if (MM != 8)
|
||||
if(data[i] > NN)
|
||||
return -1; /* Illegal symbol */
|
||||
#endif
|
||||
feedback = Index_of[data[i] ^ bb[NN - KK - 1]];
|
||||
if (feedback != A0) { /* feedback term is non-zero */
|
||||
for (j = NN - KK - 1; j > 0; j--)
|
||||
if (Gg[j] != A0)
|
||||
bb[j] = bb[j - 1] ^ Alpha_to[modnn(Gg[j] + feedback)];
|
||||
else
|
||||
bb[j] = bb[j - 1];
|
||||
bb[0] = Alpha_to[modnn(Gg[0] + feedback)];
|
||||
} else { /* feedback term is zero. encoder becomes a
|
||||
* single-byte shifter */
|
||||
for (j = NN - KK - 1; j > 0; j--)
|
||||
bb[j] = bb[j - 1];
|
||||
bb[0] = 0;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Performs ERRORS+ERASURES decoding of RS codes. If decoding is successful,
|
||||
* writes the codeword into data[] itself. Otherwise data[] is unaltered.
|
||||
*
|
||||
* Return number of symbols corrected, or -1 if codeword is illegal
|
||||
* or uncorrectable.
|
||||
*
|
||||
* First "no_eras" erasures are declared by the calling program. Then, the
|
||||
* maximum # of errors correctable is t_after_eras = floor((NN-KK-no_eras)/2).
|
||||
* If the number of channel errors is not greater than "t_after_eras" the
|
||||
* transmitted codeword will be recovered. Details of algorithm can be found
|
||||
* in R. Blahut's "Theory ... of Error-Correcting Codes".
|
||||
*/
|
||||
int
|
||||
eras_dec_rs(dtype *data, int *eras_pos, int no_eras)
|
||||
{
|
||||
int deg_lambda, el, deg_omega;
|
||||
int i, j, r;
|
||||
gf u,q,tmp,num1,num2,den,discr_r;
|
||||
gf recd[NN];
|
||||
/* Err+Eras Locator poly and syndrome poly */
|
||||
/*gf lambda[NN-KK + 1], s[NN-KK + 1];
|
||||
gf b[NN-KK + 1], t[NN-KK + 1], omega[NN-KK + 1];
|
||||
gf root[NN-KK], reg[NN-KK + 1], loc[NN-KK];*/
|
||||
gf lambda[NN + 1], s[NN + 1];
|
||||
gf b[NN + 1], t[NN + 1], omega[NN + 1];
|
||||
gf root[NN], reg[NN + 1], loc[NN];
|
||||
int syn_error, count;
|
||||
|
||||
/* data[] is in polynomial form, copy and convert to index form */
|
||||
for (i = NN-1; i >= 0; i--){
|
||||
#if (MM != 8)
|
||||
if(data[i] > NN)
|
||||
return -1; /* Illegal symbol */
|
||||
#endif
|
||||
recd[i] = Index_of[data[i]];
|
||||
}
|
||||
/* first form the syndromes; i.e., evaluate recd(x) at roots of g(x)
|
||||
* namely @**(B0+i), i = 0, ... ,(NN-KK-1)
|
||||
*/
|
||||
syn_error = 0;
|
||||
for (i = 1; i <= NN-KK; i++) {
|
||||
tmp = 0;
|
||||
for (j = 0; j < NN; j++)
|
||||
if (recd[j] != A0) /* recd[j] in index form */
|
||||
tmp ^= Alpha_to[modnn(recd[j] + (B0+i-1)*j)];
|
||||
syn_error |= tmp; /* set flag if non-zero syndrome =>
|
||||
* error */
|
||||
/* store syndrome in index form */
|
||||
s[i] = Index_of[tmp];
|
||||
}
|
||||
if (!syn_error) {
|
||||
/*
|
||||
* if syndrome is zero, data[] is a codeword and there are no
|
||||
* errors to correct. So return data[] unmodified
|
||||
*/
|
||||
return 0;
|
||||
}
|
||||
CLEAR(&lambda[1],NN-KK);
|
||||
lambda[0] = 1;
|
||||
if (no_eras > 0) {
|
||||
/* Init lambda to be the erasure locator polynomial */
|
||||
lambda[1] = Alpha_to[eras_pos[0]];
|
||||
for (i = 1; i < no_eras; i++) {
|
||||
u = eras_pos[i];
|
||||
for (j = i+1; j > 0; j--) {
|
||||
tmp = Index_of[lambda[j - 1]];
|
||||
if(tmp != A0)
|
||||
lambda[j] ^= Alpha_to[modnn(u + tmp)];
|
||||
}
|
||||
}
|
||||
#ifdef ERASURE_DEBUG
|
||||
/* find roots of the erasure location polynomial */
|
||||
for(i=1;i<=no_eras;i++)
|
||||
reg[i] = Index_of[lambda[i]];
|
||||
count = 0;
|
||||
for (i = 1; i <= NN; i++) {
|
||||
q = 1;
|
||||
for (j = 1; j <= no_eras; j++)
|
||||
if (reg[j] != A0) {
|
||||
reg[j] = modnn(reg[j] + j);
|
||||
q ^= Alpha_to[reg[j]];
|
||||
}
|
||||
if (!q) {
|
||||
/* store root and error location
|
||||
* number indices
|
||||
*/
|
||||
root[count] = i;
|
||||
loc[count] = NN - i;
|
||||
count++;
|
||||
}
|
||||
}
|
||||
if (count != no_eras) {
|
||||
printf("\n lambda(x) is WRONG\n");
|
||||
return -1;
|
||||
}
|
||||
#ifndef NO_PRINT
|
||||
printf("\n Erasure positions as determined by roots of Eras Loc Poly:\n");
|
||||
for (i = 0; i < count; i++)
|
||||
printf("%d ", loc[i]);
|
||||
printf("\n");
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
for(i=0;i<NN-KK+1;i++)
|
||||
b[i] = Index_of[lambda[i]];
|
||||
|
||||
/*
|
||||
* Begin Berlekamp-Massey algorithm to determine error+erasure
|
||||
* locator polynomial
|
||||
*/
|
||||
r = no_eras;
|
||||
el = no_eras;
|
||||
while (++r <= NN-KK) { /* r is the step number */
|
||||
/* Compute discrepancy at the r-th step in poly-form */
|
||||
discr_r = 0;
|
||||
for (i = 0; i < r; i++){
|
||||
if ((lambda[i] != 0) && (s[r - i] != A0)) {
|
||||
discr_r ^= Alpha_to[modnn(Index_of[lambda[i]] + s[r - i])];
|
||||
}
|
||||
}
|
||||
discr_r = Index_of[discr_r]; /* Index form */
|
||||
if (discr_r == A0) {
|
||||
/* 2 lines below: B(x) <-- x*B(x) */
|
||||
COPYDOWN(&b[1],b,NN-KK);
|
||||
b[0] = A0;
|
||||
} else {
|
||||
/* 7 lines below: T(x) <-- lambda(x) - discr_r*x*b(x) */
|
||||
t[0] = lambda[0];
|
||||
for (i = 0 ; i < NN-KK; i++) {
|
||||
if(b[i] != A0)
|
||||
t[i+1] = lambda[i+1] ^ Alpha_to[modnn(discr_r + b[i])];
|
||||
else
|
||||
t[i+1] = lambda[i+1];
|
||||
}
|
||||
if (2 * el <= r + no_eras - 1) {
|
||||
el = r + no_eras - el;
|
||||
/*
|
||||
* 2 lines below: B(x) <-- inv(discr_r) *
|
||||
* lambda(x)
|
||||
*/
|
||||
for (i = 0; i <= NN-KK; i++)
|
||||
b[i] = (lambda[i] == 0) ? A0 : modnn(Index_of[lambda[i]] - discr_r + NN);
|
||||
} else {
|
||||
/* 2 lines below: B(x) <-- x*B(x) */
|
||||
COPYDOWN(&b[1],b,NN-KK);
|
||||
b[0] = A0;
|
||||
}
|
||||
COPY(lambda,t,NN-KK+1);
|
||||
}
|
||||
}
|
||||
|
||||
/* Convert lambda to index form and compute deg(lambda(x)) */
|
||||
deg_lambda = 0;
|
||||
for(i=0;i<NN-KK+1;i++){
|
||||
lambda[i] = Index_of[lambda[i]];
|
||||
if(lambda[i] != A0)
|
||||
deg_lambda = i;
|
||||
}
|
||||
/*
|
||||
* Find roots of the error+erasure locator polynomial. By Chien
|
||||
* Search
|
||||
*/
|
||||
COPY(®[1],&lambda[1],NN-KK);
|
||||
count = 0; /* Number of roots of lambda(x) */
|
||||
for (i = 1; i <= NN; i++) {
|
||||
q = 1;
|
||||
for (j = deg_lambda; j > 0; j--)
|
||||
if (reg[j] != A0) {
|
||||
reg[j] = modnn(reg[j] + j);
|
||||
q ^= Alpha_to[reg[j]];
|
||||
}
|
||||
if (!q) {
|
||||
/* store root (index-form) and error location number */
|
||||
root[count] = i;
|
||||
loc[count] = NN - i;
|
||||
count++;
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef DEBUG
|
||||
printf("\n Final error positions:\t");
|
||||
for (i = 0; i < count; i++)
|
||||
printf("%d ", loc[i]);
|
||||
printf("\n");
|
||||
#endif
|
||||
if (deg_lambda != count) {
|
||||
/*
|
||||
* deg(lambda) unequal to number of roots => uncorrectable
|
||||
* error detected
|
||||
*/
|
||||
return -1;
|
||||
}
|
||||
/*
|
||||
* Compute err+eras evaluator poly omega(x) = s(x)*lambda(x) (modulo
|
||||
* x**(NN-KK)). in index form. Also find deg(omega).
|
||||
*/
|
||||
deg_omega = 0;
|
||||
for (i = 0; i < NN-KK;i++){
|
||||
tmp = 0;
|
||||
j = (deg_lambda < i) ? deg_lambda : i;
|
||||
for(;j >= 0; j--){
|
||||
if ((s[i + 1 - j] != A0) && (lambda[j] != A0))
|
||||
tmp ^= Alpha_to[modnn(s[i + 1 - j] + lambda[j])];
|
||||
}
|
||||
if(tmp != 0)
|
||||
deg_omega = i;
|
||||
omega[i] = Index_of[tmp];
|
||||
}
|
||||
omega[NN-KK] = A0;
|
||||
|
||||
/*
|
||||
* Compute error values in poly-form. num1 = omega(inv(X(l))), num2 =
|
||||
* inv(X(l))**(B0-1) and den = lambda_pr(inv(X(l))) all in poly-form
|
||||
*/
|
||||
for (j = count-1; j >=0; j--) {
|
||||
num1 = 0;
|
||||
for (i = deg_omega; i >= 0; i--) {
|
||||
if (omega[i] != A0)
|
||||
num1 ^= Alpha_to[modnn(omega[i] + i * root[j])];
|
||||
}
|
||||
num2 = Alpha_to[modnn(root[j] * (B0 - 1) + NN)];
|
||||
den = 0;
|
||||
|
||||
/* lambda[i+1] for i even is the formal derivative lambda_pr of lambda[i] */
|
||||
for (i = min(deg_lambda,NN-KK-1) & ~1; i >= 0; i -=2) {
|
||||
if(lambda[i+1] != A0)
|
||||
den ^= Alpha_to[modnn(lambda[i+1] + i * root[j])];
|
||||
}
|
||||
if (den == 0) {
|
||||
#ifdef DEBUG
|
||||
printf("\n ERROR: denominator = 0\n");
|
||||
#endif
|
||||
return -1;
|
||||
}
|
||||
/* Apply error to data */
|
||||
if (num1 != 0) {
|
||||
data[loc[j]] ^= Alpha_to[modnn(Index_of[num1] + Index_of[num2] + NN - Index_of[den])];
|
||||
}
|
||||
}
|
||||
return count;
|
||||
}
|
||||
|
||||
|
||||
#endif /* USE_JPWL */
|
|
@ -0,0 +1,101 @@
|
|||
/*
|
||||
* Copyright (c) 2001-2003, David Janssens
|
||||
* Copyright (c) 2002-2003, Yannick Verschueren
|
||||
* Copyright (c) 2003-2005, Francois Devaux and Antonin Descampe
|
||||
* Copyright (c) 2005, Hervé Drolon, FreeImage Team
|
||||
* Copyright (c) 2002-2005, Communications and remote sensing Laboratory, Universite catholique de Louvain, Belgium
|
||||
* Copyright (c) 2005-2006, Dept. of Electronic and Information Engineering, Universita' degli Studi di Perugia, Italy
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS `AS IS'
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
||||
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifdef USE_JPWL
|
||||
|
||||
/**
|
||||
@file rs.h
|
||||
@brief Functions used to compute Reed-Solomon parity and check of byte arrays
|
||||
|
||||
*/
|
||||
|
||||
#ifndef __RS_HEADER__
|
||||
#define __RS_HEADER__
|
||||
|
||||
/** Global definitions for Reed-Solomon encoder/decoder
|
||||
* Phil Karn KA9Q, September 1996
|
||||
*
|
||||
* The parameters MM and KK specify the Reed-Solomon code parameters.
|
||||
*
|
||||
* Set MM to be the size of each code symbol in bits. The Reed-Solomon
|
||||
* block size will then be NN = 2**M - 1 symbols. Supported values are
|
||||
* defined in rs.c.
|
||||
*
|
||||
* Set KK to be the number of data symbols in each block, which must be
|
||||
* less than the block size. The code will then be able to correct up
|
||||
* to NN-KK erasures or (NN-KK)/2 errors, or combinations thereof with
|
||||
* each error counting as two erasures.
|
||||
*/
|
||||
#define MM 8 /* RS code over GF(2**MM) - change to suit */
|
||||
static int KK;
|
||||
|
||||
/* Original code */
|
||||
/*#define KK 239*/ /* KK = number of information symbols */
|
||||
|
||||
#define NN ((1 << MM) - 1)
|
||||
|
||||
#if (MM <= 8)
|
||||
typedef unsigned char dtype;
|
||||
#else
|
||||
typedef unsigned int dtype;
|
||||
#endif
|
||||
|
||||
/** Initialization function */
|
||||
void init_rs(int);
|
||||
|
||||
/** These two functions *must* be called in this order (e.g.,
|
||||
* by init_rs()) before any encoding/decoding
|
||||
*/
|
||||
void generate_gf(void); /* Generate Galois Field */
|
||||
void gen_poly(void); /* Generate generator polynomial */
|
||||
|
||||
/** Reed-Solomon encoding
|
||||
* data[] is the input block, parity symbols are placed in bb[]
|
||||
* bb[] may lie past the end of the data, e.g., for (255,223):
|
||||
* encode_rs(&data[0],&data[223]);
|
||||
*/
|
||||
int encode_rs(dtype data[], dtype bb[]);
|
||||
|
||||
/** Reed-Solomon erasures-and-errors decoding
|
||||
* The received block goes into data[], and a list of zero-origin
|
||||
* erasure positions, if any, goes in eras_pos[] with a count in no_eras.
|
||||
*
|
||||
* The decoder corrects the symbols in place, if possible and returns
|
||||
* the number of corrected symbols. If the codeword is illegal or
|
||||
* uncorrectible, the data array is unchanged and -1 is returned
|
||||
*/
|
||||
int eras_dec_rs(dtype data[], int eras_pos[], int no_eras);
|
||||
|
||||
|
||||
#endif /* __CRC32_HEADER__ */
|
||||
|
||||
|
||||
#endif /* USE_JPWL */
|
Loading…
Reference in New Issue