/* (**************************************************************************) (* *) (* Schifra *) (* Reed-Solomon Error Correcting Code Library *) (* *) (* Release Version 0.0.1 *) (* http://www.schifra.com *) (* Copyright (c) 2000-2020 Arash Partow, All Rights Reserved. *) (* *) (* The Schifra Reed-Solomon error correcting code library and all its *) (* components are supplied under the terms of the General Schifra License *) (* agreement. The contents of the Schifra Reed-Solomon error correcting *) (* code library and all its components may not be copied or disclosed *) (* except in accordance with the terms of that agreement. *) (* *) (* URL: http://www.schifra.com/license.html *) (* *) (**************************************************************************) */ #ifndef INCLUDE_SCHIFRA_REED_SOLOMON_INTERLEAVING_HPP #define INCLUDE_SCHIFRA_REED_SOLOMON_INTERLEAVING_HPP #include #include #include #include "schifra_reed_solomon_block.hpp" namespace schifra { namespace reed_solomon { template inline void interleave(block (&block_stack)[code_length]) { for (std::size_t i = 0; i < code_length; ++i) { for (std::size_t j = i + 1; j < code_length; ++j) { typename block::symbol_type tmp = block_stack[i][j]; block_stack[i][j] = block_stack[j][i]; block_stack[j][i] = tmp; } } } template inline void interleave(block (&block_stack)[row_count]) { block auxiliary_stack[row_count]; std::size_t aux_row = 0; std::size_t aux_index = 0; for (std::size_t index = 0; index < code_length; ++index) { for (std::size_t row = 0; row < row_count; ++row) { auxiliary_stack[aux_row][aux_index] = block_stack[row][index]; if (++aux_index == code_length) { aux_index = 0; aux_row++; } } } copy(auxiliary_stack,block_stack); } template inline void interleave(block (&block_stack)[row_count], const std::size_t partial_code_length) { if (partial_code_length == code_length) { interleave(block_stack); } else { block auxiliary_stack[row_count]; std::size_t aux_row = 0; std::size_t aux_index = 0; for (std::size_t index = 0; index < partial_code_length; ++index) { for (std::size_t row = 0; row < row_count; ++row) { auxiliary_stack[aux_row][aux_index] = block_stack[row][index]; if (++aux_index == code_length) { aux_index = 0; aux_row++; } } } for (std::size_t index = partial_code_length; index < code_length; ++index) { for (std::size_t row = 0; row < row_count - 1; ++row) { auxiliary_stack[aux_row][aux_index] = block_stack[row][index]; if (++aux_index == code_length) { aux_index = 0; aux_row++; } } } for (std::size_t row = 0; row < row_count - 1; ++row) { for (std::size_t index = 0; index < code_length - fec_length; ++index) { block_stack[row].data[index] = auxiliary_stack[row].data[index]; } for (std::size_t index = 0; index < fec_length; ++index) { block_stack[row].fec[index] = auxiliary_stack[row].fec[index]; } } for (std::size_t index = 0; index < partial_code_length; ++index) { block_stack[row_count - 1][index] = auxiliary_stack[row_count - 1][index]; } } } template inline void interleave(data_block (&block_stack)[block_length]) { for (std::size_t i = 0; i < block_length; ++i) { for (std::size_t j = i + 1; j < block_length; ++j) { T tmp = block_stack[i][j]; block_stack[i][j] = block_stack[j][i]; block_stack[j][i] = tmp; } } } template inline void interleave(data_block (&block_stack)[row_count]) { data_block auxiliary_stack[row_count]; std::size_t aux_row = 0; std::size_t aux_index = 0; for (std::size_t index = 0; index < block_length; ++index) { for (std::size_t row = 0; row < row_count; ++row) { auxiliary_stack[aux_row][aux_index] = block_stack[row][index]; if (++aux_index == block_length) { aux_index = 0; aux_row++; } } } copy(auxiliary_stack,block_stack); } template inline void interleave(data_block (&block_stack)[row_count], const std::size_t partial_block_length) { if (partial_block_length == block_length) { interleave(block_stack); } else { data_block auxiliary_stack[row_count]; std::size_t aux_row = 0; std::size_t aux_index = 0; for (std::size_t index = 0; index < partial_block_length; ++index) { for (std::size_t row = 0; row < row_count; ++row) { auxiliary_stack[aux_row][aux_index] = block_stack[row][index]; if (++aux_index == block_length) { aux_index = 0; aux_row++; } } } for (std::size_t index = partial_block_length; index < block_length; ++index) { for (std::size_t row = 0; row < row_count - 1; ++row) { auxiliary_stack[aux_row][aux_index] = block_stack[row][index]; if (++aux_index == block_length) { aux_index = 0; aux_row++; } } } for (std::size_t row = 0; row < row_count - 1; ++row) { for (std::size_t index = 0; index < block_length; ++index) { block_stack[row][index] = auxiliary_stack[row][index]; } } for (std::size_t index = 0; index < partial_block_length; ++index) { block_stack[row_count - 1][index] = auxiliary_stack[row_count - 1][index]; } } } template inline void interleave(data_block block_stack[], const std::size_t row_count) { data_block* auxiliary_stack = new data_block[row_count]; std::size_t aux_row = 0; std::size_t aux_index = 0; for (std::size_t index = 0; index < block_length; ++index) { for (std::size_t row = 0; row < row_count; ++row) { auxiliary_stack[aux_row][aux_index] = block_stack[row][index]; if (++aux_index == block_length) { aux_index = 0; aux_row++; } } } for (std::size_t row = 0; row < row_count; ++row) { for (std::size_t index = 0; index < block_length; ++index) { block_stack[row][index] = auxiliary_stack[row][index]; } } delete[] auxiliary_stack; } template inline void interleave(data_block block_stack[], const std::size_t row_count, const std::size_t partial_block_length) { data_block* auxiliary_stack = new data_block[row_count]; std::size_t aux_row = 0; std::size_t aux_index = 0; for (std::size_t index = 0; index < partial_block_length; ++index) { for (std::size_t row = 0; row < row_count; ++row) { auxiliary_stack[aux_row][aux_index] = block_stack[row][index]; if (++aux_index == block_length) { aux_index = 0; aux_row++; } } } for (std::size_t index = partial_block_length; index < block_length; ++index) { for (std::size_t row = 0; row < row_count - 1; ++row) { auxiliary_stack[aux_row][aux_index] = block_stack[row][index]; if (++aux_index == block_length) { aux_index = 0; aux_row++; } } } for (std::size_t row = 0; row < row_count - 1; ++row) { for (std::size_t index = 0; index < block_length; ++index) { block_stack[row][index] = auxiliary_stack[row][index]; } } for (std::size_t index = 0; index < partial_block_length; ++index) { block_stack[row_count - 1][index] = auxiliary_stack[row_count - 1][index]; } delete[] auxiliary_stack; } template inline void deinterleave(block (&block_stack)[row_count]) { block auxiliary_stack[row_count]; std::size_t aux_row = 0; std::size_t aux_index = 0; for (std::size_t row = 0; row < row_count; ++row) { for (std::size_t index = 0; index < code_length; ++index) { auxiliary_stack[aux_row][aux_index] = block_stack[row][index]; if (++aux_row == row_count) { aux_row = 0; aux_index++; } } } copy(auxiliary_stack,block_stack); } template inline void deinterleave(block (&block_stack)[row_count], const std::size_t partial_code_length) { if (partial_code_length == code_length) { deinterleave(block_stack); } else { block auxiliary_stack[row_count]; std::size_t aux_row1 = 0; std::size_t aux_index1 = 0; std::size_t aux_row2 = 0; std::size_t aux_index2 = 0; for (std::size_t i = 0; i < partial_code_length * row_count; ++i) { auxiliary_stack[aux_row1][aux_index1] = block_stack[aux_row2][aux_index2]; if (++aux_row1 == row_count) { aux_row1 = 0; aux_index1++; } if (++aux_index2 == code_length) { aux_index2 = 0; aux_row2++; } } for (std::size_t i = 0; aux_index1 < code_length; ++i) { auxiliary_stack[aux_row1][aux_index1] = block_stack[aux_row2][aux_index2]; if (++aux_row1 == (row_count - 1)) { aux_row1 = 0; aux_index1++; } if (++aux_index2 == code_length) { aux_index2 = 0; aux_row2++; } } for (std::size_t row = 0; row < row_count - 1; ++row) { for (std::size_t index = 0; index < code_length; ++index) { block_stack[row][index] = auxiliary_stack[row][index]; } } for (std::size_t index = 0; index < partial_code_length; ++index) { block_stack[row_count - 1][index] = auxiliary_stack[row_count - 1][index]; } } } template inline void deinterleave(data_block (&block_stack)[block_length]) { data_block auxiliary_stack[block_length]; for (std::size_t row = 0; row < block_length; ++row) { for (std::size_t index = 0; index < block_length; ++index) { auxiliary_stack[index][row] = block_stack[row][index]; } } copy(auxiliary_stack,block_stack); } template inline void deinterleave(data_block (&block_stack)[row_count]) { data_block auxiliary_stack[row_count]; std::size_t aux_row = 0; std::size_t aux_index = 0; for (std::size_t row = 0; row < row_count; ++row) { for (std::size_t index = 0; index < block_length; ++index) { auxiliary_stack[aux_row][aux_index] = block_stack[row][index]; if (++aux_row == row_count) { aux_row = 0; aux_index++; } } } copy(auxiliary_stack,block_stack); } template inline void deinterleave(data_block block_stack[], const std::size_t row_count) { data_block* auxiliary_stack = new data_block[row_count]; std::size_t aux_row = 0; std::size_t aux_index = 0; for (std::size_t row = 0; row < row_count; ++row) { for (std::size_t index = 0; index < block_length; ++index) { auxiliary_stack[aux_row][aux_index] = block_stack[row][index]; if (++aux_row == row_count) { aux_row = 0; aux_index++; } } } for (std::size_t row = 0; row < row_count; ++row) { for (std::size_t index = 0; index < block_length; ++index) { block_stack[row][index] = auxiliary_stack[row][index]; } } delete[] auxiliary_stack; } template inline void deinterleave(data_block block_stack[], const std::size_t row_count, const std::size_t partial_block_length) { if (row_count == 1) return; data_block* auxiliary_stack = new data_block[row_count]; std::size_t aux_row1 = 0; std::size_t aux_index1 = 0; std::size_t aux_row2 = 0; std::size_t aux_index2 = 0; for (std::size_t i = 0; i < partial_block_length * row_count; ++i) { auxiliary_stack[aux_row1][aux_index1] = block_stack[aux_row2][aux_index2]; if (++aux_row1 == row_count) { aux_row1 = 0; aux_index1++; } if (++aux_index2 == block_length) { aux_index2 = 0; aux_row2++; } } for (std::size_t i = 0; aux_index1 < block_length; ++i) { auxiliary_stack[aux_row1][aux_index1] = block_stack[aux_row2][aux_index2]; if (++aux_row1 == (row_count - 1)) { aux_row1 = 0; aux_index1++; } if (++aux_index2 == block_length) { aux_index2 = 0; aux_row2++; } } for (std::size_t row = 0; row < row_count - 1; ++row) { for (std::size_t index = 0; index < block_length; ++index) { block_stack[row][index] = auxiliary_stack[row][index]; } } for (std::size_t index = 0; index < partial_block_length; ++index) { block_stack[row_count - 1][index] = auxiliary_stack[row_count - 1][index]; } delete[] auxiliary_stack; } template inline void interleave_columnskip(data_block* block_stack) { for (std::size_t i = 0; i < block_length; ++i) { for (std::size_t j = i + 1; j < block_length; ++j) { std::size_t x1 = i + skip_columns; std::size_t x2 = j + skip_columns; T tmp = block_stack[i][x2]; block_stack[i][x2] = block_stack[j][x1]; block_stack[j][x1] = tmp; } } } template inline void interleave_columnskip(data_block* block_stack, const std::size_t& row_count) { data_block* auxiliary_stack = new data_block[row_count]; std::size_t aux_row = 0; std::size_t aux_index = skip_columns; for (std::size_t index = skip_columns; index < block_length; ++index) { for (std::size_t row = 0; row < row_count; ++row) { auxiliary_stack[aux_row][aux_index] = block_stack[row][index]; if (++aux_index == block_length) { aux_index = skip_columns; aux_row++; } } } for (std::size_t row = 0; row < row_count; ++row) { for (std::size_t index = skip_columns; index < block_length; ++index) { block_stack[row][index] = auxiliary_stack[row][index]; } } delete[] auxiliary_stack; } template inline void interleave(T* block_stack[data_length]) { for (std::size_t i = 0; i < data_length; ++i) { for (std::size_t j = i + 1; j < data_length; ++j) { T tmp = block_stack[i][j]; block_stack[i][j] = block_stack[j][i]; block_stack[j][i] = tmp; } } } template inline void interleave_columnskip(T* block_stack[data_length]) { for (std::size_t i = skip_columns; i < data_length; ++i) { for (std::size_t j = i + 1; j < data_length; ++j) { T tmp = block_stack[i][j]; block_stack[i][j] = block_stack[j][i]; block_stack[j][i] = tmp; } } } } // namespace reed_solomon } // namespace schifra #endif