1 /**
2 * libdmtx - Data Matrix Encoding/Decoding Library
3 * Copyright 2008, 2009 Mike Laughton. All rights reserved.
4 * Copyright 2012-2016 Vadim A. Misbakh-Soloviov. All rights reserved.
5 * Copyright 2016 Tim Zaman. All rights reserved.
6 *
7 * See LICENSE file in the main project directory for full
8 * terms of use and distribution.
9 *
10 * Contact:
11 * Vadim A. Misbakh-Soloviov <dmtx@mva.name>
12 * Mike Laughton <mike@dragonflylogic.com>
13 *
14 * \file dmtxsymbol.c
15 * \brief Data Matrix symbol attributes
16 */
17
18
19 /**
20 * \brief Retrieve symbol index from rows and columns
21 * \param rows
22 * \param cols
23 * \return sizeIdx value
24 */
25 extern int
getSizeIdxFromSymbolDimension(int rows,int cols)26 getSizeIdxFromSymbolDimension(int rows, int cols)
27 {
28 int symbolRows, symbolCols;
29 for (int i=0; i<30; i++){
30 symbolRows = dmtxGetSymbolAttribute(DmtxSymAttribSymbolRows, i);
31 symbolCols = dmtxGetSymbolAttribute(DmtxSymAttribSymbolCols, i);
32 if (rows==symbolRows && cols==symbolCols){
33 return i;
34 }
35 }
36 return -1;
37 }
38
39
40 /**
41 * \brief Retrieve property based on symbol size
42 * \param attribute
43 * \param sizeIdx
44 * \return Attribute value
45 */
46 extern int
dmtxGetSymbolAttribute(int attribute,int sizeIdx)47 dmtxGetSymbolAttribute(int attribute, int sizeIdx)
48 {
49 static const int symbolRows[] = { 10, 12, 14, 16, 18, 20, 22, 24, 26,
50 32, 36, 40, 44, 48, 52,
51 64, 72, 80, 88, 96, 104,
52 120, 132, 144,
53 8, 8, 12, 12, 16, 16 };
54
55 static const int symbolCols[] = { 10, 12, 14, 16, 18, 20, 22, 24, 26,
56 32, 36, 40, 44, 48, 52,
57 64, 72, 80, 88, 96, 104,
58 120, 132, 144,
59 18, 32, 26, 36, 36, 48 };
60
61 static const int dataRegionRows[] = { 8, 10, 12, 14, 16, 18, 20, 22, 24,
62 14, 16, 18, 20, 22, 24,
63 14, 16, 18, 20, 22, 24,
64 18, 20, 22,
65 6, 6, 10, 10, 14, 14 };
66
67 static const int dataRegionCols[] = { 8, 10, 12, 14, 16, 18, 20, 22, 24,
68 14, 16, 18, 20, 22, 24,
69 14, 16, 18, 20, 22, 24,
70 18, 20, 22,
71 16, 14, 24, 16, 16, 22 };
72
73 static const int horizDataRegions[] = { 1, 1, 1, 1, 1, 1, 1, 1, 1,
74 2, 2, 2, 2, 2, 2,
75 4, 4, 4, 4, 4, 4,
76 6, 6, 6,
77 1, 2, 1, 2, 2, 2 };
78
79 static const int interleavedBlocks[] = { 1, 1, 1, 1, 1, 1, 1, 1, 1,
80 1, 1, 1, 1, 1, 2,
81 2, 4, 4, 4, 4, 6,
82 6, 8, 10,
83 1, 1, 1, 1, 1, 1 };
84
85 static const int symbolDataWords[] = { 3, 5, 8, 12, 18, 22, 30, 36, 44,
86 62, 86, 114, 144, 174, 204,
87 280, 368, 456, 576, 696, 816,
88 1050, 1304, 1558,
89 5, 10, 16, 22, 32, 49 };
90
91 static const int blockErrorWords[] = { 5, 7, 10, 12, 14, 18, 20, 24, 28,
92 36, 42, 48, 56, 68, 42,
93 56, 36, 48, 56, 68, 56,
94 68, 62, 62,
95 7, 11, 14, 18, 24, 28 };
96
97 static const int blockMaxCorrectable[] = { 2, 3, 5, 6, 7, 9, 10, 12, 14,
98 18, 21, 24, 28, 34, 21,
99 28, 18, 24, 28, 34, 28,
100 34, 31, 31,
101 3, 5, 7, 9, 12, 14 };
102
103 if(sizeIdx < 0 || sizeIdx >= DmtxSymbolSquareCount + DmtxSymbolRectCount)
104 return DmtxUndefined;
105
106 switch(attribute) {
107 case DmtxSymAttribSymbolRows:
108 return symbolRows[sizeIdx];
109 case DmtxSymAttribSymbolCols:
110 return symbolCols[sizeIdx];
111 case DmtxSymAttribDataRegionRows:
112 return dataRegionRows[sizeIdx];
113 case DmtxSymAttribDataRegionCols:
114 return dataRegionCols[sizeIdx];
115 case DmtxSymAttribHorizDataRegions:
116 return horizDataRegions[sizeIdx];
117 case DmtxSymAttribVertDataRegions:
118 return (sizeIdx < DmtxSymbolSquareCount) ? horizDataRegions[sizeIdx] : 1;
119 case DmtxSymAttribMappingMatrixRows:
120 return dataRegionRows[sizeIdx] *
121 dmtxGetSymbolAttribute(DmtxSymAttribVertDataRegions, sizeIdx);
122 case DmtxSymAttribMappingMatrixCols:
123 return dataRegionCols[sizeIdx] * horizDataRegions[sizeIdx];
124 case DmtxSymAttribInterleavedBlocks:
125 return interleavedBlocks[sizeIdx];
126 case DmtxSymAttribBlockErrorWords:
127 return blockErrorWords[sizeIdx];
128 case DmtxSymAttribBlockMaxCorrectable:
129 return blockMaxCorrectable[sizeIdx];
130 case DmtxSymAttribSymbolDataWords:
131 return symbolDataWords[sizeIdx];
132 case DmtxSymAttribSymbolErrorWords:
133 return blockErrorWords[sizeIdx] * interleavedBlocks[sizeIdx];
134 case DmtxSymAttribSymbolMaxCorrectable:
135 return blockMaxCorrectable[sizeIdx] * interleavedBlocks[sizeIdx];
136 }
137
138 return DmtxUndefined;
139 }
140
141 /**
142 * \brief Retrieve data size for a specific symbol size and block number
143 * \param sizeIdx
144 * \param blockIdx
145 * \return Attribute value
146 */
147 extern int
dmtxGetBlockDataSize(int sizeIdx,int blockIdx)148 dmtxGetBlockDataSize(int sizeIdx, int blockIdx)
149 {
150 int symbolDataWords;
151 int interleavedBlocks;
152 int count;
153
154 symbolDataWords = dmtxGetSymbolAttribute(DmtxSymAttribSymbolDataWords, sizeIdx);
155 interleavedBlocks = dmtxGetSymbolAttribute(DmtxSymAttribInterleavedBlocks, sizeIdx);
156
157 if(symbolDataWords < 1 || interleavedBlocks < 1)
158 return DmtxUndefined;
159
160 count = (int)(symbolDataWords/interleavedBlocks);
161
162 return (sizeIdx == DmtxSymbol144x144 && blockIdx < 8) ? count + 1 : count;
163 }
164
165 /**
166 * \brief Determine symbol size based on data size and requested properties
167 * \param dataWords
168 * \param sizeIdxRequest
169 * \return Symbol size index (or DmtxUndefined if none)
170 */
171 static int
FindSymbolSize(int dataWords,int sizeIdxRequest)172 FindSymbolSize(int dataWords, int sizeIdxRequest)
173 {
174 int sizeIdx;
175 int idxBeg, idxEnd;
176
177 if(dataWords <= 0)
178 return DmtxUndefined;
179
180 if(sizeIdxRequest == DmtxSymbolSquareAuto || sizeIdxRequest == DmtxSymbolRectAuto) {
181
182 if(sizeIdxRequest == DmtxSymbolSquareAuto) {
183 idxBeg = 0;
184 idxEnd = DmtxSymbolSquareCount;
185 }
186 else {
187 idxBeg = DmtxSymbolSquareCount;
188 idxEnd = DmtxSymbolSquareCount + DmtxSymbolRectCount;
189 }
190
191 for(sizeIdx = idxBeg; sizeIdx < idxEnd; sizeIdx++) {
192 if(dmtxGetSymbolAttribute(DmtxSymAttribSymbolDataWords, sizeIdx) >= dataWords)
193 break;
194 }
195
196 if(sizeIdx == idxEnd)
197 return DmtxUndefined;
198 }
199 else {
200 sizeIdx = sizeIdxRequest;
201 }
202
203 if(dataWords > dmtxGetSymbolAttribute(DmtxSymAttribSymbolDataWords, sizeIdx))
204 return DmtxUndefined;
205
206 return sizeIdx;
207 }
208