From 1357c87441ef2bc51b671d6fa980cf5a9c4c7dc0 Mon Sep 17 00:00:00 2001 From: dswitkin Date: Tue, 18 Nov 2008 21:34:17 +0000 Subject: [PATCH] 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 --- .../google/zxing/qrcode/encoder/Encoder.java | 12 +- .../zxing/qrcode/encoder/EncoderTestCase.java | 264 +++++++++--------- 2 files changed, 133 insertions(+), 143 deletions(-) diff --git a/core/src/com/google/zxing/qrcode/encoder/Encoder.java b/core/src/com/google/zxing/qrcode/encoder/Encoder.java index 9525cb832..8935c1819 100644 --- a/core/src/com/google/zxing/qrcode/encoder/Encoder.java +++ b/core/src/com/google/zxing/qrcode/encoder/Encoder.java @@ -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; } diff --git a/core/test/src/com/google/zxing/qrcode/encoder/EncoderTestCase.java b/core/test/src/com/google/zxing/qrcode/encoder/EncoderTestCase.java index 7678fac5f..f6a9aedb6 100644 --- a/core/test/src/com/google/zxing/qrcode/encoder/EncoderTestCase.java +++ b/core/test/src/com/google/zxing/qrcode/encoder/EncoderTestCase.java @@ -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); } }