-
Notifications
You must be signed in to change notification settings - Fork 1
/
qr.go
84 lines (74 loc) · 1.89 KB
/
qr.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
// Copyright 2017 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package gs1qr
import (
"errors"
"rsc.io/qr"
"rsc.io/qr/coding"
)
// Encode returns an encoding of the list of QR data encoding schemes
// at the given error correction level.
func Encode(list []coding.Encoding, level coding.Level, minVersion coding.Version) (*qr.Code, *coding.Plan, error) {
// Pick size.
l := coding.Level(level)
v := minVersion
if v == 0 {
v = coding.MinVersion
}
for ; ; v++ {
if v > coding.MaxVersion {
return nil, nil, errors.New("text too long to encode as QR")
}
nBits := 0
for _, enc := range list {
nBits += enc.Bits(v)
}
if nBits <= v.DataBytes(l)*8 {
break
}
}
// Build and execute plan.
p, err := coding.NewPlan(v, l, 0)
if err != nil {
return nil, nil, err
}
cc, err := p.Encode(list...)
if err != nil {
return nil, p, err
}
// TODO: Pick appropriate mask.
return &qr.Code{
Bitmap: cc.Bitmap,
Size: cc.Size,
Stride: cc.Stride,
Scale: 8}, p, nil
}
func pickEncoding(text string) coding.Encoding {
// Pick data encoding, smallest first.
// We could split the string and use different encodings
// but that seems like overkill for now.
switch {
case coding.Num(text).Check() == nil:
return coding.Num(text)
case coding.Alpha(text).Check() == nil:
return coding.Alpha(text)
}
return coding.String(text)
}
// Bytes returns, for debugging purposes, a binary representation of the
// list of QR data encoding schemes at the given error correction level.
func Bytes(list []coding.Encoding, l coding.Level, v coding.Version) ([]byte, error) {
var b coding.Bits
for _, t := range list {
if err := t.Check(); err != nil {
return nil, err
}
t.Encode(&b, v)
}
b.AddCheckBytes(v, l)
if n := b.Bits() % 8; n != 0 {
b.Write(0, 8-n)
}
return b.Bytes(), nil
}