2 * Copyright 2007 ZXing authors
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
8 * http://www.apache.org/licenses/LICENSE-2.0
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.
17 package com.google.zxing.datamatrix.decoder;
19 import com.google.zxing.FormatException;
22 * The Version object encapsulates attributes about a particular
23 * size Data Matrix Code.
25 * @author bbrown@google.com (Brian Brown)
27 public final class Version {
29 private static final Version[] VERSIONS = buildVersions();
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;
39 private Version(int versionNumber,
41 int symbolSizeColumns,
42 int dataRegionSizeRows,
43 int dataRegionSizeColumns,
45 this.versionNumber = versionNumber;
46 this.symbolSizeRows = symbolSizeRows;
47 this.symbolSizeColumns = symbolSizeColumns;
48 this.dataRegionSizeRows = dataRegionSizeRows;
49 this.dataRegionSizeColumns = dataRegionSizeColumns;
50 this.ecBlocks = ecBlocks;
52 // Calculate the total number of codewords
54 int ecCodewords = ecBlocks.getECCodewords();
55 ECB[] ecbArray = ecBlocks.getECBlocks();
56 for (ECB ecBlock : ecbArray) {
57 total += ecBlock.getCount() * (ecBlock.getDataCodewords() + ecCodewords);
59 this.totalCodewords = total;
62 public int getVersionNumber() {
66 public int getSymbolSizeRows() {
67 return symbolSizeRows;
70 public int getSymbolSizeColumns() {
71 return symbolSizeColumns;
74 public int getDataRegionSizeRows() {
75 return dataRegionSizeRows;
78 public int getDataRegionSizeColumns() {
79 return dataRegionSizeColumns;
82 public int getTotalCodewords() {
83 return totalCodewords;
86 ECBlocks getECBlocks() {
91 * <p>Deduces version information from Data Matrix dimensions.</p>
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
98 public static Version getVersionForDimensions(int numRows, int numColumns) throws FormatException {
99 if ((numRows & 0x01) != 0 || (numColumns & 0x01) != 0) {
100 throw FormatException.getFormatInstance();
103 for (Version version : VERSIONS) {
104 if (version.symbolSizeRows == numRows && version.symbolSizeColumns == numColumns) {
109 throw FormatException.getFormatInstance();
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>
118 static final class ECBlocks {
119 private final int ecCodewords;
120 private final ECB[] ecBlocks;
122 private ECBlocks(int ecCodewords, ECB ecBlocks) {
123 this.ecCodewords = ecCodewords;
124 this.ecBlocks = new ECB[] { ecBlocks };
127 private ECBlocks(int ecCodewords, ECB ecBlocks1, ECB ecBlocks2) {
128 this.ecCodewords = ecCodewords;
129 this.ecBlocks = new ECB[] { ecBlocks1, ecBlocks2 };
132 int getECCodewords() {
136 ECB[] getECBlocks() {
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>
146 static final class ECB {
147 private final int count;
148 private final int dataCodewords;
150 private ECB(int count, int dataCodewords) {
152 this.dataCodewords = dataCodewords;
159 int getDataCodewords() {
160 return dataCodewords;
165 public String toString() {
166 return String.valueOf(versionNumber);
170 * See ISO 16022:2006 5.5.1 Table 7
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)))