Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(61)

Side by Side Diff: xfa/src/fxbarcode/pdf417/BC_PDF417ScanningDecoder.cpp

Issue 1803723002: Move xfa/src up to xfa/. (Closed) Base URL: https://pdfium.googlesource.com/pdfium.git@master
Patch Set: Rebase to master Created 4 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(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/BC_DecoderResult.h"
24 #include "xfa/src/fxbarcode/BC_ResultPoint.h"
25 #include "xfa/src/fxbarcode/common/BC_CommonBitMatrix.h"
26 #include "xfa/src/fxbarcode/pdf417/BC_PDF417BarcodeMetadata.h"
27 #include "xfa/src/fxbarcode/pdf417/BC_PDF417BarcodeValue.h"
28 #include "xfa/src/fxbarcode/pdf417/BC_PDF417BoundingBox.h"
29 #include "xfa/src/fxbarcode/pdf417/BC_PDF417Codeword.h"
30 #include "xfa/src/fxbarcode/pdf417/BC_PDF417CodewordDecoder.h"
31 #include "xfa/src/fxbarcode/pdf417/BC_PDF417Common.h"
32 #include "xfa/src/fxbarcode/pdf417/BC_PDF417DecodedBitStreamParser.h"
33 #include "xfa/src/fxbarcode/pdf417/BC_PDF417DecodedBitStreamParser.h"
34 #include "xfa/src/fxbarcode/pdf417/BC_PDF417DecodedBitStreamParser.h"
35 #include "xfa/src/fxbarcode/pdf417/BC_PDF417DetectionResult.h"
36 #include "xfa/src/fxbarcode/pdf417/BC_PDF417DetectionResultColumn.h"
37 #include "xfa/src/fxbarcode/pdf417/BC_PDF417DetectionResultRowIndicatorColumn.h"
38 #include "xfa/src/fxbarcode/pdf417/BC_PDF417ECErrorCorrection.h"
39 #include "xfa/src/fxbarcode/pdf417/BC_PDF417ECModulusGF.h"
40 #include "xfa/src/fxbarcode/pdf417/BC_PDF417ECModulusPoly.h"
41 #include "xfa/src/fxbarcode/pdf417/BC_PDF417ScanningDecoder.h"
42 #include "xfa/src/fxbarcode/utils.h"
43
44 int32_t CBC_PDF417ScanningDecoder::CODEWORD_SKEW_SIZE = 2;
45 int32_t CBC_PDF417ScanningDecoder::MAX_ERRORS = 3;
46 int32_t CBC_PDF417ScanningDecoder::MAX_EC_CODEWORDS = 512;
47 CBC_PDF417ECErrorCorrection* CBC_PDF417ScanningDecoder::errorCorrection = NULL;
48
49 CBC_PDF417ScanningDecoder::CBC_PDF417ScanningDecoder() {}
50 CBC_PDF417ScanningDecoder::~CBC_PDF417ScanningDecoder() {}
51 void CBC_PDF417ScanningDecoder::Initialize() {
52 errorCorrection = new CBC_PDF417ECErrorCorrection;
53 }
54 void CBC_PDF417ScanningDecoder::Finalize() {
55 delete errorCorrection;
56 }
57 CBC_CommonDecoderResult* CBC_PDF417ScanningDecoder::decode(
58 CBC_CommonBitMatrix* image,
59 CBC_ResultPoint* imageTopLeft,
60 CBC_ResultPoint* imageBottomLeft,
61 CBC_ResultPoint* imageTopRight,
62 CBC_ResultPoint* imageBottomRight,
63 int32_t minCodewordWidth,
64 int32_t maxCodewordWidth,
65 int32_t& e) {
66 CBC_BoundingBox* boundingBox = new CBC_BoundingBox(
67 image, imageTopLeft, imageBottomLeft, imageTopRight, imageBottomRight, e);
68 BC_EXCEPTION_CHECK_ReturnValue(e, NULL);
69 CBC_DetectionResultRowIndicatorColumn* leftRowIndicatorColumn = NULL;
70 CBC_DetectionResultRowIndicatorColumn* rightRowIndicatorColumn = NULL;
71 CBC_DetectionResult* detectionResult = NULL;
72 for (int32_t i = 0; i < 2; i++) {
73 if (imageTopLeft) {
74 leftRowIndicatorColumn =
75 getRowIndicatorColumn(image, boundingBox, *imageTopLeft, TRUE,
76 minCodewordWidth, maxCodewordWidth);
77 }
78 if (imageTopRight) {
79 rightRowIndicatorColumn =
80 getRowIndicatorColumn(image, boundingBox, *imageTopRight, FALSE,
81 minCodewordWidth, maxCodewordWidth);
82 }
83 detectionResult = merge(leftRowIndicatorColumn, rightRowIndicatorColumn, e);
84 if (e != BCExceptionNO) {
85 e = BCExceptiontNotFoundInstance;
86 delete leftRowIndicatorColumn;
87 delete rightRowIndicatorColumn;
88 delete boundingBox;
89 return NULL;
90 }
91 if (i == 0 && (detectionResult->getBoundingBox()->getMinY() <
92 boundingBox->getMinY() ||
93 detectionResult->getBoundingBox()->getMaxY() >
94 boundingBox->getMaxY())) {
95 delete boundingBox;
96 boundingBox = detectionResult->getBoundingBox();
97 } else {
98 detectionResult->setBoundingBox(boundingBox);
99 break;
100 }
101 }
102 int32_t maxBarcodeColumn = detectionResult->getBarcodeColumnCount() + 1;
103 detectionResult->setDetectionResultColumn(0, leftRowIndicatorColumn);
104 detectionResult->setDetectionResultColumn(maxBarcodeColumn,
105 rightRowIndicatorColumn);
106 FX_BOOL leftToRight = leftRowIndicatorColumn != NULL;
107 for (int32_t barcodeColumnCount = 1; barcodeColumnCount <= maxBarcodeColumn;
108 barcodeColumnCount++) {
109 int32_t barcodeColumn = leftToRight ? barcodeColumnCount
110 : maxBarcodeColumn - barcodeColumnCount;
111 if (detectionResult->getDetectionResultColumn(barcodeColumn)) {
112 continue;
113 }
114 CBC_DetectionResultColumn* detectionResultColumn = NULL;
115 if (barcodeColumn == 0 || barcodeColumn == maxBarcodeColumn) {
116 detectionResultColumn = new CBC_DetectionResultRowIndicatorColumn(
117 boundingBox, barcodeColumn == 0);
118 } else {
119 detectionResultColumn = new CBC_DetectionResultColumn(boundingBox);
120 }
121 detectionResult->setDetectionResultColumn(barcodeColumn,
122 detectionResultColumn);
123 int32_t startColumn = -1;
124 int32_t previousStartColumn = startColumn;
125 for (int32_t imageRow = boundingBox->getMinY();
126 imageRow <= boundingBox->getMaxY(); imageRow++) {
127 startColumn =
128 getStartColumn(detectionResult, barcodeColumn, imageRow, leftToRight);
129 if (startColumn < 0 || startColumn > boundingBox->getMaxX()) {
130 if (previousStartColumn == -1) {
131 continue;
132 }
133 startColumn = previousStartColumn;
134 }
135 CBC_Codeword* codeword = detectCodeword(
136 image, boundingBox->getMinX(), boundingBox->getMaxX(), leftToRight,
137 startColumn, imageRow, minCodewordWidth, maxCodewordWidth);
138 if (codeword) {
139 detectionResultColumn->setCodeword(imageRow, codeword);
140 previousStartColumn = startColumn;
141 minCodewordWidth = minCodewordWidth < codeword->getWidth()
142 ? minCodewordWidth
143 : codeword->getWidth();
144 maxCodewordWidth = maxCodewordWidth > codeword->getWidth()
145 ? maxCodewordWidth
146 : codeword->getWidth();
147 }
148 }
149 }
150 CBC_CommonDecoderResult* decoderresult =
151 createDecoderResult(detectionResult, e);
152 if (e != BCExceptionNO) {
153 delete detectionResult;
154 return NULL;
155 }
156 return decoderresult;
157 }
158 CFX_ByteString CBC_PDF417ScanningDecoder::toString(
159 CFX_PtrArray* barcodeMatrix) {
160 CFX_ByteString result;
161 for (int32_t row = 0; row < barcodeMatrix->GetSize(); row++) {
162 result += row;
163 int32_t l = 0;
164 for (; l < ((CFX_PtrArray*)barcodeMatrix->GetAt(row))->GetSize(); l++) {
165 CBC_BarcodeValue* barcodeValue =
166 (CBC_BarcodeValue*)((CFX_PtrArray*)barcodeMatrix->GetAt(row))
167 ->GetAt(l);
168 if (barcodeValue->getValue()->GetSize() == 0) {
169 result += "";
170 } else {
171 result += barcodeValue->getValue()->GetAt(0);
172 result +=
173 barcodeValue->getConfidence(barcodeValue->getValue()->GetAt(0));
174 }
175 }
176 }
177 return result;
178 }
179 CBC_DetectionResult* CBC_PDF417ScanningDecoder::merge(
180 CBC_DetectionResultRowIndicatorColumn* leftRowIndicatorColumn,
181 CBC_DetectionResultRowIndicatorColumn* rightRowIndicatorColumn,
182 int32_t& e) {
183 if (leftRowIndicatorColumn == NULL && rightRowIndicatorColumn == NULL) {
184 e = BCExceptionIllegalArgument;
185 return NULL;
186 }
187 CBC_BarcodeMetadata* barcodeMetadata =
188 getBarcodeMetadata(leftRowIndicatorColumn, rightRowIndicatorColumn);
189 if (barcodeMetadata == NULL) {
190 e = BCExceptionCannotMetadata;
191 return NULL;
192 }
193 CBC_BoundingBox* leftboundingBox =
194 adjustBoundingBox(leftRowIndicatorColumn, e);
195 if (e != BCExceptionNO) {
196 delete barcodeMetadata;
197 return NULL;
198 }
199 CBC_BoundingBox* rightboundingBox =
200 adjustBoundingBox(rightRowIndicatorColumn, e);
201 if (e != BCExceptionNO) {
202 delete barcodeMetadata;
203 return NULL;
204 }
205 CBC_BoundingBox* boundingBox =
206 CBC_BoundingBox::merge(leftboundingBox, rightboundingBox, e);
207 if (e != BCExceptionNO) {
208 delete barcodeMetadata;
209 return NULL;
210 }
211 CBC_DetectionResult* detectionresult =
212 new CBC_DetectionResult(barcodeMetadata, boundingBox);
213 return detectionresult;
214 }
215 CBC_BoundingBox* CBC_PDF417ScanningDecoder::adjustBoundingBox(
216 CBC_DetectionResultRowIndicatorColumn* rowIndicatorColumn,
217 int32_t& e) {
218 if (rowIndicatorColumn == NULL) {
219 return NULL;
220 }
221 CFX_Int32Array* rowHeights = rowIndicatorColumn->getRowHeights(e);
222 BC_EXCEPTION_CHECK_ReturnValue(e, NULL);
223 int32_t maxRowHeight = getMax(*rowHeights);
224 int32_t missingStartRows = 0;
225 for (int32_t i = 0; i < rowHeights->GetSize(); i++) {
226 int32_t rowHeight = rowHeights->GetAt(i);
227 missingStartRows += maxRowHeight - rowHeight;
228 if (rowHeight > 0) {
229 break;
230 }
231 }
232 CFX_PtrArray* codewords = rowIndicatorColumn->getCodewords();
233 for (int32_t row = 0; missingStartRows > 0 && codewords->GetAt(row) == NULL;
234 row++) {
235 missingStartRows--;
236 }
237 int32_t missingEndRows = 0;
238 for (int32_t row1 = rowHeights->GetSize() - 1; row1 >= 0; row1--) {
239 missingEndRows += maxRowHeight - rowHeights->GetAt(row1);
240 if (rowHeights->GetAt(row1) > 0) {
241 break;
242 }
243 }
244 for (int32_t row2 = codewords->GetSize() - 1;
245 missingEndRows > 0 && codewords->GetAt(row2) == NULL; row2--) {
246 missingEndRows--;
247 }
248 CBC_BoundingBox* boundingBox =
249 rowIndicatorColumn->getBoundingBox()->addMissingRows(
250 missingStartRows, missingEndRows, rowIndicatorColumn->isLeft(), e);
251 BC_EXCEPTION_CHECK_ReturnValue(e, NULL);
252 return boundingBox;
253 }
254 int32_t CBC_PDF417ScanningDecoder::getMax(CFX_Int32Array& values) {
255 int32_t maxValue = -1;
256 for (int32_t i = 0; i < values.GetSize(); i++) {
257 int32_t value = values.GetAt(i);
258 maxValue = maxValue > value ? maxValue : value;
259 }
260 return maxValue;
261 }
262 CBC_BarcodeMetadata* CBC_PDF417ScanningDecoder::getBarcodeMetadata(
263 CBC_DetectionResultRowIndicatorColumn* leftRowIndicatorColumn,
264 CBC_DetectionResultRowIndicatorColumn* rightRowIndicatorColumn) {
265 CBC_BarcodeMetadata* leftBarcodeMetadata = NULL;
266 CBC_BarcodeMetadata* rightBarcodeMetadata = NULL;
267 if (leftRowIndicatorColumn == NULL ||
268 (leftBarcodeMetadata = leftRowIndicatorColumn->getBarcodeMetadata()) ==
269 NULL) {
270 return rightRowIndicatorColumn == NULL
271 ? NULL
272 : rightRowIndicatorColumn->getBarcodeMetadata();
273 }
274 if (rightRowIndicatorColumn == NULL ||
275 (rightBarcodeMetadata = rightRowIndicatorColumn->getBarcodeMetadata()) ==
276 NULL) {
277 return leftRowIndicatorColumn == NULL
278 ? NULL
279 : leftRowIndicatorColumn->getBarcodeMetadata();
280 }
281 if (leftBarcodeMetadata->getColumnCount() !=
282 rightBarcodeMetadata->getColumnCount() &&
283 leftBarcodeMetadata->getErrorCorrectionLevel() !=
284 rightBarcodeMetadata->getErrorCorrectionLevel() &&
285 leftBarcodeMetadata->getRowCount() !=
286 rightBarcodeMetadata->getRowCount()) {
287 delete leftBarcodeMetadata;
288 delete rightBarcodeMetadata;
289 return NULL;
290 }
291 delete rightBarcodeMetadata;
292 return leftBarcodeMetadata;
293 }
294 CBC_DetectionResultRowIndicatorColumn*
295 CBC_PDF417ScanningDecoder::getRowIndicatorColumn(CBC_CommonBitMatrix* image,
296 CBC_BoundingBox* boundingBox,
297 CBC_ResultPoint startPoint,
298 FX_BOOL leftToRight,
299 int32_t minCodewordWidth,
300 int32_t maxCodewordWidth) {
301 CBC_DetectionResultRowIndicatorColumn* rowIndicatorColumn =
302 new CBC_DetectionResultRowIndicatorColumn(boundingBox, leftToRight);
303 for (int32_t i = 0; i < 2; i++) {
304 int32_t increment = i == 0 ? 1 : -1;
305 int32_t startColumn = (int32_t)startPoint.GetX();
306 for (int32_t imageRow = (int32_t)startPoint.GetY();
307 imageRow <= boundingBox->getMaxY() &&
308 imageRow >= boundingBox->getMinY();
309 imageRow += increment) {
310 CBC_Codeword* codeword =
311 detectCodeword(image, 0, image->GetWidth(), leftToRight, startColumn,
312 imageRow, minCodewordWidth, maxCodewordWidth);
313 if (codeword) {
314 rowIndicatorColumn->setCodeword(imageRow, codeword);
315 if (leftToRight) {
316 startColumn = codeword->getStartX();
317 } else {
318 startColumn = codeword->getEndX();
319 }
320 }
321 }
322 }
323 return rowIndicatorColumn;
324 }
325 void CBC_PDF417ScanningDecoder::adjustCodewordCount(
326 CBC_DetectionResult* detectionResult,
327 CFX_PtrArray* barcodeMatrix,
328 int32_t& e) {
329 CFX_Int32Array* numberOfCodewords =
330 ((CBC_BarcodeValue*)((CFX_PtrArray*)barcodeMatrix->GetAt(0))->GetAt(1))
331 ->getValue();
332 int32_t calculatedNumberOfCodewords =
333 detectionResult->getBarcodeColumnCount() *
334 detectionResult->getBarcodeRowCount() -
335 getNumberOfECCodeWords(detectionResult->getBarcodeECLevel());
336 if (numberOfCodewords->GetSize() == 0) {
337 if (calculatedNumberOfCodewords < 1 ||
338 calculatedNumberOfCodewords >
339 CBC_PDF417Common::MAX_CODEWORDS_IN_BARCODE) {
340 e = BCExceptiontNotFoundInstance;
341 delete numberOfCodewords;
342 BC_EXCEPTION_CHECK_ReturnVoid(e);
343 }
344 ((CBC_BarcodeValue*)((CFX_PtrArray*)barcodeMatrix->GetAt(0))->GetAt(1))
345 ->setValue(calculatedNumberOfCodewords);
346 } else if (numberOfCodewords->GetAt(0) != calculatedNumberOfCodewords) {
347 ((CBC_BarcodeValue*)((CFX_PtrArray*)barcodeMatrix->GetAt(0))->GetAt(1))
348 ->setValue(calculatedNumberOfCodewords);
349 }
350 delete numberOfCodewords;
351 }
352 CBC_CommonDecoderResult* CBC_PDF417ScanningDecoder::createDecoderResult(
353 CBC_DetectionResult* detectionResult,
354 int32_t& e) {
355 CFX_PtrArray* barcodeMatrix = createBarcodeMatrix(detectionResult);
356 adjustCodewordCount(detectionResult, barcodeMatrix, e);
357 if (e != BCExceptionNO) {
358 for (int32_t i = 0; i < barcodeMatrix->GetSize(); i++) {
359 CFX_PtrArray* temp = (CFX_PtrArray*)barcodeMatrix->GetAt(i);
360 for (int32_t j = 0; j < temp->GetSize(); j++) {
361 delete (CBC_BarcodeValue*)temp->GetAt(j);
362 }
363 temp->RemoveAll();
364 delete temp;
365 }
366 barcodeMatrix->RemoveAll();
367 delete barcodeMatrix;
368 return NULL;
369 }
370 CFX_Int32Array erasures;
371 CFX_Int32Array codewords;
372 codewords.SetSize(detectionResult->getBarcodeRowCount() *
373 detectionResult->getBarcodeColumnCount());
374 CFX_PtrArray ambiguousIndexValuesList;
375 CFX_Int32Array ambiguousIndexesList;
376 for (int32_t row = 0; row < detectionResult->getBarcodeRowCount(); row++) {
377 for (int32_t l = 0; l < detectionResult->getBarcodeColumnCount(); l++) {
378 CFX_Int32Array* values =
379 ((CBC_BarcodeValue*)((CFX_PtrArray*)barcodeMatrix->GetAt(row))
380 ->GetAt(l + 1))
381 ->getValue();
382 int32_t codewordIndex =
383 row * detectionResult->getBarcodeColumnCount() + l;
384 if (values->GetSize() == 0) {
385 erasures.Add(codewordIndex);
386 } else if (values->GetSize() == 1) {
387 codewords[codewordIndex] = values->GetAt(0);
388 } else {
389 ambiguousIndexesList.Add(codewordIndex);
390 ambiguousIndexValuesList.Add(values);
391 }
392 }
393 }
394 CFX_PtrArray ambiguousIndexValues;
395 ambiguousIndexValues.SetSize(ambiguousIndexValuesList.GetSize());
396 for (int32_t i = 0; i < ambiguousIndexValues.GetSize(); i++) {
397 ambiguousIndexValues.SetAt(i, ambiguousIndexValuesList.GetAt(i));
398 }
399 for (int32_t l = 0; l < barcodeMatrix->GetSize(); l++) {
400 CFX_PtrArray* temp = (CFX_PtrArray*)barcodeMatrix->GetAt(l);
401 for (int32_t j = 0; j < temp->GetSize(); j++) {
402 delete (CBC_BarcodeValue*)temp->GetAt(j);
403 }
404 temp->RemoveAll();
405 delete temp;
406 }
407 barcodeMatrix->RemoveAll();
408 delete barcodeMatrix;
409 CBC_CommonDecoderResult* decoderResult =
410 createDecoderResultFromAmbiguousValues(
411 detectionResult->getBarcodeECLevel(), codewords, erasures,
412 ambiguousIndexesList, ambiguousIndexValues, e);
413 BC_EXCEPTION_CHECK_ReturnValue(e, NULL);
414 return decoderResult;
415 }
416 CBC_CommonDecoderResult*
417 CBC_PDF417ScanningDecoder::createDecoderResultFromAmbiguousValues(
418 int32_t ecLevel,
419 CFX_Int32Array& codewords,
420 CFX_Int32Array& erasureArray,
421 CFX_Int32Array& ambiguousIndexes,
422 CFX_PtrArray& ambiguousIndexValues,
423 int32_t& e) {
424 CFX_Int32Array ambiguousIndexCount;
425 ambiguousIndexCount.SetSize(ambiguousIndexes.GetSize());
426 int32_t tries = 100;
427 while (tries-- > 0) {
428 for (int32_t l = 0; l < ambiguousIndexCount.GetSize(); l++) {
429 codewords[ambiguousIndexes[l]] =
430 ((CFX_Int32Array*)ambiguousIndexValues.GetAt(l))
431 ->GetAt(ambiguousIndexCount[l]);
432 }
433 CBC_CommonDecoderResult* decoderResult =
434 decodeCodewords(codewords, ecLevel, erasureArray, e);
435 if (e != BCExceptionNO) {
436 e = BCExceptionNO;
437 continue;
438 } else {
439 return decoderResult;
440 }
441 if (ambiguousIndexCount.GetSize() == 0) {
442 e = BCExceptionChecksumInstance;
443 return NULL;
444 }
445 for (int32_t i = 0; i < ambiguousIndexCount.GetSize(); i++) {
446 if (ambiguousIndexCount[i] <
447 ((CFX_Int32Array*)(ambiguousIndexValues.GetAt(i)))->GetSize() - 1) {
448 ambiguousIndexCount[i]++;
449 break;
450 } else {
451 ambiguousIndexCount[i] = 0;
452 if (i == ambiguousIndexCount.GetSize() - 1) {
453 e = BCExceptionChecksumInstance;
454 return NULL;
455 }
456 }
457 }
458 }
459 e = BCExceptionChecksumInstance;
460 return NULL;
461 }
462 CFX_PtrArray* CBC_PDF417ScanningDecoder::createBarcodeMatrix(
463 CBC_DetectionResult* detectionResult) {
464 CFX_PtrArray* barcodeMatrix = new CFX_PtrArray;
465 barcodeMatrix->SetSize(detectionResult->getBarcodeRowCount());
466 CFX_PtrArray* temp = NULL;
467 int32_t colume = 0;
468 for (int32_t row = 0; row < barcodeMatrix->GetSize(); row++) {
469 temp = new CFX_PtrArray;
470 temp->SetSize(detectionResult->getBarcodeColumnCount() + 2);
471 for (colume = 0; colume < detectionResult->getBarcodeColumnCount() + 2;
472 colume++) {
473 temp->SetAt(colume, new CBC_BarcodeValue());
474 }
475 barcodeMatrix->SetAt(row, temp);
476 }
477 colume = -1;
478 for (int32_t i = 0;
479 i < detectionResult->getDetectionResultColumns().GetSize(); i++) {
480 CBC_DetectionResultColumn* detectionResultColumn =
481 (CBC_DetectionResultColumn*)detectionResult->getDetectionResultColumns()
482 .GetAt(i);
483 colume++;
484 if (detectionResultColumn == NULL) {
485 continue;
486 }
487 CFX_PtrArray* temp = detectionResultColumn->getCodewords();
488 for (int32_t l = 0; l < temp->GetSize(); l++) {
489 CBC_Codeword* codeword = (CBC_Codeword*)temp->GetAt(l);
490 if (codeword == NULL || codeword->getRowNumber() == -1) {
491 continue;
492 }
493 ((CBC_BarcodeValue*)((CFX_PtrArray*)barcodeMatrix->GetAt(
494 codeword->getRowNumber()))
495 ->GetAt(colume))
496 ->setValue(codeword->getValue());
497 }
498 }
499 return barcodeMatrix;
500 }
501 FX_BOOL CBC_PDF417ScanningDecoder::isValidBarcodeColumn(
502 CBC_DetectionResult* detectionResult,
503 int32_t barcodeColumn) {
504 return barcodeColumn >= 0 &&
505 barcodeColumn <= detectionResult->getBarcodeColumnCount() + 1;
506 }
507 int32_t CBC_PDF417ScanningDecoder::getStartColumn(
508 CBC_DetectionResult* detectionResult,
509 int32_t barcodeColumn,
510 int32_t imageRow,
511 FX_BOOL leftToRight) {
512 int32_t offset = leftToRight ? 1 : -1;
513 CBC_Codeword* codeword = NULL;
514 if (isValidBarcodeColumn(detectionResult, barcodeColumn - offset)) {
515 codeword = detectionResult->getDetectionResultColumn(barcodeColumn - offset)
516 ->getCodeword(imageRow);
517 }
518 if (codeword) {
519 return leftToRight ? codeword->getEndX() : codeword->getStartX();
520 }
521 codeword = detectionResult->getDetectionResultColumn(barcodeColumn)
522 ->getCodewordNearby(imageRow);
523 if (codeword) {
524 return leftToRight ? codeword->getStartX() : codeword->getEndX();
525 }
526 if (isValidBarcodeColumn(detectionResult, barcodeColumn - offset)) {
527 codeword = detectionResult->getDetectionResultColumn(barcodeColumn - offset)
528 ->getCodewordNearby(imageRow);
529 }
530 if (codeword) {
531 return leftToRight ? codeword->getEndX() : codeword->getStartX();
532 }
533 int32_t skippedColumns = 0;
534 while (isValidBarcodeColumn(detectionResult, barcodeColumn - offset)) {
535 barcodeColumn -= offset;
536 for (int32_t i = 0;
537 i < detectionResult->getDetectionResultColumn(barcodeColumn)
538 ->getCodewords()
539 ->GetSize();
540 i++) {
541 CBC_Codeword* previousRowCodeword =
542 (CBC_Codeword*)detectionResult->getDetectionResultColumn(
543 barcodeColumn)
544 ->getCodewords()
545 ->GetAt(i);
546 if (previousRowCodeword) {
547 return (leftToRight ? previousRowCodeword->getEndX()
548 : previousRowCodeword->getStartX()) +
549 offset * skippedColumns * (previousRowCodeword->getEndX() -
550 previousRowCodeword->getStartX());
551 }
552 }
553 skippedColumns++;
554 }
555 return leftToRight ? detectionResult->getBoundingBox()->getMinX()
556 : detectionResult->getBoundingBox()->getMaxX();
557 }
558 CBC_Codeword* CBC_PDF417ScanningDecoder::detectCodeword(
559 CBC_CommonBitMatrix* image,
560 int32_t minColumn,
561 int32_t maxColumn,
562 FX_BOOL leftToRight,
563 int32_t startColumn,
564 int32_t imageRow,
565 int32_t minCodewordWidth,
566 int32_t maxCodewordWidth) {
567 startColumn = adjustCodewordStartColumn(image, minColumn, maxColumn,
568 leftToRight, startColumn, imageRow);
569 CFX_Int32Array* moduleBitCount = getModuleBitCount(
570 image, minColumn, maxColumn, leftToRight, startColumn, imageRow);
571 if (moduleBitCount == NULL) {
572 return NULL;
573 }
574 int32_t endColumn;
575 int32_t codewordBitCount = CBC_PDF417Common::getBitCountSum(*moduleBitCount);
576 if (leftToRight) {
577 endColumn = startColumn + codewordBitCount;
578 } else {
579 for (int32_t i = 0; i<moduleBitCount->GetSize()>> 1; i++) {
580 int32_t tmpCount = moduleBitCount->GetAt(i);
581 moduleBitCount->SetAt(
582 i, moduleBitCount->GetAt(moduleBitCount->GetSize() - 1 - i));
583 moduleBitCount->SetAt(moduleBitCount->GetSize() - 1 - i, tmpCount);
584 }
585 endColumn = startColumn;
586 startColumn = endColumn - codewordBitCount;
587 }
588 int32_t decodedValue =
589 CBC_PDF417CodewordDecoder::getDecodedValue(*moduleBitCount);
590 int32_t codeword = CBC_PDF417Common::getCodeword(decodedValue);
591 delete moduleBitCount;
592 if (codeword == -1) {
593 return NULL;
594 }
595 return new CBC_Codeword(startColumn, endColumn,
596 getCodewordBucketNumber(decodedValue), codeword);
597 }
598 CFX_Int32Array* CBC_PDF417ScanningDecoder::getModuleBitCount(
599 CBC_CommonBitMatrix* image,
600 int32_t minColumn,
601 int32_t maxColumn,
602 FX_BOOL leftToRight,
603 int32_t startColumn,
604 int32_t imageRow) {
605 int32_t imageColumn = startColumn;
606 CFX_Int32Array* moduleBitCount = new CFX_Int32Array;
607 moduleBitCount->SetSize(8);
608 int32_t moduleNumber = 0;
609 int32_t increment = leftToRight ? 1 : -1;
610 FX_BOOL previousPixelValue = leftToRight;
611 while (((leftToRight && imageColumn < maxColumn) ||
612 (!leftToRight && imageColumn >= minColumn)) &&
613 moduleNumber < moduleBitCount->GetSize()) {
614 if (image->Get(imageColumn, imageRow) == previousPixelValue) {
615 moduleBitCount->SetAt(moduleNumber,
616 moduleBitCount->GetAt(moduleNumber) + 1);
617 imageColumn += increment;
618 } else {
619 moduleNumber++;
620 previousPixelValue = !previousPixelValue;
621 }
622 }
623 if (moduleNumber == moduleBitCount->GetSize() ||
624 (((leftToRight && imageColumn == maxColumn) ||
625 (!leftToRight && imageColumn == minColumn)) &&
626 moduleNumber == moduleBitCount->GetSize() - 1)) {
627 return moduleBitCount;
628 }
629 delete moduleBitCount;
630 return NULL;
631 }
632 int32_t CBC_PDF417ScanningDecoder::getNumberOfECCodeWords(
633 int32_t barcodeECLevel) {
634 return 2 << barcodeECLevel;
635 }
636 int32_t CBC_PDF417ScanningDecoder::adjustCodewordStartColumn(
637 CBC_CommonBitMatrix* image,
638 int32_t minColumn,
639 int32_t maxColumn,
640 FX_BOOL leftToRight,
641 int32_t codewordStartColumn,
642 int32_t imageRow) {
643 int32_t correctedStartColumn = codewordStartColumn;
644 int32_t increment = leftToRight ? -1 : 1;
645 for (int32_t i = 0; i < 2; i++) {
646 while (((leftToRight && correctedStartColumn >= minColumn) ||
647 (!leftToRight && correctedStartColumn < maxColumn)) &&
648 leftToRight == image->Get(correctedStartColumn, imageRow)) {
649 if (abs(codewordStartColumn - correctedStartColumn) >
650 CODEWORD_SKEW_SIZE) {
651 return codewordStartColumn;
652 }
653 correctedStartColumn += increment;
654 }
655 increment = -increment;
656 leftToRight = !leftToRight;
657 }
658 return correctedStartColumn;
659 }
660 FX_BOOL CBC_PDF417ScanningDecoder::checkCodewordSkew(int32_t codewordSize,
661 int32_t minCodewordWidth,
662 int32_t maxCodewordWidth) {
663 return minCodewordWidth - CODEWORD_SKEW_SIZE <= codewordSize &&
664 codewordSize <= maxCodewordWidth + CODEWORD_SKEW_SIZE;
665 }
666 CBC_CommonDecoderResult* CBC_PDF417ScanningDecoder::decodeCodewords(
667 CFX_Int32Array& codewords,
668 int32_t ecLevel,
669 CFX_Int32Array& erasures,
670 int32_t& e) {
671 if (codewords.GetSize() == 0) {
672 e = BCExceptionFormatInstance;
673 return NULL;
674 }
675 int32_t numECCodewords = 1 << (ecLevel + 1);
676 correctErrors(codewords, erasures, numECCodewords, e);
677 BC_EXCEPTION_CHECK_ReturnValue(e, NULL);
678 verifyCodewordCount(codewords, numECCodewords, e);
679 BC_EXCEPTION_CHECK_ReturnValue(e, NULL);
680 CFX_ByteString bytestring;
681 CBC_CommonDecoderResult* decoderResult = CBC_DecodedBitStreamPaser::decode(
682 codewords, bytestring.FormatInteger(ecLevel), e);
683 BC_EXCEPTION_CHECK_ReturnValue(e, NULL);
684 return decoderResult;
685 }
686 int32_t CBC_PDF417ScanningDecoder::correctErrors(CFX_Int32Array& codewords,
687 CFX_Int32Array& erasures,
688 int32_t numECCodewords,
689 int32_t& e) {
690 if ((erasures.GetSize() != 0 &&
691 erasures.GetSize() > (numECCodewords / 2 + MAX_ERRORS)) ||
692 numECCodewords < 0 || numECCodewords > MAX_EC_CODEWORDS) {
693 e = BCExceptionChecksumInstance;
694 return -1;
695 }
696 int32_t result = CBC_PDF417ECErrorCorrection::decode(
697 codewords, numECCodewords, erasures, e);
698 BC_EXCEPTION_CHECK_ReturnValue(e, -1);
699 return result;
700 }
701 void CBC_PDF417ScanningDecoder::verifyCodewordCount(CFX_Int32Array& codewords,
702 int32_t numECCodewords,
703 int32_t& e) {
704 if (codewords.GetSize() < 4) {
705 e = BCExceptionFormatInstance;
706 return;
707 }
708 int32_t numberOfCodewords = codewords.GetAt(0);
709 if (numberOfCodewords > codewords.GetSize()) {
710 e = BCExceptionFormatInstance;
711 return;
712 }
713 if (numberOfCodewords == 0) {
714 if (numECCodewords < codewords.GetSize()) {
715 codewords[0] = codewords.GetSize() - numECCodewords;
716 } else {
717 e = BCExceptionFormatInstance;
718 return;
719 }
720 }
721 }
722 CFX_Int32Array* CBC_PDF417ScanningDecoder::getBitCountForCodeword(
723 int32_t codeword) {
724 CFX_Int32Array* result = new CFX_Int32Array;
725 result->SetSize(8);
726 int32_t previousValue = 0;
727 int32_t i = result->GetSize() - 1;
728 while (TRUE) {
729 if ((codeword & 0x1) != previousValue) {
730 previousValue = codeword & 0x1;
731 i--;
732 if (i < 0) {
733 break;
734 }
735 }
736 result->SetAt(i, result->GetAt(i) + 1);
737 codeword >>= 1;
738 }
739 return result;
740 }
741 int32_t CBC_PDF417ScanningDecoder::getCodewordBucketNumber(int32_t codeword) {
742 CFX_Int32Array* array = getBitCountForCodeword(codeword);
743 int32_t result = getCodewordBucketNumber(*array);
744 delete array;
745 return result;
746 }
747 int32_t CBC_PDF417ScanningDecoder::getCodewordBucketNumber(
748 CFX_Int32Array& moduleBitCount) {
749 return (moduleBitCount.GetAt(0) - moduleBitCount.GetAt(2) +
750 moduleBitCount.GetAt(4) - moduleBitCount.GetAt(6) + 9) %
751 9;
752 }
OLDNEW
« no previous file with comments | « xfa/src/fxbarcode/pdf417/BC_PDF417ScanningDecoder.h ('k') | xfa/src/fxbarcode/pdf417/BC_PDF417Writer.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698