summaryrefslogtreecommitdiffstats
path: root/vendor/rsc.io
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/rsc.io')
-rw-r--r--vendor/rsc.io/qr/LICENSE27
-rw-r--r--vendor/rsc.io/qr/README.md3
-rw-r--r--vendor/rsc.io/qr/coding/qr.go815
-rw-r--r--vendor/rsc.io/qr/gf256/gf256.go241
-rw-r--r--vendor/rsc.io/qr/png.go400
-rw-r--r--vendor/rsc.io/qr/qr.go116
6 files changed, 1602 insertions, 0 deletions
diff --git a/vendor/rsc.io/qr/LICENSE b/vendor/rsc.io/qr/LICENSE
new file mode 100644
index 00000000..6a66aea5
--- /dev/null
+++ b/vendor/rsc.io/qr/LICENSE
@@ -0,0 +1,27 @@
+Copyright (c) 2009 The Go Authors. All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are
+met:
+
+ * Redistributions of source code must retain the above copyright
+notice, this list of conditions and the following disclaimer.
+ * Redistributions in binary form must reproduce the above
+copyright notice, this list of conditions and the following disclaimer
+in the documentation and/or other materials provided with the
+distribution.
+ * Neither the name of Google Inc. nor the names of its
+contributors may be used to endorse or promote products derived from
+this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
diff --git a/vendor/rsc.io/qr/README.md b/vendor/rsc.io/qr/README.md
new file mode 100644
index 00000000..0ba6214d
--- /dev/null
+++ b/vendor/rsc.io/qr/README.md
@@ -0,0 +1,3 @@
+Basic QR encoder.
+
+go get [-u] rsc.io/qr
diff --git a/vendor/rsc.io/qr/coding/qr.go b/vendor/rsc.io/qr/coding/qr.go
new file mode 100644
index 00000000..bfc3ea40
--- /dev/null
+++ b/vendor/rsc.io/qr/coding/qr.go
@@ -0,0 +1,815 @@
+// Copyright 2011 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 coding implements low-level QR coding details.
+package coding // import "rsc.io/qr/coding"
+
+import (
+ "fmt"
+ "strconv"
+ "strings"
+
+ "rsc.io/qr/gf256"
+)
+
+// Field is the field for QR error correction.
+var Field = gf256.NewField(0x11d, 2)
+
+// A Version represents a QR version.
+// The version specifies the size of the QR code:
+// a QR code with version v has 4v+17 pixels on a side.
+// Versions number from 1 to 40: the larger the version,
+// the more information the code can store.
+type Version int
+
+const MinVersion = 1
+const MaxVersion = 40
+
+func (v Version) String() string {
+ return strconv.Itoa(int(v))
+}
+
+func (v Version) sizeClass() int {
+ if v <= 9 {
+ return 0
+ }
+ if v <= 26 {
+ return 1
+ }
+ return 2
+}
+
+// DataBytes returns the number of data bytes that can be
+// stored in a QR code with the given version and level.
+func (v Version) DataBytes(l Level) int {
+ vt := &vtab[v]
+ lev := &vt.level[l]
+ return vt.bytes - lev.nblock*lev.check
+}
+
+// Encoding implements a QR data encoding scheme.
+// The implementations--Numeric, Alphanumeric, and String--specify
+// the character set and the mapping from UTF-8 to code bits.
+// The more restrictive the mode, the fewer code bits are needed.
+type Encoding interface {
+ Check() error
+ Bits(v Version) int
+ Encode(b *Bits, v Version)
+}
+
+type Bits struct {
+ b []byte
+ nbit int
+}
+
+func (b *Bits) Reset() {
+ b.b = b.b[:0]
+ b.nbit = 0
+}
+
+func (b *Bits) Bits() int {
+ return b.nbit
+}
+
+func (b *Bits) Bytes() []byte {
+ if b.nbit%8 != 0 {
+ panic("fractional byte")
+ }
+ return b.b
+}
+
+func (b *Bits) Append(p []byte) {
+ if b.nbit%8 != 0 {
+ panic("fractional byte")
+ }
+ b.b = append(b.b, p...)
+ b.nbit += 8 * len(p)
+}
+
+func (b *Bits) Write(v uint, nbit int) {
+ for nbit > 0 {
+ n := nbit
+ if n > 8 {
+ n = 8
+ }
+ if b.nbit%8 == 0 {
+ b.b = append(b.b, 0)
+ } else {
+ m := -b.nbit & 7
+ if n > m {
+ n = m
+ }
+ }
+ b.nbit += n
+ sh := uint(nbit - n)
+ b.b[len(b.b)-1] |= uint8(v >> sh << uint(-b.nbit&7))
+ v -= v >> sh << sh
+ nbit -= n
+ }
+}
+
+// Num is the encoding for numeric data.
+// The only valid characters are the decimal digits 0 through 9.
+type Num string
+
+func (s Num) String() string {
+ return fmt.Sprintf("Num(%#q)", string(s))
+}
+
+func (s Num) Check() error {
+ for _, c := range s {
+ if c < '0' || '9' < c {
+ return fmt.Errorf("non-numeric string %#q", string(s))
+ }
+ }
+ return nil
+}
+
+var numLen = [3]int{10, 12, 14}
+
+func (s Num) Bits(v Version) int {
+ return 4 + numLen[v.sizeClass()] + (10*len(s)+2)/3
+}
+
+func (s Num) Encode(b *Bits, v Version) {
+ b.Write(1, 4)
+ b.Write(uint(len(s)), numLen[v.sizeClass()])
+ var i int
+ for i = 0; i+3 <= len(s); i += 3 {
+ w := uint(s[i]-'0')*100 + uint(s[i+1]-'0')*10 + uint(s[i+2]-'0')
+ b.Write(w, 10)
+ }
+ switch len(s) - i {
+ case 1:
+ w := uint(s[i] - '0')
+ b.Write(w, 4)
+ case 2:
+ w := uint(s[i]-'0')*10 + uint(s[i+1]-'0')
+ b.Write(w, 7)
+ }
+}
+
+// Alpha is the encoding for alphanumeric data.
+// The valid characters are 0-9A-Z$%*+-./: and space.
+type Alpha string
+
+const alphabet = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ $%*+-./:"
+
+func (s Alpha) String() string {
+ return fmt.Sprintf("Alpha(%#q)", string(s))
+}
+
+func (s Alpha) Check() error {
+ for _, c := range s {
+ if strings.IndexRune(alphabet, c) < 0 {
+ return fmt.Errorf("non-alphanumeric string %#q", string(s))
+ }
+ }
+ return nil
+}
+
+var alphaLen = [3]int{9, 11, 13}
+
+func (s Alpha) Bits(v Version) int {
+ return 4 + alphaLen[v.sizeClass()] + (11*len(s)+1)/2
+}
+
+func (s Alpha) Encode(b *Bits, v Version) {
+ b.Write(2, 4)
+ b.Write(uint(len(s)), alphaLen[v.sizeClass()])
+ var i int
+ for i = 0; i+2 <= len(s); i += 2 {
+ w := uint(strings.IndexRune(alphabet, rune(s[i])))*45 +
+ uint(strings.IndexRune(alphabet, rune(s[i+1])))
+ b.Write(w, 11)
+ }
+
+ if i < len(s) {
+ w := uint(strings.IndexRune(alphabet, rune(s[i])))
+ b.Write(w, 6)
+ }
+}
+
+// String is the encoding for 8-bit data. All bytes are valid.
+type String string
+
+func (s String) String() string {
+ return fmt.Sprintf("String(%#q)", string(s))
+}
+
+func (s String) Check() error {
+ return nil
+}
+
+var stringLen = [3]int{8, 16, 16}
+
+func (s String) Bits(v Version) int {
+ return 4 + stringLen[v.sizeClass()] + 8*len(s)
+}
+
+func (s String) Encode(b *Bits, v Version) {
+ b.Write(4, 4)
+ b.Write(uint(len(s)), stringLen[v.sizeClass()])
+ for i := 0; i < len(s); i++ {
+ b.Write(uint(s[i]), 8)
+ }
+}
+
+// A Pixel describes a single pixel in a QR code.
+type Pixel uint32
+
+const (
+ Black Pixel = 1 << iota
+ Invert
+)
+
+func (p Pixel) Offset() uint {
+ return uint(p >> 6)
+}
+
+func OffsetPixel(o uint) Pixel {
+ return Pixel(o << 6)
+}
+
+func (r PixelRole) Pixel() Pixel {
+ return Pixel(r << 2)
+}
+
+func (p Pixel) Role() PixelRole {
+ return PixelRole(p>>2) & 15
+}
+
+func (p Pixel) String() string {
+ s := p.Role().String()
+ if p&Black != 0 {
+ s += "+black"
+ }
+ if p&Invert != 0 {
+ s += "+invert"
+ }
+ s += "+" + strconv.FormatUint(uint64(p.Offset()), 10)
+ return s
+}
+
+// A PixelRole describes the role of a QR pixel.
+type PixelRole uint32
+
+const (
+ _ PixelRole = iota
+ Position // position squares (large)
+ Alignment // alignment squares (small)
+ Timing // timing strip between position squares
+ Format // format metadata
+ PVersion // version pattern
+ Unused // unused pixel
+ Data // data bit
+ Check // error correction check bit
+ Extra
+)
+
+var roles = []string{
+ "",
+ "position",
+ "alignment",
+ "timing",
+ "format",
+ "pversion",
+ "unused",
+ "data",
+ "check",
+ "extra",
+}
+
+func (r PixelRole) String() string {
+ if Position <= r && r <= Check {
+ return roles[r]
+ }
+ return strconv.Itoa(int(r))
+}
+
+// A Level represents a QR error correction level.
+// From least to most tolerant of errors, they are L, M, Q, H.
+type Level int
+
+const (
+ L Level = iota
+ M
+ Q
+ H
+)
+
+func (l Level) String() string {
+ if L <= l && l <= H {
+ return "LMQH"[l : l+1]
+ }
+ return strconv.Itoa(int(l))
+}
+
+// A Code is a square pixel grid.
+type Code struct {
+ Bitmap []byte // 1 is black, 0 is white
+ Size int // number of pixels on a side
+ Stride int // number of bytes per row
+}
+
+func (c *Code) Black(x, y int) bool {
+ return 0 <= x && x < c.Size && 0 <= y && y < c.Size &&
+ c.Bitmap[y*c.Stride+x/8]&(1<<uint(7-x&7)) != 0
+}
+
+// A Mask describes a mask that is applied to the QR
+// code to avoid QR artifacts being interpreted as
+// alignment and timing patterns (such as the squares
+// in the corners). Valid masks are integers from 0 to 7.
+type Mask int
+
+// http://www.swetake.com/qr/qr5_en.html
+var mfunc = []func(int, int) bool{
+ func(i, j int) bool { return (i+j)%2 == 0 },
+ func(i, j int) bool { return i%2 == 0 },
+ func(i, j int) bool { return j%3 == 0 },
+ func(i, j int) bool { return (i+j)%3 == 0 },
+ func(i, j int) bool { return (i/2+j/3)%2 == 0 },
+ func(i, j int) bool { return i*j%2+i*j%3 == 0 },
+ func(i, j int) bool { return (i*j%2+i*j%3)%2 == 0 },
+ func(i, j int) bool { return (i*j%3+(i+j)%2)%2 == 0 },
+}
+
+func (m Mask) Invert(y, x int) bool {
+ if m < 0 {
+ return false
+ }
+ return mfunc[m](y, x)
+}
+
+// A Plan describes how to construct a QR code
+// with a specific version, level, and mask.
+type Plan struct {
+ Version Version
+ Level Level
+ Mask Mask
+
+ DataBytes int // number of data bytes
+ CheckBytes int // number of error correcting (checksum) bytes
+ Blocks int // number of data blocks
+
+ Pixel [][]Pixel // pixel map
+}
+
+// NewPlan returns a Plan for a QR code with the given
+// version, level, and mask.
+func NewPlan(version Version, level Level, mask Mask) (*Plan, error) {
+ p, err := vplan(version)
+ if err != nil {
+ return nil, err
+ }
+ if err := fplan(level, mask, p); err != nil {
+ return nil, err
+ }
+ if err := lplan(version, level, p); err != nil {
+ return nil, err
+ }
+ if err := mplan(mask, p); err != nil {
+ return nil, err
+ }
+ return p, nil
+}
+
+func (b *Bits) Pad(n int) {
+ if n < 0 {
+ panic("qr: invalid pad size")
+ }
+ if n <= 4 {
+ b.Write(0, n)
+ } else {
+ b.Write(0, 4)
+ n -= 4
+ n -= -b.Bits() & 7
+ b.Write(0, -b.Bits()&7)
+ pad := n / 8
+ for i := 0; i < pad; i += 2 {
+ b.Write(0xec, 8)
+ if i+1 >= pad {
+ break
+ }
+ b.Write(0x11, 8)
+ }
+ }
+}
+
+func (b *Bits) AddCheckBytes(v Version, l Level) {
+ nd := v.DataBytes(l)
+ if b.nbit < nd*8 {
+ b.Pad(nd*8 - b.nbit)
+ }
+ if b.nbit != nd*8 {
+ panic("qr: too much data")
+ }
+
+ dat := b.Bytes()
+ vt := &vtab[v]
+ lev := &vt.level[l]
+ db := nd / lev.nblock
+ extra := nd % lev.nblock
+ chk := make([]byte, lev.check)
+ rs := gf256.NewRSEncoder(Field, lev.check)
+ for i := 0; i < lev.nblock; i++ {
+ if i == lev.nblock-extra {
+ db++
+ }
+ rs.ECC(dat[:db], chk)
+ b.Append(chk)
+ dat = dat[db:]
+ }
+
+ if len(b.Bytes()) != vt.bytes {
+ panic("qr: internal error")
+ }
+}
+
+func (p *Plan) Encode(text ...Encoding) (*Code, error) {
+ var b Bits
+ for _, t := range text {
+ if err := t.Check(); err != nil {
+ return nil, err
+ }
+ t.Encode(&b, p.Version)
+ }
+ if b.Bits() > p.DataBytes*8 {
+ return nil, fmt.Errorf("cannot encode %d bits into %d-bit code", b.Bits(), p.DataBytes*8)
+ }
+ b.AddCheckBytes(p.Version, p.Level)
+ bytes := b.Bytes()
+
+ // Now we have the checksum bytes and the data bytes.
+ // Construct the actual code.
+ c := &Code{Size: len(p.Pixel), Stride: (len(p.Pixel) + 7) &^ 7}
+ c.Bitmap = make([]byte, c.Stride*c.Size)
+ crow := c.Bitmap
+ for _, row := range p.Pixel {
+ for x, pix := range row {
+ switch pix.Role() {
+ case Data, Check:
+ o := pix.Offset()
+ if bytes[o/8]&(1<<uint(7-o&7)) != 0 {
+ pix ^= Black
+ }
+ }
+ if pix&Black != 0 {
+ crow[x/8] |= 1 << uint(7-x&7)
+ }
+ }
+ crow = crow[c.Stride:]
+ }
+ return c, nil
+}
+
+// A version describes metadata associated with a version.
+type version struct {
+ apos int
+ astride int
+ bytes int
+ pattern int
+ level [4]level
+}
+
+type level struct {
+ nblock int
+ check int
+}
+
+var vtab = []version{
+ {},
+ {100, 100, 26, 0x0, [4]level{{1, 7}, {1, 10}, {1, 13}, {1, 17}}}, // 1
+ {16, 100, 44, 0x0, [4]level{{1, 10}, {1, 16}, {1, 22}, {1, 28}}}, // 2
+ {20, 100, 70, 0x0, [4]level{{1, 15}, {1, 26}, {2, 18}, {2, 22}}}, // 3
+ {24, 100, 100, 0x0, [4]level{{1, 20}, {2, 18}, {2, 26}, {4, 16}}}, // 4
+ {28, 100, 134, 0x0, [4]level{{1, 26}, {2, 24}, {4, 18}, {4, 22}}}, // 5
+ {32, 100, 172, 0x0, [4]level{{2, 18}, {4, 16}, {4, 24}, {4, 28}}}, // 6
+ {20, 16, 196, 0x7c94, [4]level{{2, 20}, {4, 18}, {6, 18}, {5, 26}}}, // 7
+ {22, 18, 242, 0x85bc, [4]level{{2, 24}, {4, 22}, {6, 22}, {6, 26}}}, // 8
+ {24, 20, 292, 0x9a99, [4]level{{2, 30}, {5, 22}, {8, 20}, {8, 24}}}, // 9
+ {26, 22, 346, 0xa4d3, [4]level{{4, 18}, {5, 26}, {8, 24}, {8, 28}}}, // 10
+ {28, 24, 404, 0xbbf6, [4]level{{4, 20}, {5, 30}, {8, 28}, {11, 24}}}, // 11
+ {30, 26, 466, 0xc762, [4]level{{4, 24}, {8, 22}, {10, 26}, {11, 28}}}, // 12
+ {32, 28, 532, 0xd847, [4]level{{4, 26}, {9, 22}, {12, 24}, {16, 22}}}, // 13
+ {24, 20, 581, 0xe60d, [4]level{{4, 30}, {9, 24}, {16, 20}, {16, 24}}}, // 14
+ {24, 22, 655, 0xf928, [4]level{{6, 22}, {10, 24}, {12, 30}, {18, 24}}}, // 15
+ {24, 24, 733, 0x10b78, [4]level{{6, 24}, {10, 28}, {17, 24}, {16, 30}}}, // 16
+ {28, 24, 815, 0x1145d, [4]level{{6, 28}, {11, 28}, {16, 28}, {19, 28}}}, // 17
+ {28, 26, 901, 0x12a17, [4]level{{6, 30}, {13, 26}, {18, 28}, {21, 28}}}, // 18
+ {28, 28, 991, 0x13532, [4]level{{7, 28}, {14, 26}, {21, 26}, {25, 26}}}, // 19
+ {32, 28, 1085, 0x149a6, [4]level{{8, 28}, {16, 26}, {20, 30}, {25, 28}}}, // 20
+ {26, 22, 1156, 0x15683, [4]level{{8, 28}, {17, 26}, {23, 28}, {25, 30}}}, // 21
+ {24, 24, 1258, 0x168c9, [4]level{{9, 28}, {17, 28}, {23, 30}, {34, 24}}}, // 22
+ {28, 24, 1364, 0x177ec, [4]level{{9, 30}, {18, 28}, {25, 30}, {30, 30}}}, // 23
+ {26, 26, 1474, 0x18ec4, [4]level{{10, 30}, {20, 28}, {27, 30}, {32, 30}}}, // 24
+ {30, 26, 1588, 0x191e1, [4]level{{12, 26}, {21, 28}, {29, 30}, {35, 30}}}, // 25
+ {28, 28, 1706, 0x1afab, [4]level{{12, 28}, {23, 28}, {34, 28}, {37, 30}}}, // 26
+ {32, 28, 1828, 0x1b08e, [4]level{{12, 30}, {25, 28}, {34, 30}, {40, 30}}}, // 27
+ {24, 24, 1921, 0x1cc1a, [4]level{{13, 30}, {26, 28}, {35, 30}, {42, 30}}}, // 28
+ {28, 24, 2051, 0x1d33f, [4]level{{14, 30}, {28, 28}, {38, 30}, {45, 30}}}, // 29
+ {24, 26, 2185, 0x1ed75, [4]level{{15, 30}, {29, 28}, {40, 30}, {48, 30}}}, // 30
+ {28, 26, 2323, 0x1f250, [4]level{{16, 30}, {31, 28}, {43, 30}, {51, 30}}}, // 31
+ {32, 26, 2465, 0x209d5, [4]level{{17, 30}, {33, 28}, {45, 30}, {54, 30}}}, // 32
+ {28, 28, 2611, 0x216f0, [4]level{{18, 30}, {35, 28}, {48, 30}, {57, 30}}}, // 33
+ {32, 28, 2761, 0x228ba, [4]level{{19, 30}, {37, 28}, {51, 30}, {60, 30}}}, // 34
+ {28, 24, 2876, 0x2379f, [4]level{{19, 30}, {38, 28}, {53, 30}, {63, 30}}}, // 35
+ {22, 26, 3034, 0x24b0b, [4]level{{20, 30}, {40, 28}, {56, 30}, {66, 30}}}, // 36
+ {26, 26, 3196, 0x2542e, [4]level{{21, 30}, {43, 28}, {59, 30}, {70, 30}}}, // 37
+ {30, 26, 3362, 0x26a64, [4]level{{22, 30}, {45, 28}, {62, 30}, {74, 30}}}, // 38
+ {24, 28, 3532, 0x27541, [4]level{{24, 30}, {47, 28}, {65, 30}, {77, 30}}}, // 39
+ {28, 28, 3706, 0x28c69, [4]level{{25, 30}, {49, 28}, {68, 30}, {81, 30}}}, // 40
+}
+
+func grid(siz int) [][]Pixel {
+ m := make([][]Pixel, siz)
+ pix := make([]Pixel, siz*siz)
+ for i := range m {
+ m[i], pix = pix[:siz], pix[siz:]
+ }
+ return m
+}
+
+// vplan creates a Plan for the given version.
+func vplan(v Version) (*Plan, error) {
+ p := &Plan{Version: v}
+ if v < 1 || v > 40 {
+ return nil, fmt.Errorf("invalid QR version %d", int(v))
+ }
+ siz := 17 + int(v)*4
+ m := grid(siz)
+ p.Pixel = m
+
+ // Timing markers (overwritten by boxes).
+ const ti = 6 // timing is in row/column 6 (counting from 0)
+ for i := range m {
+ p := Timing.Pixel()
+ if i&1 == 0 {
+ p |= Black
+ }
+ m[i][ti] = p
+ m[ti][i] = p
+ }
+
+ // Position boxes.
+ posBox(m, 0, 0)
+ posBox(m, siz-7, 0)
+ posBox(m, 0, siz-7)
+
+ // Alignment boxes.
+ info := &vtab[v]
+ for x := 4; x+5 < siz; {
+ for y := 4; y+5 < siz; {
+ // don't overwrite timing markers
+ if (x < 7 && y < 7) || (x < 7 && y+5 >= siz-7) || (x+5 >= siz-7 && y < 7) {
+ } else {
+ alignBox(m, x, y)
+ }
+ if y == 4 {
+ y = info.apos
+ } else {
+ y += info.astride
+ }
+ }
+ if x == 4 {
+ x = info.apos
+ } else {
+ x += info.astride
+ }
+ }
+
+ // Version pattern.
+ pat := vtab[v].pattern
+ if pat != 0 {
+ v := pat
+ for x := 0; x < 6; x++ {
+ for y := 0; y < 3; y++ {
+ p := PVersion.Pixel()
+ if v&1 != 0 {
+ p |= Black
+ }
+ m[siz-11+y][x] = p
+ m[x][siz-11+y] = p
+ v >>= 1
+ }
+ }
+ }
+
+ // One lonely black pixel
+ m[siz-8][8] = Unused.Pixel() | Black
+
+ return p, nil
+}
+
+// fplan adds the format pixels
+func fplan(l Level, m Mask, p *Plan) error {
+ // Format pixels.
+ fb := uint32(l^1) << 13 // level: L=01, M=00, Q=11, H=10
+ fb |= uint32(m) << 10 // mask
+ const formatPoly = 0x537
+ rem := fb
+ for i := 14; i >= 10; i-- {
+ if rem&(1<<uint(i)) != 0 {
+ rem ^= formatPoly << uint(i-10)
+ }
+ }
+ fb |= rem
+ invert := uint32(0x5412)
+ siz := len(p.Pixel)
+ for i := uint(0); i < 15; i++ {
+ pix := Format.Pixel() + OffsetPixel(i)
+ if (fb>>i)&1 == 1 {
+ pix |= Black
+ }
+ if (invert>>i)&1 == 1 {
+ pix ^= Invert | Black
+ }
+ // top left
+ switch {
+ case i < 6:
+ p.Pixel[i][8] = pix
+ case i < 8:
+ p.Pixel[i+1][8] = pix
+ case i < 9:
+ p.Pixel[8][7] = pix
+ default:
+ p.Pixel[8][14-i] = pix
+ }
+ // bottom right
+ switch {
+ case i < 8:
+ p.Pixel[8][siz-1-int(i)] = pix
+ default:
+ p.Pixel[siz-1-int(14-i)][8] = pix
+ }
+ }
+ return nil
+}
+
+// lplan edits a version-only Plan to add information
+// about the error correction levels.
+func lplan(v Version, l Level, p *Plan) error {
+ p.Level = l
+
+ nblock := vtab[v].level[l].nblock
+ ne := vtab[v].level[l].check
+ nde := (vtab[v].bytes - ne*nblock) / nblock
+ extra := (vtab[v].bytes - ne*nblock) % nblock
+ dataBits := (nde*nblock + extra) * 8
+ checkBits := ne * nblock * 8
+
+ p.DataBytes = vtab[v].bytes - ne*nblock
+ p.CheckBytes = ne * nblock
+ p.Blocks = nblock
+
+ // Make data + checksum pixels.
+ data := make([]Pixel, dataBits)
+ for i := range data {
+ data[i] = Data.Pixel() | OffsetPixel(uint(i))
+ }
+ check := make([]Pixel, checkBits)
+ for i := range check {
+ check[i] = Check.Pixel() | OffsetPixel(uint(i+dataBits))
+ }
+
+ // Split into blocks.
+ dataList := make([][]Pixel, nblock)
+ checkList := make([][]Pixel, nblock)
+ for i := 0; i < nblock; i++ {
+ // The last few blocks have an extra data byte (8 pixels).
+ nd := nde
+ if i >= nblock-extra {
+ nd++
+ }
+ dataList[i], data = data[0:nd*8], data[nd*8:]
+ checkList[i], check = check[0:ne*8], check[ne*8:]
+ }
+ if len(data) != 0 || len(check) != 0 {
+ panic("data/check math")
+ }
+
+ // Build up bit sequence, taking first byte of each block,
+ // then second byte, and so on. Then checksums.
+ bits := make([]Pixel, dataBits+checkBits)
+ dst := bits
+ for i := 0; i < nde+1; i++ {
+ for _, b := range dataList {
+ if i*8 < len(b) {
+ copy(dst, b[i*8:(i+1)*8])
+ dst = dst[8:]
+ }
+ }
+ }
+ for i := 0; i < ne; i++ {
+ for _, b := range checkList {
+ if i*8 < len(b) {
+ copy(dst, b[i*8:(i+1)*8])
+ dst = dst[8:]
+ }
+ }
+ }
+ if len(dst) != 0 {
+ panic("dst math")
+ }
+
+ // Sweep up pair of columns,
+ // then down, assigning to right then left pixel.
+ // Repeat.
+ // See Figure 2 of http://www.pclviewer.com/rs2/qrtopology.htm
+ siz := len(p.Pixel)
+ rem := make([]Pixel, 7)
+ for i := range rem {
+ rem[i] = Extra.Pixel()
+ }
+ src := append(bits, rem...)
+ for x := siz; x > 0; {
+ for y := siz - 1; y >= 0; y-- {
+ if p.Pixel[y][x-1].Role() == 0 {
+ p.Pixel[y][x-1], src = src[0], src[1:]
+ }
+ if p.Pixel[y][x-2].Role() == 0 {
+ p.Pixel[y][x-2], src = src[0], src[1:]
+ }
+ }
+ x -= 2
+ if x == 7 { // vertical timing strip
+ x--
+ }
+ for y := 0; y < siz; y++ {
+ if p.Pixel[y][x-1].Role() == 0 {
+ p.Pixel[y][x-1], src = src[0], src[1:]
+ }
+ if p.Pixel[y][x-2].Role() == 0 {
+ p.Pixel[y][x-2], src = src[0], src[1:]
+ }
+ }
+ x -= 2
+ }
+ return nil
+}
+
+// mplan edits a version+level-only Plan to add the mask.
+func mplan(m Mask, p *Plan) error {
+ p.Mask = m
+ for y, row := range p.Pixel {
+ for x, pix := range row {
+ if r := pix.Role(); (r == Data || r == Check || r == Extra) && p.Mask.Invert(y, x) {
+ row[x] ^= Black | Invert
+ }
+ }
+ }
+ return nil
+}
+
+// posBox draws a position (large) box at upper left x, y.
+func posBox(m [][]Pixel, x, y int) {
+ pos := Position.Pixel()
+ // box
+ for dy := 0; dy < 7; dy++ {
+ for dx := 0; dx < 7; dx++ {
+ p := pos
+ if dx == 0 || dx == 6 || dy == 0 || dy == 6 || 2 <= dx && dx <= 4 && 2 <= dy && dy <= 4 {
+ p |= Black
+ }
+ m[y+dy][x+dx] = p
+ }
+ }
+ // white border
+ for dy := -1; dy < 8; dy++ {
+ if 0 <= y+dy && y+dy < len(m) {
+ if x > 0 {
+ m[y+dy][x-1] = pos
+ }
+ if x+7 < len(m) {
+ m[y+dy][x+7] = pos
+ }
+ }
+ }
+ for dx := -1; dx < 8; dx++ {
+ if 0 <= x+dx && x+dx < len(m) {
+ if y > 0 {
+ m[y-1][x+dx] = pos
+ }
+ if y+7 < len(m) {
+ m[y+7][x+dx] = pos
+ }
+ }
+ }
+}
+
+// alignBox draw an alignment (small) box at upper left x, y.
+func alignBox(m [][]Pixel, x, y int) {
+ // box
+ align := Alignment.Pixel()
+ for dy := 0; dy < 5; dy++ {
+ for dx := 0; dx < 5; dx++ {
+ p := align
+ if dx == 0 || dx == 4 || dy == 0 || dy == 4 || dx == 2 && dy == 2 {
+ p |= Black
+ }
+ m[y+dy][x+dx] = p
+ }
+ }
+}
diff --git a/vendor/rsc.io/qr/gf256/gf256.go b/vendor/rsc.io/qr/gf256/gf256.go
new file mode 100644
index 00000000..05e56455
--- /dev/null
+++ b/vendor/rsc.io/qr/gf256/gf256.go
@@ -0,0 +1,241 @@
+// Copyright 2010 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 gf256 implements arithmetic over the Galois Field GF(256).
+package gf256 // import "rsc.io/qr/gf256"
+
+import "strconv"
+
+// A Field represents an instance of GF(256) defined by a specific polynomial.
+type Field struct {
+ log [256]byte // log[0] is unused
+ exp [510]byte
+}
+
+// NewField returns a new field corresponding to the polynomial poly
+// and generator α. The Reed-Solomon encoding in QR codes uses
+// polynomial 0x11d with generator 2.
+//
+// The choice of generator α only affects the Exp and Log operations.
+func NewField(poly, α int) *Field {
+ if poly < 0x100 || poly >= 0x200 || reducible(poly) {
+ panic("gf256: invalid polynomial: " + strconv.Itoa(poly))
+ }
+
+ var f Field
+ x := 1
+ for i := 0; i < 255; i++ {
+ if x == 1 && i != 0 {
+ panic("gf256: invalid generator " + strconv.Itoa(α) +
+ " for polynomial " + strconv.Itoa(poly))
+ }
+ f.exp[i] = byte(x)
+ f.exp[i+255] = byte(x)
+ f.log[x] = byte(i)
+ x = mul(x, α, poly)
+ }
+ f.log[0] = 255
+ for i := 0; i < 255; i++ {
+ if f.log[f.exp[i]] != byte(i) {
+ panic("bad log")
+ }
+ if f.log[f.exp[i+255]] != byte(i) {
+ panic("bad log")
+ }
+ }
+ for i := 1; i < 256; i++ {
+ if f.exp[f.log[i]] != byte(i) {
+ panic("bad log")
+ }
+ }
+
+ return &f
+}
+
+// nbit returns the number of significant in p.
+func nbit(p int) uint {
+ n := uint(0)
+ for ; p > 0; p >>= 1 {
+ n++
+ }
+ return n
+}
+
+// polyDiv divides the polynomial p by q and returns the remainder.
+func polyDiv(p, q int) int {
+ np := nbit(p)
+ nq := nbit(q)
+ for ; np >= nq; np-- {
+ if p&(1<<(np-1)) != 0 {
+ p ^= q << (np - nq)
+ }
+ }
+ return p
+}
+
+// mul returns the product x*y mod poly, a GF(256) multiplication.
+func mul(x, y, poly int) int {
+ z := 0
+ for x > 0 {
+ if x&1 != 0 {
+ z ^= y
+ }
+ x >>= 1
+ y <<= 1
+ if y&0x100 != 0 {
+ y ^= poly
+ }
+ }
+ return z
+}
+
+// reducible reports whether p is reducible.
+func reducible(p int) bool {
+ // Multiplying n-bit * n-bit produces (2n-1)-bit,
+ // so if p is reducible, one of its factors must be
+ // of np/2+1 bits or fewer.
+ np := nbit(p)
+ for q := 2; q < 1<<(np/2+1); q++ {
+ if polyDiv(p, q) == 0 {
+ return true
+ }
+ }
+ return false
+}
+
+// Add returns the sum of x and y in the field.
+func (f *Field) Add(x, y byte) byte {
+ return x ^ y
+}
+
+// Exp returns the base-α exponential of e in the field.
+// If e < 0, Exp returns 0.
+func (f *Field) Exp(e int) byte {
+ if e < 0 {
+ return 0
+ }
+ return f.exp[e%255]
+}
+
+// Log returns the base-α logarithm of x in the field.
+// If x == 0, Log returns -1.
+func (f *Field) Log(x byte) int {
+ if x == 0 {
+ return -1
+ }
+ return int(f.log[x])
+}
+
+// Inv returns the multiplicative inverse of x in the field.
+// If x == 0, Inv returns 0.
+func (f *Field) Inv(x byte) byte {
+ if x == 0 {
+ return 0
+ }
+ return f.exp[255-f.log[x]]
+}
+
+// Mul returns the product of x and y in the field.
+func (f *Field) Mul(x, y byte) byte {
+ if x == 0 || y == 0 {
+ return 0
+ }
+ return f.exp[int(f.log[x])+int(f.log[y])]
+}
+
+// An RSEncoder implements Reed-Solomon encoding
+// over a given field using a given number of error correction bytes.
+type RSEncoder struct {
+ f *Field
+ c int
+ gen []byte
+ lgen []byte
+ p []byte
+}
+
+func (f *Field) gen(e int) (gen, lgen []byte) {
+ // p = 1
+ p := make([]byte, e+1)
+ p[e] = 1
+
+ for i := 0; i < e; i++ {
+ // p *= (x + Exp(i))
+ // p[j] = p[j]*Exp(i) + p[j+1].
+ c := f.Exp(i)
+ for j := 0; j < e; j++ {
+ p[j] = f.Mul(p[j], c) ^ p[j+1]
+ }
+ p[e] = f.Mul(p[e], c)
+ }
+
+ // lp = log p.
+ lp := make([]byte, e+1)
+ for i, c := range p {
+ if c == 0 {
+ lp[i] = 255
+ } else {
+ lp[i] = byte(f.Log(c))
+ }
+ }
+
+ return p, lp
+}
+
+// NewRSEncoder returns a new Reed-Solomon encoder
+// over the given field and number of error correction bytes.
+func NewRSEncoder(f *Field, c int) *RSEncoder {
+ gen, lgen := f.gen(c)
+ return &RSEncoder{f: f, c: c, gen: gen, lgen: lgen}
+}
+
+// ECC writes to check the error correcting code bytes
+// for data using the given Reed-Solomon parameters.
+func (rs *RSEncoder) ECC(data []byte, check []byte) {
+ if len(check) < rs.c {
+ panic("gf256: invalid check byte length")
+ }
+ if rs.c == 0 {
+ return
+ }
+
+ // The check bytes are the remainder after dividing
+ // data padded with c zeros by the generator polynomial.
+
+ // p = data padded with c zeros.
+ var p []byte
+ n := len(data) + rs.c
+ if len(rs.p) >= n {
+ p = rs.p
+ } else {
+ p = make([]byte, n)
+ }
+ copy(p, data)
+ for i := len(data); i < len(p); i++ {
+ p[i] = 0
+ }
+
+ // Divide p by gen, leaving the remainder in p[len(data):].
+ // p[0] is the most significant term in p, and
+ // gen[0] is the most significant term in the generator,
+ // which is always 1.
+ // To avoid repeated work, we store various values as
+ // lv, not v, where lv = log[v].
+ f := rs.f
+ lgen := rs.lgen[1:]
+ for i := 0; i < len(data); i++ {
+ c := p[i]
+ if c == 0 {
+ continue
+ }
+ q := p[i+1:]
+ exp := f.exp[f.log[c]:]
+ for j, lg := range lgen {
+ if lg != 255 { // lgen uses 255 for log 0
+ q[j] ^= exp[lg]
+ }
+ }
+ }
+ copy(check, p[len(data):])
+ rs.p = p
+}
diff --git a/vendor/rsc.io/qr/png.go b/vendor/rsc.io/qr/png.go
new file mode 100644
index 00000000..db49d057
--- /dev/null
+++ b/vendor/rsc.io/qr/png.go
@@ -0,0 +1,400 @@
+// Copyright 2011 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 qr
+
+// PNG writer for QR codes.
+
+import (
+ "bytes"
+ "encoding/binary"
+ "hash"
+ "hash/crc32"
+)
+
+// PNG returns a PNG image displaying the code.
+//
+// PNG uses a custom encoder tailored to QR codes.
+// Its compressed size is about 2x away from optimal,
+// but it runs about 20x faster than calling png.Encode
+// on c.Image().
+func (c *Code) PNG() []byte {
+ var p pngWriter
+ return p.encode(c)
+}
+
+type pngWriter struct {
+ tmp [16]byte
+ wctmp [4]byte
+ buf bytes.Buffer
+ zlib bitWriter
+ crc hash.Hash32
+}
+
+var pngHeader = []byte("\x89PNG\r\n\x1a\n")
+
+func (w *pngWriter) encode(c *Code) []byte {
+ scale := c.Scale
+ siz := c.Size
+
+ w.buf.Reset()
+
+ // Header
+ w.buf.Write(pngHeader)
+
+ // Header block
+ binary.BigEndian.PutUint32(w.tmp[0:4], uint32((siz+8)*scale))
+ binary.BigEndian.PutUint32(w.tmp[4:8], uint32((siz+8)*scale))
+ w.tmp[8] = 1 // 1-bit
+ w.tmp[9] = 0 // gray
+ w.tmp[10] = 0
+ w.tmp[11] = 0
+ w.tmp[12] = 0
+ w.writeChunk("IHDR", w.tmp[:13])
+
+ // Comment
+ w.writeChunk("tEXt", comment)
+
+ // Data
+ w.zlib.writeCode(c)
+ w.writeChunk("IDAT", w.zlib.bytes.Bytes())
+
+ // End
+ w.writeChunk("IEND", nil)
+
+ return w.buf.Bytes()
+}
+
+var comment = []byte("Software\x00QR-PNG http://qr.swtch.com/")
+
+func (w *pngWriter) writeChunk(name string, data []byte) {
+ if w.crc == nil {
+ w.crc = crc32.NewIEEE()
+ }
+ binary.BigEndian.PutUint32(w.wctmp[0:4], uint32(len(data)))
+ w.buf.Write(w.wctmp[0:4])
+ w.crc.Reset()
+ copy(w.wctmp[0:4], name)
+ w.buf.Write(w.wctmp[0:4])
+ w.crc.Write(w.wctmp[0:4])
+ w.buf.Write(data)
+ w.crc.Write(data)
+ crc := w.crc.Sum32()
+ binary.BigEndian.PutUint32(w.wctmp[0:4], crc)
+ w.buf.Write(w.wctmp[0:4])
+}
+
+func (b *bitWriter) writeCode(c *Code) {
+ const ftNone = 0
+
+ b.adler32.Reset()
+ b.bytes.Reset()
+ b.nbit = 0
+
+ scale := c.Scale
+ siz := c.Size
+
+ // zlib header
+ b.tmp[0] = 0x78
+ b.tmp[1] = 0
+ b.tmp[1] += uint8(31 - (uint16(b.tmp[0])<<8+uint16(b.tmp[1]))%31)
+ b.bytes.Write(b.tmp[0:2])
+
+ // Start flate block.
+ b.writeBits(1, 1, false) // final block
+ b.writeBits(1, 2, false) // compressed, fixed Huffman tables
+
+ // White border.
+ // First row.
+ b.byte(ftNone)
+ n := (scale*(siz+8) + 7) / 8
+ b.byte(255)
+ b.repeat(n-1, 1)
+ // 4*scale rows total.
+ b.repeat((4*scale-1)*(1+n), 1+n)
+
+ for i := 0; i < 4*scale; i++ {
+ b.adler32.WriteNByte(ftNone, 1)
+ b.adler32.WriteNByte(255, n)
+ }
+
+ row := make([]byte, 1+n)
+ for y := 0; y < siz; y++ {
+ row[0] = ftNone
+ j := 1
+ var z uint8
+ nz := 0
+ for x := -4; x < siz+4; x++ {
+ // Raw data.
+ for i := 0; i < scale; i++ {
+ z <<= 1
+ if !c.Black(x, y) {
+ z |= 1
+ }
+ if nz++; nz == 8 {
+ row[j] = z
+ j++
+ nz = 0
+ }
+ }
+ }
+ if j < len(row) {
+ row[j] = z
+ }
+ for _, z := range row {
+ b.byte(z)
+ }
+
+ // Scale-1 copies.
+ b.repeat((scale-1)*(1+n), 1+n)
+
+ b.adler32.WriteN(row, scale)
+ }
+
+ // White border.
+ // First row.
+ b.byte(ftNone)
+ b.byte(255)
+ b.repeat(n-1, 1)
+ // 4*scale rows total.
+ b.repeat((4*scale-1)*(1+n), 1+n)
+
+ for i := 0; i < 4*scale; i++ {
+ b.adler32.WriteNByte(ftNone, 1)
+ b.adler32.WriteNByte(255, n)
+ }
+
+ // End of block.
+ b.hcode(256)
+ b.flushBits()
+
+ // adler32
+ binary.BigEndian.PutUint32(b.tmp[0:], b.adler32.Sum32())
+ b.bytes.Write(b.tmp[0:4])
+}
+
+// A bitWriter is a write buffer for bit-oriented data like deflate.
+type bitWriter struct {
+ bytes bytes.Buffer
+ bit uint32
+ nbit uint
+
+ tmp [4]byte
+ adler32 adigest
+}
+
+func (b *bitWriter) writeBits(bit uint32, nbit uint, rev bool) {
+ // reverse, for huffman codes
+ if rev {
+ br := uint32(0)
+ for i := uint(0); i < nbit; i++ {
+ br |= ((bit >> i) & 1) << (nbit - 1 - i)
+ }
+ bit = br
+ }
+ b.bit |= bit << b.nbit
+ b.nbit += nbit
+ for b.nbit >= 8 {
+ b.bytes.WriteByte(byte(b.bit))
+ b.bit >>= 8
+ b.nbit -= 8
+ }
+}
+
+func (b *bitWriter) flushBits() {
+ if b.nbit > 0 {
+ b.bytes.WriteByte(byte(b.bit))
+ b.nbit = 0
+ b.bit = 0
+ }
+}
+
+func (b *bitWriter) hcode(v int) {
+ /*
+ Lit Value Bits Codes
+ --------- ---- -----
+ 0 - 143 8 00110000 through
+ 10111111
+ 144 - 255 9 110010000 through
+ 111111111
+ 256 - 279 7 0000000 through
+ 0010111
+ 280 - 287 8 11000000 through
+ 11000111
+ */
+ switch {
+ case v <= 143:
+ b.writeBits(uint32(v)+0x30, 8, true)
+ case v <= 255:
+ b.writeBits(uint32(v-144)+0x190, 9, true)
+ case v <= 279:
+ b.writeBits(uint32(v-256)+0, 7, true)
+ case v <= 287:
+ b.writeBits(uint32(v-280)+0xc0, 8, true)
+ default:
+ panic("invalid hcode")
+ }
+}
+
+func (b *bitWriter) byte(x byte) {
+ b.hcode(int(x))
+}
+
+func (b *bitWriter) codex(c int, val int, nx uint) {
+ b.hcode(c + val>>nx)
+ b.writeBits(uint32(val)&(1<<nx-1), nx, false)
+}
+
+func (b *bitWriter) repeat(n, d int) {
+ for ; n >= 258+3; n -= 258 {
+ b.repeat1(258, d)
+ }
+ if n > 258 {
+ // 258 < n < 258+3
+ b.repeat1(10, d)
+ b.repeat1(n-10, d)
+ return
+ }
+ if n < 3 {
+ panic("invalid flate repeat")
+ }
+ b.repeat1(n, d)
+}
+
+func (b *bitWriter) repeat1(n, d int) {
+ /*
+ Extra Extra Extra
+ Code Bits Length(s) Code Bits Lengths Code Bits Length(s)
+ ---- ---- ------ ---- ---- ------- ---- ---- -------
+ 257 0 3 267 1 15,16 277 4 67-82
+ 258 0 4 268 1 17,18 278 4 83-98
+ 259 0 5 269 2 19-22 279 4 99-114
+ 260 0 6 270 2 23-26 280 4 115-130
+ 261 0 7 271 2 27-30 281 5 131-162
+ 262 0 8 272 2 31-34 282 5 163-194
+ 263 0 9 273 3 35-42 283 5 195-226
+ 264 0 10 274 3 43-50 284 5 227-257
+ 265 1 11,12 275 3 51-58 285 0 258
+ 266 1 13,14 276 3 59-66
+ */
+ switch {
+ case n <= 10:
+ b.codex(257, n-3, 0)
+ case n <= 18:
+ b.codex(265, n-11, 1)
+ case n <= 34:
+ b.codex(269, n-19, 2)
+ case n <= 66:
+ b.codex(273, n-35, 3)
+ case n <= 130:
+ b.codex(277, n-67, 4)
+ case n <= 257:
+ b.codex(281, n-131, 5)
+ case n == 258:
+ b.hcode(285)
+ default:
+ panic("invalid repeat length")
+ }
+
+ /*
+ Extra Extra Extra
+ Code Bits Dist Code Bits Dist Code Bits Distance
+ ---- ---- ---- ---- ---- ------ ---- ---- --------
+ 0 0 1 10 4 33-48 20 9 1025-1536
+ 1 0 2 11 4 49-64 21 9 1537-2048
+ 2 0 3 12 5 65-96 22 10 2049-3072
+ 3 0 4 13 5 97-128 23 10 3073-4096
+ 4 1 5,6 14 6 129-192 24 11 4097-6144
+ 5 1 7,8 15 6 193-256 25 11 6145-8192
+ 6 2 9-12 16 7 257-384 26 12 8193-12288
+ 7 2 13-16 17 7 385-512 27 12 12289-16384
+ 8 3 17-24 18 8 513-768 28 13 16385-24576
+ 9 3 25-32 19 8 769-1024 29 13 24577-32768
+ */
+ if d <= 4 {
+ b.writeBits(uint32(d-1), 5, true)
+ } else if d <= 32768 {
+ nbit := uint(16)
+ for d <= 1<<(nbit-1) {
+ nbit--
+ }
+ v := uint32(d - 1)
+ v &^= 1 << (nbit - 1) // top bit is implicit
+ code := uint32(2*nbit - 2) // second bit is low bit of code
+ code |= v >> (nbit - 2)
+ v &^= 1 << (nbit - 2)
+ b.writeBits(code, 5, true)
+ // rest of bits follow
+ b.writeBits(uint32(v), nbit-2, false)
+ } else {
+ panic("invalid repeat distance")
+ }
+}
+
+func (b *bitWriter) run(v byte, n int) {
+ if n == 0 {
+ return
+ }
+ b.byte(v)
+ if n-1 < 3 {
+ for i := 0; i < n-1; i++ {
+ b.byte(v)
+ }
+ } else {
+ b.repeat(n-1, 1)
+ }
+}
+
+type adigest struct {
+ a, b uint32
+}
+
+func (d *adigest) Reset() { d.a, d.b = 1, 0 }
+
+const amod = 65521
+
+func aupdate(a, b uint32, pi byte, n int) (aa, bb uint32) {
+ // TODO(rsc): 6g doesn't do magic multiplies for b %= amod,
+ // only for b = b%amod.
+
+ // invariant: a, b < amod
+ if pi == 0 {
+ b += uint32(n%amod) * a
+ b = b % amod
+ return a, b
+ }
+
+ // n times:
+ // a += pi
+ // b += a
+ // is same as
+ // b += n*a + n*(n+1)/2*pi
+ // a += n*pi
+ m := uint32(n)
+ b += (m % amod) * a
+ b = b % amod
+ b += (m * (m + 1) / 2) % amod * uint32(pi)
+ b = b % amod
+ a += (m % amod) * uint32(pi)
+ a = a % amod
+ return a, b
+}
+
+func afinish(a, b uint32) uint32 {
+ return b<<16 | a
+}
+
+func (d *adigest) WriteN(p []byte, n int) {
+ for i := 0; i < n; i++ {
+ for _, pi := range p {
+ d.a, d.b = aupdate(d.a, d.b, pi, 1)
+ }
+ }
+}
+
+func (d *adigest) WriteNByte(pi byte, n int) {
+ d.a, d.b = aupdate(d.a, d.b, pi, n)
+}
+
+func (d *adigest) Sum32() uint32 { return afinish(d.a, d.b) }
diff --git a/vendor/rsc.io/qr/qr.go b/vendor/rsc.io/qr/qr.go
new file mode 100644
index 00000000..ace7e6f1
--- /dev/null
+++ b/vendor/rsc.io/qr/qr.go
@@ -0,0 +1,116 @@
+// Copyright 2011 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 qr encodes QR codes.
+*/
+package qr // import "rsc.io/qr"
+
+import (
+ "errors"
+ "image"
+ "image/color"
+
+ "rsc.io/qr/coding"
+)
+
+// A Level denotes a QR error correction level.
+// From least to most tolerant of errors, they are L, M, Q, H.
+type Level int
+
+const (
+ L Level = iota // 20% redundant
+ M // 38% redundant
+ Q // 55% redundant
+ H // 65% redundant
+)
+
+// Encode returns an encoding of text at the given error correction level.
+func Encode(text string, level Level) (*Code, error) {
+ // Pick data encoding, smallest first.
+ // We could split the string and use different encodings
+ // but that seems like overkill for now.
+ var enc coding.Encoding
+ switch {
+ case coding.Num(text).Check() == nil:
+ enc = coding.Num(text)
+ case coding.Alpha(text).Check() == nil:
+ enc = coding.Alpha(text)
+ default:
+ enc = coding.String(text)
+ }
+
+ // Pick size.
+ l := coding.Level(level)
+ var v coding.Version
+ for v = coding.MinVersion; ; v++ {
+ if v > coding.MaxVersion {
+ return nil, errors.New("text too long to encode as QR")
+ }
+ if enc.Bits(v) <= v.DataBytes(l)*8 {
+ break
+ }
+ }
+
+ // Build and execute plan.
+ p, err := coding.NewPlan(v, l, 0)
+ if err != nil {
+ return nil, err
+ }
+ cc, err := p.Encode(enc)
+ if err != nil {
+ return nil, err
+ }
+
+ // TODO: Pick appropriate mask.
+
+ return &Code{cc.Bitmap, cc.Size, cc.Stride, 8}, nil
+}
+
+// A Code is a square pixel grid.
+// It implements image.Image and direct PNG encoding.
+type Code struct {
+ Bitmap []byte // 1 is black, 0 is white
+ Size int // number of pixels on a side
+ Stride int // number of bytes per row
+ Scale int // number of image pixels per QR pixel
+}
+
+// Black returns true if the pixel at (x,y) is black.
+func (c *Code) Black(x, y int) bool {
+ return 0 <= x && x < c.Size && 0 <= y && y < c.Size &&
+ c.Bitmap[y*c.Stride+x/8]&(1<<uint(7-x&7)) != 0
+}
+
+// Image returns an Image displaying the code.
+func (c *Code) Image() image.Image {
+ return &codeImage{c}
+
+}
+
+// codeImage implements image.Image
+type codeImage struct {
+ *Code
+}
+
+var (
+ whiteColor color.Color = color.Gray{0xFF}
+ blackColor color.Color = color.Gray{0x00}
+)
+
+func (c *codeImage) Bounds() image.Rectangle {
+ d := (c.Size + 8) * c.Scale
+ return image.Rect(0, 0, d, d)
+}
+
+func (c *codeImage) At(x, y int) color.Color {
+ if c.Black(x, y) {
+ return blackColor
+ }
+ return whiteColor
+}
+
+func (c *codeImage) ColorModel() color.Model {
+ return color.GrayModel
+}