Unify handling of Mode too

git-svn-id: https://zxing.googlecode.com/svn/trunk@771 59b500cc-1b3d-0410-9834-0bbf25fbcc57
This commit is contained in:
srowen 2008-12-02 01:30:57 +00:00
parent 784673a241
commit c74735c1b4
11 changed files with 125 additions and 236 deletions

View file

@ -16,39 +16,41 @@
package com.google.zxing.qrcode.decoder; package com.google.zxing.qrcode.decoder;
import com.google.zxing.ReaderException;
/** /**
* <p>See ISO 18004:2006, 6.4.1, Tables 2 and 3. This enum encapsulates the various modes in which * <p>See ISO 18004:2006, 6.4.1, Tables 2 and 3. This enum encapsulates the various modes in which
* data can be encoded to bits in the QR code standard.</p> * data can be encoded to bits in the QR code standard.</p>
* *
* @author Sean Owen * @author Sean Owen
*/ */
final class Mode { public final class Mode {
// No, we can't use an enum here. J2ME doesn't support it. // No, we can't use an enum here. J2ME doesn't support it.
static final Mode TERMINATOR = new Mode(new int[]{0, 0, 0}); // Not really a mode... public static final Mode TERMINATOR = new Mode(new int[]{0, 0, 0}, 0x00, "TERMINATOR"); // Not really a mode...
static final Mode NUMERIC = new Mode(new int[]{10, 12, 14}); public static final Mode NUMERIC = new Mode(new int[]{10, 12, 14}, 0x01, "NUMERIC");
static final Mode ALPHANUMERIC = new Mode(new int[]{9, 11, 13}); public static final Mode ALPHANUMERIC = new Mode(new int[]{9, 11, 13}, 0x02, "ALPHANUMERIC");
static final Mode BYTE = new Mode(new int[]{8, 16, 16}); public static final Mode BYTE = new Mode(new int[]{8, 16, 16}, 0x04, "BYTE");
static final Mode ECI = new Mode(null); // character counts don't apply public static final Mode ECI = new Mode(null, 0x07, "ECI"); // character counts don't apply
static final Mode KANJI = new Mode(new int[]{8, 10, 12}); public static final Mode KANJI = new Mode(new int[]{8, 10, 12}, 0x08, "KANJI");
static final Mode FNC1_FIRST_POSITION = new Mode(null); public static final Mode FNC1_FIRST_POSITION = new Mode(null, 0x05, "FNC1_FIRST_POSITION");
static final Mode FNC1_SECOND_POSITION = new Mode(null); public static final Mode FNC1_SECOND_POSITION = new Mode(null, 0x09, "FNC1_SECOND_POSITION");
private final int[] characterCountBitsForVersions; private final int[] characterCountBitsForVersions;
private final int bits;
private final String name;
private Mode(int[] characterCountBitsForVersions) { private Mode(int[] characterCountBitsForVersions, int bits, String name) {
this.characterCountBitsForVersions = characterCountBitsForVersions; this.characterCountBitsForVersions = characterCountBitsForVersions;
this.bits = bits;
this.name = name;
} }
/** /**
* @param bits four bits encoding a QR Code data mode * @param bits four bits encoding a QR Code data mode
* @return {@link Mode} encoded by these bits * @return {@link Mode} encoded by these bits
* @throws ReaderException if bits do not correspond to a known mode * @throws IllegalArgumentException if bits do not correspond to a known mode
*/ */
static Mode forBits(int bits) throws ReaderException { public static Mode forBits(int bits) {
switch (bits) { switch (bits) {
case 0x0: case 0x0:
return TERMINATOR; return TERMINATOR;
@ -67,7 +69,7 @@ final class Mode {
case 0x9: case 0x9:
return FNC1_SECOND_POSITION; return FNC1_SECOND_POSITION;
default: default:
throw ReaderException.getInstance(); throw new IllegalArgumentException();
} }
} }
@ -76,7 +78,7 @@ final class Mode {
* @return number of bits used, in this QR Code symbol {@link Version}, to encode the * @return number of bits used, in this QR Code symbol {@link Version}, to encode the
* count of characters that will follow encoded in this {@link Mode} * count of characters that will follow encoded in this {@link Mode}
*/ */
int getCharacterCountBits(Version version) { public int getCharacterCountBits(Version version) {
if (characterCountBitsForVersions == null) { if (characterCountBitsForVersions == null) {
throw new IllegalArgumentException("Character count doesn't apply to this mode"); throw new IllegalArgumentException("Character count doesn't apply to this mode");
} }
@ -92,4 +94,16 @@ final class Mode {
return characterCountBitsForVersions[offset]; return characterCountBitsForVersions[offset];
} }
public int getBits() {
return bits;
}
public String getName() {
return name;
}
public String toString() {
return name;
}
} }

View file

@ -100,9 +100,9 @@ public final class Version {
return getVersionForNumber((dimension - 17) >> 2); return getVersionForNumber((dimension - 17) >> 2);
} }
public static Version getVersionForNumber(int versionNumber) throws ReaderException { public static Version getVersionForNumber(int versionNumber) {
if (versionNumber < 1 || versionNumber > 40) { if (versionNumber < 1 || versionNumber > 40) {
throw ReaderException.getInstance(); throw new IllegalArgumentException();
} }
return VERSIONS[versionNumber - 1]; return VERSIONS[versionNumber - 1];
} }

View file

@ -16,12 +16,14 @@
package com.google.zxing.qrcode.encoder; package com.google.zxing.qrcode.encoder;
import com.google.zxing.common.ByteMatrix; import com.google.zxing.WriterException;
import com.google.zxing.common.ByteArray; import com.google.zxing.common.ByteArray;
import com.google.zxing.common.ByteMatrix;
import com.google.zxing.common.reedsolomon.GF256; import com.google.zxing.common.reedsolomon.GF256;
import com.google.zxing.common.reedsolomon.ReedSolomonEncoder; import com.google.zxing.common.reedsolomon.ReedSolomonEncoder;
import com.google.zxing.WriterException;
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.Version;
import java.util.Vector; import java.util.Vector;
@ -130,7 +132,7 @@ public final class Encoder {
public static void encode(final ByteArray bytes, ErrorCorrectionLevel ecLevel, QRCode qrCode) public static void encode(final ByteArray bytes, ErrorCorrectionLevel ecLevel, QRCode qrCode)
throws WriterException { throws WriterException {
// Step 1: Choose the mode (encoding). // Step 1: Choose the mode (encoding).
final int mode = chooseMode(bytes); final Mode mode = chooseMode(bytes);
// Step 2: Append "bytes" into "dataBits" in appropriate encoding. // Step 2: Append "bytes" into "dataBits" in appropriate encoding.
BitVector dataBits = new BitVector(); BitVector dataBits = new BitVector();
@ -185,7 +187,7 @@ public final class Encoder {
// interpreted as one character in Shift_JIS, but also two characters in ISO-8859-1. // interpreted as one character in Shift_JIS, but also two characters in ISO-8859-1.
// //
// JAVAPORT: This MODE_KANJI limitation sounds like a problem for us. // JAVAPORT: This MODE_KANJI limitation sounds like a problem for us.
public static int chooseMode(final ByteArray bytes) throws WriterException { public static Mode chooseMode(final ByteArray bytes) throws WriterException {
boolean hasNumeric = false; boolean hasNumeric = false;
boolean hasAlphanumeric = false; boolean hasAlphanumeric = false;
boolean hasOther = false; boolean hasOther = false;
@ -200,17 +202,17 @@ public final class Encoder {
} }
} }
if (hasOther) { if (hasOther) {
return QRCode.MODE_8BIT_BYTE; return Mode.BYTE;
} else if (hasAlphanumeric) { } else if (hasAlphanumeric) {
return QRCode.MODE_ALPHANUMERIC; return Mode.ALPHANUMERIC;
} else if (hasNumeric) { } else if (hasNumeric) {
return QRCode.MODE_NUMERIC; return Mode.NUMERIC;
} }
// "bytes" must be empty to reach here. // "bytes" must be empty to reach here.
if (!bytes.empty()) { if (!bytes.empty()) {
throw new WriterException("Bytes left over"); throw new WriterException("Bytes left over");
} }
return QRCode.MODE_8BIT_BYTE; return Mode.BYTE;
} }
private static int chooseMaskPattern(final BitVector bits, ErrorCorrectionLevel ecLevel, int version, private static int chooseMaskPattern(final BitVector bits, ErrorCorrectionLevel ecLevel, int version,
@ -235,7 +237,7 @@ public final class Encoder {
// Initialize "qrCode" according to "numInputBytes", "ecLevel", and "mode". On success, modify // Initialize "qrCode" according to "numInputBytes", "ecLevel", and "mode". On success, modify
// "qrCode" and return true. // "qrCode" and return true.
private static void initQRCode(int numInputBytes, ErrorCorrectionLevel ecLevel, int mode, QRCode qrCode) private static void initQRCode(int numInputBytes, ErrorCorrectionLevel ecLevel, Mode mode, QRCode qrCode)
throws WriterException { throws WriterException {
qrCode.setECLevel(ecLevel); qrCode.setECLevel(ecLevel);
qrCode.setMode(mode); qrCode.setMode(mode);
@ -439,25 +441,25 @@ public final class Encoder {
// Append mode info. On success, store the result in "bits" and return true. On error, return // Append mode info. On success, store the result in "bits" and return true. On error, return
// false. // false.
static void appendModeInfo(int mode, BitVector bits) throws WriterException { static void appendModeInfo(Mode mode, BitVector bits) {
final int code = QRCode.getModeCode(mode); bits.appendBits(mode.getBits(), 4);
bits.appendBits(code, 4);
} }
// Append length info. On success, store the result in "bits" and return true. On error, return // Append length info. On success, store the result in "bits" and return true. On error, return
// false. // false.
static void appendLengthInfo(int numBytes, int version, int mode, BitVector bits) throws WriterException { static void appendLengthInfo(int numBytes, int version, Mode mode, BitVector bits) throws WriterException {
int numLetters = numBytes; int numLetters = numBytes;
// In Kanji mode, a letter is represented in two bytes. // In Kanji mode, a letter is represented in two bytes.
if (mode == QRCode.MODE_KANJI) { if (mode.equals(Mode.KANJI)) {
if (numLetters % 2 != 0) { if (numLetters % 2 != 0) {
throw new WriterException("Number of letters must be even"); throw new WriterException("Number of letters must be even");
} }
numLetters /= 2; numLetters /= 2;
} }
final int numBits = QRCode.getNumBitsForLength(version, mode); final int numBits = mode.getCharacterCountBits(Version.getVersionForNumber(version));
if (numLetters > ((1 << numBits) - 1)) { if (numLetters > ((1 << numBits) - 1)) {
throw new WriterException(numLetters + "is bigger than" + ((1 << numBits) - 1)); throw new WriterException(numLetters + "is bigger than" + ((1 << numBits) - 1));
} }
@ -466,21 +468,16 @@ public final class Encoder {
// Append "bytes" in "mode" mode (encoding) into "bits". On success, store the result in "bits" // Append "bytes" in "mode" mode (encoding) into "bits". On success, store the result in "bits"
// and return true. // and return true.
static void appendBytes(final ByteArray bytes, int mode, BitVector bits) throws WriterException { static void appendBytes(final ByteArray bytes, Mode mode, BitVector bits) throws WriterException {
switch (mode) { if (mode.equals(Mode.NUMERIC)) {
case QRCode.MODE_NUMERIC:
appendNumericBytes(bytes, bits); appendNumericBytes(bytes, bits);
break; } else if (mode.equals(Mode.ALPHANUMERIC)) {
case QRCode.MODE_ALPHANUMERIC:
appendAlphanumericBytes(bytes, bits); appendAlphanumericBytes(bytes, bits);
break; } else if (mode.equals(Mode.BYTE)) {
case QRCode.MODE_8BIT_BYTE:
append8BitBytes(bytes, bits); append8BitBytes(bytes, bits);
break; } else if (mode.equals(Mode.KANJI)) {
case QRCode.MODE_KANJI:
appendKanjiBytes(bytes, bits); appendKanjiBytes(bytes, bits);
break; } else {
default:
throw new WriterException("Invalid mode: " + mode); throw new WriterException("Invalid mode: " + mode);
} }
} }

View file

@ -16,8 +16,8 @@
package com.google.zxing.qrcode.encoder; package com.google.zxing.qrcode.encoder;
import com.google.zxing.common.ByteMatrix;
import com.google.zxing.WriterException; import com.google.zxing.WriterException;
import com.google.zxing.common.ByteMatrix;
import com.google.zxing.qrcode.decoder.ErrorCorrectionLevel; import com.google.zxing.qrcode.decoder.ErrorCorrectionLevel;
/** /**

View file

@ -17,8 +17,8 @@
package com.google.zxing.qrcode.encoder; package com.google.zxing.qrcode.encoder;
import com.google.zxing.common.ByteMatrix; import com.google.zxing.common.ByteMatrix;
import com.google.zxing.WriterException;
import com.google.zxing.qrcode.decoder.ErrorCorrectionLevel; import com.google.zxing.qrcode.decoder.ErrorCorrectionLevel;
import com.google.zxing.qrcode.decoder.Mode;
/** /**
* @author satorux@google.com (Satoru Takabayashi) - creator * @author satorux@google.com (Satoru Takabayashi) - creator
@ -34,15 +34,7 @@ public final class QRCode {
private static final int MAX_MATRIX_WIDTH = 177; // Version 40 (21 + 4 * (40 -1)). private static final int MAX_MATRIX_WIDTH = 177; // Version 40 (21 + 4 * (40 -1)).
public static final int NUM_MASK_PATTERNS = 8; public static final int NUM_MASK_PATTERNS = 8;
// See table 3 of JISX0510:2004 (p.16) private Mode mode;
private static final int[][] NUM_BITS_TABLE = {
// NUMERIC ALPHANUMERIC 8BIT_BYTE KANJI
{ 10, 9, 8, 8 }, // Version 1-9
{ 12, 11, 16, 10 }, // Version 10-26
{ 14, 13, 16, 12 }, // Version 27-40
};
private int mode;
private ErrorCorrectionLevel ecLevel; private ErrorCorrectionLevel ecLevel;
private int version; private int version;
private int matrixWidth; private int matrixWidth;
@ -53,31 +45,8 @@ public final class QRCode {
private int numRSBlocks; private int numRSBlocks;
private ByteMatrix matrix; private ByteMatrix matrix;
// They call encoding "mode". The modes are defined in 8.3 of JISX0510:2004 (p.14). It's unlikely
// (probably we will not support complicated modes) but if you add an item to this, please also
// add it to modeToString(), getModeCode(), getNumBitsForLength(), Encoder.appendBytes(), and
// Encoder.chooseMode().
//
// JAVAPORT: These used to be C++ enums, but the code evaluates them as integers, and requires
// negative values. I don't want to take the ParsedResultType approach of a class full of statics
// of that class's type. The best compromise here is integer constants.
//
// Formerly enum Mode
public static final int MODE_UNDEFINED = -1;
public static final int MODE_NUMERIC = 0;
public static final int MODE_ALPHANUMERIC = 1;
public static final int MODE_8BIT_BYTE = 2;
public static final int MODE_KANJI = 3; // Shift_JIS
// The following modes are unimplemented.
// MODE_ECI,
// MODE_MIXED,
// MODE_CONCATENATED,
// MODE_FNC1,
public static final int NUM_MODES = 4;
public QRCode() { public QRCode() {
mode = MODE_UNDEFINED; mode = null;
ecLevel = null; ecLevel = null;
version = -1; version = -1;
matrixWidth = -1; matrixWidth = -1;
@ -90,7 +59,7 @@ public final class QRCode {
} }
// Mode of the QR Code. // Mode of the QR Code.
public int getMode() { public Mode getMode() {
return mode; return mode;
} }
@ -155,9 +124,9 @@ public final class QRCode {
// Checks all the member variables are set properly. Returns true on success. Otherwise, returns // Checks all the member variables are set properly. Returns true on success. Otherwise, returns
// false. // false.
public boolean isValid() { public boolean isValid() {
return ( return
// First check if all version are not uninitialized. // First check if all version are not uninitialized.
mode != MODE_UNDEFINED && mode != null &&
ecLevel != null && ecLevel != null &&
version != -1 && version != -1 &&
matrixWidth != -1 && matrixWidth != -1 &&
@ -168,7 +137,6 @@ public final class QRCode {
numRSBlocks != -1 && numRSBlocks != -1 &&
// Then check them in other ways.. // Then check them in other ways..
isValidVersion(version) && isValidVersion(version) &&
isValidMode(mode) &&
isValidMatrixWidth(matrixWidth) && isValidMatrixWidth(matrixWidth) &&
isValidMaskPattern(maskPattern) && isValidMaskPattern(maskPattern) &&
numTotalBytes == numDataBytes + numECBytes && numTotalBytes == numDataBytes + numECBytes &&
@ -177,7 +145,7 @@ public final class QRCode {
matrixWidth == matrix.width() && matrixWidth == matrix.width() &&
// See 7.3.1 of JISX0510:2004 (p.5). // See 7.3.1 of JISX0510:2004 (p.5).
matrixWidth == MIN_MATRIX_WIDTH + (version - 1) * 4 && matrixWidth == MIN_MATRIX_WIDTH + (version - 1) * 4 &&
matrix.width() == matrix.height()); // Must be square. matrix.width() == matrix.height(); // Must be square.
} }
// Return debug String. // Return debug String.
@ -185,7 +153,7 @@ public final class QRCode {
StringBuffer result = new StringBuffer(); StringBuffer result = new StringBuffer();
result.append("<<\n"); result.append("<<\n");
result.append(" mode: "); result.append(" mode: ");
result.append(modeToString(mode)); result.append(mode);
result.append("\n ecLevel: "); result.append("\n ecLevel: ");
result.append(ecLevel); result.append(ecLevel);
result.append("\n version: "); result.append("\n version: ");
@ -212,7 +180,7 @@ public final class QRCode {
return result.toString(); return result.toString();
} }
public void setMode(int value) { public void setMode(Mode value) {
mode = value; mode = value;
} }
@ -258,11 +226,6 @@ public final class QRCode {
return version >= MIN_VERSION && version <= MAX_VERSION; return version >= MIN_VERSION && version <= MAX_VERSION;
} }
// Check if "mode" is valid.
public static boolean isValidMode(final int mode) {
return mode >= 0 && mode < NUM_MODES;
}
// Check if "width" is valid. // Check if "width" is valid.
public static boolean isValidMatrixWidth(int width) { public static boolean isValidMatrixWidth(int width) {
return width >= MIN_MATRIX_WIDTH && width <= MAX_MATRIX_WIDTH; return width >= MIN_MATRIX_WIDTH && width <= MAX_MATRIX_WIDTH;
@ -273,61 +236,6 @@ public final class QRCode {
return maskPattern >= 0 && maskPattern < NUM_MASK_PATTERNS; return maskPattern >= 0 && maskPattern < NUM_MASK_PATTERNS;
} }
// Convert "mode" to String for debugging.
public static String modeToString(int mode) {
switch (mode) {
case QRCode.MODE_UNDEFINED:
return "UNDEFINED";
case QRCode.MODE_NUMERIC:
return "NUMERIC";
case QRCode.MODE_ALPHANUMERIC:
return "ALPHANUMERIC";
case QRCode.MODE_8BIT_BYTE:
return "8BIT_BYTE";
case QRCode.MODE_KANJI:
return "KANJI";
default:
break;
}
return "UNKNOWN";
}
// Return the code of mode. On error, return -1. The codes of modes are defined in the table 2 of
// JISX0510:2004 (p.16).
public static int getModeCode(final int mode) throws WriterException {
switch (mode) {
case QRCode.MODE_NUMERIC:
return 1;
case QRCode.MODE_ALPHANUMERIC:
return 2;
case QRCode.MODE_8BIT_BYTE:
return 4;
case QRCode.MODE_KANJI:
return 8;
default:
throw new WriterException("Unknown mode: " + mode);
}
}
// Return the number of bits needed for representing the length info of QR Code with "version" and
// "mode". On error, return -1.
static int getNumBitsForLength(int version, int mode) {
if (!isValidVersion(version)) {
throw new IllegalArgumentException("Invalid version: " + version);
}
if (!isValidMode(mode)) {
throw new IllegalArgumentException("Invalid mode: " + mode);
}
if (version >= 1 && version <= 9) {
return NUM_BITS_TABLE[0][mode];
} else if (version >= 10 && version <= 26) {
return NUM_BITS_TABLE[1][mode];
} else if (version >= 27 && version <= 40) {
return NUM_BITS_TABLE[2][mode];
}
throw new IllegalArgumentException("Bad version: " + version);
}
// Return true if the all values in the matrix are binary numbers. // Return true if the all values in the matrix are binary numbers.
// //
// JAVAPORT: This is going to be super expensive and unnecessary, we should not call this in // JAVAPORT: This is going to be super expensive and unnecessary, we should not call this in

View file

@ -16,7 +16,6 @@
package com.google.zxing.qrcode.decoder; package com.google.zxing.qrcode.decoder;
import com.google.zxing.ReaderException;
import junit.framework.TestCase; import junit.framework.TestCase;
/** /**
@ -24,7 +23,7 @@ import junit.framework.TestCase;
*/ */
public final class ModeTestCase extends TestCase { public final class ModeTestCase extends TestCase {
public void testForBits() throws ReaderException { public void testForBits() {
assertEquals(Mode.TERMINATOR, Mode.forBits(0x00)); assertEquals(Mode.TERMINATOR, Mode.forBits(0x00));
assertEquals(Mode.NUMERIC, Mode.forBits(0x01)); assertEquals(Mode.NUMERIC, Mode.forBits(0x01));
assertEquals(Mode.ALPHANUMERIC, Mode.forBits(0x02)); assertEquals(Mode.ALPHANUMERIC, Mode.forBits(0x02));
@ -33,12 +32,12 @@ public final class ModeTestCase extends TestCase {
try { try {
Mode.forBits(0x10); Mode.forBits(0x10);
fail("Should have thrown an exception"); fail("Should have thrown an exception");
} catch (ReaderException re) { } catch (IllegalArgumentException iae) {
// good // good
} }
} }
public void testCharacterCount() throws ReaderException { public void testCharacterCount() {
// Spot check a few values // Spot check a few values
assertEquals(10, Mode.NUMERIC.getCharacterCountBits(Version.getVersionForNumber(5))); assertEquals(10, Mode.NUMERIC.getCharacterCountBits(Version.getVersionForNumber(5)));
assertEquals(12, Mode.NUMERIC.getCharacterCountBits(Version.getVersionForNumber(26))); assertEquals(12, Mode.NUMERIC.getCharacterCountBits(Version.getVersionForNumber(26)));

View file

@ -24,11 +24,11 @@ import junit.framework.TestCase;
*/ */
public final class VersionTestCase extends TestCase { public final class VersionTestCase extends TestCase {
public void testVersionForNumber() throws ReaderException { public void testVersionForNumber() {
try { try {
Version.getVersionForNumber(0); Version.getVersionForNumber(0);
fail("Should have thrown an exception"); fail("Should have thrown an exception");
} catch (ReaderException re) { } catch (IllegalArgumentException iae) {
// good // good
} }
for (int i = 1; i <= 40; i++) { for (int i = 1; i <= 40; i++) {

View file

@ -16,9 +16,10 @@
package com.google.zxing.qrcode.encoder; package com.google.zxing.qrcode.encoder;
import com.google.zxing.common.ByteArray;
import com.google.zxing.WriterException; import com.google.zxing.WriterException;
import com.google.zxing.common.ByteArray;
import com.google.zxing.qrcode.decoder.ErrorCorrectionLevel; import com.google.zxing.qrcode.decoder.ErrorCorrectionLevel;
import com.google.zxing.qrcode.decoder.Mode;
import junit.framework.TestCase; import junit.framework.TestCase;
/** /**
@ -57,31 +58,31 @@ public final class EncoderTestCase extends TestCase {
public void testChooseMode() throws WriterException { public void testChooseMode() throws WriterException {
// Numeric mode. // Numeric mode.
assertEquals(QRCode.MODE_NUMERIC, Encoder.chooseMode(new ByteArray("0"))); assertEquals(Mode.NUMERIC, Encoder.chooseMode(new ByteArray("0")));
assertEquals(QRCode.MODE_NUMERIC, Encoder.chooseMode(new ByteArray("0123456789"))); assertEquals(Mode.NUMERIC, Encoder.chooseMode(new ByteArray("0123456789")));
// Alphanumeric mode. // Alphanumeric mode.
assertEquals(QRCode.MODE_ALPHANUMERIC, Encoder.chooseMode(new ByteArray("A"))); assertEquals(Mode.ALPHANUMERIC, Encoder.chooseMode(new ByteArray("A")));
assertEquals(QRCode.MODE_ALPHANUMERIC, assertEquals(Mode.ALPHANUMERIC,
Encoder.chooseMode(new ByteArray("0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ $%*+-./:"))); Encoder.chooseMode(new ByteArray("0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ $%*+-./:")));
// 8-bit byte mode. // 8-bit byte mode.
assertEquals(QRCode.MODE_8BIT_BYTE, Encoder.chooseMode(new ByteArray("a"))); assertEquals(Mode.BYTE, Encoder.chooseMode(new ByteArray("a")));
assertEquals(QRCode.MODE_8BIT_BYTE, Encoder.chooseMode(new ByteArray("#"))); assertEquals(Mode.BYTE, Encoder.chooseMode(new ByteArray("#")));
assertEquals(QRCode.MODE_8BIT_BYTE, Encoder.chooseMode(new ByteArray(""))); assertEquals(Mode.BYTE, Encoder.chooseMode(new ByteArray("")));
// 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.
// AIUE in Hiragana in Shift_JIS // AIUE in Hiragana in Shift_JIS
byte[] dat1 = {0x8,0xa,0x8,0xa,0x8,0xa,0x8,(byte)0xa6}; byte[] dat1 = {0x8,0xa,0x8,0xa,0x8,0xa,0x8,(byte)0xa6};
assertEquals(QRCode.MODE_8BIT_BYTE, Encoder.chooseMode(new ByteArray(dat1))); assertEquals(Mode.BYTE, Encoder.chooseMode(new ByteArray(dat1)));
// Nihon in Kanji in Shift_JIS. // Nihon in Kanji in Shift_JIS.
byte[] dat2 = {0x9,0xf,0x9,0x7b}; byte[] dat2 = {0x9,0xf,0x9,0x7b};
assertEquals(QRCode.MODE_8BIT_BYTE, Encoder.chooseMode(new ByteArray(dat2))); assertEquals(Mode.BYTE, Encoder.chooseMode(new ByteArray(dat2)));
// Sou-Utsu-Byou in Kanji in Shift_JIS. // Sou-Utsu-Byou in Kanji in Shift_JIS.
byte[] dat3 = {0xe,0x4,0x9,0x5,0x9,0x61}; byte[] dat3 = {0xe,0x4,0x9,0x5,0x9,0x61};
assertEquals(QRCode.MODE_8BIT_BYTE, Encoder.chooseMode(new ByteArray(dat3))); assertEquals(Mode.BYTE, Encoder.chooseMode(new ByteArray(dat3)));
} }
public void testEncode() throws WriterException { public void testEncode() throws WriterException {
@ -127,7 +128,7 @@ public final class EncoderTestCase extends TestCase {
public void testAppendModeInfo() throws WriterException { public void testAppendModeInfo() throws WriterException {
BitVector bits = new BitVector(); BitVector bits = new BitVector();
Encoder.appendModeInfo(QRCode.MODE_NUMERIC, bits); Encoder.appendModeInfo(Mode.NUMERIC, bits);
assertEquals("0001", bits.toString()); assertEquals("0001", bits.toString());
} }
@ -136,7 +137,7 @@ public final class EncoderTestCase extends TestCase {
BitVector bits = new BitVector(); BitVector bits = new BitVector();
Encoder.appendLengthInfo(1, // 1 letter (1/1). Encoder.appendLengthInfo(1, // 1 letter (1/1).
1, // version 1. 1, // version 1.
QRCode.MODE_NUMERIC, Mode.NUMERIC,
bits); bits);
assertEquals("0000000001", bits.toString()); // 10 bits. assertEquals("0000000001", bits.toString()); // 10 bits.
} }
@ -144,7 +145,7 @@ public final class EncoderTestCase extends TestCase {
BitVector bits = new BitVector(); BitVector bits = new BitVector();
Encoder.appendLengthInfo(2, // 2 letters (2/1). Encoder.appendLengthInfo(2, // 2 letters (2/1).
10, // version 10. 10, // version 10.
QRCode.MODE_ALPHANUMERIC, Mode.ALPHANUMERIC,
bits); bits);
assertEquals("00000000010", bits.toString()); // 11 bits. assertEquals("00000000010", bits.toString()); // 11 bits.
} }
@ -152,7 +153,7 @@ public final class EncoderTestCase extends TestCase {
BitVector bits = new BitVector(); BitVector bits = new BitVector();
Encoder.appendLengthInfo(255, // 255 letter (255/1). Encoder.appendLengthInfo(255, // 255 letter (255/1).
27, // version 27. 27, // version 27.
QRCode.MODE_8BIT_BYTE, Mode.BYTE,
bits); bits);
assertEquals("0000000011111111", bits.toString()); // 16 bits. assertEquals("0000000011111111", bits.toString()); // 16 bits.
} }
@ -160,7 +161,7 @@ public final class EncoderTestCase extends TestCase {
BitVector bits = new BitVector(); BitVector bits = new BitVector();
Encoder.appendLengthInfo(1024, // 512 letters (1024/2). Encoder.appendLengthInfo(1024, // 512 letters (1024/2).
40, // version 40. 40, // version 40.
QRCode.MODE_KANJI, Mode.KANJI,
bits); bits);
assertEquals("001000000000", bits.toString()); // 12 bits. assertEquals("001000000000", bits.toString()); // 12 bits.
} }
@ -171,11 +172,11 @@ public final class EncoderTestCase extends TestCase {
// Should use appendNumericBytes. // Should use appendNumericBytes.
// 1 = 01 = 0001 in 4 bits. // 1 = 01 = 0001 in 4 bits.
BitVector bits = new BitVector(); BitVector bits = new BitVector();
Encoder.appendBytes(new ByteArray("1"), QRCode.MODE_NUMERIC, bits); Encoder.appendBytes(new ByteArray("1"), Mode.NUMERIC, bits);
assertEquals("0001" , bits.toString()); assertEquals("0001" , bits.toString());
// 'A' cannot be encoded in MODE_NUMERIC. // 'A' cannot be encoded in MODE_NUMERIC.
try { try {
Encoder.appendBytes(new ByteArray("A"), QRCode.MODE_NUMERIC, bits); Encoder.appendBytes(new ByteArray("A"), Mode.NUMERIC, bits);
fail("Should have thrown exception"); fail("Should have thrown exception");
} catch (WriterException we) { } catch (WriterException we) {
// good // good
@ -185,11 +186,11 @@ public final class EncoderTestCase extends TestCase {
// Should use appendAlphanumericBytes. // Should use appendAlphanumericBytes.
// A = 10 = 0xa = 001010 in 6 bits // A = 10 = 0xa = 001010 in 6 bits
BitVector bits = new BitVector(); BitVector bits = new BitVector();
Encoder.appendBytes(new ByteArray("A"), QRCode.MODE_ALPHANUMERIC, bits); Encoder.appendBytes(new ByteArray("A"), Mode.ALPHANUMERIC, bits);
assertEquals("001010" , bits.toString()); assertEquals("001010" , bits.toString());
// Lower letters such as 'a' cannot be encoded in MODE_ALPHANUMERIC. // Lower letters such as 'a' cannot be encoded in MODE_ALPHANUMERIC.
try { try {
Encoder.appendBytes(new ByteArray("a"), QRCode.MODE_ALPHANUMERIC, bits); Encoder.appendBytes(new ByteArray("a"), Mode.ALPHANUMERIC, bits);
} catch (WriterException we) { } catch (WriterException we) {
// good // good
} }
@ -198,23 +199,23 @@ public final class EncoderTestCase extends TestCase {
// Should use append8BitBytes. // Should use append8BitBytes.
// 0x61, 0x62, 0x63 // 0x61, 0x62, 0x63
BitVector bits = new BitVector(); BitVector bits = new BitVector();
Encoder.appendBytes(new ByteArray("abc"), QRCode.MODE_8BIT_BYTE, bits); Encoder.appendBytes(new ByteArray("abc"), Mode.BYTE, bits);
assertEquals("01100001" + "01100010" + "01100011", bits.toString()); assertEquals("01100001" + "01100010" + "01100011", bits.toString());
// Anything can be encoded in QRCode.MODE_8BIT_BYTE. // Anything can be encoded in QRCode.MODE_8BIT_BYTE.
byte[] bytes = {0x00}; byte[] bytes = {0x00};
Encoder.appendBytes(new ByteArray(bytes), QRCode.MODE_8BIT_BYTE, bits); Encoder.appendBytes(new ByteArray(bytes), Mode.BYTE, bits);
} }
{ {
// Should use appendKanjiBytes. // Should use appendKanjiBytes.
// 0x93, 0x5f // 0x93, 0x5f
BitVector bits = new BitVector(); BitVector bits = new BitVector();
byte[] bytes = {(byte)0x93,0x5f}; byte[] bytes = {(byte)0x93,0x5f};
Encoder.appendBytes(new ByteArray(bytes), QRCode.MODE_KANJI, bits); Encoder.appendBytes(new ByteArray(bytes), Mode.KANJI, bits);
assertEquals("0110110011111", bits.toString()); assertEquals("0110110011111", bits.toString());
// ASCII characters can not be encoded in QRCode.MODE_KANJI. // ASCII characters can not be encoded in QRCode.MODE_KANJI.
try { try {
Encoder.appendBytes(new ByteArray("a"), QRCode.MODE_KANJI, bits); Encoder.appendBytes(new ByteArray("a"), Mode.KANJI, bits);
} catch (WriterException we) { } catch (WriterException we) {
// good // good
} }

View file

@ -17,7 +17,6 @@
package com.google.zxing.qrcode.encoder; package com.google.zxing.qrcode.encoder;
import com.google.zxing.common.ByteMatrix; import com.google.zxing.common.ByteMatrix;
import com.google.zxing.qrcode.encoder.MaskUtil;
import junit.framework.TestCase; import junit.framework.TestCase;
/** /**

View file

@ -16,8 +16,8 @@
package com.google.zxing.qrcode.encoder; package com.google.zxing.qrcode.encoder;
import com.google.zxing.common.ByteMatrix;
import com.google.zxing.WriterException; import com.google.zxing.WriterException;
import com.google.zxing.common.ByteMatrix;
import com.google.zxing.qrcode.decoder.ErrorCorrectionLevel; import com.google.zxing.qrcode.decoder.ErrorCorrectionLevel;
import junit.framework.TestCase; import junit.framework.TestCase;

View file

@ -17,8 +17,8 @@
package com.google.zxing.qrcode.encoder; package com.google.zxing.qrcode.encoder;
import com.google.zxing.common.ByteMatrix; import com.google.zxing.common.ByteMatrix;
import com.google.zxing.WriterException;
import com.google.zxing.qrcode.decoder.ErrorCorrectionLevel; import com.google.zxing.qrcode.decoder.ErrorCorrectionLevel;
import com.google.zxing.qrcode.decoder.Mode;
import junit.framework.TestCase; import junit.framework.TestCase;
/** /**
@ -33,7 +33,7 @@ public final class QRCodeTestCase extends TestCase {
// First, test simple setters and getters. // First, test simple setters and getters.
// We use numbers of version 7-H. // We use numbers of version 7-H.
qrCode.setMode(QRCode.MODE_8BIT_BYTE); qrCode.setMode(Mode.BYTE);
qrCode.setECLevel(ErrorCorrectionLevel.H); qrCode.setECLevel(ErrorCorrectionLevel.H);
qrCode.setVersion(7); qrCode.setVersion(7);
qrCode.setMatrixWidth(45); qrCode.setMatrixWidth(45);
@ -43,7 +43,7 @@ public final class QRCodeTestCase extends TestCase {
qrCode.setNumECBytes(130); qrCode.setNumECBytes(130);
qrCode.setNumRSBlocks(5); qrCode.setNumRSBlocks(5);
assertEquals(QRCode.MODE_8BIT_BYTE, qrCode.getMode()); assertEquals(Mode.BYTE, qrCode.getMode());
assertEquals(ErrorCorrectionLevel.H, qrCode.getECLevel()); assertEquals(ErrorCorrectionLevel.H, qrCode.getECLevel());
assertEquals(7, qrCode.getVersion()); assertEquals(7, qrCode.getVersion());
assertEquals(45, qrCode.getMatrixWidth()); assertEquals(45, qrCode.getMatrixWidth());
@ -85,7 +85,7 @@ public final class QRCodeTestCase extends TestCase {
QRCode qrCode = new QRCode(); QRCode qrCode = new QRCode();
String expected = String expected =
"<<\n" + "<<\n" +
" mode: UNDEFINED\n" + " mode: null\n" +
" ecLevel: null\n" + " ecLevel: null\n" +
" version: -1\n" + " version: -1\n" +
" matrixWidth: -1\n" + " matrixWidth: -1\n" +
@ -101,7 +101,7 @@ public final class QRCodeTestCase extends TestCase {
{ {
String expected = String expected =
"<<\n" + "<<\n" +
" mode: 8BIT_BYTE\n" + " mode: BYTE\n" +
" ecLevel: H\n" + " ecLevel: H\n" +
" version: 1\n" + " version: 1\n" +
" matrixWidth: 21\n" + " matrixWidth: 21\n" +
@ -134,7 +134,7 @@ public final class QRCodeTestCase extends TestCase {
" 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0\n" + " 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0\n" +
">>\n"; ">>\n";
QRCode qrCode = new QRCode(); QRCode qrCode = new QRCode();
qrCode.setMode(QRCode.MODE_8BIT_BYTE); qrCode.setMode(Mode.BYTE);
qrCode.setECLevel(ErrorCorrectionLevel.H); qrCode.setECLevel(ErrorCorrectionLevel.H);
qrCode.setVersion(1); qrCode.setVersion(1);
qrCode.setMatrixWidth(21); qrCode.setMatrixWidth(21);
@ -162,14 +162,6 @@ public final class QRCodeTestCase extends TestCase {
assertFalse(QRCode.isValidVersion(0)); assertFalse(QRCode.isValidVersion(0));
} }
public void testIsValidMode() {
assertFalse(QRCode.isValidMode(QRCode.MODE_UNDEFINED));
assertTrue(QRCode.isValidMode(QRCode.MODE_NUMERIC));
assertTrue(QRCode.isValidMode(QRCode.MODE_ALPHANUMERIC));
assertTrue(QRCode.isValidMode(QRCode.MODE_8BIT_BYTE));
assertFalse(QRCode.isValidMode(QRCode.NUM_MODES));
}
public void testIsValidMatrixWidth() { public void testIsValidMatrixWidth() {
assertFalse(QRCode.isValidMatrixWidth(20)); assertFalse(QRCode.isValidMatrixWidth(20));
assertTrue(QRCode.isValidMatrixWidth(21)); assertTrue(QRCode.isValidMatrixWidth(21));
@ -184,25 +176,4 @@ public final class QRCodeTestCase extends TestCase {
assertFalse(QRCode.isValidMaskPattern(8)); assertFalse(QRCode.isValidMaskPattern(8));
} }
public void testModeToString() {
assertEquals("UNDEFINED", QRCode.modeToString(QRCode.MODE_UNDEFINED));
assertEquals("NUMERIC", QRCode.modeToString(QRCode.MODE_NUMERIC));
assertEquals("ALPHANUMERIC", QRCode.modeToString(QRCode.MODE_ALPHANUMERIC));
assertEquals("8BIT_BYTE", QRCode.modeToString(QRCode.MODE_8BIT_BYTE));
assertEquals("UNKNOWN", QRCode.modeToString(QRCode.NUM_MODES));
}
public void testGetModeCode() throws WriterException {
assertEquals(1, QRCode.getModeCode(QRCode.MODE_NUMERIC));
assertEquals(2, QRCode.getModeCode(QRCode.MODE_ALPHANUMERIC));
assertEquals(4, QRCode.getModeCode(QRCode.MODE_8BIT_BYTE));
assertEquals(8, QRCode.getModeCode(QRCode.MODE_KANJI));
try {
QRCode.getModeCode(QRCode.MODE_UNDEFINED);
fail("Should have thrown exception");
} catch (WriterException we) {
// good
}
}
} }