Generator polynomial for reed-Solomon algorithm can now have coefficients in any Gallois fields rather than GF(256) only

git-svn-id: https://zxing.googlecode.com/svn/trunk@1666 59b500cc-1b3d-0410-9834-0bbf25fbcc57
This commit is contained in:
dav.olivier@gmail.com 2010-11-20 21:18:04 +00:00
parent 29dce2a397
commit 5ec9b84660
11 changed files with 499 additions and 50 deletions

View file

@ -0,0 +1,186 @@
/*
* Copyright 2007 ZXing authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.google.zxing.common.reedsolomon;
/**
* <p>This class contains utility methods for performing mathematical operations over
* the Galois Fields. Operations use a given primitive polynomial in calculations.</p>
*
* <p>Throughout this package, elements of the GF are represented as an <code>int</code>
* for convenience and speed (but at the cost of memory).
* </p>
*
* @author Sean Owen
* @author David Olivier
*/
public final class GenericGF {
public static final GenericGF AZTEC_DATA_12 = new GenericGF(0x1069, 4096); // x^12 + x^6 + x^5 + x^3 + 1
public static final GenericGF AZTEC_DATA_10 = new GenericGF(0x409, 1024); // x^10 + x^3 + 1
public static final GenericGF AZTEC_DATA_6 = new GenericGF(0x43, 64); // x^6 + x + 1
public static final GenericGF AZTEC_PARAM = new GenericGF(0x13, 16); // x^4 + x + 1
public static final GenericGF QR_CODE_FIELD_256 = new GenericGF(0x011D, 256); // x^8 + x^4 + x^3 + x^2 + 1
public static final GenericGF DATA_MATRIX_FIELD_256 = new GenericGF(0x012D, 256); // x^8 + x^5 + x^3 + x^2 + 1
public static final GenericGF AZTEC_DATA_8 = DATA_MATRIX_FIELD_256;
private static final int INITIALIZATION_THRESHOLD = 0;
private int[] expTable;
private int[] logTable;
private GenericGFPoly zero;
private GenericGFPoly one;
private final int size;
private final int primitive;
private boolean initialized = false;
/**
* Create a representation of GF(size) using the given primitive polynomial.
*
* @param primitive irreducible polynomial whose coefficients are represented by
* the bits of an int, where the least-significant bit represents the constant
* coefficient
*/
public GenericGF(int primitive, int size) {
this.primitive = primitive;
this.size = size;
if (size <= INITIALIZATION_THRESHOLD){
initialize();
}
}
private void initialize(){
expTable = new int[size];
logTable = new int[size];
int x = 1;
for (int i = 0; i < size; i++) {
expTable[i] = x;
x <<= 1; // x = x * 2; we're assuming the generator alpha is 2
if (x >= size) {
x ^= primitive;
x &= size-1;
}
}
for (int i = 0; i < size-1; i++) {
logTable[expTable[i]] = i;
}
// logTable[0] == 0 but this should never be used
zero = new GenericGFPoly(this, new int[]{0});
one = new GenericGFPoly(this, new int[]{1});
initialized = true;
}
private void checkInit(){
if (!initialized) initialize();
}
GenericGFPoly getZero() {
checkInit();
return zero;
}
GenericGFPoly getOne() {
checkInit();
return one;
}
/**
* @return the monomial representing coefficient * x^degree
*/
GenericGFPoly buildMonomial(int degree, int coefficient) {
checkInit();
if (degree < 0) {
throw new IllegalArgumentException();
}
if (coefficient == 0) {
return zero;
}
int[] coefficients = new int[degree + 1];
coefficients[0] = coefficient;
return new GenericGFPoly(this, coefficients);
}
/**
* Implements both addition and subtraction -- they are the same in GF(size).
*
* @return sum/difference of a and b
*/
static int addOrSubtract(int a, int b) {
return a ^ b;
}
/**
* @return 2 to the power of a in GF(size)
*/
int exp(int a) {
checkInit();
return expTable[a];
}
/**
* @return base 2 log of a in GF(size)
*/
int log(int a) {
checkInit();
if (a == 0) {
throw new IllegalArgumentException();
}
return logTable[a];
}
/**
* @return multiplicative inverse of a
*/
int inverse(int a) {
checkInit();
if (a == 0) {
throw new ArithmeticException();
}
return expTable[size - logTable[a] - 1];
}
/**
* @param a
* @param b
* @return product of a and b in GF(size)
*/
int multiply(int a, int b) {
checkInit();
if (a == 0 || b == 0) {
return 0;
}
if (a<0 || b <0 || a>=size || b >=size){
a++;
}
int logSum = logTable[a] + logTable[b];
return expTable[(logSum % size) + logSum / size];
}
public int getSize(){
return size;
}
}

