package com.google.zxing.datamatrix.decoder;
-import com.google.zxing.ReaderException;
+import com.google.zxing.FormatException;
import com.google.zxing.common.BitSource;
import com.google.zxing.common.DecoderResult;
-import java.util.Vector;
import java.io.UnsupportedEncodingException;
+import java.util.Vector;
/**
* <p>Data Matrix Codes can encode text as bits in one of several modes, and can use multiple modes
private static final char[] C40_SHIFT2_SET_CHARS = {
'!', '"', '#', '$', '%', '&', '\'', '(', ')', '*', '+', ',', '-', '.',
'/', ':', ';', '<', '=', '>', '?', '@', '[', '\\', ']', '^', '_'
- };
+ };
/**
* See ISO 16022:2006, Annex C Table C.2
private DecodedBitStreamParser() {
}
- static DecoderResult decode(byte[] bytes) throws ReaderException {
+ static DecoderResult decode(byte[] bytes) throws FormatException {
BitSource bits = new BitSource(bytes);
StringBuffer result = new StringBuffer(100);
StringBuffer resultTrailer = new StringBuffer(0);
decodeBase256Segment(bits, result, byteSegments);
break;
default:
- throw ReaderException.getInstance();
+ throw FormatException.getFormatInstance();
}
mode = ASCII_ENCODE;
}
* See ISO 16022:2006, 5.2.3 and Annex C, Table C.2
*/
private static int decodeAsciiSegment(BitSource bits, StringBuffer result, StringBuffer resultTrailer)
- throws ReaderException {
+ throws FormatException {
boolean upperShift = false;
do {
int oneByte = bits.readBits(8);
if (oneByte == 0) {
- throw ReaderException.getInstance();
- } else if (oneByte <= 128) { // ASCII data (ASCII value + 1)
- oneByte = upperShift ? (oneByte + 128) : oneByte;
- upperShift = false;
- result.append((char) (oneByte - 1));
- return ASCII_ENCODE;
- } else if (oneByte == 129) { // Pad
- return PAD_ENCODE;
- } else if (oneByte <= 229) { // 2-digit data 00-99 (Numeric Value + 130)
- int value = oneByte - 130;
- if (value < 10) { // padd with '0' for single digit values
- result.append('0');
- }
- result.append(value);
- } else if (oneByte == 230) { // Latch to C40 encodation
- return C40_ENCODE;
- } else if (oneByte == 231) { // Latch to Base 256 encodation
- return BASE256_ENCODE;
- } else if (oneByte == 232) { // FNC1
- //throw ReaderException.getInstance();
+ throw FormatException.getFormatInstance();
+ } else if (oneByte <= 128) { // ASCII data (ASCII value + 1)
+ oneByte = upperShift ? (oneByte + 128) : oneByte;
+ upperShift = false;
+ result.append((char) (oneByte - 1));
+ return ASCII_ENCODE;
+ } else if (oneByte == 129) { // Pad
+ return PAD_ENCODE;
+ } else if (oneByte <= 229) { // 2-digit data 00-99 (Numeric Value + 130)
+ int value = oneByte - 130;
+ if (value < 10) { // padd with '0' for single digit values
+ result.append('0');
+ }
+ result.append(value);
+ } else if (oneByte == 230) { // Latch to C40 encodation
+ return C40_ENCODE;
+ } else if (oneByte == 231) { // Latch to Base 256 encodation
+ return BASE256_ENCODE;
+ } else if (oneByte == 232) { // FNC1
+ //throw ReaderException.getInstance();
// Ignore this symbol for now
- } else if (oneByte == 233) { // Structured Append
- //throw ReaderException.getInstance();
+ } else if (oneByte == 233) { // Structured Append
+ //throw ReaderException.getInstance();
// Ignore this symbol for now
- } else if (oneByte == 234) { // Reader Programming
- //throw ReaderException.getInstance();
+ } else if (oneByte == 234) { // Reader Programming
+ //throw ReaderException.getInstance();
// Ignore this symbol for now
- } else if (oneByte == 235) { // Upper Shift (shift to Extended ASCII)
- upperShift = true;
- } else if (oneByte == 236) { // 05 Macro
+ } else if (oneByte == 235) { // Upper Shift (shift to Extended ASCII)
+ upperShift = true;
+ } else if (oneByte == 236) { // 05 Macro
result.append("[)>\u001E05\u001D");
resultTrailer.insert(0, "\u001E\u0004");
} else if (oneByte == 237) { // 06 Macro
- result.append("[)>\u001E06\u001D");
+ result.append("[)>\u001E06\u001D");
resultTrailer.insert(0, "\u001E\u0004");
- } else if (oneByte == 238) { // Latch to ANSI X12 encodation
- return ANSIX12_ENCODE;
- } else if (oneByte == 239) { // Latch to Text encodation
- return TEXT_ENCODE;
- } else if (oneByte == 240) { // Latch to EDIFACT encodation
- return EDIFACT_ENCODE;
- } else if (oneByte == 241) { // ECI Character
- // TODO(bbrown): I think we need to support ECI
- //throw ReaderException.getInstance();
+ } else if (oneByte == 238) { // Latch to ANSI X12 encodation
+ return ANSIX12_ENCODE;
+ } else if (oneByte == 239) { // Latch to Text encodation
+ return TEXT_ENCODE;
+ } else if (oneByte == 240) { // Latch to EDIFACT encodation
+ return EDIFACT_ENCODE;
+ } else if (oneByte == 241) { // ECI Character
+ // TODO(bbrown): I think we need to support ECI
+ //throw ReaderException.getInstance();
// Ignore this symbol for now
- } else if (oneByte >= 242) { // Not to be used in ASCII encodation
- throw ReaderException.getInstance();
- }
+ } else if (oneByte >= 242) { // Not to be used in ASCII encodation
+ throw FormatException.getFormatInstance();
+ }
} while (bits.available() > 0);
return ASCII_ENCODE;
}
/**
* See ISO 16022:2006, 5.2.5 and Annex C, Table C.1
*/
- private static void decodeC40Segment(BitSource bits, StringBuffer result) throws ReaderException {
+ private static void decodeC40Segment(BitSource bits, StringBuffer result) throws FormatException {
// Three C40 values are encoded in a 16-bit value as
// (1600 * C1) + (40 * C2) + C3 + 1
// TODO(bbrown): The Upper Shift with C40 doesn't work in the 4 value scenario all the time
result.append(C40_SHIFT2_SET_CHARS[cValue]);
}
} else if (cValue == 27) { // FNC1
- throw ReaderException.getInstance();
+ throw FormatException.getFormatInstance();
} else if (cValue == 30) { // Upper Shift
upperShift = true;
} else {
- throw ReaderException.getInstance();
+ throw FormatException.getFormatInstance();
}
shift = 0;
break;
shift = 0;
break;
default:
- throw ReaderException.getInstance();
+ throw FormatException.getFormatInstance();
}
}
} while (bits.available() > 0);
/**
* See ISO 16022:2006, 5.2.6 and Annex C, Table C.2
*/
- private static void decodeTextSegment(BitSource bits, StringBuffer result) throws ReaderException {
+ private static void decodeTextSegment(BitSource bits, StringBuffer result) throws FormatException {
// Three Text values are encoded in a 16-bit value as
// (1600 * C1) + (40 * C2) + C3 + 1
// TODO(bbrown): The Upper Shift with Text doesn't work in the 4 value scenario all the time
result.append(C40_SHIFT2_SET_CHARS[cValue]);
}
} else if (cValue == 27) { // FNC1
- throw ReaderException.getInstance();
+ throw FormatException.getFormatInstance();
} else if (cValue == 30) { // Upper Shift
upperShift = true;
} else {
- throw ReaderException.getInstance();
+ throw FormatException.getFormatInstance();
}
shift = 0;
break;
shift = 0;
break;
default:
- throw ReaderException.getInstance();
+ throw FormatException.getFormatInstance();
}
}
} while (bits.available() > 0);
/**
* See ISO 16022:2006, 5.2.7
*/
- private static void decodeAnsiX12Segment(BitSource bits, StringBuffer result) throws ReaderException {
+ private static void decodeAnsiX12Segment(BitSource bits, StringBuffer result) throws FormatException {
// Three ANSI X12 values are encoded in a 16-bit value as
// (1600 * C1) + (40 * C2) + C3 + 1
} else if (cValue < 40) { // A - Z
result.append((char) (cValue + 51));
} else {
- throw ReaderException.getInstance();
+ throw FormatException.getFormatInstance();
}
}
} while (bits.available() > 0);
/**
* See ISO 16022:2006, 5.2.9 and Annex B, B.2
*/
- private static void decodeBase256Segment(BitSource bits, StringBuffer result, Vector byteSegments) {
+ private static void decodeBase256Segment(BitSource bits, StringBuffer result, Vector byteSegments)
+ throws FormatException {
// Figure out how long the Base 256 Segment is.
int d1 = bits.readBits(8);
int count;
}
byte[] bytes = new byte[count];
for (int i = 0; i < count; i++) {
+ // Have seen this particular error in the wild, such as at
+ // http://www.bcgen.com/demo/IDAutomationStreamingDataMatrix.aspx?MODE=3&D=Fred&PFMT=3&PT=F&X=0.3&O=0&LM=0.2
+ if (bits.available() < 8) {
+ throw FormatException.getFormatInstance();
+ }
bytes[i] = unrandomize255State(bits.readBits(8), i);
}
byteSegments.addElement(bytes);