Remove some redundant 'throws'; allocate more reasonably sized StringBuffers for...
[zxing.git] / core / src / com / google / zxing / qrcode / decoder / Version.java
index d30fdeb..823bf2b 100755 (executable)
@@ -1,5 +1,5 @@
 /*\r
- * Copyright 2007 Google Inc.\r
+ * Copyright 2007 ZXing authors\r
  *\r
  * Licensed under the Apache License, Version 2.0 (the "License");\r
  * you may not use this file except in compliance with the License.\r
@@ -22,7 +22,7 @@ import com.google.zxing.common.BitMatrix;
 /**\r
  * See ISO 18004:2006 Annex D\r
  *\r
- * @author srowen@google.com (Sean Owen)\r
+ * @author Sean Owen\r
  */\r
 public final class Version {\r
 \r
@@ -30,7 +30,7 @@ public final class Version {
    * See ISO 18004:2006 Annex D.\r
    * Element i represents the raw version bits that specify version i + 7\r
    */\r
-  private static final int[] VERSION_DECODE_INFO = new int[]{\r
+  private static final int[] VERSION_DECODE_INFO = {\r
       0x07C94, 0x085BC, 0x09A99, 0x0A4D3, 0x0BBF6,\r
       0x0C762, 0x0D847, 0x0E60D, 0x0F928, 0x10B78,\r
       0x1145D, 0x12A17, 0x13532, 0x149A6, 0x15683,\r
@@ -57,7 +57,7 @@ public final class Version {
     this.alignmentPatternCenters = alignmentPatternCenters;\r
     this.ecBlocks = new ECBlocks[]{ecBlocks1, ecBlocks2, ecBlocks3, ecBlocks4};\r
     int total = 0;\r
-    int ecCodewords = ecBlocks1.getECCodewords();\r
+    int ecCodewords = ecBlocks1.getECCodewordsPerBlock();\r
     ECB[] ecbArray = ecBlocks1.getECBlocks();\r
     for (int i = 0; i < ecbArray.length; i++) {\r
       ECB ecBlock = ecbArray[i];\r
@@ -82,7 +82,7 @@ public final class Version {
     return 17 + 4 * versionNumber;\r
   }\r
 \r
-  ECBlocks getECBlocksForLevel(ErrorCorrectionLevel ecLevel) {\r
+  public ECBlocks getECBlocksForLevel(ErrorCorrectionLevel ecLevel) {\r
     return ecBlocks[ecLevel.ordinal()];\r
   }\r
 \r
@@ -95,19 +95,23 @@ public final class Version {
    */\r
   public static Version getProvisionalVersionForDimension(int dimension) throws ReaderException {\r
     if (dimension % 4 != 1) {\r
-      throw new ReaderException("Dimension must be 1 mod 4");\r
+      throw ReaderException.getInstance();\r
+    }\r
+    try {\r
+      return getVersionForNumber((dimension - 17) >> 2);\r
+    } catch (IllegalArgumentException iae) {\r
+      throw ReaderException.getInstance();\r
     }\r
-    return getVersionForNumber((dimension - 17) >> 2);\r
   }\r
 \r
-  public static Version getVersionForNumber(int versionNumber) throws ReaderException {\r
+  public static Version getVersionForNumber(int versionNumber) {\r
     if (versionNumber < 1 || versionNumber > 40) {\r
-      throw new ReaderException("versionNumber must be between 1 and 40");\r
+      throw new IllegalArgumentException();\r
     }\r
     return VERSIONS[versionNumber - 1];\r
   }\r
 \r
-  static Version decodeVersionInformation(int versionBits) throws ReaderException {\r
+  static Version decodeVersionInformation(int versionBits) {\r
     int bestDifference = Integer.MAX_VALUE;\r
     int bestVersion = 0;\r
     for (int i = 0; i < VERSION_DECODE_INFO.length; i++) {\r
@@ -121,6 +125,7 @@ public final class Version {
       int bitsDifference = FormatInformation.numBitsDiffering(versionBits, targetVersion);\r
       if (bitsDifference < bestDifference) {\r
         bestVersion = i + 7;\r
+        bestDifference = bitsDifference;\r
       }\r
     }\r
     // We can tolerate up to 3 bits of error since no two version info codewords will\r
@@ -142,9 +147,9 @@ public final class Version {
     // Top left finder pattern + separator + format\r
     bitMatrix.setRegion(0, 0, 9, 9);\r
     // Top right finder pattern + separator + format\r
-    bitMatrix.setRegion(0, dimension - 8, 9, 8);\r
-    // Bottom left finder pattern + separator + format\r
     bitMatrix.setRegion(dimension - 8, 0, 8, 9);\r
+    // Bottom left finder pattern + separator + format\r
+    bitMatrix.setRegion(0, dimension - 8, 9, 8);\r
 \r
     // Alignment patterns\r
     int max = alignmentPatternCenters.length;\r
@@ -155,20 +160,20 @@ public final class Version {
           // No alignment patterns near the three finder paterns\r
           continue;\r
         }\r
-        bitMatrix.setRegion(i, alignmentPatternCenters[y] - 2, 5, 5);\r
+        bitMatrix.setRegion(alignmentPatternCenters[y] - 2, i, 5, 5);\r
       }\r
     }\r
 \r
     // Vertical timing pattern\r
-    bitMatrix.setRegion(9, 6, dimension - 17, 1);\r
-    // Horizontal timing pattern\r
     bitMatrix.setRegion(6, 9, 1, dimension - 17);\r
+    // Horizontal timing pattern\r
+    bitMatrix.setRegion(9, 6, dimension - 17, 1);\r
 \r
     if (versionNumber > 6) {\r
       // Version info, top right\r
-      bitMatrix.setRegion(0, dimension - 11, 6, 3);\r
-      // Version info, bottom left\r
       bitMatrix.setRegion(dimension - 11, 0, 3, 6);\r
+      // Version info, bottom left\r
+      bitMatrix.setRegion(0, dimension - 11, 6, 3);\r
     }\r
 \r
     return bitMatrix;\r
@@ -180,25 +185,37 @@ public final class Version {
    * each set of blocks. It also holds the number of error-correction codewords per block since it\r
    * will be the same across all blocks within one version.</p>\r
    */\r
-  static final class ECBlocks {\r
-    private final int ecCodewords;\r
+  public static final class ECBlocks {\r
+    private final int ecCodewordsPerBlock;\r
     private final ECB[] ecBlocks;\r
 \r
-    private ECBlocks(int ecCodewords, ECB ecBlocks) {\r
-      this.ecCodewords = ecCodewords;\r
+    ECBlocks(int ecCodewordsPerBlock, ECB ecBlocks) {\r
+      this.ecCodewordsPerBlock = ecCodewordsPerBlock;\r
       this.ecBlocks = new ECB[]{ecBlocks};\r
     }\r
 \r
-    private ECBlocks(int ecCodewords, ECB ecBlocks1, ECB ecBlocks2) {\r
-      this.ecCodewords = ecCodewords;\r
+    ECBlocks(int ecCodewordsPerBlock, ECB ecBlocks1, ECB ecBlocks2) {\r
+      this.ecCodewordsPerBlock = ecCodewordsPerBlock;\r
       this.ecBlocks = new ECB[]{ecBlocks1, ecBlocks2};\r
     }\r
 \r
-    int getECCodewords() {\r
-      return ecCodewords;\r
+    public int getECCodewordsPerBlock() {\r
+      return ecCodewordsPerBlock;\r
+    }\r
+\r
+    public int getNumBlocks() {\r
+      int total = 0;\r
+      for (int i = 0; i < ecBlocks.length; i++) {\r
+        total += ecBlocks[i].getCount();\r
+      }\r
+      return total;\r
+    }\r
+\r
+    public int getTotalECCodewords() {\r
+      return ecCodewordsPerBlock * getNumBlocks();\r
     }\r
 \r
-    ECB[] getECBlocks() {\r
+    public ECB[] getECBlocks() {\r
       return ecBlocks;\r
     }\r
   }\r
@@ -208,20 +225,20 @@ public final class Version {
    * This includes the number of data codewords, and the number of times a block with these\r
    * parameters is used consecutively in the QR code version's format.</p>\r
    */\r
-  static final class ECB {\r
+  public static final class ECB {\r
     private final int count;\r
     private final int dataCodewords;\r
 \r
-    private ECB(int count, int dataCodewords) {\r
+    ECB(int count, int dataCodewords) {\r
       this.count = count;\r
       this.dataCodewords = dataCodewords;\r
     }\r
 \r
-    int getCount() {\r
+    public int getCount() {\r
       return count;\r
     }\r
 \r
-    int getDataCodewords() {\r
+    public int getDataCodewords() {\r
       return dataCodewords;\r
     }\r
   }\r