Browse Source

Merge pull request #133 from dutchcoders/ISSUES-86-66

QR code, html5 player
tags/v1.0.0
Andrea Spacca 5 years ago
committed by GitHub
parent
commit
3b60ba16cd
No known key found for this signature in database GPG Key ID: 4AEE18F83AFDEB23
27 changed files with 9469 additions and 1325 deletions
  1. +14
    -0
      server/handlers.go
  2. +1671
    -1325
      vendor/github.com/dutchcoders/transfer.sh-web/bindata_gen.go
  3. +4
    -0
      vendor/github.com/skip2/go-qrcode/.gitignore
  4. +8
    -0
      vendor/github.com/skip2/go-qrcode/.travis.yml
  5. +19
    -0
      vendor/github.com/skip2/go-qrcode/LICENSE
  6. +80
    -0
      vendor/github.com/skip2/go-qrcode/README.md
  7. +273
    -0
      vendor/github.com/skip2/go-qrcode/bitset/bitset.go
  8. +321
    -0
      vendor/github.com/skip2/go-qrcode/bitset/bitset_test.go
  9. +455
    -0
      vendor/github.com/skip2/go-qrcode/encoder.go
  10. +328
    -0
      vendor/github.com/skip2/go-qrcode/encoder_test.go
  11. +31
    -0
      vendor/github.com/skip2/go-qrcode/example_test.go
  12. +554
    -0
      vendor/github.com/skip2/go-qrcode/qrcode.go
  13. +85
    -0
      vendor/github.com/skip2/go-qrcode/qrcode/main.go
  14. +232
    -0
      vendor/github.com/skip2/go-qrcode/qrcode_decode_test.go
  15. +173
    -0
      vendor/github.com/skip2/go-qrcode/qrcode_test.go
  16. +387
    -0
      vendor/github.com/skip2/go-qrcode/reedsolomon/gf2_8.go
  17. +83
    -0
      vendor/github.com/skip2/go-qrcode/reedsolomon/gf2_8_test.go
  18. +216
    -0
      vendor/github.com/skip2/go-qrcode/reedsolomon/gf_poly.go
  19. +182
    -0
      vendor/github.com/skip2/go-qrcode/reedsolomon/gf_poly_test.go
  20. +73
    -0
      vendor/github.com/skip2/go-qrcode/reedsolomon/reed_solomon.go
  21. +89
    -0
      vendor/github.com/skip2/go-qrcode/reedsolomon/reed_solomon_test.go
  22. +309
    -0
      vendor/github.com/skip2/go-qrcode/regular_symbol.go
  23. +31
    -0
      vendor/github.com/skip2/go-qrcode/regular_symbol_test.go
  24. +309
    -0
      vendor/github.com/skip2/go-qrcode/symbol.go
  25. +334
    -0
      vendor/github.com/skip2/go-qrcode/symbol_test.go
  26. +3050
    -0
      vendor/github.com/skip2/go-qrcode/version.go
  27. +158
    -0
      vendor/github.com/skip2/go-qrcode/version_test.go

+ 14
- 0
server/handlers.go View File

@@ -58,6 +58,9 @@ import (
web "github.com/dutchcoders/transfer.sh-web"
"github.com/gorilla/mux"
"github.com/russross/blackfriday"

qrcode "github.com/skip2/go-qrcode"
"encoding/base64"
)

var (
@@ -147,6 +150,15 @@ func (s *Server) previewHandler(w http.ResponseWriter, r *http.Request) {
return
}

var png []byte
png, err = qrcode.Encode(resolveUrl(r, getURL(r).ResolveReference(r.URL), true), qrcode.High, 150)
if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}

qrCode := base64.StdEncoding.EncodeToString(png)

