Add to result the raw, but parsed, bytes of byte segments in 2D barcodes
[zxing.git] / core / src / com / google / zxing / qrcode / decoder / Version.java
index 80188ce..63273b6 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
@@ -55,14 +55,13 @@ public final class Version {
                   ECBlocks ecBlocks4) {\r
     this.versionNumber = versionNumber;\r
     this.alignmentPatternCenters = alignmentPatternCenters;\r
-    this.ecBlocks = new ECBlocks[] { ecBlocks1, ecBlocks2, ecBlocks3, ecBlocks4 };\r
+    this.ecBlocks = new ECBlocks[]{ecBlocks1, ecBlocks2, ecBlocks3, ecBlocks4};\r
     int total = 0;\r
-    ECBlocks levelLECBlocks = ecBlocks1; // L,M,Q,H -- all the same total\r
-    int ecCodewords = levelLECBlocks.ecCodewords;\r
-    ECB[] ecbArray = levelLECBlocks.ecBlocks;\r
+    int ecCodewords = ecBlocks1.getECCodewords();\r
+    ECB[] ecbArray = ecBlocks1.getECBlocks();\r
     for (int i = 0; i < ecbArray.length; i++) {\r
       ECB ecBlock = ecbArray[i];\r
-      total += ecBlock.count * (ecBlock.dataCodewords + ecCodewords);\r
+      total += ecBlock.getCount() * (ecBlock.getDataCodewords() + ecCodewords);\r
     }\r
     this.totalCodewords = total;\r
   }\r
@@ -87,41 +86,49 @@ public final class Version {
     return ecBlocks[ecLevel.ordinal()];\r
   }\r
 \r
-  public static Version getProvisionalVersionForDimension(int dimension)\r
-      throws ReaderException {\r
+  /**\r
+   * <p>Deduces version information purely from QR Code dimensions.</p>\r
+   *\r
+   * @param dimension dimension in modules\r
+   * @return {@link Version} for a QR Code of that dimension\r
+   * @throws ReaderException if dimension is not 1 mod 4\r
+   */\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
     }\r
     return getVersionForNumber((dimension - 17) >> 2);\r
   }\r
 \r
-  public static Version getVersionForNumber(int versionNumber)\r
-      throws ReaderException {\r
+  public static Version getVersionForNumber(int versionNumber) throws ReaderException {\r
     if (versionNumber < 1 || versionNumber > 40) {\r
-      throw new ReaderException(\r
-          "versionNumber must be between 1 and 40");\r
+      throw new ReaderException("versionNumber must be between 1 and 40");\r
     }\r
     return VERSIONS[versionNumber - 1];\r
   }\r
 \r
-  static Version decodeVersionInformation(int versionBits)\r
-      throws ReaderException {\r
+  static Version decodeVersionInformation(int versionBits) throws ReaderException {\r
     int bestDifference = Integer.MAX_VALUE;\r
     int bestVersion = 0;\r
     for (int i = 0; i < VERSION_DECODE_INFO.length; i++) {\r
       int targetVersion = VERSION_DECODE_INFO[i];\r
+      // Do the version info bits match exactly? done.\r
       if (targetVersion == versionBits) {\r
         return getVersionForNumber(i + 7);\r
       }\r
-      int bitsDifference =\r
-          FormatInformation.numBitsDiffering(versionBits, targetVersion);\r
+      // Otherwise see if this is the closest to a real version info bit string\r
+      // we have seen so far\r
+      int bitsDifference = FormatInformation.numBitsDiffering(versionBits, targetVersion);\r
       if (bitsDifference < bestDifference) {\r
         bestVersion = i + 7;\r
       }\r
     }\r
+    // We can tolerate up to 3 bits of error since no two version info codewords will\r
+    // differ in less than 4 bits.\r
     if (bestDifference <= 3) {\r
       return getVersionForNumber(bestVersion);\r
     }\r
+    // If we didn't find a close enough match, fail\r
     return null;\r
   }\r
 \r
@@ -174,17 +181,17 @@ public final class Version {
    * will be the same across all blocks within one version.</p>\r
    */\r
   static final class ECBlocks {\r
-    private int ecCodewords;\r
-    private ECB[] ecBlocks;\r
+    private final int ecCodewords;\r
+    private final ECB[] ecBlocks;\r
 \r
     private ECBlocks(int ecCodewords, ECB ecBlocks) {\r
       this.ecCodewords = ecCodewords;\r
-      this.ecBlocks = new ECB[] { ecBlocks };\r
+      this.ecBlocks = new ECB[]{ecBlocks};\r
     }\r
 \r
     private ECBlocks(int ecCodewords, ECB ecBlocks1, ECB ecBlocks2) {\r
       this.ecCodewords = ecCodewords;\r
-      this.ecBlocks = new ECB[] { ecBlocks1, ecBlocks2 };\r
+      this.ecBlocks = new ECB[]{ecBlocks1, ecBlocks2};\r
     }\r
 \r
     int getECCodewords() {\r
@@ -202,10 +209,10 @@ public final class Version {
    * parameters is used consecutively in the QR code version's format.</p>\r
    */\r
   static final class ECB {\r
-    private int count;\r
-    private int dataCodewords;\r
+    final int count;\r
+    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
@@ -414,7 +421,7 @@ public final class Version {
             new ECBlocks(30, new ECB(30, 16),\r
                 new ECB(2, 17))),\r
         new Version(25, new int[]{6, 32, 58, 84, 110},\r
-            new ECBlocks(26, new ECB(8, 1061),\r
+            new ECBlocks(26, new ECB(8, 106),\r
                 new ECB(4, 107)),\r
             new ECBlocks(28, new ECB(8, 47),\r
                 new ECB(13, 48)),\r