2 * Copyright 2007 Google Inc.
\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.ReaderException;
\r
20 import com.google.zxing.common.BitMatrix;
\r
23 * The Version object encapsulates attributes about a particular
\r
24 * size Data Matrix Code.
\r
26 * @author bbrown@google.com (Brian Brown)
\r
28 public final class Version {
\r
30 private static final Version[] VERSIONS = buildVersions();
\r
32 private final int versionNumber;
\r
33 private final int symbolSizeRows;
\r
34 private final int symbolSizeColumns;
\r
35 private final int dataRegionSizeRows;
\r
36 private final int dataRegionSizeColumns;
\r
37 private final ECBlocks ecBlocks;
\r
38 private final int totalCodewords;
\r
40 private Version(int versionNumber,
\r
42 int symbolSizeColumns,
\r
43 int dataRegionSizeRows,
\r
44 int dataRegionSizeColumns,
\r
45 ECBlocks ecBlocks) {
\r
46 this.versionNumber = versionNumber;
\r
47 this.symbolSizeRows = symbolSizeRows;
\r
48 this.symbolSizeColumns = symbolSizeColumns;
\r
49 this.dataRegionSizeRows = dataRegionSizeRows;
\r
50 this.dataRegionSizeColumns = dataRegionSizeColumns;
\r
51 this.ecBlocks = ecBlocks;
\r
53 // Calculate the total number of codewords
\r
55 int ecCodewords = ecBlocks.ecCodewords;
\r
56 ECB[] ecbArray = ecBlocks.ecBlocks;
\r
57 for (int i = 0; i < ecbArray.length; i++) {
\r
58 ECB ecBlock = ecbArray[i];
\r
59 total += ecBlock.count * (ecBlock.dataCodewords + ecCodewords);
\r
61 this.totalCodewords = total;
\r
64 public int getVersionNumber() {
\r
65 return versionNumber;
\r
68 public int getSymbolSizeRows() {
\r
69 return symbolSizeRows;
\r
72 public int getSymbolSizeColumns() {
\r
73 return symbolSizeColumns;
\r
76 public int getDataRegionSizeRows() {
\r
77 return dataRegionSizeRows;
\r
80 public int getDataRegionSizeColumns() {
\r
81 return dataRegionSizeColumns;
\r
84 public int getTotalCodewords() {
\r
85 return totalCodewords;
\r
88 ECBlocks getECBlocks() {
\r
93 * <p>Deduces version information from Data Matrix dimensions.</p>
\r
95 * @param numRows Number of rows in modules
\r
96 * @param numRows Number of columns in modules
\r
97 * @return {@link Version} for a Data Matrix Code of those dimensions
\r
98 * @throws ReaderException if dimensions do correspond to a valid Data Matrix size
\r
100 public static Version getVersionForDimensions(int numRows, int numColumns) throws ReaderException {
\r
101 if ((numRows & 0x01) != 0 || (numColumns & 0x01) != 0) {
\r
102 throw new ReaderException("Dimension must be 0 mod 2");
\r
105 // TODO(bbrown): This is doing a linear search through the array of versions.
\r
106 // If we interleave the rectangular versions with the square versions we could
\r
107 // do a binary search.
\r
108 int numVersions = VERSIONS.length;
\r
109 for (int i = 0; i < numVersions; ++i){
\r
110 Version version = VERSIONS[i];
\r
111 if (version.symbolSizeRows == numRows) {
\r
112 if (version.symbolSizeColumns == numColumns) {
\r
118 throw new ReaderException("Dimensions do not correspond to a valid Data Matrix Version.");
\r
122 * <p>Encapsulates a set of error-correction blocks in one symbol version. Most versions will
\r
123 * use blocks of differing sizes within one version, so, this encapsulates the parameters for
\r
124 * each set of blocks. It also holds the number of error-correction codewords per block since it
\r
125 * will be the same across all blocks within one version.</p>
\r
127 static final class ECBlocks {
\r
128 private int ecCodewords;
\r
129 private ECB[] ecBlocks;
\r
131 private ECBlocks(int ecCodewords, ECB ecBlocks) {
\r
132 this.ecCodewords = ecCodewords;
\r
133 this.ecBlocks = new ECB[] { ecBlocks };
\r
136 private ECBlocks(int ecCodewords, ECB ecBlocks1, ECB ecBlocks2) {
\r
137 this.ecCodewords = ecCodewords;
\r
138 this.ecBlocks = new ECB[] { ecBlocks1, ecBlocks2 };
\r
141 int getECCodewords() {
\r
142 return ecCodewords;
\r
145 ECB[] getECBlocks() {
\r
151 * <p>Encapsualtes the parameters for one error-correction block in one symbol version.
\r
152 * This includes the number of data codewords, and the number of times a block with these
\r
153 * parameters is used consecutively in the Data Matrix code version's format.</p>
\r
155 static final class ECB {
\r
157 private int dataCodewords;
\r
159 private ECB(int count, int dataCodewords) {
\r
160 this.count = count;
\r
161 this.dataCodewords = dataCodewords;
\r
168 int getDataCodewords() {
\r
169 return dataCodewords;
\r
173 public String toString() {
\r
174 return String.valueOf(versionNumber);
\r
178 * See ISO 16022:2006 5.5.1 Table 7
\r
180 private static Version[] buildVersions() {
\r
181 return new Version[]{
\r
182 new Version(1, 10, 10, 8, 8,
\r
183 new ECBlocks(5, new ECB(1, 3))),
\r
184 new Version(2, 12, 12, 10, 10,
\r
185 new ECBlocks(7, new ECB(1, 5))),
\r
186 new Version(3, 14, 14, 12, 12,
\r
187 new ECBlocks(10, new ECB(1, 8))),
\r
188 new Version(4, 16, 16, 14, 14,
\r
189 new ECBlocks(12, new ECB(1, 12))),
\r
190 new Version(5, 18, 18, 16, 16,
\r
191 new ECBlocks(14, new ECB(1, 18))),
\r
192 new Version(6, 20, 20, 18, 18,
\r
193 new ECBlocks(18, new ECB(1, 22))),
\r
194 new Version(7, 22, 22, 20, 20,
\r
195 new ECBlocks(20, new ECB(1, 30))),
\r
196 new Version(8, 24, 24, 22, 22,
\r
197 new ECBlocks(24, new ECB(1, 36))),
\r
198 new Version(9, 26, 26, 24, 24,
\r
199 new ECBlocks(28, new ECB(1, 44))),
\r
200 new Version(10, 32, 32, 14, 14,
\r
201 new ECBlocks(36, new ECB(1, 62))),
\r
202 new Version(11, 36, 36, 16, 16,
\r
203 new ECBlocks(42, new ECB(1, 86))),
\r
204 new Version(12, 40, 40, 18, 18,
\r
205 new ECBlocks(48, new ECB(1, 114))),
\r
206 new Version(13, 44, 44, 20, 20,
\r
207 new ECBlocks(56, new ECB(1, 144))),
\r
208 new Version(14, 48, 48, 22, 22,
\r
209 new ECBlocks(68, new ECB(1, 174))),
\r
210 new Version(15, 52, 52, 24, 24,
\r
211 new ECBlocks(42, new ECB(2, 102))),
\r
212 new Version(16, 64, 64, 14, 14,
\r
213 new ECBlocks(56, new ECB(2, 140))),
\r
214 new Version(17, 72, 72, 16, 16,
\r
215 new ECBlocks(36, new ECB(4, 92))),
\r
216 new Version(18, 80, 80, 18, 18,
\r
217 new ECBlocks(48, new ECB(4, 114))),
\r
218 new Version(19, 88, 88, 20, 20,
\r
219 new ECBlocks(56, new ECB(4, 144))),
\r
220 new Version(20, 96, 96, 22, 22,
\r
221 new ECBlocks(68, new ECB(4, 174))),
\r
222 new Version(21, 104, 104, 24, 24,
\r
223 new ECBlocks(56, new ECB(6, 136))),
\r
224 new Version(22, 120, 120, 18, 18,
\r
225 new ECBlocks(68, new ECB(6, 175))),
\r
226 new Version(23, 132, 132, 20, 20,
\r
227 new ECBlocks(62, new ECB(8, 163))),
\r
228 new Version(24, 144, 144, 22, 22,
\r
229 new ECBlocks(62, new ECB(8, 156), new ECB(2, 155))),
\r
230 new Version(25, 8, 18, 6, 16,
\r
231 new ECBlocks(7, new ECB(1, 5))),
\r
232 new Version(26, 8, 32, 6, 14,
\r
233 new ECBlocks(11, new ECB(1, 10))),
\r
234 new Version(27, 12, 26, 10, 24,
\r
235 new ECBlocks(14, new ECB(1, 16))),
\r
236 new Version(28, 12, 36, 10, 16,
\r
237 new ECBlocks(18, new ECB(1, 22))),
\r
238 new Version(29, 16, 36, 10, 16,
\r
239 new ECBlocks(24, new ECB(1, 32))),
\r
240 new Version(30, 16, 48, 14, 22,
\r
241 new ECBlocks(28, new ECB(1, 49)))
\r