mirror of
https://gitee.com/akwkevin/aistudio.-wpf.-diagram
synced 2026-04-23 09:56:36 +08:00
添加项目文件。
This commit is contained in:
379
zxing.core/xx/pdf417/decoder/DetectionResult.cs
Normal file
379
zxing.core/xx/pdf417/decoder/DetectionResult.cs
Normal file
@@ -0,0 +1,379 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
using System.Globalization;
|
||||
using System.Text;
|
||||
|
||||
namespace ZXing.PDF417.Internal
|
||||
{
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <author>Guenther Grau</author>
|
||||
public class DetectionResult
|
||||
{
|
||||
private const int ADJUST_ROW_NUMBER_SKIP = 2;
|
||||
|
||||
public BarcodeMetadata Metadata { get; private set; }
|
||||
public DetectionResultColumn[] DetectionResultColumns { get; set; }
|
||||
public BoundingBox Box { get; set; }
|
||||
public int ColumnCount { get; private set; }
|
||||
|
||||
public int RowCount
|
||||
{
|
||||
get { return Metadata.RowCount; }
|
||||
}
|
||||
|
||||
public int ErrorCorrectionLevel
|
||||
{
|
||||
get { return Metadata.ErrorCorrectionLevel; }
|
||||
}
|
||||
|
||||
public DetectionResult(BarcodeMetadata metadata, BoundingBox box)
|
||||
{
|
||||
Metadata = metadata;
|
||||
Box = box;
|
||||
ColumnCount = metadata.ColumnCount;
|
||||
DetectionResultColumns = new DetectionResultColumn[ColumnCount + 2];
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns the DetectionResult Columns. This does a fair bit of calculation, so call it sparingly.
|
||||
/// </summary>
|
||||
/// <returns>The detection result columns.</returns>
|
||||
public DetectionResultColumn[] getDetectionResultColumns()
|
||||
{
|
||||
adjustIndicatorColumnRowNumbers(DetectionResultColumns[0]);
|
||||
adjustIndicatorColumnRowNumbers(DetectionResultColumns[ColumnCount + 1]);
|
||||
int unadjustedCodewordCount = PDF417Common.MAX_CODEWORDS_IN_BARCODE;
|
||||
int previousUnadjustedCount;
|
||||
do
|
||||
{
|
||||
previousUnadjustedCount = unadjustedCodewordCount;
|
||||
unadjustedCodewordCount = adjustRowNumbers();
|
||||
} while (unadjustedCodewordCount > 0 && unadjustedCodewordCount < previousUnadjustedCount);
|
||||
return DetectionResultColumns;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Adjusts the indicator column row numbers.
|
||||
/// </summary>
|
||||
/// <param name="detectionResultColumn">Detection result column.</param>
|
||||
private void adjustIndicatorColumnRowNumbers(DetectionResultColumn detectionResultColumn)
|
||||
{
|
||||
if (detectionResultColumn != null)
|
||||
{
|
||||
((DetectionResultRowIndicatorColumn) detectionResultColumn)
|
||||
.adjustCompleteIndicatorColumnRowNumbers(Metadata);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// return number of codewords which don't have a valid row number. Note that the count is not accurate as codewords .
|
||||
/// will be counted several times. It just serves as an indicator to see when we can stop adjusting row numbers
|
||||
/// </summary>
|
||||
/// <returns>The row numbers.</returns>
|
||||
private int adjustRowNumbers()
|
||||
{
|
||||
// TODO ensure that no detected codewords with unknown row number are left
|
||||
// we should be able to estimate the row height and use it as a hint for the row number
|
||||
// we should also fill the rows top to bottom and bottom to top
|
||||
int unadjustedCount = adjustRowNumbersByRow();
|
||||
if (unadjustedCount == 0)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
for (int barcodeColumn = 1; barcodeColumn < ColumnCount + 1; barcodeColumn++)
|
||||
{
|
||||
Codeword[] codewords = DetectionResultColumns[barcodeColumn].Codewords;
|
||||
for (int codewordsRow = 0; codewordsRow < codewords.Length; codewordsRow++)
|
||||
{
|
||||
if (codewords[codewordsRow] == null)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
if (!codewords[codewordsRow].HasValidRowNumber)
|
||||
{
|
||||
adjustRowNumbers(barcodeColumn, codewordsRow, codewords);
|
||||
}
|
||||
}
|
||||
}
|
||||
return unadjustedCount;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Adjusts the row numbers by row.
|
||||
/// </summary>
|
||||
/// <returns>The row numbers by row.</returns>
|
||||
private int adjustRowNumbersByRow()
|
||||
{
|
||||
adjustRowNumbersFromBothRI(); // RI = RowIndicators
|
||||
// TODO we should only do full row adjustments if row numbers of left and right row indicator column match.
|
||||
// Maybe it's even better to calculated the height (in codeword rows) and divide it by the number of barcode
|
||||
// rows. This, together with the LRI and RRI row numbers should allow us to get a good estimate where a row
|
||||
// number starts and ends.
|
||||
int unadjustedCount = adjustRowNumbersFromLRI();
|
||||
return unadjustedCount + adjustRowNumbersFromRRI();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Adjusts the row numbers from both Row Indicators
|
||||
/// </summary>
|
||||
/// <returns> zero </returns>
|
||||
private void adjustRowNumbersFromBothRI()
|
||||
{
|
||||
if (DetectionResultColumns[0] == null || DetectionResultColumns[ColumnCount + 1] == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
Codeword[] LRIcodewords = DetectionResultColumns[0].Codewords;
|
||||
Codeword[] RRIcodewords = DetectionResultColumns[ColumnCount + 1].Codewords;
|
||||
for (int codewordsRow = 0; codewordsRow < LRIcodewords.Length; codewordsRow++)
|
||||
{
|
||||
if (LRIcodewords[codewordsRow] != null &&
|
||||
RRIcodewords[codewordsRow] != null &&
|
||||
LRIcodewords[codewordsRow].RowNumber == RRIcodewords[codewordsRow].RowNumber)
|
||||
{
|
||||
for (int barcodeColumn = 1; barcodeColumn <= ColumnCount; barcodeColumn++)
|
||||
{
|
||||
Codeword codeword = DetectionResultColumns[barcodeColumn].Codewords[codewordsRow];
|
||||
if (codeword == null)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
codeword.RowNumber = LRIcodewords[codewordsRow].RowNumber;
|
||||
if (!codeword.HasValidRowNumber)
|
||||
{
|
||||
// LOG.info("Removing codeword with invalid row number, cw[" + codewordsRow + "][" + barcodeColumn + "]");
|
||||
DetectionResultColumns[barcodeColumn].Codewords[codewordsRow] = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Adjusts the row numbers from Right Row Indicator.
|
||||
/// </summary>
|
||||
/// <returns>The unadjusted row count.</returns>
|
||||
private int adjustRowNumbersFromRRI()
|
||||
{
|
||||
if (DetectionResultColumns[ColumnCount + 1] == null)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
int unadjustedCount = 0;
|
||||
Codeword[] codewords = DetectionResultColumns[ColumnCount + 1].Codewords;
|
||||
for (int codewordsRow = 0; codewordsRow < codewords.Length; codewordsRow++)
|
||||
{
|
||||
if (codewords[codewordsRow] == null)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
int rowIndicatorRowNumber = codewords[codewordsRow].RowNumber;
|
||||
int invalidRowCounts = 0;
|
||||
for (int barcodeColumn = ColumnCount + 1; barcodeColumn > 0 && invalidRowCounts < ADJUST_ROW_NUMBER_SKIP; barcodeColumn--)
|
||||
{
|
||||
Codeword codeword = DetectionResultColumns[barcodeColumn].Codewords[codewordsRow];
|
||||
if (codeword != null)
|
||||
{
|
||||
invalidRowCounts = adjustRowNumberIfValid(rowIndicatorRowNumber, invalidRowCounts, codeword);
|
||||
if (!codeword.HasValidRowNumber)
|
||||
{
|
||||
unadjustedCount++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return unadjustedCount;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Adjusts the row numbers from Left Row Indicator.
|
||||
/// </summary>
|
||||
/// <returns> Unadjusted row Count.</returns>
|
||||
private int adjustRowNumbersFromLRI()
|
||||
{
|
||||
if (DetectionResultColumns[0] == null)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
int unadjustedCount = 0;
|
||||
Codeword[] codewords = DetectionResultColumns[0].Codewords;
|
||||
for (int codewordsRow = 0; codewordsRow < codewords.Length; codewordsRow++)
|
||||
{
|
||||
if (codewords[codewordsRow] == null)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
int rowIndicatorRowNumber = codewords[codewordsRow].RowNumber;
|
||||
int invalidRowCounts = 0;
|
||||
for (int barcodeColumn = 1; barcodeColumn < ColumnCount + 1 && invalidRowCounts < ADJUST_ROW_NUMBER_SKIP; barcodeColumn++)
|
||||
{
|
||||
Codeword codeword = DetectionResultColumns[barcodeColumn].Codewords[codewordsRow];
|
||||
if (codeword != null)
|
||||
{
|
||||
invalidRowCounts = adjustRowNumberIfValid(rowIndicatorRowNumber, invalidRowCounts, codeword);
|
||||
if (!codeword.HasValidRowNumber)
|
||||
{
|
||||
unadjustedCount++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return unadjustedCount;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Adjusts the row number if valid.
|
||||
/// </summary>
|
||||
/// <returns>The invalid rows</returns>
|
||||
/// <param name="rowIndicatorRowNumber">Row indicator row number.</param>
|
||||
/// <param name="invalidRowCounts">Invalid row counts.</param>
|
||||
/// <param name="codeword">Codeword.</param>
|
||||
private static int adjustRowNumberIfValid(int rowIndicatorRowNumber, int invalidRowCounts, Codeword codeword)
|
||||
{
|
||||
|
||||
if (codeword == null)
|
||||
{
|
||||
return invalidRowCounts;
|
||||
}
|
||||
if (!codeword.HasValidRowNumber)
|
||||
{
|
||||
if (codeword.IsValidRowNumber(rowIndicatorRowNumber))
|
||||
{
|
||||
codeword.RowNumber = rowIndicatorRowNumber;
|
||||
invalidRowCounts = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
++invalidRowCounts;
|
||||
}
|
||||
}
|
||||
return invalidRowCounts;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Adjusts the row numbers.
|
||||
/// </summary>
|
||||
/// <param name="barcodeColumn">Barcode column.</param>
|
||||
/// <param name="codewordsRow">Codewords row.</param>
|
||||
/// <param name="codewords">Codewords.</param>
|
||||
private void adjustRowNumbers(int barcodeColumn, int codewordsRow, Codeword[] codewords)
|
||||
{
|
||||
Codeword codeword = codewords[codewordsRow];
|
||||
Codeword[] previousColumnCodewords = DetectionResultColumns[barcodeColumn - 1].Codewords;
|
||||
Codeword[] nextColumnCodewords = previousColumnCodewords;
|
||||
if (DetectionResultColumns[barcodeColumn + 1] != null)
|
||||
{
|
||||
nextColumnCodewords = DetectionResultColumns[barcodeColumn + 1].Codewords;
|
||||
}
|
||||
|
||||
Codeword[] otherCodewords = new Codeword[14];
|
||||
|
||||
otherCodewords[2] = previousColumnCodewords[codewordsRow];
|
||||
otherCodewords[3] = nextColumnCodewords[codewordsRow];
|
||||
|
||||
if (codewordsRow > 0)
|
||||
{
|
||||
otherCodewords[0] = codewords[codewordsRow - 1];
|
||||
otherCodewords[4] = previousColumnCodewords[codewordsRow - 1];
|
||||
otherCodewords[5] = nextColumnCodewords[codewordsRow - 1];
|
||||
}
|
||||
if (codewordsRow > 1)
|
||||
{
|
||||
otherCodewords[8] = codewords[codewordsRow - 2];
|
||||
otherCodewords[10] = previousColumnCodewords[codewordsRow - 2];
|
||||
otherCodewords[11] = nextColumnCodewords[codewordsRow - 2];
|
||||
}
|
||||
if (codewordsRow < codewords.Length - 1)
|
||||
{
|
||||
otherCodewords[1] = codewords[codewordsRow + 1];
|
||||
otherCodewords[6] = previousColumnCodewords[codewordsRow + 1];
|
||||
otherCodewords[7] = nextColumnCodewords[codewordsRow + 1];
|
||||
}
|
||||
if (codewordsRow < codewords.Length - 2)
|
||||
{
|
||||
otherCodewords[9] = codewords[codewordsRow + 2];
|
||||
otherCodewords[12] = previousColumnCodewords[codewordsRow + 2];
|
||||
otherCodewords[13] = nextColumnCodewords[codewordsRow + 2];
|
||||
}
|
||||
foreach (Codeword otherCodeword in otherCodewords)
|
||||
{
|
||||
if (adjustRowNumber(codeword, otherCodeword))
|
||||
{
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Adjusts the row number.
|
||||
/// </summary>
|
||||
/// <returns><c>true</c>, if row number was adjusted, <c>false</c> otherwise.</returns>
|
||||
/// <param name="codeword">Codeword.</param>
|
||||
/// <param name="otherCodeword">Other codeword.</param>
|
||||
private static bool adjustRowNumber(Codeword codeword, Codeword otherCodeword)
|
||||
{
|
||||
if (otherCodeword == null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
if (otherCodeword.HasValidRowNumber && otherCodeword.Bucket == codeword.Bucket)
|
||||
{
|
||||
codeword.RowNumber = otherCodeword.RowNumber;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns a <see cref="System.String"/> that represents the current <see cref="ZXing.PDF417.Internal.DetectionResult"/>.
|
||||
/// </summary>
|
||||
/// <returns>A <see cref="System.String"/> that represents the current <see cref="ZXing.PDF417.Internal.DetectionResult"/>.</returns>
|
||||
public override string ToString()
|
||||
{
|
||||
StringBuilder formatter = new StringBuilder();
|
||||
DetectionResultColumn rowIndicatorColumn = DetectionResultColumns[0];
|
||||
if (rowIndicatorColumn == null)
|
||||
{
|
||||
rowIndicatorColumn = DetectionResultColumns[ColumnCount + 1];
|
||||
}
|
||||
for (int codewordsRow = 0; codewordsRow < rowIndicatorColumn.Codewords.Length; codewordsRow++)
|
||||
{
|
||||
formatter.AppendFormat(CultureInfo.InvariantCulture, "CW {0,3}:", codewordsRow);
|
||||
for (int barcodeColumn = 0; barcodeColumn < ColumnCount + 2; barcodeColumn++)
|
||||
{
|
||||
if (DetectionResultColumns[barcodeColumn] == null)
|
||||
{
|
||||
formatter.Append(" | ");
|
||||
continue;
|
||||
}
|
||||
Codeword codeword = DetectionResultColumns[barcodeColumn].Codewords[codewordsRow];
|
||||
if (codeword == null)
|
||||
{
|
||||
formatter.Append(" | ");
|
||||
continue;
|
||||
}
|
||||
formatter.AppendFormat(CultureInfo.InvariantCulture, " {0,3}|{1,3}", codeword.RowNumber, codeword.Value);
|
||||
}
|
||||
formatter.Append("\n");
|
||||
}
|
||||
|
||||
return formatter.ToString();
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user