int32_t CBC_DetectionResultRowIndicatorColumn::adjustCompleteIndicatorColumnRowNumbers( CBC_BarcodeMetadata barcodeMetadata) { CFX_PtrArray* codewords = getCodewords(); setRowNumbers(); removeIncorrectCodewords(codewords, barcodeMetadata); CBC_BoundingBox* boundingBox = getBoundingBox(); CBC_ResultPoint* top = m_isLeft ? boundingBox->getTopLeft() : boundingBox->getTopRight(); CBC_ResultPoint* bottom = m_isLeft ? boundingBox->getBottomLeft() : boundingBox->getBottomRight(); int32_t firstRow = imageRowToCodewordIndex((int32_t)top->GetY()); int32_t lastRow = imageRowToCodewordIndex((int32_t)bottom->GetY()); FX_FLOAT averageRowHeight = (lastRow - firstRow) / (FX_FLOAT)barcodeMetadata.getRowCount(); int32_t barcodeRow = -1; int32_t maxRowHeight = 1; int32_t currentRowHeight = 0; for (int32_t codewordsRow = firstRow; codewordsRow < lastRow; codewordsRow++) { if (codewords->GetAt(codewordsRow) == NULL) { continue; } CBC_Codeword* codeword = (CBC_Codeword*)codewords->GetAt(codewordsRow); int32_t rowDifference = codeword->getRowNumber() - barcodeRow; if (rowDifference == 0) { currentRowHeight++; } else if (rowDifference == 1) { maxRowHeight = maxRowHeight > currentRowHeight ? maxRowHeight : currentRowHeight; currentRowHeight = 1; barcodeRow = codeword->getRowNumber(); } else if (rowDifference < 0) { codewords->SetAt(codewordsRow, NULL); } else if (codeword->getRowNumber() >= barcodeMetadata.getRowCount()) { codewords->SetAt(codewordsRow, NULL); } else if (rowDifference > codewordsRow) { codewords->SetAt(codewordsRow, NULL); } else { int32_t checkedRows; if (maxRowHeight > 2) { checkedRows = (maxRowHeight - 2) * rowDifference; } else { checkedRows = rowDifference; } FX_BOOL closePreviousCodewordFound = checkedRows >= codewordsRow; for (int32_t i = 1; i <= checkedRows && !closePreviousCodewordFound; i++) { closePreviousCodewordFound = codewords->GetAt(codewordsRow - i) != NULL; } if (closePreviousCodewordFound) { codewords->SetAt(codewordsRow, NULL); } else { barcodeRow = codeword->getRowNumber(); currentRowHeight = 1; } } } return (int32_t)(averageRowHeight + 0.5); }
int32_t CBC_DetectionResultRowIndicatorColumn:: adjustIncompleteIndicatorColumnRowNumbers( CBC_BarcodeMetadata barcodeMetadata) { CBC_BoundingBox* boundingBox = getBoundingBox(); CBC_ResultPoint* top = m_isLeft ? boundingBox->getTopLeft() : boundingBox->getTopRight(); CBC_ResultPoint* bottom = m_isLeft ? boundingBox->getBottomLeft() : boundingBox->getBottomRight(); int32_t firstRow = imageRowToCodewordIndex((int32_t)top->GetY()); int32_t lastRow = imageRowToCodewordIndex((int32_t)bottom->GetY()); FX_FLOAT averageRowHeight = (lastRow - firstRow) / (FX_FLOAT)barcodeMetadata.getRowCount(); CFX_PtrArray* codewords = getCodewords(); int32_t barcodeRow = -1; int32_t maxRowHeight = 1; int32_t currentRowHeight = 0; for (int32_t codewordsRow = firstRow; codewordsRow < lastRow; codewordsRow++) { if (codewords->GetAt(codewordsRow) == NULL) { continue; } CBC_Codeword* codeword = (CBC_Codeword*)codewords->GetAt(codewordsRow); codeword->setRowNumberAsRowIndicatorColumn(); int32_t rowDifference = codeword->getRowNumber() - barcodeRow; if (rowDifference == 0) { currentRowHeight++; } else if (rowDifference == 1) { maxRowHeight = maxRowHeight > currentRowHeight ? maxRowHeight : currentRowHeight; currentRowHeight = 1; barcodeRow = codeword->getRowNumber(); } else if (codeword->getRowNumber() >= barcodeMetadata.getRowCount()) { codewords->SetAt(codewordsRow, NULL); } else { barcodeRow = codeword->getRowNumber(); currentRowHeight = 1; } } return (int32_t)(averageRowHeight + 0.5); }
CFX_PtrArray* CBC_Detector::findRowsWithPattern(CBC_CommonBitMatrix* matrix, int32_t height, int32_t width, int32_t startRow, int32_t startColumn, int32_t* pattern, int32_t patternLength) { CFX_PtrArray* result = new CFX_PtrArray; result->SetSize(4); FX_BOOL found = FALSE; CFX_Int32Array counters; counters.SetSize(patternLength); for (; startRow < height; startRow += ROW_STEP) { CFX_Int32Array* loc = findGuardPattern(matrix, startColumn, startRow, width, FALSE, pattern, patternLength, counters); if (loc != NULL) { while (startRow > 0) { CFX_Int32Array* previousRowLoc = findGuardPattern(matrix, startColumn, --startRow, width, FALSE, pattern, patternLength, counters); if (previousRowLoc != NULL) { delete loc; loc = previousRowLoc; } else { startRow++; break; } } result->SetAt( 0, new CBC_ResultPoint((FX_FLOAT)loc->GetAt(0), (FX_FLOAT)startRow)); result->SetAt( 1, new CBC_ResultPoint((FX_FLOAT)loc->GetAt(1), (FX_FLOAT)startRow)); found = TRUE; delete loc; break; } } int32_t stopRow = startRow + 1; if (found) { int32_t skippedRowCount = 0; CFX_Int32Array previousRowLoc; previousRowLoc.Add((int32_t)((CBC_ResultPoint*)result->GetAt(0))->GetX()); previousRowLoc.Add((int32_t)((CBC_ResultPoint*)result->GetAt(1))->GetX()); for (; stopRow < height; stopRow++) { CFX_Int32Array* loc = findGuardPattern(matrix, previousRowLoc[0], stopRow, width, FALSE, pattern, patternLength, counters); if (loc != NULL && abs(previousRowLoc[0] - loc->GetAt(0)) < MAX_PATTERN_DRIFT && abs(previousRowLoc[1] - loc->GetAt(1)) < MAX_PATTERN_DRIFT) { previousRowLoc.Copy(*loc); skippedRowCount = 0; } else { if (skippedRowCount > SKIPPED_ROW_COUNT_MAX) { delete loc; break; } else { skippedRowCount++; } } delete loc; } stopRow -= skippedRowCount + 1; result->SetAt(2, new CBC_ResultPoint((FX_FLOAT)previousRowLoc.GetAt(0), (FX_FLOAT)stopRow)); result->SetAt(3, new CBC_ResultPoint((FX_FLOAT)previousRowLoc.GetAt(1), (FX_FLOAT)stopRow)); } if (stopRow - startRow < BARCODE_MIN_HEIGHT) { for (int32_t i = 0; i < result->GetSize(); i++) { result->SetAt(i, NULL); } } return result; }