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

99 lines
3.0 KiB
Go

package decoder
import (
errors "golang.org/x/xerrors"
)
type DataBlock struct {
numDataCodewords int
codewords []byte
}
func NewDataBlock(numDataCodewords int, codewords []byte) *DataBlock {
return &DataBlock{
numDataCodewords: numDataCodewords,
codewords: codewords,
}
}
func DataBlock_GetDataBlocks(rawCodewords []byte, version *Version, ecLevel ErrorCorrectionLevel) ([]*DataBlock, error) {
if len(rawCodewords) != version.GetTotalCodewords() {
return nil, errors.Errorf(
"IllegalArgumentException: len(rawCodewords)=%v, totalCodewords=%v",
len(rawCodewords), version.GetTotalCodewords())
}
// Figure out the number and size of data blocks used by this version and
// error correction level
ecBlocks := version.GetECBlocksForLevel(ecLevel)
// First count the total number of data blocks
totalBlocks := 0
ecBlockArray := ecBlocks.GetECBlocks()
for _, ecBlock := range ecBlockArray {
totalBlocks += ecBlock.GetCount()
}
// Now establish DataBlocks of the appropriate size and number of data codewords
result := make([]*DataBlock, totalBlocks)
numResultBlocks := 0
for _, ecBlock := range ecBlockArray {
for i := 0; i < ecBlock.GetCount(); i++ {
numDataCodewords := ecBlock.GetDataCodewords()
numBlockCodewords := ecBlocks.GetECCodewordsPerBlock() + numDataCodewords
result[numResultBlocks] = NewDataBlock(numDataCodewords, make([]byte, numBlockCodewords))
numResultBlocks++
}
}
// All blocks have the same amount of data, except that the last n
// (where n may be 0) have 1 more byte. Figure out where these start.
shorterBlocksTotalCodewords := len(result[0].codewords)
longerBlocksStartAt := len(result) - 1
for longerBlocksStartAt >= 0 {
numCodewords := len(result[longerBlocksStartAt].codewords)
if numCodewords == shorterBlocksTotalCodewords {
break
}
longerBlocksStartAt--
}
longerBlocksStartAt++
shorterBlocksNumDataCodewords := shorterBlocksTotalCodewords - ecBlocks.GetECCodewordsPerBlock()
// The last elements of result may be 1 element longer;
// first fill out as many elements as all of them have
rawCodewordsOffset := 0
for i := 0; i < shorterBlocksNumDataCodewords; i++ {
for j := 0; j < numResultBlocks; j++ {
result[j].codewords[i] = rawCodewords[rawCodewordsOffset]
rawCodewordsOffset++
}
}
// Fill out the last data block in the longer ones
for j := longerBlocksStartAt; j < numResultBlocks; j++ {
result[j].codewords[shorterBlocksNumDataCodewords] = rawCodewords[rawCodewordsOffset]
rawCodewordsOffset++
}
// Now add in error correction blocks
max := len(result[0].codewords)
for i := shorterBlocksNumDataCodewords; i < max; i++ {
for j := 0; j < numResultBlocks; j++ {
iOffset := i
if j >= longerBlocksStartAt {
iOffset = i + 1
}
result[j].codewords[iOffset] = rawCodewords[rawCodewordsOffset]
rawCodewordsOffset++
}
}
return result, nil
}
func (this *DataBlock) GetNumDataCodewords() int {
return this.numDataCodewords
}
func (this *DataBlock) GetCodewords() []byte {
return this.codewords
}