View file

@ -0,0 +1,263 @@
/*
* Copyright 2007 ZXing authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.google.zxing.common.reedsolomon;
/**
* <p>Represents a polynomial whose coefficients are elements of a GF.
* Instances of this class are immutable.</p>
*
* <p>Much credit is due to William Rucklidge since portions of this code are an indirect
* port of his C++ Reed-Solomon implementation.</p>
*
* @author Sean Owen
*/
final class GenericGFPoly {
private final GenericGF field;
private final int[] coefficients;
/**
* @param field the {@link GenericGF} instance representing the field to use
* to perform computations
* @param coefficients coefficients as ints representing elements of GF(size), arranged
* from most significant (highest-power term) coefficient to least significant
* @throws IllegalArgumentException if argument is null or empty,
* or if leading coefficient is 0 and this is not a
* constant polynomial (that is, it is not the monomial "0")
*/
GenericGFPoly(GenericGF field, int[] coefficients) {
if (coefficients == null || coefficients.length == 0) {
throw new IllegalArgumentException();
}
this.field = field;
int coefficientsLength = coefficients.length;
if (coefficientsLength > 1 && coefficients[0] == 0) {
// Leading term must be non-zero for anything except the constant polynomial "0"
int firstNonZero = 1;
while (firstNonZero < coefficientsLength && coefficients[firstNonZero] == 0) {
firstNonZero++;
}
if (firstNonZero == coefficientsLength) {
this.coefficients = field.getZero().coefficients;
} else {
this.coefficients = new int[coefficientsLength - firstNonZero];
System.arraycopy(coefficients,
firstNonZero,
this.coefficients,
0,
this.coefficients.length);
}
} else {
this.coefficients = coefficients;
}
}
int[] getCoefficients() {
return coefficients;
}
/**
* @return degree of this polynomial
*/
int getDegree() {
return coefficients.length - 1;
}
/**
* @return true iff this polynomial is the monomial "0"
*/
boolean isZero() {
return coefficients[0] == 0;
}
/**
* @return coefficient of x^degree term in this polynomial
*/
int getCoefficient(int degree) {
return coefficients[coefficients.length - 1 - degree];
}
/**
* @return evaluation of this polynomial at a given point
*/
int evaluateAt(int a) {
if (a == 0) {
// Just return the x^0 coefficient
return getCoefficient(0);
}
int size = coefficients.length;
if (a == 1) {
// Just the sum of the coefficients
int result = 0;
for (int i = 0; i < size; i++) {
result = GenericGF.addOrSubtract(result, coefficients[i]);
}
return result;
}
int result = coefficients[0];
for (int i = 1; i < size; i++) {
result = GenericGF.addOrSubtract(field.multiply(a, result), coefficients[i]);
}
return result;
}
GenericGFPoly addOrSubtract(GenericGFPoly other) {
if (!field.equals(other.field)) {
throw new IllegalArgumentException("GenericGFPolys do not have same GenericGF field");
}
if (isZero()) {
return other;
}
if (other.isZero()) {
return this;
}
int[] smallerCoefficients = this.coefficients;
int[] largerCoefficients = other.coefficients;
if (smallerCoefficients.length > largerCoefficients.length) {
int[] temp = smallerCoefficients;
smallerCoefficients = largerCoefficients;
largerCoefficients = temp;
}
int[] sumDiff = new int[largerCoefficients.length];
int lengthDiff = largerCoefficients.length - smallerCoefficients.length;
// Copy high-order terms only found in higher-degree polynomial's coefficients
System.arraycopy(largerCoefficients, 0, sumDiff, 0, lengthDiff);
for (int i = lengthDiff; i < largerCoefficients.length; i++) {
sumDiff[i] = GenericGF.addOrSubtract(smallerCoefficients[i - lengthDiff], largerCoefficients[i]);
}
return new GenericGFPoly(field, sumDiff);
}
GenericGFPoly multiply(GenericGFPoly other) {
if (!field.equals(other.field)) {
throw new IllegalArgumentException("GenericGFPolys do not have same GenericGF field");
}
if (isZero() || other.isZero()) {
return field.getZero();
}
int[] aCoefficients = this.coefficients;
int aLength = aCoefficients.length;
int[] bCoefficients = other.coefficients;
int bLength = bCoefficients.length;
int[] product = new int[aLength + bLength - 1];
for (int i = 0; i < aLength; i++) {
int aCoeff = aCoefficients[i];
for (int j = 0; j < bLength; j++) {
product[i + j] = GenericGF.addOrSubtract(product[i + j],
field.multiply(aCoeff, bCoefficients[j]));
}
}
return new GenericGFPoly(field, product);
}
GenericGFPoly multiply(int scalar) {
if (scalar == 0) {
return field.getZero();
}
if (scalar == 1) {
return this;
}
int size = coefficients.length;
int[] product = new int[size];
for (int i = 0; i < size; i++) {
product[i] = field.multiply(coefficients[i], scalar);
}
return new GenericGFPoly(field, product);
}
GenericGFPoly multiplyByMonomial(int degree, int coefficient) {
if (degree < 0) {
throw new IllegalArgumentException();
}
if (coefficient == 0) {
return field.getZero();
}
int size = coefficients.length;
int[] product = new int[size + degree];
for (int i = 0; i < size; i++) {
product[i] = field.multiply(coefficients[i], coefficient);
}
return new GenericGFPoly(field, product);
}
GenericGFPoly[] divide(GenericGFPoly other) {
if (!field.equals(other.field)) {
throw new IllegalArgumentException("GenericGFPolys do not have same GenericGF field");
}
if (other.isZero()) {
throw new IllegalArgumentException("Divide by 0");
}
GenericGFPoly quotient = field.getZero();
GenericGFPoly remainder = this;
int denominatorLeadingTerm = other.getCoefficient(other.getDegree());
int inverseDenominatorLeadingTerm = field.inverse(denominatorLeadingTerm);
while (remainder.getDegree() >= other.getDegree() && !remainder.isZero()) {
int degreeDifference = remainder.getDegree() - other.getDegree();
int scale = field.multiply(remainder.getCoefficient(remainder.getDegree()), inverseDenominatorLeadingTerm);
GenericGFPoly term = other.multiplyByMonomial(degreeDifference, scale);
GenericGFPoly iterationQuotient = field.buildMonomial(degreeDifference, scale);
quotient = quotient.addOrSubtract(iterationQuotient);
remainder = remainder.addOrSubtract(term);
}
return new GenericGFPoly[] { quotient, remainder };
}
public String toString() {
StringBuffer result = new StringBuffer(8 * getDegree());
for (int degree = getDegree(); degree >= 0; degree--) {
int coefficient = getCoefficient(degree);
if (coefficient != 0) {
if (coefficient < 0) {
result.append(" - ");
coefficient = -coefficient;
} else {
if (result.length() > 0) {
result.append(" + ");
}
}
if (degree == 0 || coefficient != 1) {
int alphaPower = field.log(coefficient);
if (alphaPower == 0) {
result.append('1');
} else if (alphaPower == 1) {
result.append('a');
} else {
result.append("a^");
result.append(alphaPower);
}
}
if (degree != 0) {
if (degree == 1) {
result.append('x');
} else {
result.append("x^");
result.append(degree);
}
}
}
}
return result.toString();
}
}

