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 *
6 * See LICENSE file in the main project directory for full
7 * terms of use and distribution.
8 *
9 * Contact:
10 * Vadim A. Misbakh-Soloviov <dmtx@mva.name>
11 * Mike Laughton <mike@dragonflylogic.com>
12 *
13 * \file dmtxplacemod.c
14 * \brief Data Matrix module placement
15 */
16
17 /**
18 * receives symbol row and col and returns status
19 * DmtxModuleOn / !DmtxModuleOn (DmtxModuleOff)
20 * DmtxModuleAssigned
21 * DmtxModuleVisited
22 * DmtxModuleData / !DmtxModuleData (DmtxModuleAlignment)
23 * row and col are expressed in symbol coordinates, so (0,0) is the intersection of the "L"
24 */
25 int
dmtxSymbolModuleStatus(DmtxMessage * message,int sizeIdx,int symbolRow,int symbolCol)26 dmtxSymbolModuleStatus(DmtxMessage *message, int sizeIdx, int symbolRow, int symbolCol)
27 {
28 int symbolRowReverse;
29 int mappingRow, mappingCol;
30 int dataRegionRows, dataRegionCols;
31 int symbolRows, mappingCols;
32
33 dataRegionRows = dmtxGetSymbolAttribute(DmtxSymAttribDataRegionRows, sizeIdx);
34 dataRegionCols = dmtxGetSymbolAttribute(DmtxSymAttribDataRegionCols, sizeIdx);
35 symbolRows = dmtxGetSymbolAttribute(DmtxSymAttribSymbolRows, sizeIdx);
36 mappingCols = dmtxGetSymbolAttribute(DmtxSymAttribMappingMatrixCols, sizeIdx);
37
38 symbolRowReverse = symbolRows - symbolRow - 1;
39 mappingRow = symbolRowReverse - 1 - 2 * (symbolRowReverse / (dataRegionRows+2));
40 mappingCol = symbolCol - 1 - 2 * (symbolCol / (dataRegionCols+2));
41
42 /* Solid portion of alignment patterns */
43 if(symbolRow % (dataRegionRows+2) == 0 ||
44 symbolCol % (dataRegionCols+2) == 0)
45 return (DmtxModuleOnRGB | (!DmtxModuleData));
46
47 /* Horinzontal calibration bars */
48 if((symbolRow+1) % (dataRegionRows+2) == 0)
49 return (((symbolCol & 0x01) ? 0 : DmtxModuleOnRGB) | (!DmtxModuleData));
50
51 /* Vertical calibration bars */
52 if((symbolCol+1) % (dataRegionCols+2) == 0)
53 return (((symbolRow & 0x01) ? 0 : DmtxModuleOnRGB) | (!DmtxModuleData));
54
55 /* Data modules */
56 return (message->array[mappingRow * mappingCols + mappingCol] | DmtxModuleData);
57 }
58
59 /**
60 * \brief Logical relationship between bit and module locations
61 * \param modules
62 * \param codewords
63 * \param sizeIdx
64 * \param moduleOnColor
65 * \return Number of codewords read
66 */
67 static int
ModulePlacementEcc200(unsigned char * modules,unsigned char * codewords,int sizeIdx,int moduleOnColor)68 ModulePlacementEcc200(unsigned char *modules, unsigned char *codewords, int sizeIdx, int moduleOnColor)
69 {
70 int row, col, chr;
71 int mappingRows, mappingCols;
72
73 assert(moduleOnColor & (DmtxModuleOnRed | DmtxModuleOnGreen | DmtxModuleOnBlue));
74
75 mappingRows = dmtxGetSymbolAttribute(DmtxSymAttribMappingMatrixRows, sizeIdx);
76 mappingCols = dmtxGetSymbolAttribute(DmtxSymAttribMappingMatrixCols, sizeIdx);
77
78 /* Start in the nominal location for the 8th bit of the first character */
79 chr = 0;
80 row = 4;
81 col = 0;
82
83 do {
84 /* Repeatedly first check for one of the special corner cases */
85 if((row == mappingRows) && (col == 0))
86 PatternShapeSpecial1(modules, mappingRows, mappingCols, &(codewords[chr++]), moduleOnColor);
87 else if((row == mappingRows-2) && (col == 0) && (mappingCols%4 != 0))
88 PatternShapeSpecial2(modules, mappingRows, mappingCols, &(codewords[chr++]), moduleOnColor);
89 else if((row == mappingRows-2) && (col == 0) && (mappingCols%8 == 4))
90 PatternShapeSpecial3(modules, mappingRows, mappingCols, &(codewords[chr++]), moduleOnColor);
91 else if((row == mappingRows+4) && (col == 2) && (mappingCols%8 == 0))
92 PatternShapeSpecial4(modules, mappingRows, mappingCols, &(codewords[chr++]), moduleOnColor);
93
94 /* Sweep upward diagonally, inserting successive characters */
95 do {
96 if((row < mappingRows) && (col >= 0) &&
97 !(modules[row*mappingCols+col] & DmtxModuleVisited))
98 PatternShapeStandard(modules, mappingRows, mappingCols, row, col, &(codewords[chr++]), moduleOnColor);
99 row -= 2;
100 col += 2;
101 } while ((row >= 0) && (col < mappingCols));
102 row += 1;
103 col += 3;
104
105 /* Sweep downward diagonally, inserting successive characters */
106 do {
107 if((row >= 0) && (col < mappingCols) &&
108 !(modules[row*mappingCols+col] & DmtxModuleVisited))
109 PatternShapeStandard(modules, mappingRows, mappingCols, row, col, &(codewords[chr++]), moduleOnColor);
110 row += 2;
111 col -= 2;
112 } while ((row < mappingRows) && (col >= 0));
113 row += 3;
114 col += 1;
115 /* ... until the entire modules array is scanned */
116 } while ((row < mappingRows) || (col < mappingCols));
117
118 /* If lower righthand corner is untouched then fill in the fixed pattern */
119 if(!(modules[mappingRows * mappingCols - 1] &
120 DmtxModuleVisited)) {
121
122 modules[mappingRows * mappingCols - 1] |= moduleOnColor;
123 modules[(mappingRows * mappingCols) - mappingCols - 2] |= moduleOnColor;
124 } /* XXX should this fixed pattern also be used in reading somehow? */
125
126 /* XXX compare that chr == region->dataSize here */
127 return chr; /* XXX number of codewords read off */
128 }
129
130 /**
131 * \brief XXX
132 * \param modules
133 * \param mappingRows
134 * \param mappingCols
135 * \param row
136 * \param col
137 * \param codeword
138 * \param moduleOnColor
139 * \return void
140 */
141 static void
PatternShapeStandard(unsigned char * modules,int mappingRows,int mappingCols,int row,int col,unsigned char * codeword,int moduleOnColor)142 PatternShapeStandard(unsigned char *modules, int mappingRows, int mappingCols, int row, int col, unsigned char *codeword, int moduleOnColor)
143 {
144 PlaceModule(modules, mappingRows, mappingCols, row-2, col-2, codeword, DmtxMaskBit1, moduleOnColor);
145 PlaceModule(modules, mappingRows, mappingCols, row-2, col-1, codeword, DmtxMaskBit2, moduleOnColor);
146 PlaceModule(modules, mappingRows, mappingCols, row-1, col-2, codeword, DmtxMaskBit3, moduleOnColor);
147 PlaceModule(modules, mappingRows, mappingCols, row-1, col-1, codeword, DmtxMaskBit4, moduleOnColor);
148 PlaceModule(modules, mappingRows, mappingCols, row-1, col, codeword, DmtxMaskBit5, moduleOnColor);
149 PlaceModule(modules, mappingRows, mappingCols, row, col-2, codeword, DmtxMaskBit6, moduleOnColor);
150 PlaceModule(modules, mappingRows, mappingCols, row, col-1, codeword, DmtxMaskBit7, moduleOnColor);
151 PlaceModule(modules, mappingRows, mappingCols, row, col, codeword, DmtxMaskBit8, moduleOnColor);
152 }
153
154 /**
155 * \brief XXX
156 * \param modules
157 * \param mappingRows
158 * \param mappingCols
159 * \param codeword
160 * \param moduleOnColor
161 * \return void
162 */
163 static void
PatternShapeSpecial1(unsigned char * modules,int mappingRows,int mappingCols,unsigned char * codeword,int moduleOnColor)164 PatternShapeSpecial1(unsigned char *modules, int mappingRows, int mappingCols, unsigned char *codeword, int moduleOnColor)
165 {
166 PlaceModule(modules, mappingRows, mappingCols, mappingRows-1, 0, codeword, DmtxMaskBit1, moduleOnColor);
167 PlaceModule(modules, mappingRows, mappingCols, mappingRows-1, 1, codeword, DmtxMaskBit2, moduleOnColor);
168 PlaceModule(modules, mappingRows, mappingCols, mappingRows-1, 2, codeword, DmtxMaskBit3, moduleOnColor);
169 PlaceModule(modules, mappingRows, mappingCols, 0, mappingCols-2, codeword, DmtxMaskBit4, moduleOnColor);
170 PlaceModule(modules, mappingRows, mappingCols, 0, mappingCols-1, codeword, DmtxMaskBit5, moduleOnColor);
171 PlaceModule(modules, mappingRows, mappingCols, 1, mappingCols-1, codeword, DmtxMaskBit6, moduleOnColor);
172 PlaceModule(modules, mappingRows, mappingCols, 2, mappingCols-1, codeword, DmtxMaskBit7, moduleOnColor);
173 PlaceModule(modules, mappingRows, mappingCols, 3, mappingCols-1, codeword, DmtxMaskBit8, moduleOnColor);
174 }
175
176 /**
177 * \brief XXX
178 * \param modules
179 * \param mappingRows
180 * \param mappingCols
181 * \param codeword
182 * \param moduleOnColor
183 * \return void
184 */
185 static void
PatternShapeSpecial2(unsigned char * modules,int mappingRows,int mappingCols,unsigned char * codeword,int moduleOnColor)186 PatternShapeSpecial2(unsigned char *modules, int mappingRows, int mappingCols, unsigned char *codeword, int moduleOnColor)
187 {
188 PlaceModule(modules, mappingRows, mappingCols, mappingRows-3, 0, codeword, DmtxMaskBit1, moduleOnColor);
189 PlaceModule(modules, mappingRows, mappingCols, mappingRows-2, 0, codeword, DmtxMaskBit2, moduleOnColor);
190 PlaceModule(modules, mappingRows, mappingCols, mappingRows-1, 0, codeword, DmtxMaskBit3, moduleOnColor);
191 PlaceModule(modules, mappingRows, mappingCols, 0, mappingCols-4, codeword, DmtxMaskBit4, moduleOnColor);
192 PlaceModule(modules, mappingRows, mappingCols, 0, mappingCols-3, codeword, DmtxMaskBit5, moduleOnColor);
193 PlaceModule(modules, mappingRows, mappingCols, 0, mappingCols-2, codeword, DmtxMaskBit6, moduleOnColor);
194 PlaceModule(modules, mappingRows, mappingCols, 0, mappingCols-1, codeword, DmtxMaskBit7, moduleOnColor);
195 PlaceModule(modules, mappingRows, mappingCols, 1, mappingCols-1, codeword, DmtxMaskBit8, moduleOnColor);
196 }
197
198 /**
199 * \brief XXX
200 * \param modules
201 * \param mappingRows
202 * \param mappingCols
203 * \param codeword
204 * \param moduleOnColor
205 * \return void
206 */
207 static void
PatternShapeSpecial3(unsigned char * modules,int mappingRows,int mappingCols,unsigned char * codeword,int moduleOnColor)208 PatternShapeSpecial3(unsigned char *modules, int mappingRows, int mappingCols, unsigned char *codeword, int moduleOnColor)
209 {
210 PlaceModule(modules, mappingRows, mappingCols, mappingRows-3, 0, codeword, DmtxMaskBit1, moduleOnColor);
211 PlaceModule(modules, mappingRows, mappingCols, mappingRows-2, 0, codeword, DmtxMaskBit2, moduleOnColor);
212 PlaceModule(modules, mappingRows, mappingCols, mappingRows-1, 0, codeword, DmtxMaskBit3, moduleOnColor);
213 PlaceModule(modules, mappingRows, mappingCols, 0, mappingCols-2, codeword, DmtxMaskBit4, moduleOnColor);
214 PlaceModule(modules, mappingRows, mappingCols, 0, mappingCols-1, codeword, DmtxMaskBit5, moduleOnColor);
215 PlaceModule(modules, mappingRows, mappingCols, 1, mappingCols-1, codeword, DmtxMaskBit6, moduleOnColor);
216 PlaceModule(modules, mappingRows, mappingCols, 2, mappingCols-1, codeword, DmtxMaskBit7, moduleOnColor);
217 PlaceModule(modules, mappingRows, mappingCols, 3, mappingCols-1, codeword, DmtxMaskBit8, moduleOnColor);
218 }
219
220 /**
221 * \brief XXX
222 * \param modules
223 * \param mappingRows
224 * \param mappingCols
225 * \param codeword
226 * \param moduleOnColor
227 * \return void
228 */
229 static void
PatternShapeSpecial4(unsigned char * modules,int mappingRows,int mappingCols,unsigned char * codeword,int moduleOnColor)230 PatternShapeSpecial4(unsigned char *modules, int mappingRows, int mappingCols, unsigned char *codeword, int moduleOnColor)
231 {
232 PlaceModule(modules, mappingRows, mappingCols, mappingRows-1, 0, codeword, DmtxMaskBit1, moduleOnColor);
233 PlaceModule(modules, mappingRows, mappingCols, mappingRows-1, mappingCols-1, codeword, DmtxMaskBit2, moduleOnColor);
234 PlaceModule(modules, mappingRows, mappingCols, 0, mappingCols-3, codeword, DmtxMaskBit3, moduleOnColor);
235 PlaceModule(modules, mappingRows, mappingCols, 0, mappingCols-2, codeword, DmtxMaskBit4, moduleOnColor);
236 PlaceModule(modules, mappingRows, mappingCols, 0, mappingCols-1, codeword, DmtxMaskBit5, moduleOnColor);
237 PlaceModule(modules, mappingRows, mappingCols, 1, mappingCols-3, codeword, DmtxMaskBit6, moduleOnColor);
238 PlaceModule(modules, mappingRows, mappingCols, 1, mappingCols-2, codeword, DmtxMaskBit7, moduleOnColor);
239 PlaceModule(modules, mappingRows, mappingCols, 1, mappingCols-1, codeword, DmtxMaskBit8, moduleOnColor);
240 }
241
242 /**
243 * \brief XXX
244 * \param modules
245 * \param mappingRows
246 * \param mappingCols
247 * \param row
248 * \param col
249 * \param codeword
250 * \param mask
251 * \param moduleOnColor
252 * \return void
253 */
254 static void
PlaceModule(unsigned char * modules,int mappingRows,int mappingCols,int row,int col,unsigned char * codeword,int mask,int moduleOnColor)255 PlaceModule(unsigned char *modules, int mappingRows, int mappingCols, int row, int col, unsigned char *codeword, int mask, int moduleOnColor)
256 {
257 if(row < 0) {
258 row += mappingRows;
259 col += 4 - ((mappingRows+4)%8);
260 }
261 if(col < 0) {
262 col += mappingCols;
263 row += 4 - ((mappingCols+4)%8);
264 }
265
266 /* If module has already been assigned then we are decoding the pattern into codewords */
267 if((modules[row*mappingCols+col] & DmtxModuleAssigned) != 0) {
268 if((modules[row*mappingCols+col] & moduleOnColor) != 0)
269 *codeword |= mask;
270 else
271 *codeword &= (0xff ^ mask);
272 }
273 /* Otherwise we are encoding the codewords into a pattern */
274 else {
275 if((*codeword & mask) != 0x00)
276 modules[row*mappingCols+col] |= moduleOnColor;
277
278 modules[row*mappingCols+col] |= DmtxModuleAssigned;
279 }
280
281 modules[row*mappingCols+col] |= DmtxModuleVisited;
282 }
283