fckeuspy-go/vendor/github.com/makiuchi-d/gozxing/qrcode/decoder/version.go
2025-09-28 21:03:39 +02:00

388 lines
12 KiB
Go

package decoder
import (
"math"
"strconv"
errors "golang.org/x/xerrors"
"github.com/makiuchi-d/gozxing"
)
type Version struct {
versionNumber int
alignmentPatternCenters []int
ecBlocks []ECBlocks
totalCodewords int
}
var VERSION_DECODE_INFO = []int{
0x07C94, 0x085BC, 0x09A99, 0x0A4D3, 0x0BBF6,
0x0C762, 0x0D847, 0x0E60D, 0x0F928, 0x10B78,
0x1145D, 0x12A17, 0x13532, 0x149A6, 0x15683,
0x168C9, 0x177EC, 0x18EC4, 0x191E1, 0x1AFAB,
0x1B08E, 0x1CC1A, 0x1D33F, 0x1ED75, 0x1F250,
0x209D5, 0x216F0, 0x228BA, 0x2379F, 0x24B0B,
0x2542E, 0x26A64, 0x27541, 0x28C69,
}
func NewVersion(versionNumber int, alignmentPatternCenters []int, ecBlocks ...ECBlocks) *Version {
total := 0
ecCodewords := ecBlocks[0].GetECCodewordsPerBlock()
ecbArray := ecBlocks[0].GetECBlocks()
for _, ecBlock := range ecbArray {
total += ecBlock.GetCount() * (ecBlock.GetDataCodewords() + ecCodewords)
}
return &Version{
versionNumber,
alignmentPatternCenters,
ecBlocks,
total}
}
func (v *Version) GetVersionNumber() int {
return v.versionNumber
}
func (v *Version) GetAlignmentPatternCenters() []int {
return v.alignmentPatternCenters
}
func (v *Version) GetTotalCodewords() int {
return v.totalCodewords
}
func (v *Version) GetDimensionForVersion() int {
return 17 + 4*v.versionNumber
}
func (v *Version) GetECBlocksForLevel(ecLevel ErrorCorrectionLevel) *ECBlocks {
switch ecLevel {
case ErrorCorrectionLevel_L:
return &v.ecBlocks[0]
case ErrorCorrectionLevel_M:
return &v.ecBlocks[1]
case ErrorCorrectionLevel_Q:
return &v.ecBlocks[2]
case ErrorCorrectionLevel_H:
return &v.ecBlocks[3]
}
return nil
}
func Version_GetProvisionalVersionForDimension(dimension int) (*Version, error) {
if dimension%4 != 1 {
return nil, errors.Errorf("dimengion = %v", dimension)
}
return Version_GetVersionForNumber((dimension - 17) / 4)
}
func Version_GetVersionForNumber(versionNumber int) (*Version, error) {
if versionNumber < 1 || versionNumber > 40 {
return nil, errors.Errorf("IllegalArgumentException: versionNumber = %d", versionNumber)
}
return VERSIONS[versionNumber-1], nil
}
func Version_decodeVersionInformation(versionBits int) (*Version, error) {
bestDifference := math.MaxInt32
bestVersion := 0
for i, targetVersion := range VERSION_DECODE_INFO {
if targetVersion == versionBits {
return Version_GetVersionForNumber(i + 7)
}
bitsDifference := FormatInformation_NumBitsDiffering(uint(versionBits), uint(targetVersion))
if bitsDifference < bestDifference {
bestVersion = i + 7
bestDifference = bitsDifference
}
}
if bestDifference <= 3 {
return Version_GetVersionForNumber(bestVersion)
}
return nil, errors.Errorf("we didn't find a close enough match 0x%x", versionBits)
}
func (v *Version) buildFunctionPattern() (*gozxing.BitMatrix, error) {
dimension := v.GetDimensionForVersion()
bitMatrix, e := gozxing.NewSquareBitMatrix(dimension)
if e != nil {
return nil, e
}
bitMatrix.SetRegion(0, 0, 9, 9)
bitMatrix.SetRegion(dimension-8, 0, 8, 9)
bitMatrix.SetRegion(0, dimension-8, 9, 8)
max := len(v.alignmentPatternCenters)
for x := 0; x < max; x++ {
i := v.alignmentPatternCenters[x] - 2
for y := 0; y < max; y++ {
if (x == 0 && (y == 0 || y == max-1)) || (x == max-1 && y == 0) {
continue
}
bitMatrix.SetRegion(v.alignmentPatternCenters[y]-2, i, 5, 5)
}
}
bitMatrix.SetRegion(6, 9, 1, dimension-17)
bitMatrix.SetRegion(9, 6, dimension-17, 1)
if v.versionNumber > 6 {
bitMatrix.SetRegion(dimension-11, 0, 3, 6)
bitMatrix.SetRegion(0, dimension-11, 6, 3)
}
return bitMatrix, nil
}
type ECBlocks struct {
ecCodewordsPerBlock int
ecBlocks []ECB
}
func (b *ECBlocks) GetECCodewordsPerBlock() int {
return b.ecCodewordsPerBlock
}
func (b *ECBlocks) GetNumBlocks() int {
total := 0
for _, ecBlock := range b.ecBlocks {
total += ecBlock.GetCount()
}
return total
}
func (b *ECBlocks) GetTotalECCodewords() int {
return b.ecCodewordsPerBlock * b.GetNumBlocks()
}
func (b *ECBlocks) GetECBlocks() []ECB {
return b.ecBlocks
}
type ECB struct {
count int
dataCodewords int
}
func (e ECB) GetCount() int {
return e.count
}
func (e ECB) GetDataCodewords() int {
return e.dataCodewords
}
func (this *Version) String() string {
if this == nil {
return ""
}
return strconv.Itoa(this.versionNumber)
}
var VERSIONS = []*Version{
NewVersion(1, []int{},
ECBlocks{7, []ECB{{1, 19}}},
ECBlocks{10, []ECB{{1, 16}}},
ECBlocks{13, []ECB{{1, 13}}},
ECBlocks{17, []ECB{{1, 9}}}),
NewVersion(2, []int{6, 18},
ECBlocks{10, []ECB{{1, 34}}},
ECBlocks{16, []ECB{{1, 28}}},
ECBlocks{22, []ECB{{1, 22}}},
ECBlocks{28, []ECB{{1, 16}}}),
NewVersion(3, []int{6, 22},
ECBlocks{15, []ECB{{1, 55}}},
ECBlocks{26, []ECB{{1, 44}}},
ECBlocks{18, []ECB{{2, 17}}},
ECBlocks{22, []ECB{{2, 13}}}),
NewVersion(4, []int{6, 26},
ECBlocks{20, []ECB{{1, 80}}},
ECBlocks{18, []ECB{{2, 32}}},
ECBlocks{26, []ECB{{2, 24}}},
ECBlocks{16, []ECB{{4, 9}}}),
NewVersion(5, []int{6, 30},
ECBlocks{26, []ECB{{1, 108}}},
ECBlocks{24, []ECB{{2, 43}}},
ECBlocks{18, []ECB{{2, 15}, {2, 16}}},
ECBlocks{22, []ECB{{2, 11}, {2, 12}}}),
NewVersion(6, []int{6, 34},
ECBlocks{18, []ECB{{2, 68}}},
ECBlocks{16, []ECB{{4, 27}}},
ECBlocks{24, []ECB{{4, 19}}},
ECBlocks{28, []ECB{{4, 15}}}),
NewVersion(7, []int{6, 22, 38},
ECBlocks{20, []ECB{{2, 78}}},
ECBlocks{18, []ECB{{4, 31}}},
ECBlocks{18, []ECB{{2, 14}, {4, 15}}},
ECBlocks{26, []ECB{{4, 13}, {1, 14}}}),
NewVersion(8, []int{6, 24, 42},
ECBlocks{24, []ECB{{2, 97}}},
ECBlocks{22, []ECB{{2, 38}, {2, 39}}},
ECBlocks{22, []ECB{{4, 18}, {2, 19}}},
ECBlocks{26, []ECB{{4, 14}, {2, 15}}}),
NewVersion(9, []int{6, 26, 46},
ECBlocks{30, []ECB{{2, 116}}},
ECBlocks{22, []ECB{{3, 36}, {2, 37}}},
ECBlocks{20, []ECB{{4, 16}, {4, 17}}},
ECBlocks{24, []ECB{{4, 12}, {4, 13}}}),
NewVersion(10, []int{6, 28, 50},
ECBlocks{18, []ECB{{2, 68}, {2, 69}}},
ECBlocks{26, []ECB{{4, 43}, {1, 44}}},
ECBlocks{24, []ECB{{6, 19}, {2, 20}}},
ECBlocks{28, []ECB{{6, 15}, {2, 16}}}),
NewVersion(11, []int{6, 30, 54},
ECBlocks{20, []ECB{{4, 81}}},
ECBlocks{30, []ECB{{1, 50}, {4, 51}}},
ECBlocks{28, []ECB{{4, 22}, {4, 23}}},
ECBlocks{24, []ECB{{3, 12}, {8, 13}}}),
NewVersion(12, []int{6, 32, 58},
ECBlocks{24, []ECB{{2, 92}, {2, 93}}},
ECBlocks{22, []ECB{{6, 36}, {2, 37}}},
ECBlocks{26, []ECB{{4, 20}, {6, 21}}},
ECBlocks{28, []ECB{{7, 14}, {4, 15}}}),
NewVersion(13, []int{6, 34, 62},
ECBlocks{26, []ECB{{4, 107}}},
ECBlocks{22, []ECB{{8, 37}, {1, 38}}},
ECBlocks{24, []ECB{{8, 20}, {4, 21}}},
ECBlocks{22, []ECB{{12, 11}, {4, 12}}}),
NewVersion(14, []int{6, 26, 46, 66},
ECBlocks{30, []ECB{{3, 115}, {1, 116}}},
ECBlocks{24, []ECB{{4, 40}, {5, 41}}},
ECBlocks{20, []ECB{{11, 16}, {5, 17}}},
ECBlocks{24, []ECB{{11, 12}, {5, 13}}}),
NewVersion(15, []int{6, 26, 48, 70},
ECBlocks{22, []ECB{{5, 87}, {1, 88}}},
ECBlocks{24, []ECB{{5, 41}, {5, 42}}},
ECBlocks{30, []ECB{{5, 24}, {7, 25}}},
ECBlocks{24, []ECB{{11, 12}, {7, 13}}}),
NewVersion(16, []int{6, 26, 50, 74},
ECBlocks{24, []ECB{{5, 98}, {1, 99}}},
ECBlocks{28, []ECB{{7, 45}, {3, 46}}},
ECBlocks{24, []ECB{{15, 19}, {2, 20}}},
ECBlocks{30, []ECB{{3, 15}, {13, 16}}}),
NewVersion(17, []int{6, 30, 54, 78},
ECBlocks{28, []ECB{{1, 107}, {5, 108}}},
ECBlocks{28, []ECB{{10, 46}, {1, 47}}},
ECBlocks{28, []ECB{{1, 22}, {15, 23}}},
ECBlocks{28, []ECB{{2, 14}, {17, 15}}}),
NewVersion(18, []int{6, 30, 56, 82},
ECBlocks{30, []ECB{{5, 120}, {1, 121}}},
ECBlocks{26, []ECB{{9, 43}, {4, 44}}},
ECBlocks{28, []ECB{{17, 22}, {1, 23}}},
ECBlocks{28, []ECB{{2, 14}, {19, 15}}}),
NewVersion(19, []int{6, 30, 58, 86},
ECBlocks{28, []ECB{{3, 113}, {4, 114}}},
ECBlocks{26, []ECB{{3, 44}, {11, 45}}},
ECBlocks{26, []ECB{{17, 21}, {4, 22}}},
ECBlocks{26, []ECB{{9, 13}, {16, 14}}}),
NewVersion(20, []int{6, 34, 62, 90},
ECBlocks{28, []ECB{{3, 107}, {5, 108}}},
ECBlocks{26, []ECB{{3, 41}, {13, 42}}},
ECBlocks{30, []ECB{{15, 24}, {5, 25}}},
ECBlocks{28, []ECB{{15, 15}, {10, 16}}}),
NewVersion(21, []int{6, 28, 50, 72, 94},
ECBlocks{28, []ECB{{4, 116}, {4, 117}}},
ECBlocks{26, []ECB{{17, 42}}},
ECBlocks{28, []ECB{{17, 22}, {6, 23}}},
ECBlocks{30, []ECB{{19, 16}, {6, 17}}}),
NewVersion(22, []int{6, 26, 50, 74, 98},
ECBlocks{28, []ECB{{2, 111}, {7, 112}}},
ECBlocks{28, []ECB{{17, 46}}},
ECBlocks{30, []ECB{{7, 24}, {16, 25}}},
ECBlocks{24, []ECB{{34, 13}}}),
NewVersion(23, []int{6, 30, 54, 78, 102},
ECBlocks{30, []ECB{{4, 121}, {5, 122}}},
ECBlocks{28, []ECB{{4, 47}, {14, 48}}},
ECBlocks{30, []ECB{{11, 24}, {14, 25}}},
ECBlocks{30, []ECB{{16, 15}, {14, 16}}}),
NewVersion(24, []int{6, 28, 54, 80, 106},
ECBlocks{30, []ECB{{6, 117}, {4, 118}}},
ECBlocks{28, []ECB{{6, 45}, {14, 46}}},
ECBlocks{30, []ECB{{11, 24}, {16, 25}}},
ECBlocks{30, []ECB{{30, 16}, {2, 17}}}),
NewVersion(25, []int{6, 32, 58, 84, 110},
ECBlocks{26, []ECB{{8, 106}, {4, 107}}},
ECBlocks{28, []ECB{{8, 47}, {13, 48}}},
ECBlocks{30, []ECB{{7, 24}, {22, 25}}},
ECBlocks{30, []ECB{{22, 15}, {13, 16}}}),
NewVersion(26, []int{6, 30, 58, 86, 114},
ECBlocks{28, []ECB{{10, 114}, {2, 115}}},
ECBlocks{28, []ECB{{19, 46}, {4, 47}}},
ECBlocks{28, []ECB{{28, 22}, {6, 23}}},
ECBlocks{30, []ECB{{33, 16}, {4, 17}}}),
NewVersion(27, []int{6, 34, 62, 90, 118},
ECBlocks{30, []ECB{{8, 122}, {4, 123}}},
ECBlocks{28, []ECB{{22, 45}, {3, 46}}},
ECBlocks{30, []ECB{{8, 23}, {26, 24}}},
ECBlocks{30, []ECB{{12, 15}, {28, 16}}}),
NewVersion(28, []int{6, 26, 50, 74, 98, 122},
ECBlocks{30, []ECB{{3, 117}, {10, 118}}},
ECBlocks{28, []ECB{{3, 45}, {23, 46}}},
ECBlocks{30, []ECB{{4, 24}, {31, 25}}},
ECBlocks{30, []ECB{{11, 15}, {31, 16}}}),
NewVersion(29, []int{6, 30, 54, 78, 102, 126},
ECBlocks{30, []ECB{{7, 116}, {7, 117}}},
ECBlocks{28, []ECB{{21, 45}, {7, 46}}},
ECBlocks{30, []ECB{{1, 23}, {37, 24}}},
ECBlocks{30, []ECB{{19, 15}, {26, 16}}}),
NewVersion(30, []int{6, 26, 52, 78, 104, 130},
ECBlocks{30, []ECB{{5, 115}, {10, 116}}},
ECBlocks{28, []ECB{{19, 47}, {10, 48}}},
ECBlocks{30, []ECB{{15, 24}, {25, 25}}},
ECBlocks{30, []ECB{{23, 15}, {25, 16}}}),
NewVersion(31, []int{6, 30, 56, 82, 108, 134},
ECBlocks{30, []ECB{{13, 115}, {3, 116}}},
ECBlocks{28, []ECB{{2, 46}, {29, 47}}},
ECBlocks{30, []ECB{{42, 24}, {1, 25}}},
ECBlocks{30, []ECB{{23, 15}, {28, 16}}}),
NewVersion(32, []int{6, 34, 60, 86, 112, 138},
ECBlocks{30, []ECB{{17, 115}}},
ECBlocks{28, []ECB{{10, 46}, {23, 47}}},
ECBlocks{30, []ECB{{10, 24}, {35, 25}}},
ECBlocks{30, []ECB{{19, 15}, {35, 16}}}),
NewVersion(33, []int{6, 30, 58, 86, 114, 142},
ECBlocks{30, []ECB{{17, 115}, {1, 116}}},
ECBlocks{28, []ECB{{14, 46}, {21, 47}}},
ECBlocks{30, []ECB{{29, 24}, {19, 25}}},
ECBlocks{30, []ECB{{11, 15}, {46, 16}}}),
NewVersion(34, []int{6, 34, 62, 90, 118, 146},
ECBlocks{30, []ECB{{13, 115}, {6, 116}}},
ECBlocks{28, []ECB{{14, 46}, {23, 47}}},
ECBlocks{30, []ECB{{44, 24}, {7, 25}}},
ECBlocks{30, []ECB{{59, 16}, {1, 17}}}),
NewVersion(35, []int{6, 30, 54, 78, 102, 126, 150},
ECBlocks{30, []ECB{{12, 121}, {7, 122}}},
ECBlocks{28, []ECB{{12, 47}, {26, 48}}},
ECBlocks{30, []ECB{{39, 24}, {14, 25}}},
ECBlocks{30, []ECB{{22, 15}, {41, 16}}}),
NewVersion(36, []int{6, 24, 50, 76, 102, 128, 154},
ECBlocks{30, []ECB{{6, 121}, {14, 122}}},
ECBlocks{28, []ECB{{6, 47}, {34, 48}}},
ECBlocks{30, []ECB{{46, 24}, {10, 25}}},
ECBlocks{30, []ECB{{2, 15}, {64, 16}}}),
NewVersion(37, []int{6, 28, 54, 80, 106, 132, 158},
ECBlocks{30, []ECB{{17, 122}, {4, 123}}},
ECBlocks{28, []ECB{{29, 46}, {14, 47}}},
ECBlocks{30, []ECB{{49, 24}, {10, 25}}},
ECBlocks{30, []ECB{{24, 15}, {46, 16}}}),
NewVersion(38, []int{6, 32, 58, 84, 110, 136, 162},
ECBlocks{30, []ECB{{4, 122}, {18, 123}}},
ECBlocks{28, []ECB{{13, 46}, {32, 47}}},
ECBlocks{30, []ECB{{48, 24}, {14, 25}}},
ECBlocks{30, []ECB{{42, 15}, {32, 16}}}),
NewVersion(39, []int{6, 26, 54, 82, 110, 138, 166},
ECBlocks{30, []ECB{{20, 117}, {4, 118}}},
ECBlocks{28, []ECB{{40, 47}, {7, 48}}},
ECBlocks{30, []ECB{{43, 24}, {22, 25}}},
ECBlocks{30, []ECB{{10, 15}, {67, 16}}}),
NewVersion(40, []int{6, 30, 58, 86, 114, 142, 170},
ECBlocks{30, []ECB{{19, 118}, {6, 119}}},
ECBlocks{28, []ECB{{18, 47}, {31, 48}}},
ECBlocks{30, []ECB{{34, 24}, {34, 25}}},
ECBlocks{30, []ECB{{20, 15}, {61, 16}}}),
}