mirror of
https://github.com/zxing/zxing.git
synced 2025-03-05 20:48:51 -08:00
Made several good fixes to and because of the unit tests. Turns out the EC array was never being set to the right size. I've now established that the Reed Solomon code is generating one fewer coefficient than the layer above it asked for.
git-svn-id: https://zxing.googlecode.com/svn/trunk@726 59b500cc-1b3d-0410-9834-0bbf25fbcc57
This commit is contained in:
parent
b5dbec4469
commit
c95fe48a76
|
@ -52,13 +52,21 @@ public final class ReedSolomonEncoder {
|
|||
|
||||
public void encode(int[] toEncode, int ecBytes) {
|
||||
int dataBytes = toEncode.length - ecBytes;
|
||||
if (dataBytes < 0) {
|
||||
throw new IllegalArgumentException("Too few data bytes provided: " + dataBytes);
|
||||
}
|
||||
GF256Poly generator = buildGenerator(ecBytes);
|
||||
int[] infoCoefficients = new int[dataBytes];
|
||||
System.arraycopy(toEncode, 0, infoCoefficients, 0, dataBytes);
|
||||
GF256Poly info = new GF256Poly(field, infoCoefficients);
|
||||
info = info.multiplyByMonomial(ecBytes, 1);
|
||||
GF256Poly remainder = info.divide(generator)[1];
|
||||
System.arraycopy(remainder.getCoefficients(), 0, toEncode, dataBytes, ecBytes);
|
||||
int[] coefficients = remainder.getCoefficients();
|
||||
if (coefficients.length < ecBytes) {
|
||||
throw new RuntimeException("Coefficients array is smaller than EC array (" +
|
||||
coefficients.length + " < " + ecBytes + ")");
|
||||
}
|
||||
System.arraycopy(coefficients, 0, toEncode, dataBytes, ecBytes);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -33,6 +33,11 @@ public final class ByteArray {
|
|||
size = 0;
|
||||
}
|
||||
|
||||
public ByteArray(int size) {
|
||||
bytes = new byte[size];
|
||||
this.size = size;
|
||||
}
|
||||
|
||||
public ByteArray(String string) {
|
||||
bytes = string.getBytes();
|
||||
size = bytes.length;
|
||||
|
@ -83,12 +88,12 @@ public final class ByteArray {
|
|||
}
|
||||
}
|
||||
|
||||
// This could probably be generalized to take a byte[] instead of a BitVector.
|
||||
public void set(BitVector bits, int offset, int count) {
|
||||
// Copy count bytes from array source starting at offset.
|
||||
public void set(byte[] source, int offset, int count) {
|
||||
bytes = new byte[count];
|
||||
size = count;
|
||||
for (int x = 0; x < count; x++) {
|
||||
bytes[x] = (byte) bits.at(x + offset);
|
||||
bytes[x] = source[offset + x];
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -16,9 +16,9 @@
|
|||
|
||||
package com.google.zxing.qrcode.encoder;
|
||||
|
||||
import com.google.zxing.common.reedsolomon.ReedSolomonEncoder;
|
||||
import com.google.zxing.common.reedsolomon.GF256;
|
||||
import com.google.zxing.common.ByteMatrix;
|
||||
import com.google.zxing.common.reedsolomon.GF256;
|
||||
import com.google.zxing.common.reedsolomon.ReedSolomonEncoder;
|
||||
|
||||
import java.util.Vector;
|
||||
|
||||
|
@ -579,12 +579,10 @@ private static final ECPolyInfo kECPolynomials[] = {
|
|||
num_data_bytes_in_block, num_ec_bytes_in_block);
|
||||
|
||||
ByteArray data_bytes = new ByteArray();
|
||||
ByteArray ec_bytes = new ByteArray();
|
||||
data_bytes.set(bits.getArray(), data_bytes_offset, num_data_bytes_in_block[0]);
|
||||
ByteArray ec_bytes = GenerateECBytes(data_bytes, num_ec_bytes_in_block[0]);
|
||||
blocks.addElement(new BlockPair(data_bytes, ec_bytes));
|
||||
|
||||
data_bytes.set(bits, data_bytes_offset, num_data_bytes_in_block[0]);
|
||||
GenerateECBytes(data_bytes, num_ec_bytes_in_block[0], ec_bytes);
|
||||
|
||||
max_num_data_bytes = Math.max(max_num_data_bytes, data_bytes.size());
|
||||
max_num_ec_bytes = Math.max(max_num_ec_bytes, ec_bytes.size());
|
||||
data_bytes_offset += num_data_bytes_in_block[0];
|
||||
|
@ -617,16 +615,19 @@ private static final ECPolyInfo kECPolynomials[] = {
|
|||
return false;
|
||||
}
|
||||
|
||||
static void GenerateECBytes(ByteArray data_bytes, int num_ec_bytes_in_block, ByteArray ec_bytes) {
|
||||
static ByteArray GenerateECBytes(ByteArray data_bytes, int num_ec_bytes_in_block) {
|
||||
int numDataBytes = data_bytes.size();
|
||||
int[] toEncode = new int[numDataBytes + ec_bytes.size()];
|
||||
int[] toEncode = new int[numDataBytes + num_ec_bytes_in_block];
|
||||
for (int i = 0; i < numDataBytes; i++) {
|
||||
toEncode[i] = data_bytes.at(i);
|
||||
}
|
||||
new ReedSolomonEncoder(GF256.QR_CODE_FIELD).encode(toEncode, num_ec_bytes_in_block);
|
||||
for (int i = 0; i < ec_bytes.size(); i++) {
|
||||
|
||||
ByteArray ec_bytes = new ByteArray(num_ec_bytes_in_block);
|
||||
for (int i = 0; i < num_ec_bytes_in_block; i++) {
|
||||
ec_bytes.set(i, toEncode[numDataBytes + i]);
|
||||
}
|
||||
return ec_bytes;
|
||||
}
|
||||
|
||||
// Append mode info. On success, store the result in "bits" and return true. On error, return
|
||||
|
|
|
@ -512,9 +512,8 @@ public final class EncoderTestCase extends TestCase {
|
|||
// http://www.swetake.com/qr/qr9.html
|
||||
public void testGenerateECBytes() {
|
||||
{
|
||||
ByteArray ec_bytes = new ByteArray();
|
||||
final byte[] data_bytes = {32, 65, (byte)205, 69, 41, (byte)220, 46, (byte)128, (byte)236};
|
||||
Encoder.GenerateECBytes(new ByteArray(data_bytes), 17, ec_bytes);
|
||||
ByteArray ec_bytes = Encoder.GenerateECBytes(new ByteArray(data_bytes), 17);
|
||||
final byte[] expected = {
|
||||
42, (byte)159, 74, (byte)221, (byte)244, (byte)169, (byte)239, (byte)150, (byte)138, 70,
|
||||
(byte)237, 85, (byte)224, 96, 74, (byte)219, 61
|
||||
|
@ -522,10 +521,9 @@ public final class EncoderTestCase extends TestCase {
|
|||
assertEquals(new ByteArray(expected), ec_bytes);
|
||||
}
|
||||
{
|
||||
ByteArray ec_bytes = new ByteArray();
|
||||
final byte[] data_bytes = {67, 70, 22, 38, 54, 70, 86, 102, 118,
|
||||
(byte)134, (byte)150, (byte)166, (byte)182, (byte)198, (byte)214};
|
||||
Encoder.GenerateECBytes(new ByteArray(data_bytes), 18, ec_bytes);
|
||||
ByteArray ec_bytes = Encoder.GenerateECBytes(new ByteArray(data_bytes), 18);
|
||||
final byte[] expected = {
|
||||
(byte)175, 80, (byte)155, 64, (byte)178, 45, (byte)214, (byte)233, 65, (byte)209, 12,
|
||||
(byte)155, 117, 31, (byte)140, (byte)214, 27, (byte)187
|
||||
|
@ -534,9 +532,8 @@ public final class EncoderTestCase extends TestCase {
|
|||
}
|
||||
{
|
||||
// High-order zero cofficient case.
|
||||
ByteArray ec_bytes = new ByteArray();
|
||||
final byte[] data_bytes = {32, 49, (byte)205, 69, 42, 20, 0, (byte)236, 17};
|
||||
Encoder.GenerateECBytes(new ByteArray(data_bytes), 17, ec_bytes);
|
||||
ByteArray ec_bytes = Encoder.GenerateECBytes(new ByteArray(data_bytes), 17);
|
||||
final byte[] expected = {
|
||||
0, 3, (byte)130, (byte)179, (byte)194, 0, 55, (byte)211, 110, 79, 98, 72, (byte)170, 96,
|
||||
(byte)211, (byte)137, (byte)213
|
||||
|
|
Loading…
Reference in a new issue