Add library OpenFEC v1.4.2

This commit is contained in:
dijunkun
2023-11-09 01:00:39 -08:00
parent f833a503ae
commit 6d89a2aa35
77 changed files with 20282 additions and 1 deletions

43
thirdparty/openfec/CMakeLists.txt vendored Normal file
View File

@@ -0,0 +1,43 @@
cmake_minimum_required(VERSION 2.6)
##project
project(openfec C)
ENABLE_TESTING()
if (PROFILING STREQUAL "ON")
else(PROFILING STREQUAL "ON")
endif(PROFILING STREQUAL "ON")
if (DEBUG STREQUAL "ON")
# Debug mode
ADD_DEFINITIONS(-DOF_DEBUG)
set(CMAKE_BUILD_TYPE Debug)
message(STATUS "Debug mode ON" )
else(DEBUG STREQUAL "ON")
# Release mode
set(CMAKE_BUILD_TYPE Release)
set(CMAKE_C_FLAGS "-O4")
message(STATUS "Debug mode OFF")
endif (DEBUG STREQUAL "ON")
# set(LIBRARY_OUTPUT_PATH ${PROJECT_SOURCE_DIR}/bin/${CMAKE_BUILD_TYPE})
# set(EXECUTABLE_OUTPUT_PATH ${PROJECT_SOURCE_DIR}/bin/${CMAKE_BUILD_TYPE})
# set(LIBRARY_OUTPUT_PATH ${PROJECT_SOURCE_DIR}/lib)
# include_directories(${PROJECT_SOURCE_DIR}/src/lib_common)
# set(CMAKE_INSTALL_LIBDIR ${PROJECT_SOURCE_DIR}/src/lib_common)
# set(EXECUTABLE_OUTPUT_PATH ${PROJECT_SOURCE_DIR}/bin)
MARK_AS_ADVANCED(
LIBRARY_OUTPUT_PATH
EXECUTABLE_OUTPUT_PATH
)
link_directories(${LIBRARY_OUTPUT_PATH})
add_subdirectory(src)

29
thirdparty/openfec/src/CMakeLists.txt vendored Normal file
View File

@@ -0,0 +1,29 @@
file (GLOB_RECURSE openfec_sources *)
add_library(openfec STATIC ${openfec_sources})
# From: $cmake --help-property SOVERSION
# For shared libraries VERSION and SOVERSION can be used to specify
# the build version and api version respectively.
#
# Edit it as appropriate to be in line with the src/lib_common/of_openfec_api.c::more_about() version
#
set_target_properties(openfec PROPERTIES
VERSION 1.4.2
SOVERSION 1)
# Feel free to edit as appropriate the "target_link_libraries".
#
# Add the IL (DevIL) library if you want to have the possibility to
# produce H/G matrix images with LDPC codes.
# More precisely, we are relying on the DevIL library
# (http://openil.sourceforge.net/).
# Please install it on your machine before compiling the OpenFEC
# library if needed.
# Otherwise remove the IL library.
target_link_libraries(openfec m)
#target_link_libraries(openfec m IL)
#target_link_libraries(openfec pthread IL)
#target_link_libraries(openfec pthread)

View File

@@ -0,0 +1,59 @@
/* $Id: of_codec_profile.h 72 2012-04-13 13:27:26Z detchart $ */
/*
* OpenFEC.org AL-FEC Library.
* (c) Copyright 2009 - 2012 INRIA - All rights reserved
* Contact: vincent.roca@inria.fr
*
* This software is governed by the CeCILL-C license under French law and
* abiding by the rules of distribution of free software. You can use,
* modify and/ or redistribute the software under the terms of the CeCILL-C
* license as circulated by CEA, CNRS and INRIA at the following URL
* "http://www.cecill.info".
*
* As a counterpart to the access to the source code and rights to copy,
* modify and redistribute granted by the license, users are provided only
* with a limited warranty and the software's author, the holder of the
* economic rights, and the successive licensors have only limited
* liability.
*
* In this respect, the user's attention is drawn to the risks associated
* with loading, using, modifying and/or developing or reproducing the
* software by the user in light of its specific status of free software,
* that may mean that it is complicated to manipulate, and that also
* therefore means that it is reserved for developers and experienced
* professionals having in-depth computer knowledge. Users are therefore
* encouraged to load and test the software's suitability as regards their
* requirements in conditions enabling the security of their systems and/or
* data to be ensured and, more generally, to use and operate it in the
* same conditions as regards security.
*
* The fact that you are presently reading this means that you have had
* knowledge of the CeCILL-C license and that you accept its terms.
*/
/****** GENERAL SETUP OPTIONS; EDIT AS APPROPRIATE ****************************/
#define OF_USE_LDPC_FROM_FILE_CODEC
#define READ_MATRIX_FILE
/**
* Default maximum number of source and encoding symbols for this codec.
* This value depends in particular on the kind of decoder used. To this
* limit, codec implementation details might add other limits (e.g. if
* the ESI values are stored in UINT16 instead of UINT32...).
*
* Hints:
* If ML decoding is enabled and used, then limit yourself to a value
* that is not too high, since decoding might finish with a Gaussian
* elimination on the simplified system.
* In situations where decoding is restricted to IT, the main limit is
* the available memory. It usually means you can set very large values.
*/
#ifdef ML_DECODING
#define OF_LDPC_FROM_FILE_MAX_NB_SOURCE_SYMBOLS_DEFAULT 40000
#define OF_LDPC_FROM_FILE_MAX_NB_ENCODING_SYMBOLS_DEFAULT 40000
#else
#define OF_LDPC_FROM_FILE_MAX_NB_SOURCE_SYMBOLS_DEFAULT 100000
#define OF_LDPC_FROM_FILE_MAX_NB_ENCODING_SYMBOLS_DEFAULT 100000
#endif

View File

@@ -0,0 +1,152 @@
/* $Id: of_ldpc_ff.h 182 2014-07-15 09:27:51Z roca $ */
/*
* OpenFEC.org AL-FEC Library.
* (c) Copyright 2009 - 2012 INRIA - All rights reserved
* Contact: vincent.roca@inria.fr
*
* This software is governed by the CeCILL-C license under French law and
* abiding by the rules of distribution of free software. You can use,
* modify and/ or redistribute the software under the terms of the CeCILL-C
* license as circulated by CEA, CNRS and INRIA at the following URL
* "http://www.cecill.info".
*
* As a counterpart to the access to the source code and rights to copy,
* modify and redistribute granted by the license, users are provided only
* with a limited warranty and the software's author, the holder of the
* economic rights, and the successive licensors have only limited
* liability.
*
* In this respect, the user's attention is drawn to the risks associated
* with loading, using, modifying and/or developing or reproducing the
* software by the user in light of its specific status of free software,
* that may mean that it is complicated to manipulate, and that also
* therefore means that it is reserved for developers and experienced
* professionals having in-depth computer knowledge. Users are therefore
* encouraged to load and test the software's suitability as regards their
* requirements in conditions enabling the security of their systems and/or
* data to be ensured and, more generally, to use and operate it in the
* same conditions as regards security.
*
* The fact that you are presently reading this means that you have had
* knowledge of the CeCILL-C license and that you accept its terms.
*/
#ifdef OF_USE_LDPC_FROM_FILE_CODEC
#ifndef OF_LDPC_FF_H
#define OF_LDPC_FF_H
/**
* LDPC from file stable codec specific control block structure.
*/
typedef struct of_ldpc_ff_cb
{
struct of_ldpc_staircase_cb cb1;
/*
* entries specific to LDPC from file...
*/
/** True if the right side of the parity check matrix is an identity with a
* lower triangle below this identity (and 0 above the identity). */
bool H2_is_identity_with_lower_triangle;
} of_ldpc_ff_cb_t;
/**
* This function create the codec instance for the LDPC from file codec.
*
* @fn of_status_t of_ldpc_ff_create_codec_instance (of_ldpc_ff_cb_t** of_cb)
* @brief create a LDPC from file codec instance
* @param of_cb (IN/OUT) address of the pointer to a LDPC from file codec control block. This pointer is updated
* by this function.
* In case of success, it points to a session structure allocated by the
* library. In case of failure it points to NULL.
* @return Error status. The ofcb pointer is updated according to the success return
* status.
*/
of_status_t of_ldpc_ff_create_codec_instance (of_ldpc_ff_cb_t** of_cb);
/**
*
* @fn of_status_t of_ldpc_ff_set_fec_parameters (of_ldpc_ff_cb_t* cb, of_ldpc_ff_parameters_t* params)
* @brief set all the FEC codec parameters (e.g. k, n, or symbol size)
* @param cb (IN) Pointer to the control block.
* @param params (IN) pointer to a structure containing the FEC parameters associated to
* a specific FEC codec.
* @return Error status.
*/
of_status_t of_ldpc_ff_set_fec_parameters (of_ldpc_ff_cb_t* cb,
of_ldpc_ff_parameters_t* params);
#ifdef OF_USE_ENCODER
/**
* @fn of_status_t of_ldpc_ff_build_repair_symbol (of_ldpc_ff_cb_t* ofcb, void* encoding_symbols_tab[], UINT32 esi_of_symbol_to_build)
* @brief build a repair symbol (encoder only)
* @param ofcb (IN) Pointer to the session.
* @param encoding_symbols_tab (IN/OUT) table of source and repair symbols.
* The entry for the repair symbol to build can either point
* to a buffer allocated by the application, or let to NULL
* meaning that of_build_repair_symbol will allocate memory.
* @param esi_of_symbol_to_build
* (IN) encoding symbol ID of the repair symbol to build in
* {k..n-1}
* @return Error status.
*/
of_status_t of_ldpc_ff_build_repair_symbol (of_ldpc_ff_cb_t* ofcb,
void* encoding_symbols_tab[],
UINT32 esi_of_symbol_to_build);
#endif //OF_USE_ENCODER
#ifdef OF_USE_DECODER
/**
* @fn of_status_t of_ldpc_ff_set_control_parameter (of_ldpc_ff_cb_t* ofcb,UINT32 type,void* value,UINT32 length)
* @brief set a specific FEC parameter
* @param ofcb (IN) Pointer to the session.
* @param type (IN) Type of parameter. This type is FEC codec ID specific.
* @param value (IN) Pointer to the value of the parameter. The type of the object pointed
* is FEC codec ID specific.
* @return Error status.
*/
of_status_t of_ldpc_ff_set_control_parameter (of_ldpc_ff_cb_t* ofcb,
UINT32 type,
void* value,
UINT32 length);
/**
* @fn of_status_t of_ldpc_ff_get_control_parameter (of_ldpc_ff_cb_t* ofcb,UINT32 type,void* value,UINT32 length)
* @brief get a specific FEC parameter
* @param ses (IN) Pointer to the session.
* @param type (IN) Type of parameter. This type is FEC codec ID specific.
* @param value (IN/OUT) Pointer to the value of the parameter. The type of the object
* pointed is FEC codec ID specific. This function updates the value object
* accordingly. The application, who knows the FEC codec ID, is responsible
* to allocating the approriate object pointed by the value pointer.
* @return Error status.
*/
of_status_t of_ldpc_ff_get_control_parameter (of_ldpc_ff_cb_t* ofcb,
UINT32 type,
void* value,
UINT32 length);
#endif //OF_USE_DECODER
/**
* This function return the number of rows and cols of a matrix read into matrix_file.
*
* @fn of_status_t of_get_pck_matrix_dimensions_from_file(char * matrix_file,UINT32 * n_rows, UINT32 *n_cols)
* @brief return the number of rows and cols of a matrix
* @param matrix_file (IN) name of the file containing the matrix
* @param n_rows (OUT) number of rows in matrix
* @param n_cols (OUT) number of cols in matrix
* @return Error status. If it's OK, nb_row and nb_col contain the number of rows and cols of matrix.
*/
of_status_t of_get_pck_matrix_dimensions_from_file (char* matrix_file,
UINT32 * n_rows,
UINT32 * n_cols);
#endif //OF_LDPC_FF_H
#endif

View File

@@ -0,0 +1,300 @@
/* $Id: of_ldpc_ff_api.c 182 2014-07-15 09:27:51Z roca $ */
/*
* OpenFEC.org AL-FEC Library.
* (c) Copyright 2009 - 2012 INRIA - All rights reserved
* Contact: vincent.roca@inria.fr
*
* This software is governed by the CeCILL-C license under French law and
* abiding by the rules of distribution of free software. You can use,
* modify and/ or redistribute the software under the terms of the CeCILL-C
* license as circulated by CEA, CNRS and INRIA at the following URL
* "http://www.cecill.info".
*
* As a counterpart to the access to the source code and rights to copy,
* modify and redistribute granted by the license, users are provided only
* with a limited warranty and the software's author, the holder of the
* economic rights, and the successive licensors have only limited
* liability.
*
* In this respect, the user's attention is drawn to the risks associated
* with loading, using, modifying and/or developing or reproducing the
* software by the user in light of its specific status of free software,
* that may mean that it is complicated to manipulate, and that also
* therefore means that it is reserved for developers and experienced
* professionals having in-depth computer knowledge. Users are therefore
* encouraged to load and test the software's suitability as regards their
* requirements in conditions enabling the security of their systems and/or
* data to be ensured and, more generally, to use and operate it in the
* same conditions as regards security.
*
* The fact that you are presently reading this means that you have had
* knowledge of the CeCILL-C license and that you accept its terms.
*/
#include "of_ldpc_ff_includes.h"
#ifdef OF_USE_LDPC_FROM_FILE_CODEC
of_status_t of_ldpc_ff_create_codec_instance(of_ldpc_ff_cb_t** of_cb)
{
OF_ENTER_FUNCTION
of_codec_type_t codec_type; /* temporary value */
of_ldpc_ff_cb_t* ff_cb = (of_ldpc_ff_cb_t*) of_realloc(*of_cb, sizeof(of_ldpc_ff_cb_t));
of_ldpc_staircase_cb_t* cb = (of_ldpc_staircase_cb_t*) ff_cb;
*of_cb=ff_cb;
/* realloc does not initialize the additional buffer space, so do that manually,
* then re-initialize a few parameters */
codec_type = cb->codec_type;
memset(cb, 0, sizeof(*cb));
//*of_cb = cb;
cb->codec_id = OF_CODEC_LDPC_FROM_FILE_ADVANCED;
cb->codec_type = codec_type;
cb->max_nb_source_symbols = OF_LDPC_FROM_FILE_MAX_NB_SOURCE_SYMBOLS_DEFAULT; /* init it immediately... */
cb->max_nb_encoding_symbols = OF_LDPC_FROM_FILE_MAX_NB_ENCODING_SYMBOLS_DEFAULT; /* init it immediately... */
OF_EXIT_FUNCTION
return OF_STATUS_OK;
}
of_status_t of_ldpc_ff_set_fec_parameters (of_ldpc_ff_cb_t* cb,
of_ldpc_ff_parameters_t* params)
{
of_mod2entry *e;
UINT32 row;
UINT32 seq;
UINT32 matrix_nb_par;
UINT32 matrix_nb_src;
UINT32 *p_matrix_nb_par;
UINT32 *p_matrix_nb_src;
char * m_matrix_file;
FILE *pFile;
OF_ENTER_FUNCTION
p_matrix_nb_src = &matrix_nb_src;
p_matrix_nb_par = &matrix_nb_par;
#ifdef OF_DEBUG
cb->cb1.stats_xor = of_calloc(1, sizeof(of_symbol_stats_op_t));
#endif
/* open the matrix file */
m_matrix_file= params->pchk_file;
of_ldpc_staircase_cb_t* ofcb = (of_ldpc_staircase_cb_t*) cb;
pFile = fopen (m_matrix_file,"r");
if (pFile == NULL)
{
OF_PRINT_ERROR(("of_ldpc_ff_set_fec_parameters : ERROR, cannot open matrix file %s",m_matrix_file))
goto error;
}
ofcb->pchk_matrix = of_mod2sparse_read_human_readable(pFile, p_matrix_nb_src, p_matrix_nb_par);
fclose(pFile);
if (ofcb->pchk_matrix == NULL)
{
OF_PRINT_ERROR(("of_ldpc_ff_set_fec_parameters : ERROR, parity check matrix can't be created with this parameters.."))
goto error;
}
cb->H2_is_identity_with_lower_triangle = true;
of_mod2sparse_matrix_stats(stdout, ofcb->pchk_matrix, *p_matrix_nb_src, *p_matrix_nb_par);
/* set ofcb attribute specific to from file code*/
if ((ofcb->nb_source_symbols = matrix_nb_src ) > ofcb->max_nb_source_symbols) {
OF_PRINT_ERROR(("of_ldpc_staircase_set_fec_parameters: ERROR, invalid nb_source_symbols parameter (got %d, maximum is %d)",
ofcb->nb_source_symbols, ofcb->max_nb_source_symbols));
goto error;
}
ofcb->nb_repair_symbols =matrix_nb_par;
ofcb->nb_total_symbols = matrix_nb_src + matrix_nb_par;
if (ofcb->nb_total_symbols > ofcb->max_nb_encoding_symbols) {
OF_PRINT_ERROR(("of_ldpc_staircase_set_fec_parameters: ERROR, invalid number of encoding symbols (got %d, maximum is %d)",
ofcb->nb_total_symbols, ofcb->max_nb_encoding_symbols));
goto error;
}
params->nb_source_symbols = ofcb->nb_source_symbols;
params->nb_repair_symbols = ofcb->nb_repair_symbols;
/*set ofcb attribute non-specific to from file code */
ofcb->encoding_symbol_length = params->encoding_symbol_length;
OF_TRACE_LVL (1, ("%s: k=%u, n-k=%u, n=%u, symbol_length=%u, PRNG seed=%u, N1=%u\n", __FUNCTION__,
ofcb->nb_source_symbols, ofcb->nb_repair_symbols, ofcb->nb_total_symbols,
ofcb->encoding_symbol_length, ofcb->prng_seed, ofcb->N1))
#ifdef ML_DECODING
ofcb->pchk_matrix_simplified = NULL;
#endif
if ((ofcb->encoding_symbols_tab = (void**) of_calloc(ofcb->nb_total_symbols, sizeof(void*))) == NULL) {
goto no_mem;
}
#ifdef OF_USE_DECODER
if (ofcb->codec_type & OF_DECODER)
{
ofcb->tab_nb_unknown_symbols = (UINT16*) of_calloc(ofcb->nb_repair_symbols, sizeof(UINT16));
ofcb->tab_const_term_of_equ = (void**) of_calloc(ofcb->nb_repair_symbols, sizeof(void*));
ofcb->tab_nb_equ_for_repair = (UINT16*) of_calloc(ofcb->nb_repair_symbols, sizeof(UINT16));
ofcb->tab_nb_enc_symbols_per_equ = (UINT16*) of_calloc(ofcb->nb_repair_symbols, sizeof(UINT16));
if (ofcb->tab_nb_unknown_symbols == NULL || ofcb->tab_const_term_of_equ == NULL ||
ofcb->tab_nb_equ_for_repair == NULL || ofcb->tab_nb_enc_symbols_per_equ == NULL) {
goto no_mem;
}
// and update the various tables now
for (row = 0; row < ofcb->nb_repair_symbols; row++)
{
for (e = of_mod2sparse_first_in_row (ofcb->pchk_matrix, row);
!of_mod2sparse_at_end (e);
e = of_mod2sparse_next_in_row (e))
{
ofcb->tab_nb_enc_symbols_per_equ[row]++;
ofcb->tab_nb_unknown_symbols[row]++;
}
}
for (seq = ofcb->nb_source_symbols; seq < (ofcb->nb_total_symbols); seq++)
{
for (e = of_mod2sparse_first_in_col (ofcb->pchk_matrix, of_get_symbol_col ((of_cb_t*)ofcb, seq));
!of_mod2sparse_at_end (e);
e = of_mod2sparse_next_in_col (e))
{
ofcb->tab_nb_equ_for_repair[seq - ofcb->nb_source_symbols]++;
}
}
}
#endif //OF_USE_DECODER
ofcb->nb_source_symbol_ready = 0; // Number of source symbols ready
ofcb->nb_repair_symbol_ready = 0; // Number of parity symbols ready
//ofcb->nb_non_dup_symbols_recvd = 0;// Number of non-duplicated symbols received
#ifdef ML_DECODING
ofcb->index_rows = NULL; // Indirection index to access initial m_chekValues array
ofcb->index_cols = NULL; // Indirection index to access initial symbol array
ofcb->remain_cols = 0; // Nb of non empty remaining cols in the future simplified matrix
ofcb->remain_rows = 0; // Nb of non empty remaining rows in the future simplified matrix
ofcb->pchk_matrix_simplified = NULL; // Simplified Parity Check Matrix in sparse mode format
ofcb->original_pchkMatrix = NULL;
ofcb->pchk_matrix_gauss = NULL; // Parity Check matrix in sparse mode format. This matrix
// is also used as a generator matrix in LDGM-* modes
ofcb->dec_step = 0; // Current step in the Gauss Elimination algorithm
ofcb->threshold_simplification = 0; // threshold (number of symbols) above which we
// run the Gauss Elimination algorithm
#endif
OF_EXIT_FUNCTION
return OF_STATUS_OK;
no_mem:
OF_PRINT_ERROR(("out of memory"));
error:
OF_EXIT_FUNCTION
return OF_STATUS_FATAL_ERROR;
}
of_status_t of_ldpc_ff_build_repair_symbol (of_ldpc_ff_cb_t* ofcb,
void* encoding_symbols_tab[],
UINT32 esi_of_symbol_to_build)
{
if (ofcb->H2_is_identity_with_lower_triangle)
{
/* encoding is exactly the same as that of ldpc staircase codes */
return of_ldpc_staircase_build_repair_symbol((of_ldpc_staircase_cb_t*)ofcb, encoding_symbols_tab, esi_of_symbol_to_build);
}
else
{
/* encoding requires to work on the generator matrix */
OF_EXIT_FUNCTION
return OF_STATUS_ERROR;
}
}
of_status_t of_ldpc_ff_set_control_parameter (of_ldpc_ff_cb_t* ofcb,
UINT32 type,
void* value,
UINT32 length)
{
OF_PRINT_ERROR(("of_ldpc_ff_set_control_parameter: ERROR, not implemented...\n"))
return OF_STATUS_ERROR;
}
of_status_t of_ldpc_ff_get_control_parameter (of_ldpc_ff_cb_t* ofcb,
UINT32 type,
void* value,
UINT32 length)
{
of_ldpc_staircase_cb_t *ofcb_staircase;
OF_ENTER_FUNCTION
ofcb_staircase = (of_ldpc_staircase_cb_t*)ofcb;
switch (type) {
case OF_CTRL_GET_MAX_K:
if (value == NULL || length != sizeof(UINT32)) {
OF_PRINT_ERROR(("%s: OF_CTRL_GET_MAX_K ERROR: null value or bad length (got %d, expected %ld)\n",
__FUNCTION__, length, sizeof(UINT32)))
goto error;
}
*(UINT32*)value = ofcb_staircase->max_nb_source_symbols;
OF_TRACE_LVL(1, ("%s: OF_CTRL_GET_MAX_K (%d)\n", __FUNCTION__, *(UINT32*)value))
break;
case OF_CTRL_GET_MAX_N:
if (value == NULL || length != sizeof(UINT32)) {
OF_PRINT_ERROR(("%s: OF_CTRL_GET_MAX_N ERROR: null value or bad length (got %d, expected %ld)\n",
__FUNCTION__, length, sizeof(UINT32)))
goto error;
}
*(UINT32*)value = ofcb_staircase->max_nb_encoding_symbols;
OF_TRACE_LVL(1, ("%s: OF_CTRL_GET_MAX_N (%d)\n", __FUNCTION__, *(UINT32*)value))
break;
default:
OF_PRINT_ERROR(("%s: unknown type (%d)\n", __FUNCTION__, type))
goto error;
}
OF_EXIT_FUNCTION
return OF_STATUS_OK;
error:
OF_EXIT_FUNCTION
return OF_STATUS_ERROR;
}
of_status_t of_get_pck_matrix_dimensions_from_file(char * matrix_file,UINT32 * n_rows, UINT32 *n_cols){
FILE * f;
char * pch;
char line[1024];
f = fopen (matrix_file,"r");
if (f == NULL) {
OF_PRINT_ERROR(("Cannot open file %s\n",matrix_file))
goto error;
}
// get the number of row of the matrix
if (fgets (line, sizeof line, f) != NULL)
{
//size_t i = strspn ( line, " \t\n\v" );
pch = strtok (line, " ");
*n_rows = atoi (pch);
//printf("nrows = %d\n",n_rows);
}
// get the number of columns of the matrix
if (fgets (line, sizeof line, f) != NULL)
{
//size_t i = strspn ( line, " \t\n\v" );
pch = strtok (line, " ");
*n_cols = atoi (pch);
//printf("ncol = %d\n",n_cols);
}
fclose(f);
OF_EXIT_FUNCTION
return OF_STATUS_OK;
error:
OF_EXIT_FUNCTION
return OF_STATUS_ERROR;
}
#endif //OF_USE_LDPC_FROM_FILE_CODEC

View File

@@ -0,0 +1,62 @@
/* $Id: of_ldpc_ff_api.h 89 2012-05-23 15:15:36Z roca $ */
/*
* OpenFEC.org AL-FEC Library.
* (c) Copyright 2009 - 2012 INRIA - All rights reserved
* Contact: vincent.roca@inria.fr
*
* This software is governed by the CeCILL-C license under French law and
* abiding by the rules of distribution of free software. You can use,
* modify and/ or redistribute the software under the terms of the CeCILL-C
* license as circulated by CEA, CNRS and INRIA at the following URL
* "http://www.cecill.info".
*
* As a counterpart to the access to the source code and rights to copy,
* modify and redistribute granted by the license, users are provided only
* with a limited warranty and the software's author, the holder of the
* economic rights, and the successive licensors have only limited
* liability.
*
* In this respect, the user's attention is drawn to the risks associated
* with loading, using, modifying and/or developing or reproducing the
* software by the user in light of its specific status of free software,
* that may mean that it is complicated to manipulate, and that also
* therefore means that it is reserved for developers and experienced
* professionals having in-depth computer knowledge. Users are therefore
* encouraged to load and test the software's suitability as regards their
* requirements in conditions enabling the security of their systems and/or
* data to be ensured and, more generally, to use and operate it in the
* same conditions as regards security.
*
* The fact that you are presently reading this means that you have had
* knowledge of the CeCILL-C license and that you accept its terms.
*/
#ifdef OF_USE_LDPC_FROM_FILE_CODEC
#ifndef OF_CODEC_STABLE_LDPC_FF_API
#define OF_CODEC_STABLE_LDPC_FF_API
#include "../../lib_common/of_types.h"
/**
* @struct of_ldpc_ff_parameters_t
* @brief LDPC from file advanced codec specific FEC parameter structure.
*
* This structure contains the pieces of information required to initialize a codec instance,
* using the of_set_fec_parameters() function.
*/
typedef struct of_ldpc_ff_parameters
{
UINT32 nb_source_symbols; /* must be 1st item */
UINT32 nb_repair_symbols; /* must be 2nd item */
UINT32 encoding_symbol_length; /* must be 3rd item */
/*
* FEC codec id specific attributes follow...
*/
/** Input file containing the binary parity check matrix, of size n-k x n */
char *pchk_file;
} of_ldpc_ff_parameters_t;
#endif /* OF_CODEC_STABLE_LDPC_FF_API */
#endif

View File

@@ -0,0 +1,55 @@
/* $Id: of_ldpc_ff_includes.h 186 2014-07-16 07:17:53Z roca $ */
/*
* OpenFEC.org AL-FEC Library.
* (c) Copyright 2009 - 2012 INRIA - All rights reserved
* Contact: vincent.roca@inria.fr
*
* This software is governed by the CeCILL-C license under French law and
* abiding by the rules of distribution of free software. You can use,
* modify and/ or redistribute the software under the terms of the CeCILL-C
* license as circulated by CEA, CNRS and INRIA at the following URL
* "http://www.cecill.info".
*
* As a counterpart to the access to the source code and rights to copy,
* modify and redistribute granted by the license, users are provided only
* with a limited warranty and the software's author, the holder of the
* economic rights, and the successive licensors have only limited
* liability.
*
* In this respect, the user's attention is drawn to the risks associated
* with loading, using, modifying and/or developing or reproducing the
* software by the user in light of its specific status of free software,
* that may mean that it is complicated to manipulate, and that also
* therefore means that it is reserved for developers and experienced
* professionals having in-depth computer knowledge. Users are therefore
* encouraged to load and test the software's suitability as regards their
* requirements in conditions enabling the security of their systems and/or
* data to be ensured and, more generally, to use and operate it in the
* same conditions as regards security.
*
* The fact that you are presently reading this means that you have had
* knowledge of the CeCILL-C license and that you accept its terms.
*/
#ifndef OF_LDPC_FF_INCLUDES_H
#define OF_LDPC_FF_INCLUDES_H
#include <stdio.h>
#include <string.h>
#include <math.h>
#include <sys/time.h> /* for timersub */
#include "../../lib_common/of_openfec_api.h"
#ifdef OF_USE_LDPC_FROM_FILE_CODEC
#include "../../lib_common/linear_binary_codes_utils/of_linear_binary_code.h"
#include "../../lib_stable/ldpc_staircase/of_ldpc_staircase_api.h"
#include "../../lib_stable/ldpc_staircase/of_ldpc_staircase.h"
#include "of_ldpc_ff_api.h"
#include "of_ldpc_ff.h"
#endif
#endif //OF_LDPC_FF_INCLUDES

View File

@@ -0,0 +1,68 @@
/* $Id: of_ldpc_includes.h 72 2012-04-13 13:27:26Z detchart $ */
/*
* OpenFEC.org AL-FEC Library.
* (c) Copyright 2009 - 2012 INRIA - All rights reserved
* Main authors: Mathieu Cunche (INRIA)
* Jonathan Detchart (INRIA)
* Julien Laboure (INRIA)
* Christoph Neumann (INRIA)
* Vincent Roca (INRIA)
* Contact: vincent.roca@inria.fr
*
* This software is governed by the CeCILL-C license under French law and
* abiding by the rules of distribution of free software. You can use,
* modify and/ or redistribute the software under the terms of the CeCILL-C
* license as circulated by CEA, CNRS and INRIA at the following URL
* "http://www.cecill.info".
*
* As a counterpart to the access to the source code and rights to copy,
* modify and redistribute granted by the license, users are provided only
* with a limited warranty and the software's author, the holder of the
* economic rights, and the successive licensors have only limited
* liability.
*
* In this respect, the user's attention is drawn to the risks associated
* with loading, using, modifying and/or developing or reproducing the
* software by the user in light of its specific status of free software,
* that may mean that it is complicated to manipulate, and that also
* therefore means that it is reserved for developers and experienced
* professionals having in-depth computer knowledge. Users are therefore
* encouraged to load and test the software's suitability as regards their
* requirements in conditions enabling the security of their systems and/or
* data to be ensured and, more generally, to use and operate it in the
* same conditions as regards security.
*
* The fact that you are presently reading this means that you have had
* knowledge of the CeCILL-C license and that you accept its terms.
*/
#ifndef OF_LDPC_INCLUDES
#define OF_LDPC_INCLUDES
#include <stdio.h>
//#include <malloc.h>
#include <math.h>
#include <sys/time.h> /* for timersub */
#include "../../lib_common/of_types.h"
#include "../../lib_common/of_mem.h"
#include "../../lib_common/of_debug.h"
#include "../../lib_common/of_openfec_api.h"
#include "../../lib_common/of_cb.h"
#include "of_rand.h"
#include "of_tools.h"
#include "of_hamming_weight.h"
#include "of_ldpc_staircase.h"
#include "of_matrix_sparse.h"
#include "of_matrix_dense.h"
#include "of_matrix_convert.h"
#include "of_ldpc_staircase_api.h"
#include "of_symbol.h"
#include "of_create_pchk.h"
#include "of_ml_decoding.h"
#include "of_ml_tool.h"
#include "of_ml_tool_2.h"
#endif //OF_LDPC_INCLUDES

View File

@@ -0,0 +1,160 @@
/* $Id: of_hamming_weight.c 186 2014-07-16 07:17:53Z roca $ */
/*
* Source: Wikipedia http://en.wikipedia.org/wiki/Hamming_weight
*
* Creative Commons Attribution-ShareAlike 3.0 Unported License.
*
* You are free:
*
* to Share — to copy, distribute and transmit the work
* to Remix — to adapt the work
*
* Under the following conditions:
*
* Attribution — You must attribute the work in the manner specified by the author or licensor
* (but not in any way that suggests that they endorse you or your use of the work).
* Share Alike — If you alter, transform, or build upon this work, you may distribute the
* resulting work only under the same, similar or a compatible license.
*
* With the understanding that:
*
* Waiver — Any of the above conditions can be waived if you get permission from the copyright holder.
* Public Domain — Where the work or any of its elements is in the public domain under applicable law,
* that status is in no way affected by the license.
* Other Rights — In no way are any of the following rights affected by the license:
* Your fair dealing or fair use rights, or other applicable copyright exceptions and limitations;
* The author's moral rights;
* Rights other persons may have either in the work itself or in how the work is used, such as publicity
* or privacy rights.
* Notice — For any reuse or distribution, you must make clear to others the license terms of this work.
*
* The best way to do this is with a link to this web page: http://creativecommons.org/licenses/by-sa/3.0/
*/
#include "../of_linear_binary_code.h"
#ifdef OF_USE_LINEAR_BINARY_CODES_UTILS
static const UINT64 of_m1 = 0x5555555555555555LL; //binary: 0101...
static const UINT64 of_m2 = 0x3333333333333333LL; //binary: 00110011..
static const UINT64 of_m4 = 0x0f0f0f0f0f0f0f0fLL; //binary: 4 zeros, 4 ones ...
static const UINT64 of_m8 = 0x00ff00ff00ff00ffLL; //binary: 8 zeros, 8 ones ...
static const UINT64 of_m16 = 0x0000ffff0000ffffLL; //binary: 16 zeros, 16 ones ...
static const UINT64 of_m32 = 0x00000000ffffffffLL; //binary: 32 zeros, 32 ones
static const UINT64 of_hff = 0xffffffffffffffffLL; //binary: all ones
static const UINT64 of_h01 = 0x0101010101010101LL; //the sum of 256 to the power of 0,1,2,3...
UINT8 of_hw8table[256] = {0, 1, 1, 2, 1, 2, 2, 3, 1, 2, 2, 3, 2, 3, 3, 4, 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5, 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5, 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5, 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7, 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5, 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7, 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7, 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7, 4, 5, 5, 6, 5, 6, 6, 7, 5, 6, 6, 7, 6, 7, 7, 8};
//This uses fewer arithmetic operations than any other known
//implementation on machines with fast multiplication.
//It uses 12 arithmetic operations, one of which is a multiply.
INT32 of_popcount_3 (UINT64 x)
{
x -= (x >> 1) & of_m1; //put count of each 2 bits into those 2 bits
x = (x & of_m2) + ( (x >> 2) & of_m2); //put count of each 4 bits into those 4 bits
x = (x + (x >> 4)) & of_m4; //put count of each 8 bits into those 8 bits
return (x * of_h01) >> 56; //returns left 8 bits of x + (x<<8) + (x<<16) + (x<<24) + ...
}
UINT32 of_hweight32 (UINT32 w)
{
UINT32 res = w - ( (w >> 1) & 0x55555555);
res = (res & 0x33333333) + ( (res >> 2) & 0x33333333);
res = (res + (res >> 4)) & 0x0F0F0F0F;
res = res + (res >> 8);
return (res + (res >> 16)) & 0x000000FF;
}
UINT8 of_hweight8_table (UINT8 w)
{
//unsigned char res;
//res=of_hw8table[w];
//printf("of_hw8table[%d]=%d\n",w,res);
//return res;
return of_hw8table[w];
}
UINT32 of_hweight32_table (UINT32 w)
{
UINT32 res = 0;
UINT8 *w8 = (UINT8*) (&w);
// for (int j = 0; j<4; j++){
// res+=hweight8_table(w8[j]);
// }
// res=hweight8_table(w8[0])+hweight8_table(w8[1])+hweight8_table(w8[2])+hweight8_table(w8[3]);
res = of_hw8table[w8[0]] + of_hw8table[w8[1]] + of_hw8table[w8[2]] + of_hw8table[w8[3]];
return res;
}
UINT32 of_hweight32_naive (UINT32 w)
{
INT32 j;
UINT32 res = 0;
UINT32 x = w;
for (j = 0; j < sizeof (UINT32); j++)
{
res += x & 1;
x = x >> 1;
}
return res;
}
/* compute the hamming weight of an array containg 32bits words*/
UINT32 of_hweight_array (UINT32 *array, INT32 size)
{
UINT32 weight = 0;
UINT32 i;
UINT32 array_size_32, array_size_32_rem;
UINT32 *v32;
array_size_32 = size >> 5;
array_size_32_rem = size % 32; // Remaining bytes
if (array_size_32_rem > 0)
{
array_size_32++;
}
#if defined (__LP64__) || (__WORDSIZE == 64)
UINT32 array_size64; // Size of array in 64bits unit
UINT32 array_size64rem;
array_size64 = array_size_32 >> 1;
array_size64rem = array_size_32 % 2;
// 64-bit machines
/* First perform as many 64-bit XORs as needed... */
UINT64 *v64 = (UINT64*) array; // to pointer to 64-bit integers
for (i = array_size64; i > 0; i--)
{
weight += of_popcount_3 (*v64);
v64++;
}
/* then perform a 32-bit XOR if needed... */
if (array_size64rem > 0)
{
v32 = (UINT32*) v64; // to pointer to 32-bit integers
weight += of_hweight32_table (*v32);
v32++;
}
#else // 32-bit machines
v32 = (UINT32*) array;
for (i = array_size_32;i > 0;i--)
{
weight += of_hweight32_table (*v32);
v32++;
}
#endif
return weight;
}
#endif //OF_USE_LINEAR_BINARY_CODES_UTILS

View File

@@ -0,0 +1,96 @@
/* $Id: of_hamming_weight.h 186 2014-07-16 07:17:53Z roca $ */
/*
* Source: Wikipedia http://en.wikipedia.org/wiki/Hamming_weight
*
* Creative Commons Attribution-ShareAlike 3.0 Unported License.
*
* You are free:
*
* to Share — to copy, distribute and transmit the work
* to Remix — to adapt the work
*
* Under the following conditions:
*
* Attribution — You must attribute the work in the manner specified by the author or licensor
* (but not in any way that suggests that they endorse you or your use of the work).
* Share Alike — If you alter, transform, or build upon this work, you may distribute the
* resulting work only under the same, similar or a compatible license.
*
* With the understanding that:
*
* Waiver — Any of the above conditions can be waived if you get permission from the copyright holder.
* Public Domain — Where the work or any of its elements is in the public domain under applicable law,
* that status is in no way affected by the license.
* Other Rights — In no way are any of the following rights affected by the license:
* Your fair dealing or fair use rights, or other applicable copyright exceptions and limitations;
* The author's moral rights;
* Rights other persons may have either in the work itself or in how the work is used, such as publicity
* or privacy rights.
* Notice — For any reuse or distribution, you must make clear to others the license terms of this work.
*
* The best way to do this is with a link to this web page: http://creativecommons.org/licenses/by-sa/3.0/
*/
#ifndef HAMMING_WEIGHT_H
#define HAMMING_WEIGHT_H
#ifdef OF_USE_LINEAR_BINARY_CODES_UTILS
/**
* This uses fewer arithmetic operations than any other known
* implementation on machines with fast multiplication.
* It uses 12 arithmetic operations, one of which is a multiply.
*
* @fn INT32 of_popcount_3 (UINT64 x)
* @brief return the number of "1" in a 64 bits word.
* @param x (IN) 64bits word
* @return count of "1" of x
*/
INT32 of_popcount_3 (UINT64 x);
/**
* return the hamming weight of a 32bits word
*
* @fn UINT32 of_hweight32 (UINT32 w)
* @brief return the hamming weight of a 32bits word
* @param w (IN) 32bits word
* @return hamming weight of w
*/
UINT32 of_hweight32 (UINT32 w);
/**
* return the hamming weight of a 32bits word with a naive method
*
* @fn UINT32 of_hweight32_naive (UINT32 w)
* @brief return the hamming weight of a 32bits word
* @param w (IN) 32bits word
* @return hamming weight of w
*/
UINT32 of_hweight32_naive (UINT32 w);
/**
* return the hamming weight of a 32bits word with a corresponding table method
*
* @fn UINT32 of_hweight32_table (UINT32 w)
* @brief return the hamming weight of a 32bits word
* @param w (IN) 32bits word
* @return hamming weight of w
*/
UINT32 of_hweight32_table (UINT32 w);
/**
* return the hamming weight of an array word
*
* @fn UINT32 of_hweight_array (UINT32 *array, INT32 size)
* @brief return the hamming weight of a 32bits word
* @param array (IN) pointer to array
* @param size (IN) size of array
* @return hamming weight of array
*/
UINT32 of_hweight_array (UINT32 *array, INT32 size);
#endif //OF_USE_LINEAR_BINARY_CODES_UTILS
#endif

View File

@@ -0,0 +1,97 @@
/* $Id: of_matrix_convert.c 186 2014-07-16 07:17:53Z roca $ */
/*
* OpenFEC.org AL-FEC Library.
* (c) Copyright 2009 - 2012 INRIA - All rights reserved
* Contact: vincent.roca@inria.fr
*
* This software is governed by the CeCILL-C license under French law and
* abiding by the rules of distribution of free software. You can use,
* modify and/ or redistribute the software under the terms of the CeCILL-C
* license as circulated by CEA, CNRS and INRIA at the following URL
* "http://www.cecill.info".
*
* As a counterpart to the access to the source code and rights to copy,
* modify and redistribute granted by the license, users are provided only
* with a limited warranty and the software's author, the holder of the
* economic rights, and the successive licensors have only limited
* liability.
*
* In this respect, the user's attention is drawn to the risks associated
* with loading, using, modifying and/or developing or reproducing the
* software by the user in light of its specific status of free software,
* that may mean that it is complicated to manipulate, and that also
* therefore means that it is reserved for developers and experienced
* professionals having in-depth computer knowledge. Users are therefore
* encouraged to load and test the software's suitability as regards their
* requirements in conditions enabling the security of their systems and/or
* data to be ensured and, more generally, to use and operate it in the
* same conditions as regards security.
*
* The fact that you are presently reading this means that you have had
* knowledge of the CeCILL-C license and that you accept its terms.
*/
#include "../of_linear_binary_code.h"
#ifdef OF_USE_LINEAR_BINARY_CODES_UTILS
/* CONVERT A MOD2 MATRIX FROM SPARSE TO DENSE FORM. */
void of_mod2sparse_to_dense (of_mod2sparse *m, /* Sparse matrix to convert */
of_mod2dense *r) /* Place to store result */
{
OF_ENTER_FUNCTION
of_mod2entry *e;
UINT32 i;
if (of_mod2sparse_rows (m) > of_mod2dense_rows (r)
|| of_mod2sparse_cols (m) > of_mod2dense_cols (r))
{
OF_PRINT_ERROR(("mod2sparse_to_dense: Dimension of result matrix is less than source\n"))
OF_EXIT_FUNCTION
return;
}
of_mod2dense_clear (r);
for (i = 0; i < of_mod2sparse_rows (m); i++)
{
e = of_mod2sparse_first_in_row (m, i);
while (!of_mod2sparse_at_end (e))
{
of_mod2dense_set (r, i, of_mod2sparse_col (e), 1);
e = of_mod2sparse_next_in_row (e);
}
}
}
/* CONVERT A MOD2 MATRIX FROM DENSE TO SPARSE FORM. */
void of_mod2dense_to_sparse (of_mod2dense *m, /* Dense matrix to convert */
of_mod2sparse *r) /* Place to store result */
{
UINT32 i, j;
if (of_mod2dense_rows (m) > of_mod2sparse_rows (r)
|| of_mod2dense_cols (m) > of_mod2sparse_cols (r))
{
OF_PRINT_ERROR(("mod2dense_to_sparse: Dimension of result matrix is less than source\n"))
OF_EXIT_FUNCTION
return;
}
of_mod2sparse_clear (r);
for (i = 0; i < of_mod2dense_rows (m); i++)
{
for (j = 0; j < of_mod2dense_cols (m); j++)
{
if (of_mod2dense_get (m, i, j))
{
of_mod2sparse_insert (r, i, j);
}
}
}
}
#endif //OF_USE_LINEAR_BINARY_CODES_UTILS

View File

@@ -0,0 +1,45 @@
/* $Id: of_matrix_convert.h 182 2014-07-15 09:27:51Z roca $ */
/* Copyright (c) 1996 by Radford M. Neal
*
* Permission is granted for anyone to copy, use, modify, or distribute this
* program and accompanying programs and documents for any purpose, provided
* this copyright notice is retained and prominently displayed, along with
* a note saying that the original programs are available from Radford Neal's
* web page, and note is made of any changes made to the programs. The
* programs and documents are distributed without any warranty, express or
* implied. As the programs were written for research purposes only, they have
* not been tested to the degree that would be advisable in any important
* application. All use of these programs is entirely at the user's own risk.
*/
#ifndef OF_MATRIX_CONVERT
#define OF_MATRIX_CONVERT
#ifdef OF_USE_LINEAR_BINARY_CODES_UTILS
/**
* @brief convert a sparse matrix to a dense matrix
* @param m (IN) sparse matrix
* @param r (IN) dense matrix
* @return void
*/
void of_mod2sparse_to_dense (of_mod2sparse *m,
of_mod2dense *r);
/**
* @brief convert a dense matrix to a sparse matrix
* @param m (IN) dense matrix
* @param r (IN) sparse matrix
* @return void
*/
void of_mod2dense_to_sparse (of_mod2dense *m,
of_mod2sparse *r);
#endif //OF_USE_LINEAR_BINARY_CODES_UTILS
#endif /* OF_MATRIX_CONVERT */

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,141 @@
/* $Id: of_matrix_dense.h 197 2014-07-16 15:21:56Z roca $ */
/* Copyright (c) 1996, 2000, 2001 by Radford M. Neal
*
* Permission is granted for anyone to copy, use, modify, or distribute this
* program and accompanying programs and documents for any purpose, provided
* this copyright notice is retained and prominently displayed, along with
* a note saying that the original programs are available from Radford Neal's
* web page, and note is made of any changes made to the programs. The
* programs and documents are distributed without any warranty, express or
* implied. As the programs were written for research purposes only, they have
* not been tested to the degree that would be advisable in any important
* application. All use of these programs is entirely at the user's own risk.
*/
/*
* This module implements operations on matrices of mod2 elements (bits,
* with addition and multiplication being done modulo 2). The matrices
* are stored with consecutive bits of a column packed into words, and
* the procedures are implemented where possible using bit operations
* on these words. This is an appropriate representation when the matrices
* are dense (ie, 0s and 1s are about equally frequent).
*
* All procedures in this module display an error message on standard
* error and terminate the program if passed an invalid argument (indicative
* of a programming error), or if memory cannot be allocated. Errors from
* invalid contents of a file result in an error code being returned to the
* caller, with no message being printed by this module.
*/
#ifndef MOD2DENSE_H /* { */
#define MOD2DENSE_H
#ifdef OF_USE_LINEAR_BINARY_CODES_UTILS
/* PACKING OF BITS INTO WORDS. Bits are packed into 32-bit words, with
the low-order bit coming first. */
typedef UINT32 of_mod2word; /* Data type that holds packed bits */
#define of_mod2_wordsize 32 /* Number of bits that fit in a of_mod2word. Can't
be increased without changing intio module */
#define of_mod2_wordsize_shift 5 /* Amount to shift by to divide by wordsize */
#define of_mod2_wordsize_mask 0x1f /* What to and with to produce mod wordsize */
/* Extract the i'th bit of a of_mod2word. */
#define of_mod2_getbit(w,i) (((w)>>(i))&1)
/* Make a word like w, but with the i'th bit set to 1 (if it wasn't already). */
#define of_mod2_setbit1(w,i) ((w)|(1<<(i)))
/* Make a word like w, but with the i'th bit set to 0 (if it wasn't already). */
#define of_mod2_setbit0(w,i) ((w)&(~(1<<(i))))
/* STRUCTURE REPRESENTING A DENSE MATRIX. These structures are dynamically
allocated using mod2dense_allocate (or by other procedures that call
mod2dense_allocate). They should be freed with mod2dense_free when no
longer required.
Direct access to this structure should be avoided except in low-level
routines. Use the macros and procedures defined below instead. */
typedef struct
{
UINT32 n_rows; /* Number of rows in the matrix */
UINT32 n_cols; /* Number of columns in the matrix */
UINT32 n_words; /* Number of words used to store a column of bits */
#ifdef COL_ORIENTED
of_mod2word **col; /* Pointer to array of pointers to columns */
#else
of_mod2word **row; /* Pointer to array of pointers to row */
#endif
of_mod2word *bits; /* Pointer to storage block for bits in this matrix
(pieces of this block are pointed to from col) */
} of_mod2dense;
/* MACROS. */
#define of_mod2dense_rows(m) ((m)->n_rows) /* Get the number of rows or columns */
#define of_mod2dense_cols(m) ((m)->n_cols) /* in a matrix */
/* PROCEDURES. */
of_mod2dense *of_mod2dense_allocate (UINT32, UINT32);
void of_mod2dense_free (of_mod2dense *);
void of_mod2dense_clear (of_mod2dense *);
void of_mod2dense_copy (of_mod2dense *, of_mod2dense *);
void of_mod2dense_copyrows (of_mod2dense*, of_mod2dense *, UINT32 *);
void of_mod2dense_copycols (of_mod2dense*, of_mod2dense *, UINT32 *);
void of_mod2dense_print (FILE *, of_mod2dense *);
UINT32 of_mod2dense_write (FILE *, of_mod2dense *);
of_mod2dense *of_mod2dense_read (FILE *);
UINT32 of_mod2dense_get (of_mod2dense *, UINT32, UINT32);
INT32 of_mod2dense_set (of_mod2dense *, UINT32, UINT32, UINT32);
UINT32 of_mod2dense_flip (of_mod2dense *, UINT32, UINT32);
void of_mod2dense_transpose (of_mod2dense *, of_mod2dense *);
void of_mod2dense_add (of_mod2dense *, of_mod2dense *, of_mod2dense *);
void of_mod2dense_multiply (of_mod2dense *, of_mod2dense *, of_mod2dense *);
UINT32 of_mod2dense_equal (of_mod2dense *, of_mod2dense *);
UINT32 of_mod2dense_invert (of_mod2dense *, of_mod2dense *);
UINT32 of_mod2dense_forcibly_invert (of_mod2dense *, of_mod2dense *, UINT32 *, UINT32 *);
UINT32 of_mod2dense_invert_selected (of_mod2dense *, of_mod2dense *, UINT32 *, UINT32 *);
UINT32 of_mod2dense_triangularize (of_mod2dense *, of_mod2dense *);
void of_mod2dense_print_bitmap (of_mod2dense *, char *); //MC added
void of_mod2dense_print_memory_info (of_mod2dense *); //MC added
double of_mod2dense_density (of_mod2dense *); // MC added
bool of_mod2dense_row_is_empty (of_mod2dense *m, UINT32 row); // VR added
UINT32 of_mod2word_weight (of_mod2word); // MC added
UINT32 of_mod2dense_row_weight (of_mod2dense *, UINT32); // MC added
UINT32 of_mod2dense_row_weight_ignore_first (of_mod2dense *m, UINT32 i, UINT32 nb_ignore);// MC added
UINT32 of_mod2dense_col_weight (of_mod2dense *, UINT32); // MC added
void of_mod2dense_print_stats (FILE *, of_mod2dense *);// MC added
//void of_mod2dense_add_row (of_mod2dense *, UINT32 , UINT32); // MC added
//void of_mod2dense_add_row_ignore_first (of_mod2dense *, UINT32 , UINT32, UINT32); // MC added
void of_mod2dense_xor_rows(of_mod2dense *m, UINT16 from, UINT16 to);
#endif //OF_USE_LINEAR_BINARY_CODES_UTILS
#endif

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,380 @@
/* $Id: of_matrix_sparse.h 197 2014-07-16 15:21:56Z roca $ */
/*
* The contents of this directory and its sub-directories are
* Copyright (c) 1995-2003 by Radford M. Neal
*
* Permission is granted for anyone to copy, use, modify, or distribute these
* programs and accompanying documents for any purpose, provided this copyright
* notice is retained and prominently displayed, along with a note saying
* that the original programs are available from Radford Neal's web page, and
* note is made of any changes made to these programs. These programs and
* documents are distributed without any warranty, express or implied. As the
* programs were written for research purposes only, they have not been tested
* to the degree that would be advisable in any important application. All use
* of these programs is entirely at the user's own risk.
*/
/*
* This module implements operations on sparse matrices of mod2 elements
* (bits, with addition and multiplication being done modulo 2).
*
* All procedures in this module display an error message on standard
* error and terminate the program if passed an invalid argument (indicative
* of a programming error), or if memory cannot be allocated. Errors from
* invalid contents of a file result in an error code being returned to the
* caller, with no message being printed by this module.
*/
/*
* DATA STRUCTURES USED TO STORE A SPARSE MATRIX. Non-zero entries (ie, 1s)
* are represented by nodes that are doubly-linked both by row and by column,
* with the headers for these lists being kept in arrays. Nodes are allocated
* in blocks to reduce time and space overhead. Freed nodes are kept for
* reuse in the same matrix, rather than being freed for other uses, except
* that they are all freed when the matrix is cleared to all zeros by the
* of_mod2sparse_clear procedure, or copied into by of_mod2sparse_copy.
*
* Direct access to these structures should be avoided except in low-level
* routines. Use the macros and procedures defined below instead.
*/
#ifndef OF_LDPC_MATRIX_SPARSE__
#define OF_LDPC_MATRIX_SPARSE__
#ifdef OF_USE_LINEAR_BINARY_CODES_UTILS
//#define SPARSE_MATRIX_OPT_FOR_LDPC_STAIRCASE
/**
* Structure representing a non-zero entry, or the header for a row or column.
*/
typedef struct of_mod2entry
{
/**
* Row and column indexes of this entry, starting at 0, and
* with -1 for a row or column header
*/
#ifdef SPARSE_MATRIX_OPT_SMALL_INDEXES /* memory optimization, see ldpc_profile.h */
currently not used... otherwise remove this line...
INT16 row;
INT16 col;
#else
INT32 row;
INT32 col;
#endif
/**
* Pointers to entries adjacent in row and column, or to headers.
* Free entries are linked by 'left'.
*/
struct of_mod2entry *left,
*right,
*down;
#ifndef SPARSE_MATRIX_OPT_FOR_LDPC_STAIRCASE /* memory optimization */
struct of_mod2entry *up;
#endif
} of_mod2entry;
#define of_mod2sparse_block 1024 /* Number of entries to block together for memory allocation */
/*
* Block of entries allocated all at once.
*/
typedef struct of_mod2block
{
/** Next block that has been allocated. */
struct of_mod2block *next;
/** Entries in this block. */
of_mod2entry entry[of_mod2sparse_block];
} of_mod2block;
/**
* Representation of a sparse matrix.
*/
typedef struct of_mod2sparse
{
INT32 n_rows; /* Number of rows in the matrix */
INT32 n_cols; /* Number of columns in the matrix */
of_mod2entry *rows; /* Pointer to array of row headers */
of_mod2entry *cols; /* Pointer to array of column headers */
of_mod2block *blocks; /* Blocks that have been allocated */
of_mod2entry *next_free; /* Next free entry */
#ifdef LDPC_QC
INT32 exp_factor; /* expansion factor of the matrix, it is also the size of the circulant matrix */
#endif
} of_mod2sparse;
/* MACROS TO GET AT ELEMENTS OF A SPARSE MATRIX. The 'first', 'last', 'next',
and 'prev' macros traverse the elements in a row or column. Moving past
the first/last element gets one to a header element, which can be identified
using the 'at_end' macro. Macros also exist for finding out the row
and column of an entry, and for finding out the dimensions of a matrix. */
#define of_mod2sparse_first_in_row(m,i) ((m)->rows[i].right) /* Find the first */
#define of_mod2sparse_first_in_col(m,j) ((m)->cols[j].down) /* or last entry in */
#define of_mod2sparse_last_in_row(m,i) ((m)->rows[i].left) /* a row or column */
#ifndef SPARSE_MATRIX_OPT_FOR_LDPC_STAIRCASE
#define of_mod2sparse_last_in_col(m,j) ((m)->cols[j].up)
#else
of_mod2entry * of_mod2sparse_last_in_col (of_mod2sparse * m, UINT32 i); /* a bit more complex if we don't have the "up" pointer */
#endif
#define of_mod2sparse_next_in_row(e) ((e)->right) /* Move from one entry to */
#define of_mod2sparse_next_in_col(e) ((e)->down) /* another in any of the three */
#define of_mod2sparse_prev_in_row(e) ((e)->left) /* possible directions */
#ifndef SPARSE_MATRIX_OPT_FOR_LDPC_STAIRCASE
#define of_mod2sparse_prev_in_col(e) ((e)->up)
#endif
#define of_mod2sparse_at_end_col(e) ((e)->col < 0) /* See if we've reached the end of column */
#define of_mod2sparse_at_end_row(e) ((e)->row < 0) /* See if we've reached the end of row */
#define of_mod2sparse_at_end(e) ((e)->row < 0) /* See if we've reached the end of row */
#define of_mod2sparse_row(e) ((e)->row) /* Find out the row or column index */
#define of_mod2sparse_col(e) ((e)->col) /* of an entry (indexes start at 0) */
#define of_mod2sparse_rows(m) ((m)->n_rows) /* Get the number of rows or columns*/
#define of_mod2sparse_cols(m) ((m)->n_cols) /* in a matrix */
#if 0
/* POSSIBLE LU DECOMPOSITION STRATEGIES. For use with mod2sparse_decomp. */
typedef enum mod2sparse_strategy_enum
{ Mod2sparse_first,
Mod2sparse_mincol,
Mod2sparse_minprod
} mod2sparse_strategy;
#endif // #if 0
/* PROCEDURES TO MANIPULATE SPARSE MATRICES. */
of_mod2sparse *of_mod2sparse_allocate (UINT32, UINT32);
void of_mod2sparse_free (of_mod2sparse *);
void of_mod2sparse_clear (of_mod2sparse *);
//#if 0
void of_mod2sparse_copy (of_mod2sparse *, of_mod2sparse *);
//#endif // #if 0
#if defined(ML_DECODING)
void of_mod2sparse_copyrows (of_mod2sparse *, of_mod2sparse *, UINT32 *);
void of_mod2sparse_copycols (of_mod2sparse *, of_mod2sparse *, UINT32 *);
/**
* Copy a list of rows from one matrix to another.
*
* @param m (IN) Matrix to print out (only 0 and 1)
* @param r (OUT) Resulting matrix
* @param rows (IN) List of rows to copy
* @param __parsing (IN) Optimization for the insertion of new elements,
* avoid parsing again all the element in a cal before
* finding the good position
*/
void of_mod2sparse_copyrows_opt (of_mod2sparse * m,
of_mod2sparse * r,
UINT32 * rows,
of_mod2entry ** __parsing);
/**
* Copy a list of columns from one matrix to another.
*
* @param m (IN) Matrix to print out (only 0 and 1)
* @param r (OUT) Resulting matrix
* @param cols (IN) List of cols to copy
*/
void of_mod2sparse_copycols_opt (of_mod2sparse * m,
of_mod2sparse * r,
UINT32 * cols);
#endif // #if defined(ML_DECODING)
/**
* Print out a matrix in a file, print only 0 and 1
*
* @param fout (IN) The stream to write in
* @param m (IN) Matrix to print out (only 0 and 1)
*/
void of_mod2sparse_printf (FILE * fout, of_mod2sparse * m);
void of_mod2sparse_print (FILE *, of_mod2sparse *);
void of_mod2sparse_print_bitmap (of_mod2sparse *m);
#if 0
UINT32 mod2sparse_write (FILE *, of_mod2sparse *);
of_mod2sparse *mod2sparse_read (FILE *);
#endif // #if 0
UINT32 of_mod2sparse_write_human_readable (FILE *,
of_mod2sparse *,
UINT32 nb_source,
UINT32 nb_parity);
of_mod2sparse *of_mod2sparse_read_human_readable (FILE *f,
UINT32 *nb_source,
UINT32 *nb_parity);
/* PRINT matrix statistics: average number of 1's per row/line etc ...*/
void of_mod2sparse_matrix_stats (FILE *,
of_mod2sparse *,
UINT32 nb_src,
UINT32 nb_par);
of_mod2entry *of_mod2sparse_find (of_mod2sparse *,
UINT32,
UINT32);
of_mod2entry *of_mod2sparse_insert (of_mod2sparse *,
UINT32,
UINT32);
void of_mod2sparse_delete (of_mod2sparse *,
of_mod2entry *);
#if defined(ML_DECODING)
/**
* Swap row0 and row1 of the matrix m, using an additional matrix (either allocated or not).
* The two additional parameters optimize the parsing of the matrix.
*
* @param m (IN/OUT) The matrix which hold the two lines
* @param row0 (IN) First line to be swapped
* @param row1 (IN) Second line to be swapped
* @param __swapMatrix (IN) Additional matrix used to store
* one of the line to be swapped.
* if NULL, the additionnal matrix is created and
* freed by the function
* @param __links (IN/OUT) Used to minimised the parsing of the matrix on insertion of
* one element in the row row0. The gauss pivoting method parses
* the matrix from up to bottom, __links keeps the last element
* before row0 in the matrix (optimization for gauss pivoting)
* @param __parsing (IN/OUT) Optimization for Gauss pivoting in the XOR steps. Gauss pivoting
* parses from up to bottom to XOR lines and then eliminates simplifies
* the matrix. At the end of swapping, __parsing is initialyzed.
*
* @return The hamming weight of the new row0 line
*/
UINT32 of_mod2sparse_swap_rows (of_mod2sparse * m,
UINT32 row0,
UINT32 row1,
of_mod2sparse * __swapMatrix,
of_mod2entry ** __links,
of_mod2entry ** __parsing);
/**
* XOR two lines of the matrix m: row1 = row0 + row1.
*
* @param m (IN/OUT) The matrix which hold the two lines
* @param row0 (IN) First line to be XORed
* @param row1 (IN) Second line to be XORed
* @param __links (IN/OUT) Used to minimised the parsing of the matrix on insertion of
* one element in the row row0. The gauss pivoting method parses
* the matrix from up to bottom, __links keeps the last element
* before row0 in the matrix (optimization for gauss pivoting)
* @param __parsing (IN/OUT) Optimization for Gauss pivoting in the XOR steps. Gauss pivoting
* parses from up to bottom to XOR lines and then eliminates simplifies
* the matrix. At the end of swapping, __parsing is initialyzed.
*
* @return The hamming weight of the new row1 line
*/
UINT32 of_mod2sparse_xor_rows (of_mod2sparse * m,
UINT32 row0, UINT32 row1,
of_mod2entry ** __links,
of_mod2entry ** __parsing);
/**
* Determine if a row is empty
*
* @param m (IN/OUT) The matrix which hold the row
* @param row (IN) The row to check
*
* @return TRUE if the row is empty, else FALSE
*/
bool of_mod2sparse_empty_row (of_mod2sparse * m, UINT32 row);
/**
* Determine if a col is empty
*
* @param m (IN/OUT) The matrix which hold the col
* @param col (IN) The col to check
*
* @return TRUE if the row is empty, else FALSE
*/
bool of_mod2sparse_empty_col (of_mod2sparse * m, UINT32 col);
/**
* Count the number of 1 in a row
*
* @param m (IN/OUT) The matrix which the row
* @param row (IN) The row to check
*
* @return The weight of the row
*/
UINT32 of_mod2sparse_weight_row (of_mod2sparse * m, UINT32 row);
#if 0
/**
* Count the number of 1 in a col
*
* @param m (IN/OUT) The matrix which the row
* @param col (IN) The col to check
*
* @return The weight of the col
*/
UINT32 mod2sparse_weight_col (of_mod2sparse * m, UINT32 col);
#endif
#endif // defined(ML_DECODING)
#if 0
void mod2sparse_transpose (of_mod2sparse *, of_mod2sparse *);
void mod2sparse_add (of_mod2sparse *, of_mod2sparse *, of_mod2sparse *);
void mod2sparse_multiply (of_mod2sparse *, of_mod2sparse *, of_mod2sparse *);
void mod2sparse_mulvec (of_mod2sparse *, UINT8 *, UINT8 *);
UINT32 mod2sparse_equal (of_mod2sparse *, of_mod2sparse *);
UINT32 mod2sparse_count_row (of_mod2sparse *, UINT32);
UINT32 mod2sparse_count_col (of_mod2sparse *, UINT32);
void mod2sparse_add_row (of_mod2sparse *, UINT32, of_mod2sparse *, UINT32);
void mod2sparse_add_col (of_mod2sparse *, UINT32, of_mod2sparse *, UINT32);
UINT32 mod2sparse_decomp (of_mod2sparse *, UINT32, of_mod2sparse *, of_mod2sparse *,
UINT32 *, UINT32 *, mod2sparse_strategy,UINT32, UINT32);
UINT32 mod2sparse_forward_sub (of_mod2sparse *, UINT32 *, UINT8 *, UINT8 *);
UINT32 mod2sparse_backward_sub (of_mod2sparse *, UINT32 *, UINT8 *, UINT8 *);
#endif
/* copy only filled rows and cols from m to r */
void of_mod2sparse_copy_filled_matrix (of_mod2sparse *m,
of_mod2sparse *r,
UINT32 *index_rows,
UINT32 *index_cols);
#endif /* #ifndef OF_LDPC_MATRIX_SPARSE__ */
#endif //OF_USE_LINEAR_BINARY_CODES_UTILS

View File

@@ -0,0 +1,146 @@
/* $Id: of_tools.c 182 2014-07-15 09:27:51Z roca $ */
/*
* The contents of this directory and its sub-directories are
* Copyright (c) 1995-2003 by Radford M. Neal
*
* Permission is granted for anyone to copy, use, modify, or distribute these
* programs and accompanying documents for any purpose, provided this copyright
* notice is retained and prominently displayed, along with a note saying
* that the original programs are available from Radford Neal's web page, and
* note is made of any changes made to these programs. These programs and
* documents are distributed without any warranty, express or implied. As the
* programs were written for research purposes only, they have not been tested
* to the degree that would be advisable in any important application. All use
* of these programs is entirely at the user's own risk.
*/
/* This module implements operations on sparse matrices of mod2 elements
(bits, with addition and multiplication being done modulo 2).
All procedures in this module display an error message on standard
error and terminate the program if passed an invalid argument (indicative
of a programming error), or if memory cannot be allocated. Errors from
invalid contents of a file result in an error code being returned to the
caller, with no message being printed by this module.
*/
/* DATA STRUCTURES USED TO STORE A SPARSE MATRIX. Non-zero entries (ie, 1s)
are represented by nodes that are doubly-linked both by row and by column,
with the headers for these lists being kept in arrays. Nodes are allocated
in blocks to reduce time and space overhead. Freed nodes are kept for
reuse in the same matrix, rather than being freed for other uses, except
that they are all freed when the matrix is cleared to all zeros by the
of_mod2sparse_clear procedure, or copied into by of_mod2sparse_copy.
Direct access to these structures should be avoided except in low-level
routines. Use the macros and procedures defined below instead. */
#include "../of_linear_binary_code.h"
#ifdef OF_USE_LINEAR_BINARY_CODES_UTILS
/* ALLOCATE SPACE AND CHECK FOR ERROR. Calls 'calloc' to allocate space,
and then displays an error message and exits if the space couldn't be
found. */
void *of_chk_alloc (UINT32 n, /* Number of elements */
UINT32 size) /* Size of each element */
{
void *p;
OF_ENTER_FUNCTION
p = of_calloc (n, size);
if (p == NULL)
{
fprintf (stderr, "Ran out of memory (while trying to allocate %d bytes)\n", n*size);
OF_EXIT_FUNCTION
return NULL;
}
OF_EXIT_FUNCTION
return p;
}
#if 1
/* READ AN INTEGER ONE BYTE AT A TIME. Four bytes are read, ordered from
low to high order. These are considered to represent a signed integer,
in two's complement form. The value returned is this integer, converted
to whatever a C "int" is. The conversion should work as long as an "int"
is at least four bytes, even if it's not in two's complement representation
(except for the largest two's complement negative integer).
If an error or eof is encountered, zero is returned. The caller can
check for these events using feof and ferror.
The file read from should have been opened as "binary".
*/
INT32 of_intio_read (FILE *f) /* File to read from */
{
UINT8 b[4];
INT32 top;
INT32 i;
OF_ENTER_FUNCTION
for (i = 0; i < 4; i++)
{
if (fread (&b[i], 1, 1, f) != 1)
{
OF_EXIT_FUNCTION
return 0;
}
}
top = b[3] > 127 ? (INT32) b[3] - 256 : b[3];
OF_EXIT_FUNCTION
return (top << 24) + (b[2] << 16) + (b[1] << 8) + b[0];
}
/* WRITE AN INTEGER ONE BYTE AT A TIME. Four bytes are written, ordered from
low to high order. These are considered to represent a signed integer,
in two's complement form. This should work as long as the integer passed
can be represented in four bytes, even if a C "int" is longer than this.
The file written to should have been opened as "binary".
*/
void of_intio_write (FILE *f, /* File to write to */
INT32 v) /* Value to write to file */
{
UINT8 b;
INT32 i;
OF_ENTER_FUNCTION
for (i = 0; i < 3; i++)
{
b = v & 0xff;
fwrite (&b, 1, 1, f);
v >>= 8;
}
b = v > 0 ? v : v + 256;
fwrite (&b, 1, 1, f);
OF_EXIT_FUNCTION
}
#endif
void of_print_composition (char* symbol, UINT32 size)
{
UINT32 i;
OF_ENTER_FUNCTION
for (i = 0;i < size;i++)
{
if (symbol[i] != 0)
{
printf ("%d ", i);
}
}
printf ("\n");
OF_EXIT_FUNCTION
}
#endif //OF_USE_LINEAR_BINARY_CODES_UTILS

View File

@@ -0,0 +1,72 @@
/* $Id: of_tools.h 186 2014-07-16 07:17:53Z roca $ */
/*
* The contents of this directory and its sub-directories are
* Copyright (c) 1995-2003 by Radford M. Neal
*
* Permission is granted for anyone to copy, use, modify, or distribute these
* programs and accompanying documents for any purpose, provided this copyright
* notice is retained and prominently displayed, along with a note saying
* that the original programs are available from Radford Neal's web page, and
* note is made of any changes made to these programs. These programs and
* documents are distributed without any warranty, express or implied. As the
* programs were written for research purposes only, they have not been tested
* to the degree that would be advisable in any important application. All use
* of these programs is entirely at the user's own risk.
*/
/* This module implements operations on sparse matrices of mod2 elements
(bits, with addition and multiplication being done modulo 2).
All procedures in this module display an error message on standard
error and terminate the program if passed an invalid argument (indicative
of a programming error), or if memory cannot be allocated. Errors from
invalid contents of a file result in an error code being returned to the
caller, with no message being printed by this module.
*/
/* DATA STRUCTURES USED TO STORE A SPARSE MATRIX. Non-zero entries (ie, 1s)
are represented by nodes that are doubly-linked both by row and by column,
with the headers for these lists being kept in arrays. Nodes are allocated
in blocks to reduce time and space overhead. Freed nodes are kept for
reuse in the same matrix, rather than being freed for other uses, except
that they are all freed when the matrix is cleared to all zeros by the
of_mod2sparse_clear procedure, or copied into by of_mod2sparse_copy.
Direct access to these structures should be avoided except in low-level
routines. Use the macros and procedures defined below instead. */
#ifndef TOOLS_H__
#define TOOLS_H__
#ifdef OF_USE_LINEAR_BINARY_CODES_UTILS
/**
* Call calloc and exits with an error if it fails
*/
void * of_chk_alloc (UINT32 n,
UINT32 size);
/**
*/
void of_print_composition (char* symbol,
UINT32 size);
/**
* Read an integer
*/
INT32 of_intio_read (FILE *);
/**
* Write an integer
*/
void of_intio_write (FILE *, INT32);
#endif //OF_USE_LINEAR_BINARY_CODES_UTILS
#endif

View File

@@ -0,0 +1,348 @@
/* $Id: of_it_decoding.c 217 2014-12-13 13:55:01Z roca $ */
/*
* OpenFEC.org AL-FEC Library.
* (c) Copyright 2009 - 2012 INRIA - All rights reserved
* Contact: vincent.roca@inria.fr
*
* This software is governed by the CeCILL-C license under French law and
* abiding by the rules of distribution of free software. You can use,
* modify and/ or redistribute the software under the terms of the CeCILL-C
* license as circulated by CEA, CNRS and INRIA at the following URL
* "http://www.cecill.info".
*
* As a counterpart to the access to the source code and rights to copy,
* modify and redistribute granted by the license, users are provided only
* with a limited warranty and the software's author, the holder of the
* economic rights, and the successive licensors have only limited
* liability.
*
* In this respect, the user's attention is drawn to the risks associated
* with loading, using, modifying and/or developing or reproducing the
* software by the user in light of its specific status of free software,
* that may mean that it is complicated to manipulate, and that also
* therefore means that it is reserved for developers and experienced
* professionals having in-depth computer knowledge. Users are therefore
* encouraged to load and test the software's suitability as regards their
* requirements in conditions enabling the security of their systems and/or
* data to be ensured and, more generally, to use and operate it in the
* same conditions as regards security.
*
* The fact that you are presently reading this means that you have had
* knowledge of the CeCILL-C license and that you accept its terms.
*/
#include "../of_linear_binary_code.h"
#ifdef OF_USE_DECODER
#ifdef OF_USE_LINEAR_BINARY_CODES_UTILS
of_status_t of_linear_binary_code_decode_with_new_symbol (of_linear_binary_code_cb_t* ofcb,
void* new_symbol,
UINT32 new_symbol_esi)
{
of_mod2entry *e = NULL; // entry ("1") in parity check matrix
of_mod2entry *mod_entry_to_delete; // temp: entry to delete in row/column
void *const_term; // temp: pointer to constant term, containing the sum of
// all the known symbols of this equation
UINT32 row; // temp: current row value
UINT32 *table_of_check_deg_1 = NULL; // table of check nodes of degree
// one after the processing of new_symbol
INT32 table_of_check_deg_1_nb = 0; // number of entries in table
UINT32 size_of_table_of_check_deg_1 = 0; // size of the memory block
UINT32 decoded_symbol_esi; // sequence number of decoded symbol
OF_ENTER_FUNCTION
ASSERT(ofcb);
ASSERT(new_symbol);
ASSERT(new_symbol_esi < ofcb->nb_total_symbols);
/*
* Step 0: check if this is a fresh symbol, otherwise return
*/
if (ofcb->encoding_symbols_tab[new_symbol_esi] != NULL)
{
OF_TRACE_LVL (1, ("%s: %s symbol (esi=%d) already received or rebuilt, ignored.\n", __FUNCTION__,
(of_is_source_symbol ((of_cb_t*)ofcb, new_symbol_esi)) ? "source" : "parity", new_symbol_esi))
#ifdef OF_DEBUG
if (of_is_source_symbol ((of_cb_t*)ofcb, new_symbol_esi))
ofcb->stats_symbols->nb_source_symbols_ignored++;
else
ofcb->stats_symbols->nb_repair_symbols_ignored++;
#endif
OF_EXIT_FUNCTION
return OF_STATUS_OK;
}
//of_mod2sparse_print_bitmap(ofcb->pchk_matrix);
/*
* Step 1: Store the symbol in a permanent array.
*/
if (of_is_source_symbol ((of_cb_t*)ofcb, new_symbol_esi))
{
ofcb->nb_source_symbol_ready++;
#ifdef OF_DEBUG
ofcb->stats_symbols->nb_source_symbols_received++;
#endif
ofcb->encoding_symbols_tab[new_symbol_esi] = new_symbol;
if (of_is_decoding_complete ((of_session_t*)ofcb))
{
OF_TRACE_LVL (1, ("%s: decoding finished\n", __FUNCTION__))
OF_EXIT_FUNCTION
return OF_STATUS_OK;
}
}
else
{
ofcb->nb_repair_symbol_ready++;
#ifdef OF_DEBUG
ofcb->stats_symbols->nb_repair_symbols_received++;
#endif
// in ML decoding, we need to store all parity symbols, whereas with pure IT
// decoding this is not necessary.
if ((ofcb->encoding_symbols_tab[new_symbol_esi] = (void *)
of_malloc (ofcb->encoding_symbol_length)) == NULL)
{
goto no_mem;
}
// copy the content...
memcpy (ofcb->encoding_symbols_tab[new_symbol_esi], new_symbol, ofcb->encoding_symbol_length);
}
OF_TRACE_LVL (1, ("%s: new %s symbol (esi=%d), total of %d/%d source/repair symbols ready\n",
__FUNCTION__, (of_is_source_symbol ((of_cb_t*)ofcb, new_symbol_esi)) ? "source" : "parity",
new_symbol_esi, ofcb->nb_source_symbol_ready, ofcb->nb_repair_symbol_ready))
/*
* Step 2: Inject the symbol value in each equation it is involved
*/
// (if partial sum already exists or if partial sum should be created)
for (e = of_mod2sparse_first_in_col (ofcb->pchk_matrix, of_get_symbol_col ((of_cb_t*)ofcb, new_symbol_esi)); !of_mod2sparse_at_end_col (e); )
{
// for a given row, ie for a given equation where this symbol
// is implicated, do the following:
row = e->row;
ofcb->tab_nb_unknown_symbols[row]--; // symbol is known
const_term = ofcb->tab_const_term_of_equ[row]; // associated partial sum buffer (if any)
if ((const_term == NULL) && ((ofcb->tab_nb_unknown_symbols[row] == 1)))
{
// we need to allocate a partial sum (i.e. check node)
// and add the symbol to it, because it is the
// last missing symbol of this equation.
const_term = (void*) of_calloc (1, ofcb->encoding_symbol_length);
if ((ofcb->tab_const_term_of_equ[row] = const_term) == NULL)
{
goto no_mem;
}
}
if (const_term != NULL)
{
mod_entry_to_delete = e;
of_mod2entry *tmp_e; // current symbol in this equation
UINT32 tmp_esi; // corresponding esi
void *tmp_symbol; // corresponding symbol pointer
// there's a partial sum for this row...
if (ofcb->tab_nb_enc_symbols_per_equ[row] > 1)
{
//ofcb->tmp_tab_symbols[ofcb->nb_tmp_symbols++] = new_symbol;
// we can add the symbol content to this constant term
of_add_to_symbol (const_term, new_symbol, ofcb->encoding_symbol_length
#ifdef OF_DEBUG
, &(ofcb->stats_xor->nb_xor_for_IT)
#endif
);
}
// else this is useless, since new_symbol is the last
// symbol of this equation, and its value is necessarilly
// equal to the constant term. Their sum must be 0 (we don't check it).
// Remove the symbol from the equation since this entry is now useless.
e = of_mod2sparse_next_in_col (e);
of_mod2sparse_delete (ofcb->pchk_matrix, mod_entry_to_delete);
ofcb->tab_nb_enc_symbols_per_equ[row]--;
if (of_is_repair_symbol ((of_cb_t*)ofcb, new_symbol_esi))
{
ofcb->tab_nb_equ_for_repair[new_symbol_esi - ofcb->nb_source_symbols]--;
}
// Inject all permanently stored symbols
// (source and repair) into this partial sum.
// Requires to scan the equation (i.e. row).
for (tmp_e = of_mod2sparse_first_in_row (ofcb->pchk_matrix, row); !of_mod2sparse_at_end_row (tmp_e); )
{
tmp_esi = of_get_symbol_esi ((of_cb_t*)ofcb, tmp_e->col);
tmp_symbol = ofcb->encoding_symbols_tab[tmp_esi];
if (tmp_symbol != NULL)
{
// add the symbol content now
of_add_to_symbol (const_term, tmp_symbol, ofcb->encoding_symbol_length
#ifdef OF_DEBUG
, &(ofcb->stats_xor->nb_xor_for_IT)
#endif
);
// delete the entry
mod_entry_to_delete = tmp_e;
tmp_e = of_mod2sparse_next_in_row (tmp_e);
of_mod2sparse_delete (ofcb->pchk_matrix, mod_entry_to_delete);
ofcb->tab_nb_enc_symbols_per_equ[row]--;
if (of_is_repair_symbol ((of_cb_t*)ofcb, tmp_esi))
{
ofcb->tab_nb_equ_for_repair[tmp_esi - ofcb->nb_source_symbols]--;
#ifndef ML_DECODING
// we can delete parity symbol altogether if in IT decoding only,
// if ML decoding is needed, then keep the repair symbol
if (ofcb->tab_nb_equ_for_repair[tmp_esi - ofcb->nb_source_symbols] == 0)
{
of_free (tmp_symbol);
ofcb->encoding_symbols_tab[tmp_esi] = NULL;
}
#endif
}
}
else
{
// this symbol is not yet known, switch to next one in equation
tmp_e = of_mod2sparse_next_in_row (tmp_e);
}
}
}
else
{
// here m_checkValues[row] is NULL, ie. the partial
// sum has not been allocated
e = of_mod2sparse_next_in_col (e);
}
if (ofcb->tab_nb_enc_symbols_per_equ[row] == 1)
{
// register this entry for step 3 since the symbol
// associated to this equation can now be decoded...
if (table_of_check_deg_1 == NULL)
{
// allocate memory for the table first
size_of_table_of_check_deg_1 = 4;
if ((table_of_check_deg_1 = (UINT32*) of_calloc (size_of_table_of_check_deg_1, sizeof (UINT32*))) == NULL)
{
goto no_mem;
}
}
else if (table_of_check_deg_1_nb == size_of_table_of_check_deg_1)
{
// not enough size in table, add some more
size_of_table_of_check_deg_1 += 4;
if ((table_of_check_deg_1 = (UINT32*) of_realloc (table_of_check_deg_1, size_of_table_of_check_deg_1 * sizeof (UINT32*))) == NULL)
{
goto no_mem;
}
}
table_of_check_deg_1[table_of_check_deg_1_nb++] = row;
}
}
/*
* Step 3: Check if a new symbol has been decoded and take appropriate measures ...
*/
for (table_of_check_deg_1_nb--; table_of_check_deg_1_nb >= 0; table_of_check_deg_1_nb--)
{
if (of_is_decoding_complete ((of_session_t*)ofcb))
{
/* decoding has just finished, no need to do anything else.
* Stop this decoding loop and return immediately. */
break;
}
// get the index (ie row) of the partial sum concerned
row = table_of_check_deg_1[table_of_check_deg_1_nb];
if (ofcb->tab_nb_enc_symbols_per_equ[row] == 1)
{
// A new decoded symbol is available...
// NB: because of the recursion below, we need to
// check that all equations mentioned in the
// table_of_check_deg_1 list are __still__ of degree 1.
e = of_mod2sparse_first_in_row (ofcb->pchk_matrix, row);
ASSERT (!of_mod2sparse_at_end_row (e) && of_mod2sparse_at_end_row (e->right))
decoded_symbol_esi = of_get_symbol_esi ((of_cb_t*)ofcb, e->col);
// remove the entry from the matrix
const_term = ofcb->tab_const_term_of_equ[row]; // remember it
ofcb->tab_const_term_of_equ[row] = NULL;
ofcb->tab_nb_enc_symbols_per_equ[row]--;
if (of_is_repair_symbol ((of_cb_t*)ofcb, decoded_symbol_esi))
{
ofcb->tab_nb_equ_for_repair[decoded_symbol_esi - ofcb->nb_source_symbols]--;
}
of_mod2sparse_delete (ofcb->pchk_matrix, e);
OF_TRACE_LVL (1, ("%s: REBUILT %s symbol %d\n", __FUNCTION__,
(of_is_repair_symbol ((of_cb_t*)ofcb, decoded_symbol_esi)) ? "Parity" : "Source",
decoded_symbol_esi));
if (of_is_source_symbol ((of_cb_t*)ofcb, decoded_symbol_esi))
{
// source symbol.
void *decoded_symbol_dst; // temp variable used to store symbol
#ifdef OF_DEBUG
ofcb->stats_symbols->nb_source_symbols_built_with_it++;
ofcb->stats_symbols->nb_source_symbols_received--;
#endif
// First copy it into a permanent buffer.
if (ofcb->decoded_source_symbol_callback != NULL)
{
// Call the associated callback (that allocates a buffer) and then
// copy the symbol content in it.
if ((decoded_symbol_dst = ofcb->decoded_source_symbol_callback(
ofcb->context_4_callback,
ofcb->encoding_symbol_length,
decoded_symbol_esi)) != NULL)
{
// if the application has allocated a buffer, copy the symbol into it.
memcpy (decoded_symbol_dst, const_term, ofcb->encoding_symbol_length);
// we don't need the const_term buffer any more, so free it.
of_free (const_term);
}
else
{
// else reuse the const_term buffer in order to save extra malloc/memcpy.
decoded_symbol_dst = const_term;
}
}
else
{
// else reuse the const_term buffer in order to save extra malloc/memcpy.
decoded_symbol_dst = const_term;
}
// And finally call this function recursively
of_linear_binary_code_decode_with_new_symbol (ofcb, decoded_symbol_dst, decoded_symbol_esi);
}
else
{
#ifdef OF_DEBUG
ofcb->stats_symbols->nb_repair_symbols_built_with_it++;
ofcb->stats_symbols->nb_repair_symbols_received--;
#endif
// Parity symbol.
if (ofcb->decoded_repair_symbol_callback != NULL)
{
ofcb->decoded_repair_symbol_callback (ofcb->context_4_callback,
ofcb->encoding_symbol_length,
decoded_symbol_esi);
}
// Call this function recursively first...
of_linear_binary_code_decode_with_new_symbol (ofcb, const_term, decoded_symbol_esi);
// ...then free the partial sum which is no longer needed.
of_free (const_term);
}
}
}
if (table_of_check_deg_1 != NULL)
{
of_free (table_of_check_deg_1);
}
//OF_TRACE_LVL(1,("max:%u,cur:%u\n",ofcb->stats->maximum_mem,ofcb->stats->current_mem))
OF_EXIT_FUNCTION
return OF_STATUS_OK;
no_mem:
OF_PRINT_ERROR(("out of memory\n"));
OF_EXIT_FUNCTION
return OF_STATUS_FATAL_ERROR;
}
#endif //OF_USE_LINEAR_BINARY_CODES_UTILS
#endif //OF_USE_DECODER

View File

@@ -0,0 +1,58 @@
/* $Id: of_it_decoding.h 186 2014-07-16 07:17:53Z roca $ */
/*
* OpenFEC.org AL-FEC Library.
* (c) Copyright 2009 - 2012 INRIA - All rights reserved
* Contact: vincent.roca@inria.fr
*
* This software is governed by the CeCILL-C license under French law and
* abiding by the rules of distribution of free software. You can use,
* modify and/ or redistribute the software under the terms of the CeCILL-C
* license as circulated by CEA, CNRS and INRIA at the following URL
* "http://www.cecill.info".
*
* As a counterpart to the access to the source code and rights to copy,
* modify and redistribute granted by the license, users are provided only
* with a limited warranty and the software's author, the holder of the
* economic rights, and the successive licensors have only limited
* liability.
*
* In this respect, the user's attention is drawn to the risks associated
* with loading, using, modifying and/or developing or reproducing the
* software by the user in light of its specific status of free software,
* that may mean that it is complicated to manipulate, and that also
* therefore means that it is reserved for developers and experienced
* professionals having in-depth computer knowledge. Users are therefore
* encouraged to load and test the software's suitability as regards their
* requirements in conditions enabling the security of their systems and/or
* data to be ensured and, more generally, to use and operate it in the
* same conditions as regards security.
*
* The fact that you are presently reading this means that you have had
* knowledge of the CeCILL-C license and that you accept its terms.
*/
#ifndef IT_DECODING_H
#define IT_DECODING_H
#ifdef OF_USE_DECODER
#ifdef OF_USE_LINEAR_BINARY_CODES_UTILS
/**
* @fn of_status_t of_linear_binary_code_decode_with_new_symbol (of_linear_binary_code_cb_t* ofcb, void* const new_symbol_buf, UINT32 new_symbol_esi)
* @brief (try to) decode with a newly received symbol
* @param ofcb (IN) Pointer to the linear binary code control block.
* @param new_symbol (IN) Pointer to the encoding symbol now available (i.e. a new
* symbol received by the application, or a decoded symbol in case
* of a recursive call).
* @param new_symbol_esi (IN) Encoding symbol ID of the newly symbol available, in {0..n-1}.
* @return Error status (NB: this function does not return OF_STATUS_FAILURE).
*/
of_status_t of_linear_binary_code_decode_with_new_symbol(of_linear_binary_code_cb_t* ofcb,void* new_symbol,UINT32 new_symbol_esi);
#endif //OF_USE_LINEAR_BINARY_CODES_UTILS
#endif //OF_USE_DECODER
#endif //IT_DECODING_H

View File

@@ -0,0 +1,624 @@
/* $Id: of_ml_decoding.c 218 2014-12-13 14:15:11Z roca $ */
/*
* OpenFEC.org AL-FEC Library.
* (c) Copyright 2009 - 2012 INRIA - All rights reserved
* Contact: vincent.roca@inria.fr
*
* This software is governed by the CeCILL-C license under French law and
* abiding by the rules of distribution of free software. You can use,
* modify and/ or redistribute the software under the terms of the CeCILL-C
* license as circulated by CEA, CNRS and INRIA at the following URL
* "http://www.cecill.info".
*
* As a counterpart to the access to the source code and rights to copy,
* modify and redistribute granted by the license, users are provided only
* with a limited warranty and the software's author, the holder of the
* economic rights, and the successive licensors have only limited
* liability.
*
* In this respect, the user's attention is drawn to the risks associated
* with loading, using, modifying and/or developing or reproducing the
* software by the user in light of its specific status of free software,
* that may mean that it is complicated to manipulate, and that also
* therefore means that it is reserved for developers and experienced
* professionals having in-depth computer knowledge. Users are therefore
* encouraged to load and test the software's suitability as regards their
* requirements in conditions enabling the security of their systems and/or
* data to be ensured and, more generally, to use and operate it in the
* same conditions as regards security.
*
* The fact that you are presently reading this means that you have had
* knowledge of the CeCILL-C license and that you accept its terms.
*/
#include "../of_linear_binary_code.h"
#ifdef OF_USE_DECODER
#ifdef OF_USE_LINEAR_BINARY_CODES_UTILS
#ifdef ML_DECODING
/****** Static Functions ****************************************************/
/**
* This function prepars the linear system (H) to be further simplified.
*
* @brief creates a copy of H matrix and update all ML deconding variables
* @param ofcb (IN/OUT) Linear-Binary-Code control-block.
* @return OF_STATUS_OK if it's OK
*/
static of_status_t
of_linear_binary_code_prepar_linear_system (of_linear_binary_code_cb_t *ofcb);
/**
* This function simplifies the linear system (H): delete rows and cols when feasible.
* This step is needed as IT decoding performs in a lazzy way, avoiding to sum the available symbols
* (received or decoded) to the constant term of the equations they are involved in unless it is the
* last symbol of this equation. Here we need to do that explicitely in order to simplify the system
* as much as possible.
*
* @brief symplifies the linear system
* @param ofcb (IN/OUT) Linear-Binary-Code control-block.
* @param new_symbol (IN/OUT) pointer to new symbol to process
* @param new_symbol_esi (IN) Encoding Symbol Index
* @return OF_STATUS_OK if it's OK
*/
static of_status_t
of_linear_binary_code_simplify_linear_system_with_a_symbol (of_linear_binary_code_cb_t *ofcb,
const void *new_symbol,
UINT32 new_symbol_esi);
/**
* This function creates the simplified linear system, considering only the non empty columns.
* This funtion creates the new ofcb->pchk_matrix_simplified matrix.
*
* @brief creates the simplified linear system
* @param ofcb (IN/OUT) Linear-Binary-Code control-block.
* @return OF_STATUS_OK if it's OK
*/
static of_status_t
of_linear_binary_code_create_simplified_linear_system (of_linear_binary_code_cb_t *ofcb);
/******************************************************************************/
of_status_t
of_linear_binary_code_finish_decoding_with_ml (of_linear_binary_code_cb_t *ofcb)
{
INT32 i;
UINT32 *permutation_array = NULL;
of_mod2dense *dense_pchk_matrix_simplified = NULL;
INT32 *column_idx = NULL;
void **const_term = NULL;
void **variable_member = NULL;
UINT32 nb_computed_repair_in_ml;
#ifdef DEBUG
struct timeval gdtv0; /* start */
struct timeval gdtv1; /* end */
struct timeval gdtv_delta; /* difference tv1 - tv0 */
#endif
OF_ENTER_FUNCTION
OF_TRACE_LVL (1, ("ML decoding on parity check matrix\n"))
/*
* Step 0: Matrix simplification, where we remove known symbols from the system, adding their value
* to corresponding constant terms.
*
* This step is needed as IT decoding performs in a lazzy way, avoiding to sum the available symbols
* (received or decoded) to the constant term of the equations they are involved in unless it is the
* last symbol of this equation. Here we need to do that explicitely in order to simplify the system
* as much as possible.
*/
ofcb->remain_rows = ofcb->nb_repair_symbols;
ofcb->remain_cols = ofcb->nb_source_symbols + ofcb->nb_repair_symbols;
if (of_linear_binary_code_prepar_linear_system (ofcb) != OF_STATUS_OK)
{
if (ofcb->remain_cols == 0)
{
// in fact decoding is already finished!
OF_TRACE_LVL (1, ("Create simplified linear system says it's finished!\n"))
OF_EXIT_FUNCTION
return OF_STATUS_FAILURE;
}
// but here it failed!
OF_TRACE_LVL (1, ("Create simplified linear system failed, ofcb->remain_cols=%d\n", ofcb->remain_cols))
OF_EXIT_FUNCTION
return OF_STATUS_FAILURE;
}
/*
* Inject all known source symbols
*/
for (i = 0 ; i < ofcb->nb_source_symbols ; i++)
{
if (ofcb->encoding_symbols_tab[i] != NULL)
{
if (of_linear_binary_code_simplify_linear_system_with_a_symbol (ofcb, ofcb->encoding_symbols_tab[i], i) != OF_STATUS_OK)
{
OF_TRACE_LVL(0,("Simplifying the matrix with source symbols failed\n"))
OF_EXIT_FUNCTION
return OF_STATUS_FAILURE;
}
}
}
/*
* Inject all known repair symbols
*/
/* Randomize the repair symbols order before injecting them (it makes the decoding process more efficient). */
permutation_array = (UINT32 *) of_malloc (ofcb->nb_repair_symbols * sizeof(UINT32));
for (i = 0 ; i < ofcb->nb_repair_symbols ; i++)
{
permutation_array[i] = i;
}
for (i = 0 ; i < ofcb->nb_repair_symbols ; i++)
{
INT32 backup;
INT32 rand_val;
backup = permutation_array[i];
rand_val = rand() % ofcb->nb_repair_symbols;
permutation_array[i] = permutation_array[rand_val];
permutation_array[rand_val] = backup;
}
/* Inject parity symbols following the random order given by permutation_array */
for (i = 0 ; i < ofcb->nb_repair_symbols ; i++)
{
if (ofcb->encoding_symbols_tab[ofcb->nb_source_symbols+permutation_array[i]] != NULL)
{
if (of_linear_binary_code_simplify_linear_system_with_a_symbol (ofcb, ofcb->encoding_symbols_tab[ofcb->nb_source_symbols+permutation_array[i]],
of_get_symbol_esi ((of_cb_t*)ofcb, permutation_array[i])) != OF_STATUS_OK)
{
OF_TRACE_LVL(0,("Simplifying the matrix with parity symbols failed\n"))
goto failure;
}
}
}
of_free (permutation_array);
permutation_array = NULL;
OF_TRACE_LVL (1, ("%s: ofcb->remain_rows=%d, ofcb->remain_cols=%d\n", __FUNCTION__, ofcb->remain_rows, ofcb->remain_cols))
if (of_linear_binary_code_create_simplified_linear_system (ofcb) != OF_STATUS_OK)
{
OF_TRACE_LVL(0, ("Create Simplified Linear System failed\n"))
goto failure;
}
#ifdef IL_SUPPORT
of_mod2sparse_print_bitmap(ofcb->pchk_matrix_simplified);
#endif
/*
* It's now time to create the simplified matrix, in dense format.
*/
dense_pchk_matrix_simplified = of_mod2dense_allocate (ofcb->pchk_matrix_simplified->n_rows, ofcb->pchk_matrix_simplified->n_cols);
of_mod2sparse_to_dense (ofcb->pchk_matrix_simplified, dense_pchk_matrix_simplified);
/* and immediately free the now useless sparse version to save memory... */
of_mod2sparse_free (ofcb->pchk_matrix_simplified);
of_free (ofcb->pchk_matrix_simplified);
ofcb->pchk_matrix_simplified = NULL;
#ifdef DEBUG
gettimeofday (&gdtv0, NULL);
OF_TRACE_LVL (1, ("gauss_decoding_start=%ld.%ld\n", gdtv0.tv_sec, gdtv0.tv_usec))
#endif
if ((column_idx = (INT32 *) of_malloc (of_mod2dense_cols (dense_pchk_matrix_simplified) * sizeof (INT32))) == NULL)
{
goto no_mem;
}
for (i = 0; i < of_mod2dense_cols (dense_pchk_matrix_simplified); i++)
{
column_idx[i] = i;
}
if ((const_term = (void **) of_malloc (of_mod2dense_rows (dense_pchk_matrix_simplified) * sizeof (void*))) == NULL)
{
goto no_mem;
}
for (i = 0; i < of_mod2dense_rows (dense_pchk_matrix_simplified); i++)
{
const_term[i] = ofcb->tab_const_term_of_equ[ofcb->index_rows[i]];
ofcb->tab_const_term_of_equ[ofcb->index_rows[i]] = NULL;
}
if ((variable_member = (void **) of_calloc (of_mod2dense_cols (dense_pchk_matrix_simplified), sizeof (void*))) == NULL)
{
goto no_mem;
}
/*
* And finally launch Gaussian Elimination.
*/
if (of_linear_binary_code_solve_dense_system (ofcb, dense_pchk_matrix_simplified, const_term, variable_member) != OF_STATUS_OK)
{
OF_TRACE_LVL(0,("Solve dense system failed\n"))
goto failure;
}
/*
* the system has been solved, so store the result in the canvas
*/
OF_TRACE_LVL (1, ("Solve dense system successful\n"))
nb_computed_repair_in_ml = ofcb->nb_repair_symbols - ofcb->nb_repair_symbol_ready; /* this is the number of repair found in ML */
/* ignore the first nb_computed_repair_in_ml symbols found in ML as they are repair symbols and we don't need them */
for (i = 0; i < nb_computed_repair_in_ml; i++)
{
if (variable_member[i] != NULL)
of_free(variable_member[i]);
}
/* the remaining symbols found in ML are source symbols, so we copy pointers */
for (i = 0; i < ofcb->nb_source_symbols; i++)
{
if (ofcb->encoding_symbols_tab[i] == NULL)
{
ofcb->encoding_symbols_tab[i] = variable_member[nb_computed_repair_in_ml];
nb_computed_repair_in_ml++;
}
}
#ifdef DEBUG
if (of_is_decoding_complete (ofcb))
{
OF_TRACE_LVL (1, ("ML decoding successful\n"))
}
gettimeofday (&gdtv1, NULL);
timersub (&gdtv1, &gdtv0, &gdtv_delta);
OF_TRACE_LVL (1, ("gauss_decoding_end=%ld.%ld gauss_decoding_time=%ld.%06ld \n",
gdtv1.tv_sec, gdtv1.tv_usec, gdtv_delta.tv_sec, gdtv_delta.tv_usec))
#endif
for (i = 0; i < of_mod2dense_rows (dense_pchk_matrix_simplified); i++)
{
if (const_term[i])
{
of_free(const_term[i]);
}
}
of_free(const_term);
const_term = NULL;
of_free(variable_member);
variable_member = NULL;
of_free(column_idx);
column_idx = NULL;
of_mod2dense_free(dense_pchk_matrix_simplified);
dense_pchk_matrix_simplified = NULL;
OF_EXIT_FUNCTION
return OF_STATUS_OK;
failure:
if (permutation_array != NULL)
{
of_free (permutation_array);
permutation_array = NULL;
}
if (const_term != NULL)
{
for (i = 0; i < of_mod2dense_rows (dense_pchk_matrix_simplified); i++)
{
if (const_term[i])
{
of_free(const_term[i]);
}
}
of_free(const_term);
const_term = NULL;
}
if (variable_member != NULL)
{
of_free(variable_member);
variable_member = NULL;
}
if (column_idx != NULL)
{
of_free(column_idx);
column_idx = NULL;
}
if (dense_pchk_matrix_simplified != NULL)
{
of_mod2dense_free(dense_pchk_matrix_simplified);
dense_pchk_matrix_simplified = NULL;
}
OF_EXIT_FUNCTION
return OF_STATUS_FAILURE;
no_mem:
OF_PRINT_ERROR(("out of memory"))
OF_EXIT_FUNCTION
return OF_STATUS_FATAL_ERROR;
}
/****** Static Functions ****************************************************/
of_status_t
of_linear_binary_code_prepar_linear_system (of_linear_binary_code_cb_t *ofcb)
{
INT32 _row;
INT32 _col;
OF_ENTER_FUNCTION
if (ofcb->index_rows == NULL)
{
ofcb->index_rows = (UINT32*) of_calloc (ofcb->nb_repair_symbols, sizeof (UINT32));
}
if (ofcb->index_cols == NULL)
{
ofcb->index_cols = (UINT32*) of_calloc (ofcb->nb_total_symbols, sizeof (UINT32));
}
for (_row = 0; _row < ofcb->nb_repair_symbols; _row++)
{
ofcb->index_rows[_row] = _row;
}
ofcb->remain_rows = _row;
for (_col = 0; _col < ofcb->nb_total_symbols; _col++)
{
ofcb->index_cols[_col] = _col;
}
ofcb->remain_cols = _col;
// Update the ML decoding variables too
for (_row = 0 ; _row < ofcb->nb_repair_symbols ; _row++)
{
of_mod2entry *e;
ofcb->tab_nb_enc_symbols_per_equ[_row] = 0;
ofcb->tab_nb_unknown_symbols[_row] = 0;
for (e = of_mod2sparse_first_in_row (ofcb->pchk_matrix, _row); !of_mod2sparse_at_end (e); e = of_mod2sparse_next_in_row (e))
{
ofcb->tab_nb_enc_symbols_per_equ[_row]++;
ofcb->tab_nb_unknown_symbols[_row]++;
}
}
OF_EXIT_FUNCTION
return OF_STATUS_OK;
}
static of_status_t
of_linear_binary_code_simplify_linear_system_with_a_symbol (of_linear_binary_code_cb_t *ofcb,
const void *new_symbol,
UINT32 new_symbol_esi)
{
of_mod2entry *_e; // entry ("1") in parity check matrix and entry to delete in row/column (temp)
of_mod2entry *_del_me;
INT32 _row;
OF_ENTER_FUNCTION
if (of_mod2sparse_empty_col (ofcb->pchk_matrix, of_get_symbol_col((of_cb_t*)ofcb, new_symbol_esi)))
{
OF_TRACE_LVL (1, ((" nothing to do, col empty\n")))
OF_EXIT_FUNCTION
return OF_STATUS_OK;
}
if (of_is_source_symbol((of_cb_t*)ofcb, new_symbol_esi) && of_is_decoding_complete((of_session_t*)ofcb))
{
// Decoding is now finished, return...
OF_TRACE_LVL (1, ((" decoding is finished!\n")))
OF_EXIT_FUNCTION
return OF_STATUS_OK;
}
_e = of_mod2sparse_first_in_col (ofcb->pchk_matrix, of_get_symbol_col((of_cb_t*)ofcb, new_symbol_esi));
while (!of_mod2sparse_at_end_col (_e))
{
_row = of_mod2sparse_row (_e);
// If the constant term buffer does not exist, create it
if (ofcb->tab_const_term_of_equ[_row] == NULL)
{
if ((ofcb->tab_const_term_of_equ[_row] = of_malloc (ofcb->encoding_symbol_length)) == NULL)
{
goto no_mem;
}
memcpy(ofcb->tab_const_term_of_equ[_row], new_symbol, ofcb->encoding_symbol_length);
}
else
{
// Inject the symbol in the partial sum
of_add_to_symbol((ofcb->tab_const_term_of_equ[_row]), new_symbol, ofcb->encoding_symbol_length
#ifdef OF_DEBUG
, &(ofcb->stats_xor->nb_xor_for_ML)
#endif
);
}
// Decrease the number of unknown symbols in the equation
ofcb->tab_nb_unknown_symbols[_row]--; // symbol is known
// Delete the current element
_del_me = _e;
_e = of_mod2sparse_next_in_col (_e);
of_mod2sparse_delete (ofcb->pchk_matrix, _del_me);
// If there is only one more symbol in the line, reinject it and progress like that
if (ofcb->tab_nb_unknown_symbols[_row] == 1)
{
of_mod2entry *__r;
UINT32 decoded_symbol_seqno;
// Get the only one symbol in the equation
__r = of_mod2sparse_first_in_row (ofcb->pchk_matrix, _row);
decoded_symbol_seqno = of_get_symbol_esi ((of_cb_t*)ofcb, of_mod2sparse_col (__r));
// Identify the symbol with its value, and reinject it.
if (of_is_source_symbol ((of_cb_t*)ofcb, decoded_symbol_seqno))
{
if (ofcb->encoding_symbols_tab[decoded_symbol_seqno] == NULL)
{
if (ofcb->decoded_source_symbol_callback != NULL)
{
ofcb->encoding_symbols_tab[decoded_symbol_seqno] =
ofcb->decoded_source_symbol_callback(ofcb->context_4_callback,
ofcb->encoding_symbol_length,
decoded_symbol_seqno);
}
else
{
ofcb->encoding_symbols_tab[decoded_symbol_seqno] = of_malloc (ofcb->encoding_symbol_length);
}
if (ofcb->encoding_symbols_tab[decoded_symbol_seqno] == NULL)
{
goto no_mem;
}
// Source symbol.
memcpy((ofcb->encoding_symbols_tab[decoded_symbol_seqno]),
(ofcb->tab_const_term_of_equ[_row]),
ofcb->encoding_symbol_length);
of_free (ofcb->tab_const_term_of_equ[_row]);
ofcb->tab_const_term_of_equ[_row] = NULL;
// It'll be known at the end of this step
ofcb->tab_nb_unknown_symbols[_row]--; // symbol is known
of_mod2sparse_delete (ofcb->pchk_matrix, __r);
of_linear_binary_code_simplify_linear_system_with_a_symbol (ofcb, ofcb->encoding_symbols_tab[decoded_symbol_seqno],
decoded_symbol_seqno);
ofcb->nb_source_symbol_ready++;
}
}
else
{
// Decoded symbol is a parity symbol
if (ofcb->encoding_symbols_tab[decoded_symbol_seqno] == NULL)
{
if (ofcb->decoded_repair_symbol_callback != NULL)
{
ofcb->encoding_symbols_tab[decoded_symbol_seqno] =
ofcb->decoded_repair_symbol_callback(ofcb->context_4_callback,
ofcb->encoding_symbol_length,
decoded_symbol_seqno);
}
else
{
ofcb->encoding_symbols_tab[decoded_symbol_seqno] = of_malloc (ofcb->encoding_symbol_length);
}
if (ofcb->encoding_symbols_tab[decoded_symbol_seqno] == NULL)
{
goto no_mem;
}
// copy the content...
memcpy(ofcb->encoding_symbols_tab[decoded_symbol_seqno],
ofcb->tab_const_term_of_equ[_row],
ofcb->encoding_symbol_length);
of_free (ofcb->tab_const_term_of_equ[_row]);
ofcb->tab_const_term_of_equ[_row] = NULL;
// It'll be known at the end of this step
ofcb->tab_nb_unknown_symbols[_row]--; // symbol is known
ofcb->tab_nb_equ_for_repair[decoded_symbol_seqno - ofcb->nb_source_symbols]--;
of_mod2sparse_delete (ofcb->pchk_matrix, __r);
of_linear_binary_code_simplify_linear_system_with_a_symbol (ofcb, ofcb->encoding_symbols_tab[decoded_symbol_seqno],
decoded_symbol_seqno);
ofcb->nb_repair_symbol_ready++;
}
}
ofcb->remain_rows--;
}
}
ofcb->remain_cols--;
OF_EXIT_FUNCTION
return OF_STATUS_OK;
no_mem:
OF_PRINT_ERROR(("out of memory"))
OF_EXIT_FUNCTION
return OF_STATUS_FATAL_ERROR;
}
of_status_t of_linear_binary_code_create_simplified_linear_system (of_linear_binary_code_cb_t *ofcb)
{
INT32 _row;
INT32 _col;
of_mod2sparse *__pchk_matrix_simplified_cols;
UINT32 *index_rows;
UINT32 *index_cols;
OF_ENTER_FUNCTION
ofcb->remain_rows = 0;
ofcb->remain_cols = 0;
if (ofcb->index_rows == NULL)
{
if ((ofcb->index_rows = (UINT32 *) of_calloc (ofcb->nb_repair_symbols, sizeof (UINT32))) == NULL)
{
goto no_mem;
}
}
if (ofcb->index_cols == NULL)
{
if ((ofcb->index_cols = (UINT32 *) of_calloc (ofcb->nb_total_symbols - ofcb->nb_repair_symbol_ready - ofcb->nb_source_symbol_ready,
sizeof (UINT32))) == NULL)
{
goto no_mem;
}
}
index_rows = (UINT32*) of_malloc(ofcb->nb_repair_symbols * sizeof(UINT32));
index_cols = (UINT32*) of_malloc(ofcb->nb_total_symbols * sizeof(UINT32));
if ((index_rows == NULL) || (index_cols == NULL))
{
goto no_mem;
}
// Get the index of cols to copy from the original matrix
for (_col = 0 ; _col < ofcb->nb_total_symbols ; _col++)
{
if (!of_mod2sparse_empty_col (ofcb->pchk_matrix, _col))
{
/* copy this col */
index_cols[_col] = ofcb->remain_cols; // old location
ofcb->index_cols[ofcb->remain_cols++] = _col; // new location
}
}
// Get the index of rows to copy from the original matrix
for (_row = 0 ; _row < ofcb->nb_repair_symbols ; _row++)
{
if (!of_mod2sparse_empty_row (ofcb->pchk_matrix, _row))
{
/* copy this row */
index_rows[_row] = ofcb->remain_rows;
ofcb->index_rows[ofcb->remain_rows++] = _row;
}
}
if (ofcb->remain_cols == 0)
{
// the initial matrix is completely simplified, nothing remains.
OF_PRINT_LVL (1, ("%s: Failure, initial matrix is now empty, ofcb->remain_cols==0\n", __FUNCTION__))
goto failure;
}
else if (ofcb->remain_rows < ofcb->remain_cols)
{
// impossible to continue as there are fewer rows than columns.
OF_PRINT_LVL (1, ("%s: Failure, fewer rows than columns, ofcb->remain_rows (%d) < ofcb->remain_cols (%d)\n",
__FUNCTION__, ofcb->remain_rows, ofcb->remain_cols))
goto failure;
}
OF_TRACE_LVL (1, ("%s: Simplified Matrix: %dx%d; already decoded symbols: ready_src=%d, ready_parity=%d remaining_rows=%d remaining_cols=%d\n",
__FUNCTION__, ofcb->remain_rows, ofcb->remain_cols, ofcb->nb_source_symbol_ready,
ofcb->nb_repair_symbol_ready, ofcb->remain_rows, ofcb->remain_cols))
// allocate the new pchk_matrix_simplified, copy the non empty rows/cols in it
ofcb->pchk_matrix_simplified = of_mod2sparse_allocate (ofcb->nb_repair_symbols, ofcb->remain_cols);
of_mod2sparse_copy_filled_matrix(ofcb->pchk_matrix, ofcb->pchk_matrix_simplified, index_rows, index_cols);
of_mod2sparse_free (ofcb->pchk_matrix);
of_free (ofcb->pchk_matrix);
ofcb->pchk_matrix = NULL;
of_free(index_rows);
of_free(index_cols);
OF_TRACE_LVL (1, ("ok\n"))
OF_EXIT_FUNCTION
return OF_STATUS_OK;
failure:
if (ofcb->index_rows)
{
of_free (ofcb->index_rows);
ofcb->index_rows = NULL;
}
if (ofcb->index_cols)
{
of_free (ofcb->index_cols);
ofcb->index_cols = NULL;
}
if (index_rows)
of_free(index_rows);
if (index_cols)
of_free(index_cols);
OF_EXIT_FUNCTION
return OF_STATUS_FAILURE;
no_mem:
OF_PRINT_ERROR(("out of memory"))
OF_EXIT_FUNCTION
return OF_STATUS_FATAL_ERROR;
}
#endif //ML_DECODING
#endif //OF_USE_LINEAR_BINARY_CODES_UTILS
#endif //OF_USE_DECODER

View File

@@ -0,0 +1,61 @@
/* $Id: of_ml_decoding.h 208 2014-12-12 18:39:20Z roca $ */
/*
* OpenFEC.org AL-FEC Library.
* (c) Copyright 2009 - 2012 INRIA - All rights reserved
* Contact: vincent.roca@inria.fr
*
* This software is governed by the CeCILL-C license under French law and
* abiding by the rules of distribution of free software. You can use,
* modify and/ or redistribute the software under the terms of the CeCILL-C
* license as circulated by CEA, CNRS and INRIA at the following URL
* "http://www.cecill.info".
*
* As a counterpart to the access to the source code and rights to copy,
* modify and redistribute granted by the license, users are provided only
* with a limited warranty and the software's author, the holder of the
* economic rights, and the successive licensors have only limited
* liability.
*
* In this respect, the user's attention is drawn to the risks associated
* with loading, using, modifying and/or developing or reproducing the
* software by the user in light of its specific status of free software,
* that may mean that it is complicated to manipulate, and that also
* therefore means that it is reserved for developers and experienced
* professionals having in-depth computer knowledge. Users are therefore
* encouraged to load and test the software's suitability as regards their
* requirements in conditions enabling the security of their systems and/or
* data to be ensured and, more generally, to use and operate it in the
* same conditions as regards security.
*
* The fact that you are presently reading this means that you have had
* knowledge of the CeCILL-C license and that you accept its terms.
*/
#ifndef ML_DECODING_H
#define ML_DECODING_H
//#include "../../of_openfec_api.h"
#ifdef OF_USE_DECODER
#ifdef OF_USE_LINEAR_BINARY_CODES_UTILS
#ifdef ML_DECODING
/**
* This function tries to finish decoding.
*
* @fn of_status_t of_linear_binary_code_finish_decoding_with_ml (of_linear_binary_code_cb_t *ofcb)
* @brief try to finish decoding
* @param ofcb (IN/OUT) Linear-Binary-Code control-block.
* @return 1 if it's OK, or 0 if an error appears.
*/
of_status_t of_linear_binary_code_finish_decoding_with_ml (of_linear_binary_code_cb_t *ofcb);
#endif //ML_DECODING
#endif //OF_USE_LINEAR_BINARY_CODES_UTILS
#endif //OF_USE_DECODER
#endif /* ML_DECODING_H */

View File

@@ -0,0 +1,338 @@
/* $Id: of_ml_tool.c 213 2014-12-12 22:36:41Z roca $ */
/*
* OpenFEC.org AL-FEC Library.
* (c) Copyright 2009 - 2011 INRIA - All rights reserved
* Contact: vincent.roca@inria.fr
*
* This software is governed by the CeCILL-C license under French law and
* abiding by the rules of distribution of free software. You can use,
* modify and/ or redistribute the software under the terms of the CeCILL-C
* license as circulated by CEA, CNRS and INRIA at the following URL
* "http://www.cecill.info".
*
* As a counterpart to the access to the source code and rights to copy,
* modify and redistribute granted by the license, users are provided only
* with a limited warranty and the software's author, the holder of the
* economic rights, and the successive licensors have only limited
* liability.
*
* In this respect, the user's attention is drawn to the risks associated
* with loading, using, modifying and/or developing or reproducing the
* software by the user in light of its specific status of free software,
* that may mean that it is complicated to manipulate, and that also
* therefore means that it is reserved for developers and experienced
* professionals having in-depth computer knowledge. Users are therefore
* encouraged to load and test the software's suitability as regards their
* requirements in conditions enabling the security of their systems and/or
* data to be ensured and, more generally, to use and operate it in the
* same conditions as regards security.
*
* The fact that you are presently reading this means that you have had
* knowledge of the CeCILL-C license and that you accept its terms.
*/
#include "../of_linear_binary_code.h"
#ifdef OF_USE_DECODER
#ifdef OF_USE_LINEAR_BINARY_CODES_UTILS
#ifdef ML_DECODING
/****** Static Functions ****************************************************/
/**
* This function transforms the matrix into a triangular matrix. It goes through each column and calls of_linear_binary_code_col_forward_elimination()
* to find the pivot and eliminate '1's below the pivot.
*
* @brief triangularize the dense system
* @param m (IN/OUT) address of the dense matrix.
* @param constant_tab (IN/OUT)
* @param ofcb (IN) Linear-Binary-Code control-block.
* @return 1 if it's OK, or 0 if an error took place.
*/
static INT32
of_linear_binary_code_triangularize_dense_system (of_linear_binary_code_cb_t *ofcb,
of_mod2dense *m,
void **constant_tab);
/**
* This function finds the pivot for this column and eliminates '1's below this pivot.
*
* @brief eliminates "1" entries in parity check matrix
* @param m (IN/OUT) address of the dense matrix.
* @param constant_tab (IN/OUT) pointer to all constant members
* @param ofcb (IN/OUT) Linear-Binary-Code control-block.
* @param col_idx (IN) column index
* @param stats (IN)
* @return 1 if it's OK, or 0 if an error took place.
*/
static INT32
of_linear_binary_code_col_forward_elimination (of_linear_binary_code_cb_t *ofcb,
of_mod2dense *m,
void **constant_tab,
INT32 col_idx);
/**
* This function computes the actual values of the symbols, starting from the bottom row up to the first one. It assumes the parity check matrix has
* already been transformed into a triangular matrix.
*
* @brief solve system with backward substitution
* @param variable_tab (IN/OUT) address of the dense matrix.
* @param constant_tab
* @param m (IN/OUT) address of the dense matrix.
* @param ofcb (IN/OUT) Linear-Binary-Code control-block.
* @return 1 if it's OK, or 0 if an error took place.
*/
static INT32
of_linear_binary_code_backward_substitution (of_linear_binary_code_cb_t *ofcb,
of_mod2dense *m,
void *variable_tab[],
void *constant_tab[]);
/******************************************************************************/
/**
* This function solves the system: first triangularize the system, then for each column,
* do a forward elimination, then do the backward elimination.
*/
of_status_t
of_linear_binary_code_solve_dense_system (of_linear_binary_code_cb_t *ofcb,
of_mod2dense *m,
void **constant_tab,
void **variable_tab)
{
OF_ENTER_FUNCTION
if (!of_linear_binary_code_triangularize_dense_system (ofcb, m, constant_tab))
{
OF_TRACE_LVL(0,("%s: triangularize_dense_system failed for system with %d rows, %d cols\n",
__FUNCTION__, of_mod2dense_rows(m), of_mod2dense_cols(m)))
OF_EXIT_FUNCTION
return OF_STATUS_FAILURE;
}
//of_mod2dense_print_bitmap(m);
if (!of_linear_binary_code_backward_substitution (ofcb, m, variable_tab, constant_tab))
{
OF_TRACE_LVL(0,("%s: backward_substitution failed\n", __FUNCTION__))
OF_EXIT_FUNCTION
return OF_STATUS_FAILURE;
}
OF_EXIT_FUNCTION
return OF_STATUS_OK;
}
/****** Static Functions ****************************************************/
static
INT32 of_linear_binary_code_triangularize_dense_system (of_linear_binary_code_cb_t *ofcb,
of_mod2dense *m,
void **constant_tab)
{
INT32 i, n;
OF_ENTER_FUNCTION
n = of_mod2dense_cols (m);
/* for each row */
for (i = 0; i < n; i++)
{
if (!of_linear_binary_code_col_forward_elimination(ofcb, m, constant_tab, i))
{
OF_EXIT_FUNCTION
return 0;
}
}
OF_EXIT_FUNCTION
return 1;
}
static
INT32 of_linear_binary_code_col_forward_elimination (of_linear_binary_code_cb_t *ofcb,
of_mod2dense *m,
void **constant_tab,
INT32 col_idx)
{
of_mod2word *s;
of_mod2word *t;
INT32 i, j, k;
INT32 n, p;
INT32 w;
INT32 w0;
INT32 b0;
INT32 symbol_size;
void *tmp_buffer;
OF_ENTER_FUNCTION
symbol_size = ofcb->encoding_symbol_length;
n = of_mod2dense_cols (m);
p = of_mod2dense_rows (m);
w = m->n_words;
i = col_idx;
//printf("of_col_forward_elimination of col %d\n",i);
w0 = i >> of_mod2_wordsize_shift; // word index of the ith bit
b0 = i & of_mod2_wordsize_mask; // bit index of the ith bit in the w0-th word
/* search for the first non-null element of that column (pivot) */
for (j = i; j < p; j++)
{
if (of_mod2_getbit(m->row[j][w0], b0))
break;
}
/* now j is the index of the first non null element in column i */
if (j == p)
{
/* it's a failure, it's not possible to choose a pivot for this empty column */
OF_EXIT_FUNCTION
return 0;
}
if (j != i)
{
// swap columns i and j in the two matrices
//printf("swap rows %i and %i\n",j,i);
t = m->row[i];
m->row[i] = m->row[j];
m->row[j] = t;
// swap the partial sum
tmp_buffer = constant_tab[i];
constant_tab[i] = constant_tab[j];
constant_tab[j] = tmp_buffer;
//of_mod2dense_print(stdout,m);
}
/* we have found the pivot and made sure that it is at row i (potentially after swapping two rows).
* Now eliminate the other '1's below this pivot... */
ofcb->nb_tmp_symbols = 0;
for (j = i + 1; j < p; j++)
{
if (of_mod2_getbit(m->row[j][w0], b0))
{
/* there's a '1' below the pivot, so XOR the two rows (word by word to go faster). */
//printf("\n\nxor in %i, %i\n",j,i);
s = m->row[j];
t = m->row[i];
s += w0;
t += w0;
for (k = w0; k < w; k++)
{
*s ^= *t;
s++;
t++;
}
//of_mod2dense_print(stdout,m);
if (constant_tab[i] != NULL)
{
/* if the buffer of line i is NULL there is nothing to add.
* add the constant term of the i to the constant term of line j */
if (constant_tab[j] == NULL)
{
constant_tab[j] = of_malloc (symbol_size);
/* copy data directly, there's no XOR to perform */
memcpy (constant_tab[j], constant_tab[i], symbol_size);
}
else
{
/* add constant term i to constant term j */
ofcb->tmp_tab_symbols[ofcb->nb_tmp_symbols++] = constant_tab[j];
}
}
else
{
constant_tab[i] = of_calloc (1, symbol_size);
}
}
}
if (ofcb->nb_tmp_symbols != 0)
{
if (ofcb->nb_tmp_symbols == 1)
{
of_add_to_symbol (ofcb->tmp_tab_symbols[0], constant_tab[i], symbol_size OP_ARG_VAL);
}
else
{
of_add_to_multiple_symbols (ofcb->tmp_tab_symbols,
constant_tab[i],
ofcb->nb_tmp_symbols,
ofcb->encoding_symbol_length
#ifdef OF_DEBUG
, &(ofcb->stats_xor->nb_xor_for_ML)
#endif
);
}
}
OF_EXIT_FUNCTION
return 1;
}
/* old trivial backward substitution algorithm. */
static
INT32 of_linear_binary_code_backward_substitution (of_linear_binary_code_cb_t *ofcb,
of_mod2dense *m,
void *variable_tab[],
void *constant_tab[])
{
INT32 i; /* current variable index for which we apply backward substition. It's also the row index. */
INT32 j; /* */
INT32 n;
INT32 w0; /* dense matrix word index for variable j */
INT32 b0; /* dense matrix bit index in word of index w0 */
OF_ENTER_FUNCTION
n = of_mod2dense_cols (m);
/* go through all the rows, starting from the last one... */
for (i = n - 1; i >= 0; i--)
{
ASSERT(variable_tab[i] == NULL);
//if (variable_tab[i] == NULL)
{
of_mod2word *row = m->row[i]; // row corresponding to variable i
#ifdef OF_DEBUG
w0 = i >> of_mod2_wordsize_shift; // word index of the ith bit
b0 = i & of_mod2_wordsize_mask; // bit index of the ith bit in the w0-th word
ASSERT(of_mod2_getbit(row[w0], b0))
#endif
/*
* the missing source symbol in col i is equal to the sum of the constant term of this
* equation (i.e. row i) plus all the variables of this equation.
*/
//OF_TRACE_LVL(1, ("%s: rebuilding source symbol %d with col %d\n", __FUNCTION__, col_index[i], i))
ASSERT(variable_tab[i] == NULL);
variable_tab[i] = constant_tab[i];
constant_tab[i] = NULL;
/* determine the list of symbols to add to compute the decoded source symbol */
ofcb->nb_tmp_symbols = 0;
for (j = i + 1; j < n; j++)
{
w0 = j >> of_mod2_wordsize_shift; // word index of the ith bit
b0 = j & of_mod2_wordsize_mask; // bit index of the ith bit in the w0-th word
/* search for the non-null element in row i */
if (of_mod2_getbit(row[w0], b0))
{
/* since the bit is set, add the variable_tab[j] symbol */
ofcb->tmp_tab_symbols[ofcb->nb_tmp_symbols++] = variable_tab[j];
}
}
if (ofcb->nb_tmp_symbols != 0)
{
of_add_from_multiple_symbols(variable_tab[i], (const void**)ofcb->tmp_tab_symbols,
ofcb->nb_tmp_symbols, ofcb->encoding_symbol_length
#ifdef OF_DEBUG
, &(ofcb->stats_xor->nb_xor_for_ML)
#endif
);
}
}
}
OF_EXIT_FUNCTION
return 1;
}
#endif //ML_DECODING
#endif //OF_USE_LINEAR_BINARY_CODES_UTILS
#endif //OF_USE_DECODER

View File

@@ -0,0 +1,74 @@
/* $Id: of_ml_tool.h 205 2014-12-10 04:17:19Z roca $ */
/*
* OpenFEC.org AL-FEC Library.
* (c) Copyright 2009 - 2011 INRIA - All rights reserved
* Contact: vincent.roca@inria.fr
*
* This software is governed by the CeCILL-C license under French law and
* abiding by the rules of distribution of free software. You can use,
* modify and/ or redistribute the software under the terms of the CeCILL-C
* license as circulated by CEA, CNRS and INRIA at the following URL
* "http://www.cecill.info".
*
* As a counterpart to the access to the source code and rights to copy,
* modify and redistribute granted by the license, users are provided only
* with a limited warranty and the software's author, the holder of the
* economic rights, and the successive licensors have only limited
* liability.
*
* In this respect, the user's attention is drawn to the risks associated
* with loading, using, modifying and/or developing or reproducing the
* software by the user in light of its specific status of free software,
* that may mean that it is complicated to manipulate, and that also
* therefore means that it is reserved for developers and experienced
* professionals having in-depth computer knowledge. Users are therefore
* encouraged to load and test the software's suitability as regards their
* requirements in conditions enabling the security of their systems and/or
* data to be ensured and, more generally, to use and operate it in the
* same conditions as regards security.
*
* The fact that you are presently reading this means that you have had
* knowledge of the CeCILL-C license and that you accept its terms.
*/
#ifndef OF_ML_TOOL
#define OF_ML_TOOL
#ifdef OF_USE_DECODER
#ifdef OF_USE_LINEAR_BINARY_CODES_UTILS
#ifdef ML_DECODING
#ifdef OF_DEBUG
#define OP_ARGS ,UINT32* op
#define OP_ARG_VAL ,&(ofcb->stats_xor->nb_xor_for_ML)
#else
#define OP_ARGS
#define OP_ARG_VAL
#endif
/**
* This function solves the system: first triangularize the system, then for each column,
* do a forward elimination, then do the backward elimination.
*
* @fn INT32 of_linear_binary_code_solve_dense_system (of_mod2dense *m,void ** constant_member,void **variables,of_linear_binary_code_cb_t *ofcb)
* @brief solves the system
* @param m (IN/OUT) address of the dense matrix.
* @param variables
* @param constant_member (IN/OUT)pointer to all constant members
* @param ofcb (IN/OUT) Linear-Binary-Code control-block.
* @return error status
*/
of_status_t
of_linear_binary_code_solve_dense_system (of_linear_binary_code_cb_t *ofcb,
of_mod2dense *m,
void **constant_tab,
void **variable_tab);
#endif //ML_DECODING
#endif //OF_USE_LINEAR_BINARY_CODES_UTILS
#endif //OF_USE_DECODER
#endif //OF_ML_TOOL

View File

@@ -0,0 +1,351 @@
/* $Id: of_create_pchk.c 186 2014-07-16 07:17:53Z roca $ */
/*
* The contents of this directory and its sub-directories are
* Copyright (c) 1995-2003 by Radford M. Neal
*
* Permission is granted for anyone to copy, use, modify, or distribute these
* programs and accompanying documents for any purpose, provided this copyright
* notice is retained and prominently displayed, along with a note saying
* that the original programs are available from Radford Neal's web page, and
* note is made of any changes made to these programs. These programs and
* documents are distributed without any warranty, express or implied. As the
* programs were written for research purposes only, they have not been tested
* to the degree that would be advisable in any important application. All use
* of these programs is entirely at the user's own risk.
*/
#include "of_linear_binary_code.h"
of_mod2sparse* of_create_pchk_matrix (UINT32 nb_rows,
UINT32 nb_cols,
make_method make_method,
UINT32 left_degree,
UINT32 seed,
bool no4cycle,
of_session_type type,
UINT8 verbosity)
{
OF_ENTER_FUNCTION
of_mod2sparse* m;
switch (type) {
case TypeREGULAR_LDPC:
m = of_create_pchk_matrix_general (nb_rows, nb_cols, make_method, left_degree,
seed, no4cycle, type, verbosity);
break;
case Type2DMATRIX:
m = of_create_2D_pchk_matrix (nb_rows, nb_cols, type, verbosity);
break;
default:
abort();
OF_EXIT_FUNCTION
return NULL;
}
OF_EXIT_FUNCTION
return m;
}
of_mod2sparse* of_create_pchk_matrix_general (UINT32 nb_rows,
UINT32 nb_cols,
make_method make_method,
UINT32 left_degree,
UINT32 seed,
bool no4cycle,
of_session_type type,
UINT8 verbosity)
{
UINT32 row_start = 0;
UINT32 row_end = 0;
UINT32 col_start = 0;
UINT32 col_end = 0;
INT32 i;
of_mod2sparse *pchkMatrix = NULL;
OF_ENTER_FUNCTION
if (type != TypeLDGM && type != TypeSTAIRS && type != TypeTRIANGLE && type != TypeREGULAR_LDPC)
{
OF_PRINT_ERROR(("unsupported code type (%d)\n", type));
OF_EXIT_FUNCTION
return NULL;
}
/* a few sanity checks... */
if (left_degree > nb_rows)
{
OF_PRINT_ERROR(("number of checks per bit (%d) is greater than total checks (%d)\n",
left_degree, nb_rows));
OF_EXIT_FUNCTION
return NULL;
}
if (no4cycle)
{
OF_PRINT_ERROR(("no4cycle mode is no longer supported!"));
OF_EXIT_FUNCTION
return NULL;
}
of_rfc5170_srand (seed);
pchkMatrix = of_mod2sparse_allocate (nb_rows, nb_cols);
switch (type) {
case TypeLDGM:
row_start = 0;
row_end = nb_rows;
col_start = nb_rows;
col_end = nb_cols;
break;
case TypeREGULAR_LDPC:
row_start = 0;
row_end = nb_rows;
col_start = 0;
col_end = nb_cols;
break;
default:
break;
}
of_fill_regular_pchk_matrix (pchkMatrix, row_start, row_end, col_start, col_end, make_method,
left_degree, no4cycle, verbosity);
switch (type) {
case TypeLDGM:
for (i = 0; i < nb_rows; i++)
{
/* identity */
of_mod2sparse_insert (pchkMatrix, i, i);
}
break;
default:
// nothing to do
break;
}
OF_EXIT_FUNCTION
return pchkMatrix;
}
of_mod2sparse* of_create_2D_pchk_matrix (UINT32 nb_rows,
UINT32 nb_cols,
of_session_type type,
UINT8 verbosity)
{
OF_ENTER_FUNCTION
of_mod2sparse *pchkMatrix;
float d,l; // code dimensions for 2D pchk matrix
if (nb_rows >= nb_cols)
{
OF_PRINT_ERROR(("In 2D parity check matrix, number of rows must not be greater than number of cols.\n"))
goto error;
}
for (d = floor(sqrt(nb_cols)); d > 0; d-- )
{
l = ((float)((nb_cols-nb_rows))) / d;
if (l - floor(l) == 0 && ((d + l) == nb_rows))
{
//it's OK for a correct 2D-pchk matrix
pchkMatrix = of_mod2sparse_allocate((l + d), (l * d) + (l + d));
of_fill_2D_pchk_matrix(pchkMatrix, l, d, verbosity);
OF_EXIT_FUNCTION
return pchkMatrix;
}
}
error:
OF_EXIT_FUNCTION
return NULL;
}
of_mod2sparse* of_fill_2D_pchk_matrix (of_mod2sparse *m,
UINT32 d,
UINT32 l,
UINT8 verbosity)
{
OF_ENTER_FUNCTION
UINT32 i, j;
for (i = 0; i < (l+d); i++)
{
of_mod2sparse_insert(m, i, i);
}
// create non interleaved constraints
for (i = 0; i < d; i++)
{
//set 1 for source symbols included in equation
for (j = 0; j < l; j++)
{
of_mod2sparse_insert(m, i, j + (i * l) + l + d);
}
}
// create interleaved constraints
for (i = d; i < l + d; i++)
{
for (j = 0; j < d; j++)
{
of_mod2sparse_insert(m, i, 4 * j + ( i - d )+l+d);
}
}
return m;
OF_EXIT_FUNCTION
}
of_mod2sparse* of_fill_regular_pchk_matrix (of_mod2sparse *m,
UINT32 row_start,
UINT32 row_end,
UINT32 col_start,
UINT32 col_end,
make_method make_method,
UINT32 left_degree,
bool no4cycle,
UINT8 verbosity)
{
of_mod2entry *e;
UINT32 added, uneven;
INT32 i, j, k, t;
UINT32 *u;
of_mod2sparse *pchkMatrix = m;
UINT32 nb_col, nb_row;
OF_ENTER_FUNCTION
nb_col = col_end - col_start;
nb_row = row_end - row_start;
/* Create the initial version of the parity check matrix. */
switch (make_method)
{
case Evencol:
for (j = col_start; j < col_end; j++)
{
for (k = 0; k < left_degree; k++)
{
do
{
i = of_rfc5170_rand (nb_row);
}
while (of_mod2sparse_find (pchkMatrix, i, j));
of_mod2sparse_insert (pchkMatrix, i, j);
}
}
break;
case Evenboth:
u = (UINT32*) of_calloc (left_degree * nb_col, sizeof * u);
/* initialize a list of possible choices to guarantee a homogeneous "1" distribution */
for (k = left_degree * nb_col - 1; k >= 0; k--)
{
u[k] = k % nb_row;
}
uneven = 0;
t = 0; /* left limit within the list of possible choices, u[] */
for (j = col_start; j < col_end; j++)
{
/* for each source symbol column */
for (k = 0; k < left_degree; k++)
{
/* add left_degree "1s" */
/* check that valid available choices remain */
for (i = t; i < left_degree*nb_col && of_mod2sparse_find (pchkMatrix, u[i], j); i++)
;
if (i < left_degree*nb_col)
{
/* choose one index within the list of possible choices */
do
{
i = t + of_rfc5170_rand (left_degree * nb_col - t);
}
while (of_mod2sparse_find (pchkMatrix, u[i], j));
of_mod2sparse_insert (pchkMatrix, u[i], j);
/* replace with u[t] which has never been chosen */
u[i] = u[t];
t++;
}
else
{
/* no choice left, choose one randomly */
uneven += 1;
do
{
i = of_rfc5170_rand (nb_row);
}
while (of_mod2sparse_find (pchkMatrix, i, j));
of_mod2sparse_insert (pchkMatrix, i, j);
}
}
}
if (uneven > 0 && verbosity >= 1)
{
OF_PRINT_ERROR(("Had to place %d checks in rows unevenly\n", uneven));
}
of_free (u); /* VR: added */
break;
default:
abort();
}
/* Add extra bits to avoid rows with less than two checks. */
added = 0;
for (i = row_start; i < row_end; i++)
{
e = of_mod2sparse_first_in_row (pchkMatrix, i);
if (of_mod2sparse_at_end (e))
{
j = (of_rfc5170_rand (nb_col) + col_start);
e = of_mod2sparse_insert (pchkMatrix, i, j);
added ++;
}
e = of_mod2sparse_first_in_row (pchkMatrix, i);
if (of_mod2sparse_at_end (of_mod2sparse_next_in_row (e)) && nb_col > 1)
{
do
{
j = (of_rfc5170_rand (nb_col)) + col_start;
}
while (j == of_mod2sparse_col (e));
of_mod2sparse_insert (pchkMatrix, i, j);
added ++;
}
}
if (added > 0 && verbosity >= 1)
{
OF_PRINT_ERROR(("Added %d extra bit-checks to make row counts at least two\n", added));
}
/* Add extra bits to try to avoid problems with even column counts. */
if (left_degree % 2 == 0 && left_degree < nb_row && nb_col > 1 && added < 2)
{
UINT32 a;
for (a = 0; added + a < 2; a++)
{
do
{
i = of_rfc5170_rand (nb_row);
j = (of_rfc5170_rand (nb_col)) + col_start;
}
while (of_mod2sparse_find (pchkMatrix, i, j));
of_mod2sparse_insert (pchkMatrix, i, j);
}
if (verbosity >= 1)
{
OF_PRINT_ERROR(("Added %d extra bit-checks to try to avoid problems from even column counts\n", a));
}
OF_PRINT_LVL (1, ("Added %d extra bit-checks to try to avoid problems from even column counts\n", a));
}
OF_EXIT_FUNCTION
return pchkMatrix;
}

View File

@@ -0,0 +1,155 @@
/* $Id: of_create_pchk.h 182 2014-07-15 09:27:51Z roca $ */
/*
* The contents of this directory and its sub-directories are
* Copyright (c) 1995-2003 by Radford M. Neal
*
* Permission is granted for anyone to copy, use, modify, or distribute these
* programs and accompanying documents for any purpose, provided this copyright
* notice is retained and prominently displayed, along with a note saying
* that the original programs are available from Radford Neal's web page, and
* note is made of any changes made to these programs. These programs and
* documents are distributed without any warranty, express or implied. As the
* programs were written for research purposes only, they have not been tested
* to the degree that would be advisable in any important application. All use
* of these programs is entirely at the user's own risk.
*/
#ifndef OF_LDPC_CREATE_PCHK
#define OF_LDPC_CREATE_PCHK
/**
* @enum make_method_enum
* @brief Define differents methods to build the parity check matrix.
*/
typedef enum make_method_enum
{
Evencol, /* Uniform number of bits per column, with number specified */
Evenboth /* Uniform (as possible) over both columns and rows */
} make_method;
/**
* @enum SessionType_enum
* @brief Define differents type of sessions for creating the correct matrix
*/
typedef enum SessionType_enum
{
TypeLDGM,
TypeSTAIRS,
TypeTRIANGLE,
TypeREAD_FROM_FILE,
TypeREAD_QC_FROM_FILE,
TypeLDPC_QC,
TypeREGULAR_LDPC,
Type2DMATRIX
} of_session_type;
/**
* This function creates the correct parity check matrix.
*
* @brief creates the correct parity check matrix
* @param nb_rows (IN) number of rows
* @param nb_cols (IN) number of cols
* @param make_method (IN) method to create the matrix
* @param left_degree (IN) number of "1" entry for each column
* @param seed (IN) seed for random generator
* @param no4cycle (IN) with or without cycles
* @param type (IN) type of matrix
* @param verbosity (IN) verbosity level
* @param stats (IN/OUT) memory statistics (can be NULL)
* @return pointer to the matrix
*/
of_mod2sparse* of_create_pchk_matrix (UINT32 nb_rows,
UINT32 nb_cols,
make_method make_method,
UINT32 left_degree,
UINT32 seed,
bool no4cycle,
of_session_type type,
UINT8 verbosity);
/**
* This function creates a generic parity check matrix.
*
* @brief creates a matrix corresponding to RFC5170
* @param nb_rows (IN) number of rows
* @param nb_cols (IN) number of cols
* @param make_method (IN) method to create the matrix
* @param left_degree (IN) number of "1" entry for each column
* @param seed (IN) seed for random generator
* @param no4cycle (IN) with or without cycles
* @param type (IN) type of matrix
* @param verbosity (IN) verbosity level
* @param stats (IN/OUT) memory statistics (can be NULL)
* @return pointer to the matrix
*/
of_mod2sparse* of_create_pchk_matrix_general (UINT32 nb_rows,
UINT32 nb_cols,
make_method make_method,
UINT32 left_degree,
UINT32 seed,
bool no4cycle,
of_session_type type,
UINT8 verbosity);
/**
* This function fills a parity check matrix.
*
* @brief fills a parity check matrix
* @param m (IN) matrix to fill
* @param row_start (IN) number of row to start
* @param row_end (IN) number of row to stop
* @param col_start (IN) number of col to start
* @param col_end (IN) number of col to stop
* @param make_method (IN) method to fill the matrix
* @param left_degree (IN) number of "1" entry for each column
* @param no4cycle (IN) with or without cycles
* @param verbosity (IN) verbosity level
* @param stats (IN/OUT) memory statistics (can be NULL)
* @return pointer to the matrix
*/
of_mod2sparse* of_fill_regular_pchk_matrix (of_mod2sparse* m,
UINT32 row_start,
UINT32 row_end,
UINT32 col_start,
UINT32 col_end,
make_method make_method,
UINT32 left_degree,
bool no4cycle,
UINT8 verbosity);
/**
* This function creates a parity check matrix for 2D codec.
*
* @brief creates a parity check matrix for 2D codec
* @param nb_rows (IN) number of rows
* @param nb_cols (IN) number of cols
* @param type (IN) type of matrix
* @param verbosity (IN) verbosity level
* @param stats (IN/OUT) memory statistics (can be NULL)
* @return pointer to the matrix
*/
of_mod2sparse* of_create_2D_pchk_matrix (UINT32 nb_rows,
UINT32 nb_cols,
of_session_type type,
UINT8 verbosity);
/**
* This function fills a 2D parity check matrix.
*
* @brief fills a 2D parity check matrix
* @param m (IN/OUT) matrix to fill
* @param d (IN) number of rows
* @param l (IN) number of cols
* @param verbosity (IN) verbosity level
* @param stats (IN/OUT) memory statistics (can be NULL)
* @return pointer to the matrix
*/
of_mod2sparse* of_fill_2D_pchk_matrix (of_mod2sparse* m,
UINT32 d,
UINT32 l,
UINT8 verbosity);
#endif

View File

@@ -0,0 +1,147 @@
/* $Id: of_linear_binary_code.h 209 2014-12-12 18:49:58Z roca $ */
/*
* OpenFEC.org AL-FEC Library.
* (c) Copyright 2009 - 2011 INRIA - All rights reserved
* Contact: vincent.roca@inria.fr
*
* This software is governed by the CeCILL-C license under French law and
* abiding by the rules of distribution of free software. You can use,
* modify and/ or redistribute the software under the terms of the CeCILL-C
* license as circulated by CEA, CNRS and INRIA at the following URL
* "http://www.cecill.info".
*
* As a counterpart to the access to the source code and rights to copy,
* modify and redistribute granted by the license, users are provided only
* with a limited warranty and the software's author, the holder of the
* economic rights, and the successive licensors have only limited
* liability.
*
* In this respect, the user's attention is drawn to the risks associated
* with loading, using, modifying and/or developing or reproducing the
* software by the user in light of its specific status of free software,
* that may mean that it is complicated to manipulate, and that also
* therefore means that it is reserved for developers and experienced
* professionals having in-depth computer knowledge. Users are therefore
* encouraged to load and test the software's suitability as regards their
* requirements in conditions enabling the security of their systems and/or
* data to be ensured and, more generally, to use and operate it in the
* same conditions as regards security.
*
* The fact that you are presently reading this means that you have had
* knowledge of the CeCILL-C license and that you accept its terms.
*/
#ifndef LINEAR_BINARY_CODE_H
#define LINEAR_BINARY_CODE_H
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <string.h>
//#ifdef USE_NEON
//#include <arm_neon.h>
//#endif
#include "../of_openfec_api.h" // includes of_type.h, of_debug.h
#ifdef IL_SUPPORT
#include <IL/il.h>
#endif
#ifdef ASSEMBLY_SSE_OPT
#include <xmmintrin.h>
#endif
#include "../of_rand.h"
#include "../of_cb.h"
#include "../of_mem.h"
#include "of_symbol.h"
#include "../statistics/of_statistics.h"
#include "binary_matrix/of_matrix_sparse.h"
#include "binary_matrix/of_matrix_dense.h"
#include "of_create_pchk.h"
#include "binary_matrix/of_matrix_convert.h"
#include "binary_matrix/of_hamming_weight.h"
#include "binary_matrix/of_tools.h"
/**
* Linear-Binary-Code stable codec specific control block structure.
*/
typedef struct of_linear_binary_code_cb
{
/*****************************************************************************
* of_cb_t *
******************************************************************************/
of_codec_id_t codec_id; /* must begin with fec_codec_id */
of_codec_type_t codec_type; /* must be 2nd item */
UINT32 nb_source_symbols; /** k parameter (AKA code dimension). */
UINT32 nb_repair_symbols; /** r = n - k parameter. */
UINT32 encoding_symbol_length; /** symbol length. */
/*****************************************************************************/
UINT32 nb_total_symbols; /** n parameter (AKA code length). */
/* parity check matrix */
of_mod2sparse* pchk_matrix;
/** statistics for this codec instance. */
of_symbol_stats_op_t *stats_xor;
#ifdef OF_DEBUG
of_symbols_stats_t *stats_symbols;
#endif
UINT32 nb_source_symbol_ready; // Number of source symbols ready
UINT32 nb_repair_symbol_ready; // Number of parity symbols ready
#ifdef ML_DECODING
UINT32 *index_rows; // Indirection index to access initial m_chekValues array
UINT32 *index_cols; // Indirection index to access initial symbol array
UINT32 remain_cols; // Nb of non empty remaining cols in the future simplified matrix
UINT32 remain_rows; // Nb of non empty remaining rows in the future simplified matrix
of_mod2sparse *pchk_matrix_simplified; // Simplified Parity Check Matrix in sparse mode format
of_mod2sparse *original_pchkMatrix;
of_mod2sparse *pchk_matrix_gauss; // Parity Check matrix in sparse mode format.
UINT32 dec_step; // Current step in the Gauss decoding algorithm
UINT32 threshold_simplification;// threshold (number of symbols) above which we
// run the Gaussian Elimination algorithm
#endif
#ifdef OF_USE_DECODER /* { */
/** table of all check values, i.e. that contain the constant term of each equation. */
void** tab_const_term_of_equ;
/** table containing the number of encoding symbols of each equation. */
UINT16* tab_nb_enc_symbols_per_equ;
/** table containing the number of unknow symbols (i.e. neither received nor decoded
* at that time) of each equation. */
UINT16* tab_nb_unknown_symbols;
/** table containing the number of equations in which a repair symbol is included. */
UINT16* tab_nb_equ_for_repair;
void ** repair_symbols_values;
void ** tmp_tab_symbols;
UINT16 nb_tmp_symbols;
#endif /* } OF_USE_DECODER */
void **encoding_symbols_tab;
/** callbacks registered by the application. */
void* (*decoded_source_symbol_callback) (void *context,
UINT32 size, /* size of decoded source symbol */
UINT32 esi); /* encoding symbol ID in {0..k-1} */
void* (*decoded_repair_symbol_callback) (void *context,
UINT32 size, /* size of decoded repair symbol */
UINT32 esi); /* encoding symbol ID in {0..k-1} */
void* context_4_callback;
} of_linear_binary_code_cb_t;
#include "it_decoding/of_it_decoding.h"
#include "ml_decoding/of_ml_decoding.h"
#include "ml_decoding/of_ml_tool.h"
#endif

View File

@@ -0,0 +1,657 @@
/* $Id: of_symbol.c 206 2014-12-10 04:47:09Z roca $ */
/*
* OpenFEC.org AL-FEC Library.
* (c) Copyright 2009 - 2012 INRIA - All rights reserved
* Contact: vincent.roca@inria.fr
*
* This software is governed by the CeCILL-C license under French law and
* abiding by the rules of distribution of free software. You can use,
* modify and/ or redistribute the software under the terms of the CeCILL-C
* license as circulated by CEA, CNRS and INRIA at the following URL
* "http://www.cecill.info".
*
* As a counterpart to the access to the source code and rights to copy,
* modify and redistribute granted by the license, users are provided only
* with a limited warranty and the software's author, the holder of the
* economic rights, and the successive licensors have only limited
* liability.
*
* In this respect, the user's attention is drawn to the risks associated
* with loading, using, modifying and/or developing or reproducing the
* software by the user in light of its specific status of free software,
* that may mean that it is complicated to manipulate, and that also
* therefore means that it is reserved for developers and experienced
* professionals having in-depth computer knowledge. Users are therefore
* encouraged to load and test the software's suitability as regards their
* requirements in conditions enabling the security of their systems and/or
* data to be ensured and, more generally, to use and operate it in the
* same conditions as regards security.
*
* The fact that you are presently reading this means that you have had
* knowledge of the CeCILL-C license and that you accept its terms.
*/
#include "of_linear_binary_code.h"
#ifdef OF_USE_LINEAR_BINARY_CODES_UTILS
#ifndef OF_DEBUG
void of_add_from_multiple_symbols (void *to,
const void **from,
UINT32 from_size,
UINT32 symbol_size)
#else
void of_add_from_multiple_symbols (void *to,
const void **from,
UINT32 from_size,
UINT32 symbol_size,
UINT32 *op)
#endif
{
OF_ENTER_FUNCTION
#ifdef OF_DEBUG
if (op != NULL)
(*op)+=from_size;
#endif
UINT32 i;
//#ifndef ASSEMBLY_SSE_OPT /* { */
UINT32 symbolSize32;
UINT32 symbolSize32rem;
//printf("%i\n",from_size);
symbolSize32 = symbol_size >> 2;
symbolSize32rem = symbol_size % 4; // Remaining bytes when the symbol
// size is not multiple of 32 bits.
#if defined (__LP64__) || (__WORDSIZE == 64) // {
/*
* 64-bit machines
*/
UINT32 symbolSize64; // Size of symbols in 64-bit unit
// symbol_size is not necessarily a multiple of 8, but >> 3 will divide
// it by 8 and keep the integral part automatically.
symbolSize64 = symbol_size >> 3;
while (from_size >=8)
{
UINT64* t = (UINT64*) to; // to pointer to 64-bit integers
UINT64* ps1 = (UINT64*)from[0];
UINT64* ps2 = (UINT64*)from[1];
UINT64* ps3 = (UINT64*)from[2];
UINT64* ps4 = (UINT64*)from[3];
UINT64* ps5 = (UINT64*)from[4];
UINT64* ps6 = (UINT64*)from[5];
UINT64* ps7 = (UINT64*)from[6];
UINT64* ps8 = (UINT64*)from[7];
from_size-=8;
from+=8;
for (i = symbolSize64; i > 0; i--)
{
*t ^= (*ps1 ^ *ps2 ^ *ps3 ^ *ps4 ^ *ps5 ^ *ps6 ^ *ps7 ^ *ps8);
t++;
ps1++;
ps2++;
ps3++;
ps4++;
ps5++;
ps6++;
ps7++;
ps8++;
}
UINT32* t32 = (UINT32*) t; // to pointer to 32-bit integers
UINT32* ps1_32 = (UINT32*) ps1; // from pointer to 32-bit integers
UINT32* ps2_32 = (UINT32*) ps2; // from pointer to 32-bit integers
UINT32* ps3_32 = (UINT32*) ps3; // from pointer to 32-bit integers
UINT32* ps4_32 = (UINT32*) ps4; // from pointer to 32-bit integers
UINT32* ps5_32 = (UINT32*) ps5; // from pointer to 32-bit integers
UINT32* ps6_32 = (UINT32*) ps6; // from pointer to 32-bit integers
UINT32* ps7_32 = (UINT32*) ps7; // from pointer to 32-bit integers
UINT32* ps8_32 = (UINT32*) ps8; // from pointer to 32-bit integers
/* then perform a 32-bit XOR if needed... */
if ( (symbolSize64 << 1) < symbolSize32)
{
* (UINT32*) t32 ^= (* (UINT32*) ps1_32 ^ * (UINT32*) ps2_32 ^ * (UINT32*) ps3_32 ^ * (UINT32*) ps4_32 ^
* (UINT32*) ps5_32 ^ * (UINT32*) ps6_32 ^ * (UINT32*) ps7_32 ^ * (UINT32*) ps8_32);
ps1_32++;
ps2_32++;
ps3_32++;
ps4_32++;
ps5_32++;
ps6_32++;
ps7_32++;
ps8_32++;
t32++;
}
if (symbolSize32rem > 0)
{
for (i = 0; i < symbolSize32rem; i++)
{
* (UINT8*) ( (UINT8*) t32 + i) ^= ((* (UINT8*) ( (UINT8*) ps1_32 + i)) ^ (* (UINT8*) ( (UINT8*) ps2_32 + i) ) ^
(* (UINT8*) ( (UINT8*) ps3_32 + i) ) ^ (* (UINT8*) ( (UINT8*) ps4_32 + i) ) ^
(* (UINT8*) ( (UINT8*) ps5_32 + i) ) ^ (* (UINT8*) ( (UINT8*) ps6_32 + i) ) ^
(* (UINT8*) ( (UINT8*) ps7_32 + i) ) ^ (* (UINT8*) ( (UINT8*) ps8_32 + i) ) );
}
}
}
while (from_size >=4)
{
UINT64* t = (UINT64*) to; // to pointer to 64-bit integers
UINT64* ps1 = (UINT64*)from[0];
UINT64* ps2 = (UINT64*)from[1];
UINT64* ps3 = (UINT64*)from[2];
UINT64* ps4 = (UINT64*)from[3];
from_size-=4;
from+=4;
for (i = symbolSize64; i > 0; i--)
{
*t ^= (*ps1 ^ *ps2 ^ *ps3 ^ *ps4);
t++;
ps1++;
ps2++;
ps3++;
ps4++;
}
UINT32* t32 = (UINT32*) t; // to pointer to 32-bit integers
UINT32* ps1_32 = (UINT32*) ps1; // from pointer to 32-bit integers
UINT32* ps2_32 = (UINT32*) ps2; // from pointer to 32-bit integers
UINT32* ps3_32 = (UINT32*) ps3; // from pointer to 32-bit integers
UINT32* ps4_32 = (UINT32*) ps4; // from pointer to 32-bit integers
/* then perform a 32-bit XOR if needed... */
if ( (symbolSize64 << 1) < symbolSize32)
{
* (UINT32*) t32 ^= (* (UINT32*) ps1_32 ^ * (UINT32*) ps2_32 ^ * (UINT32*) ps3_32 ^ * (UINT32*) ps4_32 );
ps1_32++;
ps2_32++;
ps3_32++;
ps4_32++;
t32++;
}
if (symbolSize32rem > 0)
{
for (i = 0; i < symbolSize32rem; i++)
{
* (UINT8*) ( (UINT8*) t32 + i) ^= ((* (UINT8*) ( (UINT8*) ps1_32 + i)) ^ (* (UINT8*) ( (UINT8*) ps2_32 + i) ) ^
(* (UINT8*) ( (UINT8*) ps3_32 + i) ) ^ (* (UINT8*) ( (UINT8*) ps4_32 + i) ) );
}
}
}
while (from_size >=2)
{
UINT64* t = (UINT64*) to; // to pointer to 64-bit integers
UINT64* ps1 = (UINT64*)from[0];
UINT64* ps2 = (UINT64*)from[1];
from+=2;
from_size-=2;
for (i = symbolSize64; i > 0; i--)
{
*t ^= (*ps1 ^ *ps2);
t++;
ps1++;
ps2++;
}
UINT32* t32 = (UINT32*) t; // to pointer to 32-bit integers
UINT32* ps1_32 = (UINT32*) ps1; // from pointer to 32-bit integers
UINT32* ps2_32 = (UINT32*) ps2; // from pointer to 32-bit integers
/* then perform a 32-bit XOR if needed... */
if ( (symbolSize64 << 1) < symbolSize32)
{
* (UINT32*) t32 ^= (* (UINT32*) ps1_32 ^ * (UINT32*) ps2_32);
ps1_32++;
ps2_32++;
t32++;
}
if (symbolSize32rem > 0)
{
for (i = 0; i < symbolSize32rem; i++)
{
* (UINT8*) ( (UINT8*) t32 + i) ^= ((* (UINT8*) ( (UINT8*) ps1_32 + i)) ^ (* (UINT8*) ( (UINT8*) ps2_32 + i) ));
}
}
}
if (from_size == 0) return;
UINT64 *t = (UINT64*) to; // to pointer to 64-bit integers
UINT64 *f = (UINT64*) from[0]; // from pointer to 64-bit integers
for (i = symbolSize64; i > 0; i--)
{
*t ^= *f;
t++;
f++;
}
UINT32 *t32 = (UINT32*) t; // to pointer to 32-bit integers
UINT32 *f32 = (UINT32*) f; // from pointer to 32-bit integers
/* then perform a 32-bit XOR if needed... */
if ( (symbolSize64 << 1) < symbolSize32)
{
* (UINT32*) t32 ^= * (UINT32*) f32;
t32++;
f32++;
}
/* finally perform as many 8-bit XORs as needed if symbol size is not
* multiple of 32 bits... */
if (symbolSize32rem > 0)
{
for (i = 0; i < symbolSize32rem; i++)
{
* (UINT8*) ( (UINT8*) t32 + i) ^= * (UINT8*) ( (UINT8*) f32 + i);
}
}
#else //defined (__LP64__) || (__WORDSIZE == 64) } {
/*
* 32-bit machines
*/
UINT32 *t32 = (UINT32*) to; // to pointer to 32-bit integers
UINT32 *f32 = (UINT32*) from; // from pointer to 32-bit integers
/* First perform as many 32-bit XORs as needed... */
for (i = symbolSize32; i > 0; i--)
{
*t32 ^= *f32;
t32++;
f32++;
}
/* finally perform as many 8-bit XORs as needed if symbol size is not
* multiple of 32 bits... */
if (symbolSize32rem > 0)
{
for (i = 0; i < symbolSize32rem; i++)
{
* (UINT8*) ( (UINT8*) t32 + i) ^= * (UINT8*) ( (UINT8*) f32 + i);
}
}
#endif //defined (__LP64__) || (__WORDSIZE == 64) }
//#else /* } ASSEMBLY_SSE_OPT { */
//#endif
}
#ifndef OF_DEBUG
void of_add_to_multiple_symbols (void **to,
const void *from,
UINT32 to_size,
UINT32 symbol_size)
#else
void of_add_to_multiple_symbols (void **to,
const void *from,
UINT32 to_size,
UINT32 symbol_size,
UINT32 *op)
#endif
{
OF_ENTER_FUNCTION
#ifdef OF_DEBUG
if (op != NULL)
(*op) += to_size;
#endif
UINT32 i;
//#ifndef ASSEMBLY_SSE_OPT /* { */
UINT32 symbolSize32;
UINT32 symbolSize32rem;
symbolSize32 = symbol_size >> 2;
symbolSize32rem = symbol_size % 4; // Remaining bytes when the symbol
// size is not multiple of 32 bits.
#if defined (__LP64__) || (__WORDSIZE == 64) // {
/*
* 64-bit machines
*/
UINT32 symbolSize64; // Size of symbols in 64-bit unit
// symbol_size is not necessarily a multiple of 8, but >> 3 will divide
// it by 8 and keep the integral part automatically.
symbolSize64 = symbol_size >> 3;
UINT64 *pt1, *pt2, *pt3, *pt4, *pt5, *pt6, *pt7, *pt8, *from_s, from_value;
while (to_size >= 8)
{
from_s = (UINT64*) from; // to pointer to 64-bit integers
pt1 = (UINT64*)to[0];
pt2 = (UINT64*)to[1];
pt3 = (UINT64*)to[2];
pt4 = (UINT64*)to[3];
pt5 = (UINT64*)to[4];
pt6 = (UINT64*)to[5];
pt7 = (UINT64*)to[6];
pt8 = (UINT64*)to[7];
to += 8;
to_size -= 8;
for (i = symbolSize64; i > 0; i--)
{
from_value = *from_s;
*pt1 ^= from_value;
*pt2 ^= from_value ;
*pt3 ^= from_value ;
*pt4 ^= from_value ;
*pt5 ^= from_value ;
*pt6 ^= from_value ;
*pt7 ^= from_value ;
*pt8 ^= from_value ;
from_s++;
pt1++;
pt2++;
pt3++;
pt4++;
pt5++;
pt6++;
pt7++;
pt8++;
}
UINT32* from_s32 = (UINT32*) from_s; // to pointer to 32-bit integers
/* then perform a 32-bit XOR if needed... */
from_s32 = (UINT32*) from_s; // pointer to 32-bit integers
if ( (symbolSize64 << 1) < symbolSize32)
{
(* (UINT32*) pt1++) ^= *from_s32;
(* (UINT32*) pt2++) ^= *from_s32;
(* (UINT32*) pt3++) ^= *from_s32;
(* (UINT32*) pt4++) ^= *from_s32;
(* (UINT32*) pt5++) ^= *from_s32;
(* (UINT32*) pt6++) ^= *from_s32;
(* (UINT32*) pt7++) ^= *from_s32;
(* (UINT32*) pt8++) ^= *from_s32;
from_s32++;
}
if (symbolSize32rem > 0)
{
UINT8* s8;
for (i = 0; i < symbolSize32rem; i++)
{
s8 = ( (UINT8*) from_s32 + i);
(* (UINT8*) ( (UINT8*) pt1 + i)) ^= * (UINT8*) s8;
(* (UINT8*) ( (UINT8*) pt2 + i)) ^= * (UINT8*) s8;
(* (UINT8*) ( (UINT8*) pt3 + i)) ^= * (UINT8*) s8;
(* (UINT8*) ( (UINT8*) pt4 + i)) ^= * (UINT8*) s8;
(* (UINT8*) ( (UINT8*) pt5 + i)) ^= * (UINT8*) s8;
(* (UINT8*) ( (UINT8*) pt6 + i)) ^= * (UINT8*) s8;
(* (UINT8*) ( (UINT8*) pt7 + i)) ^= * (UINT8*) s8;
(* (UINT8*) ( (UINT8*) pt8 + i)) ^= * (UINT8*) s8;
}
}
}
while (to_size >= 4)
{
UINT32 *from_s32; // to pointer to 32-bit integers
from_s = (UINT64*) from; // to pointer to 64-bit integers
pt1 = (UINT64*)to[0];
pt2 = (UINT64*)to[1];
pt3 = (UINT64*)to[2];
pt4 = (UINT64*)to[3];
to += 4;
to_size -= 4;
for (i = symbolSize64; i > 0; i--)
{
from_value = *from_s;
*pt1 ^= from_value;
*pt2 ^= from_value;
*pt3 ^= from_value;
*pt4 ^= from_value;
from_s++;
pt1++;
pt2++;
pt3++;
pt4++;
}
/* then perform a 32-bit XOR if needed... */
from_s32 = (UINT32*) from_s;
if ( (symbolSize64 << 1) < symbolSize32)
{
(* (UINT32*) pt1++) ^= *from_s32;
(* (UINT32*) pt2++) ^= *from_s32;
(* (UINT32*) pt3++) ^= *from_s32;
(* (UINT32*) pt4++) ^= *from_s32;
from_s32++;
}
if (symbolSize32rem > 0)
{
UINT8 *s8;
for (i = 0; i < symbolSize32rem; i++)
{
s8 = ( (UINT8*) from_s32 + i);
(* (UINT8*) ( (UINT8*) pt1 + i)) ^= * (UINT8*) s8;
(* (UINT8*) ( (UINT8*) pt2 + i)) ^= * (UINT8*) s8;
(* (UINT8*) ( (UINT8*) pt3 + i)) ^= * (UINT8*) s8;
(* (UINT8*) ( (UINT8*) pt4 + i)) ^= * (UINT8*) s8;
}
}
}
while (to_size >= 2)
{
UINT32 *from_s32; // to pointer to 32-bit integers
from_s = (UINT64*) from; // to pointer to 64-bit integers
pt1 = (UINT64*)to[0];
pt2 = (UINT64*)to[1];
to += 2;
to_size -= 2;
for (i = symbolSize64; i > 0; i--)
{
*pt1 ^= *from_s ;
*pt2 ^= *from_s ;
from_s++;
pt1++;
pt2++;
}
/* then perform a 32-bit XOR if needed... */
from_s32 = (UINT32*) from_s; // pointer to 32-bit integers
if ( (symbolSize64 << 1) < symbolSize32)
{
(* (UINT32*) pt1++) ^= *from_s32;
(* (UINT32*) pt2++) ^= *from_s32;
from_s32++;
}
if (symbolSize32rem > 0)
{
UINT8 *s8;
for (i = 0; i < symbolSize32rem; i++)
{
s8 = ( (UINT8*) from_s32 + i);
(* (UINT8*) ( (UINT8*) pt1 + i)) ^= * (UINT8*) s8;
(* (UINT8*) ( (UINT8*) pt2 + i)) ^= * (UINT8*) s8;
}
}
}
if (to_size == 0) return;
UINT64 *t = (UINT64*) to[0]; // to pointer to 64-bit integers
UINT64 *f = (UINT64*) from; // from pointer to 64-bit integers
for (i = symbolSize64; i > 0; i--)
{
*t ^= *f;
t++;
f++;
}
UINT32* t32 = (UINT32*) t; // to pointer to 32-bit integers
UINT32 *f32 = (UINT32*) f; // from pointer to 32-bit integers
/* then perform a 32-bit XOR if needed... */
if ( (symbolSize64 << 1) < symbolSize32)
{
* (UINT32*) t32 ^= * (UINT32*) f32;
t32++;
f32++;
}
/* finally perform as many 8-bit XORs as needed if symbol size is not
* multiple of 32 bits... */
if (symbolSize32rem > 0)
{
for (i = 0; i < symbolSize32rem; i++)
{
* (UINT8*) ( (UINT8*) t32 + i) ^= * (UINT8*) ( (UINT8*) f32 + i);
}
}
#else //defined (__LP64__) || (__WORDSIZE == 64) } {
/*
* 32-bit machines
*/
UINT32 *t32 = (UINT32*) to; // to pointer to 32-bit integers
UINT32 *f32 = (UINT32*) from; // from pointer to 32-bit integers
/* First perform as many 32-bit XORs as needed... */
for (i = symbolSize32; i > 0; i--)
{
*t32 ^= *f32;
t32++;
f32++;
}
/* finally perform as many 8-bit XORs as needed if symbol size is not
* multiple of 32 bits... */
if (symbolSize32rem > 0)
{
for (i = 0; i < symbolSize32rem; i++)
{
* (UINT8*) ( (UINT8*) t32 + i) ^= * (UINT8*) ( (UINT8*) f32 + i);
}
}
#endif //defined (__LP64__) || (__WORDSIZE == 64) }
//#else /* } ASSEMBLY_SSE_OPT { */
//#endif /* } ASSEMBLY_SSE_OPT */
}
#ifdef OF_DEBUG
void of_add_to_symbol (void *to,
const void *from,
UINT32 symbol_size,
UINT32 *op)
#else
void of_add_to_symbol (void *to,
const void *from,
UINT32 symbol_size)
#endif
{
//OF_ENTER_FUNCTION
UINT32 i;
#ifdef OF_DEBUG
if (op != NULL)
(*op)++;
#endif
#ifndef ASSEMBLY_SSE_OPT /* { */
UINT32 symbolSize32;
UINT32 symbolSize32rem;
symbolSize32 = symbol_size >> 2;
symbolSize32rem = symbol_size % 4; // Remaining bytes when the symbol
// size is not multiple of 32 bits.
#if defined (__LP64__) || (__WORDSIZE == 64) // {
/*
* 64-bit machines
*/
UINT32 symbolSize64; // Size of symbols in 64-bit unit
// symbol_size is not necessarily a multiple of 8, but >> 3 will divide
// it by 8 and keep the integral part automatically.
symbolSize64 = symbol_size >> 3;
/* First perform as many 64-bit XORs as needed... */
UINT64 *t = (UINT64*) to; // to pointer to 64-bit integers
UINT64 *f = (UINT64*) from; // from pointer to 64-bit integers
for (i = symbolSize64; i > 0; i--)
{
*t ^= *f;
t++;
f++;
}
UINT32 *t32 = (UINT32*) t; // to pointer to 32-bit integers
UINT32 *f32 = (UINT32*) f; // from pointer to 32-bit integers
/* then perform a 32-bit XOR if needed... */
if ( (symbolSize64 << 1) < symbolSize32)
{
* (UINT32*) t32 ^= * (UINT32*) f32;
t32++;
f32++;
}
/* finally perform as many 8-bit XORs as needed if symbol size is not
* multiple of 32 bits... */
if (symbolSize32rem > 0)
{
for (i = 0; i < symbolSize32rem; i++)
{
* (UINT8*) ( (UINT8*) t32 + i) ^= * (UINT8*) ( (UINT8*) f32 + i);
}
}
#else //defined (__LP64__) || (__WORDSIZE == 64) } {
/*
* 32-bit machines
*/
UINT32 *t32 = (UINT32*) to; // to pointer to 32-bit integers
UINT32 *f32 = (UINT32*) from; // from pointer to 32-bit integers
/* First perform as many 32-bit XORs as needed... */
for (i = symbolSize32; i > 0; i--)
{
*t32 ^= *f32;
t32++;
f32++;
}
/* finally perform as many 8-bit XORs as needed if symbol size is not
* multiple of 32 bits... */
if (symbolSize32rem > 0)
{
for (i = 0; i < symbolSize32rem; i++)
{
* (UINT8*) ( (UINT8*) t32 + i) ^= * (UINT8*) ( (UINT8*) f32 + i);
}
}
#endif //defined (__LP64__) || (__WORDSIZE == 64) }
#else /* } ASSEMBLY_SSE_OPT { */
/*
* machine with SSE capable CPU
* Use assembly language to XOR two 128 bit registers at a time.
*/
UINT32 symbolSize32rem = symbol_size % 16; // Remaining bytes when the symbol
// size is not multiple of 32 bits.
UINT32 symbolSize128;
symbolSize128 = symbol_size >> 4;
float *dst128;
float *src128;
dst128 = (float *) to;
src128 = (float *) from;
__m128 a, b;
for (i = symbolSize128 ; i-- ;)
{
a = _mm_load_ps (dst128);
b = _mm_load_ps (src128);
a = _mm_xor_ps (a, b);
_mm_store_ps (dst128, a);
dst128 += 4;
src128 += 4;
}
if (symbolSize32rem > 0)
{
for (i = 0; i < symbolSize32rem; i++)
{
* (UINT8*) ( (UINT8*) dst128 + i) ^= * (UINT8*) ( (UINT8*) src128 + i);
}
}
#endif /* } ASSEMBLY_SSE_OPT */
OF_EXIT_FUNCTION
}
void of_print_xor_symbols_statistics (of_symbol_stats_op_t *xor)
{
if (xor != NULL)
{
OF_TRACE_LVL(0, ("XOR stats:\n\tnb_xor_for_IT=%u nb_xor_for_ML=%u\n",
xor->nb_xor_for_IT, xor->nb_xor_for_ML))
}
}
#endif //OF_USE_LINEAR_BINARY_CODES_UTILS

View File

@@ -0,0 +1,155 @@
/* $Id: of_symbol.h 198 2014-07-17 08:41:01Z roca $ */
/*
* OpenFEC.org AL-FEC Library.
* (c) Copyright 2009 - 2012 INRIA - All rights reserved
* Contact: vincent.roca@inria.fr
*
* This software is governed by the CeCILL-C license under French law and
* abiding by the rules of distribution of free software. You can use,
* modify and/ or redistribute the software under the terms of the CeCILL-C
* license as circulated by CEA, CNRS and INRIA at the following URL
* "http://www.cecill.info".
*
* As a counterpart to the access to the source code and rights to copy,
* modify and redistribute granted by the license, users are provided only
* with a limited warranty and the software's author, the holder of the
* economic rights, and the successive licensors have only limited
* liability.
*
* In this respect, the user's attention is drawn to the risks associated
* with loading, using, modifying and/or developing or reproducing the
* software by the user in light of its specific status of free software,
* that may mean that it is complicated to manipulate, and that also
* therefore means that it is reserved for developers and experienced
* professionals having in-depth computer knowledge. Users are therefore
* encouraged to load and test the software's suitability as regards their
* requirements in conditions enabling the security of their systems and/or
* data to be ensured and, more generally, to use and operate it in the
* same conditions as regards security.
*
* The fact that you are presently reading this means that you have had
* knowledge of the CeCILL-C license and that you accept its terms.
*/
#ifndef OF_SYMBOL
#define OF_SYMBOL
#ifdef OF_USE_LINEAR_BINARY_CODES_UTILS
typedef struct of_symbol_stats_op
{
UINT32 nb_xor_for_IT;
UINT32 nb_xor_for_ML;
} of_symbol_stats_op_t;
/**
* @brief check if the symbol number "new_symbol_esi" is a source symbol
* @param ofcb (IN) Pointer to the control block.
* @param new_symbol_esi (IN) encoding symbol ID
* @return Error status.
*/
#define of_is_source_symbol(ofcb,new_symbol_esi) (((new_symbol_esi) < (ofcb)->nb_source_symbols) ? true : false)
/*
* @brief check if the symbol number "new_symbol_esi" is a repair symbol
* @param ofcb (IN) Pointer to the control block.
* @param new_symbol_esi (IN) encoding symbol ID
* @return Error status.
*/
#define of_is_repair_symbol(ofcb,new_symbol_esi) (((new_symbol_esi) < (ofcb)->nb_source_symbols) ? false : true)
/**
* @brief get the encoding symbol ID of a matrix column
* @param ofcb (IN) Pointer to the control block.
* @param matrix_col (IN) number of the matrix column
* @return Error status.
*/
#define of_get_symbol_esi(ofcb,matrix_col) (((matrix_col) < (ofcb)->nb_repair_symbols) ? (INT32)((matrix_col) + (ofcb)->nb_source_symbols) : (INT32)((matrix_col) - (ofcb)->nb_repair_symbols))
/**
* @brief get symbol matrix column
* @param ofcb (IN) Pointer to the control block.
* @param esi (IN) encoding symbol ID
* @return Error status.
*/
#define of_get_symbol_col(ofcb,esi) (((esi) < (ofcb)->nb_source_symbols) ? (INT32)((esi) + (ofcb)->nb_repair_symbols) : (INT32)((esi) - (ofcb)->nb_source_symbols))
/**
* Compute the XOR sum of two symbols: to = to + from.
* This function must be highly optimized, since it is one of the most computationally
* expensive ones. These optimizations depend on the target platform, from both the
* hardware and software point of views.
*
* @param to (IN/OUT) source symbol.
* @param from (IN) symbol added to the source symbol.
* @param symbol_size (IN) size in byte
*/
#ifdef OF_DEBUG
void of_add_to_symbol (void *to,
const void *from,
UINT32 symbol_size,
UINT32*);
#else
void of_add_to_symbol (void *to,
const void *from,
UINT32 symbol_size);
#endif
/**
* Compute the XOR sum of several symbols: to = to + from1 + from2 + ....
* This function must be highly optimized, since it is one of the most computationally
* expensive ones. These optimizations depend on the target platform, from both the
* hardware and software point of views.
*
* @param to (IN/OUT) source symbol.
* @param from (IN) symbols added to the source symbol.
* @param from_size (IN) number of "from" symbols
* @param symbol_size (IN) size in byte
*/
#ifdef OF_DEBUG
void of_add_from_multiple_symbols (void *to,
const void **from,
UINT32 from_size,
UINT32 symbol_size,
UINT32*);
#else
void of_add_from_multiple_symbols (void *to,
const void **from,
UINT32 from_size,
UINT32 symbol_size);
#endif
/**
* Compute the XOR sum of several symbols: to1 = to1 + from; to2 = to2 + from; ...
* This function must be highly optimized, since it is one of the most computationally
* expensive ones. These optimizations depend on the target platform, from both the
* hardware and software point of views.
*
* @param to (IN/OUT) source symbols.
* @param from (IN) symbol added to the source symbol.
* @param to_size (IN) number of "to" symbols
* @param symbol_size (IN) size in byte
*/
#ifdef OF_DEBUG
void of_add_to_multiple_symbols (void **to,
const void *from,
UINT32 to_size,
UINT32 symbol_size,
UINT32*);
#else
void of_add_to_multiple_symbols (void **to,
const void *from,
UINT32 to_size,
UINT32 symbol_size);
#endif
#ifdef OF_DEBUG
void of_print_xor_symbols_statistics(of_symbol_stats_op_t*);
#endif
#endif //OF_USE_LINEAR_BINARY_CODES_UTILS
#endif //OF_SYMBOL

View File

@@ -0,0 +1,54 @@
/* $Id: of_cb.h 72 2012-04-13 13:27:26Z detchart $ */
/*
* OpenFEC.org AL-FEC Library.
* (c) Copyright 2009 - 2012 INRIA - All rights reserved
* Contact: vincent.roca@inria.fr
*
* This software is governed by the CeCILL-C license under French law and
* abiding by the rules of distribution of free software. You can use,
* modify and/ or redistribute the software under the terms of the CeCILL-C
* license as circulated by CEA, CNRS and INRIA at the following URL
* "http://www.cecill.info".
*
* As a counterpart to the access to the source code and rights to copy,
* modify and redistribute granted by the license, users are provided only
* with a limited warranty and the software's author, the holder of the
* economic rights, and the successive licensors have only limited
* liability.
*
* In this respect, the user's attention is drawn to the risks associated
* with loading, using, modifying and/or developing or reproducing the
* software by the user in light of its specific status of free software,
* that may mean that it is complicated to manipulate, and that also
* therefore means that it is reserved for developers and experienced
* professionals having in-depth computer knowledge. Users are therefore
* encouraged to load and test the software's suitability as regards their
* requirements in conditions enabling the security of their systems and/or
* data to be ensured and, more generally, to use and operate it in the
* same conditions as regards security.
*
* The fact that you are presently reading this means that you have had
* knowledge of the CeCILL-C license and that you accept its terms.
*/
#ifndef OF_CB
#define OF_CB
/**
* @struct of_cb_t
* @brief Generic (empty) control block for a codec.
*
* This is the structure where all the pieces
* of information related to a codec instanciation are stored.
* All the instanciated control block structures MUST begin with the entries listed below.
*/
typedef struct of_cb
{
of_codec_id_t codec_id;
of_codec_type_t codec_type;
UINT32 nb_source_symbols;
UINT32 nb_repair_symbols;
UINT32 encoding_symbol_length;
} of_cb_t;
#endif //OF_CB

View File

@@ -0,0 +1,104 @@
/* $Id: of_debug.h 72 2012-04-13 13:27:26Z detchart $ */
/*
* OpenFEC.org AL-FEC Library.
* (c) Copyright 2009 - 2012 INRIA - All rights reserved
* Contact: vincent.roca@inria.fr
*
* This software is governed by the CeCILL-C license under French law and
* abiding by the rules of distribution of free software. You can use,
* modify and/ or redistribute the software under the terms of the CeCILL-C
* license as circulated by CEA, CNRS and INRIA at the following URL
* "http://www.cecill.info".
*
* As a counterpart to the access to the source code and rights to copy,
* modify and redistribute granted by the license, users are provided only
* with a limited warranty and the software's author, the holder of the
* economic rights, and the successive licensors have only limited
* liability.
*
* In this respect, the user's attention is drawn to the risks associated
* with loading, using, modifying and/or developing or reproducing the
* software by the user in light of its specific status of free software,
* that may mean that it is complicated to manipulate, and that also
* therefore means that it is reserved for developers and experienced
* professionals having in-depth computer knowledge. Users are therefore
* encouraged to load and test the software's suitability as regards their
* requirements in conditions enabling the security of their systems and/or
* data to be ensured and, more generally, to use and operate it in the
* same conditions as regards security.
*
* The fact that you are presently reading this means that you have had
* knowledge of the CeCILL-C license and that you accept its terms.
*/
#ifndef OF_DEBUG_H
#define OF_DEBUG_H /* { */
/****** general macros ******/
#define OF_ENTER_FUNCTION OF_TRACE_LVL(2, ("-> %s:\n",__FUNCTION__))
#define OF_EXIT_FUNCTION OF_TRACE_LVL(2, ("<- %s:\n",__FUNCTION__))
/*
* Message print macros exist into two categories:
* - OF_PRINT_*: print either to stdout or stderr, possibly controlled by a verbosity
* level in case of OF_PRINT_LVL. The printf code is always compiled.
* - OF_TRACE_LVL: print debug messages, possibly controlled by a verbosity level.
* The printf code is only compiled in OF_DEBUG mode, there's no code otherwise.
*/
/**
* Print to stdout.
*/
#define OF_PRINT(a) { printf a; fflush(stdout); }
/**
* Print to stdout with a verbosity level.
*/
#define OF_PRINT_LVL(l, a) if (of_verbosity >= (l)) { \
printf a; \
fflush(stdout); \
}
/**
* Print to stderr.
*/
#define OF_PRINT_ERROR(a) { fprintf(stderr, "ERROR in \"%s\":%d:%s(): ", \
__FILE__, __LINE__, __FUNCTION__); \
printf a; fflush(stderr); fflush(stdout); }
#define OF_PRINT_FAILURE(a) { fprintf(stderr, "Failure in \"%s\":%d:%s(): ", \
__FILE__, __LINE__, __FUNCTION__); \
printf a; fflush(stderr); fflush(stdout); }
/**
* Trace with a level in OF_DEBUG mode only
*/
#ifdef OF_DEBUG
#define OF_TRACE_LVL(l, a) if (of_verbosity >= (l)) { \
printf a; \
fflush(stdout); \
}
#else
#define OF_TRACE_LVL(l, a)
#endif
/**
* assertion in OF_DEBUG mode
*/
#ifdef ASSERT
#undef ASSERT
#endif
#ifdef OF_DEBUG
#define ASSERT(c) if (!(c)) { \
fprintf(stderr, "ASSERT [%s:%d] failed\n", \
__FILE__, __LINE__); \
fflush(stderr); \
exit(-1); \
}
#else /* OF_DEBUG */
#define ASSERT(c)
#endif /* OF_DEBUG */
#endif /* } OF_DEBUG_H */

View File

@@ -0,0 +1,84 @@
/* $Id: of_mem.c 182 2014-07-15 09:27:51Z roca $ */
/*
* OpenFEC.org AL-FEC Library.
* (c) Copyright 2009 - 2011 INRIA - All rights reserved
* Contact: vincent.roca@inria.fr
*
* This software is governed by the CeCILL-C license under French law and
* abiding by the rules of distribution of free software. You can use,
* modify and/ or redistribute the software under the terms of the CeCILL-C
* license as circulated by CEA, CNRS and INRIA at the following URL
* "http://www.cecill.info".
*
* As a counterpart to the access to the source code and rights to copy,
* modify and redistribute granted by the license, users are provided only
* with a limited warranty and the software's author, the holder of the
* economic rights, and the successive licensors have only limited
* liability.
*
* In this respect, the user's attention is drawn to the risks associated
* with loading, using, modifying and/or developing or reproducing the
* software by the user in light of its specific status of free software,
* that may mean that it is complicated to manipulate, and that also
* therefore means that it is reserved for developers and experienced
* professionals having in-depth computer knowledge. Users are therefore
* encouraged to load and test the software's suitability as regards their
* requirements in conditions enabling the security of their systems and/or
* data to be ensured and, more generally, to use and operate it in the
* same conditions as regards security.
*
* The fact that you are presently reading this means that you have had
* knowledge of the CeCILL-C license and that you accept its terms.
*/
#include <stdio.h>
#include <stdlib.h>
#include "of_openfec_api.h"
void* of_malloc (size_t size)
{
return malloc (size);
}
void* of_calloc (size_t nmemb,
size_t size)
{
return calloc (nmemb, size);
}
void* of_realloc (void* ptr,
size_t size)
{
return realloc (ptr, size);
}
void of_free (void* ptr)
{
if (ptr) {
free (ptr);
}
}
#if 0
void of_dump_buffer (char* buf, UINT32 size)
{
UINT32 i;
UINT32 *s32;
if (size % 4 != 0)
{
size = (size % 4) * 4;
}
for (i = 0, s32 = (UINT32*)buf; i < size; i += 4, s32++)
{
printf ("%08x ", *s32);
}
printf ("\n");
}
#endif

View File

@@ -0,0 +1,78 @@
/* $Id: of_mem.h 186 2014-07-16 07:17:53Z roca $ */
/*
* OpenFEC.org AL-FEC Library.
* (c) Copyright 2009 - 2012 INRIA - All rights reserved
* Contact: vincent.roca@inria.fr
*
* This software is governed by the CeCILL-C license under French law and
* abiding by the rules of distribution of free software. You can use,
* modify and/ or redistribute the software under the terms of the CeCILL-C
* license as circulated by CEA, CNRS and INRIA at the following URL
* "http://www.cecill.info".
*
* As a counterpart to the access to the source code and rights to copy,
* modify and redistribute granted by the license, users are provided only
* with a limited warranty and the software's author, the holder of the
* economic rights, and the successive licensors have only limited
* liability.
*
* In this respect, the user's attention is drawn to the risks associated
* with loading, using, modifying and/or developing or reproducing the
* software by the user in light of its specific status of free software,
* that may mean that it is complicated to manipulate, and that also
* therefore means that it is reserved for developers and experienced
* professionals having in-depth computer knowledge. Users are therefore
* encouraged to load and test the software's suitability as regards their
* requirements in conditions enabling the security of their systems and/or
* data to be ensured and, more generally, to use and operate it in the
* same conditions as regards security.
*
* The fact that you are presently reading this means that you have had
* knowledge of the CeCILL-C license and that you accept its terms.
*/
/*
* This module implements memory management operations.
* In debug mode, it also performs memory usage statistics.
*/
#ifndef OF_MEM_H
#define OF_MEM_H
/**
* @fn inline void* of_malloc (size_t size)
* @brief do a malloc
* @param size (IN) size of wanted allocated area.
* @return allocated pointer or NULL if error.
*/
void* of_malloc (size_t size);
/**
* @fn inline void* of_calloc (size_t nmemb,size_t size)
* @brief do a calloc
* @param nmemb (IN) number of elements
* @param size (IN) size of wanted allocated area.
* @return allocated pointer or NULL if error.
*/
void* of_calloc (size_t nmemb, size_t size);
/**
* @fn inline void* of_realloc (void* ptr, size_t size)
* @brief realloc memory adress
* @param ptr (IN) pointer to realloc
* @param size (IN) size of wanted allocated area.
* @return allocated pointer or NULL if error.
*/
void* of_realloc (void* ptr, size_t size);
/**
* @fn inline void of_free (void* ptr)
* @brief free amemory adress
* @param ptr (IN) pointer to free
* @return void
*/
void of_free (void* ptr);
#endif //OF_MEM_H

View File

@@ -0,0 +1,800 @@
/* $Id: of_openfec_api.c 214 2014-12-12 23:14:02Z roca $ */
/*
* OpenFEC.org AL-FEC Library.
* (c) Copyright 2009 - 2012 INRIA - All rights reserved
* Contact: vincent.roca@inria.fr
*
* This software is governed by the CeCILL-C license under French law and
* abiding by the rules of distribution of free software. You can use,
* modify and/ or redistribute the software under the terms of the CeCILL-C
* license as circulated by CEA, CNRS and INRIA at the following URL
* "http://www.cecill.info".
*
* As a counterpart to the access to the source code and rights to copy,
* modify and redistribute granted by the license, users are provided only
* with a limited warranty and the software's author, the holder of the
* economic rights, and the successive licensors have only limited
* liability.
*
* In this respect, the user's attention is drawn to the risks associated
* with loading, using, modifying and/or developing or reproducing the
* software by the user in light of its specific status of free software,
* that may mean that it is complicated to manipulate, and that also
* therefore means that it is reserved for developers and experienced
* professionals having in-depth computer knowledge. Users are therefore
* encouraged to load and test the software's suitability as regards their
* requirements in conditions enabling the security of their systems and/or
* data to be ensured and, more generally, to use and operate it in the
* same conditions as regards security.
*
* The fact that you are presently reading this means that you have had
* knowledge of the CeCILL-C license and that you accept its terms.
*/
#include "of_openfec_api.h"
#ifdef OF_USE_REED_SOLOMON_CODEC
#include "../lib_stable/reed-solomon_gf_2_8/of_reed-solomon_gf_2_8_includes.h"
#endif
#ifdef OF_USE_REED_SOLOMON_2_M_CODEC
#include "../lib_stable/reed-solomon_gf_2_m/of_reed-solomon_gf_2_m_includes.h"
#endif
#ifdef OF_USE_LDPC_STAIRCASE_CODEC
#include "../lib_stable/ldpc_staircase/of_ldpc_includes.h"
#endif
#ifdef OF_USE_2D_PARITY_MATRIX_CODEC
#include "../lib_stable/2d_parity_matrix/of_2d_parity_includes.h"
#endif
#ifdef OF_USE_LDPC_FROM_FILE_CODEC
#include "../lib_advanced/ldpc_from_file/of_ldpc_ff_includes.h"
#endif
UINT32 of_verbosity;
of_status_t of_create_codec_instance(of_session_t** ses, of_codec_id_t codec_id,
of_codec_type_t codec_type,
UINT32 verbosity) {
of_status_t status;
OF_ENTER_FUNCTION
of_verbosity = verbosity;
/**
* each codec must realloc control block.
*/
(*ses) = of_calloc(1, sizeof(of_cb_t));
if (*ses == NULL) {
OF_PRINT_ERROR(("Error, of_calloc failed\n"))
goto error2;
}
((of_cb_t*)(*ses))->codec_type = codec_type;
((of_cb_t*)(*ses))->codec_id = codec_id;
switch (codec_id) {
#ifdef OF_USE_REED_SOLOMON_CODEC
case OF_CODEC_REED_SOLOMON_GF_2_8_STABLE:
status = of_rs_create_codec_instance((of_rs_cb_t**)ses);
break;
#endif
#ifdef OF_USE_REED_SOLOMON_2_M_CODEC
case OF_CODEC_REED_SOLOMON_GF_2_M_STABLE:
status = of_rs_2_m_create_codec_instance((of_rs_2_m_cb_t**)ses);
break;
#endif
#ifdef OF_USE_LDPC_STAIRCASE_CODEC
case OF_CODEC_LDPC_STAIRCASE_STABLE:
status = of_ldpc_staircase_create_codec_instance(
(of_ldpc_staircase_cb_t**)ses);
break;
#endif
#ifdef OF_USE_2D_PARITY_MATRIX_CODEC
case OF_CODEC_2D_PARITY_MATRIX_STABLE:
status = of_2d_parity_create_codec_instance((of_2d_parity_cb_t**)ses);
break;
#endif
#ifdef OF_USE_LDPC_FROM_FILE_CODEC
case OF_CODEC_LDPC_FROM_FILE_ADVANCED:
status = of_ldpc_ff_create_codec_instance((of_ldpc_ff_cb_t**)ses);
break;
#endif
default:
OF_PRINT_ERROR(("Error, codec %d non available\n", codec_id))
goto error;
}
OF_EXIT_FUNCTION
return status;
error:
of_free(*ses);
*ses = NULL;
error2:
OF_EXIT_FUNCTION
return OF_STATUS_FATAL_ERROR;
}
of_status_t of_release_codec_instance(of_session_t* ses) {
of_status_t status;
OF_ENTER_FUNCTION
if (ses != NULL) {
switch (((of_cb_t*)ses)->codec_id) {
#ifdef OF_USE_REED_SOLOMON_CODEC
case OF_CODEC_REED_SOLOMON_GF_2_8_STABLE:
status = of_rs_release_codec_instance((of_rs_cb_t*)ses);
break;
#endif
#ifdef OF_USE_REED_SOLOMON_2_M_CODEC
case OF_CODEC_REED_SOLOMON_GF_2_M_STABLE:
status = of_rs_2_m_release_codec_instance((of_rs_2_m_cb_t*)ses);
break;
#endif
#ifdef OF_USE_LDPC_STAIRCASE_CODEC
case OF_CODEC_LDPC_STAIRCASE_STABLE:
status = of_ldpc_staircase_release_codec_instance(
(of_ldpc_staircase_cb_t*)ses);
break;
#endif
#ifdef OF_USE_2D_PARITY_MATRIX_CODEC
case OF_CODEC_2D_PARITY_MATRIX_STABLE:
status = of_2d_parity_release_codec_instance((of_2d_parity_cb_t*)ses);
break;
#endif
#ifdef OF_USE_LDPC_FROM_FILE_CODEC
case OF_CODEC_LDPC_FROM_FILE_ADVANCED:
status = of_ldpc_staircase_release_codec_instance(
(of_ldpc_staircase_cb_t*)ses);
break;
#endif
default:
OF_PRINT_ERROR(
("Error, codec %d non available\n", ((of_cb_t*)ses)->codec_id))
goto error;
}
of_free(ses);
ses = NULL;
}
OF_EXIT_FUNCTION
return status;
error:
OF_EXIT_FUNCTION
return OF_STATUS_FATAL_ERROR;
}
of_status_t of_set_fec_parameters(of_session_t* ses, of_parameters_t* params) {
of_status_t status;
OF_ENTER_FUNCTION
if ((ses == NULL) || (params == NULL)) {
OF_PRINT_ERROR(("Error, bad ses or params pointer (null)\n"))
goto error;
}
#ifdef OF_USE_LDPC_FROM_FILE_CODEC
if (((of_cb_t*)ses)->codec_id != OF_CODEC_LDPC_FROM_FILE_ADVANCED &&
((params->nb_source_symbols <= 0) ||
(params->nb_repair_symbols <= 0)) ||
(params->encoding_symbol_length <= 0)) {
OF_PRINT_ERROR(("Error, bad parameters:"))
if (params->nb_source_symbols <= 0) {
OF_PRINT_ERROR(("nb_source_symbols %d <= 0\n", params->nb_source_symbols))
}
if (params->nb_repair_symbols <= 0) {
OF_PRINT_ERROR(("nb_repair_symbols %d <= 0\n", params->nb_repair_symbols))
}
if (params->encoding_symbol_length <= 0) {
OF_PRINT_ERROR(
("encoding_symbol_length %d <= 0\n", params->encoding_symbol_length))
}
goto error;
}
#endif
switch (((of_cb_t*)ses)->codec_id) {
#ifdef OF_USE_REED_SOLOMON_CODEC
case OF_CODEC_REED_SOLOMON_GF_2_8_STABLE:
status = of_rs_set_fec_parameters((of_rs_cb_t*)ses,
(of_rs_parameters_t*)params);
break;
#endif
#ifdef OF_USE_REED_SOLOMON_2_M_CODEC
case OF_CODEC_REED_SOLOMON_GF_2_M_STABLE:
status = of_rs_2_m_set_fec_parameters((of_rs_2_m_cb_t*)ses,
(of_rs_2_m_parameters_t*)params);
break;
#endif
#ifdef OF_USE_LDPC_STAIRCASE_CODEC
case OF_CODEC_LDPC_STAIRCASE_STABLE:
status = of_ldpc_staircase_set_fec_parameters(
(of_ldpc_staircase_cb_t*)ses, (of_ldpc_parameters_t*)params);
break;
#endif
#ifdef OF_USE_2D_PARITY_MATRIX_CODEC
case OF_CODEC_2D_PARITY_MATRIX_STABLE:
status = of_2d_parity_set_fec_parameters(
(of_2d_parity_cb_t*)ses, (of_2d_parity_parameters_t*)params);
break;
#endif
#ifdef OF_USE_LDPC_FROM_FILE_CODEC
case OF_CODEC_LDPC_FROM_FILE_ADVANCED:
status = of_ldpc_ff_set_fec_parameters((of_ldpc_ff_cb_t*)ses,
(of_ldpc_ff_parameters_t*)params);
break;
#endif
default:
OF_PRINT_ERROR(
("Error, codec %d non available\n", ((of_cb_t*)ses)->codec_id))
goto error;
}
OF_EXIT_FUNCTION
return status;
error:
OF_EXIT_FUNCTION
return OF_STATUS_FATAL_ERROR;
}
of_status_t of_set_callback_functions(
of_session_t* ses,
void* (*decoded_source_symbol_callback)(void* context, UINT32 size,
UINT32 esi),
void* (*decoded_repair_symbol_callback)(void* context, UINT32 size,
UINT32 esi),
void* context_4_callback) {
of_status_t status;
OF_ENTER_FUNCTION
if (ses == NULL) {
OF_PRINT_ERROR(("Error, bad ses pointer (null)\n"))
goto error;
}
if ((decoded_source_symbol_callback == NULL) &&
(decoded_repair_symbol_callback == NULL)) {
OF_PRINT_ERROR(
("decoded_source_symbol_callback and decoded_repair_symbol_callback or "
"both NULL\n"))
goto error;
}
switch (((of_cb_t*)ses)->codec_id) {
#ifdef OF_USE_REED_SOLOMON_CODEC
case OF_CODEC_REED_SOLOMON_GF_2_8_STABLE:
status = of_rs_set_callback_functions(
(of_rs_cb_t*)ses, decoded_source_symbol_callback,
decoded_repair_symbol_callback, context_4_callback);
break;
#endif
#ifdef OF_USE_REED_SOLOMON_2_M_CODEC
case OF_CODEC_REED_SOLOMON_GF_2_M_STABLE:
status = of_rs_2_m_set_callback_functions(
(of_rs_2_m_cb_t*)ses, decoded_source_symbol_callback,
decoded_repair_symbol_callback, context_4_callback);
break;
#endif
#ifdef OF_USE_LDPC_STAIRCASE_CODEC
case OF_CODEC_LDPC_STAIRCASE_STABLE:
status = of_ldpc_staircase_set_callback_functions(
(of_ldpc_staircase_cb_t*)ses, decoded_source_symbol_callback,
decoded_repair_symbol_callback, context_4_callback);
break;
#endif
#ifdef OF_USE_2D_PARITY_MATRIX_CODEC
case OF_CODEC_2D_PARITY_MATRIX_STABLE:
status = of_2d_parity_set_callback_functions(
(of_2d_parity_cb_t*)ses, decoded_source_symbol_callback,
decoded_repair_symbol_callback, context_4_callback);
break;
#endif
#ifdef OF_USE_LDPC_FROM_FILE_CODEC
case OF_CODEC_LDPC_FROM_FILE_ADVANCED:
status = of_ldpc_staircase_set_callback_functions(
(of_ldpc_staircase_cb_t*)ses, decoded_source_symbol_callback,
decoded_repair_symbol_callback, context_4_callback);
break;
#endif
default:
OF_PRINT_ERROR(
("Error, codec %d non available\n", ((of_cb_t*)ses)->codec_id))
goto error;
}
OF_EXIT_FUNCTION
return status;
error:
OF_EXIT_FUNCTION
return OF_STATUS_FATAL_ERROR;
}
of_status_t of_more_about(of_session_t* ses, char** version_str,
char** copyrights_str) {
OF_ENTER_FUNCTION
static char of_version_string[] =
"OpenFEC.org - Version 1.4.2, December 16th, 2014\n";
static char of_copyrights_string[] =
"\n\
OpenFEC.org - Because free, open source AL-FEC codes and codecs matter\n\
Copyright (c) 2003-2014 INRIA - All rights reserved\n\
\n\
LDPC codecs:\n\
Copyright (c) 2003-2014 INRIA - All rights reserved\n\
This library contains code from R. Neal:\n\
Copyright (c) 1995-2003 by Radford M. Neal\n\
\n\
Reed-Solomon codecs:\n\
This library contains code from L. Rizzo:\n\
Copyright (c) 1997-98 Luigi Rizzo (luigi@iet.unipi.it)\n\
Portions derived from code by Phil Karn (karn@ka9q.ampr.org), \n\
Robert Morelos-Zaragoza (robert@spectra.eng.hawaii.edu) and Hari \n\
Thirumoorthy (harit@spectra.eng.hawaii.edu), Aug 1995 \n\
\n\
See the associated LICENCE.TXT file for licence information\n";
if (version_str) {
*version_str = of_version_string;
}
if (copyrights_str) {
*copyrights_str = of_copyrights_string;
}
OF_EXIT_FUNCTION
return OF_STATUS_OK;
}
#ifdef OF_USE_ENCODER
of_status_t of_build_repair_symbol(of_session_t* ses,
void* encoding_symbols_tab[],
UINT32 esi_of_symbol_to_build) {
of_status_t status;
OF_ENTER_FUNCTION
if (ses == NULL) {
OF_PRINT_ERROR(("Error, bad ses pointer (null)\n"))
goto error;
}
if (!(((of_cb_t*)ses)->codec_type & OF_ENCODER)) {
OF_PRINT_ERROR(("Error, bad codec_type\n"))
goto error;
}
switch (((of_cb_t*)ses)->codec_id) {
#ifdef OF_USE_REED_SOLOMON_CODEC
case OF_CODEC_REED_SOLOMON_GF_2_8_STABLE:
status = of_rs_build_repair_symbol((of_rs_cb_t*)ses, encoding_symbols_tab,
esi_of_symbol_to_build);
break;
#endif
#ifdef OF_USE_REED_SOLOMON_2_M_CODEC
case OF_CODEC_REED_SOLOMON_GF_2_M_STABLE:
status = of_rs_2_m_build_repair_symbol(
(of_rs_2_m_cb_t*)ses, encoding_symbols_tab, esi_of_symbol_to_build);
break;
#endif
#ifdef OF_USE_LDPC_STAIRCASE_CODEC
case OF_CODEC_LDPC_STAIRCASE_STABLE:
status = of_ldpc_staircase_build_repair_symbol(
(of_ldpc_staircase_cb_t*)ses, encoding_symbols_tab,
esi_of_symbol_to_build);
break;
#endif
#ifdef OF_USE_2D_PARITY_MATRIX_CODEC
case OF_CODEC_2D_PARITY_MATRIX_STABLE:
status = of_2d_parity_build_repair_symbol((of_2d_parity_cb_t*)ses,
encoding_symbols_tab,
esi_of_symbol_to_build);
break;
#endif
#ifdef OF_USE_LDPC_FROM_FILE_CODEC
case OF_CODEC_LDPC_FROM_FILE_ADVANCED:
status = of_ldpc_ff_build_repair_symbol(
(of_ldpc_ff_cb_t*)ses, encoding_symbols_tab, esi_of_symbol_to_build);
break;
#endif
default:
OF_PRINT_ERROR(
("Error, codec %d non available\n", ((of_cb_t*)ses)->codec_id))
goto error;
}
OF_EXIT_FUNCTION
return status;
error:
OF_EXIT_FUNCTION
return OF_STATUS_FATAL_ERROR;
}
#endif // OF_USE_ENCODER
#ifdef OF_USE_DECODER
of_status_t of_decode_with_new_symbol(of_session_t* ses,
void* const new_symbol_buf,
UINT32 new_symbol_esi) {
of_status_t status;
OF_ENTER_FUNCTION
if (ses == NULL) {
OF_PRINT_ERROR(("Error, bad ses pointer (null)\n"))
goto error;
}
if (new_symbol_esi >= (((of_cb_t*)ses)->nb_source_symbols +
((of_cb_t*)ses)->nb_repair_symbols)) {
OF_PRINT_ERROR(("Error, bad parameters new_symbol_esi(%d) out of range\n",
new_symbol_esi))
goto error;
}
if (new_symbol_buf == NULL ||
new_symbol_esi >= (((of_cb_t*)ses)->nb_source_symbols +
((of_cb_t*)ses)->nb_repair_symbols) ||
!(((of_cb_t*)ses)->codec_type & OF_DECODER)) {
OF_PRINT_ERROR(("Error, bad parameters\n"))
goto error;
}
switch (((of_cb_t*)ses)->codec_id) {
#ifdef OF_USE_REED_SOLOMON_CODEC
case OF_CODEC_REED_SOLOMON_GF_2_8_STABLE:
status = of_rs_decode_with_new_symbol((of_rs_cb_t*)ses, new_symbol_buf,
new_symbol_esi);
break;
#endif
#ifdef OF_USE_REED_SOLOMON_2_M_CODEC
case OF_CODEC_REED_SOLOMON_GF_2_M_STABLE:
status = of_rs_2_m_decode_with_new_symbol((of_rs_2_m_cb_t*)ses,
new_symbol_buf, new_symbol_esi);
break;
#endif
#ifdef OF_USE_LDPC_STAIRCASE_CODEC
case OF_CODEC_LDPC_STAIRCASE_STABLE:
status = of_ldpc_staircase_decode_with_new_symbol(
(of_ldpc_staircase_cb_t*)ses, new_symbol_buf, new_symbol_esi);
break;
#endif
#ifdef OF_USE_2D_PARITY_MATRIX_CODEC
case OF_CODEC_2D_PARITY_MATRIX_STABLE:
status = of_2d_parity_decode_with_new_symbol(
(of_2d_parity_cb_t*)ses, new_symbol_buf, new_symbol_esi);
break;
#endif
#ifdef OF_USE_LDPC_FROM_FILE_CODEC
case OF_CODEC_LDPC_FROM_FILE_ADVANCED:
status = of_ldpc_staircase_decode_with_new_symbol(
(of_ldpc_staircase_cb_t*)ses, new_symbol_buf, new_symbol_esi);
break;
#endif
default:
OF_PRINT_ERROR(
("Error, codec %d non available\n", ((of_cb_t*)ses)->codec_id))
goto error;
}
OF_EXIT_FUNCTION
return status;
error:
OF_EXIT_FUNCTION
return OF_STATUS_FATAL_ERROR;
}
of_status_t of_set_available_symbols(of_session_t* ses,
void* const encoding_symbols_tab[]) {
of_status_t status;
OF_ENTER_FUNCTION
if (ses == NULL) {
OF_PRINT_ERROR(("Error, bad ses pointer (null)\n"))
goto error;
}
if (encoding_symbols_tab == NULL) {
OF_PRINT_ERROR(("Error, bad encoding_symbols_tab (null)\n"))
goto error;
}
if (!((of_cb_t*)ses)->codec_type & OF_DECODER) {
OF_PRINT_ERROR(("Error, bad codec_type\n"))
goto error;
}
switch (((of_cb_t*)ses)->codec_id) {
#ifdef OF_USE_REED_SOLOMON_CODEC
case OF_CODEC_REED_SOLOMON_GF_2_8_STABLE:
status =
of_rs_set_available_symbols((of_rs_cb_t*)ses, encoding_symbols_tab);
break;
#endif
#ifdef OF_USE_REED_SOLOMON_2_M_CODEC
case OF_CODEC_REED_SOLOMON_GF_2_M_STABLE:
status = of_rs_2_m_set_available_symbols((of_rs_2_m_cb_t*)ses,
encoding_symbols_tab);
break;
#endif
#ifdef OF_USE_LDPC_STAIRCASE_CODEC
case OF_CODEC_LDPC_STAIRCASE_STABLE:
status = of_ldpc_staircase_set_available_symbols(
(of_ldpc_staircase_cb_t*)ses, encoding_symbols_tab);
break;
#endif
#ifdef OF_USE_LDPC_FROM_FILE_CODEC
case OF_CODEC_LDPC_FROM_FILE_ADVANCED:
status = of_ldpc_staircase_set_available_symbols(
(of_ldpc_staircase_cb_t*)ses, encoding_symbols_tab);
break;
#endif
#ifdef OF_USE_2D_PARITY_MATRIX_CODEC
case OF_CODEC_2D_PARITY_MATRIX_STABLE:
status = of_2d_parity_set_available_symbols((of_2d_parity_cb_t*)ses,
encoding_symbols_tab);
break;
#endif
default:
OF_PRINT_ERROR(
("Error, codec %d non available\n", ((of_cb_t*)ses)->codec_id))
goto error;
}
OF_EXIT_FUNCTION
return status;
error:
OF_EXIT_FUNCTION
return OF_STATUS_FATAL_ERROR;
}
of_status_t of_finish_decoding(of_session_t* ses) {
of_status_t status;
OF_ENTER_FUNCTION
if (ses == NULL) {
OF_PRINT_ERROR(("Error, bad ses pointer (null)\n"))
goto error;
}
if (!((of_cb_t*)ses)->codec_type & OF_DECODER) {
OF_PRINT_ERROR(("Error, bad codec_type\n"))
goto error;
}
switch (((of_cb_t*)ses)->codec_id) {
#ifdef OF_USE_REED_SOLOMON_CODEC
case OF_CODEC_REED_SOLOMON_GF_2_8_STABLE:
status = of_rs_finish_decoding((of_rs_cb_t*)ses);
break;
#endif
#ifdef OF_USE_REED_SOLOMON_2_M_CODEC
case OF_CODEC_REED_SOLOMON_GF_2_M_STABLE:
status = of_rs_2_m_finish_decoding((of_rs_2_m_cb_t*)ses);
break;
#endif
#ifdef OF_USE_LDPC_STAIRCASE_CODEC
case OF_CODEC_LDPC_STAIRCASE_STABLE:
status = of_ldpc_staircase_finish_decoding((of_ldpc_staircase_cb_t*)ses);
break;
#endif
#ifdef OF_USE_2D_PARITY_MATRIX_CODEC
case OF_CODEC_2D_PARITY_MATRIX_STABLE:
status = of_2d_parity_finish_decoding((of_2d_parity_cb_t*)ses);
break;
#endif
#ifdef OF_USE_LDPC_FROM_FILE_CODEC
case OF_CODEC_LDPC_FROM_FILE_ADVANCED:
status = of_ldpc_staircase_finish_decoding((of_ldpc_staircase_cb_t*)ses);
break;
#endif
default:
OF_PRINT_ERROR(
("Error, codec %d non available\n", ((of_cb_t*)ses)->codec_id))
goto error;
}
OF_EXIT_FUNCTION
return status;
error:
OF_EXIT_FUNCTION
return OF_STATUS_FATAL_ERROR;
}
bool of_is_decoding_complete(of_session_t* ses) {
of_status_t status;
OF_ENTER_FUNCTION
if (ses == NULL) {
OF_PRINT_ERROR(("Error, bad ses pointer (null)\n"))
goto error;
}
if (!((of_cb_t*)ses)->codec_type & OF_DECODER) {
OF_PRINT_ERROR(("Error, bad codec_type\n"))
goto error;
}
switch (((of_cb_t*)ses)->codec_id) {
#ifdef OF_USE_REED_SOLOMON_CODEC
case OF_CODEC_REED_SOLOMON_GF_2_8_STABLE:
status = of_rs_is_decoding_complete((of_rs_cb_t*)ses);
break;
#endif
#ifdef OF_USE_REED_SOLOMON_2_M_CODEC
case OF_CODEC_REED_SOLOMON_GF_2_M_STABLE:
status = of_rs_2_m_is_decoding_complete((of_rs_2_m_cb_t*)ses);
break;
#endif
#ifdef OF_USE_LDPC_STAIRCASE_CODEC
case OF_CODEC_LDPC_STAIRCASE_STABLE:
status =
of_ldpc_staircase_is_decoding_complete((of_ldpc_staircase_cb_t*)ses);
break;
#endif
#ifdef OF_USE_LDPC_FROM_FILE_CODEC
case OF_CODEC_LDPC_FROM_FILE_ADVANCED:
status =
of_ldpc_staircase_is_decoding_complete((of_ldpc_staircase_cb_t*)ses);
break;
#endif
#ifdef OF_USE_2D_PARITY_MATRIX_CODEC
case OF_CODEC_2D_PARITY_MATRIX_STABLE:
status = of_2d_parity_is_decoding_complete((of_2d_parity_cb_t*)ses);
break;
#endif
default:
OF_PRINT_ERROR(
("Error, codec %d non available\n", ((of_cb_t*)ses)->codec_id))
goto error;
}
OF_EXIT_FUNCTION
return status;
error:
OF_EXIT_FUNCTION
/* should be a fatal error since we arrive here because something wrong
happen, but this is not permitted */
return false;
}
of_status_t of_get_source_symbols_tab(of_session_t* ses,
void* source_symbols_tab[]) {
of_status_t status;
OF_ENTER_FUNCTION
if (ses == NULL) {
OF_PRINT_ERROR(("Error, bad ses pointer (null)\n"))
goto error;
}
if (!((of_cb_t*)ses)->codec_type & OF_DECODER) {
OF_PRINT_ERROR(("Error, bad codec_type\n"))
goto error;
}
switch (((of_cb_t*)ses)->codec_id) {
#ifdef OF_USE_REED_SOLOMON_CODEC
case OF_CODEC_REED_SOLOMON_GF_2_8_STABLE:
status =
of_rs_get_source_symbols_tab((of_rs_cb_t*)ses, source_symbols_tab);
break;
#endif
#ifdef OF_USE_REED_SOLOMON_2_M_CODEC
case OF_CODEC_REED_SOLOMON_GF_2_M_STABLE:
status = of_rs_2_m_get_source_symbols_tab((of_rs_2_m_cb_t*)ses,
source_symbols_tab);
break;
#endif
#ifdef OF_USE_LDPC_STAIRCASE_CODEC
case OF_CODEC_LDPC_STAIRCASE_STABLE:
status = of_ldpc_staircase_get_source_symbols_tab(
(of_ldpc_staircase_cb_t*)ses, source_symbols_tab);
break;
#endif
#ifdef OF_USE_2D_PARITY_MATRIX_CODEC
case OF_CODEC_2D_PARITY_MATRIX_STABLE:
status = of_2d_parity_get_source_symbols_tab((of_2d_parity_cb_t*)ses,
source_symbols_tab);
break;
#endif
#ifdef OF_USE_LDPC_FROM_FILE_CODEC
case OF_CODEC_LDPC_FROM_FILE_ADVANCED:
status = of_ldpc_staircase_get_source_symbols_tab(
(of_ldpc_staircase_cb_t*)ses, source_symbols_tab);
break;
#endif
default:
OF_PRINT_ERROR(
("Error, codec %d non available\n", ((of_cb_t*)ses)->codec_id))
goto error;
}
OF_EXIT_FUNCTION
return status;
error:
OF_EXIT_FUNCTION
return OF_STATUS_FATAL_ERROR;
}
of_status_t of_set_control_parameter(of_session_t* ses, UINT32 type,
void* value, UINT32 length) {
of_status_t status;
OF_ENTER_FUNCTION
if (ses == NULL) {
OF_PRINT_ERROR(("Error, bad ses pointer (null)\n"))
goto error;
}
switch (((of_cb_t*)ses)->codec_id) {
#ifdef OF_USE_REED_SOLOMON_CODEC
case OF_CODEC_REED_SOLOMON_GF_2_8_STABLE:
// status = of_rs_set_control_parameter ( (of_rs_cb_t*) ses, type, value,
// length);
break;
#endif
#ifdef OF_USE_REED_SOLOMON_2_M_CODEC
case OF_CODEC_REED_SOLOMON_GF_2_M_STABLE:
status = of_rs_2_m_set_control_parameter((of_rs_2_m_cb_t*)ses, type,
value, length);
break;
#endif
#ifdef OF_USE_LDPC_STAIRCASE_CODEC
case OF_CODEC_LDPC_STAIRCASE_STABLE:
status = of_ldpc_staircase_set_control_parameter(
(of_ldpc_staircase_cb_t*)ses, type, value, length);
break;
#endif
#ifdef OF_USE_2D_PARITY_MATRIX_CODEC
case OF_CODEC_2D_PARITY_MATRIX_STABLE:
status = of_2d_parity_set_control_parameter((of_2d_parity_cb_t*)ses, type,
value, length);
break;
#endif
#ifdef OF_USE_LDPC_FROM_FILE_CODEC
case OF_CODEC_LDPC_FROM_FILE_ADVANCED:
status = of_ldpc_ff_set_control_parameter((of_ldpc_ff_cb_t*)ses, type,
value, length);
break;
#endif
default:
OF_PRINT_ERROR(
("Error, codec %d non available\n", ((of_cb_t*)ses)->codec_id))
goto error;
}
OF_EXIT_FUNCTION
return status;
error:
OF_EXIT_FUNCTION
return OF_STATUS_FATAL_ERROR;
}
of_status_t of_get_control_parameter(of_session_t* ses, UINT32 type,
void* value, UINT32 length) {
of_status_t status;
OF_ENTER_FUNCTION
if (ses == NULL) {
OF_PRINT_ERROR(("Error, bad ses pointer (null)\n"))
goto error;
}
switch (((of_cb_t*)ses)->codec_id) {
#ifdef OF_USE_REED_SOLOMON_CODEC
case OF_CODEC_REED_SOLOMON_GF_2_8_STABLE:
status =
of_rs_get_control_parameter((of_rs_cb_t*)ses, type, value, length);
break;
#endif
#ifdef OF_USE_REED_SOLOMON_2_M_CODEC
case OF_CODEC_REED_SOLOMON_GF_2_M_STABLE:
status = of_rs_2_m_get_control_parameter((of_rs_2_m_cb_t*)ses, type,
value, length);
break;
#endif
#ifdef OF_USE_LDPC_STAIRCASE_CODEC
case OF_CODEC_LDPC_STAIRCASE_STABLE:
status = of_ldpc_staircase_get_control_parameter(
(of_ldpc_staircase_cb_t*)ses, type, value, length);
break;
#endif
#ifdef OF_USE_LDPC_FROM_FILE_CODEC
case OF_CODEC_LDPC_FROM_FILE_ADVANCED:
status = of_ldpc_ff_get_control_parameter((of_ldpc_ff_cb_t*)ses, type,
value, length);
break;
#endif
#ifdef OF_USE_2D_PARITY_MATRIX_CODEC
case OF_CODEC_2D_PARITY_MATRIX_STABLE:
status = of_2d_parity_get_control_parameter((of_2d_parity_cb_t*)ses, type,
value, length);
break;
#endif
default:
OF_PRINT_ERROR(
("Error, codec %d non available\n", ((of_cb_t*)ses)->codec_id))
goto error;
}
OF_EXIT_FUNCTION
return status;
error:
OF_EXIT_FUNCTION
return OF_STATUS_FATAL_ERROR;
}
#endif // OF_USE_DECODER

View File

@@ -0,0 +1,588 @@
/* $Id: of_openfec_api.h 189 2014-07-16 08:53:50Z roca $ */
/*
* OpenFEC.org AL-FEC Library.
* (c) Copyright 2009 - 2012 INRIA - All rights reserved
* Contact: vincent.roca@inria.fr
*
* This software is governed by the CeCILL-C license under French law and
* abiding by the rules of distribution of free software. You can use,
* modify and/ or redistribute the software under the terms of the CeCILL-C
* license as circulated by CEA, CNRS and INRIA at the following URL
* "http://www.cecill.info".
*
* As a counterpart to the access to the source code and rights to copy,
* modify and redistribute granted by the license, users are provided only
* with a limited warranty and the software's author, the holder of the
* economic rights, and the successive licensors have only limited
* liability.
*
* In this respect, the user's attention is drawn to the risks associated
* with loading, using, modifying and/or developing or reproducing the
* software by the user in light of its specific status of free software,
* that may mean that it is complicated to manipulate, and that also
* therefore means that it is reserved for developers and experienced
* professionals having in-depth computer knowledge. Users are therefore
* encouraged to load and test the software's suitability as regards their
* requirements in conditions enabling the security of their systems and/or
* data to be ensured and, more generally, to use and operate it in the
* same conditions as regards security.
*
* The fact that you are presently reading this means that you have had
* knowledge of the CeCILL-C license and that you accept its terms.
*/
#ifndef OPENFEC_API_H
#define OPENFEC_API_H
#include "of_openfec_profile.h"
#include "of_types.h"
#ifdef OF_USE_REED_SOLOMON_CODEC
#include "../lib_stable/reed-solomon_gf_2_8/of_reed-solomon_gf_2_8_api.h"
#endif
#ifdef OF_USE_REED_SOLOMON_2_M_CODEC
#include "../lib_stable/reed-solomon_gf_2_m/of_reed-solomon_gf_2_m_api.h"
#endif
#ifdef OF_USE_LDPC_STAIRCASE_CODEC
#include "../lib_stable/ldpc_staircase/of_ldpc_staircase_api.h"
#endif
#ifdef OF_USE_2D_PARITY_MATRIX_CODEC
#include "../lib_stable/2d_parity_matrix/of_2d_parity_api.h"
#endif
#ifdef OF_USE_LDPC_FROM_FILE_CODEC
#include "../lib_advanced/ldpc_from_file/of_ldpc_ff_api.h"
#endif
#include "of_debug.h"
/****** OpenFEC.org general definitions
* ***********************************************************/
/**
* The of_fec_codec_id_t enum identifies the FEC code/codec being used.
* A given of_fec_codec_id_t can then be used by one or several FEC schemes
*(that specify both the codes and way of using these codes), as specified in:
* - RFC 5052, "Forward Error Correction (FEC) Building Block" for
*file/object transfer applications, or
* - <draft-ietf-fecframe-XXX> (work under progress) "Forward Error
*Correction (FEC) Framework" for real-time streaming applications.
*
* The following FEC codec IDs are currently identified (but not necessarily
*supported):
*
* OF_CODEC_NIL = 0 reserved invalid value
*
*** Stable codecs ***
*
*
* OF_CODEC_REED_SOLOMON_GF_2_8_STABLE
* Reed-Solomon codes over GF(2^8), stable
*version.
* - E.g. FEC Encoding ID 5 (RMT IETF WG)
* (see RFC 5510, "Reed-Solomon Forward
*Error Correction (FEC) schemes")
* - E.g. FEC Encoding ID 129 / FEC
*Instance ID 0 (see RFC 5510, "Reed-Solomon Forward Error Correction (FEC)
*Schemes")
*
* OF_CODEC_REED_SOLOMON_GF_2_M_STABLE
* Reed-Solomon codes over GF(2^m), stable
*version.
*
*
* OF_CODEC_LDPC_STAIRCASE_STABLE LDPC-Staircase large block FEC codes,
*stable version.
* - E.g. FEC Encoding ID 3
* (see RFC 5170, "Low Density Parity
*Check (LDPC) Staircase and Triangle Forward Error Correction (FEC) Schemes")
*
* OF_CODEC_LDPC_TRIANGLE_STABLE LDPC-Staircase large block FEC codes,
*stable version.
* - E.g. FEC Encoding ID 4
* (see RFC 5170, "Low Density Parity
*Check (LDPC) Staircase and Triangle Forward Error Correction (FEC) Schemes")
*
* OF_CODEC_2D_PARITY_MATRIX_STABLE 2D-parity-matrix codes, stable version.
*
*
*** Advanced codecs ***
*
* OF_CODEC_LDPC_FROM_FILE_ADVANCED LDPC codes whose binary parity check
*matrix is provided by the application within an ASCII file. The format of this
*ASCII file is the usual LDPC structure [REF].
*/
typedef enum {
OF_CODEC_NIL = 0,
OF_CODEC_REED_SOLOMON_GF_2_8_STABLE = 1,
OF_CODEC_REED_SOLOMON_GF_2_M_STABLE = 2,
OF_CODEC_LDPC_STAIRCASE_STABLE = 3,
// OF_CODEC_LDPC_TRIANGLE_STABLE = 4,
OF_CODEC_2D_PARITY_MATRIX_STABLE = 5,
OF_CODEC_LDPC_FROM_FILE_ADVANCED = 6
} of_codec_id_t;
/**
* Specifies if this codec instance is a pure encoder, a pure decoder, or a
* codec capable of both encoding and decoding.
*/
typedef UINT8 of_codec_type_t;
#define OF_ENCODER 0x1
#define OF_DECODER 0x2
#define OF_ENCODER_AND_DECODER (OF_ENCODER | OF_DECODER)
/**
* Function return value, indicating wether the function call succeeded
*(OF_STATUS_OK) or not. In case of failure, the detailed error type is returned
*in a global variable, of_errno (see of_errno.h).
*
* OF_STATUS_OK = 0 Success
* OF_STATUS_FAILURE, Failure. The function called did not
*succeed to perform its task, however this is not an error. This can happen for
*instance when decoding did not succeed (which is a valid output).
* OF_STATUS_ERROR, Generic error type. The caller is
*expected to be able to call the library in the future after having corrected
* the error cause.
* OF_STATUS_FATAL_ERROR Fatal error. The caller is expected to
*stop using this codec instance immediately (it replaces an exit() system
* call).
*/
typedef enum {
OF_STATUS_OK = 0,
OF_STATUS_FAILURE,
OF_STATUS_ERROR,
OF_STATUS_FATAL_ERROR
} of_status_t;
/**
* Throughout the API, a pointer to this structure is used as an identifier of
* the current codec instance, also known as "session".
*
* This generic structure is meant to be extended by each codec and new pieces
* of information that are specific to each codec be specified there. However,
* all the codec specific structures MUST begin the same entries as the ones
* provided in this generic structure, otherwise hazardeous behaviors may
* happen.
*/
typedef struct of_session {
of_codec_id_t codec_id;
of_codec_type_t codec_type;
} of_session_t;
/**
* Generic FEC parameter structure used by of_set_fec_parameters().
*
* This generic structure is meant to be extended by each codec and new pieces
* of information that are specific to each codec be specified there. However,
* all the codec specific structures MUST begin the same entries as the ones
* provided in this generic structure, otherwise hazardeous behaviors may
* happen.
*/
typedef struct of_parameters {
UINT32 nb_source_symbols;
UINT32 nb_repair_symbols;
UINT32 encoding_symbol_length;
} of_parameters_t;
/** Verbosity level for the whole library. */
extern UINT32 of_verbosity;
/****** OpenFEC.org general methods/functions
* *****************************************************/
/*
* Usual functions shared by encoders and decoders
* ***********************************************
*/
/**
* This function allocates and partially initializes a new session structure.
* Throughout the API, a pointer to this session is used as an identifier of the
*current codec instance.
*
* @fn of_status_t of_create_codec_instance (of_session_t** ses,
*of_codec_id_t codec_id, of_codec_type_t codec_type, UINT32 verbosity)
* @brief create a codec instance
*<2A>0<EFBFBD>2@param ses (IN/OUT) address of the pointer to a session. This
*pointer is updated by this function. In case of success, it points to a
*session structure allocated by the library. In case of failure it points to
*NULL.
* @param codec_id identifies the FEC code/codec being used.
* @param codec_type indicates if this is a coder, a decoder, or both.
* @param verbosity set the verbosity level: 0: no trace, 1: main traces, 2:
*maximum.
* @return Error status. The ses pointer is updated according to
*the success return status.
*/
of_status_t of_create_codec_instance(of_session_t** ses, of_codec_id_t codec_id,
of_codec_type_t codec_type,
UINT32 verbosity);
/**
* This function releases all the internal resources used by this FEC codec
*instance. None of the source symbol buffers will be free'ed by this function,
*even those decoded by the library if any, regardless of whether a callback has
*been registered or not. It's the responsibility of the caller to free them.
*
* @fn of_status_t of_release_codec_instance (of_session_t* ses)
* @brief release all resources used by the codec
*<2A>0<EFBFBD>2@param ses (IN) Pointer to the session.
* @return Error status.
*/
of_status_t of_release_codec_instance(of_session_t* ses);
/**
* Second step of the initialization.
* This is the place where the application specifies the parameters associated
*to the desired FEC codec.
*
* At a receiver, the parameters can be extracted from the FEC OTI that is
*usually communicated to the receiver by either an in-band mechanism (e.g. the
*EXT_FTI header extension of ALC/LCT, or the FLUTE File Delivery Table, or the
*FCAST meta-data), or an out-of-band mechanism (e.g. in an SDP session
*description), or set statically for a specific use-case.
*
* Note also that a subset of the FEC OTI information is not strictly needed by
*the codec but only required for instance when using the associated object
*blocking functions. This is the case of the object length (Transfer Length).
*
* @fn of_status_t of_set_fec_parameters (of_session_t* ses,
*of_parameters_t* params)
* @brief set all the FEC codec parameters (e.g. k, n, or symbol
*size) <20>0<EFBFBD>2@param ses (IN) Pointer to the session.
* @param params (IN) pointer to a structure containing the FEC
*parameters associated to a specific FEC codec.
* @return Error status.
*/
of_status_t of_set_fec_parameters(of_session_t* ses, of_parameters_t* params);
/**
* Set the various callback functions for this session.
*
* - The decoded_source_symbol callback function is called each time a source
*symbol (not a repair symbol!) is decoded by one of the decoding functions.
*What this function does is application-dependant, but it MUST return either a
*pointer to a data buffer, left uninitialized, of the appropriate size, or NULL
*if the application prefers to let the OpenFEC library allocate the buffer. In
*any case the OpenFEC library is responsible for storing the actual symbol
*value within the data buffer. In all cases (i.e. whether the data buffer is
*allocated by the application or codec), it is the responsibility of the
* application to free this buffer when needed, once decoding is over (but not
*before since the codec does not keep any internal copy).
*
* - The decoded_repair_symbol callback is similar but limited to decoded repair
*symbols. It is not expected that this callback be frequently used (decoded
*repair symbols are usually temporary, internal symbols). It might be used for
*statistics purposes, e.g. to identify which repair symbol is decoded and when.
*Unlike the decoded_source_symbol callback, this one is not expected to return
*any data buffer.
*
* All the callback functions require an opaque context parameter, that must be
* initialized accordingly by the application, since it is application specific.
*
* @fn of_status_t of_set_callback_functions (of_session_t *ses,void*
*(*decoded_source_symbol_callback) (void *context,UINT32 size,UINT32
*esi), void* (*decoded_repair_symbol_callback) (void *context,UINT32
*size,UINT32 esi),void* context_4_callback)
* @brief set various callbock functions (see header
*of_open_fec_api.h) <20>0<EFBFBD>2@param ses (IN) Pointer to the session.
*
* @param decoded_source_symbol_callback
* (IN) Pointer to the function, within the
*application, that needs to be called each time a source symbol is decoded. If
*this callback is not initialized, the symbol is managed internally.
*
* @param decoded_repair_symbol_callback
* (IN) Pointer to the function, within the
*application, that needs to be called each time a repair symbol is decoded. If
*this callback is not initialized, the symbol is managed internally.
*
* @param context_4_callback (IN) Pointer to the application-specific context
*that will be passed to the callback function (if any). This context is not
* interpreted by this function.
*
* @return Completion status (LDPC_OK or LDPC_ERROR).
*/
of_status_t of_set_callback_functions(
of_session_t* ses,
void* (*decoded_source_symbol_callback)(
void* context, UINT32 size, /* size of decoded source symbol */
UINT32 esi), /* encoding symbol ID in {0..k-1} */
void* (*decoded_repair_symbol_callback)(
void* context, UINT32 size, /* size of decoded repair symbol */
UINT32 esi), /* encoding symbol ID in {k..n-1} */
void* context_4_callback);
#ifdef OF_USE_ENCODER
/*
* Encoder specific functions
* **************************
*/
/**
* Create a single repair symbol, i.e. perform an encoding.
* The application needs to communicate all the source symbols by means of the
* encoding_symbols_tab[] table, which contains pointers to buffers totally
*managed by the application, and that contain the source symbols. This table
*may also contain a subset of the repair symbols, those that have already been
*built. For instance, with OF_CODEC_LDPC_STAIRCASE_STABLE the repair symbol of
*ESI i+1 depends on the repair symbol of ESI i. In any case, upon calling this
*function, the entry: encoding_symbols_tab[esi_of_symbol_to_build] can either
*be set to NULL, in which case the library allocates a buffer and copies the
* newly built symbol to it, or point to a buffer allocated by the application,
*in which case the library only copies the newly built symbol to it.
*
* @fn of_status_t of_build_repair_symbol (of_session_t* ses, void*
*encoding_symbols_tab[], UINT32 esi_of_symbol_to_build)
* @brief build a repair symbol (encoder only)
*<2A>0<EFBFBD>2@param ses (IN) Pointer to the session.
* @param encoding_symbols_tab (IN/OUT) table of source and repair symbols.
* The entry for the repair symbol to build can
*either point to a buffer allocated by the application, or let to NULL meaning
*that of_build_repair_symbol will allocate memory.
* @param esi_of_symbol_to_build
* (IN) encoding symbol ID of the repair symbol to
*build in {k..n-1}
* @return Error status.
*/
of_status_t of_build_repair_symbol(of_session_t* ses,
void* encoding_symbols_tab[],
UINT32 esi_of_symbol_to_build);
#endif /* OF_USE_ENCODER */
#ifdef OF_USE_DECODER
/*
* Decoder specific functions
* **************************
*/
/**
* Try to decode using the newly received symbol.
* Although no decoding algorithm is specified here, in case of LDPC-* codecs,
*this function usually performs on an ITerative decoding (IT) algorithm, on the
*fly as each new symbol is available. In case of Reed-Solomon, as long as the
*number of available symbols is inferior to k, this function only registers the
*new symbol in an internal table. Then as soon as exactly k symbols are
*available, decoding takes place.
*
* Be careful, no codec keep any internal copy of the symbols provided by the
*application. Therefore it is assumed that the buffer provided by this
*function, whether it contains a fresh source or repair symbol, will be
*available throughout the decoding process. This is motivated by performance
*reasons since it means the codec does not need to keep any internal copy of
*received symbols.
*
* @fn of_status_t of_decode_with_new_symbol (of_session_t* ses,
*void* const new_symbol_buf, UINT32 new_symbol_esi)
* @brief (try to) decode with a newly received symbol
*<2A>0<EFBFBD>2@param ses (IN) Pointer to the session.
* @param new_symbol_buf (IN) Pointer to the encoding symbol now
*available (i.e. a new symbol received by the application, or a decoded symbol
*in case of a recursive call).
* @param new_symbol_esi (IN) Encoding symbol ID of the newly symbol
*available, in {0..n-1}.
* @return Error status (NB: this function does not return
*OF_STATUS_FAILURE).
*/
of_status_t of_decode_with_new_symbol(of_session_t* ses,
void* const new_symbol_buf,
UINT32 new_symbol_esi);
/**
* Inform the decoder of all the available (e.g. received from the network)
*encoding symbols. This function should not be used when the application uses
*of_decode_with_new_symbol() since the available symbols are already known. No
*decoding is performed at this step, a call to of_finish_decoding() is needed.
*The goal is only to give the application the opportunity to register the set
*of symbols available for the future decoding. This function must be called
*only once for a given session.
*
* Be careful, no codec keep any internal copy of the symbols provided by the
*application Therefore it is assumed that the buffers provided by this
*function, whether they contain fresh source or repair symbols, will be
*available throughout the decoding process. This is motivated by performance
*reasons since it means the codec does not need to keep any internal copy of
*received symbols.
*
* @fn of_status_t of_set_available_symbols
*(of_session_t* ses, void* const encoding_symbols_tab[]);
* @brief inform the decoder of all the available
*(received) symbols <20>0<EFBFBD>2@param ses (IN) Pointer to the
*session.
* @param encoding_symbols_tab (IN) Pointer to the available encoding symbols
*table. To each available symbol the corresponding entry in the table must
*point to the associated buffer. Entries set to NULL are interpreted as
* corresponding to erased symbols.
* @return Error status.
*/
of_status_t of_set_available_symbols(of_session_t* ses,
void* const encoding_symbols_tab[]);
#if 0 /* NOT YET */
/**
* Idem but the application specifies the list of available symbols instead of using a table.
*/
of_status_t of_set_available_symbol_list (of_session_t* ses,
of_es_list_t encoding_symbols_list);
#endif
/**
* Finish decoding with whatever symbol is available.
* The application is expected to have used either of_decode_with_new_symbol()
*or of_set_available_symbols() prior to calling this function.
*
* Although no decoding algorithm is specified here (this is codec specific), in
*case of the LDPC-* codecs, this function usually performs an ITerative
*decoding (IT) algorithm first (if not already done by using
*of_decode_with_new_symbol()) and finishes with a Gaussian Elimination.
*
* @fn of_status_t of_finish_decoding (of_session_t*
*ses)
* @brief finish decoding with available symbols
*<2A>0<EFBFBD>2@param ses (IN) Pointer to the session.
* @return Error status. Returns OF_STATUS_FAILURE if decoding
*failed, or OF_STATUS_OK if decoding succeeded, or OF_STATUS_*_ERROR in case of
*(fatal) error.
*/
of_status_t of_finish_decoding(of_session_t* ses);
/**
* Returns true if the decoding is finished, i.e. if all the source symbols have
*been received or decoded. Returns false otherwise.
*
* @fn bool of_is_decoding_complete (of_session_t*
*ses)
* @brief check if decoding is finished
*<2A>0<EFBFBD>2@param ses (IN) Pointer to the session.
* @return Boolean. Warning, this is one of the very functions of
*the library that does not return an error status.
*/
bool of_is_decoding_complete(of_session_t* ses);
/**
* Get a copy of the table of available (received or decoded) source symbols.
* This function is usually called once decoding is finished. In some
*situations, it might be interesting to call it even if decoding is not
*succesful, since additional source symbols might have been decoded.
*
* @fn of_status_t of_get_source_symbols_tab (of_session_t*
*ses, void* source_symbols_tab[])
* @brief get the table of available source symbols (after
*decoding) <20>0<EFBFBD>2@param ses (IN) Pointer to the session.
* @param source_symbols_tab (IN/OUT) table, that will be filled by the
*library and returned to the application.
* @return Error status.
*/
of_status_t of_get_source_symbols_tab(of_session_t* ses,
void* source_symbols_tab[]);
#endif /* OF_USE_DECODER */
/*
* Additional functions
* ********************
*/
/**
* Return information about the OpenFEC Library in general, and the codec used
*in particular on condition the session pointer is not NULL. If the session
*pointer is NULL, only the general string is returned. Note that the returned
*string is totally managed by the library and must not be released by the
*application.
*
*<2A>0<EFBFBD>2@param ses (IN) Pointer to the session or NULL.
*<2A>0<EFBFBD>2@param version_str (IN/OUT) address of a pointer to a string. This pointer
*is updated by this function to point ot a static string (that must not be
*released by the caller). <20>0<EFBFBD>2@param copyrights_str (IN/OUT) address of a pointer
*to a string. This pointer is updated by this function to point ot a static
*string (that must not be released by the caller).
* @return Error status.
*/
of_status_t of_more_about(of_session_t* ses, char** version_str,
char** copyrights_str);
/**
* This function sets a FEC scheme/FEC codec specific control parameter, in
*addition to the FEC OTI, using a type/value method.
*
*<2A>0<EFBFBD>2@param ses (IN) Pointer to the session.
* @param type (IN) Type of parameter. This type is FEC codec ID
*specific.
* @param value (IN) Pointer to the value of the parameter. The type of
*the object pointed is FEC codec ID specific.
* @param length (IN) length of pointer value
* @return Error status.
*/
of_status_t of_set_control_parameter(of_session_t* ses, UINT32 type,
void* value, UINT32 length);
/**
* This function gets a FEC scheme/FEC codec specific control parameter, in
*addition to the FEC OTI, using a type/value method.
*
*<2A>0<EFBFBD>2@param ses (IN) Pointer to the session.
* @param type (IN) Type of parameter. This type is FEC codec ID
*specific.
* @param value (IN/OUT) Pointer to the value of the parameter. The type
*of the object pointed is FEC codec ID specific. This function updates the
*value object accordingly. The application, who knows the FEC codec ID, is
*responsible to allocating the approriate object pointed by the value pointer.
* @param length (IN) length of pointer value
* @return Error status.
*/
of_status_t of_get_control_parameter(of_session_t* ses, UINT32 type,
void* value, UINT32 length);
/**
* Control parameters for of_set_control_parameter()/of_get_control_parameter()
*functions:
* - range {0 .. 1023} inclusive are for generic parameters;
* - range {1024 .. above} inclusive are for code/codec specific parameters
*(and different codecs can re-use the same value); The "void * value" type
*depends on the type. The generic parameters are listed bellow, the code/codec
*specific parameters are listed in the codec directory.
*/
/**
* Get the maximum k parameter for this codec. To the potential limits of the
* code itself (e.g. RS over GF(2^8) have a strict limit to k<n<=255), the codec
* may add some practical additional limits, e.g. caused by memory management
* aspects (maximum working memory), or by internal codec implementation
* details, e.g. the fact an index is stored in 16-bit integers. This is true
* both for k and n. Argument: UINT32
*/
#define OF_CTRL_GET_MAX_K 1
/**
* Get the maximum n parameter for this codec. To the potential limits of the
* code itself (e.g. RS over GF(2^8) have a strict limit to n<=255), the codec
* may add some practical additional limits, e.g. caused by memory management
* aspects (maximum working memory), or by internal codec implementation
* details, e.g. the fact an index is stored in 16-bit integers. This is true
* both for k and n. Argument: UINT32
*/
#define OF_CTRL_GET_MAX_N 2
/**
* Set the field size using the of__set_control_parameter function.
* Instead of using of_set_fec_parameter function to initialize the field size
* during the encoder or decoder instance creation, we initialize this field
* size here.
*/
#define OF_RS_CTRL_SET_FIELD_SIZE 1024
#if 0 /* NOT YET */
/**
* Returns an (estimated) probability that the decoding finish, given the provided number
* of available source and repair symbols. The way this probability is calculated depends
* on many parameters, and above all the code nature.
*
*<2A>0<EFBFBD>2@param ses (IN) Pointer to the session.
* @return Error status.
*/
bool of_get_decoding_success_proba (of_session_t* ses,
UINT32 nb_available_source_symbols,
UINT32 nb_available_repair_symbols);
#endif
#endif /* OPENFEC_API_H */

View File

@@ -0,0 +1,85 @@
/* $Id: of_openfec_profile.h 207 2014-12-10 19:47:50Z roca $ */
/*
* OpenFEC.org AL-FEC Library.
* (c) Copyright 2009 - 2012 INRIA - All rights reserved
* Contact: vincent.roca@inria.fr
*
* This software is governed by the CeCILL-C license under French law and
* abiding by the rules of distribution of free software. You can use,
* modify and/ or redistribute the software under the terms of the CeCILL-C
* license as circulated by CEA, CNRS and INRIA at the following URL
* "http://www.cecill.info".
*
* As a counterpart to the access to the source code and rights to copy,
* modify and redistribute granted by the license, users are provided only
* with a limited warranty and the software's author, the holder of the
* economic rights, and the successive licensors have only limited
* liability.
*
* In this respect, the user's attention is drawn to the risks associated
* with loading, using, modifying and/or developing or reproducing the
* software by the user in light of its specific status of free software,
* that may mean that it is complicated to manipulate, and that also
* therefore means that it is reserved for developers and experienced
* professionals having in-depth computer knowledge. Users are therefore
* encouraged to load and test the software's suitability as regards their
* requirements in conditions enabling the security of their systems and/or
* data to be ensured and, more generally, to use and operate it in the
* same conditions as regards security.
*
* The fact that you are presently reading this means that you have had
* knowledge of the CeCILL-C license and that you accept its terms.
*/
#ifndef OF_OPENFEC_PROFILE_H
#define OF_OPENFEC_PROFILE_H
#define OF_USE_ENCODER
#define OF_USE_DECODER
/*
* Edit as needed to define which codec(s) you need.
* By default all codecs are considered.
*
* Commenting an include entry below prevents the compiler to read
* the associated of_codec_profile.h file where the USE_*_
* macro is defined. Therefore the associated codec will be ignored
* during compilation.
*
* Removing codecs known to be useless can be important for highly
* specialized usage of OpenFEC, like embedded systems.
*/
#include "../lib_stable/reed-solomon_gf_2_8/of_codec_profile.h"
#include "../lib_stable/reed-solomon_gf_2_m/of_codec_profile.h"
#include "../lib_stable/ldpc_staircase/of_codec_profile.h"
#include "../lib_stable/2d_parity_matrix/of_codec_profile.h"
//#include "../lib_advanced/ldpc_from_file/of_codec_profile.h"
/*
* Edit as needed to define which core solving system to use.
* By default all systems are considered.
*
* Note that the above codecs require certain solving systems.
* For instance, LDPC-staircase requires IT decoding, and ML
* decoding is highly recommended for improved performances.
*
* Removing solving systems known to be useless can be important
* for highly specialized usage of OpenFEC, like embedded systems.
*/
#define OF_USE_LINEAR_BINARY_CODES_UTILS
#define OF_USE_GALOIS_FIELD_CODES_UTILS
/**
* Define if you need SSE optimizations for XOR operations.
* This is useful for PC usage, with processors that support this
* extension (i.e. all the processors except the very old ones).
*/
//#define ASSEMBLY_SSE_OPT
/*
* NB: if SSE is not defined, then we'll use regular XOR operations,
* either on 32 bit or 64 bit integers depending on the operating
* system.
*/
#endif // OF_OPENFEC_PROFILE_H

View File

@@ -0,0 +1,298 @@
/* $Id: of_rand.c 186 2014-07-16 07:17:53Z roca $ */
//////////////////////////////////////////////////////////////////////////////
//
// rand31pmc
//
// Robin Whittle 2005 September 20
//
// 31 bit pseudo-random number generator based on:
//
// Lehmer (1951)
// Lewis, Goodman & Miller (1969)
// Park & Miller (1983)
//
// implemented according to the optimisation suggested by David G. Carta
// in 1990 which uses 32 bit math and does not require division.
// Park and Miller rejected Carta's approach in 1993. Carta provided no
// code examples. Carta's approach produces identical results to Park
// and Miller's code.
//
// Copyright public domain . . . *but*:
//
// * Please leave the comments intact so inquiring minds have a chance of
// * understanding how this implementation works and chasing the
// * references to see the strengths and limitations of this particular
// * pseudo-random number generator.
//
// Output is a 31 bit unsigned integer. The range of values output is
// 1 to 2,147,483,646 and the of_seed must be in this range too. The
// output sequence repeats in a loop of this length = (2^31 - 2).
//
// The output stream has some predictable patterns. For instance, after
// a very low output, the next one or two outputs will be relatively low
// (compared to the 2 billion range) because the multiplier is only 16,807.
// Linear congruential generators are not suitable for cryptography or
// simulation work (such as Monte Carlo Method), but they are probably
// fine for many uses where the output is sound or vision for human
// perception.
//
// The particular generator implemented here:
//
// New-value = (old-value * 16807) mod 0x7FFFFFFF
//
// is probably the best studied linear congruentual PRNG. It is not the very
// best, but it is far from the worst.
//
// For the background on this implementation, and the Park Miller
// "Minimal Standard" linear congruential PRNG, please see:
//
// http://www.firstpr.com.au/dsp/rand31/
//
// Stephen K. Park and Keith W. Miller
// Random Number Generators: Good Ones are Hard to Find
// Communications of the ACM, Oct 1988, Vol 31 Number 10 1192-1201
//
// David G. Carta
// Two Fast Implementations of the "Minimal Standard" Random Number Generator
// Communications of the ACM, Jan 1990, Vol 33 Number 1 87-88
//
// George Marsaglia; Stephen J. Sullivan; Stephen K. Park, Keith W. Miller,
// Paul K. Stockmeyer
// Remarks on Choosing and Implementing Random Number Generators
// Communications of the ACM, Jul 1993, Vol 36 Number 7 105-110
//
// http://random.mat.sbg.ac.at has lots of material on PRNG quality.
//
//
// The sequence of values this PRNG should produce includes:
//
// Result Number of results after of_seed of 1
//
// 16807 1
// 282475249 2
// 1622650073 3
// 984943658 4
// 1144108930 5
// 470211272 6
// 101027544 7
// 1457850878 8
// 1458777923 9
// 2007237709 10
//
// 925166085 9998
// 1484786315 9999
// 1043618065 10000
// 1589873406 10001
// 2010798668 10002
//
// 1227283347 1000000
// 1808217256 2000000
// 1140279430 3000000
// 851767375 4000000
// 1885818104 5000000
//
// 168075678 99000000
// 1209575029 100000000
// 941596188 101000000
//
// 1207672015 2147483643
// 1475608308 2147483644
// 1407677000 2147483645
// 1 2147483646
// 16807 2147483647
//
// Carta refers to two registers p (15 bits) and q (31 bits) which
// together hold the 46 bit multiplication product:
//
// | | | |
// 4444 4444 3333 3333 3322 2222 2222 1111 1111 11
// 7654 3210 9876 5432 1098 7654 3210 9876 5432 1098 7654 3210
//
// q 31 qqq qqqq qqqq qqqq qqqq qqqq qqqq qqqq
// p 15 pp pppp pppp pppp p
//
// The maximum 46 bit result occurs
// when the of_seed is at its highest
// allowable value: 0x7FFFFFFE.
//
// 0x20D37FFF7CB2
//
// which splits up like this
//
// q 31 111 1111 1111 1111 0111 1100 1011 0010
// p 15 10 0000 1101 0011 0
// = 100 0001 1010 0110
//
// In hex, these maxiumum values are:
//
// q 31 7FFF7CB2 = 2^31 - (2 * 16807)
// p 15 41A6 = 16807 - 1
//
//
// The task is to combine the two partial products p and q as if they were
// both parts of a 46 bit number, with the final result being modulo:
//
// 0111 1111 1111 1111 1111 1111 1111 1111
//
// when we are actually only doing 32 bits at a time.
//
// Here I explain David G. Carta's trick - in a different and much simpler
// way than he does.
//
// We need to deal with the p bits "pp pppp pppp pppp p" shown above.
// These bits carry weights of bits 45 to 31 in the multiplication product
// of the usual Park Miller algorithm.
//
// David Carta writes that in order to calculate mod(0x7FFFFFFF) of the
// complete multiplication product (taking into account the total value
// of p and q) we should simply add the bits of p into the bit positions
// 14 to 0 of q and then do a mod(0x7FFFFFFF) on the result!
//
// | | | |
// 4444 4444 3333 3333 3322 2222 2222 1111 1111 11
// 7654 3210 9876 5432 1098 7654 3210 9876 5432 1098 7654 3210
//
// 31 qqq qqqq qqqq qqqq qqqq qqqq qqqq qqqq
// 15 + ppp pppp pppp pppp
// = Cxxx xxxx xxxx xxxx xxxx xxxx xxxx xxxx
//
// Highest possible value,
// for q, with a value for
// p which would allow it:
//
// 7FFFFFFF 111 1111 1111 1111 1111 1111 1111 1111
// + 41A5 100 0001 1010 0101
// = 8000041A4 1000 0000 0000 0000 0100 0001 1010 0100
//
// The result can't be larger than 2 * 0x7FFFFFFF = 0xFFFFFFFE. So when we
// do the modulus operation, we will have to subtract either nothing or just
// one 0x7FFFFFFF. With this model of addition, the subtraction only
// occurs very rarely.
//
// David Carta's explanation for why this produces the correct answer is too
// long to repeat here. Mine is easy to understand.
//
// Lets define some labels:
//
// Q = 31 bits 30 to 0.
// P = 15 bits 14 to 0.
//
// If we were doing 46 bit math, the multiplication product (of_seed * 16807)
// would be:
//
// Q
// + (P * 0x80000000)
//
// Observe that this is the same as:
//
// Q
// + (P * 0x7FFFFFFF)
// + (P * 0x00000001)
//
// However, we don't need or want a 46 bit result. We only want that result
// mod(0x7FFFFFFF). Therfore we can ignore the middle line above and use for
// our result:
//
// Q
// + P
//
// This is a lot snappier than using a division, as the Schrage technique
// requires.
//
#include <stdio.h>
#include "of_openfec_api.h"
#include "of_rand.h"
UINT64 of_seed;
/**
* Set this constant to check the conformity for this prng.
* Do that only in debug mode since it's time consumming.
*/
//#define CHECK_PRNG_CONFORMITY
#if CHECK_PRNG_CONFORMITY
/**
* Check that the PRNG is compliant with [Park88].
*/
void
of_check_prng (void)
{
OF_ENTER_FUNCTION
INT32 i;
UINT64 val;
of_seed = 1;
for (i = 0; i < 10000; i++)
{
val = of_rand (0x7FFFFFFF);
}
if (val != 1043618065)
{
fprintf (stderr, "ldpc_rand: ERROR, invalid PRNG, 10,000th value is %d\n", val);
OF_EXIT_FUNCTION
return;
}
else
{
fprintf (stderr, "ldpc_rand: okay, PRNG is valid, 10,000th value is %d\n", val);
}
OF_EXIT_FUNCTION
}
#endif
/**
* Initialize the PRNG with a of_seed between 1 and 0x7FFFFFFE
* (2^^31-2) inclusive.
*/
void of_rfc5170_srand (UINT64 s)
{
OF_ENTER_FUNCTION
if ( (s >= 1) && (s <= 0x7FFFFFFE))
of_seed = s;
else
{
fprintf (stderr, "ldpc_rand: ERROR, seed (%llu) out of range\n", of_seed);
OF_EXIT_FUNCTION
return;
}
#if CHECK_PRNG_CONFORMITY
check_PRNG();
of_seed = s;
#endif
OF_EXIT_FUNCTION
}
/**
* Returns a random integer between 0 and maxv-1 inclusive.
* Derived from rand31pmc, Robin Whittle, Sept 20th 2005.
* http://www.firstpr.com.au/dsp/rand31/
* 16807 multiplier constant (7^^5)
* 0x7FFFFFFF modulo constant (2^^31-1)
* The inner PRNG produces a value between 1 and 0x7FFFFFFE
* (2^^31-2) inclusive.
* This value is then scaled between 0 and maxv-1 inclusive.
* This is the PRNG required by the LDPC-staircase RFC 5170.
*/
UINT64
of_rfc5170_rand (UINT64 maxv)
{
//OF_ENTER_FUNCTION
UINT64 hi, lo;
lo = 16807 * (of_seed & 0xFFFF);
hi = 16807 * (of_seed >> 16);
lo += (hi & 0x7FFF) << 16;
lo += hi >> 15;
if (lo > 0x7FFFFFFF)
lo -= 0x7FFFFFFF;
of_seed = (UINT64) lo;
//OF_EXIT_FUNCTION
return ( (UINT64)
( (double) of_seed * (double) maxv / (double) 0x7FFFFFFF));
}

View File

@@ -0,0 +1,62 @@
/* $Id: of_rand.h 186 2014-07-16 07:17:53Z roca $ */
/*
* OpenFEC.org AL-FEC Library.
* (c) Copyright 2009 - 2012 INRIA - All rights reserved
* Contact: vincent.roca@inria.fr
*
* This software is governed by the CeCILL-C license under French law and
* abiding by the rules of distribution of free software. You can use,
* modify and/ or redistribute the software under the terms of the CeCILL-C
* license as circulated by CEA, CNRS and INRIA at the following URL
* "http://www.cecill.info".
*
* As a counterpart to the access to the source code and rights to copy,
* modify and redistribute granted by the license, users are provided only
* with a limited warranty and the software's author, the holder of the
* economic rights, and the successive licensors have only limited
* liability.
*
* In this respect, the user's attention is drawn to the risks associated
* with loading, using, modifying and/or developing or reproducing the
* software by the user in light of its specific status of free software,
* that may mean that it is complicated to manipulate, and that also
* therefore means that it is reserved for developers and experienced
* professionals having in-depth computer knowledge. Users are therefore
* encouraged to load and test the software's suitability as regards their
* requirements in conditions enabling the security of their systems and/or
* data to be ensured and, more generally, to use and operate it in the
* same conditions as regards security.
*
* The fact that you are presently reading this means that you have had
* knowledge of the CeCILL-C license and that you accept its terms.
*/
#ifndef OF_RAND
#define OF_RAND
/**
* \fn void of_rfc5170_srand (UINT64 s)
* \brief Initialize the PRNG with a of_seed between 1 and 0x7FFFFFFE
* (2^^31-2) inclusive.
* \param s (IN) seed
* \return void
*/
void of_rfc5170_srand (UINT64 s);
/**
* \fn UINT64 of_rfc5170_rand (UINT64 maxv)
* \brief Derived from rand31pmc, Robin Whittle, Sept 20th 2005.
* http://www.firstpr.com.au/dsp/rand31/
* 16807 multiplier constant (7^^5)
* 0x7FFFFFFF modulo constant (2^^31-1)
* The inner PRNG produces a value between 1 and 0x7FFFFFFE
* (2^^31-2) inclusive.
* This value is then scaled between 0 and maxv-1 inclusive.
* This is the PRNG required by the LDPC-staircase RFC 5170.
* \return Returns a random integer between 0 and maxv-1 inclusive.
*/
UINT64 of_rfc5170_rand (UINT64 maxv);
#endif //OF_RAND

View File

@@ -0,0 +1,82 @@
/* $Id: of_types.h 72 2012-04-13 13:27:26Z detchart $ */
/*
* OpenFEC.org AL-FEC Library.
* (c) Copyright 2009 - 2012 INRIA - All rights reserved
* Contact: vincent.roca@inria.fr
*
* This software is governed by the CeCILL-C license under French law and
* abiding by the rules of distribution of free software. You can use,
* modify and/ or redistribute the software under the terms of the CeCILL-C
* license as circulated by CEA, CNRS and INRIA at the following URL
* "http://www.cecill.info".
*
* As a counterpart to the access to the source code and rights to copy,
* modify and redistribute granted by the license, users are provided only
* with a limited warranty and the software's author, the holder of the
* economic rights, and the successive licensors have only limited
* liability.
*
* In this respect, the user's attention is drawn to the risks associated
* with loading, using, modifying and/or developing or reproducing the
* software by the user in light of its specific status of free software,
* that may mean that it is complicated to manipulate, and that also
* therefore means that it is reserved for developers and experienced
* professionals having in-depth computer knowledge. Users are therefore
* encouraged to load and test the software's suitability as regards their
* requirements in conditions enabling the security of their systems and/or
* data to be ensured and, more generally, to use and operate it in the
* same conditions as regards security.
*
* The fact that you are presently reading this means that you have had
* knowledge of the CeCILL-C license and that you accept its terms.
*/
#ifndef OF_TYPES
#define OF_TYPES
#ifndef __cplusplus
#ifndef bool
#define bool UINT32
#define true 1
#define false 0
#endif
#endif /* !__cplusplus */
#ifndef UINT32
#define INT8 char
#define INT16 short
#define UINT8 unsigned char
#define UINT16 unsigned short
#if defined(__LP64__) || (__WORDSIZE == 64) /* 64 bit architectures */
#define INT32 int /* yes, it's also true in LP64! */
#define UINT32 unsigned int /* yes, it's also true in LP64! */
#else /* 32 bit architectures */
#define INT32 int /* int creates fewer compilations pbs than long */
#define UINT32 unsigned int /* int creates fewer compilations pbs than long */
#endif /* 32/64 architectures */
#endif /* !UINT32 */
#ifndef UINT64
#ifdef WIN32
#define INT64 __int64
#define UINT64 __uint64
#else /* UNIX */
#define INT64 long long
#define UINT64 unsigned long long
#endif /* OS */
#endif /* !UINT64 */
/**
* gf type is used for Reed-Solomon codecs (over 2^8 and 2^m with m <=8).
* It reprensents a Galois field element.
*/
typedef unsigned char gf;
#endif //OF_TYPES

View File

@@ -0,0 +1,56 @@
/* $Id: of_statistics.c 207 2014-12-10 19:47:50Z roca $ */
/*
* OpenFEC.org AL-FEC Library.
* (c) Copyright 2009 - 2012 INRIA - All rights reserved
* Contact: vincent.roca@inria.fr
*
* This software is governed by the CeCILL-C license under French law and
* abiding by the rules of distribution of free software. You can use,
* modify and/ or redistribute the software under the terms of the CeCILL-C
* license as circulated by CEA, CNRS and INRIA at the following URL
* "http://www.cecill.info".
*
* As a counterpart to the access to the source code and rights to copy,
* modify and redistribute granted by the license, users are provided only
* with a limited warranty and the software's author, the holder of the
* economic rights, and the successive licensors have only limited
* liability.
*
* In this respect, the user's attention is drawn to the risks associated
* with loading, using, modifying and/or developing or reproducing the
* software by the user in light of its specific status of free software,
* that may mean that it is complicated to manipulate, and that also
* therefore means that it is reserved for developers and experienced
* professionals having in-depth computer knowledge. Users are therefore
* encouraged to load and test the software's suitability as regards their
* requirements in conditions enabling the security of their systems and/or
* data to be ensured and, more generally, to use and operate it in the
* same conditions as regards security.
*
* The fact that you are presently reading this means that you have had
* knowledge of the CeCILL-C license and that you accept its terms.
*/
#include <stdio.h>
#include "../of_types.h"
#include "../of_debug.h"
#include "../of_openfec_api.h"
#include "of_statistics.h"
#ifdef OF_DEBUG
void of_print_symbols_stats(of_symbols_stats_t* stats)
{
OF_TRACE_LVL(0,("nb source symbols received: %u\n", stats->nb_source_symbols_received))
OF_TRACE_LVL(0,("nb repair symbols received: %u\n", stats->nb_repair_symbols_received));
OF_TRACE_LVL(0,("nb source symbols built during IT decoding: %i\n", stats->nb_source_symbols_built_with_it));
OF_TRACE_LVL(0,("nb repair symbols built during IT decoding: %i\n", stats->nb_repair_symbols_built_with_it));
OF_TRACE_LVL(0,("nb source symbols built during ML decoding: %i\n", stats->nb_source_symbols_built_with_ml));
OF_TRACE_LVL(0,("nb repair symbols built during ML decoding: %i\n", stats->nb_repair_symbols_built_with_ml));
OF_TRACE_LVL(0,("nb source symbols ignored: %i\n", stats->nb_source_symbols_ignored));
OF_TRACE_LVL(0,("nb repair symbols ignored: %i\n", stats->nb_repair_symbols_ignored));
}
#endif

View File

@@ -0,0 +1,73 @@
/* $Id: of_statistics.h 186 2014-07-16 07:17:53Z roca $ */
/*
* OpenFEC.org AL-FEC Library.
* (c) Copyright 2009 - 2012 INRIA - All rights reserved
* Contact: vincent.roca@inria.fr
*
* This software is governed by the CeCILL-C license under French law and
* abiding by the rules of distribution of free software. You can use,
* modify and/ or redistribute the software under the terms of the CeCILL-C
* license as circulated by CEA, CNRS and INRIA at the following URL
* "http://www.cecill.info".
*
* As a counterpart to the access to the source code and rights to copy,
* modify and redistribute granted by the license, users are provided only
* with a limited warranty and the software's author, the holder of the
* economic rights, and the successive licensors have only limited
* liability.
*
* In this respect, the user's attention is drawn to the risks associated
* with loading, using, modifying and/or developing or reproducing the
* software by the user in light of its specific status of free software,
* that may mean that it is complicated to manipulate, and that also
* therefore means that it is reserved for developers and experienced
* professionals having in-depth computer knowledge. Users are therefore
* encouraged to load and test the software's suitability as regards their
* requirements in conditions enabling the security of their systems and/or
* data to be ensured and, more generally, to use and operate it in the
* same conditions as regards security.
*
* The fact that you are presently reading this means that you have had
* knowledge of the CeCILL-C license and that you accept its terms.
*/
#ifndef STATISTICS_H
#define STATISTICS_H
#ifdef OF_DEBUG
/**
* Symbol level statistics.
*/
typedef struct of_symbols_stats
{
/** Number of source symbols received by decoder (they havn't been decoded). */
UINT32 nb_source_symbols_received;
/** Number of repair symbols received by decoder (they havn't been decoded). */
UINT32 nb_repair_symbols_received;
/** Number of source symbols decoded during IT decoding. */
UINT32 nb_source_symbols_built_with_it;
/** Number of source symbols decoded during ML decoding. */
UINT32 nb_source_symbols_built_with_ml;
/** Number of repair symbols decoded during IT decoding. */
UINT32 nb_repair_symbols_built_with_it;
/** Number of repair symbols decoded during ML decoding. */
UINT32 nb_repair_symbols_built_with_ml;
/** Number of source symbols ...... */
UINT32 nb_source_symbols_ignored;
/** Number of repair symbols ...... */
UINT32 nb_repair_symbols_ignored;
} of_symbols_stats_t;
/**
* Print the statistics to the standard output.
*/
void of_print_symbols_stats(of_symbols_stats_t*);
#endif // OF_DEBUG
#endif //STATISTICS_H

View File

@@ -0,0 +1,319 @@
/* $Id: of_2d_parity.h 184 2014-07-15 09:42:57Z roca $ */
/*
* OpenFEC.org AL-FEC Library.
* (c) Copyright 2009 - 2012 INRIA - All rights reserved
* Contact: vincent.roca@inria.fr
*
* This software is governed by the CeCILL-C license under French law and
* abiding by the rules of distribution of free software. You can use,
* modify and/ or redistribute the software under the terms of the CeCILL-C
* license as circulated by CEA, CNRS and INRIA at the following URL
* "http://www.cecill.info".
*
* As a counterpart to the access to the source code and rights to copy,
* modify and redistribute granted by the license, users are provided only
* with a limited warranty and the software's author, the holder of the
* economic rights, and the successive licensors have only limited
* liability.
*
* In this respect, the user's attention is drawn to the risks associated
* with loading, using, modifying and/or developing or reproducing the
* software by the user in light of its specific status of free software,
* that may mean that it is complicated to manipulate, and that also
* therefore means that it is reserved for developers and experienced
* professionals having in-depth computer knowledge. Users are therefore
* encouraged to load and test the software's suitability as regards their
* requirements in conditions enabling the security of their systems and/or
* data to be ensured and, more generally, to use and operate it in the
* same conditions as regards security.
*
* The fact that you are presently reading this means that you have had
* knowledge of the CeCILL-C license and that you accept its terms.
*/
#ifdef OF_USE_2D_PARITY_MATRIX_CODEC
#ifndef OF_2D_PARITY_H
#define OF_2D_PARITY_H
typedef struct of_2d_symbol_stats_op
{
UINT32 nb_xor_for_IT;
UINT32 nb_xor_for_ML;
} of_2d_symbol_stats_op_t;
/**
* 2d-parity stable codec specific control block structure.
*/
typedef struct of_2d_parity_cb
{
/*****************************************************************************
* of_linear_binary_code_cb *
******************************************************************************/
/* *
************************************************************************** *
* of_cb_t * *
************************************************************************** */
of_codec_id_t codec_id; /* must begin with fec_codec_id * */
of_codec_type_t codec_type; /* must be 2nd item * */
UINT32 nb_source_symbols; /** k parameter (AKA code dimension).* */
UINT32 nb_repair_symbols; /** r = n - k parameter. * */
UINT32 encoding_symbol_length; /** symbol length. * */
/************************************************************************* */
UINT32 nb_total_symbols; /** n parameter (AKA code length). */
/* parity check matrix */
of_mod2sparse* pchk_matrix;
/** usage statistics, for this codec instance. */
of_symbol_stats_op_t *stats_xor;
#ifdef OF_DEBUG
of_symbols_stats_t* stats_symbols;
#endif
UINT32 nb_source_symbol_ready; // Number of source symbols ready
UINT32 nb_repair_symbol_ready; // Number of parity symbols ready
#ifdef ML_DECODING /* { */
UINT32 *index_rows; // Indirection index to access initial m_chekValues array
UINT32 *index_cols; // Indirection index to access initial symbol array
UINT32 remain_cols; // Nb of non empty remaining cols in the future simplified matrix
UINT32 remain_rows; // Nb of non empty remaining rows in the future simplified matrix
of_mod2sparse *pchk_matrix_simplified; // Simplified Parity Check Matrix in sparse mode format
of_mod2sparse *original_pchkMatrix;
of_mod2sparse* pchk_matrix_gauss; // Parity Check matrix in sparse mode format.
// This matrix is also used as a generator matrix
UINT32 dec_step; // Current step in the Gauss decoding algorithm
UINT32 threshold_simplification; // threshold (number of symbols) above which we
// run the Gaussian Elimination algorithm
#endif /* } ML_DECODING */
#ifdef OF_USE_DECODER /* { */
/** table of all check values, i.e. that contain the constant term of each equation. */
void** tab_const_term_of_equ;
/** table containing the number of encoding symbols of each equation. */
UINT16* tab_nb_enc_symbols_per_equ;
/** table containing the number of unknow symbols (i.e. neither received nor decoded
* at that time) of each equation. */
UINT16* tab_nb_unknown_symbols;
/** table containing the number of equations in which a repair symbol is included. */
UINT16* tab_nb_equ_for_repair;
void** repair_symbols_values;
#endif /* } OF_USE_DECODER */
void **encoding_symbols_tab;
/** callbacks registered by the application. */
void* (*decoded_source_symbol_callback) (void *context,/* */
UINT32 size, /* size of decoded source symbol */
UINT32 esi); /* encoding symbol ID in {0..k-1} */
void* (*decoded_repair_symbol_callback) (void *context,/* */
UINT32 size, /* size of decoded repair symbol */
UINT32 esi); /* encoding symbol ID in {0..k-1} */
void* context_4_callback;/* */
/*****************************************************************************/
/** Maximum number of source symbols supported by this codec for practical reasons. */
UINT32 max_nb_source_symbols;
/** Maximum number of encoding symbols supported by this codec for practical reasons. */
UINT32 max_nb_encoding_symbols;
/** ESI of first non decoded source symbol.
* Used by is_decoding_complete function. */
UINT32 first_non_decoded;
} of_2d_parity_cb_t;
/*
* Function prototypes.
*/
/**
* This function create the codec instance for the 2D parity codec.
*
* @fn of_status_t of_2d_parity_create_codec_instance (of_2d_parity_cb_t** of_cb)
* @brief create a 2D parity codec instance
* @param of_cb (IN/OUT) address of the pointer to a 2D parity codec control block. This pointer is updated
* by this function.
* In case of success, it points to a session structure allocated by the
* library. In case of failure it points to NULL.
* @return Error status. The ofcb pointer is updated according to the success return
* status.
*/
of_status_t of_2d_parity_create_codec_instance (of_2d_parity_cb_t** of_cb);
/**
* This function releases all the internal resources used by this FEC codec instance.
* None of the source symbol buffers will be free'ed by this function, even those decoded by
* the library if any, regardless of whether a callback has been registered or not. It's the
* responsibility of the caller to free them.
*
* @fn of_status_t of_2d_parity_release_codec_instance (of_2d_parity_cb_t* ofcb)
* @brief release all resources used by the codec
* @param ofcb (IN) Pointer to the control block.
* @return Error status.
*/
of_status_t of_2d_parity_release_codec_instance (of_2d_parity_cb_t* ofcb);
/**
*
* @fn of_status_t of_2d_parity_set_fec_parameters (of_2d_parity_cb_t* ofcb, of_2d_parity_parameters_t* params)
* @brief set all the FEC codec parameters (e.g. k, n, or symbol size)
* @param ofcb (IN) Pointer to the control block.
* @param params (IN) pointer to a structure containing the FEC parameters associated to
* a specific FEC codec.
* @return Error status.
*/
of_status_t of_2d_parity_set_fec_parameters (of_2d_parity_cb_t* ofcb,
of_2d_parity_parameters_t* params);
/**
* @fn of_status_t of_2d_parity_set_callback_functions (of_2d_parity_cb_t *ofcb,void* (*decoded_source_symbol_callback)
* (void *context,UINT32 size,UINT32 esi), void* (*decoded_repair_symbol_callback)
* (void *context,UINT32 size,UINT32 esi),void* context_4_callback)
* @brief set various callbock functions (see header of_open_fec_api.h)
* @param ofcb (IN) Pointer to the session.
*
* @param decoded_source_symbol_callback
* (IN) Pointer to the function, within the application, that
* needs to be called each time a source symbol is decoded.
* If this callback is not initialized, the symbol is managed
* internally.
*
* @param decoded_repair_symbol_callback
* (IN) Pointer to the function, within the application, that
* needs to be called each time a repair symbol is decoded.
* If this callback is not initialized, the symbol is managed
* internally.
*
* @param context_4_callback (IN) Pointer to the application-specific context that will be
* passed to the callback function (if any). This context is not
* interpreted by this function.
*
* @return Completion status (LDPC_OK or LDPC_ERROR).
*/
of_status_t of_2d_parity_set_callback_functions (of_2d_parity_cb_t* ofcb,
void* (*decoded_source_symbol_callback) (void *context,
UINT32 size, /* size of decoded source symbol */
UINT32 esi), /* encoding symbol ID in {0..k-1} */
void* (*decoded_repair_symbol_callback) (void *context,
UINT32 size, /* size of decoded repair symbol */
UINT32 esi), /* encoding symbol ID in {0..k-1} */
void* context_4_callback);
#ifdef OF_USE_ENCODER
/**
* @fn of_status_t of_2d_parity_build_repair_symbol (of_2d_parity_cb_t* ofcb, void* encoding_symbols_tab[], UINT32 esi_of_symbol_to_build)
* @brief build a repair symbol (encoder only)
* @param ofcb (IN) Pointer to the session.
* @param encoding_symbols_tab (IN/OUT) table of source and repair symbols.
* The entry for the repair symbol to build can either point
* to a buffer allocated by the application, or let to NULL
* meaning that of_build_repair_symbol will allocate memory.
* @param esi_of_symbol_to_build
* (IN) encoding symbol ID of the repair symbol to build in
* {k..n-1}
* @return Error status.
*/
of_status_t of_2d_parity_build_repair_symbol (of_2d_parity_cb_t* ofcb,
void* encoding_symbols_tab[],
UINT32 esi_of_symbol_to_build);
#endif //OF_USE_ENCODER
#ifdef OF_USE_DECODER
/**
* @fn of_status_t of_2d_parity_decode_with_new_symbol (of_2d_parity_cb_t* ofcb, void* const new_symbol_buf, UINT32 new_symbol_esi)
* @brief (try to) decode with a newly received symbol
* @param ofcb (IN) Pointer to the session.
* @param new_symbol (IN) Pointer to the encoding symbol now available (i.e. a new
* symbol received by the application, or a decoded symbol in case
* of a recursive call).
* @param new_symbol_esi (IN) Encoding symbol ID of the newly symbol available, in {0..n-1}.
* @return Error status (NB: this function does not return OF_STATUS_FAILURE).
*/
of_status_t of_2d_parity_decode_with_new_symbol (of_2d_parity_cb_t* ofcb,
void* new_symbol,
UINT32 new_symbol_esi);
/**
* @fn of_status_t of_2d_parity_set_available_symbols (of_2d_parity_cb_t* ofcb, void* const encoding_symbols_tab[]);
* @brief inform the decoder of all the available (received) symbols
* @param ofcb (IN) Pointer to the session.
* @param encoding_symbols_tab (IN) Pointer to the available encoding symbols table. To each
* available symbol the corresponding entry in the table must point
* to the associated buffer. Entries set to NULL are interpreted as
* corresponding to erased symbols.
* @return Error status.
*/
of_status_t of_2d_parity_set_available_symbols (of_2d_parity_cb_t* ofcb,
void* const encoding_symbols_tab[]);
/**
* @fn of_status_t of_2d_parity_finish_decoding (of_2d_parity_cb_t* ofcb)
* @brief finish decoding with available symbols
* @param ofcb (IN) Pointer to the session.
* @return Error status. Returns OF_STATUS_FAILURE if decoding failed, or
* OF_STATUS_OK if decoding succeeded, or OF_STATUS_*_ERROR in case
* of (fatal) error.
*/
of_status_t of_2d_parity_finish_decoding (of_2d_parity_cb_t* ofcb);
/**
* @fn bool of_2d_parity_is_decoding_complete (of_2d_parity_cb_t* ofcb)
* @brief check if decoding is finished
* @param ofcb (IN) Pointer to the session.
* @return Boolean. Warning, this is one of the very functions of the library that
* does not return an error status.
*/
bool of_2d_parity_is_decoding_complete (of_2d_parity_cb_t* ofcb);
/**
* @fn of_status_t of_2d_parity_get_source_symbols_tab (of_2d_parity_cb_t* ofcb, void* source_symbols_tab[])
* @brief get the table of available source symbols (after decoding)
* @param ofcb (IN) Pointer to the session.
* @param source_symbols_tab (IN/OUT) table, that will be filled by the library and returned
* to the application.
* @return Error status.
*/
of_status_t of_2d_parity_get_source_symbols_tab (of_2d_parity_cb_t* ofcb,
void* source_symbols_tab[]);
/**
* @fn of_status_t of_2d_parity_set_control_parameter (of_2d_parity_cb_t* ofcb,UINT32 type,void* value,UINT32 length)
* @brief set a specific FEC parameter
* @param ofcb (IN) Pointer to the session.
* @param type (IN) Type of parameter. This type is FEC codec ID specific.
* @param value (IN) Pointer to the value of the parameter. The type of the object pointed
* is FEC codec ID specific.
* @param length (IN) length of pointer value
* @return Error status.
*/
of_status_t of_2d_parity_set_control_parameter(of_2d_parity_cb_t* ofcb,
UINT32 type,
void* value,
UINT32 length);
/**
* @fn of_status_t of_2d_parity_get_control_parameter (of_2d_parity_cb_t* ofcb,UINT32 type,void* value,UINT32 length)
* @brief get a specific FEC parameter
* @param ofcb (IN) Pointer to the session.
* @param type (IN) Type of parameter. This type is FEC codec ID specific.
* @param value (IN/OUT) Pointer to the value of the parameter. The type of the object
* pointed is FEC codec ID specific. This function updates the value object
* accordingly. The application, who knows the FEC codec ID, is responsible
* to allocating the approriate object pointed by the value pointer.
* @param length (IN) length of pointer value
* @return Error status.
*/
of_status_t of_2d_parity_get_control_parameter(of_2d_parity_cb_t* ofcb,
UINT32 type,
void* value,
UINT32 length);
#endif //OF_USE_DECODER
#endif //OF_2D_PARITY_H
#endif /* #ifdef OF_USE_2D_PARITY_MATRIX_CODEC */

View File

@@ -0,0 +1,464 @@
/* $Id: of_2d_parity_api.c 185 2014-07-15 09:57:16Z roca $ */
/*
* OpenFEC.org AL-FEC Library.
* (c) Copyright 2009 - 2012 INRIA - All rights reserved
* Contact: vincent.roca@inria.fr
*
* This software is governed by the CeCILL-C license under French law and
* abiding by the rules of distribution of free software. You can use,
* modify and/ or redistribute the software under the terms of the CeCILL-C
* license as circulated by CEA, CNRS and INRIA at the following URL
* "http://www.cecill.info".
*
* As a counterpart to the access to the source code and rights to copy,
* modify and redistribute granted by the license, users are provided only
* with a limited warranty and the software's author, the holder of the
* economic rights, and the successive licensors have only limited
* liability.
*
* In this respect, the user's attention is drawn to the risks associated
* with loading, using, modifying and/or developing or reproducing the
* software by the user in light of its specific status of free software,
* that may mean that it is complicated to manipulate, and that also
* therefore means that it is reserved for developers and experienced
* professionals having in-depth computer knowledge. Users are therefore
* encouraged to load and test the software's suitability as regards their
* requirements in conditions enabling the security of their systems and/or
* data to be ensured and, more generally, to use and operate it in the
* same conditions as regards security.
*
* The fact that you are presently reading this means that you have had
* knowledge of the CeCILL-C license and that you accept its terms.
*/
#include "of_2d_parity_includes.h"
#ifdef OF_USE_2D_PARITY_MATRIX_CODEC
of_status_t of_2d_parity_create_codec_instance (of_2d_parity_cb_t** of_cb)
{
of_codec_type_t codec_type; /* temporary value */
of_2d_parity_cb_t *cb;
OF_ENTER_FUNCTION
cb = (of_2d_parity_cb_t*) of_realloc (*of_cb, sizeof (of_2d_parity_cb_t));
/* realloc does not initialize the additional buffer space, so do that manually,
* then re-initialize a few parameters */
codec_type = cb->codec_type;
memset(cb, 0, sizeof(*cb));
*of_cb = cb;
cb->codec_id = OF_CODEC_2D_PARITY_MATRIX_STABLE;
cb->codec_type = codec_type;
cb->max_nb_source_symbols = OF_2D_PARITY_MATRIX_MAX_NB_SOURCE_SYMBOLS_DEFAULT; /* init it immediately... */
cb->max_nb_encoding_symbols = OF_2D_PARITY_MATRIX_MAX_NB_ENCODING_SYMBOLS_DEFAULT; /* init it immediately... */
OF_EXIT_FUNCTION
return OF_STATUS_OK;
}
of_status_t of_2d_parity_release_codec_instance (of_2d_parity_cb_t* ofcb)
{
UINT32 i;
OF_ENTER_FUNCTION
if (ofcb->pchk_matrix != NULL)
{
of_mod2sparse_free(ofcb->pchk_matrix);
of_free (ofcb->pchk_matrix);
ofcb->pchk_matrix = NULL;
}
if (ofcb->encoding_symbols_tab != NULL)
{
/* do not try to free source buffers, it's the responsibility of the application
* using this library to free everything. Only try to free repair symbols. */
for (i = ofcb->nb_source_symbols; i < ofcb->nb_total_symbols; i++)
{
if (ofcb->encoding_symbols_tab[i] != NULL)
{
of_free (ofcb->encoding_symbols_tab[i]);
ofcb->encoding_symbols_tab[i] = NULL;
}
}
of_free (ofcb->encoding_symbols_tab);
ofcb->encoding_symbols_tab = NULL;
}
#ifdef OF_USE_DECODER
if(ofcb->codec_type & OF_DECODER)
{
if (ofcb->tab_nb_enc_symbols_per_equ != NULL)
{
of_free (ofcb->tab_nb_enc_symbols_per_equ);
ofcb->tab_nb_enc_symbols_per_equ = NULL;
}
if (ofcb->tab_nb_equ_for_repair != NULL)
{
of_free (ofcb->tab_nb_equ_for_repair);
ofcb->tab_nb_equ_for_repair = NULL;
}
if (ofcb->tab_nb_unknown_symbols != NULL)
{
of_free (ofcb->tab_nb_unknown_symbols);
ofcb->tab_nb_unknown_symbols = NULL;
}
if (ofcb->tab_const_term_of_equ != NULL)
{
for (i = 0; i < ofcb->nb_repair_symbols; i++)
{
if (ofcb->tab_const_term_of_equ[i] != NULL)
{
of_free (ofcb->tab_const_term_of_equ[i]);
ofcb->tab_const_term_of_equ[i] = NULL;
}
}
of_free(ofcb->tab_const_term_of_equ);
}
}
#endif
#ifdef OF_2D_PARITY_ML_DECODING
if (ofcb->index_rows != NULL)
{
of_free (ofcb->index_rows);
ofcb->index_rows = NULL;
}
if (ofcb->index_cols != NULL)
{
of_free (ofcb->index_cols);
ofcb->index_cols = NULL;
}
if (ofcb->pchk_matrix_simplified != NULL)
{
of_mod2sparse_free (ofcb->pchk_matrix_simplified);
of_free(ofcb->pchk_matrix_simplified);
ofcb->pchk_matrix_simplified = NULL;
}
if (ofcb->original_pchkMatrix != NULL)
{
of_mod2sparse_free (ofcb->original_pchkMatrix);
ofcb->original_pchkMatrix = NULL;
}
if (ofcb->pchk_matrix_gauss != NULL)
{
of_mod2sparse_free (ofcb->pchk_matrix_gauss);
ofcb->pchk_matrix_gauss = NULL;
}
#endif
#ifdef OF_DEBUG
if (ofcb->stats_xor != NULL)
{
of_print_xor_symbols_statistics(ofcb->stats_xor);
of_free(ofcb->stats_xor);
}
#endif
OF_EXIT_FUNCTION
return OF_STATUS_OK;
}
of_status_t of_2d_parity_set_fec_parameters (of_2d_parity_cb_t* ofcb,
of_2d_parity_parameters_t* params)
{
of_mod2entry *e;
UINT32 row;
UINT32 seq;
OF_ENTER_FUNCTION
#ifdef OF_DEBUG
ofcb->stats_xor = of_calloc(1, sizeof(of_2d_symbol_stats_op_t));
ofcb->stats_symbols = of_calloc(1,sizeof(of_symbols_stats_t));
#endif
if ((ofcb->nb_source_symbols = params->nb_source_symbols) > ofcb->max_nb_source_symbols) {
OF_PRINT_ERROR(("of_2d_parity_set_fec_parameters: ERROR, invalid nb_source_symbols parameter (got %d, maximum is %d)",
ofcb->nb_source_symbols, ofcb->max_nb_source_symbols));
goto error;
}
ofcb->nb_repair_symbols = params->nb_repair_symbols;
ofcb->nb_total_symbols = ofcb->nb_source_symbols + ofcb->nb_repair_symbols;
if (ofcb->nb_total_symbols > ofcb->max_nb_encoding_symbols) {
OF_PRINT_ERROR(("of_2d_parity_set_fec_parameters: ERROR, invalid number of encoding symbols (got %d, maximum is %d)",
ofcb->nb_total_symbols, ofcb->max_nb_encoding_symbols));
goto error;
}
ofcb->encoding_symbol_length = params->encoding_symbol_length;
OF_TRACE_LVL (1, ("%s: k=%u, n-k=%u, n=%u, symbol_length=%u, PRNG seed=%u, N1=%u\n", __FUNCTION__,
ofcb->nb_source_symbols, ofcb->nb_repair_symbols, ofcb->nb_total_symbols,
ofcb->encoding_symbol_length, 0, 0))
ofcb->pchk_matrix = of_create_pchk_matrix (ofcb->nb_repair_symbols, ofcb->nb_total_symbols, Evenboth,
0, 0, false, Type2DMATRIX, 1);
if (ofcb->pchk_matrix == NULL)
{
OF_PRINT_ERROR(("of_2d_parity_set_fec_parameters : ERROR, parity check matrix can't be created with this parameters.."))
goto error;
}
#ifdef OF_DEBUG
if (of_verbosity >= 2)
{
of_mod2sparse_matrix_stats(stdout, ofcb->pchk_matrix, ofcb->nb_source_symbols, ofcb->nb_repair_symbols);
}
#endif
#ifdef OF_2D_PARITY_ML_DECODING
ofcb->pchk_matrix_simplified = NULL;
#endif
if ((ofcb->encoding_symbols_tab = (void**) of_calloc (ofcb->nb_total_symbols, sizeof (void*))) == NULL) {
goto no_mem;
}
#ifdef OF_USE_DECODER
if (ofcb->codec_type & OF_DECODER)
{
ofcb->tab_nb_unknown_symbols = (UINT16*)
of_calloc (ofcb->nb_repair_symbols, sizeof (UINT16));
ofcb->tab_const_term_of_equ = (void**)
of_calloc (ofcb->nb_repair_symbols, sizeof (void*));
ofcb->tab_nb_equ_for_repair = (UINT16*)
of_calloc (ofcb->nb_repair_symbols, sizeof (UINT16));
ofcb->tab_nb_enc_symbols_per_equ = (UINT16*)
of_calloc (ofcb->nb_repair_symbols, sizeof (UINT16));
if (ofcb->tab_nb_unknown_symbols == NULL || ofcb->tab_const_term_of_equ == NULL ||
ofcb->tab_nb_equ_for_repair == NULL || ofcb->tab_nb_enc_symbols_per_equ == NULL) {
goto no_mem;
}
// and update the various tables now
for (row = 0; row < ofcb->nb_repair_symbols; row++)
{
for (e = of_mod2sparse_first_in_row (ofcb->pchk_matrix, row);
!of_mod2sparse_at_end (e);
e = of_mod2sparse_next_in_row (e))
{
ofcb->tab_nb_enc_symbols_per_equ[row]++;
ofcb->tab_nb_unknown_symbols[row]++;
}
}
for (seq = ofcb->nb_source_symbols; seq < (ofcb->nb_total_symbols); seq++)
{
for (e = of_mod2sparse_first_in_col (ofcb->pchk_matrix, of_get_symbol_col ((of_cb_t*)ofcb, seq));
!of_mod2sparse_at_end (e);
e = of_mod2sparse_next_in_col (e))
{
ofcb->tab_nb_equ_for_repair[seq - ofcb->nb_source_symbols]++;
}
}
}
#endif //OF_USE_DECODER
ofcb->nb_source_symbol_ready = 0; // Number of source symbols ready
ofcb->nb_repair_symbol_ready = 0; // Number of parity symbols ready
//ofcb->nb_non_dup_symbols_recvd = 0;// Number of non-duplicated symbols received
#ifdef OF_2D_PARITY_ML_DECODING
ofcb->index_rows = NULL; // Indirection index to access initial m_chekValues array
ofcb->index_cols = NULL; // Indirection index to access initial symbol array
ofcb->remain_cols = 0; // Nb of non empty remaining cols in the future simplified matrix
ofcb->remain_rows = 0; // Nb of non empty remaining rows in the future simplified matrix
ofcb->pchk_matrix_simplified = NULL; // Simplified Parity Check Matrix in sparse mode format
ofcb->original_pchkMatrix = NULL;
ofcb->pchk_matrix_gauss = NULL; // Parity Check matrix in sparse mode format. This matrix
// is also used as a generator matrix in LDGM-* modes
ofcb->dec_step = 0; // Current step in the Gauss Elimination algorithm
ofcb->threshold_simplification = 0; // threshold (number of symbols) above which we
// run the Gauss Elimination algorithm
#endif
OF_EXIT_FUNCTION
return OF_STATUS_OK;
no_mem:
OF_PRINT_ERROR(("out of memory"));
error:
OF_EXIT_FUNCTION
return OF_STATUS_FATAL_ERROR;
}
of_status_t of_2d_parity_set_callback_functions (
of_2d_parity_cb_t* ofcb,
void* (*decoded_source_symbol_callback) (
void *context,
UINT32 size, /* size of decoded source symbol */
UINT32 esi), /* encoding symbol ID in {0..k-1} */
void* (*decoded_repair_symbol_callback) (
void *context,
UINT32 size, /* size of decoded repair symbol */
UINT32 esi), /* encoding symbol ID in {k..n-1} */
void* context_4_callback)
{
OF_ENTER_FUNCTION
ofcb->decoded_source_symbol_callback = decoded_source_symbol_callback;
ofcb->decoded_repair_symbol_callback = decoded_repair_symbol_callback;
ofcb->context_4_callback = context_4_callback;
OF_EXIT_FUNCTION
return OF_STATUS_OK;
}
#ifdef OF_USE_ENCODER
of_status_t of_2d_parity_build_repair_symbol (of_2d_parity_cb_t* ofcb,
void* encoding_symbols_tab[],
UINT32 esi_of_symbol_to_build)
{
of_mod2entry *e;
UINT32 col_to_build;
UINT32 esi;
void *to_add_buf;
void *parity_symbol;
OF_ENTER_FUNCTION
if (esi_of_symbol_to_build< ofcb->nb_source_symbols || esi_of_symbol_to_build >= ofcb->nb_total_symbols)
{
OF_PRINT_ERROR(("of_2d_parity_build_repair_symbol: Error, bad esi of encoding symbol (%d)", esi_of_symbol_to_build))
goto error;
}
parity_symbol = encoding_symbols_tab[esi_of_symbol_to_build];
memset (parity_symbol, 0, ofcb->encoding_symbol_length);
col_to_build = of_get_symbol_col ((of_cb_t*)ofcb, esi_of_symbol_to_build);
e = of_mod2sparse_first_in_row (ofcb->pchk_matrix, col_to_build);
while (!of_mod2sparse_at_end (e))
{
// paritySymbol_index in {0.. n-k-1} range, so this test is ok
if (e->col != col_to_build)
{
// don't add paritySymbol to itself
esi = of_get_symbol_esi ((of_cb_t*)ofcb, e->col);
to_add_buf = (void*) encoding_symbols_tab[esi];
if (to_add_buf == NULL)
{
OF_PRINT_ERROR(("symbol %d is not allocated", esi));
goto error;
}
#ifdef OF_DEBUG
of_add_to_symbol (parity_symbol, to_add_buf, ofcb->encoding_symbol_length, &(ofcb->stats_xor->nb_xor_for_IT));
#else
of_add_to_symbol (parity_symbol, to_add_buf, ofcb->encoding_symbol_length);
#endif
}
e = of_mod2sparse_next_in_row (e);
}
OF_TRACE_LVL (1, ("%s: repair symbol (esi=%d) built\n", __FUNCTION__, esi_of_symbol_to_build))
OF_EXIT_FUNCTION
return OF_STATUS_OK;
error:
OF_EXIT_FUNCTION
return OF_STATUS_ERROR;
}
#endif //OF_USE_ENCODER
#ifdef OF_USE_DECODER
of_status_t of_2d_parity_decode_with_new_symbol (of_2d_parity_cb_t* ofcb,
void* new_symbol,
UINT32 new_symbol_esi)
{
OF_ENTER_FUNCTION
return of_linear_binary_code_decode_with_new_symbol((of_linear_binary_code_cb_t*)ofcb,new_symbol,new_symbol_esi);
}
of_status_t of_2d_parity_set_available_symbols (of_2d_parity_cb_t* ofcb,
void* const encoding_symbols_tab[])
{
OF_ENTER_FUNCTION
UINT32 i;
for (i = 0; i < ofcb->nb_total_symbols; i++)
{
if (encoding_symbols_tab[i] != NULL)
{
ofcb->encoding_symbols_tab[i] = of_calloc (1, ofcb->encoding_symbol_length);
memcpy (ofcb->encoding_symbols_tab[i], encoding_symbols_tab[i], ofcb->encoding_symbol_length);
}
}
OF_EXIT_FUNCTION
return OF_STATUS_OK;
}
of_status_t of_2d_parity_finish_decoding (of_2d_parity_cb_t* ofcb)
{
OF_ENTER_FUNCTION
#ifdef OF_2D_PARITY_ML_DECODING
return of_linear_binary_code_finish_decoding_with_ml ((of_linear_binary_code_cb_t*)ofcb);
#else
return OF_STATUS_ERROR;
#endif
}
bool of_2d_parity_is_decoding_complete (of_2d_parity_cb_t* ofcb)
{
for (; ofcb->first_non_decoded < ofcb->nb_source_symbols; ofcb->first_non_decoded++)
{
if (ofcb->encoding_symbols_tab[ofcb->first_non_decoded] == NULL)
{
OF_TRACE_LVL (1, ("decoding not complete (%u source symbols ready, %u expected)\n",
ofcb->nb_source_symbol_ready, ofcb->nb_source_symbols))
//ASSERT(ofcb->nb_source_symbol_ready < ofcb->nb_source_symbols);
return false;
}
}
OF_TRACE_LVL (1, ("decoding is complete\n"))
//ASSERT(ofcb->nb_source_symbol_ready == ofcb->nb_source_symbols);
return true;
}
of_status_t of_2d_parity_get_source_symbols_tab(of_2d_parity_cb_t* ofcb,
void* source_symbols_tab[])
{
OF_ENTER_FUNCTION
memcpy (source_symbols_tab, ofcb->encoding_symbols_tab, sizeof (void *) * ofcb->nb_source_symbols);
OF_EXIT_FUNCTION
return OF_STATUS_OK;
}
#endif //OF_USE_DECODER
of_status_t of_2d_parity_set_control_parameter (of_2d_parity_cb_t* ofcb,
UINT32 type,
void* value,
UINT32 length)
{
OF_PRINT_ERROR(("of_2d_parity_set_control_parameter: ERROR, not implemented...\n"))
return OF_STATUS_ERROR;
}
of_status_t of_2d_parity_get_control_parameter (of_2d_parity_cb_t* ofcb,
UINT32 type,
void* value,
UINT32 length)
{
OF_ENTER_FUNCTION
switch (type) {
case OF_CTRL_GET_MAX_K:
if (value == NULL || length != sizeof(UINT32)) {
OF_PRINT_ERROR(("%s: OF_CTRL_GET_MAX_K ERROR: null value or bad length (got %d, expected %ld)\n",
__FUNCTION__, length, sizeof(UINT32)))
goto error;
}
*(UINT32*)value = ofcb->max_nb_source_symbols;
OF_TRACE_LVL(1, ("%s: OF_CTRL_GET_MAX_K (%d)\n", __FUNCTION__, *(UINT32*)value))
break;
case OF_CTRL_GET_MAX_N:
if (value == NULL || length != sizeof(UINT32)) {
OF_PRINT_ERROR(("%s: OF_CTRL_GET_MAX_N ERROR: null value or bad length (got %d, expected %ld)\n",
__FUNCTION__, length, sizeof(UINT32)))
goto error;
}
*(UINT32*)value = ofcb->max_nb_encoding_symbols;
OF_TRACE_LVL(1, ("%s: OF_CTRL_GET_MAX_N (%d)\n", __FUNCTION__, *(UINT32*)value))
break;
default:
OF_PRINT_ERROR(("%s: unknown type (%d)\n", __FUNCTION__, type))
goto error;
}
OF_EXIT_FUNCTION
return OF_STATUS_OK;
error:
OF_EXIT_FUNCTION
return OF_STATUS_ERROR;
}
#endif /* #ifdef OF_USE_2D_PARITY_MATRIX_CODEC */

View File

@@ -0,0 +1,62 @@
/* $Id: of_2d_parity_api.h 72 2012-04-13 13:27:26Z detchart $ */
/*
* OpenFEC.org AL-FEC Library.
* (c) Copyright 2009 - 2012 INRIA - All rights reserved
* Contact: vincent.roca@inria.fr
*
* This software is governed by the CeCILL-C license under French law and
* abiding by the rules of distribution of free software. You can use,
* modify and/ or redistribute the software under the terms of the CeCILL-C
* license as circulated by CEA, CNRS and INRIA at the following URL
* "http://www.cecill.info".
*
* As a counterpart to the access to the source code and rights to copy,
* modify and redistribute granted by the license, users are provided only
* with a limited warranty and the software's author, the holder of the
* economic rights, and the successive licensors have only limited
* liability.
*
* In this respect, the user's attention is drawn to the risks associated
* with loading, using, modifying and/or developing or reproducing the
* software by the user in light of its specific status of free software,
* that may mean that it is complicated to manipulate, and that also
* therefore means that it is reserved for developers and experienced
* professionals having in-depth computer knowledge. Users are therefore
* encouraged to load and test the software's suitability as regards their
* requirements in conditions enabling the security of their systems and/or
* data to be ensured and, more generally, to use and operate it in the
* same conditions as regards security.
*
* The fact that you are presently reading this means that you have had
* knowledge of the CeCILL-C license and that you accept its terms.
*/
#ifdef OF_USE_2D_PARITY_MATRIX_CODEC
#ifndef OF_CODEC_STABLE_2D_PARITY_API
#define OF_CODEC_STABLE_2D_PARITY_API
#include "../../lib_common/of_types.h"
/**
* @struct of_2d_parity_parameters_t
* @brief 2D parity stable codec specific FEC parameter structure.
*
* This structure contains the pieces of information required to initialize a codec instance,
* using the of_set_fec_parameters() function.
*/
typedef struct of_2d_parity_parameters
{
UINT32 nb_source_symbols; /* must be 1st item */
UINT32 nb_repair_symbols; /* must be 2nd item */
UINT32 encoding_symbol_length; /* must be 3rd item */
/*
* FEC codec id specific attributes follow...
*/
} of_2d_parity_parameters_t;
#endif /* OF_CODEC_STABLE_2D_PARITY_API */
#endif /* #ifdef OF_USE_2D_PARITY_MATRIX_CODEC */

View File

@@ -0,0 +1,55 @@
/* $Id: of_2d_parity_includes.h 189 2014-07-16 08:53:50Z roca $ */
/*
* OpenFEC.org AL-FEC Library.
* (c) Copyright 2009 - 2012 INRIA - All rights reserved
* Contact: vincent.roca@inria.fr
*
* This software is governed by the CeCILL-C license under French law and
* abiding by the rules of distribution of free software. You can use,
* modify and/ or redistribute the software under the terms of the CeCILL-C
* license as circulated by CEA, CNRS and INRIA at the following URL
* "http://www.cecill.info".
*
* As a counterpart to the access to the source code and rights to copy,
* modify and redistribute granted by the license, users are provided only
* with a limited warranty and the software's author, the holder of the
* economic rights, and the successive licensors have only limited
* liability.
*
* In this respect, the user's attention is drawn to the risks associated
* with loading, using, modifying and/or developing or reproducing the
* software by the user in light of its specific status of free software,
* that may mean that it is complicated to manipulate, and that also
* therefore means that it is reserved for developers and experienced
* professionals having in-depth computer knowledge. Users are therefore
* encouraged to load and test the software's suitability as regards their
* requirements in conditions enabling the security of their systems and/or
* data to be ensured and, more generally, to use and operate it in the
* same conditions as regards security.
*
* The fact that you are presently reading this means that you have had
* knowledge of the CeCILL-C license and that you accept its terms.
*/
#ifndef OF_2D_PARITY_INCLUDES
#define OF_2D_PARITY_INCLUDES
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <string.h>
#include "../../lib_common/of_openfec_api.h"
/*
* the remaining includes will only be considered if of_codec_profile.h is
* included above by of_openfec_api.h => of_openfec_profile.h
*/
#ifdef OF_USE_2D_PARITY_MATRIX_CODEC
#include "../../lib_common/linear_binary_codes_utils/of_linear_binary_code.h"
#include "of_2d_parity_api.h"
#include "of_2d_parity.h"
#endif //OF_USE_2D_PARITY_MATRIX_CODEC
#endif //OF_2D_PARITY_INCLUDES

View File

@@ -0,0 +1,112 @@
/* $Id: of_codec_profile.h 175 2014-07-11 09:58:38Z roca $ */
/*
* OpenFEC.org AL-FEC Library.
* (c) Copyright 2009 - 2012 INRIA - All rights reserved
* Contact: vincent.roca@inria.fr
*
* This software is governed by the CeCILL-C license under French law and
* abiding by the rules of distribution of free software. You can use,
* modify and/ or redistribute the software under the terms of the CeCILL-C
* license as circulated by CEA, CNRS and INRIA at the following URL
* "http://www.cecill.info".
*
* As a counterpart to the access to the source code and rights to copy,
* modify and redistribute granted by the license, users are provided only
* with a limited warranty and the software's author, the holder of the
* economic rights, and the successive licensors have only limited
* liability.
*
* In this respect, the user's attention is drawn to the risks associated
* with loading, using, modifying and/or developing or reproducing the
* software by the user in light of its specific status of free software,
* that may mean that it is complicated to manipulate, and that also
* therefore means that it is reserved for developers and experienced
* professionals having in-depth computer knowledge. Users are therefore
* encouraged to load and test the software's suitability as regards their
* requirements in conditions enabling the security of their systems and/or
* data to be ensured and, more generally, to use and operate it in the
* same conditions as regards security.
*
* The fact that you are presently reading this means that you have had
* knowledge of the CeCILL-C license and that you accept its terms.
*/
/****** GENERAL SETUP OPTIONS; EDIT AS APPROPRIATE ****************************/
#define OF_USE_2D_PARITY_MATRIX_CODEC
#ifdef OF_DEBUG
/* additional parameter for memory statistic purposes */
#define MEM_STATS_ARG ,ofcb->stats
#define MEM_STATS ,stats
#else
#define MEM_STATS_ARG
#define MEM_STATS
#endif
/**
* Define if you want to enable the use of the ML (Maximum Likelyhood) decoding.
* If enabled, in practice decoding will start with IT decoding and end with ML
* decoding (in this case a Gaussian Elimination) if needed.
*
* Warning: ML decoding enables to reach the best erasure recovery capabilities,
* at the expense of potentially significant computation loads, depending on
* the size and complexity of the simplified system at the end of IT decoding.
*
* See the MAX_NB_SOURCE_SYMBOLS_DEFAULT/MAX_NB_ENCODING_SYMBOLS_DEFAULT
* constants that enable to limit the computation overheads.
*/
#define ML_DECODING
#ifdef ML_DECODING
#define OF_2D_PARITY_ML_DECODING
#endif
/**
* This optimization is only significant in 32-bit architectures.
* With LP64 architectures, padding will be needed, adding 32 more bits,
* which makes this optimization useless...
*
* NB: not yet operational...
*/
#if defined (__LP64__) || (__WORDSIZE == 64)
// useless with 64-bit architectures
#else
#endif
/**
* Define IL_SUPPORT in debug mode if you want to have the possibility to
* produce H/G matrix images, e.g. to include in a report on new LDPC code
* evaluation.
* More precisely, we are relying on the DevIL library (http://openil.sourceforge.net/).
* Please install it on your machine before compiling the OpenFEC library
* if needed.
*/
//#define IL_SUPPORT
/**
* Default maximum number of source and encoding symbols for this codec.
* This value depends in particular on the kind of decoder used. To this
* limit, codec implementation details might add other limits (e.g. if
* the ESI values are stored in UINT16 instead of UINT32...).
*
* Hints:
* If ML decoding is enabled and used, then limit yourself to a value
* that is not too high, since decoding might finish with a Gaussian
* elimination on the simplified system.
* In situations where decoding is restricted to IT, the main limit is
* the available memory. It usually means you can set very large values.
*/
#ifndef OF_2D_PARITY_MATRIX_MAX_NB_SOURCE_SYMBOLS_DEFAULT
#ifdef ML_DECODING
#define OF_2D_PARITY_MATRIX_MAX_NB_SOURCE_SYMBOLS_DEFAULT 16
#define OF_2D_PARITY_MATRIX_MAX_NB_ENCODING_SYMBOLS_DEFAULT 24
#else
#define OF_2D_PARITY_MATRIX_MAX_NB_SOURCE_SYMBOLS_DEFAULT 16
#define OF_2D_PARITY_MATRIX_MAX_NB_ENCODING_SYMBOLS_DEFAULT 24
#endif
#endif

View File

@@ -0,0 +1,99 @@
/* $Id: of_codec_profile.h 199 2014-10-21 14:25:02Z roca $ */
/*
* OpenFEC.org AL-FEC Library.
* (c) Copyright 2009 - 2012 INRIA - All rights reserved
* Contact: vincent.roca@inria.fr
*
* This software is governed by the CeCILL license under French law and
* abiding by the rules of distribution of free software. You can use,
* modify and/ or redistribute the software under the terms of the CeCILL-C
* license as circulated by CEA, CNRS and INRIA at the following URL
* "http://www.cecill.info".
*
* As a counterpart to the access to the source code and rights to copy,
* modify and redistribute granted by the license, users are provided only
* with a limited warranty and the software's author, the holder of the
* economic rights, and the successive licensors have only limited
* liability.
*
* In this respect, the user's attention is drawn to the risks associated
* with loading, using, modifying and/or developing or reproducing the
* software by the user in light of its specific status of free software,
* that may mean that it is complicated to manipulate, and that also
* therefore means that it is reserved for developers and experienced
* professionals having in-depth computer knowledge. Users are therefore
* encouraged to load and test the software's suitability as regards their
* requirements in conditions enabling the security of their systems and/or
* data to be ensured and, more generally, to use and operate it in the
* same conditions as regards security.
*
* The fact that you are presently reading this means that you have had
* knowledge of the CeCILL-C license and that you accept its terms.
*/
/****** GENERAL SETUP OPTIONS; EDIT AS APPROPRIATE ****************************/
#define OF_USE_LDPC_STAIRCASE_CODEC
#ifdef OF_DEBUG
/* additional parameter for memory statistic purposes */
#define MEM_STATS_ARG ,ofcb->stats
#define MEM_STATS ,stats
#else
#define MEM_STATS_ARG
#define MEM_STATS
#endif
/**
* Define if you want to enable the use of the ML (Maximum Likelyhood) decoding.
* If enabled, in practice decoding will start with IT decoding and end with ML
* decoding (in this case a Gaussian Elimination) if needed.
*
* Warning: ML decoding enables to reach the best erasure recovery capabilities,
* at the expense of potentially significant computation loads, depending on
* the size and complexity of the simplified system at the end of IT decoding.
*
* See the MAX_NB_SOURCE_SYMBOLS_DEFAULT/MAX_NB_ENCODING_SYMBOLS_DEFAULT
* constants that enable to limit the computation overheads.
*/
#define ML_DECODING
#ifdef ML_DECODING
#define OF_LDPC_STAIRCASE_ML_DECODING
#endif
/**
* Define IL_SUPPORT in debug mode if you want to have the possibility to
* produce H/G matrix images, e.g. to include in a report on new LDPC code
* evaluation.
* More precisely, we are relying on the DevIL library (http://openil.sourceforge.net/).
* Please install it on your machine before compiling the OpenFEC library
* if needed.
*/
//#define IL_SUPPORT
/**
* Default maximum number of source and encoding symbols for this codec.
* This value depends in particular on the kind of decoder used. To this
* limit, codec implementation details might add other limits (e.g. if
* the ESI values are stored in UINT16 instead of UINT32...).
*
* Hints:
* If ML decoding is enabled and used, then limit yourself to a value
* that is not too high, since decoding might finish with a Gaussian
* elimination on the simplified system.
* In situations where decoding is restricted to IT, the main limit is
* the available memory. It usually means you can set very large values.
*/
#ifndef OF_LDPC_STAIRCASE_MAX_NB_SOURCE_SYMBOLS_DEFAULT
#ifdef ML_DECODING
#define OF_LDPC_STAIRCASE_MAX_NB_SOURCE_SYMBOLS_DEFAULT 50000
#define OF_LDPC_STAIRCASE_MAX_NB_ENCODING_SYMBOLS_DEFAULT 50000
#else
#define OF_LDPC_STAIRCASE_MAX_NB_SOURCE_SYMBOLS_DEFAULT 100000
#define OF_LDPC_STAIRCASE_MAX_NB_ENCODING_SYMBOLS_DEFAULT 100000
#endif
#endif

View File

@@ -0,0 +1,57 @@
/* $Id: of_ldpc_includes.h 189 2014-07-16 08:53:50Z roca $ */
/*
* OpenFEC.org AL-FEC Library.
* (c) Copyright 2009 - 2012 INRIA - All rights reserved
* Contact: vincent.roca@inria.fr
*
* This software is governed by the CeCILL license under French law and
* abiding by the rules of distribution of free software. You can use,
* modify and/ or redistribute the software under the terms of the CeCILL-C
* license as circulated by CEA, CNRS and INRIA at the following URL
* "http://www.cecill.info".
*
* As a counterpart to the access to the source code and rights to copy,
* modify and redistribute granted by the license, users are provided only
* with a limited warranty and the software's author, the holder of the
* economic rights, and the successive licensors have only limited
* liability.
*
* In this respect, the user's attention is drawn to the risks associated
* with loading, using, modifying and/or developing or reproducing the
* software by the user in light of its specific status of free software,
* that may mean that it is complicated to manipulate, and that also
* therefore means that it is reserved for developers and experienced
* professionals having in-depth computer knowledge. Users are therefore
* encouraged to load and test the software's suitability as regards their
* requirements in conditions enabling the security of their systems and/or
* data to be ensured and, more generally, to use and operate it in the
* same conditions as regards security.
*
* The fact that you are presently reading this means that you have had
* knowledge of the CeCILL-C license and that you accept its terms.
*/
#ifndef OF_LDPC_INCLUDES
#define OF_LDPC_INCLUDES
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <string.h>
#include "../../lib_common/of_openfec_api.h"
/*
* the remaining includes will only be considered if of_codec_profile.h is
* included above by of_openfec_api.h => of_openfec_profile.h
*/
#ifdef OF_USE_LDPC_STAIRCASE_CODEC
#include "../../lib_common/linear_binary_codes_utils/of_linear_binary_code.h"
#include "of_ldpc_staircase_api.h"
#include "of_ldpc_staircase.h"
#endif //OF_USE_LDPC_STAIRCASE_CODEC
#endif //OF_LDPC_INCLUDES

View File

@@ -0,0 +1,328 @@
/* $Id: of_ldpc_staircase.h 184 2014-07-15 09:42:57Z roca $ */
/*
* OpenFEC.org AL-FEC Library.
* (c) Copyright 2009 - 2012 INRIA - All rights reserved
* Contact: vincent.roca@inria.fr
*
* This software is governed by the CeCILL license under French law and
* abiding by the rules of distribution of free software. You can use,
* modify and/ or redistribute the software under the terms of the CeCILL-C
* license as circulated by CEA, CNRS and INRIA at the following URL
* "http://www.cecill.info".
*
* As a counterpart to the access to the source code and rights to copy,
* modify and redistribute granted by the license, users are provided only
* with a limited warranty and the software's author, the holder of the
* economic rights, and the successive licensors have only limited
* liability.
*
* In this respect, the user's attention is drawn to the risks associated
* with loading, using, modifying and/or developing or reproducing the
* software by the user in light of its specific status of free software,
* that may mean that it is complicated to manipulate, and that also
* therefore means that it is reserved for developers and experienced
* professionals having in-depth computer knowledge. Users are therefore
* encouraged to load and test the software's suitability as regards their
* requirements in conditions enabling the security of their systems and/or
* data to be ensured and, more generally, to use and operate it in the
* same conditions as regards security.
*
* The fact that you are presently reading this means that you have had
* knowledge of the CeCILL-C license and that you accept its terms.
*/
#ifdef OF_USE_LDPC_STAIRCASE_CODEC
#ifndef OF_LDPC_STAIRCASE_H
#define OF_LDPC_STAIRCASE_H
/**
* LDPC-Staircase stable codec specific control block structure.
*/
typedef struct of_ldpc_staircase_cb
{
/****** of_linear_binary_code_cb part { *******************************/
/****** of_cb part { **************************************************/
of_codec_id_t codec_id;
of_codec_type_t codec_type;
UINT32 nb_source_symbols; /** k parameter (AKA code dimension). */
UINT32 nb_repair_symbols; /** r = n - k parameter. */
UINT32 encoding_symbol_length; /** symbol length. */
/****** } of_cb part **************************************************/
UINT32 nb_total_symbols; /** n parameter (AKA code length). */
/* parity check matrix */
of_mod2sparse *pchk_matrix;
/** usage statistics for this codec instance. */
of_symbol_stats_op_t *stats_xor;
#ifdef OF_DEBUG
of_symbols_stats_t *stats_symbols;
#endif
UINT32 nb_source_symbol_ready; // Number of source symbols ready
UINT32 nb_repair_symbol_ready; // Number of parity symbols ready
#ifdef ML_DECODING /* { */
UINT32 *index_rows; // Indirection index to access initial m_chekValues array
UINT32 *index_cols; // Indirection index to access initial symbol array
UINT32 remain_cols; // Nb of non empty remaining cols in the future simplified matrix
UINT32 remain_rows; // Nb of non empty remaining rows in the future simplified matrix
of_mod2sparse *pchk_matrix_simplified; // Simplified Parity Check Matrix in sparse mode format
of_mod2sparse *original_pchkMatrix;
of_mod2sparse *pchk_matrix_gauss; // Parity Check matrix in sparse mode format.
UINT32 dec_step; // Current step in the Gauss decoding algorithm
UINT32 threshold_simplification; // threshold (number of symbols) above which we
// run the Gaussian Elimination algorithm
#endif /* } ML_DECODING */
#ifdef OF_USE_DECODER /* { */
/** table of all check values, i.e. that contain the constant term of each equation. */
void** tab_const_term_of_equ;
/** table containing the number of encoding symbols of each equation. */
UINT16* tab_nb_enc_symbols_per_equ;
/** table containing the number of unknow symbols (i.e. neither received nor decoded
* at that time) of each equation. */
UINT16* tab_nb_unknown_symbols;
/** table containing the number of equations in which a repair symbol is included. */
UINT16* tab_nb_equ_for_repair;
void** repair_symbols_values;
void** tmp_tab_symbols;
UINT16 nb_tmp_symbols;
#endif /* } OF_USE_DECODER */
void **encoding_symbols_tab;
/** callbacks registered by the application. */
void* (*decoded_source_symbol_callback) (void *context,
UINT32 size, /* size of decoded source symbol */
UINT32 esi); /* encoding symbol ID in {0..k-1} */
void* (*decoded_repair_symbol_callback) (void *context,
UINT32 size, /* size of decoded repair symbol */
UINT32 esi); /* encoding symbol ID in {0..k-1} */
void* context_4_callback;
/****** } of_linear_binary_code_cb part *******************************/
/** Maximum number of source symbols supported by this codec for practical reasons. */
UINT32 max_nb_source_symbols;
/** Maximum number of encoding symbols supported by this codec for practical reasons. */
UINT32 max_nb_encoding_symbols;
/** Seed used to build this code. */
UINT32 prng_seed;
/** Target number or "1s" per column for H1 (see RFC5170). */
UINT8 N1;
/** During H1 creation, have extra entries been added per row to make the row hamming weight at least two? */
bool extra_entries_added_in_pchk;
/** ESI of first non decoded source symbol. Used by is_decoding_complete function. */
UINT32 first_non_decoded;
} of_ldpc_staircase_cb_t;
/*
* Function prototypes.
*/
/**
* This function create the codec instance for the LDPC-SC codec.
*
* @fn of_status_t of_ldpc_staircase_create_codec_instance (of_ldpc_staircase_cb_t** of_cb)
* @brief create a LDPC-SC codec instance
* @param of_cb (IN/OUT) address of the pointer to a LDPC-SC codec control block. This pointer is updated
* by this function.
* In case of success, it points to a session structure allocated by the
* library. In case of failure it points to NULL.
* @return Error status. The ofcb pointer is updated according to the success return
* status.
*/
of_status_t of_ldpc_staircase_create_codec_instance (of_ldpc_staircase_cb_t** of_cb);
/**
* This function releases all the internal resources used by this FEC codec instance.
* None of the source symbol buffers will be free'ed by this function, even those decoded by
* the library if any, regardless of whether a callback has been registered or not. It's the
* responsibility of the caller to free them.
*
* @fn of_status_t of_ldpc_staircase_release_codec_instance (of_ldpc_staircase_cb_t* ofcb)
* @brief release all resources used by the codec
* @param ofcb (IN) Pointer to the control block.
* @return Error status.
*/
of_status_t of_ldpc_staircase_release_codec_instance (of_ldpc_staircase_cb_t* ofcb);
/**
*
* @fn of_status_t of_ldpc_staircase_set_fec_parameters (of_ldpc_staircase_cb_t* ofcb, of_ldpc_parameters_t* params)
* @brief set all the FEC codec parameters (e.g. k, n, or symbol size)
* @param ofcb (IN) Pointer to the control block.
* @param params (IN) pointer to a structure containing the FEC parameters associated to
* a specific FEC codec.
* @return Error status.
*/
of_status_t of_ldpc_staircase_set_fec_parameters (of_ldpc_staircase_cb_t* ofcb,
of_ldpc_parameters_t* params);
/**
* @fn of_status_t of_ldpc_staircase_set_callback_functions (of_ldpc_staircase_cb_t *ofcb,void* (*decoded_source_symbol_callback)
* (void *context,UINT32 size,UINT32 esi), void* (*decoded_repair_symbol_callback)
* (void *context,UINT32 size,UINT32 esi),void* context_4_callback)
* @brief set various callbock functions (see header of_open_fec_api.h)
* @param ofcb (IN) Pointer to the session.
*
* @param decoded_source_symbol_callback
* (IN) Pointer to the function, within the application, that
* needs to be called each time a source symbol is decoded.
* If this callback is not initialized, the symbol is managed
* internally.
*
* @param decoded_repair_symbol_callback
* (IN) Pointer to the function, within the application, that
* needs to be called each time a repair symbol is decoded.
* If this callback is not initialized, the symbol is managed
* internally.
*
* @param context_4_callback (IN) Pointer to the application-specific context that will be
* passed to the callback function (if any). This context is not
* interpreted by this function.
*
* @return Completion status (LDPC_OK or LDPC_ERROR).
*/
of_status_t of_ldpc_staircase_set_callback_functions (of_ldpc_staircase_cb_t* ofcb,
void* (*decoded_source_symbol_callback) (void *context,
UINT32 size, /* size of decoded source symbol */
UINT32 esi), /* encoding symbol ID in {0..k-1} */
void* (*decoded_repair_symbol_callback) (void *context,
UINT32 size, /* size of decoded repair symbol */
UINT32 esi), /* encoding symbol ID in {0..k-1} */
void* context_4_callback);
#ifdef OF_USE_ENCODER
/**
* @fn of_status_t of_ldpc_staircase_build_repair_symbol (of_ldpc_staircase_cb_t* ofcb, void* encoding_symbols_tab[], UINT32 esi_of_symbol_to_build)
* @brief build a repair symbol (encoder only)
* @param ofcb (IN) Pointer to the session.
* @param encoding_symbols_tab (IN/OUT) table of source and repair symbols.
* The entry for the repair symbol to build can either point
* to a buffer allocated by the application, or let to NULL
* meaning that of_build_repair_symbol will allocate memory.
* @param esi_of_symbol_to_build
* (IN) encoding symbol ID of the repair symbol to build in
* {k..n-1}
* @return Error status.
*/
of_status_t of_ldpc_staircase_build_repair_symbol (of_ldpc_staircase_cb_t* ofcb,
void* encoding_symbols_tab[],
UINT32 esi_of_symbol_to_build);
#endif //OF_USE_ENCODER
#ifdef OF_USE_DECODER
/**
* @fn of_status_t of_ldpc_staircase_decode_with_new_symbol (of_ldpc_staircase_cb_t* ofcb, void* const new_symbol_buf, UINT32 new_symbol_esi)
* @brief (try to) decode with a newly received symbol
* @param ofcb (IN) Pointer to the session.
* @param new_symbol (IN) Pointer to the encoding symbol now available (i.e. a new
* symbol received by the application, or a decoded symbol in case
* of a recursive call).
* @param new_symbol_esi (IN) Encoding symbol ID of the newly symbol available, in {0..n-1}.
* @return Error status (NB: this function does not return OF_STATUS_FAILURE).
*/
of_status_t of_ldpc_staircase_decode_with_new_symbol (of_ldpc_staircase_cb_t* ofcb,
void* new_symbol,
UINT32 new_symbol_esi);
/**
* @fn of_status_t of_ldpc_staircase_set_available_symbols (of_ldpc_staircase_cb_t* ofcb, void* const encoding_symbols_tab[]);
* @brief inform the decoder of all the available (received) symbols
* @param ofcb (IN) Pointer to the session.
* @param encoding_symbols_tab (IN) Pointer to the available encoding symbols table. To each
* available symbol the corresponding entry in the table must point
* to the associated buffer. Entries set to NULL are interpreted as
* corresponding to erased symbols.
* @return Error status.
*/
of_status_t of_ldpc_staircase_set_available_symbols (of_ldpc_staircase_cb_t* ofcb,
void* const encoding_symbols_tab[]);
/**
* @fn of_status_t of_ldpc_staircase_finish_decoding (of_ldpc_staircase_cb_t* ofcb)
* @brief finish decoding with available symbols
* @param ofcb (IN) Pointer to the session.
* @return Error status. Returns OF_STATUS_FAILURE if decoding failed, or
* OF_STATUS_OK if decoding succeeded, or OF_STATUS_*_ERROR in case
* of (fatal) error.
*/
of_status_t of_ldpc_staircase_finish_decoding (of_ldpc_staircase_cb_t* ofcb);
/**
* @fn bool of_ldpc_staircase_is_decoding_complete (of_ldpc_staircase_cb_t* ofcb)
* @brief check if decoding is finished
* @param ofcb (IN) Pointer to the session.
* @return Boolean. Warning, this is one of the very functions of the library that
* does not return an error status.
*/
bool of_ldpc_staircase_is_decoding_complete (of_ldpc_staircase_cb_t* ofcb);
/**
* @fn of_status_t of_ldpc_staircase_get_source_symbols_tab (of_ldpc_staircase_cb_t* ofcb, void* source_symbols_tab[])
* @brief get the table of available source symbols (after decoding)
* @param ofcb (IN) Pointer to the session.
* @param source_symbols_tab (IN/OUT) table, that will be filled by the library and returned
* to the application.
* @return Error status.
*/
of_status_t of_ldpc_staircase_get_source_symbols_tab (of_ldpc_staircase_cb_t* ofcb,
void* source_symbols_tab[]);
/**
* @fn of_status_t of_ldpc_staircase_set_control_parameter (of_ldpc_staircase_cb_t* ofcb,UINT32 type,void* value,UINT32 length)
* @brief set a specific FEC parameter
* @param ofcb (IN) Pointer to the session.
* @param type (IN) Type of parameter. This type is FEC codec ID specific.
* @param value (IN) Pointer to the value of the parameter. The type of the object pointed
* is FEC codec ID specific.
* @param length (IN) length of pointer value
* @return Error status.
*/
of_status_t of_ldpc_staircase_set_control_parameter(of_ldpc_staircase_cb_t* ofcb,
UINT32 type,
void* value,
UINT32 length);
/**
* @fn of_status_t of_ldpc_staircase_get_control_parameter (of_ldpc_staircase_cb_t* ofcb, UINT32 type, void* value, UINT32 length)
* @brief get a specific FEC parameter
* @param ofcb (IN) Pointer to the session.
* @param type (IN) Type of parameter. This type is FEC codec ID specific.
* @param value (IN/OUT) Pointer to the value of the parameter. The type of the object
* pointed is FEC codec ID specific. This function updates the value object
* accordingly. The application, who knows the FEC codec ID, is responsible
* to allocating the approriate object pointed by the value pointer.
* @param length (IN) length of pointer value
* @return Error status.
*/
of_status_t of_ldpc_staircase_get_control_parameter(of_ldpc_staircase_cb_t* ofcb,
UINT32 type,
void* value,
UINT32 length);
/**
* @brief Create the LDPC-Staircase matrix as defined in RFC 5170.
* @param nb_rows (IN) number of rows, also equal to n-k.
* @param nb_cols (IN) number of columns, also equal to n.
* @param left_degree (IN) another name of the N1 parameter.
* @param seed (IN) seed to use for the PRNG.
* @param ofcb (IN/OUT)
* @return pointer to the parity check matrix that has just been allocated and initialized.
*/
of_mod2sparse* of_create_pchck_matrix_rfc5170_compliant (UINT32 nb_rows,
UINT32 nb_cols,
UINT32 left_degree,
UINT32 seed,
of_ldpc_staircase_cb_t *ofcb);
#endif //OF_USE_DECODER
#endif //OF_LDPC_STAIRCASE_H
#endif /* #ifdef OF_USE_LDPC_STAIRCASE_CODEC */

View File

@@ -0,0 +1,570 @@
/* $Id: of_ldpc_staircase_api.c 186 2014-07-16 07:17:53Z roca $ */
/*
* OpenFEC.org AL-FEC Library.
* (c) Copyright 2009 - 2012 INRIA - All rights reserved
* Contact: vincent.roca@inria.fr
*
* This software is governed by the CeCILL license under French law and
* abiding by the rules of distribution of free software. You can use,
* modify and/ or redistribute the software under the terms of the CeCILL-C
* license as circulated by CEA, CNRS and INRIA at the following URL
* "http://www.cecill.info".
*
* As a counterpart to the access to the source code and rights to copy,
* modify and redistribute granted by the license, users are provided only
* with a limited warranty and the software's author, the holder of the
* economic rights, and the successive licensors have only limited
* liability.
*
* In this respect, the user's attention is drawn to the risks associated
* with loading, using, modifying and/or developing or reproducing the
* software by the user in light of its specific status of free software,
* that may mean that it is complicated to manipulate, and that also
* therefore means that it is reserved for developers and experienced
* professionals having in-depth computer knowledge. Users are therefore
* encouraged to load and test the software's suitability as regards their
* requirements in conditions enabling the security of their systems and/or
* data to be ensured and, more generally, to use and operate it in the
* same conditions as regards security.
*
* The fact that you are presently reading this means that you have had
* knowledge of the CeCILL-C license and that you accept its terms.
*/
#include "of_ldpc_includes.h"
#ifdef OF_USE_LDPC_STAIRCASE_CODEC
of_status_t of_ldpc_staircase_create_codec_instance (of_ldpc_staircase_cb_t** of_cb)
{
of_codec_type_t codec_type; /* temporary value */
of_ldpc_staircase_cb_t *cb;
OF_ENTER_FUNCTION
cb = (of_ldpc_staircase_cb_t*) of_realloc (*of_cb, sizeof (of_ldpc_staircase_cb_t));
/* realloc does not initialize the additional buffer space, so do that manually,
* then re-initialize a few parameters */
codec_type = cb->codec_type;
memset(cb, 0, sizeof(*cb));
*of_cb = cb;
cb->codec_id = OF_CODEC_LDPC_STAIRCASE_STABLE;
cb->codec_type = codec_type;
cb->max_nb_source_symbols = OF_LDPC_STAIRCASE_MAX_NB_SOURCE_SYMBOLS_DEFAULT; /* init it immediately... */
cb->max_nb_encoding_symbols = OF_LDPC_STAIRCASE_MAX_NB_ENCODING_SYMBOLS_DEFAULT; /* init it immediately... */
OF_EXIT_FUNCTION
return OF_STATUS_OK;
}
of_status_t of_ldpc_staircase_release_codec_instance (of_ldpc_staircase_cb_t* ofcb)
{
OF_ENTER_FUNCTION
UINT32 i;
if (ofcb->pchk_matrix != NULL)
{
of_mod2sparse_free(ofcb->pchk_matrix);
of_free (ofcb->pchk_matrix);
ofcb->pchk_matrix = NULL;
}
if (ofcb->encoding_symbols_tab != NULL)
{
/* do not try to free source buffers, it's the responsibility of the application
* using this library to free everything. Only try to free repair symbols. */
for (i = ofcb->nb_source_symbols; i < ofcb->nb_total_symbols; i++)
{
if (ofcb->encoding_symbols_tab[i] != NULL)
{
of_free (ofcb->encoding_symbols_tab[i]);
ofcb->encoding_symbols_tab[i] = NULL;
}
}
of_free (ofcb->encoding_symbols_tab);
ofcb->encoding_symbols_tab = NULL;
}
#ifdef OF_USE_DECODER
if (ofcb->codec_type & OF_DECODER)
{
if (ofcb->tmp_tab_symbols != NULL)
{
of_free(ofcb->tmp_tab_symbols);
ofcb->tmp_tab_symbols = NULL;
}
if (ofcb->tab_nb_enc_symbols_per_equ != NULL)
{
of_free (ofcb->tab_nb_enc_symbols_per_equ);
ofcb->tab_nb_enc_symbols_per_equ = NULL;
}
if (ofcb->tab_nb_equ_for_repair != NULL)
{
of_free (ofcb->tab_nb_equ_for_repair);
ofcb->tab_nb_equ_for_repair = NULL;
}
if (ofcb->tab_nb_unknown_symbols != NULL)
{
of_free (ofcb->tab_nb_unknown_symbols);
ofcb->tab_nb_unknown_symbols = NULL;
}
if (ofcb->tab_const_term_of_equ != NULL)
{
for (i = 0; i < ofcb->nb_repair_symbols; i++)
{
if (ofcb->tab_const_term_of_equ[i] != NULL)
{
of_free (ofcb->tab_const_term_of_equ[i]);
ofcb->tab_const_term_of_equ[i] = NULL;
}
}
of_free(ofcb->tab_const_term_of_equ);
}
of_free(ofcb->tmp_tab_symbols);
ofcb->tmp_tab_symbols=NULL;
}
#endif
#ifdef OF_LDPC_STAIRCASE_ML_DECODING
if (ofcb->index_rows != NULL)
{
of_free (ofcb->index_rows);
ofcb->index_rows = NULL;
}
if (ofcb->index_cols != NULL)
{
of_free (ofcb->index_cols);
ofcb->index_cols = NULL;
}
if (ofcb->pchk_matrix_simplified != NULL)
{
of_mod2sparse_free (ofcb->pchk_matrix_simplified);
of_free(ofcb->pchk_matrix_simplified);
ofcb->pchk_matrix_simplified = NULL;
}
if (ofcb->original_pchkMatrix != NULL)
{
of_mod2sparse_free (ofcb->original_pchkMatrix);
ofcb->original_pchkMatrix = NULL;
}
if (ofcb->pchk_matrix_gauss != NULL)
{
of_mod2sparse_free (ofcb->pchk_matrix_gauss);
ofcb->pchk_matrix_gauss = NULL;
}
#endif
#ifdef OF_DEBUG
if (ofcb->stats_xor != NULL) {
of_print_xor_symbols_statistics(ofcb->stats_xor);
of_free(ofcb->stats_xor);
}
if (ofcb->stats_symbols != NULL) {
of_free(ofcb->stats_symbols);
}
#endif
OF_EXIT_FUNCTION
return OF_STATUS_OK;
}
of_status_t of_ldpc_staircase_set_fec_parameters (of_ldpc_staircase_cb_t* ofcb,
of_ldpc_parameters_t* params)
{
of_mod2entry *e;
UINT32 row;
UINT32 seq;
OF_ENTER_FUNCTION
#ifdef OF_DEBUG
ofcb->stats_xor = of_calloc(1, sizeof(of_symbol_stats_op_t));
ofcb->stats_symbols = of_calloc(1, sizeof(of_symbols_stats_t));
#endif
if (params->N1 < 3)
{
OF_PRINT_ERROR(("of_ldpc_staircase_set_fec_parameters: invalid N1 value (%d), must be at least equal to 3.\n",
params->N1))
goto error;
}
if ((ofcb->nb_source_symbols = params->nb_source_symbols) > ofcb->max_nb_source_symbols)
{
OF_PRINT_ERROR(("of_ldpc_staircase_set_fec_parameters: ERROR, invalid nb_source_symbols parameter (got %d, maximum is %d)\n",
ofcb->nb_source_symbols, ofcb->max_nb_source_symbols));
goto error;
}
if ((ofcb->nb_repair_symbols = params->nb_repair_symbols) > ofcb->max_nb_encoding_symbols)
{
/* this test is needed because if the number of repair symbols is
* erroneously < 0, because we are using UINT32, this is transformed
* into a very large integer, which, when added to k, wraps once again
* and the test on nb_total_symbols returns true... */
OF_PRINT_ERROR(("of_ldpc_staircase_set_fec_parameters: ERROR, invalid number of repair symbols (got %d, maximum number of encoding symbols is %d)\n",
ofcb->nb_repair_symbols, ofcb->max_nb_encoding_symbols));
goto error;
}
ofcb->nb_total_symbols = ofcb->nb_source_symbols + ofcb->nb_repair_symbols;
if (ofcb->nb_total_symbols > ofcb->max_nb_encoding_symbols)
{
OF_PRINT_ERROR(("of_ldpc_staircase_set_fec_parameters: ERROR, invalid number of encoding symbols (got %d, maximum is %d)\n",
ofcb->nb_total_symbols, ofcb->max_nb_encoding_symbols));
goto error;
}
ofcb->encoding_symbol_length = params->encoding_symbol_length;
ofcb->prng_seed = params->prng_seed;
ofcb->N1 = params->N1;
OF_TRACE_LVL (1, ("%s: k=%u, n-k=%u, n=%u, symbol_length=%u, PRNG seed=%u, N1=%u\n", __FUNCTION__,
ofcb->nb_source_symbols, ofcb->nb_repair_symbols, ofcb->nb_total_symbols,
ofcb->encoding_symbol_length, ofcb->prng_seed, ofcb->N1))
/* it's now time to create the parity check matrix! */
ofcb->pchk_matrix = of_create_pchck_matrix_rfc5170_compliant
(ofcb->nb_repair_symbols,
ofcb->nb_total_symbols,
ofcb->N1,
ofcb->prng_seed,
ofcb);
if (ofcb->pchk_matrix == NULL)
{
OF_PRINT_ERROR(("of_ldpc_staircase_set_fec_parameters : ERROR, parity check matrix can't be created with this parameters..\n"))
goto error;
}
#ifdef IL_SUPPORT
/* print the matrix using the DevIL library */
of_mod2sparse_print_bitmap(ofcb->pchk_matrix);
#else
//of_mod2sparse_matrix_stats(stdout,ofcb->pchk_matrix,ofcb->nb_source_symbols, ofcb->nb_repair_symbols);
#endif
//#define PRINT_LDGM_VARIANT /* enable this constant to get a trace of the identity version of H */
#if defined(OF_DEBUG) && defined(PRINT_LDGM_VARIANT) && defined(IL_SUPPORT)
{
/*
* calculate and plot the identity variant, H_id, where the staircase is replaced by an identity.
* This is only for curiosity/research purposes. DO NOT use it otherwise.
*/
of_mod2dense *dm = NULL;
dm = of_mod2dense_allocate(ofcb->nb_repair_symbols, ofcb->nb_total_symbols, NULL);
of_mod2sparse_to_dense(ofcb->pchk_matrix, dm);
for (row = 0; row < ofcb->nb_repair_symbols - 1; row++)
{
of_mod2dense_xor_rows(dm, row, row + 1);
}
of_mod2dense_print_bitmap(dm);
of_mod2dense_density(dm);
of_mod2dense_free(dm, NULL);
}
#endif
if ((ofcb->encoding_symbols_tab = (void**) of_calloc (ofcb->nb_total_symbols, sizeof (void*))) == NULL) {
goto no_mem;
}
#ifdef OF_USE_DECODER
if (ofcb->codec_type & OF_DECODER)
{
ofcb->tab_nb_unknown_symbols = (UINT16*)
of_calloc (ofcb->nb_repair_symbols, sizeof (UINT16));
ofcb->tab_const_term_of_equ = (void**)
of_calloc (ofcb->nb_repair_symbols, sizeof (void*));
ofcb->tab_nb_equ_for_repair = (UINT16*)
of_calloc (ofcb->nb_repair_symbols, sizeof (UINT16));
ofcb->tab_nb_enc_symbols_per_equ = (UINT16*)
of_calloc (ofcb->nb_repair_symbols, sizeof (UINT16));
if (ofcb->tab_nb_unknown_symbols == NULL || ofcb->tab_const_term_of_equ == NULL ||
ofcb->tab_nb_equ_for_repair == NULL || ofcb->tab_nb_enc_symbols_per_equ == NULL) {
goto no_mem;
}
// and update the various tables now
for (row = 0; row < ofcb->nb_repair_symbols; row++)
{
for (e = of_mod2sparse_first_in_row (ofcb->pchk_matrix, row);
!of_mod2sparse_at_end (e);
e = of_mod2sparse_next_in_row (e))
{
ofcb->tab_nb_enc_symbols_per_equ[row]++;
ofcb->tab_nb_unknown_symbols[row]++;
}
}
for (seq = ofcb->nb_source_symbols; seq < (ofcb->nb_total_symbols); seq++)
{
for (e = of_mod2sparse_first_in_col (ofcb->pchk_matrix, of_get_symbol_col ((of_cb_t*)ofcb, seq));
!of_mod2sparse_at_end (e);
e = of_mod2sparse_next_in_col (e))
{
ofcb->tab_nb_equ_for_repair[seq - ofcb->nb_source_symbols]++;
}
}
ofcb->tmp_tab_symbols = (void**)of_malloc(sizeof(void*)*ofcb->nb_total_symbols);
}
#endif //OF_USE_DECODER
ofcb->nb_source_symbol_ready = 0; // Number of source symbols ready
ofcb->nb_repair_symbol_ready = 0; // Number of parity symbols ready
//ofcb->nb_non_dup_symbols_recvd = 0;// Number of non-duplicated symbols received
#ifdef OF_LDPC_STAIRCASE_ML_DECODING
ofcb->index_rows = NULL; // Indirection index to access initial m_chekValues array
ofcb->index_cols = NULL; // Indirection index to access initial symbol array
ofcb->remain_cols = 0; // Nb of non empty remaining cols in the future simplified matrix
ofcb->remain_rows = 0; // Nb of non empty remaining rows in the future simplified matrix
ofcb->pchk_matrix_simplified = NULL; // Simplified Parity Check Matrix in sparse mode format
ofcb->original_pchkMatrix = NULL;
ofcb->pchk_matrix_gauss = NULL; // Parity Check matrix in sparse mode format. This matrix
// is also used as a generator matrix in LDGM-* modes
ofcb->dec_step = 0; // Current step in the Gauss Elimination algorithm
ofcb->threshold_simplification = 0; // threshold (number of symbols) above which we
// run the Gauss Elimination algorithm
#endif
#ifdef OF_USE_DECODER
/*
* with LDPC-Staircase, if N1 is even, the last repair symbol is often null (if the code rate
* is above a certain threshold), so pretend we received it since we already know its value.
*/
if (ofcb->codec_type & OF_DECODER)
{
bool is_null; /* is last repair symbol null? */
if (of_ldpc_staircase_get_control_parameter(ofcb, OF_CRTL_LDPC_STAIRCASE_IS_LAST_SYMBOL_NULL,
(void*)&is_null, sizeof(is_null)) != OF_STATUS_OK) {
OF_PRINT_ERROR(("%s: ERROR: of_ldpc_staircase_get_control_parameter() failed\n", __FUNCTION__))
goto error;
}
if (is_null)
{
/*
* since the last repair symbol is known to be null, pretent we received it.
*/
void *null_symbol; /* that's the null repair symbol */
if ((null_symbol = of_calloc(1, ofcb->encoding_symbol_length)) == NULL)
{
goto no_mem;
}
OF_TRACE_LVL(1, ("%s: last repair is null, pretend we received it\n", __FUNCTION__))
if (of_ldpc_staircase_decode_with_new_symbol (ofcb, null_symbol, ofcb->nb_total_symbols - 1)
!= OF_STATUS_OK)
{
OF_PRINT_ERROR(("%s: ERROR: of_ldpc_staircase_decode_with_new_symbol() failed\n", __FUNCTION__))
goto error;
}
}
}
#endif //OF_USE_DECODER
OF_EXIT_FUNCTION
return OF_STATUS_OK;
no_mem:
OF_PRINT_ERROR(("out of memory\n"));
error:
OF_EXIT_FUNCTION
return OF_STATUS_FATAL_ERROR;
}
of_status_t of_ldpc_staircase_set_callback_functions (of_ldpc_staircase_cb_t* ofcb,
void* (*decoded_source_symbol_callback) (void *context,
UINT32 size, /* size of decoded source symbol */
UINT32 esi), /* encoding symbol ID in {0..k-1} */
void* (*decoded_repair_symbol_callback) (void *context,
UINT32 size, /* size of decoded repair symbol */
UINT32 esi), /* encoding symbol ID in {k..n-1} */
void* context_4_callback)
{
OF_ENTER_FUNCTION
ofcb->decoded_source_symbol_callback = decoded_source_symbol_callback;
ofcb->decoded_repair_symbol_callback = decoded_repair_symbol_callback;
ofcb->context_4_callback = context_4_callback;
OF_EXIT_FUNCTION
return OF_STATUS_OK;
}
#ifdef OF_USE_ENCODER
of_status_t of_ldpc_staircase_build_repair_symbol (of_ldpc_staircase_cb_t* ofcb,
void* encoding_symbols_tab[],
UINT32 esi_of_symbol_to_build)
{
of_mod2entry *e;
UINT32 col_to_build;
UINT32 esi;
void *to_add_buf;
void *parity_symbol;
OF_ENTER_FUNCTION
if (esi_of_symbol_to_build < ofcb->nb_source_symbols || esi_of_symbol_to_build >= ofcb->nb_total_symbols)
{
OF_PRINT_ERROR(("of_ldpc_staircase_build_repair_symbol: Error, bad esi of encoding symbol (%d)\n", esi_of_symbol_to_build))
goto error;
}
parity_symbol = encoding_symbols_tab[esi_of_symbol_to_build];
memset (parity_symbol, 0, ofcb->encoding_symbol_length);
col_to_build = of_get_symbol_col ((of_cb_t*)ofcb, esi_of_symbol_to_build);
e = of_mod2sparse_first_in_row (ofcb->pchk_matrix, col_to_build);
while (!of_mod2sparse_at_end (e))
{
// paritySymbol_index in {0.. n-k-1} range, so this test is ok
if (e->col != col_to_build)
{
// don't add paritySymbol to itself
esi = of_get_symbol_esi ((of_cb_t*)ofcb, e->col);
to_add_buf = (void*) encoding_symbols_tab[esi];
if (to_add_buf == NULL)
{
OF_PRINT_ERROR(("symbol %d is not allocated\n", esi));
goto error;
}
#ifdef OF_DEBUG
of_add_to_symbol (parity_symbol, to_add_buf, ofcb->encoding_symbol_length,&(ofcb->stats_xor->nb_xor_for_IT));
#else
of_add_to_symbol (parity_symbol, to_add_buf, ofcb->encoding_symbol_length);
#endif
}
e = of_mod2sparse_next_in_row (e);
}
OF_TRACE_LVL (1, ("%s: repair symbol (esi=%d) built\n", __FUNCTION__, esi_of_symbol_to_build))
OF_EXIT_FUNCTION
return OF_STATUS_OK;
error:
OF_EXIT_FUNCTION
return OF_STATUS_ERROR;
}
#endif //OF_USE_ENCODER
#ifdef OF_USE_DECODER
of_status_t of_ldpc_staircase_decode_with_new_symbol (of_ldpc_staircase_cb_t* ofcb,
void* new_symbol,
UINT32 new_symbol_esi)
{
OF_ENTER_FUNCTION
return of_linear_binary_code_decode_with_new_symbol((of_linear_binary_code_cb_t*)ofcb, new_symbol, new_symbol_esi);
}
of_status_t of_ldpc_staircase_set_available_symbols (of_ldpc_staircase_cb_t* ofcb,
void* const encoding_symbols_tab[])
{
UINT32 i;
OF_ENTER_FUNCTION
for (i = 0; i < ofcb->nb_total_symbols; i++)
{
if (encoding_symbols_tab[i] == NULL)
{
continue;
}
/* use the decode_with_new_symbol function */
of_linear_binary_code_decode_with_new_symbol((of_linear_binary_code_cb_t*)ofcb, encoding_symbols_tab[i], i);
/* NB: this approach is a little bit sub-optimal with LDPC codes, as symbols are submit for IT decoding in sequence.
* We should consider randomizing this order. */
}
OF_EXIT_FUNCTION
return OF_STATUS_OK;
}
of_status_t of_ldpc_staircase_finish_decoding (of_ldpc_staircase_cb_t* ofcb)
{
OF_ENTER_FUNCTION
#ifdef OF_LDPC_STAIRCASE_ML_DECODING
return of_linear_binary_code_finish_decoding_with_ml ((of_linear_binary_code_cb_t*)ofcb);
#else
return OF_STATUS_ERROR;
#endif
}
bool of_ldpc_staircase_is_decoding_complete (of_ldpc_staircase_cb_t* ofcb)
{
for (; ofcb->first_non_decoded < ofcb->nb_source_symbols; ofcb->first_non_decoded++)
{
if (ofcb->encoding_symbols_tab[ofcb->first_non_decoded] == NULL)
{
OF_TRACE_LVL (1, ("decoding not complete (%u source symbols ready, %u expected)\n",
ofcb->nb_source_symbol_ready, ofcb->nb_source_symbols))
//ASSERT(ofcb->nb_source_symbol_ready < ofcb->nb_source_symbols);
return false;
}
}
OF_TRACE_LVL (1, ("decoding is complete\n"))
//ASSERT(ofcb->nb_source_symbol_ready == ofcb->nb_source_symbols);
return true;
}
of_status_t of_ldpc_staircase_get_source_symbols_tab (of_ldpc_staircase_cb_t* ofcb,
void* source_symbols_tab[])
{
OF_ENTER_FUNCTION
/* copy the internal table containing the pointers to all source symbols into the table provided by the caller */
memcpy (source_symbols_tab, ofcb->encoding_symbols_tab, sizeof (void *) * ofcb->nb_source_symbols);
OF_EXIT_FUNCTION
return OF_STATUS_OK;
}
#endif //OF_USE_DECODER
of_status_t of_ldpc_staircase_set_control_parameter (of_ldpc_staircase_cb_t* ofcb,
UINT32 type,
void* value,
UINT32 length)
{
OF_PRINT_ERROR(("of_ldpc_staircase_set_control_parameter: ERROR, not implemented...\n"))
return OF_STATUS_ERROR;
}
of_status_t of_ldpc_staircase_get_control_parameter (of_ldpc_staircase_cb_t* ofcb,
UINT32 type,
void* value,
UINT32 length)
{
OF_ENTER_FUNCTION
switch (type) {
case OF_CTRL_GET_MAX_K:
if (value == NULL || length != sizeof(UINT32)) {
OF_PRINT_ERROR(("%s: OF_CTRL_GET_MAX_K ERROR: null value or bad length (got %d, expected %ld)\n",
__FUNCTION__, length, sizeof(UINT32)))
goto error;
}
*(UINT32*)value = ofcb->max_nb_source_symbols;
OF_TRACE_LVL(1, ("%s: OF_CTRL_GET_MAX_K (%d)\n", __FUNCTION__, *(UINT32*)value))
break;
case OF_CTRL_GET_MAX_N:
if (value == NULL || length != sizeof(UINT32)) {
OF_PRINT_ERROR(("%s: OF_CTRL_GET_MAX_N ERROR: null value or bad length (got %d, expected %ld)\n",
__FUNCTION__, length, sizeof(UINT32)))
goto error;
}
*(UINT32*)value = ofcb->max_nb_encoding_symbols;
OF_TRACE_LVL(1, ("%s: OF_CTRL_GET_MAX_N (%d)\n", __FUNCTION__, *(UINT32*)value))
break;
case OF_CRTL_LDPC_STAIRCASE_IS_LAST_SYMBOL_NULL:
if (ofcb->extra_entries_added_in_pchk == true)
{
/* the parity check matrix does not have exactly N1 "1s" per column, so the
* last repair symbol will not be NULL in general. */
*(bool*)value = false;
OF_TRACE_LVL(1, ("%s: OF_CRTL_LDPC_STAIRCASE_IS_LAST_SYMBOL_NULL (false) (extra entries added in pchk)\n", __FUNCTION__))
}
else
{
/* there are exacly N1 "1s" per column, so if this number if even, the last
* repair symbol is known to be always NULL, no matter the value of the source
* symbols. */
*(bool*)value = ((ofcb->N1 & 0x1) == 0) ? true : false;
OF_TRACE_LVL(1, ("%s: OF_CRTL_LDPC_STAIRCASE_IS_LAST_SYMBOL_NULL (%d)\n", __FUNCTION__, *(bool*)value))
}
break;
default:
OF_PRINT_ERROR(("%s: unknown type (%d)\n", __FUNCTION__, type))
goto error;
}
OF_EXIT_FUNCTION
return OF_STATUS_OK;
error:
OF_EXIT_FUNCTION
return OF_STATUS_ERROR;
}
#endif /* #ifdef OF_USE_LDPC_STAIRCASE_CODEC */

View File

@@ -0,0 +1,82 @@
/* $Id: of_ldpc_staircase_api.h 72 2012-04-13 13:27:26Z detchart $ */
/*
* OpenFEC.org AL-FEC Library.
* (c) Copyright 2009 - 2012 INRIA - All rights reserved
* Contact: vincent.roca@inria.fr
*
* This software is governed by the CeCILL license under French law and
* abiding by the rules of distribution of free software. You can use,
* modify and/ or redistribute the software under the terms of the CeCILL-C
* license as circulated by CEA, CNRS and INRIA at the following URL
* "http://www.cecill.info".
*
* As a counterpart to the access to the source code and rights to copy,
* modify and redistribute granted by the license, users are provided only
* with a limited warranty and the software's author, the holder of the
* economic rights, and the successive licensors have only limited
* liability.
*
* In this respect, the user's attention is drawn to the risks associated
* with loading, using, modifying and/or developing or reproducing the
* software by the user in light of its specific status of free software,
* that may mean that it is complicated to manipulate, and that also
* therefore means that it is reserved for developers and experienced
* professionals having in-depth computer knowledge. Users are therefore
* encouraged to load and test the software's suitability as regards their
* requirements in conditions enabling the security of their systems and/or
* data to be ensured and, more generally, to use and operate it in the
* same conditions as regards security.
*
* The fact that you are presently reading this means that you have had
* knowledge of the CeCILL-C license and that you accept its terms.
*/
#ifdef OF_USE_LDPC_STAIRCASE_CODEC
#ifndef OF_CODEC_STABLE_LDPC_STAIRCASE_API
#define OF_CODEC_STABLE_LDPC_STAIRCASE_API
#include "../../lib_common/of_types.h"
/**
* @struct of_ldpc_parameters_t
* @brief LDPC-Staircase stable codec specific FEC parameter structure.
*
* This structure contains the pieces of information required to initialize a codec instance,
* using the of_set_fec_parameters() function.
*/
typedef struct of_ldpc_parameters
{
UINT32 nb_source_symbols; /* must be 1st item */
UINT32 nb_repair_symbols; /* must be 2nd item */
UINT32 encoding_symbol_length; /* must be 3rd item */
/*
* FEC codec id specific attributes follow...
*/
INT32 prng_seed;
UINT8 N1;
} of_ldpc_parameters_t;
/**
* Control parameters for of_set_control_parameter()/of_get_control_parameter() functions:
* - range {0 .. 1023} inclusive are for generic parameters;
* - range {1024 .. above} inclusive are for code/codec specific parameters (and different
* codecs can re-use the same value);
* The "void * value" type depends on the type.
*/
/**
* Ask the OF library if the last repair symbol of an LDPC-Staircase code is equal to zero
* or not. This is used for various optimizations (e.g. it's useless to transmit a symbol
* that is known to be null). This call returns 1 if the property is true (i.e. the last
* repair symbol is actually NULL), 0 otherwise.
* Argument: bool
*/
#define OF_CRTL_LDPC_STAIRCASE_IS_LAST_SYMBOL_NULL 1024
#endif /* OF_CODEC_STABLE_LDPC_SCSTAIRCASE_API */
#endif /*#ifdef OF_USE_LDPC_STAIRCASE_CODEC */

View File

@@ -0,0 +1,181 @@
/* $Id: of_ldpc_staircase_pchk.c 184 2014-07-15 09:42:57Z roca $ */
/*
* The contents of this directory and its sub-directories are
* Copyright (c) 1995-2003 by Radford M. Neal
*
* Permission is granted for anyone to copy, use, modify, or distribute these
* programs and accompanying documents for any purpose, provided this copyright
* notice is retained and prominently displayed, along with a note saying
* that the original programs are available from Radford Neal's web page, and
* note is made of any changes made to these programs. These programs and
* documents are distributed without any warranty, express or implied. As the
* programs were written for research purposes only, they have not been tested
* to the degree that would be advisable in any important application. All use
* of these programs is entirely at the user's own risk.
*/
/*
* OpenFEC.org AL-FEC Library.
* (c) Copyright 2009 - 2011 INRIA - All rights reserved
* Contact: vincent.roca@inria.fr
*
* This software is governed by the CeCILL license under French law and
* abiding by the rules of distribution of free software. You can use,
* modify and/ or redistribute the software under the terms of the CeCILL-C
* license as circulated by CEA, CNRS and INRIA at the following URL
* "http://www.cecill.info".
*
* As a counterpart to the access to the source code and rights to copy,
* modify and redistribute granted by the license, users are provided only
* with a limited warranty and the software's author, the holder of the
* economic rights, and the successive licensors have only limited
* liability.
*
* In this respect, the user's attention is drawn to the risks associated
* with loading, using, modifying and/or developing or reproducing the
* software by the user in light of its specific status of free software,
* that may mean that it is complicated to manipulate, and that also
* therefore means that it is reserved for developers and experienced
* professionals having in-depth computer knowledge. Users are therefore
* encouraged to load and test the software's suitability as regards their
* requirements in conditions enabling the security of their systems and/or
* data to be ensured and, more generally, to use and operate it in the
* same conditions as regards security.
*
* The fact that you are presently reading this means that you have had
* knowledge of the CeCILL-C license and that you accept its terms.
*/
#include "of_ldpc_includes.h"
#ifdef OF_USE_LDPC_STAIRCASE_CODEC
/* RFC5170 compliant fonction. DO NOT MODIFY */
of_mod2sparse* of_create_pchck_matrix_rfc5170_compliant (UINT32 nb_rows,
UINT32 nb_cols,
UINT32 left_degree,
UINT32 seed,
of_ldpc_staircase_cb_t *ofcb)
{
OF_ENTER_FUNCTION
of_mod2entry *e;
UINT32 added, uneven;
INT32 i, j, k;
INT32 t; /* left limit within the list of possible choices u[] */
UINT32 *u; /* table used to have a homogeneous 1 distrib. */
of_mod2sparse *pchkMatrix = NULL;
UINT32 skipCols = 0; // avoid warning
UINT32 nbDataCols = 0; // avoid warning
skipCols = nb_rows;
nbDataCols = nb_cols - skipCols;
/* a few sanity checks... */
if (left_degree > nb_rows)
{
OF_PRINT_ERROR(("number of 1s per column (i.e. N1=%d parameter) is greater than total number of rows (i.e. n-k=%d)\n",
left_degree, nb_rows));
OF_EXIT_FUNCTION
return NULL;
}
of_rfc5170_srand (seed);
pchkMatrix = of_mod2sparse_allocate (nb_rows, nb_cols);
/* create the initial version of the parity check matrix. */
/* evenboth make method only */
u = (UINT32*) of_calloc (left_degree * nbDataCols, sizeof * u);
/* initialize a list of possible choices to guarantee a homogeneous "1" distribution */
for (k = left_degree * nbDataCols - 1; k >= 0; k--)
{
u[k] = k % nb_rows;
}
uneven = 0;
t = 0; /* left limit within the list of possible choices, u[] */
for (j = skipCols; j < nb_cols; j++)
{
/* for each source symbol column */
for (k = 0; k < left_degree; k++)
{
/* add left_degree "1s" */
/* check that valid available choices remain */
for (i = t; i < left_degree * nbDataCols && of_mod2sparse_find (pchkMatrix, u[i], j); i++)
;
if (i < left_degree * nbDataCols)
{
/* choose one index within the list of possible choices */
do
{
i = t + of_rfc5170_rand (left_degree * nbDataCols - t);
}
while (of_mod2sparse_find (pchkMatrix, u[i], j));
of_mod2sparse_insert (pchkMatrix, u[i], j);
/* replace with u[t] which has never been chosen */
u[i] = u[t];
t++;
}
else
{
/* no choice left, choose one randomly.
* This happens if we're not lucky and if in the remaining possible
* choices, for instance for the last source symbol, the same row
* appears several times. */
uneven += 1;
do
{
i = of_rfc5170_rand (nb_rows);
}
while (of_mod2sparse_find (pchkMatrix, i, j));
of_mod2sparse_insert (pchkMatrix, i, j);
}
}
}
if (uneven > 0 && of_verbosity >= 1)
{
OF_PRINT_LVL(1, ("%s: Had to place %d checks in rows unevenly\n", __FUNCTION__, uneven))
}
of_free (u); /* VR: added */
/* Add extra bits to avoid rows with less than two checks. */
added = 0;
for (i = 0; i < nb_rows; i++)
{
e = of_mod2sparse_first_in_row (pchkMatrix, i);
if (of_mod2sparse_at_end (e))
{
j = (of_rfc5170_rand (nbDataCols)) + skipCols;
e = of_mod2sparse_insert (pchkMatrix, i, j);
added ++;
}
e = of_mod2sparse_first_in_row (pchkMatrix, i);
if (of_mod2sparse_at_end (of_mod2sparse_next_in_row (e)) && nbDataCols > 1)
{
do
{
j = (of_rfc5170_rand (nbDataCols)) + skipCols;
}
while (j == of_mod2sparse_col (e));
of_mod2sparse_insert (pchkMatrix, i, j);
added ++;
}
}
if (added >= 1)
{
ofcb->extra_entries_added_in_pchk = 1;
OF_TRACE_LVL(1,("%s: Added %d extra bit-checks to make row Hamming weight at least two\n", __FUNCTION__, added));
}
else
{
ofcb->extra_entries_added_in_pchk = 0; /* nothing added, there are exactly N1 entries per column. */
}
/* finally, create the staircase */
of_mod2sparse_insert (pchkMatrix, 0, 0); /* 1st row */
for (i = 1; i < nb_rows; i++)
{
/* for all other rows */
/* identity */
of_mod2sparse_insert (pchkMatrix, i, i);
/* staircase */
of_mod2sparse_insert (pchkMatrix, i, i - 1);
}
OF_EXIT_FUNCTION
return pchkMatrix;
}
#endif /* #ifdef OF_USE_LDPC_STAIRCASE_CODEC */

View File

@@ -0,0 +1,48 @@
/* $Id: of_codec_profile.h 72 2012-04-13 13:27:26Z detchart $ */
/*
* OpenFEC.org AL-FEC Library.
* (c) Copyright 2009 - 2012 INRIA - All rights reserved
* Contact: vincent.roca@inria.fr
*
* This software is governed by the CeCILL-C license under French law and
* abiding by the rules of distribution of free software. You can use,
* modify and/ or redistribute the software under the terms of the CeCILL-C
* license as circulated by CEA, CNRS and INRIA at the following URL
* "http://www.cecill.info".
*
* As a counterpart to the access to the source code and rights to copy,
* modify and redistribute granted by the license, users are provided only
* with a limited warranty and the software's author, the holder of the
* economic rights, and the successive licensors have only limited
* liability.
*
* In this respect, the user's attention is drawn to the risks associated
* with loading, using, modifying and/or developing or reproducing the
* software by the user in light of its specific status of free software,
* that may mean that it is complicated to manipulate, and that also
* therefore means that it is reserved for developers and experienced
* professionals having in-depth computer knowledge. Users are therefore
* encouraged to load and test the software's suitability as regards their
* requirements in conditions enabling the security of their systems and/or
* data to be ensured and, more generally, to use and operate it in the
* same conditions as regards security.
*
* The fact that you are presently reading this means that you have had
* knowledge of the CeCILL-C license and that you accept its terms.
*/
/****** GENERAL SETUP OPTIONS; EDIT AS APPROPRIATE ****************************/
#define OF_USE_REED_SOLOMON_CODEC
/**
* Default maximum number of source and encoding symbols for this codec.
* This value depends in particular on the Finite Field size used (here GF(2^8)).
* To this limit, codec implementation details might add other limits (e.g. if
* the ESI values are stored in UINT16 instead of UINT32...).
*/
#define OF_REED_SOLOMON_MAX_NB_SOURCE_SYMBOLS_DEFAULT 255
#define OF_REED_SOLOMON_MAX_NB_ENCODING_SYMBOLS_DEFAULT 255

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,308 @@
/* $Id: of_reed-solomon_gf_2_8.h 72 2012-04-13 13:27:26Z detchart $ */
/*
* OpenFEC.org AL-FEC Library.
* (c) Copyright 2009 - 2012 INRIA - All rights reserved
* Contact: vincent.roca@inria.fr
*
* This software is governed by the CeCILL-C license under French law and
* abiding by the rules of distribution of free software. You can use,
* modify and/ or redistribute the software under the terms of the CeCILL-C
* license as circulated by CEA, CNRS and INRIA at the following URL
* "http://www.cecill.info".
*
* As a counterpart to the access to the source code and rights to copy,
* modify and redistribute granted by the license, users are provided only
* with a limited warranty and the software's author, the holder of the
* economic rights, and the successive licensors have only limited
* liability.
*
* In this respect, the user's attention is drawn to the risks associated
* with loading, using, modifying and/or developing or reproducing the
* software by the user in light of its specific status of free software,
* that may mean that it is complicated to manipulate, and that also
* therefore means that it is reserved for developers and experienced
* professionals having in-depth computer knowledge. Users are therefore
* encouraged to load and test the software's suitability as regards their
* requirements in conditions enabling the security of their systems and/or
* data to be ensured and, more generally, to use and operate it in the
* same conditions as regards security.
*
* The fact that you are presently reading this means that you have had
* knowledge of the CeCILL-C license and that you accept its terms.
*/
#ifdef OF_USE_REED_SOLOMON_CODEC
#ifndef OF_REED_SOLOMON_GF_2_8_H
#define OF_REED_SOLOMON_GF_2_8_H
/*
* The following parameter defines how many bits are used for
* field elements. The code supports any value from 2 to 16
* but fastest operation is achieved with 8 bit elements
* This is the only parameter you may want to change.
*/
#ifndef GF_BITS
#define GF_BITS 8 /* code over GF(2**GF_BITS) - change to suit */
#endif
#define GF_SIZE ((1 << GF_BITS) - 1) /* powers of \alpha */
/**
* Reed-Solomon stable codec specific control block structure.
*/
typedef struct of_rs_cb
{
of_codec_id_t codec_id; /* must begin with fec_codec_id */
of_codec_type_t codec_type; /* must be 2nd item */
/*
* FEC codec id specific attributes follow...
*/
UINT32 nb_source_symbols; /** k parameter (AKA code dimension). */
UINT32 nb_repair_symbols; /** r = n - k parameter. */
UINT32 nb_encoding_symbols; /** n parameter (AKA code length). */
/** Maximum number of source symbols supported by this codec for practical reasons. */
UINT32 max_nb_source_symbols;
/** Maximum number of encoding symbols supported by this codec for practical reasons. */
UINT32 max_nb_encoding_symbols;
UINT32 encoding_symbol_length; /** symbol length. */
void *rs_cb; /** Reed-Solomon internal codec control block */
#ifdef OF_USE_DECODER
/*
* decoder specific variables.
*/
/**
* Table of available source and repair symbols. This table is ordered, no matter
* the symbol arrival order.
*/
void ** available_symbols_tab;
/** Number of available source and repair symbols. This is the number of entries in
* the available_symbols_tab tables. */
UINT32 nb_available_symbols;
/** Number of available source symbols. */
UINT32 nb_available_source_symbols;
bool decoding_finished; /** true as soon as decoding completed. */
#endif /* OF_USE_DECODER */
/** callbacks for this codec. */
void* (*decoded_source_symbol_callback) (void *context,
UINT32 size, /* size of decoded source symbol */
UINT32 esi); /* encoding symbol ID in {0..k-1} */
void* (*decoded_repair_symbol_callback) (void *context,
UINT32 size, /* size of decoded repair symbol */
UINT32 esi); /* encoding symbol ID in {0..k-1} */
void* context_4_callback;
} of_rs_cb_t;
/*
* API function prototypes.
*/
/**
* This function create the codec instance for the Reed-Solomon codec.
*
* @fn of_status_t of_rs_create_codec_instance (of_rs_cb_t** of_cb)
* @brief create a Reed-Solomon codec instance
* @param of_cb (IN/OUT) address of the pointer to a Reed-Solomon codec control block. This pointer is updated
* by this function.
* In case of success, it points to a session structure allocated by the
* library. In case of failure it points to NULL.
* @return Error status. The ofcb pointer is updated according to the success return
* status.
*/
of_status_t of_rs_create_codec_instance (of_rs_cb_t** of_cb);
/**
* This function releases all the internal resources used by this FEC codec instance.
* None of the source symbol buffers will be free'ed by this function, even those decoded by
* the library if any, regardless of whether a callback has been registered or not. It's the
* responsibility of the caller to free them.
*
* @fn of_status_t of_rs_release_codec_instance (of_rs_cb_t* ofcb)
* @brief release all resources used by the codec
* @param ofcb (IN) Pointer to the control block.
* @return Error status.
*/
of_status_t of_rs_release_codec_instance (of_rs_cb_t* ofcb);
/**
*
* @fn of_status_t of_rs_set_fec_parameters (of_rs_cb_t* ofcb, of_rs_parameters_t* params)
* @brief set all the FEC codec parameters (e.g. k, n, or symbol size)
* @param ofcb (IN) Pointer to the control block.
* @param params (IN) pointer to a structure containing the FEC parameters associated to
* a specific FEC codec.
* @return Error status.
*/
of_status_t of_rs_set_fec_parameters (of_rs_cb_t* ofcb,
of_rs_parameters_t* params);
/**
* @fn of_status_t of_rs_set_callback_functions (of_rs_cb_t *ofcb,void* (*decoded_source_symbol_callback)
* (void *context,UINT32 size,UINT32 esi), void* (*decoded_repair_symbol_callback)
* (void *context,UINT32 size,UINT32 esi),void* context_4_callback)
* @brief set various callbock functions (see header of_open_fec_api.h)
* @param ofcb (IN) Pointer to the session.
*
* @param decoded_source_symbol_callback
* (IN) Pointer to the function, within the application, that
* needs to be called each time a source symbol is decoded.
* If this callback is not initialized, the symbol is managed
* internally.
*
* @param decoded_repair_symbol_callback
* (IN) Pointer to the function, within the application, that
* needs to be called each time a repair symbol is decoded.
* If this callback is not initialized, the symbol is managed
* internally.
*
* @param context_4_callback (IN) Pointer to the application-specific context that will be
* passed to the callback function (if any). This context is not
* interpreted by this function.
*
* @return Completion status (LDPC_OK or LDPC_ERROR).
*/
of_status_t of_rs_set_callback_functions (of_rs_cb_t* ofcb,
void* (*decoded_source_symbol_callback) (void *context,
UINT32 size, /* size of decoded source symbol */
UINT32 esi), /* encoding symbol ID in {0..k-1} */
void* (*decoded_repair_symbol_callback) (void *context,
UINT32 size, /* size of decoded repair symbol */
UINT32 esi), /* encoding symbol ID in {0..k-1} */
void* context_4_callback);
#ifdef OF_USE_ENCODER
/**
* @fn of_status_t of_rs_build_repair_symbol (of_rs_cb_t* ofcb, void* encoding_symbols_tab[], UINT32 esi_of_symbol_to_build)
* @brief build a repair symbol (encoder only)
* @param ofcb (IN) Pointer to the session.
* @param encoding_symbols_tab (IN/OUT) table of source and repair symbols.
* The entry for the repair symbol to build can either point
* to a buffer allocated by the application, or let to NULL
* meaning that of_build_repair_symbol will allocate memory.
* @param esi_of_symbol_to_build
* (IN) encoding symbol ID of the repair symbol to build in
* {k..n-1}
* @return Error status.
*/
of_status_t of_rs_build_repair_symbol (of_rs_cb_t* ofcb,
void* encoding_symbols_tab[],
UINT32 esi_of_symbol_to_build);
#endif //OF_USE_ENCODER
#ifdef OF_USE_DECODER
/**
* @fn of_status_t of_rs_decode_with_new_symbol (of_rs_cb_t* ofcb, void* const new_symbol_buf, UINT32 new_symbol_esi)
* @brief (try to) decode with a newly received symbol
* @param ofcb (IN) Pointer to the session.
* @param new_symbol (IN) Pointer to the encoding symbol now available (i.e. a new
* symbol received by the application, or a decoded symbol in case
* of a recursive call).
* @param new_symbol_esi (IN) Encoding symbol ID of the newly symbol available, in {0..n-1}.
* @return Error status (NB: this function does not return OF_STATUS_FAILURE).
*/
of_status_t of_rs_decode_with_new_symbol (of_rs_cb_t* ofcb,
void* new_symbol,
UINT32 new_symbol_esi);
/**
* @fn of_status_t of_rs_set_available_symbols (of_rs_cb_t* ofcb, void* const encoding_symbols_tab[]);
* @brief inform the decoder of all the available (received) symbols
* @param ofcb (IN) Pointer to the session.
* @param encoding_symbols_tab (IN) Pointer to the available encoding symbols table. To each
* available symbol the corresponding entry in the table must point
* to the associated buffer. Entries set to NULL are interpreted as
* corresponding to erased symbols.
* @return Error status.
*/
of_status_t of_rs_set_available_symbols (of_rs_cb_t* ofcb,
void* const encoding_symbols_tab[]);
/**
* @fn of_status_t of_rs_finish_decoding (of_rs_cb_t* ofcb)
* @brief finish decoding with available symbols
* @param ofcb (IN) Pointer to the session.
* @return Error status. Returns OF_STATUS_FAILURE if decoding failed, or
* OF_STATUS_OK if decoding succeeded, or OF_STATUS_*_ERROR in case
* of (fatal) error.
*/
of_status_t of_rs_finish_decoding (of_rs_cb_t* ofcb);
/**
* @fn bool of_rs_is_decoding_complete (of_rs_cb_t* ofcb)
* @brief check if decoding is finished
* @param ofcb (IN) Pointer to the session.
* @return Boolean. Warning, this is one of the very functions of the library that
* does not return an error status.
*/
bool of_rs_is_decoding_complete (of_rs_cb_t* ofcb);
/**
* @fn of_status_t of_rs_get_source_symbols_tab (of_rs_cb_t* ofcb, void* source_symbols_tab[])
* @brief get the table of available source symbols (after decoding)
* @param ofcb (IN) Pointer to the session.
* @param source_symbols_tab (IN/OUT) table, that will be filled by the library and returned
* to the application.
* @return Error status.
*/
of_status_t of_rs_get_source_symbols_tab (of_rs_cb_t* ofcb,
void* source_symbols_tab[]);
#endif //OF_USE_DECODER
/**
* @fn of_status_t of_rs_set_control_parameter (of_rs_cb_t* ofcb,UINT32 type,void* value,UINT32 length)
* @brief set a specific FEC parameter
* @param ofcb (IN) Pointer to the session.
* @param type (IN) Type of parameter. This type is FEC codec ID specific.
* @param value (IN) Pointer to the value of the parameter. The type of the object pointed
* is FEC codec ID specific.
* @param length (IN) length of pointer
* @return Error status.
*/
of_status_t of_rs_set_control_parameter (of_rs_cb_t* ofcb,
UINT32 type,
void* value,
UINT32 length);
/**
* @fn of_status_t of_rs_get_control_parameter (of_rs_cb_t* ofcb,UINT32 type,void* value,UINT32 length)
* @brief get a specific FEC parameter
* @param ofcb (IN) Pointer to the session.
* @param type (IN) Type of parameter. This type is FEC codec ID specific.
* @param value (IN/OUT) Pointer to the value of the parameter. The type of the object
* pointed is FEC codec ID specific. This function updates the value object
* accordingly. The application, who knows the FEC codec ID, is responsible
* to allocating the approriate object pointed by the value pointer.
* @param length (IN) length of pointer
* @return Error status.
*/
of_status_t of_rs_get_control_parameter (of_rs_cb_t* ofcb,
UINT32 type,
void* value,
UINT32 length);
/*
* Internal Reed-Solomon codec function prototypes.
*/
void of_rs_free (void *p) ;
void * of_rs_new (UINT32 k, UINT32 n) ;
void of_rs_init (void) ;
of_status_t of_rs_encode (void *code, void **src, void *dst, int index, int sz) ;
of_status_t of_rs_decode (void *code, void **pkt, int index[], int sz) ;
#endif /* OF_REED_SOLOMON_GF_2_8_H */
#endif //#ifdef OF_USE_REED_SOLOMON_CODEC

View File

@@ -0,0 +1,530 @@
/* $Id: of_reed-solomon_gf_2_8_api.c 186 2014-07-16 07:17:53Z roca $ */
/*
* OpenFEC.org AL-FEC Library.
* (c) Copyright 2009 - 2011 INRIA - All rights reserved
* Contact: vincent.roca@inria.fr
*
* This software is governed by the CeCILL-C license under French law and
* abiding by the rules of distribution of free software. You can use,
* modify and/ or redistribute the software under the terms of the CeCILL-C
* license as circulated by CEA, CNRS and INRIA at the following URL
* "http://www.cecill.info".
*
* As a counterpart to the access to the source code and rights to copy,
* modify and redistribute granted by the license, users are provided only
* with a limited warranty and the software's author, the holder of the
* economic rights, and the successive licensors have only limited
* liability.
*
* In this respect, the user's attention is drawn to the risks associated
* with loading, using, modifying and/or developing or reproducing the
* software by the user in light of its specific status of free software,
* that may mean that it is complicated to manipulate, and that also
* therefore means that it is reserved for developers and experienced
* professionals having in-depth computer knowledge. Users are therefore
* encouraged to load and test the software's suitability as regards their
* requirements in conditions enabling the security of their systems and/or
* data to be ensured and, more generally, to use and operate it in the
* same conditions as regards security.
*
* The fact that you are presently reading this means that you have had
* knowledge of the CeCILL-C license and that you accept its terms.
*/
#include "of_reed-solomon_gf_2_8_includes.h"
#ifdef OF_USE_REED_SOLOMON_CODEC
bool of_rs_is_source_symbol (of_rs_cb_t* ofcb,
UINT32 new_symbol_esi)
{
if (new_symbol_esi < ofcb->nb_source_symbols)
return true;
else
return false;
}
bool of_rs_is_repair_symbol (of_rs_cb_t* ofcb,
UINT32 new_symbol_esi)
{
if (new_symbol_esi < ofcb->nb_source_symbols)
return false;
else
return true;
}
of_status_t of_rs_create_codec_instance (of_rs_cb_t** of_cb)
{
of_codec_type_t codec_type; /* temporary value */
of_rs_cb_t *cb;
OF_ENTER_FUNCTION
cb = (of_rs_cb_t*) of_realloc (*of_cb, sizeof (of_rs_cb_t));
*of_cb = cb;
/* realloc does not initialize the additional buffer space, so do that manually,
* then re-initialize a few parameters */
codec_type = cb->codec_type;
memset(cb, 0, sizeof(*cb));
cb->codec_type = codec_type;
cb->codec_id = OF_CODEC_REED_SOLOMON_GF_2_8_STABLE;
cb->max_nb_source_symbols = OF_REED_SOLOMON_MAX_NB_SOURCE_SYMBOLS_DEFAULT; /* init it immediately... */
cb->max_nb_encoding_symbols = OF_REED_SOLOMON_MAX_NB_ENCODING_SYMBOLS_DEFAULT; /* init it immediately... */
OF_EXIT_FUNCTION
return OF_STATUS_OK;
}
of_status_t of_rs_release_codec_instance (of_rs_cb_t* ofcb)
{
OF_ENTER_FUNCTION
UINT32 i;
if (ofcb->rs_cb != NULL)
{
of_rs_free (ofcb->rs_cb);
ofcb->rs_cb = NULL;
}
#ifdef OF_USE_DECODER
if (ofcb->available_symbols_tab != NULL)
{
of_free(ofcb->available_symbols_tab);
ofcb->available_symbols_tab = NULL;
}
#endif /* OF_USE_DECODER */
OF_EXIT_FUNCTION
return OF_STATUS_OK;
}
of_status_t of_rs_set_fec_parameters (of_rs_cb_t* ofcb,
of_rs_parameters_t* params)
{
OF_ENTER_FUNCTION
if ((ofcb->nb_source_symbols = params->nb_source_symbols) > ofcb->max_nb_source_symbols) {
OF_PRINT_ERROR(("of_rs_set_fec_parameters: ERROR, invalid nb_source_symbols parameter (got %d, maximum is %d)",
ofcb->nb_source_symbols, ofcb->max_nb_source_symbols));
goto error;
}
ofcb->nb_source_symbols = params->nb_source_symbols;
ofcb->nb_repair_symbols = params->nb_repair_symbols;
ofcb->encoding_symbol_length = params->encoding_symbol_length;
ofcb->nb_encoding_symbols = ofcb->nb_source_symbols + ofcb->nb_repair_symbols;
#ifdef OF_USE_DECODER
ofcb->available_symbols_tab = (void**) of_calloc (ofcb->nb_encoding_symbols, sizeof (void*));
ofcb->nb_available_symbols = 0;
ofcb->nb_available_source_symbols = 0;
#endif /* OF_USE_DECODER */
OF_EXIT_FUNCTION
return OF_STATUS_OK;
error:
OF_EXIT_FUNCTION
return OF_STATUS_FATAL_ERROR;
}
of_status_t of_rs_set_callback_functions (of_rs_cb_t* ofcb,
void* (*decoded_source_symbol_callback) (void *context,
UINT32 size, /* size of decoded source symbol */
UINT32 esi), /* encoding symbol ID in {0..k-1} */
void* (*decoded_repair_symbol_callback) (void *context,
UINT32 size, /* size of decoded repair symbol */
UINT32 esi), /* encoding symbol ID in {0..k-1} */
void* context_4_callback)
{
ofcb->decoded_source_symbol_callback = decoded_source_symbol_callback;
ofcb->decoded_repair_symbol_callback = decoded_repair_symbol_callback;
ofcb->context_4_callback = context_4_callback;
if (ofcb->decoded_repair_symbol_callback != NULL)
{
OF_PRINT_ERROR(("of_rs_set_callback_functions: Warning, the decoded repair symbol callback is never called with Reed-Solomon codes, since those repair symbols are never decoded\n"))
}
return OF_STATUS_OK;
}
#ifdef OF_USE_ENCODER
of_status_t of_rs_build_repair_symbol (of_rs_cb_t* ofcb,
void* encoding_symbols_tab[],
UINT32 esi_of_symbol_to_build)
{
OF_ENTER_FUNCTION
if (esi_of_symbol_to_build < ofcb->nb_source_symbols || esi_of_symbol_to_build >= ofcb->nb_encoding_symbols)
{
OF_PRINT_ERROR(("of_rs_build_repair_symbol: Error, bad esi of encoding symbol (%d)",
esi_of_symbol_to_build))
goto error;
}
if (encoding_symbols_tab[esi_of_symbol_to_build] == NULL)
{
if ((encoding_symbols_tab[esi_of_symbol_to_build] = of_calloc (1, ofcb->encoding_symbol_length)) == NULL)
{
OF_PRINT_ERROR(("of_rs_build_repair_symbol: Error, no memory\n"))
goto error;
}
}
if (ofcb->rs_cb == NULL)
{
/* this is the first time we do an encoding for this codec instance, so initialize
* the Reed-Solomon internal codec */
ofcb->rs_cb = of_rs_new (ofcb->nb_source_symbols, ofcb->nb_encoding_symbols);
if (ofcb->rs_cb == NULL)
{
OF_PRINT_ERROR(("of_rs_build_repair_symbol: Error, of_rs_new failed"))
goto error;
}
}
if (of_rs_encode(ofcb->rs_cb,
encoding_symbols_tab,
encoding_symbols_tab[esi_of_symbol_to_build],
esi_of_symbol_to_build,
ofcb->encoding_symbol_length) != OF_STATUS_OK)
{
OF_PRINT_ERROR(("of_rs_build_repair_symbol: Error, of_rs_encode failed"))
goto error;
}
OF_EXIT_FUNCTION
return OF_STATUS_OK;
error:
OF_EXIT_FUNCTION
return OF_STATUS_ERROR;
}
#endif //OF_USE_ENCODER
#ifdef OF_USE_DECODER
of_status_t of_rs_decode_with_new_symbol (of_rs_cb_t* ofcb,
void* new_symbol,
UINT32 new_symbol_esi)
{
OF_ENTER_FUNCTION
if (ofcb->decoding_finished)
{
OF_TRACE_LVL(2, ("of_rs_decode_with_new_symbol: decoding already done\n"));
return OF_STATUS_OK;
}
if (ofcb->available_symbols_tab[new_symbol_esi] != NULL)
{
/* duplicated symbol, ignore */
OF_TRACE_LVL(2, ("of_rs_decode_with_new_symbol: symbol (esi=%d) duplicated\n", new_symbol_esi));
goto end;
}
ofcb->available_symbols_tab[new_symbol_esi] = new_symbol;
ofcb->nb_available_symbols++;
if (new_symbol_esi < ofcb->nb_source_symbols)
{
/* remember a new source symbol is available */
ofcb->nb_available_source_symbols++;
}
if (ofcb->nb_available_source_symbols == ofcb->nb_source_symbols)
{
/* we received all the k source symbols, so it's finished */
ofcb->decoding_finished = true;
OF_TRACE_LVL(2, ("of_rs_decode_with_new_symbol: done, all source symbols have been received\n"));
OF_EXIT_FUNCTION
return OF_STATUS_OK;
}
if (ofcb->nb_available_symbols >= ofcb->nb_source_symbols)
{
/* we received a sufficient number of symbols, so let's decode */
if (of_rs_finish_decoding(ofcb) != OF_STATUS_OK)
{
OF_PRINT_ERROR(("of_rs_decode_with_new_symbol: Error, of_rs_decode failure\n"))
goto error;
}
ASSERT(ofcb->decoding_finished == true);
OF_TRACE_LVL(2, ("of_rs_decode_with_new_symbol: done, decoding successful\n"));
OF_EXIT_FUNCTION
return OF_STATUS_OK;
}
end:
OF_TRACE_LVL(2, ("of_rs_decode_with_new_symbol: okay, but not yet finished\n"));
OF_EXIT_FUNCTION
return OF_STATUS_OK;
error:
OF_EXIT_FUNCTION
return OF_STATUS_ERROR;
}
of_status_t of_rs_set_available_symbols (of_rs_cb_t* ofcb,
void* const encoding_symbols_tab[])
{
UINT32 i;
OF_ENTER_FUNCTION
ofcb->nb_available_symbols = 0;
ofcb->nb_available_source_symbols = 0;
for (i = 0; i < ofcb->nb_encoding_symbols; i++)
{
if ((ofcb->available_symbols_tab[i] = encoding_symbols_tab[i]) == NULL)
{
continue;
}
if (i < ofcb->nb_source_symbols)
{
ofcb->nb_available_source_symbols++;
}
ofcb->nb_available_symbols++;
}
OF_EXIT_FUNCTION
return OF_STATUS_OK;
}
of_status_t of_rs_finish_decoding (of_rs_cb_t* ofcb)
{
UINT32 k;
UINT32 n;
char *tmp_buf[GF_SIZE]; /* copy available source/repair symbol buffers here... */
int tmp_esi[GF_SIZE]; /* ...and their esi here. In fact we only need k entries
* in these tables, but in order to avoid using malloc (time
* consumming), we use an automatic table of maximum size for
* both tmp_buf[] and tmp_esi[]. */
INT32 tmp_idx; /* index in tmp_buf[] and tmp_esi[] tabs */
char *large_buf = NULL; /* single large buffer where to copy all source/repair symbols */
UINT32 off; /* offset, in unit of characters, in large_buf */
void **ass_buf; /* tmp pointer to the current source symbol entry in
* available_symbols_tab[] */
UINT32 ass_esi; /* corresponding available source symbol ESI */
void **ars_buf; /* tmp pointer to the current repair symbol entry in
* available_symbols_tab[] */
UINT32 ars_esi; /* corresponding available repair symbol ESI */
OF_ENTER_FUNCTION
if (ofcb->decoding_finished)
{
return OF_STATUS_OK;
}
k = ofcb->nb_source_symbols;
n = ofcb->nb_encoding_symbols;
if (ofcb->nb_available_symbols < k)
{
OF_PRINT_ERROR(("of_rs_finish_decoding: Error, nb received symbols < nb source symbols\n"))
OF_EXIT_FUNCTION
return OF_STATUS_FAILURE;
}
if (ofcb->nb_available_source_symbols == k)
{
/* we received all the k source symbols, so it's finished */
ofcb->decoding_finished = true;
OF_EXIT_FUNCTION
return OF_STATUS_OK;
}
/*
* Copy available source and repair symbols in a single large buffer first.
* NB: this is required by the current FEC codec which modifies
* the tmp_buf buffers!!!
*/
large_buf = (char *) of_malloc(k * ofcb->encoding_symbol_length);
if (large_buf == NULL)
{
goto no_mem;
}
/* Then remember the location of each symbol buffer */
for (tmp_idx = 0, off = 0; tmp_idx < k; tmp_idx++, off += ofcb->encoding_symbol_length) {
tmp_buf[tmp_idx] = large_buf + off;
}
tmp_idx = 0; /* index in tmp_buf and tmp_esi tables */
/*
* Copy all the available source symbols (it's essential for decoding speed purposes) and
* a sufficient number of repair symbols to the tmp_buf array. Copy data as well in the
* large_buf buffer.
* Because of of_rs_decode internal details, we put source symbols at their right location
* and fill in the gaps (i.e. erased source symbols) with repair symbols.
*/
ass_esi = 0;
ars_esi = k;
ass_buf = ofcb->available_symbols_tab;
ars_buf = ofcb->available_symbols_tab + k;
for (tmp_idx = 0; tmp_idx < k; tmp_idx++)
{
if (*ass_buf == NULL)
{
/* this source symbol is not available, replace it with a repair */
while (*ars_buf == NULL)
{
ars_esi++;
ars_buf++;
}
OF_TRACE_LVL(2, ("of_rs_finish_decoding: copy repair with esi=%d in tmp_buf[%d]\n",
ars_esi, tmp_idx))
memcpy(tmp_buf[tmp_idx], *ars_buf, ofcb->encoding_symbol_length);
tmp_esi[tmp_idx] = ars_esi;
ars_esi++;
ars_buf++;
}
else
{
OF_TRACE_LVL(2, ("of_rs_finish_decoding: copy source with esi=%d in tmp_buf[%d]\n",
ars_esi, tmp_idx))
memcpy(tmp_buf[tmp_idx], *ass_buf, ofcb->encoding_symbol_length);
tmp_esi[tmp_idx] = ass_esi;
}
ass_esi++;
ass_buf++;
}
#if 0
for (tmp_idx = 0; tmp_idx < k; tmp_idx++)
{
OF_TRACE_LVL(2, ("Before of_rs_decode: esi=%d, k=%d, tmp_idx=%d\n", tmp_esi[tmp_idx], k, tmp_idx))
}
#endif
/*
* Let's decode now.
* Create a context first, decode, then release this context.
*/
ofcb->rs_cb = of_rs_new (ofcb->nb_source_symbols, ofcb->nb_encoding_symbols);
if (of_rs_decode (ofcb->rs_cb, (void**)tmp_buf, (int*)tmp_esi, ofcb->encoding_symbol_length) != OF_STATUS_OK)
{
OF_PRINT_ERROR(("of_rs_finish_decoding: Error, of_rs_decode failure\n"))
goto error;
}
of_rs_free (ofcb->rs_cb);
ofcb->rs_cb = NULL;
ofcb->decoding_finished = true;
#if 0
for (tmp_idx = 0; tmp_idx < k; tmp_idx++)
{
OF_TRACE_LVL(2, ("After of_rs_decode: esi=%d, k=%d, tmp_idx=%d\n", tmp_esi[tmp_idx], k, tmp_idx))
}
#endif
/*
* finally update the source_symbols_tab table with the decoded source symbols.
*/
for (tmp_idx = 0; tmp_idx < k; tmp_idx++)
{
ASSERT(tmp_idx < k);
ass_buf = &(ofcb->available_symbols_tab[tmp_idx]);
if (*ass_buf != NULL)
{
/* nothing to do, this source symbol has already been received. */
continue;
}
/*
* This is a new, decoded source symbol.
* First copy it into a permanent buffer.
* Call either the associated callback or allocate memory, and then
* copy the symbol content in it.
*/
if (ofcb->decoded_source_symbol_callback != NULL)
{
*ass_buf = ofcb->decoded_source_symbol_callback (ofcb->context_4_callback,
ofcb->encoding_symbol_length, tmp_idx);
}
else
{
*ass_buf = (void *) of_malloc (ofcb->encoding_symbol_length);
}
if (*ass_buf == NULL)
{
goto no_mem;
}
memcpy(*ass_buf, tmp_buf[tmp_idx], ofcb->encoding_symbol_length);
OF_TRACE_LVL(2, ("of_rs_finish_decoding: decoded source symbol esi=%d from tmp_buf[%d]\n",
tmp_idx, tmp_idx))
}
of_free(large_buf);
OF_EXIT_FUNCTION
return OF_STATUS_OK;
no_mem:
OF_PRINT_ERROR(("of_rs_finish_decoding: out of memory.\n"))
error:
OF_EXIT_FUNCTION
return OF_STATUS_ERROR;
}
bool of_rs_is_decoding_complete (of_rs_cb_t* ofcb)
{
OF_ENTER_FUNCTION
OF_EXIT_FUNCTION
return ofcb->decoding_finished;
}
of_status_t of_rs_get_source_symbols_tab (of_rs_cb_t* ofcb,
void* source_symbols_tab[])
{
OF_ENTER_FUNCTION
if (of_rs_is_decoding_complete(ofcb) == false)
{
OF_PRINT_ERROR(("of_rs_get_source_symbols_tab: Error, decoding not complete.\n"))
OF_EXIT_FUNCTION
return OF_STATUS_ERROR;
}
#if 0
UINT32 i;
for (i = 0; i < ofcb->nb_source_symbols; i++)
{
if (source_symbols_tab[i] == NULL)
{
source_symbols_tab[i] = ofcb->available_symbols_tab[i];
}
}
#else
memcpy(source_symbols_tab, ofcb->available_symbols_tab, ofcb->nb_source_symbols * sizeof(void*));
#endif
OF_EXIT_FUNCTION
return OF_STATUS_OK;
}
#endif //OF_USE_DECODER
of_status_t of_rs_set_control_parameter (of_rs_cb_t* ofcb,
UINT32 type,
void* value,
UINT32 length)
{
OF_PRINT_ERROR(("of_rs_set_control_parameter: ERROR, not implemented...\n"))
return OF_STATUS_ERROR;
}
of_status_t of_rs_get_control_parameter (of_rs_cb_t* ofcb,
UINT32 type,
void* value,
UINT32 length)
{
OF_ENTER_FUNCTION
switch (type) {
case OF_CTRL_GET_MAX_K:
if (value == NULL || length != sizeof(UINT32)) {
OF_PRINT_ERROR(("%s: OF_CTRL_GET_MAX_K ERROR: null value or bad length (got %d, expected %ld)\n",
__FUNCTION__, length, sizeof(UINT32)))
goto error;
}
*(UINT32*)value = ofcb->max_nb_source_symbols;
OF_TRACE_LVL(1, ("%s: OF_CTRL_GET_MAX_K (%d)\n", __FUNCTION__, *(UINT32*)value))
break;
case OF_CTRL_GET_MAX_N:
if (value == NULL || length != sizeof(UINT32)) {
OF_PRINT_ERROR(("%s: OF_CTRL_GET_MAX_N ERROR: null value or bad length (got %d, expected %ld)\n",
__FUNCTION__, length, sizeof(UINT32)))
goto error;
}
*(UINT32*)value = ofcb->max_nb_encoding_symbols;
OF_TRACE_LVL(1, ("%s: OF_CTRL_GET_MAX_N (%d)\n", __FUNCTION__, *(UINT32*)value))
break;
default:
OF_PRINT_ERROR(("%s: unknown type (%d)\n", __FUNCTION__, type))
goto error;
}
OF_EXIT_FUNCTION
return OF_STATUS_OK;
error:
OF_EXIT_FUNCTION
return OF_STATUS_ERROR;
}
#endif //#ifdef OF_USE_REED_SOLOMON_CODEC

View File

@@ -0,0 +1,59 @@
/* $Id: of_reed-solomon_gf_2_8_api.h 72 2012-04-13 13:27:26Z detchart $ */
/*
* OpenFEC.org AL-FEC Library.
* (c) Copyright 2009 - 2012 INRIA - All rights reserved
* Contact: vincent.roca@inria.fr
*
* This software is governed by the CeCILL-C license under French law and
* abiding by the rules of distribution of free software. You can use,
* modify and/ or redistribute the software under the terms of the CeCILL-C
* license as circulated by CEA, CNRS and INRIA at the following URL
* "http://www.cecill.info".
*
* As a counterpart to the access to the source code and rights to copy,
* modify and redistribute granted by the license, users are provided only
* with a limited warranty and the software's author, the holder of the
* economic rights, and the successive licensors have only limited
* liability.
*
* In this respect, the user's attention is drawn to the risks associated
* with loading, using, modifying and/or developing or reproducing the
* software by the user in light of its specific status of free software,
* that may mean that it is complicated to manipulate, and that also
* therefore means that it is reserved for developers and experienced
* professionals having in-depth computer knowledge. Users are therefore
* encouraged to load and test the software's suitability as regards their
* requirements in conditions enabling the security of their systems and/or
* data to be ensured and, more generally, to use and operate it in the
* same conditions as regards security.
*
* The fact that you are presently reading this means that you have had
* knowledge of the CeCILL-C license and that you accept its terms.
*/
#ifdef OF_USE_REED_SOLOMON_CODEC
#ifndef OF_REED_SOLOMON_GF_2_8_API_H
#define OF_REED_SOLOMON_GF_2_8_API_H
/**
* \struct of_rs_parameters_t
* \brief Reed-Solomon stable codec specific FEC parameter structure.
* This structure contains the pieces of information required to initialize a codec instance,
* using the of_set_fec_parameters() function.
*/
typedef struct of_rs_parameters
{
UINT32 nb_source_symbols; /* must be 1st item */
UINT32 nb_repair_symbols; /* must be 2nd item */
UINT32 encoding_symbol_length; /* must be 3rd item */
/*
* FEC codec id specific attributes follow...
*/
} of_rs_parameters_t;
#endif /* OF_REED_SOLOMON_GF_2_8_API_H */
#endif //#ifdef OF_USE_REED_SOLOMON_CODEC

View File

@@ -0,0 +1,57 @@
/* $Id: of_reed-solomon_gf_2_8_includes.h 189 2014-07-16 08:53:50Z roca $ */
/*
* OpenFEC.org AL-FEC Library.
* (c) Copyright 2009 - 2012 INRIA - All rights reserved
* Contact: vincent.roca@inria.fr
*
* This software is governed by the CeCILL-C license under French law and
* abiding by the rules of distribution of free software. You can use,
* modify and/ or redistribute the software under the terms of the CeCILL-C
* license as circulated by CEA, CNRS and INRIA at the following URL
* "http://www.cecill.info".
*
* As a counterpart to the access to the source code and rights to copy,
* modify and redistribute granted by the license, users are provided only
* with a limited warranty and the software's author, the holder of the
* economic rights, and the successive licensors have only limited
* liability.
*
* In this respect, the user's attention is drawn to the risks associated
* with loading, using, modifying and/or developing or reproducing the
* software by the user in light of its specific status of free software,
* that may mean that it is complicated to manipulate, and that also
* therefore means that it is reserved for developers and experienced
* professionals having in-depth computer knowledge. Users are therefore
* encouraged to load and test the software's suitability as regards their
* requirements in conditions enabling the security of their systems and/or
* data to be ensured and, more generally, to use and operate it in the
* same conditions as regards security.
*
* The fact that you are presently reading this means that you have had
* knowledge of the CeCILL-C license and that you accept its terms.
*/
#ifndef OF_REED_SOLOMON_INCLUDES_H
#define OF_REED_SOLOMON_INCLUDES_H
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <string.h>
#include "../../lib_common/of_openfec_api.h"
/*
* the remaining includes will only be considered if of_codec_profile.h is
* included above by of_openfec_api.h => of_openfec_profile.h
*/
#ifdef OF_USE_REED_SOLOMON_CODEC
#include "../../lib_common/linear_binary_codes_utils/of_linear_binary_code.h"
#include "of_reed-solomon_gf_2_8_api.h"
#include "of_reed-solomon_gf_2_8.h"
#endif //OF_USE_REED_SOLOMON_CODEC
#endif //OF_REED_SOLOMON_INCLUDES_H

View File

@@ -0,0 +1,413 @@
/* $Id: algebra_2_4.c 185 2014-07-15 09:57:16Z roca $ */
/*
* OpenFEC.org AL-FEC Library.
* (C) 1997-98 Luigi Rizzo (luigi@iet.unipi.it)
*
* Portions derived from code by Phil Karn (karn@ka9q.ampr.org),
* Robert Morelos-Zaragoza (robert@spectra.eng.hawaii.edu) and Hari
* Thirumoorthy (harit@spectra.eng.hawaii.edu), Aug 1995
*
* 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 AUTHORS ``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 AUTHORS
* 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.
*/
#include "algebra_2_4.h"
#ifdef OF_USE_REED_SOLOMON_2_M_CODEC
#define UNROLL 16
#define USE_GF_MULC register gf * __gf_mulc_
#define GF_MULC0(c) __gf_mulc_ = (gf*)of_gf_2_4_mul_table[c]
#define GF_OPT_MULC0(c) __gf_mulc_ = (gf*)of_gf_2_4_opt_mul_table[c]
#define GF_ADDMULC(dst, x) {dst ^= __gf_mulc_[x];}
#define GF_ADDMULC_COMPACT(dst,x) {dst = (dst>>4 ^ __gf_mulc_[x>>4])<<4 |(dst & 0x0F ^ __gf_mulc_[x & 0x0F]); }
/*
* addmul() computes dst[] = dst[] + c * src[]
* This is used often, so better optimize it! Currently the loop is
* unrolled 16 times, a good value for 486 and pentium-class machines.
* The case c=0 is also optimized, whereas c=1 is not. These
* calls are unfrequent in my typical apps so I did not bother.
*/
/*
* of_galois_field_2_4_addmul1() computes dst[] = dst[] + c * src[] when src and dst
* both point to vectors where each GF(2^4) element is stored in an unsigned char.
* This is used for matrix operations where no source/repair symbol is involved.
*/
void of_galois_field_2_4_addmul1(gf *dst1, gf *src1, gf c, int sz)
{
USE_GF_MULC ;
register gf *dst = dst1, *src = src1 ;
gf *lim = &dst[sz - UNROLL + 1] ;
#if ((defined (__LP64__) || (__WORDSIZE == 64)) && !defined (OF_RS_2M_USE_32BITS))
UINT64 tmp;
UINT64 *dst_64 = (UINT64*)dst1;
#else
UINT32 tmp;
UINT32 *dst_32 = (UINT32*)dst1;
#endif
GF_MULC0 (c) ;
#if (UNROLL > 1) /* unrolling by 16 is quite effective on the pentium */
for (; dst < lim ;dst += UNROLL, src += UNROLL)
{
#if ((defined (__LP64__) || (__WORDSIZE == 64)) && !defined (OF_RS_2M_USE_32BITS))
/* perform 64-bit operations for improved performances on 64-bit systems */
tmp = ((UINT64)__gf_mulc_[src[0]]) | ((UINT64)__gf_mulc_[src[1]]<<8) | ((UINT64)__gf_mulc_[src[2]]<<16) |
((UINT64)__gf_mulc_[src[3]]<<24) | ((UINT64)__gf_mulc_[src[4]]<<32) | ((UINT64)__gf_mulc_[src[5]]<<40) |
((UINT64)__gf_mulc_[src[6]]<<48) | ((UINT64)__gf_mulc_[src[7]]<<56) ;
*dst_64 ^= tmp;
dst_64++;
tmp = ((UINT64)__gf_mulc_[src[8]]) | ((UINT64)__gf_mulc_[src[9]]<<8) | ((UINT64)__gf_mulc_[src[10]]<<16) |
((UINT64)__gf_mulc_[src[11]]<<24) | ((UINT64)__gf_mulc_[src[12]]<<32) | ((UINT64)__gf_mulc_[src[13]]<<40) |
((UINT64)__gf_mulc_[src[14]]<<48) | ((UINT64)__gf_mulc_[src[15]]<<56) ;
*dst_64 ^= tmp;
dst_64++;
#else
/* otherwise perform 32-bit operations on 32-bit systems */
tmp = ((UINT32)__gf_mulc_[src[0]]) | ((UINT32)__gf_mulc_[src[1]]<<8) | ((UINT32)__gf_mulc_[src[2]]<<16) |
((UINT32)__gf_mulc_[src[3]]<<24);
*dst_32 ^= tmp;
dst_32++;
tmp = ((UINT32)__gf_mulc_[src[4]]) | ((UINT32)__gf_mulc_[src[5]]<<8) | ((UINT32)__gf_mulc_[src[6]]<<16) |
((UINT32)__gf_mulc_[src[7]]<<24);
*dst_32 ^= tmp;
dst_32++;
tmp = ((UINT32)__gf_mulc_[src[8]]) | ((UINT32)__gf_mulc_[src[9]]<<8) | ((UINT32)__gf_mulc_[src[10]]<<16) |
((UINT32)__gf_mulc_[src[11]]<<24);
*dst_32 ^= tmp;
dst_32++;
tmp = ((UINT32)__gf_mulc_[src[12]]) | ((UINT32)__gf_mulc_[src[13]]<<8) | ((UINT32)__gf_mulc_[src[14]]<<16) |
((UINT32)__gf_mulc_[src[15]]<<24);
*dst_32 ^= tmp;
dst_32++;
#endif
}
#endif
lim += UNROLL - 1 ;
for (; dst < lim; dst++, src++) {
/* final components, since sz is not necessarily a multiple of UNROLL */
GF_ADDMULC (*dst , *src);
}
}
/*
* of_galois_field_2_4_addmul1_compact() computes dst[] = dst[] + c * src[] when src and dst
* both point to vectors where each GF(2^4) element is actually stored in 4-bits.
* Said differently, there are two elements per byte.
* This is used for matrix operations where source/repair symbols are involved (encoding
* and decoding).
* This function has been optimized so that two elements are accessed each time, and the
* mulc table works on two elements at a time. This is a highly effective solution which
* warrants high performances.
*/
void of_galois_field_2_4_addmul1_compact (gf *dst1, gf *src1, gf c, int sz)
{
USE_GF_MULC ;
register gf *dst = dst1, *src = src1 ;
gf *lim = &dst[sz - UNROLL + 1] ;
#if ((defined (__LP64__) || (__WORDSIZE == 64)) && !defined (OF_RS_2M_USE_32BITS))
UINT64 tmp;
UINT64 *dst_64 = (UINT64*)dst1;
#else
UINT32 tmp;
UINT32 *dst_32 = (UINT32*)dst1;
#endif
GF_OPT_MULC0(c);
#if (UNROLL > 1) /* unrolling by 16 is quite effective on the pentium */
for (; dst < lim ;dst += UNROLL, src += UNROLL)
{
#if ((defined (__LP64__) || (__WORDSIZE == 64)) && !defined (OF_RS_2M_USE_32BITS))
/* perform 64-bit operations for improved performances on 64-bit systems */
tmp = ((UINT64)__gf_mulc_[src[0]]) | ((UINT64)__gf_mulc_[src[1]]<<8) | ((UINT64)__gf_mulc_[src[2]]<<16) |
((UINT64)__gf_mulc_[src[3]]<<24) | ((UINT64)__gf_mulc_[src[4]]<<32) | ((UINT64)__gf_mulc_[src[5]]<<40) |
((UINT64)__gf_mulc_[src[6]]<<48) | ((UINT64)__gf_mulc_[src[7]]<<56) ;
*dst_64 ^= tmp;
dst_64++;
tmp = ((UINT64)__gf_mulc_[src[8]]) | ((UINT64)__gf_mulc_[src[9]]<<8) | ((UINT64)__gf_mulc_[src[10]]<<16) |
((UINT64)__gf_mulc_[src[11]]<<24) | ((UINT64)__gf_mulc_[src[12]]<<32) | ((UINT64)__gf_mulc_[src[13]]<<40) |
((UINT64)__gf_mulc_[src[14]]<<48) | ((UINT64)__gf_mulc_[src[15]]<<56) ;
*dst_64 ^= tmp;
dst_64++;
#else
/* otherwise perform 32-bit operations on 32-bit systems */
tmp = ((UINT32)__gf_mulc_[src[0]]) | ((UINT32)__gf_mulc_[src[1]]<<8) | ((UINT32)__gf_mulc_[src[2]]<<16) |
((UINT32)__gf_mulc_[src[3]]<<24);
*dst_32 ^= tmp;
dst_32++;
tmp = ((UINT32)__gf_mulc_[src[4]]) | ((UINT32)__gf_mulc_[src[5]]<<8) | ((UINT32)__gf_mulc_[src[6]]<<16) |
((UINT32)__gf_mulc_[src[7]]<<24);
*dst_32 ^= tmp;
dst_32++;
tmp = ((UINT32)__gf_mulc_[src[8]]) | ((UINT32)__gf_mulc_[src[9]]<<8) | ((UINT32)__gf_mulc_[src[10]]<<16) |
((UINT32)__gf_mulc_[src[11]]<<24);
*dst_32 ^= tmp;
dst_32++;
tmp = ((UINT32)__gf_mulc_[src[12]]) | ((UINT32)__gf_mulc_[src[13]]<<8) | ((UINT32)__gf_mulc_[src[14]]<<16) |
((UINT32)__gf_mulc_[src[15]]<<24);
*dst_32 ^= tmp;
dst_32++;
#endif
}
#endif
lim += UNROLL - 1 ;
for (; dst < lim; dst++, src++) {
/* final components, since sz is not necessarily a multiple of UNROLL */
GF_ADDMULC_COMPACT (*dst , *src);
}
}
/*
* computes C = AB where A is n*k, B is k*m, C is n*m
*/
void of_galois_field_2_4_matmul (gf *a, gf *b, gf *c, int n, int k, int m) {
OF_ENTER_FUNCTION
int row, col, i ;
for (row = 0; row < n ; row++)
{
for (col = 0; col < m ; col++)
{
gf *pa = &a[ row * k ];
gf *pb = &b[ col ];
gf acc = 0 ;
for (i = 0; i < k ; i++, pa++, pb += m)
acc ^= of_gf_2_4_mul_table[*pa][ *pb] ;
c[ row * m + col ] = acc ;
}
}
OF_EXIT_FUNCTION
}
int of_galois_field_2_4_invert_mat (of_galois_field_code_cb_t* ofcb, gf *src, int k) {
OF_ENTER_FUNCTION
gf c, *p ;
int irow, icol, row, col, i, ix ;
int error = 1 ;
int *indxc = (int*) of_malloc (k * sizeof (int));
int *indxr = (int*) of_malloc (k * sizeof (int));
int *ipiv = (int*) of_malloc (k * sizeof (int));
gf *id_row = (gf*) of_malloc (1 * k * sizeof(gf));
gf *temp_row = (gf*) of_malloc (1 * k * sizeof(gf));
bzero (id_row, k*sizeof (gf));
/*
* ipiv marks elements already used as pivots.
*/
for (i = 0; i < k ; i++)
ipiv[i] = 0 ;
for (col = 0; col < k ; col++)
{
gf *pivot_row ;
/*
* Zeroing column 'col', look for a non-zero element.
* First try on the diagonal, if it fails, look elsewhere.
*/
irow = icol = -1 ;
if (ipiv[col] != 1 && src[col*k + col] != 0)
{
irow = col ;
icol = col ;
goto found_piv ;
}
for (row = 0 ; row < k ; row++)
{
if (ipiv[row] != 1)
{
for (ix = 0 ; ix < k ; ix++)
{
if (ipiv[ix] == 0)
{
if (src[row*k + ix] != 0)
{
irow = row ;
icol = ix ;
goto found_piv ;
}
}
else
if (ipiv[ix] > 1)
{
// PRINT_ERR((mcl_stderr, "singular matrix\n"))
goto fail ;
}
}
}
}
if (icol == -1)
{
// PRINT_ERR((mcl_stderr, "XXX pivot not found!\n"))
goto fail ;
}
found_piv:
++ (ipiv[icol]) ;
/*
* swap rows irow and icol, so afterwards the diagonal
* element will be correct. Rarely done, not worth
* optimizing.
*/
if (irow != icol)
{
for (ix = 0 ; ix < k ; ix++)
{
SWAP (src[irow*k + ix], src[icol*k + ix], gf) ;
}
}
indxr[col] = irow ;
indxc[col] = icol ;
pivot_row = &src[icol*k] ;
c = pivot_row[icol] ;
if (c == 0)
{
OF_PRINT_ERROR(("singular matrix 2\n"))
goto fail ;
}
if (c != 1)
{
/* otherwhise this is a NOP */
/*
* this is done often , but optimizing is not so
* fruitful, at least in the obvious ways (unrolling)
*/
c = of_gf_2_4_inv[ c ] ;
pivot_row[icol] = 1 ;
for (ix = 0 ; ix < k ; ix++)
pivot_row[ix] = of_gf_2_4_mul_table[c][ pivot_row[ix]];
}
/*
* from all rows, remove multiples of the selected row
* to zero the relevant entry (in fact, the entry is not zero
* because we know it must be zero).
* (Here, if we know that the pivot_row is the identity,
* we can optimize the addmul).
*/
id_row[icol] = 1;
if (bcmp (pivot_row, id_row, k*sizeof (gf)) != 0)
{
for (p = src, ix = 0 ; ix < k ; ix++, p += k)
{
if (ix != icol)
{
c = p[icol] ;
p[icol] = 0 ;
if (c != 0)
of_galois_field_2_4_addmul1 (p, pivot_row, c, k);
}
}
}
id_row[icol] = 0;
} /* done all columns */
for (col = k - 1 ; col >= 0 ; col--)
{
if (indxr[col] < 0 || indxr[col] >= k)
OF_PRINT_ERROR(("AARGH, indxr[col] %d\n", indxr[col]))
else
if (indxc[col] < 0 || indxc[col] >= k)
OF_PRINT_ERROR(( "AARGH, indxc[col] %d\n", indxc[col]))
else
if (indxr[col] != indxc[col])
{
for (row = 0 ; row < k ; row++)
{
SWAP (src[row*k + indxr[col]], src[row*k + indxc[col]], gf) ;
}
}
}
error = 0 ;
fail:
of_free (indxc);
of_free (indxr);
of_free (ipiv);
of_free (id_row);
of_free (temp_row);
OF_EXIT_FUNCTION
return error ;
}
int of_galois_field_2_4_invert_vdm (of_galois_field_code_cb_t* ofcb, gf *src, int k) {
OF_ENTER_FUNCTION
int i, j, row, col ;
gf *b, *c, *p;
gf t, xx ;
if (k == 1) /* degenerate case, matrix must be p^0 = 1 */
return 0 ;
/*
* c holds the coefficient of P(x) = Prod (x - p_i), i=0..k-1
* b holds the coefficient for the matrix inversion
*/
c = (gf*) of_malloc(1 * k * sizeof(gf));
b = (gf*) of_malloc(1 * k * sizeof(gf));
p = (gf*) of_malloc(1 * k * sizeof(gf));
for (j = 1, i = 0 ; i < k ; i++, j += k)
{
c[i] = 0 ;
p[i] = src[j] ; /* p[i] */
}
/*
* construct coeffs. recursively. We know c[k] = 1 (implicit)
* and start P_0 = x - p_0, then at each stage multiply by
* x - p_i generating P_i = x P_{i-1} - p_i P_{i-1}
* After k steps we are done.
*/
c[k-1] = p[0] ; /* really -p(0), but x = -x in GF(2^m) */
for (i = 1 ; i < k ; i++)
{
gf p_i = p[i] ; /* see above comment */
for (j = k - 1 - (i - 1) ; j < k - 1 ; j++)
c[j] ^= of_gf_2_4_mul_table[p_i][ c[j+1]] ;
c[k-1] ^= p_i ;
}
for (row = 0 ; row < k ; row++)
{
/*
* synthetic division etc.
*/
xx = p[row] ;
t = 1 ;
b[k-1] = 1 ; /* this is in fact c[k] */
for (i = k - 2 ; i >= 0 ; i--)
{
b[i] = c[i+1] ^ of_gf_2_4_mul_table[xx][ b[i+1]] ;
t = of_gf_2_4_mul_table[xx][ t] ^ b[i] ;
}
for (col = 0 ; col < k ; col++)
src[col*k + row] = of_gf_2_4_mul_table [of_gf_2_4_inv[t]][ b[col]];
}
of_free (c);
of_free (b);
of_free (p);
OF_EXIT_FUNCTION
return 0 ;
}
#endif

View File

@@ -0,0 +1,114 @@
/* $Id: algebra_2_4.h 207 2014-12-10 19:47:50Z roca $ */
/*
* OpenFEC.org AL-FEC Library.
* (C) 1997-98 Luigi Rizzo (luigi@iet.unipi.it)
*
* Portions derived from code by Phil Karn (karn@ka9q.ampr.org),
* Robert Morelos-Zaragoza (robert@spectra.eng.hawaii.edu) and Hari
* Thirumoorthy (harit@spectra.eng.hawaii.edu), Aug 1995
*
* 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 AUTHORS ``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 AUTHORS
* 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 OF_GALOIS_FIELD_ALGEBRA_2_4_H
#define OF_GALOIS_FIELD_ALGEBRA_2_4_H
#include "../of_reed-solomon_gf_2_m_includes.h"
#ifdef OF_USE_REED_SOLOMON_2_M_CODEC
#define SWAP(a,b,t) {t tmp; tmp=a; a=b; b=tmp;}
static const gf of_gf_2_4_log[] = {15,0,1,4,2,8,5,10,3,14,9,7,6,13,11,12};
static const gf of_gf_2_4_exp[] = {1,2,4,8,3,6,12,11,5,10,7,14,15,13,9,1};
static const gf of_gf_2_4_inv[] = {0,1,9,14,13,11,7,6,15,2,12,5,10,4,3,8};
static const gf of_gf_2_4_mul_table[][16]={
{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15},
{0, 2, 4, 6, 8, 10, 12, 14, 3, 1, 7, 5, 11, 9, 15, 13},
{0, 3, 6, 5, 12, 15, 10, 9, 11, 8, 13, 14, 7, 4, 1, 2},
{0, 4, 8, 12, 3, 7, 11, 15, 6, 2, 14, 10, 5, 1, 13, 9},
{0, 5, 10, 15, 7, 2, 13, 8, 14, 11, 4, 1, 9, 12, 3, 6},
{0, 6, 12, 10, 11, 13, 7, 1, 5, 3, 9, 15, 14, 8, 2, 4},
{0, 7, 14, 9, 15, 8, 1, 6, 13, 10, 3, 4, 2, 5, 12, 11},
{0, 8, 3, 11, 6, 14, 5, 13, 12, 4, 15, 7, 10, 2, 9, 1},
{0, 9, 1, 8, 2, 11, 3, 10, 4, 13, 5, 12, 6, 15, 7, 14},
{0, 10, 7, 13, 14, 4, 9, 3, 15, 5, 8, 2, 1, 11, 6, 12},
{0, 11, 5, 14, 10, 1, 15, 4, 7, 12, 2, 9, 13, 6, 8, 3},
{0, 12, 11, 7, 5, 9, 14, 2, 10, 6, 1, 13, 15, 3, 4, 8},
{0, 13, 9, 4, 1, 12, 8, 5, 2, 15, 11, 6, 3, 14, 10, 7},
{0, 14, 15, 1, 13, 3, 2, 12, 9, 7, 6, 8, 4, 10, 11, 5},
{0, 15, 13, 2, 9, 6, 4, 11, 1, 14, 12, 3, 8, 7, 5, 10}};
static const gf of_gf_2_4_opt_mul_table[][256] = {
{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
{0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95,96,97,98,99,100,101,102,103,104,105,106,107,108,109,110,111,112,113,114,115,116,117,118,119,120,121,122,123,124,125,126,127,128,129,130,131,132,133,134,135,136,137,138,139,140,141,142,143,144,145,146,147,148,149,150,151,152,153,154,155,156,157,158,159,160,161,162,163,164,165,166,167,168,169,170,171,172,173,174,175,176,177,178,179,180,181,182,183,184,185,186,187,188,189,190,191,192,193,194,195,196,197,198,199,200,201,202,203,204,205,206,207,208,209,210,211,212,213,214,215,216,217,218,219,220,221,222,223,224,225,226,227,228,229,230,231,232,233,234,235,236,237,238,239,240,241,242,243,244,245,246,247,248,249,250,251,252,253,254,255},
{0,2,4,6,8,10,12,14,3,1,7,5,11,9,15,13,32,34,36,38,40,42,44,46,35,33,39,37,43,41,47,45,64,66,68,70,72,74,76,78,67,65,71,69,75,73,79,77,96,98,100,102,104,106,108,110,99,97,103,101,107,105,111,109,128,130,132,134,136,138,140,142,131,129,135,133,139,137,143,141,160,162,164,166,168,170,172,174,163,161,167,165,171,169,175,173,192,194,196,198,200,202,204,206,195,193,199,197,203,201,207,205,224,226,228,230,232,234,236,238,227,225,231,229,235,233,239,237,48,50,52,54,56,58,60,62,51,49,55,53,59,57,63,61,16,18,20,22,24,26,28,30,19,17,23,21,27,25,31,29,112,114,116,118,120,122,124,126,115,113,119,117,123,121,127,125,80,82,84,86,88,90,92,94,83,81,87,85,91,89,95,93,176,178,180,182,184,186,188,190,179,177,183,181,187,185,191,189,144,146,148,150,152,154,156,158,147,145,151,149,155,153,159,157,240,242,244,246,248,250,252,254,243,241,247,245,251,249,255,253,208,210,212,214,216,218,220,222,211,209,215,213,219,217,223,221},
{0,3,6,5,12,15,10,9,11,8,13,14,7,4,1,2,48,51,54,53,60,63,58,57,59,56,61,62,55,52,49,50,96,99,102,101,108,111,106,105,107,104,109,110,103,100,97,98,80,83,86,85,92,95,90,89,91,88,93,94,87,84,81,82,192,195,198,197,204,207,202,201,203,200,205,206,199,196,193,194,240,243,246,245,252,255,250,249,251,248,253,254,247,244,241,242,160,163,166,165,172,175,170,169,171,168,173,174,167,164,161,162,144,147,150,149,156,159,154,153,155,152,157,158,151,148,145,146,176,179,182,181,188,191,186,185,187,184,189,190,183,180,177,178,128,131,134,133,140,143,138,137,139,136,141,142,135,132,129,130,208,211,214,213,220,223,218,217,219,216,221,222,215,212,209,210,224,227,230,229,236,239,234,233,235,232,237,238,231,228,225,226,112,115,118,117,124,127,122,121,123,120,125,126,119,116,113,114,64,67,70,69,76,79,74,73,75,72,77,78,71,68,65,66,16,19,22,21,28,31,26,25,27,24,29,30,23,20,17,18,32,35,38,37,44,47,42,41,43,40,45,46,39,36,33,34},
{0,4,8,12,3,7,11,15,6,2,14,10,5,1,13,9,64,68,72,76,67,71,75,79,70,66,78,74,69,65,77,73,128,132,136,140,131,135,139,143,134,130,142,138,133,129,141,137,192,196,200,204,195,199,203,207,198,194,206,202,197,193,205,201,48,52,56,60,51,55,59,63,54,50,62,58,53,49,61,57,112,116,120,124,115,119,123,127,118,114,126,122,117,113,125,121,176,180,184,188,179,183,187,191,182,178,190,186,181,177,189,185,240,244,248,252,243,247,251,255,246,242,254,250,245,241,253,249,96,100,104,108,99,103,107,111,102,98,110,106,101,97,109,105,32,36,40,44,35,39,43,47,38,34,46,42,37,33,45,41,224,228,232,236,227,231,235,239,230,226,238,234,229,225,237,233,160,164,168,172,163,167,171,175,166,162,174,170,165,161,173,169,80,84,88,92,83,87,91,95,86,82,94,90,85,81,93,89,16,20,24,28,19,23,27,31,22,18,30,26,21,17,29,25,208,212,216,220,211,215,219,223,214,210,222,218,213,209,221,217,144,148,152,156,147,151,155,159,150,146,158,154,149,145,157,153},
{0,5,10,15,7,2,13,8,14,11,4,1,9,12,3,6,80,85,90,95,87,82,93,88,94,91,84,81,89,92,83,86,160,165,170,175,167,162,173,168,174,171,164,161,169,172,163,166,240,245,250,255,247,242,253,248,254,251,244,241,249,252,243,246,112,117,122,127,119,114,125,120,126,123,116,113,121,124,115,118,32,37,42,47,39,34,45,40,46,43,36,33,41,44,35,38,208,213,218,223,215,210,221,216,222,219,212,209,217,220,211,214,128,133,138,143,135,130,141,136,142,139,132,129,137,140,131,134,224,229,234,239,231,226,237,232,238,235,228,225,233,236,227,230,176,181,186,191,183,178,189,184,190,187,180,177,185,188,179,182,64,69,74,79,71,66,77,72,78,75,68,65,73,76,67,70,16,21,26,31,23,18,29,24,30,27,20,17,25,28,19,22,144,149,154,159,151,146,157,152,158,155,148,145,153,156,147,150,192,197,202,207,199,194,205,200,206,203,196,193,201,204,195,198,48,53,58,63,55,50,61,56,62,59,52,49,57,60,51,54,96,101,106,111,103,98,109,104,110,107,100,97,105,108,99,102},
{0,6,12,10,11,13,7,1,5,3,9,15,14,8,2,4,96,102,108,106,107,109,103,97,101,99,105,111,110,104,98,100,192,198,204,202,203,205,199,193,197,195,201,207,206,200,194,196,160,166,172,170,171,173,167,161,165,163,169,175,174,168,162,164,176,182,188,186,187,189,183,177,181,179,185,191,190,184,178,180,208,214,220,218,219,221,215,209,213,211,217,223,222,216,210,212,112,118,124,122,123,125,119,113,117,115,121,127,126,120,114,116,16,22,28,26,27,29,23,17,21,19,25,31,30,24,18,20,80,86,92,90,91,93,87,81,85,83,89,95,94,88,82,84,48,54,60,58,59,61,55,49,53,51,57,63,62,56,50,52,144,150,156,154,155,157,151,145,149,147,153,159,158,152,146,148,240,246,252,250,251,253,247,241,245,243,249,255,254,248,242,244,224,230,236,234,235,237,231,225,229,227,233,239,238,232,226,228,128,134,140,138,139,141,135,129,133,131,137,143,142,136,130,132,32,38,44,42,43,45,39,33,37,35,41,47,46,40,34,36,64,70,76,74,75,77,71,65,69,67,73,79,78,72,66,68},
{0,7,14,9,15,8,1,6,13,10,3,4,2,5,12,11,112,119,126,121,127,120,113,118,125,122,115,116,114,117,124,123,224,231,238,233,239,232,225,230,237,234,227,228,226,229,236,235,144,151,158,153,159,152,145,150,157,154,147,148,146,149,156,155,240,247,254,249,255,248,241,246,253,250,243,244,242,245,252,251,128,135,142,137,143,136,129,134,141,138,131,132,130,133,140,139,16,23,30,25,31,24,17,22,29,26,19,20,18,21,28,27,96,103,110,105,111,104,97,102,109,106,99,100,98,101,108,107,208,215,222,217,223,216,209,214,221,218,211,212,210,213,220,219,160,167,174,169,175,168,161,166,173,170,163,164,162,165,172,171,48,55,62,57,63,56,49,54,61,58,51,52,50,53,60,59,64,71,78,73,79,72,65,70,77,74,67,68,66,69,76,75,32,39,46,41,47,40,33,38,45,42,35,36,34,37,44,43,80,87,94,89,95,88,81,86,93,90,83,84,82,85,92,91,192,199,206,201,207,200,193,198,205,202,195,196,194,197,204,203,176,183,190,185,191,184,177,182,189,186,179,180,178,181,188,187},
{0,8,3,11,6,14,5,13,12,4,15,7,10,2,9,1,128,136,131,139,134,142,133,141,140,132,143,135,138,130,137,129,48,56,51,59,54,62,53,61,60,52,63,55,58,50,57,49,176,184,179,187,182,190,181,189,188,180,191,183,186,178,185,177,96,104,99,107,102,110,101,109,108,100,111,103,106,98,105,97,224,232,227,235,230,238,229,237,236,228,239,231,234,226,233,225,80,88,83,91,86,94,85,93,92,84,95,87,90,82,89,81,208,216,211,219,214,222,213,221,220,212,223,215,218,210,217,209,192,200,195,203,198,206,197,205,204,196,207,199,202,194,201,193,64,72,67,75,70,78,69,77,76,68,79,71,74,66,73,65,240,248,243,251,246,254,245,253,252,244,255,247,250,242,249,241,112,120,115,123,118,126,117,125,124,116,127,119,122,114,121,113,160,168,163,171,166,174,165,173,172,164,175,167,170,162,169,161,32,40,35,43,38,46,37,45,44,36,47,39,42,34,41,33,144,152,147,155,150,158,149,157,156,148,159,151,154,146,153,145,16,24,19,27,22,30,21,29,28,20,31,23,26,18,25,17},
{0,9,1,8,2,11,3,10,4,13,5,12,6,15,7,14,144,153,145,152,146,155,147,154,148,157,149,156,150,159,151,158,16,25,17,24,18,27,19,26,20,29,21,28,22,31,23,30,128,137,129,136,130,139,131,138,132,141,133,140,134,143,135,142,32,41,33,40,34,43,35,42,36,45,37,44,38,47,39,46,176,185,177,184,178,187,179,186,180,189,181,188,182,191,183,190,48,57,49,56,50,59,51,58,52,61,53,60,54,63,55,62,160,169,161,168,162,171,163,170,164,173,165,172,166,175,167,174,64,73,65,72,66,75,67,74,68,77,69,76,70,79,71,78,208,217,209,216,210,219,211,218,212,221,213,220,214,223,215,222,80,89,81,88,82,91,83,90,84,93,85,92,86,95,87,94,192,201,193,200,194,203,195,202,196,205,197,204,198,207,199,206,96,105,97,104,98,107,99,106,100,109,101,108,102,111,103,110,240,249,241,248,242,251,243,250,244,253,245,252,246,255,247,254,112,121,113,120,114,123,115,122,116,125,117,124,118,127,119,126,224,233,225,232,226,235,227,234,228,237,229,236,230,239,231,238},
{0,10,7,13,14,4,9,3,15,5,8,2,1,11,6,12,160,170,167,173,174,164,169,163,175,165,168,162,161,171,166,172,112,122,119,125,126,116,121,115,127,117,120,114,113,123,118,124,208,218,215,221,222,212,217,211,223,213,216,210,209,219,214,220,224,234,231,237,238,228,233,227,239,229,232,226,225,235,230,236,64,74,71,77,78,68,73,67,79,69,72,66,65,75,70,76,144,154,151,157,158,148,153,147,159,149,152,146,145,155,150,156,48,58,55,61,62,52,57,51,63,53,56,50,49,59,54,60,240,250,247,253,254,244,249,243,255,245,248,242,241,251,246,252,80,90,87,93,94,84,89,83,95,85,88,82,81,91,86,92,128,138,135,141,142,132,137,131,143,133,136,130,129,139,134,140,32,42,39,45,46,36,41,35,47,37,40,34,33,43,38,44,16,26,23,29,30,20,25,19,31,21,24,18,17,27,22,28,176,186,183,189,190,180,185,179,191,181,184,178,177,187,182,188,96,106,103,109,110,100,105,99,111,101,104,98,97,107,102,108,192,202,199,205,206,196,201,195,207,197,200,194,193,203,198,204},
{0,11,5,14,10,1,15,4,7,12,2,9,13,6,8,3,176,187,181,190,186,177,191,180,183,188,178,185,189,182,184,179,80,91,85,94,90,81,95,84,87,92,82,89,93,86,88,83,224,235,229,238,234,225,239,228,231,236,226,233,237,230,232,227,160,171,165,174,170,161,175,164,167,172,162,169,173,166,168,163,16,27,21,30,26,17,31,20,23,28,18,25,29,22,24,19,240,251,245,254,250,241,255,244,247,252,242,249,253,246,248,243,64,75,69,78,74,65,79,68,71,76,66,73,77,70,72,67,112,123,117,126,122,113,127,116,119,124,114,121,125,118,120,115,192,203,197,206,202,193,207,196,199,204,194,201,205,198,200,195,32,43,37,46,42,33,47,36,39,44,34,41,45,38,40,35,144,155,149,158,154,145,159,148,151,156,146,153,157,150,152,147,208,219,213,222,218,209,223,212,215,220,210,217,221,214,216,211,96,107,101,110,106,97,111,100,103,108,98,105,109,102,104,99,128,139,133,142,138,129,143,132,135,140,130,137,141,134,136,131,48,59,53,62,58,49,63,52,55,60,50,57,61,54,56,51},
{0,12,11,7,5,9,14,2,10,6,1,13,15,3,4,8,192,204,203,199,197,201,206,194,202,198,193,205,207,195,196,200,176,188,187,183,181,185,190,178,186,182,177,189,191,179,180,184,112,124,123,119,117,121,126,114,122,118,113,125,127,115,116,120,80,92,91,87,85,89,94,82,90,86,81,93,95,83,84,88,144,156,155,151,149,153,158,146,154,150,145,157,159,147,148,152,224,236,235,231,229,233,238,226,234,230,225,237,239,227,228,232,32,44,43,39,37,41,46,34,42,38,33,45,47,35,36,40,160,172,171,167,165,169,174,162,170,166,161,173,175,163,164,168,96,108,107,103,101,105,110,98,106,102,97,109,111,99,100,104,16,28,27,23,21,25,30,18,26,22,17,29,31,19,20,24,208,220,219,215,213,217,222,210,218,214,209,221,223,211,212,216,240,252,251,247,245,249,254,242,250,246,241,253,255,243,244,248,48,60,59,55,53,57,62,50,58,54,49,61,63,51,52,56,64,76,75,71,69,73,78,66,74,70,65,77,79,67,68,72,128,140,139,135,133,137,142,130,138,134,129,141,143,131,132,136},
{0,13,9,4,1,12,8,5,2,15,11,6,3,14,10,7,208,221,217,212,209,220,216,213,210,223,219,214,211,222,218,215,144,157,153,148,145,156,152,149,146,159,155,150,147,158,154,151,64,77,73,68,65,76,72,69,66,79,75,70,67,78,74,71,16,29,25,20,17,28,24,21,18,31,27,22,19,30,26,23,192,205,201,196,193,204,200,197,194,207,203,198,195,206,202,199,128,141,137,132,129,140,136,133,130,143,139,134,131,142,138,135,80,93,89,84,81,92,88,85,82,95,91,86,83,94,90,87,32,45,41,36,33,44,40,37,34,47,43,38,35,46,42,39,240,253,249,244,241,252,248,245,242,255,251,246,243,254,250,247,176,189,185,180,177,188,184,181,178,191,187,182,179,190,186,183,96,109,105,100,97,108,104,101,98,111,107,102,99,110,106,103,48,61,57,52,49,60,56,53,50,63,59,54,51,62,58,55,224,237,233,228,225,236,232,229,226,239,235,230,227,238,234,231,160,173,169,164,161,172,168,165,162,175,171,166,163,174,170,167,112,125,121,116,113,124,120,117,114,127,123,118,115,126,122,119},
{0,14,15,1,13,3,2,12,9,7,6,8,4,10,11,5,224,238,239,225,237,227,226,236,233,231,230,232,228,234,235,229,240,254,255,241,253,243,242,252,249,247,246,248,244,250,251,245,16,30,31,17,29,19,18,28,25,23,22,24,20,26,27,21,208,222,223,209,221,211,210,220,217,215,214,216,212,218,219,213,48,62,63,49,61,51,50,60,57,55,54,56,52,58,59,53,32,46,47,33,45,35,34,44,41,39,38,40,36,42,43,37,192,206,207,193,205,195,194,204,201,199,198,200,196,202,203,197,144,158,159,145,157,147,146,156,153,151,150,152,148,154,155,149,112,126,127,113,125,115,114,124,121,119,118,120,116,122,123,117,96,110,111,97,109,99,98,108,105,103,102,104,100,106,107,101,128,142,143,129,141,131,130,140,137,135,134,136,132,138,139,133,64,78,79,65,77,67,66,76,73,71,70,72,68,74,75,69,160,174,175,161,173,163,162,172,169,167,166,168,164,170,171,165,176,190,191,177,189,179,178,188,185,183,182,184,180,186,187,181,80,94,95,81,93,83,82,92,89,87,86,88,84,90,91,85},
{0,15,13,2,9,6,4,11,1,14,12,3,8,7,5,10,240,255,253,242,249,246,244,251,241,254,252,243,248,247,245,250,208,223,221,210,217,214,212,219,209,222,220,211,216,215,213,218,32,47,45,34,41,38,36,43,33,46,44,35,40,39,37,42,144,159,157,146,153,150,148,155,145,158,156,147,152,151,149,154,96,111,109,98,105,102,100,107,97,110,108,99,104,103,101,106,64,79,77,66,73,70,68,75,65,78,76,67,72,71,69,74,176,191,189,178,185,182,180,187,177,190,188,179,184,183,181,186,16,31,29,18,25,22,20,27,17,30,28,19,24,23,21,26,224,239,237,226,233,230,228,235,225,238,236,227,232,231,229,234,192,207,205,194,201,198,196,203,193,206,204,195,200,199,197,202,48,63,61,50,57,54,52,59,49,62,60,51,56,55,53,58,128,143,141,130,137,134,132,139,129,142,140,131,136,135,133,138,112,127,125,114,121,118,116,123,113,126,124,115,120,119,117,122,80,95,93,82,89,86,84,91,81,94,92,83,88,87,85,90,160,175,173,162,169,166,164,171,161,174,172,163,168,167,165,170}
};
/*
* addmul() computes dst[] = dst[] + c * src[]
*/
void of_galois_field_2_4_addmul1(gf *dst1, gf *src1, gf c, int sz);
/*
* of_galois_field_2_4_addmul1_compact() computes dst[] = dst[] + c * src[] when src and dst
* both point to vectors where each GF(2^4) element is actually stored in 4-bits.
* Said differently, there are two elements per byte.
* This is used for matrix operations where source/repair symbols are involved (encoding
* and decoding).
* This function has been optimized so that two elements are accessed each time, and the
* mulc table works on two elements at a time. This is a highly effective solution which
* warrants high performances.
*/
void of_galois_field_2_4_addmul1_compact (gf *dst1, gf *src1, gf c, int sz);
/*
* computes C = AB where A is n*k, B is k*m, C is n*m
*/
void of_galois_field_2_4_matmul (gf *a, gf *b, gf *c, int n, int k, int m);
int of_galois_field_2_4_invert_mat (of_galois_field_code_cb_t* ofcb, gf *src, int k);
int of_galois_field_2_4_invert_vdm (of_galois_field_code_cb_t* ofcb, gf *src, int k);
#endif //OF_USE_GALOIS_FIELD_CODES_UTILS
#endif //OF_GALOIS_FIELD_ALGEBRA_2_4_H

View File

@@ -0,0 +1,329 @@
/* $Id: algebra_2_8.c 185 2014-07-15 09:57:16Z roca $ */
/*
* OpenFEC.org AL-FEC Library.
* (C) 1997-98 Luigi Rizzo (luigi@iet.unipi.it)
*
* Portions derived from code by Phil Karn (karn@ka9q.ampr.org),
* Robert Morelos-Zaragoza (robert@spectra.eng.hawaii.edu) and Hari
* Thirumoorthy (harit@spectra.eng.hawaii.edu), Aug 1995
*
* 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 AUTHORS ``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 AUTHORS
* 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.
*/
#include "algebra_2_8.h"
#ifdef OF_USE_REED_SOLOMON_2_M_CODEC
#define UNROLL 16
#define USE_GF_MULC register gf * __gf_mulc_
#define GF_MULC0(c) __gf_mulc_ = (gf*)of_gf_2_8_mul_table[c]
#define GF_ADDMULC(dst, x) {dst ^= __gf_mulc_[x];}
/*
* addmul() computes dst[] = dst[] + c * src[]
* This is used often, so better optimize it! Currently the loop is
* unrolled 16 times, a good value for 486 and pentium-class machines.
* The case c=0 is also optimized, whereas c=1 is not. These
* calls are unfrequent in my typical apps so I did not bother.
*/
void of_galois_field_2_8_addmul1(gf *dst1, gf *src1, gf c, int sz) {
USE_GF_MULC ;
register gf *dst = dst1, *src = src1 ;
gf *lim = &dst[sz - UNROLL + 1] ;
#if ((defined (__LP64__) || (__WORDSIZE == 64)) && !defined (OF_RS_2M_USE_32BITS))
UINT64 tmp;
UINT64 *dst_64 = (UINT64*)dst1;
#else
UINT32 tmp;
UINT32 *dst_32 = (UINT32*)dst1;
#endif
GF_MULC0 (c) ;
#if (UNROLL > 1) /* unrolling by 8/16 is quite effective on the pentium */
//for (; dst < lim ; dst += UNROLL, src += UNROLL)
for (; dst < lim ;dst += UNROLL, src += UNROLL)
{
#if ((defined (__LP64__) || (__WORDSIZE == 64)) && !defined (OF_RS_2M_USE_32BITS))
tmp = ((UINT64)__gf_mulc_[src[0]]) | ((UINT64)__gf_mulc_[src[1]]<<8) | ((UINT64)__gf_mulc_[src[2]]<<16) |
((UINT64)__gf_mulc_[src[3]]<<24) | ((UINT64)__gf_mulc_[src[4]]<<32) | ((UINT64)__gf_mulc_[src[5]]<<40) |
((UINT64)__gf_mulc_[src[6]]<<48) | ((UINT64)__gf_mulc_[src[7]]<<56) ;
*dst_64 ^= tmp;
dst_64++;
tmp = ((UINT64)__gf_mulc_[src[8]]) | ((UINT64)__gf_mulc_[src[9]]<<8) | ((UINT64)__gf_mulc_[src[10]]<<16) |
((UINT64)__gf_mulc_[src[11]]<<24) | ((UINT64)__gf_mulc_[src[12]]<<32) | ((UINT64)__gf_mulc_[src[13]]<<40) |
((UINT64)__gf_mulc_[src[14]]<<48) | ((UINT64)__gf_mulc_[src[15]]<<56) ;
*dst_64 ^= tmp;
dst_64++;
#else
tmp = ((UINT32)__gf_mulc_[src[0]]) | ((UINT32)__gf_mulc_[src[1]]<<8) | ((UINT32)__gf_mulc_[src[2]]<<16) |
((UINT32)__gf_mulc_[src[3]]<<24);
*dst_32 ^= tmp;
dst_32++;
tmp = ((UINT32)__gf_mulc_[src[4]]) | ((UINT32)__gf_mulc_[src[5]]<<8) | ((UINT32)__gf_mulc_[src[6]]<<16) |
((UINT32)__gf_mulc_[src[7]]<<24);
*dst_32 ^= tmp;
dst_32++;
tmp = ((UINT32)__gf_mulc_[src[8]]) | ((UINT32)__gf_mulc_[src[9]]<<8) | ((UINT32)__gf_mulc_[src[10]]<<16) |
((UINT32)__gf_mulc_[src[11]]<<24);
*dst_32 ^= tmp;
dst_32++;
tmp = ((UINT32)__gf_mulc_[src[12]]) | ((UINT32)__gf_mulc_[src[13]]<<8) | ((UINT32)__gf_mulc_[src[14]]<<16) |
((UINT32)__gf_mulc_[src[15]]<<24);
*dst_32 ^= tmp;
dst_32++;
#endif
}
#endif
lim += UNROLL - 1 ;
for (; dst < lim; dst++, src++) /* final components */
GF_ADDMULC (*dst , *src);
}
/*
* computes C = AB where A is n*k, B is k*m, C is n*m
*/
void of_galois_field_2_8_matmul (gf *a, gf *b, gf *c, int n, int k, int m) {
OF_ENTER_FUNCTION
int row, col, i ;
for (row = 0; row < n ; row++)
{
for (col = 0; col < m ; col++)
{
gf *pa = &a[ row * k ];
gf *pb = &b[ col ];
gf acc = 0 ;
for (i = 0; i < k ; i++, pa++, pb += m)
acc ^= of_gf_2_8_mul_table[*pa][ *pb] ;
c[ row * m + col ] = acc ;
}
}
OF_EXIT_FUNCTION
}
int of_galois_field_2_8_invert_mat (of_galois_field_code_cb_t* ofcb, gf *src, int k) {
OF_ENTER_FUNCTION
gf c, *p ;
int irow, icol, row, col, i, ix ;
int error = 1 ;
int *indxc = (int*) of_malloc (k * sizeof (int));
int *indxr = (int*) of_malloc (k * sizeof (int));
int *ipiv = (int*) of_malloc (k * sizeof (int));
gf *id_row = (gf*) of_malloc (1 * k * sizeof(gf));
gf *temp_row = (gf*) of_malloc (1 * k * sizeof(gf));
bzero (id_row, k*sizeof (gf));
/*
* ipiv marks elements already used as pivots.
*/
for (i = 0; i < k ; i++)
ipiv[i] = 0 ;
for (col = 0; col < k ; col++)
{
gf *pivot_row ;
/*
* Zeroing column 'col', look for a non-zero element.
* First try on the diagonal, if it fails, look elsewhere.
*/
irow = icol = -1 ;
if (ipiv[col] != 1 && src[col*k + col] != 0)
{
irow = col ;
icol = col ;
goto found_piv ;
}
for (row = 0 ; row < k ; row++)
{
if (ipiv[row] != 1)
{
for (ix = 0 ; ix < k ; ix++)
{
if (ipiv[ix] == 0)
{
if (src[row*k + ix] != 0)
{
irow = row ;
icol = ix ;
goto found_piv ;
}
}
else if (ipiv[ix] > 1)
{
// PRINT_ERR((mcl_stderr, "singular matrix\n"))
goto fail ;
}
}
}
}
if (icol == -1)
{
// PRINT_ERR((mcl_stderr, "XXX pivot not found!\n"))
goto fail ;
}
found_piv:
++ (ipiv[icol]) ;
/*
* swap rows irow and icol, so afterwards the diagonal
* element will be correct. Rarely done, not worth
* optimizing.
*/
if (irow != icol)
{
for (ix = 0 ; ix < k ; ix++)
{
SWAP (src[irow*k + ix], src[icol*k + ix], gf) ;
}
}
indxr[col] = irow ;
indxc[col] = icol ;
pivot_row = &src[icol*k] ;
c = pivot_row[icol] ;
if (c == 0)
{
OF_PRINT_ERROR(("singular matrix 2\n"))
goto fail ;
}
if (c != 1)
{
/* otherwhise this is a NOP */
/*
* this is done often , but optimizing is not so
* fruitful, at least in the obvious ways (unrolling)
*/
c = of_gf_2_8_inv[ c ] ;
pivot_row[icol] = 1 ;
for (ix = 0 ; ix < k ; ix++)
pivot_row[ix] = of_gf_2_8_mul_table[c][ pivot_row[ix]];
}
/*
* from all rows, remove multiples of the selected row
* to zero the relevant entry (in fact, the entry is not zero
* because we know it must be zero).
* (Here, if we know that the pivot_row is the identity,
* we can optimize the addmul).
*/
id_row[icol] = 1;
if (bcmp (pivot_row, id_row, k*sizeof (gf)) != 0)
{
for (p = src, ix = 0 ; ix < k ; ix++, p += k)
{
if (ix != icol)
{
c = p[icol] ;
p[icol] = 0 ;
if (c != 0)
of_galois_field_2_8_addmul1 (p, pivot_row, c, k);
}
}
}
id_row[icol] = 0;
} /* done all columns */
for (col = k - 1 ; col >= 0 ; col--)
{
if (indxr[col] < 0 || indxr[col] >= k)
OF_PRINT_ERROR(("AARGH, indxr[col] %d\n", indxr[col]))
else if (indxc[col] < 0 || indxc[col] >= k)
OF_PRINT_ERROR(( "AARGH, indxc[col] %d\n", indxc[col]))
else if (indxr[col] != indxc[col])
{
for (row = 0 ; row < k ; row++)
{
SWAP (src[row*k + indxr[col]], src[row*k + indxc[col]], gf) ;
}
}
}
error = 0 ;
fail:
of_free (indxc);
of_free (indxr);
of_free (ipiv);
of_free (id_row);
of_free (temp_row);
OF_EXIT_FUNCTION
return error ;
}
int of_galois_field_2_8_invert_vdm (of_galois_field_code_cb_t* ofcb, gf *src, int k) {
OF_ENTER_FUNCTION
int i, j, row, col ;
gf *b, *c, *p;
gf t, xx ;
if (k == 1) /* degenerate case, matrix must be p^0 = 1 */
return 0 ;
/*
* c holds the coefficient of P(x) = Prod (x - p_i), i=0..k-1
* b holds the coefficient for the matrix inversion
*/
c = (gf*) of_malloc(1 * k * sizeof(gf));
b = (gf*) of_malloc(1 * k * sizeof(gf));
p = (gf*) of_malloc(1 * k * sizeof(gf));
for (j = 1, i = 0 ; i < k ; i++, j += k)
{
c[i] = 0 ;
p[i] = src[j] ; /* p[i] */
}
/*
* construct coeffs. recursively. We know c[k] = 1 (implicit)
* and start P_0 = x - p_0, then at each stage multiply by
* x - p_i generating P_i = x P_{i-1} - p_i P_{i-1}
* After k steps we are done.
*/
c[k-1] = p[0] ; /* really -p(0), but x = -x in GF(2^m) */
for (i = 1 ; i < k ; i++)
{
gf p_i = p[i] ; /* see above comment */
for (j = k - 1 - (i - 1) ; j < k - 1 ; j++)
c[j] ^= of_gf_2_8_mul_table[p_i][ c[j+1]] ;
c[k-1] ^= p_i ;
}
for (row = 0 ; row < k ; row++)
{
/*
* synthetic division etc.
*/
xx = p[row] ;
t = 1 ;
b[k-1] = 1 ; /* this is in fact c[k] */
for (i = k - 2 ; i >= 0 ; i--)
{
b[i] = c[i+1] ^ of_gf_2_8_mul_table[xx][ b[i+1]] ;
t = of_gf_2_8_mul_table[xx][ t] ^ b[i] ;
}
for (col = 0 ; col < k ; col++)
src[col*k + row] = of_gf_2_8_mul_table [of_gf_2_8_inv[t]][ b[col]];
}
of_free (c);
of_free (b);
of_free (p);
OF_EXIT_FUNCTION
return 0 ;
}
#endif

View File

@@ -0,0 +1,329 @@
/* $Id: algebra_2_8.h 148 2014-07-08 08:01:56Z roca $ */
/*
* OpenFEC.org AL-FEC Library.
* (C) 1997-98 Luigi Rizzo (luigi@iet.unipi.it)
*
* Portions derived from code by Phil Karn (karn@ka9q.ampr.org),
* Robert Morelos-Zaragoza (robert@spectra.eng.hawaii.edu) and Hari
* Thirumoorthy (harit@spectra.eng.hawaii.edu), Aug 1995
*
* 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 AUTHORS ``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 AUTHORS
* 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 OF_GALOIS_FIELD_ALGEBRA_2_8_H
#define OF_GALOIS_FIELD_ALGEBRA_2_8_H
#include "../of_reed-solomon_gf_2_m_includes.h"
#ifdef OF_USE_REED_SOLOMON_2_M_CODEC
#define SWAP(a,b,t) {t tmp; tmp=a; a=b; b=tmp;}
static const int of_gf_2_8_log[] = {255,0,1,25,2,50,26,198,3,223,51,238,27,104,199,75,4,100,224,14,52,141,239,129,28,193,105,248,200,8,76,113,5,138,101,47,225,36,15,33,53,147,142,218,240,18,130,69,29,181,194,125,106,39,249,185,201,154,9,120,77,228,114,166,6,191,139,98,102,221,48,253,226,152,37,179,16,145,34,136,54,208,148,206,143,150,219,189,241,210,19,92,131,56,70,64,30,66,182,163,195,72,126,110,107,58,40,84,250,133,186,61,202,94,155,159,10,21,121,43,78,212,229,172,115,243,167,87,7,112,192,247,140,128,99,13,103,74,222,237,49,197,254,24,227,165,153,119,38,184,180,124,17,68,146,217,35,32,137,46,55,63,209,91,149,188,207,205,144,135,151,178,220,252,190,97,242,86,211,171,20,42,93,158,132,60,57,83,71,109,65,162,31,45,67,216,183,123,164,118,196,23,73,236,127,12,111,246,108,161,59,82,41,157,85,170,251,96,134,177,187,204,62,90,203,89,95,176,156,169,160,81,11,245,22,235,122,117,44,215,79,174,213,233,230,231,173,232,116,214,244,234,168,80,88,175255,0,1,25,2,50,26,198,3,223,51,238,27,104,199,75,4,100,224,14,52,141,239,129,28,193,105,248,200,8,76,113,5,138,101,47,225,36,15,33,53,147,142,218,240,18,130,69,29,181,194,125,106,39,249,185,201,154,9,120,77,228,114,166,6,191,139,98,102,221,48,253,226,152,37,179,16,145,34,136,54,208,148,206,143,150,219,189,241,210,19,92,131,56,70,64,30,66,182,163,195,72,126,110,107,58,40,84,250,133,186,61,202,94,155,159,10,21,121,43,78,212,229,172,115,243,167,87,7,112,192,247,140,128,99,13,103,74,222,237,49,197,254,24,227,165,153,119,38,184,180,124,17,68,146,217,35,32,137,46,55,63,209,91,149,188,207,205,144,135,151,178,220,252,190,97,242,86,211,171,20,42,93,158,132,60,57,83,71,109,65,162,31,45,67,216,183,123,164,118,196,23,73,236,127,12,111,246,108,161,59,82,41,157,85,170,251,96,134,177,187,204,62,90,203,89,95,176,156,169,160,81,11,245,22,235,122,117,44,215,79,174,213,233,230,231,173,232,116,214,244,234,168,80,88,175};
static const gf of_gf_2_8_exp[] = {1,2,4,8,16,32,64,128,29,58,116,232,205,135,19,38,76,152,45,90,180,117,234,201,143,3,6,12,24,48,96,192,157,39,78,156,37,74,148,53,106,212,181,119,238,193,159,35,70,140,5,10,20,40,80,160,93,186,105,210,185,111,222,161,95,190,97,194,153,47,94,188,101,202,137,15,30,60,120,240,253,231,211,187,107,214,177,127,254,225,223,163,91,182,113,226,217,175,67,134,17,34,68,136,13,26,52,104,208,189,103,206,129,31,62,124,248,237,199,147,59,118,236,197,151,51,102,204,133,23,46,92,184,109,218,169,79,158,33,66,132,21,42,84,168,77,154,41,82,164,85,170,73,146,57,114,228,213,183,115,230,209,191,99,198,145,63,126,252,229,215,179,123,246,241,255,227,219,171,75,150,49,98,196,149,55,110,220,165,87,174,65,130,25,50,100,200,141,7,14,28,56,112,224,221,167,83,166,81,162,89,178,121,242,249,239,195,155,43,86,172,69,138,9,18,36,72,144,61,122,244,245,247,243,251,235,203,139,11,22,44,88,176,125,250,233,207,131,27,54,108,216,173,71,142,1};
static const gf of_gf_2_8_inv[] = {0,1,142,244,71,167,122,186,173,157,221,152,61,170,93,150,216,114,192,88,224,62,76,102,144,222,85,128,160,131,75,42,108,237,57,81,96,86,44,138,112,208,31,74,38,139,51,110,72,137,111,46,164,195,64,94,80,34,207,169,171,12,21,225,54,95,248,213,146,78,166,4,48,136,43,30,22,103,69,147,56,35,104,140,129,26,37,97,19,193,203,99,151,14,55,65,36,87,202,91,185,196,23,77,82,141,239,179,32,236,47,50,40,209,17,217,233,251,218,121,219,119,6,187,132,205,254,252,27,84,161,29,124,204,228,176,73,49,39,45,83,105,2,245,24,223,68,79,155,188,15,92,11,220,189,148,172,9,199,162,28,130,159,198,52,194,70,5,206,59,13,60,156,8,190,183,135,229,238,107,235,242,191,175,197,100,7,123,149,154,174,182,18,89,165,53,101,184,163,158,210,247,98,90,133,125,168,58,41,113,200,246,249,67,215,214,16,115,118,120,153,10,25,145,20,63,230,240,134,177,226,241,250,116,243,180,109,33,178,106,227,231,181,234,3,143,211,201,66,212,232,117,127,255,126,253};
static const gf of_gf_2_8_mul_table[][256] = {
{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
{0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95,96,97,98,99,100,101,102,103,104,105,106,107,108,109,110,111,112,113,114,115,116,117,118,119,120,121,122,123,124,125,126,127,128,129,130,131,132,133,134,135,136,137,138,139,140,141,142,143,144,145,146,147,148,149,150,151,152,153,154,155,156,157,158,159,160,161,162,163,164,165,166,167,168,169,170,171,172,173,174,175,176,177,178,179,180,181,182,183,184,185,186,187,188,189,190,191,192,193,194,195,196,197,198,199,200,201,202,203,204,205,206,207,208,209,210,211,212,213,214,215,216,217,218,219,220,221,222,223,224,225,226,227,228,229,230,231,232,233,234,235,236,237,238,239,240,241,242,243,244,245,246,247,248,249,250,251,252,253,254,255},
{0,2,4,6,8,10,12,14,16,18,20,22,24,26,28,30,32,34,36,38,40,42,44,46,48,50,52,54,56,58,60,62,64,66,68,70,72,74,76,78,80,82,84,86,88,90,92,94,96,98,100,102,104,106,108,110,112,114,116,118,120,122,124,126,128,130,132,134,136,138,140,142,144,146,148,150,152,154,156,158,160,162,164,166,168,170,172,174,176,178,180,182,184,186,188,190,192,194,196,198,200,202,204,206,208,210,212,214,216,218,220,222,224,226,228,230,232,234,236,238,240,242,244,246,248,250,252,254,29,31,25,27,21,23,17,19,13,15,9,11,5,7,1,3,61,63,57,59,53,55,49,51,45,47,41,43,37,39,33,35,93,95,89,91,85,87,81,83,77,79,73,75,69,71,65,67,125,127,121,123,117,119,113,115,109,111,105,107,101,103,97,99,157,159,153,155,149,151,145,147,141,143,137,139,133,135,129,131,189,191,185,187,181,183,177,179,173,175,169,171,165,167,161,163,221,223,217,219,213,215,209,211,205,207,201,203,197,199,193,195,253,255,249,251,245,247,241,243,237,239,233,235,229,231,225,227},
{0,3,6,5,12,15,10,9,24,27,30,29,20,23,18,17,48,51,54,53,60,63,58,57,40,43,46,45,36,39,34,33,96,99,102,101,108,111,106,105,120,123,126,125,116,119,114,113,80,83,86,85,92,95,90,89,72,75,78,77,68,71,66,65,192,195,198,197,204,207,202,201,216,219,222,221,212,215,210,209,240,243,246,245,252,255,250,249,232,235,238,237,228,231,226,225,160,163,166,165,172,175,170,169,184,187,190,189,180,183,178,177,144,147,150,149,156,159,154,153,136,139,142,141,132,135,130,129,157,158,155,152,145,146,151,148,133,134,131,128,137,138,143,140,173,174,171,168,161,162,167,164,181,182,179,176,185,186,191,188,253,254,251,248,241,242,247,244,229,230,227,224,233,234,239,236,205,206,203,200,193,194,199,196,213,214,211,208,217,218,223,220,93,94,91,88,81,82,87,84,69,70,67,64,73,74,79,76,109,110,107,104,97,98,103,100,117,118,115,112,121,122,127,124,61,62,59,56,49,50,55,52,37,38,35,32,41,42,47,44,13,14,11,8,1,2,7,4,21,22,19,16,25,26,31,28},
{0,4,8,12,16,20,24,28,32,36,40,44,48,52,56,60,64,68,72,76,80,84,88,92,96,100,104,108,112,116,120,124,128,132,136,140,144,148,152,156,160,164,168,172,176,180,184,188,192,196,200,204,208,212,216,220,224,228,232,236,240,244,248,252,29,25,21,17,13,9,5,1,61,57,53,49,45,41,37,33,93,89,85,81,77,73,69,65,125,121,117,113,109,105,101,97,157,153,149,145,141,137,133,129,189,185,181,177,173,169,165,161,221,217,213,209,205,201,197,193,253,249,245,241,237,233,229,225,58,62,50,54,42,46,34,38,26,30,18,22,10,14,2,6,122,126,114,118,106,110,98,102,90,94,82,86,74,78,66,70,186,190,178,182,170,174,162,166,154,158,146,150,138,142,130,134,250,254,242,246,234,238,226,230,218,222,210,214,202,206,194,198,39,35,47,43,55,51,63,59,7,3,15,11,23,19,31,27,103,99,111,107,119,115,127,123,71,67,79,75,87,83,95,91,167,163,175,171,183,179,191,187,135,131,143,139,151,147,159,155,231,227,239,235,247,243,255,251,199,195,207,203,215,211,223,219},
{0,5,10,15,20,17,30,27,40,45,34,39,60,57,54,51,80,85,90,95,68,65,78,75,120,125,114,119,108,105,102,99,160,165,170,175,180,177,190,187,136,141,130,135,156,153,150,147,240,245,250,255,228,225,238,235,216,221,210,215,204,201,198,195,93,88,87,82,73,76,67,70,117,112,127,122,97,100,107,110,13,8,7,2,25,28,19,22,37,32,47,42,49,52,59,62,253,248,247,242,233,236,227,230,213,208,223,218,193,196,203,206,173,168,167,162,185,188,179,182,133,128,143,138,145,148,155,158,186,191,176,181,174,171,164,161,146,151,152,157,134,131,140,137,234,239,224,229,254,251,244,241,194,199,200,205,214,211,220,217,26,31,16,21,14,11,4,1,50,55,56,61,38,35,44,41,74,79,64,69,94,91,84,81,98,103,104,109,118,115,124,121,231,226,237,232,243,246,249,252,207,202,197,192,219,222,209,212,183,178,189,184,163,166,169,172,159,154,149,144,139,142,129,132,71,66,77,72,83,86,89,92,111,106,101,96,123,126,113,116,23,18,29,24,3,6,9,12,63,58,53,48,43,46,33,36},
{0,6,12,10,24,30,20,18,48,54,60,58,40,46,36,34,96,102,108,106,120,126,116,114,80,86,92,90,72,78,68,66,192,198,204,202,216,222,212,210,240,246,252,250,232,238,228,226,160,166,172,170,184,190,180,178,144,150,156,154,136,142,132,130,157,155,145,151,133,131,137,143,173,171,161,167,181,179,185,191,253,251,241,247,229,227,233,239,205,203,193,199,213,211,217,223,93,91,81,87,69,67,73,79,109,107,97,103,117,115,121,127,61,59,49,55,37,35,41,47,13,11,1,7,21,19,25,31,39,33,43,45,63,57,51,53,23,17,27,29,15,9,3,5,71,65,75,77,95,89,83,85,119,113,123,125,111,105,99,101,231,225,235,237,255,249,243,245,215,209,219,221,207,201,195,197,135,129,139,141,159,153,147,149,183,177,187,189,175,169,163,165,186,188,182,176,162,164,174,168,138,140,134,128,146,148,158,152,218,220,214,208,194,196,206,200,234,236,230,224,242,244,254,248,122,124,118,112,98,100,110,104,74,76,70,64,82,84,94,88,26,28,22,16,2,4,14,8,42,44,38,32,50,52,62,56},
{0,7,14,9,28,27,18,21,56,63,54,49,36,35,42,45,112,119,126,121,108,107,98,101,72,79,70,65,84,83,90,93,224,231,238,233,252,251,242,245,216,223,214,209,196,195,202,205,144,151,158,153,140,139,130,133,168,175,166,161,180,179,186,189,221,218,211,212,193,198,207,200,229,226,235,236,249,254,247,240,173,170,163,164,177,182,191,184,149,146,155,156,137,142,135,128,61,58,51,52,33,38,47,40,5,2,11,12,25,30,23,16,77,74,67,68,81,86,95,88,117,114,123,124,105,110,103,96,167,160,169,174,187,188,181,178,159,152,145,150,131,132,141,138,215,208,217,222,203,204,197,194,239,232,225,230,243,244,253,250,71,64,73,78,91,92,85,82,127,120,113,118,99,100,109,106,55,48,57,62,43,44,37,34,15,8,1,6,19,20,29,26,122,125,116,115,102,97,104,111,66,69,76,75,94,89,80,87,10,13,4,3,22,17,24,31,50,53,60,59,46,41,32,39,154,157,148,147,134,129,136,143,162,165,172,171,190,185,176,183,234,237,228,227,246,241,248,255,210,213,220,219,206,201,192,199},
{0,8,16,24,32,40,48,56,64,72,80,88,96,104,112,120,128,136,144,152,160,168,176,184,192,200,208,216,224,232,240,248,29,21,13,5,61,53,45,37,93,85,77,69,125,117,109,101,157,149,141,133,189,181,173,165,221,213,205,197,253,245,237,229,58,50,42,34,26,18,10,2,122,114,106,98,90,82,74,66,186,178,170,162,154,146,138,130,250,242,234,226,218,210,202,194,39,47,55,63,7,15,23,31,103,111,119,127,71,79,87,95,167,175,183,191,135,143,151,159,231,239,247,255,199,207,215,223,116,124,100,108,84,92,68,76,52,60,36,44,20,28,4,12,244,252,228,236,212,220,196,204,180,188,164,172,148,156,132,140,105,97,121,113,73,65,89,81,41,33,57,49,9,1,25,17,233,225,249,241,201,193,217,209,169,161,185,177,137,129,153,145,78,70,94,86,110,102,126,118,14,6,30,22,46,38,62,54,206,198,222,214,238,230,254,246,142,134,158,150,174,166,190,182,83,91,67,75,115,123,99,107,19,27,3,11,51,59,35,43,211,219,195,203,243,251,227,235,147,155,131,139,179,187,163,171},
{0,9,18,27,36,45,54,63,72,65,90,83,108,101,126,119,144,153,130,139,180,189,166,175,216,209,202,195,252,245,238,231,61,52,47,38,25,16,11,2,117,124,103,110,81,88,67,74,173,164,191,182,137,128,155,146,229,236,247,254,193,200,211,218,122,115,104,97,94,87,76,69,50,59,32,41,22,31,4,13,234,227,248,241,206,199,220,213,162,171,176,185,134,143,148,157,71,78,85,92,99,106,113,120,15,6,29,20,43,34,57,48,215,222,197,204,243,250,225,232,159,150,141,132,187,178,169,160,244,253,230,239,208,217,194,203,188,181,174,167,152,145,138,131,100,109,118,127,64,73,82,91,44,37,62,55,8,1,26,19,201,192,219,210,237,228,255,246,129,136,147,154,165,172,183,190,89,80,75,66,125,116,111,102,17,24,3,10,53,60,39,46,142,135,156,149,170,163,184,177,198,207,212,221,226,235,240,249,30,23,12,5,58,51,40,33,86,95,68,77,114,123,96,105,179,186,161,168,151,158,133,140,251,242,233,224,223,214,205,196,35,42,49,56,7,14,21,28,107,98,121,112,79,70,93,84},
{0,10,20,30,40,34,60,54,80,90,68,78,120,114,108,102,160,170,180,190,136,130,156,150,240,250,228,238,216,210,204,198,93,87,73,67,117,127,97,107,13,7,25,19,37,47,49,59,253,247,233,227,213,223,193,203,173,167,185,179,133,143,145,155,186,176,174,164,146,152,134,140,234,224,254,244,194,200,214,220,26,16,14,4,50,56,38,44,74,64,94,84,98,104,118,124,231,237,243,249,207,197,219,209,183,189,163,169,159,149,139,129,71,77,83,89,111,101,123,113,23,29,3,9,63,53,43,33,105,99,125,119,65,75,85,95,57,51,45,39,17,27,5,15,201,195,221,215,225,235,245,255,153,147,141,135,177,187,165,175,52,62,32,42,28,22,8,2,100,110,112,122,76,70,88,82,148,158,128,138,188,182,168,162,196,206,208,218,236,230,248,242,211,217,199,205,251,241,239,229,131,137,151,157,171,161,191,181,115,121,103,109,91,81,79,69,35,41,55,61,11,1,31,21,142,132,154,144,166,172,178,184,222,212,202,192,246,252,226,232,46,36,58,48,6,12,18,24,126,116,106,96,86,92,66,72},
{0,11,22,29,44,39,58,49,88,83,78,69,116,127,98,105,176,187,166,173,156,151,138,129,232,227,254,245,196,207,210,217,125,118,107,96,81,90,71,76,37,46,51,56,9,2,31,20,205,198,219,208,225,234,247,252,149,158,131,136,185,178,175,164,250,241,236,231,214,221,192,203,162,169,180,191,142,133,152,147,74,65,92,87,102,109,112,123,18,25,4,15,62,53,40,35,135,140,145,154,171,160,189,182,223,212,201,194,243,248,229,238,55,60,33,42,27,16,13,6,111,100,121,114,67,72,85,94,233,226,255,244,197,206,211,216,177,186,167,172,157,150,139,128,89,82,79,68,117,126,99,104,1,10,23,28,45,38,59,48,148,159,130,137,184,179,174,165,204,199,218,209,224,235,246,253,36,47,50,57,8,3,30,21,124,119,106,97,80,91,70,77,19,24,5,14,63,52,41,34,75,64,93,86,103,108,113,122,163,168,181,190,143,132,153,146,251,240,237,230,215,220,193,202,110,101,120,115,66,73,84,95,54,61,32,43,26,17,12,7,222,213,200,195,242,249,228,239,134,141,144,155,170,161,188,183},
{0,12,24,20,48,60,40,36,96,108,120,116,80,92,72,68,192,204,216,212,240,252,232,228,160,172,184,180,144,156,136,132,157,145,133,137,173,161,181,185,253,241,229,233,205,193,213,217,93,81,69,73,109,97,117,121,61,49,37,41,13,1,21,25,39,43,63,51,23,27,15,3,71,75,95,83,119,123,111,99,231,235,255,243,215,219,207,195,135,139,159,147,183,187,175,163,186,182,162,174,138,134,146,158,218,214,194,206,234,230,242,254,122,118,98,110,74,70,82,94,26,22,2,14,42,38,50,62,78,66,86,90,126,114,102,106,46,34,54,58,30,18,6,10,142,130,150,154,190,178,166,170,238,226,246,250,222,210,198,202,211,223,203,199,227,239,251,247,179,191,171,167,131,143,155,151,19,31,11,7,35,47,59,55,115,127,107,103,67,79,91,87,105,101,113,125,89,85,65,77,9,5,17,29,57,53,33,45,169,165,177,189,153,149,129,141,201,197,209,221,249,245,225,237,244,248,236,224,196,200,220,208,148,152,140,128,164,168,188,176,52,56,44,32,4,8,28,16,84,88,76,64,100,104,124,112},
{0,13,26,23,52,57,46,35,104,101,114,127,92,81,70,75,208,221,202,199,228,233,254,243,184,181,162,175,140,129,150,155,189,176,167,170,137,132,147,158,213,216,207,194,225,236,251,246,109,96,119,122,89,84,67,78,5,8,31,18,49,60,43,38,103,106,125,112,83,94,73,68,15,2,21,24,59,54,33,44,183,186,173,160,131,142,153,148,223,210,197,200,235,230,241,252,218,215,192,205,238,227,244,249,178,191,168,165,134,139,156,145,10,7,16,29,62,51,36,41,98,111,120,117,86,91,76,65,206,195,212,217,250,247,224,237,166,171,188,177,146,159,136,133,30,19,4,9,42,39,48,61,118,123,108,97,66,79,88,85,115,126,105,100,71,74,93,80,27,22,1,12,47,34,53,56,163,174,185,180,151,154,141,128,203,198,209,220,255,242,229,232,169,164,179,190,157,144,135,138,193,204,219,214,245,248,239,226,121,116,99,110,77,64,87,90,17,28,11,6,37,40,63,50,20,25,14,3,32,45,58,55,124,113,102,107,72,69,82,95,196,201,222,211,240,253,234,231,172,161,182,187,152,149,130,143},
{0,14,28,18,56,54,36,42,112,126,108,98,72,70,84,90,224,238,252,242,216,214,196,202,144,158,140,130,168,166,180,186,221,211,193,207,229,235,249,247,173,163,177,191,149,155,137,135,61,51,33,47,5,11,25,23,77,67,81,95,117,123,105,103,167,169,187,181,159,145,131,141,215,217,203,197,239,225,243,253,71,73,91,85,127,113,99,109,55,57,43,37,15,1,19,29,122,116,102,104,66,76,94,80,10,4,22,24,50,60,46,32,154,148,134,136,162,172,190,176,234,228,246,248,210,220,206,192,83,93,79,65,107,101,119,121,35,45,63,49,27,21,7,9,179,189,175,161,139,133,151,153,195,205,223,209,251,245,231,233,142,128,146,156,182,184,170,164,254,240,226,236,198,200,218,212,110,96,114,124,86,88,74,68,30,16,2,12,38,40,58,52,244,250,232,230,204,194,208,222,132,138,152,150,188,178,160,174,20,26,8,6,44,34,48,62,100,106,120,118,92,82,64,78,41,39,53,59,17,31,13,3,89,87,69,75,97,111,125,115,201,199,213,219,241,255,237,227,185,183,165,171,129,143,157,147},
{0,15,30,17,60,51,34,45,120,119,102,105,68,75,90,85,240,255,238,225,204,195,210,221,136,135,150,153,180,187,170,165,253,242,227,236,193,206,223,208,133,138,155,148,185,182,167,168,13,2,19,28,49,62,47,32,117,122,107,100,73,70,87,88,231,232,249,246,219,212,197,202,159,144,129,142,163,172,189,178,23,24,9,6,43,36,53,58,111,96,113,126,83,92,77,66,26,21,4,11,38,41,56,55,98,109,124,115,94,81,64,79,234,229,244,251,214,217,200,199,146,157,140,131,174,161,176,191,211,220,205,194,239,224,241,254,171,164,181,186,151,152,137,134,35,44,61,50,31,16,1,14,91,84,69,74,103,104,121,118,46,33,48,63,18,29,12,3,86,89,72,71,106,101,116,123,222,209,192,207,226,237,252,243,166,169,184,183,154,149,132,139,52,59,42,37,8,7,22,25,76,67,82,93,112,127,110,97,196,203,218,213,248,247,230,233,188,179,162,173,128,143,158,145,201,198,215,216,245,250,235,228,177,190,175,160,141,130,147,156,57,54,39,40,5,10,27,20,65,78,95,80,125,114,99,108},
{0,16,32,48,64,80,96,112,128,144,160,176,192,208,224,240,29,13,61,45,93,77,125,109,157,141,189,173,221,205,253,237,58,42,26,10,122,106,90,74,186,170,154,138,250,234,218,202,39,55,7,23,103,119,71,87,167,183,135,151,231,247,199,215,116,100,84,68,52,36,20,4,244,228,212,196,180,164,148,132,105,121,73,89,41,57,9,25,233,249,201,217,169,185,137,153,78,94,110,126,14,30,46,62,206,222,238,254,142,158,174,190,83,67,115,99,19,3,51,35,211,195,243,227,147,131,179,163,232,248,200,216,168,184,136,152,104,120,72,88,40,56,8,24,245,229,213,197,181,165,149,133,117,101,85,69,53,37,21,5,210,194,242,226,146,130,178,162,82,66,114,98,18,2,50,34,207,223,239,255,143,159,175,191,79,95,111,127,15,31,47,63,156,140,188,172,220,204,252,236,28,12,60,44,92,76,124,108,129,145,161,177,193,209,225,241,1,17,33,49,65,81,97,113,166,182,134,150,230,246,198,214,38,54,6,22,102,118,70,86,187,171,155,139,251,235,219,203,59,43,27,11,123,107,91,75},
{0,17,34,51,68,85,102,119,136,153,170,187,204,221,238,255,13,28,47,62,73,88,107,122,133,148,167,182,193,208,227,242,26,11,56,41,94,79,124,109,146,131,176,161,214,199,244,229,23,6,53,36,83,66,113,96,159,142,189,172,219,202,249,232,52,37,22,7,112,97,82,67,188,173,158,143,248,233,218,203,57,40,27,10,125,108,95,78,177,160,147,130,245,228,215,198,46,63,12,29,106,123,72,89,166,183,132,149,226,243,192,209,35,50,1,16,103,118,69,84,171,186,137,152,239,254,205,220,104,121,74,91,44,61,14,31,224,241,194,211,164,181,134,151,101,116,71,86,33,48,3,18,237,252,207,222,169,184,139,154,114,99,80,65,54,39,20,5,250,235,216,201,190,175,156,141,127,110,93,76,59,42,25,8,247,230,213,196,179,162,145,128,92,77,126,111,24,9,58,43,212,197,246,231,144,129,178,163,81,64,115,98,21,4,55,38,217,200,251,234,157,140,191,174,70,87,100,117,2,19,32,49,206,223,236,253,138,155,168,185,75,90,105,120,15,30,45,60,195,210,225,240,135,150,165,180},
{0,18,36,54,72,90,108,126,144,130,180,166,216,202,252,238,61,47,25,11,117,103,81,67,173,191,137,155,229,247,193,211,122,104,94,76,50,32,22,4,234,248,206,220,162,176,134,148,71,85,99,113,15,29,43,57,215,197,243,225,159,141,187,169,244,230,208,194,188,174,152,138,100,118,64,82,44,62,8,26,201,219,237,255,129,147,165,183,89,75,125,111,17,3,53,39,142,156,170,184,198,212,226,240,30,12,58,40,86,68,114,96,179,161,151,133,251,233,223,205,35,49,7,21,107,121,79,93,245,231,209,195,189,175,153,139,101,119,65,83,45,63,9,27,200,218,236,254,128,146,164,182,88,74,124,110,16,2,52,38,143,157,171,185,199,213,227,241,31,13,59,41,87,69,115,97,178,160,150,132,250,232,222,204,34,48,6,20,106,120,78,92,1,19,37,55,73,91,109,127,145,131,181,167,217,203,253,239,60,46,24,10,116,102,80,66,172,190,136,154,228,246,192,210,123,105,95,77,51,33,23,5,235,249,207,221,163,177,135,149,70,84,98,112,14,28,42,56,214,196,242,224,158,140,186,168},
{0,19,38,53,76,95,106,121,152,139,190,173,212,199,242,225,45,62,11,24,97,114,71,84,181,166,147,128,249,234,223,204,90,73,124,111,22,5,48,35,194,209,228,247,142,157,168,187,119,100,81,66,59,40,29,14,239,252,201,218,163,176,133,150,180,167,146,129,248,235,222,205,44,63,10,25,96,115,70,85,153,138,191,172,213,198,243,224,1,18,39,52,77,94,107,120,238,253,200,219,162,177,132,151,118,101,80,67,58,41,28,15,195,208,229,246,143,156,169,186,91,72,125,110,23,4,49,34,117,102,83,64,57,42,31,12,237,254,203,216,161,178,135,148,88,75,126,109,20,7,50,33,192,211,230,245,140,159,170,185,47,60,9,26,99,112,69,86,183,164,145,130,251,232,221,206,2,17,36,55,78,93,104,123,154,137,188,175,214,197,240,227,193,210,231,244,141,158,171,184,89,74,127,108,21,6,51,32,236,255,202,217,160,179,134,149,116,103,82,65,56,43,30,13,155,136,189,174,215,196,241,226,3,16,37,54,79,92,105,122,182,165,144,131,250,233,220,207,46,61,8,27,98,113,68,87},
{0,20,40,60,80,68,120,108,160,180,136,156,240,228,216,204,93,73,117,97,13,25,37,49,253,233,213,193,173,185,133,145,186,174,146,134,234,254,194,214,26,14,50,38,74,94,98,118,231,243,207,219,183,163,159,139,71,83,111,123,23,3,63,43,105,125,65,85,57,45,17,5,201,221,225,245,153,141,177,165,52,32,28,8,100,112,76,88,148,128,188,168,196,208,236,248,211,199,251,239,131,151,171,191,115,103,91,79,35,55,11,31,142,154,166,178,222,202,246,226,46,58,6,18,126,106,86,66,210,198,250,238,130,150,170,190,114,102,90,78,34,54,10,30,143,155,167,179,223,203,247,227,47,59,7,19,127,107,87,67,104,124,64,84,56,44,16,4,200,220,224,244,152,140,176,164,53,33,29,9,101,113,77,89,149,129,189,169,197,209,237,249,187,175,147,135,235,255,195,215,27,15,51,39,75,95,99,119,230,242,206,218,182,162,158,138,70,82,110,122,22,2,62,42,1,21,41,61,81,69,121,109,161,181,137,157,241,229,217,205,92,72,116,96,12,24,36,48,252,232,212,192,172,184,132,144},
{0,21,42,63,84,65,126,107,168,189,130,151,252,233,214,195,77,88,103,114,25,12,51,38,229,240,207,218,177,164,155,142,154,143,176,165,206,219,228,241,50,39,24,13,102,115,76,89,215,194,253,232,131,150,169,188,127,106,85,64,43,62,1,20,41,60,3,22,125,104,87,66,129,148,171,190,213,192,255,234,100,113,78,91,48,37,26,15,204,217,230,243,152,141,178,167,179,166,153,140,231,242,205,216,27,14,49,36,79,90,101,112,254,235,212,193,170,191,128,149,86,67,124,105,2,23,40,61,82,71,120,109,6,19,44,57,250,239,208,197,174,187,132,145,31,10,53,32,75,94,97,116,183,162,157,136,227,246,201,220,200,221,226,247,156,137,182,163,96,117,74,95,52,33,30,11,133,144,175,186,209,196,251,238,45,56,7,18,121,108,83,70,123,110,81,68,47,58,5,16,211,198,249,236,135,146,173,184,54,35,28,9,98,119,72,93,158,139,180,161,202,223,224,245,225,244,203,222,181,160,159,138,73,92,99,118,29,8,55,34,172,185,134,147,248,237,210,199,4,17,46,59,80,69,122,111},
{0,22,44,58,88,78,116,98,176,166,156,138,232,254,196,210,125,107,81,71,37,51,9,31,205,219,225,247,149,131,185,175,250,236,214,192,162,180,142,152,74,92,102,112,18,4,62,40,135,145,171,189,223,201,243,229,55,33,27,13,111,121,67,85,233,255,197,211,177,167,157,139,89,79,117,99,1,23,45,59,148,130,184,174,204,218,224,246,36,50,8,30,124,106,80,70,19,5,63,41,75,93,103,113,163,181,143,153,251,237,215,193,110,120,66,84,54,32,26,12,222,200,242,228,134,144,170,188,207,217,227,245,151,129,187,173,127,105,83,69,39,49,11,29,178,164,158,136,234,252,198,208,2,20,46,56,90,76,118,96,53,35,25,15,109,123,65,87,133,147,169,191,221,203,241,231,72,94,100,114,16,6,60,42,248,238,212,194,160,182,140,154,38,48,10,28,126,104,82,68,150,128,186,172,206,216,226,244,91,77,119,97,3,21,47,57,235,253,199,209,179,165,159,137,220,202,240,230,132,146,168,190,108,122,64,86,52,34,24,14,161,183,141,155,249,239,213,195,17,7,61,43,73,95,101,115},
{0,23,46,57,92,75,114,101,184,175,150,129,228,243,202,221,109,122,67,84,49,38,31,8,213,194,251,236,137,158,167,176,218,205,244,227,134,145,168,191,98,117,76,91,62,41,16,7,183,160,153,142,235,252,197,210,15,24,33,54,83,68,125,106,169,190,135,144,245,226,219,204,17,6,63,40,77,90,99,116,196,211,234,253,152,143,182,161,124,107,82,69,32,55,14,25,115,100,93,74,47,56,1,22,203,220,229,242,151,128,185,174,30,9,48,39,66,85,108,123,166,177,136,159,250,237,212,195,79,88,97,118,19,4,61,42,247,224,217,206,171,188,133,146,34,53,12,27,126,105,80,71,154,141,180,163,198,209,232,255,149,130,187,172,201,222,231,240,45,58,3,20,113,102,95,72,248,239,214,193,164,179,138,157,64,87,110,121,28,11,50,37,230,241,200,223,186,173,148,131,94,73,112,103,2,21,44,59,139,156,165,178,215,192,249,238,51,36,29,10,111,120,65,86,60,43,18,5,96,119,78,89,132,147,170,189,216,207,246,225,81,70,127,104,13,26,35,52,233,254,199,208,181,162,155,140},
{0,24,48,40,96,120,80,72,192,216,240,232,160,184,144,136,157,133,173,181,253,229,205,213,93,69,109,117,61,37,13,21,39,63,23,15,71,95,119,111,231,255,215,207,135,159,183,175,186,162,138,146,218,194,234,242,122,98,74,82,26,2,42,50,78,86,126,102,46,54,30,6,142,150,190,166,238,246,222,198,211,203,227,251,179,171,131,155,19,11,35,59,115,107,67,91,105,113,89,65,9,17,57,33,169,177,153,129,201,209,249,225,244,236,196,220,148,140,164,188,52,44,4,28,84,76,100,124,156,132,172,180,252,228,204,212,92,68,108,116,60,36,12,20,1,25,49,41,97,121,81,73,193,217,241,233,161,185,145,137,187,163,139,147,219,195,235,243,123,99,75,83,27,3,43,51,38,62,22,14,70,94,118,110,230,254,214,206,134,158,182,174,210,202,226,250,178,170,130,154,18,10,34,58,114,106,66,90,79,87,127,103,47,55,31,7,143,151,191,167,239,247,223,199,245,237,197,221,149,141,165,189,53,45,5,29,85,77,101,125,104,112,88,64,8,16,56,32,168,176,152,128,200,208,248,224},
{0,25,50,43,100,125,86,79,200,209,250,227,172,181,158,135,141,148,191,166,233,240,219,194,69,92,119,110,33,56,19,10,7,30,53,44,99,122,81,72,207,214,253,228,171,178,153,128,138,147,184,161,238,247,220,197,66,91,112,105,38,63,20,13,14,23,60,37,106,115,88,65,198,223,244,237,162,187,144,137,131,154,177,168,231,254,213,204,75,82,121,96,47,54,29,4,9,16,59,34,109,116,95,70,193,216,243,234,165,188,151,142,132,157,182,175,224,249,210,203,76,85,126,103,40,49,26,3,28,5,46,55,120,97,74,83,212,205,230,255,176,169,130,155,145,136,163,186,245,236,199,222,89,64,107,114,61,36,15,22,27,2,41,48,127,102,77,84,211,202,225,248,183,174,133,156,150,143,164,189,242,235,192,217,94,71,108,117,58,35,8,17,18,11,32,57,118,111,68,93,218,195,232,241,190,167,140,149,159,134,173,180,251,226,201,208,87,78,101,124,51,42,1,24,21,12,39,62,113,104,67,90,221,196,239,246,185,160,139,146,152,129,170,179,252,229,206,215,80,73,98,123,52,45,6,31},
{0,26,52,46,104,114,92,70,208,202,228,254,184,162,140,150,189,167,137,147,213,207,225,251,109,119,89,67,5,31,49,43,103,125,83,73,15,21,59,33,183,173,131,153,223,197,235,241,218,192,238,244,178,168,134,156,10,16,62,36,98,120,86,76,206,212,250,224,166,188,146,136,30,4,42,48,118,108,66,88,115,105,71,93,27,1,47,53,163,185,151,141,203,209,255,229,169,179,157,135,193,219,245,239,121,99,77,87,17,11,37,63,20,14,32,58,124,102,72,82,196,222,240,234,172,182,152,130,129,155,181,175,233,243,221,199,81,75,101,127,57,35,13,23,60,38,8,18,84,78,96,122,236,246,216,194,132,158,176,170,230,252,210,200,142,148,186,160,54,44,2,24,94,68,106,112,91,65,111,117,51,41,7,29,139,145,191,165,227,249,215,205,79,85,123,97,39,61,19,9,159,133,171,177,247,237,195,217,242,232,198,220,154,128,174,180,34,56,22,12,74,80,126,100,40,50,28,6,64,90,116,110,248,226,204,214,144,138,164,190,149,143,161,187,253,231,201,211,69,95,113,107,45,55,25,3},
{0,27,54,45,108,119,90,65,216,195,238,245,180,175,130,153,173,182,155,128,193,218,247,236,117,110,67,88,25,2,47,52,71,92,113,106,43,48,29,6,159,132,169,178,243,232,197,222,234,241,220,199,134,157,176,171,50,41,4,31,94,69,104,115,142,149,184,163,226,249,212,207,86,77,96,123,58,33,12,23,35,56,21,14,79,84,121,98,251,224,205,214,151,140,161,186,201,210,255,228,165,190,147,136,17,10,39,60,125,102,75,80,100,127,82,73,8,19,62,37,188,167,138,145,208,203,230,253,1,26,55,44,109,118,91,64,217,194,239,244,181,174,131,152,172,183,154,129,192,219,246,237,116,111,66,89,24,3,46,53,70,93,112,107,42,49,28,7,158,133,168,179,242,233,196,223,235,240,221,198,135,156,177,170,51,40,5,30,95,68,105,114,143,148,185,162,227,248,213,206,87,76,97,122,59,32,13,22,34,57,20,15,78,85,120,99,250,225,204,215,150,141,160,187,200,211,254,229,164,191,146,137,16,11,38,61,124,103,74,81,101,126,83,72,9,18,63,36,189,166,139,144,209,202,231,252},
{0,28,56,36,112,108,72,84,224,252,216,196,144,140,168,180,221,193,229,249,173,177,149,137,61,33,5,25,77,81,117,105,167,187,159,131,215,203,239,243,71,91,127,99,55,43,15,19,122,102,66,94,10,22,50,46,154,134,162,190,234,246,210,206,83,79,107,119,35,63,27,7,179,175,139,151,195,223,251,231,142,146,182,170,254,226,198,218,110,114,86,74,30,2,38,58,244,232,204,208,132,152,188,160,20,8,44,48,100,120,92,64,41,53,17,13,89,69,97,125,201,213,241,237,185,165,129,157,166,186,158,130,214,202,238,242,70,90,126,98,54,42,14,18,123,103,67,95,11,23,51,47,155,135,163,191,235,247,211,207,1,29,57,37,113,109,73,85,225,253,217,197,145,141,169,181,220,192,228,248,172,176,148,136,60,32,4,24,76,80,116,104,245,233,205,209,133,153,189,161,21,9,45,49,101,121,93,65,40,52,16,12,88,68,96,124,200,212,240,236,184,164,128,156,82,78,106,118,34,62,26,6,178,174,138,150,194,222,250,230,143,147,183,171,255,227,199,219,111,115,87,75,31,3,39,59},
{0,29,58,39,116,105,78,83,232,245,210,207,156,129,166,187,205,208,247,234,185,164,131,158,37,56,31,2,81,76,107,118,135,154,189,160,243,238,201,212,111,114,85,72,27,6,33,60,74,87,112,109,62,35,4,25,162,191,152,133,214,203,236,241,19,14,41,52,103,122,93,64,251,230,193,220,143,146,181,168,222,195,228,249,170,183,144,141,54,43,12,17,66,95,120,101,148,137,174,179,224,253,218,199,124,97,70,91,8,21,50,47,89,68,99,126,45,48,23,10,177,172,139,150,197,216,255,226,38,59,28,1,82,79,104,117,206,211,244,233,186,167,128,157,235,246,209,204,159,130,165,184,3,30,57,36,119,106,77,80,161,188,155,134,213,200,239,242,73,84,115,110,61,32,7,26,108,113,86,75,24,5,34,63,132,153,190,163,240,237,202,215,53,40,15,18,65,92,123,102,221,192,231,250,169,180,147,142,248,229,194,223,140,145,182,171,16,13,42,55,100,121,94,67,178,175,136,149,198,219,252,225,90,71,96,125,46,51,20,9,127,98,69,88,11,22,49,44,151,138,173,176,227,254,217,196},
{0,30,60,34,120,102,68,90,240,238,204,210,136,150,180,170,253,227,193,223,133,155,185,167,13,19,49,47,117,107,73,87,231,249,219,197,159,129,163,189,23,9,43,53,111,113,83,77,26,4,38,56,98,124,94,64,234,244,214,200,146,140,174,176,211,205,239,241,171,181,151,137,35,61,31,1,91,69,103,121,46,48,18,12,86,72,106,116,222,192,226,252,166,184,154,132,52,42,8,22,76,82,112,110,196,218,248,230,188,162,128,158,201,215,245,235,177,175,141,147,57,39,5,27,65,95,125,99,187,165,135,153,195,221,255,225,75,85,119,105,51,45,15,17,70,88,122,100,62,32,2,28,182,168,138,148,206,208,242,236,92,66,96,126,36,58,24,6,172,178,144,142,212,202,232,246,161,191,157,131,217,199,229,251,81,79,109,115,41,55,21,11,104,118,84,74,16,14,44,50,152,134,164,186,224,254,220,194,149,139,169,183,237,243,209,207,101,123,89,71,29,3,33,63,143,145,179,173,247,233,203,213,127,97,67,93,7,25,59,37,114,108,78,80,10,20,54,40,130,156,190,160,250,228,198,216},
{0,31,62,33,124,99,66,93,248,231,198,217,132,155,186,165,237,242,211,204,145,142,175,176,21,10,43,52,105,118,87,72,199,216,249,230,187,164,133,154,63,32,1,30,67,92,125,98,42,53,20,11,86,73,104,119,210,205,236,243,174,177,144,143,147,140,173,178,239,240,209,206,107,116,85,74,23,8,41,54,126,97,64,95,2,29,60,35,134,153,184,167,250,229,196,219,84,75,106,117,40,55,22,9,172,179,146,141,208,207,238,241,185,166,135,152,197,218,251,228,65,94,127,96,61,34,3,28,59,36,5,26,71,88,121,102,195,220,253,226,191,160,129,158,214,201,232,247,170,181,148,139,46,49,16,15,82,77,108,115,252,227,194,221,128,159,190,161,4,27,58,37,120,103,70,89,17,14,47,48,109,114,83,76,233,246,215,200,149,138,171,180,168,183,150,137,212,203,234,245,80,79,110,113,44,51,18,13,69,90,123,100,57,38,7,24,189,162,131,156,193,222,255,224,111,112,81,78,19,12,45,50,151,136,169,182,235,244,213,202,130,157,188,163,254,225,192,223,122,101,68,91,6,25,56,39},
{0,32,64,96,128,160,192,224,29,61,93,125,157,189,221,253,58,26,122,90,186,154,250,218,39,7,103,71,167,135,231,199,116,84,52,20,244,212,180,148,105,73,41,9,233,201,169,137,78,110,14,46,206,238,142,174,83,115,19,51,211,243,147,179,232,200,168,136,104,72,40,8,245,213,181,149,117,85,53,21,210,242,146,178,82,114,18,50,207,239,143,175,79,111,15,47,156,188,220,252,28,60,92,124,129,161,193,225,1,33,65,97,166,134,230,198,38,6,102,70,187,155,251,219,59,27,123,91,205,237,141,173,77,109,13,45,208,240,144,176,80,112,16,48,247,215,183,151,119,87,55,23,234,202,170,138,106,74,42,10,185,153,249,217,57,25,121,89,164,132,228,196,36,4,100,68,131,163,195,227,3,35,67,99,158,190,222,254,30,62,94,126,37,5,101,69,165,133,229,197,56,24,120,88,184,152,248,216,31,63,95,127,159,191,223,255,2,34,66,98,130,162,194,226,81,113,17,49,209,241,145,177,76,108,12,44,204,236,140,172,107,75,43,11,235,203,171,139,118,86,54,22,246,214,182,150},
{0,33,66,99,132,165,198,231,21,52,87,118,145,176,211,242,42,11,104,73,174,143,236,205,63,30,125,92,187,154,249,216,84,117,22,55,208,241,146,179,65,96,3,34,197,228,135,166,126,95,60,29,250,219,184,153,107,74,41,8,239,206,173,140,168,137,234,203,44,13,110,79,189,156,255,222,57,24,123,90,130,163,192,225,6,39,68,101,151,182,213,244,19,50,81,112,252,221,190,159,120,89,58,27,233,200,171,138,109,76,47,14,214,247,148,181,82,115,16,49,195,226,129,160,71,102,5,36,77,108,15,46,201,232,139,170,88,121,26,59,220,253,158,191,103,70,37,4,227,194,161,128,114,83,48,17,246,215,180,149,25,56,91,122,157,188,223,254,12,45,78,111,136,169,202,235,51,18,113,80,183,150,245,212,38,7,100,69,162,131,224,193,229,196,167,134,97,64,35,2,240,209,178,147,116,85,54,23,207,238,141,172,75,106,9,40,218,251,152,185,94,127,28,61,177,144,243,210,53,20,119,86,164,133,230,199,32,1,98,67,155,186,217,248,31,62,93,124,142,175,204,237,10,43,72,105},
{0,34,68,102,136,170,204,238,13,47,73,107,133,167,193,227,26,56,94,124,146,176,214,244,23,53,83,113,159,189,219,249,52,22,112,82,188,158,248,218,57,27,125,95,177,147,245,215,46,12,106,72,166,132,226,192,35,1,103,69,171,137,239,205,104,74,44,14,224,194,164,134,101,71,33,3,237,207,169,139,114,80,54,20,250,216,190,156,127,93,59,25,247,213,179,145,92,126,24,58,212,246,144,178,81,115,21,55,217,251,157,191,70,100,2,32,206,236,138,168,75,105,15,45,195,225,135,165,208,242,148,182,88,122,28,62,221,255,153,187,85,119,17,51,202,232,142,172,66,96,6,36,199,229,131,161,79,109,11,41,228,198,160,130,108,78,40,10,233,203,173,143,97,67,37,7,254,220,186,152,118,84,50,16,243,209,183,149,123,89,63,29,184,154,252,222,48,18,116,86,181,151,241,211,61,31,121,91,162,128,230,196,42,8,110,76,175,141,235,201,39,5,99,65,140,174,200,234,4,38,64,98,129,163,197,231,9,43,77,111,150,180,210,240,30,60,90,120,155,185,223,253,19,49,87,117},
{0,35,70,101,140,175,202,233,5,38,67,96,137,170,207,236,10,41,76,111,134,165,192,227,15,44,73,106,131,160,197,230,20,55,82,113,152,187,222,253,17,50,87,116,157,190,219,248,30,61,88,123,146,177,212,247,27,56,93,126,151,180,209,242,40,11,110,77,164,135,226,193,45,14,107,72,161,130,231,196,34,1,100,71,174,141,232,203,39,4,97,66,171,136,237,206,60,31,122,89,176,147,246,213,57,26,127,92,181,150,243,208,54,21,112,83,186,153,252,223,51,16,117,86,191,156,249,218,80,115,22,53,220,255,154,185,85,118,19,48,217,250,159,188,90,121,28,63,214,245,144,179,95,124,25,58,211,240,149,182,68,103,2,33,200,235,142,173,65,98,7,36,205,238,139,168,78,109,8,43,194,225,132,167,75,104,13,46,199,228,129,162,120,91,62,29,244,215,178,145,125,94,59,24,241,210,183,148,114,81,52,23,254,221,184,155,119,84,49,18,251,216,189,158,108,79,42,9,224,195,166,133,105,74,47,12,229,198,163,128,102,69,32,3,234,201,172,143,99,64,37,6,239,204,169,138},
{0,36,72,108,144,180,216,252,61,25,117,81,173,137,229,193,122,94,50,22,234,206,162,134,71,99,15,43,215,243,159,187,244,208,188,152,100,64,44,8,201,237,129,165,89,125,17,53,142,170,198,226,30,58,86,114,179,151,251,223,35,7,107,79,245,209,189,153,101,65,45,9,200,236,128,164,88,124,16,52,143,171,199,227,31,59,87,115,178,150,250,222,34,6,106,78,1,37,73,109,145,181,217,253,60,24,116,80,172,136,228,192,123,95,51,23,235,207,163,135,70,98,14,42,214,242,158,186,247,211,191,155,103,67,47,11,202,238,130,166,90,126,18,54,141,169,197,225,29,57,85,113,176,148,248,220,32,4,104,76,3,39,75,111,147,183,219,255,62,26,118,82,174,138,230,194,121,93,49,21,233,205,161,133,68,96,12,40,212,240,156,184,2,38,74,110,146,182,218,254,63,27,119,83,175,139,231,195,120,92,48,20,232,204,160,132,69,97,13,41,213,241,157,185,246,210,190,154,102,66,46,10,203,239,131,167,91,127,19,55,140,168,196,224,28,56,84,112,177,149,249,221,33,5,105,77},
{0,37,74,111,148,177,222,251,53,16,127,90,161,132,235,206,106,79,32,5,254,219,180,145,95,122,21,48,203,238,129,164,212,241,158,187,64,101,10,47,225,196,171,142,117,80,63,26,190,155,244,209,42,15,96,69,139,174,193,228,31,58,85,112,181,144,255,218,33,4,107,78,128,165,202,239,20,49,94,123,223,250,149,176,75,110,1,36,234,207,160,133,126,91,52,17,97,68,43,14,245,208,191,154,84,113,30,59,192,229,138,175,11,46,65,100,159,186,213,240,62,27,116,81,170,143,224,197,119,82,61,24,227,198,169,140,66,103,8,45,214,243,156,185,29,56,87,114,137,172,195,230,40,13,98,71,188,153,246,211,163,134,233,204,55,18,125,88,150,179,220,249,2,39,72,109,201,236,131,166,93,120,23,50,252,217,182,147,104,77,34,7,194,231,136,173,86,115,28,57,247,210,189,152,99,70,41,12,168,141,226,199,60,25,118,83,157,184,215,242,9,44,67,102,22,51,92,121,130,167,200,237,35,6,105,76,183,146,253,216,124,89,54,19,232,205,162,135,73,108,3,38,221,248,151,178},
{0,38,76,106,152,190,212,242,45,11,97,71,181,147,249,223,90,124,22,48,194,228,142,168,119,81,59,29,239,201,163,133,180,146,248,222,44,10,96,70,153,191,213,243,1,39,77,107,238,200,162,132,118,80,58,28,195,229,143,169,91,125,23,49,117,83,57,31,237,203,161,135,88,126,20,50,192,230,140,170,47,9,99,69,183,145,251,221,2,36,78,104,154,188,214,240,193,231,141,171,89,127,21,51,236,202,160,134,116,82,56,30,155,189,215,241,3,37,79,105,182,144,250,220,46,8,98,68,234,204,166,128,114,84,62,24,199,225,139,173,95,121,19,53,176,150,252,218,40,14,100,66,157,187,209,247,5,35,73,111,94,120,18,52,198,224,138,172,115,85,63,25,235,205,167,129,4,34,72,110,156,186,208,246,41,15,101,67,177,151,253,219,159,185,211,245,7,33,75,109,178,148,254,216,42,12,102,64,197,227,137,175,93,123,17,55,232,206,164,130,112,86,60,26,43,13,103,65,179,149,255,217,6,32,74,108,158,184,210,244,113,87,61,27,233,207,165,131,92,122,16,54,196,226,136,174},
{0,39,78,105,156,187,210,245,37,2,107,76,185,158,247,208,74,109,4,35,214,241,152,191,111,72,33,6,243,212,189,154,148,179,218,253,8,47,70,97,177,150,255,216,45,10,99,68,222,249,144,183,66,101,12,43,251,220,181,146,103,64,41,14,53,18,123,92,169,142,231,192,16,55,94,121,140,171,194,229,127,88,49,22,227,196,173,138,90,125,20,51,198,225,136,175,161,134,239,200,61,26,115,84,132,163,202,237,24,63,86,113,235,204,165,130,119,80,57,30,206,233,128,167,82,117,28,59,106,77,36,3,246,209,184,159,79,104,1,38,211,244,157,186,32,7,110,73,188,155,242,213,5,34,75,108,153,190,215,240,254,217,176,151,98,69,44,11,219,252,149,178,71,96,9,46,180,147,250,221,40,15,102,65,145,182,223,248,13,42,67,100,95,120,17,54,195,228,141,170,122,93,52,19,230,193,168,143,21,50,91,124,137,174,199,224,48,23,126,89,172,139,226,197,203,236,133,162,87,112,25,62,238,201,160,135,114,85,60,27,129,166,207,232,29,58,83,116,164,131,234,205,56,31,118,81},
{0,40,80,120,160,136,240,216,93,117,13,37,253,213,173,133,186,146,234,194,26,50,74,98,231,207,183,159,71,111,23,63,105,65,57,17,201,225,153,177,52,28,100,76,148,188,196,236,211,251,131,171,115,91,35,11,142,166,222,246,46,6,126,86,210,250,130,170,114,90,34,10,143,167,223,247,47,7,127,87,104,64,56,16,200,224,152,176,53,29,101,77,149,189,197,237,187,147,235,195,27,51,75,99,230,206,182,158,70,110,22,62,1,41,81,121,161,137,241,217,92,116,12,36,252,212,172,132,185,145,233,193,25,49,73,97,228,204,180,156,68,108,20,60,3,43,83,123,163,139,243,219,94,118,14,38,254,214,174,134,208,248,128,168,112,88,32,8,141,165,221,245,45,5,125,85,106,66,58,18,202,226,154,178,55,31,103,79,151,191,199,239,107,67,59,19,203,227,155,179,54,30,102,78,150,190,198,238,209,249,129,169,113,89,33,9,140,164,220,244,44,4,124,84,2,42,82,122,162,138,242,218,95,119,15,39,255,215,175,135,184,144,232,192,24,48,72,96,229,205,181,157,69,109,21,61},
{0,41,82,123,164,141,246,223,85,124,7,46,241,216,163,138,170,131,248,209,14,39,92,117,255,214,173,132,91,114,9,32,73,96,27,50,237,196,191,150,28,53,78,103,184,145,234,195,227,202,177,152,71,110,21,60,182,159,228,205,18,59,64,105,146,187,192,233,54,31,100,77,199,238,149,188,99,74,49,24,56,17,106,67,156,181,206,231,109,68,63,22,201,224,155,178,219,242,137,160,127,86,45,4,142,167,220,245,42,3,120,81,113,88,35,10,213,252,135,174,36,13,118,95,128,169,210,251,57,16,107,66,157,180,207,230,108,69,62,23,200,225,154,179,147,186,193,232,55,30,101,76,198,239,148,189,98,75,48,25,112,89,34,11,212,253,134,175,37,12,119,94,129,168,211,250,218,243,136,161,126,87,44,5,143,166,221,244,43,2,121,80,171,130,249,208,15,38,93,116,254,215,172,133,90,115,8,33,1,40,83,122,165,140,247,222,84,125,6,47,240,217,162,139,226,203,176,153,70,111,20,61,183,158,229,204,19,58,65,104,72,97,26,51,236,197,190,151,29,52,79,102,185,144,235,194},
{0,42,84,126,168,130,252,214,77,103,25,51,229,207,177,155,154,176,206,228,50,24,102,76,215,253,131,169,127,85,43,1,41,3,125,87,129,171,213,255,100,78,48,26,204,230,152,178,179,153,231,205,27,49,79,101,254,212,170,128,86,124,2,40,82,120,6,44,250,208,174,132,31,53,75,97,183,157,227,201,200,226,156,182,96,74,52,30,133,175,209,251,45,7,121,83,123,81,47,5,211,249,135,173,54,28,98,72,158,180,202,224,225,203,181,159,73,99,29,55,172,134,248,210,4,46,80,122,164,142,240,218,12,38,88,114,233,195,189,151,65,107,21,63,62,20,106,64,150,188,194,232,115,89,39,13,219,241,143,165,141,167,217,243,37,15,113,91,192,234,148,190,104,66,60,22,23,61,67,105,191,149,235,193,90,112,14,36,242,216,166,140,246,220,162,136,94,116,10,32,187,145,239,197,19,57,71,109,108,70,56,18,196,238,144,186,33,11,117,95,137,163,221,247,223,245,139,161,119,93,35,9,146,184,198,236,58,16,110,68,69,111,17,59,237,199,185,147,8,34,92,118,160,138,244,222},
{0,43,86,125,172,135,250,209,69,110,19,56,233,194,191,148,138,161,220,247,38,13,112,91,207,228,153,178,99,72,53,30,9,34,95,116,165,142,243,216,76,103,26,49,224,203,182,157,131,168,213,254,47,4,121,82,198,237,144,187,106,65,60,23,18,57,68,111,190,149,232,195,87,124,1,42,251,208,173,134,152,179,206,229,52,31,98,73,221,246,139,160,113,90,39,12,27,48,77,102,183,156,225,202,94,117,8,35,242,217,164,143,145,186,199,236,61,22,107,64,212,255,130,169,120,83,46,5,36,15,114,89,136,163,222,245,97,74,55,28,205,230,155,176,174,133,248,211,2,41,84,127,235,192,189,150,71,108,17,58,45,6,123,80,129,170,215,252,104,67,62,21,196,239,146,185,167,140,241,218,11,32,93,118,226,201,180,159,78,101,24,51,54,29,96,75,154,177,204,231,115,88,37,14,223,244,137,162,188,151,234,193,16,59,70,109,249,210,175,132,85,126,3,40,63,20,105,66,147,184,197,238,122,81,44,7,214,253,128,171,181,158,227,200,25,50,79,100,240,219,166,141,92,119,10,33},
{0,44,88,116,176,156,232,196,125,81,37,9,205,225,149,185,250,214,162,142,74,102,18,62,135,171,223,243,55,27,111,67,233,197,177,157,89,117,1,45,148,184,204,224,36,8,124,80,19,63,75,103,163,143,251,215,110,66,54,26,222,242,134,170,207,227,151,187,127,83,39,11,178,158,234,198,2,46,90,118,53,25,109,65,133,169,221,241,72,100,16,60,248,212,160,140,38,10,126,82,150,186,206,226,91,119,3,47,235,199,179,159,220,240,132,168,108,64,52,24,161,141,249,213,17,61,73,101,131,175,219,247,51,31,107,71,254,210,166,138,78,98,22,58,121,85,33,13,201,229,145,189,4,40,92,112,180,152,236,192,106,70,50,30,218,246,130,174,23,59,79,99,167,139,255,211,144,188,200,228,32,12,120,84,237,193,181,153,93,113,5,41,76,96,20,56,252,208,164,136,49,29,105,69,129,173,217,245,182,154,238,194,6,42,94,114,203,231,147,191,123,87,35,15,165,137,253,209,21,57,77,97,216,244,128,172,104,68,48,28,95,115,7,43,239,195,183,155,34,14,122,86,146,190,202,230},
{0,45,90,119,180,153,238,195,117,88,47,2,193,236,155,182,234,199,176,157,94,115,4,41,159,178,197,232,43,6,113,92,201,228,147,190,125,80,39,10,188,145,230,203,8,37,82,127,35,14,121,84,151,186,205,224,86,123,12,33,226,207,184,149,143,162,213,248,59,22,97,76,250,215,160,141,78,99,20,57,101,72,63,18,209,252,139,166,16,61,74,103,164,137,254,211,70,107,28,49,242,223,168,133,51,30,105,68,135,170,221,240,172,129,246,219,24,53,66,111,217,244,131,174,109,64,55,26,3,46,89,116,183,154,237,192,118,91,44,1,194,239,152,181,233,196,179,158,93,112,7,42,156,177,198,235,40,5,114,95,202,231,144,189,126,83,36,9,191,146,229,200,11,38,81,124,32,13,122,87,148,185,206,227,85,120,15,34,225,204,187,150,140,161,214,251,56,21,98,79,249,212,163,142,77,96,23,58,102,75,60,17,210,255,136,165,19,62,73,100,167,138,253,208,69,104,31,50,241,220,171,134,48,29,106,71,132,169,222,243,175,130,245,216,27,54,65,108,218,247,128,173,110,67,52,25},
{0,46,92,114,184,150,228,202,109,67,49,31,213,251,137,167,218,244,134,168,98,76,62,16,183,153,235,197,15,33,83,125,169,135,245,219,17,63,77,99,196,234,152,182,124,82,32,14,115,93,47,1,203,229,151,185,30,48,66,108,166,136,250,212,79,97,19,61,247,217,171,133,34,12,126,80,154,180,198,232,149,187,201,231,45,3,113,95,248,214,164,138,64,110,28,50,230,200,186,148,94,112,2,44,139,165,215,249,51,29,111,65,60,18,96,78,132,170,216,246,81,127,13,35,233,199,181,155,158,176,194,236,38,8,122,84,243,221,175,129,75,101,23,57,68,106,24,54,252,210,160,142,41,7,117,91,145,191,205,227,55,25,107,69,143,161,211,253,90,116,6,40,226,204,190,144,237,195,177,159,85,123,9,39,128,174,220,242,56,22,100,74,209,255,141,163,105,71,53,27,188,146,224,206,4,42,88,118,11,37,87,121,179,157,239,193,102,72,58,20,222,240,130,172,120,86,36,10,192,238,156,178,21,59,73,103,173,131,241,223,162,140,254,208,26,52,70,104,207,225,147,189,119,89,43,5},
{0,47,94,113,188,147,226,205,101,74,59,20,217,246,135,168,202,229,148,187,118,89,40,7,175,128,241,222,19,60,77,98,137,166,215,248,53,26,107,68,236,195,178,157,80,127,14,33,67,108,29,50,255,208,161,142,38,9,120,87,154,181,196,235,15,32,81,126,179,156,237,194,106,69,52,27,214,249,136,167,197,234,155,180,121,86,39,8,160,143,254,209,28,51,66,109,134,169,216,247,58,21,100,75,227,204,189,146,95,112,1,46,76,99,18,61,240,223,174,129,41,6,119,88,149,186,203,228,30,49,64,111,162,141,252,211,123,84,37,10,199,232,153,182,212,251,138,165,104,71,54,25,177,158,239,192,13,34,83,124,151,184,201,230,43,4,117,90,242,221,172,131,78,97,16,63,93,114,3,44,225,206,191,144,56,23,102,73,132,171,218,245,17,62,79,96,173,130,243,220,116,91,42,5,200,231,150,185,219,244,133,170,103,72,57,22,190,145,224,207,2,45,92,115,152,183,198,233,36,11,122,85,253,210,163,140,65,110,31,48,82,125,12,35,238,193,176,159,55,24,105,70,139,164,213,250},
{0,48,96,80,192,240,160,144,157,173,253,205,93,109,61,13,39,23,71,119,231,215,135,183,186,138,218,234,122,74,26,42,78,126,46,30,142,190,238,222,211,227,179,131,19,35,115,67,105,89,9,57,169,153,201,249,244,196,148,164,52,4,84,100,156,172,252,204,92,108,60,12,1,49,97,81,193,241,161,145,187,139,219,235,123,75,27,43,38,22,70,118,230,214,134,182,210,226,178,130,18,34,114,66,79,127,47,31,143,191,239,223,245,197,149,165,53,5,85,101,104,88,8,56,168,152,200,248,37,21,69,117,229,213,133,181,184,136,216,232,120,72,24,40,2,50,98,82,194,242,162,146,159,175,255,207,95,111,63,15,107,91,11,59,171,155,203,251,246,198,150,166,54,6,86,102,76,124,44,28,140,188,236,220,209,225,177,129,17,33,113,65,185,137,217,233,121,73,25,41,36,20,68,116,228,212,132,180,158,174,254,206,94,110,62,14,3,51,99,83,195,243,163,147,247,199,151,167,55,7,87,103,106,90,10,58,170,154,202,250,208,224,176,128,16,32,112,64,77,125,45,29,141,189,237,221},
{0,49,98,83,196,245,166,151,149,164,247,198,81,96,51,2,55,6,85,100,243,194,145,160,162,147,192,241,102,87,4,53,110,95,12,61,170,155,200,249,251,202,153,168,63,14,93,108,89,104,59,10,157,172,255,206,204,253,174,159,8,57,106,91,220,237,190,143,24,41,122,75,73,120,43,26,141,188,239,222,235,218,137,184,47,30,77,124,126,79,28,45,186,139,216,233,178,131,208,225,118,71,20,37,39,22,69,116,227,210,129,176,133,180,231,214,65,112,35,18,16,33,114,67,212,229,182,135,165,148,199,246,97,80,3,50,48,1,82,99,244,197,150,167,146,163,240,193,86,103,52,5,7,54,101,84,195,242,161,144,203,250,169,152,15,62,109,92,94,111,60,13,154,171,248,201,252,205,158,175,56,9,90,107,105,88,11,58,173,156,207,254,121,72,27,42,189,140,223,238,236,221,142,191,40,25,74,123,78,127,44,29,138,187,232,217,219,234,185,136,31,46,125,76,23,38,117,68,211,226,177,128,130,179,224,209,70,119,36,21,32,17,66,115,228,213,134,183,181,132,215,230,113,64,19,34},
{0,50,100,86,200,250,172,158,141,191,233,219,69,119,33,19,7,53,99,81,207,253,171,153,138,184,238,220,66,112,38,20,14,60,106,88,198,244,162,144,131,177,231,213,75,121,47,29,9,59,109,95,193,243,165,151,132,182,224,210,76,126,40,26,28,46,120,74,212,230,176,130,145,163,245,199,89,107,61,15,27,41,127,77,211,225,183,133,150,164,242,192,94,108,58,8,18,32,118,68,218,232,190,140,159,173,251,201,87,101,51,1,21,39,113,67,221,239,185,139,152,170,252,206,80,98,52,6,56,10,92,110,240,194,148,166,181,135,209,227,125,79,25,43,63,13,91,105,247,197,147,161,178,128,214,228,122,72,30,44,54,4,82,96,254,204,154,168,187,137,223,237,115,65,23,37,49,3,85,103,249,203,157,175,188,142,216,234,116,70,16,34,36,22,64,114,236,222,136,186,169,155,205,255,97,83,5,55,35,17,71,117,235,217,143,189,174,156,202,248,102,84,2,48,42,24,78,124,226,208,134,180,167,149,195,241,111,93,11,57,45,31,73,123,229,215,129,179,160,146,196,246,104,90,12,62},
{0,51,102,85,204,255,170,153,133,182,227,208,73,122,47,28,23,36,113,66,219,232,189,142,146,161,244,199,94,109,56,11,46,29,72,123,226,209,132,183,171,152,205,254,103,84,1,50,57,10,95,108,245,198,147,160,188,143,218,233,112,67,22,37,92,111,58,9,144,163,246,197,217,234,191,140,21,38,115,64,75,120,45,30,135,180,225,210,206,253,168,155,2,49,100,87,114,65,20,39,190,141,216,235,247,196,145,162,59,8,93,110,101,86,3,48,169,154,207,252,224,211,134,181,44,31,74,121,184,139,222,237,116,71,18,33,61,14,91,104,241,194,151,164,175,156,201,250,99,80,5,54,42,25,76,127,230,213,128,179,150,165,240,195,90,105,60,15,19,32,117,70,223,236,185,138,129,178,231,212,77,126,43,24,4,55,98,81,200,251,174,157,228,215,130,177,40,27,78,125,97,82,7,52,173,158,203,248,243,192,149,166,63,12,89,106,118,69,16,35,186,137,220,239,202,249,172,159,6,53,96,83,79,124,41,26,131,176,229,214,221,238,187,136,17,34,119,68,88,107,62,13,148,167,242,193},
{0,52,104,92,208,228,184,140,189,137,213,225,109,89,5,49,103,83,15,59,183,131,223,235,218,238,178,134,10,62,98,86,206,250,166,146,30,42,118,66,115,71,27,47,163,151,203,255,169,157,193,245,121,77,17,37,20,32,124,72,196,240,172,152,129,181,233,221,81,101,57,13,60,8,84,96,236,216,132,176,230,210,142,186,54,2,94,106,91,111,51,7,139,191,227,215,79,123,39,19,159,171,247,195,242,198,154,174,34,22,74,126,40,28,64,116,248,204,144,164,149,161,253,201,69,113,45,25,31,43,119,67,207,251,167,147,162,150,202,254,114,70,26,46,120,76,16,36,168,156,192,244,197,241,173,153,21,33,125,73,209,229,185,141,1,53,105,93,108,88,4,48,188,136,212,224,182,130,222,234,102,82,14,58,11,63,99,87,219,239,179,135,158,170,246,194,78,122,38,18,35,23,75,127,243,199,155,175,249,205,145,165,41,29,65,117,68,112,44,24,148,160,252,200,80,100,56,12,128,180,232,220,237,217,133,177,61,9,85,97,55,3,95,107,231,211,143,187,138,190,226,214,90,110,50,6},
{0,53,106,95,212,225,190,139,181,128,223,234,97,84,11,62,119,66,29,40,163,150,201,252,194,247,168,157,22,35,124,73,238,219,132,177,58,15,80,101,91,110,49,4,143,186,229,208,153,172,243,198,77,120,39,18,44,25,70,115,248,205,146,167,193,244,171,158,21,32,127,74,116,65,30,43,160,149,202,255,182,131,220,233,98,87,8,61,3,54,105,92,215,226,189,136,47,26,69,112,251,206,145,164,154,175,240,197,78,123,36,17,88,109,50,7,140,185,230,211,237,216,135,178,57,12,83,102,159,170,245,192,75,126,33,20,42,31,64,117,254,203,148,161,232,221,130,183,60,9,86,99,93,104,55,2,137,188,227,214,113,68,27,46,165,144,207,250,196,241,174,155,16,37,122,79,6,51,108,89,210,231,184,141,179,134,217,236,103,82,13,56,94,107,52,1,138,191,224,213,235,222,129,180,63,10,85,96,41,28,67,118,253,200,151,162,156,169,246,195,72,125,34,23,176,133,218,239,100,81,14,59,5,48,111,90,209,228,187,142,199,242,173,152,19,38,121,76,114,71,24,45,166,147,204,249},
{0,54,108,90,216,238,180,130,173,155,193,247,117,67,25,47,71,113,43,29,159,169,243,197,234,220,134,176,50,4,94,104,142,184,226,212,86,96,58,12,35,21,79,121,251,205,151,161,201,255,165,147,17,39,125,75,100,82,8,62,188,138,208,230,1,55,109,91,217,239,181,131,172,154,192,246,116,66,24,46,70,112,42,28,158,168,242,196,235,221,135,177,51,5,95,105,143,185,227,213,87,97,59,13,34,20,78,120,250,204,150,160,200,254,164,146,16,38,124,74,101,83,9,63,189,139,209,231,2,52,110,88,218,236,182,128,175,153,195,245,119,65,27,45,69,115,41,31,157,171,241,199,232,222,132,178,48,6,92,106,140,186,224,214,84,98,56,14,33,23,77,123,249,207,149,163,203,253,167,145,19,37,127,73,102,80,10,60,190,136,210,228,3,53,111,89,219,237,183,129,174,152,194,244,118,64,26,44,68,114,40,30,156,170,240,198,233,223,133,179,49,7,93,107,141,187,225,215,85,99,57,15,32,22,76,122,248,206,148,162,202,252,166,144,18,36,126,72,103,81,11,61,191,137,211,229},
{0,55,110,89,220,235,178,133,165,146,203,252,121,78,23,32,87,96,57,14,139,188,229,210,242,197,156,171,46,25,64,119,174,153,192,247,114,69,28,43,11,60,101,82,215,224,185,142,249,206,151,160,37,18,75,124,92,107,50,5,128,183,238,217,65,118,47,24,157,170,243,196,228,211,138,189,56,15,86,97,22,33,120,79,202,253,164,147,179,132,221,234,111,88,1,54,239,216,129,182,51,4,93,106,74,125,36,19,150,161,248,207,184,143,214,225,100,83,10,61,29,42,115,68,193,246,175,152,130,181,236,219,94,105,48,7,39,16,73,126,251,204,149,162,213,226,187,140,9,62,103,80,112,71,30,41,172,155,194,245,44,27,66,117,240,199,158,169,137,190,231,208,85,98,59,12,123,76,21,34,167,144,201,254,222,233,176,135,2,53,108,91,195,244,173,154,31,40,113,70,102,81,8,63,186,141,212,227,148,163,250,205,72,127,38,17,49,6,95,104,237,218,131,180,109,90,3,52,177,134,223,232,200,255,166,145,20,35,122,77,58,13,84,99,230,209,136,191,159,168,241,198,67,116,45,26},
{0,56,112,72,224,216,144,168,221,229,173,149,61,5,77,117,167,159,215,239,71,127,55,15,122,66,10,50,154,162,234,210,83,107,35,27,179,139,195,251,142,182,254,198,110,86,30,38,244,204,132,188,20,44,100,92,41,17,89,97,201,241,185,129,166,158,214,238,70,126,54,14,123,67,11,51,155,163,235,211,1,57,113,73,225,217,145,169,220,228,172,148,60,4,76,116,245,205,133,189,21,45,101,93,40,16,88,96,200,240,184,128,82,106,34,26,178,138,194,250,143,183,255,199,111,87,31,39,81,105,33,25,177,137,193,249,140,180,252,196,108,84,28,36,246,206,134,190,22,46,102,94,43,19,91,99,203,243,187,131,2,58,114,74,226,218,146,170,223,231,175,151,63,7,79,119,165,157,213,237,69,125,53,13,120,64,8,48,152,160,232,208,247,207,135,191,23,47,103,95,42,18,90,98,202,242,186,130,80,104,32,24,176,136,192,248,141,181,253,197,109,85,29,37,164,156,212,236,68,124,52,12,121,65,9,49,153,161,233,209,3,59,115,75,227,219,147,171,222,230,174,150,62,6,78,118},
{0,57,114,75,228,221,150,175,213,236,167,158,49,8,67,122,183,142,197,252,83,106,33,24,98,91,16,41,134,191,244,205,115,74,1,56,151,174,229,220,166,159,212,237,66,123,48,9,196,253,182,143,32,25,82,107,17,40,99,90,245,204,135,190,230,223,148,173,2,59,112,73,51,10,65,120,215,238,165,156,81,104,35,26,181,140,199,254,132,189,246,207,96,89,18,43,149,172,231,222,113,72,3,58,64,121,50,11,164,157,214,239,34,27,80,105,198,255,180,141,247,206,133,188,19,42,97,88,209,232,163,154,53,12,71,126,4,61,118,79,224,217,146,171,102,95,20,45,130,187,240,201,179,138,193,248,87,110,37,28,162,155,208,233,70,127,52,13,119,78,5,60,147,170,225,216,21,44,103,94,241,200,131,186,192,249,178,139,36,29,86,111,55,14,69,124,211,234,161,152,226,219,144,169,6,63,116,77,128,185,242,203,100,93,22,47,85,108,39,30,177,136,195,250,68,125,54,15,160,153,210,235,145,168,227,218,117,76,7,62,243,202,129,184,23,46,101,92,38,31,84,109,194,251,176,137},
{0,58,116,78,232,210,156,166,205,247,185,131,37,31,81,107,135,189,243,201,111,85,27,33,74,112,62,4,162,152,214,236,19,41,103,93,251,193,143,181,222,228,170,144,54,12,66,120,148,174,224,218,124,70,8,50,89,99,45,23,177,139,197,255,38,28,82,104,206,244,186,128,235,209,159,165,3,57,119,77,161,155,213,239,73,115,61,7,108,86,24,34,132,190,240,202,53,15,65,123,221,231,169,147,248,194,140,182,16,42,100,94,178,136,198,252,90,96,46,20,127,69,11,49,151,173,227,217,76,118,56,2,164,158,208,234,129,187,245,207,105,83,29,39,203,241,191,133,35,25,87,109,6,60,114,72,238,212,154,160,95,101,43,17,183,141,195,249,146,168,230,220,122,64,14,52,216,226,172,150,48,10,68,126,21,47,97,91,253,199,137,179,106,80,30,36,130,184,246,204,167,157,211,233,79,117,59,1,237,215,153,163,5,63,113,75,32,26,84,110,200,242,188,134,121,67,13,55,145,171,229,223,180,142,192,250,92,102,40,18,254,196,138,176,22,44,98,88,51,9,71,125,219,225,175,149},
{0,59,118,77,236,215,154,161,197,254,179,136,41,18,95,100,151,172,225,218,123,64,13,54,82,105,36,31,190,133,200,243,51,8,69,126,223,228,169,146,246,205,128,187,26,33,108,87,164,159,210,233,72,115,62,5,97,90,23,44,141,182,251,192,102,93,16,43,138,177,252,199,163,152,213,238,79,116,57,2,241,202,135,188,29,38,107,80,52,15,66,121,216,227,174,149,85,110,35,24,185,130,207,244,144,171,230,221,124,71,10,49,194,249,180,143,46,21,88,99,7,60,113,74,235,208,157,166,204,247,186,129,32,27,86,109,9,50,127,68,229,222,147,168,91,96,45,22,183,140,193,250,158,165,232,211,114,73,4,63,255,196,137,178,19,40,101,94,58,1,76,119,214,237,160,155,104,83,30,37,132,191,242,201,173,150,219,224,65,122,55,12,170,145,220,231,70,125,48,11,111,84,25,34,131,184,245,206,61,6,75,112,209,234,167,156,248,195,142,181,20,47,98,89,153,162,239,212,117,78,3,56,92,103,42,17,176,139,198,253,14,53,120,67,226,217,148,175,203,240,189,134,39,28,81,106},
{0,60,120,68,240,204,136,180,253,193,133,185,13,49,117,73,231,219,159,163,23,43,111,83,26,38,98,94,234,214,146,174,211,239,171,151,35,31,91,103,46,18,86,106,222,226,166,154,52,8,76,112,196,248,188,128,201,245,177,141,57,5,65,125,187,135,195,255,75,119,51,15,70,122,62,2,182,138,206,242,92,96,36,24,172,144,212,232,161,157,217,229,81,109,41,21,104,84,16,44,152,164,224,220,149,169,237,209,101,89,29,33,143,179,247,203,127,67,7,59,114,78,10,54,130,190,250,198,107,87,19,47,155,167,227,223,150,170,238,210,102,90,30,34,140,176,244,200,124,64,4,56,113,77,9,53,129,189,249,197,184,132,192,252,72,116,48,12,69,121,61,1,181,137,205,241,95,99,39,27,175,147,215,235,162,158,218,230,82,110,42,22,208,236,168,148,32,28,88,100,45,17,85,105,221,225,165,153,55,11,79,115,199,251,191,131,202,246,178,142,58,6,66,126,3,63,123,71,243,207,139,183,254,194,134,186,14,50,118,74,228,216,156,160,20,40,108,80,25,37,97,93,233,213,145,173},
{0,61,122,71,244,201,142,179,245,200,143,178,1,60,123,70,247,202,141,176,3,62,121,68,2,63,120,69,246,203,140,177,243,206,137,180,7,58,125,64,6,59,124,65,242,207,136,181,4,57,126,67,240,205,138,183,241,204,139,182,5,56,127,66,251,198,129,188,15,50,117,72,14,51,116,73,250,199,128,189,12,49,118,75,248,197,130,191,249,196,131,190,13,48,119,74,8,53,114,79,252,193,134,187,253,192,135,186,9,52,115,78,255,194,133,184,11,54,113,76,10,55,112,77,254,195,132,185,235,214,145,172,31,34,101,88,30,35,100,89,234,215,144,173,28,33,102,91,232,213,146,175,233,212,147,174,29,32,103,90,24,37,98,95,236,209,150,171,237,208,151,170,25,36,99,94,239,210,149,168,27,38,97,92,26,39,96,93,238,211,148,169,16,45,106,87,228,217,158,163,229,216,159,162,17,44,107,86,231,218,157,160,19,46,105,84,18,47,104,85,230,219,156,161,227,222,153,164,23,42,109,80,22,43,108,81,226,223,152,165,20,41,110,83,224,221,154,167,225,220,155,166,21,40,111,82},
{0,62,124,66,248,198,132,186,237,211,145,175,21,43,105,87,199,249,187,133,63,1,67,125,42,20,86,104,210,236,174,144,147,173,239,209,107,85,23,41,126,64,2,60,134,184,250,196,84,106,40,22,172,146,208,238,185,135,197,251,65,127,61,3,59,5,71,121,195,253,191,129,214,232,170,148,46,16,82,108,252,194,128,190,4,58,120,70,17,47,109,83,233,215,149,171,168,150,212,234,80,110,44,18,69,123,57,7,189,131,193,255,111,81,19,45,151,169,235,213,130,188,254,192,122,68,6,56,118,72,10,52,142,176,242,204,155,165,231,217,99,93,31,33,177,143,205,243,73,119,53,11,92,98,32,30,164,154,216,230,229,219,153,167,29,35,97,95,8,54,116,74,240,206,140,178,34,28,94,96,218,228,166,152,207,241,179,141,55,9,75,117,77,115,49,15,181,139,201,247,160,158,220,226,88,102,36,26,138,180,246,200,114,76,14,48,103,89,27,37,159,161,227,221,222,224,162,156,38,24,90,100,51,13,79,113,203,245,183,137,25,39,101,91,225,223,157,163,244,202,136,182,12,50,112,78},
{0,63,126,65,252,195,130,189,229,218,155,164,25,38,103,88,215,232,169,150,43,20,85,106,50,13,76,115,206,241,176,143,179,140,205,242,79,112,49,14,86,105,40,23,170,149,212,235,100,91,26,37,152,167,230,217,129,190,255,192,125,66,3,60,123,68,5,58,135,184,249,198,158,161,224,223,98,93,28,35,172,147,210,237,80,111,46,17,73,118,55,8,181,138,203,244,200,247,182,137,52,11,74,117,45,18,83,108,209,238,175,144,31,32,97,94,227,220,157,162,250,197,132,187,6,57,120,71,246,201,136,183,10,53,116,75,19,44,109,82,239,208,145,174,33,30,95,96,221,226,163,156,196,251,186,133,56,7,70,121,69,122,59,4,185,134,199,248,160,159,222,225,92,99,34,29,146,173,236,211,110,81,16,47,119,72,9,54,139,180,245,202,141,178,243,204,113,78,15,48,104,87,22,41,148,171,234,213,90,101,36,27,166,153,216,231,191,128,193,254,67,124,61,2,62,1,64,127,194,253,188,131,219,228,165,154,39,24,89,102,233,214,151,168,21,42,107,84,12,51,114,77,240,207,142,177},
{0,64,128,192,29,93,157,221,58,122,186,250,39,103,167,231,116,52,244,180,105,41,233,169,78,14,206,142,83,19,211,147,232,168,104,40,245,181,117,53,210,146,82,18,207,143,79,15,156,220,28,92,129,193,1,65,166,230,38,102,187,251,59,123,205,141,77,13,208,144,80,16,247,183,119,55,234,170,106,42,185,249,57,121,164,228,36,100,131,195,3,67,158,222,30,94,37,101,165,229,56,120,184,248,31,95,159,223,2,66,130,194,81,17,209,145,76,12,204,140,107,43,235,171,118,54,246,182,135,199,7,71,154,218,26,90,189,253,61,125,160,224,32,96,243,179,115,51,238,174,110,46,201,137,73,9,212,148,84,20,111,47,239,175,114,50,242,178,85,21,213,149,72,8,200,136,27,91,155,219,6,70,134,198,33,97,161,225,60,124,188,252,74,10,202,138,87,23,215,151,112,48,240,176,109,45,237,173,62,126,190,254,35,99,163,227,4,68,132,196,25,89,153,217,162,226,34,98,191,255,63,127,152,216,24,88,133,197,5,69,214,150,86,22,203,139,75,11,236,172,108,44,241,177,113,49},
{0,65,130,195,25,88,155,218,50,115,176,241,43,106,169,232,100,37,230,167,125,60,255,190,86,23,212,149,79,14,205,140,200,137,74,11,209,144,83,18,250,187,120,57,227,162,97,32,172,237,46,111,181,244,55,118,158,223,28,93,135,198,5,68,141,204,15,78,148,213,22,87,191,254,61,124,166,231,36,101,233,168,107,42,240,177,114,51,219,154,89,24,194,131,64,1,69,4,199,134,92,29,222,159,119,54,245,180,110,47,236,173,33,96,163,226,56,121,186,251,19,82,145,208,10,75,136,201,7,70,133,196,30,95,156,221,53,116,183,246,44,109,174,239,99,34,225,160,122,59,248,185,81,16,211,146,72,9,202,139,207,142,77,12,214,151,84,21,253,188,127,62,228,165,102,39,171,234,41,104,178,243,48,113,153,216,27,90,128,193,2,67,138,203,8,73,147,210,17,80,184,249,58,123,161,224,35,98,238,175,108,45,247,182,117,52,220,157,94,31,197,132,71,6,66,3,192,129,91,26,217,152,112,49,242,179,105,40,235,170,38,103,164,229,63,126,189,252,20,85,150,215,13,76,143,206},
{0,66,132,198,21,87,145,211,42,104,174,236,63,125,187,249,84,22,208,146,65,3,197,135,126,60,250,184,107,41,239,173,168,234,44,110,189,255,57,123,130,192,6,68,151,213,19,81,252,190,120,58,233,171,109,47,214,148,82,16,195,129,71,5,77,15,201,139,88,26,220,158,103,37,227,161,114,48,246,180,25,91,157,223,12,78,136,202,51,113,183,245,38,100,162,224,229,167,97,35,240,178,116,54,207,141,75,9,218,152,94,28,177,243,53,119,164,230,32,98,155,217,31,93,142,204,10,72,154,216,30,92,143,205,11,73,176,242,52,118,165,231,33,99,206,140,74,8,219,153,95,29,228,166,96,34,241,179,117,55,50,112,182,244,39,101,163,225,24,90,156,222,13,79,137,203,102,36,226,160,115,49,247,181,76,14,200,138,89,27,221,159,215,149,83,17,194,128,70,4,253,191,121,59,232,170,108,46,131,193,7,69,150,212,18,80,169,235,45,111,188,254,56,122,127,61,251,185,106,40,238,172,85,23,209,147,64,2,196,134,43,105,175,237,62,124,186,248,1,67,133,199,20,86,144,210},
{0,67,134,197,17,82,151,212,34,97,164,231,51,112,181,246,68,7,194,129,85,22,211,144,102,37,224,163,119,52,241,178,136,203,14,77,153,218,31,92,170,233,44,111,187,248,61,126,204,143,74,9,221,158,91,24,238,173,104,43,255,188,121,58,13,78,139,200,28,95,154,217,47,108,169,234,62,125,184,251,73,10,207,140,88,27,222,157,107,40,237,174,122,57,252,191,133,198,3,64,148,215,18,81,167,228,33,98,182,245,48,115,193,130,71,4,208,147,86,21,227,160,101,38,242,177,116,55,26,89,156,223,11,72,141,206,56,123,190,253,41,106,175,236,94,29,216,155,79,12,201,138,124,63,250,185,109,46,235,168,146,209,20,87,131,192,5,70,176,243,54,117,161,226,39,100,214,149,80,19,199,132,65,2,244,183,114,49,229,166,99,32,23,84,145,210,6,69,128,195,53,118,179,240,36,103,162,225,83,16,213,150,66,1,196,135,113,50,247,180,96,35,230,165,159,220,25,90,142,205,8,75,189,254,59,120,172,239,42,105,219,152,93,30,202,137,76,15,249,186,127,60,232,171,110,45},
{0,68,136,204,13,73,133,193,26,94,146,214,23,83,159,219,52,112,188,248,57,125,177,245,46,106,166,226,35,103,171,239,104,44,224,164,101,33,237,169,114,54,250,190,127,59,247,179,92,24,212,144,81,21,217,157,70,2,206,138,75,15,195,135,208,148,88,28,221,153,85,17,202,142,66,6,199,131,79,11,228,160,108,40,233,173,97,37,254,186,118,50,243,183,123,63,184,252,48,116,181,241,61,121,162,230,42,110,175,235,39,99,140,200,4,64,129,197,9,77,150,210,30,90,155,223,19,87,189,249,53,113,176,244,56,124,167,227,47,107,170,238,34,102,137,205,1,69,132,192,12,72,147,215,27,95,158,218,22,82,213,145,93,25,216,156,80,20,207,139,71,3,194,134,74,14,225,165,105,45,236,168,100,32,251,191,115,55,246,178,126,58,109,41,229,161,96,36,232,172,119,51,255,187,122,62,242,182,89,29,209,149,84,16,220,152,67,7,203,143,78,10,198,130,5,65,141,201,8,76,128,196,31,91,151,211,18,86,154,222,49,117,185,253,60,120,180,240,43,111,163,231,38,98,174,234},
{0,69,138,207,9,76,131,198,18,87,152,221,27,94,145,212,36,97,174,235,45,104,167,226,54,115,188,249,63,122,181,240,72,13,194,135,65,4,203,142,90,31,208,149,83,22,217,156,108,41,230,163,101,32,239,170,126,59,244,177,119,50,253,184,144,213,26,95,153,220,19,86,130,199,8,77,139,206,1,68,180,241,62,123,189,248,55,114,166,227,44,105,175,234,37,96,216,157,82,23,209,148,91,30,202,143,64,5,195,134,73,12,252,185,118,51,245,176,127,58,238,171,100,33,231,162,109,40,61,120,183,242,52,113,190,251,47,106,165,224,38,99,172,233,25,92,147,214,16,85,154,223,11,78,129,196,2,71,136,205,117,48,255,186,124,57,246,179,103,34,237,168,110,43,228,161,81,20,219,158,88,29,210,151,67,6,201,140,74,15,192,133,173,232,39,98,164,225,46,107,191,250,53,112,182,243,60,121,137,204,3,70,128,197,10,79,155,222,17,84,146,215,24,93,229,160,111,42,236,169,102,35,247,178,125,56,254,187,116,49,193,132,75,14,200,141,66,7,211,150,89,28,218,159,80,21},
{0,70,140,202,5,67,137,207,10,76,134,192,15,73,131,197,20,82,152,222,17,87,157,219,30,88,146,212,27,93,151,209,40,110,164,226,45,107,161,231,34,100,174,232,39,97,171,237,60,122,176,246,57,127,181,243,54,112,186,252,51,117,191,249,80,22,220,154,85,19,217,159,90,28,214,144,95,25,211,149,68,2,200,142,65,7,205,139,78,8,194,132,75,13,199,129,120,62,244,178,125,59,241,183,114,52,254,184,119,49,251,189,108,42,224,166,105,47,229,163,102,32,234,172,99,37,239,169,160,230,44,106,165,227,41,111,170,236,38,96,175,233,35,101,180,242,56,126,177,247,61,123,190,248,50,116,187,253,55,113,136,206,4,66,141,203,1,71,130,196,14,72,135,193,11,77,156,218,16,86,153,223,21,83,150,208,26,92,147,213,31,89,240,182,124,58,245,179,121,63,250,188,118,48,255,185,115,53,228,162,104,46,225,167,109,43,238,168,98,36,235,173,103,33,216,158,84,18,221,155,81,23,210,148,94,24,215,145,91,29,204,138,64,6,201,143,69,3,198,128,74,12,195,133,79,9},
{0,71,142,201,1,70,143,200,2,69,140,203,3,68,141,202,4,67,138,205,5,66,139,204,6,65,136,207,7,64,137,206,8,79,134,193,9,78,135,192,10,77,132,195,11,76,133,194,12,75,130,197,13,74,131,196,14,73,128,199,15,72,129,198,16,87,158,217,17,86,159,216,18,85,156,219,19,84,157,218,20,83,154,221,21,82,155,220,22,81,152,223,23,80,153,222,24,95,150,209,25,94,151,208,26,93,148,211,27,92,149,210,28,91,146,213,29,90,147,212,30,89,144,215,31,88,145,214,32,103,174,233,33,102,175,232,34,101,172,235,35,100,173,234,36,99,170,237,37,98,171,236,38,97,168,239,39,96,169,238,40,111,166,225,41,110,167,224,42,109,164,227,43,108,165,226,44,107,162,229,45,106,163,228,46,105,160,231,47,104,161,230,48,119,190,249,49,118,191,248,50,117,188,251,51,116,189,250,52,115,186,253,53,114,187,252,54,113,184,255,55,112,185,254,56,127,182,241,57,126,183,240,58,125,180,243,59,124,181,242,60,123,178,245,61,122,179,244,62,121,176,247,63,120,177,246},
{0,72,144,216,61,117,173,229,122,50,234,162,71,15,215,159,244,188,100,44,201,129,89,17,142,198,30,86,179,251,35,107,245,189,101,45,200,128,88,16,143,199,31,87,178,250,34,106,1,73,145,217,60,116,172,228,123,51,235,163,70,14,214,158,247,191,103,47,202,130,90,18,141,197,29,85,176,248,32,104,3,75,147,219,62,118,174,230,121,49,233,161,68,12,212,156,2,74,146,218,63,119,175,231,120,48,232,160,69,13,213,157,246,190,102,46,203,131,91,19,140,196,28,84,177,249,33,105,243,187,99,43,206,134,94,22,137,193,25,81,180,252,36,108,7,79,151,223,58,114,170,226,125,53,237,165,64,8,208,152,6,78,150,222,59,115,171,227,124,52,236,164,65,9,209,153,242,186,98,42,207,135,95,23,136,192,24,80,181,253,37,109,4,76,148,220,57,113,169,225,126,54,238,166,67,11,211,155,240,184,96,40,205,133,93,21,138,194,26,82,183,255,39,111,241,185,97,41,204,132,92,20,139,195,27,83,182,254,38,110,5,77,149,221,56,112,168,224,127,55,239,167,66,10,210,154},
{0,73,146,219,57,112,171,226,114,59,224,169,75,2,217,144,228,173,118,63,221,148,79,6,150,223,4,77,175,230,61,116,213,156,71,14,236,165,126,55,167,238,53,124,158,215,12,69,49,120,163,234,8,65,154,211,67,10,209,152,122,51,232,161,183,254,37,108,142,199,28,85,197,140,87,30,252,181,110,39,83,26,193,136,106,35,248,177,33,104,179,250,24,81,138,195,98,43,240,185,91,18,201,128,16,89,130,203,41,96,187,242,134,207,20,93,191,246,45,100,244,189,102,47,205,132,95,22,115,58,225,168,74,3,216,145,1,72,147,218,56,113,170,227,151,222,5,76,174,231,60,117,229,172,119,62,220,149,78,7,166,239,52,125,159,214,13,68,212,157,70,15,237,164,127,54,66,11,208,153,123,50,233,160,48,121,162,235,9,64,155,210,196,141,86,31,253,180,111,38,182,255,36,109,143,198,29,84,32,105,178,251,25,80,139,194,82,27,192,137,107,34,249,176,17,88,131,202,40,97,186,243,99,42,241,184,90,19,200,129,245,188,103,46,204,133,94,23,135,206,21,92,190,247,44,101},
{0,74,148,222,53,127,161,235,106,32,254,180,95,21,203,129,212,158,64,10,225,171,117,63,190,244,42,96,139,193,31,85,181,255,33,107,128,202,20,94,223,149,75,1,234,160,126,52,97,43,245,191,84,30,192,138,11,65,159,213,62,116,170,224,119,61,227,169,66,8,214,156,29,87,137,195,40,98,188,246,163,233,55,125,150,220,2,72,201,131,93,23,252,182,104,34,194,136,86,28,247,189,99,41,168,226,60,118,157,215,9,67,22,92,130,200,35,105,183,253,124,54,232,162,73,3,221,151,238,164,122,48,219,145,79,5,132,206,16,90,177,251,37,111,58,112,174,228,15,69,155,209,80,26,196,142,101,47,241,187,91,17,207,133,110,36,250,176,49,123,165,239,4,78,144,218,143,197,27,81,186,240,46,100,229,175,113,59,208,154,68,14,153,211,13,71,172,230,56,114,243,185,103,45,198,140,82,24,77,7,217,147,120,50,236,166,39,109,179,249,18,88,134,204,44,102,184,242,25,83,141,199,70,12,210,152,115,57,231,173,248,178,108,38,205,135,89,19,146,216,6,76,167,237,51,121},
{0,75,150,221,49,122,167,236,98,41,244,191,83,24,197,142,196,143,82,25,245,190,99,40,166,237,48,123,151,220,1,74,149,222,3,72,164,239,50,121,247,188,97,42,198,141,80,27,81,26,199,140,96,43,246,189,51,120,165,238,2,73,148,223,55,124,161,234,6,77,144,219,85,30,195,136,100,47,242,185,243,184,101,46,194,137,84,31,145,218,7,76,160,235,54,125,162,233,52,127,147,216,5,78,192,139,86,29,241,186,103,44,102,45,240,187,87,28,193,138,4,79,146,217,53,126,163,232,110,37,248,179,95,20,201,130,12,71,154,209,61,118,171,224,170,225,60,119,155,208,13,70,200,131,94,21,249,178,111,36,251,176,109,38,202,129,92,23,153,210,15,68,168,227,62,117,63,116,169,226,14,69,152,211,93,22,203,128,108,39,250,177,89,18,207,132,104,35,254,181,59,112,173,230,10,65,156,215,157,214,11,64,172,231,58,113,255,180,105,34,206,133,88,19,204,135,90,17,253,182,107,32,174,229,56,115,159,212,9,66,8,67,158,213,57,114,175,228,106,33,252,183,91,16,205,134},
{0,76,152,212,45,97,181,249,90,22,194,142,119,59,239,163,180,248,44,96,153,213,1,77,238,162,118,58,195,143,91,23,117,57,237,161,88,20,192,140,47,99,183,251,2,78,154,214,193,141,89,21,236,160,116,56,155,215,3,79,182,250,46,98,234,166,114,62,199,139,95,19,176,252,40,100,157,209,5,73,94,18,198,138,115,63,235,167,4,72,156,208,41,101,177,253,159,211,7,75,178,254,42,102,197,137,93,17,232,164,112,60,43,103,179,255,6,74,158,210,113,61,233,165,92,16,196,136,201,133,81,29,228,168,124,48,147,223,11,71,190,242,38,106,125,49,229,169,80,28,200,132,39,107,191,243,10,70,146,222,188,240,36,104,145,221,9,69,230,170,126,50,203,135,83,31,8,68,144,220,37,105,189,241,82,30,202,134,127,51,231,171,35,111,187,247,14,66,150,218,121,53,225,173,84,24,204,128,151,219,15,67,186,246,34,110,205,129,85,25,224,172,120,52,86,26,206,130,123,55,227,175,12,64,148,216,33,109,185,245,226,174,122,54,207,131,87,27,184,244,32,108,149,217,13,65},
{0,77,154,215,41,100,179,254,82,31,200,133,123,54,225,172,164,233,62,115,141,192,23,90,246,187,108,33,223,146,69,8,85,24,207,130,124,49,230,171,7,74,157,208,46,99,180,249,241,188,107,38,216,149,66,15,163,238,57,116,138,199,16,93,170,231,48,125,131,206,25,84,248,181,98,47,209,156,75,6,14,67,148,217,39,106,189,240,92,17,198,139,117,56,239,162,255,178,101,40,214,155,76,1,173,224,55,122,132,201,30,83,91,22,193,140,114,63,232,165,9,68,147,222,32,109,186,247,73,4,211,158,96,45,250,183,27,86,129,204,50,127,168,229,237,160,119,58,196,137,94,19,191,242,37,104,150,219,12,65,28,81,134,203,53,120,175,226,78,3,212,153,103,42,253,176,184,245,34,111,145,220,11,70,234,167,112,61,195,142,89,20,227,174,121,52,202,135,80,29,177,252,43,102,152,213,2,79,71,10,221,144,110,35,244,185,21,88,143,194,60,113,166,235,182,251,44,97,159,210,5,72,228,169,126,51,205,128,87,26,18,95,136,197,59,118,161,236,64,13,218,151,105,36,243,190},
{0,78,156,210,37,107,185,247,74,4,214,152,111,33,243,189,148,218,8,70,177,255,45,99,222,144,66,12,251,181,103,41,53,123,169,231,16,94,140,194,127,49,227,173,90,20,198,136,161,239,61,115,132,202,24,86,235,165,119,57,206,128,82,28,106,36,246,184,79,1,211,157,32,110,188,242,5,75,153,215,254,176,98,44,219,149,71,9,180,250,40,102,145,223,13,67,95,17,195,141,122,52,230,168,21,91,137,199,48,126,172,226,203,133,87,25,238,160,114,60,129,207,29,83,164,234,56,118,212,154,72,6,241,191,109,35,158,208,2,76,187,245,39,105,64,14,220,146,101,43,249,183,10,68,150,216,47,97,179,253,225,175,125,51,196,138,88,22,171,229,55,121,142,192,18,92,117,59,233,167,80,30,204,130,63,113,163,237,26,84,134,200,190,240,34,108,155,213,7,73,244,186,104,38,209,159,77,3,42,100,182,248,15,65,147,221,96,46,252,178,69,11,217,151,139,197,23,89,174,224,50,124,193,143,93,19,228,170,120,54,31,81,131,205,58,116,166,232,85,27,201,135,112,62,236,162},
{0,79,158,209,33,110,191,240,66,13,220,147,99,44,253,178,132,203,26,85,165,234,59,116,198,137,88,23,231,168,121,54,21,90,139,196,52,123,170,229,87,24,201,134,118,57,232,167,145,222,15,64,176,255,46,97,211,156,77,2,242,189,108,35,42,101,180,251,11,68,149,218,104,39,246,185,73,6,215,152,174,225,48,127,143,192,17,94,236,163,114,61,205,130,83,28,63,112,161,238,30,81,128,207,125,50,227,172,92,19,194,141,187,244,37,106,154,213,4,75,249,182,103,40,216,151,70,9,84,27,202,133,117,58,235,164,22,89,136,199,55,120,169,230,208,159,78,1,241,190,111,32,146,221,12,67,179,252,45,98,65,14,223,144,96,47,254,177,3,76,157,210,34,109,188,243,197,138,91,20,228,171,122,53,135,200,25,86,166,233,56,119,126,49,224,175,95,16,193,142,60,115,162,237,29,82,131,204,250,181,100,43,219,148,69,10,184,247,38,105,153,214,7,72,107,36,245,186,74,5,212,155,41,102,183,248,8,71,150,217,239,160,113,62,206,129,80,31,173,226,51,124,140,195,18,93},
{0,80,160,240,93,13,253,173,186,234,26,74,231,183,71,23,105,57,201,153,52,100,148,196,211,131,115,35,142,222,46,126,210,130,114,34,143,223,47,127,104,56,200,152,53,101,149,197,187,235,27,75,230,182,70,22,1,81,161,241,92,12,252,172,185,233,25,73,228,180,68,20,3,83,163,243,94,14,254,174,208,128,112,32,141,221,45,125,106,58,202,154,55,103,151,199,107,59,203,155,54,102,150,198,209,129,113,33,140,220,44,124,2,82,162,242,95,15,255,175,184,232,24,72,229,181,69,21,111,63,207,159,50,98,146,194,213,133,117,37,136,216,40,120,6,86,166,246,91,11,251,171,188,236,28,76,225,177,65,17,189,237,29,77,224,176,64,16,7,87,167,247,90,10,250,170,212,132,116,36,137,217,41,121,110,62,206,158,51,99,147,195,214,134,118,38,139,219,43,123,108,60,204,156,49,97,145,193,191,239,31,79,226,178,66,18,5,85,165,245,88,8,248,168,4,84,164,244,89,9,249,169,190,238,30,78,227,179,67,19,109,61,205,157,48,96,144,192,215,135,119,39,138,218,42,122},
{0,81,162,243,89,8,251,170,178,227,16,65,235,186,73,24,121,40,219,138,32,113,130,211,203,154,105,56,146,195,48,97,242,163,80,1,171,250,9,88,64,17,226,179,25,72,187,234,139,218,41,120,210,131,112,33,57,104,155,202,96,49,194,147,249,168,91,10,160,241,2,83,75,26,233,184,18,67,176,225,128,209,34,115,217,136,123,42,50,99,144,193,107,58,201,152,11,90,169,248,82,3,240,161,185,232,27,74,224,177,66,19,114,35,208,129,43,122,137,216,192,145,98,51,153,200,59,106,239,190,77,28,182,231,20,69,93,12,255,174,4,85,166,247,150,199,52,101,207,158,109,60,36,117,134,215,125,44,223,142,29,76,191,238,68,21,230,183,175,254,13,92,246,167,84,5,100,53,198,151,61,108,159,206,214,135,116,37,143,222,45,124,22,71,180,229,79,30,237,188,164,245,6,87,253,172,95,14,111,62,205,156,54,103,148,197,221,140,127,46,132,213,38,119,228,181,70,23,189,236,31,78,86,7,244,165,15,94,173,252,157,204,63,110,196,149,102,55,47,126,141,220,118,39,212,133},
{0,82,164,246,85,7,241,163,170,248,14,92,255,173,91,9,73,27,237,191,28,78,184,234,227,177,71,21,182,228,18,64,146,192,54,100,199,149,99,49,56,106,156,206,109,63,201,155,219,137,127,45,142,220,42,120,113,35,213,135,36,118,128,210,57,107,157,207,108,62,200,154,147,193,55,101,198,148,98,48,112,34,212,134,37,119,129,211,218,136,126,44,143,221,43,121,171,249,15,93,254,172,90,8,1,83,165,247,84,6,240,162,226,176,70,20,183,229,19,65,72,26,236,190,29,79,185,235,114,32,214,132,39,117,131,209,216,138,124,46,141,223,41,123,59,105,159,205,110,60,202,152,145,195,53,103,196,150,96,50,224,178,68,22,181,231,17,67,74,24,238,188,31,77,187,233,169,251,13,95,252,174,88,10,3,81,167,245,86,4,242,160,75,25,239,189,30,76,186,232,225,179,69,23,180,230,16,66,2,80,166,244,87,5,243,161,168,250,12,94,253,175,89,11,217,139,125,47,140,222,40,122,115,33,215,133,38,116,130,208,144,194,52,102,197,151,97,51,58,104,158,204,111,61,203,153},
{0,83,166,245,81,2,247,164,162,241,4,87,243,160,85,6,89,10,255,172,8,91,174,253,251,168,93,14,170,249,12,95,178,225,20,71,227,176,69,22,16,67,182,229,65,18,231,180,235,184,77,30,186,233,28,79,73,26,239,188,24,75,190,237,121,42,223,140,40,123,142,221,219,136,125,46,138,217,44,127,32,115,134,213,113,34,215,132,130,209,36,119,211,128,117,38,203,152,109,62,154,201,60,111,105,58,207,156,56,107,158,205,146,193,52,103,195,144,101,54,48,99,150,197,97,50,199,148,242,161,84,7,163,240,5,86,80,3,246,165,1,82,167,244,171,248,13,94,250,169,92,15,9,90,175,252,88,11,254,173,64,19,230,181,17,66,183,228,226,177,68,23,179,224,21,70,25,74,191,236,72,27,238,189,187,232,29,78,234,185,76,31,139,216,45,126,218,137,124,47,41,122,143,220,120,43,222,141,210,129,116,39,131,208,37,118,112,35,214,133,33,114,135,212,57,106,159,204,104,59,206,157,155,200,61,110,202,153,108,63,96,51,198,149,49,98,151,196,194,145,100,55,147,192,53,102},
{0,84,168,252,77,25,229,177,154,206,50,102,215,131,127,43,41,125,129,213,100,48,204,152,179,231,27,79,254,170,86,2,82,6,250,174,31,75,183,227,200,156,96,52,133,209,45,121,123,47,211,135,54,98,158,202,225,181,73,29,172,248,4,80,164,240,12,88,233,189,65,21,62,106,150,194,115,39,219,143,141,217,37,113,192,148,104,60,23,67,191,235,90,14,242,166,246,162,94,10,187,239,19,71,108,56,196,144,33,117,137,221,223,139,119,35,146,198,58,110,69,17,237,185,8,92,160,244,85,1,253,169,24,76,176,228,207,155,103,51,130,214,42,126,124,40,212,128,49,101,153,205,230,178,78,26,171,255,3,87,7,83,175,251,74,30,226,182,157,201,53,97,208,132,120,44,46,122,134,210,99,55,203,159,180,224,28,72,249,173,81,5,241,165,89,13,188,232,20,64,107,63,195,151,38,114,142,218,216,140,112,36,149,193,61,105,66,22,234,190,15,91,167,243,163,247,11,95,238,186,70,18,57,109,145,197,116,32,220,136,138,222,34,118,199,147,111,59,16,68,184,236,93,9,245,161},
{0,85,170,255,73,28,227,182,146,199,56,109,219,142,113,36,57,108,147,198,112,37,218,143,171,254,1,84,226,183,72,29,114,39,216,141,59,110,145,196,224,181,74,31,169,252,3,86,75,30,225,180,2,87,168,253,217,140,115,38,144,197,58,111,228,177,78,27,173,248,7,82,118,35,220,137,63,106,149,192,221,136,119,34,148,193,62,107,79,26,229,176,6,83,172,249,150,195,60,105,223,138,117,32,4,81,174,251,77,24,231,178,175,250,5,80,230,179,76,25,61,104,151,194,116,33,222,139,213,128,127,42,156,201,54,99,71,18,237,184,14,91,164,241,236,185,70,19,165,240,15,90,126,43,212,129,55,98,157,200,167,242,13,88,238,187,68,17,53,96,159,202,124,41,214,131,158,203,52,97,215,130,125,40,12,89,166,243,69,16,239,186,49,100,155,206,120,45,210,135,163,246,9,92,234,191,64,21,8,93,162,247,65,20,235,190,154,207,48,101,211,134,121,44,67,22,233,188,10,95,160,245,209,132,123,46,152,205,50,103,122,47,208,133,51,102,153,204,232,189,66,23,161,244,11,94},
{0,86,172,250,69,19,233,191,138,220,38,112,207,153,99,53,9,95,165,243,76,26,224,182,131,213,47,121,198,144,106,60,18,68,190,232,87,1,251,173,152,206,52,98,221,139,113,39,27,77,183,225,94,8,242,164,145,199,61,107,212,130,120,46,36,114,136,222,97,55,205,155,174,248,2,84,235,189,71,17,45,123,129,215,104,62,196,146,167,241,11,93,226,180,78,24,54,96,154,204,115,37,223,137,188,234,16,70,249,175,85,3,63,105,147,197,122,44,214,128,181,227,25,79,240,166,92,10,72,30,228,178,13,91,161,247,194,148,110,56,135,209,43,125,65,23,237,187,4,82,168,254,203,157,103,49,142,216,34,116,90,12,246,160,31,73,179,229,208,134,124,42,149,195,57,111,83,5,255,169,22,64,186,236,217,143,117,35,156,202,48,102,108,58,192,150,41,127,133,211,230,176,74,28,163,245,15,89,101,51,201,159,32,118,140,218,239,185,67,21,170,252,6,80,126,40,210,132,59,109,151,193,244,162,88,14,177,231,29,75,119,33,219,141,50,100,158,200,253,171,81,7,184,238,20,66},
{0,87,174,249,65,22,239,184,130,213,44,123,195,148,109,58,25,78,183,224,88,15,246,161,155,204,53,98,218,141,116,35,50,101,156,203,115,36,221,138,176,231,30,73,241,166,95,8,43,124,133,210,106,61,196,147,169,254,7,80,232,191,70,17,100,51,202,157,37,114,139,220,230,177,72,31,167,240,9,94,125,42,211,132,60,107,146,197,255,168,81,6,190,233,16,71,86,1,248,175,23,64,185,238,212,131,122,45,149,194,59,108,79,24,225,182,14,89,160,247,205,154,99,52,140,219,34,117,200,159,102,49,137,222,39,112,74,29,228,179,11,92,165,242,209,134,127,40,144,199,62,105,83,4,253,170,18,69,188,235,250,173,84,3,187,236,21,66,120,47,214,129,57,110,151,192,227,180,77,26,162,245,12,91,97,54,207,152,32,119,142,217,172,251,2,85,237,186,67,20,46,121,128,215,111,56,193,150,181,226,27,76,244,163,90,13,55,96,153,206,118,33,216,143,158,201,48,103,223,136,113,38,28,75,178,229,93,10,243,164,135,208,41,126,198,145,104,63,5,82,171,252,68,19,234,189},
{0,88,176,232,125,37,205,149,250,162,74,18,135,223,55,111,233,177,89,1,148,204,36,124,19,75,163,251,110,54,222,134,207,151,127,39,178,234,2,90,53,109,133,221,72,16,248,160,38,126,150,206,91,3,235,179,220,132,108,52,161,249,17,73,131,219,51,107,254,166,78,22,121,33,201,145,4,92,180,236,106,50,218,130,23,79,167,255,144,200,32,120,237,181,93,5,76,20,252,164,49,105,129,217,182,238,6,94,203,147,123,35,165,253,21,77,216,128,104,48,95,7,239,183,34,122,146,202,27,67,171,243,102,62,214,142,225,185,81,9,156,196,44,116,242,170,66,26,143,215,63,103,8,80,184,224,117,45,197,157,212,140,100,60,169,241,25,65,46,118,158,198,83,11,227,187,61,101,141,213,64,24,240,168,199,159,119,47,186,226,10,82,152,192,40,112,229,189,85,13,98,58,210,138,31,71,175,247,113,41,193,153,12,84,188,228,139,211,59,99,246,174,70,30,87,15,231,191,42,114,154,194,173,245,29,69,208,136,96,56,190,230,14,86,195,155,115,43,68,28,244,172,57,97,137,209},
{0,89,178,235,121,32,203,146,242,171,64,25,139,210,57,96,249,160,75,18,128,217,50,107,11,82,185,224,114,43,192,153,239,182,93,4,150,207,36,125,29,68,175,246,100,61,214,143,22,79,164,253,111,54,221,132,228,189,86,15,157,196,47,118,195,154,113,40,186,227,8,81,49,104,131,218,72,17,250,163,58,99,136,209,67,26,241,168,200,145,122,35,177,232,3,90,44,117,158,199,85,12,231,190,222,135,108,53,167,254,21,76,213,140,103,62,172,245,30,71,39,126,149,204,94,7,236,181,155,194,41,112,226,187,80,9,105,48,219,130,16,73,162,251,98,59,208,137,27,66,169,240,144,201,34,123,233,176,91,2,116,45,198,159,13,84,191,230,134,223,52,109,255,166,77,20,141,212,63,102,244,173,70,31,127,38,205,148,6,95,180,237,88,1,234,179,33,120,147,202,170,243,24,65,211,138,97,56,161,248,19,74,216,129,106,51,83,10,225,184,42,115,152,193,183,238,5,92,206,151,124,37,69,28,247,174,60,101,142,215,78,23,252,165,55,110,133,220,188,229,14,87,197,156,119,46},
{0,90,180,238,117,47,193,155,234,176,94,4,159,197,43,113,201,147,125,39,188,230,8,82,35,121,151,205,86,12,226,184,143,213,59,97,250,160,78,20,101,63,209,139,16,74,164,254,70,28,242,168,51,105,135,221,172,246,24,66,217,131,109,55,3,89,183,237,118,44,194,152,233,179,93,7,156,198,40,114,202,144,126,36,191,229,11,81,32,122,148,206,85,15,225,187,140,214,56,98,249,163,77,23,102,60,210,136,19,73,167,253,69,31,241,171,48,106,132,222,175,245,27,65,218,128,110,52,6,92,178,232,115,41,199,157,236,182,88,2,153,195,45,119,207,149,123,33,186,224,14,84,37,127,145,203,80,10,228,190,137,211,61,103,252,166,72,18,99,57,215,141,22,76,162,248,64,26,244,174,53,111,129,219,170,240,30,68,223,133,107,49,5,95,177,235,112,42,196,158,239,181,91,1,154,192,46,116,204,150,120,34,185,227,13,87,38,124,146,200,83,9,231,189,138,208,62,100,255,165,75,17,96,58,212,142,21,79,161,251,67,25,247,173,54,108,130,216,169,243,29,71,220,134,104,50},
{0,91,182,237,113,42,199,156,226,185,84,15,147,200,37,126,217,130,111,52,168,243,30,69,59,96,141,214,74,17,252,167,175,244,25,66,222,133,104,51,77,22,251,160,60,103,138,209,118,45,192,155,7,92,177,234,148,207,34,121,229,190,83,8,67,24,245,174,50,105,132,223,161,250,23,76,208,139,102,61,154,193,44,119,235,176,93,6,120,35,206,149,9,82,191,228,236,183,90,1,157,198,43,112,14,85,184,227,127,36,201,146,53,110,131,216,68,31,242,169,215,140,97,58,166,253,16,75,134,221,48,107,247,172,65,26,100,63,210,137,21,78,163,248,95,4,233,178,46,117,152,195,189,230,11,80,204,151,122,33,41,114,159,196,88,3,238,181,203,144,125,38,186,225,12,87,240,171,70,29,129,218,55,108,18,73,164,255,99,56,213,142,197,158,115,40,180,239,2,89,39,124,145,202,86,13,224,187,28,71,170,241,109,54,219,128,254,165,72,19,143,212,57,98,106,49,220,135,27,64,173,246,136,211,62,101,249,162,79,20,179,232,5,94,194,153,116,47,81,10,231,188,32,123,150,205},
{0,92,184,228,109,49,213,137,218,134,98,62,183,235,15,83,169,245,17,77,196,152,124,32,115,47,203,151,30,66,166,250,79,19,247,171,34,126,154,198,149,201,45,113,248,164,64,28,230,186,94,2,139,215,51,111,60,96,132,216,81,13,233,181,158,194,38,122,243,175,75,23,68,24,252,160,41,117,145,205,55,107,143,211,90,6,226,190,237,177,85,9,128,220,56,100,209,141,105,53,188,224,4,88,11,87,179,239,102,58,222,130,120,36,192,156,21,73,173,241,162,254,26,70,207,147,119,43,33,125,153,197,76,16,244,168,251,167,67,31,150,202,46,114,136,212,48,108,229,185,93,1,82,14,234,182,63,99,135,219,110,50,214,138,3,95,187,231,180,232,12,80,217,133,97,61,199,155,127,35,170,246,18,78,29,65,165,249,112,44,200,148,191,227,7,91,210,142,106,54,101,57,221,129,8,84,176,236,22,74,174,242,123,39,195,159,204,144,116,40,161,253,25,69,240,172,72,20,157,193,37,121,42,118,146,206,71,27,255,163,89,5,225,189,52,104,140,208,131,223,59,103,238,178,86,10},
{0,93,186,231,105,52,211,142,210,143,104,53,187,230,1,92,185,228,3,94,208,141,106,55,107,54,209,140,2,95,184,229,111,50,213,136,6,91,188,225,189,224,7,90,212,137,110,51,214,139,108,49,191,226,5,88,4,89,190,227,109,48,215,138,222,131,100,57,183,234,13,80,12,81,182,235,101,56,223,130,103,58,221,128,14,83,180,233,181,232,15,82,220,129,102,59,177,236,11,86,216,133,98,63,99,62,217,132,10,87,176,237,8,85,178,239,97,60,219,134,218,135,96,61,179,238,9,84,161,252,27,70,200,149,114,47,115,46,201,148,26,71,160,253,24,69,162,255,113,44,203,150,202,151,112,45,163,254,25,68,206,147,116,41,167,250,29,64,28,65,166,251,117,40,207,146,119,42,205,144,30,67,164,249,165,248,31,66,204,145,118,43,127,34,197,152,22,75,172,241,173,240,23,74,196,153,126,35,198,155,124,33,175,242,21,72,20,73,174,243,125,32,199,154,16,77,170,247,121,36,195,158,194,159,120,37,171,246,17,76,169,244,19,78,192,157,122,39,123,38,193,156,18,79,168,245},
{0,94,188,226,101,59,217,135,202,148,118,40,175,241,19,77,137,215,53,107,236,178,80,14,67,29,255,161,38,120,154,196,15,81,179,237,106,52,214,136,197,155,121,39,160,254,28,66,134,216,58,100,227,189,95,1,76,18,240,174,41,119,149,203,30,64,162,252,123,37,199,153,212,138,104,54,177,239,13,83,151,201,43,117,242,172,78,16,93,3,225,191,56,102,132,218,17,79,173,243,116,42,200,150,219,133,103,57,190,224,2,92,152,198,36,122,253,163,65,31,82,12,238,176,55,105,139,213,60,98,128,222,89,7,229,187,246,168,74,20,147,205,47,113,181,235,9,87,208,142,108,50,127,33,195,157,26,68,166,248,51,109,143,209,86,8,234,180,249,167,69,27,156,194,32,126,186,228,6,88,223,129,99,61,112,46,204,146,21,75,169,247,34,124,158,192,71,25,251,165,232,182,84,10,141,211,49,111,171,245,23,73,206,144,114,44,97,63,221,131,4,90,184,230,45,115,145,207,72,22,244,170,231,185,91,5,130,220,62,96,164,250,24,70,193,159,125,35,110,48,210,140,11,85,183,233},
{0,95,190,225,97,62,223,128,194,157,124,35,163,252,29,66,153,198,39,120,248,167,70,25,91,4,229,186,58,101,132,219,47,112,145,206,78,17,240,175,237,178,83,12,140,211,50,109,182,233,8,87,215,136,105,54,116,43,202,149,21,74,171,244,94,1,224,191,63,96,129,222,156,195,34,125,253,162,67,28,199,152,121,38,166,249,24,71,5,90,187,228,100,59,218,133,113,46,207,144,16,79,174,241,179,236,13,82,210,141,108,51,232,183,86,9,137,214,55,104,42,117,148,203,75,20,245,170,188,227,2,93,221,130,99,60,126,33,192,159,31,64,161,254,37,122,155,196,68,27,250,165,231,184,89,6,134,217,56,103,147,204,45,114,242,173,76,19,81,14,239,176,48,111,142,209,10,85,180,235,107,52,213,138,200,151,118,41,169,246,23,72,226,189,92,3,131,220,61,98,32,127,158,193,65,30,255,160,123,36,197,154,26,69,164,251,185,230,7,88,216,135,102,57,205,146,115,44,172,243,18,77,15,80,177,238,110,49,208,143,84,11,234,181,53,106,139,212,150,201,40,119,247,168,73,22},
{0,96,192,160,157,253,93,61,39,71,231,135,186,218,122,26,78,46,142,238,211,179,19,115,105,9,169,201,244,148,52,84,156,252,92,60,1,97,193,161,187,219,123,27,38,70,230,134,210,178,18,114,79,47,143,239,245,149,53,85,104,8,168,200,37,69,229,133,184,216,120,24,2,98,194,162,159,255,95,63,107,11,171,203,246,150,54,86,76,44,140,236,209,177,17,113,185,217,121,25,36,68,228,132,158,254,94,62,3,99,195,163,247,151,55,87,106,10,170,202,208,176,16,112,77,45,141,237,74,42,138,234,215,183,23,119,109,13,173,205,240,144,48,80,4,100,196,164,153,249,89,57,35,67,227,131,190,222,126,30,214,182,22,118,75,43,139,235,241,145,49,81,108,12,172,204,152,248,88,56,5,101,197,165,191,223,127,31,34,66,226,130,111,15,175,207,242,146,50,82,72,40,136,232,213,181,21,117,33,65,225,129,188,220,124,28,6,102,198,166,155,251,91,59,243,147,51,83,110,14,174,206,212,180,20,116,73,41,137,233,189,221,125,29,32,64,224,128,154,250,90,58,7,103,199,167},
{0,97,194,163,153,248,91,58,47,78,237,140,182,215,116,21,94,63,156,253,199,166,5,100,113,16,179,210,232,137,42,75,188,221,126,31,37,68,231,134,147,242,81,48,10,107,200,169,226,131,32,65,123,26,185,216,205,172,15,110,84,53,150,247,101,4,167,198,252,157,62,95,74,43,136,233,211,178,17,112,59,90,249,152,162,195,96,1,20,117,214,183,141,236,79,46,217,184,27,122,64,33,130,227,246,151,52,85,111,14,173,204,135,230,69,36,30,127,220,189,168,201,106,11,49,80,243,146,202,171,8,105,83,50,145,240,229,132,39,70,124,29,190,223,148,245,86,55,13,108,207,174,187,218,121,24,34,67,224,129,118,23,180,213,239,142,45,76,89,56,155,250,192,161,2,99,40,73,234,139,177,208,115,18,7,102,197,164,158,255,92,61,175,206,109,12,54,87,244,149,128,225,66,35,25,120,219,186,241,144,51,82,104,9,170,203,222,191,28,125,71,38,133,228,19,114,209,176,138,235,72,41,60,93,254,159,165,196,103,6,77,44,143,238,212,181,22,119,98,3,160,193,251,154,57,88},
{0,98,196,166,149,247,81,51,55,85,243,145,162,192,102,4,110,12,170,200,251,153,63,93,89,59,157,255,204,174,8,106,220,190,24,122,73,43,141,239,235,137,47,77,126,28,186,216,178,208,118,20,39,69,227,129,133,231,65,35,16,114,212,182,165,199,97,3,48,82,244,150,146,240,86,52,7,101,195,161,203,169,15,109,94,60,154,248,252,158,56,90,105,11,173,207,121,27,189,223,236,142,40,74,78,44,138,232,219,185,31,125,23,117,211,177,130,224,70,36,32,66,228,134,181,215,113,19,87,53,147,241,194,160,6,100,96,2,164,198,245,151,49,83,57,91,253,159,172,206,104,10,14,108,202,168,155,249,95,61,139,233,79,45,30,124,218,184,188,222,120,26,41,75,237,143,229,135,33,67,112,18,180,214,210,176,22,116,71,37,131,225,242,144,54,84,103,5,163,193,197,167,1,99,80,50,148,246,156,254,88,58,9,107,205,175,171,201,111,13,62,92,250,152,46,76,234,136,187,217,127,29,25,123,221,191,140,238,72,42,64,34,132,230,213,183,17,115,119,21,179,209,226,128,38,68},
{0,99,198,165,145,242,87,52,63,92,249,154,174,205,104,11,126,29,184,219,239,140,41,74,65,34,135,228,208,179,22,117,252,159,58,89,109,14,171,200,195,160,5,102,82,49,148,247,130,225,68,39,19,112,213,182,189,222,123,24,44,79,234,137,229,134,35,64,116,23,178,209,218,185,28,127,75,40,141,238,155,248,93,62,10,105,204,175,164,199,98,1,53,86,243,144,25,122,223,188,136,235,78,45,38,69,224,131,183,212,113,18,103,4,161,194,246,149,48,83,88,59,158,253,201,170,15,108,215,180,17,114,70,37,128,227,232,139,46,77,121,26,191,220,169,202,111,12,56,91,254,157,150,245,80,51,7,100,193,162,43,72,237,142,186,217,124,31,20,119,210,177,133,230,67,32,85,54,147,240,196,167,2,97,106,9,172,207,251,152,61,94,50,81,244,151,163,192,101,6,13,110,203,168,156,255,90,57,76,47,138,233,221,190,27,120,115,16,181,214,226,129,36,71,206,173,8,107,95,60,153,250,241,146,55,84,96,3,166,197,176,211,118,21,33,66,231,132,143,236,73,42,30,125,216,187},
{0,100,200,172,141,233,69,33,7,99,207,171,138,238,66,38,14,106,198,162,131,231,75,47,9,109,193,165,132,224,76,40,28,120,212,176,145,245,89,61,27,127,211,183,150,242,94,58,18,118,218,190,159,251,87,51,21,113,221,185,152,252,80,52,56,92,240,148,181,209,125,25,63,91,247,147,178,214,122,30,54,82,254,154,187,223,115,23,49,85,249,157,188,216,116,16,36,64,236,136,169,205,97,5,35,71,235,143,174,202,102,2,42,78,226,134,167,195,111,11,45,73,229,129,160,196,104,12,112,20,184,220,253,153,53,81,119,19,191,219,250,158,50,86,126,26,182,210,243,151,59,95,121,29,177,213,244,144,60,88,108,8,164,192,225,133,41,77,107,15,163,199,230,130,46,74,98,6,170,206,239,139,39,67,101,1,173,201,232,140,32,68,72,44,128,228,197,161,13,105,79,43,135,227,194,166,10,110,70,34,142,234,203,175,3,103,65,37,137,237,204,168,4,96,84,48,156,248,217,189,17,117,83,55,155,255,222,186,22,114,90,62,146,246,215,179,31,123,93,57,149,241,208,180,24,124},
{0,101,202,175,137,236,67,38,15,106,197,160,134,227,76,41,30,123,212,177,151,242,93,56,17,116,219,190,152,253,82,55,60,89,246,147,181,208,127,26,51,86,249,156,186,223,112,21,34,71,232,141,171,206,97,4,45,72,231,130,164,193,110,11,120,29,178,215,241,148,59,94,119,18,189,216,254,155,52,81,102,3,172,201,239,138,37,64,105,12,163,198,224,133,42,79,68,33,142,235,205,168,7,98,75,46,129,228,194,167,8,109,90,63,144,245,211,182,25,124,85,48,159,250,220,185,22,115,240,149,58,95,121,28,179,214,255,154,53,80,118,19,188,217,238,139,36,65,103,2,173,200,225,132,43,78,104,13,162,199,204,169,6,99,69,32,143,234,195,166,9,108,74,47,128,229,210,183,24,125,91,62,145,244,221,184,23,114,84,49,158,251,136,237,66,39,1,100,203,174,135,226,77,40,14,107,196,161,150,243,92,57,31,122,213,176,153,252,83,54,16,117,218,191,180,209,126,27,61,88,247,146,187,222,113,20,50,87,248,157,170,207,96,5,35,70,233,140,165,192,111,10,44,73,230,131},
{0,102,204,170,133,227,73,47,23,113,219,189,146,244,94,56,46,72,226,132,171,205,103,1,57,95,245,147,188,218,112,22,92,58,144,246,217,191,21,115,75,45,135,225,206,168,2,100,114,20,190,216,247,145,59,93,101,3,169,207,224,134,44,74,184,222,116,18,61,91,241,151,175,201,99,5,42,76,230,128,150,240,90,60,19,117,223,185,129,231,77,43,4,98,200,174,228,130,40,78,97,7,173,203,243,149,63,89,118,16,186,220,202,172,6,96,79,41,131,229,221,187,17,119,88,62,148,242,109,11,161,199,232,142,36,66,122,28,182,208,255,153,51,85,67,37,143,233,198,160,10,108,84,50,152,254,209,183,29,123,49,87,253,155,180,210,120,30,38,64,234,140,163,197,111,9,31,121,211,181,154,252,86,48,8,110,196,162,141,235,65,39,213,179,25,127,80,54,156,250,194,164,14,104,71,33,139,237,251,157,55,81,126,24,178,212,236,138,32,70,105,15,165,195,137,239,69,35,12,106,192,166,158,248,82,52,27,125,215,177,167,193,107,13,34,68,238,136,176,214,124,26,53,83,249,159},
{0,103,206,169,129,230,79,40,31,120,209,182,158,249,80,55,62,89,240,151,191,216,113,22,33,70,239,136,160,199,110,9,124,27,178,213,253,154,51,84,99,4,173,202,226,133,44,75,66,37,140,235,195,164,13,106,93,58,147,244,220,187,18,117,248,159,54,81,121,30,183,208,231,128,41,78,102,1,168,207,198,161,8,111,71,32,137,238,217,190,23,112,88,63,150,241,132,227,74,45,5,98,203,172,155,252,85,50,26,125,212,179,186,221,116,19,59,92,245,146,165,194,107,12,36,67,234,141,237,138,35,68,108,11,162,197,242,149,60,91,115,20,189,218,211,180,29,122,82,53,156,251,204,171,2,101,77,42,131,228,145,246,95,56,16,119,222,185,142,233,64,39,15,104,193,166,175,200,97,6,46,73,224,135,176,215,126,25,49,86,255,152,21,114,219,188,148,243,90,61,10,109,196,163,139,236,69,34,43,76,229,130,170,205,100,3,52,83,250,157,181,210,123,28,105,14,167,192,232,143,38,65,118,17,184,223,247,144,57,94,87,48,153,254,214,177,24,127,72,47,134,225,201,174,7,96},
{0,104,208,184,189,213,109,5,103,15,183,223,218,178,10,98,206,166,30,118,115,27,163,203,169,193,121,17,20,124,196,172,129,233,81,57,60,84,236,132,230,142,54,94,91,51,139,227,79,39,159,247,242,154,34,74,40,64,248,144,149,253,69,45,31,119,207,167,162,202,114,26,120,16,168,192,197,173,21,125,209,185,1,105,108,4,188,212,182,222,102,14,11,99,219,179,158,246,78,38,35,75,243,155,249,145,41,65,68,44,148,252,80,56,128,232,237,133,61,85,55,95,231,143,138,226,90,50,62,86,238,134,131,235,83,59,89,49,137,225,228,140,52,92,240,152,32,72,77,37,157,245,151,255,71,47,42,66,250,146,191,215,111,7,2,106,210,186,216,176,8,96,101,13,181,221,113,25,161,201,204,164,28,116,22,126,198,174,171,195,123,19,33,73,241,153,156,244,76,36,70,46,150,254,251,147,43,67,239,135,63,87,82,58,130,234,136,224,88,48,53,93,229,141,160,200,112,24,29,117,205,165,199,175,23,127,122,18,170,194,110,6,190,214,211,187,3,107,9,97,217,177,180,220,100,12},
{0,105,210,187,185,208,107,2,111,6,189,212,214,191,4,109,222,183,12,101,103,14,181,220,177,216,99,10,8,97,218,179,161,200,115,26,24,113,202,163,206,167,28,117,119,30,165,204,127,22,173,196,198,175,20,125,16,121,194,171,169,192,123,18,95,54,141,228,230,143,52,93,48,89,226,139,137,224,91,50,129,232,83,58,56,81,234,131,238,135,60,85,87,62,133,236,254,151,44,69,71,46,149,252,145,248,67,42,40,65,250,147,32,73,242,155,153,240,75,34,79,38,157,244,246,159,36,77,190,215,108,5,7,110,213,188,209,184,3,106,104,1,186,211,96,9,178,219,217,176,11,98,15,102,221,180,182,223,100,13,31,118,205,164,166,207,116,29,112,25,162,203,201,160,27,114,193,168,19,122,120,17,170,195,174,199,124,21,23,126,197,172,225,136,51,90,88,49,138,227,142,231,92,53,55,94,229,140,63,86,237,132,134,239,84,61,80,57,130,235,233,128,59,82,64,41,146,251,249,144,43,66,47,70,253,148,150,255,68,45,158,247,76,37,39,78,245,156,241,152,35,74,72,33,154,243},
{0,106,212,190,181,223,97,11,119,29,163,201,194,168,22,124,238,132,58,80,91,49,143,229,153,243,77,39,44,70,248,146,193,171,21,127,116,30,160,202,182,220,98,8,3,105,215,189,47,69,251,145,154,240,78,36,88,50,140,230,237,135,57,83,159,245,75,33,42,64,254,148,232,130,60,86,93,55,137,227,113,27,165,207,196,174,16,122,6,108,210,184,179,217,103,13,94,52,138,224,235,129,63,85,41,67,253,151,156,246,72,34,176,218,100,14,5,111,209,187,199,173,19,121,114,24,166,204,35,73,247,157,150,252,66,40,84,62,128,234,225,139,53,95,205,167,25,115,120,18,172,198,186,208,110,4,15,101,219,177,226,136,54,92,87,61,131,233,149,255,65,43,32,74,244,158,12,102,216,178,185,211,109,7,123,17,175,197,206,164,26,112,188,214,104,2,9,99,221,183,203,161,31,117,126,20,170,192,82,56,134,236,231,141,51,89,37,79,241,155,144,250,68,46,125,23,169,195,200,162,28,118,10,96,222,180,191,213,107,1,147,249,71,45,38,76,242,152,228,142,48,90,81,59,133,239},
{0,107,214,189,177,218,103,12,127,20,169,194,206,165,24,115,254,149,40,67,79,36,153,242,129,234,87,60,48,91,230,141,225,138,55,92,80,59,134,237,158,245,72,35,47,68,249,146,31,116,201,162,174,197,120,19,96,11,182,221,209,186,7,108,223,180,9,98,110,5,184,211,160,203,118,29,17,122,199,172,33,74,247,156,144,251,70,45,94,53,136,227,239,132,57,82,62,85,232,131,143,228,89,50,65,42,151,252,240,155,38,77,192,171,22,125,113,26,167,204,191,212,105,2,14,101,216,179,163,200,117,30,18,121,196,175,220,183,10,97,109,6,187,208,93,54,139,224,236,135,58,81,34,73,244,159,147,248,69,46,66,41,148,255,243,152,37,78,61,86,235,128,140,231,90,49,188,215,106,1,13,102,219,176,195,168,21,126,114,25,164,207,124,23,170,193,205,166,27,112,3,104,213,190,178,217,100,15,130,233,84,63,51,88,229,142,253,150,43,64,76,39,154,241,157,246,75,32,44,71,250,145,226,137,52,95,83,56,133,238,99,8,181,222,210,185,4,111,28,119,202,161,173,198,123,16},
{0,108,216,180,173,193,117,25,71,43,159,243,234,134,50,94,142,226,86,58,35,79,251,151,201,165,17,125,100,8,188,208,1,109,217,181,172,192,116,24,70,42,158,242,235,135,51,95,143,227,87,59,34,78,250,150,200,164,16,124,101,9,189,209,2,110,218,182,175,195,119,27,69,41,157,241,232,132,48,92,140,224,84,56,33,77,249,149,203,167,19,127,102,10,190,210,3,111,219,183,174,194,118,26,68,40,156,240,233,133,49,93,141,225,85,57,32,76,248,148,202,166,18,126,103,11,191,211,4,104,220,176,169,197,113,29,67,47,155,247,238,130,54,90,138,230,82,62,39,75,255,147,205,161,21,121,96,12,184,212,5,105,221,177,168,196,112,28,66,46,154,246,239,131,55,91,139,231,83,63,38,74,254,146,204,160,20,120,97,13,185,213,6,106,222,178,171,199,115,31,65,45,153,245,236,128,52,88,136,228,80,60,37,73,253,145,207,163,23,123,98,14,186,214,7,107,223,179,170,198,114,30,64,44,152,244,237,129,53,89,137,229,81,61,36,72,252,144,206,162,22,122,99,15,187,215},
{0,109,218,183,169,196,115,30,79,34,149,248,230,139,60,81,158,243,68,41,55,90,237,128,209,188,11,102,120,21,162,207,33,76,251,150,136,229,82,63,110,3,180,217,199,170,29,112,191,210,101,8,22,123,204,161,240,157,42,71,89,52,131,238,66,47,152,245,235,134,49,92,13,96,215,186,164,201,126,19,220,177,6,107,117,24,175,194,147,254,73,36,58,87,224,141,99,14,185,212,202,167,16,125,44,65,246,155,133,232,95,50,253,144,39,74,84,57,142,227,178,223,104,5,27,118,193,172,132,233,94,51,45,64,247,154,203,166,17,124,98,15,184,213,26,119,192,173,179,222,105,4,85,56,143,226,252,145,38,75,165,200,127,18,12,97,214,187,234,135,48,93,67,46,153,244,59,86,225,140,146,255,72,37,116,25,174,195,221,176,7,106,198,171,28,113,111,2,181,216,137,228,83,62,32,77,250,151,88,53,130,239,241,156,43,70,23,122,205,160,190,211,100,9,231,138,61,80,78,35,148,249,168,197,114,31,1,108,219,182,121,20,163,206,208,189,10,103,54,91,236,129,159,242,69,40},
{0,110,220,178,165,203,121,23,87,57,139,229,242,156,46,64,174,192,114,28,11,101,215,185,249,151,37,75,92,50,128,238,65,47,157,243,228,138,56,86,22,120,202,164,179,221,111,1,239,129,51,93,74,36,150,248,184,214,100,10,29,115,193,175,130,236,94,48,39,73,251,149,213,187,9,103,112,30,172,194,44,66,240,158,137,231,85,59,123,21,167,201,222,176,2,108,195,173,31,113,102,8,186,212,148,250,72,38,49,95,237,131,109,3,177,223,200,166,20,122,58,84,230,136,159,241,67,45,25,119,197,171,188,210,96,14,78,32,146,252,235,133,55,89,183,217,107,5,18,124,206,160,224,142,60,82,69,43,153,247,88,54,132,234,253,147,33,79,15,97,211,189,170,196,118,24,246,152,42,68,83,61,143,225,161,207,125,19,4,106,216,182,155,245,71,41,62,80,226,140,204,162,16,126,105,7,181,219,53,91,233,135,144,254,76,34,98,12,190,208,199,169,27,117,218,180,6,104,127,17,163,205,141,227,81,63,40,70,244,154,116,26,168,198,209,191,13,99,35,77,255,145,134,232,90,52},
{0,111,222,177,161,206,127,16,95,48,129,238,254,145,32,79,190,209,96,15,31,112,193,174,225,142,63,80,64,47,158,241,97,14,191,208,192,175,30,113,62,81,224,143,159,240,65,46,223,176,1,110,126,17,160,207,128,239,94,49,33,78,255,144,194,173,28,115,99,12,189,210,157,242,67,44,60,83,226,141,124,19,162,205,221,178,3,108,35,76,253,146,130,237,92,51,163,204,125,18,2,109,220,179,252,147,34,77,93,50,131,236,29,114,195,172,188,211,98,13,66,45,156,243,227,140,61,82,153,246,71,40,56,87,230,137,198,169,24,119,103,8,185,214,39,72,249,150,134,233,88,55,120,23,166,201,217,182,7,104,248,151,38,73,89,54,135,232,167,200,121,22,6,105,216,183,70,41,152,247,231,136,57,86,25,118,199,168,184,215,102,9,91,52,133,234,250,149,36,75,4,107,218,181,165,202,123,20,229,138,59,84,68,43,154,245,186,213,100,11,27,116,197,170,58,85,228,139,155,244,69,42,101,10,187,212,196,171,26,117,132,235,90,53,37,74,251,148,219,180,5,106,122,21,164,203},
{0,112,224,144,221,173,61,77,167,215,71,55,122,10,154,234,83,35,179,195,142,254,110,30,244,132,20,100,41,89,201,185,166,214,70,54,123,11,155,235,1,113,225,145,220,172,60,76,245,133,21,101,40,88,200,184,82,34,178,194,143,255,111,31,81,33,177,193,140,252,108,28,246,134,22,102,43,91,203,187,2,114,226,146,223,175,63,79,165,213,69,53,120,8,152,232,247,135,23,103,42,90,202,186,80,32,176,192,141,253,109,29,164,212,68,52,121,9,153,233,3,115,227,147,222,174,62,78,162,210,66,50,127,15,159,239,5,117,229,149,216,168,56,72,241,129,17,97,44,92,204,188,86,38,182,198,139,251,107,27,4,116,228,148,217,169,57,73,163,211,67,51,126,14,158,238,87,39,183,199,138,250,106,26,240,128,16,96,45,93,205,189,243,131,19,99,46,94,206,190,84,36,180,196,137,249,105,25,160,208,64,48,125,13,157,237,7,119,231,151,218,170,58,74,85,37,181,197,136,248,104,24,242,130,18,98,47,95,207,191,6,118,230,150,219,171,59,75,161,209,65,49,124,12,156,236},
{0,113,226,147,217,168,59,74,175,222,77,60,118,7,148,229,67,50,161,208,154,235,120,9,236,157,14,127,53,68,215,166,134,247,100,21,95,46,189,204,41,88,203,186,240,129,18,99,197,180,39,86,28,109,254,143,106,27,136,249,179,194,81,32,17,96,243,130,200,185,42,91,190,207,92,45,103,22,133,244,82,35,176,193,139,250,105,24,253,140,31,110,36,85,198,183,151,230,117,4,78,63,172,221,56,73,218,171,225,144,3,114,212,165,54,71,13,124,239,158,123,10,153,232,162,211,64,49,34,83,192,177,251,138,25,104,141,252,111,30,84,37,182,199,97,16,131,242,184,201,90,43,206,191,44,93,23,102,245,132,164,213,70,55,125,12,159,238,11,122,233,152,210,163,48,65,231,150,5,116,62,79,220,173,72,57,170,219,145,224,115,2,51,66,209,160,234,155,8,121,156,237,126,15,69,52,167,214,112,1,146,227,169,216,75,58,223,174,61,76,6,119,228,149,181,196,87,38,108,29,142,255,26,107,248,137,195,178,33,80,246,135,20,101,47,94,205,188,89,40,187,202,128,241,98,19},
{0,114,228,150,213,167,49,67,183,197,83,33,98,16,134,244,115,1,151,229,166,212,66,48,196,182,32,82,17,99,245,135,230,148,2,112,51,65,215,165,81,35,181,199,132,246,96,18,149,231,113,3,64,50,164,214,34,80,198,180,247,133,19,97,209,163,53,71,4,118,224,146,102,20,130,240,179,193,87,37,162,208,70,52,119,5,147,225,21,103,241,131,192,178,36,86,55,69,211,161,226,144,6,116,128,242,100,22,85,39,177,195,68,54,160,210,145,227,117,7,243,129,23,101,38,84,194,176,191,205,91,41,106,24,142,252,8,122,236,158,221,175,57,75,204,190,40,90,25,107,253,143,123,9,159,237,174,220,74,56,89,43,189,207,140,254,104,26,238,156,10,120,59,73,223,173,42,88,206,188,255,141,27,105,157,239,121,11,72,58,172,222,110,28,138,248,187,201,95,45,217,171,61,79,12,126,232,154,29,111,249,139,200,186,44,94,170,216,78,60,127,13,155,233,136,250,108,30,93,47,185,203,63,77,219,169,234,152,14,124,251,137,31,109,46,92,202,184,76,62,168,218,153,235,125,15},
{0,115,230,149,209,162,55,68,191,204,89,42,110,29,136,251,99,16,133,246,178,193,84,39,220,175,58,73,13,126,235,152,198,181,32,83,23,100,241,130,121,10,159,236,168,219,78,61,165,214,67,48,116,7,146,225,26,105,252,143,203,184,45,94,145,226,119,4,64,51,166,213,46,93,200,187,255,140,25,106,242,129,20,103,35,80,197,182,77,62,171,216,156,239,122,9,87,36,177,194,134,245,96,19,232,155,14,125,57,74,223,172,52,71,210,161,229,150,3,112,139,248,109,30,90,41,188,207,63,76,217,170,238,157,8,123,128,243,102,21,81,34,183,196,92,47,186,201,141,254,107,24,227,144,5,118,50,65,212,167,249,138,31,108,40,91,206,189,70,53,160,211,151,228,113,2,154,233,124,15,75,56,173,222,37,86,195,176,244,135,18,97,174,221,72,59,127,12,153,234,17,98,247,132,192,179,38,85,205,190,43,88,28,111,250,137,114,1,148,231,163,208,69,54,104,27,142,253,185,202,95,44,215,164,49,66,6,117,224,147,11,120,237,158,218,169,60,79,180,199,82,33,101,22,131,240},
{0,116,232,156,205,185,37,81,135,243,111,27,74,62,162,214,19,103,251,143,222,170,54,66,148,224,124,8,89,45,177,197,38,82,206,186,235,159,3,119,161,213,73,61,108,24,132,240,53,65,221,169,248,140,16,100,178,198,90,46,127,11,151,227,76,56,164,208,129,245,105,29,203,191,35,87,6,114,238,154,95,43,183,195,146,230,122,14,216,172,48,68,21,97,253,137,106,30,130,246,167,211,79,59,237,153,5,113,32,84,200,188,121,13,145,229,180,192,92,40,254,138,22,98,51,71,219,175,152,236,112,4,85,33,189,201,31,107,247,131,210,166,58,78,139,255,99,23,70,50,174,218,12,120,228,144,193,181,41,93,190,202,86,34,115,7,155,239,57,77,209,165,244,128,28,104,173,217,69,49,96,20,136,252,42,94,194,182,231,147,15,123,212,160,60,72,25,109,241,133,83,39,187,207,158,234,118,2,199,179,47,91,10,126,226,150,64,52,168,220,141,249,101,17,242,134,26,110,63,75,215,163,117,1,157,233,184,204,80,36,225,149,9,125,44,88,196,176,102,18,142,250,171,223,67,55},
{0,117,234,159,201,188,35,86,143,250,101,16,70,51,172,217,3,118,233,156,202,191,32,85,140,249,102,19,69,48,175,218,6,115,236,153,207,186,37,80,137,252,99,22,64,53,170,223,5,112,239,154,204,185,38,83,138,255,96,21,67,54,169,220,12,121,230,147,197,176,47,90,131,246,105,28,74,63,160,213,15,122,229,144,198,179,44,89,128,245,106,31,73,60,163,214,10,127,224,149,195,182,41,92,133,240,111,26,76,57,166,211,9,124,227,150,192,181,42,95,134,243,108,25,79,58,165,208,24,109,242,135,209,164,59,78,151,226,125,8,94,43,180,193,27,110,241,132,210,167,56,77,148,225,126,11,93,40,183,194,30,107,244,129,215,162,61,72,145,228,123,14,88,45,178,199,29,104,247,130,212,161,62,75,146,231,120,13,91,46,177,196,20,97,254,139,221,168,55,66,155,238,113,4,82,39,184,205,23,98,253,136,222,171,52,65,152,237,114,7,81,36,187,206,18,103,248,141,219,174,49,68,157,232,119,2,84,33,190,203,17,100,251,142,216,173,50,71,158,235,116,1,87,34,189,200},
{0,118,236,154,197,179,41,95,151,225,123,13,82,36,190,200,51,69,223,169,246,128,26,108,164,210,72,62,97,23,141,251,102,16,138,252,163,213,79,57,241,135,29,107,52,66,216,174,85,35,185,207,144,230,124,10,194,180,46,88,7,113,235,157,204,186,32,86,9,127,229,147,91,45,183,193,158,232,114,4,255,137,19,101,58,76,214,160,104,30,132,242,173,219,65,55,170,220,70,48,111,25,131,245,61,75,209,167,248,142,20,98,153,239,117,3,92,42,176,198,14,120,226,148,203,189,39,81,133,243,105,31,64,54,172,218,18,100,254,136,215,161,59,77,182,192,90,44,115,5,159,233,33,87,205,187,228,146,8,126,227,149,15,121,38,80,202,188,116,2,152,238,177,199,93,43,208,166,60,74,21,99,249,143,71,49,171,221,130,244,110,24,73,63,165,211,140,250,96,22,222,168,50,68,27,109,247,129,122,12,150,224,191,201,83,37,237,155,1,119,40,94,196,178,47,89,195,181,234,156,6,112,184,206,84,34,125,11,145,231,28,106,240,134,217,175,53,67,139,253,103,17,78,56,162,212},
{0,119,238,153,193,182,47,88,159,232,113,6,94,41,176,199,35,84,205,186,226,149,12,123,188,203,82,37,125,10,147,228,70,49,168,223,135,240,105,30,217,174,55,64,24,111,246,129,101,18,139,252,164,211,74,61,250,141,20,99,59,76,213,162,140,251,98,21,77,58,163,212,19,100,253,138,210,165,60,75,175,216,65,54,110,25,128,247,48,71,222,169,241,134,31,104,202,189,36,83,11,124,229,146,85,34,187,204,148,227,122,13,233,158,7,112,40,95,198,177,118,1,152,239,183,192,89,46,5,114,235,156,196,179,42,93,154,237,116,3,91,44,181,194,38,81,200,191,231,144,9,126,185,206,87,32,120,15,150,225,67,52,173,218,130,245,108,27,220,171,50,69,29,106,243,132,96,23,142,249,161,214,79,56,255,136,17,102,62,73,208,167,137,254,103,16,72,63,166,209,22,97,248,143,215,160,57,78,170,221,68,51,107,28,133,242,53,66,219,172,244,131,26,109,207,184,33,86,14,121,224,151,80,39,190,201,145,230,127,8,236,155,2,117,45,90,195,180,115,4,157,234,178,197,92,43},
{0,120,240,136,253,133,13,117,231,159,23,111,26,98,234,146,211,171,35,91,46,86,222,166,52,76,196,188,201,177,57,65,187,195,75,51,70,62,182,206,92,36,172,212,161,217,81,41,104,16,152,224,149,237,101,29,143,247,127,7,114,10,130,250,107,19,155,227,150,238,102,30,140,244,124,4,113,9,129,249,184,192,72,48,69,61,181,205,95,39,175,215,162,218,82,42,208,168,32,88,45,85,221,165,55,79,199,191,202,178,58,66,3,123,243,139,254,134,14,118,228,156,20,108,25,97,233,145,214,174,38,94,43,83,219,163,49,73,193,185,204,180,60,68,5,125,245,141,248,128,8,112,226,154,18,106,31,103,239,151,109,21,157,229,144,232,96,24,138,242,122,2,119,15,135,255,190,198,78,54,67,59,179,203,89,33,169,209,164,220,84,44,189,197,77,53,64,56,176,200,90,34,170,210,167,223,87,47,110,22,158,230,147,235,99,27,137,241,121,1,116,12,132,252,6,126,246,142,251,131,11,115,225,153,17,105,28,100,236,148,213,173,37,93,40,80,216,160,50,74,194,186,207,183,63,71},
{0,121,242,139,249,128,11,114,239,150,29,100,22,111,228,157,195,186,49,72,58,67,200,177,44,85,222,167,213,172,39,94,155,226,105,16,98,27,144,233,116,13,134,255,141,244,127,6,88,33,170,211,161,216,83,42,183,206,69,60,78,55,188,197,43,82,217,160,210,171,32,89,196,189,54,79,61,68,207,182,232,145,26,99,17,104,227,154,7,126,245,140,254,135,12,117,176,201,66,59,73,48,187,194,95,38,173,212,166,223,84,45,115,10,129,248,138,243,120,1,156,229,110,23,101,28,151,238,86,47,164,221,175,214,93,36,185,192,75,50,64,57,178,203,149,236,103,30,108,21,158,231,122,3,136,241,131,250,113,8,205,180,63,70,52,77,198,191,34,91,208,169,219,162,41,80,14,119,252,133,247,142,5,124,225,152,19,106,24,97,234,147,125,4,143,246,132,253,118,15,146,235,96,25,107,18,153,224,190,199,76,53,71,62,181,204,81,40,163,218,168,209,90,35,230,159,20,109,31,102,237,148,9,112,251,130,240,137,2,123,37,92,215,174,220,165,46,87,202,179,56,65,51,74,193,184},
{0,122,244,142,245,143,1,123,247,141,3,121,2,120,246,140,243,137,7,125,6,124,242,136,4,126,240,138,241,139,5,127,251,129,15,117,14,116,250,128,12,118,248,130,249,131,13,119,8,114,252,134,253,135,9,115,255,133,11,113,10,112,254,132,235,145,31,101,30,100,234,144,28,102,232,146,233,147,29,103,24,98,236,150,237,151,25,99,239,149,27,97,26,96,238,148,16,106,228,158,229,159,17,107,231,157,19,105,18,104,230,156,227,153,23,109,22,108,226,152,20,110,224,154,225,155,21,111,203,177,63,69,62,68,202,176,60,70,200,178,201,179,61,71,56,66,204,182,205,183,57,67,207,181,59,65,58,64,206,180,48,74,196,190,197,191,49,75,199,189,51,73,50,72,198,188,195,185,55,77,54,76,194,184,52,78,192,186,193,187,53,79,32,90,212,174,213,175,33,91,215,173,35,89,34,88,214,172,211,169,39,93,38,92,210,168,36,94,208,170,209,171,37,95,219,161,47,85,46,84,218,160,44,86,216,162,217,163,45,87,40,82,220,166,221,167,41,83,223,165,43,81,42,80,222,164},
{0,123,246,141,241,138,7,124,255,132,9,114,14,117,248,131,227,152,21,110,18,105,228,159,28,103,234,145,237,150,27,96,219,160,45,86,42,81,220,167,36,95,210,169,213,174,35,88,56,67,206,181,201,178,63,68,199,188,49,74,54,77,192,187,171,208,93,38,90,33,172,215,84,47,162,217,165,222,83,40,72,51,190,197,185,194,79,52,183,204,65,58,70,61,176,203,112,11,134,253,129,250,119,12,143,244,121,2,126,5,136,243,147,232,101,30,98,25,148,239,108,23,154,225,157,230,107,16,75,48,189,198,186,193,76,55,180,207,66,57,69,62,179,200,168,211,94,37,89,34,175,212,87,44,161,218,166,221,80,43,144,235,102,29,97,26,151,236,111,20,153,226,158,229,104,19,115,8,133,254,130,249,116,15,140,247,122,1,125,6,139,240,224,155,22,109,17,106,231,156,31,100,233,146,238,149,24,99,3,120,245,142,242,137,4,127,252,135,10,113,13,118,251,128,59,64,205,182,202,177,60,71,196,191,50,73,53,78,195,184,216,163,46,85,41,82,223,164,39,92,209,170,214,173,32,91},
{0,124,248,132,237,145,21,105,199,187,63,67,42,86,210,174,147,239,107,23,126,2,134,250,84,40,172,208,185,197,65,61,59,71,195,191,214,170,46,82,252,128,4,120,17,109,233,149,168,212,80,44,69,57,189,193,111,19,151,235,130,254,122,6,118,10,142,242,155,231,99,31,177,205,73,53,92,32,164,216,229,153,29,97,8,116,240,140,34,94,218,166,207,179,55,75,77,49,181,201,160,220,88,36,138,246,114,14,103,27,159,227,222,162,38,90,51,79,203,183,25,101,225,157,244,136,12,112,236,144,20,104,1,125,249,133,43,87,211,175,198,186,62,66,127,3,135,251,146,238,106,22,184,196,64,60,85,41,173,209,215,171,47,83,58,70,194,190,16,108,232,148,253,129,5,121,68,56,188,192,169,213,81,45,131,255,123,7,110,18,150,234,154,230,98,30,119,11,143,243,93,33,165,217,176,204,72,52,9,117,241,141,228,152,28,96,206,178,54,74,35,95,219,167,161,221,89,37,76,48,180,200,102,26,158,226,139,247,115,15,50,78,202,182,223,163,39,91,245,137,13,113,24,100,224,156},
{0,125,250,135,233,148,19,110,207,178,53,72,38,91,220,161,131,254,121,4,106,23,144,237,76,49,182,203,165,216,95,34,27,102,225,156,242,143,8,117,212,169,46,83,61,64,199,186,152,229,98,31,113,12,139,246,87,42,173,208,190,195,68,57,54,75,204,177,223,162,37,88,249,132,3,126,16,109,234,151,181,200,79,50,92,33,166,219,122,7,128,253,147,238,105,20,45,80,215,170,196,185,62,67,226,159,24,101,11,118,241,140,174,211,84,41,71,58,189,192,97,28,155,230,136,245,114,15,108,17,150,235,133,248,127,2,163,222,89,36,74,55,176,205,239,146,21,104,6,123,252,129,32,93,218,167,201,180,51,78,119,10,141,240,158,227,100,25,184,197,66,63,81,44,171,214,244,137,14,115,29,96,231,154,59,70,193,188,210,175,40,85,90,39,160,221,179,206,73,52,149,232,111,18,124,1,134,251,217,164,35,94,48,77,202,183,22,107,236,145,255,130,5,120,65,60,187,198,168,213,82,47,142,243,116,9,103,26,157,224,194,191,56,69,43,86,209,172,13,112,247,138,228,153,30,99},
{0,126,252,130,229,155,25,103,215,169,43,85,50,76,206,176,179,205,79,49,86,40,170,212,100,26,152,230,129,255,125,3,123,5,135,249,158,224,98,28,172,210,80,46,73,55,181,203,200,182,52,74,45,83,209,175,31,97,227,157,250,132,6,120,246,136,10,116,19,109,239,145,33,95,221,163,196,186,56,70,69,59,185,199,160,222,92,34,146,236,110,16,119,9,139,245,141,243,113,15,104,22,148,234,90,36,166,216,191,193,67,61,62,64,194,188,219,165,39,89,233,151,21,107,12,114,240,142,241,143,13,115,20,106,232,150,38,88,218,164,195,189,63,65,66,60,190,192,167,217,91,37,149,235,105,23,112,14,140,242,138,244,118,8,111,17,147,237,93,35,161,223,184,198,68,58,57,71,197,187,220,162,32,94,238,144,18,108,11,117,247,137,7,121,251,133,226,156,30,96,208,174,44,82,53,75,201,183,180,202,72,54,81,47,173,211,99,29,159,225,134,248,122,4,124,2,128,254,153,231,101,27,171,213,87,41,78,48,178,204,207,177,51,77,42,84,214,168,24,102,228,154,253,131,1,127},
{0,127,254,129,225,158,31,96,223,160,33,94,62,65,192,191,163,220,93,34,66,61,188,195,124,3,130,253,157,226,99,28,91,36,165,218,186,197,68,59,132,251,122,5,101,26,155,228,248,135,6,121,25,102,231,152,39,88,217,166,198,185,56,71,182,201,72,55,87,40,169,214,105,22,151,232,136,247,118,9,21,106,235,148,244,139,10,117,202,181,52,75,43,84,213,170,237,146,19,108,12,115,242,141,50,77,204,179,211,172,45,82,78,49,176,207,175,208,81,46,145,238,111,16,112,15,142,241,113,14,143,240,144,239,110,17,174,209,80,47,79,48,177,206,210,173,44,83,51,76,205,178,13,114,243,140,236,147,18,109,42,85,212,171,203,180,53,74,245,138,11,116,20,107,234,149,137,246,119,8,104,23,150,233,86,41,168,215,183,200,73,54,199,184,57,70,38,89,216,167,24,103,230,153,249,134,7,120,100,27,154,229,133,250,123,4,187,196,69,58,90,37,164,219,156,227,98,29,125,2,131,252,67,60,189,194,162,221,92,35,63,64,193,190,222,161,32,95,224,159,30,97,1,126,255,128},
{0,128,29,157,58,186,39,167,116,244,105,233,78,206,83,211,232,104,245,117,210,82,207,79,156,28,129,1,166,38,187,59,205,77,208,80,247,119,234,106,185,57,164,36,131,3,158,30,37,165,56,184,31,159,2,130,81,209,76,204,107,235,118,246,135,7,154,26,189,61,160,32,243,115,238,110,201,73,212,84,111,239,114,242,85,213,72,200,27,155,6,134,33,161,60,188,74,202,87,215,112,240,109,237,62,190,35,163,4,132,25,153,162,34,191,63,152,24,133,5,214,86,203,75,236,108,241,113,19,147,14,142,41,169,52,180,103,231,122,250,93,221,64,192,251,123,230,102,193,65,220,92,143,15,146,18,181,53,168,40,222,94,195,67,228,100,249,121,170,42,183,55,144,16,141,13,54,182,43,171,12,140,17,145,66,194,95,223,120,248,101,229,148,20,137,9,174,46,179,51,224,96,253,125,218,90,199,71,124,252,97,225,70,198,91,219,8,136,21,149,50,178,47,175,89,217,68,196,99,227,126,254,45,173,48,176,23,151,10,138,177,49,172,44,139,11,150,22,197,69,216,88,255,127,226,98},
{0,129,31,158,62,191,33,160,124,253,99,226,66,195,93,220,248,121,231,102,198,71,217,88,132,5,155,26,186,59,165,36,237,108,242,115,211,82,204,77,145,16,142,15,175,46,176,49,21,148,10,139,43,170,52,181,105,232,118,247,87,214,72,201,199,70,216,89,249,120,230,103,187,58,164,37,133,4,154,27,63,190,32,161,1,128,30,159,67,194,92,221,125,252,98,227,42,171,53,180,20,149,11,138,86,215,73,200,104,233,119,246,210,83,205,76,236,109,243,114,174,47,177,48,144,17,143,14,147,18,140,13,173,44,178,51,239,110,240,113,209,80,206,79,107,234,116,245,85,212,74,203,23,150,8,137,41,168,54,183,126,255,97,224,64,193,95,222,2,131,29,156,60,189,35,162,134,7,153,24,184,57,167,38,250,123,229,100,196,69,219,90,84,213,75,202,106,235,117,244,40,169,55,182,22,151,9,136,172,45,179,50,146,19,141,12,208,81,207,78,238,111,241,112,185,56,166,39,135,6,152,25,197,68,218,91,251,122,228,101,65,192,94,223,127,254,96,225,61,188,34,163,3,130,28,157},
{0,130,25,155,50,176,43,169,100,230,125,255,86,212,79,205,200,74,209,83,250,120,227,97,172,46,181,55,158,28,135,5,141,15,148,22,191,61,166,36,233,107,240,114,219,89,194,64,69,199,92,222,119,245,110,236,33,163,56,186,19,145,10,136,7,133,30,156,53,183,44,174,99,225,122,248,81,211,72,202,207,77,214,84,253,127,228,102,171,41,178,48,153,27,128,2,138,8,147,17,184,58,161,35,238,108,247,117,220,94,197,71,66,192,91,217,112,242,105,235,38,164,63,189,20,150,13,143,14,140,23,149,60,190,37,167,106,232,115,241,88,218,65,195,198,68,223,93,244,118,237,111,162,32,187,57,144,18,137,11,131,1,154,24,177,51,168,42,231,101,254,124,213,87,204,78,75,201,82,208,121,251,96,226,47,173,54,180,29,159,4,134,9,139,16,146,59,185,34,160,109,239,116,246,95,221,70,196,193,67,216,90,243,113,234,104,165,39,188,62,151,21,142,12,132,6,157,31,182,52,175,45,224,98,249,123,210,80,203,73,76,206,85,215,126,252,103,229,40,170,49,179,26,152,3,129},
{0,131,27,152,54,181,45,174,108,239,119,244,90,217,65,194,216,91,195,64,238,109,245,118,180,55,175,44,130,1,153,26,173,46,182,53,155,24,128,3,193,66,218,89,247,116,236,111,117,246,110,237,67,192,88,219,25,154,2,129,47,172,52,183,71,196,92,223,113,242,106,233,43,168,48,179,29,158,6,133,159,28,132,7,169,42,178,49,243,112,232,107,197,70,222,93,234,105,241,114,220,95,199,68,134,5,157,30,176,51,171,40,50,177,41,170,4,135,31,156,94,221,69,198,104,235,115,240,142,13,149,22,184,59,163,32,226,97,249,122,212,87,207,76,86,213,77,206,96,227,123,248,58,185,33,162,12,143,23,148,35,160,56,187,21,150,14,141,79,204,84,215,121,250,98,225,251,120,224,99,205,78,214,85,151,20,140,15,161,34,186,57,201,74,210,81,255,124,228,103,165,38,190,61,147,16,136,11,17,146,10,137,39,164,60,191,125,254,102,229,75,200,80,211,100,231,127,252,82,209,73,202,8,139,19,144,62,189,37,166,188,63,167,36,138,9,145,18,208,83,203,72,230,101,253,126},
{0,132,21,145,42,174,63,187,84,208,65,197,126,250,107,239,168,44,189,57,130,6,151,19,252,120,233,109,214,82,195,71,77,201,88,220,103,227,114,246,25,157,12,136,51,183,38,162,229,97,240,116,207,75,218,94,177,53,164,32,155,31,142,10,154,30,143,11,176,52,165,33,206,74,219,95,228,96,241,117,50,182,39,163,24,156,13,137,102,226,115,247,76,200,89,221,215,83,194,70,253,121,232,108,131,7,150,18,169,45,188,56,127,251,106,238,85,209,64,196,43,175,62,186,1,133,20,144,41,173,60,184,3,135,22,146,125,249,104,236,87,211,66,198,129,5,148,16,171,47,190,58,213,81,192,68,255,123,234,110,100,224,113,245,78,202,91,223,48,180,37,161,26,158,15,139,204,72,217,93,230,98,243,119,152,28,141,9,178,54,167,35,179,55,166,34,153,29,140,8,231,99,242,118,205,73,216,92,27,159,14,138,49,181,36,160,79,203,90,222,101,225,112,244,254,122,235,111,212,80,193,69,170,46,191,59,128,4,149,17,86,210,67,199,124,248,105,237,2,134,23,147,40,172,61,185},
{0,133,23,146,46,171,57,188,92,217,75,206,114,247,101,224,184,61,175,42,150,19,129,4,228,97,243,118,202,79,221,88,109,232,122,255,67,198,84,209,49,180,38,163,31,154,8,141,213,80,194,71,251,126,236,105,137,12,158,27,167,34,176,53,218,95,205,72,244,113,227,102,134,3,145,20,168,45,191,58,98,231,117,240,76,201,91,222,62,187,41,172,16,149,7,130,183,50,160,37,153,28,142,11,235,110,252,121,197,64,210,87,15,138,24,157,33,164,54,179,83,214,68,193,125,248,106,239,169,44,190,59,135,2,144,21,245,112,226,103,219,94,204,73,17,148,6,131,63,186,40,173,77,200,90,223,99,230,116,241,196,65,211,86,234,111,253,120,152,29,143,10,182,51,161,36,124,249,107,238,82,215,69,192,32,165,55,178,14,139,25,156,115,246,100,225,93,216,74,207,47,170,56,189,1,132,22,147,203,78,220,89,229,96,242,119,151,18,128,5,185,60,174,43,30,155,9,140,48,181,39,162,66,199,85,208,108,233,123,254,166,35,177,52,136,13,159,26,250,127,237,104,212,81,195,70},
{0,134,17,151,34,164,51,181,68,194,85,211,102,224,119,241,136,14,153,31,170,44,187,61,204,74,221,91,238,104,255,121,13,139,28,154,47,169,62,184,73,207,88,222,107,237,122,252,133,3,148,18,167,33,182,48,193,71,208,86,227,101,242,116,26,156,11,141,56,190,41,175,94,216,79,201,124,250,109,235,146,20,131,5,176,54,161,39,214,80,199,65,244,114,229,99,23,145,6,128,53,179,36,162,83,213,66,196,113,247,96,230,159,25,142,8,189,59,172,42,219,93,202,76,249,127,232,110,52,178,37,163,22,144,7,129,112,246,97,231,82,212,67,197,188,58,173,43,158,24,143,9,248,126,233,111,218,92,203,77,57,191,40,174,27,157,10,140,125,251,108,234,95,217,78,200,177,55,160,38,147,21,130,4,245,115,228,98,215,81,198,64,46,168,63,185,12,138,29,155,106,236,123,253,72,206,89,223,166,32,183,49,132,2,149,19,226,100,243,117,192,70,209,87,35,165,50,180,1,135,16,150,103,225,118,240,69,195,84,210,171,45,186,60,137,15,152,30,239,105,254,120,205,75,220,90},
{0,135,19,148,38,161,53,178,76,203,95,216,106,237,121,254,152,31,139,12,190,57,173,42,212,83,199,64,242,117,225,102,45,170,62,185,11,140,24,159,97,230,114,245,71,192,84,211,181,50,166,33,147,20,128,7,249,126,234,109,223,88,204,75,90,221,73,206,124,251,111,232,22,145,5,130,48,183,35,164,194,69,209,86,228,99,247,112,142,9,157,26,168,47,187,60,119,240,100,227,81,214,66,197,59,188,40,175,29,154,14,137,239,104,252,123,201,78,218,93,163,36,176,55,133,2,150,17,180,51,167,32,146,21,129,6,248,127,235,108,222,89,205,74,44,171,63,184,10,141,25,158,96,231,115,244,70,193,85,210,153,30,138,13,191,56,172,43,213,82,198,65,243,116,224,103,1,134,18,149,39,160,52,179,77,202,94,217,107,236,120,255,238,105,253,122,200,79,219,92,162,37,177,54,132,3,151,16,118,241,101,226,80,215,67,196,58,189,41,174,28,155,15,136,195,68,208,87,229,98,246,113,143,8,156,27,169,46,186,61,91,220,72,207,125,250,110,233,23,144,4,131,49,182,34,165},
{0,136,13,133,26,146,23,159,52,188,57,177,46,166,35,171,104,224,101,237,114,250,127,247,92,212,81,217,70,206,75,195,208,88,221,85,202,66,199,79,228,108,233,97,254,118,243,123,184,48,181,61,162,42,175,39,140,4,129,9,150,30,155,19,189,53,176,56,167,47,170,34,137,1,132,12,147,27,158,22,213,93,216,80,207,71,194,74,225,105,236,100,251,115,246,126,109,229,96,232,119,255,122,242,89,209,84,220,67,203,78,198,5,141,8,128,31,151,18,154,49,185,60,180,43,163,38,174,103,239,106,226,125,245,112,248,83,219,94,214,73,193,68,204,15,135,2,138,21,157,24,144,59,179,54,190,33,169,44,164,183,63,186,50,173,37,160,40,131,11,142,6,153,17,148,28,223,87,210,90,197,77,200,64,235,99,230,110,241,121,252,116,218,82,215,95,192,72,205,69,238,102,227,107,244,124,249,113,178,58,191,55,168,32,165,45,134,14,139,3,156,20,145,25,10,130,7,143,16,152,29,149,62,182,51,187,36,172,41,161,98,234,111,231,120,240,117,253,86,222,91,211,76,196,65,201},
{0,137,15,134,30,151,17,152,60,181,51,186,34,171,45,164,120,241,119,254,102,239,105,224,68,205,75,194,90,211,85,220,240,121,255,118,238,103,225,104,204,69,195,74,210,91,221,84,136,1,135,14,150,31,153,16,180,61,187,50,170,35,165,44,253,116,242,123,227,106,236,101,193,72,206,71,223,86,208,89,133,12,138,3,155,18,148,29,185,48,182,63,167,46,168,33,13,132,2,139,19,154,28,149,49,184,62,183,47,166,32,169,117,252,122,243,107,226,100,237,73,192,70,207,87,222,88,209,231,110,232,97,249,112,246,127,219,82,212,93,197,76,202,67,159,22,144,25,129,8,142,7,163,42,172,37,189,52,178,59,23,158,24,145,9,128,6,143,43,162,36,173,53,188,58,179,111,230,96,233,113,248,126,247,83,218,92,213,77,196,66,203,26,147,21,156,4,141,11,130,38,175,41,160,56,177,55,190,98,235,109,228,124,245,115,250,94,215,81,216,64,201,79,198,234,99,229,108,244,125,251,114,214,95,217,80,200,65,199,78,146,27,157,20,140,5,131,10,174,39,161,40,176,57,191,54},
{0,138,9,131,18,152,27,145,36,174,45,167,54,188,63,181,72,194,65,203,90,208,83,217,108,230,101,239,126,244,119,253,144,26,153,19,130,8,139,1,180,62,189,55,166,44,175,37,216,82,209,91,202,64,195,73,252,118,245,127,238,100,231,109,61,183,52,190,47,165,38,172,25,147,16,154,11,129,2,136,117,255,124,246,103,237,110,228,81,219,88,210,67,201,74,192,173,39,164,46,191,53,182,60,137,3,128,10,155,17,146,24,229,111,236,102,247,125,254,116,193,75,200,66,211,89,218,80,122,240,115,249,104,226,97,235,94,212,87,221,76,198,69,207,50,184,59,177,32,170,41,163,22,156,31,149,4,142,13,135,234,96,227,105,248,114,241,123,206,68,199,77,220,86,213,95,162,40,171,33,176,58,185,51,134,12,143,5,148,30,157,23,71,205,78,196,85,223,92,214,99,233,106,224,113,251,120,242,15,133,6,140,29,151,20,158,43,161,34,168,57,179,48,186,215,93,222,84,197,79,204,70,243,121,250,112,225,107,232,98,159,21,150,28,141,7,132,14,187,49,178,56,169,35,160,42},
{0,139,11,128,22,157,29,150,44,167,39,172,58,177,49,186,88,211,83,216,78,197,69,206,116,255,127,244,98,233,105,226,176,59,187,48,166,45,173,38,156,23,151,28,138,1,129,10,232,99,227,104,254,117,245,126,196,79,207,68,210,89,217,82,125,246,118,253,107,224,96,235,81,218,90,209,71,204,76,199,37,174,46,165,51,184,56,179,9,130,2,137,31,148,20,159,205,70,198,77,219,80,208,91,225,106,234,97,247,124,252,119,149,30,158,21,131,8,136,3,185,50,178,57,175,36,164,47,250,113,241,122,236,103,231,108,214,93,221,86,192,75,203,64,162,41,169,34,180,63,191,52,142,5,133,14,152,19,147,24,74,193,65,202,92,215,87,220,102,237,109,230,112,251,123,240,18,153,25,146,4,143,15,132,62,181,53,190,40,163,35,168,135,12,140,7,145,26,154,17,171,32,160,43,189,54,182,61,223,84,212,95,201,66,194,73,243,120,248,115,229,110,238,101,55,188,60,183,33,170,42,161,27,144,16,155,13,134,6,141,111,228,100,239,121,242,114,249,67,200,72,195,85,222,94,213},
{0,140,5,137,10,134,15,131,20,152,17,157,30,146,27,151,40,164,45,161,34,174,39,171,60,176,57,181,54,186,51,191,80,220,85,217,90,214,95,211,68,200,65,205,78,194,75,199,120,244,125,241,114,254,119,251,108,224,105,229,102,234,99,239,160,44,165,41,170,38,175,35,180,56,177,61,190,50,187,55,136,4,141,1,130,14,135,11,156,16,153,21,150,26,147,31,240,124,245,121,250,118,255,115,228,104,225,109,238,98,235,103,216,84,221,81,210,94,215,91,204,64,201,69,198,74,195,79,93,209,88,212,87,219,82,222,73,197,76,192,67,207,70,202,117,249,112,252,127,243,122,246,97,237,100,232,107,231,110,226,13,129,8,132,7,139,2,142,25,149,28,144,19,159,22,154,37,169,32,172,47,163,42,166,49,189,52,184,59,183,62,178,253,113,248,116,247,123,242,126,233,101,236,96,227,111,230,106,213,89,208,92,223,83,218,86,193,77,196,72,203,71,206,66,173,33,168,36,167,43,162,46,185,53,188,48,179,63,182,58,133,9,128,12,143,3,138,6,145,29,148,24,155,23,158,18},
{0,141,7,138,14,131,9,132,28,145,27,150,18,159,21,152,56,181,63,178,54,187,49,188,36,169,35,174,42,167,45,160,112,253,119,250,126,243,121,244,108,225,107,230,98,239,101,232,72,197,79,194,70,203,65,204,84,217,83,222,90,215,93,208,224,109,231,106,238,99,233,100,252,113,251,118,242,127,245,120,216,85,223,82,214,91,209,92,196,73,195,78,202,71,205,64,144,29,151,26,158,19,153,20,140,1,139,6,130,15,133,8,168,37,175,34,166,43,161,44,180,57,179,62,186,55,189,48,221,80,218,87,211,94,212,89,193,76,198,75,207,66,200,69,229,104,226,111,235,102,236,97,249,116,254,115,247,122,240,125,173,32,170,39,163,46,164,41,177,60,182,59,191,50,184,53,149,24,146,31,155,22,156,17,137,4,142,3,135,10,128,13,61,176,58,183,51,190,52,185,33,172,38,171,47,162,40,165,5,136,2,143,11,134,12,129,25,148,30,147,23,154,16,157,77,192,74,199,67,206,68,201,81,220,86,219,95,210,88,213,117,248,114,255,123,246,124,241,105,228,110,227,103,234,96,237},
{0,142,1,143,2,140,3,141,4,138,5,139,6,136,7,137,8,134,9,135,10,132,11,133,12,130,13,131,14,128,15,129,16,158,17,159,18,156,19,157,20,154,21,155,22,152,23,153,24,150,25,151,26,148,27,149,28,146,29,147,30,144,31,145,32,174,33,175,34,172,35,173,36,170,37,171,38,168,39,169,40,166,41,167,42,164,43,165,44,162,45,163,46,160,47,161,48,190,49,191,50,188,51,189,52,186,53,187,54,184,55,185,56,182,57,183,58,180,59,181,60,178,61,179,62,176,63,177,64,206,65,207,66,204,67,205,68,202,69,203,70,200,71,201,72,198,73,199,74,196,75,197,76,194,77,195,78,192,79,193,80,222,81,223,82,220,83,221,84,218,85,219,86,216,87,217,88,214,89,215,90,212,91,213,92,210,93,211,94,208,95,209,96,238,97,239,98,236,99,237,100,234,101,235,102,232,103,233,104,230,105,231,106,228,107,229,108,226,109,227,110,224,111,225,112,254,113,255,114,252,115,253,116,250,117,251,118,248,119,249,120,246,121,247,122,244,123,245,124,242,125,243,126,240,127,241},
{0,143,3,140,6,137,5,138,12,131,15,128,10,133,9,134,24,151,27,148,30,145,29,146,20,155,23,152,18,157,17,158,48,191,51,188,54,185,53,186,60,179,63,176,58,181,57,182,40,167,43,164,46,161,45,162,36,171,39,168,34,173,33,174,96,239,99,236,102,233,101,234,108,227,111,224,106,229,105,230,120,247,123,244,126,241,125,242,116,251,119,248,114,253,113,254,80,223,83,220,86,217,85,218,92,211,95,208,90,213,89,214,72,199,75,196,78,193,77,194,68,203,71,200,66,205,65,206,192,79,195,76,198,73,197,74,204,67,207,64,202,69,201,70,216,87,219,84,222,81,221,82,212,91,215,88,210,93,209,94,240,127,243,124,246,121,245,122,252,115,255,112,250,117,249,118,232,103,235,100,238,97,237,98,228,107,231,104,226,109,225,110,160,47,163,44,166,41,165,42,172,35,175,32,170,37,169,38,184,55,187,52,190,49,189,50,180,59,183,56,178,61,177,62,144,31,147,28,150,25,149,26,156,19,159,16,154,21,153,22,136,7,139,4,142,1,141,2,132,11,135,8,130,13,129,14},
{0,144,61,173,122,234,71,215,244,100,201,89,142,30,179,35,245,101,200,88,143,31,178,34,1,145,60,172,123,235,70,214,247,103,202,90,141,29,176,32,3,147,62,174,121,233,68,212,2,146,63,175,120,232,69,213,246,102,203,91,140,28,177,33,243,99,206,94,137,25,180,36,7,151,58,170,125,237,64,208,6,150,59,171,124,236,65,209,242,98,207,95,136,24,181,37,4,148,57,169,126,238,67,211,240,96,205,93,138,26,183,39,241,97,204,92,139,27,182,38,5,149,56,168,127,239,66,210,251,107,198,86,129,17,188,44,15,159,50,162,117,229,72,216,14,158,51,163,116,228,73,217,250,106,199,87,128,16,189,45,12,156,49,161,118,230,75,219,248,104,197,85,130,18,191,47,249,105,196,84,131,19,190,46,13,157,48,160,119,231,74,218,8,152,53,165,114,226,79,223,252,108,193,81,134,22,187,43,253,109,192,80,135,23,186,42,9,153,52,164,115,227,78,222,255,111,194,82,133,21,184,40,11,155,54,166,113,225,76,220,10,154,55,167,112,224,77,221,254,110,195,83,132,20,185,41},
{0,145,63,174,126,239,65,208,252,109,195,82,130,19,189,44,229,116,218,75,155,10,164,53,25,136,38,183,103,246,88,201,215,70,232,121,169,56,150,7,43,186,20,133,85,196,106,251,50,163,13,156,76,221,115,226,206,95,241,96,176,33,143,30,179,34,140,29,205,92,242,99,79,222,112,225,49,160,14,159,86,199,105,248,40,185,23,134,170,59,149,4,212,69,235,122,100,245,91,202,26,139,37,180,152,9,167,54,230,119,217,72,129,16,190,47,255,110,192,81,125,236,66,211,3,146,60,173,123,234,68,213,5,148,58,171,135,22,184,41,249,104,198,87,158,15,161,48,224,113,223,78,98,243,93,204,28,141,35,178,172,61,147,2,210,67,237,124,80,193,111,254,46,191,17,128,73,216,118,231,55,166,8,153,181,36,138,27,203,90,244,101,200,89,247,102,182,39,137,24,52,165,11,154,74,219,117,228,45,188,18,131,83,194,108,253,209,64,238,127,175,62,144,1,31,142,32,177,97,240,94,207,227,114,220,77,157,12,162,51,250,107,197,84,132,21,187,42,6,151,57,168,120,233,71,214},
{0,146,57,171,114,224,75,217,228,118,221,79,150,4,175,61,213,71,236,126,167,53,158,12,49,163,8,154,67,209,122,232,183,37,142,28,197,87,252,110,83,193,106,248,33,179,24,138,98,240,91,201,16,130,41,187,134,20,191,45,244,102,205,95,115,225,74,216,1,147,56,170,151,5,174,60,229,119,220,78,166,52,159,13,212,70,237,127,66,208,123,233,48,162,9,155,196,86,253,111,182,36,143,29,32,178,25,139,82,192,107,249,17,131,40,186,99,241,90,200,245,103,204,94,135,21,190,44,230,116,223,77,148,6,173,63,2,144,59,169,112,226,73,219,51,161,10,152,65,211,120,234,215,69,238,124,165,55,156,14,81,195,104,250,35,177,26,136,181,39,140,30,199,85,254,108,132,22,189,47,246,100,207,93,96,242,89,203,18,128,43,185,149,7,172,62,231,117,222,76,113,227,72,218,3,145,58,168,64,210,121,235,50,160,11,153,164,54,157,15,214,68,239,125,34,176,27,137,80,194,105,251,198,84,255,109,180,38,141,31,247,101,206,92,133,23,188,46,19,129,42,184,97,243,88,202},
{0,147,59,168,118,229,77,222,236,127,215,68,154,9,161,50,197,86,254,109,179,32,136,27,41,186,18,129,95,204,100,247,151,4,172,63,225,114,218,73,123,232,64,211,13,158,54,165,82,193,105,250,36,183,31,140,190,45,133,22,200,91,243,96,51,160,8,155,69,214,126,237,223,76,228,119,169,58,146,1,246,101,205,94,128,19,187,40,26,137,33,178,108,255,87,196,164,55,159,12,210,65,233,122,72,219,115,224,62,173,5,150,97,242,90,201,23,132,44,191,141,30,182,37,251,104,192,83,102,245,93,206,16,131,43,184,138,25,177,34,252,111,199,84,163,48,152,11,213,70,238,125,79,220,116,231,57,170,2,145,241,98,202,89,135,20,188,47,29,142,38,181,107,248,80,195,52,167,15,156,66,209,121,234,216,75,227,112,174,61,149,6,85,198,110,253,35,176,24,139,185,42,130,17,207,92,244,103,144,3,171,56,230,117,221,78,124,239,71,212,10,153,49,162,194,81,249,106,180,39,143,28,46,189,21,134,88,203,99,240,7,148,60,175,113,226,74,217,235,120,208,67,157,14,166,53},
{0,148,53,161,106,254,95,203,212,64,225,117,190,42,139,31,181,33,128,20,223,75,234,126,97,245,84,192,11,159,62,170,119,227,66,214,29,137,40,188,163,55,150,2,201,93,252,104,194,86,247,99,168,60,157,9,22,130,35,183,124,232,73,221,238,122,219,79,132,16,177,37,58,174,15,155,80,196,101,241,91,207,110,250,49,165,4,144,143,27,186,46,229,113,208,68,153,13,172,56,243,103,198,82,77,217,120,236,39,179,18,134,44,184,25,141,70,210,115,231,248,108,205,89,146,6,167,51,193,85,244,96,171,63,158,10,21,129,32,180,127,235,74,222,116,224,65,213,30,138,43,191,160,52,149,1,202,94,255,107,182,34,131,23,220,72,233,125,98,246,87,195,8,156,61,169,3,151,54,162,105,253,92,200,215,67,226,118,189,41,136,28,47,187,26,142,69,209,112,228,251,111,206,90,145,5,164,48,154,14,175,59,240,100,197,81,78,218,123,239,36,176,17,133,88,204,109,249,50,166,7,147,140,24,185,45,230,114,211,71,237,121,216,76,135,19,178,38,57,173,12,152,83,199,102,242},
{0,149,55,162,110,251,89,204,220,73,235,126,178,39,133,16,165,48,146,7,203,94,252,105,121,236,78,219,23,130,32,181,87,194,96,245,57,172,14,155,139,30,188,41,229,112,210,71,242,103,197,80,156,9,171,62,46,187,25,140,64,213,119,226,174,59,153,12,192,85,247,98,114,231,69,208,28,137,43,190,11,158,60,169,101,240,82,199,215,66,224,117,185,44,142,27,249,108,206,91,151,2,160,53,37,176,18,135,75,222,124,233,92,201,107,254,50,167,5,144,128,21,183,34,238,123,217,76,65,212,118,227,47,186,24,141,157,8,170,63,243,102,196,81,228,113,211,70,138,31,189,40,56,173,15,154,86,195,97,244,22,131,33,180,120,237,79,218,202,95,253,104,164,49,147,6,179,38,132,17,221,72,234,127,111,250,88,205,1,148,54,163,239,122,216,77,129,20,182,35,51,166,4,145,93,200,106,255,74,223,125,232,36,177,19,134,150,3,161,52,248,109,207,90,184,45,143,26,214,67,225,116,100,241,83,198,10,159,61,168,29,136,42,191,115,230,68,209,193,84,246,99,175,58,152,13},
{0,150,49,167,98,244,83,197,196,82,245,99,166,48,151,1,149,3,164,50,247,97,198,80,81,199,96,246,51,165,2,148,55,161,6,144,85,195,100,242,243,101,194,84,145,7,160,54,162,52,147,5,192,86,241,103,102,240,87,193,4,146,53,163,110,248,95,201,12,154,61,171,170,60,155,13,200,94,249,111,251,109,202,92,153,15,168,62,63,169,14,152,93,203,108,250,89,207,104,254,59,173,10,156,157,11,172,58,255,105,206,88,204,90,253,107,174,56,159,9,8,158,57,175,106,252,91,205,220,74,237,123,190,40,143,25,24,142,41,191,122,236,75,221,73,223,120,238,43,189,26,140,141,27,188,42,239,121,222,72,235,125,218,76,137,31,184,46,47,185,30,136,77,219,124,234,126,232,79,217,28,138,45,187,186,44,139,29,216,78,233,127,178,36,131,21,208,70,225,119,118,224,71,209,20,130,37,179,39,177,22,128,69,211,116,226,227,117,210,68,129,23,176,38,133,19,180,34,231,113,214,64,65,215,112,230,35,181,18,132,16,134,33,183,114,228,67,213,212,66,229,115,182,32,135,17},
{0,151,51,164,102,241,85,194,204,91,255,104,170,61,153,14,133,18,182,33,227,116,208,71,73,222,122,237,47,184,28,139,23,128,36,179,113,230,66,213,219,76,232,127,189,42,142,25,146,5,161,54,244,99,199,80,94,201,109,250,56,175,11,156,46,185,29,138,72,223,123,236,226,117,209,70,132,19,183,32,171,60,152,15,205,90,254,105,103,240,84,195,1,150,50,165,57,174,10,157,95,200,108,251,245,98,198,81,147,4,160,55,188,43,143,24,218,77,233,126,112,231,67,212,22,129,37,178,92,203,111,248,58,173,9,158,144,7,163,52,246,97,197,82,217,78,234,125,191,40,140,27,21,130,38,177,115,228,64,215,75,220,120,239,45,186,30,137,135,16,180,35,225,118,210,69,206,89,253,106,168,63,155,12,2,149,49,166,100,243,87,192,114,229,65,214,20,131,39,176,190,41,141,26,216,79,235,124,247,96,196,83,145,6,162,53,59,172,8,159,93,202,110,249,101,242,86,193,3,148,48,167,169,62,154,13,207,88,252,107,224,119,211,68,134,17,181,34,44,187,31,136,74,221,121,238},
{0,152,45,181,90,194,119,239,180,44,153,1,238,118,195,91,117,237,88,192,47,183,2,154,193,89,236,116,155,3,182,46,234,114,199,95,176,40,157,5,94,198,115,235,4,156,41,177,159,7,178,42,197,93,232,112,43,179,6,158,113,233,92,196,201,81,228,124,147,11,190,38,125,229,80,200,39,191,10,146,188,36,145,9,230,126,203,83,8,144,37,189,82,202,127,231,35,187,14,150,121,225,84,204,151,15,186,34,205,85,224,120,86,206,123,227,12,148,33,185,226,122,207,87,184,32,149,13,143,23,162,58,213,77,248,96,59,163,22,142,97,249,76,212,250,98,215,79,160,56,141,21,78,214,99,251,20,140,57,161,101,253,72,208,63,167,18,138,209,73,252,100,139,19,166,62,16,136,61,165,74,210,103,255,164,60,137,17,254,102,211,75,70,222,107,243,28,132,49,169,242,106,223,71,168,48,133,29,51,171,30,134,105,241,68,220,135,31,170,50,221,69,240,104,172,52,129,25,246,110,219,67,24,128,53,173,66,218,111,247,217,65,244,108,131,27,174,54,109,245,64,216,55,175,26,130},
{0,153,47,182,94,199,113,232,188,37,147,10,226,123,205,84,101,252,74,211,59,162,20,141,217,64,246,111,135,30,168,49,202,83,229,124,148,13,187,34,118,239,89,192,40,177,7,158,175,54,128,25,241,104,222,71,19,138,60,165,77,212,98,251,137,16,166,63,215,78,248,97,53,172,26,131,107,242,68,221,236,117,195,90,178,43,157,4,80,201,127,230,14,151,33,184,67,218,108,245,29,132,50,171,255,102,208,73,161,56,142,23,38,191,9,144,120,225,87,206,154,3,181,44,196,93,235,114,15,150,32,185,81,200,126,231,179,42,156,5,237,116,194,91,106,243,69,220,52,173,27,130,214,79,249,96,136,17,167,62,197,92,234,115,155,2,180,45,121,224,86,207,39,190,8,145,160,57,143,22,254,103,209,72,28,133,51,170,66,219,109,244,134,31,169,48,216,65,247,110,58,163,21,140,100,253,75,210,227,122,204,85,189,36,146,11,95,198,112,233,1,152,46,183,76,213,99,250,18,139,61,164,240,105,223,70,174,55,129,24,41,176,6,159,119,238,88,193,149,12,186,35,203,82,228,125},
{0,154,41,179,82,200,123,225,164,62,141,23,246,108,223,69,85,207,124,230,7,157,46,180,241,107,216,66,163,57,138,16,170,48,131,25,248,98,209,75,14,148,39,189,92,198,117,239,255,101,214,76,173,55,132,30,91,193,114,232,9,147,32,186,73,211,96,250,27,129,50,168,237,119,196,94,191,37,150,12,28,134,53,175,78,212,103,253,184,34,145,11,234,112,195,89,227,121,202,80,177,43,152,2,71,221,110,244,21,143,60,166,182,44,159,5,228,126,205,87,18,136,59,161,64,218,105,243,146,8,187,33,192,90,233,115,54,172,31,133,100,254,77,215,199,93,238,116,149,15,188,38,99,249,74,208,49,171,24,130,56,162,17,139,106,240,67,217,156,6,181,47,206,84,231,125,109,247,68,222,63,165,22,140,201,83,224,122,155,1,178,40,219,65,242,104,137,19,160,58,127,229,86,204,45,183,4,158,142,20,167,61,220,70,245,111,42,176,3,153,120,226,81,203,113,235,88,194,35,185,10,144,213,79,252,102,135,29,174,52,36,190,13,151,118,236,95,197,128,26,169,51,210,72,251,97},
{0,155,43,176,86,205,125,230,172,55,135,28,250,97,209,74,69,222,110,245,19,136,56,163,233,114,194,89,191,36,148,15,138,17,161,58,220,71,247,108,38,189,13,150,112,235,91,192,207,84,228,127,153,2,178,41,99,248,72,211,53,174,30,133,9,146,34,185,95,196,116,239,165,62,142,21,243,104,216,67,76,215,103,252,26,129,49,170,224,123,203,80,182,45,157,6,131,24,168,51,213,78,254,101,47,180,4,159,121,226,82,201,198,93,237,118,144,11,187,32,106,241,65,218,60,167,23,140,18,137,57,162,68,223,111,244,190,37,149,14,232,115,195,88,87,204,124,231,1,154,42,177,251,96,208,75,173,54,134,29,152,3,179,40,206,85,229,126,52,175,31,132,98,249,73,210,221,70,246,109,139,16,160,59,113,234,90,193,39,188,12,151,27,128,48,171,77,214,102,253,183,44,156,7,225,122,202,81,94,197,117,238,8,147,35,184,242,105,217,66,164,63,143,20,145,10,186,33,199,92,236,119,61,166,22,141,107,240,64,219,212,79,255,100,130,25,169,50,120,227,83,200,46,181,5,158},
{0,156,37,185,74,214,111,243,148,8,177,45,222,66,251,103,53,169,16,140,127,227,90,198,161,61,132,24,235,119,206,82,106,246,79,211,32,188,5,153,254,98,219,71,180,40,145,13,95,195,122,230,21,137,48,172,203,87,238,114,129,29,164,56,212,72,241,109,158,2,187,39,64,220,101,249,10,150,47,179,225,125,196,88,171,55,142,18,117,233,80,204,63,163,26,134,190,34,155,7,244,104,209,77,42,182,15,147,96,252,69,217,139,23,174,50,193,93,228,120,31,131,58,166,85,201,112,236,181,41,144,12,255,99,218,70,33,189,4,152,107,247,78,210,128,28,165,57,202,86,239,115,20,136,49,173,94,194,123,231,223,67,250,102,149,9,176,44,75,215,110,242,1,157,36,184,234,118,207,83,160,60,133,25,126,226,91,199,52,168,17,141,97,253,68,216,43,183,14,146,245,105,208,76,191,35,154,6,84,200,113,237,30,130,59,167,192,92,229,121,138,22,175,51,11,151,46,178,65,221,100,248,159,3,186,38,213,73,240,108,62,162,27,135,116,232,81,205,170,54,143,19,224,124,197,89},
{0,157,39,186,78,211,105,244,156,1,187,38,210,79,245,104,37,184,2,159,107,246,76,209,185,36,158,3,247,106,208,77,74,215,109,240,4,153,35,190,214,75,241,108,152,5,191,34,111,242,72,213,33,188,6,155,243,110,212,73,189,32,154,7,148,9,179,46,218,71,253,96,8,149,47,178,70,219,97,252,177,44,150,11,255,98,216,69,45,176,10,151,99,254,68,217,222,67,249,100,144,13,183,42,66,223,101,248,12,145,43,182,251,102,220,65,181,40,146,15,103,250,64,221,41,180,14,147,53,168,18,143,123,230,92,193,169,52,142,19,231,122,192,93,16,141,55,170,94,195,121,228,140,17,171,54,194,95,229,120,127,226,88,197,49,172,22,139,227,126,196,89,173,48,138,23,90,199,125,224,20,137,51,174,198,91,225,124,136,21,175,50,161,60,134,27,239,114,200,85,61,160,26,135,115,238,84,201,132,25,163,62,202,87,237,112,24,133,63,162,86,203,113,236,235,118,204,81,165,56,130,31,119,234,80,205,57,164,30,131,206,83,233,116,128,29,167,58,82,207,117,232,28,129,59,166},
{0,158,33,191,66,220,99,253,132,26,165,59,198,88,231,121,21,139,52,170,87,201,118,232,145,15,176,46,211,77,242,108,42,180,11,149,104,246,73,215,174,48,143,17,236,114,205,83,63,161,30,128,125,227,92,194,187,37,154,4,249,103,216,70,84,202,117,235,22,136,55,169,208,78,241,111,146,12,179,45,65,223,96,254,3,157,34,188,197,91,228,122,135,25,166,56,126,224,95,193,60,162,29,131,250,100,219,69,184,38,153,7,107,245,74,212,41,183,8,150,239,113,206,80,173,51,140,18,168,54,137,23,234,116,203,85,44,178,13,147,110,240,79,209,189,35,156,2,255,97,222,64,57,167,24,134,123,229,90,196,130,28,163,61,192,94,225,127,6,152,39,185,68,218,101,251,151,9,182,40,213,75,244,106,19,141,50,172,81,207,112,238,252,98,221,67,190,32,159,1,120,230,89,199,58,164,27,133,233,119,200,86,171,53,138,20,109,243,76,210,47,177,14,144,214,72,247,105,148,10,181,43,82,204,115,237,16,142,49,175,195,93,226,124,129,31,160,62,71,217,102,248,5,155,36,186},
{0,159,35,188,70,217,101,250,140,19,175,48,202,85,233,118,5,154,38,185,67,220,96,255,137,22,170,53,207,80,236,115,10,149,41,182,76,211,111,240,134,25,165,58,192,95,227,124,15,144,44,179,73,214,106,245,131,28,160,63,197,90,230,121,20,139,55,168,82,205,113,238,152,7,187,36,222,65,253,98,17,142,50,173,87,200,116,235,157,2,190,33,219,68,248,103,30,129,61,162,88,199,123,228,146,13,177,46,212,75,247,104,27,132,56,167,93,194,126,225,151,8,180,43,209,78,242,109,40,183,11,148,110,241,77,210,164,59,135,24,226,125,193,94,45,178,14,145,107,244,72,215,161,62,130,29,231,120,196,91,34,189,1,158,100,251,71,216,174,49,141,18,232,119,203,84,39,184,4,155,97,254,66,221,171,52,136,23,237,114,206,81,60,163,31,128,122,229,89,198,176,47,147,12,246,105,213,74,57,166,26,133,127,224,92,195,181,42,150,9,243,108,208,79,54,169,21,138,112,239,83,204,186,37,153,6,252,99,223,64,51,172,16,143,117,234,86,201,191,32,156,3,249,102,218,69},
{0,160,93,253,186,26,231,71,105,201,52,148,211,115,142,46,210,114,143,47,104,200,53,149,187,27,230,70,1,161,92,252,185,25,228,68,3,163,94,254,208,112,141,45,106,202,55,151,107,203,54,150,209,113,140,44,2,162,95,255,184,24,229,69,111,207,50,146,213,117,136,40,6,166,91,251,188,28,225,65,189,29,224,64,7,167,90,250,212,116,137,41,110,206,51,147,214,118,139,43,108,204,49,145,191,31,226,66,5,165,88,248,4,164,89,249,190,30,227,67,109,205,48,144,215,119,138,42,222,126,131,35,100,196,57,153,183,23,234,74,13,173,80,240,12,172,81,241,182,22,235,75,101,197,56,152,223,127,130,34,103,199,58,154,221,125,128,32,14,174,83,243,180,20,233,73,181,21,232,72,15,175,82,242,220,124,129,33,102,198,59,155,177,17,236,76,11,171,86,246,216,120,133,37,98,194,63,159,99,195,62,158,217,121,132,36,10,170,87,247,176,16,237,77,8,168,85,245,178,18,239,79,97,193,60,156,219,123,134,38,218,122,135,39,96,192,61,157,179,19,238,78,9,169,84,244},
{0,161,95,254,190,31,225,64,97,192,62,159,223,126,128,33,194,99,157,60,124,221,35,130,163,2,252,93,29,188,66,227,153,56,198,103,39,134,120,217,248,89,167,6,70,231,25,184,91,250,4,165,229,68,186,27,58,155,101,196,132,37,219,122,47,142,112,209,145,48,206,111,78,239,17,176,240,81,175,14,237,76,178,19,83,242,12,173,140,45,211,114,50,147,109,204,182,23,233,72,8,169,87,246,215,118,136,41,105,200,54,151,116,213,43,138,202,107,149,52,21,180,74,235,171,10,244,85,94,255,1,160,224,65,191,30,63,158,96,193,129,32,222,127,156,61,195,98,34,131,125,220,253,92,162,3,67,226,28,189,199,102,152,57,121,216,38,135,166,7,249,88,24,185,71,230,5,164,90,251,187,26,228,69,100,197,59,154,218,123,133,36,113,208,46,143,207,110,144,49,16,177,79,238,174,15,241,80,179,18,236,77,13,172,82,243,210,115,141,44,108,205,51,146,232,73,183,22,86,247,9,168,137,40,214,119,55,150,104,201,42,139,117,212,148,53,203,106,75,234,20,181,245,84,170,11},
{0,162,89,251,178,16,235,73,121,219,32,130,203,105,146,48,242,80,171,9,64,226,25,187,139,41,210,112,57,155,96,194,249,91,160,2,75,233,18,176,128,34,217,123,50,144,107,201,11,169,82,240,185,27,224,66,114,208,43,137,192,98,153,59,239,77,182,20,93,255,4,166,150,52,207,109,36,134,125,223,29,191,68,230,175,13,246,84,100,198,61,159,214,116,143,45,22,180,79,237,164,6,253,95,111,205,54,148,221,127,132,38,228,70,189,31,86,244,15,173,157,63,196,102,47,141,118,212,195,97,154,56,113,211,40,138,186,24,227,65,8,170,81,243,49,147,104,202,131,33,218,120,72,234,17,179,250,88,163,1,58,152,99,193,136,42,209,115,67,225,26,184,241,83,168,10,200,106,145,51,122,216,35,129,177,19,232,74,3,161,90,248,44,142,117,215,158,60,199,101,85,247,12,174,231,69,190,28,222,124,135,37,108,206,53,151,167,5,254,92,21,183,76,238,213,119,140,46,103,197,62,156,172,14,245,87,30,188,71,229,39,133,126,220,149,55,204,110,94,252,7,165,236,78,181,23},
{0,163,91,248,182,21,237,78,113,210,42,137,199,100,156,63,226,65,185,26,84,247,15,172,147,48,200,107,37,134,126,221,217,122,130,33,111,204,52,151,168,11,243,80,30,189,69,230,59,152,96,195,141,46,214,117,74,233,17,178,252,95,167,4,175,12,244,87,25,186,66,225,222,125,133,38,104,203,51,144,77,238,22,181,251,88,160,3,60,159,103,196,138,41,209,114,118,213,45,142,192,99,155,56,7,164,92,255,177,18,234,73,148,55,207,108,34,129,121,218,229,70,190,29,83,240,8,171,67,224,24,187,245,86,174,13,50,145,105,202,132,39,223,124,161,2,250,89,23,180,76,239,208,115,139,40,102,197,61,158,154,57,193,98,44,143,119,212,235,72,176,19,93,254,6,165,120,219,35,128,206,109,149,54,9,170,82,241,191,28,228,71,236,79,183,20,90,249,1,162,157,62,198,101,43,136,112,211,14,173,85,246,184,27,227,64,127,220,36,135,201,106,146,49,53,150,110,205,131,32,216,123,68,231,31,188,242,81,169,10,215,116,140,47,97,194,58,153,166,5,253,94,16,179,75,232},
{0,164,85,241,170,14,255,91,73,237,28,184,227,71,182,18,146,54,199,99,56,156,109,201,219,127,142,42,113,213,36,128,57,157,108,200,147,55,198,98,112,212,37,129,218,126,143,43,171,15,254,90,1,165,84,240,226,70,183,19,72,236,29,185,114,214,39,131,216,124,141,41,59,159,110,202,145,53,196,96,224,68,181,17,74,238,31,187,169,13,252,88,3,167,86,242,75,239,30,186,225,69,180,16,2,166,87,243,168,12,253,89,217,125,140,40,115,215,38,130,144,52,197,97,58,158,111,203,228,64,177,21,78,234,27,191,173,9,248,92,7,163,82,246,118,210,35,135,220,120,137,45,63,155,106,206,149,49,192,100,221,121,136,44,119,211,34,134,148,48,193,101,62,154,107,207,79,235,26,190,229,65,176,20,6,162,83,247,172,8,249,93,150,50,195,103,60,152,105,205,223,123,138,46,117,209,32,132,4,160,81,245,174,10,251,95,77,233,24,188,231,67,178,22,175,11,250,94,5,161,80,244,230,66,179,23,76,232,25,189,61,153,104,204,151,51,194,102,116,208,33,133,222,122,139,47},
{0,165,87,242,174,11,249,92,65,228,22,179,239,74,184,29,130,39,213,112,44,137,123,222,195,102,148,49,109,200,58,159,25,188,78,235,183,18,224,69,88,253,15,170,246,83,161,4,155,62,204,105,53,144,98,199,218,127,141,40,116,209,35,134,50,151,101,192,156,57,203,110,115,214,36,129,221,120,138,47,176,21,231,66,30,187,73,236,241,84,166,3,95,250,8,173,43,142,124,217,133,32,210,119,106,207,61,152,196,97,147,54,169,12,254,91,7,162,80,245,232,77,191,26,70,227,17,180,100,193,51,150,202,111,157,56,37,128,114,215,139,46,220,121,230,67,177,20,72,237,31,186,167,2,240,85,9,172,94,251,125,216,42,143,211,118,132,33,60,153,107,206,146,55,197,96,255,90,168,13,81,244,6,163,190,27,233,76,16,181,71,226,86,243,1,164,248,93,175,10,23,178,64,229,185,28,238,75,212,113,131,38,122,223,45,136,149,48,194,103,59,158,108,201,79,234,24,189,225,68,182,19,14,171,89,252,160,5,247,82,205,104,154,63,99,198,52,145,140,41,219,126,34,135,117,208},
{0,166,81,247,162,4,243,85,89,255,8,174,251,93,170,12,178,20,227,69,16,182,65,231,235,77,186,28,73,239,24,190,121,223,40,142,219,125,138,44,32,134,113,215,130,36,211,117,203,109,154,60,105,207,56,158,146,52,195,101,48,150,97,199,242,84,163,5,80,246,1,167,171,13,250,92,9,175,88,254,64,230,17,183,226,68,179,21,25,191,72,238,187,29,234,76,139,45,218,124,41,143,120,222,210,116,131,37,112,214,33,135,57,159,104,206,155,61,202,108,96,198,49,151,194,100,147,53,249,95,168,14,91,253,10,172,160,6,241,87,2,164,83,245,75,237,26,188,233,79,184,30,18,180,67,229,176,22,225,71,128,38,209,119,34,132,115,213,217,127,136,46,123,221,42,140,50,148,99,197,144,54,193,103,107,205,58,156,201,111,152,62,11,173,90,252,169,15,248,94,82,244,3,165,240,86,161,7,185,31,232,78,27,189,74,236,224,70,177,23,66,228,19,181,114,212,35,133,208,118,129,39,43,141,122,220,137,47,216,126,192,102,145,55,98,196,51,149,153,63,200,110,59,157,106,204},
{0,167,83,244,166,1,245,82,81,246,2,165,247,80,164,3,162,5,241,86,4,163,87,240,243,84,160,7,85,242,6,161,89,254,10,173,255,88,172,11,8,175,91,252,174,9,253,90,251,92,168,15,93,250,14,169,170,13,249,94,12,171,95,248,178,21,225,70,20,179,71,224,227,68,176,23,69,226,22,177,16,183,67,228,182,17,229,66,65,230,18,181,231,64,180,19,235,76,184,31,77,234,30,185,186,29,233,78,28,187,79,232,73,238,26,189,239,72,188,27,24,191,75,236,190,25,237,74,121,222,42,141,223,120,140,43,40,143,123,220,142,41,221,122,219,124,136,47,125,218,46,137,138,45,217,126,44,139,127,216,32,135,115,212,134,33,213,114,113,214,34,133,215,112,132,35,130,37,209,118,36,131,119,208,211,116,128,39,117,210,38,129,203,108,152,63,109,202,62,153,154,61,201,110,60,155,111,200,105,206,58,157,207,104,156,59,56,159,107,204,158,57,205,106,146,53,193,102,52,147,103,192,195,100,144,55,101,194,54,145,48,151,99,196,150,49,197,98,97,198,50,149,199,96,148,51},
{0,168,77,229,154,50,215,127,41,129,100,204,179,27,254,86,82,250,31,183,200,96,133,45,123,211,54,158,225,73,172,4,164,12,233,65,62,150,115,219,141,37,192,104,23,191,90,242,246,94,187,19,108,196,33,137,223,119,146,58,69,237,8,160,85,253,24,176,207,103,130,42,124,212,49,153,230,78,171,3,7,175,74,226,157,53,208,120,46,134,99,203,180,28,249,81,241,89,188,20,107,195,38,142,216,112,149,61,66,234,15,167,163,11,238,70,57,145,116,220,138,34,199,111,16,184,93,245,170,2,231,79,48,152,125,213,131,43,206,102,25,177,84,252,248,80,181,29,98,202,47,135,209,121,156,52,75,227,6,174,14,166,67,235,148,60,217,113,39,143,106,194,189,21,240,88,92,244,17,185,198,110,139,35,117,221,56,144,239,71,162,10,255,87,178,26,101,205,40,128,214,126,155,51,76,228,1,169,173,5,224,72,55,159,122,210,132,44,201,97,30,182,83,251,91,243,22,190,193,105,140,36,114,218,63,151,232,64,165,13,9,161,68,236,147,59,222,118,32,136,109,197,186,18,247,95},
{0,169,79,230,158,55,209,120,33,136,110,199,191,22,240,89,66,235,13,164,220,117,147,58,99,202,44,133,253,84,178,27,132,45,203,98,26,179,85,252,165,12,234,67,59,146,116,221,198,111,137,32,88,241,23,190,231,78,168,1,121,208,54,159,21,188,90,243,139,34,196,109,52,157,123,210,170,3,229,76,87,254,24,177,201,96,134,47,118,223,57,144,232,65,167,14,145,56,222,119,15,166,64,233,176,25,255,86,46,135,97,200,211,122,156,53,77,228,2,171,242,91,189,20,108,197,35,138,42,131,101,204,180,29,251,82,11,162,68,237,149,60,218,115,104,193,39,142,246,95,185,16,73,224,6,175,215,126,152,49,174,7,225,72,48,153,127,214,143,38,192,105,17,184,94,247,236,69,163,10,114,219,61,148,205,100,130,43,83,250,28,181,63,150,112,217,161,8,238,71,30,183,81,248,128,41,207,102,125,212,50,155,227,74,172,5,92,245,19,186,194,107,141,36,187,18,244,93,37,140,106,195,154,51,213,124,4,173,75,226,249,80,182,31,103,206,40,129,216,113,151,62,70,239,9,160},
{0,170,73,227,146,56,219,113,57,147,112,218,171,1,226,72,114,216,59,145,224,74,169,3,75,225,2,168,217,115,144,58,228,78,173,7,118,220,63,149,221,119,148,62,79,229,6,172,150,60,223,117,4,174,77,231,175,5,230,76,61,151,116,222,213,127,156,54,71,237,14,164,236,70,165,15,126,212,55,157,167,13,238,68,53,159,124,214,158,52,215,125,12,166,69,239,49,155,120,210,163,9,234,64,8,162,65,235,154,48,211,121,67,233,10,160,209,123,152,50,122,208,51,153,232,66,161,11,183,29,254,84,37,143,108,198,142,36,199,109,28,182,85,255,197,111,140,38,87,253,30,180,252,86,181,31,110,196,39,141,83,249,26,176,193,107,136,34,106,192,35,137,248,82,177,27,33,139,104,194,179,25,250,80,24,178,81,251,138,32,195,105,98,200,43,129,240,90,185,19,91,241,18,184,201,99,128,42,16,186,89,243,130,40,203,97,41,131,96,202,187,17,242,88,134,44,207,101,20,190,93,247,191,21,246,92,45,135,100,206,244,94,189,23,102,204,47,133,205,103,132,46,95,245,22,188},
{0,171,75,224,150,61,221,118,49,154,122,209,167,12,236,71,98,201,41,130,244,95,191,20,83,248,24,179,197,110,142,37,196,111,143,36,82,249,25,178,245,94,190,21,99,200,40,131,166,13,237,70,48,155,123,208,151,60,220,119,1,170,74,225,149,62,222,117,3,168,72,227,164,15,239,68,50,153,121,210,247,92,188,23,97,202,42,129,198,109,141,38,80,251,27,176,81,250,26,177,199,108,140,39,96,203,43,128,246,93,189,22,51,152,120,211,165,14,238,69,2,169,73,226,148,63,223,116,55,156,124,215,161,10,234,65,6,173,77,230,144,59,219,112,85,254,30,181,195,104,136,35,100,207,47,132,242,89,185,18,243,88,184,19,101,206,46,133,194,105,137,34,84,255,31,180,145,58,218,113,7,172,76,231,160,11,235,64,54,157,125,214,162,9,233,66,52,159,127,212,147,56,216,115,5,174,78,229,192,107,139,32,86,253,29,182,241,90,186,17,103,204,44,135,102,205,45,134,240,91,187,16,87,252,28,183,193,106,138,33,4,175,79,228,146,57,217,114,53,158,126,213,163,8,232,67},
{0,172,69,233,138,38,207,99,9,165,76,224,131,47,198,106,18,190,87,251,152,52,221,113,27,183,94,242,145,61,212,120,36,136,97,205,174,2,235,71,45,129,104,196,167,11,226,78,54,154,115,223,188,16,249,85,63,147,122,214,181,25,240,92,72,228,13,161,194,110,135,43,65,237,4,168,203,103,142,34,90,246,31,179,208,124,149,57,83,255,22,186,217,117,156,48,108,192,41,133,230,74,163,15,101,201,32,140,239,67,170,6,126,210,59,151,244,88,177,29,119,219,50,158,253,81,184,20,144,60,213,121,26,182,95,243,153,53,220,112,19,191,86,250,130,46,199,107,8,164,77,225,139,39,206,98,1,173,68,232,180,24,241,93,62,146,123,215,189,17,248,84,55,155,114,222,166,10,227,79,44,128,105,197,175,3,234,70,37,137,96,204,216,116,157,49,82,254,23,187,209,125,148,56,91,247,30,178,202,102,143,35,64,236,5,169,195,111,134,42,73,229,12,160,252,80,185,21,118,218,51,159,245,89,176,28,127,211,58,150,238,66,171,7,100,200,33,141,231,75,162,14,109,193,40,132},
{0,173,71,234,142,35,201,100,1,172,70,235,143,34,200,101,2,175,69,232,140,33,203,102,3,174,68,233,141,32,202,103,4,169,67,238,138,39,205,96,5,168,66,239,139,38,204,97,6,171,65,236,136,37,207,98,7,170,64,237,137,36,206,99,8,165,79,226,134,43,193,108,9,164,78,227,135,42,192,109,10,167,77,224,132,41,195,110,11,166,76,225,133,40,194,111,12,161,75,230,130,47,197,104,13,160,74,231,131,46,196,105,14,163,73,228,128,45,199,106,15,162,72,229,129,44,198,107,16,189,87,250,158,51,217,116,17,188,86,251,159,50,216,117,18,191,85,248,156,49,219,118,19,190,84,249,157,48,218,119,20,185,83,254,154,55,221,112,21,184,82,255,155,54,220,113,22,187,81,252,152,53,223,114,23,186,80,253,153,52,222,115,24,181,95,242,150,59,209,124,25,180,94,243,151,58,208,125,26,183,93,240,148,57,211,126,27,182,92,241,149,56,210,127,28,177,91,246,146,63,213,120,29,176,90,247,147,62,212,121,30,179,89,244,144,61,215,122,31,178,88,245,145,60,214,123},
{0,174,65,239,130,44,195,109,25,183,88,246,155,53,218,116,50,156,115,221,176,30,241,95,43,133,106,196,169,7,232,70,100,202,37,139,230,72,167,9,125,211,60,146,255,81,190,16,86,248,23,185,212,122,149,59,79,225,14,160,205,99,140,34,200,102,137,39,74,228,11,165,209,127,144,62,83,253,18,188,250,84,187,21,120,214,57,151,227,77,162,12,97,207,32,142,172,2,237,67,46,128,111,193,181,27,244,90,55,153,118,216,158,48,223,113,28,178,93,243,135,41,198,104,5,171,68,234,141,35,204,98,15,161,78,224,148,58,213,123,22,184,87,249,191,17,254,80,61,147,124,210,166,8,231,73,36,138,101,203,233,71,168,6,107,197,42,132,240,94,177,31,114,220,51,157,219,117,154,52,89,247,24,182,194,108,131,45,64,238,1,175,69,235,4,170,199,105,134,40,92,242,29,179,222,112,159,49,119,217,54,152,245,91,180,26,110,192,47,129,236,66,173,3,33,143,96,206,163,13,226,76,56,150,121,215,186,20,251,85,19,189,82,252,145,63,208,126,10,164,75,229,136,38,201,103},
{0,175,67,236,134,41,197,106,17,190,82,253,151,56,212,123,34,141,97,206,164,11,231,72,51,156,112,223,181,26,246,89,68,235,7,168,194,109,129,46,85,250,22,185,211,124,144,63,102,201,37,138,224,79,163,12,119,216,52,155,241,94,178,29,136,39,203,100,14,161,77,226,153,54,218,117,31,176,92,243,170,5,233,70,44,131,111,192,187,20,248,87,61,146,126,209,204,99,143,32,74,229,9,166,221,114,158,49,91,244,24,183,238,65,173,2,104,199,43,132,255,80,188,19,121,214,58,149,13,162,78,225,139,36,200,103,28,179,95,240,154,53,217,118,47,128,108,195,169,6,234,69,62,145,125,210,184,23,251,84,73,230,10,165,207,96,140,35,88,247,27,180,222,113,157,50,107,196,40,135,237,66,174,1,122,213,57,150,252,83,191,16,133,42,198,105,3,172,64,239,148,59,215,120,18,189,81,254,167,8,228,75,33,142,98,205,182,25,245,90,48,159,115,220,193,110,130,45,71,232,4,171,208,127,147,60,86,249,21,186,227,76,160,15,101,202,38,137,242,93,177,30,116,219,55,152},
{0,176,125,205,250,74,135,55,233,89,148,36,19,163,110,222,207,127,178,2,53,133,72,248,38,150,91,235,220,108,161,17,131,51,254,78,121,201,4,180,106,218,23,167,144,32,237,93,76,252,49,129,182,6,203,123,165,21,216,104,95,239,34,146,27,171,102,214,225,81,156,44,242,66,143,63,8,184,117,197,212,100,169,25,46,158,83,227,61,141,64,240,199,119,186,10,152,40,229,85,98,210,31,175,113,193,12,188,139,59,246,70,87,231,42,154,173,29,208,96,190,14,195,115,68,244,57,137,54,134,75,251,204,124,177,1,223,111,162,18,37,149,88,232,249,73,132,52,3,179,126,206,16,160,109,221,234,90,151,39,181,5,200,120,79,255,50,130,92,236,33,145,166,22,219,107,122,202,7,183,128,48,253,77,147,35,238,94,105,217,20,164,45,157,80,224,215,103,170,26,196,116,185,9,62,142,67,243,226,82,159,47,24,168,101,213,11,187,118,198,241,65,140,60,174,30,211,99,84,228,41,153,71,247,58,138,189,13,192,112,97,209,28,172,155,43,230,86,136,56,245,69,114,194,15,191},
{0,177,127,206,254,79,129,48,225,80,158,47,31,174,96,209,223,110,160,17,33,144,94,239,62,143,65,240,192,113,191,14,163,18,220,109,93,236,34,147,66,243,61,140,188,13,195,114,124,205,3,178,130,51,253,76,157,44,226,83,99,210,28,173,91,234,36,149,165,20,218,107,186,11,197,116,68,245,59,138,132,53,251,74,122,203,5,180,101,212,26,171,155,42,228,85,248,73,135,54,6,183,121,200,25,168,102,215,231,86,152,41,39,150,88,233,217,104,166,23,198,119,185,8,56,137,71,246,182,7,201,120,72,249,55,134,87,230,40,153,169,24,214,103,105,216,22,167,151,38,232,89,136,57,247,70,118,199,9,184,21,164,106,219,235,90,148,37,244,69,139,58,10,187,117,196,202,123,181,4,52,133,75,250,43,154,84,229,213,100,170,27,237,92,146,35,19,162,108,221,12,189,115,194,242,67,141,60,50,131,77,252,204,125,179,2,211,98,172,29,45,156,82,227,78,255,49,128,176,1,207,126,175,30,208,97,81,224,46,159,145,32,238,95,111,222,16,161,112,193,15,190,142,63,241,64},
{0,178,121,203,242,64,139,57,249,75,128,50,11,185,114,192,239,93,150,36,29,175,100,214,22,164,111,221,228,86,157,47,195,113,186,8,49,131,72,250,58,136,67,241,200,122,177,3,44,158,85,231,222,108,167,21,213,103,172,30,39,149,94,236,155,41,226,80,105,219,16,162,98,208,27,169,144,34,233,91,116,198,13,191,134,52,255,77,141,63,244,70,127,205,6,180,88,234,33,147,170,24,211,97,161,19,216,106,83,225,42,152,183,5,206,124,69,247,60,142,78,252,55,133,188,14,197,119,43,153,82,224,217,107,160,18,210,96,171,25,32,146,89,235,196,118,189,15,54,132,79,253,61,143,68,246,207,125,182,4,232,90,145,35,26,168,99,209,17,163,104,218,227,81,154,40,7,181,126,204,245,71,140,62,254,76,135,53,12,190,117,199,176,2,201,123,66,240,59,137,73,251,48,130,187,9,194,112,95,237,38,148,173,31,212,102,166,20,223,109,84,230,45,159,115,193,10,184,129,51,248,74,138,56,243,65,120,202,1,179,156,46,229,87,110,220,23,165,101,215,28,174,151,37,238,92},
{0,179,123,200,246,69,141,62,241,66,138,57,7,180,124,207,255,76,132,55,9,186,114,193,14,189,117,198,248,75,131,48,227,80,152,43,21,166,110,221,18,161,105,218,228,87,159,44,28,175,103,212,234,89,145,34,237,94,150,37,27,168,96,211,219,104,160,19,45,158,86,229,42,153,81,226,220,111,167,20,36,151,95,236,210,97,169,26,213,102,174,29,35,144,88,235,56,139,67,240,206,125,181,6,201,122,178,1,63,140,68,247,199,116,188,15,49,130,74,249,54,133,77,254,192,115,187,8,171,24,208,99,93,238,38,149,90,233,33,146,172,31,215,100,84,231,47,156,162,17,217,106,165,22,222,109,83,224,40,155,72,251,51,128,190,13,197,118,185,10,194,113,79,252,52,135,183,4,204,127,65,242,58,137,70,245,61,142,176,3,203,120,112,195,11,184,134,53,253,78,129,50,250,73,119,196,12,191,143,60,244,71,121,202,2,177,126,205,5,182,136,59,243,64,147,32,232,91,101,214,30,173,98,209,25,170,148,39,239,92,108,223,23,164,154,41,225,82,157,46,230,85,107,216,16,163},
{0,180,117,193,234,94,159,43,201,125,188,8,35,151,86,226,143,59,250,78,101,209,16,164,70,242,51,135,172,24,217,109,3,183,118,194,233,93,156,40,202,126,191,11,32,148,85,225,140,56,249,77,102,210,19,167,69,241,48,132,175,27,218,110,6,178,115,199,236,88,153,45,207,123,186,14,37,145,80,228,137,61,252,72,99,215,22,162,64,244,53,129,170,30,223,107,5,177,112,196,239,91,154,46,204,120,185,13,38,146,83,231,138,62,255,75,96,212,21,161,67,247,54,130,169,29,220,104,12,184,121,205,230,82,147,39,197,113,176,4,47,155,90,238,131,55,246,66,105,221,28,168,74,254,63,139,160,20,213,97,15,187,122,206,229,81,144,36,198,114,179,7,44,152,89,237,128,52,245,65,106,222,31,171,73,253,60,136,163,23,214,98,10,190,127,203,224,84,149,33,195,119,182,2,41,157,92,232,133,49,240,68,111,219,26,174,76,248,57,141,166,18,211,103,9,189,124,200,227,87,150,34,192,116,181,1,42,158,95,235,134,50,243,71,108,216,25,173,79,251,58,142,165,17,208,100},
{0,181,119,194,238,91,153,44,193,116,182,3,47,154,88,237,159,42,232,93,113,196,6,179,94,235,41,156,176,5,199,114,35,150,84,225,205,120,186,15,226,87,149,32,12,185,123,206,188,9,203,126,82,231,37,144,125,200,10,191,147,38,228,81,70,243,49,132,168,29,223,106,135,50,240,69,105,220,30,171,217,108,174,27,55,130,64,245,24,173,111,218,246,67,129,52,101,208,18,167,139,62,252,73,164,17,211,102,74,255,61,136,250,79,141,56,20,161,99,214,59,142,76,249,213,96,162,23,140,57,251,78,98,215,21,160,77,248,58,143,163,22,212,97,19,166,100,209,253,72,138,63,210,103,165,16,60,137,75,254,175,26,216,109,65,244,54,131,110,219,25,172,128,53,247,66,48,133,71,242,222,107,169,28,241,68,134,51,31,170,104,221,202,127,189,8,36,145,83,230,11,190,124,201,229,80,146,39,85,224,34,151,187,14,204,121,148,33,227,86,122,207,13,184,233,92,158,43,7,178,112,197,40,157,95,234,198,115,177,4,118,195,1,180,152,45,239,90,183,2,192,117,89,236,46,155},
{0,182,113,199,226,84,147,37,217,111,168,30,59,141,74,252,175,25,222,104,77,251,60,138,118,192,7,177,148,34,229,83,67,245,50,132,161,23,208,102,154,44,235,93,120,206,9,191,236,90,157,43,14,184,127,201,53,131,68,242,215,97,166,16,134,48,247,65,100,210,21,163,95,233,46,152,189,11,204,122,41,159,88,238,203,125,186,12,240,70,129,55,18,164,99,213,197,115,180,2,39,145,86,224,28,170,109,219,254,72,143,57,106,220,27,173,136,62,249,79,179,5,194,116,81,231,32,150,17,167,96,214,243,69,130,52,200,126,185,15,42,156,91,237,190,8,207,121,92,234,45,155,103,209,22,160,133,51,244,66,82,228,35,149,176,6,193,119,139,61,250,76,105,223,24,174,253,75,140,58,31,169,110,216,36,146,85,227,198,112,183,1,151,33,230,80,117,195,4,178,78,248,63,137,172,26,221,107,56,142,73,255,218,108,171,29,225,87,144,38,3,181,114,196,212,98,165,19,54,128,71,241,13,187,124,202,239,89,158,40,123,205,10,188,153,47,232,94,162,20,211,101,64,246,49,135},
{0,183,115,196,230,81,149,34,209,102,162,21,55,128,68,243,191,8,204,123,89,238,42,157,110,217,29,170,136,63,251,76,99,212,16,167,133,50,246,65,178,5,193,118,84,227,39,144,220,107,175,24,58,141,73,254,13,186,126,201,235,92,152,47,198,113,181,2,32,151,83,228,23,160,100,211,241,70,130,53,121,206,10,189,159,40,236,91,168,31,219,108,78,249,61,138,165,18,214,97,67,244,48,135,116,195,7,176,146,37,225,86,26,173,105,222,252,75,143,56,203,124,184,15,45,154,94,233,145,38,226,85,119,192,4,179,64,247,51,132,166,17,213,98,46,153,93,234,200,127,187,12,255,72,140,59,25,174,106,221,242,69,129,54,20,163,103,208,35,148,80,231,197,114,182,1,77,250,62,137,171,28,216,111,156,43,239,88,122,205,9,190,87,224,36,147,177,6,194,117,134,49,245,66,96,215,19,164,232,95,155,44,14,185,125,202,57,142,74,253,223,104,172,27,52,131,71,240,210,101,161,22,229,82,150,33,3,180,112,199,139,60,248,79,109,218,30,169,90,237,41,158,188,11,207,120},
{0,184,109,213,218,98,183,15,169,17,196,124,115,203,30,166,79,247,34,154,149,45,248,64,230,94,139,51,60,132,81,233,158,38,243,75,68,252,41,145,55,143,90,226,237,85,128,56,209,105,188,4,11,179,102,222,120,192,21,173,162,26,207,119,33,153,76,244,251,67,150,46,136,48,229,93,82,234,63,135,110,214,3,187,180,12,217,97,199,127,170,18,29,165,112,200,191,7,210,106,101,221,8,176,22,174,123,195,204,116,161,25,240,72,157,37,42,146,71,255,89,225,52,140,131,59,238,86,66,250,47,151,152,32,245,77,235,83,134,62,49,137,92,228,13,181,96,216,215,111,186,2,164,28,201,113,126,198,19,171,220,100,177,9,6,190,107,211,117,205,24,160,175,23,194,122,147,43,254,70,73,241,36,156,58,130,87,239,224,88,141,53,99,219,14,182,185,1,212,108,202,114,167,31,16,168,125,197,44,148,65,249,246,78,155,35,133,61,232,80,95,231,50,138,253,69,144,40,39,159,74,242,84,236,57,129,142,54,227,91,178,10,223,103,104,208,5,189,27,163,118,206,193,121,172,20},
{0,185,111,214,222,103,177,8,161,24,206,119,127,198,16,169,95,230,48,137,129,56,238,87,254,71,145,40,32,153,79,246,190,7,209,104,96,217,15,182,31,166,112,201,193,120,174,23,225,88,142,55,63,134,80,233,64,249,47,150,158,39,241,72,97,216,14,183,191,6,208,105,192,121,175,22,30,167,113,200,62,135,81,232,224,89,143,54,159,38,240,73,65,248,46,151,223,102,176,9,1,184,110,215,126,199,17,168,160,25,207,118,128,57,239,86,94,231,49,136,33,152,78,247,255,70,144,41,194,123,173,20,28,165,115,202,99,218,12,181,189,4,210,107,157,36,242,75,67,250,44,149,60,133,83,234,226,91,141,52,124,197,19,170,162,27,205,116,221,100,178,11,3,186,108,213,35,154,76,245,253,68,146,43,130,59,237,84,92,229,51,138,163,26,204,117,125,196,18,171,2,187,109,212,220,101,179,10,252,69,147,42,34,155,77,244,93,228,50,139,131,58,236,85,29,164,114,203,195,122,172,21,188,5,211,106,98,219,13,180,66,251,45,148,156,37,243,74,227,90,140,53,61,132,82,235},
{0,186,105,211,210,104,187,1,185,3,208,106,107,209,2,184,111,213,6,188,189,7,212,110,214,108,191,5,4,190,109,215,222,100,183,13,12,182,101,223,103,221,14,180,181,15,220,102,177,11,216,98,99,217,10,176,8,178,97,219,218,96,179,9,161,27,200,114,115,201,26,160,24,162,113,203,202,112,163,25,206,116,167,29,28,166,117,207,119,205,30,164,165,31,204,118,127,197,22,172,173,23,196,126,198,124,175,21,20,174,125,199,16,170,121,195,194,120,171,17,169,19,192,122,123,193,18,168,95,229,54,140,141,55,228,94,230,92,143,53,52,142,93,231,48,138,89,227,226,88,139,49,137,51,224,90,91,225,50,136,129,59,232,82,83,233,58,128,56,130,81,235,234,80,131,57,238,84,135,61,60,134,85,239,87,237,62,132,133,63,236,86,254,68,151,45,44,150,69,255,71,253,46,148,149,47,252,70,145,43,248,66,67,249,42,144,40,146,65,251,250,64,147,41,32,154,73,243,242,72,155,33,153,35,240,74,75,241,34,152,79,245,38,156,157,39,244,78,246,76,159,37,36,158,77,247},
{0,187,107,208,214,109,189,6,177,10,218,97,103,220,12,183,127,196,20,175,169,18,194,121,206,117,165,30,24,163,115,200,254,69,149,46,40,147,67,248,79,244,36,159,153,34,242,73,129,58,234,81,87,236,60,135,48,139,91,224,230,93,141,54,225,90,138,49,55,140,92,231,80,235,59,128,134,61,237,86,158,37,245,78,72,243,35,152,47,148,68,255,249,66,146,41,31,164,116,207,201,114,162,25,174,21,197,126,120,195,19,168,96,219,11,176,182,13,221,102,209,106,186,1,7,188,108,215,223,100,180,15,9,178,98,217,110,213,5,190,184,3,211,104,160,27,203,112,118,205,29,166,17,170,122,193,199,124,172,23,33,154,74,241,247,76,156,39,144,43,251,64,70,253,45,150,94,229,53,142,136,51,227,88,239,84,132,63,57,130,82,233,62,133,85,238,232,83,131,56,143,52,228,95,89,226,50,137,65,250,42,145,151,44,252,71,240,75,155,32,38,157,77,246,192,123,171,16,22,173,125,198,113,202,26,161,167,28,204,119,191,4,212,111,105,210,2,185,14,181,101,222,216,99,179,8},
{0,188,101,217,202,118,175,19,137,53,236,80,67,255,38,154,15,179,106,214,197,121,160,28,134,58,227,95,76,240,41,149,30,162,123,199,212,104,177,13,151,43,242,78,93,225,56,132,17,173,116,200,219,103,190,2,152,36,253,65,82,238,55,139,60,128,89,229,246,74,147,47,181,9,208,108,127,195,26,166,51,143,86,234,249,69,156,32,186,6,223,99,112,204,21,169,34,158,71,251,232,84,141,49,171,23,206,114,97,221,4,184,45,145,72,244,231,91,130,62,164,24,193,125,110,210,11,183,120,196,29,161,178,14,215,107,241,77,148,40,59,135,94,226,119,203,18,174,189,1,216,100,254,66,155,39,52,136,81,237,102,218,3,191,172,16,201,117,239,83,138,54,37,153,64,252,105,213,12,176,163,31,198,122,224,92,133,57,42,150,79,243,68,248,33,157,142,50,235,87,205,113,168,20,7,187,98,222,75,247,46,146,129,61,228,88,194,126,167,27,8,180,109,209,90,230,63,131,144,44,245,73,211,111,182,10,25,165,124,192,85,233,48,140,159,35,250,70,220,96,185,5,22,170,115,207},
{0,189,103,218,206,115,169,20,129,60,230,91,79,242,40,149,31,162,120,197,209,108,182,11,158,35,249,68,80,237,55,138,62,131,89,228,240,77,151,42,191,2,216,101,113,204,22,171,33,156,70,251,239,82,136,53,160,29,199,122,110,211,9,180,124,193,27,166,178,15,213,104,253,64,154,39,51,142,84,233,99,222,4,185,173,16,202,119,226,95,133,56,44,145,75,246,66,255,37,152,140,49,235,86,195,126,164,25,13,176,106,215,93,224,58,135,147,46,244,73,220,97,187,6,18,175,117,200,248,69,159,34,54,139,81,236,121,196,30,163,183,10,208,109,231,90,128,61,41,148,78,243,102,219,1,188,168,21,207,114,198,123,161,28,8,181,111,210,71,250,32,157,137,52,238,83,217,100,190,3,23,170,112,205,88,229,63,130,150,43,241,76,132,57,227,94,74,247,45,144,5,184,98,223,203,118,172,17,155,38,252,65,85,232,50,143,26,167,125,192,212,105,179,14,186,7,221,96,116,201,19,174,59,134,92,225,245,72,146,47,165,24,194,127,107,214,12,177,36,153,67,254,234,87,141,48},
{0,190,97,223,194,124,163,29,153,39,248,70,91,229,58,132,47,145,78,240,237,83,140,50,182,8,215,105,116,202,21,171,94,224,63,129,156,34,253,67,199,121,166,24,5,187,100,218,113,207,16,174,179,13,210,108,232,86,137,55,42,148,75,245,188,2,221,99,126,192,31,161,37,155,68,250,231,89,134,56,147,45,242,76,81,239,48,142,10,180,107,213,200,118,169,23,226,92,131,61,32,158,65,255,123,197,26,164,185,7,216,102,205,115,172,18,15,177,110,208,84,234,53,139,150,40,247,73,101,219,4,186,167,25,198,120,252,66,157,35,62,128,95,225,74,244,43,149,136,54,233,87,211,109,178,12,17,175,112,206,59,133,90,228,249,71,152,38,162,28,195,125,96,222,1,191,20,170,117,203,214,104,183,9,141,51,236,82,79,241,46,144,217,103,184,6,27,165,122,196,64,254,33,159,130,60,227,93,246,72,151,41,52,138,85,235,111,209,14,176,173,19,204,114,135,57,230,88,69,251,36,154,30,160,127,193,220,98,189,3,168,22,201,119,106,212,11,181,49,143,80,238,243,77,146,44},
{0,191,99,220,198,121,165,26,145,46,242,77,87,232,52,139,63,128,92,227,249,70,154,37,174,17,205,114,104,215,11,180,126,193,29,162,184,7,219,100,239,80,140,51,41,150,74,245,65,254,34,157,135,56,228,91,208,111,179,12,22,169,117,202,252,67,159,32,58,133,89,230,109,210,14,177,171,20,200,119,195,124,160,31,5,186,102,217,82,237,49,142,148,43,247,72,130,61,225,94,68,251,39,152,19,172,112,207,213,106,182,9,189,2,222,97,123,196,24,167,44,147,79,240,234,85,137,54,229,90,134,57,35,156,64,255,116,203,23,168,178,13,209,110,218,101,185,6,28,163,127,192,75,244,40,151,141,50,238,81,155,36,248,71,93,226,62,129,10,181,105,214,204,115,175,16,164,27,199,120,98,221,1,190,53,138,86,233,243,76,144,47,25,166,122,197,223,96,188,3,136,55,235,84,78,241,45,146,38,153,69,250,224,95,131,60,183,8,212,107,113,206,18,173,103,216,4,187,161,30,194,125,246,73,149,42,48,143,83,236,88,231,59,132,158,33,253,66,201,118,170,21,15,176,108,211},
{0,192,157,93,39,231,186,122,78,142,211,19,105,169,244,52,156,92,1,193,187,123,38,230,210,18,79,143,245,53,104,168,37,229,184,120,2,194,159,95,107,171,246,54,76,140,209,17,185,121,36,228,158,94,3,195,247,55,106,170,208,16,77,141,74,138,215,23,109,173,240,48,4,196,153,89,35,227,190,126,214,22,75,139,241,49,108,172,152,88,5,197,191,127,34,226,111,175,242,50,72,136,213,21,33,225,188,124,6,198,155,91,243,51,110,174,212,20,73,137,189,125,32,224,154,90,7,199,148,84,9,201,179,115,46,238,218,26,71,135,253,61,96,160,8,200,149,85,47,239,178,114,70,134,219,27,97,161,252,60,177,113,44,236,150,86,11,203,255,63,98,162,216,24,69,133,45,237,176,112,10,202,151,87,99,163,254,62,68,132,217,25,222,30,67,131,249,57,100,164,144,80,13,205,183,119,42,234,66,130,223,31,101,165,248,56,12,204,145,81,43,235,182,118,251,59,102,166,220,28,65,129,181,117,40,232,146,82,15,207,103,167,250,58,64,128,221,29,41,233,180,116,14,206,147,83},
{0,193,159,94,35,226,188,125,70,135,217,24,101,164,250,59,140,77,19,210,175,110,48,241,202,11,85,148,233,40,118,183,5,196,154,91,38,231,185,120,67,130,220,29,96,161,255,62,137,72,22,215,170,107,53,244,207,14,80,145,236,45,115,178,10,203,149,84,41,232,182,119,76,141,211,18,111,174,240,49,134,71,25,216,165,100,58,251,192,1,95,158,227,34,124,189,15,206,144,81,44,237,179,114,73,136,214,23,106,171,245,52,131,66,28,221,160,97,63,254,197,4,90,155,230,39,121,184,20,213,139,74,55,246,168,105,82,147,205,12,113,176,238,47,152,89,7,198,187,122,36,229,222,31,65,128,253,60,98,163,17,208,142,79,50,243,173,108,87,150,200,9,116,181,235,42,157,92,2,195,190,127,33,224,219,26,68,133,248,57,103,166,30,223,129,64,61,252,162,99,88,153,199,6,123,186,228,37,146,83,13,204,177,112,46,239,212,21,75,138,247,54,104,169,27,218,132,69,56,249,167,102,93,156,194,3,126,191,225,32,151,86,8,201,180,117,43,234,209,16,78,143,242,51,109,172},
{0,194,153,91,47,237,182,116,94,156,199,5,113,179,232,42,188,126,37,231,147,81,10,200,226,32,123,185,205,15,84,150,101,167,252,62,74,136,211,17,59,249,162,96,20,214,141,79,217,27,64,130,246,52,111,173,135,69,30,220,168,106,49,243,202,8,83,145,229,39,124,190,148,86,13,207,187,121,34,224,118,180,239,45,89,155,192,2,40,234,177,115,7,197,158,92,175,109,54,244,128,66,25,219,241,51,104,170,222,28,71,133,19,209,138,72,60,254,165,103,77,143,212,22,98,160,251,57,137,75,16,210,166,100,63,253,215,21,78,140,248,58,97,163,53,247,172,110,26,216,131,65,107,169,242,48,68,134,221,31,236,46,117,183,195,1,90,152,178,112,43,233,157,95,4,198,80,146,201,11,127,189,230,36,14,204,151,85,33,227,184,122,67,129,218,24,108,174,245,55,29,223,132,70,50,240,171,105,255,61,102,164,208,18,73,139,161,99,56,250,142,76,23,213,38,228,191,125,9,203,144,82,120,186,225,35,87,149,206,12,154,88,3,193,181,119,44,238,196,6,93,159,235,41,114,176},
{0,195,155,88,43,232,176,115,86,149,205,14,125,190,230,37,172,111,55,244,135,68,28,223,250,57,97,162,209,18,74,137,69,134,222,29,110,173,245,54,19,208,136,75,56,251,163,96,233,42,114,177,194,1,89,154,191,124,36,231,148,87,15,204,138,73,17,210,161,98,58,249,220,31,71,132,247,52,108,175,38,229,189,126,13,206,150,85,112,179,235,40,91,152,192,3,207,12,84,151,228,39,127,188,153,90,2,193,178,113,41,234,99,160,248,59,72,139,211,16,53,246,174,109,30,221,133,70,9,202,146,81,34,225,185,122,95,156,196,7,116,183,239,44,165,102,62,253,142,77,21,214,243,48,104,171,216,27,67,128,76,143,215,20,103,164,252,63,26,217,129,66,49,242,170,105,224,35,123,184,203,8,80,147,182,117,45,238,157,94,6,197,131,64,24,219,168,107,51,240,213,22,78,141,254,61,101,166,47,236,180,119,4,199,159,92,121,186,226,33,82,145,201,10,198,5,93,158,237,46,118,181,144,83,11,200,187,120,32,227,106,169,241,50,65,130,218,25,60,255,167,100,23,212,140,79},
{0,196,149,81,55,243,162,102,110,170,251,63,89,157,204,8,220,24,73,141,235,47,126,186,178,118,39,227,133,65,16,212,165,97,48,244,146,86,7,195,203,15,94,154,252,56,105,173,121,189,236,40,78,138,219,31,23,211,130,70,32,228,181,113,87,147,194,6,96,164,245,49,57,253,172,104,14,202,155,95,139,79,30,218,188,120,41,237,229,33,112,180,210,22,71,131,242,54,103,163,197,1,80,148,156,88,9,205,171,111,62,250,46,234,187,127,25,221,140,72,64,132,213,17,119,179,226,38,174,106,59,255,153,93,12,200,192,4,85,145,247,51,98,166,114,182,231,35,69,129,208,20,28,216,137,77,43,239,190,122,11,207,158,90,60,248,169,109,101,161,240,52,82,150,199,3,215,19,66,134,224,36,117,177,185,125,44,232,142,74,27,223,249,61,108,168,206,10,91,159,151,83,2,198,160,100,53,241,37,225,176,116,18,214,135,67,75,143,222,26,124,184,233,45,92,152,201,13,107,175,254,58,50,246,167,99,5,193,144,84,128,68,21,209,183,115,34,230,238,42,123,191,217,29,76,136},
{0,197,151,82,51,246,164,97,102,163,241,52,85,144,194,7,204,9,91,158,255,58,104,173,170,111,61,248,153,92,14,203,133,64,18,215,182,115,33,228,227,38,116,177,208,21,71,130,73,140,222,27,122,191,237,40,47,234,184,125,28,217,139,78,23,210,128,69,36,225,179,118,113,180,230,35,66,135,213,16,219,30,76,137,232,45,127,186,189,120,42,239,142,75,25,220,146,87,5,192,161,100,54,243,244,49,99,166,199,2,80,149,94,155,201,12,109,168,250,63,56,253,175,106,11,206,156,89,46,235,185,124,29,216,138,79,72,141,223,26,123,190,236,41,226,39,117,176,209,20,70,131,132,65,19,214,183,114,32,229,171,110,60,249,152,93,15,202,205,8,90,159,254,59,105,172,103,162,240,53,84,145,195,6,1,196,150,83,50,247,165,96,57,252,174,107,10,207,157,88,95,154,200,13,108,169,251,62,245,48,98,167,198,3,81,148,147,86,4,193,160,101,55,242,188,121,43,238,143,74,24,221,218,31,77,136,233,44,126,187,112,181,231,34,67,134,212,17,22,211,129,68,37,224,178,119},
{0,198,145,87,63,249,174,104,126,184,239,41,65,135,208,22,252,58,109,171,195,5,82,148,130,68,19,213,189,123,44,234,229,35,116,178,218,28,75,141,155,93,10,204,164,98,53,243,25,223,136,78,38,224,183,113,103,161,246,48,88,158,201,15,215,17,70,128,232,46,121,191,169,111,56,254,150,80,7,193,43,237,186,124,20,210,133,67,85,147,196,2,106,172,251,61,50,244,163,101,13,203,156,90,76,138,221,27,115,181,226,36,206,8,95,153,241,55,96,166,176,118,33,231,143,73,30,216,179,117,34,228,140,74,29,219,205,11,92,154,242,52,99,165,79,137,222,24,112,182,225,39,49,247,160,102,14,200,159,89,86,144,199,1,105,175,248,62,40,238,185,127,23,209,134,64,170,108,59,253,149,83,4,194,212,18,69,131,235,45,122,188,100,162,245,51,91,157,202,12,26,220,139,77,37,227,180,114,152,94,9,207,167,97,54,240,230,32,119,177,217,31,72,142,129,71,16,214,190,120,47,233,255,57,110,168,192,6,81,151,125,187,236,42,66,132,211,21,3,197,146,84,60,250,173,107},
{0,199,147,84,59,252,168,111,118,177,229,34,77,138,222,25,236,43,127,184,215,16,68,131,154,93,9,206,161,102,50,245,197,2,86,145,254,57,109,170,179,116,32,231,136,79,27,220,41,238,186,125,18,213,129,70,95,152,204,11,100,163,247,48,151,80,4,195,172,107,63,248,225,38,114,181,218,29,73,142,123,188,232,47,64,135,211,20,13,202,158,89,54,241,165,98,82,149,193,6,105,174,250,61,36,227,183,112,31,216,140,75,190,121,45,234,133,66,22,209,200,15,91,156,243,52,96,167,51,244,160,103,8,207,155,92,69,130,214,17,126,185,237,42,223,24,76,139,228,35,119,176,169,110,58,253,146,85,1,198,246,49,101,162,205,10,94,153,128,71,19,212,187,124,40,239,26,221,137,78,33,230,178,117,108,171,255,56,87,144,196,3,164,99,55,240,159,88,12,203,210,21,65,134,233,46,122,189,72,143,219,28,115,180,224,39,62,249,173,106,5,194,150,81,97,166,242,53,90,157,201,14,23,208,132,67,44,235,191,120,141,74,30,217,182,113,37,226,251,60,104,175,192,7,83,148},
{0,200,141,69,7,207,138,66,14,198,131,75,9,193,132,76,28,212,145,89,27,211,150,94,18,218,159,87,21,221,152,80,56,240,181,125,63,247,178,122,54,254,187,115,49,249,188,116,36,236,169,97,35,235,174,102,42,226,167,111,45,229,160,104,112,184,253,53,119,191,250,50,126,182,243,59,121,177,244,60,108,164,225,41,107,163,230,46,98,170,239,39,101,173,232,32,72,128,197,13,79,135,194,10,70,142,203,3,65,137,204,4,84,156,217,17,83,155,222,22,90,146,215,31,93,149,208,24,224,40,109,165,231,47,106,162,238,38,99,171,233,33,100,172,252,52,113,185,251,51,118,190,242,58,127,183,245,61,120,176,216,16,85,157,223,23,82,154,214,30,91,147,209,25,92,148,196,12,73,129,195,11,78,134,202,2,71,143,205,5,64,136,144,88,29,213,151,95,26,210,158,86,19,219,153,81,20,220,140,68,1,201,139,67,6,206,130,74,15,199,133,77,8,192,168,96,37,237,175,103,34,234,166,110,43,227,161,105,44,228,180,124,57,241,179,123,62,246,186,114,55,255,189,117,48,248},
{0,201,143,70,3,202,140,69,6,207,137,64,5,204,138,67,12,197,131,74,15,198,128,73,10,195,133,76,9,192,134,79,24,209,151,94,27,210,148,93,30,215,145,88,29,212,146,91,20,221,155,82,23,222,152,81,18,219,157,84,17,216,158,87,48,249,191,118,51,250,188,117,54,255,185,112,53,252,186,115,60,245,179,122,63,246,176,121,58,243,181,124,57,240,182,127,40,225,167,110,43,226,164,109,46,231,161,104,45,228,162,107,36,237,171,98,39,238,168,97,34,235,173,100,33,232,174,103,96,169,239,38,99,170,236,37,102,175,233,32,101,172,234,35,108,165,227,42,111,166,224,41,106,163,229,44,105,160,230,47,120,177,247,62,123,178,244,61,126,183,241,56,125,180,242,59,116,189,251,50,119,190,248,49,114,187,253,52,113,184,254,55,80,153,223,22,83,154,220,21,86,159,217,16,85,156,218,19,92,149,211,26,95,150,208,25,90,147,213,28,89,144,214,31,72,129,199,14,75,130,196,13,78,135,193,8,77,132,194,11,68,141,203,2,71,142,200,1,66,139,205,4,65,136,206,7},
{0,202,137,67,15,197,134,76,30,212,151,93,17,219,152,82,60,246,181,127,51,249,186,112,34,232,171,97,45,231,164,110,120,178,241,59,119,189,254,52,102,172,239,37,105,163,224,42,68,142,205,7,75,129,194,8,90,144,211,25,85,159,220,22,240,58,121,179,255,53,118,188,238,36,103,173,225,43,104,162,204,6,69,143,195,9,74,128,210,24,91,145,221,23,84,158,136,66,1,203,135,77,14,196,150,92,31,213,153,83,16,218,180,126,61,247,187,113,50,248,170,96,35,233,165,111,44,230,253,55,116,190,242,56,123,177,227,41,106,160,236,38,101,175,193,11,72,130,206,4,71,141,223,21,86,156,208,26,89,147,133,79,12,198,138,64,3,201,155,81,18,216,148,94,29,215,185,115,48,250,182,124,63,245,167,109,46,228,168,98,33,235,13,199,132,78,2,200,139,65,19,217,154,80,28,214,149,95,49,251,184,114,62,244,183,125,47,229,166,108,32,234,169,99,117,191,252,54,122,176,243,57,107,161,226,40,100,174,237,39,73,131,192,10,70,140,207,5,87,157,222,20,88,146,209,27},
{0,203,139,64,11,192,128,75,22,221,157,86,29,214,150,93,44,231,167,108,39,236,172,103,58,241,177,122,49,250,186,113,88,147,211,24,83,152,216,19,78,133,197,14,69,142,206,5,116,191,255,52,127,180,244,63,98,169,233,34,105,162,226,41,176,123,59,240,187,112,48,251,166,109,45,230,173,102,38,237,156,87,23,220,151,92,28,215,138,65,1,202,129,74,10,193,232,35,99,168,227,40,104,163,254,53,117,190,245,62,126,181,196,15,79,132,207,4,68,143,210,25,89,146,217,18,82,153,125,182,246,61,118,189,253,54,107,160,224,43,96,171,235,32,81,154,218,17,90,145,209,26,71,140,204,7,76,135,199,12,37,238,174,101,46,229,165,110,51,248,184,115,56,243,179,120,9,194,130,73,2,201,137,66,31,212,148,95,20,223,159,84,205,6,70,141,198,13,77,134,219,16,80,155,208,27,91,144,225,42,106,161,234,33,97,170,247,60,124,183,252,55,119,188,149,94,30,213,158,85,21,222,131,72,8,195,136,67,3,200,185,114,50,249,178,121,57,242,175,100,36,239,164,111,47,228},
{0,204,133,73,23,219,146,94,46,226,171,103,57,245,188,112,92,144,217,21,75,135,206,2,114,190,247,59,101,169,224,44,184,116,61,241,175,99,42,230,150,90,19,223,129,77,4,200,228,40,97,173,243,63,118,186,202,6,79,131,221,17,88,148,109,161,232,36,122,182,255,51,67,143,198,10,84,152,209,29,49,253,180,120,38,234,163,111,31,211,154,86,8,196,141,65,213,25,80,156,194,14,71,139,251,55,126,178,236,32,105,165,137,69,12,192,158,82,27,215,167,107,34,238,176,124,53,249,218,22,95,147,205,1,72,132,244,56,113,189,227,47,102,170,134,74,3,207,145,93,20,216,168,100,45,225,191,115,58,246,98,174,231,43,117,185,240,60,76,128,201,5,91,151,222,18,62,242,187,119,41,229,172,96,16,220,149,89,7,203,130,78,183,123,50,254,160,108,37,233,153,85,28,208,142,66,11,199,235,39,110,162,252,48,121,181,197,9,64,140,210,30,87,155,15,195,138,70,24,212,157,81,33,237,164,104,54,250,179,127,83,159,214,26,68,136,193,13,125,177,248,52,106,166,239,35},
{0,205,135,74,19,222,148,89,38,235,161,108,53,248,178,127,76,129,203,6,95,146,216,21,106,167,237,32,121,180,254,51,152,85,31,210,139,70,12,193,190,115,57,244,173,96,42,231,212,25,83,158,199,10,64,141,242,63,117,184,225,44,102,171,45,224,170,103,62,243,185,116,11,198,140,65,24,213,159,82,97,172,230,43,114,191,245,56,71,138,192,13,84,153,211,30,181,120,50,255,166,107,33,236,147,94,20,217,128,77,7,202,249,52,126,179,234,39,109,160,223,18,88,149,204,1,75,134,90,151,221,16,73,132,206,3,124,177,251,54,111,162,232,37,22,219,145,92,5,200,130,79,48,253,183,122,35,238,164,105,194,15,69,136,209,28,86,155,228,41,99,174,247,58,112,189,142,67,9,196,157,80,26,215,168,101,47,226,187,118,60,241,119,186,240,61,100,169,227,46,81,156,214,27,66,143,197,8,59,246,188,113,40,229,175,98,29,208,154,87,14,195,137,68,239,34,104,165,252,49,123,182,201,4,78,131,218,23,93,144,163,110,36,233,176,125,55,250,133,72,2,207,150,91,17,220},
{0,206,129,79,31,209,158,80,62,240,191,113,33,239,160,110,124,178,253,51,99,173,226,44,66,140,195,13,93,147,220,18,248,54,121,183,231,41,102,168,198,8,71,137,217,23,88,150,132,74,5,203,155,85,26,212,186,116,59,245,165,107,36,234,237,35,108,162,242,60,115,189,211,29,82,156,204,2,77,131,145,95,16,222,142,64,15,193,175,97,46,224,176,126,49,255,21,219,148,90,10,196,139,69,43,229,170,100,52,250,181,123,105,167,232,38,118,184,247,57,87,153,214,24,72,134,201,7,199,9,70,136,216,22,89,151,249,55,120,182,230,40,103,169,187,117,58,244,164,106,37,235,133,75,4,202,154,84,27,213,63,241,190,112,32,238,161,111,1,207,128,78,30,208,159,81,67,141,194,12,92,146,221,19,125,179,252,50,98,172,227,45,42,228,171,101,53,251,180,122,20,218,149,91,11,197,138,68,86,152,215,25,73,135,200,6,104,166,233,39,119,185,246,56,210,28,83,157,205,3,76,130,236,34,109,163,243,61,114,188,174,96,47,225,177,127,48,254,144,94,17,223,143,65,14,192},
{0,207,131,76,27,212,152,87,54,249,181,122,45,226,174,97,108,163,239,32,119,184,244,59,90,149,217,22,65,142,194,13,216,23,91,148,195,12,64,143,238,33,109,162,245,58,118,185,180,123,55,248,175,96,44,227,130,77,1,206,153,86,26,213,173,98,46,225,182,121,53,250,155,84,24,215,128,79,3,204,193,14,66,141,218,21,89,150,247,56,116,187,236,35,111,160,117,186,246,57,110,161,237,34,67,140,192,15,88,151,219,20,25,214,154,85,2,205,129,78,47,224,172,99,52,251,183,120,71,136,196,11,92,147,223,16,113,190,242,61,106,165,233,38,43,228,168,103,48,255,179,124,29,210,158,81,6,201,133,74,159,80,28,211,132,75,7,200,169,102,42,229,178,125,49,254,243,60,112,191,232,39,107,164,197,10,70,137,222,17,93,146,234,37,105,166,241,62,114,189,220,19,95,144,199,8,68,139,134,73,5,202,157,82,30,209,176,127,51,252,171,100,40,231,50,253,177,126,41,230,170,101,4,203,135,72,31,208,156,83,94,145,221,18,69,138,198,9,104,167,235,36,115,188,240,63},
{0,208,189,109,103,183,218,10,206,30,115,163,169,121,20,196,129,81,60,236,230,54,91,139,79,159,242,34,40,248,149,69,31,207,162,114,120,168,197,21,209,1,108,188,182,102,11,219,158,78,35,243,249,41,68,148,80,128,237,61,55,231,138,90,62,238,131,83,89,137,228,52,240,32,77,157,151,71,42,250,191,111,2,210,216,8,101,181,113,161,204,28,22,198,171,123,33,241,156,76,70,150,251,43,239,63,82,130,136,88,53,229,160,112,29,205,199,23,122,170,110,190,211,3,9,217,180,100,124,172,193,17,27,203,166,118,178,98,15,223,213,5,104,184,253,45,64,144,154,74,39,247,51,227,142,94,84,132,233,57,99,179,222,14,4,212,185,105,173,125,16,192,202,26,119,167,226,50,95,143,133,85,56,232,44,252,145,65,75,155,246,38,66,146,255,47,37,245,152,72,140,92,49,225,235,59,86,134,195,19,126,174,164,116,25,201,13,221,176,96,106,186,215,7,93,141,224,48,58,234,135,87,147,67,46,254,244,36,73,153,220,12,97,177,187,107,6,214,18,194,175,127,117,165,200,24},
{0,209,191,110,99,178,220,13,198,23,121,168,165,116,26,203,145,64,46,255,242,35,77,156,87,134,232,57,52,229,139,90,63,238,128,81,92,141,227,50,249,40,70,151,154,75,37,244,174,127,17,192,205,28,114,163,104,185,215,6,11,218,180,101,126,175,193,16,29,204,162,115,184,105,7,214,219,10,100,181,239,62,80,129,140,93,51,226,41,248,150,71,74,155,245,36,65,144,254,47,34,243,157,76,135,86,56,233,228,53,91,138,208,1,111,190,179,98,12,221,22,199,169,120,117,164,202,27,252,45,67,146,159,78,32,241,58,235,133,84,89,136,230,55,109,188,210,3,14,223,177,96,171,122,20,197,200,25,119,166,195,18,124,173,160,113,31,206,5,212,186,107,102,183,217,8,82,131,237,60,49,224,142,95,148,69,43,250,247,38,72,153,130,83,61,236,225,48,94,143,68,149,251,42,39,246,152,73,19,194,172,125,112,161,207,30,213,4,106,187,182,103,9,216,189,108,2,211,222,15,97,176,123,170,196,21,24,201,167,118,44,253,147,66,79,158,240,33,234,59,85,132,137,88,54,231},
{0,210,185,107,111,189,214,4,222,12,103,181,177,99,8,218,161,115,24,202,206,28,119,165,127,173,198,20,16,194,169,123,95,141,230,52,48,226,137,91,129,83,56,234,238,60,87,133,254,44,71,149,145,67,40,250,32,242,153,75,79,157,246,36,190,108,7,213,209,3,104,186,96,178,217,11,15,221,182,100,31,205,166,116,112,162,201,27,193,19,120,170,174,124,23,197,225,51,88,138,142,92,55,229,63,237,134,84,80,130,233,59,64,146,249,43,47,253,150,68,158,76,39,245,241,35,72,154,97,179,216,10,14,220,183,101,191,109,6,212,208,2,105,187,192,18,121,171,175,125,22,196,30,204,167,117,113,163,200,26,62,236,135,85,81,131,232,58,224,50,89,139,143,93,54,228,159,77,38,244,240,34,73,155,65,147,248,42,46,252,151,69,223,13,102,180,176,98,9,219,1,211,184,106,110,188,215,5,126,172,199,21,17,195,168,122,160,114,25,203,207,29,118,164,128,82,57,235,239,61,86,132,94,140,231,53,49,227,136,90,33,243,152,74,78,156,247,37,255,45,70,148,144,66,41,251},
{0,211,187,104,107,184,208,3,214,5,109,190,189,110,6,213,177,98,10,217,218,9,97,178,103,180,220,15,12,223,183,100,127,172,196,23,20,199,175,124,169,122,18,193,194,17,121,170,206,29,117,166,165,118,30,205,24,203,163,112,115,160,200,27,254,45,69,150,149,70,46,253,40,251,147,64,67,144,248,43,79,156,244,39,36,247,159,76,153,74,34,241,242,33,73,154,129,82,58,233,234,57,81,130,87,132,236,63,60,239,135,84,48,227,139,88,91,136,224,51,230,53,93,142,141,94,54,229,225,50,90,137,138,89,49,226,55,228,140,95,92,143,231,52,80,131,235,56,59,232,128,83,134,85,61,238,237,62,86,133,158,77,37,246,245,38,78,157,72,155,243,32,35,240,152,75,47,252,148,71,68,151,255,44,249,42,66,145,146,65,41,250,31,204,164,119,116,167,207,28,201,26,114,161,162,113,25,202,174,125,21,198,197,22,126,173,120,171,195,16,19,192,168,123,96,179,219,8,11,216,176,99,182,101,13,222,221,14,102,181,209,2,106,185,186,105,1,210,7,212,188,111,108,191,215,4},
{0,212,181,97,119,163,194,22,238,58,91,143,153,77,44,248,193,21,116,160,182,98,3,215,47,251,154,78,88,140,237,57,159,75,42,254,232,60,93,137,113,165,196,16,6,210,179,103,94,138,235,63,41,253,156,72,176,100,5,209,199,19,114,166,35,247,150,66,84,128,225,53,205,25,120,172,186,110,15,219,226,54,87,131,149,65,32,244,12,216,185,109,123,175,206,26,188,104,9,221,203,31,126,170,82,134,231,51,37,241,144,68,125,169,200,28,10,222,191,107,147,71,38,242,228,48,81,133,70,146,243,39,49,229,132,80,168,124,29,201,223,11,106,190,135,83,50,230,240,36,69,145,105,189,220,8,30,202,171,127,217,13,108,184,174,122,27,207,55,227,130,86,64,148,245,33,24,204,173,121,111,187,218,14,246,34,67,151,129,85,52,224,101,177,208,4,18,198,167,115,139,95,62,234,252,40,73,157,164,112,17,197,211,7,102,178,74,158,255,43,61,233,136,92,250,46,79,155,141,89,56,236,20,192,161,117,99,183,214,2,59,239,142,90,76,152,249,45,213,1,96,180,162,118,23,195},
{0,213,183,98,115,166,196,17,230,51,81,132,149,64,34,247,209,4,102,179,162,119,21,192,55,226,128,85,68,145,243,38,191,106,8,221,204,25,123,174,89,140,238,59,42,255,157,72,110,187,217,12,29,200,170,127,136,93,63,234,251,46,76,153,99,182,212,1,16,197,167,114,133,80,50,231,246,35,65,148,178,103,5,208,193,20,118,163,84,129,227,54,39,242,144,69,220,9,107,190,175,122,24,205,58,239,141,88,73,156,254,43,13,216,186,111,126,171,201,28,235,62,92,137,152,77,47,250,198,19,113,164,181,96,2,215,32,245,151,66,83,134,228,49,23,194,160,117,100,177,211,6,241,36,70,147,130,87,53,224,121,172,206,27,10,223,189,104,159,74,40,253,236,57,91,142,168,125,31,202,219,14,108,185,78,155,249,44,61,232,138,95,165,112,18,199,214,3,97,180,67,150,244,33,48,229,135,82,116,161,195,22,7,210,176,101,146,71,37,240,225,52,86,131,26,207,173,120,105,188,222,11,252,41,75,158,143,90,56,237,203,30,124,169,184,109,15,218,45,248,154,79,94,139,233,60},
{0,214,177,103,127,169,206,24,254,40,79,153,129,87,48,230,225,55,80,134,158,72,47,249,31,201,174,120,96,182,209,7,223,9,110,184,160,118,17,199,33,247,144,70,94,136,239,57,62,232,143,89,65,151,240,38,192,22,113,167,191,105,14,216,163,117,18,196,220,10,109,187,93,139,236,58,34,244,147,69,66,148,243,37,61,235,140,90,188,106,13,219,195,21,114,164,124,170,205,27,3,213,178,100,130,84,51,229,253,43,76,154,157,75,44,250,226,52,83,133,99,181,210,4,28,202,173,123,91,141,234,60,36,242,149,67,165,115,20,194,218,12,107,189,186,108,11,221,197,19,116,162,68,146,245,35,59,237,138,92,132,82,53,227,251,45,74,156,122,172,203,29,5,211,180,98,101,179,212,2,26,204,171,125,155,77,42,252,228,50,85,131,248,46,73,159,135,81,54,224,6,208,183,97,121,175,200,30,25,207,168,126,102,176,215,1,231,49,86,128,152,78,41,255,39,241,150,64,88,142,233,63,217,15,104,190,166,112,23,193,198,16,119,161,185,111,8,222,56,238,137,95,71,145,246,32},
{0,215,179,100,123,172,200,31,246,33,69,146,141,90,62,233,241,38,66,149,138,93,57,238,7,208,180,99,124,171,207,24,255,40,76,155,132,83,55,224,9,222,186,109,114,165,193,22,14,217,189,106,117,162,198,17,248,47,75,156,131,84,48,231,227,52,80,135,152,79,43,252,21,194,166,113,110,185,221,10,18,197,161,118,105,190,218,13,228,51,87,128,159,72,44,251,28,203,175,120,103,176,212,3,234,61,89,142,145,70,34,245,237,58,94,137,150,65,37,242,27,204,168,127,96,183,211,4,219,12,104,191,160,119,19,196,45,250,158,73,86,129,229,50,42,253,153,78,81,134,226,53,220,11,111,184,167,112,20,195,36,243,151,64,95,136,236,59,210,5,97,182,169,126,26,205,213,2,102,177,174,121,29,202,35,244,144,71,88,143,235,60,56,239,139,92,67,148,240,39,206,25,125,170,181,98,6,209,201,30,122,173,178,101,1,214,63,232,140,91,68,147,247,32,199,16,116,163,188,107,15,216,49,230,130,85,74,157,249,46,54,225,133,82,77,154,254,41,192,23,115,164,187,108,8,223},
{0,216,173,117,71,159,234,50,142,86,35,251,201,17,100,188,1,217,172,116,70,158,235,51,143,87,34,250,200,16,101,189,2,218,175,119,69,157,232,48,140,84,33,249,203,19,102,190,3,219,174,118,68,156,233,49,141,85,32,248,202,18,103,191,4,220,169,113,67,155,238,54,138,82,39,255,205,21,96,184,5,221,168,112,66,154,239,55,139,83,38,254,204,20,97,185,6,222,171,115,65,153,236,52,136,80,37,253,207,23,98,186,7,223,170,114,64,152,237,53,137,81,36,252,206,22,99,187,8,208,165,125,79,151,226,58,134,94,43,243,193,25,108,180,9,209,164,124,78,150,227,59,135,95,42,242,192,24,109,181,10,210,167,127,77,149,224,56,132,92,41,241,195,27,110,182,11,211,166,126,76,148,225,57,133,93,40,240,194,26,111,183,12,212,161,121,75,147,230,62,130,90,47,247,197,29,104,176,13,213,160,120,74,146,231,63,131,91,46,246,196,28,105,177,14,214,163,123,73,145,228,60,128,88,45,245,199,31,106,178,15,215,162,122,72,144,229,61,129,89,44,244,198,30,107,179},
{0,217,175,118,67,154,236,53,134,95,41,240,197,28,106,179,17,200,190,103,82,139,253,36,151,78,56,225,212,13,123,162,34,251,141,84,97,184,206,23,164,125,11,210,231,62,72,145,51,234,156,69,112,169,223,6,181,108,26,195,246,47,89,128,68,157,235,50,7,222,168,113,194,27,109,180,129,88,46,247,85,140,250,35,22,207,185,96,211,10,124,165,144,73,63,230,102,191,201,16,37,252,138,83,224,57,79,150,163,122,12,213,119,174,216,1,52,237,155,66,241,40,94,135,178,107,29,196,136,81,39,254,203,18,100,189,14,215,161,120,77,148,226,59,153,64,54,239,218,3,117,172,31,198,176,105,92,133,243,42,170,115,5,220,233,48,70,159,44,245,131,90,111,182,192,25,187,98,20,205,248,33,87,142,61,228,146,75,126,167,209,8,204,21,99,186,143,86,32,249,74,147,229,60,9,208,166,127,221,4,114,171,158,71,49,232,91,130,244,45,24,193,183,110,238,55,65,152,173,116,2,219,104,177,199,30,43,242,132,93,255,38,80,137,188,101,19,202,121,160,214,15,58,227,149,76},
{0,218,169,115,79,149,230,60,158,68,55,237,209,11,120,162,33,251,136,82,110,180,199,29,191,101,22,204,240,42,89,131,66,152,235,49,13,215,164,126,220,6,117,175,147,73,58,224,99,185,202,16,44,246,133,95,253,39,84,142,178,104,27,193,132,94,45,247,203,17,98,184,26,192,179,105,85,143,252,38,165,127,12,214,234,48,67,153,59,225,146,72,116,174,221,7,198,28,111,181,137,83,32,250,88,130,241,43,23,205,190,100,231,61,78,148,168,114,1,219,121,163,208,10,54,236,159,69,21,207,188,102,90,128,243,41,139,81,34,248,196,30,109,183,52,238,157,71,123,161,210,8,170,112,3,217,229,63,76,150,87,141,254,36,24,194,177,107,201,19,96,186,134,92,47,245,118,172,223,5,57,227,144,74,232,50,65,155,167,125,14,212,145,75,56,226,222,4,119,173,15,213,166,124,64,154,233,51,176,106,25,195,255,37,86,140,46,244,135,93,97,187,200,18,211,9,122,160,156,70,53,239,77,151,228,62,2,216,171,113,242,40,91,129,189,103,20,206,108,182,197,31,35,249,138,80},
{0,219,171,112,75,144,224,59,150,77,61,230,221,6,118,173,49,234,154,65,122,161,209,10,167,124,12,215,236,55,71,156,98,185,201,18,41,242,130,89,244,47,95,132,191,100,20,207,83,136,248,35,24,195,179,104,197,30,110,181,142,85,37,254,196,31,111,180,143,84,36,255,82,137,249,34,25,194,178,105,245,46,94,133,190,101,21,206,99,184,200,19,40,243,131,88,166,125,13,214,237,54,70,157,48,235,155,64,123,160,208,11,151,76,60,231,220,7,119,172,1,218,170,113,74,145,225,58,149,78,62,229,222,5,117,174,3,216,168,115,72,147,227,56,164,127,15,212,239,52,68,159,50,233,153,66,121,162,210,9,247,44,92,135,188,103,23,204,97,186,202,17,42,241,129,90,198,29,109,182,141,86,38,253,80,139,251,32,27,192,176,107,81,138,250,33,26,193,177,106,199,28,108,183,140,87,39,252,96,187,203,16,43,240,128,91,246,45,93,134,189,102,22,205,51,232,152,67,120,163,211,8,165,126,14,213,238,53,69,158,2,217,169,114,73,146,226,57,148,79,63,228,223,4,116,175},
{0,220,165,121,87,139,242,46,174,114,11,215,249,37,92,128,65,157,228,56,22,202,179,111,239,51,74,150,184,100,29,193,130,94,39,251,213,9,112,172,44,240,137,85,123,167,222,2,195,31,102,186,148,72,49,237,109,177,200,20,58,230,159,67,25,197,188,96,78,146,235,55,183,107,18,206,224,60,69,153,88,132,253,33,15,211,170,118,246,42,83,143,161,125,4,216,155,71,62,226,204,16,105,181,53,233,144,76,98,190,199,27,218,6,127,163,141,81,40,244,116,168,209,13,35,255,134,90,50,238,151,75,101,185,192,28,156,64,57,229,203,23,110,178,115,175,214,10,36,248,129,93,221,1,120,164,138,86,47,243,176,108,21,201,231,59,66,158,30,194,187,103,73,149,236,48,241,45,84,136,166,122,3,223,95,131,250,38,8,212,173,113,43,247,142,82,124,160,217,5,133,89,32,252,210,14,119,171,106,182,207,19,61,225,152,68,196,24,97,189,147,79,54,234,169,117,12,208,254,34,91,135,7,219,162,126,80,140,245,41,232,52,77,145,191,99,26,198,70,154,227,63,17,205,180,104},
{0,221,167,122,83,142,244,41,166,123,1,220,245,40,82,143,81,140,246,43,2,223,165,120,247,42,80,141,164,121,3,222,162,127,5,216,241,44,86,139,4,217,163,126,87,138,240,45,243,46,84,137,160,125,7,218,85,136,242,47,6,219,161,124,89,132,254,35,10,215,173,112,255,34,88,133,172,113,11,214,8,213,175,114,91,134,252,33,174,115,9,212,253,32,90,135,251,38,92,129,168,117,15,210,93,128,250,39,14,211,169,116,170,119,13,208,249,36,94,131,12,209,171,118,95,130,248,37,178,111,21,200,225,60,70,155,20,201,179,110,71,154,224,61,227,62,68,153,176,109,23,202,69,152,226,63,22,203,177,108,16,205,183,106,67,158,228,57,182,107,17,204,229,56,66,159,65,156,230,59,18,207,181,104,231,58,64,157,180,105,19,206,235,54,76,145,184,101,31,194,77,144,234,55,30,195,185,100,186,103,29,192,233,52,78,147,28,193,187,102,79,146,232,53,73,148,238,51,26,199,189,96,239,50,72,149,188,97,27,198,24,197,191,98,75,150,236,49,190,99,25,196,237,48,74,151},
{0,222,161,127,95,129,254,32,190,96,31,193,225,63,64,158,97,191,192,30,62,224,159,65,223,1,126,160,128,94,33,255,194,28,99,189,157,67,60,226,124,162,221,3,35,253,130,92,163,125,2,220,252,34,93,131,29,195,188,98,66,156,227,61,153,71,56,230,198,24,103,185,39,249,134,88,120,166,217,7,248,38,89,135,167,121,6,216,70,152,231,57,25,199,184,102,91,133,250,36,4,218,165,123,229,59,68,154,186,100,27,197,58,228,155,69,101,187,196,26,132,90,37,251,219,5,122,164,47,241,142,80,112,174,209,15,145,79,48,238,206,16,111,177,78,144,239,49,17,207,176,110,240,46,81,143,175,113,14,208,237,51,76,146,178,108,19,205,83,141,242,44,12,210,173,115,140,82,45,243,211,13,114,172,50,236,147,77,109,179,204,18,182,104,23,201,233,55,72,150,8,214,169,119,87,137,246,40,215,9,118,168,136,86,41,247,105,183,200,22,54,232,151,73,116,170,213,11,43,245,138,84,202,20,107,181,149,75,52,234,21,203,180,106,74,148,235,53,171,117,10,212,244,42,85,139},
{0,223,163,124,91,132,248,39,182,105,21,202,237,50,78,145,113,174,210,13,42,245,137,86,199,24,100,187,156,67,63,224,226,61,65,158,185,102,26,197,84,139,247,40,15,208,172,115,147,76,48,239,200,23,107,180,37,250,134,89,126,161,221,2,217,6,122,165,130,93,33,254,111,176,204,19,52,235,151,72,168,119,11,212,243,44,80,143,30,193,189,98,69,154,230,57,59,228,152,71,96,191,195,28,141,82,46,241,214,9,117,170,74,149,233,54,17,206,178,109,252,35,95,128,167,120,4,219,175,112,12,211,244,43,87,136,25,198,186,101,66,157,225,62,222,1,125,162,133,90,38,249,104,183,203,20,51,236,144,79,77,146,238,49,22,201,181,106,251,36,88,135,160,127,3,220,60,227,159,64,103,184,196,27,138,85,41,246,209,14,114,173,118,169,213,10,45,242,142,81,192,31,99,188,155,68,56,231,7,216,164,123,92,131,255,32,177,110,18,205,234,53,73,150,148,75,55,232,207,16,108,179,34,253,129,94,121,166,218,5,229,58,70,153,190,97,29,194,83,140,240,47,8,215,171,116},
{0,224,221,61,167,71,122,154,83,179,142,110,244,20,41,201,166,70,123,155,1,225,220,60,245,21,40,200,82,178,143,111,81,177,140,108,246,22,43,203,2,226,223,63,165,69,120,152,247,23,42,202,80,176,141,109,164,68,121,153,3,227,222,62,162,66,127,159,5,229,216,56,241,17,44,204,86,182,139,107,4,228,217,57,163,67,126,158,87,183,138,106,240,16,45,205,243,19,46,206,84,180,137,105,160,64,125,157,7,231,218,58,85,181,136,104,242,18,47,207,6,230,219,59,161,65,124,156,89,185,132,100,254,30,35,195,10,234,215,55,173,77,112,144,255,31,34,194,88,184,133,101,172,76,113,145,11,235,214,54,8,232,213,53,175,79,114,146,91,187,134,102,252,28,33,193,174,78,115,147,9,233,212,52,253,29,32,192,90,186,135,103,251,27,38,198,92,188,129,97,168,72,117,149,15,239,210,50,93,189,128,96,250,26,39,199,14,238,211,51,169,73,116,148,170,74,119,151,13,237,208,48,249,25,36,196,94,190,131,99,12,236,209,49,171,75,118,150,95,191,130,98,248,24,37,197},
{0,225,223,62,163,66,124,157,91,186,132,101,248,25,39,198,182,87,105,136,21,244,202,43,237,12,50,211,78,175,145,112,113,144,174,79,210,51,13,236,42,203,245,20,137,104,86,183,199,38,24,249,100,133,187,90,156,125,67,162,63,222,224,1,226,3,61,220,65,160,158,127,185,88,102,135,26,251,197,36,84,181,139,106,247,22,40,201,15,238,208,49,172,77,115,146,147,114,76,173,48,209,239,14,200,41,23,246,107,138,180,85,37,196,250,27,134,103,89,184,126,159,161,64,221,60,2,227,217,56,6,231,122,155,165,68,130,99,93,188,33,192,254,31,111,142,176,81,204,45,19,242,52,213,235,10,151,118,72,169,168,73,119,150,11,234,212,53,243,18,44,205,80,177,143,110,30,255,193,32,189,92,98,131,69,164,154,123,230,7,57,216,59,218,228,5,152,121,71,166,96,129,191,94,195,34,28,253,141,108,82,179,46,207,241,16,214,55,9,232,117,148,170,75,74,171,149,116,233,8,54,215,17,240,206,47,178,83,109,140,252,29,35,194,95,190,128,97,167,70,120,153,4,229,219,58},
{0,226,217,59,175,77,118,148,67,161,154,120,236,14,53,215,134,100,95,189,41,203,240,18,197,39,28,254,106,136,179,81,17,243,200,42,190,92,103,133,82,176,139,105,253,31,36,198,151,117,78,172,56,218,225,3,212,54,13,239,123,153,162,64,34,192,251,25,141,111,84,182,97,131,184,90,206,44,23,245,164,70,125,159,11,233,210,48,231,5,62,220,72,170,145,115,51,209,234,8,156,126,69,167,112,146,169,75,223,61,6,228,181,87,108,142,26,248,195,33,246,20,47,205,89,187,128,98,68,166,157,127,235,9,50,208,7,229,222,60,168,74,113,147,194,32,27,249,109,143,180,86,129,99,88,186,46,204,247,21,85,183,140,110,250,24,35,193,22,244,207,45,185,91,96,130,211,49,10,232,124,158,165,71,144,114,73,171,63,221,230,4,102,132,191,93,201,43,16,242,37,199,252,30,138,104,83,177,224,2,57,219,79,173,150,116,163,65,122,152,12,238,213,55,119,149,174,76,216,58,1,227,52,214,237,15,155,121,66,160,241,19,40,202,94,188,135,101,178,80,107,137,29,255,196,38},
{0,227,219,56,171,72,112,147,75,168,144,115,224,3,59,216,150,117,77,174,61,222,230,5,221,62,6,229,118,149,173,78,49,210,234,9,154,121,65,162,122,153,161,66,209,50,10,233,167,68,124,159,12,239,215,52,236,15,55,212,71,164,156,127,98,129,185,90,201,42,18,241,41,202,242,17,130,97,89,186,244,23,47,204,95,188,132,103,191,92,100,135,20,247,207,44,83,176,136,107,248,27,35,192,24,251,195,32,179,80,104,139,197,38,30,253,110,141,181,86,142,109,85,182,37,198,254,29,196,39,31,252,111,140,180,87,143,108,84,183,36,199,255,28,82,177,137,106,249,26,34,193,25,250,194,33,178,81,105,138,245,22,46,205,94,189,133,102,190,93,101,134,21,246,206,45,99,128,184,91,200,43,19,240,40,203,243,16,131,96,88,187,166,69,125,158,13,238,214,53,237,14,54,213,70,165,157,126,48,211,235,8,155,120,64,163,123,152,160,67,208,51,11,232,151,116,76,175,60,223,231,4,220,63,7,228,119,148,172,79,1,226,218,57,170,73,113,146,74,169,145,114,225,2,58,217},
{0,228,213,49,183,83,98,134,115,151,166,66,196,32,17,245,230,2,51,215,81,181,132,96,149,113,64,164,34,198,247,19,209,53,4,224,102,130,179,87,162,70,119,147,21,241,192,36,55,211,226,6,128,100,85,177,68,160,145,117,243,23,38,194,191,91,106,142,8,236,221,57,204,40,25,253,123,159,174,74,89,189,140,104,238,10,59,223,42,206,255,27,157,121,72,172,110,138,187,95,217,61,12,232,29,249,200,44,170,78,127,155,136,108,93,185,63,219,234,14,251,31,46,202,76,168,153,125,99,135,182,82,212,48,1,229,16,244,197,33,167,67,114,150,133,97,80,180,50,214,231,3,246,18,35,199,65,165,148,112,178,86,103,131,5,225,208,52,193,37,20,240,118,146,163,71,84,176,129,101,227,7,54,210,39,195,242,22,144,116,69,161,220,56,9,237,107,143,190,90,175,75,122,158,24,252,205,41,58,222,239,11,141,105,88,188,73,173,156,120,254,26,43,207,13,233,216,60,186,94,111,139,126,154,171,79,201,45,28,248,235,15,62,218,92,184,137,109,152,124,77,169,47,203,250,30},
{0,229,215,50,179,86,100,129,123,158,172,73,200,45,31,250,246,19,33,196,69,160,146,119,141,104,90,191,62,219,233,12,241,20,38,195,66,167,149,112,138,111,93,184,57,220,238,11,7,226,208,53,180,81,99,134,124,153,171,78,207,42,24,253,255,26,40,205,76,169,155,126,132,97,83,182,55,210,224,5,9,236,222,59,186,95,109,136,114,151,165,64,193,36,22,243,14,235,217,60,189,88,106,143,117,144,162,71,198,35,17,244,248,29,47,202,75,174,156,121,131,102,84,177,48,213,231,2,227,6,52,209,80,181,135,98,152,125,79,170,43,206,252,25,21,240,194,39,166,67,113,148,110,139,185,92,221,56,10,239,18,247,197,32,161,68,118,147,105,140,190,91,218,63,13,232,228,1,51,214,87,178,128,101,159,122,72,173,44,201,251,30,28,249,203,46,175,74,120,157,103,130,176,85,212,49,3,230,234,15,61,216,89,188,142,107,145,116,70,163,34,199,245,16,237,8,58,223,94,187,137,108,150,115,65,164,37,192,242,23,27,254,204,41,168,77,127,154,96,133,183,82,211,54,4,225},
{0,230,209,55,191,89,110,136,99,133,178,84,220,58,13,235,198,32,23,241,121,159,168,78,165,67,116,146,26,252,203,45,145,119,64,166,46,200,255,25,242,20,35,197,77,171,156,122,87,177,134,96,232,14,57,223,52,210,229,3,139,109,90,188,63,217,238,8,128,102,81,183,92,186,141,107,227,5,50,212,249,31,40,206,70,160,151,113,154,124,75,173,37,195,244,18,174,72,127,153,17,247,192,38,205,43,28,250,114,148,163,69,104,142,185,95,215,49,6,224,11,237,218,60,180,82,101,131,126,152,175,73,193,39,16,246,29,251,204,42,162,68,115,149,184,94,105,143,7,225,214,48,219,61,10,236,100,130,181,83,239,9,62,216,80,182,129,103,140,106,93,187,51,213,226,4,41,207,248,30,150,112,71,161,74,172,155,125,245,19,36,194,65,167,144,118,254,24,47,201,34,196,243,21,157,123,76,170,135,97,86,176,56,222,233,15,228,2,53,211,91,189,138,108,208,54,1,231,111,137,190,88,179,85,98,132,12,234,221,59,22,240,199,33,169,79,120,158,117,147,164,66,202,44,27,253},
{0,231,211,52,187,92,104,143,107,140,184,95,208,55,3,228,214,49,5,226,109,138,190,89,189,90,110,137,6,225,213,50,177,86,98,133,10,237,217,62,218,61,9,238,97,134,178,85,103,128,180,83,220,59,15,232,12,235,223,56,183,80,100,131,127,152,172,75,196,35,23,240,20,243,199,32,175,72,124,155,169,78,122,157,18,245,193,38,194,37,17,246,121,158,170,77,206,41,29,250,117,146,166,65,165,66,118,145,30,249,205,42,24,255,203,44,163,68,112,151,115,148,160,71,200,47,27,252,254,25,45,202,69,162,150,113,149,114,70,161,46,201,253,26,40,207,251,28,147,116,64,167,67,164,144,119,248,31,43,204,79,168,156,123,244,19,39,192,36,195,247,16,159,120,76,171,153,126,74,173,34,197,241,22,242,21,33,198,73,174,154,125,129,102,82,181,58,221,233,14,234,13,57,222,81,182,130,101,87,176,132,99,236,11,63,216,60,219,239,8,135,96,84,179,48,215,227,4,139,108,88,191,91,188,136,111,224,7,51,212,230,1,53,210,93,186,142,105,141,106,94,185,54,209,229,2},
{0,232,205,37,135,111,74,162,19,251,222,54,148,124,89,177,38,206,235,3,161,73,108,132,53,221,248,16,178,90,127,151,76,164,129,105,203,35,6,238,95,183,146,122,216,48,21,253,106,130,167,79,237,5,32,200,121,145,180,92,254,22,51,219,152,112,85,189,31,247,210,58,139,99,70,174,12,228,193,41,190,86,115,155,57,209,244,28,173,69,96,136,42,194,231,15,212,60,25,241,83,187,158,118,199,47,10,226,64,168,141,101,242,26,63,215,117,157,184,80,225,9,44,196,102,142,171,67,45,197,224,8,170,66,103,143,62,214,243,27,185,81,116,156,11,227,198,46,140,100,65,169,24,240,213,61,159,119,82,186,97,137,172,68,230,14,43,195,114,154,191,87,245,29,56,208,71,175,138,98,192,40,13,229,84,188,153,113,211,59,30,246,181,93,120,144,50,218,255,23,166,78,107,131,33,201,236,4,147,123,94,182,20,252,217,49,128,104,77,165,7,239,202,34,249,17,52,220,126,150,179,91,234,2,39,207,109,133,160,72,223,55,18,250,88,176,149,125,204,36,1,233,75,163,134,110},
{0,233,207,38,131,106,76,165,27,242,212,61,152,113,87,190,54,223,249,16,181,92,122,147,45,196,226,11,174,71,97,136,108,133,163,74,239,6,32,201,119,158,184,81,244,29,59,210,90,179,149,124,217,48,22,255,65,168,142,103,194,43,13,228,216,49,23,254,91,178,148,125,195,42,12,229,64,169,143,102,238,7,33,200,109,132,162,75,245,28,58,211,118,159,185,80,180,93,123,146,55,222,248,17,175,70,96,137,44,197,227,10,130,107,77,164,1,232,206,39,153,112,86,191,26,243,213,60,173,68,98,139,46,199,225,8,182,95,121,144,53,220,250,19,155,114,84,189,24,241,215,62,128,105,79,166,3,234,204,37,193,40,14,231,66,171,141,100,218,51,21,252,89,176,150,127,247,30,56,209,116,157,187,82,236,5,35,202,111,134,160,73,117,156,186,83,246,31,57,208,110,135,161,72,237,4,34,203,67,170,140,101,192,41,15,230,88,177,151,126,219,50,20,253,25,240,214,63,154,115,85,188,2,235,205,36,129,104,78,167,47,198,224,9,172,69,99,138,52,221,251,18,183,94,120,145},
{0,234,201,35,143,101,70,172,3,233,202,32,140,102,69,175,6,236,207,37,137,99,64,170,5,239,204,38,138,96,67,169,12,230,197,47,131,105,74,160,15,229,198,44,128,106,73,163,10,224,195,41,133,111,76,166,9,227,192,42,134,108,79,165,24,242,209,59,151,125,94,180,27,241,210,56,148,126,93,183,30,244,215,61,145,123,88,178,29,247,212,62,146,120,91,177,20,254,221,55,155,113,82,184,23,253,222,52,152,114,81,187,18,248,219,49,157,119,84,190,17,251,216,50,158,116,87,189,48,218,249,19,191,85,118,156,51,217,250,16,188,86,117,159,54,220,255,21,185,83,112,154,53,223,252,22,186,80,115,153,60,214,245,31,179,89,122,144,63,213,246,28,176,90,121,147,58,208,243,25,181,95,124,150,57,211,240,26,182,92,127,149,40,194,225,11,167,77,110,132,43,193,226,8,164,78,109,135,46,196,231,13,161,75,104,130,45,199,228,14,162,72,107,129,36,206,237,7,171,65,98,136,39,205,238,4,168,66,97,139,34,200,235,1,173,71,100,142,33,203,232,2,174,68,103,141},
{0,235,203,32,139,96,64,171,11,224,192,43,128,107,75,160,22,253,221,54,157,118,86,189,29,246,214,61,150,125,93,182,44,199,231,12,167,76,108,135,39,204,236,7,172,71,103,140,58,209,241,26,177,90,122,145,49,218,250,17,186,81,113,154,88,179,147,120,211,56,24,243,83,184,152,115,216,51,19,248,78,165,133,110,197,46,14,229,69,174,142,101,206,37,5,238,116,159,191,84,255,20,52,223,127,148,180,95,244,31,63,212,98,137,169,66,233,2,34,201,105,130,162,73,226,9,41,194,176,91,123,144,59,208,240,27,187,80,112,155,48,219,251,16,166,77,109,134,45,198,230,13,173,70,102,141,38,205,237,6,156,119,87,188,23,252,220,55,151,124,92,183,28,247,215,60,138,97,65,170,1,234,202,33,129,106,74,161,10,225,193,42,232,3,35,200,99,136,168,67,227,8,40,195,104,131,163,72,254,21,53,222,117,158,190,85,245,30,62,213,126,149,181,94,196,47,15,228,79,164,132,111,207,36,4,239,68,175,143,100,210,57,25,242,89,178,146,121,217,50,18,249,82,185,153,114},
{0,236,197,41,151,123,82,190,51,223,246,26,164,72,97,141,102,138,163,79,241,29,52,216,85,185,144,124,194,46,7,235,204,32,9,229,91,183,158,114,255,19,58,214,104,132,173,65,170,70,111,131,61,209,248,20,153,117,92,176,14,226,203,39,133,105,64,172,18,254,215,59,182,90,115,159,33,205,228,8,227,15,38,202,116,152,177,93,208,60,21,249,71,171,130,110,73,165,140,96,222,50,27,247,122,150,191,83,237,1,40,196,47,195,234,6,184,84,125,145,28,240,217,53,139,103,78,162,23,251,210,62,128,108,69,169,36,200,225,13,179,95,118,154,113,157,180,88,230,10,35,207,66,174,135,107,213,57,16,252,219,55,30,242,76,160,137,101,232,4,45,193,127,147,186,86,189,81,120,148,42,198,239,3,142,98,75,167,25,245,220,48,146,126,87,187,5,233,192,44,161,77,100,136,54,218,243,31,244,24,49,221,99,143,166,74,199,43,2,238,80,188,149,121,94,178,155,119,201,37,12,224,109,129,168,68,250,22,63,211,56,212,253,17,175,67,106,134,11,231,206,34,156,112,89,181},
{0,237,199,42,147,126,84,185,59,214,252,17,168,69,111,130,118,155,177,92,229,8,34,207,77,160,138,103,222,51,25,244,236,1,43,198,127,146,184,85,215,58,16,253,68,169,131,110,154,119,93,176,9,228,206,35,161,76,102,139,50,223,245,24,197,40,2,239,86,187,145,124,254,19,57,212,109,128,170,71,179,94,116,153,32,205,231,10,136,101,79,162,27,246,220,49,41,196,238,3,186,87,125,144,18,255,213,56,129,108,70,171,95,178,152,117,204,33,11,230,100,137,163,78,247,26,48,221,151,122,80,189,4,233,195,46,172,65,107,134,63,210,248,21,225,12,38,203,114,159,181,88,218,55,29,240,73,164,142,99,123,150,188,81,232,5,47,194,64,173,135,106,211,62,20,249,13,224,202,39,158,115,89,180,54,219,241,28,165,72,98,143,82,191,149,120,193,44,6,235,105,132,174,67,250,23,61,208,36,201,227,14,183,90,112,157,31,242,216,53,140,97,75,166,190,83,121,148,45,192,234,7,133,104,66,175,22,251,209,60,200,37,15,226,91,182,156,113,243,30,52,217,96,141,167,74},
{0,238,193,47,159,113,94,176,35,205,226,12,188,82,125,147,70,168,135,105,217,55,24,246,101,139,164,74,250,20,59,213,140,98,77,163,19,253,210,60,175,65,110,128,48,222,241,31,202,36,11,229,85,187,148,122,233,7,40,198,118,152,183,89,5,235,196,42,154,116,91,181,38,200,231,9,185,87,120,150,67,173,130,108,220,50,29,243,96,142,161,79,255,17,62,208,137,103,72,166,22,248,215,57,170,68,107,133,53,219,244,26,207,33,14,224,80,190,145,127,236,2,45,195,115,157,178,92,10,228,203,37,149,123,84,186,41,199,232,6,182,88,119,153,76,162,141,99,211,61,18,252,111,129,174,64,240,30,49,223,134,104,71,169,25,247,216,54,165,75,100,138,58,212,251,21,192,46,1,239,95,177,158,112,227,13,34,204,124,146,189,83,15,225,206,32,144,126,81,191,44,194,237,3,179,93,114,156,73,167,136,102,214,56,23,249,106,132,171,69,245,27,52,218,131,109,66,172,28,242,221,51,160,78,97,143,63,209,254,16,197,43,4,234,90,180,155,117,230,8,39,201,121,151,184,86},
{0,239,195,44,155,116,88,183,43,196,232,7,176,95,115,156,86,185,149,122,205,34,14,225,125,146,190,81,230,9,37,202,172,67,111,128,55,216,244,27,135,104,68,171,28,243,223,48,250,21,57,214,97,142,162,77,209,62,18,253,74,165,137,102,69,170,134,105,222,49,29,242,110,129,173,66,245,26,54,217,19,252,208,63,136,103,75,164,56,215,251,20,163,76,96,143,233,6,42,197,114,157,177,94,194,45,1,238,89,182,154,117,191,80,124,147,36,203,231,8,148,123,87,184,15,224,204,35,138,101,73,166,17,254,210,61,161,78,98,141,58,213,249,22,220,51,31,240,71,168,132,107,247,24,52,219,108,131,175,64,38,201,229,10,189,82,126,145,13,226,206,33,150,121,85,186,112,159,179,92,235,4,40,199,91,180,152,119,192,47,3,236,207,32,12,227,84,187,151,120,228,11,39,200,127,144,188,83,153,118,90,181,2,237,193,46,178,93,113,158,41,198,234,5,99,140,160,79,248,23,59,212,72,167,139,100,211,60,16,255,53,218,246,25,174,65,109,130,30,241,221,50,133,106,70,169},
{0,240,253,13,231,23,26,234,211,35,46,222,52,196,201,57,187,75,70,182,92,172,161,81,104,152,149,101,143,127,114,130,107,155,150,102,140,124,113,129,184,72,69,181,95,175,162,82,208,32,45,221,55,199,202,58,3,243,254,14,228,20,25,233,214,38,43,219,49,193,204,60,5,245,248,8,226,18,31,239,109,157,144,96,138,122,119,135,190,78,67,179,89,169,164,84,189,77,64,176,90,170,167,87,110,158,147,99,137,121,116,132,6,246,251,11,225,17,28,236,213,37,40,216,50,194,207,63,177,65,76,188,86,166,171,91,98,146,159,111,133,117,120,136,10,250,247,7,237,29,16,224,217,41,36,212,62,206,195,51,218,42,39,215,61,205,192,48,9,249,244,4,238,30,19,227,97,145,156,108,134,118,123,139,178,66,79,191,85,165,168,88,103,151,154,106,128,112,125,141,180,68,73,185,83,163,174,94,220,44,33,209,59,203,198,54,15,255,242,2,232,24,21,229,12,252,241,1,235,27,22,230,223,47,34,210,56,200,197,53,183,71,74,186,80,160,173,93,100,148,153,105,131,115,126,142},
{0,241,255,14,227,18,28,237,219,42,36,213,56,201,199,54,171,90,84,165,72,185,183,70,112,129,143,126,147,98,108,157,75,186,180,69,168,89,87,166,144,97,111,158,115,130,140,125,224,17,31,238,3,242,252,13,59,202,196,53,216,41,39,214,150,103,105,152,117,132,138,123,77,188,178,67,174,95,81,160,61,204,194,51,222,47,33,208,230,23,25,232,5,244,250,11,221,44,34,211,62,207,193,48,6,247,249,8,229,20,26,235,118,135,137,120,149,100,106,155,173,92,82,163,78,191,177,64,49,192,206,63,210,35,45,220,234,27,21,228,9,248,246,7,154,107,101,148,121,136,134,119,65,176,190,79,162,83,93,172,122,139,133,116,153,104,102,151,161,80,94,175,66,179,189,76,209,32,46,223,50,195,205,60,10,251,245,4,233,24,22,231,167,86,88,169,68,181,187,74,124,141,131,114,159,110,96,145,12,253,243,2,239,30,16,225,215,38,40,217,52,197,203,58,236,29,19,226,15,254,240,1,55,198,200,57,212,37,43,218,71,182,184,73,164,85,91,170,156,109,99,146,127,142,128,113},
{0,242,249,11,239,29,22,228,195,49,58,200,44,222,213,39,155,105,98,144,116,134,141,127,88,170,161,83,183,69,78,188,43,217,210,32,196,54,61,207,232,26,17,227,7,245,254,12,176,66,73,187,95,173,166,84,115,129,138,120,156,110,101,151,86,164,175,93,185,75,64,178,149,103,108,158,122,136,131,113,205,63,52,198,34,208,219,41,14,252,247,5,225,19,24,234,125,143,132,118,146,96,107,153,190,76,71,181,81,163,168,90,230,20,31,237,9,251,240,2,37,215,220,46,202,56,51,193,172,94,85,167,67,177,186,72,111,157,150,100,128,114,121,139,55,197,206,60,216,42,33,211,244,6,13,255,27,233,226,16,135,117,126,140,104,154,145,99,68,182,189,79,171,89,82,160,28,238,229,23,243,1,10,248,223,45,38,212,48,194,201,59,250,8,3,241,21,231,236,30,57,203,192,50,214,36,47,221,97,147,152,106,142,124,119,133,162,80,91,169,77,191,180,70,209,35,40,218,62,204,199,53,18,224,235,25,253,15,4,246,74,184,179,65,165,87,92,174,137,123,112,130,102,148,159,109},
{0,243,251,8,235,24,16,227,203,56,48,195,32,211,219,40,139,120,112,131,96,147,155,104,64,179,187,72,171,88,80,163,11,248,240,3,224,19,27,232,192,51,59,200,43,216,208,35,128,115,123,136,107,152,144,99,75,184,176,67,160,83,91,168,22,229,237,30,253,14,6,245,221,46,38,213,54,197,205,62,157,110,102,149,118,133,141,126,86,165,173,94,189,78,70,181,29,238,230,21,246,5,13,254,214,37,45,222,61,206,198,53,150,101,109,158,125,142,134,117,93,174,166,85,182,69,77,190,44,223,215,36,199,52,60,207,231,20,28,239,12,255,247,4,167,84,92,175,76,191,183,68,108,159,151,100,135,116,124,143,39,212,220,47,204,63,55,196,236,31,23,228,7,244,252,15,172,95,87,164,71,180,188,79,103,148,156,111,140,127,119,132,58,201,193,50,209,34,42,217,241,2,10,249,26,233,225,18,177,66,74,185,90,169,161,82,122,137,129,114,145,98,106,153,49,194,202,57,218,41,33,210,250,9,1,242,17,226,234,25,186,73,65,178,81,162,170,89,113,130,138,121,154,105,97,146},
{0,244,245,1,247,3,2,246,243,7,6,242,4,240,241,5,251,15,14,250,12,248,249,13,8,252,253,9,255,11,10,254,235,31,30,234,28,232,233,29,24,236,237,25,239,27,26,238,16,228,229,17,231,19,18,230,227,23,22,226,20,224,225,21,203,63,62,202,60,200,201,61,56,204,205,57,207,59,58,206,48,196,197,49,199,51,50,198,195,55,54,194,52,192,193,53,32,212,213,33,215,35,34,214,211,39,38,210,36,208,209,37,219,47,46,218,44,216,217,45,40,220,221,41,223,43,42,222,139,127,126,138,124,136,137,125,120,140,141,121,143,123,122,142,112,132,133,113,135,115,114,134,131,119,118,130,116,128,129,117,96,148,149,97,151,99,98,150,147,103,102,146,100,144,145,101,155,111,110,154,108,152,153,109,104,156,157,105,159,107,106,158,64,180,181,65,183,67,66,182,179,71,70,178,68,176,177,69,187,79,78,186,76,184,185,77,72,188,189,73,191,75,74,190,171,95,94,170,92,168,169,93,88,172,173,89,175,91,90,174,80,164,165,81,167,83,82,166,163,87,86,162,84,160,161,85},
{0,245,247,2,243,6,4,241,251,14,12,249,8,253,255,10,235,30,28,233,24,237,239,26,16,229,231,18,227,22,20,225,203,62,60,201,56,205,207,58,48,197,199,50,195,54,52,193,32,213,215,34,211,38,36,209,219,46,44,217,40,221,223,42,139,126,124,137,120,141,143,122,112,133,135,114,131,118,116,129,96,149,151,98,147,102,100,145,155,110,108,153,104,157,159,106,64,181,183,66,179,70,68,177,187,78,76,185,72,189,191,74,171,94,92,169,88,173,175,90,80,165,167,82,163,86,84,161,11,254,252,9,248,13,15,250,240,5,7,242,3,246,244,1,224,21,23,226,19,230,228,17,27,238,236,25,232,29,31,234,192,53,55,194,51,198,196,49,59,206,204,57,200,61,63,202,43,222,220,41,216,45,47,218,208,37,39,210,35,214,212,33,128,117,119,130,115,134,132,113,123,142,140,121,136,125,127,138,107,158,156,105,152,109,111,154,144,101,103,146,99,150,148,97,75,190,188,73,184,77,79,186,176,69,71,178,67,182,180,65,160,85,87,162,83,166,164,81,91,174,172,89,168,93,95,170},
{0,246,241,7,255,9,14,248,227,21,18,228,28,234,237,27,219,45,42,220,36,210,213,35,56,206,201,63,199,49,54,192,171,93,90,172,84,162,165,83,72,190,185,79,183,65,70,176,112,134,129,119,143,121,126,136,147,101,98,148,108,154,157,107,75,189,186,76,180,66,69,179,168,94,89,175,87,161,166,80,144,102,97,151,111,153,158,104,115,133,130,116,140,122,125,139,224,22,17,231,31,233,238,24,3,245,242,4,252,10,13,251,59,205,202,60,196,50,53,195,216,46,41,223,39,209,214,32,150,96,103,145,105,159,152,110,117,131,132,114,138,124,123,141,77,187,188,74,178,68,67,181,174,88,95,169,81,167,160,86,61,203,204,58,194,52,51,197,222,40,47,217,33,215,208,38,230,16,23,225,25,239,232,30,5,243,244,2,250,12,11,253,221,43,44,218,34,212,211,37,62,200,207,57,193,55,48,198,6,240,247,1,249,15,8,254,229,19,20,226,26,236,235,29,118,128,135,113,137,127,120,142,149,99,100,146,106,156,155,109,173,91,92,170,82,164,163,85,78,184,191,73,177,71,64,182},
{0,247,243,4,251,12,8,255,235,28,24,239,16,231,227,20,203,60,56,207,48,199,195,52,32,215,211,36,219,44,40,223,139,124,120,143,112,135,131,116,96,151,147,100,155,108,104,159,64,183,179,68,187,76,72,191,171,92,88,175,80,167,163,84,11,252,248,15,240,7,3,244,224,23,19,228,27,236,232,31,192,55,51,196,59,204,200,63,43,220,216,47,208,39,35,212,128,119,115,132,123,140,136,127,107,156,152,111,144,103,99,148,75,188,184,79,176,71,67,180,160,87,83,164,91,172,168,95,22,225,229,18,237,26,30,233,253,10,14,249,6,241,245,2,221,42,46,217,38,209,213,34,54,193,197,50,205,58,62,201,157,106,110,153,102,145,149,98,118,129,133,114,141,122,126,137,86,161,165,82,173,90,94,169,189,74,78,185,70,177,181,66,29,234,238,25,230,17,21,226,246,1,5,242,13,250,254,9,214,33,37,210,45,218,222,41,61,202,206,57,198,49,53,194,150,97,101,146,109,154,158,105,125,138,142,121,134,113,117,130,93,170,174,89,166,81,85,162,182,65,69,178,77,186,190,73},
{0,248,237,21,199,63,42,210,147,107,126,134,84,172,185,65,59,195,214,46,252,4,17,233,168,80,69,189,111,151,130,122,118,142,155,99,177,73,92,164,229,29,8,240,34,218,207,55,77,181,160,88,138,114,103,159,222,38,51,203,25,225,244,12,236,20,1,249,43,211,198,62,127,135,146,106,184,64,85,173,215,47,58,194,16,232,253,5,68,188,169,81,131,123,110,150,154,98,119,143,93,165,176,72,9,241,228,28,206,54,35,219,161,89,76,180,102,158,139,115,50,202,223,39,245,13,24,224,197,61,40,208,2,250,239,23,86,174,187,67,145,105,124,132,254,6,19,235,57,193,212,44,109,149,128,120,170,82,71,191,179,75,94,166,116,140,153,97,32,216,205,53,231,31,10,242,136,112,101,157,79,183,162,90,27,227,246,14,220,36,49,201,41,209,196,60,238,22,3,251,186,66,87,175,125,133,144,104,18,234,255,7,213,45,56,192,129,121,108,148,70,190,171,83,95,167,178,74,152,96,117,141,204,52,33,217,11,243,230,30,100,156,137,113,163,91,78,182,247,15,26,226,48,200,221,37},
{0,249,239,22,195,58,44,213,155,98,116,141,88,161,183,78,43,210,196,61,232,17,7,254,176,73,95,166,115,138,156,101,86,175,185,64,149,108,122,131,205,52,34,219,14,247,225,24,125,132,146,107,190,71,81,168,230,31,9,240,37,220,202,51,172,85,67,186,111,150,128,121,55,206,216,33,244,13,27,226,135,126,104,145,68,189,171,82,28,229,243,10,223,38,48,201,250,3,21,236,57,192,214,47,97,152,142,119,162,91,77,180,209,40,62,199,18,235,253,4,74,179,165,92,137,112,102,159,69,188,170,83,134,127,105,144,222,39,49,200,29,228,242,11,110,151,129,120,173,84,66,187,245,12,26,227,54,207,217,32,19,234,252,5,208,41,63,198,136,113,103,158,75,178,164,93,56,193,215,46,251,2,20,237,163,90,76,181,96,153,143,118,233,16,6,255,42,211,197,60,114,139,157,100,177,72,94,167,194,59,45,212,1,248,238,23,89,160,182,79,154,99,117,140,191,70,80,169,124,133,147,106,36,221,203,50,231,30,8,241,148,109,123,130,87,174,184,65,15,246,224,25,204,53,35,218},
{0,250,233,19,207,53,38,220,131,121,106,144,76,182,165,95,27,225,242,8,212,46,61,199,152,98,113,139,87,173,190,68,54,204,223,37,249,3,16,234,181,79,92,166,122,128,147,105,45,215,196,62,226,24,11,241,174,84,71,189,97,155,136,114,108,150,133,127,163,89,74,176,239,21,6,252,32,218,201,51,119,141,158,100,184,66,81,171,244,14,29,231,59,193,210,40,90,160,179,73,149,111,124,134,217,35,48,202,22,236,255,5,65,187,168,82,142,116,103,157,194,56,43,209,13,247,228,30,216,34,49,203,23,237,254,4,91,161,178,72,148,110,125,135,195,57,42,208,12,246,229,31,64,186,169,83,143,117,102,156,238,20,7,253,33,219,200,50,109,151,132,126,162,88,75,177,245,15,28,230,58,192,211,41,118,140,159,101,185,67,80,170,180,78,93,167,123,129,146,104,55,205,222,36,248,2,17,235,175,85,70,188,96,154,137,115,44,214,197,63,227,25,10,240,130,120,107,145,77,183,164,94,1,251,232,18,206,52,39,221,153,99,112,138,86,172,191,69,26,224,243,9,213,47,60,198},
{0,251,235,16,203,48,32,219,139,112,96,155,64,187,171,80,11,240,224,27,192,59,43,208,128,123,107,144,75,176,160,91,22,237,253,6,221,38,54,205,157,102,118,141,86,173,189,70,29,230,246,13,214,45,61,198,150,109,125,134,93,166,182,77,44,215,199,60,231,28,12,247,167,92,76,183,108,151,135,124,39,220,204,55,236,23,7,252,172,87,71,188,103,156,140,119,58,193,209,42,241,10,26,225,177,74,90,161,122,129,145,106,49,202,218,33,250,1,17,234,186,65,81,170,113,138,154,97,88,163,179,72,147,104,120,131,211,40,56,195,24,227,243,8,83,168,184,67,152,99,115,136,216,35,51,200,19,232,248,3,78,181,165,94,133,126,110,149,197,62,46,213,14,245,229,30,69,190,174,85,142,117,101,158,206,53,37,222,5,254,238,21,116,143,159,100,191,68,84,175,255,4,20,239,52,207,223,36,127,132,148,111,180,79,95,164,244,15,31,228,63,196,212,47,98,153,137,114,169,82,66,185,233,18,2,249,34,217,201,50,105,146,130,121,162,89,73,178,226,25,9,242,41,210,194,57},
{0,252,229,25,215,43,50,206,179,79,86,170,100,152,129,125,123,135,158,98,172,80,73,181,200,52,45,209,31,227,250,6,246,10,19,239,33,221,196,56,69,185,160,92,146,110,119,139,141,113,104,148,90,166,191,67,62,194,219,39,233,21,12,240,241,13,20,232,38,218,195,63,66,190,167,91,149,105,112,140,138,118,111,147,93,161,184,68,57,197,220,32,238,18,11,247,7,251,226,30,208,44,53,201,180,72,81,173,99,159,134,122,124,128,153,101,171,87,78,178,207,51,42,214,24,228,253,1,255,3,26,230,40,212,205,49,76,176,169,85,155,103,126,130,132,120,97,157,83,175,182,74,55,203,210,46,224,28,5,249,9,245,236,16,222,34,59,199,186,70,95,163,109,145,136,116,114,142,151,107,165,89,64,188,193,61,36,216,22,234,243,15,14,242,235,23,217,37,60,192,189,65,88,164,106,150,143,115,117,137,144,108,162,94,71,187,198,58,35,223,17,237,244,8,248,4,29,225,47,211,202,54,75,183,174,82,156,96,121,133,131,127,102,154,84,168,177,77,48,204,213,41,231,27,2,254},
{0,253,231,26,211,46,52,201,187,70,92,161,104,149,143,114,107,150,140,113,184,69,95,162,208,45,55,202,3,254,228,25,214,43,49,204,5,248,226,31,109,144,138,119,190,67,89,164,189,64,90,167,110,147,137,116,6,251,225,28,213,40,50,207,177,76,86,171,98,159,133,120,10,247,237,16,217,36,62,195,218,39,61,192,9,244,238,19,97,156,134,123,178,79,85,168,103,154,128,125,180,73,83,174,220,33,59,198,15,242,232,21,12,241,235,22,223,34,56,197,183,74,80,173,100,153,131,126,127,130,152,101,172,81,75,182,196,57,35,222,23,234,240,13,20,233,243,14,199,58,32,221,175,82,72,181,124,129,155,102,169,84,78,179,122,135,157,96,18,239,245,8,193,60,38,219,194,63,37,216,17,236,246,11,121,132,158,99,170,87,77,176,206,51,41,212,29,224,250,7,117,136,146,111,166,91,65,188,165,88,66,191,118,139,145,108,30,227,249,4,205,48,42,215,24,229,255,2,203,54,44,209,163,94,68,185,112,141,151,106,115,142,148,105,160,93,71,186,200,53,47,210,27,230,252,1},
{0,254,225,31,223,33,62,192,163,93,66,188,124,130,157,99,91,165,186,68,132,122,101,155,248,6,25,231,39,217,198,56,182,72,87,169,105,151,136,118,21,235,244,10,202,52,43,213,237,19,12,242,50,204,211,45,78,176,175,81,145,111,112,142,113,143,144,110,174,80,79,177,210,44,51,205,13,243,236,18,42,212,203,53,245,11,20,234,137,119,104,150,86,168,183,73,199,57,38,216,24,230,249,7,100,154,133,123,187,69,90,164,156,98,125,131,67,189,162,92,63,193,222,32,224,30,1,255,226,28,3,253,61,195,220,34,65,191,160,94,158,96,127,129,185,71,88,166,102,152,135,121,26,228,251,5,197,59,36,218,84,170,181,75,139,117,106,148,247,9,22,232,40,214,201,55,15,241,238,16,208,46,49,207,172,82,77,179,115,141,146,108,147,109,114,140,76,178,173,83,48,206,209,47,239,17,14,240,200,54,41,215,23,233,246,8,107,149,138,116,180,74,85,171,37,219,196,58,250,4,27,229,134,120,103,153,89,167,184,70,126,128,159,97,161,95,64,190,221,35,60,194,2,252,227,29},
{0,255,227,28,219,36,56,199,171,84,72,183,112,143,147,108,75,180,168,87,144,111,115,140,224,31,3,252,59,196,216,39,150,105,117,138,77,178,174,81,61,194,222,33,230,25,5,250,221,34,62,193,6,249,229,26,118,137,149,106,173,82,78,177,49,206,210,45,234,21,9,246,154,101,121,134,65,190,162,93,122,133,153,102,161,94,66,189,209,46,50,205,10,245,233,22,167,88,68,187,124,131,159,96,12,243,239,16,215,40,52,203,236,19,15,240,55,200,212,43,71,184,164,91,156,99,127,128,98,157,129,126,185,70,90,165,201,54,42,213,18,237,241,14,41,214,202,53,242,13,17,238,130,125,97,158,89,166,186,69,244,11,23,232,47,208,204,51,95,160,188,67,132,123,103,152,191,64,92,163,100,155,135,120,20,235,247,8,207,48,44,211,83,172,176,79,136,119,107,148,248,7,27,228,35,220,192,63,24,231,251,4,195,60,32,223,179,76,80,175,104,151,139,116,197,58,38,217,30,225,253,2,110,145,141,114,181,74,86,169,142,113,109,146,85,170,182,73,37,218,198,57,254,1,29,226}
};
/*
* addmul() computes dst[] = dst[] + c * src[]
* This is used often, so better optimize it! Currently the loop is
* unrolled 16 times, a good value for 486 and pentium-class machines.
* The case c=0 is also optimized, whereas c=1 is not. These
* calls are unfrequent in my typical apps so I did not bother.
*/
void of_galois_field_2_8_addmul1 (gf *dst1, gf *src1, gf c, int sz);
/*
* computes C = AB where A is n*k, B is k*m, C is n*m
*/
void of_galois_field_2_8_matmul (gf *a, gf *b, gf *c, int n, int k, int m);
int of_galois_field_2_8_invert_mat (of_galois_field_code_cb_t* ofcb, gf *src, int k);
int of_galois_field_2_8_invert_vdm (of_galois_field_code_cb_t* ofcb, gf *src, int k);
#endif //OF_USE_GALOIS_FIELD_CODES_UTILS
#endif //OF_GALOIS_FIELD_ALGEBRA_2_4_H

View File

@@ -0,0 +1,368 @@
/* $Id: of_galois_field_code.c 185 2014-07-15 09:57:16Z roca $ */
/*
* OpenFEC.org AL-FEC Library.
* (c) Copyright 2009 - 2012 INRIA - All rights reserved
* Contact: vincent.roca@inria.fr
*
* This software is governed by the CeCILL-C license under French law and
* abiding by the rules of distribution of free software. You can use,
* modify and/ or redistribute the software under the terms of the CeCILL-C
* license as circulated by CEA, CNRS and INRIA at the following URL
* "http://www.cecill.info".
*
* As a counterpart to the access to the source code and rights to copy,
* modify and redistribute granted by the license, users are provided only
* with a limited warranty and the software's author, the holder of the
* economic rights, and the successive licensors have only limited
* liability.
*
* In this respect, the user's attention is drawn to the risks associated
* with loading, using, modifying and/or developing or reproducing the
* software by the user in light of its specific status of free software,
* that may mean that it is complicated to manipulate, and that also
* therefore means that it is reserved for developers and experienced
* professionals having in-depth computer knowledge. Users are therefore
* encouraged to load and test the software's suitability as regards their
* requirements in conditions enabling the security of their systems and/or
* data to be ensured and, more generally, to use and operate it in the
* same conditions as regards security.
*
* The fact that you are presently reading this means that you have had
* knowledge of the CeCILL-C license and that you accept its terms.
*/
#include "../of_reed-solomon_gf_2_m_includes.h"
#ifdef OF_USE_REED_SOLOMON_2_M_CODEC
gf of_modnn(of_galois_field_code_cb_t* ofcb,INT32 x)
{
UINT16 field_size = ofcb->field_size;
while (x >= field_size)
{
x -= field_size;
x = (x >> ofcb->m) + (x & field_size);
}
return x;
}
void of_rs_2m_display_gf(of_galois_field_code_cb_t* ofcb)
{
OF_ENTER_FUNCTION
int i;
for (i = 0; i <= ofcb->field_size; i++) {
printf("i=%i,log(i)=%i,exp(i)=%i,exp(log(i))=%i\n",i,ofcb->of_rs_gf_log[i],ofcb->of_rs_gf_exp[i],ofcb->of_rs_gf_exp[ofcb->of_rs_gf_log[i]]);
}
OF_EXIT_FUNCTION
}
/*
* shuffle move src packets in their position
*/
static int
of_rs_2m_shuffle (gf *pkt[], int index[], int k)
{
OF_ENTER_FUNCTION
int i;
for (i = 0 ; i < k ;)
{
if (index[i] >= k || index[i] == i)
i++ ;
else
{
/*
* put pkt in the right position (first check for conflicts).
*/
int c = index[i] ;
if (index[c] == c)
{
OF_EXIT_FUNCTION
return 1 ;
}
SWAP (index[i], index[c], int) ;
SWAP (pkt[i], pkt[c], gf *) ;
}
}
OF_EXIT_FUNCTION
return 0 ;
}
void of_rs_2m_release(of_galois_field_code_cb_t* ofcb)
{
OF_ENTER_FUNCTION
if (ofcb->enc_matrix != NULL)
{
of_free(ofcb->enc_matrix);
ofcb->enc_matrix=NULL;
}
if (ofcb->dec_matrix != NULL)
{
of_free(ofcb->dec_matrix);
ofcb->dec_matrix=NULL;
}
OF_EXIT_FUNCTION
}
of_status_t of_rs_2m_build_encoding_matrix(of_galois_field_code_cb_t* ofcb)
{
OF_ENTER_FUNCTION
gf *tmp_m, *p;
UINT32 k,r,col,row;
k=ofcb->nb_source_symbols;
r = ofcb->nb_repair_symbols;
if ((ofcb->enc_matrix = of_malloc((k+r)*(k))) == NULL)
{
goto no_mem;
}
/* cast the pointer (a 64 bit integer on LP64 systems) to uintptr_t first, and then
* truncate it to keep only the lowest 32 bits. Works the same on both 32 bit and 64
* bit systems */
ofcb->magic = ( (FEC_MAGIC ^ k) ^ (k+r)) ^ ((uintptr_t)(ofcb->enc_matrix) & 0xFFFFFFFF);
if ((tmp_m = of_malloc((k+r)*(k))) == NULL)
{
goto no_mem;
}
/*
* fill the matrix with powers of field elements, starting from 0.
* The first row is special, cannot be computed with exp. table.
*/
tmp_m[0] = 1 ;
for (col = 1; col < k ; col++)
tmp_m[col] = 0 ;
for (p = tmp_m + k, row = 0; row < k+r - 1 ; row++, p += k)
{
for (col = 0 ; col < k ; col ++)
switch(ofcb->m) {
case 4:
p[col] = of_gf_2_4_exp[of_modnn (ofcb,row*col) ];
break;
case 8:
p[col] = of_gf_2_8_exp[of_modnn (ofcb,row*col) ];
break;
}
}
/*
* quick code to build systematic matrix: invert the top
* k*k vandermonde matrix, multiply right the bottom n-k rows
* by the inverse, and construct the identity matrix at the top.
*/
switch(ofcb->m) {
case 4:
of_galois_field_2_4_invert_vdm(ofcb, tmp_m, k);
of_galois_field_2_4_matmul(tmp_m + k*k, tmp_m, ofcb->enc_matrix + k*k, r, k, k);
break;
case 8:
of_galois_field_2_8_invert_vdm(ofcb, tmp_m, k);
of_galois_field_2_8_matmul(tmp_m + k*k, tmp_m, ofcb->enc_matrix + k*k, r, k, k);
break;
}
/*
* the upper matrix is I so do not bother with a slow multiply
*/
bzero (ofcb->enc_matrix, k*k*sizeof (gf));
for (p = ofcb->enc_matrix, col = 0 ; col < k ; col++, p += k + 1)
*p = 1 ;
of_free (tmp_m);
OF_EXIT_FUNCTION
return OF_STATUS_OK;
no_mem:
OF_PRINT_ERROR(("out of memory\n"));
error:
OF_EXIT_FUNCTION
return OF_STATUS_FATAL_ERROR;
}
#ifdef OF_USE_DECODER
of_status_t of_rs_2m_build_decoding_matrix(of_galois_field_code_cb_t* ofcb, int *index)
{
OF_ENTER_FUNCTION
UINT32 k,r,i;
gf *p;
k = ofcb->nb_source_symbols;
r = ofcb->nb_repair_symbols;
if ((ofcb->dec_matrix = of_malloc((k)*(k))) == NULL)
{
goto no_mem;
}
for (i = 0, p = ofcb->dec_matrix ; i < k ; i++, p += k)
{
#if 1 /* this is simply an optimization, not very useful indeed */
if (index[i] < k)
{
bzero (p, k*sizeof (gf));
p[i] = 1 ;
}
else
#endif
if (index[i] < (k+r))
bcopy (& (ofcb->enc_matrix[index[i]*k]), p, k*sizeof (gf));
else
{
OF_PRINT_ERROR ( ("decode: invalid index %d (max %d)\n",
index[i], k+r - 1))
of_free (ofcb->dec_matrix);
OF_EXIT_FUNCTION
return OF_STATUS_FATAL_ERROR ;
}
}
int result;
switch (ofcb->m)
{
case 4:
result = of_galois_field_2_4_invert_mat(ofcb, ofcb->dec_matrix, k);
break;
case 8:
result = of_galois_field_2_8_invert_mat(ofcb, ofcb->dec_matrix, k);
break;
}
if (result)
{
of_free (ofcb->dec_matrix);
ofcb->dec_matrix = NULL ;
}
OF_EXIT_FUNCTION
return OF_STATUS_OK;
no_mem:
OF_PRINT_ERROR(("out of memory\n"));
error:
OF_EXIT_FUNCTION
return OF_STATUS_FATAL_ERROR;
}
of_status_t of_rs_2m_decode (of_galois_field_code_cb_t* ofcb, gf *_pkt[], int index[], int sz)
{
OF_ENTER_FUNCTION
gf **pkt = (gf**) _pkt; /* VR */
gf **new_pkt ;
int row, col, k = ofcb->nb_source_symbols ;
if (ofcb->m > 8)
sz /= 2 ;
if (of_rs_2m_shuffle (pkt, index, k))
{
/* error if true */
OF_EXIT_FUNCTION
return OF_STATUS_ERROR ;
}
if (of_rs_2m_build_decoding_matrix (ofcb, index) != OF_STATUS_OK)
{
OF_PRINT_ERROR(("of_rs_2m_decode : cannot build decoding matrix."))
goto error;
}
/*
* do the actual decoding
*/
new_pkt = (gf **) of_malloc (k * sizeof (gf *));
for (row = 0 ; row < k ; row++)
{
if (index[row] >= k)
{
new_pkt[row] = (gf *) of_calloc (sz, sizeof (gf));
for (col = 0 ; col < k ; col++)
{
if (ofcb->dec_matrix[row*k + col] != 0)
{
switch (ofcb->m)
{
case 4:
of_galois_field_2_4_addmul1_compact(new_pkt[row], pkt[col], ofcb->dec_matrix[row*k + col], sz);
break;
case 8:
// no addmul1 compact form for GF(2^8)
of_galois_field_2_8_addmul1(new_pkt[row], pkt[col], ofcb->dec_matrix[row*k + col], sz);
break;
}
}
}
}
}
//#if 0
/*
* move pkts to their final destination
* Warning: this function does not update the index[] table to contain
* the actual reconstructed packet index.
*/
for (row = 0 ; row < k ; row++)
{
if (index[row] >= k)
{
bcopy (new_pkt[row], pkt[row], sz*sizeof (gf));
of_free (new_pkt[row]);
}
}
//#endif
of_free (new_pkt);
of_free(ofcb->dec_matrix);
ofcb->dec_matrix = NULL;
OF_EXIT_FUNCTION
return OF_STATUS_OK;
error:
OF_EXIT_FUNCTION
return OF_STATUS_FATAL_ERROR;
}
#endif
#ifdef OF_USE_ENCODER
of_status_t of_rs_2m_encode(of_galois_field_code_cb_t* ofcb,gf *_src[], gf *_fec, int index, int sz)
{
OF_ENTER_FUNCTION
gf **src = (gf**) _src; /* VR */
gf *fec = (gf*) _fec; /* VR */
int i, k = ofcb->nb_source_symbols ;
gf *p ;
if (ofcb->m > 8)
sz /= 2 ;
if (index < k)
{
bcopy (src[index], fec, sz * sizeof(gf));
}
else if (index < (ofcb->nb_source_symbols + ofcb->nb_repair_symbols))
{
p = & (ofcb->enc_matrix[index*k]);
bzero (fec, sz * sizeof (gf));
for (i = 0; i < k ; i++)
{
if (p[i] != 0 )
{
switch(ofcb->m)
{
case 4:
of_galois_field_2_4_addmul1_compact(fec, src[i], p[i], sz);
break;
case 8:
of_galois_field_2_8_addmul1(fec, src[i], p[i], sz);
break;
}
}
}
return OF_STATUS_OK;
}
else
{
OF_PRINT_ERROR (("Invalid index %d (max %d)\n", index, ofcb->nb_source_symbols+ofcb->nb_repair_symbols - 1))
}
OF_EXIT_FUNCTION
return OF_STATUS_ERROR;
}
#endif
#endif //OF_USE_GALOIS_FIELD_CODES_UTILS

View File

@@ -0,0 +1,104 @@
/* $Id: of_galois_field_code.h 148 2014-07-08 08:01:56Z roca $ */
/*
* OpenFEC.org AL-FEC Library.
* (c) Copyright 2009 - 2012 INRIA - All rights reserved
* Contact: vincent.roca@inria.fr
*
* This software is governed by the CeCILL-C license under French law and
* abiding by the rules of distribution of free software. You can use,
* modify and/ or redistribute the software under the terms of the CeCILL-C
* license as circulated by CEA, CNRS and INRIA at the following URL
* "http://www.cecill.info".
*
* As a counterpart to the access to the source code and rights to copy,
* modify and redistribute granted by the license, users are provided only
* with a limited warranty and the software's author, the holder of the
* economic rights, and the successive licensors have only limited
* liability.
*
* In this respect, the user's attention is drawn to the risks associated
* with loading, using, modifying and/or developing or reproducing the
* software by the user in light of its specific status of free software,
* that may mean that it is complicated to manipulate, and that also
* therefore means that it is reserved for developers and experienced
* professionals having in-depth computer knowledge. Users are therefore
* encouraged to load and test the software's suitability as regards their
* requirements in conditions enabling the security of their systems and/or
* data to be ensured and, more generally, to use and operate it in the
* same conditions as regards security.
*
* The fact that you are presently reading this means that you have had
* knowledge of the CeCILL-C license and that you accept its terms.
*/
#ifndef GALOIS_FIELD_CODE_H
#define GALOIS_FIELD_CODE_H
#include "../of_reed-solomon_gf_2_m_includes.h"
#define bcmp(s1 ,s2, n) memcmp((s1), (s2), (size_t)(n))
#ifdef OF_USE_REED_SOLOMON_2_M_CODEC
#define FEC_MAGIC 0xFECC0DEC
/*
* Primitive polynomials - see Lin & Costello, Appendix A,
* and Lee & Messerschmitt, p. 453.
*/
#if 0
static const char *of_rs_allPp[] = /* GF_BITS polynomial */
{
NULL, /* 0 no code */
NULL, /* 1 no code */
"111", /* 2 1+x+x^2 */
"1101", /* 3 1+x+x^3 */
"11001", /* 4 1+x+x^4 */
"101001", /* 5 1+x^2+x^5 */
"1100001", /* 6 1+x+x^6 */
"10010001", /* 7 1 + x^3 + x^7 */
"101110001", /* 8 1+x^2+x^3+x^4+x^8 */
"1000100001", /* 9 1+x^4+x^9 */
"10010000001", /* 10 1+x^3+x^10 */
"101000000001", /* 11 1+x^2+x^11 */
"1100101000001", /* 12 1+x+x^4+x^6+x^12 */
"11011000000001", /* 13 1+x+x^3+x^4+x^13 */
"110000100010001", /* 14 1+x+x^6+x^10+x^14 */
"1100000000000001", /* 15 1+x+x^15 */
"11010000000010001" /* 16 1+x+x^3+x^12+x^16 */
};
#endif
/**
* Galois-Field-Code stable codec specific control block structure.
*/
typedef of_rs_2_m_cb_t of_galois_field_code_cb_t; /* XXX: the two types are synonymous in fact! */
/**
* just a helper to init all we need to use GF
*/
of_status_t of_rs_2m_init(of_galois_field_code_cb_t* ofcb);
/**
* and the helper to release memory
*/
void of_rs_2m_release(of_galois_field_code_cb_t* ofcb);
/**
* even if only decoder is defined, we need an encoding matrix.
*/
of_status_t of_rs_2m_build_encoding_matrix(of_galois_field_code_cb_t* ofcb);
#ifdef OF_USE_DECODER
of_status_t of_rs_2m_build_decoding_matrix(of_galois_field_code_cb_t* ofcb,int* index);
of_status_t of_rs_2m_decode(of_galois_field_code_cb_t* ofcb,gf *pkt[], int index[], int sz);
#endif
#ifdef OF_USE_ENCODER
of_status_t of_rs_2m_encode(of_galois_field_code_cb_t* ofcb,gf *_src[], gf *_fec, int index, int sz);
#endif
#endif //OF_USE_GALOIS_FIELD_CODES_UTILS
#endif //GALOIS_FIELD_CODE_H

View File

@@ -0,0 +1,61 @@
/* $Id: of_codec_profile.h 152 2014-07-08 14:01:42Z roca $ */
/*
* OpenFEC.org AL-FEC Library.
* (c) Copyright 2009 - 2012 INRIA - All rights reserved
* Contact: vincent.roca@inria.fr
*
* This software is governed by the CeCILL-C license under French law and
* abiding by the rules of distribution of free software. You can use,
* modify and/ or redistribute the software under the terms of the CeCILL-C
* license as circulated by CEA, CNRS and INRIA at the following URL
* "http://www.cecill.info".
*
* As a counterpart to the access to the source code and rights to copy,
* modify and redistribute granted by the license, users are provided only
* with a limited warranty and the software's author, the holder of the
* economic rights, and the successive licensors have only limited
* liability.
*
* In this respect, the user's attention is drawn to the risks associated
* with loading, using, modifying and/or developing or reproducing the
* software by the user in light of its specific status of free software,
* that may mean that it is complicated to manipulate, and that also
* therefore means that it is reserved for developers and experienced
* professionals having in-depth computer knowledge. Users are therefore
* encouraged to load and test the software's suitability as regards their
* requirements in conditions enabling the security of their systems and/or
* data to be ensured and, more generally, to use and operate it in the
* same conditions as regards security.
*
* The fact that you are presently reading this means that you have had
* knowledge of the CeCILL-C license and that you accept its terms.
*/
/****** GENERAL SETUP OPTIONS; EDIT AS APPROPRIATE ****************************/
#define OF_USE_REED_SOLOMON_2_M_CODEC
#ifdef OF_DEBUG
/* additional parameter for memory statistic purposes */
#define MEM_STATS_ARG ,ofcb->stats
#define MEM_STATS ,stats
#else
#define MEM_STATS_ARG
#define MEM_STATS
#endif
/**
* This parameter can be used to force 32 bits computations in addmull1
*/
//#define OF_RS_2M_USE_32BITS
/**
* Maximum m value for the GF(2^m) field.
* WARNING: for the moment, only m=4 and 8 are supported!
*/
#define OF_REED_SOLOMON_2_M_MAX_M 8

View File

@@ -0,0 +1,312 @@
/* $Id: of_reed-solomon_gf_2_m.h 182 2014-07-15 09:27:51Z roca $ */
/*
* OpenFEC.org AL-FEC Library.
* (c) Copyright 2009 - 2012 INRIA - All rights reserved
* Contact: vincent.roca@inria.fr
*
* This software is governed by the CeCILL-C license under French law and
* abiding by the rules of distribution of free software. You can use,
* modify and/ or redistribute the software under the terms of the CeCILL-C
* license as circulated by CEA, CNRS and INRIA at the following URL
* "http://www.cecill.info".
*
* As a counterpart to the access to the source code and rights to copy,
* modify and redistribute granted by the license, users are provided only
* with a limited warranty and the software's author, the holder of the
* economic rights, and the successive licensors have only limited
* liability.
*
* In this respect, the user's attention is drawn to the risks associated
* with loading, using, modifying and/or developing or reproducing the
* software by the user in light of its specific status of free software,
* that may mean that it is complicated to manipulate, and that also
* therefore means that it is reserved for developers and experienced
* professionals having in-depth computer knowledge. Users are therefore
* encouraged to load and test the software's suitability as regards their
* requirements in conditions enabling the security of their systems and/or
* data to be ensured and, more generally, to use and operate it in the
* same conditions as regards security.
*
* The fact that you are presently reading this means that you have had
* knowledge of the CeCILL-C license and that you accept its terms.
*/
#ifdef OF_USE_REED_SOLOMON_2_M_CODEC
#ifndef OF_REED_SOLOMON_GF_2_M_H
#define OF_REED_SOLOMON_GF_2_M_H
/**
* Reed-Solomon stable codec specific control block structure.
*/
typedef struct of_rs_2_m_cb
{
/************************************************************************************
* of_rs_2_m_cb *
***********************************************************************************/
/************************************************************************************
* of_cb_t *
***********************************************************************************/
of_codec_id_t codec_id; /* must begin with fec_codec_id */
of_codec_type_t codec_type; /* must be 2nd item */
UINT32 nb_source_symbols; /** k parameter (AKA code dimension). */
UINT32 nb_repair_symbols; /** r = n - k parameter. */
UINT32 encoding_symbol_length; /** symbol length. */
/***********************************************************************************/
UINT16 m; /* in theory between 2..16. Currently only values 4 and 8 are supported */
UINT16 field_size; /* 2^m */
gf* of_rs_gf_exp; /* index->poly form conversion table. */
int* of_rs_gf_log; /* Poly->index form conversion table. */
gf* of_rs_inverse; /* inverse of field elem. */
gf** of_gf_mul_table; /* table of 2 numbers multiplication. */
//#ifdef OF_USE_ENCODER
/**
* Encoding matrix (G).
* The encoding matrix is computed starting with a Vandermonde matrix,
* and then transforming it into a systematic matrix.
*/
gf *enc_matrix ;
//#endif
#ifdef OF_USE_DECODER
/**
* Decoding matrix (k*k).
*/
gf *dec_matrix;
#endif
/***********************************************************************************/
UINT32 magic;
/** Maximum number of source symbols supported by this codec for practical reasons. */
UINT32 max_nb_source_symbols;
/** Maximum number of encoding symbols supported by this codec for practical reasons. */
UINT32 max_nb_encoding_symbols;
/* maximum m value in GF(2^m) supported by the codec */
UINT16 max_m;
UINT32 nb_encoding_symbols;
#ifdef OF_USE_DECODER
/*
* decoder specific variables.
*/
/**
* Table of available source and repair symbols. This table is ordered, no matter
* the symbol arrival order.
*/
void ** available_symbols_tab;
/** Number of available source and repair symbols. This is the number of entries in
* the available_symbols_tab tables. */
UINT32 nb_available_symbols;
/** Number of available source symbols. */
UINT32 nb_available_source_symbols;
bool decoding_finished; /** true as soon as decoding completed. */
#endif /* OF_USE_DECODER */
/** callbacks for this codec. */
void* (*decoded_source_symbol_callback) (void *context,
UINT32 size, /* size of decoded source symbol */
UINT32 esi); /* encoding symbol ID in {0..k-1} */
void* (*decoded_repair_symbol_callback) (void *context,
UINT32 size, /* size of decoded repair symbol */
UINT32 esi); /* encoding symbol ID in {0..k-1} */
void* context_4_callback;
} of_rs_2_m_cb_t;
/*
* API function prototypes.
*/
/**
* This function create the codec instance for the Reed-Solomon codec.
*
* @fn of_status_t of_rs_2_m_create_codec_instance (of_rs_2_m_cb_t** of_cb)
* @brief create a Reed-Solomon codec instance
* @param of_cb (IN/OUT) address of the pointer to a Reed-Solomon codec control block. This pointer is updated
* by this function.
* In case of success, it points to a session structure allocated by the
* library. In case of failure it points to NULL.
* @return Error status. The ofcb pointer is updated according to the success return
* status.
*/
of_status_t of_rs_2_m_create_codec_instance (of_rs_2_m_cb_t** of_cb);
/**
* This function releases all the internal resources used by this FEC codec instance.
* None of the source symbol buffers will be free'ed by this function, even those decoded by
* the library if any, regardless of whether a callback has been registered or not. It's the
* responsibility of the caller to free them.
*
* @fn of_status_t of_rs_2_m_release_codec_instance (of_rs_2_m_cb_t* ofcb)
* @brief release all resources used by the codec
* @param ofcb (IN) Pointer to the control block.
* @return Error status.
*/
of_status_t of_rs_2_m_release_codec_instance (of_rs_2_m_cb_t* ofcb);
/**
*
* @fn of_status_t of_rs_2_m_set_fec_parameters (of_rs_2_m_cb_t* ofcb, of_rs_parameters_t* params)
* @brief set all the FEC codec parameters (e.g. k, n, or symbol size)
* @param ofcb (IN) Pointer to the control block.
* @param params (IN) pointer to a structure containing the FEC parameters associated to
* a specific FEC codec.
* @return Error status.
*/
of_status_t of_rs_2_m_set_fec_parameters (of_rs_2_m_cb_t* ofcb,
of_rs_2_m_parameters_t* params);
/**
* @fn of_status_t of_rs_2_m_set_callback_functions (of_rs_2_m_cb_t *ofcb,void* (*decoded_source_symbol_callback)
* (void *context,UINT32 size,UINT32 esi), void* (*decoded_repair_symbol_callback)
* (void *context,UINT32 size,UINT32 esi),void* context_4_callback)
* @brief set various callbock functions (see header of_open_fec_api.h)
* @param ofcb (IN) Pointer to the session.
*
* @param decoded_source_symbol_callback
* (IN) Pointer to the function, within the application, that
* needs to be called each time a source symbol is decoded.
* If this callback is not initialized, the symbol is managed
* internally.
*
* @param decoded_repair_symbol_callback
* (IN) Pointer to the function, within the application, that
* needs to be called each time a repair symbol is decoded.
* If this callback is not initialized, the symbol is managed
* internally.
*
* @param context_4_callback (IN) Pointer to the application-specific context that will be
* passed to the callback function (if any). This context is not
* interpreted by this function.
*
* @return Completion status (LDPC_OK or LDPC_ERROR).
*/
of_status_t of_rs_2_m_set_callback_functions (of_rs_2_m_cb_t* ofcb,
void* (*decoded_source_symbol_callback) (void *context,
UINT32 size, /* size of decoded source symbol */
UINT32 esi), /* encoding symbol ID in {0..k-1} */
void* (*decoded_repair_symbol_callback) (void *context,
UINT32 size, /* size of decoded repair symbol */
UINT32 esi), /* encoding symbol ID in {0..k-1} */
void* context_4_callback);
#ifdef OF_USE_ENCODER
/**
* @fn of_status_t of_rs_2_m_build_repair_symbol (of_rs_2_m_cb_t* ofcb, void* encoding_symbols_tab[], UINT32 esi_of_symbol_to_build)
* @brief build a repair symbol (encoder only)
* @param ofcb (IN) Pointer to the session.
* @param encoding_symbols_tab (IN/OUT) table of source and repair symbols.
* The entry for the repair symbol to build can either point
* to a buffer allocated by the application, or let to NULL
* meaning that of_build_repair_symbol will allocate memory.
* @param esi_of_symbol_to_build
* (IN) encoding symbol ID of the repair symbol to build in
* {k..n-1}
* @return Error status.
*/
of_status_t of_rs_2_m_build_repair_symbol (of_rs_2_m_cb_t* ofcb,
void* encoding_symbols_tab[],
UINT32 esi_of_symbol_to_build);
#endif //OF_USE_ENCODER
#ifdef OF_USE_DECODER
/**
* @fn of_status_t of_rs_2_m_decode_with_new_symbol (of_rs_2_m_cb_t* ofcb, void* const new_symbol_buf, UINT32 new_symbol_esi)
* @brief (try to) decode with a newly received symbol
* @param ofcb (IN) Pointer to the session.
* @param new_symbol (IN) Pointer to the encoding symbol now available (i.e. a new
* symbol received by the application, or a decoded symbol in case
* of a recursive call).
* @param new_symbol_esi (IN) Encoding symbol ID of the newly symbol available, in {0..n-1}.
* @return Error status (NB: this function does not return OF_STATUS_FAILURE).
*/
of_status_t of_rs_2_m_decode_with_new_symbol (of_rs_2_m_cb_t* ofcb,
void* new_symbol,
UINT32 new_symbol_esi);
/**
* @fn of_status_t of_rs_2_m_set_available_symbols (of_rs_2_m_cb_t* ofcb, void* const encoding_symbols_tab[]);
* @brief inform the decoder of all the available (received) symbols
* @param ofcb (IN) Pointer to the session.
* @param encoding_symbols_tab (IN) Pointer to the available encoding symbols table. To each
* available symbol the corresponding entry in the table must point
* to the associated buffer. Entries set to NULL are interpreted as
* corresponding to erased symbols.
* @return Error status.
*/
of_status_t of_rs_2_m_set_available_symbols (of_rs_2_m_cb_t* ofcb,
void* const encoding_symbols_tab[]);
/**
* @fn of_status_t of_rs_2_m_finish_decoding (of_rs_2_m_cb_t* ofcb)
* @brief finish decoding with available symbols
* @param ofcb (IN) Pointer to the session.
* @return Error status. Returns OF_STATUS_FAILURE if decoding failed, or
* OF_STATUS_OK if decoding succeeded, or OF_STATUS_*_ERROR in case
* of (fatal) error.
*/
of_status_t of_rs_2_m_finish_decoding (of_rs_2_m_cb_t* ofcb);
/**
* @fn bool of_rs_2_m_is_decoding_complete (of_rs_2_m_cb_t* ofcb)
* @brief check if decoding is finished
* @param ofcb (IN) Pointer to the session.
* @return Boolean. Warning, this is one of the very functions of the library that
* does not return an error status.
*/
bool of_rs_2_m_is_decoding_complete (of_rs_2_m_cb_t* ofcb);
/**
* @fn of_status_t of_rs_2_m_get_source_symbols_tab (of_rs_2_m_cb_t* ofcb, void* source_symbols_tab[])
* @brief get the table of available source symbols (after decoding)
* @param ofcb (IN) Pointer to the session.
* @param source_symbols_tab (IN/OUT) table, that will be filled by the library and returned
* to the application.
* @return Error status.
*/
of_status_t of_rs_2_m_get_source_symbols_tab (of_rs_2_m_cb_t* ofcb,
void* source_symbols_tab[]);
#endif //OF_USE_DECODER
/**
* @fn of_status_t of_rs_2_m_set_control_parameter (of_rs_2_m_cb_t* ofcb,UINT32 type,void* value,UINT32 length)
* @brief set a specific FEC parameter
* @param ofcb (IN) Pointer to the session.
* @param type (IN) Type of parameter. This type is FEC codec ID specific.
* @param value (IN) Pointer to the value of the parameter. The type of the object pointed
* is FEC codec ID specific.
* @param length (IN) length of pointer
* @return Error status.
*/
of_status_t of_rs_2_m_set_control_parameter (of_rs_2_m_cb_t* ofcb,
UINT32 type,
void* value,
UINT32 length);
/**
* @fn of_status_t of_rs_2_m_get_control_parameter (of_rs_2_m_cb_t* ofcb,UINT32 type,void* value,UINT32 length)
* @brief get a specific FEC parameter
* @param ofcb (IN) Pointer to the session.
* @param type (IN) Type of parameter. This type is FEC codec ID specific.
* @param value (IN/OUT) Pointer to the value of the parameter. The type of the object
* pointed is FEC codec ID specific. This function updates the value object
* accordingly. The application, who knows the FEC codec ID, is responsible
* to allocating the approriate object pointed by the value pointer.
* @param length (IN) length of pointer
* @return Error status.
*/
of_status_t of_rs_2_m_get_control_parameter (of_rs_2_m_cb_t* ofcb,
UINT32 type,
void* value,
UINT32 length);
#endif //OF_REED_SOLOMON_GF_2_M_H
#endif /* #ifdef OF_USE_REED_SOLOMON_CODEC_2_M */

View File

@@ -0,0 +1,663 @@
/* $Id: of_reed-solomon_gf_2_m_api.c 186 2014-07-16 07:17:53Z roca $ */
/*
* OpenFEC.org AL-FEC Library.
* (c) Copyright 2009 - 2012 INRIA - All rights reserved
* Contact: vincent.roca@inria.fr
*
* This software is governed by the CeCILL-C license under French law and
* abiding by the rules of distribution of free software. You can use,
* modify and/ or redistribute the software under the terms of the CeCILL-C
* license as circulated by CEA, CNRS and INRIA at the following URL
* "http://www.cecill.info".
*
* As a counterpart to the access to the source code and rights to copy,
* modify and redistribute granted by the license, users are provided only
* with a limited warranty and the software's author, the holder of the
* economic rights, and the successive licensors have only limited
* liability.
*
* In this respect, the user's attention is drawn to the risks associated
* with loading, using, modifying and/or developing or reproducing the
* software by the user in light of its specific status of free software,
* that may mean that it is complicated to manipulate, and that also
* therefore means that it is reserved for developers and experienced
* professionals having in-depth computer knowledge. Users are therefore
* encouraged to load and test the software's suitability as regards their
* requirements in conditions enabling the security of their systems and/or
* data to be ensured and, more generally, to use and operate it in the
* same conditions as regards security.
*
* The fact that you are presently reading this means that you have had
* knowledge of the CeCILL-C license and that you accept its terms.
*/
#include "of_reed-solomon_gf_2_m_includes.h"
#ifdef OF_USE_REED_SOLOMON_2_M_CODEC
of_status_t of_rs_2_m_create_codec_instance (of_rs_2_m_cb_t** of_cb)
{
of_codec_type_t codec_type; /* temporary value */
of_rs_2_m_cb_t *cb;
OF_ENTER_FUNCTION
cb = (of_rs_2_m_cb_t*) of_realloc (*of_cb, sizeof (of_rs_2_m_cb_t));
*of_cb = cb;
/* realloc does not initialize the additional buffer space, so do that manually,
* then re-initialize a few parameters */
codec_type = cb->codec_type;
memset(cb, 0, sizeof(*cb));
cb->codec_type = codec_type;
cb->codec_id = OF_CODEC_REED_SOLOMON_GF_2_M_STABLE;
/**
* max nb source symbols and max nb encoding symbols are computed
* in the of_rs_2_m_set_fec_parameters function (m is needed).
*/
cb->max_m = OF_REED_SOLOMON_2_M_MAX_M; /* init it immediately... */
OF_EXIT_FUNCTION
return OF_STATUS_OK;
}
of_status_t of_rs_2_m_release_codec_instance (of_rs_2_m_cb_t* ofcb)
{
OF_ENTER_FUNCTION
of_rs_2m_release((of_galois_field_code_cb_t*)ofcb);
#ifdef OF_USE_DECODER
if (ofcb->available_symbols_tab != NULL)
{
of_free(ofcb->available_symbols_tab);
ofcb->available_symbols_tab = NULL;
}
#endif /* OF_USE_DECODER */
#ifdef OF_DEBUG /* { */
OF_TRACE_LVL(1, ("\tTo be added: Reed-Solomon GF(2^4): total of %ld bytes for precalculated tables (incl. %ld for the optimized mult table)\n",
sizeof(of_gf_2_4_log) + sizeof(of_gf_2_4_exp) + sizeof(of_gf_2_4_inv) + sizeof(of_gf_2_4_mul_table) + sizeof(of_gf_2_4_opt_mul_table), sizeof(of_gf_2_4_opt_mul_table)))
OF_TRACE_LVL(1, ("\tTo be added: Reed-Solomon GF(2^8): total of %ld bytes for precalculated tables (incl. %ld for mult table)\n",
sizeof(of_gf_2_8_log) + sizeof(of_gf_2_8_exp) + sizeof(of_gf_2_8_inv) + sizeof(of_gf_2_8_mul_table), sizeof(of_gf_2_8_mul_table)))
#endif /* } OF_DEBUG */
OF_EXIT_FUNCTION
return OF_STATUS_OK;
}
of_status_t of_rs_2_m_set_fec_parameters (of_rs_2_m_cb_t* ofcb,
of_rs_2_m_parameters_t* params)
{
OF_ENTER_FUNCTION
ofcb->m = params->m;
if ((ofcb->m != 4) && (ofcb->m != 8)) {
OF_PRINT_ERROR(("ERROR: invalid m parameter (must be 4 or 8)"));
goto error;
}
ofcb->field_size = (1 << ofcb->m) - 1;
ofcb->max_nb_encoding_symbols = ofcb->max_nb_source_symbols = ofcb->field_size;
if ((ofcb->nb_source_symbols = params->nb_source_symbols) > ofcb->max_nb_source_symbols) {
OF_PRINT_ERROR(("ERROR: invalid nb_source_symbols parameter (got %d, maximum is %d)",
ofcb->nb_source_symbols, ofcb->max_nb_source_symbols))
goto error;
}
ofcb->nb_source_symbols = params->nb_source_symbols;
ofcb->nb_repair_symbols = params->nb_repair_symbols;
ofcb->encoding_symbol_length = params->encoding_symbol_length;
ofcb->nb_encoding_symbols = ofcb->nb_source_symbols + ofcb->nb_repair_symbols;
#ifdef OF_USE_DECODER
ofcb->available_symbols_tab = (void**) of_calloc (ofcb->nb_encoding_symbols, sizeof (void*));
ofcb->nb_available_symbols = 0;
ofcb->nb_available_source_symbols = 0;
#endif /* OF_USE_DECODER */
OF_EXIT_FUNCTION
return OF_STATUS_OK;
error:
OF_EXIT_FUNCTION
return OF_STATUS_FATAL_ERROR;
}
of_status_t of_rs_2_m_set_callback_functions (of_rs_2_m_cb_t* ofcb,
void* (*decoded_source_symbol_callback) (void *context,
UINT32 size, /* size of decoded source symbol */
UINT32 esi), /* encoding symbol ID in {0..k-1} */
void* (*decoded_repair_symbol_callback) (void *context,
UINT32 size, /* size of decoded repair symbol */
UINT32 esi), /* encoding symbol ID in {0..k-1} */
void* context_4_callback)
{
ofcb->decoded_source_symbol_callback = decoded_source_symbol_callback;
ofcb->decoded_repair_symbol_callback = decoded_repair_symbol_callback;
ofcb->context_4_callback = context_4_callback;
if (ofcb->decoded_repair_symbol_callback != NULL)
{
OF_PRINT_ERROR(("WARNING, the decoded repair symbol callback is never called with Reed-Solomon codes, since those repair symbols are never decoded\n"))
}
return OF_STATUS_OK;
}
#ifdef OF_USE_ENCODER
of_status_t of_rs_2_m_build_repair_symbol (of_rs_2_m_cb_t* ofcb,
void* encoding_symbols_tab[],
UINT32 esi_of_symbol_to_build)
{
OF_ENTER_FUNCTION
if (esi_of_symbol_to_build < ofcb->nb_source_symbols || esi_of_symbol_to_build >= ofcb->nb_encoding_symbols)
{
OF_PRINT_ERROR(("ERROR: bad esi of encoding symbol (%d)\n", esi_of_symbol_to_build))
goto error;
}
if (encoding_symbols_tab[esi_of_symbol_to_build] == NULL)
{
if ((encoding_symbols_tab[esi_of_symbol_to_build] = of_calloc (1, ofcb->encoding_symbol_length)) == NULL)
{
OF_PRINT_ERROR(("ERROR: no memory\n"))
goto error;
}
}
if (ofcb->enc_matrix == NULL)
{
if (of_rs_2m_build_encoding_matrix((of_galois_field_code_cb_t*)ofcb) != OF_STATUS_OK)
{
OF_PRINT_ERROR(("ERROR: creating encoding matrix failed\n"))
goto error;
}
}
if (of_rs_2m_encode((of_galois_field_code_cb_t*) ofcb, (gf**)encoding_symbols_tab,
encoding_symbols_tab[esi_of_symbol_to_build], esi_of_symbol_to_build,
ofcb->encoding_symbol_length) != OF_STATUS_OK)
{
OF_PRINT_ERROR(("ERROR: of_rs_encode failed\n"))
goto error;
}
OF_EXIT_FUNCTION
return OF_STATUS_OK;
error:
OF_EXIT_FUNCTION
return OF_STATUS_ERROR;
}
#endif //OF_USE_ENCODER
#ifdef OF_USE_DECODER
of_status_t of_rs_2_m_decode_with_new_symbol (of_rs_2_m_cb_t* ofcb,
void* new_symbol,
UINT32 new_symbol_esi)
{
OF_ENTER_FUNCTION
if (ofcb->decoding_finished)
{
OF_TRACE_LVL(2, ("%s: decoding already done\n", __FUNCTION__));
return OF_STATUS_OK;
}
if (ofcb->available_symbols_tab[new_symbol_esi] != NULL)
{
/* duplicated symbol, ignore */
OF_TRACE_LVL(2, ("%s: symbol (esi=%d) duplicated\n", __FUNCTION__, new_symbol_esi));
goto end;
}
ofcb->available_symbols_tab[new_symbol_esi] = new_symbol;
ofcb->nb_available_symbols++;
if (new_symbol_esi < ofcb->nb_source_symbols)
{
/* remember a new source symbol is available */
ofcb->nb_available_source_symbols++;
}
if (ofcb->nb_available_source_symbols == ofcb->nb_source_symbols)
{
/* we received all the k source symbols, so it's finished */
ofcb->decoding_finished = true;
OF_TRACE_LVL(2, ("%s: done, all source symbols have been received\n", __FUNCTION__));
OF_EXIT_FUNCTION
return OF_STATUS_OK;
}
if (ofcb->nb_available_symbols >= ofcb->nb_source_symbols)
{
/* we received a sufficient number of symbols, so let's decode */
if (of_rs_2_m_finish_decoding(ofcb) != OF_STATUS_OK)
{
OF_PRINT_ERROR(("ERROR: of_rs_decode failure\n"))
goto error;
}
ASSERT(ofcb->decoding_finished == true);
OF_TRACE_LVL(2, ("%s: done, decoding successful\n", __FUNCTION__));
OF_EXIT_FUNCTION
return OF_STATUS_OK;
}
end:
OF_TRACE_LVL(2, ("%s: okay, but not yet finished\n", __FUNCTION__));
OF_EXIT_FUNCTION
return OF_STATUS_OK;
error:
OF_EXIT_FUNCTION
return OF_STATUS_ERROR;
}
of_status_t of_rs_2_m_set_available_symbols (of_rs_2_m_cb_t* ofcb,
void* const encoding_symbols_tab[])
{
UINT32 i;
OF_ENTER_FUNCTION
ofcb->nb_available_symbols = 0;
ofcb->nb_available_source_symbols = 0;
for (i = 0; i < ofcb->nb_encoding_symbols; i++)
{
if ((ofcb->available_symbols_tab[i] = encoding_symbols_tab[i]) == NULL)
{
continue;
}
if (i < ofcb->nb_source_symbols)
{
ofcb->nb_available_source_symbols++;
}
ofcb->nb_available_symbols++;
}
OF_EXIT_FUNCTION
return OF_STATUS_OK;
}
#if 0 /* new */
of_status_t of_rs_2_m_finish_decoding (of_rs_2_m_cb_t* ofcb)
{
UINT32 k;
UINT32 n;
char *tmp_buf[ofcb->nb_source_symbols];/* keep available source/repair symbol buffers here... */
int tmp_esi[ofcb->nb_source_symbols]; /* ...and their esi here. In fact we only need k entries
* in these tables, but in order to avoid using malloc (time
* consumming), we use an automatic table of maximum size for
* both tmp_buf[] and tmp_esi[]. */
INT32 tmp_idx; /* index in tmp_buf[] and tmp_esi[] tabs */
void **ass_buf; /* tmp pointer to the current available source symbol entry in available_symbols_tab[] */
UINT32 ass_esi; /* corresponding available source symbol ESI */
void **ars_buf; /* tmp pointer to the current available repair symbol entry in available_symbols_tab[] */
UINT32 ars_esi; /* corresponding available repair symbol ESI */
OF_ENTER_FUNCTION
if (ofcb->decoding_finished)
{
return OF_STATUS_OK;
}
k = ofcb->nb_source_symbols;
n = ofcb->nb_encoding_symbols;
if (ofcb->nb_available_symbols < k)
{
OF_PRINT_ERROR(("ERROR: nb received symbols < nb source symbols\n"))
OF_EXIT_FUNCTION
return OF_STATUS_FAILURE;
}
if (ofcb->nb_available_source_symbols == k)
{
/* we received all the k source symbols, so it's finished */
ofcb->decoding_finished = true;
OF_EXIT_FUNCTION
return OF_STATUS_OK;
}
/*
* Because of of_rs_decode internal details, we put source symbols at their right location
* and fill in the gaps (i.e. erased source symbols) with repair symbols.
*/
ass_esi = 0;
ars_esi = k;
ass_buf = ofcb->available_symbols_tab;
ars_buf = ofcb->available_symbols_tab + k;
for (tmp_idx = 0; tmp_idx < k; tmp_idx++)
{
if (*ass_buf == NULL)
{
/* this source symbol is not available, replace it with a repair */
while (*ars_buf == NULL)
{
ars_esi++;
ars_buf++;
}
OF_TRACE_LVL(2, ("of_rs_finish_decoding: copy repair with esi=%d in tmp_buf[%d]\n",
ars_esi, tmp_idx))
tmp_buf[tmp_idx] = *ars_buf;
tmp_esi[tmp_idx] = ars_esi;
ars_esi++;
ars_buf++;
}
else
{
OF_TRACE_LVL(2, ("of_rs_finish_decoding: copy source with esi=%d in tmp_buf[%d]\n",
ars_esi, tmp_idx))
tmp_buf[tmp_idx] = *ass_buf;
tmp_esi[tmp_idx] = ass_esi;
}
ass_esi++;
ass_buf++;
}
//#if 0
for (tmp_idx = 0; tmp_idx < k; tmp_idx++)
{
OF_TRACE_LVL(2, ("Before of_rs_decode: esi=%d, k=%d, tmp_idx=%d\n", tmp_esi[tmp_idx], k, tmp_idx))
}
//#endif
if (ofcb->enc_matrix == NULL)
{
if (of_rs_2m_build_encoding_matrix((of_galois_field_code_cb_t*)ofcb) != OF_STATUS_OK)
{
OF_PRINT_ERROR(("ERROR: creating encoding matrix failed"))
goto error;
}
}
if (of_rs_2m_decode((of_galois_field_code_cb_t*)ofcb, (gf**)tmp_buf, (int*)tmp_esi, ofcb->encoding_symbol_length) != OF_STATUS_OK)
{
OF_PRINT_ERROR(("ERROR: of_rs_decode failure\n"))
goto error;
}
ofcb->decoding_finished = true;
//#if 0
for (tmp_idx = 0; tmp_idx < k; tmp_idx++)
{
OF_TRACE_LVL(2, ("After of_rs_decode: esi=%d, k=%d, tmp_idx=%d\n", tmp_esi[tmp_idx], k, tmp_idx))
}
//#endif
OF_EXIT_FUNCTION
return OF_STATUS_OK;
error:
OF_EXIT_FUNCTION
return OF_STATUS_ERROR;
}
#else /* old follows */
of_status_t of_rs_2_m_finish_decoding (of_rs_2_m_cb_t* ofcb)
{
UINT32 k;
UINT32 n;
char *tmp_buf[ofcb->nb_source_symbols];/* keep available source/repair symbol buffers here... */
int tmp_esi[ofcb->nb_source_symbols]; /* ...and their esi here. In fact we only need k entries
* in these tables, but in order to avoid using malloc (time
* consumming), we use an automatic table of maximum size for
* both tmp_buf[] and tmp_esi[]. */
INT32 tmp_idx; /* index in tmp_buf[] and tmp_esi[] tabs */
char *large_buf = NULL; /* single large buffer where to copy all source/repair symbols */
UINT32 off; /* offset, in unit of characters, in large_buf */
void **ass_buf; /* tmp pointer to the current available source symbol entry in available_symbols_tab[] */
UINT32 ass_esi; /* corresponding available source symbol ESI */
void **ars_buf; /* tmp pointer to the current available repair symbol entry in available_symbols_tab[] */
UINT32 ars_esi; /* corresponding available repair symbol ESI */
OF_ENTER_FUNCTION
if (ofcb->decoding_finished)
{
return OF_STATUS_OK;
}
k = ofcb->nb_source_symbols;
n = ofcb->nb_encoding_symbols;
//int *tmp_esi = (int*)malloc(ofcb->field_size*sizeof(int));
//char ** tmp_buf = (char**)malloc(n*sizeof(char*)); // ???? WRT RS(255)
if (ofcb->nb_available_symbols < k)
{
OF_PRINT_ERROR(("ERROR: nb received symbols < nb source symbols\n"))
OF_EXIT_FUNCTION
return OF_STATUS_FAILURE;
}
if (ofcb->nb_available_source_symbols == k)
{
/* we received all the k source symbols, so it's finished */
ofcb->decoding_finished = true;
OF_EXIT_FUNCTION
return OF_STATUS_OK;
}
/*
* Copy available source and repair symbols in a single large buffer first.
* NB: this is required by the current FEC codec which modifies
* the tmp_buf buffers!!!
*/
large_buf = (char *) of_malloc(k * ofcb->encoding_symbol_length);
if (large_buf == NULL)
{
goto no_mem;
}
/* Then remember the location of each symbol buffer */
for (tmp_idx = 0, off = 0; tmp_idx < k; tmp_idx++, off += ofcb->encoding_symbol_length) {
tmp_buf[tmp_idx] = large_buf + off;
}
tmp_idx = 0; /* index in tmp_buf and tmp_esi tables */
/*
* Copy all the available source symbols (it's essential for decoding speed purposes) and
* a sufficient number of repair symbols to the tmp_buf array. Copy data as well in the
* large_buf buffer.
* Because of of_rs_decode internal details, we put source symbols at their right location
* and fill in the gaps (i.e. erased source symbols) with repair symbols.
*/
ass_esi = 0;
ars_esi = k;
ass_buf = ofcb->available_symbols_tab;
ars_buf = ofcb->available_symbols_tab + k;
for (tmp_idx = 0; tmp_idx < k; tmp_idx++)
{
if (*ass_buf == NULL)
{
/* this source symbol is not available, replace it with a repair */
while (*ars_buf == NULL)
{
ars_esi++;
ars_buf++;
}
OF_TRACE_LVL(2, ("of_rs_finish_decoding: copy repair with esi=%d in tmp_buf[%d]\n",
ars_esi, tmp_idx))
memcpy(tmp_buf[tmp_idx], *ars_buf, ofcb->encoding_symbol_length);
tmp_esi[tmp_idx] = ars_esi;
ars_esi++;
ars_buf++;
}
else
{
OF_TRACE_LVL(2, ("of_rs_finish_decoding: copy source with esi=%d in tmp_buf[%d]\n",
ars_esi, tmp_idx))
int i;
for (i=0;i<ofcb->encoding_symbol_length;i++) {
}
memcpy(tmp_buf[tmp_idx], *ass_buf, ofcb->encoding_symbol_length);
tmp_esi[tmp_idx] = ass_esi;
}
ass_esi++;
ass_buf++;
}
#if 0
for (tmp_idx = 0; tmp_idx < k; tmp_idx++)
{
OF_TRACE_LVL(2, ("Before of_rs_decode: esi=%d, k=%d, tmp_idx=%d\n", tmp_esi[tmp_idx], k, tmp_idx))
}
#endif
if (ofcb->enc_matrix == NULL)
{
if (of_rs_2m_build_encoding_matrix((of_galois_field_code_cb_t*)ofcb) != OF_STATUS_OK)
{
OF_PRINT_ERROR(("ERROR: creating encoding matrix failed\n"))
goto error;
}
}
if (of_rs_2m_decode ((of_galois_field_code_cb_t*)ofcb, (gf**)tmp_buf, (int*)tmp_esi, ofcb->encoding_symbol_length) != OF_STATUS_OK)
{
OF_PRINT_ERROR(("ERROR: of_rs_decode failure\n"))
goto error;
}
ofcb->decoding_finished = true;
#if 0
for (tmp_idx = 0; tmp_idx < k; tmp_idx++)
{
OF_TRACE_LVL(2, ("After of_rs_decode: esi=%d, k=%d, tmp_idx=%d\n", tmp_esi[tmp_idx], k, tmp_idx))
}
#endif
/*
* finally update the source_symbols_tab table with the decoded source symbols.
*/
for (tmp_idx = 0; tmp_idx < k; tmp_idx++)
{
ASSERT(tmp_idx < k);
ass_buf = &(ofcb->available_symbols_tab[tmp_idx]);
if (*ass_buf != NULL)
{
/* nothing to do, this source symbol has already been received. */
continue;
}
/*
* This is a new, decoded source symbol.
* First copy it into a permanent buffer.
* Call either the associated callback or allocate memory, and then
* copy the symbol content in it.
*/
if (ofcb->decoded_source_symbol_callback != NULL)
{
*ass_buf = ofcb->decoded_source_symbol_callback (ofcb->context_4_callback,
ofcb->encoding_symbol_length, tmp_idx);
}
else
{
*ass_buf = (void *) of_malloc (ofcb->encoding_symbol_length);
}
if (*ass_buf == NULL)
{
goto no_mem;
}
memcpy(*ass_buf, tmp_buf[tmp_idx], ofcb->encoding_symbol_length);
OF_TRACE_LVL(2, ("of_rs_finish_decoding: decoded source symbol esi=%d from tmp_buf[%d]\n",
tmp_idx, tmp_idx))
}
of_free(large_buf);
OF_EXIT_FUNCTION
return OF_STATUS_OK;
no_mem:
OF_PRINT_ERROR(("ERROR: out of memory.\n"))
error:
OF_EXIT_FUNCTION
return OF_STATUS_ERROR;
}
#endif
bool of_rs_2_m_is_decoding_complete (of_rs_2_m_cb_t* ofcb)
{
OF_ENTER_FUNCTION
OF_EXIT_FUNCTION
return ofcb->decoding_finished;
}
of_status_t of_rs_2_m_get_source_symbols_tab (of_rs_2_m_cb_t* ofcb,
void* source_symbols_tab[])
{
OF_ENTER_FUNCTION
if (of_rs_2_m_is_decoding_complete(ofcb) == false)
{
OF_PRINT_ERROR(("ERROR: decoding not complete.\n"))
OF_EXIT_FUNCTION
return OF_STATUS_ERROR;
}
#if 0
UINT32 i;
for (i = 0; i < ofcb->nb_source_symbols; i++)
{
if (source_symbols_tab[i] == NULL)
{
source_symbols_tab[i] = ofcb->available_symbols_tab[i];
}
}
#else
memcpy(source_symbols_tab, ofcb->available_symbols_tab, ofcb->nb_source_symbols * sizeof(void*));
#endif
OF_EXIT_FUNCTION
return OF_STATUS_OK;
}
#endif //OF_USE_DECODER
of_status_t of_rs_2_m_set_control_parameter (of_rs_2_m_cb_t* ofcb,
UINT32 type,
void* value,
UINT32 length)
{
UINT16 m;
OF_ENTER_FUNCTION
switch (type) {
case OF_RS_CTRL_SET_FIELD_SIZE:
if (value == NULL || length != sizeof(UINT16)) {
OF_PRINT_ERROR(("OF_CTRL_SET_FIELD_SIZE ERROR: null value or bad length (got %d, expected %ld)\n", length, sizeof(UINT16)))
goto error;
}
m = *(UINT16*)value;
if (m != 4 && m != 8) {
OF_PRINT_ERROR(("ERROR: invalid m=%d parameter (must be 4 or 8)\n", m));
goto error;
}
ofcb->m = m;
ofcb->field_size = (1 << ofcb->m) - 1;
ofcb->max_nb_encoding_symbols = ofcb->max_nb_source_symbols = ofcb->field_size;
break;
default:
OF_PRINT_ERROR(("ERROR: unknown type (%d)\n", type))
break;
}
OF_EXIT_FUNCTION
return OF_STATUS_OK;
error:
OF_EXIT_FUNCTION
return OF_STATUS_ERROR;
}
of_status_t of_rs_2_m_get_control_parameter (of_rs_2_m_cb_t* ofcb,
UINT32 type,
void* value,
UINT32 length)
{
OF_ENTER_FUNCTION
switch (type) {
case OF_CTRL_GET_MAX_K:
if (value == NULL || length != sizeof(UINT32)) {
OF_PRINT_ERROR(("OF_CTRL_GET_MAX_K ERROR: null value or bad length (got %d, expected %ld)\n", length, sizeof(UINT32)))
goto error;
}
if (ofcb->max_nb_source_symbols == 0) {
OF_PRINT_ERROR(("OF_CTRL_GET_MAX_K ERROR: this parameter is not initialized. Use the of_rs_2_m_set_fec_parameters function to initialize it or of_rs_2_m_set_control_parameter.\n"))
goto error;
}
*(UINT32*)value = ofcb->max_nb_source_symbols;
OF_TRACE_LVL(1, ("%s: OF_CTRL_GET_MAX_K (%d)\n", __FUNCTION__, *(UINT32*)value))
break;
case OF_CTRL_GET_MAX_N:
if (value == NULL || length != sizeof(UINT32)) {
OF_PRINT_ERROR(("OF_CTRL_GET_MAX_N ERROR: null value or bad length (got %d, expected %ld)\n", length, sizeof(UINT32)))
goto error;
}
if (ofcb->max_nb_encoding_symbols == 0) {
OF_PRINT_ERROR(("OF_CTRL_GET_MAX_N ERROR: this parameter is not initialized. Use the of_rs_2_m_set_fec_parameters function to initialize it or of_rs_2_m_set_control_parameter.\n"))
goto error;
}
*(UINT32*)value = ofcb->max_nb_encoding_symbols;
OF_TRACE_LVL(1, ("%s: OF_CTRL_GET_MAX_N (%d)\n", __FUNCTION__, *(UINT32*)value))
break;
default:
OF_PRINT_ERROR(("ERROR: unknown type (%d)\n", type))
goto error;
}
OF_EXIT_FUNCTION
return OF_STATUS_OK;
error:
OF_EXIT_FUNCTION
return OF_STATUS_ERROR;
}
#endif

View File

@@ -0,0 +1,60 @@
/* $Id: of_reed-solomon_gf_2_m_api.h 115 2014-04-09 14:00:27Z roca $ */
/*
* OpenFEC.org AL-FEC Library.
* (c) Copyright 2009 - 2012 INRIA - All rights reserved
* Contact: vincent.roca@inria.fr
*
* This software is governed by the CeCILL-C license under French law and
* abiding by the rules of distribution of free software. You can use,
* modify and/ or redistribute the software under the terms of the CeCILL-C
* license as circulated by CEA, CNRS and INRIA at the following URL
* "http://www.cecill.info".
*
* As a counterpart to the access to the source code and rights to copy,
* modify and redistribute granted by the license, users are provided only
* with a limited warranty and the software's author, the holder of the
* economic rights, and the successive licensors have only limited
* liability.
*
* In this respect, the user's attention is drawn to the risks associated
* with loading, using, modifying and/or developing or reproducing the
* software by the user in light of its specific status of free software,
* that may mean that it is complicated to manipulate, and that also
* therefore means that it is reserved for developers and experienced
* professionals having in-depth computer knowledge. Users are therefore
* encouraged to load and test the software's suitability as regards their
* requirements in conditions enabling the security of their systems and/or
* data to be ensured and, more generally, to use and operate it in the
* same conditions as regards security.
*
* The fact that you are presently reading this means that you have had
* knowledge of the CeCILL-C license and that you accept its terms.
*/
#ifdef OF_USE_REED_SOLOMON_2_M_CODEC
#ifndef OF_REED_SOLOMON_GF_2_M_API_H
#define OF_REED_SOLOMON_GF_2_M_API_H
/**
* \struct of_rs_parameters_t
* \brief Reed-Solomon stable codec specific FEC parameter structure.
* This structure contains the pieces of information required to initialize a codec instance,
* using the of_set_fec_parameters() function.
*/
typedef struct of_rs_2_m_parameters
{
UINT32 nb_source_symbols; /* must be 1st item */
UINT32 nb_repair_symbols; /* must be 2nd item */
UINT32 encoding_symbol_length; /* must be 3rd item */
/*
* FEC codec id specific attributes follow...
*/
UINT16 m; /* WARNING: was bit_size */
} of_rs_2_m_parameters_t;
#endif /* OF_REED_SOLOMON_GF_2_M_API_H */
#endif /*#ifdef OF_USE_REED_SOLOMON_CODEC_2_M */

View File

@@ -0,0 +1,60 @@
/* $Id: of_reed-solomon_gf_2_m_includes.h 189 2014-07-16 08:53:50Z roca $ */
/*
* OpenFEC.org AL-FEC Library.
* (c) Copyright 2009 - 2012 INRIA - All rights reserved
* Contact: vincent.roca@inria.fr
*
* This software is governed by the CeCILL-C license under French law and
* abiding by the rules of distribution of free software. You can use,
* modify and/ or redistribute the software under the terms of the CeCILL-C
* license as circulated by CEA, CNRS and INRIA at the following URL
* "http://www.cecill.info".
*
* As a counterpart to the access to the source code and rights to copy,
* modify and redistribute granted by the license, users are provided only
* with a limited warranty and the software's author, the holder of the
* economic rights, and the successive licensors have only limited
* liability.
*
* In this respect, the user's attention is drawn to the risks associated
* with loading, using, modifying and/or developing or reproducing the
* software by the user in light of its specific status of free software,
* that may mean that it is complicated to manipulate, and that also
* therefore means that it is reserved for developers and experienced
* professionals having in-depth computer knowledge. Users are therefore
* encouraged to load and test the software's suitability as regards their
* requirements in conditions enabling the security of their systems and/or
* data to be ensured and, more generally, to use and operate it in the
* same conditions as regards security.
*
* The fact that you are presently reading this means that you have had
* knowledge of the CeCILL-C license and that you accept its terms.
*/
#ifndef OF_REED_SOLOMON_2M_INCLUDES_H
#define OF_REED_SOLOMON_2M_INCLUDES_H
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <string.h>
#include "../../lib_common/of_openfec_api.h"
/*
* the remaining includes will only be considered if of_codec_profile.h is
* included above by of_openfec_api.h => of_openfec_profile.h
*/
#ifdef OF_USE_REED_SOLOMON_2_M_CODEC
#include "../../lib_common/linear_binary_codes_utils/of_linear_binary_code.h"
#include "of_reed-solomon_gf_2_m_api.h"
#include "of_reed-solomon_gf_2_m.h"
#include "galois_field_codes_utils/of_galois_field_code.h"
#include "galois_field_codes_utils/algebra_2_4.h"
#include "galois_field_codes_utils/algebra_2_8.h"
#endif //OF_USE_REED_SOLOMON_2_M_CODEC
#endif //OF_REED_SOLOMON_INCLUDES_H

19
thirdparty/openfec/xmake.lua vendored Normal file
View File

@@ -0,0 +1,19 @@
package("openfec")
set_homepage("http://openfec.org/")
set_license("CeCCIL-C")
set_sourcedir(os.scriptdir())
on_install(function (package)
local configs = {}
table.insert(configs, "-DDEBUG:STRING=" .. (package:debug() and "ON" or "OFF"))
table.insert(configs, "-DLIBRARY_OUTPUT_PATH=" .. (path.join(package:installdir(), "lib")))
import("package.tools.cmake").install(package, configs)
os.cp("src", package:installdir())
package:add("includedirs", "src")
end)
on_test(function (package)
assert(package:has_cfuncs("of_create_codec_instance", {includes = "lib_common/of_openfec_api.h"}))
end)

View File

@@ -1,3 +1,4 @@
includes("openfec")
if is_plat("windows") then
elseif is_plat("linux") then
includes("ffmpeg")