\r
package com.google.zxing.qrcode.decoder;\r
\r
-import com.google.zxing.ReaderException;\r
+import com.google.zxing.FormatException;\r
import com.google.zxing.common.BitMatrix;\r
\r
/**\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
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
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
*\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
+ * @throws FormatException if dimension is not 1 mod 4\r
*/\r
- public static Version getProvisionalVersionForDimension(int dimension) throws ReaderException {\r
+ public static Version getProvisionalVersionForDimension(int dimension) throws FormatException {\r
if (dimension % 4 != 1) {\r
- throw new ReaderException("Dimension must be 1 mod 4");\r
+ throw FormatException.getFormatInstance();\r
+ }\r
+ try {\r
+ return getVersionForNumber((dimension - 17) >> 2);\r
+ } catch (IllegalArgumentException iae) {\r
+ throw FormatException.getFormatInstance();\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
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
// 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
// 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
* 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
* 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
- final int count;\r
- final int dataCodewords;\r
+ public static final class ECB {\r
+ private final int count;\r
+ private final int dataCodewords;\r
\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