VideoTools/vendor/github.com/skip2/go-qrcode/version.go
Stu Leak 68df790d27 Fix player frame generation and video playback
Major improvements to UnifiedPlayer:

1. GetFrameImage() now works when paused for responsive UI updates
2. Play() method properly starts FFmpeg process
3. Frame display loop runs continuously for smooth video display
4. Disabled audio temporarily to fix video playback fundamentals
5. Simplified FFmpeg command to focus on video stream only

Player now:
- Generates video frames correctly
- Shows video when paused
- Has responsive progress tracking
- Starts playback properly

Next steps: Re-enable audio playback once video is stable
2026-01-07 22:20:00 -05:00

3051 lines
30 KiB
Go

// go-qrcode
// Copyright 2014 Tom Harwood
package qrcode
import (
"log"
bitset "github.com/skip2/go-qrcode/bitset"
)
// Error detection/recovery capacity.
//
// There are several levels of error detection/recovery capacity. Higher levels
// of error recovery are able to correct more errors, with the trade-off of
// increased symbol size.
type RecoveryLevel int
const (
// Level L: 7% error recovery.
Low RecoveryLevel = iota
// Level M: 15% error recovery. Good default choice.
Medium
// Level Q: 25% error recovery.
High
// Level H: 30% error recovery.
Highest
)
// qrCodeVersion describes the data length and encoding order of a single QR
// Code version. There are 40 versions numbers x 4 recovery levels == 160
// possible qrCodeVersion structures.
type qrCodeVersion struct {
// Version number (1-40 inclusive).
version int
// Error recovery level.
level RecoveryLevel
dataEncoderType dataEncoderType
// Encoded data can be split into multiple blocks. Each block contains data
// and error recovery bytes.
//
// Larger QR Codes contain more blocks.
block []block
// Number of bits required to pad the combined data & error correction bit
// stream up to the symbol's full capacity.
numRemainderBits int
}
type block struct {
numBlocks int
// Total codewords (numCodewords == numErrorCodewords+numDataCodewords).
numCodewords int
// Number of data codewords.
numDataCodewords int
}
var (
versions = []qrCodeVersion{
{
1,
Low,
dataEncoderType1To9,
[]block{
{
1,
26,
19,
},
},
0,
},
{
1,
Medium,
dataEncoderType1To9,
[]block{
{
1,
26,
16,
},
},
0,
},
{
1,
High,
dataEncoderType1To9,
[]block{
{
1,
26,
13,
},
},
0,
},
{
1,
Highest,
dataEncoderType1To9,
[]block{
{
1,
26,
9,
},
},
0,
},
{
2,
Low,
dataEncoderType1To9,
[]block{
{
1,
44,
34,
},
},
7,
},
{
2,
Medium,
dataEncoderType1To9,
[]block{
{
1,
44,
28,
},
},
7,
},
{
2,
High,
dataEncoderType1To9,
[]block{
{
1,
44,
22,
},
},
7,
},
{
2,
Highest,
dataEncoderType1To9,
[]block{
{
1,
44,
16,
},
},
7,
},
{
3,
Low,
dataEncoderType1To9,
[]block{
{
1,
70,
55,
},
},
7,
},
{
3,
Medium,
dataEncoderType1To9,
[]block{
{
1,
70,
44,
},
},
7,
},
{
3,
High,
dataEncoderType1To9,
[]block{
{
2,
35,
17,
},
},
7,
},
{
3,
Highest,
dataEncoderType1To9,
[]block{
{
2,
35,
13,
},
},
7,
},
{
4,
Low,
dataEncoderType1To9,
[]block{
{
1,
100,
80,
},
},
7,
},
{
4,
Medium,
dataEncoderType1To9,
[]block{
{
2,
50,
32,
},
},
7,
},
{
4,
High,
dataEncoderType1To9,
[]block{
{
2,
50,
24,
},
},
7,
},
{
4,
Highest,
dataEncoderType1To9,
[]block{
{
4,
25,
9,
},
},
7,
},
{
5,
Low,
dataEncoderType1To9,
[]block{
{
1,
134,
108,
},
},
7,
},
{
5,
Medium,
dataEncoderType1To9,
[]block{
{
2,
67,
43,
},
},
7,
},
{
5,
High,
dataEncoderType1To9,
[]block{
{
2,
33,
15,
},
{
2,
34,
16,
},
},
7,
},
{
5,
Highest,
dataEncoderType1To9,
[]block{
{
2,
33,
11,
},
{
2,
34,
12,
},
},
7,
},
{
6,
Low,
dataEncoderType1To9,
[]block{
{
2,
86,
68,
},
},
7,
},
{
6,
Medium,
dataEncoderType1To9,
[]block{
{
4,
43,
27,
},
},
7,
},
{
6,
High,
dataEncoderType1To9,
[]block{
{
4,
43,
19,
},
},
7,
},
{
6,
Highest,
dataEncoderType1To9,
[]block{
{
4,
43,
15,
},
},
7,
},
{
7,
Low,
dataEncoderType1To9,
[]block{
{
2,
98,
78,
},
},
0,
},
{
7,
Medium,
dataEncoderType1To9,
[]block{
{
4,
49,
31,
},
},
0,
},
{
7,
High,
dataEncoderType1To9,
[]block{
{
2,
32,
14,
},
{
4,
33,
15,
},
},
0,
},
{
7,
Highest,
dataEncoderType1To9,
[]block{
{
4,
39,
13,
},
{
1,
40,
14,
},
},
0,
},
{
8,
Low,
dataEncoderType1To9,
[]block{
{
2,
121,
97,
},
},
0,
},
{
8,
Medium,
dataEncoderType1To9,
[]block{
{
2,
60,
38,
},
{
2,
61,
39,
},
},
0,
},
{
8,
High,
dataEncoderType1To9,
[]block{
{
4,
40,
18,
},
{
2,
41,
19,
},
},
0,
},
{
8,
Highest,
dataEncoderType1To9,
[]block{
{
4,
40,
14,
},
{
2,
41,
15,
},
},
0,
},
{
9,
Low,
dataEncoderType1To9,
[]block{
{
2,
146,
116,
},
},
0,
},
{
9,
Medium,
dataEncoderType1To9,
[]block{
{
3,
58,
36,
},
{
2,
59,
37,
},
},
0,
},
{
9,
High,
dataEncoderType1To9,
[]block{
{
4,
36,
16,
},
{
4,
37,
17,
},
},
0,
},
{
9,
Highest,
dataEncoderType1To9,
[]block{
{
4,
36,
12,
},
{
4,
37,
13,
},
},
0,
},
{
10,
Low,
dataEncoderType10To26,
[]block{
{
2,
86,
68,
},
{
2,
87,
69,
},
},
0,
},
{
10,
Medium,
dataEncoderType10To26,
[]block{
{
4,
69,
43,
},
{
1,
70,
44,
},
},
0,
},
{
10,
High,
dataEncoderType10To26,
[]block{
{
6,
43,
19,
},
{
2,
44,
20,
},
},
0,
},
{
10,
Highest,
dataEncoderType10To26,
[]block{
{
6,
43,
15,
},
{
2,
44,
16,
},
},
0,
},
{
11,
Low,
dataEncoderType10To26,
[]block{
{
4,
101,
81,
},
},
0,
},
{
11,
Medium,
dataEncoderType10To26,
[]block{
{
1,
80,
50,
},
{
4,
81,
51,
},
},
0,
},
{
11,
High,
dataEncoderType10To26,
[]block{
{
4,
50,
22,
},
{
4,
51,
23,
},
},
0,
},
{
11,
Highest,
dataEncoderType10To26,
[]block{
{
3,
36,
12,
},
{
8,
37,
13,
},
},
0,
},
{
12,
Low,
dataEncoderType10To26,
[]block{
{
2,
116,
92,
},
{
2,
117,
93,
},
},
0,
},
{
12,
Medium,
dataEncoderType10To26,
[]block{
{
6,
58,
36,
},
{
2,
59,
37,
},
},
0,
},
{
12,
High,
dataEncoderType10To26,
[]block{
{
4,
46,
20,
},
{
6,
47,
21,
},
},
0,
},
{
12,
Highest,
dataEncoderType10To26,
[]block{
{
7,
42,
14,
},
{
4,
43,
15,
},
},
0,
},
{
13,
Low,
dataEncoderType10To26,
[]block{
{
4,
133,
107,
},
},
0,
},
{
13,
Medium,
dataEncoderType10To26,
[]block{
{
8,
59,
37,
},
{
1,
60,
38,
},
},
0,
},
{
13,
High,
dataEncoderType10To26,
[]block{
{
8,
44,
20,
},
{
4,
45,
21,
},
},
0,
},
{
13,
Highest,
dataEncoderType10To26,
[]block{
{
12,
33,
11,
},
{
4,
34,
12,
},
},
0,
},
{
14,
Low,
dataEncoderType10To26,
[]block{
{
3,
145,
115,
},
{
1,
146,
116,
},
},
3,
},
{
14,
Medium,
dataEncoderType10To26,
[]block{
{
4,
64,
40,
},
{
5,
65,
41,
},
},
3,
},
{
14,
High,
dataEncoderType10To26,
[]block{
{
11,
36,
16,
},
{
5,
37,
17,
},
},
3,
},
{
14,
Highest,
dataEncoderType10To26,
[]block{
{
11,
36,
12,
},
{
5,
37,
13,
},
},
3,
},
{
15,
Low,
dataEncoderType10To26,
[]block{
{
5,
109,
87,
},
{
1,
110,
88,
},
},
3,
},
{
15,
Medium,
dataEncoderType10To26,
[]block{
{
5,
65,
41,
},
{
5,
66,
42,
},
},
3,
},
{
15,
High,
dataEncoderType10To26,
[]block{
{
5,
54,
24,
},
{
7,
55,
25,
},
},
3,
},
{
15,
Highest,
dataEncoderType10To26,
[]block{
{
11,
36,
12,
},
{
7,
37,
13,
},
},
3,
},
{
16,
Low,
dataEncoderType10To26,
[]block{
{
5,
122,
98,
},
{
1,
123,
99,
},
},
3,
},
{
16,
Medium,
dataEncoderType10To26,
[]block{
{
7,
73,
45,
},
{
3,
74,
46,
},
},
3,
},
{
16,
High,
dataEncoderType10To26,
[]block{
{
15,
43,
19,
},
{
2,
44,
20,
},
},
3,
},
{
16,
Highest,
dataEncoderType10To26,
[]block{
{
3,
45,
15,
},
{
13,
46,
16,
},
},
3,
},
{
17,
Low,
dataEncoderType10To26,
[]block{
{
1,
135,
107,
},
{
5,
136,
108,
},
},
3,
},
{
17,
Medium,
dataEncoderType10To26,
[]block{
{
10,
74,
46,
},
{
1,
75,
47,
},
},
3,
},
{
17,
High,
dataEncoderType10To26,
[]block{
{
1,
50,
22,
},
{
15,
51,
23,
},
},
3,
},
{
17,
Highest,
dataEncoderType10To26,
[]block{
{
2,
42,
14,
},
{
17,
43,
15,
},
},
3,
},
{
18,
Low,
dataEncoderType10To26,
[]block{
{
5,
150,
120,
},
{
1,
151,
121,
},
},
3,
},
{
18,
Medium,
dataEncoderType10To26,
[]block{
{
9,
69,
43,
},
{
4,
70,
44,
},
},
3,
},
{
18,
High,
dataEncoderType10To26,
[]block{
{
17,
50,
22,
},
{
1,
51,
23,
},
},
3,
},
{
18,
Highest,
dataEncoderType10To26,
[]block{
{
2,
42,
14,
},
{
19,
43,
15,
},
},
3,
},
{
19,
Low,
dataEncoderType10To26,
[]block{
{
3,
141,
113,
},
{
4,
142,
114,
},
},
3,
},
{
19,
Medium,
dataEncoderType10To26,
[]block{
{
3,
70,
44,
},
{
11,
71,
45,
},
},
3,
},
{
19,
High,
dataEncoderType10To26,
[]block{
{
17,
47,
21,
},
{
4,
48,
22,
},
},
3,
},
{
19,
Highest,
dataEncoderType10To26,
[]block{
{
9,
39,
13,
},
{
16,
40,
14,
},
},
3,
},
{
20,
Low,
dataEncoderType10To26,
[]block{
{
3,
135,
107,
},
{
5,
136,
108,
},
},
3,
},
{
20,
Medium,
dataEncoderType10To26,
[]block{
{
3,
67,
41,
},
{
13,
68,
42,
},
},
3,
},
{
20,
High,
dataEncoderType10To26,
[]block{
{
15,
54,
24,
},
{
5,
55,
25,
},
},
3,
},
{
20,
Highest,
dataEncoderType10To26,
[]block{
{
15,
43,
15,
},
{
10,
44,
16,
},
},
3,
},
{
21,
Low,
dataEncoderType10To26,
[]block{
{
4,
144,
116,
},
{
4,
145,
117,
},
},
4,
},
{
21,
Medium,
dataEncoderType10To26,
[]block{
{
17,
68,
42,
},
},
4,
},
{
21,
High,
dataEncoderType10To26,
[]block{
{
17,
50,
22,
},
{
6,
51,
23,
},
},
4,
},
{
21,
Highest,
dataEncoderType10To26,
[]block{
{
19,
46,
16,
},
{
6,
47,
17,
},
},
4,
},
{
22,
Low,
dataEncoderType10To26,
[]block{
{
2,
139,
111,
},
{
7,
140,
112,
},
},
4,
},
{
22,
Medium,
dataEncoderType10To26,
[]block{
{
17,
74,
46,
},
},
4,
},
{
22,
High,
dataEncoderType10To26,
[]block{
{
7,
54,
24,
},
{
16,
55,
25,
},
},
4,
},
{
22,
Highest,
dataEncoderType10To26,
[]block{
{
34,
37,
13,
},
},
4,
},
{
23,
Low,
dataEncoderType10To26,
[]block{
{
4,
151,
121,
},
{
5,
152,
122,
},
},
4,
},
{
23,
Medium,
dataEncoderType10To26,
[]block{
{
4,
75,
47,
},
{
14,
76,
48,
},
},
4,
},
{
23,
High,
dataEncoderType10To26,
[]block{
{
11,
54,
24,
},
{
14,
55,
25,
},
},
4,
},
{
23,
Highest,
dataEncoderType10To26,
[]block{
{
16,
45,
15,
},
{
14,
46,
16,
},
},
4,
},
{
24,
Low,
dataEncoderType10To26,
[]block{
{
6,
147,
117,
},
{
4,
148,
118,
},
},
4,
},
{
24,
Medium,
dataEncoderType10To26,
[]block{
{
6,
73,
45,
},
{
14,
74,
46,
},
},
4,
},
{
24,
High,
dataEncoderType10To26,
[]block{
{
11,
54,
24,
},
{
16,
55,
25,
},
},
4,
},
{
24,
Highest,
dataEncoderType10To26,
[]block{
{
30,
46,
16,
},
{
2,
47,
17,
},
},
4,
},
{
25,
Low,
dataEncoderType10To26,
[]block{
{
8,
132,
106,
},
{
4,
133,
107,
},
},
4,
},
{
25,
Medium,
dataEncoderType10To26,
[]block{
{
8,
75,
47,
},
{
13,
76,
48,
},
},
4,
},
{
25,
High,
dataEncoderType10To26,
[]block{
{
7,
54,
24,
},
{
22,
55,
25,
},
},
4,
},
{
25,
Highest,
dataEncoderType10To26,
[]block{
{
22,
45,
15,
},
{
13,
46,
16,
},
},
4,
},
{
26,
Low,
dataEncoderType10To26,
[]block{
{
10,
142,
114,
},
{
2,
143,
115,
},
},
4,
},
{
26,
Medium,
dataEncoderType10To26,
[]block{
{
19,
74,
46,
},
{
4,
75,
47,
},
},
4,
},
{
26,
High,
dataEncoderType10To26,
[]block{
{
28,
50,
22,
},
{
6,
51,
23,
},
},
4,
},
{
26,
Highest,
dataEncoderType10To26,
[]block{
{
33,
46,
16,
},
{
4,
47,
17,
},
},
4,
},
{
27,
Low,
dataEncoderType27To40,
[]block{
{
8,
152,
122,
},
{
4,
153,
123,
},
},
4,
},
{
27,
Medium,
dataEncoderType27To40,
[]block{
{
22,
73,
45,
},
{
3,
74,
46,
},
},
4,
},
{
27,
High,
dataEncoderType27To40,
[]block{
{
8,
53,
23,
},
{
26,
54,
24,
},
},
4,
},
{
27,
Highest,
dataEncoderType27To40,
[]block{
{
12,
45,
15,
},
{
28,
46,
16,
},
},
4,
},
{
28,
Low,
dataEncoderType27To40,
[]block{
{
3,
147,
117,
},
{
10,
148,
118,
},
},
3,
},
{
28,
Medium,
dataEncoderType27To40,
[]block{
{
3,
73,
45,
},
{
23,
74,
46,
},
},
3,
},
{
28,
High,
dataEncoderType27To40,
[]block{
{
4,
54,
24,
},
{
31,
55,
25,
},
},
3,
},
{
28,
Highest,
dataEncoderType27To40,
[]block{
{
11,
45,
15,
},
{
31,
46,
16,
},
},
3,
},
{
29,
Low,
dataEncoderType27To40,
[]block{
{
7,
146,
116,
},
{
7,
147,
117,
},
},
3,
},
{
29,
Medium,
dataEncoderType27To40,
[]block{
{
21,
73,
45,
},
{
7,
74,
46,
},
},
3,
},
{
29,
High,
dataEncoderType27To40,
[]block{
{
1,
53,
23,
},
{
37,
54,
24,
},
},
3,
},
{
29,
Highest,
dataEncoderType27To40,
[]block{
{
19,
45,
15,
},
{
26,
46,
16,
},
},
3,
},
{
30,
Low,
dataEncoderType27To40,
[]block{
{
5,
145,
115,
},
{
10,
146,
116,
},
},
3,
},
{
30,
Medium,
dataEncoderType27To40,
[]block{
{
19,
75,
47,
},
{
10,
76,
48,
},
},
3,
},
{
30,
High,
dataEncoderType27To40,
[]block{
{
15,
54,
24,
},
{
25,
55,
25,
},
},
3,
},
{
30,
Highest,
dataEncoderType27To40,
[]block{
{
23,
45,
15,
},
{
25,
46,
16,
},
},
3,
},
{
31,
Low,
dataEncoderType27To40,
[]block{
{
13,
145,
115,
},
{
3,
146,
116,
},
},
3,
},
{
31,
Medium,
dataEncoderType27To40,
[]block{
{
2,
74,
46,
},
{
29,
75,
47,
},
},
3,
},
{
31,
High,
dataEncoderType27To40,
[]block{
{
42,
54,
24,
},
{
1,
55,
25,
},
},
3,
},
{
31,
Highest,
dataEncoderType27To40,
[]block{
{
23,
45,
15,
},
{
28,
46,
16,
},
},
3,
},
{
32,
Low,
dataEncoderType27To40,
[]block{
{
17,
145,
115,
},
},
3,
},
{
32,
Medium,
dataEncoderType27To40,
[]block{
{
10,
74,
46,
},
{
23,
75,
47,
},
},
3,
},
{
32,
High,
dataEncoderType27To40,
[]block{
{
10,
54,
24,
},
{
35,
55,
25,
},
},
3,
},
{
32,
Highest,
dataEncoderType27To40,
[]block{
{
19,
45,
15,
},
{
35,
46,
16,
},
},
3,
},
{
33,
Low,
dataEncoderType27To40,
[]block{
{
17,
145,
115,
},
{
1,
146,
116,
},
},
3,
},
{
33,
Medium,
dataEncoderType27To40,
[]block{
{
14,
74,
46,
},
{
21,
75,
47,
},
},
3,
},
{
33,
High,
dataEncoderType27To40,
[]block{
{
29,
54,
24,
},
{
19,
55,
25,
},
},
3,
},
{
33,
Highest,
dataEncoderType27To40,
[]block{
{
11,
45,
15,
},
{
46,
46,
16,
},
},
3,
},
{
34,
Low,
dataEncoderType27To40,
[]block{
{
13,
145,
115,
},
{
6,
146,
116,
},
},
3,
},
{
34,
Medium,
dataEncoderType27To40,
[]block{
{
14,
74,
46,
},
{
23,
75,
47,
},
},
3,
},
{
34,
High,
dataEncoderType27To40,
[]block{
{
44,
54,
24,
},
{
7,
55,
25,
},
},
3,
},
{
34,
Highest,
dataEncoderType27To40,
[]block{
{
59,
46,
16,
},
{
1,
47,
17,
},
},
3,
},
{
35,
Low,
dataEncoderType27To40,
[]block{
{
12,
151,
121,
},
{
7,
152,
122,
},
},
0,
},
{
35,
Medium,
dataEncoderType27To40,
[]block{
{
12,
75,
47,
},
{
26,
76,
48,
},
},
0,
},
{
35,
High,
dataEncoderType27To40,
[]block{
{
39,
54,
24,
},
{
14,
55,
25,
},
},
0,
},
{
35,
Highest,
dataEncoderType27To40,
[]block{
{
22,
45,
15,
},
{
41,
46,
16,
},
},
0,
},
{
36,
Low,
dataEncoderType27To40,
[]block{
{
6,
151,
121,
},
{
14,
152,
122,
},
},
0,
},
{
36,
Medium,
dataEncoderType27To40,
[]block{
{
6,
75,
47,
},
{
34,
76,
48,
},
},
0,
},
{
36,
High,
dataEncoderType27To40,
[]block{
{
46,
54,
24,
},
{
10,
55,
25,
},
},
0,
},
{
36,
Highest,
dataEncoderType27To40,
[]block{
{
2,
45,
15,
},
{
64,
46,
16,
},
},
0,
},
{
37,
Low,
dataEncoderType27To40,
[]block{
{
17,
152,
122,
},
{
4,
153,
123,
},
},
0,
},
{
37,
Medium,
dataEncoderType27To40,
[]block{
{
29,
74,
46,
},
{
14,
75,
47,
},
},
0,
},
{
37,
High,
dataEncoderType27To40,
[]block{
{
49,
54,
24,
},
{
10,
55,
25,
},
},
0,
},
{
37,
Highest,
dataEncoderType27To40,
[]block{
{
24,
45,
15,
},
{
46,
46,
16,
},
},
0,
},
{
38,
Low,
dataEncoderType27To40,
[]block{
{
4,
152,
122,
},
{
18,
153,
123,
},
},
0,
},
{
38,
Medium,
dataEncoderType27To40,
[]block{
{
13,
74,
46,
},
{
32,
75,
47,
},
},
0,
},
{
38,
High,
dataEncoderType27To40,
[]block{
{
48,
54,
24,
},
{
14,
55,
25,
},
},
0,
},
{
38,
Highest,
dataEncoderType27To40,
[]block{
{
42,
45,
15,
},
{
32,
46,
16,
},
},
0,
},
{
39,
Low,
dataEncoderType27To40,
[]block{
{
20,
147,
117,
},
{
4,
148,
118,
},
},
0,
},
{
39,
Medium,
dataEncoderType27To40,
[]block{
{
40,
75,
47,
},
{
7,
76,
48,
},
},
0,
},
{
39,
High,
dataEncoderType27To40,
[]block{
{
43,
54,
24,
},
{
22,
55,
25,
},
},
0,
},
{
39,
Highest,
dataEncoderType27To40,
[]block{
{
10,
45,
15,
},
{
67,
46,
16,
},
},
0,
},
{
40,
Low,
dataEncoderType27To40,
[]block{
{
19,
148,
118,
},
{
6,
149,
119,
},
},
0,
},
{
40,
Medium,
dataEncoderType27To40,
[]block{
{
18,
75,
47,
},
{
31,
76,
48,
},
},
0,
},
{
40,
High,
dataEncoderType27To40,
[]block{
{
34,
54,
24,
},
{
34,
55,
25,
},
},
0,
},
{
40,
Highest,
dataEncoderType27To40,
[]block{
{
20,
45,
15,
},
{
61,
46,
16,
},
},
0,
},
}
)
var (
// Each QR Code contains a 15-bit Format Information value. The 15 bits
// consist of 5 data bits concatenated with 10 error correction bits.
//
// The 5 data bits consist of:
// - 2 bits for the error correction level (L=01, M=00, G=11, H=10).
// - 3 bits for the data mask pattern identifier.
//
// formatBitSequence is a mapping from the 5 data bits to the completed 15-bit
// Format Information value.
//
// For example, a QR Code using error correction level L, and data mask
// pattern identifier 001:
//
// 01 | 001 = 01001 = 0x9
// formatBitSequence[0x9].qrCode = 0x72f3 = 111001011110011
formatBitSequence = []struct {
regular uint32
micro uint32
}{
{0x5412, 0x4445},
{0x5125, 0x4172},
{0x5e7c, 0x4e2b},
{0x5b4b, 0x4b1c},
{0x45f9, 0x55ae},
{0x40ce, 0x5099},
{0x4f97, 0x5fc0},
{0x4aa0, 0x5af7},
{0x77c4, 0x6793},
{0x72f3, 0x62a4},
{0x7daa, 0x6dfd},
{0x789d, 0x68ca},
{0x662f, 0x7678},
{0x6318, 0x734f},
{0x6c41, 0x7c16},
{0x6976, 0x7921},
{0x1689, 0x06de},
{0x13be, 0x03e9},
{0x1ce7, 0x0cb0},
{0x19d0, 0x0987},
{0x0762, 0x1735},
{0x0255, 0x1202},
{0x0d0c, 0x1d5b},
{0x083b, 0x186c},
{0x355f, 0x2508},
{0x3068, 0x203f},
{0x3f31, 0x2f66},
{0x3a06, 0x2a51},
{0x24b4, 0x34e3},
{0x2183, 0x31d4},
{0x2eda, 0x3e8d},
{0x2bed, 0x3bba},
}
// QR Codes version 7 and higher contain an 18-bit Version Information value,
// consisting of a 6 data bits and 12 error correction bits.
//
// versionBitSequence is a mapping from QR Code version to the completed
// 18-bit Version Information value.
//
// For example, a QR code of version 7:
// versionBitSequence[0x7] = 0x07c94 = 000111110010010100
versionBitSequence = []uint32{
0x00000,
0x00000,
0x00000,
0x00000,
0x00000,
0x00000,
0x00000,
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,
}
)
const (
formatInfoLengthBits = 15
versionInfoLengthBits = 18
)
// formatInfo returns the 15-bit Format Information value for a QR
// code.
func (v qrCodeVersion) formatInfo(maskPattern int) *bitset.Bitset {
formatID := 0
switch v.level {
case Low:
formatID = 0x08 // 0b01000
case Medium:
formatID = 0x00 // 0b00000
case High:
formatID = 0x18 // 0b11000
case Highest:
formatID = 0x10 // 0b10000
default:
log.Panicf("Invalid level %d", v.level)
}
if maskPattern < 0 || maskPattern > 7 {
log.Panicf("Invalid maskPattern %d", maskPattern)
}
formatID |= maskPattern & 0x7
result := bitset.New()
result.AppendUint32(formatBitSequence[formatID].regular, formatInfoLengthBits)
return result
}
// versionInfo returns the 18-bit Version Information value for a QR Code.
//
// Version Information is applicable only to QR Codes versions 7-40 inclusive.
// nil is returned if Version Information is not required.
func (v qrCodeVersion) versionInfo() *bitset.Bitset {
if v.version < 7 {
return nil
}
result := bitset.New()
result.AppendUint32(versionBitSequence[v.version], 18)
return result
}
// numDataBits returns the data capacity in bits.
func (v qrCodeVersion) numDataBits() int {
numDataBits := 0
for _, b := range v.block {
numDataBits += 8 * b.numBlocks * b.numDataCodewords // 8 bits in a byte
}
return numDataBits
}
// chooseQRCodeVersion chooses the most suitable QR Code version for a stated
// data length in bits, the error recovery level required, and the data encoder
// used.
//
// The chosen QR Code version is the smallest version able to fit numDataBits
// and the optional terminator bits required by the specified encoder.
//
// On success the chosen QR Code version is returned.
func chooseQRCodeVersion(level RecoveryLevel, encoder *dataEncoder, numDataBits int) *qrCodeVersion {
var chosenVersion *qrCodeVersion
for _, v := range versions {
if v.level != level {
continue
} else if v.version < encoder.minVersion {
continue
} else if v.version > encoder.maxVersion {
break
}
numFreeBits := v.numDataBits() - numDataBits
if numFreeBits >= 0 {
chosenVersion = &v
break
}
}
return chosenVersion
}
func (v qrCodeVersion) numTerminatorBitsRequired(numDataBits int) int {
numFreeBits := v.numDataBits() - numDataBits
var numTerminatorBits int
switch {
case numFreeBits >= 4:
numTerminatorBits = 4
default:
numTerminatorBits = numFreeBits
}
return numTerminatorBits
}
// numBlocks returns the number of blocks.
func (v qrCodeVersion) numBlocks() int {
numBlocks := 0
for _, b := range v.block {
numBlocks += b.numBlocks
}
return numBlocks
}
// numBitsToPadToCodeword returns the number of bits required to pad data of
// length numDataBits upto the nearest codeword size.
func (v qrCodeVersion) numBitsToPadToCodeword(numDataBits int) int {
if numDataBits == v.numDataBits() {
return 0
}
return (8 - numDataBits%8) % 8
}
// symbolSize returns the size of the QR Code symbol in number of modules (which
// is both the width and height, since QR codes are square). The QR Code has
// size symbolSize() x symbolSize() pixels. This does not include the quiet
// zone.
func (v qrCodeVersion) symbolSize() int {
return 21 + (v.version-1)*4
}
// quietZoneSize returns the number of pixels of border space on each side of
// the QR Code. The quiet space assists with decoding.
func (v qrCodeVersion) quietZoneSize() int {
return 4
}
// getQRCodeVersion returns the QR Code version by version number and recovery
// level. Returns nil if the requested combination is not defined.
func getQRCodeVersion(level RecoveryLevel, version int) *qrCodeVersion {
for _, v := range versions {
if v.level == level && v.version == version {
return &v
}
}
return nil
}