Added "extended mode" to optionally support Extended Code 39

git-svn-id: https://zxing.googlecode.com/svn/trunk@213 59b500cc-1b3d-0410-9834-0bbf25fbcc57
This commit is contained in:
srowen 2008-02-19 19:36:29 +00:00
parent c09cb7d381
commit 8c3045d9eb

View file

@ -48,23 +48,42 @@ public final class Code39Reader extends AbstractOneDReader {
private static final int ASTERISK_ENCODING = CHARACTER_ENCODINGS[39];
private final boolean usingCheckDigit;
private final boolean extendedMode;
/**
* Creates a reader that assumes all encoded data is data, and does not treat the final
* character as a check digit.
* character as a check digit. It will not decoded "extended Code 39" sequences.
*/
public Code39Reader() {
usingCheckDigit = false;
extendedMode = false;
}
/**
* Creates a reader that can be configured to check the last character as a check digit.
* It will not decoded "extended Code 39" sequences.
*
* @param usingCheckDigit if true, treat the last data character as a check digit, not
* data, and verify that the checksum passes
*/
public Code39Reader(boolean usingCheckDigit) {
this.usingCheckDigit = usingCheckDigit;
this.extendedMode = false;
}
/**
* Creates a reader that can be configured to check the last character as a check digit,
* or optionally attempt to decode "extended Code 39" sequences that are used to encode
* the full ASCII character set.
*
* @param usingCheckDigit if true, treat the last data character as a check digit, not
* data, and verify that the checksum passes
* @param extendedMode if true, willa tetmpt to decode extended Code 39 sequences in the
* text
*/
public Code39Reader(boolean usingCheckDigit, boolean extendedMode) {
this.usingCheckDigit = usingCheckDigit;
this.extendedMode = extendedMode;
}
public Result decodeRow(final int rowNumber, final BitArray row) throws ReaderException {
@ -113,6 +132,9 @@ public final class Code39Reader extends AbstractOneDReader {
}
String resultString = result.toString();
if (extendedMode) {
resultString = decodeExtended(resultString);
}
return new Result(resultString,
new ResultPoint[]{new GenericResultPoint((float) (start[1] - start[0]) / 2.0f, (float) rowNumber),
new GenericResultPoint((float) (nextStart - lastStart) / 2.0f, (float) rowNumber)});
@ -194,4 +216,60 @@ public final class Code39Reader extends AbstractOneDReader {
throw new ReaderException("Pattern did not match character encoding");
}
private static String decodeExtended(String encoded) throws ReaderException {
int length = encoded.length();
StringBuffer decoded = new StringBuffer(length);
for (int i = 0; i < length; i++) {
char c = encoded.charAt(i);
if (c == '+' || c == '$' || c == '%' || c == '/') {
char next = encoded.charAt(i + 1);
char decodedChar = '\0';
switch (c) {
case '+':
// +A to +Z map to a to z
if (next >= 'A' && next <= 'Z') {
decodedChar = (char) (next + 32);
} else {
throw new ReaderException("Invalid extended code 39 sequence: " + c + next);
}
break;
case '$':
// $A to $Z map to control codes SH to SB
if (next >= 'A' && next <= 'Z') {
decodedChar = (char) (next - 64);
} else {
throw new ReaderException("Invalid extended code 39 sequence: " + c + next);
}
break;
case '%':
// %A to %E map to control codes ESC to US
if (next >= 'A' && next <= 'E') {
decodedChar = (char) (next - 38);
} else if (next >= 'F' && next <= 'W') {
decodedChar = (char) (next - 11);
} else {
throw new ReaderException("Invalid extended code 39 sequence: " + c + next);
}
break;
case '/':
// /A to /O map to ! to , and /Z maps to :
if (next >= 'A' && next <= 'O') {
decodedChar = (char) (next - 32);
} else if (next == 'Z') {
decodedChar = ':';
} else {
throw new ReaderException("Invalid extended sequence: " + c + next);
}
break;
}
decoded.append(decodedChar);
// bump up i again since we read two characters
i++;
} else {
decoded.append(c);
}
}
return decoded.toString();
}
}