Made some incremental progress on the Encoder unit test. I think we've now hit the first real bug in the code.

git-svn-id: https://zxing.googlecode.com/svn/trunk@724 59b500cc-1b3d-0410-9834-0bbf25fbcc57
This commit is contained in:
dswitkin 2008-11-18 21:34:17 +00:00
parent 87ab9a5aa5
commit 1357c87441
2 changed files with 133 additions and 143 deletions

View file

@ -364,7 +364,7 @@ private static final ECPolyInfo kECPolynomials[] = {
// Return the code point of the table used in alphanumeric mode. Return -1 if there is no
// corresponding code in the table.
private static int GetAlphanumericCode(int code) {
static int GetAlphanumericCode(int code) {
if (code < kAlphanumericTable.length) {
return kAlphanumericTable[code];
}
@ -617,7 +617,7 @@ private static final ECPolyInfo kECPolynomials[] = {
return false;
}
private static void GenerateECBytes(ByteArray data_bytes, int num_ec_bytes_in_block, ByteArray ec_bytes) {
static void GenerateECBytes(ByteArray data_bytes, int num_ec_bytes_in_block, ByteArray ec_bytes) {
int numDataBytes = data_bytes.size();
int[] toEncode = new int[numDataBytes + ec_bytes.size()];
for (int i = 0; i < numDataBytes; i++) {
@ -779,7 +779,7 @@ private static final ECPolyInfo kECPolynomials[] = {
// Check if "byte1" and "byte2" can compose a valid Kanji letter (2-byte Shift_JIS letter). The
// numbers are from http://ja.wikipedia.org/wiki/Shift_JIS.
private static boolean IsValidKanji(final int byte1, final int byte2) {
static boolean IsValidKanji(final int byte1, final int byte2) {
return (byte2 != 0x7f &&
((byte1 >= 0x81 && byte1 <= 0x9f &&
byte2 >= 0x40 && byte2 <= 0xfc) ||
@ -787,10 +787,8 @@ private static final ECPolyInfo kECPolynomials[] = {
byte2 >= 0x40 && byte2 <= 0xfc))));
}
// Check if "bytes" is a valid Kanji sequence.
//
// JAVAPORT - Remove if not used by the unit tests.
private static boolean IsValidKanjiSequence(final ByteArray bytes) {
// Check if "bytes" is a valid Kanji sequence. Used by the unit tests.
static boolean IsValidKanjiSequence(final ByteArray bytes) {
if (bytes.size() % 2 != 0) {
return false;
}

View file

@ -16,24 +16,14 @@
package com.google.zxing.qrcode.encoder;
import com.google.zxing.qrcode.encoder.MaskUtil;
import junit.framework.TestCase;
//#include "util/array/array2d-inl.h"
//#include "wireless/qrcode/bit_vector-inl.h"
//#include "base/google.h"
//#include "Strings/Stringpiece.h"
//#include "testing/base/benchmark.h"
//#include "testing/base/gunit.h"
//#include "util/reedsolomon/galois_field.h"
//#include "util/reedsolomon/galois_poly.h"
//#include "wireless/qrcode/qrcode_encoder.h"
/**
* @author satorux@google.com (Satoru Takabayashi) - creator
* @author mysen@google.com (Chris Mysen) - ported from C++
*/
public final class EncoderTestCase extends TestCase {
public void testGetAlphanumericCode() {
// The first ten code points are numbers.
for (int i = 0; i < 10; ++i) {
@ -65,13 +55,11 @@ public final class EncoderTestCase extends TestCase {
public void testChooseMode() {
// Numeric mode.
assertEquals(QRCode.MODE_NUMERIC, Encoder.ChooseMode(new ByteArray("0")));
assertEquals(QRCode.MODE_NUMERIC,
Encoder.ChooseMode(new ByteArray("0123456789")));
assertEquals(QRCode.MODE_NUMERIC, Encoder.ChooseMode(new ByteArray("0123456789")));
// Alphanumeric mode.
assertEquals(QRCode.MODE_ALPHANUMERIC, Encoder.ChooseMode(new ByteArray("A")));
assertEquals(QRCode.MODE_ALPHANUMERIC,
Encoder.ChooseMode(
new ByteArray("0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ $%*+-./:")));
Encoder.ChooseMode(new ByteArray("0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ $%*+-./:")));
// 8-bit byte mode.
assertEquals(QRCode.MODE_8BIT_BYTE, Encoder.ChooseMode(new ByteArray("a")));
assertEquals(QRCode.MODE_8BIT_BYTE, Encoder.ChooseMode(new ByteArray("#")));
@ -79,18 +67,18 @@ public final class EncoderTestCase extends TestCase {
// Kanji mode. We used to use MODE_KANJI for these, but we stopped
// doing that as we cannot distinguish Shift_JIS from other encodings
// from data bytes alone. See also comments in qrcode_encoder.h.
// AIUE in Hiragana in Shift_JIS
byte[] dat1 = {0x8,0xa,0x8,0xa,0x8,0xa,0x8,(byte)0xa6};
assertEquals(QRCode.MODE_8BIT_BYTE,
// AIUE in Hiragana in Shift_JIS
Encoder.ChooseMode(new ByteArray(dat1)));
assertEquals(QRCode.MODE_8BIT_BYTE, Encoder.ChooseMode(new ByteArray(dat1)));
// Nihon in Kanji in Shift_JIS.
byte[] dat2 = {0x9,0xf,0x9,0x7b};
assertEquals(QRCode.MODE_8BIT_BYTE,
// Nihon in Kanji in Shift_JIS.
Encoder.ChooseMode(new ByteArray(dat2)));
assertEquals(QRCode.MODE_8BIT_BYTE, Encoder.ChooseMode(new ByteArray(dat2)));
// Sou-Utsu-Byou in Kanji in Shift_JIS.
byte[] dat3 = {0xe,0x4,0x9,0x5,0x9,0x61};
assertEquals(QRCode.MODE_8BIT_BYTE,
// Sou-Utsu-Byou in Kanji in Shift_JIS.
Encoder.ChooseMode(new ByteArray(dat3)));
assertEquals(QRCode.MODE_8BIT_BYTE, Encoder.ChooseMode(new ByteArray(dat3)));
}
public void testEncode() {
@ -271,41 +259,41 @@ public final class EncoderTestCase extends TestCase {
int[] num_ec_bytes = new int[0];
// Version 1-H.
Encoder.GetNumDataBytesAndNumECBytesForBlockID(
26, 9, 1, 0, num_data_bytes, num_ec_bytes);
26, 9, 1, 0, num_data_bytes, num_ec_bytes);
assertEquals(9, num_data_bytes[0]);
assertEquals(17, num_ec_bytes[0]);
// Version 3-H. 2 blocks.
Encoder.GetNumDataBytesAndNumECBytesForBlockID(
70, 26, 2, 0, num_data_bytes, num_ec_bytes);
70, 26, 2, 0, num_data_bytes, num_ec_bytes);
assertEquals(13, num_data_bytes[0]);
assertEquals(22, num_ec_bytes[0]);
Encoder.GetNumDataBytesAndNumECBytesForBlockID(
70, 26, 2, 1, num_data_bytes, num_ec_bytes);
70, 26, 2, 1, num_data_bytes, num_ec_bytes);
assertEquals(13, num_data_bytes[0]);
assertEquals(22, num_ec_bytes[0]);
// Version 7-H. (4 + 1) blocks.
Encoder.GetNumDataBytesAndNumECBytesForBlockID(
196, 66, 5, 0, num_data_bytes, num_ec_bytes);
196, 66, 5, 0, num_data_bytes, num_ec_bytes);
assertEquals(13, num_data_bytes[0]);
assertEquals(26, num_ec_bytes[0]);
Encoder.GetNumDataBytesAndNumECBytesForBlockID(
196, 66, 5, 4, num_data_bytes, num_ec_bytes);
196, 66, 5, 4, num_data_bytes, num_ec_bytes);
assertEquals(14, num_data_bytes[0]);
assertEquals(26, num_ec_bytes[0]);
// Version 40-H. (20 + 61) blocks.
Encoder.GetNumDataBytesAndNumECBytesForBlockID(
3706, 1276, 81, 0, num_data_bytes, num_ec_bytes);
3706, 1276, 81, 0, num_data_bytes, num_ec_bytes);
assertEquals(15, num_data_bytes[0]);
assertEquals(30, num_ec_bytes[0]);
Encoder.GetNumDataBytesAndNumECBytesForBlockID(
3706, 1276, 81, 20, num_data_bytes, num_ec_bytes);
3706, 1276, 81, 20, num_data_bytes, num_ec_bytes);
assertEquals(16, num_data_bytes[0]);
assertEquals(30, num_ec_bytes[0]);
Encoder.GetNumDataBytesAndNumECBytesForBlockID(
3706, 1276, 81, 80, num_data_bytes, num_ec_bytes);
3706, 1276, 81, 80, num_data_bytes, num_ec_bytes);
assertEquals(16, num_data_bytes[0]);
assertEquals(30, num_ec_bytes[0]);
}
@ -315,45 +303,45 @@ public final class EncoderTestCase extends TestCase {
final char[] data_bytes = {32, 65, 205, 69, 41, 220, 46, 128, 236};
BitVector in = new BitVector();
for (char data_byte: data_bytes) {
in.AppendBits(data_byte, 8);
in.AppendBits(data_byte, 8);
}
BitVector out = new BitVector();
assertTrue(Encoder.InterleaveWithECBytes(in, 26, 9, 1, out));
final char[] expected = {
// Data bytes.
32, 65, 205, 69, 41, 220, 46, 128, 236,
// Error correction bytes.
42, 159, 74, 221, 244, 169, 239, 150, 138, 70, 237, 85, 224,
96, 74, 219, 61,
// Data bytes.
32, 65, 205, 69, 41, 220, 46, 128, 236,
// Error correction bytes.
42, 159, 74, 221, 244, 169, 239, 150, 138, 70, 237, 85, 224,
96, 74, 219, 61,
};
assertEquals(new String(expected), out.toString());
}
// Numbers are from http://www.swetake.com/qr/qr8.html
{
final char[] data_bytes = {
67, 70, 22, 38, 54, 70, 86, 102, 118, 134, 150, 166, 182, 198, 214,
230, 247, 7, 23, 39, 55, 71, 87, 103, 119, 135, 151, 166, 22, 38,
54, 70, 86, 102, 118, 134, 150, 166, 182, 198, 214, 230, 247, 7, 23, 39,
55, 71, 87, 103, 119, 135, 151, 160, 236, 17, 236, 17, 236, 17, 236, 17,
67, 70, 22, 38, 54, 70, 86, 102, 118, 134, 150, 166, 182, 198, 214,
230, 247, 7, 23, 39, 55, 71, 87, 103, 119, 135, 151, 166, 22, 38,
54, 70, 86, 102, 118, 134, 150, 166, 182, 198, 214, 230, 247, 7, 23, 39,
55, 71, 87, 103, 119, 135, 151, 160, 236, 17, 236, 17, 236, 17, 236, 17,
};
BitVector in = new BitVector();
for (char data_byte: data_bytes) {
in.AppendBits(data_byte, 8);
in.AppendBits(data_byte, 8);
}
BitVector out = new BitVector();
assertTrue(Encoder.InterleaveWithECBytes(in, 134, 62, 4, out));
final char[] expected = {
// Data bytes.
67, 230, 54, 55, 70, 247, 70, 71, 22, 7, 86, 87, 38, 23, 102, 103, 54,
39, 118, 119, 70, 55, 134, 135, 86, 71, 150, 151, 102, 87, 166, 160,
118, 103, 182, 236, 134, 119, 198, 17, 150, 135, 214, 236, 166, 151,
230, 17, 182, 166, 247, 236, 198, 22, 7, 17, 214, 38, 23, 236, 39, 17,
// Error correction bytes.
175, 155, 245, 236, 80, 146, 56, 74, 155, 165, 133, 142, 64, 183, 132,
13, 178, 54, 132, 108, 45, 113, 53, 50, 214, 98, 193, 152, 233, 147, 50,
71, 65, 190, 82, 51, 209, 199, 171, 54, 12, 112, 57, 113, 155, 117, 211,
164, 117, 30, 158, 225, 31, 190, 242, 38, 140, 61, 179, 154, 214, 138,
147, 87, 27, 96, 77, 47, 187, 49, 156, 214,
// Data bytes.
67, 230, 54, 55, 70, 247, 70, 71, 22, 7, 86, 87, 38, 23, 102, 103, 54,
39, 118, 119, 70, 55, 134, 135, 86, 71, 150, 151, 102, 87, 166, 160,
118, 103, 182, 236, 134, 119, 198, 17, 150, 135, 214, 236, 166, 151,
230, 17, 182, 166, 247, 236, 198, 22, 7, 17, 214, 38, 23, 236, 39, 17,
// Error correction bytes.
175, 155, 245, 236, 80, 146, 56, 74, 155, 165, 133, 142, 64, 183, 132,
13, 178, 54, 132, 108, 45, 113, 53, 50, 214, 98, 193, 152, 233, 147, 50,
71, 65, 190, 82, 51, 209, 199, 171, 54, 12, 112, 57, 113, 155, 117, 211,
164, 117, 30, 158, 225, 31, 190, 242, 38, 140, 61, 179, 154, 214, 138,
147, 87, 27, 96, 77, 47, 187, 49, 156, 214,
};
assertEquals(new String(expected), out.toString());
}
@ -457,99 +445,103 @@ public final class EncoderTestCase extends TestCase {
}
}
static boolean ComparePoly(final int[] expected, final int size, final GF_Poly poly) {
if (size != poly.degree() + 1) {
return false;
}
for (int i = 0; i < size; ++i) {
// "expected" is ordered in a reverse order. We reverse the coeff
// index for comparison.
final int coeff = GaloisField.GetField(8).Log(
poly.coeff(size - i - 1));
if (expected[i] != coeff) {
Debug.LOG_ERROR("values don't match at " + i + ": " +
expected[i] + " vs. " + coeff);
return false;
}
}
return true;
}
// Numbers are from Appendix A of JISX0510 2004 (p.59).
public void testGetECPoly() {
{
final GF_Poly poly = Encoder.GetECPoly(7);
final int[] expected = {0, 87, 229, 146, 149, 238, 102, 21};
assertTrue(ComparePoly(expected, expected.length, poly));
}
{
final GF_Poly poly = Encoder.GetECPoly(17);
final int[] expected = {
0, 43, 139, 206, 78, 43, 239, 123, 206, 214, 147, 24, 99, 150,
39, 243, 163, 136
};
assertTrue(ComparePoly(expected, expected.length, poly));
}
{
final GF_Poly poly = Encoder.GetECPoly(34);
final int[] expected = {
0, 111, 77, 146, 94, 26, 21, 108, 19,
105, 94, 113, 193, 86, 140, 163, 125,
58,
158, 229, 239, 218, 103, 56, 70, 114,
61, 183, 129, 167, 13, 98, 62, 129, 51
};
assertTrue(ComparePoly(expected, expected.length, poly));
}
{
final GF_Poly poly = Encoder.GetECPoly(68);
final int[] expected = {
0, 247, 159, 223, 33, 224, 93, 77, 70,
90, 160, 32, 254, 43, 150, 84, 101,
190,
205, 133, 52, 60, 202, 165, 220, 203,
151, 93, 84, 15, 84, 253, 173, 160,
89, 227, 52, 199, 97, 95, 231, 52,
177, 41, 125, 137, 241, 166, 225, 118,
2, 54,
32, 82, 215, 175, 198, 43, 238, 235,
27, 101, 184, 127, 3, 5, 8, 163, 238
};
assertTrue(ComparePoly(expected, expected.length, poly));
}
}
// JAVAPORT: Uncomment and fix up with new Reed Solomon objects
// static boolean ComparePoly(final int[] expected, final int size, final GF_Poly poly) {
// if (size != poly.degree() + 1) {
// return false;
// }
// for (int i = 0; i < size; ++i) {
// // "expected" is ordered in a reverse order. We reverse the coeff
// // index for comparison.
// final int coeff = GaloisField.GetField(8).Log(
// poly.coeff(size - i - 1));
// if (expected[i] != coeff) {
// Debug.LOG_ERROR("values don't match at " + i + ": " +
// expected[i] + " vs. " + coeff);
// return false;
// }
// }
// return true;
// }
//
// // Numbers are from Appendix A of JISX0510 2004 (p.59).
// public void testGetECPoly() {
// {
// final GF_Poly poly = Encoder.GetECPoly(7);
// final int[] expected = {0, 87, 229, 146, 149, 238, 102, 21};
// assertTrue(ComparePoly(expected, expected.length, poly));
// }
// {
// final GF_Poly poly = Encoder.GetECPoly(17);
// final int[] expected = {
// 0, 43, 139, 206, 78, 43, 239, 123, 206, 214, 147, 24, 99, 150,
// 39, 243, 163, 136
// };
// assertTrue(ComparePoly(expected, expected.length, poly));
// }
// {
// final GF_Poly poly = Encoder.GetECPoly(34);
// final int[] expected = {
// 0, 111, 77, 146, 94, 26, 21, 108, 19,
// 105, 94, 113, 193, 86, 140, 163, 125,
// 58,
// 158, 229, 239, 218, 103, 56, 70, 114,
// 61, 183, 129, 167, 13, 98, 62, 129, 51
// };
// assertTrue(ComparePoly(expected, expected.length, poly));
// }
// {
// final GF_Poly poly = Encoder.GetECPoly(68);
// final int[] expected = {
// 0, 247, 159, 223, 33, 224, 93, 77, 70,
// 90, 160, 32, 254, 43, 150, 84, 101,
// 190,
// 205, 133, 52, 60, 202, 165, 220, 203,
// 151, 93, 84, 15, 84, 253, 173, 160,
// 89, 227, 52, 199, 97, 95, 231, 52,
// 177, 41, 125, 137, 241, 166, 225, 118,
// 2, 54,
// 32, 82, 215, 175, 198, 43, 238, 235,
// 27, 101, 184, 127, 3, 5, 8, 163, 238
// };
// assertTrue(ComparePoly(expected, expected.length, poly));
// }
// }
// Numbers are from http://www.swetake.com/qr/qr3.html and
// http://www.swetake.com/qr/qr9.html
public void testGenerateECBytes() {
{
String ec_bytes;
final char[] data_bytes = {32, 65, 205, 69, 41, 220, 46, 128, 236};
Encoder.GenerateECBytes(new ByteArray(new String(data_bytes)), 17, new ByteArray(ec_bytes));
final char[] expected = {
42, 159, 74, 221, 244, 169, 239, 150, 138, 70, 237, 85, 224,
96, 74, 219, 61};
assertEquals(new String(expected), ec_bytes);
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);
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
};
assertEquals(new ByteArray(expected), ec_bytes);
}
{
String ec_bytes;
final char[] data_bytes = {67, 70, 22, 38, 54, 70, 86, 102, 118,
134, 150, 166, 182, 198, 214};
Encoder.GenerateECBytes(new ByteArray(new String(data_bytes)), 18, new ByteArray(ec_bytes));
final char[] expected = {
175, 80, 155, 64, 178, 45, 214, 233, 65, 209, 12, 155, 117, 31, 140,
214, 27, 187};
assertEquals(new String(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);
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
};
assertEquals(new ByteArray(expected), ec_bytes);
}
{
// High-order zero cofficient case.
String ec_bytes;
final char[] data_bytes = {32, 49, 205, 69, 42, 20, 0, 236, 17};
Encoder.GenerateECBytes(new ByteArray(new String(data_bytes)), 17, new ByteArray(ec_bytes));
final char[] expected = {
0, 3, 130, 179, 194, 0, 55, 211, 110, 79, 98, 72, 170, 96, 211, 137, 213
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);
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
};
assertEquals(new String(expected), ec_bytes);
assertEquals(new ByteArray(expected), ec_bytes);
}
}