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