OLD | NEW |
| (Empty) |
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 2013 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/pdf417/BC_PDF417BarcodeMetadata.h" | |
24 #include "xfa/src/fxbarcode/pdf417/BC_PDF417BoundingBox.h" | |
25 #include "xfa/src/fxbarcode/pdf417/BC_PDF417Codeword.h" | |
26 #include "xfa/src/fxbarcode/pdf417/BC_PDF417Common.h" | |
27 #include "xfa/src/fxbarcode/pdf417/BC_PDF417DetectionResult.h" | |
28 #include "xfa/src/fxbarcode/pdf417/BC_PDF417DetectionResultColumn.h" | |
29 #include "xfa/src/fxbarcode/pdf417/BC_PDF417DetectionResultRowIndicatorColumn.h" | |
30 | |
31 int32_t CBC_DetectionResult::ADJUST_ROW_NUMBER_SKIP = 2; | |
32 | |
33 CBC_DetectionResult::CBC_DetectionResult(CBC_BarcodeMetadata* barcodeMetadata, | |
34 CBC_BoundingBox* boundingBox) { | |
35 m_barcodeMetadata = barcodeMetadata; | |
36 m_barcodeColumnCount = barcodeMetadata->getColumnCount(); | |
37 m_boundingBox = boundingBox; | |
38 m_detectionResultColumns.SetSize(m_barcodeColumnCount + 2); | |
39 for (int32_t i = 0; i < m_barcodeColumnCount + 2; i++) { | |
40 m_detectionResultColumns[i] = NULL; | |
41 } | |
42 } | |
43 CBC_DetectionResult::~CBC_DetectionResult() { | |
44 delete m_boundingBox; | |
45 delete m_barcodeMetadata; | |
46 m_detectionResultColumns.RemoveAll(); | |
47 } | |
48 CFX_PtrArray& CBC_DetectionResult::getDetectionResultColumns() { | |
49 adjustIndicatorColumnRowNumbers( | |
50 (CBC_DetectionResultColumn*)m_detectionResultColumns.GetAt(0)); | |
51 adjustIndicatorColumnRowNumbers( | |
52 (CBC_DetectionResultColumn*)m_detectionResultColumns.GetAt( | |
53 m_barcodeColumnCount + 1)); | |
54 int32_t unadjustedCodewordCount = CBC_PDF417Common::MAX_CODEWORDS_IN_BARCODE; | |
55 int32_t previousUnadjustedCount; | |
56 do { | |
57 previousUnadjustedCount = unadjustedCodewordCount; | |
58 unadjustedCodewordCount = adjustRowNumbers(); | |
59 } while (unadjustedCodewordCount > 0 && | |
60 unadjustedCodewordCount < previousUnadjustedCount); | |
61 return m_detectionResultColumns; | |
62 } | |
63 void CBC_DetectionResult::setBoundingBox(CBC_BoundingBox* boundingBox) { | |
64 m_boundingBox = boundingBox; | |
65 } | |
66 CBC_BoundingBox* CBC_DetectionResult::getBoundingBox() { | |
67 return m_boundingBox; | |
68 } | |
69 void CBC_DetectionResult::setDetectionResultColumn( | |
70 int32_t barcodeColumn, | |
71 CBC_DetectionResultColumn* detectionResultColumn) { | |
72 m_detectionResultColumns[barcodeColumn] = detectionResultColumn; | |
73 } | |
74 CBC_DetectionResultColumn* CBC_DetectionResult::getDetectionResultColumn( | |
75 int32_t barcodeColumn) { | |
76 return (CBC_DetectionResultColumn*)m_detectionResultColumns[barcodeColumn]; | |
77 } | |
78 CFX_ByteString CBC_DetectionResult::toString() { | |
79 CBC_DetectionResultColumn* rowIndicatorColumn = | |
80 (CBC_DetectionResultColumn*)m_detectionResultColumns[0]; | |
81 if (rowIndicatorColumn == NULL) { | |
82 rowIndicatorColumn = (CBC_DetectionResultColumn*) | |
83 m_detectionResultColumns[m_barcodeColumnCount + 1]; | |
84 } | |
85 CFX_ByteString result; | |
86 for (int32_t codewordsRow = 0; | |
87 codewordsRow < rowIndicatorColumn->getCodewords()->GetSize(); | |
88 codewordsRow++) { | |
89 result += (FX_CHAR)codewordsRow; | |
90 for (int32_t barcodeColumn = 0; barcodeColumn < m_barcodeColumnCount + 2; | |
91 barcodeColumn++) { | |
92 if (m_detectionResultColumns[barcodeColumn] == NULL) { | |
93 result += " | "; | |
94 continue; | |
95 } | |
96 CBC_Codeword* codeword = | |
97 (CBC_Codeword*)((CBC_DetectionResultColumn*) | |
98 m_detectionResultColumns[barcodeColumn]) | |
99 ->getCodewords() | |
100 ->GetAt(codewordsRow); | |
101 if (codeword == NULL) { | |
102 result += " | "; | |
103 continue; | |
104 } | |
105 result += codeword->getRowNumber(); | |
106 result += codeword->getValue(); | |
107 } | |
108 } | |
109 return result; | |
110 } | |
111 void CBC_DetectionResult::adjustIndicatorColumnRowNumbers( | |
112 CBC_DetectionResultColumn* detectionResultColumn) { | |
113 if (detectionResultColumn) { | |
114 ((CBC_DetectionResultRowIndicatorColumn*)detectionResultColumn) | |
115 ->adjustCompleteIndicatorColumnRowNumbers(*m_barcodeMetadata); | |
116 } | |
117 } | |
118 int32_t CBC_DetectionResult::adjustRowNumbers() { | |
119 int32_t unadjustedCount = adjustRowNumbersByRow(); | |
120 if (unadjustedCount == 0) { | |
121 return 0; | |
122 } | |
123 for (int32_t barcodeColumn = 1; barcodeColumn < m_barcodeColumnCount + 1; | |
124 barcodeColumn++) { | |
125 CFX_PtrArray* codewords = | |
126 ((CBC_DetectionResultColumn*)m_detectionResultColumns[barcodeColumn]) | |
127 ->getCodewords(); | |
128 for (int32_t codewordsRow = 0; codewordsRow < codewords->GetSize(); | |
129 codewordsRow++) { | |
130 if (codewords->GetAt(codewordsRow) == NULL) { | |
131 continue; | |
132 } | |
133 if (!((CBC_Codeword*)codewords->GetAt(codewordsRow)) | |
134 ->hasValidRowNumber()) { | |
135 adjustRowNumbers(barcodeColumn, codewordsRow, codewords); | |
136 } | |
137 } | |
138 } | |
139 return unadjustedCount; | |
140 } | |
141 int32_t CBC_DetectionResult::adjustRowNumbersByRow() { | |
142 adjustRowNumbersFromBothRI(); | |
143 int32_t unadjustedCount = adjustRowNumbersFromLRI(); | |
144 return unadjustedCount + adjustRowNumbersFromRRI(); | |
145 } | |
146 int32_t CBC_DetectionResult::adjustRowNumbersFromBothRI() { | |
147 if (m_detectionResultColumns[0] == NULL || | |
148 m_detectionResultColumns[m_barcodeColumnCount + 1] == NULL) { | |
149 return 0; | |
150 } | |
151 CFX_PtrArray* LRIcodewords = | |
152 ((CBC_DetectionResultColumn*)m_detectionResultColumns[0])->getCodewords(); | |
153 CFX_PtrArray* RRIcodewords = | |
154 ((CBC_DetectionResultColumn*) | |
155 m_detectionResultColumns[m_barcodeColumnCount + 1]) | |
156 ->getCodewords(); | |
157 for (int32_t codewordsRow = 0; codewordsRow < LRIcodewords->GetSize(); | |
158 codewordsRow++) { | |
159 if (LRIcodewords->GetAt(codewordsRow) && | |
160 RRIcodewords->GetAt(codewordsRow) && | |
161 ((CBC_Codeword*)LRIcodewords->GetAt(codewordsRow))->getRowNumber() == | |
162 ((CBC_Codeword*)RRIcodewords->GetAt(codewordsRow)) | |
163 ->getRowNumber()) { | |
164 for (int32_t barcodeColumn = 1; barcodeColumn <= m_barcodeColumnCount; | |
165 barcodeColumn++) { | |
166 CBC_Codeword* codeword = | |
167 (CBC_Codeword*)((CBC_DetectionResultColumn*) | |
168 m_detectionResultColumns[barcodeColumn]) | |
169 ->getCodewords() | |
170 ->GetAt(codewordsRow); | |
171 if (codeword == NULL) { | |
172 continue; | |
173 } | |
174 codeword->setRowNumber( | |
175 ((CBC_Codeword*)LRIcodewords->GetAt(codewordsRow))->getRowNumber()); | |
176 if (!codeword->hasValidRowNumber()) { | |
177 ((CBC_DetectionResultColumn*)m_detectionResultColumns[barcodeColumn]) | |
178 ->getCodewords() | |
179 ->SetAt(codewordsRow, NULL); | |
180 } | |
181 } | |
182 } | |
183 } | |
184 return 0; | |
185 } | |
186 int32_t CBC_DetectionResult::adjustRowNumbersFromRRI() { | |
187 if (m_detectionResultColumns[m_barcodeColumnCount + 1] == NULL) { | |
188 return 0; | |
189 } | |
190 int32_t unadjustedCount = 0; | |
191 CFX_PtrArray* codewords = | |
192 ((CBC_DetectionResultColumn*)m_detectionResultColumns.GetAt( | |
193 m_barcodeColumnCount + 1)) | |
194 ->getCodewords(); | |
195 for (int32_t codewordsRow = 0; codewordsRow < codewords->GetSize(); | |
196 codewordsRow++) { | |
197 if (codewords->GetAt(codewordsRow) == NULL) { | |
198 continue; | |
199 } | |
200 int32_t rowIndicatorRowNumber = | |
201 ((CBC_Codeword*)codewords->GetAt(codewordsRow))->getRowNumber(); | |
202 int32_t invalidRowCounts = 0; | |
203 for (int32_t barcodeColumn = m_barcodeColumnCount + 1; | |
204 barcodeColumn > 0 && invalidRowCounts < ADJUST_ROW_NUMBER_SKIP; | |
205 barcodeColumn--) { | |
206 CBC_Codeword* codeword = | |
207 (CBC_Codeword*)((CBC_DetectionResultColumn*) | |
208 m_detectionResultColumns.GetAt(barcodeColumn)) | |
209 ->getCodewords() | |
210 ->GetAt(codewordsRow); | |
211 if (codeword) { | |
212 invalidRowCounts = adjustRowNumberIfValid(rowIndicatorRowNumber, | |
213 invalidRowCounts, codeword); | |
214 if (!codeword->hasValidRowNumber()) { | |
215 unadjustedCount++; | |
216 } | |
217 } | |
218 } | |
219 } | |
220 return unadjustedCount; | |
221 } | |
222 int32_t CBC_DetectionResult::adjustRowNumbersFromLRI() { | |
223 if (m_detectionResultColumns[0] == NULL) { | |
224 return 0; | |
225 } | |
226 int32_t unadjustedCount = 0; | |
227 CFX_PtrArray* codewords = | |
228 ((CBC_DetectionResultColumn*)m_detectionResultColumns.GetAt(0)) | |
229 ->getCodewords(); | |
230 for (int32_t codewordsRow = 0; codewordsRow < codewords->GetSize(); | |
231 codewordsRow++) { | |
232 if (codewords->GetAt(codewordsRow) == NULL) { | |
233 continue; | |
234 } | |
235 int32_t rowIndicatorRowNumber = | |
236 ((CBC_Codeword*)codewords->GetAt(codewordsRow))->getRowNumber(); | |
237 int32_t invalidRowCounts = 0; | |
238 for (int32_t barcodeColumn = 1; barcodeColumn < m_barcodeColumnCount + 1 && | |
239 invalidRowCounts < ADJUST_ROW_NUMBER_SKIP; | |
240 barcodeColumn++) { | |
241 CBC_Codeword* codeword = | |
242 (CBC_Codeword*)((CBC_DetectionResultColumn*) | |
243 m_detectionResultColumns[barcodeColumn]) | |
244 ->getCodewords() | |
245 ->GetAt(codewordsRow); | |
246 if (codeword) { | |
247 invalidRowCounts = adjustRowNumberIfValid(rowIndicatorRowNumber, | |
248 invalidRowCounts, codeword); | |
249 if (!codeword->hasValidRowNumber()) { | |
250 unadjustedCount++; | |
251 } | |
252 } | |
253 } | |
254 } | |
255 return unadjustedCount; | |
256 } | |
257 int32_t CBC_DetectionResult::adjustRowNumberIfValid( | |
258 int32_t rowIndicatorRowNumber, | |
259 int32_t invalidRowCounts, | |
260 CBC_Codeword* codeword) { | |
261 if (codeword == NULL) { | |
262 return invalidRowCounts; | |
263 } | |
264 if (!codeword->hasValidRowNumber()) { | |
265 if (codeword->isValidRowNumber(rowIndicatorRowNumber)) { | |
266 codeword->setRowNumber(rowIndicatorRowNumber); | |
267 invalidRowCounts = 0; | |
268 } else { | |
269 ++invalidRowCounts; | |
270 } | |
271 } | |
272 return invalidRowCounts; | |
273 } | |
274 void CBC_DetectionResult::adjustRowNumbers(int32_t barcodeColumn, | |
275 int32_t codewordsRow, | |
276 CFX_PtrArray* codewords) { | |
277 CBC_Codeword* codeword = (CBC_Codeword*)codewords->GetAt(codewordsRow); | |
278 CFX_PtrArray* previousColumnCodewords = | |
279 ((CBC_DetectionResultColumn*)m_detectionResultColumns.GetAt( | |
280 barcodeColumn - 1)) | |
281 ->getCodewords(); | |
282 CFX_PtrArray* nextColumnCodewords = previousColumnCodewords; | |
283 if (m_detectionResultColumns[barcodeColumn + 1]) { | |
284 nextColumnCodewords = ((CBC_DetectionResultColumn*) | |
285 m_detectionResultColumns[barcodeColumn + 1]) | |
286 ->getCodewords(); | |
287 } | |
288 CFX_PtrArray otherCodewords; | |
289 otherCodewords.SetSize(14); | |
290 otherCodewords[2] = previousColumnCodewords->GetAt(codewordsRow); | |
291 otherCodewords[3] = nextColumnCodewords->GetAt(codewordsRow); | |
292 if (codewordsRow > 0) { | |
293 otherCodewords[0] = codewords->GetAt(codewordsRow - 1); | |
294 otherCodewords[4] = previousColumnCodewords->GetAt(codewordsRow - 1); | |
295 otherCodewords[5] = nextColumnCodewords->GetAt(codewordsRow - 1); | |
296 } | |
297 if (codewordsRow > 1) { | |
298 otherCodewords[8] = codewords->GetAt(codewordsRow - 2); | |
299 otherCodewords[10] = previousColumnCodewords->GetAt(codewordsRow - 2); | |
300 otherCodewords[11] = nextColumnCodewords->GetAt(codewordsRow - 2); | |
301 } | |
302 if (codewordsRow < codewords->GetSize() - 1) { | |
303 otherCodewords[1] = codewords->GetAt(codewordsRow + 1); | |
304 otherCodewords[6] = previousColumnCodewords->GetAt(codewordsRow + 1); | |
305 otherCodewords[7] = nextColumnCodewords->GetAt(codewordsRow + 1); | |
306 } | |
307 if (codewordsRow < codewords->GetSize() - 2) { | |
308 otherCodewords[9] = codewords->GetAt(codewordsRow + 2); | |
309 otherCodewords[12] = previousColumnCodewords->GetAt(codewordsRow + 2); | |
310 otherCodewords[13] = nextColumnCodewords->GetAt(codewordsRow + 2); | |
311 } | |
312 for (int32_t i = 0; i < otherCodewords.GetSize(); i++) { | |
313 CBC_Codeword* otherCodeword = (CBC_Codeword*)otherCodewords.GetAt(i); | |
314 if (adjustRowNumber(codeword, otherCodeword)) { | |
315 return; | |
316 } | |
317 } | |
318 } | |
319 FX_BOOL CBC_DetectionResult::adjustRowNumber(CBC_Codeword* codeword, | |
320 CBC_Codeword* otherCodeword) { | |
321 if (otherCodeword == NULL) { | |
322 return FALSE; | |
323 } | |
324 if (otherCodeword->hasValidRowNumber() && | |
325 otherCodeword->getBucket() == codeword->getBucket()) { | |
326 codeword->setRowNumber(otherCodeword->getRowNumber()); | |
327 return TRUE; | |
328 } | |
329 return FALSE; | |
330 } | |
331 int32_t CBC_DetectionResult::getBarcodeColumnCount() { | |
332 return m_barcodeColumnCount; | |
333 } | |
334 int32_t CBC_DetectionResult::getBarcodeRowCount() { | |
335 return m_barcodeMetadata->getRowCount(); | |
336 } | |
337 int32_t CBC_DetectionResult::getBarcodeECLevel() { | |
338 return m_barcodeMetadata->getErrorCorrectionLevel(); | |
339 } | |
OLD | NEW |