View file

@ -40,9 +40,9 @@ package com.google.zxing.common.reedsolomon;
*/ */
public final class ReedSolomonDecoder { public final class ReedSolomonDecoder {
private final GF256 field; private final GenericGF field;
public ReedSolomonDecoder(GF256 field) { public ReedSolomonDecoder(GenericGF field) {
this.field = field; this.field = field;
} }
@ -56,9 +56,9 @@ public final class ReedSolomonDecoder {
* @throws ReedSolomonException if decoding fails for any reason * @throws ReedSolomonException if decoding fails for any reason
*/ */
public void decode(int[] received, int twoS) throws ReedSolomonException { public void decode(int[] received, int twoS) throws ReedSolomonException {
GF256Poly poly = new GF256Poly(field, received); GenericGFPoly poly = new GenericGFPoly(field, received);
int[] syndromeCoefficients = new int[twoS]; int[] syndromeCoefficients = new int[twoS];
boolean dataMatrix = field.equals(GF256.DATA_MATRIX_FIELD); boolean dataMatrix = field.equals(GenericGF.DATA_MATRIX_FIELD_256);
boolean noError = true; boolean noError = true;
for (int i = 0; i < twoS; i++) { for (int i = 0; i < twoS; i++) {
// Thanks to sanfordsquires for this fix: // Thanks to sanfordsquires for this fix:
@ -71,11 +71,11 @@ public final class ReedSolomonDecoder {
if (noError) { if (noError) {
return; return;
} }
GF256Poly syndrome = new GF256Poly(field, syndromeCoefficients); GenericGFPoly syndrome = new GenericGFPoly(field, syndromeCoefficients);
GF256Poly[] sigmaOmega = GenericGFPoly[] sigmaOmega =
runEuclideanAlgorithm(field.buildMonomial(twoS, 1), syndrome, twoS); runEuclideanAlgorithm(field.buildMonomial(twoS, 1), syndrome, twoS);
GF256Poly sigma = sigmaOmega[0]; GenericGFPoly sigma = sigmaOmega[0];
GF256Poly omega = sigmaOmega[1]; GenericGFPoly omega = sigmaOmega[1];
int[] errorLocations = findErrorLocations(sigma); int[] errorLocations = findErrorLocations(sigma);
int[] errorMagnitudes = findErrorMagnitudes(omega, errorLocations, dataMatrix); int[] errorMagnitudes = findErrorMagnitudes(omega, errorLocations, dataMatrix);
for (int i = 0; i < errorLocations.length; i++) { for (int i = 0; i < errorLocations.length; i++) {
@ -83,31 +83,31 @@ public final class ReedSolomonDecoder {
if (position < 0) { if (position < 0) {
throw new ReedSolomonException("Bad error location"); throw new ReedSolomonException("Bad error location");
} }
received[position] = GF256.addOrSubtract(received[position], errorMagnitudes[i]); received[position] = GenericGF.addOrSubtract(received[position], errorMagnitudes[i]);
} }
} }
private GF256Poly[] runEuclideanAlgorithm(GF256Poly a, GF256Poly b, int R) private GenericGFPoly[] runEuclideanAlgorithm(GenericGFPoly a, GenericGFPoly b, int R)
throws ReedSolomonException { throws ReedSolomonException {
// Assume a's degree is >= b's // Assume a's degree is >= b's
if (a.getDegree() < b.getDegree()) { if (a.getDegree() < b.getDegree()) {
GF256Poly temp = a; GenericGFPoly temp = a;
a = b; a = b;
b = temp; b = temp;
} }
GF256Poly rLast = a; GenericGFPoly rLast = a;
GF256Poly r = b; GenericGFPoly r = b;
GF256Poly sLast = field.getOne(); GenericGFPoly sLast = field.getOne();
GF256Poly s = field.getZero(); GenericGFPoly s = field.getZero();
GF256Poly tLast = field.getZero(); GenericGFPoly tLast = field.getZero();
GF256Poly t = field.getOne(); GenericGFPoly t = field.getOne();
// Run Euclidean algorithm until r's degree is less than R/2 // Run Euclidean algorithm until r's degree is less than R/2
while (r.getDegree() >= R / 2) { while (r.getDegree() >= R / 2) {
GF256Poly rLastLast = rLast; GenericGFPoly rLastLast = rLast;
GF256Poly sLastLast = sLast; GenericGFPoly sLastLast = sLast;
GF256Poly tLastLast = tLast; GenericGFPoly tLastLast = tLast;
rLast = r; rLast = r;
sLast = s; sLast = s;
tLast = t; tLast = t;
@ -118,7 +118,7 @@ public final class ReedSolomonDecoder {
throw new ReedSolomonException("r_{i-1} was zero"); throw new ReedSolomonException("r_{i-1} was zero");
} }
r = rLastLast; r = rLastLast;
GF256Poly q = field.getZero(); GenericGFPoly q = field.getZero();
int denominatorLeadingTerm = rLast.getCoefficient(rLast.getDegree()); int denominatorLeadingTerm = rLast.getCoefficient(rLast.getDegree());
int dltInverse = field.inverse(denominatorLeadingTerm); int dltInverse = field.inverse(denominatorLeadingTerm);
while (r.getDegree() >= rLast.getDegree() && !r.isZero()) { while (r.getDegree() >= rLast.getDegree() && !r.isZero()) {
@ -138,12 +138,12 @@ public final class ReedSolomonDecoder {
} }
int inverse = field.inverse(sigmaTildeAtZero); int inverse = field.inverse(sigmaTildeAtZero);
GF256Poly sigma = t.multiply(inverse); GenericGFPoly sigma = t.multiply(inverse);
GF256Poly omega = r.multiply(inverse); GenericGFPoly omega = r.multiply(inverse);
return new GF256Poly[]{sigma, omega}; return new GenericGFPoly[]{sigma, omega};
} }
private int[] findErrorLocations(GF256Poly errorLocator) throws ReedSolomonException { private int[] findErrorLocations(GenericGFPoly errorLocator) throws ReedSolomonException {
// This is a direct application of Chien's search // This is a direct application of Chien's search
int numErrors = errorLocator.getDegree(); int numErrors = errorLocator.getDegree();
if (numErrors == 1) { // shortcut if (numErrors == 1) { // shortcut
@ -151,7 +151,7 @@ public final class ReedSolomonDecoder {
} }
int[] result = new int[numErrors]; int[] result = new int[numErrors];
int e = 0; int e = 0;
for (int i = 1; i < 256 && e < numErrors; i++) { for (int i = 1; i < field.getSize() && e < numErrors; i++) {
if (errorLocator.evaluateAt(i) == 0) { if (errorLocator.evaluateAt(i) == 0) {
result[e] = field.inverse(i); result[e] = field.inverse(i);
e++; e++;
@ -163,7 +163,7 @@ public final class ReedSolomonDecoder {
return result; return result;
} }
private int[] findErrorMagnitudes(GF256Poly errorEvaluator, int[] errorLocations, boolean dataMatrix) { private int[] findErrorMagnitudes(GenericGFPoly errorEvaluator, int[] errorLocations, boolean dataMatrix) {
// This is directly applying Forney's Formula // This is directly applying Forney's Formula
int s = errorLocations.length; int s = errorLocations.length;
int[] result = new int[s]; int[] result = new int[s];
@ -173,7 +173,7 @@ public final class ReedSolomonDecoder {
for (int j = 0; j < s; j++) { for (int j = 0; j < s; j++) {
if (i != j) { if (i != j) {
//denominator = field.multiply(denominator, //denominator = field.multiply(denominator,
// GF256.addOrSubtract(1, field.multiply(errorLocations[j], xiInverse))); // GenericGF.addOrSubtract(1, field.multiply(errorLocations[j], xiInverse)));
// Above should work but fails on some Apple and Linux JDKs due to a Hotspot bug. // Above should work but fails on some Apple and Linux JDKs due to a Hotspot bug.
// Below is a funny-looking workaround from Steven Parkes // Below is a funny-looking workaround from Steven Parkes
int term = field.multiply(errorLocations[j], xiInverse); int term = field.multiply(errorLocations[j], xiInverse);

View file

@ -26,28 +26,28 @@ import java.util.Vector;
*/ */
public final class ReedSolomonEncoder { public final class ReedSolomonEncoder {
private final GF256 field; private final GenericGF field;
private final Vector cachedGenerators; private final Vector cachedGenerators;
public ReedSolomonEncoder(GF256 field) { public ReedSolomonEncoder(GenericGF field) {
if (!GF256.QR_CODE_FIELD.equals(field)) { if (!GenericGF.QR_CODE_FIELD_256.equals(field)) {
throw new IllegalArgumentException("Only QR Code is supported at this time"); throw new IllegalArgumentException("Only QR Code is supported at this time");
} }
this.field = field; this.field = field;
this.cachedGenerators = new Vector(); this.cachedGenerators = new Vector();
cachedGenerators.addElement(new GF256Poly(field, new int[] { 1 })); cachedGenerators.addElement(new GenericGFPoly(field, new int[] { 1 }));
} }
private GF256Poly buildGenerator(int degree) { private GenericGFPoly buildGenerator(int degree) {
if (degree >= cachedGenerators.size()) { if (degree >= cachedGenerators.size()) {
GF256Poly lastGenerator = (GF256Poly) cachedGenerators.elementAt(cachedGenerators.size() - 1); GenericGFPoly lastGenerator = (GenericGFPoly) cachedGenerators.elementAt(cachedGenerators.size() - 1);
for (int d = cachedGenerators.size(); d <= degree; d++) { for (int d = cachedGenerators.size(); d <= degree; d++) {
GF256Poly nextGenerator = lastGenerator.multiply(new GF256Poly(field, new int[] { 1, field.exp(d - 1) })); GenericGFPoly nextGenerator = lastGenerator.multiply(new GenericGFPoly(field, new int[] { 1, field.exp(d - 1) }));
cachedGenerators.addElement(nextGenerator); cachedGenerators.addElement(nextGenerator);
lastGenerator = nextGenerator; lastGenerator = nextGenerator;
} }
} }
return (GF256Poly) cachedGenerators.elementAt(degree); return (GenericGFPoly) cachedGenerators.elementAt(degree);
} }
public void encode(int[] toEncode, int ecBytes) { public void encode(int[] toEncode, int ecBytes) {
@ -58,12 +58,12 @@ public final class ReedSolomonEncoder {
if (dataBytes <= 0) { if (dataBytes <= 0) {
throw new IllegalArgumentException("No data bytes provided"); throw new IllegalArgumentException("No data bytes provided");
} }
GF256Poly generator = buildGenerator(ecBytes); GenericGFPoly generator = buildGenerator(ecBytes);
int[] infoCoefficients = new int[dataBytes]; int[] infoCoefficients = new int[dataBytes];
System.arraycopy(toEncode, 0, infoCoefficients, 0, dataBytes); System.arraycopy(toEncode, 0, infoCoefficients, 0, dataBytes);
GF256Poly info = new GF256Poly(field, infoCoefficients); GenericGFPoly info = new GenericGFPoly(field, infoCoefficients);
info = info.multiplyByMonomial(ecBytes, 1); info = info.multiplyByMonomial(ecBytes, 1);
GF256Poly remainder = info.divide(generator)[1]; GenericGFPoly remainder = info.divide(generator)[1];
int[] coefficients = remainder.getCoefficients(); int[] coefficients = remainder.getCoefficients();
int numZeroCoefficients = ecBytes - coefficients.length; int numZeroCoefficients = ecBytes - coefficients.length;
for (int i = 0; i < numZeroCoefficients; i++) { for (int i = 0; i < numZeroCoefficients; i++) {

View file

@ -20,7 +20,7 @@ import com.google.zxing.ChecksumException;
import com.google.zxing.FormatException; import com.google.zxing.FormatException;
import com.google.zxing.common.BitMatrix; import com.google.zxing.common.BitMatrix;
import com.google.zxing.common.DecoderResult; import com.google.zxing.common.DecoderResult;
import com.google.zxing.common.reedsolomon.GF256; import com.google.zxing.common.reedsolomon.GenericGF;
import com.google.zxing.common.reedsolomon.ReedSolomonDecoder; import com.google.zxing.common.reedsolomon.ReedSolomonDecoder;
import com.google.zxing.common.reedsolomon.ReedSolomonException; import com.google.zxing.common.reedsolomon.ReedSolomonException;
@ -35,7 +35,7 @@ public final class Decoder {
private final ReedSolomonDecoder rsDecoder; private final ReedSolomonDecoder rsDecoder;
public Decoder() { public Decoder() {
rsDecoder = new ReedSolomonDecoder(GF256.DATA_MATRIX_FIELD); rsDecoder = new ReedSolomonDecoder(GenericGF.DATA_MATRIX_FIELD_256);
} }
/** /**

View file

@ -21,7 +21,7 @@ import com.google.zxing.FormatException;
import com.google.zxing.NotFoundException; import com.google.zxing.NotFoundException;
import com.google.zxing.common.BitMatrix; import com.google.zxing.common.BitMatrix;
import com.google.zxing.common.DecoderResult; import com.google.zxing.common.DecoderResult;
import com.google.zxing.common.reedsolomon.GF256; import com.google.zxing.common.reedsolomon.GenericGF;
import com.google.zxing.common.reedsolomon.ReedSolomonDecoder; import com.google.zxing.common.reedsolomon.ReedSolomonDecoder;
import com.google.zxing.common.reedsolomon.ReedSolomonException; import com.google.zxing.common.reedsolomon.ReedSolomonException;
@ -38,7 +38,7 @@ public final class Decoder {
private final ReedSolomonDecoder rsDecoder; private final ReedSolomonDecoder rsDecoder;
public Decoder() { public Decoder() {
rsDecoder = new ReedSolomonDecoder(GF256.QR_CODE_FIELD); rsDecoder = new ReedSolomonDecoder(GenericGF.QR_CODE_FIELD_256);
} }
public DecoderResult decode(boolean[][] image) public DecoderResult decode(boolean[][] image)

View file

@ -21,7 +21,7 @@ import com.google.zxing.WriterException;
import com.google.zxing.common.BitArray; import com.google.zxing.common.BitArray;
import com.google.zxing.common.CharacterSetECI; import com.google.zxing.common.CharacterSetECI;
import com.google.zxing.common.ECI; import com.google.zxing.common.ECI;
import com.google.zxing.common.reedsolomon.GF256; import com.google.zxing.common.reedsolomon.GenericGF;
import com.google.zxing.common.reedsolomon.ReedSolomonEncoder; import com.google.zxing.common.reedsolomon.ReedSolomonEncoder;
import com.google.zxing.qrcode.decoder.ErrorCorrectionLevel; import com.google.zxing.qrcode.decoder.ErrorCorrectionLevel;
import com.google.zxing.qrcode.decoder.Mode; import com.google.zxing.qrcode.decoder.Mode;
@ -414,7 +414,7 @@ public final class Encoder {
for (int i = 0; i < numDataBytes; i++) { for (int i = 0; i < numDataBytes; i++) {
toEncode[i] = dataBytes[i] & 0xFF; toEncode[i] = dataBytes[i] & 0xFF;
} }
new ReedSolomonEncoder(GF256.QR_CODE_FIELD).encode(toEncode, numEcBytesInBlock); new ReedSolomonEncoder(GenericGF.QR_CODE_FIELD_256).encode(toEncode, numEcBytesInBlock);
byte[] ecBytes = new byte[numEcBytesInBlock]; byte[] ecBytes = new byte[numEcBytesInBlock];
for (int i = 0; i < numEcBytesInBlock; i++) { for (int i = 0; i < numEcBytesInBlock; i++) {

View file

@ -42,7 +42,7 @@ abstract class AbstractReedSolomonTestCase extends Assert {
static void doTestQRCodeEncoding(int[] dataBytes, int[] expectedECBytes) { static void doTestQRCodeEncoding(int[] dataBytes, int[] expectedECBytes) {
int[] toEncode = new int[dataBytes.length + expectedECBytes.length]; int[] toEncode = new int[dataBytes.length + expectedECBytes.length];
System.arraycopy(dataBytes, 0, toEncode, 0, dataBytes.length); System.arraycopy(dataBytes, 0, toEncode, 0, dataBytes.length);
new ReedSolomonEncoder(GF256.QR_CODE_FIELD).encode(toEncode, expectedECBytes.length); new ReedSolomonEncoder(GenericGF.QR_CODE_FIELD_256).encode(toEncode, expectedECBytes.length);
assertArraysEqual(dataBytes, 0, toEncode, 0, dataBytes.length); assertArraysEqual(dataBytes, 0, toEncode, 0, dataBytes.length);
assertArraysEqual(expectedECBytes, 0, toEncode, dataBytes.length, expectedECBytes.length); assertArraysEqual(expectedECBytes, 0, toEncode, dataBytes.length, expectedECBytes.length);
} }

View file

@ -31,7 +31,7 @@ public final class ReedSolomonDecoderDataMatrixTestCase extends AbstractReedSolo
private static final int DM_CODE_ECC_BYTES = DM_CODE_TEST_WITH_EC.length - DM_CODE_TEST.length; private static final int DM_CODE_ECC_BYTES = DM_CODE_TEST_WITH_EC.length - DM_CODE_TEST.length;
private static final int DM_CODE_CORRECTABLE = DM_CODE_ECC_BYTES / 2; private static final int DM_CODE_CORRECTABLE = DM_CODE_ECC_BYTES / 2;
private final ReedSolomonDecoder dmRSDecoder = new ReedSolomonDecoder(GF256.DATA_MATRIX_FIELD); private final ReedSolomonDecoder dmRSDecoder = new ReedSolomonDecoder(GenericGF.DATA_MATRIX_FIELD_256);
@Test @Test
public void testNoError() throws ReedSolomonException { public void testNoError() throws ReedSolomonException {

View file

@ -36,7 +36,7 @@ public final class ReedSolomonDecoderQRCodeTestCase extends AbstractReedSolomonT
private static final int QR_CODE_ECC_BYTES = QR_CODE_TEST_WITH_EC.length - QR_CODE_TEST.length; private static final int QR_CODE_ECC_BYTES = QR_CODE_TEST_WITH_EC.length - QR_CODE_TEST.length;
private static final int QR_CODE_CORRECTABLE = QR_CODE_ECC_BYTES / 2; private static final int QR_CODE_CORRECTABLE = QR_CODE_ECC_BYTES / 2;
private final ReedSolomonDecoder qrRSDecoder = new ReedSolomonDecoder(GF256.QR_CODE_FIELD); private final ReedSolomonDecoder qrRSDecoder = new ReedSolomonDecoder(GenericGF.QR_CODE_FIELD_256);
@Test @Test
public void testNoError() throws ReedSolomonException { public void testNoError() throws ReedSolomonException {

View file

@ -42,8 +42,8 @@ public final class ReedSolomonEncoderQRCodeTestCase extends AbstractReedSolomonT
@Test @Test
public void testQRCodeVersusDecoder() throws Exception { public void testQRCodeVersusDecoder() throws Exception {
Random random = getRandom(); Random random = getRandom();
ReedSolomonEncoder encoder = new ReedSolomonEncoder(GF256.QR_CODE_FIELD); ReedSolomonEncoder encoder = new ReedSolomonEncoder(GenericGF.QR_CODE_FIELD_256);
ReedSolomonDecoder decoder = new ReedSolomonDecoder(GF256.QR_CODE_FIELD); ReedSolomonDecoder decoder = new ReedSolomonDecoder(GenericGF.QR_CODE_FIELD_256);
for (int i = 0; i < 100; i++) { for (int i = 0; i < 100; i++) {
int size = random.nextInt(1000); int size = random.nextInt(1000);
int[] toEncode = new int[size]; int[] toEncode = new int[size];