Added, at least, parsing of ECI mode in QR Code

git-svn-id: https://zxing.googlecode.com/svn/trunk@443 59b500cc-1b3d-0410-9834-0bbf25fbcc57
This commit is contained in:
srowen 2008-06-19 01:37:49 +00:00
parent 15f34edb52
commit 9ee69fee5a
2 changed files with 43 additions and 11 deletions

View file

@ -67,18 +67,27 @@ final class DecodedBitStreamParser {
mode = Mode.forBits(bits.readBits(4)); // mode is encoded by 4 bits mode = Mode.forBits(bits.readBits(4)); // mode is encoded by 4 bits
} }
if (!mode.equals(Mode.TERMINATOR)) { if (!mode.equals(Mode.TERMINATOR)) {
// How many characters will follow, encoded in this mode? if (mode.equals(Mode.ECI)) {
int count = bits.readBits(mode.getCharacterCountBits(version)); // Count doesn't apply to ECI
if (mode.equals(Mode.NUMERIC)) { parseECI(bits);
decodeNumericSegment(bits, result, count); // We don't currently do anything with ECI, since there seems to be no reference
} else if (mode.equals(Mode.ALPHANUMERIC)) { // defining what each value means. AIM's "Extended Channel Interpretations" does
decodeAlphanumericSegment(bits, result, count); // not define it. I have never observed a QR Code using it. So for now, we at least
} else if (mode.equals(Mode.BYTE)) { // parse it but don't know how to take action on it.
decodeByteSegment(bits, result, count);
} else if (mode.equals(Mode.KANJI)) {
decodeKanjiSegment(bits, result, count);
} else { } else {
throw new ReaderException("Unsupported mode indicator"); // How many characters will follow, encoded in this mode?
int count = bits.readBits(mode.getCharacterCountBits(version));
if (mode.equals(Mode.NUMERIC)) {
decodeNumericSegment(bits, result, count);
} else if (mode.equals(Mode.ALPHANUMERIC)) {
decodeAlphanumericSegment(bits, result, count);
} else if (mode.equals(Mode.BYTE)) {
decodeByteSegment(bits, result, count);
} else if (mode.equals(Mode.KANJI)) {
decodeKanjiSegment(bits, result, count);
} else {
throw new ReaderException("Unsupported mode indicator");
}
} }
} }
} while (!mode.equals(Mode.TERMINATOR)); } while (!mode.equals(Mode.TERMINATOR));
@ -95,6 +104,23 @@ final class DecodedBitStreamParser {
return result.toString(); return result.toString();
} }
private static int parseECI(BitSource bits) {
int firstByte = bits.readBits(8);
if (firstByte & 0x80 == 0) {
// just one byte
return firstByte & 0x7F;
} else if (firstByte & 0xC0 == 0x80) {
// two bytes
int secondByte = bits.readBits(8);
return ((firstByte & 0x3F) << 8) | secondByte;
} else if (firstByte & 0xE0 == 0xC0) {
// three bytes
int secondByte = bits.readBits(8);
int thirdByte = bits.readBits(8);
return ((firstByte & 0x1F) << 16) | (secondByte << 8) | thirdByte;
}
}
private static void decodeKanjiSegment(BitSource bits, private static void decodeKanjiSegment(BitSource bits,
StringBuffer result, StringBuffer result,
int count) throws ReaderException { int count) throws ReaderException {

View file

@ -32,6 +32,7 @@ final class Mode {
static final Mode NUMERIC = new Mode(new int[]{10, 12, 14}); static final Mode NUMERIC = new Mode(new int[]{10, 12, 14});
static final Mode ALPHANUMERIC = new Mode(new int[]{9, 11, 13}); static final Mode ALPHANUMERIC = new Mode(new int[]{9, 11, 13});
static final Mode BYTE = new Mode(new int[]{8, 16, 16}); static final Mode BYTE = new Mode(new int[]{8, 16, 16});
static final Mode ECI = new Mode(null); // character counts don't apply
static final Mode KANJI = new Mode(new int[]{8, 10, 12}); static final Mode KANJI = new Mode(new int[]{8, 10, 12});
private final int[] characterCountBitsForVersions; private final int[] characterCountBitsForVersions;
@ -55,6 +56,8 @@ final class Mode {
return ALPHANUMERIC; return ALPHANUMERIC;
case 0x4: case 0x4:
return BYTE; return BYTE;
case 0x7:
return ECI;
case 0x8: case 0x8:
return KANJI; return KANJI;
default: default:
@ -68,6 +71,9 @@ final class Mode {
* 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) { int getCharacterCountBits(Version version) {
if (this == ECI) {
throw new UnsupportedOperationException("Character count doesn't apply to ECI mode");
}
int number = version.getVersionNumber(); int number = version.getVersionNumber();
int offset; int offset;
if (number <= 9) { if (number <= 9) {