diff options
Diffstat (limited to 'xfa/src/fxbarcode/pdf417/BC_PDF417DetectionResult.cpp')
-rw-r--r-- | xfa/src/fxbarcode/pdf417/BC_PDF417DetectionResult.cpp | 338 |
1 files changed, 338 insertions, 0 deletions
diff --git a/xfa/src/fxbarcode/pdf417/BC_PDF417DetectionResult.cpp b/xfa/src/fxbarcode/pdf417/BC_PDF417DetectionResult.cpp new file mode 100644 index 0000000000..ecb5f75134 --- /dev/null +++ b/xfa/src/fxbarcode/pdf417/BC_PDF417DetectionResult.cpp @@ -0,0 +1,338 @@ +// Copyright 2014 PDFium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com +// Original code is licensed as follows: +/* + * Copyright 2013 ZXing authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "xfa/src/fxbarcode/barcode.h" +#include "BC_PDF417Codeword.h" +#include "BC_PDF417BarcodeMetadata.h" +#include "BC_PDF417BoundingBox.h" +#include "BC_PDF417DetectionResultColumn.h" +#include "BC_PDF417Common.h" +#include "BC_PDF417DetectionResultRowIndicatorColumn.h" +#include "BC_PDF417DetectionResult.h" +int32_t CBC_DetectionResult::ADJUST_ROW_NUMBER_SKIP = 2; +CBC_DetectionResult::CBC_DetectionResult(CBC_BarcodeMetadata* barcodeMetadata, + CBC_BoundingBox* boundingBox) { + m_barcodeMetadata = barcodeMetadata; + m_barcodeColumnCount = barcodeMetadata->getColumnCount(); + m_boundingBox = boundingBox; + m_detectionResultColumns.SetSize(m_barcodeColumnCount + 2); + for (int32_t i = 0; i < m_barcodeColumnCount + 2; i++) { + m_detectionResultColumns[i] = NULL; + } +} +CBC_DetectionResult::~CBC_DetectionResult() { + delete m_boundingBox; + delete m_barcodeMetadata; + m_detectionResultColumns.RemoveAll(); +} +CFX_PtrArray& CBC_DetectionResult::getDetectionResultColumns() { + adjustIndicatorColumnRowNumbers( + (CBC_DetectionResultColumn*)m_detectionResultColumns.GetAt(0)); + adjustIndicatorColumnRowNumbers( + (CBC_DetectionResultColumn*)m_detectionResultColumns.GetAt( + m_barcodeColumnCount + 1)); + int32_t unadjustedCodewordCount = CBC_PDF417Common::MAX_CODEWORDS_IN_BARCODE; + int32_t previousUnadjustedCount; + do { + previousUnadjustedCount = unadjustedCodewordCount; + unadjustedCodewordCount = adjustRowNumbers(); + } while (unadjustedCodewordCount > 0 && + unadjustedCodewordCount < previousUnadjustedCount); + return m_detectionResultColumns; +} +void CBC_DetectionResult::setBoundingBox(CBC_BoundingBox* boundingBox) { + m_boundingBox = boundingBox; +} +CBC_BoundingBox* CBC_DetectionResult::getBoundingBox() { + return m_boundingBox; +} +void CBC_DetectionResult::setDetectionResultColumn( + int32_t barcodeColumn, + CBC_DetectionResultColumn* detectionResultColumn) { + m_detectionResultColumns[barcodeColumn] = detectionResultColumn; +} +CBC_DetectionResultColumn* CBC_DetectionResult::getDetectionResultColumn( + int32_t barcodeColumn) { + return (CBC_DetectionResultColumn*)m_detectionResultColumns[barcodeColumn]; +} +CFX_ByteString CBC_DetectionResult::toString() { + CBC_DetectionResultColumn* rowIndicatorColumn = + (CBC_DetectionResultColumn*)m_detectionResultColumns[0]; + if (rowIndicatorColumn == NULL) { + rowIndicatorColumn = (CBC_DetectionResultColumn*) + m_detectionResultColumns[m_barcodeColumnCount + 1]; + } + CFX_ByteString result; + for (int32_t codewordsRow = 0; + codewordsRow < rowIndicatorColumn->getCodewords()->GetSize(); + codewordsRow++) { + result += (FX_CHAR)codewordsRow; + for (int32_t barcodeColumn = 0; barcodeColumn < m_barcodeColumnCount + 2; + barcodeColumn++) { + if (m_detectionResultColumns[barcodeColumn] == NULL) { + result += " | "; + continue; + } + CBC_Codeword* codeword = + (CBC_Codeword*)((CBC_DetectionResultColumn*) + m_detectionResultColumns[barcodeColumn]) + ->getCodewords() + ->GetAt(codewordsRow); + if (codeword == NULL) { + result += " | "; + continue; + } + result += codeword->getRowNumber(); + result += codeword->getValue(); + } + } + return result; +} +void CBC_DetectionResult::adjustIndicatorColumnRowNumbers( + CBC_DetectionResultColumn* detectionResultColumn) { + if (detectionResultColumn != NULL) { + ((CBC_DetectionResultRowIndicatorColumn*)detectionResultColumn) + ->adjustCompleteIndicatorColumnRowNumbers(*m_barcodeMetadata); + } +} +int32_t CBC_DetectionResult::adjustRowNumbers() { + int32_t unadjustedCount = adjustRowNumbersByRow(); + if (unadjustedCount == 0) { + return 0; + } + for (int32_t barcodeColumn = 1; barcodeColumn < m_barcodeColumnCount + 1; + barcodeColumn++) { + CFX_PtrArray* codewords = + ((CBC_DetectionResultColumn*)m_detectionResultColumns[barcodeColumn]) + ->getCodewords(); + for (int32_t codewordsRow = 0; codewordsRow < codewords->GetSize(); + codewordsRow++) { + if (codewords->GetAt(codewordsRow) == NULL) { + continue; + } + if (!((CBC_Codeword*)codewords->GetAt(codewordsRow)) + ->hasValidRowNumber()) { + adjustRowNumbers(barcodeColumn, codewordsRow, codewords); + } + } + } + return unadjustedCount; +} +int32_t CBC_DetectionResult::adjustRowNumbersByRow() { + adjustRowNumbersFromBothRI(); + int32_t unadjustedCount = adjustRowNumbersFromLRI(); + return unadjustedCount + adjustRowNumbersFromRRI(); +} +int32_t CBC_DetectionResult::adjustRowNumbersFromBothRI() { + if (m_detectionResultColumns[0] == NULL || + m_detectionResultColumns[m_barcodeColumnCount + 1] == NULL) { + return 0; + } + CFX_PtrArray* LRIcodewords = + ((CBC_DetectionResultColumn*)m_detectionResultColumns[0])->getCodewords(); + CFX_PtrArray* RRIcodewords = + ((CBC_DetectionResultColumn*) + m_detectionResultColumns[m_barcodeColumnCount + 1]) + ->getCodewords(); + for (int32_t codewordsRow = 0; codewordsRow < LRIcodewords->GetSize(); + codewordsRow++) { + if (LRIcodewords->GetAt(codewordsRow) != NULL && + RRIcodewords->GetAt(codewordsRow) != NULL && + ((CBC_Codeword*)LRIcodewords->GetAt(codewordsRow))->getRowNumber() == + ((CBC_Codeword*)RRIcodewords->GetAt(codewordsRow)) + ->getRowNumber()) { + for (int32_t barcodeColumn = 1; barcodeColumn <= m_barcodeColumnCount; + barcodeColumn++) { + CBC_Codeword* codeword = + (CBC_Codeword*)((CBC_DetectionResultColumn*) + m_detectionResultColumns[barcodeColumn]) + ->getCodewords() + ->GetAt(codewordsRow); + if (codeword == NULL) { + continue; + } + codeword->setRowNumber( + ((CBC_Codeword*)LRIcodewords->GetAt(codewordsRow))->getRowNumber()); + if (!codeword->hasValidRowNumber()) { + ((CBC_DetectionResultColumn*)m_detectionResultColumns[barcodeColumn]) + ->getCodewords() + ->SetAt(codewordsRow, NULL); + } + } + } + } + return 0; +} +int32_t CBC_DetectionResult::adjustRowNumbersFromRRI() { + if (m_detectionResultColumns[m_barcodeColumnCount + 1] == NULL) { + return 0; + } + int32_t unadjustedCount = 0; + CFX_PtrArray* codewords = + ((CBC_DetectionResultColumn*)m_detectionResultColumns.GetAt( + m_barcodeColumnCount + 1)) + ->getCodewords(); + for (int32_t codewordsRow = 0; codewordsRow < codewords->GetSize(); + codewordsRow++) { + if (codewords->GetAt(codewordsRow) == NULL) { + continue; + } + int32_t rowIndicatorRowNumber = + ((CBC_Codeword*)codewords->GetAt(codewordsRow))->getRowNumber(); + int32_t invalidRowCounts = 0; + for (int32_t barcodeColumn = m_barcodeColumnCount + 1; + barcodeColumn > 0 && invalidRowCounts < ADJUST_ROW_NUMBER_SKIP; + barcodeColumn--) { + CBC_Codeword* codeword = + (CBC_Codeword*)((CBC_DetectionResultColumn*) + m_detectionResultColumns.GetAt(barcodeColumn)) + ->getCodewords() + ->GetAt(codewordsRow); + if (codeword != NULL) { + invalidRowCounts = adjustRowNumberIfValid(rowIndicatorRowNumber, + invalidRowCounts, codeword); + if (!codeword->hasValidRowNumber()) { + unadjustedCount++; + } + } + } + } + return unadjustedCount; +} +int32_t CBC_DetectionResult::adjustRowNumbersFromLRI() { + if (m_detectionResultColumns[0] == NULL) { + return 0; + } + int32_t unadjustedCount = 0; + CFX_PtrArray* codewords = + ((CBC_DetectionResultColumn*)m_detectionResultColumns.GetAt(0)) + ->getCodewords(); + for (int32_t codewordsRow = 0; codewordsRow < codewords->GetSize(); + codewordsRow++) { + if (codewords->GetAt(codewordsRow) == NULL) { + continue; + } + int32_t rowIndicatorRowNumber = + ((CBC_Codeword*)codewords->GetAt(codewordsRow))->getRowNumber(); + int32_t invalidRowCounts = 0; + for (int32_t barcodeColumn = 1; barcodeColumn < m_barcodeColumnCount + 1 && + invalidRowCounts < ADJUST_ROW_NUMBER_SKIP; + barcodeColumn++) { + CBC_Codeword* codeword = + (CBC_Codeword*)((CBC_DetectionResultColumn*) + m_detectionResultColumns[barcodeColumn]) + ->getCodewords() + ->GetAt(codewordsRow); + if (codeword != NULL) { + invalidRowCounts = adjustRowNumberIfValid(rowIndicatorRowNumber, + invalidRowCounts, codeword); + if (!codeword->hasValidRowNumber()) { + unadjustedCount++; + } + } + } + } + return unadjustedCount; +} +int32_t CBC_DetectionResult::adjustRowNumberIfValid( + int32_t rowIndicatorRowNumber, + int32_t invalidRowCounts, + CBC_Codeword* codeword) { + if (codeword == NULL) { + return invalidRowCounts; + } + if (!codeword->hasValidRowNumber()) { + if (codeword->isValidRowNumber(rowIndicatorRowNumber)) { + codeword->setRowNumber(rowIndicatorRowNumber); + invalidRowCounts = 0; + } else { + ++invalidRowCounts; + } + } + return invalidRowCounts; +} +void CBC_DetectionResult::adjustRowNumbers(int32_t barcodeColumn, + int32_t codewordsRow, + CFX_PtrArray* codewords) { + CBC_Codeword* codeword = (CBC_Codeword*)codewords->GetAt(codewordsRow); + CFX_PtrArray* previousColumnCodewords = + ((CBC_DetectionResultColumn*)m_detectionResultColumns.GetAt( + barcodeColumn - 1)) + ->getCodewords(); + CFX_PtrArray* nextColumnCodewords = previousColumnCodewords; + if (m_detectionResultColumns[barcodeColumn + 1] != NULL) { + nextColumnCodewords = ((CBC_DetectionResultColumn*) + m_detectionResultColumns[barcodeColumn + 1]) + ->getCodewords(); + } + CFX_PtrArray otherCodewords; + otherCodewords.SetSize(14); + otherCodewords[2] = previousColumnCodewords->GetAt(codewordsRow); + otherCodewords[3] = nextColumnCodewords->GetAt(codewordsRow); + if (codewordsRow > 0) { + otherCodewords[0] = codewords->GetAt(codewordsRow - 1); + otherCodewords[4] = previousColumnCodewords->GetAt(codewordsRow - 1); + otherCodewords[5] = nextColumnCodewords->GetAt(codewordsRow - 1); + } + if (codewordsRow > 1) { + otherCodewords[8] = codewords->GetAt(codewordsRow - 2); + otherCodewords[10] = previousColumnCodewords->GetAt(codewordsRow - 2); + otherCodewords[11] = nextColumnCodewords->GetAt(codewordsRow - 2); + } + if (codewordsRow < codewords->GetSize() - 1) { + otherCodewords[1] = codewords->GetAt(codewordsRow + 1); + otherCodewords[6] = previousColumnCodewords->GetAt(codewordsRow + 1); + otherCodewords[7] = nextColumnCodewords->GetAt(codewordsRow + 1); + } + if (codewordsRow < codewords->GetSize() - 2) { + otherCodewords[9] = codewords->GetAt(codewordsRow + 2); + otherCodewords[12] = previousColumnCodewords->GetAt(codewordsRow + 2); + otherCodewords[13] = nextColumnCodewords->GetAt(codewordsRow + 2); + } + for (int32_t i = 0; i < otherCodewords.GetSize(); i++) { + CBC_Codeword* otherCodeword = (CBC_Codeword*)otherCodewords.GetAt(i); + if (adjustRowNumber(codeword, otherCodeword)) { + return; + } + } +} +FX_BOOL CBC_DetectionResult::adjustRowNumber(CBC_Codeword* codeword, + CBC_Codeword* otherCodeword) { + if (otherCodeword == NULL) { + return FALSE; + } + if (otherCodeword->hasValidRowNumber() && + otherCodeword->getBucket() == codeword->getBucket()) { + codeword->setRowNumber(otherCodeword->getRowNumber()); + return TRUE; + } + return FALSE; +} +int32_t CBC_DetectionResult::getBarcodeColumnCount() { + return m_barcodeColumnCount; +} +int32_t CBC_DetectionResult::getBarcodeRowCount() { + return m_barcodeMetadata->getRowCount(); +} +int32_t CBC_DetectionResult::getBarcodeECLevel() { + return m_barcodeMetadata->getErrorCorrectionLevel(); +} |