Update C++ code from Java implementation, binarizer and ReedSolomon. Closes issue 1099.

git-svn-id: https://zxing.googlecode.com/svn/trunk@2082 59b500cc-1b3d-0410-9834-0bbf25fbcc57
This commit is contained in:
smparkes@smparkes.net 2011-12-12 22:38:50 +00:00
parent 18f357a36f
commit 1cd49dbcb1
5 changed files with 14 additions and 13 deletions

View file

@ -64,7 +64,7 @@ Ref<BitArray> GlobalHistogramBinarizer::getBlackRow(int y, Ref<BitArray> row) {
for (int x = 0; x < width; x++) { for (int x = 0; x < width; x++) {
histogram[row_pixels[x] >> LUMINANCE_SHIFT]++; histogram[row_pixels[x] >> LUMINANCE_SHIFT]++;
} }
int blackPoint = estimate(histogram) << LUMINANCE_SHIFT; int blackPoint = estimate(histogram);
BitArray& array = *row; BitArray& array = *row;
int left = row_pixels[0]; int left = row_pixels[0];
@ -118,14 +118,14 @@ Ref<BitMatrix> GlobalHistogramBinarizer::getBlackMatrix() {
} }
} }
int blackPoint = estimate(histogram) << LUMINANCE_SHIFT; int blackPoint = estimate(histogram);
Ref<BitMatrix> matrix_ref(new BitMatrix(width, height)); Ref<BitMatrix> matrix_ref(new BitMatrix(width, height));
BitMatrix& matrix = *matrix_ref; BitMatrix& matrix = *matrix_ref;
for (int y = 0; y < height; y++) { for (int y = 0; y < height; y++) {
row = source.getRow(y, row); row = source.getRow(y, row);
for (int x = 0; x < width; x++) { for (int x = 0; x < width; x++) {
if (row[x] <= blackPoint) if (row[x] < blackPoint)
matrix.set(x, y); matrix.set(x, y);
} }
} }
@ -199,7 +199,7 @@ int GlobalHistogramBinarizer::estimate(vector<int> &histogram) {
} }
} }
return bestValley; return bestValley << LUMINANCE_SHIFT;
} }
Ref<Binarizer> GlobalHistogramBinarizer::createBinarizer(Ref<LuminanceSource> source) { Ref<Binarizer> GlobalHistogramBinarizer::createBinarizer(Ref<LuminanceSource> source) {

View file

@ -26,10 +26,6 @@ using namespace std;
using namespace zxing; using namespace zxing;
namespace { namespace {
const int LUMINANCE_BITS = 5;
const int LUMINANCE_SHIFT = 8 - LUMINANCE_BITS;
const int LUMINANCE_BUCKETS = 1 << LUMINANCE_BITS;
const int BLOCK_SIZE_POWER = 3; const int BLOCK_SIZE_POWER = 3;
const int BLOCK_SIZE = 1 << BLOCK_SIZE_POWER; const int BLOCK_SIZE = 1 << BLOCK_SIZE_POWER;
const int BLOCK_SIZE_MASK = BLOCK_SIZE - 1; const int BLOCK_SIZE_MASK = BLOCK_SIZE - 1;

View file

@ -55,9 +55,10 @@ void ReedSolomonDecoder::decode(ArrayRef<int> received, int twoS) {
syndromeCoefficients.array_ << "\n"; syndromeCoefficients.array_ << "\n";
#endif #endif
bool dataMatrix = (&field == &GF256::DATA_MATRIX_FIELD);
bool noError = true; bool noError = true;
for (int i = 0; i < twoS; i++) { for (int i = 0; i < twoS; i++) {
int eval = poly->evaluateAt(field.exp(i)); int eval = poly->evaluateAt(field.exp(dataMatrix ? i + 1 : i));
syndromeCoefficients[syndromeCoefficients->size() - 1 - i] = eval; syndromeCoefficients[syndromeCoefficients->size() - 1 - i] = eval;
if (eval != 0) { if (eval != 0) {
noError = false; noError = false;
@ -71,7 +72,7 @@ void ReedSolomonDecoder::decode(ArrayRef<int> received, int twoS) {
Ref<GF256Poly> monomial(field.buildMonomial(twoS, 1)); Ref<GF256Poly> monomial(field.buildMonomial(twoS, 1));
vector<Ref<GF256Poly> > sigmaOmega(runEuclideanAlgorithm(monomial, syndrome, twoS)); vector<Ref<GF256Poly> > sigmaOmega(runEuclideanAlgorithm(monomial, syndrome, twoS));
ArrayRef<int> errorLocations = findErrorLocations(sigmaOmega[0]); ArrayRef<int> errorLocations = findErrorLocations(sigmaOmega[0]);
ArrayRef<int> errorMagitudes = findErrorMagnitudes(sigmaOmega[1], errorLocations); ArrayRef<int> errorMagitudes = findErrorMagnitudes(sigmaOmega[1], errorLocations, dataMatrix);
for (unsigned i = 0; i < errorLocations->size(); i++) { for (unsigned i = 0; i < errorLocations->size(); i++) {
int position = received->size() - 1 - field.log(errorLocations[i]); int position = received->size() - 1 - field.log(errorLocations[i]);
//TODO: check why the position would be invalid //TODO: check why the position would be invalid
@ -173,7 +174,7 @@ ArrayRef<int> ReedSolomonDecoder::findErrorLocations(Ref<GF256Poly> errorLocator
return result; return result;
} }
ArrayRef<int> ReedSolomonDecoder::findErrorMagnitudes(Ref<GF256Poly> errorEvaluator, ArrayRef<int> errorLocations) { ArrayRef<int> ReedSolomonDecoder::findErrorMagnitudes(Ref<GF256Poly> errorEvaluator, ArrayRef<int> errorLocations, bool dataMatrix) {
// This is directly applying Forney's Formula // This is directly applying Forney's Formula
int s = errorLocations.size(); int s = errorLocations.size();
ArrayRef<int> result(s); ArrayRef<int> result(s);
@ -187,6 +188,10 @@ ArrayRef<int> ReedSolomonDecoder::findErrorMagnitudes(Ref<GF256Poly> errorEvalua
} }
} }
result[i] = field.multiply(errorEvaluator->evaluateAt(xiInverse), field.inverse(denominator)); result[i] = field.multiply(errorEvaluator->evaluateAt(xiInverse), field.inverse(denominator));
if (dataMatrix) {
result[i] = field.multiply(result[i], xiInverse);
}
} }
return result; return result;
} }

View file

@ -39,7 +39,7 @@ public:
private: private:
std::vector<Ref<GF256Poly> > runEuclideanAlgorithm(Ref<GF256Poly> a, Ref<GF256Poly> b, int R); std::vector<Ref<GF256Poly> > runEuclideanAlgorithm(Ref<GF256Poly> a, Ref<GF256Poly> b, int R);
ArrayRef<int> findErrorLocations(Ref<GF256Poly> errorLocator); ArrayRef<int> findErrorLocations(Ref<GF256Poly> errorLocator);
ArrayRef<int> findErrorMagnitudes(Ref<GF256Poly> errorEvaluator, ArrayRef<int> errorLocations); ArrayRef<int> findErrorMagnitudes(Ref<GF256Poly> errorEvaluator, ArrayRef<int> errorLocations, bool dataMatrix);
}; };
} }

View file

@ -30,7 +30,7 @@ void BlackPointEstimatorTest::testBasic() {
int histogramRaw[] = { 0, 0, 11, 43, 37, 18, 3, 1, 0, 0, 13, 36, 24, 0, 11, 2 }; int histogramRaw[] = { 0, 0, 11, 43, 37, 18, 3, 1, 0, 0, 13, 36, 24, 0, 11, 2 };
vector<int> histogram(histogramRaw, histogramRaw+16); vector<int> histogram(histogramRaw, histogramRaw+16);
size_t point = GlobalHistogramBinarizer::estimate(histogram); size_t point = GlobalHistogramBinarizer::estimate(histogram);
CPPUNIT_ASSERT_EQUAL((size_t)8, point); CPPUNIT_ASSERT_EQUAL((size_t)64, point);
} }
void BlackPointEstimatorTest::testTooLittleRange() { void BlackPointEstimatorTest::testTooLittleRange() {