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