data := struct {
ContentType string
Content html_template.HTML
@@ -155,6 +167,7 @@ func (s *Server) previewHandler(w http.ResponseWriter, r *http.Request) {
ContentLength uint64
GAKey string
UserVoiceKey string
QRCode string
}{
contentType,
content,
@@ -163,6 +176,7 @@ func (s *Server) previewHandler(w http.ResponseWriter, r *http.Request) {
contentLength,
s.gaKey,
s.userVoiceKey,
qrCode,
}

if err := htmlTemplates.ExecuteTemplate(w, templatePath, data); err != nil {


+ 1671
- 1325
vendor/github.com/dutchcoders/transfer.sh-web/bindata_gen.go
File diff suppressed because it is too large
View File


+ 4
- 0
vendor/github.com/skip2/go-qrcode/.gitignore View File

@@ -0,0 +1,4 @@
*.sw*
*.png
*.directory
qrcode/qrcode

+ 8
- 0
vendor/github.com/skip2/go-qrcode/.travis.yml View File

@@ -0,0 +1,8 @@
language: go

go:
- 1.7

script:
- go test -v ./...


+ 19
- 0
vendor/github.com/skip2/go-qrcode/LICENSE View File

@@ -0,0 +1,19 @@
Copyright (c) 2014 Tom Harwood

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.

+ 80
- 0
vendor/github.com/skip2/go-qrcode/README.md View File

@@ -0,0 +1,80 @@
# go-qrcode #

<img src='https://skip.org/img/nyancat-youtube-qr.png' align='right'>

Package qrcode implements a QR Code encoder. [![Build Status](https://travis-ci.org/skip2/go-qrcode.svg?branch=master)](https://travis-ci.org/skip2/go-qrcode)

A QR Code is a matrix (two-dimensional) barcode. Arbitrary content may be encoded, with URLs being a popular choice :)

Each QR Code contains error recovery information to aid reading damaged or obscured codes. There are four levels of error recovery: Low, medium, high and highest. QR Codes with a higher recovery level are more robust to damage, at the cost of being physically larger.

## Install

go get -u github.com/skip2/go-qrcode/...

A command-line tool `qrcode` will be built into `$GOPATH/bin/`.

## Usage

import qrcode "github.com/skip2/go-qrcode"

- **Create a PNG image:**

var png []byte
png, err := qrcode.Encode("https://example.org", qrcode.Medium, 256)

- **Create a PNG image and write to a file:**

err := qrcode.WriteFile("https://example.org", qrcode.Medium, 256, "qr.png")

- **Create a PNG image with custom colors and write to file:**

err := qrcode.WriteColorFile("https://example.org", qrcode.Medium, 256, color.Black, color.White, "qr.png")

All examples use the qrcode.Medium error Recovery Level and create a fixed
256x256px size QR Code. The last function creates a white on black instead of black
on white QR Code.

The maximum capacity of a QR Code varies according to the content encoded and
the error recovery level. The maximum capacity is 2,953 bytes, 4,296
alphanumeric characters, 7,089 numeric digits, or a combination of these.

## Documentation

[![godoc](https://godoc.org/github.com/skip2/go-qrcode?status.png)](https://godoc.org/github.com/skip2/go-qrcode)

## Demoapp

[http://go-qrcode.appspot.com](http://go-qrcode.appspot.com)

## CLI

A command-line tool `qrcode` will be built into `$GOPATH/bin/`.

```
qrcode -- QR Code encoder in Go
https://github.com/skip2/go-qrcode

Flags:
-o string
out PNG file prefix, empty for stdout
-s int
image size (pixel) (default 256)

Usage:
1. Arguments except for flags are joined by " " and used to generate QR code.
Default output is STDOUT, pipe to imagemagick command "display" to display
on any X server.

qrcode hello word | display

2. Save to file if "display" not available:

qrcode "homepage: https://github.com/skip2/go-qrcode" > out.png
```

## Links

- [http://en.wikipedia.org/wiki/QR_code](http://en.wikipedia.org/wiki/QR_code)
- [ISO/IEC 18004:2006](http://www.iso.org/iso/catalogue_detail.htm?csnumber=43655) - Main QR Code specification (approx CHF 198,00)<br>
- [https://github.com/qpliu/qrencode-go/](https://github.com/qpliu/qrencode-go/) - alternative Go QR encoding library based on [ZXing](https://github.com/zxing/zxing)

+ 273
- 0
vendor/github.com/skip2/go-qrcode/bitset/bitset.go View File

@@ -0,0 +1,273 @@
// go-qrcode
// Copyright 2014 Tom Harwood

// Package bitset implements an append only bit array.
//
// To create a Bitset and append some bits:
// // Bitset Contents
// b := bitset.New() // {}
// b.AppendBools(true, true, false) // {1, 1, 0}
// b.AppendBools(true) // {1, 1, 0, 1}
// b.AppendValue(0x02, 4) // {1, 1, 0, 1, 0, 0, 1, 0}
//
// To read values:
//
// len := b.Len() // 8
// v := b.At(0) // 1
// v = b.At(1) // 1
// v = b.At(2) // 0
// v = b.At(8) // 0
package bitset

import (
"bytes"
"fmt"
"log"
)

const (
b0 = false
b1 = true
)

// Bitset stores an array of bits.
type Bitset struct {
// The number of bits stored.
numBits int

// Storage for individual bits.
bits []byte
}

// New returns an initialised Bitset with optional initial bits v.
func New(v ...bool) *Bitset {
b := &Bitset{numBits: 0, bits: make([]byte, 0)}
b.AppendBools(v...)

return b
}

// Clone returns a copy.
func Clone(from *Bitset) *Bitset {
return &Bitset{numBits: from.numBits, bits: from.bits[:]}
}

// Substr returns a substring, consisting of the bits from indexes start to end.
func (b *Bitset) Substr(start int, end int) *Bitset {
if start > end || end > b.numBits {
log.Panicf("Out of range start=%d end=%d numBits=%d", start, end, b.numBits)
}

result := New()
result.ensureCapacity(end - start)

for i := start; i < end; i++ {
if b.At(i) {
result.bits[result.numBits/8] |= 0x80 >> uint(result.numBits%8)
}
result.numBits++
}

return result
}

// NewFromBase2String constructs and returns a Bitset from a string. The string
// consists of '1', '0' or ' ' characters, e.g. "1010 0101". The '1' and '0'
// characters represent true/false bits respectively, and ' ' characters are
// ignored.
//
// The function panics if the input string contains other characters.
func NewFromBase2String(b2string string) *Bitset {
b := &Bitset{numBits: 0, bits: make([]byte, 0)}

for _, c := range b2string {
switch c {
case '1':
b.AppendBools(true)
case '0':
b.AppendBools(false)
case ' ':
default:
log.Panicf("Invalid char %c in NewFromBase2String", c)
}
}

return b
}

// AppendBytes appends a list of whole bytes.
func (b *Bitset) AppendBytes(data []byte) {
for _, d := range data {
b.AppendByte(d, 8)
}
}

// AppendByte appends the numBits least significant bits from value.
func (b *Bitset) AppendByte(value byte, numBits int) {
b.ensureCapacity(numBits)

if numBits > 8 {
log.Panicf("numBits %d out of range 0-8", numBits)
}

for i := numBits - 1; i >= 0; i-- {
if value&(1<<uint(i)) != 0 {
b.bits[b.numBits/8] |= 0x80 >> uint(b.numBits%8)
}

b.numBits++
}
}

// AppendUint32 appends the numBits least significant bits from value.
func (b *Bitset) AppendUint32(value uint32, numBits int) {
b.ensureCapacity(numBits)

if numBits > 32 {
log.Panicf("numBits %d out of range 0-32", numBits)
}

for i := numBits - 1; i >= 0; i-- {
if value&(1<<uint(i)) != 0 {
b.bits[b.numBits/8] |= 0x80 >> uint(b.numBits%8)
}

b.numBits++
}
}

// ensureCapacity ensures the Bitset can store an additional |numBits|.
//
// The underlying array is expanded if necessary. To prevent frequent
// reallocation, expanding the underlying array at least doubles its capacity.
func (b *Bitset) ensureCapacity(numBits int) {
numBits += b.numBits

newNumBytes := numBits / 8
if numBits%8 != 0 {
newNumBytes++
}

if len(b.bits) >= newNumBytes {
return
}

b.bits = append(b.bits, make([]byte, newNumBytes+2*len(b.bits))...)
}

// Append bits copied from |other|.
//
// The new length is b.Len() + other.Len().
func (b *Bitset) Append(other *Bitset) {
b.ensureCapacity(other.numBits)

for i := 0; i < other.numBits; i++ {
if other.At(i) {
b.bits[b.numBits/8] |= 0x80 >> uint(b.numBits%8)
}
b.numBits++
}
}

// AppendBools appends bits to the Bitset.
func (b *Bitset) AppendBools(bits ...bool) {
b.ensureCapacity(len(bits))

for _, v := range bits {
if v {
b.bits[b.numBits/8] |= 0x80 >> uint(b.numBits%8)
}
b.numBits++
}
}

// AppendNumBools appends num bits of value value.
func (b *Bitset) AppendNumBools(num int, value bool) {
for i := 0; i < num; i++ {
b.AppendBools(value)
}
}

// String returns a human readable representation of the Bitset's contents.
func (b *Bitset) String() string {
var bitString string
for i := 0; i < b.numBits; i++ {
if (i % 8) == 0 {
bitString += " "
}

if (b.bits[i/8] & (0x80 >> byte(i%8))) != 0 {
bitString += "1"
} else {
bitString += "0"
}
}

return fmt.Sprintf("numBits=%d, bits=%s", b.numBits, bitString)
}

// Len returns the length of the Bitset in bits.
func (b *Bitset) Len() int {
return b.numBits
}

// Bits returns the contents of the Bitset.
func (b *Bitset) Bits() []bool {
result := make([]bool, b.numBits)

var i int
for i = 0; i < b.numBits; i++ {
result[i] = (b.bits[i/8] & (0x80 >> byte(i%8))) != 0
}

return result
}

// At returns the value of the bit at |index|.
func (b *Bitset) At(index int) bool {
if index >= b.numBits {
log.Panicf("Index %d out of range", index)
}

return (b.bits[index/8] & (0x80 >> byte(index%8))) != 0
}

// Equals returns true if the Bitset equals other.
func (b *Bitset) Equals(other *Bitset) bool {
if b.numBits != other.numBits {
return false
}

if !bytes.Equal(b.bits[0:b.numBits/8], other.bits[0:b.numBits/8]) {
return false
}

for i := 8 * (b.numBits / 8); i < b.numBits; i++ {
a := (b.bits[i/8] & (0x80 >> byte(i%8)))
b := (other.bits[i/8] & (0x80 >> byte(i%8)))

if a != b {
return false
}
}

return true
}

// ByteAt returns a byte consisting of upto 8 bits starting at index.
func (b *Bitset) ByteAt(index int) byte {
if index < 0 || index >= b.numBits {
log.Panicf("Index %d out of range", index)
}

var result byte

for i := index; i < index+8 && i < b.numBits; i++ {
result <<= 1
if b.At(i) {
result |= 1
}
}

return result
}

+ 321
- 0
vendor/github.com/skip2/go-qrcode/bitset/bitset_test.go View File

@@ -0,0 +1,321 @@
// go-qrcode
// Copyright 2014 Tom Harwood

package bitset

import (
rand "math/rand"
"testing"
)

func TestNewBitset(t *testing.T) {
tests := [][]bool{
{},
{b1},
{b0},
{b1, b0},
{b1, b0, b1},
{b0, b0, b1},
}

for _, v := range tests {
result := New(v...)

if !equal(result.Bits(), v) {
t.Errorf("%s", result.String())
t.Errorf("%v => %v, want %v", v, result.Bits(), v)
}
}
}

func TestAppend(t *testing.T) {
randomBools := make([]bool, 128)

rng := rand.New(rand.NewSource(1))

for i := 0; i < len(randomBools); i++ {
randomBools[i] = rng.Intn(2) == 1
}

for i := 0; i < len(randomBools)-1; i++ {
a := New(randomBools[0:i]...)
b := New(randomBools[i:]...)

a.Append(b)

if !equal(a.Bits(), randomBools) {
t.Errorf("got %v, want %v", a.Bits(), randomBools)
}
}
}

func TestAppendByte(t *testing.T) {
tests := []struct {
initial *Bitset
value byte
numBits int
expected *Bitset
}{
{
New(),
0x01,
1,
New(b1),
},
{
New(b1),
0x01,
1,
New(b1, b1),
},
{
New(b0),
0x01,
1,
New(b0, b1),
},
{
New(b1, b0, b1, b0, b1, b0, b1),
0xAA, // 0b10101010
2,
New(b1, b0, b1, b0, b1, b0, b1, b1, b0),
},
{
New(b1, b0, b1, b0, b1, b0, b1),
0xAA, // 0b10101010
8,
New(b1, b0, b1, b0, b1, b0, b1, b1, b0, b1, b0, b1, b0, b1, b0),
},
}

for _, test := range tests {
test.initial.AppendByte(test.value, test.numBits)
if !equal(test.initial.Bits(), test.expected.Bits()) {
t.Errorf("Got %v, expected %v", test.initial.Bits(),
test.expected.Bits())
}
}
}

func TestAppendUint32(t *testing.T) {
tests := []struct {
initial *Bitset
value uint32
numBits int
expected *Bitset
}{
{
New(),
0xAAAAAAAF,
4,
New(b1, b1, b1, b1),
},
{
New(),
0xFFFFFFFF,
32,
New(b1, b1, b1, b1, b1, b1, b1, b1, b1, b1, b1, b1, b1, b1, b1, b1, b1,
b1, b1, b1, b1, b1, b1, b1, b1, b1, b1, b1, b1, b1, b1, b1),
},
{
New(),
0x0,
32,
New(b0, b0, b0, b0, b0, b0, b0, b0, b0, b0, b0, b0, b0, b0, b0, b0, b0,
b0, b0, b0, b0, b0, b0, b0, b0, b0, b0, b0, b0, b0, b0, b0),
},
{
New(),
0xAAAAAAAA,
32,
New(b1, b0, b1, b0, b1, b0, b1, b0, b1, b0, b1, b0, b1, b0, b1, b0, b1,
b0, b1, b0, b1, b0, b1, b0, b1, b0, b1, b0, b1, b0, b1, b0),
},
{
New(),
0xAAAAAAAA,
31,
New(b0, b1, b0, b1, b0, b1, b0, b1, b0, b1, b0, b1, b0, b1, b0, b1,
b0, b1, b0, b1, b0, b1, b0, b1, b0, b1, b0, b1, b0, b1, b0),
},
}

for _, test := range tests {
test.initial.AppendUint32(test.value, test.numBits)
if !equal(test.initial.Bits(), test.expected.Bits()) {
t.Errorf("Got %v, expected %v", test.initial.Bits(),
test.expected.Bits())
}
}
}

func TestAppendBools(t *testing.T) {
randomBools := make([]bool, 128)

rng := rand.New(rand.NewSource(1))

for i := 0; i < len(randomBools); i++ {
randomBools[i] = rng.Intn(2) == 1
}

for i := 0; i < len(randomBools)-1; i++ {
result := New(randomBools[0:i]...)
result.AppendBools(randomBools[i:]...)

if !equal(result.Bits(), randomBools) {
t.Errorf("got %v, want %v", result.Bits(), randomBools)
}
}
}

func BenchmarkShortAppend(b *testing.B) {
bitset := New()

for i := 0; i < b.N; i++ {
bitset.AppendBools(b0, b1, b0, b1, b0, b1, b0)
}
}

func TestLen(t *testing.T) {
randomBools := make([]bool, 128)

rng := rand.New(rand.NewSource(1))

for i := 0; i < len(randomBools); i++ {
randomBools[i] = rng.Intn(2) == 1
}

for i := 0; i < len(randomBools)-1; i++ {
result := New(randomBools[0:i]...)

if result.Len() != i {
t.Errorf("Len = %d, want %d", result.Len(), i)
}
}
}

func TestAt(t *testing.T) {
test := []bool{b0, b1, b0, b1, b0, b1, b1, b0, b1}

bitset := New(test...)
for i, v := range test {
result := bitset.At(i)

if result != test[i] {
t.Errorf("bitset[%d] => %t, want %t", i, result, v)
}
}
}

func equal(a []bool, b []bool) bool {
if len(a) != len(b) {
return false
}

for i := 0; i < len(a); i++ {
if a[i] != b[i] {
return false
}
}

return true
}

func TestExample(t *testing.T) {
b := New() // {}
b.AppendBools(true, true, false) // {1, 1, 0}
b.AppendBools(true) // {1, 1, 0, 1}
b.AppendByte(0x02, 4) // {1, 1, 0, 1, 0, 0, 1, 0}

expected := []bool{b1, b1, b0, b1, b0, b0, b1, b0}

if !equal(b.Bits(), expected) {
t.Errorf("Got %v, expected %v", b.Bits(), expected)
}
}

func TestByteAt(t *testing.T) {
data := []bool{b0, b1, b0, b1, b0, b1, b1, b0, b1}

tests := []struct {
index int
expected byte
}{
{
0,
0x56,
},
{
1,
0xad,
},
{
2,
0x2d,
},
{
5,
0x0d,
},
{
8,
0x01,
},
}

for _, test := range tests {
b := New()
b.AppendBools(data...)

result := b.ByteAt(test.index)

if result != test.expected {
t.Errorf("Got %#x, expected %#x", result, test.expected)
}
}
}

func TestSubstr(t *testing.T) {
data := []bool{b0, b1, b0, b1, b0, b1, b1, b0}

tests := []struct {
start int
end int
expected []bool
}{
{
0,
8,
[]bool{b0, b1, b0, b1, b0, b1, b1, b0},
},
{
0,
0,
[]bool{},
},
{
0,
1,
[]bool{b0},
},
{
2,
4,
[]bool{b0, b1},
},
}

for _, test := range tests {
b := New()
b.AppendBools(data...)

result := b.Substr(test.start, test.end)

expected := New()
expected.AppendBools(test.expected...)

if !result.Equals(expected) {
t.Errorf("Got %s, expected %s", result.String(), expected.String())
}
}
}

+ 455
- 0
vendor/github.com/skip2/go-qrcode/encoder.go View File

@@ -0,0 +1,455 @@
// go-qrcode
// Copyright 2014 Tom Harwood

package qrcode

import (
"errors"
"log"

bitset "github.com/skip2/go-qrcode/bitset"
)

// Data encoding.
//
// The main data portion of a QR Code consists of one or more segments of data.
// A segment consists of:
//
// - The segment Data Mode: numeric, alphanumeric, or byte.
// - The length of segment in bits.
// - Encoded data.
//
// For example, the string "123ZZ#!#!" may be represented as:
//
// [numeric, 3, "123"] [alphanumeric, 2, "ZZ"] [byte, 4, "#!#!"]
//
// Multiple data modes exist to minimise the size of encoded data. For example,
// 8-bit bytes require 8 bits to encode each, but base 10 numeric data can be
// encoded at a higher density of 3 numbers (e.g. 123) per 10 bits.
//
// Some data can be represented in multiple modes. Numeric data can be
// represented in all three modes, whereas alphanumeric data (e.g. 'A') can be
// represented in alphanumeric and byte mode.
//
// Starting a new segment (to use a different Data Mode) has a cost, the bits to
// state the new segment Data Mode and length. To minimise each QR Code's symbol
// size, an optimisation routine coalesces segment types where possible, to
// reduce the encoded data length.
//
// There are several other data modes available (e.g. Kanji mode) which are not
// implemented here.

// A segment encoding mode.
type dataMode uint8

const (
// Each dataMode is a subset of the subsequent dataMode:
// dataModeNone < dataModeNumeric < dataModeAlphanumeric < dataModeByte
//
// This ordering is important for determining which data modes a character can
// be encoded with. E.g. 'E' can be encoded in both dataModeAlphanumeric and
// dataModeByte.
dataModeNone dataMode = 1 << iota
dataModeNumeric
dataModeAlphanumeric
dataModeByte
)

// dataModeString returns d as a short printable string.
func dataModeString(d dataMode) string {
switch d {
case dataModeNone:
return "none"
case dataModeNumeric:
return "numeric"
case dataModeAlphanumeric:
return "alphanumeric"
case dataModeByte:
return "byte"
}

return "unknown"
}

type dataEncoderType uint8

const (
dataEncoderType1To9 dataEncoderType = iota
dataEncoderType10To26
dataEncoderType27To40
)

// segment is a single segment of data.
type segment struct {
// Data Mode (e.g. numeric).
dataMode dataMode

// segment data (e.g. "abc").
data []byte
}

// A dataEncoder encodes data for a particular QR Code version.
type dataEncoder struct {
// Minimum & maximum versions supported.
minVersion int
maxVersion int

// Mode indicator bit sequences.
numericModeIndicator *bitset.Bitset
alphanumericModeIndicator *bitset.Bitset
byteModeIndicator *bitset.Bitset

// Character count lengths.
numNumericCharCountBits int
numAlphanumericCharCountBits int
numByteCharCountBits int

// The raw input data.
data []byte

// The data classified into unoptimised segments.
actual []segment

// The data classified into optimised segments.
optimised []segment
}

// newDataEncoder constructs a dataEncoder.
func newDataEncoder(t dataEncoderType) *dataEncoder {
d := &dataEncoder{}

switch t {
case dataEncoderType1To9:
d = &dataEncoder{
minVersion: 1,
maxVersion: 9,
numericModeIndicator: bitset.New(b0, b0, b0, b1),
alphanumericModeIndicator: bitset.New(b0, b0, b1, b0),
byteModeIndicator: bitset.New(b0, b1, b0, b0),
numNumericCharCountBits: 10,
numAlphanumericCharCountBits: 9,
numByteCharCountBits: 8,
}
case dataEncoderType10To26:
d = &dataEncoder{
minVersion: 10,
maxVersion: 26,
numericModeIndicator: bitset.New(b0, b0, b0, b1),
alphanumericModeIndicator: bitset.New(b0, b0, b1, b0),
byteModeIndicator: bitset.New(b0, b1, b0, b0),
numNumericCharCountBits: 12,
numAlphanumericCharCountBits: 11,
numByteCharCountBits: 16,
}
case dataEncoderType27To40:
d = &dataEncoder{
minVersion: 27,
maxVersion: 40,
numericModeIndicator: bitset.New(b0, b0, b0, b1),
alphanumericModeIndicator: bitset.New(b0, b0, b1, b0),
byteModeIndicator: bitset.New(b0, b1, b0, b0),
numNumericCharCountBits: 14,
numAlphanumericCharCountBits: 13,
numByteCharCountBits: 16,
}
default:
log.Panic("Unknown dataEncoderType")
}

return d
}

// encode data as one or more segments and return the encoded data.
//
// The returned data does not include the terminator bit sequence.
func (d *dataEncoder) encode(data []byte) (*bitset.Bitset, error) {
d.data = data
d.actual = nil
d.optimised = nil

if len(data) == 0 {
return nil, errors.New("no data to encode")
}

// Classify data into unoptimised segments.
d.classifyDataModes()

// Optimise segments.
err := d.optimiseDataModes()
if err != nil {
return nil, err
}

// Encode data.
encoded := bitset.New()
for _, s := range d.optimised {
d.encodeDataRaw(s.data, s.dataMode, encoded)
}

return encoded, nil
}

// classifyDataModes classifies the raw data into unoptimised segments.
// e.g. "123ZZ#!#!" =>
// [numeric, 3, "123"] [alphanumeric, 2, "ZZ"] [byte, 4, "#!#!"].
func (d *dataEncoder) classifyDataModes() {
var start int
mode := dataModeNone

for i, v := range d.data {
newMode := dataModeNone
switch {
case v >= 0x30 && v <= 0x39:
newMode = dataModeNumeric
case v == 0x20 || v == 0x24 || v == 0x25 || v == 0x2a || v == 0x2b || v ==
0x2d || v == 0x2e || v == 0x2f || v == 0x3a || (v >= 0x41 && v <= 0x5a):
newMode = dataModeAlphanumeric
default:
newMode = dataModeByte
}

if newMode != mode {
if i > 0 {
d.actual = append(d.actual, segment{dataMode: mode, data: d.data[start:i]})

start = i
}

mode = newMode
}
}

d.actual = append(d.actual, segment{dataMode: mode, data: d.data[start:len(d.data)]})
}

// optimiseDataModes optimises the list of segments to reduce the overall output
// encoded data length.
//
// The algorithm coalesces adjacent segments. segments are only coalesced when
// the Data Modes are compatible, and when the coalesced segment has a shorter
// encoded length than separate segments.
//
// Multiple segments may be coalesced. For example a string of alternating
// alphanumeric/numeric segments ANANANANA can be optimised to just A.
func (d *dataEncoder) optimiseDataModes() error {
for i := 0; i < len(d.actual); {
mode := d.actual[i].dataMode
numChars := len(d.actual[i].data)

j := i + 1
for j < len(d.actual) {
nextNumChars := len(d.actual[j].data)
nextMode := d.actual[j].dataMode

if nextMode > mode {
break
}

coalescedLength, err := d.encodedLength(mode, numChars+nextNumChars)

if err != nil {
return err
}

seperateLength1, err := d.encodedLength(mode, numChars)

if err != nil {
return err
}

seperateLength2, err := d.encodedLength(nextMode, nextNumChars)

if err != nil {
return err
}

if coalescedLength < seperateLength1+seperateLength2 {
j++
numChars += nextNumChars
} else {
break
}
}

optimised := segment{dataMode: mode,
data: make([]byte, 0, numChars)}

for k := i; k < j; k++ {
optimised.data = append(optimised.data, d.actual[k].data...)
}

d.optimised = append(d.optimised, optimised)

i = j
}

return nil
}

// encodeDataRaw encodes data in dataMode. The encoded data is appended to
// encoded.
func (d *dataEncoder) encodeDataRaw(data []byte, dataMode dataMode, encoded *bitset.Bitset) {
modeIndicator := d.modeIndicator(dataMode)
charCountBits := d.charCountBits(dataMode)

// Append mode indicator.
encoded.Append(modeIndicator)

// Append character count.
encoded.AppendUint32(uint32(len(data)), charCountBits)

// Append data.
switch dataMode {
case dataModeNumeric:
for i := 0; i < len(data); i += 3 {
charsRemaining := len(data) - i

var value uint32
bitsUsed := 1

for j := 0; j < charsRemaining && j < 3; j++ {
value *= 10
value += uint32(data[i+j] - 0x30)
bitsUsed += 3
}
encoded.AppendUint32(value, bitsUsed)
}
case dataModeAlphanumeric:
for i := 0; i < len(data); i += 2 {
charsRemaining := len(data) - i

var value uint32
for j := 0; j < charsRemaining && j < 2; j++ {
value *= 45
value += encodeAlphanumericCharacter(data[i+j])
}

bitsUsed := 6
if charsRemaining > 1 {
bitsUsed = 11
}

encoded.AppendUint32(value, bitsUsed)
}
case dataModeByte:
for _, b := range data {
encoded.AppendByte(b, 8)
}
}
}

// modeIndicator returns the segment header bits for a segment of type dataMode.
func (d *dataEncoder) modeIndicator(dataMode dataMode) *bitset.Bitset {
switch dataMode {
case dataModeNumeric:
return d.numericModeIndicator
case dataModeAlphanumeric:
return d.alphanumericModeIndicator
case dataModeByte:
return d.byteModeIndicator
default:
log.Panic("Unknown data mode")
}

return nil
}

// charCountBits returns the number of bits used to encode the length of a data
// segment of type dataMode.
func (d *dataEncoder) charCountBits(dataMode dataMode) int {
switch dataMode {
case dataModeNumeric:
return d.numNumericCharCountBits
case dataModeAlphanumeric:
return d.numAlphanumericCharCountBits
case dataModeByte:
return d.numByteCharCountBits
default:
log.Panic("Unknown data mode")
}

return 0
}

// encodedLength returns the number of bits required to encode n symbols in
// dataMode.
//
// The number of bits required is affected by:
// - QR code type - Mode Indicator length.
// - Data mode - number of bits used to represent data length.
// - Data mode - how the data is encoded.
// - Number of symbols encoded.
//
// An error is returned if the mode is not supported, or the length requested is
// too long to be represented.
func (d *dataEncoder) encodedLength(dataMode dataMode, n int) (int, error) {
modeIndicator := d.modeIndicator(dataMode)
charCountBits := d.charCountBits(dataMode)

if modeIndicator == nil {
return 0, errors.New("mode not supported")
}

maxLength := (1 << uint8(charCountBits)) - 1

if n > maxLength {
return 0, errors.New("length too long to be represented")
}

length := modeIndicator.Len() + charCountBits

switch dataMode {
case dataModeNumeric:
length += 10 * (n / 3)

if n%3 != 0 {
length += 1 + 3*(n%3)
}
case dataModeAlphanumeric:
length += 11 * (n / 2)
length += 6 * (n % 2)
case dataModeByte:
length += 8 * n
}

return length, nil
}

// encodeAlphanumericChar returns the QR Code encoded value of v.
//
// v must be a QR Code defined alphanumeric character: 0-9, A-Z, SP, $%*+-./ or
// :. The characters are mapped to values in the range 0-44 respectively.
func encodeAlphanumericCharacter(v byte) uint32 {
c := uint32(v)

switch {
case c >= '0' && c <= '9':
// 0-9 encoded as 0-9.
return c - '0'
case c >= 'A' && c <= 'Z':
// A-Z encoded as 10-35.
return c - 'A' + 10
case c == ' ':
return 36
case c == '$':
return 37
case c == '%':
return 38
case c == '*':
return 39
case c == '+':
return 40
case c == '-':
return 41
case c == '.':
return 42
case c == '/':
return 43
case c == ':':
return 44
default:
log.Panicf("encodeAlphanumericCharacter() with non alphanumeric char %v.", v)
}

return 0
}

+ 328
- 0
vendor/github.com/skip2/go-qrcode/encoder_test.go View File

@@ -0,0 +1,328 @@
// go-qrcode
// Copyright 2014 Tom Harwood

package qrcode

import (
"fmt"
"reflect"
"testing"

bitset "github.com/skip2/go-qrcode/bitset"
)

func TestClassifyDataMode(t *testing.T) {
type Test struct {
}

tests := []struct {
data []byte
actual []segment
}{
{
[]byte{0x30},
[]segment{
{
dataModeNumeric,
[]byte{0x30},
},
},
},
{
[]byte{0x30, 0x41, 0x42, 0x43, 0x20, 0x00, 0xf0, 0xf1, 0xf2, 0x31},
[]segment{
{
dataModeNumeric,
[]byte{0x30},
},
{
dataModeAlphanumeric,
[]byte{0x41, 0x42, 0x43, 0x20},
},
{
dataModeByte,
[]byte{0x00, 0xf0, 0xf1, 0xf2},
},
{
dataModeNumeric,
[]byte{0x31},
},
},
},
}

for _, test := range tests {
encoder := newDataEncoder(dataEncoderType1To9)
encoder.encode(test.data)

if !reflect.DeepEqual(test.actual, encoder.actual) {
t.Errorf("Got %v, expected %v", encoder.actual, test.actual)
}
}
}

func TestByteModeLengthCalculations(t *testing.T) {
tests := []struct {
dataEncoderType dataEncoderType
dataMode dataMode
numSymbols int
expectedLength int
}{}

for i, test := range tests {
encoder := newDataEncoder(test.dataEncoderType)
var resultLength int

resultLength, err := encoder.encodedLength(test.dataMode, test.numSymbols)

if test.expectedLength == -1 {
if err == nil {
t.Errorf("Test %d: got length %d, expected error", i, resultLength)
}
} else if resultLength != test.expectedLength {
t.Errorf("Test %d: got length %d, expected length %d", i, resultLength,
test.expectedLength)
}
}
}

func TestSingleModeEncodings(t *testing.T) {
tests := []struct {
dataEncoderType dataEncoderType
dataMode dataMode
data string
expected *bitset.Bitset
}{
{
dataEncoderType1To9,
dataModeNumeric,
"01234567",
bitset.NewFromBase2String("0001 0000001000 0000001100 0101011001 1000011"),
},
{
dataEncoderType1To9,
dataModeAlphanumeric,
"AC-42",
bitset.NewFromBase2String("0010 000000101 00111001110 11100111001 000010"),
},
{
dataEncoderType1To9,
dataModeByte,
"123",
bitset.NewFromBase2String("0100 00000011 00110001 00110010 00110011"),
},
{
dataEncoderType10To26,
dataModeByte,
"123",
bitset.NewFromBase2String("0100 00000000 00000011 00110001 00110010 00110011"),
},
{
dataEncoderType27To40,
dataModeByte,
"123",
bitset.NewFromBase2String("0100 00000000 00000011 00110001 00110010 00110011"),
},
}

for _, test := range tests {
encoder := newDataEncoder(test.dataEncoderType)
encoded := bitset.New()

encoder.encodeDataRaw([]byte(test.data), test.dataMode, encoded)

if !test.expected.Equals(encoded) {
t.Errorf("For %s got %s, expected %s", test.data, encoded.String(),
test.expected.String())
}
}
}

type testModeSegment struct {
dataMode dataMode
numChars int
}

func TestOptimiseEncoding(t *testing.T) {
tests := []struct {
dataEncoderType dataEncoderType
actual []testModeSegment
optimised []testModeSegment
}{
// Coalescing multiple segments.
{
dataEncoderType1To9,
[]testModeSegment{
{dataModeAlphanumeric, 1}, // length = 4 + 9 + 6 = 19 bits
{dataModeNumeric, 1}, // length = 4 + 10 + 4 = 18 bits
{dataModeAlphanumeric, 1}, // 19 bits.
{dataModeNumeric, 1}, // 18 bits.
{dataModeAlphanumeric, 1}, // 19 bits.
// total = 93 bits.
},
[]testModeSegment{
{dataModeAlphanumeric, 5}, // length = 4 + 9 + 22 + 6 = 41.
},
},
// Coalesing not necessary.
{
dataEncoderType1To9,
[]testModeSegment{
{dataModeAlphanumeric, 1},
{dataModeNumeric, 20},
},
[]testModeSegment{
{dataModeAlphanumeric, 1},
{dataModeNumeric, 20},
},
},
// Switch to more general dataMode.
{
dataEncoderType1To9,
[]testModeSegment{
{dataModeAlphanumeric, 1},
{dataModeByte, 1},
{dataModeNumeric, 1},
},
[]testModeSegment{
{dataModeAlphanumeric, 1},
{dataModeByte, 2},
},
},
// https://www.google.com/123
// BBBBBAAABBBABBBBBBABBBANNN
{
dataEncoderType1To9,
[]testModeSegment{
{dataModeByte, 5},
{dataModeAlphanumeric, 3},
{dataModeByte, 3},
{dataModeAlphanumeric, 1},
{dataModeByte, 6},
{dataModeAlphanumeric, 1},
{dataModeAlphanumeric, 4},
{dataModeNumeric, 3},
},
[]testModeSegment{
{dataModeByte, 23},
{dataModeNumeric, 3},
},
},
// HTTPS://WWW.GOOGLE.COM/123
// AAAAAAAAAAAAAAAAAAAAAAANNN
{
dataEncoderType1To9,
[]testModeSegment{
{dataModeAlphanumeric, 23},
{dataModeNumeric, 3},
},
[]testModeSegment{
{dataModeAlphanumeric, 26},
},
},
{
dataEncoderType27To40,
[]testModeSegment{
{dataModeByte, 1},
{dataModeNumeric, 1},
{dataModeByte, 1},
{dataModeNumeric, 1},
{dataModeByte, 1},
{dataModeNumeric, 1},
{dataModeByte, 1},
{dataModeNumeric, 1},
},
[]testModeSegment{
{dataModeByte, 8},
},
},
}

for _, test := range tests {
numTotalChars := 0
for _, v := range test.actual {
numTotalChars += v.numChars
}

data := make([]byte, numTotalChars)

i := 0
for _, v := range test.actual {
for j := 0; j < v.numChars; j++ {
switch v.dataMode {
case dataModeNumeric:
data[i] = '1'
case dataModeAlphanumeric:
data[i] = 'A'
case dataModeByte:
data[i] = '#'
default:
t.Fatal("Unrecognised data mode")
}

i++
}
}

encoder := newDataEncoder(test.dataEncoderType)

_, err := encoder.encode(data)

if err != nil {
t.Errorf("Got %s, expected valid encoding", err.Error())
} else {
ok := true

if len(encoder.optimised) != len(test.optimised) {
ok = false
} else {
for i, s := range test.optimised {
if encoder.optimised[i].dataMode != s.dataMode ||
len(encoder.optimised[i].data) != s.numChars {
ok = false
break
}
}
}

if !ok {
t.Errorf("got %s, expected %s", segmentsString(encoder.optimised),
testModeSegmentsString(test.optimised))
}
}
}
}

func testModeSegmentsString(segments []testModeSegment) string {
result := "["

for i, segment := range segments {
if i > 0 {
result += ", "
}

result += fmt.Sprintf("%d*%s", segment.numChars,
dataModeString(segment.dataMode))
}

result += "]"

return result
}

func segmentsString(segments []segment) string {
result := "["

for i, segment := range segments {
if i > 0 {
result += ", "
}

result += fmt.Sprintf("%d*%s", len(segment.data),
dataModeString(segment.dataMode))
}

result += "]"

return result
}

+ 31
- 0
vendor/github.com/skip2/go-qrcode/example_test.go View File

@@ -0,0 +1,31 @@
// go-qrcode
// Copyright 2014 Tom Harwood
/*
Amendments Thu, 2017-December-14:
- test integration (go test -v)
- idiomatic go code
*/
package qrcode

import (
"fmt"
"os"
"testing"
)

func TestExampleEncode(t *testing.T) {
if png, err := Encode("https://example.org", Medium, 256); err != nil {
t.Errorf("Error: %s", err.Error())
} else {
fmt.Printf("PNG is %d bytes long", len(png))
}
}

func TestExampleWriteFile(t *testing.T) {
filename := "example.png"
if err := WriteFile("https://example.org", Medium, 256, filename); err != nil {
if err = os.Remove(filename); err != nil {
t.Errorf("Error: %s", err.Error())
}
}
}

+ 554
- 0
vendor/github.com/skip2/go-qrcode/qrcode.go View File

@@ -0,0 +1,554 @@
// go-qrcode
// Copyright 2014 Tom Harwood

/*
Package qrcode implements a QR Code encoder.

A QR Code is a matrix (two-dimensional) barcode. Arbitrary content may be
encoded.

A QR Code contains error recovery information to aid reading damaged or
obscured codes. There are four levels of error recovery: qrcode.{Low, Medium,
High, Highest}. QR Codes with a higher recovery level are more robust to damage,
at the cost of being physically larger.

Three functions cover most use cases:

- Create a PNG image:

var png []byte
png, err := qrcode.Encode("https://example.org", qrcode.Medium, 256)

- Create a PNG image and write to a file:

err := qrcode.WriteFile("https://example.org", qrcode.Medium, 256, "qr.png")

- Create a PNG image with custom colors and write to file:

err := qrcode.WriteColorFile("https://example.org", qrcode.Medium, 256, color.Black, color.White, "qr.png")

All examples use the qrcode.Medium error Recovery Level and create a fixed
256x256px size QR Code. The last function creates a white on black instead of black
on white QR Code.

To generate a variable sized image instead, specify a negative size (in place of
the 256 above), such as -4 or -5. Larger negative numbers create larger images:
A size of -5 sets each module (QR Code "pixel") to be 5px wide/high.

- Create a PNG image (variable size, with minimum white padding) and write to a file:

err := qrcode.WriteFile("https://example.org", qrcode.Medium, -5, "qr.png")

The maximum capacity of a QR Code varies according to the content encoded and
the error recovery level. The maximum capacity is 2,953 bytes, 4,296
alphanumeric characters, 7,089 numeric digits, or a combination of these.

This package implements a subset of QR Code 2005, as defined in ISO/IEC
18004:2006.
*/
package qrcode

import (
"bytes"
"errors"
"image"
"image/color"
"image/png"
"io"
"io/ioutil"
"log"
"os"

bitset "github.com/skip2/go-qrcode/bitset"
reedsolomon "github.com/skip2/go-qrcode/reedsolomon"
)

// Encode a QR Code and return a raw PNG image.
//
// size is both the image width and height in pixels. If size is too small then
// a larger image is silently returned. Negative values for size cause a
// variable sized image to be returned: See the documentation for Image().
//
// To serve over HTTP, remember to send a Content-Type: image/png header.
func Encode(content string, level RecoveryLevel, size int) ([]byte, error) {
var q *QRCode

q, err := New(content, level)

if err != nil {
return nil, err
}

return q.PNG(size)
}

// WriteFile encodes, then writes a QR Code to the given filename in PNG format.
//
// size is both the image width and height in pixels. If size is too small then
// a larger image is silently written. Negative values for size cause a variable
// sized image to be written: See the documentation for Image().
func WriteFile(content string, level RecoveryLevel, size int, filename string) error {
var q *QRCode

q, err := New(content, level)

if err != nil {
return err
}

return q.WriteFile(size, filename)
}

// WriteColorFile encodes, then writes a QR Code to the given filename in PNG format.
// With WriteColorFile you can also specify the colors you want to use.
//
// size is both the image width and height in pixels. If size is too small then
// a larger image is silently written. Negative values for size cause a variable
// sized image to be written: See the documentation for Image().
func WriteColorFile(content string, level RecoveryLevel, size int, background,
foreground color.Color, filename string) error {

var q *QRCode

q, err := New(content, level)

q.BackgroundColor = background
q.ForegroundColor = foreground

if err != nil {
return err
}

return q.WriteFile(size, filename)
}

// A QRCode represents a valid encoded QRCode.
type QRCode struct {
// Original content encoded.
Content string

// QR Code type.
Level RecoveryLevel
VersionNumber int

// User settable drawing options.
ForegroundColor color.Color
BackgroundColor color.Color

encoder *dataEncoder
version qrCodeVersion

data *bitset.Bitset
symbol *symbol
mask int
}

// New constructs a QRCode.
//
// var q *qrcode.QRCode
// q, err := qrcode.New("my content", qrcode.Medium)
//
// An error occurs if the content is too long.
func New(content string, level RecoveryLevel) (*QRCode, error) {
encoders := []dataEncoderType{dataEncoderType1To9, dataEncoderType10To26,
dataEncoderType27To40}

var encoder *dataEncoder
var encoded *bitset.Bitset
var chosenVersion *qrCodeVersion
var err error

for _, t := range encoders {
encoder = newDataEncoder(t)
encoded, err = encoder.encode([]byte(content))

if err != nil {
continue
}

chosenVersion = chooseQRCodeVersion(level, encoder, encoded.Len())

if chosenVersion != nil {
break
}
}

if err != nil {
return nil, err
} else if chosenVersion == nil {
return nil, errors.New("content too long to encode")
}

q := &QRCode{
Content: content,

Level: level,
VersionNumber: chosenVersion.version,

ForegroundColor: color.Black,
BackgroundColor: color.White,

encoder: encoder,
data: encoded,
version: *chosenVersion,
}

q.encode(chosenVersion.numTerminatorBitsRequired(encoded.Len()))

return q, nil
}

func newWithForcedVersion(content string, version int, level RecoveryLevel) (*QRCode, error) {
var encoder *dataEncoder

switch {
case version >= 1 && version <= 9:
encoder = newDataEncoder(dataEncoderType1To9)
case version >= 10 && version <= 26:
encoder = newDataEncoder(dataEncoderType10To26)
case version >= 27 && version <= 40:
encoder = newDataEncoder(dataEncoderType27To40)
default:
log.Fatalf("Invalid version %d (expected 1-40 inclusive)", version)
}

var encoded *bitset.Bitset
encoded, err := encoder.encode([]byte(content))

if err != nil {
return nil, err
}

chosenVersion := getQRCodeVersion(level, version)

if chosenVersion == nil {
return nil, errors.New("cannot find QR Code version")
}

q := &QRCode{
Content: content,

Level: level,
VersionNumber: chosenVersion.version,

ForegroundColor: color.Black,
BackgroundColor: color.White,

encoder: encoder,
data: encoded,
version: *chosenVersion,
}

q.encode(chosenVersion.numTerminatorBitsRequired(encoded.Len()))

return q, nil
}

// Bitmap returns the QR Code as a 2D array of 1-bit pixels.
//
// bitmap[y][x] is true if the pixel at (x, y) is set.
//
// The bitmap includes the required "quiet zone" around the QR Code to aid
// decoding.
func (q *QRCode) Bitmap() [][]bool {
return q.symbol.bitmap()
}

// Image returns the QR Code as an image.Image.
//
// A positive size sets a fixed image width and height (e.g. 256 yields an
// 256x256px image).
//
// Depending on the amount of data encoded, fixed size images can have different
// amounts of padding (white space around the QR Code). As an alternative, a
// variable sized image can be generated instead:
//
// A negative size causes a variable sized image to be returned. The image
// returned is the minimum size required for the QR Code. Choose a larger
// negative number to increase the scale of the image. e.g. a size of -5 causes
// each module (QR Code "pixel") to be 5px in size.
func (q *QRCode) Image(size int) image.Image {
// Minimum pixels (both width and height) required.
realSize := q.symbol.size

// Variable size support.
if size < 0 {
size = size * -1 * realSize
}

// Actual pixels available to draw the symbol. Automatically increase the
// image size if it's not large enough.
if size < realSize {
size = realSize
}

// Size of each module drawn.
pixelsPerModule := size / realSize

// Center the symbol within the image.
offset := (size - realSize*pixelsPerModule) / 2

rect := image.Rectangle{Min: image.Point{0, 0}, Max: image.Point{size, size}}

// Saves a few bytes to have them in this order
p := color.Palette([]color.Color{q.BackgroundColor, q.ForegroundColor})
img := image.NewPaletted(rect, p)

for i := 0; i < size; i++ {
for j := 0; j < size; j++ {
img.Set(i, j, q.BackgroundColor)
}
}

bitmap := q.symbol.bitmap()
for y, row := range bitmap {
for x, v := range row {
if v {
startX := x*pixelsPerModule + offset
startY := y*pixelsPerModule + offset
for i := startX; i < startX+pixelsPerModule; i++ {
for j := startY; j < startY+pixelsPerModule; j++ {
img.Set(i, j, q.ForegroundColor)
}
}
}
}
}

return img
}

// PNG returns the QR Code as a PNG image.
//
// size is both the image width and height in pixels. If size is too small then
// a larger image is silently returned. Negative values for size cause a
// variable sized image to be returned: See the documentation for Image().
func (q *QRCode) PNG(size int) ([]byte, error) {
img := q.Image(size)

encoder := png.Encoder{CompressionLevel: png.BestCompression}

var b bytes.Buffer
err := encoder.Encode(&b, img)

if err != nil {
return nil, err
}

return b.Bytes(), nil
}

// Write writes the QR Code as a PNG image to io.Writer.
//
// size is both the image width and height in pixels. If size is too small then
// a larger image is silently written. Negative values for size cause a
// variable sized image to be written: See the documentation for Image().
func (q *QRCode) Write(size int, out io.Writer) error {
var png []byte

png, err := q.PNG(size)

if err != nil {
return err
}
_, err = out.Write(png)
return err
}

// WriteFile writes the QR Code as a PNG image to the specified file.
//
// size is both the image width and height in pixels. If size is too small then
// a larger image is silently written. Negative values for size cause a
// variable sized image to be written: See the documentation for Image().
func (q *QRCode) WriteFile(size int, filename string) error {
var png []byte

png, err := q.PNG(size)

if err != nil {
return err
}

return ioutil.WriteFile(filename, png, os.FileMode(0644))
}

// encode completes the steps required to encode the QR Code. These include
// adding the terminator bits and padding, splitting the data into blocks and
// applying the error correction, and selecting the best data mask.
func (q *QRCode) encode(numTerminatorBits int) {
q.addTerminatorBits(numTerminatorBits)
q.addPadding()

encoded := q.encodeBlocks()

const numMasks int = 8
penalty := 0

for mask := 0; mask < numMasks; mask++ {
var s *symbol
var err error

s, err = buildRegularSymbol(q.version, mask, encoded)

if err != nil {
log.Panic(err.Error())
}

numEmptyModules := s.numEmptyModules()
if numEmptyModules != 0 {
log.Panicf("bug: numEmptyModules is %d (expected 0) (version=%d)",
numEmptyModules, q.VersionNumber)
}

p := s.penaltyScore()

//log.Printf("mask=%d p=%3d p1=%3d p2=%3d p3=%3d p4=%d\n", mask, p, s.penalty1(), s.penalty2(), s.penalty3(), s.penalty4())

if q.symbol == nil || p < penalty {
q.symbol = s
q.mask = mask
penalty = p
}
}
}

// addTerminatorBits adds final terminator bits to the encoded data.
//
// The number of terminator bits required is determined when the QR Code version
// is chosen (which itself depends on the length of the data encoded). The
// terminator bits are thus added after the QR Code version
// is chosen, rather than at the data encoding stage.
func (q *QRCode) addTerminatorBits(numTerminatorBits int) {
q.data.AppendNumBools(numTerminatorBits, false)
}

// encodeBlocks takes the completed (terminated & padded) encoded data, splits
// the data into blocks (as specified by the QR Code version), applies error
// correction to each block, then interleaves the blocks together.
//
// The QR Code's final data sequence is returned.
func (q *QRCode) encodeBlocks() *bitset.Bitset {
// Split into blocks.
type dataBlock struct {
data *bitset.Bitset
ecStartOffset int
}

block := make([]dataBlock, q.version.numBlocks())

start := 0
end := 0
blockID := 0

for _, b := range q.version.block {
for j := 0; j < b.numBlocks; j++ {
start = end
end = start + b.numDataCodewords*8

// Apply error correction to each block.
numErrorCodewords := b.numCodewords - b.numDataCodewords
block[blockID].data = reedsolomon.Encode(q.data.Substr(start, end), numErrorCodewords)
block[blockID].ecStartOffset = end - start

blockID++
}
}

// Interleave the blocks.

result := bitset.New()

// Combine data blocks.
working := true
for i := 0; working; i += 8 {
working = false

for j, b := range block {
if i >= block[j].ecStartOffset {
continue
}

result.Append(b.data.Substr(i, i+8))

working = true
}
}

// Combine error correction blocks.
working = true
for i := 0; working; i += 8 {
working = false

for j, b := range block {
offset := i + block[j].ecStartOffset
if offset >= block[j].data.Len() {
continue
}

result.Append(b.data.Substr(offset, offset+8))

working = true
}
}

// Append remainder bits.
result.AppendNumBools(q.version.numRemainderBits, false)

return result
}

// max returns the maximum of a and b.
func max(a int, b int) int {
if a > b {
return a
}

return b
}

// addPadding pads the encoded data upto the full length required.
func (q *QRCode) addPadding() {
numDataBits := q.version.numDataBits()

if q.data.Len() == numDataBits {
return
}

// Pad to the nearest codeword boundary.
q.data.AppendNumBools(q.version.numBitsToPadToCodeword(q.data.Len()), false)

// Pad codewords 0b11101100 and 0b00010001.
padding := [2]*bitset.Bitset{
bitset.New(true, true, true, false, true, true, false, false),
bitset.New(false, false, false, true, false, false, false, true),
}

// Insert pad codewords alternately.
i := 0
for numDataBits-q.data.Len() >= 8 {
q.data.Append(padding[i])

i = 1 - i // Alternate between 0 and 1.
}

if q.data.Len() != numDataBits {
log.Panicf("BUG: got len %d, expected %d", q.data.Len(), numDataBits)
}
}

// ToString produces a multi-line string that forms a QR-code image.
func (q *QRCode) ToString(inverseColor bool) string {
bits := q.Bitmap()
var buf bytes.Buffer
for y := range bits {
for x := range bits[y] {
if bits[y][x] != inverseColor {
buf.WriteString(" ")
} else {
buf.WriteString("██")
}
}
buf.WriteString("\n")
}
return buf.String()
}

+ 85
- 0
vendor/github.com/skip2/go-qrcode/qrcode/main.go View File

@@ -0,0 +1,85 @@
// go-qrcode
// Copyright 2014 Tom Harwood

package main

import (
"flag"
"fmt"
"os"
"strings"

qrcode "github.com/skip2/go-qrcode"
)

func main() {
outFile := flag.String("o", "", "out PNG file prefix, empty for stdout")
size := flag.Int("s", 256, "image size (pixel)")
textArt := flag.Bool("t", false, "print as text-art on stdout")
negative := flag.Bool("i", false, "invert black and white")
flag.Usage = func() {
fmt.Fprintf(os.Stderr, `qrcode -- QR Code encoder in Go
https://github.com/skip2/go-qrcode

Flags:
`)
flag.PrintDefaults()
fmt.Fprintf(os.Stderr, `
Usage:
1. Arguments except for flags are joined by " " and used to generate QR code.
Default output is STDOUT, pipe to imagemagick command "display" to display
on any X server.

qrcode hello word | display

2. Save to file if "display" not available:

qrcode "homepage: https://github.com/skip2/go-qrcode" > out.png

`)
}
flag.Parse()

if len(flag.Args()) == 0 {
flag.Usage()
checkError(fmt.Errorf("Error: no content given"))
}

content := strings.Join(flag.Args(), " ")

var err error
var q *qrcode.QRCode
q, err = qrcode.New(content, qrcode.Highest)
checkError(err)

if *textArt {
art := q.ToString(*negative)
fmt.Println(art)
return
}

if *negative {
q.ForegroundColor, q.BackgroundColor = q.BackgroundColor, q.ForegroundColor
}

var png []byte
png, err = q.PNG(*size)
checkError(err)

if *outFile == "" {
os.Stdout.Write(png)
} else {
var fh *os.File
fh, err = os.Create(*outFile + ".png")
checkError(err)
defer fh.Close()
fh.Write(png)
}
}

func checkError(err error) {
if err != nil {
fmt.Fprintf(os.Stderr, "%s\n", err)
os.Exit(1)
}
}

+ 232
- 0
vendor/github.com/skip2/go-qrcode/qrcode_decode_test.go View File

@@ -0,0 +1,232 @@
// go-qrcode
// Copyright 2014 Tom Harwood

package qrcode

import (
"bytes"
"flag"
"fmt"
"math/rand"
"os/exec"
"strings"
"testing"
)

// These tests use zbarimg to decode generated QR Codes to ensure they are
// readable. sudo apt-get install zbar-tools, or download from
// http://zbar.sourceforge.net.
//
// By default these tests are disabled to avoid a dependency on zbarimg if
// you're not running the tests. Use the -test-decode flag (go test
// -test-decode) to enable.

var testDecode *bool = flag.Bool("test-decode",
false,
"Enable decode tests. Requires zbarimg installed.")

var testDecodeFuzz *bool = flag.Bool("test-decode-fuzz",
false,
"Enable decode fuzz tests. Requires zbarimg installed.")

func TestDecodeBasic(t *testing.T) {
if !*testDecode {
t.Skip("Decode tests not enabled")
}

tests := []struct {
content string
numRepetitions int
level RecoveryLevel
}{
{
"A",
1,
Low,
},
{
"A",
1,
Medium,
},
{
"A",
1,
High,
},
{
"A",
1,
Highest,
},
{
"01234567",
1,
Medium,
},
}

for _, test := range tests {
content := strings.Repeat(test.content, test.numRepetitions)

q, err := New(content, test.level)
if err != nil {
t.Error(err.Error())
}

err = zbarimgCheck(q)

if err != nil {
t.Error(err.Error())
}
}
}

func TestDecodeAllVersionLevels(t *testing.T) {
if !*testDecode {
t.Skip("Decode tests not enabled")
}

for version := 1; version <= 40; version++ {
for _, level := range []RecoveryLevel{Low, Medium, High, Highest} {
t.Logf("Version=%d Level=%d",
version,
level)

q, err := newWithForcedVersion(
fmt.Sprintf("v-%d l-%d", version, level), version, level)
if err != nil {
t.Fatal(err.Error())
return
}

err = zbarimgCheck(q)

if err != nil {
t.Errorf("Version=%d Level=%d, err=%s, expected success",
version,
level,
err.Error())
continue
}
}
}
}

func TestDecodeAllCharacters(t *testing.T) {
if !*testDecode {
t.Skip("Decode tests not enabled")
}

var content string

// zbarimg has trouble with null bytes, hence start from ASCII 1.
for i := 1; i < 256; i++ {
content += string(i)
}

q, err := New(content, Low)
if err != nil {
t.Error(err.Error())
}

err = zbarimgCheck(q)

if err != nil {
t.Error(err.Error())
}
}

func TestDecodeFuzz(t *testing.T) {
if !*testDecodeFuzz {
t.Skip("Decode fuzz tests not enabled")
}

r := rand.New(rand.NewSource(0))

const iterations int = 32
const maxLength int = 128

for i := 0; i < iterations; i++ {
len := r.Intn(maxLength-1) + 1

var content string
for j := 0; j < len; j++ {
// zbarimg seems to have trouble with special characters, test printable
// characters only for now.
content += string(32 + r.Intn(94))
}

for _, level := range []RecoveryLevel{Low, Medium, High, Highest} {
q, err := New(content, level)
if err != nil {
t.Error(err.Error())
}

err = zbarimgCheck(q)

if err != nil {
t.Error(err.Error())
}
}
}
}

func zbarimgCheck(q *QRCode) error {
s, err := zbarimgDecode(q)
if err != nil {
return err
}

if s != q.Content {
q.WriteFile(256, fmt.Sprintf("%x.png", q.Content))
return fmt.Errorf("got '%s' (%x) expected '%s' (%x)", s, s, q.Content, q.Content)
}

return nil
}

func zbarimgDecode(q *QRCode) (string, error) {
var png []byte

// 512x512px
png, err := q.PNG(512)
if err != nil {
return "", err
}

cmd := exec.Command("zbarimg", "--quiet", "-Sdisable",
"-Sqrcode.enable", "/dev/stdin")

var out bytes.Buffer

cmd.Stdin = bytes.NewBuffer(png)
cmd.Stdout = &out

err = cmd.Run()

if err != nil {
return "", err
}

return strings.TrimSuffix(strings.TrimPrefix(out.String(), "QR-Code:"), "\n"), nil
}

func BenchmarkDecodeTest(b *testing.B) {
if !*testDecode {
b.Skip("Decode benchmarks not enabled")
}

for n := 0; n < b.N; n++ {
q, err := New("content", Medium)
if err != nil {
b.Error(err.Error())
}

err = zbarimgCheck(q)

if err != nil {
b.Error(err.Error())
}
}
}

+ 173
- 0
vendor/github.com/skip2/go-qrcode/qrcode_test.go View File

@@ -0,0 +1,173 @@
// go-qrcode
// Copyright 2014 Tom Harwood

package qrcode

import (
"strings"
"testing"
)

func TestQRCodeMaxCapacity(t *testing.T) {
if testing.Short() {
t.Skip("Skipping TestQRCodeCapacity")
}

tests := []struct {
string string
numRepetitions int
}{
{
"0",
7089,
},
{
"A",
4296,
},
{
"#",
2953,
},
// Alternate byte/numeric data types. Optimises to 2,952 bytes.
{
"#1",
1476,
},
}

for _, test := range tests {
_, err := New(strings.Repeat(test.string, test.numRepetitions), Low)

if err != nil {
t.Errorf("%d x '%s' got %s expected success", test.numRepetitions,
test.string, err.Error())
}
}

for _, test := range tests {
_, err := New(strings.Repeat(test.string, test.numRepetitions+1), Low)

if err == nil {
t.Errorf("%d x '%s' chars encodable, expected not encodable",
test.numRepetitions+1, test.string)
}
}
}

func TestQRCodeVersionCapacity(t *testing.T) {
tests := []struct {
version int
level RecoveryLevel
maxNumeric int
maxAlphanumeric int
maxByte int
}{
{
1,
Low,
41,
25,
17,
},
{
2,
Low,
77,
47,
32,
},
{
2,
Highest,
34,
20,
14,
},
{
40,
Low,
7089,
4296,
2953,
},
{
40,
Highest,
3057,
1852,
1273,
},
}

for i, test := range tests {
numericData := strings.Repeat("1", test.maxNumeric)
alphanumericData := strings.Repeat("A", test.maxAlphanumeric)
byteData := strings.Repeat("#", test.maxByte)

var n *QRCode
var a *QRCode
var b *QRCode
var err error

n, err = New(numericData, test.level)
if err != nil {
t.Fatal(err.Error())
}

a, err = New(alphanumericData, test.level)
if err != nil {
t.Fatal(err.Error())
}

b, err = New(byteData, test.level)
if err != nil {
t.Fatal(err.Error())
}

if n.VersionNumber != test.version {
t.Fatalf("Test #%d numeric has version #%d, expected #%d", i,
n.VersionNumber, test.version)
}

if a.VersionNumber != test.version {
t.Fatalf("Test #%d alphanumeric has version #%d, expected #%d", i,
a.VersionNumber, test.version)
}

if b.VersionNumber != test.version {
t.Fatalf("Test #%d byte has version #%d, expected #%d", i,
b.VersionNumber, test.version)
}
}
}

func TestQRCodeISOAnnexIExample(t *testing.T) {
var q *QRCode
q, err := New("01234567", Medium)

if err != nil {
t.Fatalf("Error producing ISO Annex I Example: %s, expected success",
err.Error())
}

const expectedMask int = 2

if q.mask != 2 {
t.Errorf("ISO Annex I example mask got %d, expected %d\n", q.mask,
expectedMask)
}
}

func BenchmarkQRCodeURLSize(b *testing.B) {
for n := 0; n < b.N; n++ {
New("http://www.example.org", Medium)
}
}

func BenchmarkQRCodeMaximumSize(b *testing.B) {
for n := 0; n < b.N; n++ {
// 7089 is the maximum encodable number of numeric digits.
New(strings.Repeat("0", 7089), Low)
}
}

+ 387
- 0
vendor/github.com/skip2/go-qrcode/reedsolomon/gf2_8.go View File

@@ -0,0 +1,387 @@
// go-qrcode
// Copyright 2014 Tom Harwood

package reedsolomon

// Addition, subtraction, multiplication, and division in GF(2^8).
// Operations are performed modulo x^8 + x^4 + x^3 + x^2 + 1.

// http://en.wikipedia.org/wiki/Finite_field_arithmetic

import "log"

const (
gfZero = gfElement(0)
gfOne = gfElement(1)
)

var (
gfExpTable = [256]gfElement{
/* 0 - 9 */ 1, 2, 4, 8, 16, 32, 64, 128, 29, 58,
/* 10 - 19 */ 116, 232, 205, 135, 19, 38, 76, 152, 45, 90,
/* 20 - 29 */ 180, 117, 234, 201, 143, 3, 6, 12, 24, 48,
/* 30 - 39 */ 96, 192, 157, 39, 78, 156, 37, 74, 148, 53,
/* 40 - 49 */ 106, 212, 181, 119, 238, 193, 159, 35, 70, 140,
/* 50 - 59 */ 5, 10, 20, 40, 80, 160, 93, 186, 105, 210,
/* 60 - 69 */ 185, 111, 222, 161, 95, 190, 97, 194, 153, 47,
/* 70 - 79 */ 94, 188, 101, 202, 137, 15, 30, 60, 120, 240,
/* 80 - 89 */ 253, 231, 211, 187, 107, 214, 177, 127, 254, 225,
/* 90 - 99 */ 223, 163, 91, 182, 113, 226, 217, 175, 67, 134,
/* 100 - 109 */ 17, 34, 68, 136, 13, 26, 52, 104, 208, 189,
/* 110 - 119 */ 103, 206, 129, 31, 62, 124, 248, 237, 199, 147,
/* 120 - 129 */ 59, 118, 236, 197, 151, 51, 102, 204, 133, 23,
/* 130 - 139 */ 46, 92, 184, 109, 218, 169, 79, 158, 33, 66,
/* 140 - 149 */ 132, 21, 42, 84, 168, 77, 154, 41, 82, 164,
/* 150 - 159 */ 85, 170, 73, 146, 57, 114, 228, 213, 183, 115,
/* 160 - 169 */ 230, 209, 191, 99, 198, 145, 63, 126, 252, 229,
/* 170 - 179 */ 215, 179, 123, 246, 241, 255, 227, 219, 171, 75,
/* 180 - 189 */ 150, 49, 98, 196, 149, 55, 110, 220, 165, 87,
/* 190 - 199 */ 174, 65, 130, 25, 50, 100, 200, 141, 7, 14,
/* 200 - 209 */ 28, 56, 112, 224, 221, 167, 83, 166, 81, 162,
/* 210 - 219 */ 89, 178, 121, 242, 249, 239, 195, 155, 43, 86,
/* 220 - 229 */ 172, 69, 138, 9, 18, 36, 72, 144, 61, 122,
/* 230 - 239 */ 244, 245, 247, 243, 251, 235, 203, 139, 11, 22,
/* 240 - 249 */ 44, 88, 176, 125, 250, 233, 207, 131, 27, 54,
/* 250 - 255 */ 108, 216, 173, 71, 142, 1}

gfLogTable = [256]int{
/* 0 - 9 */ -1, 0, 1, 25, 2, 50, 26, 198, 3, 223,
/* 10 - 19 */ 51, 238, 27, 104, 199, 75, 4, 100, 224, 14,
/* 20 - 29 */ 52, 141, 239, 129, 28, 193, 105, 248, 200, 8,
/* 30 - 39 */ 76, 113, 5, 138, 101, 47, 225, 36, 15, 33,
/* 40 - 49 */ 53, 147, 142, 218, 240, 18, 130, 69, 29, 181,
/* 50 - 59 */ 194, 125, 106, 39, 249, 185, 201, 154, 9, 120,
/* 60 - 69 */ 77, 228, 114, 166, 6, 191, 139, 98, 102, 221,
/* 70 - 79 */ 48, 253, 226, 152, 37, 179, 16, 145, 34, 136,
/* 80 - 89 */ 54, 208, 148, 206, 143, 150, 219, 189, 241, 210,
/* 90 - 99 */ 19, 92, 131, 56, 70, 64, 30, 66, 182, 163,
/* 100 - 109 */ 195, 72, 126, 110, 107, 58, 40, 84, 250, 133,
/* 110 - 119 */ 186, 61, 202, 94, 155, 159, 10, 21, 121, 43,
/* 120 - 129 */ 78, 212, 229, 172, 115, 243, 167, 87, 7, 112,
/* 130 - 139 */ 192, 247, 140, 128, 99, 13, 103, 74, 222, 237,
/* 140 - 149 */ 49, 197, 254, 24, 227, 165, 153, 119, 38, 184,
/* 150 - 159 */ 180, 124, 17, 68, 146, 217, 35, 32, 137, 46,
/* 160 - 169 */ 55, 63, 209, 91, 149, 188, 207, 205, 144, 135,
/* 170 - 179 */ 151, 178, 220, 252, 190, 97, 242, 86, 211, 171,
/* 180 - 189 */ 20, 42, 93, 158, 132, 60, 57, 83, 71, 109,
/* 190 - 199 */ 65, 162, 31, 45, 67, 216, 183, 123, 164, 118,
/* 200 - 209 */ 196, 23, 73, 236, 127, 12, 111, 246, 108, 161,
/* 210 - 219 */ 59, 82, 41, 157, 85, 170, 251, 96, 134, 177,
/* 220 - 229 */ 187, 204, 62, 90, 203, 89, 95, 176, 156, 169,
/* 230 - 239 */ 160, 81, 11, 245, 22, 235, 122, 117, 44, 215,
/* 240 - 249 */ 79, 174, 213, 233, 230, 231, 173, 232, 116, 214,
/* 250 - 255 */ 244, 234, 168, 80, 88, 175}
)

// gfElement is an element in GF(2^8).
type gfElement uint8

// newGFElement creates and returns a new gfElement.
func newGFElement(data byte) gfElement {
return gfElement(data)
}

// gfAdd returns a + b.
func gfAdd(a, b gfElement) gfElement {
return a ^ b
}

// gfSub returns a - b.
//
// Note addition is equivalent to subtraction in GF(2).
func gfSub(a, b gfElement) gfElement {
return a ^ b
}

// gfMultiply returns a * b.
func gfMultiply(a, b gfElement) gfElement {
if a == gfZero || b == gfZero {
return gfZero
}

return gfExpTable[(gfLogTable[a]+gfLogTable[b])%255]
}

// gfDivide returns a / b.
//
// Divide by zero results in a panic.
func gfDivide(a, b gfElement) gfElement {
if a == gfZero {
return gfZero
} else if b == gfZero {
log.Panicln("Divide by zero")
}

return gfMultiply(a, gfInverse(b))
}

// gfInverse returns the multiplicative inverse of a, a^-1.
//
// a * a^-1 = 1
func gfInverse(a gfElement) gfElement {
if a == gfZero {
log.Panicln("No multiplicative inverse of 0")
}

return gfExpTable[255-gfLogTable[a]]
}

// a^i | bits | polynomial | decimal
// --------------------------------------------------------------------------
// 0 | 000000000 | 0x^8 0x^7 0x^6 0x^5 0x^4 0x^3 0x^2 0x^1 0x^0 | 0
// a^0 | 000000001 | 0x^8 0x^7 0x^6 0x^5 0x^4 0x^3 0x^2 0x^1 1x^0 | 1
// a^1 | 000000010 | 0x^8 0x^7 0x^6 0x^5 0x^4 0x^3 0x^2 1x^1 0x^0 | 2
// a^2 | 000000100 | 0x^8 0x^7 0x^6 0x^5 0x^4 0x^3 1x^2 0x^1 0x^0 | 4
// a^3 | 000001000 | 0x^8 0x^7 0x^6 0x^5 0x^4 1x^3 0x^2 0x^1 0x^0 | 8
// a^4 | 000010000 | 0x^8 0x^7 0x^6 0x^5 1x^4 0x^3 0x^2 0x^1 0x^0 | 16
// a^5 | 000100000 | 0x^8 0x^7 0x^6 1x^5 0x^4 0x^3 0x^2 0x^1 0x^0 | 32
// a^6 | 001000000 | 0x^8 0x^7 1x^6 0x^5 0x^4 0x^3 0x^2 0x^1 0x^0 | 64
// a^7 | 010000000 | 0x^8 1x^7 0x^6 0x^5 0x^4 0x^3 0x^2 0x^1 0x^0 | 128
// a^8 | 000011101 | 0x^8 0x^7 0x^6 0x^5 1x^4 1x^3 1x^2 0x^1 1x^0 | 29
// a^9 | 000111010 | 0x^8 0x^7 0x^6 1x^5 1x^4 1x^3 0x^2 1x^1 0x^0 | 58
// a^10 | 001110100 | 0x^8 0x^7 1x^6 1x^5 1x^4 0x^3 1x^2 0x^1 0x^0 | 116
// a^11 | 011101000 | 0x^8 1x^7 1x^6 1x^5 0x^4 1x^3 0x^2 0x^1 0x^0 | 232
// a^12 | 011001101 | 0x^8 1x^7 1x^6 0x^5 0x^4 1x^3 1x^2 0x^1 1x^0 | 205
// a^13 | 010000111 | 0x^8 1x^7 0x^6 0x^5 0x^4 0x^3 1x^2 1x^1 1x^0 | 135
// a^14 | 000010011 | 0x^8 0x^7 0x^6 0x^5 1x^4 0x^3 0x^2 1x^1 1x^0 | 19
// a^15 | 000100110 | 0x^8 0x^7 0x^6 1x^5 0x^4 0x^3 1x^2 1x^1 0x^0 | 38
// a^16 | 001001100 | 0x^8 0x^7 1x^6 0x^5 0x^4 1x^3 1x^2 0x^1 0x^0 | 76
// a^17 | 010011000 | 0x^8 1x^7 0x^6 0x^5 1x^4 1x^3 0x^2 0x^1 0x^0 | 152
// a^18 | 000101101 | 0x^8 0x^7 0x^6 1x^5 0x^4 1x^3 1x^2 0x^1 1x^0 | 45
// a^19 | 001011010 | 0x^8 0x^7 1x^6 0x^5 1x^4 1x^3 0x^2 1x^1 0x^0 | 90
// a^20 | 010110100 | 0x^8 1x^7 0x^6 1x^5 1x^4 0x^3 1x^2 0x^1 0x^0 | 180
// a^21 | 001110101 | 0x^8 0x^7 1x^6 1x^5 1x^4 0x^3 1x^2 0x^1 1x^0 | 117
// a^22 | 011101010 | 0x^8 1x^7 1x^6 1x^5 0x^4 1x^3 0x^2 1x^1 0x^0 | 234
// a^23 | 011001001 | 0x^8 1x^7 1x^6 0x^5 0x^4 1x^3 0x^2 0x^1 1x^0 | 201
// a^24 | 010001111 | 0x^8 1x^7 0x^6 0x^5 0x^4 1x^3 1x^2 1x^1 1x^0 | 143
// a^25 | 000000011 | 0x^8 0x^7 0x^6 0x^5 0x^4 0x^3 0x^2 1x^1 1x^0 | 3
// a^26 | 000000110 | 0x^8 0x^7 0x^6 0x^5 0x^4 0x^3 1x^2 1x^1 0x^0 | 6
// a^27 | 000001100 | 0x^8 0x^7 0x^6 0x^5 0x^4 1x^3 1x^2 0x^1 0x^0 | 12
// a^28 | 000011000 | 0x^8 0x^7 0x^6 0x^5 1x^4 1x^3 0x^2 0x^1 0x^0 | 24
// a^29 | 000110000 | 0x^8 0x^7 0x^6 1x^5 1x^4 0x^3 0x^2 0x^1 0x^0 | 48
// a^30 | 001100000 | 0x^8 0x^7 1x^6 1x^5 0x^4 0x^3 0x^2 0x^1 0x^0 | 96
// a^31 | 011000000 | 0x^8 1x^7 1x^6 0x^5 0x^4 0x^3 0x^2 0x^1 0x^0 | 192
// a^32 | 010011101 | 0x^8 1x^7 0x^6 0x^5 1x^4 1x^3 1x^2 0x^1 1x^0 | 157
// a^33 | 000100111 | 0x^8 0x^7 0x^6 1x^5 0x^4 0x^3 1x^2 1x^1 1x^0 | 39
// a^34 | 001001110 | 0x^8 0x^7 1x^6 0x^5 0x^4 1x^3 1x^2 1x^1 0x^0 | 78
// a^35 | 010011100 | 0x^8 1x^7 0x^6 0x^5 1x^4 1x^3 1x^2 0x^1 0x^0 | 156
// a^36 | 000100101 | 0x^8 0x^7 0x^6 1x^5 0x^4 0x^3 1x^2 0x^1 1x^0 | 37
// a^37 | 001001010 | 0x^8 0x^7 1x^6 0x^5 0x^4 1x^3 0x^2 1x^1 0x^0 | 74
// a^38 | 010010100 | 0x^8 1x^7 0x^6 0x^5 1x^4 0x^3 1x^2 0x^1 0x^0 | 148
// a^39 | 000110101 | 0x^8 0x^7 0x^6 1x^5 1x^4 0x^3 1x^2 0x^1 1x^0 | 53
// a^40 | 001101010 | 0x^8 0x^7 1x^6 1x^5 0x^4 1x^3 0x^2 1x^1 0x^0 | 106
// a^41 | 011010100 | 0x^8 1x^7 1x^6 0x^5 1x^4 0x^3 1x^2 0x^1 0x^0 | 212
// a^42 | 010110101 | 0x^8 1x^7 0x^6 1x^5 1x^4 0x^3 1x^2 0x^1 1x^0 | 181
// a^43 | 001110111 | 0x^8 0x^7 1x^6 1x^5 1x^4 0x^3 1x^2 1x^1 1x^0 | 119
// a^44 | 011101110 | 0x^8 1x^7 1x^6 1x^5 0x^4 1x^3 1x^2 1x^1 0x^0 | 238
// a^45 | 011000001 | 0x^8 1x^7 1x^6 0x^5 0x^4 0x^3 0x^2 0x^1 1x^0 | 193
// a^46 | 010011111 | 0x^8 1x^7 0x^6 0x^5 1x^4 1x^3 1x^2 1x^1 1x^0 | 159
// a^47 | 000100011 | 0x^8 0x^7 0x^6 1x^5 0x^4 0x^3 0x^2 1x^1 1x^0 | 35
// a^48 | 001000110 | 0x^8 0x^7 1x^6 0x^5 0x^4 0x^3 1x^2 1x^1 0x^0 | 70
// a^49 | 010001100 | 0x^8 1x^7 0x^6 0x^5 0x^4 1x^3 1x^2 0x^1 0x^0 | 140
// a^50 | 000000101 | 0x^8 0x^7 0x^6 0x^5 0x^4 0x^3 1x^2 0x^1 1x^0 | 5
// a^51 | 000001010 | 0x^8 0x^7 0x^6 0x^5 0x^4 1x^3 0x^2 1x^1 0x^0 | 10
// a^52 | 000010100 | 0x^8 0x^7 0x^6 0x^5 1x^4 0x^3 1x^2 0x^1 0x^0 | 20
// a^53 | 000101000 | 0x^8 0x^7 0x^6 1x^5 0x^4 1x^3 0x^2 0x^1 0x^0 | 40
// a^54 | 001010000 | 0x^8 0x^7 1x^6 0x^5 1x^4 0x^3 0x^2 0x^1 0x^0 | 80
// a^55 | 010100000 | 0x^8 1x^7 0x^6 1x^5 0x^4 0x^3 0x^2 0x^1 0x^0 | 160
// a^56 | 001011101 | 0x^8 0x^7 1x^6 0x^5 1x^4 1x^3 1x^2 0x^1 1x^0 | 93
// a^57 | 010111010 | 0x^8 1x^7 0x^6 1x^5 1x^4 1x^3 0x^2 1x^1 0x^0 | 186
// a^58 | 001101001 | 0x^8 0x^7 1x^6 1x^5 0x^4 1x^3 0x^2 0x^1 1x^0 | 105
// a^59 | 011010010 | 0x^8 1x^7 1x^6 0x^5 1x^4 0x^3 0x^2 1x^1 0x^0 | 210
// a^60 | 010111001 | 0x^8 1x^7 0x^6 1x^5 1x^4 1x^3 0x^2 0x^1 1x^0 | 185
// a^61 | 001101111 | 0x^8 0x^7 1x^6 1x^5 0x^4 1x^3 1x^2 1x^1 1x^0 | 111
// a^62 | 011011110 | 0x^8 1x^7 1x^6 0x^5 1x^4 1x^3 1x^2 1x^1 0x^0 | 222
// a^63 | 010100001 | 0x^8 1x^7 0x^6 1x^5 0x^4 0x^3 0x^2 0x^1 1x^0 | 161
// a^64 | 001011111 | 0x^8 0x^7 1x^6 0x^5 1x^4 1x^3 1x^2 1x^1 1x^0 | 95
// a^65 | 010111110 | 0x^8 1x^7 0x^6 1x^5 1x^4 1x^3 1x^2 1x^1 0x^0 | 190
// a^66 | 001100001 | 0x^8 0x^7 1x^6 1x^5 0x^4 0x^3 0x^2 0x^1 1x^0 | 97
// a^67 | 011000010 | 0x^8 1x^7 1x^6 0x^5 0x^4 0x^3 0x^2 1x^1 0x^0 | 194
// a^68 | 010011001 | 0x^8 1x^7 0x^6 0x^5 1x^4 1x^3 0x^2 0x^1 1x^0 | 153
// a^69 | 000101111 | 0x^8 0x^7 0x^6 1x^5 0x^4 1x^3 1x^2 1x^1 1x^0 | 47
// a^70 | 001011110 | 0x^8 0x^7 1x^6 0x^5 1x^4 1x^3 1x^2 1x^1 0x^0 | 94
// a^71 | 010111100 | 0x^8 1x^7 0x^6 1x^5 1x^4 1x^3 1x^2 0x^1 0x^0 | 188
// a^72 | 001100101 | 0x^8 0x^7 1x^6 1x^5 0x^4 0x^3 1x^2 0x^1 1x^0 | 101
// a^73 | 011001010 | 0x^8 1x^7 1x^6 0x^5 0x^4 1x^3 0x^2 1x^1 0x^0 | 202
// a^74 | 010001001 | 0x^8 1x^7 0x^6 0x^5 0x^4 1x^3 0x^2 0x^1 1x^0 | 137
// a^75 | 000001111 | 0x^8 0x^7 0x^6 0x^5 0x^4 1x^3 1x^2 1x^1 1x^0 | 15
// a^76 | 000011110 | 0x^8 0x^7 0x^6 0x^5 1x^4 1x^3 1x^2 1x^1 0x^0 | 30
// a^77 | 000111100 | 0x^8 0x^7 0x^6 1x^5 1x^4 1x^3 1x^2 0x^1 0x^0 | 60
// a^78 | 001111000 | 0x^8 0x^7 1x^6 1x^5 1x^4 1x^3 0x^2 0x^1 0x^0 | 120
// a^79 | 011110000 | 0x^8 1x^7 1x^6 1x^5 1x^4 0x^3 0x^2 0x^1 0x^0 | 240
// a^80 | 011111101 | 0x^8 1x^7 1x^6 1x^5 1x^4 1x^3 1x^2 0x^1 1x^0 | 253
// a^81 | 011100111 | 0x^8 1x^7 1x^6 1x^5 0x^4 0x^3 1x^2 1x^1 1x^0 | 231
// a^82 | 011010011 | 0x^8 1x^7 1x^6 0x^5 1x^4 0x^3 0x^2 1x^1 1x^0 | 211
// a^83 | 010111011 | 0x^8 1x^7 0x^6 1x^5 1x^4 1x^3 0x^2 1x^1 1x^0 | 187
// a^84 | 001101011 | 0x^8 0x^7 1x^6 1x^5 0x^4 1x^3 0x^2 1x^1 1x^0 | 107
// a^85 | 011010110 | 0x^8 1x^7 1x^6 0x^5 1x^4 0x^3 1x^2 1x^1 0x^0 | 214
// a^86 | 010110001 | 0x^8 1x^7 0x^6 1x^5 1x^4 0x^3 0x^2 0x^1 1x^0 | 177
// a^87 | 001111111 | 0x^8 0x^7 1x^6 1x^5 1x^4 1x^3 1x^2 1x^1 1x^0 | 127
// a^88 | 011111110 | 0x^8 1x^7 1x^6 1x^5 1x^4 1x^3 1x^2 1x^1 0x^0 | 254
// a^89 | 011100001 | 0x^8 1x^7 1x^6 1x^5 0x^4 0x^3 0x^2 0x^1 1x^0 | 225
// a^90 | 011011111 | 0x^8 1x^7 1x^6 0x^5 1x^4 1x^3 1x^2 1x^1 1x^0 | 223
// a^91 | 010100011 | 0x^8 1x^7 0x^6 1x^5 0x^4 0x^3 0x^2 1x^1 1x^0 | 163
// a^92 | 001011011 | 0x^8 0x^7 1x^6 0x^5 1x^4 1x^3 0x^2 1x^1 1x^0 | 91
// a^93 | 010110110 | 0x^8 1x^7 0x^6 1x^5 1x^4 0x^3 1x^2 1x^1 0x^0 | 182
// a^94 | 001110001 | 0x^8 0x^7 1x^6 1x^5 1x^4 0x^3 0x^2 0x^1 1x^0 | 113
// a^95 | 011100010 | 0x^8 1x^7 1x^6 1x^5 0x^4 0x^3 0x^2 1x^1 0x^0 | 226
// a^96 | 011011001 | 0x^8 1x^7 1x^6 0x^5 1x^4 1x^3 0x^2 0x^1 1x^0 | 217
// a^97 | 010101111 | 0x^8 1x^7 0x^6 1x^5 0x^4 1x^3 1x^2 1x^1 1x^0 | 175
// a^98 | 001000011 | 0x^8 0x^7 1x^6 0x^5 0x^4 0x^3 0x^2 1x^1 1x^0 | 67
// a^99 | 010000110 | 0x^8 1x^7 0x^6 0x^5 0x^4 0x^3 1x^2 1x^1 0x^0 | 134
// a^100 | 000010001 | 0x^8 0x^7 0x^6 0x^5 1x^4 0x^3 0x^2 0x^1 1x^0 | 17
// a^101 | 000100010 | 0x^8 0x^7 0x^6 1x^5 0x^4 0x^3 0x^2 1x^1 0x^0 | 34
// a^102 | 001000100 | 0x^8 0x^7 1x^6 0x^5 0x^4 0x^3 1x^2 0x^1 0x^0 | 68
// a^103 | 010001000 | 0x^8 1x^7 0x^6 0x^5 0x^4 1x^3 0x^2 0x^1 0x^0 | 136
// a^104 | 000001101 | 0x^8 0x^7 0x^6 0x^5 0x^4 1x^3 1x^2 0x^1 1x^0 | 13
// a^105 | 000011010 | 0x^8 0x^7 0x^6 0x^5 1x^4 1x^3 0x^2 1x^1 0x^0 | 26
// a^106 | 000110100 | 0x^8 0x^7 0x^6 1x^5 1x^4 0x^3 1x^2 0x^1 0x^0 | 52
// a^107 | 001101000 | 0x^8 0x^7 1x^6 1x^5 0x^4 1x^3 0x^2 0x^1 0x^0 | 104
// a^108 | 011010000 | 0x^8 1x^7 1x^6 0x^5 1x^4 0x^3 0x^2 0x^1 0x^0 | 208
// a^109 | 010111101 | 0x^8 1x^7 0x^6 1x^5 1x^4 1x^3 1x^2 0x^1 1x^0 | 189
// a^110 | 001100111 | 0x^8 0x^7 1x^6 1x^5 0x^4 0x^3 1x^2 1x^1 1x^0 | 103
// a^111 | 011001110 | 0x^8 1x^7 1x^6 0x^5 0x^4 1x^3 1x^2 1x^1 0x^0 | 206
// a^112 | 010000001 | 0x^8 1x^7 0x^6 0x^5 0x^4 0x^3 0x^2 0x^1 1x^0 | 129
// a^113 | 000011111 | 0x^8 0x^7 0x^6 0x^5 1x^4 1x^3 1x^2 1x^1 1x^0 | 31
// a^114 | 000111110 | 0x^8 0x^7 0x^6 1x^5 1x^4 1x^3 1x^2 1x^1 0x^0 | 62
// a^115 | 001111100 | 0x^8 0x^7 1x^6 1x^5 1x^4 1x^3 1x^2 0x^1 0x^0 | 124
// a^116 | 011111000 | 0x^8 1x^7 1x^6 1x^5 1x^4 1x^3 0x^2 0x^1 0x^0 | 248
// a^117 | 011101101 | 0x^8 1x^7 1x^6 1x^5 0x^4 1x^3 1x^2 0x^1 1x^0 | 237
// a^118 | 011000111 | 0x^8 1x^7 1x^6 0x^5 0x^4 0x^3 1x^2 1x^1 1x^0 | 199
// a^119 | 010010011 | 0x^8 1x^7 0x^6 0x^5 1x^4 0x^3 0x^2 1x^1 1x^0 | 147
// a^120 | 000111011 | 0x^8 0x^7 0x^6 1x^5 1x^4 1x^3 0x^2 1x^1 1x^0 | 59
// a^121 | 001110110 | 0x^8 0x^7 1x^6 1x^5 1x^4 0x^3 1x^2 1x^1 0x^0 | 118
// a^122 | 011101100 | 0x^8 1x^7 1x^6 1x^5 0x^4 1x^3 1x^2 0x^1 0x^0 | 236
// a^123 | 011000101 | 0x^8 1x^7 1x^6 0x^5 0x^4 0x^3 1x^2 0x^1 1x^0 | 197
// a^124 | 010010111 | 0x^8 1x^7 0x^6 0x^5 1x^4 0x^3 1x^2 1x^1 1x^0 | 151
// a^125 | 000110011 | 0x^8 0x^7 0x^6 1x^5 1x^4 0x^3 0x^2 1x^1 1x^0 | 51
// a^126 | 001100110 | 0x^8 0x^7 1x^6 1x^5 0x^4 0x^3 1x^2 1x^1 0x^0 | 102
// a^127 | 011001100 | 0x^8 1x^7 1x^6 0x^5 0x^4 1x^3 1x^2 0x^1 0x^0 | 204
// a^128 | 010000101 | 0x^8 1x^7 0x^6 0x^5 0x^4 0x^3 1x^2 0x^1 1x^0 | 133
// a^129 | 000010111 | 0x^8 0x^7 0x^6 0x^5 1x^4 0x^3 1x^2 1x^1 1x^0 | 23
// a^130 | 000101110 | 0x^8 0x^7 0x^6 1x^5 0x^4 1x^3 1x^2 1x^1 0x^0 | 46
// a^131 | 001011100 | 0x^8 0x^7 1x^6 0x^5 1x^4 1x^3 1x^2 0x^1 0x^0 | 92
// a^132 | 010111000 | 0x^8 1x^7 0x^6 1x^5 1x^4 1x^3 0x^2 0x^1 0x^0 | 184
// a^133 | 001101101 | 0x^8 0x^7 1x^6 1x^5 0x^4 1x^3 1x^2 0x^1 1x^0 | 109
// a^134 | 011011010 | 0x^8 1x^7 1x^6 0x^5 1x^4 1x^3 0x^2 1x^1 0x^0 | 218
// a^135 | 010101001 | 0x^8 1x^7 0x^6 1x^5 0x^4 1x^3 0x^2 0x^1 1x^0 | 169
// a^136 | 001001111 | 0x^8 0x^7 1x^6 0x^5 0x^4 1x^3 1x^2 1x^1 1x^0 | 79
// a^137 | 010011110 | 0x^8 1x^7 0x^6 0x^5 1x^4 1x^3 1x^2 1x^1 0x^0 | 158
// a^138 | 000100001 | 0x^8 0x^7 0x^6 1x^5 0x^4 0x^3 0x^2 0x^1 1x^0 | 33
// a^139 | 001000010 | 0x^8 0x^7 1x^6 0x^5 0x^4 0x^3 0x^2 1x^1 0x^0 | 66
// a^140 | 010000100 | 0x^8 1x^7 0x^6 0x^5 0x^4 0x^3 1x^2 0x^1 0x^0 | 132
// a^141 | 000010101 | 0x^8 0x^7 0x^6 0x^5 1x^4 0x^3 1x^2 0x^1 1x^0 | 21
// a^142 | 000101010 | 0x^8 0x^7 0x^6 1x^5 0x^4 1x^3 0x^2 1x^1 0x^0 | 42
// a^143 | 001010100 | 0x^8 0x^7 1x^6 0x^5 1x^4 0x^3 1x^2 0x^1 0x^0 | 84
// a^144 | 010101000 | 0x^8 1x^7 0x^6 1x^5 0x^4 1x^3 0x^2 0x^1 0x^0 | 168
// a^145 | 001001101 | 0x^8 0x^7 1x^6 0x^5 0x^4 1x^3 1x^2 0x^1 1x^0 | 77
// a^146 | 010011010 | 0x^8 1x^7 0x^6 0x^5 1x^4 1x^3 0x^2 1x^1 0x^0 | 154
// a^147 | 000101001 | 0x^8 0x^7 0x^6 1x^5 0x^4 1x^3 0x^2 0x^1 1x^0 | 41
// a^148 | 001010010 | 0x^8 0x^7 1x^6 0x^5 1x^4 0x^3 0x^2 1x^1 0x^0 | 82
// a^149 | 010100100 | 0x^8 1x^7 0x^6 1x^5 0x^4 0x^3 1x^2 0x^1 0x^0 | 164
// a^150 | 001010101 | 0x^8 0x^7 1x^6 0x^5 1x^4 0x^3 1x^2 0x^1 1x^0 | 85
// a^151 | 010101010 | 0x^8 1x^7 0x^6 1x^5 0x^4 1x^3 0x^2 1x^1 0x^0 | 170
// a^152 | 001001001 | 0x^8 0x^7 1x^6 0x^5 0x^4 1x^3 0x^2 0x^1 1x^0 | 73
// a^153 | 010010010 | 0x^8 1x^7 0x^6 0x^5 1x^4 0x^3 0x^2 1x^1 0x^0 | 146
// a^154 | 000111001 | 0x^8 0x^7 0x^6 1x^5 1x^4 1x^3 0x^2 0x^1 1x^0 | 57
// a^155 | 001110010 | 0x^8 0x^7 1x^6 1x^5 1x^4 0x^3 0x^2 1x^1 0x^0 | 114
// a^156 | 011100100 | 0x^8 1x^7 1x^6 1x^5 0x^4 0x^3 1x^2 0x^1 0x^0 | 228
// a^157 | 011010101 | 0x^8 1x^7 1x^6 0x^5 1x^4 0x^3 1x^2 0x^1 1x^0 | 213
// a^158 | 010110111 | 0x^8 1x^7 0x^6 1x^5 1x^4 0x^3 1x^2 1x^1 1x^0 | 183
// a^159 | 001110011 | 0x^8 0x^7 1x^6 1x^5 1x^4 0x^3 0x^2 1x^1 1x^0 | 115
// a^160 | 011100110 | 0x^8 1x^7 1x^6 1x^5 0x^4 0x^3 1x^2 1x^1 0x^0 | 230
// a^161 | 011010001 | 0x^8 1x^7 1x^6 0x^5 1x^4 0x^3 0x^2 0x^1 1x^0 | 209
// a^162 | 010111111 | 0x^8 1x^7 0x^6 1x^5 1x^4 1x^3 1x^2 1x^1 1x^0 | 191
// a^163 | 001100011 | 0x^8 0x^7 1x^6 1x^5 0x^4 0x^3 0x^2 1x^1 1x^0 | 99
// a^164 | 011000110 | 0x^8 1x^7 1x^6 0x^5 0x^4 0x^3 1x^2 1x^1 0x^0 | 198
// a^165 | 010010001 | 0x^8 1x^7 0x^6 0x^5 1x^4 0x^3 0x^2 0x^1 1x^0 | 145
// a^166 | 000111111 | 0x^8 0x^7 0x^6 1x^5 1x^4 1x^3 1x^2 1x^1 1x^0 | 63
// a^167 | 001111110 | 0x^8 0x^7 1x^6 1x^5 1x^4 1x^3 1x^2 1x^1 0x^0 | 126
// a^168 | 011111100 | 0x^8 1x^7 1x^6 1x^5 1x^4 1x^3 1x^2 0x^1 0x^0 | 252
// a^169 | 011100101 | 0x^8 1x^7 1x^6 1x^5 0x^4 0x^3 1x^2 0x^1 1x^0 | 229
// a^170 | 011010111 | 0x^8 1x^7 1x^6 0x^5 1x^4 0x^3 1x^2 1x^1 1x^0 | 215
// a^171 | 010110011 | 0x^8 1x^7 0x^6 1x^5 1x^4 0x^3 0x^2 1x^1 1x^0 | 179
// a^172 | 001111011 | 0x^8 0x^7 1x^6 1x^5 1x^4 1x^3 0x^2 1x^1 1x^0 | 123
// a^173 | 011110110 | 0x^8 1x^7 1x^6 1x^5 1x^4 0x^3 1x^2 1x^1 0x^0 | 246
// a^174 | 011110001 | 0x^8 1x^7 1x^6 1x^5 1x^4 0x^3 0x^2 0x^1 1x^0 | 241
// a^175 | 011111111 | 0x^8 1x^7 1x^6 1x^5 1x^4 1x^3 1x^2 1x^1 1x^0 | 255
// a^176 | 011100011 | 0x^8 1x^7 1x^6 1x^5 0x^4 0x^3 0x^2 1x^1 1x^0 | 227
// a^177 | 011011011 | 0x^8 1x^7 1x^6 0x^5 1x^4 1x^3 0x^2 1x^1 1x^0 | 219
// a^178 | 010101011 | 0x^8 1x^7 0x^6 1x^5 0x^4 1x^3 0x^2 1x^1 1x^0 | 171
// a^179 | 001001011 | 0x^8 0x^7 1x^6 0x^5 0x^4 1x^3 0x^2 1x^1 1x^0 | 75
// a^180 | 010010110 | 0x^8 1x^7 0x^6 0x^5 1x^4 0x^3 1x^2 1x^1 0x^0 | 150
// a^181 | 000110001 | 0x^8 0x^7 0x^6 1x^5 1x^4 0x^3 0x^2 0x^1 1x^0 | 49
// a^182 | 001100010 | 0x^8 0x^7 1x^6 1x^5 0x^4 0x^3 0x^2 1x^1 0x^0 | 98
// a^183 | 011000100 | 0x^8 1x^7 1x^6 0x^5 0x^4 0x^3 1x^2 0x^1 0x^0 | 196
// a^184 | 010010101 | 0x^8 1x^7 0x^6 0x^5 1x^4 0x^3 1x^2 0x^1 1x^0 | 149
// a^185 | 000110111 | 0x^8 0x^7 0x^6 1x^5 1x^4 0x^3 1x^2 1x^1 1x^0 | 55
// a^186 | 001101110 | 0x^8 0x^7 1x^6 1x^5 0x^4 1x^3 1x^2 1x^1 0x^0 | 110
// a^187 | 011011100 | 0x^8 1x^7 1x^6 0x^5 1x^4 1x^3 1x^2 0x^1 0x^0 | 220
// a^188 | 010100101 | 0x^8 1x^7 0x^6 1x^5 0x^4 0x^3 1x^2 0x^1 1x^0 | 165
// a^189 | 001010111 | 0x^8 0x^7 1x^6 0x^5 1x^4 0x^3 1x^2 1x^1 1x^0 | 87
// a^190 | 010101110 | 0x^8 1x^7 0x^6 1x^5 0x^4 1x^3 1x^2 1x^1 0x^0 | 174
// a^191 | 001000001 | 0x^8 0x^7 1x^6 0x^5 0x^4 0x^3 0x^2 0x^1 1x^0 | 65
// a^192 | 010000010 | 0x^8 1x^7 0x^6 0x^5 0x^4 0x^3 0x^2 1x^1 0x^0 | 130
// a^193 | 000011001 | 0x^8 0x^7 0x^6 0x^5 1x^4 1x^3 0x^2 0x^1 1x^0 | 25
// a^194 | 000110010 | 0x^8 0x^7 0x^6 1x^5 1x^4 0x^3 0x^2 1x^1 0x^0 | 50
// a^195 | 001100100 | 0x^8 0x^7 1x^6 1x^5 0x^4 0x^3 1x^2 0x^1 0x^0 | 100
// a^196 | 011001000 | 0x^8 1x^7 1x^6 0x^5 0x^4 1x^3 0x^2 0x^1 0x^0 | 200
// a^197 | 010001101 | 0x^8 1x^7 0x^6 0x^5 0x^4 1x^3 1x^2 0x^1 1x^0 | 141
// a^198 | 000000111 | 0x^8 0x^7 0x^6 0x^5 0x^4 0x^3 1x^2 1x^1 1x^0 | 7
// a^199 | 000001110 | 0x^8 0x^7 0x^6 0x^5 0x^4 1x^3 1x^2 1x^1 0x^0 | 14
// a^200 | 000011100 | 0x^8 0x^7 0x^6 0x^5 1x^4 1x^3 1x^2 0x^1 0x^0 | 28
// a^201 | 000111000 | 0x^8 0x^7 0x^6 1x^5 1x^4 1x^3 0x^2 0x^1 0x^0 | 56
// a^202 | 001110000 | 0x^8 0x^7 1x^6 1x^5 1x^4 0x^3 0x^2 0x^1 0x^0 | 112
// a^203 | 011100000 | 0x^8 1x^7 1x^6 1x^5 0x^4 0x^3 0x^2 0x^1 0x^0 | 224
// a^204 | 011011101 | 0x^8 1x^7 1x^6 0x^5 1x^4 1x^3 1x^2 0x^1 1x^0 | 221
// a^205 | 010100111 | 0x^8 1x^7 0x^6 1x^5 0x^4 0x^3 1x^2 1x^1 1x^0 | 167
// a^206 | 001010011 | 0x^8 0x^7 1x^6 0x^5 1x^4 0x^3 0x^2 1x^1 1x^0 | 83
// a^207 | 010100110 | 0x^8 1x^7 0x^6 1x^5 0x^4 0x^3 1x^2 1x^1 0x^0 | 166
// a^208 | 001010001 | 0x^8 0x^7 1x^6 0x^5 1x^4 0x^3 0x^2 0x^1 1x^0 | 81
// a^209 | 010100010 | 0x^8 1x^7 0x^6 1x^5 0x^4 0x^3 0x^2 1x^1 0x^0 | 162
// a^210 | 001011001 | 0x^8 0x^7 1x^6 0x^5 1x^4 1x^3 0x^2 0x^1 1x^0 | 89
// a^211 | 010110010 | 0x^8 1x^7 0x^6 1x^5 1x^4 0x^3 0x^2 1x^1 0x^0 | 178
// a^212 | 001111001 | 0x^8 0x^7 1x^6 1x^5 1x^4 1x^3 0x^2 0x^1 1x^0 | 121
// a^213 | 011110010 | 0x^8 1x^7 1x^6 1x^5 1x^4 0x^3 0x^2 1x^1 0x^0 | 242
// a^214 | 011111001 | 0x^8 1x^7 1x^6 1x^5 1x^4 1x^3 0x^2 0x^1 1x^0 | 249
// a^215 | 011101111 | 0x^8 1x^7 1x^6 1x^5 0x^4 1x^3 1x^2 1x^1 1x^0 | 239
// a^216 | 011000011 | 0x^8 1x^7 1x^6 0x^5 0x^4 0x^3 0x^2 1x^1 1x^0 | 195
// a^217 | 010011011 | 0x^8 1x^7 0x^6 0x^5 1x^4 1x^3 0x^2 1x^1 1x^0 | 155
// a^218 | 000101011 | 0x^8 0x^7 0x^6 1x^5 0x^4 1x^3 0x^2 1x^1 1x^0 | 43
// a^219 | 001010110 | 0x^8 0x^7 1x^6 0x^5 1x^4 0x^3 1x^2 1x^1 0x^0 | 86
// a^220 | 010101100 | 0x^8 1x^7 0x^6 1x^5 0x^4 1x^3 1x^2 0x^1 0x^0 | 172
// a^221 | 001000101 | 0x^8 0x^7 1x^6 0x^5 0x^4 0x^3 1x^2 0x^1 1x^0 | 69
// a^222 | 010001010 | 0x^8 1x^7 0x^6 0x^5 0x^4 1x^3 0x^2 1x^1 0x^0 | 138
// a^223 | 000001001 | 0x^8 0x^7 0x^6 0x^5 0x^4 1x^3 0x^2 0x^1 1x^0 | 9
// a^224 | 000010010 | 0x^8 0x^7 0x^6 0x^5 1x^4 0x^3 0x^2 1x^1 0x^0 | 18
// a^225 | 000100100 | 0x^8 0x^7 0x^6 1x^5 0x^4 0x^3 1x^2 0x^1 0x^0 | 36
// a^226 | 001001000 | 0x^8 0x^7 1x^6 0x^5 0x^4 1x^3 0x^2 0x^1 0x^0 | 72
// a^227 | 010010000 | 0x^8 1x^7 0x^6 0x^5 1x^4 0x^3 0x^2 0x^1 0x^0 | 144
// a^228 | 000111101 | 0x^8 0x^7 0x^6 1x^5 1x^4 1x^3 1x^2 0x^1 1x^0 | 61
// a^229 | 001111010 | 0x^8 0x^7 1x^6 1x^5 1x^4 1x^3 0x^2 1x^1 0x^0 | 122
// a^230 | 011110100 | 0x^8 1x^7 1x^6 1x^5 1x^4 0x^3 1x^2 0x^1 0x^0 | 244
// a^231 | 011110101 | 0x^8 1x^7 1x^6 1x^5 1x^4 0x^3 1x^2 0x^1 1x^0 | 245
// a^232 | 011110111 | 0x^8 1x^7 1x^6 1x^5 1x^4 0x^3 1x^2 1x^1 1x^0 | 247
// a^233 | 011110011 | 0x^8 1x^7 1x^6 1x^5 1x^4 0x^3 0x^2 1x^1 1x^0 | 243
// a^234 | 011111011 | 0x^8 1x^7 1x^6 1x^5 1x^4 1x^3 0x^2 1x^1 1x^0 | 251
// a^235 | 011101011 | 0x^8 1x^7 1x^6 1x^5 0x^4 1x^3 0x^2 1x^1 1x^0 | 235
// a^236 | 011001011 | 0x^8 1x^7 1x^6 0x^5 0x^4 1x^3 0x^2 1x^1 1x^0 | 203
// a^237 | 010001011 | 0x^8 1x^7 0x^6 0x^5 0x^4 1x^3 0x^2 1x^1 1x^0 | 139
// a^238 | 000001011 | 0x^8 0x^7 0x^6 0x^5 0x^4 1x^3 0x^2 1x^1 1x^0 | 11
// a^239 | 000010110 | 0x^8 0x^7 0x^6 0x^5 1x^4 0x^3 1x^2 1x^1 0x^0 | 22
// a^240 | 000101100 | 0x^8 0x^7 0x^6 1x^5 0x^4 1x^3 1x^2 0x^1 0x^0 | 44
// a^241 | 001011000 | 0x^8 0x^7 1x^6 0x^5 1x^4 1x^3 0x^2 0x^1 0x^0 | 88
// a^242 | 010110000 | 0x^8 1x^7 0x^6 1x^5 1x^4 0x^3 0x^2 0x^1 0x^0 | 176
// a^243 | 001111101 | 0x^8 0x^7 1x^6 1x^5 1x^4 1x^3 1x^2 0x^1 1x^0 | 125
// a^244 | 011111010 | 0x^8 1x^7 1x^6 1x^5 1x^4 1x^3 0x^2 1x^1 0x^0 | 250
// a^245 | 011101001 | 0x^8 1x^7 1x^6 1x^5 0x^4 1x^3 0x^2 0x^1 1x^0 | 233
// a^246 | 011001111 | 0x^8 1x^7 1x^6 0x^5 0x^4 1x^3 1x^2 1x^1 1x^0 | 207
// a^247 | 010000011 | 0x^8 1x^7 0x^6 0x^5 0x^4 0x^3 0x^2 1x^1 1x^0 | 131
// a^248 | 000011011 | 0x^8 0x^7 0x^6 0x^5 1x^4 1x^3 0x^2 1x^1 1x^0 | 27
// a^249 | 000110110 | 0x^8 0x^7 0x^6 1x^5 1x^4 0x^3 1x^2 1x^1 0x^0 | 54
// a^250 | 001101100 | 0x^8 0x^7 1x^6 1x^5 0x^4 1x^3 1x^2 0x^1 0x^0 | 108
// a^251 | 011011000 | 0x^8 1x^7 1x^6 0x^5 1x^4 1x^3 0x^2 0x^1 0x^0 | 216
// a^252 | 010101101 | 0x^8 1x^7 0x^6 1x^5 0x^4 1x^3 1x^2 0x^1 1x^0 | 173
// a^253 | 001000111 | 0x^8 0x^7 1x^6 0x^5 0x^4 0x^3 1x^2 1x^1 1x^0 | 71
// a^254 | 010001110 | 0x^8 1x^7 0x^6 0x^5 0x^4 1x^3 1x^2 1x^1 0x^0 | 142
// a^255 | 000000001 | 0x^8 0x^7 0x^6 0x^5 0x^4 0x^3 0x^2 0x^1 1x^0 | 1

+ 83
- 0
vendor/github.com/skip2/go-qrcode/reedsolomon/gf2_8_test.go View File

@@ -0,0 +1,83 @@
// go-qrcode
// Copyright 2014 Tom Harwood

package reedsolomon

import "testing"

func TestGFMultiplicationIdentities(t *testing.T) {
for i := 0; i < 256; i++ {
value := gfElement(i)
if gfMultiply(gfZero, value) != gfZero {
t.Errorf("0 . %d != 0", value)
}

if gfMultiply(value, gfOne) != value {
t.Errorf("%d . 1 == %d, want %d", value, gfMultiply(value, gfOne), value)
}
}
}

func TestGFMultiplicationAndDivision(t *testing.T) {
// a * b == result
var tests = []struct {
a gfElement
b gfElement
result gfElement
}{
{0, 29, 0},
{1, 1, 1},
{1, 32, 32},
{2, 4, 8},
{16, 128, 232},
{17, 17, 28},
{27, 9, 195},
}

for _, test := range tests {
result := gfMultiply(test.a, test.b)

if result != test.result {
t.Errorf("%d * %d = %d, want %d", test.a, test.b, result, test.result)
}

if test.b != gfZero && test.result != gfZero {
b := gfDivide(test.result, test.a)

if b != test.b {
t.Errorf("%d / %d = %d, want %d", test.result, test.a, b, test.b)
}
}
}
}

func TestGFInverse(t *testing.T) {
for i := 1; i < 256; i++ {
a := gfElement(i)
inverse := gfInverse(a)

result := gfMultiply(a, inverse)

if result != gfOne {
t.Errorf("%d * %d^-1 == %d, want %d", a, inverse, result, gfOne)
}
}
}

func TestGFDivide(t *testing.T) {
for i := 1; i < 256; i++ {
for j := 1; j < 256; j++ {
// a * b == product
a := gfElement(i)
b := gfElement(j)
product := gfMultiply(a, b)

// product / b == a
result := gfDivide(product, b)

if result != a {
t.Errorf("%d / %d == %d, want %d", product, b, result, a)
}
}
}
}

+ 216
- 0
vendor/github.com/skip2/go-qrcode/reedsolomon/gf_poly.go View File

@@ -0,0 +1,216 @@
// go-qrcode
// Copyright 2014 Tom Harwood

package reedsolomon

import (
"fmt"
"log"

bitset "github.com/skip2/go-qrcode/bitset"
)

// gfPoly is a polynomial over GF(2^8).
type gfPoly struct {
// The ith value is the coefficient of the ith degree of x.
// term[0]*(x^0) + term[1]*(x^1) + term[2]*(x^2) ...
term []gfElement
}

// newGFPolyFromData returns |data| as a polynomial over GF(2^8).
//
// Each data byte becomes the coefficient of an x term.
//
// For an n byte input the polynomial is:
// data[n-1]*(x^n-1) + data[n-2]*(x^n-2) ... + data[0]*(x^0).
func newGFPolyFromData(data *bitset.Bitset) gfPoly {
numTotalBytes := data.Len() / 8
if data.Len()%8 != 0 {
numTotalBytes++
}

result := gfPoly{term: make([]gfElement, numTotalBytes)}

i := numTotalBytes - 1
for j := 0; j < data.Len(); j += 8 {
result.term[i] = gfElement(data.ByteAt(j))
i--
}

return result
}

// newGFPolyMonomial returns term*(x^degree).
func newGFPolyMonomial(term gfElement, degree int) gfPoly {
if term == gfZero {
return gfPoly{}
}

result := gfPoly{term: make([]gfElement, degree+1)}
result.term[degree] = term

return result
}

func (e gfPoly) data(numTerms int) []byte {
result := make([]byte, numTerms)

i := numTerms - len(e.term)
for j := len(e.term) - 1; j >= 0; j-- {
result[i] = byte(e.term[j])
i++
}

return result
}

// numTerms returns the number of
func (e gfPoly) numTerms() int {
return len(e.term)
}

// gfPolyMultiply returns a * b.
func gfPolyMultiply(a, b gfPoly) gfPoly {
numATerms := a.numTerms()
numBTerms := b.numTerms()

result := gfPoly{term: make([]gfElement, numATerms+numBTerms)}

for i := 0; i < numATerms; i++ {
for j := 0; j < numBTerms; j++ {
if a.term[i] != 0 && b.term[j] != 0 {
monomial := gfPoly{term: make([]gfElement, i+j+1)}
monomial.term[i+j] = gfMultiply(a.term[i], b.term[j])

result = gfPolyAdd(result, monomial)
}
}
}

return result.normalised()
}

// gfPolyRemainder return the remainder of numerator / denominator.
func gfPolyRemainder(numerator, denominator gfPoly) gfPoly {
if denominator.equals(gfPoly{}) {
log.Panicln("Remainder by zero")
}

remainder := numerator

for remainder.numTerms() >= denominator.numTerms() {
degree := remainder.numTerms() - denominator.numTerms()
coefficient := gfDivide(remainder.term[remainder.numTerms()-1],
denominator.term[denominator.numTerms()-1])

divisor := gfPolyMultiply(denominator,
newGFPolyMonomial(coefficient, degree))

remainder = gfPolyAdd(remainder, divisor)
}

return remainder.normalised()
}

// gfPolyAdd returns a + b.
func gfPolyAdd(a, b gfPoly) gfPoly {
numATerms := a.numTerms()
numBTerms := b.numTerms()

numTerms := numATerms
if numBTerms > numTerms {
numTerms = numBTerms
}

result := gfPoly{term: make([]gfElement, numTerms)}

for i := 0; i < numTerms; i++ {
switch {
case numATerms > i && numBTerms > i:
result.term[i] = gfAdd(a.term[i], b.term[i])
case numATerms > i:
result.term[i] = a.term[i]
default:
result.term[i] = b.term[i]
}
}

return result.normalised()
}

func (e gfPoly) normalised() gfPoly {
numTerms := e.numTerms()
maxNonzeroTerm := numTerms - 1

for i := numTerms - 1; i >= 0; i-- {
if e.term[i] != 0 {
break
}

maxNonzeroTerm = i - 1
}

if maxNonzeroTerm < 0 {
return gfPoly{}
} else if maxNonzeroTerm < numTerms-1 {
e.term = e.term[0 : maxNonzeroTerm+1]
}

return e
}

func (e gfPoly) string(useIndexForm bool) string {
var str string
numTerms := e.numTerms()

for i := numTerms - 1; i >= 0; i-- {
if e.term[i] > 0 {
if len(str) > 0 {
str += " + "
}

if !useIndexForm {
str += fmt.Sprintf("%dx^%d", e.term[i], i)
} else {
str += fmt.Sprintf("a^%dx^%d", gfLogTable[e.term[i]], i)
}
}
}

if len(str) == 0 {
str = "0"
}

return str
}

// equals returns true if e == other.
func (e gfPoly) equals(other gfPoly) bool {
var minecPoly *gfPoly
var maxecPoly *gfPoly

if e.numTerms() > other.numTerms() {
minecPoly = &other
maxecPoly = &e
} else {
minecPoly = &e
maxecPoly = &other
}

numMinTerms := minecPoly.numTerms()
numMaxTerms := maxecPoly.numTerms()

for i := 0; i < numMinTerms; i++ {
if e.term[i] != other.term[i] {
return false
}
}

for i := numMinTerms; i < numMaxTerms; i++ {
if maxecPoly.term[i] != 0 {
return false
}
}

return true
}

+ 182
- 0
vendor/github.com/skip2/go-qrcode/reedsolomon/gf_poly_test.go View File

@@ -0,0 +1,182 @@
// go-qrcode
// Copyright 2014 Tom Harwood

package reedsolomon

import (
"testing"
)

func TestGFPolyAdd(t *testing.T) {
// a + b == result
var tests = []struct {
a gfPoly
b gfPoly
result gfPoly
}{
{
gfPoly{[]gfElement{0, 0, 0}},
gfPoly{[]gfElement{0}},
gfPoly{[]gfElement{}},
},
{
gfPoly{[]gfElement{1, 0}},
gfPoly{[]gfElement{1, 0}},
gfPoly{[]gfElement{0, 0}},
},
{
gfPoly{[]gfElement{0xA0, 0x80, 0xFF, 0x00}},
gfPoly{[]gfElement{0x0A, 0x82}},
gfPoly{[]gfElement{0xAA, 0x02, 0xFF}},
},
}

for _, test := range tests {
result := gfPolyAdd(test.a, test.b)

if !test.result.equals(result) {
t.Errorf("%s * %s != %s (got %s)\n", test.a.string(false), test.b.string(false),
test.result.string(false), result.string(false))
}

if len(result.term) > 0 && result.term[len(result.term)-1] == 0 {
t.Errorf("Result's maximum term coefficient is zero")
}
}
}

func TestGFPolyequals(t *testing.T) {
// a == b if isEqual
var tests = []struct {
a gfPoly
b gfPoly
isEqual bool
}{
{
gfPoly{[]gfElement{0}},
gfPoly{[]gfElement{0}},
true,
},
{
gfPoly{[]gfElement{1}},
gfPoly{[]gfElement{0}},
false,
},
{
gfPoly{[]gfElement{1, 0, 1, 0, 1}},
gfPoly{[]gfElement{1, 0, 1, 0, 1}},
true,
},
{
gfPoly{[]gfElement{1, 0, 1}},
gfPoly{[]gfElement{1, 0, 1, 0, 0}},
true,
},
}

for _, test := range tests {
isEqual := test.a.equals(test.b)

if isEqual != test.isEqual {
t.Errorf("%s and %s equality is %t (got %t)\n", test.a.string(false), test.b.string(false),
test.isEqual, isEqual)
}
}
}

func TestGFPolyMultiply(t *testing.T) {
// a * b == result
var tests = []struct {
a gfPoly
b gfPoly
result gfPoly
}{
{
gfPoly{[]gfElement{0, 0, 1}},
gfPoly{[]gfElement{9}},
gfPoly{[]gfElement{0, 0, 9}},
},
{
gfPoly{[]gfElement{0, 16, 1}},
gfPoly{[]gfElement{128, 2}},
gfPoly{[]gfElement{0, 232, 160, 2}},
},
{
gfPoly{[]gfElement{254, 120, 88, 44, 11, 1}},
gfPoly{[]gfElement{16, 2, 0, 51, 44}},
gfPoly{[]gfElement{91, 50, 25, 184, 194, 105, 45, 244, 58, 44}},
},
}

for _, test := range tests {
result := gfPolyMultiply(test.a, test.b)

if !test.result.equals(result) {
t.Errorf("%s * %s = %s (got %s)\n",
test.a.string(false),
test.b.string(false),
test.result.string(false),
result.string(false))
}
}
}

func TestGFPolyRemainder(t *testing.T) {
// numerator / denominator == quotient + remainder.
var tests = []struct {
numerator gfPoly
denominator gfPoly
remainder gfPoly
}{
{
gfPoly{[]gfElement{1}},
gfPoly{[]gfElement{1}},
gfPoly{[]gfElement{0}},
},
{
gfPoly{[]gfElement{1, 0}},
gfPoly{[]gfElement{1}},
gfPoly{[]gfElement{0}},
},
{
gfPoly{[]gfElement{1}},
gfPoly{[]gfElement{1, 0}},
gfPoly{[]gfElement{1}},
},
{
gfPoly{[]gfElement{1, 0, 1}},
gfPoly{[]gfElement{0, 1}},
gfPoly{[]gfElement{1}},
},
// (x^12 + x^10) / (x^10 + x^8 + x^5 + x^4 + x^2 + x^1 + x^0) =
// (x^10 + x^8 + x^5 + x^4 + x^2 + x^1 + x^0) * x^2 +
// (x^7 + x^6 + x^4 + x^3 + x^2) (the remainder)
{
gfPoly{[]gfElement{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1}},
gfPoly{[]gfElement{1, 1, 1, 0, 1, 1, 0, 0, 1, 0, 1}},
gfPoly{[]gfElement{0, 0, 1, 1, 1, 0, 1, 1}},
},
{
gfPoly{[]gfElement{91, 50, 25, 184, 194, 105, 45, 244, 58, 44}},
gfPoly{[]gfElement{254, 120, 88, 44, 11, 1}},
gfPoly{[]gfElement{}},
},
{
gfPoly{[]gfElement{0, 0, 0, 0, 0, 0, 195, 172, 24, 64}},
gfPoly{[]gfElement{116, 147, 63, 198, 31, 1}},
gfPoly{[]gfElement{48, 174, 34, 13, 134}},
},
}

for _, test := range tests {
remainder := gfPolyRemainder(test.numerator, test.denominator)

if !test.remainder.equals(remainder) {
t.Errorf("%s / %s, remainder = %s (got %s)\n",
test.numerator.string(false),
test.denominator.string(false),
test.remainder.string(false),
remainder.string(false))
}
}
}

+ 73
- 0
vendor/github.com/skip2/go-qrcode/reedsolomon/reed_solomon.go View File

@@ -0,0 +1,73 @@
// go-qrcode
// Copyright 2014 Tom Harwood

// Package reedsolomon provides error correction encoding for QR Code 2005.
//
// QR Code 2005 uses a Reed-Solomon error correcting code to detect and correct
// errors encountered during decoding.
//
// The generated RS codes are systematic, and consist of the input data with
// error correction bytes appended.
package reedsolomon

import (
"log"

bitset "github.com/skip2/go-qrcode/bitset"
)

// Encode data for QR Code 2005 using the appropriate Reed-Solomon code.
//
// numECBytes is the number of error correction bytes to append, and is
// determined by the target QR Code's version and error correction level.
//
// ISO/IEC 18004 table 9 specifies the numECBytes required. e.g. a 1-L code has
// numECBytes=7.
func Encode(data *bitset.Bitset, numECBytes int) *bitset.Bitset {
// Create a polynomial representing |data|.
//
// The bytes are interpreted as the sequence of coefficients of a polynomial.
// The last byte's value becomes the x^0 coefficient, the second to last
// becomes the x^1 coefficient and so on.
ecpoly := newGFPolyFromData(data)
ecpoly = gfPolyMultiply(ecpoly, newGFPolyMonomial(gfOne, numECBytes))

// Pick the generator polynomial.
generator := rsGeneratorPoly(numECBytes)

// Generate the error correction bytes.
remainder := gfPolyRemainder(ecpoly, generator)

// Combine the data & error correcting bytes.
// The mathematically correct answer is:
//
// result := gfPolyAdd(ecpoly, remainder).
//
// The encoding used by QR Code 2005 is slightly different this result: To
// preserve the original |data| bit sequence exactly, the data and remainder
// are combined manually below. This ensures any most significant zero bits
// are preserved (and not optimised away).
result := bitset.Clone(data)
result.AppendBytes(remainder.data(numECBytes))

return result
}

// rsGeneratorPoly returns the Reed-Solomon generator polynomial with |degree|.
//
// The generator polynomial is calculated as:
// (x + a^0)(x + a^1)...(x + a^degree-1)
func rsGeneratorPoly(degree int) gfPoly {
if degree < 2 {
log.Panic("degree < 2")
}

generator := gfPoly{term: []gfElement{1}}

for i := 0; i < degree; i++ {
nextPoly := gfPoly{term: []gfElement{gfExpTable[i], 1}}
generator = gfPolyMultiply(generator, nextPoly)
}

return generator
}

+ 89
- 0
vendor/github.com/skip2/go-qrcode/reedsolomon/reed_solomon_test.go View File

@@ -0,0 +1,89 @@
// go-qrcode
// Copyright 2014 Tom Harwood

package reedsolomon

import (
"testing"

bitset "github.com/skip2/go-qrcode/bitset"
)

func TestGeneratorPoly(t *testing.T) {
var tests = []struct {
degree int
generator gfPoly
}{
// x^2 + 3x^1 + 2x^0 (the shortest generator poly)
{
2,
gfPoly{term: []gfElement{2, 3, 1}},
},
// x^5 + 31x^4 + 198x^3 + 63x^2 + 147x^1 + 116x^0
{
5,
gfPoly{term: []gfElement{116, 147, 63, 198, 31, 1}},
},
// x^68 + 131x^67 + 115x^66 + 9x^65 + 39x^64 + 18x^63 + 182x^62 + 60x^61 +
// 94x^60 + 223x^59 + 230x^58 + 157x^57 + 142x^56 + 119x^55 + 85x^54 +
// 107x^53 + 34x^52 + 174x^51 + 167x^50 + 109x^49 + 20x^48 + 185x^47 +
// 112x^46 + 145x^45 + 172x^44 + 224x^43 + 170x^42 + 182x^41 + 107x^40 +
// 38x^39 + 107x^38 + 71x^37 + 246x^36 + 230x^35 + 225x^34 + 144x^33 +
// 20x^32 + 14x^31 + 175x^30 + 226x^29 + 245x^28 + 20x^27 + 219x^26 +
// 212x^25 + 51x^24 + 158x^23 + 88x^22 + 63x^21 + 36x^20 + 199x^19 + 4x^18 +
// 80x^17 + 157x^16 + 211x^15 + 239x^14 + 255x^13 + 7x^12 + 119x^11 + 11x^10
// + 235x^9 + 12x^8 + 34x^7 + 149x^6 + 204x^5 + 8x^4 + 32x^3 + 29x^2 + 99x^1
// + 11x^0 (the longest generator poly)
{
68,
gfPoly{term: []gfElement{11, 99, 29, 32, 8, 204, 149, 34, 12,
235, 11, 119, 7, 255, 239, 211, 157, 80, 4, 199, 36, 63, 88, 158, 51, 212,
219, 20, 245, 226, 175, 14, 20, 144, 225, 230, 246, 71, 107, 38, 107, 182,
170, 224, 172, 145, 112, 185, 20, 109, 167, 174, 34, 107, 85, 119, 142,
157, 230, 223, 94, 60, 182, 18, 39, 9, 115, 131, 1}},
},
}

for _, test := range tests {
generator := rsGeneratorPoly(test.degree)

if !generator.equals(test.generator) {
t.Errorf("degree=%d generator=%s, want %s", test.degree,
generator.string(true), test.generator.string(true))
}
}
}

func TestEncode(t *testing.T) {
var tests = []struct {
numECBytes int
data string
rsCode string
}{
{
5,
"01000000 00011000 10101100 11000011 00000000",
"01000000 00011000 10101100 11000011 00000000 10000110 00001101 00100010 10101110 00110000",
},
{
10,
"00010000 00100000 00001100 01010110 01100001 10000000 11101100 00010001 11101100 00010001 11101100 00010001 11101100 00010001 11101100 00010001",
"00010000 00100000 00001100 01010110 01100001 10000000 11101100 00010001 11101100 00010001 11101100 00010001 11101100 00010001 11101100 00010001 10100101 00100100 11010100 11000001 11101101 00110110 11000111 10000111 00101100 01010101",
},
}

for _, test := range tests {
data := bitset.NewFromBase2String(test.data)
rsCode := bitset.NewFromBase2String(test.rsCode)

result := Encode(data, test.numECBytes)

if !rsCode.Equals(result) {
t.Errorf("data=%s, numECBytes=%d, encoded=%s, want %s",
data.String(),
test.numECBytes,
result.String(),
rsCode)
}
}
}

+ 309
- 0
vendor/github.com/skip2/go-qrcode/regular_symbol.go View File

@@ -0,0 +1,309 @@
// go-qrcode
// Copyright 2014 Tom Harwood

package qrcode

import (
bitset "github.com/skip2/go-qrcode/bitset"
)

type regularSymbol struct {
version qrCodeVersion
mask int

data *bitset.Bitset

symbol *symbol
size int
}

// Abbreviated true/false.
const (
b0 = false
b1 = true
)

var (
alignmentPatternCenter = [][]int{
{}, // Version 0 doesn't exist.
{}, // Version 1 doesn't use alignment patterns.
{6, 18},
{6, 22},
{6, 26},
{6, 30},
{6, 34},
{6, 22, 38},
{6, 24, 42},
{6, 26, 46},
{6, 28, 50},
{6, 30, 54},
{6, 32, 58},
{6, 34, 62},
{6, 26, 46, 66},
{6, 26, 48, 70},
{6, 26, 50, 74},
{6, 30, 54, 78},
{6, 30, 56, 82},
{6, 30, 58, 86},
{6, 34, 62, 90},
{6, 28, 50, 72, 94},
{6, 26, 50, 74, 98},
{6, 30, 54, 78, 102},
{6, 28, 54, 80, 106},
{6, 32, 58, 84, 110},
{6, 30, 58, 86, 114},
{6, 34, 62, 90, 118},
{6, 26, 50, 74, 98, 122},
{6, 30, 54, 78, 102, 126},
{6, 26, 52, 78, 104, 130},
{6, 30, 56, 82, 108, 134},
{6, 34, 60, 86, 112, 138},
{6, 30, 58, 86, 114, 142},
{6, 34, 62, 90, 118, 146},
{6, 30, 54, 78, 102, 126, 150},
{6, 24, 50, 76, 102, 128, 154},
{6, 28, 54, 80, 106, 132, 158},
{6, 32, 58, 84, 110, 136, 162},
{6, 26, 54, 82, 110, 138, 166},
{6, 30, 58, 86, 114, 142, 170},
}

finderPattern = [][]bool{
{b1, b1, b1, b1, b1, b1, b1},
{b1, b0, b0, b0, b0, b0, b1},
{b1, b0, b1, b1, b1, b0, b1},
{b1, b0, b1, b1, b1, b0, b1},
{b1, b0, b1, b1, b1, b0, b1},
{b1, b0, b0, b0, b0, b0, b1},
{b1, b1, b1, b1, b1, b1, b1},
}

finderPatternSize = 7

finderPatternHorizontalBorder = [][]bool{
{b0, b0, b0, b0, b0, b0, b0, b0},
}

finderPatternVerticalBorder = [][]bool{
{b0},
{b0},
{b0},
{b0},
{b0},
{b0},
{b0},
{b0},
}

alignmentPattern = [][]bool{
{b1, b1, b1, b1, b1},
{b1, b0, b0, b0, b1},
{b1, b0, b1, b0, b1},
{b1, b0, b0, b0, b1},
{b1, b1, b1, b1, b1},
}
)

func buildRegularSymbol(version qrCodeVersion, mask int,
data *bitset.Bitset) (*symbol, error) {
m := &regularSymbol{
version: version,
mask: mask,
data: data,

symbol: newSymbol(version.symbolSize(), version.quietZoneSize()),
size: version.symbolSize(),
}

m.addFinderPatterns()
m.addAlignmentPatterns()
m.addTimingPatterns()
m.addFormatInfo()
m.addVersionInfo()

ok, err := m.addData()
if !ok {
return nil, err
}

return m.symbol, nil
}

func (m *regularSymbol) addFinderPatterns() {
fpSize := finderPatternSize
fp := finderPattern
fpHBorder := finderPatternHorizontalBorder
fpVBorder := finderPatternVerticalBorder

// Top left Finder Pattern.
m.symbol.set2dPattern(0, 0, fp)
m.symbol.set2dPattern(0, fpSize, fpHBorder)
m.symbol.set2dPattern(fpSize, 0, fpVBorder)

// Top right Finder Pattern.
m.symbol.set2dPattern(m.size-fpSize, 0, fp)
m.symbol.set2dPattern(m.size-fpSize-1, fpSize, fpHBorder)
m.symbol.set2dPattern(m.size-fpSize-1, 0, fpVBorder)

// Bottom left Finder Pattern.
m.symbol.set2dPattern(0, m.size-fpSize, fp)
m.symbol.set2dPattern(0, m.size-fpSize-1, fpHBorder)
m.symbol.set2dPattern(fpSize, m.size-fpSize-1, fpVBorder)
}

func (m *regularSymbol) addAlignmentPatterns() {
for _, x := range alignmentPatternCenter[m.version.version] {
for _, y := range alignmentPatternCenter[m.version.version] {
if !m.symbol.empty(x, y) {
continue
}

m.symbol.set2dPattern(x-2, y-2, alignmentPattern)
}
}
}

func (m *regularSymbol) addTimingPatterns() {
value := true

for i := finderPatternSize + 1; i < m.size-finderPatternSize; i++ {
m.symbol.set(i, finderPatternSize-1, value)
m.symbol.set(finderPatternSize-1, i, value)

value = !value
}
}

func (m *regularSymbol) addFormatInfo() {
fpSize := finderPatternSize
l := formatInfoLengthBits - 1

f := m.version.formatInfo(m.mask)

// Bits 0-7, under the top right finder pattern.
for i := 0; i <= 7; i++ {
m.symbol.set(m.size-i-1, fpSize+1, f.At(l-i))
}

// Bits 0-5, right of the top left finder pattern.
for i := 0; i <= 5; i++ {
m.symbol.set(fpSize+1, i, f.At(l-i))
}

// Bits 6-8 on the corner of the top left finder pattern.
m.symbol.set(fpSize+1, fpSize, f.At(l-6))
m.symbol.set(fpSize+1, fpSize+1, f.At(l-7))
m.symbol.set(fpSize, fpSize+1, f.At(l-8))

// Bits 9-14 on the underside of the top left finder pattern.
for i := 9; i <= 14; i++ {
m.symbol.set(14-i, fpSize+1, f.At(l-i))
}

// Bits 8-14 on the right side of the bottom left finder pattern.
for i := 8; i <= 14; i++ {
m.symbol.set(fpSize+1, m.size-fpSize+i-8, f.At(l-i))
}

// Always dark symbol.
m.symbol.set(fpSize+1, m.size-fpSize-1, true)
}

func (m *regularSymbol) addVersionInfo() {
fpSize := finderPatternSize

v := m.version.versionInfo()
l := versionInfoLengthBits - 1

if v == nil {
return
}

for i := 0; i < v.Len(); i++ {
// Above the bottom left finder pattern.
m.symbol.set(i/3, m.size-fpSize-4+i%3, v.At(l-i))

// Left of the top right finder pattern.
m.symbol.set(m.size-fpSize-4+i%3, i/3, v.At(l-i))
}
}

type direction uint8

const (
up direction = iota
down
)

func (m *regularSymbol) addData() (bool, error) {
xOffset := 1
dir := up

x := m.size - 2
y := m.size - 1

for i := 0; i < m.data.Len(); i++ {
var mask bool
switch m.mask {
case 0:
mask = (y+x+xOffset)%2 == 0
case 1:
mask = y%2 == 0
case 2:
mask = (x+xOffset)%3 == 0
case 3:
mask = (y+x+xOffset)%3 == 0
case 4:
mask = (y/2+(x+xOffset)/3)%2 == 0
case 5:
mask = (y*(x+xOffset))%2+(y*(x+xOffset))%3 == 0
case 6:
mask = ((y*(x+xOffset))%2+((y*(x+xOffset))%3))%2 == 0
case 7:
mask = ((y+x+xOffset)%2+((y*(x+xOffset))%3))%2 == 0
}

// != is equivalent to XOR.
m.symbol.set(x+xOffset, y, mask != m.data.At(i))

if i == m.data.Len()-1 {
break
}

// Find next free bit in the symbol.
for {
if xOffset == 1 {
xOffset = 0
} else {
xOffset = 1

if dir == up {
if y > 0 {
y--
} else {
dir = down
x -= 2
}
} else {
if y < m.size-1 {
y++
} else {
dir = up
x -= 2
}
}
}

// Skip over the vertical timing pattern entirely.
if x == 5 {
x--
}

if m.symbol.empty(x+xOffset, y) {
break
}
}
}

return true, nil
}

+ 31
- 0
vendor/github.com/skip2/go-qrcode/regular_symbol_test.go View File

@@ -0,0 +1,31 @@
// go-qrcode
// Copyright 2014 Tom Harwood

package qrcode

import (
"fmt"
"testing"

bitset "github.com/skip2/go-qrcode/bitset"
)

func TestBuildRegularSymbol(t *testing.T) {
for k := 0; k <= 7; k++ {
v := getQRCodeVersion(Low, 1)

data := bitset.New()
for i := 0; i < 26; i++ {
data.AppendNumBools(8, false)
}

s, err := buildRegularSymbol(*v, k, data)

if err != nil {
fmt.Println(err.Error())
} else {
_ = s
//fmt.Print(m.string())
}
}
}

+ 309
- 0
vendor/github.com/skip2/go-qrcode/symbol.go View File

@@ -0,0 +1,309 @@
// go-qrcode
// Copyright 2014 Tom Harwood

package qrcode

// symbol is a 2D array of bits representing a QR Code symbol.
//
// A symbol consists of size*size modules, with each module normally drawn as a
// black or white square. The symbol also has a border of quietZoneSize modules.
//
// A (fictional) size=2, quietZoneSize=1 QR Code looks like:
//
// +----+
// | |
// | ab |
// | cd |
// | |
// +----+
//
// For ease of implementation, the functions to set/get bits ignore the border,
// so (0,0)=a, (0,1)=b, (1,0)=c, and (1,1)=d. The entire symbol (including the
// border) is returned by bitmap().
//
type symbol struct {
// Value of module at [y][x]. True is set.
module [][]bool

// True if the module at [y][x] is used (to either true or false).
// Used to identify unused modules.
isUsed [][]bool

// Combined width/height of the symbol and quiet zones.
//
// size = symbolSize + 2*quietZoneSize.
size int

// Width/height of the symbol only.
symbolSize int

// Width/height of a single quiet zone.
quietZoneSize int
}

// newSymbol constructs a symbol of size size*size, with a border of
// quietZoneSize.
func newSymbol(size int, quietZoneSize int) *symbol {
var m symbol

m.module = make([][]bool, size+2*quietZoneSize)
m.isUsed = make([][]bool, size+2*quietZoneSize)

for i := range m.module {
m.module[i] = make([]bool, size+2*quietZoneSize)
m.isUsed[i] = make([]bool, size+2*quietZoneSize)
}

m.size = size + 2*quietZoneSize
m.symbolSize = size
m.quietZoneSize = quietZoneSize

return &m
}

// get returns the module value at (x, y).
func (m *symbol) get(x int, y int) (v bool) {
v = m.module[y+m.quietZoneSize][x+m.quietZoneSize]
return
}

// empty returns true if the module at (x, y) has not been set (to either true
// or false).
func (m *symbol) empty(x int, y int) bool {
return !m.isUsed[y+m.quietZoneSize][x+m.quietZoneSize]
}

// numEmptyModules returns the number of empty modules.
//
// Initially numEmptyModules is symbolSize * symbolSize. After every module has
// been set (to either true or false), the number of empty modules is zero.
func (m *symbol) numEmptyModules() int {
var count int
for y := 0; y < m.symbolSize; y++ {
for x := 0; x < m.symbolSize; x++ {
if !m.isUsed[y+m.quietZoneSize][x+m.quietZoneSize] {
count++
}
}
}

return count
}

// set sets the module at (x, y) to v.
func (m *symbol) set(x int, y int, v bool) {
m.module[y+m.quietZoneSize][x+m.quietZoneSize] = v
m.isUsed[y+m.quietZoneSize][x+m.quietZoneSize] = true
}

// set2dPattern sets a 2D array of modules, starting at (x, y).
func (m *symbol) set2dPattern(x int, y int, v [][]bool) {
for j, row := range v {
for i, value := range row {
m.set(x+i, y+j, value)
}
}
}

// bitmap returns the entire symbol, including the quiet zone.
func (m *symbol) bitmap() [][]bool {
module := make([][]bool, len(m.module))

for i := range m.module {
module[i] = m.module[i][:]
}

return module
}

// string returns a pictorial representation of the symbol, suitable for
// printing in a TTY.
func (m *symbol) string() string {
var result string

for _, row := range m.module {
for _, value := range row {
switch value {
case true:
result += " "
case false:
// Unicode 'FULL BLOCK' (U+2588).
result += "██"
}
}
result += "\n"
}

return result
}

// Constants used to weight penalty calculations. Specified by ISO/IEC
// 18004:2006.
const (
penaltyWeight1 = 3
penaltyWeight2 = 3
penaltyWeight3 = 40
penaltyWeight4 = 10
)

// penaltyScore returns the penalty score of the symbol. The penalty score
// consists of the sum of the four individual penalty types.
func (m *symbol) penaltyScore() int {
return m.penalty1() + m.penalty2() + m.penalty3() + m.penalty4()
}

// penalty1 returns the penalty score for "adjacent modules in row/column with
// same colour".
//
// The numbers of adjacent matching modules and scores are:
// 0-5: score = 0
// 6+ : score = penaltyWeight1 + (numAdjacentModules - 5)
func (m *symbol) penalty1() int {
penalty := 0

for x := 0; x < m.symbolSize; x++ {
lastValue := m.get(x, 0)
count := 1

for y := 1; y < m.symbolSize; y++ {
v := m.get(x, y)

if v != lastValue {
count = 1
lastValue = v
} else {
count++
if count == 6 {
penalty += penaltyWeight1 + 1
} else if count > 6 {
penalty++
}
}
}
}

for y := 0; y < m.symbolSize; y++ {
lastValue := m.get(0, y)
count := 1

for x := 1; x < m.symbolSize; x++ {
v := m.get(x, y)

if v != lastValue {
count = 1
lastValue = v
} else {
count++
if count == 6 {
penalty += penaltyWeight1 + 1
} else if count > 6 {
penalty++
}
}
}
}

return penalty
}

// penalty2 returns the penalty score for "block of modules in the same colour".
//
// m*n: score = penaltyWeight2 * (m-1) * (n-1).
func (m *symbol) penalty2() int {
penalty := 0

for y := 1; y < m.symbolSize; y++ {
for x := 1; x < m.symbolSize; x++ {
topLeft := m.get(x-1, y-1)
above := m.get(x, y-1)
left := m.get(x-1, y)
current := m.get(x, y)

if current == left && current == above && current == topLeft {
penalty++
}
}
}

return penalty * penaltyWeight2
}

// penalty3 returns the penalty score for "1:1:3:1:1 ratio
// (dark:light:dark:light:dark) pattern in row/column, preceded or followed by
// light area 4 modules wide".
//
// Existence of the pattern scores penaltyWeight3.
func (m *symbol) penalty3() int {
penalty := 0

for y := 0; y < m.symbolSize; y++ {
var bitBuffer int16 = 0x00

for x := 0; x < m.symbolSize; x++ {
bitBuffer <<= 1
if v := m.get(x, y); v {
bitBuffer |= 1
}

switch bitBuffer & 0x7ff {
// 0b000 0101 1101 or 0b10111010000
// 0x05d or 0x5d0
case 0x05d, 0x5d0:
penalty += penaltyWeight3
bitBuffer = 0xFF
default:
if x == m.symbolSize-1 && (bitBuffer&0x7f) == 0x5d {
penalty += penaltyWeight3
bitBuffer = 0xFF
}
}
}
}

for x := 0; x < m.symbolSize; x++ {
var bitBuffer int16 = 0x00

for y := 0; y < m.symbolSize; y++ {
bitBuffer <<= 1
if v := m.get(x, y); v {
bitBuffer |= 1
}

switch bitBuffer & 0x7ff {
// 0b000 0101 1101 or 0b10111010000
// 0x05d or 0x5d0
case 0x05d, 0x5d0:
penalty += penaltyWeight3
bitBuffer = 0xFF
default:
if y == m.symbolSize-1 && (bitBuffer&0x7f) == 0x5d {
penalty += penaltyWeight3
bitBuffer = 0xFF
}
}
}
}

return penalty
}

// penalty4 returns the penalty score...
func (m *symbol) penalty4() int {
numModules := m.symbolSize * m.symbolSize
numDarkModules := 0

for x := 0; x < m.symbolSize; x++ {
for y := 0; y < m.symbolSize; y++ {
if v := m.get(x, y); v {
numDarkModules++
}
}
}

numDarkModuleDeviation := numModules/2 - numDarkModules
if numDarkModuleDeviation < 0 {
numDarkModuleDeviation *= -1
}

return penaltyWeight4 * (numDarkModuleDeviation / (numModules / 20))
}

+ 334
- 0
vendor/github.com/skip2/go-qrcode/symbol_test.go View File

@@ -0,0 +1,334 @@
// go-qrcode
// Copyright 2014 Tom Harwood

package qrcode

import "testing"

func TestSymbolBasic(t *testing.T) {
size := 10
quietZoneSize := 4

m := newSymbol(size, quietZoneSize)

if m.size != size+quietZoneSize*2 {
t.Errorf("Symbol size is %d, expected %d", m.size, size+quietZoneSize*2)
}

for i := 0; i < size; i++ {
for j := 0; j < size; j++ {

v := m.get(i, j)

if v != false {
t.Errorf("New symbol not empty")
}

if !m.empty(i, j) {
t.Errorf("New symbol is not empty")
}

value := i*j%2 == 0
m.set(i, j, value)

v = m.get(i, j)

if v != value {
t.Errorf("Symbol ignores set bits")
}

if m.empty(i, j) {
t.Errorf("Symbol ignores set bits")
}
}
}
}

func TestSymbolPenalties(t *testing.T) {
tests := []struct {
pattern [][]bool
expectedPenalty1 int
expectedPenalty2 int
expectedPenalty3 int
expectedPenalty4 int
}{
{
[][]bool{
{b0, b1, b0, b1, b0, b1},
{b1, b0, b1, b0, b1, b0},
{b0, b1, b0, b1, b0, b1},
{b1, b0, b1, b0, b1, b0},
{b0, b1, b0, b1, b0, b1},
{b1, b0, b1, b0, b1, b0},
},
0, // No adjacent modules of same color.
0, // No 2x2+ sized blocks.
0, // No 1:1:3:1:1 pattern.
-1,
},
{
[][]bool{
{b0, b0, b0, b1, b0, b1},
{b1, b0, b1, b0, b1, b0},
{b0, b1, b0, b1, b0, b1},
{b1, b0, b1, b0, b1, b0},
{b0, b1, b0, b1, b0, b1},
{b1, b0, b1, b0, b1, b0},
},
0, // 5 adjacent modules of same colour, score = 0.
0, // No 2x2+ sized blocks.
0, // No 1:1:3:1:1 pattern.
-1,
},
{
[][]bool{
{b0, b0, b0, b0, b0, b0},
{b1, b0, b1, b0, b1, b0},
{b0, b1, b0, b1, b0, b1},
{b1, b0, b1, b0, b1, b0},
{b0, b1, b0, b1, b0, b1},
{b1, b0, b1, b0, b1, b0},
},
4, // 6 adjacent modules of same colour, score = 3 + (6-5)
0, // No 2x2+ sized blocks.
0, // No 1:1:3:1:1 pattern.
-1,
},
{
[][]bool{
{b0, b0, b0, b0, b0, b0, b0},
{b1, b0, b1, b0, b1, b0, b1},
{b1, b0, b0, b0, b0, b0, b1},
{b1, b0, b1, b0, b1, b0, b1},
{b1, b0, b0, b0, b0, b0, b1},
{b1, b0, b1, b0, b1, b0, b1},
{b1, b0, b0, b0, b0, b0, b0},
},
28, // 3+(7-5) + 3+(6-5) + 3+(6-5) + 3+(6-5) + 3+(7-5) + 3+(7-5) = 28
0, // No 2x2+ sized blocks.
0, // No 1:1:3:1:1 pattern.
-1,
},
{
[][]bool{
{b0, b0, b0, b1, b0, b1},
{b0, b0, b1, b0, b1, b0},
{b0, b1, b0, b1, b0, b1},
{b1, b0, b1, b1, b1, b0},
{b0, b1, b1, b1, b0, b1},
{b1, b0, b1, b0, b1, b0},
},
-1,
6, // 3*(2-1)*(2-1) + 3(2-1)*(2-1)
0, // No 1:1:3:1:1 pattern.
-1,
},
{
[][]bool{
{b0, b0, b0, b0, b0, b1},
{b0, b0, b0, b0, b0, b1},
{b0, b0, b0, b0, b0, b1},
{b0, b0, b0, b0, b0, b1},
{b0, b0, b0, b0, b0, b1},
{b0, b0, b0, b0, b0, b1},
},
-1,
60, // 3 * (5-1) * (6-1)
0, // No 1:1:3:1:1 pattern.
-1,
},
{
[][]bool{
{b0, b0, b0, b0, b0, b1},
{b0, b0, b0, b0, b0, b1},
{b1, b1, b0, b1, b0, b1},
{b1, b1, b0, b1, b0, b1},
{b1, b1, b0, b1, b0, b1},
{b1, b1, b0, b1, b0, b1},
},
-1,
21, // 3*(5-1)*(2-1) + 3*(2-1)*(4-1) = 3*4 + 3*3
0, // No 1:1:3:1:1 pattern.
-1,
},
{
[][]bool{
{b0, b0, b0, b0, b1, b0, b1, b1, b1, b0, b1, b0},
{b0, b0, b0, b0, b1, b0, b1, b1, b1, b0, b1, b0},
{b0, b0, b0, b0, b1, b0, b1, b1, b1, b0, b1, b0},
{b0, b0, b0, b0, b1, b0, b1, b1, b1, b0, b1, b0},
{b0, b0, b0, b0, b1, b0, b1, b1, b1, b0, b1, b0},
{b0, b0, b0, b0, b1, b0, b1, b1, b1, b0, b1, b0},
{b0, b0, b0, b0, b1, b0, b1, b1, b1, b0, b1, b0},
{b0, b0, b0, b0, b1, b0, b1, b1, b1, b0, b1, b0},
{b0, b0, b0, b0, b1, b0, b1, b1, b1, b0, b1, b0},
{b0, b0, b0, b0, b1, b0, b1, b1, b1, b0, b1, b0},
{b0, b0, b0, b0, b1, b0, b1, b1, b1, b0, b1, b0},
{b0, b0, b0, b0, b1, b0, b1, b1, b1, b0, b1, b0},
},
-1,
-1,
480, // 12* 1:1:3:1:1 patterns, 12 * 40.
-1,
},
{
[][]bool{
{b1, b0, b0, b0, b0, b0, b0, b0, b0, b0, b0, b0},
{b0, b0, b0, b0, b0, b0, b0, b0, b0, b0, b0, b0},
{b1, b0, b0, b0, b0, b0, b0, b0, b0, b0, b0, b0},
{b1, b0, b0, b0, b0, b0, b0, b0, b0, b0, b0, b0},
{b1, b1, b0, b0, b0, b0, b0, b0, b0, b0, b0, b0},
{b0, b0, b0, b0, b0, b0, b0, b0, b0, b0, b0, b0},
{b1, b1, b0, b0, b0, b0, b0, b0, b0, b0, b0, b0},
{b0, b1, b0, b0, b0, b0, b0, b0, b0, b0, b0, b0},
{b0, b1, b0, b0, b0, b0, b0, b0, b0, b0, b0, b0},
{b0, b0, b0, b0, b0, b0, b0, b0, b0, b0, b0, b0},
{b0, b1, b0, b0, b0, b0, b0, b0, b0, b0, b0, b0},
{b0, b0, b0, b0, b0, b0, b0, b0, b0, b0, b0, b0},
},
-1,
-1,
80, // 2* 1:1:3:1:1 patterns, 2 * 40.
-1,
},
{
[][]bool{
{b0, b0, b0, b0, b0, b0, b0, b0, b0, b0},
{b0, b0, b0, b0, b0, b0, b0, b0, b0, b0},
{b0, b0, b0, b0, b0, b0, b0, b0, b0, b0},
{b0, b0, b0, b0, b0, b0, b0, b0, b0, b0},
{b0, b0, b0, b0, b0, b0, b0, b0, b0, b0},
{b0, b0, b0, b0, b0, b0, b0, b0, b0, b0},
{b0, b0, b0, b0, b0, b0, b0, b0, b0, b0},
{b0, b0, b0, b0, b0, b0, b0, b0, b0, b0},
{b0, b0, b0, b0, b0, b0, b0, b0, b0, b0},
{b0, b0, b0, b0, b0, b0, b0, b0, b0, b0},
},
-1,
-1,
-1,
100, // 10 * (10 steps of 5% deviation from 50% black/white).
},
{
[][]bool{
{b1, b1, b1, b1, b1, b1, b1, b1, b1, b1},
{b1, b1, b1, b1, b1, b1, b1, b1, b1, b1},
{b1, b1, b1, b1, b1, b1, b1, b1, b1, b1},
{b1, b1, b1, b1, b1, b1, b1, b1, b1, b1},
{b1, b1, b1, b1, b1, b1, b1, b1, b1, b1},
{b1, b1, b1, b1, b1, b1, b1, b1, b1, b1},
{b1, b1, b1, b1, b1, b1, b1, b1, b1, b1},
{b1, b1, b1, b1, b1, b1, b1, b1, b1, b1},
{b1, b1, b1, b1, b1, b1, b1, b1, b1, b1},
{b1, b1, b1, b1, b1, b1, b1, b1, b1, b1},
},
-1,
-1,
-1,
100, // 10 * (10 steps of 5% deviation from 50% black/white).
},
{
[][]bool{
{b0, b0, b0, b0, b0, b0, b0, b0, b0, b0},
{b0, b0, b0, b0, b0, b0, b0, b0, b0, b0},
{b0, b0, b0, b0, b0, b0, b0, b0, b0, b0},
{b0, b0, b0, b0, b0, b0, b0, b0, b0, b0},
{b0, b0, b0, b0, b0, b0, b0, b0, b0, b0},
{b1, b1, b1, b1, b1, b1, b1, b1, b1, b1},
{b1, b1, b1, b1, b1, b1, b1, b1, b1, b1},
{b1, b1, b1, b1, b1, b1, b1, b1, b1, b1},
{b1, b1, b1, b1, b1, b1, b1, b1, b1, b1},
{b1, b1, b1, b1, b1, b1, b1, b1, b1, b1},
},
-1,
-1,
-1,
0, // Exactly 50%/50% black/white.
},
{
[][]bool{
{b0, b0, b0, b0, b0, b0, b0, b0, b0, b0},
{b0, b0, b0, b0, b0, b0, b0, b0, b0, b0},
{b0, b0, b0, b0, b0, b0, b0, b0, b0, b0},
{b0, b0, b0, b0, b0, b0, b0, b0, b0, b0},
{b0, b0, b0, b0, b0, b0, b0, b0, b0, b0},
{b0, b0, b0, b0, b0, b0, b0, b0, b0, b0},
{b1, b1, b1, b1, b1, b1, b1, b1, b1, b1},
{b1, b1, b1, b1, b1, b1, b1, b1, b1, b1},
{b1, b1, b1, b1, b1, b1, b1, b1, b1, b1},
{b1, b1, b1, b1, b1, b1, b1, b1, b1, b1},
},
-1,
-1,
-1,
20, // 10 * (2 steps of 5% deviation towards white).
},
{
[][]bool{
{b0, b0, b0, b0, b0, b0, b0, b0, b0, b0},
{b0, b0, b0, b0, b0, b0, b0, b0, b0, b0},
{b0, b0, b0, b0, b0, b0, b0, b0, b0, b0},
{b0, b0, b0, b0, b0, b0, b0, b0, b0, b0},
{b0, b0, b0, b0, b0, b0, b0, b0, b0, b0},
{b0, b0, b0, b0, b0, b0, b0, b0, b0, b0},
{b0, b0, b0, b0, b0, b0, b1, b1, b1, b1},
{b1, b1, b1, b1, b1, b1, b1, b1, b1, b1},
{b1, b1, b1, b1, b1, b1, b1, b1, b1, b1},
{b1, b1, b1, b1, b1, b1, b1, b1, b1, b1},
},
-1,
-1,
-1,
30, // 10 * (3 steps of 5% deviation towards white).
},
{
[][]bool{
{b0, b0, b0, b0, b0, b0, b0, b0, b0, b0},
{b0, b0, b0, b0, b0, b0, b0, b0, b0, b0},
{b0, b0, b0, b0, b0, b0, b0, b0, b0, b0},
{b0, b0, b0, b0, b0, b0, b0, b0, b0, b0},
{b0, b0, b0, b0, b0, b0, b0, b0, b0, b0},
{b0, b0, b0, b0, b0, b0, b0, b0, b0, b0},
{b0, b0, b0, b0, b0, b0, b0, b0, b0, b1},
{b1, b1, b1, b1, b1, b1, b1, b1, b1, b1},
{b1, b1, b1, b1, b1, b1, b1, b1, b1, b1},
{b1, b1, b1, b1, b1, b1, b1, b1, b1, b1},
},
-1,
-1,
-1,
30, // 10 * (3 steps of 5% deviation towards white).
},
}

for i, test := range tests {
s := newSymbol(len(test.pattern[0]), 4)
s.set2dPattern(0, 0, test.pattern)

penalty1 := s.penalty1()
penalty2 := s.penalty2()
penalty3 := s.penalty3()
penalty4 := s.penalty4()

ok := true

if test.expectedPenalty1 != -1 && test.expectedPenalty1 != penalty1 {
ok = false
}
if test.expectedPenalty2 != -1 && test.expectedPenalty2 != penalty2 {
ok = false
}
if test.expectedPenalty3 != -1 && test.expectedPenalty3 != penalty3 {
ok = false
}
if test.expectedPenalty4 != -1 && test.expectedPenalty4 != penalty4 {
ok = false
}

if !ok {
t.Fatalf("Penalty test #%d p1=%d, p2=%d, p3=%d, p4=%d (expected p1=%d, p2=%d, p3=%d, p4=%d)", i, penalty1, penalty2, penalty3, penalty4,
test.expectedPenalty1, test.expectedPenalty2, test.expectedPenalty3,
test.expectedPenalty4)
}
}
}

+ 3050
- 0
vendor/github.com/skip2/go-qrcode/version.go
File diff suppressed because it is too large
View File


+ 158
- 0
vendor/github.com/skip2/go-qrcode/version_test.go View File

@@ -0,0 +1,158 @@
// go-qrcode
// Copyright 2014 Tom Harwood

package qrcode

import (
"testing"

bitset "github.com/skip2/go-qrcode/bitset"
)

func TestFormatInfo(t *testing.T) {
tests := []struct {
level RecoveryLevel
maskPattern int

expected uint32
}{
{ // L=01 M=00 Q=11 H=10
Low,
1,
0x72f3,
},
{
Medium,
2,
0x5e7c,
},
{
High,
3,
0x3a06,
},
{
Highest,
4,
0x0762,
},
{
Low,
5,
0x6318,
},
{
Medium,
6,
0x4f97,
},
{
High,
7,
0x2bed,
},
}

for i, test := range tests {
v := getQRCodeVersion(test.level, 1)

result := v.formatInfo(test.maskPattern)

expected := bitset.New()
expected.AppendUint32(test.expected, formatInfoLengthBits)

if !expected.Equals(result) {
t.Errorf("formatInfo test #%d got %s, expected %s", i, result.String(),
expected.String())
}
}
}

func TestVersionInfo(t *testing.T) {
tests := []struct {
version int
expected uint32
}{
{
7,
0x007c94,
},
{
10,
0x00a4d3,
},
{
20,
0x0149a6,
},
{
30,
0x01ed75,
},
{
40,
0x028c69,
},
}

for i, test := range tests {
var v *qrCodeVersion

v = getQRCodeVersion(Low, test.version)

result := v.versionInfo()

expected := bitset.New()
expected.AppendUint32(test.expected, versionInfoLengthBits)

if !expected.Equals(result) {
t.Errorf("versionInfo test #%d got %s, expected %s", i, result.String(),
expected.String())
}
}
}

func TestNumBitsToPadToCodeoword(t *testing.T) {
tests := []struct {
level RecoveryLevel
version int

numDataBits int
expected int
}{
{
Low,
1,
0,
0,
}, {
Low,
1,
1,
7,
}, {
Low,
1,
7,
1,
}, {
Low,
1,
8,
0,
},
}

for i, test := range tests {
var v *qrCodeVersion

v = getQRCodeVersion(test.level, test.version)

result := v.numBitsToPadToCodeword(test.numDataBits)

if result != test.expected {
t.Errorf("numBitsToPadToCodeword test %d (version=%d numDataBits=%d), got %d, expected %d",
i, test.version, test.numDataBits, result, test.expected)
}
}
}

Loading…
Cancel
Save