From 3ecb2fa8d8f70ba304738622273a20c9429635af Mon Sep 17 00:00:00 2001 From: favoritas37 Date: Sun, 14 Jun 2015 20:50:26 +0300 Subject: [PATCH] completed the first implementation of zxing::ReedSolomonEncoder --- .../common/reedsolomon/ReedSolomonEncoder.cpp | 64 +++++++++++++++++++ .../common/reedsolomon/ReedSolomonEncoder.h | 26 ++++++++ 2 files changed, 90 insertions(+) create mode 100644 source/zxing/zxing/common/reedsolomon/ReedSolomonEncoder.cpp create mode 100644 source/zxing/zxing/common/reedsolomon/ReedSolomonEncoder.h diff --git a/source/zxing/zxing/common/reedsolomon/ReedSolomonEncoder.cpp b/source/zxing/zxing/common/reedsolomon/ReedSolomonEncoder.cpp new file mode 100644 index 0000000..d37f4d8 --- /dev/null +++ b/source/zxing/zxing/common/reedsolomon/ReedSolomonEncoder.cpp @@ -0,0 +1,64 @@ +#include "ReedSolomonEncoder.h" + +#include +#include +#include + +namespace zxing { + +ReedSolomonEncoder::ReedSolomonEncoder(Ref field) : + field_(field), cachedGenerators_() +{ + ArrayRef arrayRef(1); //will this work? + arrayRef[0] = 1; + Ref< GenericGFPoly > tmpGeneratorRef(new GenericGFPoly(field, arrayRef)); + cachedGenerators_.push_back(tmpGeneratorRef); +} + +Ref ReedSolomonEncoder::buildGenerator(int degree) +{ + if (degree >= cachedGenerators_.size()) { + Ref lastGenerator = cachedGenerators_.at(cachedGenerators_.size() - 1); + for (int d = cachedGenerators_.size(); d <= degree; d++) + { + ArrayRef arrayRef(2); //will this work? + arrayRef[0] = 1; + arrayRef[1] = field_->exp(d - 1 + field_->getGeneratorBase()); + Ref tmpGFRef(new GenericGFPoly(field_, arrayRef)); + Ref nextGenerator = (*lastGenerator).multiply(tmpGFRef); + cachedGenerators_.push_back(nextGenerator); + lastGenerator = nextGenerator; + } + } + return cachedGenerators_.at(degree); // ??? wont this through exception? +} + +void ReedSolomonEncoder::encode(std::vector &toEncode, int ecBytes) +{ + if (ecBytes == 0) { + throw new Exception("No error correction bytes"); + } + int dataBytes = toEncode.size() - ecBytes; + if (dataBytes <= 0) { + throw new Exception("No data bytes provided"); + } + Ref generator = buildGenerator(ecBytes); + ArrayRef infoCoefficients(dataBytes); + memcpy(infoCoefficients.operator ->(), toEncode.data(), dataBytes); + Ref info(new GenericGFPoly(field_, infoCoefficients)); + info = info->multiplyByMonomial(ecBytes, 1); + Ref remainder = info->divide(generator)[1]; + ArrayRef coefficients = remainder->getCoefficients(); + int numZeroCoefficients = ecBytes - coefficients->size(); + for (int i = 0; i < numZeroCoefficients; i++) { + toEncode[dataBytes + i] = 0; + } + + //original kept for future checks + //System.arraycopy(coefficients, 0, toEncode, dataBytes + numZeroCoefficients, coefficients.length); + toEncode.insert(toEncode.begin() + dataBytes + numZeroCoefficients, + coefficients.array_->values().begin(), + coefficients.array_->values().end()); +} + +} diff --git a/source/zxing/zxing/common/reedsolomon/ReedSolomonEncoder.h b/source/zxing/zxing/common/reedsolomon/ReedSolomonEncoder.h new file mode 100644 index 0000000..968ad34 --- /dev/null +++ b/source/zxing/zxing/common/reedsolomon/ReedSolomonEncoder.h @@ -0,0 +1,26 @@ +#ifndef REEDSOLOMONENCODER_H +#define REEDSOLOMONENCODER_H + +#include +#include +#include + +namespace zxing { + +class ReedSolomonEncoder +{ +private: + Ref field_; + std::vector< Ref< GenericGFPoly > >cachedGenerators_; + + Ref buildGenerator(int degree); + +public: + ReedSolomonEncoder(Ref field); + + void encode(std::vector& toEncode, int ecBytes); +}; + +} + +#endif // REEDSOLOMONENCODER_H