]> Pileus Git - ~andy/freeotp/blob - src/com/google/zxing/datamatrix/decoder/Version.java
Add native camera support
[~andy/freeotp] / src / com / google / zxing / datamatrix / decoder / Version.java
1 /*
2  * Copyright 2007 ZXing authors
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16
17 package com.google.zxing.datamatrix.decoder;
18
19 import com.google.zxing.FormatException;
20
21 /**
22  * The Version object encapsulates attributes about a particular
23  * size Data Matrix Code.
24  *
25  * @author bbrown@google.com (Brian Brown)
26  */
27 public final class Version {
28
29   private static final Version[] VERSIONS = buildVersions();
30
31   private final int versionNumber;
32   private final int symbolSizeRows;
33   private final int symbolSizeColumns;
34   private final int dataRegionSizeRows;
35   private final int dataRegionSizeColumns;
36   private final ECBlocks ecBlocks;
37   private final int totalCodewords;
38
39   private Version(int versionNumber,
40                   int symbolSizeRows,
41                   int symbolSizeColumns,
42                   int dataRegionSizeRows,
43                   int dataRegionSizeColumns,
44                   ECBlocks ecBlocks) {
45     this.versionNumber = versionNumber;
46     this.symbolSizeRows = symbolSizeRows;
47     this.symbolSizeColumns = symbolSizeColumns;
48     this.dataRegionSizeRows = dataRegionSizeRows;
49     this.dataRegionSizeColumns = dataRegionSizeColumns;
50     this.ecBlocks = ecBlocks;
51     
52     // Calculate the total number of codewords
53     int total = 0;
54     int ecCodewords = ecBlocks.getECCodewords();
55     ECB[] ecbArray = ecBlocks.getECBlocks();
56     for (ECB ecBlock : ecbArray) {
57       total += ecBlock.getCount() * (ecBlock.getDataCodewords() + ecCodewords);
58     }
59     this.totalCodewords = total;
60   }
61
62   public int getVersionNumber() {
63     return versionNumber;
64   }
65
66   public int getSymbolSizeRows() {
67     return symbolSizeRows;
68   }
69   
70   public int getSymbolSizeColumns() {
71     return symbolSizeColumns;
72   }
73   
74   public int getDataRegionSizeRows() {
75     return dataRegionSizeRows;
76   }
77   
78   public int getDataRegionSizeColumns() {
79     return dataRegionSizeColumns;
80   }
81   
82   public int getTotalCodewords() {
83     return totalCodewords;
84   }
85   
86   ECBlocks getECBlocks() {
87     return ecBlocks;
88   }
89
90   /**
91    * <p>Deduces version information from Data Matrix dimensions.</p>
92    *
93    * @param numRows Number of rows in modules
94    * @param numColumns Number of columns in modules
95    * @return Version for a Data Matrix Code of those dimensions
96    * @throws FormatException if dimensions do correspond to a valid Data Matrix size
97    */
98   public static Version getVersionForDimensions(int numRows, int numColumns) throws FormatException {
99     if ((numRows & 0x01) != 0 || (numColumns & 0x01) != 0) {
100       throw FormatException.getFormatInstance();
101     }
102
103     for (Version version : VERSIONS) {
104       if (version.symbolSizeRows == numRows && version.symbolSizeColumns == numColumns) {
105         return version;
106       }
107     }
108     
109     throw FormatException.getFormatInstance();
110   }
111
112   /**
113    * <p>Encapsulates a set of error-correction blocks in one symbol version. Most versions will
114    * use blocks of differing sizes within one version, so, this encapsulates the parameters for
115    * each set of blocks. It also holds the number of error-correction codewords per block since it
116    * will be the same across all blocks within one version.</p>
117    */
118   static final class ECBlocks {
119     private final int ecCodewords;
120     private final ECB[] ecBlocks;
121
122     private ECBlocks(int ecCodewords, ECB ecBlocks) {
123       this.ecCodewords = ecCodewords;
124       this.ecBlocks = new ECB[] { ecBlocks };
125     }
126
127     private ECBlocks(int ecCodewords, ECB ecBlocks1, ECB ecBlocks2) {
128       this.ecCodewords = ecCodewords;
129       this.ecBlocks = new ECB[] { ecBlocks1, ecBlocks2 };
130     }
131
132     int getECCodewords() {
133       return ecCodewords;
134     }
135
136     ECB[] getECBlocks() {
137       return ecBlocks;
138     }
139   }
140
141   /**
142    * <p>Encapsualtes the parameters for one error-correction block in one symbol version.
143    * This includes the number of data codewords, and the number of times a block with these
144    * parameters is used consecutively in the Data Matrix code version's format.</p>
145    */
146   static final class ECB {
147     private final int count;
148     private final int dataCodewords;
149
150     private ECB(int count, int dataCodewords) {
151       this.count = count;
152       this.dataCodewords = dataCodewords;
153     }
154
155     int getCount() {
156       return count;
157     }
158
159     int getDataCodewords() {
160       return dataCodewords;
161     }
162   }
163
164   @Override
165   public String toString() {
166     return String.valueOf(versionNumber);
167   }
168
169   /**
170    * See ISO 16022:2006 5.5.1 Table 7
171    */
172   private static Version[] buildVersions() {
173     return new Version[]{
174         new Version(1, 10, 10, 8, 8,
175             new ECBlocks(5, new ECB(1, 3))),
176         new Version(2, 12, 12, 10, 10,
177             new ECBlocks(7, new ECB(1, 5))),
178         new Version(3, 14, 14, 12, 12,
179             new ECBlocks(10, new ECB(1, 8))),
180         new Version(4, 16, 16, 14, 14,
181             new ECBlocks(12, new ECB(1, 12))),
182         new Version(5, 18, 18, 16, 16,
183             new ECBlocks(14, new ECB(1, 18))),
184         new Version(6, 20, 20, 18, 18,
185             new ECBlocks(18, new ECB(1, 22))),
186         new Version(7, 22, 22, 20, 20,
187             new ECBlocks(20, new ECB(1, 30))),
188         new Version(8, 24, 24, 22, 22,
189             new ECBlocks(24, new ECB(1, 36))),
190         new Version(9, 26, 26, 24, 24,
191             new ECBlocks(28, new ECB(1, 44))),
192         new Version(10, 32, 32, 14, 14,
193             new ECBlocks(36, new ECB(1, 62))),
194         new Version(11, 36, 36, 16, 16,
195             new ECBlocks(42, new ECB(1, 86))),
196         new Version(12, 40, 40, 18, 18,
197             new ECBlocks(48, new ECB(1, 114))),
198         new Version(13, 44, 44, 20, 20,
199             new ECBlocks(56, new ECB(1, 144))),
200         new Version(14, 48, 48, 22, 22,
201             new ECBlocks(68, new ECB(1, 174))),
202         new Version(15, 52, 52, 24, 24,
203             new ECBlocks(42, new ECB(2, 102))),
204         new Version(16, 64, 64, 14, 14,
205             new ECBlocks(56, new ECB(2, 140))),
206         new Version(17, 72, 72, 16, 16,
207             new ECBlocks(36, new ECB(4, 92))),
208         new Version(18, 80, 80, 18, 18,
209             new ECBlocks(48, new ECB(4, 114))),
210         new Version(19, 88, 88, 20, 20,
211             new ECBlocks(56, new ECB(4, 144))),
212         new Version(20, 96, 96, 22, 22,
213             new ECBlocks(68, new ECB(4, 174))),
214         new Version(21, 104, 104, 24, 24,
215             new ECBlocks(56, new ECB(6, 136))),
216         new Version(22, 120, 120, 18, 18,
217             new ECBlocks(68, new ECB(6, 175))),
218         new Version(23, 132, 132, 20, 20,
219             new ECBlocks(62, new ECB(8, 163))),
220         new Version(24, 144, 144, 22, 22,
221             new ECBlocks(62, new ECB(8, 156), new ECB(2, 155))),
222         new Version(25, 8, 18, 6, 16,
223             new ECBlocks(7, new ECB(1, 5))),
224         new Version(26, 8, 32, 6, 14,
225             new ECBlocks(11, new ECB(1, 10))),
226         new Version(27, 12, 26, 10, 24,
227             new ECBlocks(14, new ECB(1, 16))),
228         new Version(28, 12, 36, 10, 16,
229             new ECBlocks(18, new ECB(1, 22))),
230         new Version(29, 16, 36, 14, 16,
231             new ECBlocks(24, new ECB(1, 32))),
232         new Version(30, 16, 48, 14, 22,
233             new ECBlocks(28, new ECB(1, 49)))
234     };
235   }
236
237 }