• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright 2006 Jeremias Maerki
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.encoder;
18 
19 import com.google.zxing.Dimension;
20 
21 /**
22  * Symbol info table for DataMatrix.
23  *
24  * @version $Id$
25  */
26 public class SymbolInfo {
27 
28   static final SymbolInfo[] PROD_SYMBOLS = {
29     new SymbolInfo(false, 3, 5, 8, 8, 1),
30     new SymbolInfo(false, 5, 7, 10, 10, 1),
31       /*rect*/new SymbolInfo(true, 5, 7, 16, 6, 1),
32     new SymbolInfo(false, 8, 10, 12, 12, 1),
33       /*rect*/new SymbolInfo(true, 10, 11, 14, 6, 2),
34     new SymbolInfo(false, 12, 12, 14, 14, 1),
35       /*rect*/new SymbolInfo(true, 16, 14, 24, 10, 1),
36 
37     new SymbolInfo(false, 18, 14, 16, 16, 1),
38     new SymbolInfo(false, 22, 18, 18, 18, 1),
39       /*rect*/new SymbolInfo(true, 22, 18, 16, 10, 2),
40     new SymbolInfo(false, 30, 20, 20, 20, 1),
41       /*rect*/new SymbolInfo(true, 32, 24, 16, 14, 2),
42     new SymbolInfo(false, 36, 24, 22, 22, 1),
43     new SymbolInfo(false, 44, 28, 24, 24, 1),
44       /*rect*/new SymbolInfo(true, 49, 28, 22, 14, 2),
45 
46     new SymbolInfo(false, 62, 36, 14, 14, 4),
47     new SymbolInfo(false, 86, 42, 16, 16, 4),
48     new SymbolInfo(false, 114, 48, 18, 18, 4),
49     new SymbolInfo(false, 144, 56, 20, 20, 4),
50     new SymbolInfo(false, 174, 68, 22, 22, 4),
51 
52     new SymbolInfo(false, 204, 84, 24, 24, 4, 102, 42),
53     new SymbolInfo(false, 280, 112, 14, 14, 16, 140, 56),
54     new SymbolInfo(false, 368, 144, 16, 16, 16, 92, 36),
55     new SymbolInfo(false, 456, 192, 18, 18, 16, 114, 48),
56     new SymbolInfo(false, 576, 224, 20, 20, 16, 144, 56),
57     new SymbolInfo(false, 696, 272, 22, 22, 16, 174, 68),
58     new SymbolInfo(false, 816, 336, 24, 24, 16, 136, 56),
59     new SymbolInfo(false, 1050, 408, 18, 18, 36, 175, 68),
60     new SymbolInfo(false, 1304, 496, 20, 20, 36, 163, 62),
61     new DataMatrixSymbolInfo144(),
62   };
63 
64   private static SymbolInfo[] symbols = PROD_SYMBOLS;
65 
66   private final boolean rectangular;
67   private final int dataCapacity;
68   private final int errorCodewords;
69   public final int matrixWidth;
70   public final int matrixHeight;
71   private final int dataRegions;
72   private final int rsBlockData;
73   private final int rsBlockError;
74 
75   /**
76    * Overrides the symbol info set used by this class. Used for testing purposes.
77    *
78    * @param override the symbol info set to use
79    */
overrideSymbolSet(SymbolInfo[] override)80   public static void overrideSymbolSet(SymbolInfo[] override) {
81     symbols = override;
82   }
83 
SymbolInfo(boolean rectangular, int dataCapacity, int errorCodewords, int matrixWidth, int matrixHeight, int dataRegions)84   public SymbolInfo(boolean rectangular, int dataCapacity, int errorCodewords,
85                     int matrixWidth, int matrixHeight, int dataRegions) {
86     this(rectangular, dataCapacity, errorCodewords, matrixWidth, matrixHeight, dataRegions,
87          dataCapacity, errorCodewords);
88   }
89 
SymbolInfo(boolean rectangular, int dataCapacity, int errorCodewords, int matrixWidth, int matrixHeight, int dataRegions, int rsBlockData, int rsBlockError)90   SymbolInfo(boolean rectangular, int dataCapacity, int errorCodewords,
91              int matrixWidth, int matrixHeight, int dataRegions,
92              int rsBlockData, int rsBlockError) {
93     this.rectangular = rectangular;
94     this.dataCapacity = dataCapacity;
95     this.errorCodewords = errorCodewords;
96     this.matrixWidth = matrixWidth;
97     this.matrixHeight = matrixHeight;
98     this.dataRegions = dataRegions;
99     this.rsBlockData = rsBlockData;
100     this.rsBlockError = rsBlockError;
101   }
102 
lookup(int dataCodewords)103   public static SymbolInfo lookup(int dataCodewords) {
104     return lookup(dataCodewords, SymbolShapeHint.FORCE_NONE, true);
105   }
106 
lookup(int dataCodewords, SymbolShapeHint shape)107   public static SymbolInfo lookup(int dataCodewords, SymbolShapeHint shape) {
108     return lookup(dataCodewords, shape, true);
109   }
110 
lookup(int dataCodewords, boolean allowRectangular, boolean fail)111   public static SymbolInfo lookup(int dataCodewords, boolean allowRectangular, boolean fail) {
112     SymbolShapeHint shape = allowRectangular
113         ? SymbolShapeHint.FORCE_NONE : SymbolShapeHint.FORCE_SQUARE;
114     return lookup(dataCodewords, shape, fail);
115   }
116 
lookup(int dataCodewords, SymbolShapeHint shape, boolean fail)117   private static SymbolInfo lookup(int dataCodewords, SymbolShapeHint shape, boolean fail) {
118     return lookup(dataCodewords, shape, null, null, fail);
119   }
120 
lookup(int dataCodewords, SymbolShapeHint shape, Dimension minSize, Dimension maxSize, boolean fail)121   public static SymbolInfo lookup(int dataCodewords,
122                                   SymbolShapeHint shape,
123                                   Dimension minSize,
124                                   Dimension maxSize,
125                                   boolean fail) {
126     for (SymbolInfo symbol : symbols) {
127       if (shape == SymbolShapeHint.FORCE_SQUARE && symbol.rectangular) {
128         continue;
129       }
130       if (shape == SymbolShapeHint.FORCE_RECTANGLE && !symbol.rectangular) {
131         continue;
132       }
133       if (minSize != null
134           && (symbol.getSymbolWidth() < minSize.getWidth()
135           || symbol.getSymbolHeight() < minSize.getHeight())) {
136         continue;
137       }
138       if (maxSize != null
139           && (symbol.getSymbolWidth() > maxSize.getWidth()
140           || symbol.getSymbolHeight() > maxSize.getHeight())) {
141         continue;
142       }
143       if (dataCodewords <= symbol.dataCapacity) {
144         return symbol;
145       }
146     }
147     if (fail) {
148       throw new IllegalArgumentException(
149           "Can't find a symbol arrangement that matches the message. Data codewords: "
150               + dataCodewords);
151     }
152     return null;
153   }
154 
getHorizontalDataRegions()155   private int getHorizontalDataRegions() {
156     switch (dataRegions) {
157       case 1:
158         return 1;
159       case 2:
160       case 4:
161         return 2;
162       case 16:
163         return 4;
164       case 36:
165         return 6;
166       default:
167         throw new IllegalStateException("Cannot handle this number of data regions");
168     }
169   }
170 
getVerticalDataRegions()171   private int getVerticalDataRegions() {
172     switch (dataRegions) {
173       case 1:
174       case 2:
175         return 1;
176       case 4:
177         return 2;
178       case 16:
179         return 4;
180       case 36:
181         return 6;
182       default:
183         throw new IllegalStateException("Cannot handle this number of data regions");
184     }
185   }
186 
getSymbolDataWidth()187   public final int getSymbolDataWidth() {
188     return getHorizontalDataRegions() * matrixWidth;
189   }
190 
getSymbolDataHeight()191   public final int getSymbolDataHeight() {
192     return getVerticalDataRegions() * matrixHeight;
193   }
194 
getSymbolWidth()195   public final int getSymbolWidth() {
196     return getSymbolDataWidth() + (getHorizontalDataRegions() * 2);
197   }
198 
getSymbolHeight()199   public final int getSymbolHeight() {
200     return getSymbolDataHeight() + (getVerticalDataRegions() * 2);
201   }
202 
getCodewordCount()203   public int getCodewordCount() {
204     return dataCapacity + errorCodewords;
205   }
206 
getInterleavedBlockCount()207   public int getInterleavedBlockCount() {
208     return dataCapacity / rsBlockData;
209   }
210 
getDataCapacity()211   public final int getDataCapacity() {
212     return dataCapacity;
213   }
214 
getErrorCodewords()215   public final int getErrorCodewords() {
216     return errorCodewords;
217   }
218 
getDataLengthForInterleavedBlock(int index)219   public int getDataLengthForInterleavedBlock(int index) {
220     return rsBlockData;
221   }
222 
getErrorLengthForInterleavedBlock(int index)223   public final int getErrorLengthForInterleavedBlock(int index) {
224     return rsBlockError;
225   }
226 
227   @Override
toString()228   public final String toString() {
229     return (rectangular ? "Rectangular Symbol:" : "Square Symbol:") +
230         " data region " + matrixWidth + 'x' + matrixHeight +
231         ", symbol size " + getSymbolWidth() + 'x' + getSymbolHeight() +
232         ", symbol data size " + getSymbolDataWidth() + 'x' + getSymbolDataHeight() +
233         ", codewords " + dataCapacity + '+' + errorCodewords;
234   }
235 
236 }
237