1 // Copyright 2014 PDFium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 // Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
6 // Original code is licensed as follows:
7 /*
8 * Copyright 2007 ZXing authors
9 *
10 * Licensed under the Apache License, Version 2.0 (the "License");
11 * you may not use this file except in compliance with the License.
12 * You may obtain a copy of the License at
13 *
14 * http://www.apache.org/licenses/LICENSE-2.0
15 *
16 * Unless required by applicable law or agreed to in writing, software
17 * distributed under the License is distributed on an "AS IS" BASIS,
18 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
19 * See the License for the specific language governing permissions and
20 * limitations under the License.
21 */
22
23 #include "xfa/src/fxbarcode/barcode.h"
24 #include "xfa/src/fxbarcode/common/BC_CommonBitMatrix.h"
25 #include "BC_DataMatrixVersion.h"
26 #include "BC_DataMatrixBitMatrixParser.h"
CBC_DataMatrixBitMatrixParser()27 CBC_DataMatrixBitMatrixParser::CBC_DataMatrixBitMatrixParser() {
28 m_mappingBitMatrix = NULL;
29 m_version = NULL;
30 m_readMappingMatrix = NULL;
31 }
Init(CBC_CommonBitMatrix * bitMatrix,int32_t & e)32 void CBC_DataMatrixBitMatrixParser::Init(CBC_CommonBitMatrix* bitMatrix,
33 int32_t& e) {
34 int32_t dimension = bitMatrix->GetHeight();
35 if (dimension < 8 || dimension > 144 || (dimension & 0x01) != 0) {
36 e = BCExceptionFormatException;
37 return;
38 }
39 m_version = ReadVersion(bitMatrix, e);
40 BC_EXCEPTION_CHECK_ReturnVoid(e);
41 m_mappingBitMatrix = ExtractDataRegion(bitMatrix, e);
42 BC_EXCEPTION_CHECK_ReturnVoid(e);
43 m_readMappingMatrix = new CBC_CommonBitMatrix();
44 m_readMappingMatrix->Init(m_mappingBitMatrix->GetWidth(),
45 m_mappingBitMatrix->GetHeight());
46 }
~CBC_DataMatrixBitMatrixParser()47 CBC_DataMatrixBitMatrixParser::~CBC_DataMatrixBitMatrixParser() {
48 if (m_mappingBitMatrix != NULL) {
49 delete m_mappingBitMatrix;
50 }
51 m_mappingBitMatrix = NULL;
52 if (m_readMappingMatrix != NULL) {
53 delete m_readMappingMatrix;
54 }
55 m_readMappingMatrix = NULL;
56 }
GetVersion()57 CBC_DataMatrixVersion* CBC_DataMatrixBitMatrixParser::GetVersion() {
58 return m_version;
59 }
ReadVersion(CBC_CommonBitMatrix * bitMatrix,int32_t & e)60 CBC_DataMatrixVersion* CBC_DataMatrixBitMatrixParser::ReadVersion(
61 CBC_CommonBitMatrix* bitMatrix,
62 int32_t& e) {
63 int32_t rows = bitMatrix->GetHeight();
64 int32_t columns = bitMatrix->GetWidth();
65 CBC_DataMatrixVersion* temp =
66 CBC_DataMatrixVersion::GetVersionForDimensions(rows, columns, e);
67 BC_EXCEPTION_CHECK_ReturnValue(e, NULL);
68 return temp;
69 }
ReadCodewords(int32_t & e)70 CFX_ByteArray* CBC_DataMatrixBitMatrixParser::ReadCodewords(int32_t& e) {
71 CBC_AutoPtr<CFX_ByteArray> result(new CFX_ByteArray());
72 result->SetSize(m_version->GetTotalCodewords());
73 int32_t resultOffset = 0;
74 int32_t row = 4;
75 int32_t column = 0;
76 int32_t numRows = m_mappingBitMatrix->GetHeight();
77 int32_t numColumns = m_mappingBitMatrix->GetWidth();
78 FX_BOOL corner1Read = FALSE;
79 FX_BOOL corner2Read = FALSE;
80 FX_BOOL corner3Read = FALSE;
81 FX_BOOL corner4Read = FALSE;
82 do {
83 if ((row == numRows) && (column == 0) && !corner1Read) {
84 (*result)[resultOffset++] = (uint8_t)ReadCorner1(numRows, numColumns);
85 row -= 2;
86 column += 2;
87 corner1Read = TRUE;
88 } else if ((row == numRows - 2) && (column == 0) &&
89 ((numColumns & 0x03) != 0) && !corner2Read) {
90 (*result)[resultOffset++] = (uint8_t)ReadCorner2(numRows, numColumns);
91 row -= 2;
92 column += 2;
93 corner2Read = TRUE;
94 } else if ((row == numRows + 4) && (column == 2) &&
95 ((numColumns & 0x07) == 0) && !corner3Read) {
96 (*result)[resultOffset++] = (uint8_t)ReadCorner3(numRows, numColumns);
97 row -= 2;
98 column += 2;
99 corner3Read = TRUE;
100 } else if ((row == numRows - 2) && (column == 0) &&
101 ((numColumns & 0x07) == 4) && !corner4Read) {
102 (*result)[resultOffset++] = (uint8_t)ReadCorner4(numRows, numColumns);
103 row -= 2;
104 column += 2;
105 corner4Read = TRUE;
106 } else {
107 do {
108 if ((row < numRows) && (column >= 0) &&
109 !m_readMappingMatrix->Get(column, row)) {
110 if (resultOffset < (*result).GetSize()) {
111 (*result)[resultOffset++] =
112 (uint8_t)ReadUtah(row, column, numRows, numColumns);
113 }
114 }
115 row -= 2;
116 column += 2;
117 } while ((row >= 0) && (column < numColumns));
118 row += 1;
119 column += 3;
120 do {
121 if ((row >= 0) && (column < numColumns) &&
122 !m_readMappingMatrix->Get(column, row)) {
123 if (resultOffset < (*result).GetSize()) {
124 (*result)[resultOffset++] =
125 (uint8_t)ReadUtah(row, column, numRows, numColumns);
126 }
127 }
128 row += 2;
129 column -= 2;
130 } while ((row < numRows) && (column >= 0));
131 row += 3;
132 column += 1;
133 }
134 } while ((row < numRows) || (column < numColumns));
135 if (resultOffset != m_version->GetTotalCodewords()) {
136 e = BCExceptionFormatException;
137 return NULL;
138 }
139 return result.release();
140 }
ReadModule(int32_t row,int32_t column,int32_t numRows,int32_t numColumns)141 FX_BOOL CBC_DataMatrixBitMatrixParser::ReadModule(int32_t row,
142 int32_t column,
143 int32_t numRows,
144 int32_t numColumns) {
145 if (row < 0) {
146 row += numRows;
147 column += 4 - ((numRows + 4) & 0x07);
148 }
149 if (column < 0) {
150 column += numColumns;
151 row += 4 - ((numColumns + 4) & 0x07);
152 }
153 m_readMappingMatrix->Set(column, row);
154 return m_mappingBitMatrix->Get(column, row);
155 }
ReadUtah(int32_t row,int32_t column,int32_t numRows,int32_t numColumns)156 int32_t CBC_DataMatrixBitMatrixParser::ReadUtah(int32_t row,
157 int32_t column,
158 int32_t numRows,
159 int32_t numColumns) {
160 int32_t currentByte = 0;
161 if (ReadModule(row - 2, column - 2, numRows, numColumns)) {
162 currentByte |= 1;
163 }
164 currentByte <<= 1;
165 if (ReadModule(row - 2, column - 1, numRows, numColumns)) {
166 currentByte |= 1;
167 }
168 currentByte <<= 1;
169 if (ReadModule(row - 1, column - 2, numRows, numColumns)) {
170 currentByte |= 1;
171 }
172 currentByte <<= 1;
173 if (ReadModule(row - 1, column - 1, numRows, numColumns)) {
174 currentByte |= 1;
175 }
176 currentByte <<= 1;
177 if (ReadModule(row - 1, column, numRows, numColumns)) {
178 currentByte |= 1;
179 }
180 currentByte <<= 1;
181 if (ReadModule(row, column - 2, numRows, numColumns)) {
182 currentByte |= 1;
183 }
184 currentByte <<= 1;
185 if (ReadModule(row, column - 1, numRows, numColumns)) {
186 currentByte |= 1;
187 }
188 currentByte <<= 1;
189 if (ReadModule(row, column, numRows, numColumns)) {
190 currentByte |= 1;
191 }
192 return currentByte;
193 }
ReadCorner1(int32_t numRows,int32_t numColumns)194 int32_t CBC_DataMatrixBitMatrixParser::ReadCorner1(int32_t numRows,
195 int32_t numColumns) {
196 int32_t currentByte = 0;
197 if (ReadModule(numRows - 1, 0, numRows, numColumns)) {
198 currentByte |= 1;
199 }
200 currentByte <<= 1;
201 if (ReadModule(numRows - 1, 1, numRows, numColumns)) {
202 currentByte |= 1;
203 }
204 currentByte <<= 1;
205 if (ReadModule(numRows - 1, 2, numRows, numColumns)) {
206 currentByte |= 1;
207 }
208 currentByte <<= 1;
209 if (ReadModule(0, numColumns - 2, numRows, numColumns)) {
210 currentByte |= 1;
211 }
212 currentByte <<= 1;
213 if (ReadModule(0, numColumns - 1, numRows, numColumns)) {
214 currentByte |= 1;
215 }
216 currentByte <<= 1;
217 if (ReadModule(1, numColumns - 1, numRows, numColumns)) {
218 currentByte |= 1;
219 }
220 currentByte <<= 1;
221 if (ReadModule(2, numColumns - 1, numRows, numColumns)) {
222 currentByte |= 1;
223 }
224 currentByte <<= 1;
225 if (ReadModule(3, numColumns - 1, numRows, numColumns)) {
226 currentByte |= 1;
227 }
228 return currentByte;
229 }
ReadCorner2(int32_t numRows,int32_t numColumns)230 int32_t CBC_DataMatrixBitMatrixParser::ReadCorner2(int32_t numRows,
231 int32_t numColumns) {
232 int32_t currentByte = 0;
233 if (ReadModule(numRows - 3, 0, numRows, numColumns)) {
234 currentByte |= 1;
235 }
236 currentByte <<= 1;
237 if (ReadModule(numRows - 2, 0, numRows, numColumns)) {
238 currentByte |= 1;
239 }
240 currentByte <<= 1;
241 if (ReadModule(numRows - 1, 0, numRows, numColumns)) {
242 currentByte |= 1;
243 }
244 currentByte <<= 1;
245 if (ReadModule(0, numColumns - 4, numRows, numColumns)) {
246 currentByte |= 1;
247 }
248 currentByte <<= 1;
249 if (ReadModule(0, numColumns - 3, numRows, numColumns)) {
250 currentByte |= 1;
251 }
252 currentByte <<= 1;
253 if (ReadModule(0, numColumns - 2, numRows, numColumns)) {
254 currentByte |= 1;
255 }
256 currentByte <<= 1;
257 if (ReadModule(0, numColumns - 1, numRows, numColumns)) {
258 currentByte |= 1;
259 }
260 currentByte <<= 1;
261 if (ReadModule(1, numColumns - 1, numRows, numColumns)) {
262 currentByte |= 1;
263 }
264 return currentByte;
265 }
ReadCorner3(int32_t numRows,int32_t numColumns)266 int32_t CBC_DataMatrixBitMatrixParser::ReadCorner3(int32_t numRows,
267 int32_t numColumns) {
268 int32_t currentByte = 0;
269 if (ReadModule(numRows - 1, 0, numRows, numColumns)) {
270 currentByte |= 1;
271 }
272 currentByte <<= 1;
273 if (ReadModule(numRows - 1, numColumns - 1, numRows, numColumns)) {
274 currentByte |= 1;
275 }
276 currentByte <<= 1;
277 if (ReadModule(0, numColumns - 3, numRows, numColumns)) {
278 currentByte |= 1;
279 }
280 currentByte <<= 1;
281 if (ReadModule(0, numColumns - 2, numRows, numColumns)) {
282 currentByte |= 1;
283 }
284 currentByte <<= 1;
285 if (ReadModule(0, numColumns - 1, numRows, numColumns)) {
286 currentByte |= 1;
287 }
288 currentByte <<= 1;
289 if (ReadModule(1, numColumns - 3, numRows, numColumns)) {
290 currentByte |= 1;
291 }
292 currentByte <<= 1;
293 if (ReadModule(1, numColumns - 2, numRows, numColumns)) {
294 currentByte |= 1;
295 }
296 currentByte <<= 1;
297 if (ReadModule(1, numColumns - 1, numRows, numColumns)) {
298 currentByte |= 1;
299 }
300 return currentByte;
301 }
ReadCorner4(int32_t numRows,int32_t numColumns)302 int32_t CBC_DataMatrixBitMatrixParser::ReadCorner4(int32_t numRows,
303 int32_t numColumns) {
304 int32_t currentByte = 0;
305 if (ReadModule(numRows - 3, 0, numRows, numColumns)) {
306 currentByte |= 1;
307 }
308 currentByte <<= 1;
309 if (ReadModule(numRows - 2, 0, numRows, numColumns)) {
310 currentByte |= 1;
311 }
312 currentByte <<= 1;
313 if (ReadModule(numRows - 1, 0, numRows, numColumns)) {
314 currentByte |= 1;
315 }
316 currentByte <<= 1;
317 if (ReadModule(0, numColumns - 2, numRows, numColumns)) {
318 currentByte |= 1;
319 }
320 currentByte <<= 1;
321 if (ReadModule(0, numColumns - 1, numRows, numColumns)) {
322 currentByte |= 1;
323 }
324 currentByte <<= 1;
325 if (ReadModule(1, numColumns - 1, numRows, numColumns)) {
326 currentByte |= 1;
327 }
328 currentByte <<= 1;
329 if (ReadModule(2, numColumns - 1, numRows, numColumns)) {
330 currentByte |= 1;
331 }
332 currentByte <<= 1;
333 if (ReadModule(3, numColumns - 1, numRows, numColumns)) {
334 currentByte |= 1;
335 }
336 return currentByte;
337 }
ExtractDataRegion(CBC_CommonBitMatrix * bitMatrix,int32_t & e)338 CBC_CommonBitMatrix* CBC_DataMatrixBitMatrixParser::ExtractDataRegion(
339 CBC_CommonBitMatrix* bitMatrix,
340 int32_t& e) {
341 int32_t symbolSizeRows = m_version->GetSymbolSizeRows();
342 int32_t symbolSizeColumns = m_version->GetSymbolSizeColumns();
343 if (bitMatrix->GetHeight() != symbolSizeRows) {
344 e = BCExceptionCanNotCallGetDimensionOnNonSquareMatrix;
345 return NULL;
346 }
347 int32_t dataRegionSizeRows = m_version->GetDataRegionSizeRows();
348 int32_t dataRegionSizeColumns = m_version->GetDataRegionSizeColumns();
349 int32_t numDataRegionsRow = symbolSizeRows / dataRegionSizeRows;
350 int32_t numDataRegionsColumn = symbolSizeColumns / dataRegionSizeColumns;
351 int32_t sizeDataRegionRow = numDataRegionsRow * dataRegionSizeRows;
352 int32_t sizeDataRegionColumn = numDataRegionsColumn * dataRegionSizeColumns;
353 CBC_CommonBitMatrix* bitMatrixWithoutAlignment = new CBC_CommonBitMatrix();
354 bitMatrixWithoutAlignment->Init(sizeDataRegionColumn, sizeDataRegionRow);
355 int32_t dataRegionRow;
356 for (dataRegionRow = 0; dataRegionRow < numDataRegionsRow; ++dataRegionRow) {
357 int32_t dataRegionRowOffset = dataRegionRow * dataRegionSizeRows;
358 int32_t dataRegionColumn;
359 for (dataRegionColumn = 0; dataRegionColumn < numDataRegionsColumn;
360 ++dataRegionColumn) {
361 int32_t dataRegionColumnOffset = dataRegionColumn * dataRegionSizeColumns;
362 int32_t i;
363 for (i = 0; i < dataRegionSizeRows; ++i) {
364 int32_t readRowOffset =
365 dataRegionRow * (dataRegionSizeRows + 2) + 1 + i;
366 int32_t writeRowOffset = dataRegionRowOffset + i;
367 int32_t j;
368 for (j = 0; j < dataRegionSizeColumns; ++j) {
369 int32_t readColumnOffset =
370 dataRegionColumn * (dataRegionSizeColumns + 2) + 1 + j;
371 if (bitMatrix->Get(readColumnOffset, readRowOffset)) {
372 int32_t writeColumnOffset = dataRegionColumnOffset + j;
373 bitMatrixWithoutAlignment->Set(writeColumnOffset, writeRowOffset);
374 }
375 }
376 }
377 }
378 }
379 return bitMatrixWithoutAlignment;
380 }
381