Adjust formatting on last change. Simplify GridSampler
[zxing.git] / core / src / com / google / zxing / datamatrix / decoder / DecodedBitStreamParser.java
index 7f6deca..16ce63d 100644 (file)
 
 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
@@ -47,7 +47,7 @@ final class DecodedBitStreamParser {
   private static final char[] C40_SHIFT2_SET_CHARS = {
     '!', '"', '#', '$', '%', '&', '\'', '(', ')', '*', '+', ',', '-', '.',
     '/', ':', ';', '<', '=', '>', '?', '@', '[', '\\', ']', '^', '_'
-       };
+  };
   
   /**
    * See ISO 16022:2006, Annex C Table C.2
@@ -75,7 +75,7 @@ final class DecodedBitStreamParser {
   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);
@@ -102,7 +102,7 @@ final class DecodedBitStreamParser {
             decodeBase256Segment(bits, result, byteSegments);
             break;
           default:
-            throw ReaderException.getInstance();
+            throw FormatException.getFormatInstance();
         }
         mode = ASCII_ENCODE;
       }
@@ -117,59 +117,59 @@ final class DecodedBitStreamParser {
    * 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;
   }
@@ -177,7 +177,7 @@ final class DecodedBitStreamParser {
   /**
    * 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
@@ -230,11 +230,11 @@ final class DecodedBitStreamParser {
                 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;
@@ -248,7 +248,7 @@ final class DecodedBitStreamParser {
             shift = 0;
             break;
           default:
-            throw ReaderException.getInstance();
+            throw FormatException.getFormatInstance();
         }
       }
     } while (bits.available() > 0);
@@ -257,7 +257,7 @@ final class DecodedBitStreamParser {
   /**
    * 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
@@ -311,11 +311,11 @@ final class DecodedBitStreamParser {
                 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;
@@ -329,7 +329,7 @@ final class DecodedBitStreamParser {
             shift = 0;
             break;
           default:
-            throw ReaderException.getInstance();
+            throw FormatException.getFormatInstance();
         }
       }
     } while (bits.available() > 0);
@@ -338,7 +338,7 @@ final class DecodedBitStreamParser {
   /**
    * 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
 
@@ -370,7 +370,7 @@ final class DecodedBitStreamParser {
         } else if (cValue < 40) {  // A - Z
           result.append((char) (cValue + 51));
         } else {
-          throw ReaderException.getInstance();
+          throw FormatException.getFormatInstance();
         }
       }
     } while (bits.available() > 0);
@@ -420,7 +420,8 @@ final class DecodedBitStreamParser {
   /**
    * 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;
@@ -433,6 +434,11 @@ final class DecodedBitStreamParser {
     }
     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);