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 // Return the code point of the table used in alphanumeric mode. Return -1 if there is no
// corresponding code in the table. // corresponding code in the table.
private static int GetAlphanumericCode(int code) { static int GetAlphanumericCode(int code) {
if (code < kAlphanumericTable.length) { if (code < kAlphanumericTable.length) {
return kAlphanumericTable[code]; return kAlphanumericTable[code];
} }
@ -617,7 +617,7 @@ private static final ECPolyInfo kECPolynomials[] = {
return false; 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 numDataBytes = data_bytes.size();
int[] toEncode = new int[numDataBytes + ec_bytes.size()]; int[] toEncode = new int[numDataBytes + ec_bytes.size()];
for (int i = 0; i < numDataBytes; i++) { 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 // 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. // 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 && return (byte2 != 0x7f &&
((byte1 >= 0x81 && byte1 <= 0x9f && ((byte1 >= 0x81 && byte1 <= 0x9f &&
byte2 >= 0x40 && byte2 <= 0xfc) || byte2 >= 0x40 && byte2 <= 0xfc) ||
@ -787,10 +787,8 @@ private static final ECPolyInfo kECPolynomials[] = {
byte2 >= 0x40 && byte2 <= 0xfc)))); byte2 >= 0x40 && byte2 <= 0xfc))));
} }
// Check if "bytes" is a valid Kanji sequence. // Check if "bytes" is a valid Kanji sequence. Used by the unit tests.
// static boolean IsValidKanjiSequence(final ByteArray bytes) {
// JAVAPORT - Remove if not used by the unit tests.
private static boolean IsValidKanjiSequence(final ByteArray bytes) {
if (bytes.size() % 2 != 0) { if (bytes.size() % 2 != 0) {
return false; return false;
} }

View file

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