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