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