Toolkit.UI.Controls.Avalonia
This commit is contained in:
@@ -0,0 +1,114 @@
|
||||
using System;
|
||||
using Gma.QrCodeNet.Encoding.Masking;
|
||||
|
||||
namespace Gma.QrCodeNet.Encoding.EncodingRegion;
|
||||
|
||||
/// <summary>
|
||||
/// 6.9 Format information
|
||||
/// The Format Information is a 15 bit sequence containing 5 data bits, with 10 error correction bits calculated using the (15, 5) BCH code.
|
||||
/// </summary>
|
||||
/// <remarks>ISO/IEC 18004:2000 Chapter 8.9 Page 53</remarks>
|
||||
internal static class FormatInformation
|
||||
{
|
||||
/// <summary>
|
||||
/// From Appendix C in JISX0510:2004 (p.65).
|
||||
/// </summary>
|
||||
private const int FormatInfoPoly = 0x537;
|
||||
|
||||
/// <summary>
|
||||
/// From Appendix C in JISX0510:2004 (p.65).
|
||||
/// </summary>
|
||||
private const int FormatInfoMaskPattern = 0x5412;
|
||||
|
||||
/// <summary>
|
||||
/// Embed format information to tristatematrix.
|
||||
/// Process combination of create info bits, BCH error correction bits calculation, embed towards matrix.
|
||||
/// </summary>
|
||||
/// <remarks>ISO/IEC 18004:2000 Chapter 8.9 Page 53</remarks>
|
||||
internal static void EmbedFormatInformation(this TriStateMatrix triMatrix, ErrorCorrectionLevel errorLevel, Pattern pattern)
|
||||
{
|
||||
BitList formatInfo = GetFormatInfoBits(errorLevel, pattern);
|
||||
int width = triMatrix.Width;
|
||||
for (int index = 0; index < 15; index++)
|
||||
{
|
||||
MatrixPoint point = PointForInfo1(index);
|
||||
bool bit = formatInfo[index];
|
||||
triMatrix[point.X, point.Y, MatrixStatus.NoMask] = bit;
|
||||
|
||||
if (index < 7)
|
||||
{
|
||||
triMatrix[8, width - 1 - index, MatrixStatus.NoMask] = bit;
|
||||
}
|
||||
else
|
||||
{
|
||||
triMatrix[width - 8 + (index - 7), 8, MatrixStatus.NoMask] = bit;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static MatrixPoint PointForInfo1(int bitsIndex)
|
||||
{
|
||||
if (bitsIndex <= 7)
|
||||
{
|
||||
return bitsIndex >= 6
|
||||
? new MatrixPoint(bitsIndex + 1, 8)
|
||||
: new MatrixPoint(bitsIndex, 8);
|
||||
}
|
||||
else
|
||||
{
|
||||
return bitsIndex == 8
|
||||
? new MatrixPoint(8, 8 - (bitsIndex - 7))
|
||||
: new MatrixPoint(8, 8 - (bitsIndex - 7) - 1);
|
||||
}
|
||||
}
|
||||
|
||||
private static BitList GetFormatInfoBits(ErrorCorrectionLevel errorLevel, Pattern pattern)
|
||||
{
|
||||
int formatInfo = (int)pattern.MaskPatternType;
|
||||
|
||||
// Pattern bits length = 3
|
||||
formatInfo |= GetErrorCorrectionIndicatorBits(errorLevel) << 3;
|
||||
|
||||
int bchCode = BCHCalculator.CalculateBCH(formatInfo, FormatInfoPoly);
|
||||
|
||||
// bchCode length = 10
|
||||
formatInfo = (formatInfo << 10) | bchCode;
|
||||
|
||||
// xor maskPattern
|
||||
formatInfo ^= FormatInfoMaskPattern;
|
||||
|
||||
BitList resultBits = new()
|
||||
{
|
||||
{ formatInfo, 15 }
|
||||
};
|
||||
|
||||
if (resultBits.Count != 15)
|
||||
{
|
||||
throw new Exception("FormatInfoBits length is not 15");
|
||||
}
|
||||
else
|
||||
{
|
||||
return resultBits;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// According Table 25 — Error correction level indicators
|
||||
/// Using these bits as enum values would destroy their order which currently corresponds to error correction strength.
|
||||
/// </summary>
|
||||
internal static int GetErrorCorrectionIndicatorBits(ErrorCorrectionLevel errorLevel)
|
||||
{
|
||||
// L 01
|
||||
// M 00
|
||||
// Q 11
|
||||
// H 10
|
||||
return errorLevel switch
|
||||
{
|
||||
ErrorCorrectionLevel.H => 0x02,
|
||||
ErrorCorrectionLevel.L => 0x01,
|
||||
ErrorCorrectionLevel.M => 0x00,
|
||||
ErrorCorrectionLevel.Q => 0x03,
|
||||
_ => throw new ArgumentException($"Unsupported error correction level [{errorLevel}]", nameof(errorLevel))
|
||||
};
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user