From 62819a5376dad50934fcee1cc3d5800699a4b800 Mon Sep 17 00:00:00 2001 From: Ahmet Inan Date: Thu, 27 Sep 2018 18:29:13 +0200 Subject: [PATCH] added data_len argument for shortened codes --- bose_chaudhuri_hocquenghem_decoder.hh | 48 +++++++++++++++++---------- bose_chaudhuri_hocquenghem_encoder.hh | 10 +++--- reed_solomon_decoder.hh | 32 ++++++++++-------- reed_solomon_encoder.hh | 9 ++--- 4 files changed, 60 insertions(+), 39 deletions(-) diff --git a/bose_chaudhuri_hocquenghem_decoder.hh b/bose_chaudhuri_hocquenghem_decoder.hh index 176a2be..6a53b67 100644 --- a/bose_chaudhuri_hocquenghem_decoder.hh +++ b/bose_chaudhuri_hocquenghem_decoder.hh @@ -34,35 +34,41 @@ private: } } public: - int compute_syndromes(uint8_t *data, uint8_t *parity, ValueType *syndromes) + int compute_syndromes(uint8_t *data, uint8_t *parity, ValueType *syndromes, int data_len = K) { + assert(0 < data_len && data_len <= K); // $syndromes_i = code(pe^{FCR+i})$ ValueType coeff(get_be_bit(data, 0)); for (int i = 0; i < NR; ++i) syndromes[i] = coeff; - update_syndromes(data, syndromes, 1, K); + update_syndromes(data, syndromes, 1, data_len); update_syndromes(parity, syndromes, 0, NP); int nonzero = 0; for (int i = 0; i < NR; ++i) nonzero += !!syndromes[i]; return nonzero; } - int compute_syndromes(uint8_t *data, uint8_t *parity, value_type *syndromes) + int compute_syndromes(uint8_t *data, uint8_t *parity, value_type *syndromes, int data_len = K) { - return compute_syndromes(data, parity, reinterpret_cast(syndromes)); + return compute_syndromes(data, parity, reinterpret_cast(syndromes), data_len); } - int operator()(uint8_t *data, uint8_t *parity, value_type *erasures = 0, int erasures_count = 0) + int operator()(uint8_t *data, uint8_t *parity, value_type *erasures = 0, int erasures_count = 0, int data_len = K) { assert(0 <= erasures_count && erasures_count <= NR); + assert(0 < data_len && data_len <= K); if (0) { for (int i = 0; i < erasures_count; ++i) { int idx = (int)erasures[i]; - if (idx < K) + if (idx < data_len) set_be_bit(data, idx, 0); else - set_be_bit(parity, idx-K, 0); + set_be_bit(parity, idx-data_len, 0); } } + if (erasures_count && data_len < K) { + for (int i = 0; i < erasures_count; ++i) + erasures[i] += K - data_len; + } ValueType syndromes[NR]; if (!compute_syndromes(data, parity, syndromes)) return 0; @@ -75,12 +81,12 @@ public: if (1 < (int)magnitudes[i]) return -1; for (int i = 0; i < count; ++i) { - int idx = (int)locations[i]; + int idx = (int)locations[i] + data_len - K; bool err = (bool)magnitudes[i]; - if (idx < K) + if (idx < data_len) xor_be_bit(data, idx, err); else - xor_be_bit(parity, idx-K, err); + xor_be_bit(parity, idx-data_len, err); } int corrections_count = 0; for (int i = 0; i < count; ++i) @@ -111,31 +117,37 @@ private: } } public: - int compute_syndromes(ValueType *data, ValueType *parity, ValueType *syndromes) + int compute_syndromes(ValueType *data, ValueType *parity, ValueType *syndromes, int data_len = K) { + assert(0 < data_len && data_len <= K); // $syndromes_i = code(pe^{FCR+i})$ ValueType coeff(data[0]); for (int i = 0; i < NR; ++i) syndromes[i] = coeff; - update_syndromes(data, syndromes, 1, K); + update_syndromes(data, syndromes, 1, data_len); update_syndromes(parity, syndromes, 0, NP); int nonzero = 0; for (int i = 0; i < NR; ++i) nonzero += !!syndromes[i]; return nonzero; } - int operator()(ValueType *data, ValueType *parity, IndexType *erasures = 0, int erasures_count = 0) + int operator()(ValueType *data, ValueType *parity, IndexType *erasures = 0, int erasures_count = 0, int data_len = K) { assert(0 <= erasures_count && erasures_count <= NR); + assert(0 < data_len && data_len <= K); if (0) { for (int i = 0; i < erasures_count; ++i) { int idx = (int)erasures[i]; - if (idx < K) + if (idx < data_len) data[idx] = ValueType(0); else - parity[idx-K] = ValueType(0); + parity[idx-data_len] = ValueType(0); } } + if (erasures_count && data_len < K) { + for (int i = 0; i < erasures_count; ++i) + erasures[i] = IndexType((int)erasures[i] + K - data_len); + } ValueType syndromes[NR]; if (!compute_syndromes(data, parity, syndromes)) return 0; @@ -148,11 +160,11 @@ public: if (1 < (int)magnitudes[i]) return -1; for (int i = 0; i < count; ++i) { - int idx = (int)locations[i]; - if (idx < K) + int idx = (int)locations[i] + data_len - K; + if (idx < data_len) data[idx] += magnitudes[i]; else - parity[idx-K] += magnitudes[i]; + parity[idx-data_len] += magnitudes[i]; } int corrections_count = 0; for (int i = 0; i < count; ++i) diff --git a/bose_chaudhuri_hocquenghem_encoder.hh b/bose_chaudhuri_hocquenghem_encoder.hh index 0b24830..c04a5d7 100644 --- a/bose_chaudhuri_hocquenghem_encoder.hh +++ b/bose_chaudhuri_hocquenghem_encoder.hh @@ -59,12 +59,13 @@ public: set_be_bit(generator, i, get_be_bit(generator, i+1)); set_be_bit(generator, NP, 0); } - void operator()(uint8_t *data, uint8_t *parity) + void operator()(uint8_t *data, uint8_t *parity, int data_len = K) { + assert(0 < data_len && data_len <= K); // $code = data * x^{NP} + (data * x^{NP}) \mod{generator}$ for (int l = 0; l < NP/8; ++l) parity[l] = 0; - for (int i = 0; i < K; ++i) { + for (int i = 0; i < data_len; ++i) { if (get_be_bit(data, i) != get_be_bit(parity, 0)) { for (int l = 0; l < (NP-1)/8; ++l) parity[l] = generator[l] ^ slb1(parity, l); @@ -125,12 +126,13 @@ public: std::cerr << std::endl; } } - void operator()(ValueType *data, ValueType *parity) + void operator()(ValueType *data, ValueType *parity, int data_len = K) { + assert(0 < data_len && data_len <= K); // $code = data * x^{NP} + (data * x^{NP}) \mod{generator}$ for (int i = 0; i < NP; ++i) parity[i] = ValueType(0); - for (int i = 0; i < K; ++i) { + for (int i = 0; i < data_len; ++i) { if (data[i] != parity[0]) { for (int j = 1; j < NP; ++j) parity[j-1] = generator[NP-j] + parity[j]; diff --git a/reed_solomon_decoder.hh b/reed_solomon_decoder.hh index 00d715f..d33c5dd 100644 --- a/reed_solomon_decoder.hh +++ b/reed_solomon_decoder.hh @@ -33,33 +33,39 @@ private: } } public: - int compute_syndromes(ValueType *data, ValueType *parity, ValueType *syndromes) + int compute_syndromes(ValueType *data, ValueType *parity, ValueType *syndromes, int data_len = K) { + assert(0 < data_len && data_len <= K); // $syndromes_i = code(pe^{FCR+i})$ ValueType coeff(data[0]); for (int i = 0; i < NR; ++i) syndromes[i] = coeff; - update_syndromes(data, syndromes, 1, K); + update_syndromes(data, syndromes, 1, data_len); update_syndromes(parity, syndromes, 0, NP); int nonzero = 0; for (int i = 0; i < NR; ++i) nonzero += !!syndromes[i]; return nonzero; } - int operator()(ValueType *data, ValueType *parity, IndexType *erasures = 0, int erasures_count = 0) + int operator()(ValueType *data, ValueType *parity, IndexType *erasures = 0, int erasures_count = 0, int data_len = K) { assert(0 <= erasures_count && erasures_count <= NR); + assert(0 < data_len && data_len <= K); if (0) { for (int i = 0; i < erasures_count; ++i) { int idx = (int)erasures[i]; - if (idx < K) + if (idx < data_len) data[idx] = ValueType(0); else - parity[idx-K] = ValueType(0); + parity[idx-data_len] = ValueType(0); } } + if (erasures_count && data_len < K) { + for (int i = 0; i < erasures_count; ++i) + erasures[i] = IndexType((int)erasures[i] + K - data_len); + } ValueType syndromes[NR]; - if (!compute_syndromes(data, parity, syndromes)) + if (!compute_syndromes(data, parity, syndromes, data_len)) return 0; IndexType locations[NR]; ValueType magnitudes[NR]; @@ -67,24 +73,24 @@ public: if (count <= 0) return count; for (int i = 0; i < count; ++i) { - int idx = (int)locations[i]; - if (idx < K) + int idx = (int)locations[i] + data_len - K; + if (idx < data_len) data[idx] += magnitudes[i]; else - parity[idx-K] += magnitudes[i]; + parity[idx-data_len] += magnitudes[i]; } int corrections_count = 0; for (int i = 0; i < count; ++i) corrections_count += !!magnitudes[i]; return corrections_count; } - int operator()(value_type *data, value_type *parity, value_type *erasures = 0, int erasures_count = 0) + int operator()(value_type *data, value_type *parity, value_type *erasures = 0, int erasures_count = 0, int data_len = K) { - return (*this)(reinterpret_cast(data), reinterpret_cast(parity), reinterpret_cast(erasures), erasures_count); + return (*this)(reinterpret_cast(data), reinterpret_cast(parity), reinterpret_cast(erasures), erasures_count, data_len); } - int compute_syndromes(value_type *data, value_type *parity, value_type *syndromes) + int compute_syndromes(value_type *data, value_type *parity, value_type *syndromes, int data_len = K) { - return compute_syndromes(reinterpret_cast(data), reinterpret_cast(parity), reinterpret_cast(syndromes)); + return compute_syndromes(reinterpret_cast(data), reinterpret_cast(parity), reinterpret_cast(syndromes), data_len); } }; diff --git a/reed_solomon_encoder.hh b/reed_solomon_encoder.hh index dc20c8c..66e44f4 100644 --- a/reed_solomon_encoder.hh +++ b/reed_solomon_encoder.hh @@ -48,12 +48,13 @@ public: for (int i = 0; i <= NR; ++i) generator[i] = index(tmp[i]); } - void operator()(ValueType *data, ValueType *parity) + void operator()(ValueType *data, ValueType *parity, int data_len = K) { + assert(0 < data_len && data_len <= K); // $code = data * x^{NR} + (data * x^{NR}) \mod{generator}$ for (int i = 0; i < NR; ++i) parity[i] = ValueType(0); - for (int i = 0; i < K; ++i) { + for (int i = 0; i < data_len; ++i) { ValueType feedback = data[i] + parity[0]; if (feedback) { IndexType fb = index(feedback); @@ -67,9 +68,9 @@ public: } } } - void operator()(value_type *data, value_type *parity) + void operator()(value_type *data, value_type *parity, int data_len = K) { - (*this)(reinterpret_cast(data), reinterpret_cast(parity)); + (*this)(reinterpret_cast(data), reinterpret_cast(parity), data_len); } };