mirror of https://github.com/perkeep/perkeep.git
vendor: update qr package
to Rev 48b2ede4844e13f1a2b7ce4d2529c9af7e359fc5 The qr package has moved from code.google.com/p/rsc/qr to it's new canonical home at rsc.io/qr Change-Id: Ibb04ee7e83c9707ff253a91abb4f60f9b150d61c
This commit is contained in:
parent
3654a0f623
commit
141328c697
|
@ -49,9 +49,9 @@ import (
|
|||
"camlistore.org/pkg/types/camtypes"
|
||||
uistatic "camlistore.org/server/camlistored/ui"
|
||||
closurestatic "camlistore.org/server/camlistored/ui/closure"
|
||||
"code.google.com/p/rsc/qr"
|
||||
"go4.org/jsonconfig"
|
||||
"go4.org/syncutil"
|
||||
"rsc.io/qr"
|
||||
)
|
||||
|
||||
var (
|
||||
|
|
|
@ -0,0 +1,27 @@
|
|||
Copyright (c) 2009 The Go Authors. All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are
|
||||
met:
|
||||
|
||||
* Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above
|
||||
copyright notice, this list of conditions and the following disclaimer
|
||||
in the documentation and/or other materials provided with the
|
||||
distribution.
|
||||
* Neither the name of Google Inc. nor the names of its
|
||||
contributors may be used to endorse or promote products derived from
|
||||
this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
@ -0,0 +1,3 @@
|
|||
Basic QR encoder.
|
||||
|
||||
go get [-u] rsc.io/qr
|
|
@ -10,7 +10,7 @@ import (
|
|||
"strconv"
|
||||
"strings"
|
||||
|
||||
"code.google.com/p/rsc/gf256"
|
||||
"rsc.io/qr/gf256"
|
||||
)
|
||||
|
||||
// Field is the field for QR error correction.
|
|
@ -0,0 +1,133 @@
|
|||
// Copyright 2011 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package coding
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"testing"
|
||||
|
||||
"rsc.io/qr/gf256"
|
||||
"rsc.io/qr/libqrencode"
|
||||
)
|
||||
|
||||
func test(t *testing.T, v Version, l Level, text ...Encoding) bool {
|
||||
s := ""
|
||||
ty := libqrencode.EightBit
|
||||
switch x := text[0].(type) {
|
||||
case String:
|
||||
s = string(x)
|
||||
case Alpha:
|
||||
s = string(x)
|
||||
ty = libqrencode.Alphanumeric
|
||||
case Num:
|
||||
s = string(x)
|
||||
ty = libqrencode.Numeric
|
||||
}
|
||||
key, err := libqrencode.Encode(libqrencode.Version(v), libqrencode.Level(l), ty, s)
|
||||
if err != nil {
|
||||
t.Errorf("libqrencode.Encode(%v, %v, %d, %#q): %v", v, l, ty, s, err)
|
||||
return false
|
||||
}
|
||||
mask := (^key.Pixel[8][2]&1)<<2 | (key.Pixel[8][3]&1)<<1 | (^key.Pixel[8][4] & 1)
|
||||
p, err := NewPlan(v, l, Mask(mask))
|
||||
if err != nil {
|
||||
t.Errorf("NewPlan(%v, L, %d): %v", v, err, mask)
|
||||
return false
|
||||
}
|
||||
if len(p.Pixel) != len(key.Pixel) {
|
||||
t.Errorf("%v: NewPlan uses %dx%d, libqrencode uses %dx%d", v, len(p.Pixel), len(p.Pixel), len(key.Pixel), len(key.Pixel))
|
||||
return false
|
||||
}
|
||||
c, err := p.Encode(text...)
|
||||
if err != nil {
|
||||
t.Errorf("Encode: %v", err)
|
||||
return false
|
||||
}
|
||||
badpix := 0
|
||||
Pixel:
|
||||
for y, prow := range p.Pixel {
|
||||
for x, pix := range prow {
|
||||
pix &^= Black
|
||||
if c.Black(x, y) {
|
||||
pix |= Black
|
||||
}
|
||||
|
||||
keypix := key.Pixel[y][x]
|
||||
want := Pixel(0)
|
||||
switch {
|
||||
case keypix&libqrencode.Finder != 0:
|
||||
want = Position.Pixel()
|
||||
case keypix&libqrencode.Alignment != 0:
|
||||
want = Alignment.Pixel()
|
||||
case keypix&libqrencode.Timing != 0:
|
||||
want = Timing.Pixel()
|
||||
case keypix&libqrencode.Format != 0:
|
||||
want = Format.Pixel()
|
||||
want |= OffsetPixel(pix.Offset()) // sic
|
||||
want |= pix & Invert
|
||||
case keypix&libqrencode.PVersion != 0:
|
||||
want = PVersion.Pixel()
|
||||
case keypix&libqrencode.DataECC != 0:
|
||||
if pix.Role() == Check || pix.Role() == Extra {
|
||||
want = pix.Role().Pixel()
|
||||
} else {
|
||||
want = Data.Pixel()
|
||||
}
|
||||
want |= OffsetPixel(pix.Offset())
|
||||
want |= pix & Invert
|
||||
default:
|
||||
want = Unused.Pixel()
|
||||
}
|
||||
if keypix&libqrencode.Black != 0 {
|
||||
want |= Black
|
||||
}
|
||||
if pix != want {
|
||||
t.Errorf("%v/%v: Pixel[%d][%d] = %v, want %v %#x", v, mask, y, x, pix, want, keypix)
|
||||
if badpix++; badpix >= 100 {
|
||||
t.Errorf("stopping after %d bad pixels", badpix)
|
||||
break Pixel
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return badpix == 0
|
||||
}
|
||||
|
||||
var input = []Encoding{
|
||||
String("hello"),
|
||||
Num("1"),
|
||||
Num("12"),
|
||||
Num("123"),
|
||||
Alpha("AB"),
|
||||
Alpha("ABC"),
|
||||
}
|
||||
|
||||
func TestVersion(t *testing.T) {
|
||||
badvers := 0
|
||||
Version:
|
||||
for v := Version(1); v <= 40; v++ {
|
||||
for l := L; l <= H; l++ {
|
||||
for _, in := range input {
|
||||
if !test(t, v, l, in) {
|
||||
if badvers++; badvers >= 10 {
|
||||
t.Errorf("stopping after %d bad versions", badvers)
|
||||
break Version
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestEncode(t *testing.T) {
|
||||
data := []byte{0x10, 0x20, 0x0c, 0x56, 0x61, 0x80, 0xec, 0x11, 0xec, 0x11, 0xec, 0x11, 0xec, 0x11, 0xec, 0x11}
|
||||
check := []byte{0xa5, 0x24, 0xd4, 0xc1, 0xed, 0x36, 0xc7, 0x87, 0x2c, 0x55}
|
||||
rs := gf256.NewRSEncoder(Field, len(check))
|
||||
out := make([]byte, len(check))
|
||||
rs.ECC(data, out)
|
||||
if !bytes.Equal(out, check) {
|
||||
t.Errorf("have %x want %x", out, check)
|
||||
}
|
||||
}
|
|
@ -109,7 +109,7 @@ func (f *Field) Add(x, y byte) byte {
|
|||
return x ^ y
|
||||
}
|
||||
|
||||
// Exp returns the the base-α exponential of e in the field.
|
||||
// Exp returns the base-α exponential of e in the field.
|
||||
// If e < 0, Exp returns 0.
|
||||
func (f *Field) Exp(e int) byte {
|
||||
if e < 0 {
|
|
@ -0,0 +1,149 @@
|
|||
// Copyright 2011 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
// Package libqrencode wraps the C libqrencode library.
|
||||
// The qr package (in this package's parent directory)
|
||||
// does not use any C wrapping. This code is here only
|
||||
// for use during that package's tests.
|
||||
package libqrencode
|
||||
|
||||
/*
|
||||
#cgo LDFLAGS: -lqrencode
|
||||
#include <qrencode.h>
|
||||
*/
|
||||
import "C"
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"image"
|
||||
"image/color"
|
||||
"unsafe"
|
||||
)
|
||||
|
||||
type Version int
|
||||
|
||||
type Mode int
|
||||
|
||||
const (
|
||||
Numeric Mode = C.QR_MODE_NUM
|
||||
Alphanumeric Mode = C.QR_MODE_AN
|
||||
EightBit Mode = C.QR_MODE_8
|
||||
)
|
||||
|
||||
type Level int
|
||||
|
||||
const (
|
||||
L Level = C.QR_ECLEVEL_L
|
||||
M Level = C.QR_ECLEVEL_M
|
||||
Q Level = C.QR_ECLEVEL_Q
|
||||
H Level = C.QR_ECLEVEL_H
|
||||
)
|
||||
|
||||
type Pixel int
|
||||
|
||||
const (
|
||||
Black Pixel = 1 << iota
|
||||
DataECC
|
||||
Format
|
||||
PVersion
|
||||
Timing
|
||||
Alignment
|
||||
Finder
|
||||
NonData
|
||||
)
|
||||
|
||||
type Code struct {
|
||||
Version int
|
||||
Width int
|
||||
Pixel [][]Pixel
|
||||
Scale int
|
||||
}
|
||||
|
||||
func (*Code) ColorModel() color.Model {
|
||||
return color.RGBAModel
|
||||
}
|
||||
|
||||
func (c *Code) Bounds() image.Rectangle {
|
||||
d := (c.Width + 8) * c.Scale
|
||||
return image.Rect(0, 0, d, d)
|
||||
}
|
||||
|
||||
var (
|
||||
white color.Color = color.RGBA{0xFF, 0xFF, 0xFF, 0xFF}
|
||||
black color.Color = color.RGBA{0x00, 0x00, 0x00, 0xFF}
|
||||
blue color.Color = color.RGBA{0x00, 0x00, 0x80, 0xFF}
|
||||
red color.Color = color.RGBA{0xFF, 0x40, 0x40, 0xFF}
|
||||
yellow color.Color = color.RGBA{0xFF, 0xFF, 0x00, 0xFF}
|
||||
gray color.Color = color.RGBA{0x80, 0x80, 0x80, 0xFF}
|
||||
green color.Color = color.RGBA{0x22, 0x8B, 0x22, 0xFF}
|
||||
)
|
||||
|
||||
func (c *Code) At(x, y int) color.Color {
|
||||
x = x/c.Scale - 4
|
||||
y = y/c.Scale - 4
|
||||
if 0 <= x && x < c.Width && 0 <= y && y < c.Width {
|
||||
switch p := c.Pixel[y][x]; {
|
||||
case p&Black == 0:
|
||||
// nothing
|
||||
case p&DataECC != 0:
|
||||
return black
|
||||
case p&Format != 0:
|
||||
return blue
|
||||
case p&PVersion != 0:
|
||||
return red
|
||||
case p&Timing != 0:
|
||||
return yellow
|
||||
case p&Alignment != 0:
|
||||
return gray
|
||||
case p&Finder != 0:
|
||||
return green
|
||||
}
|
||||
}
|
||||
return white
|
||||
}
|
||||
|
||||
type Chunk struct {
|
||||
Mode Mode
|
||||
Text string
|
||||
}
|
||||
|
||||
func Encode(version Version, level Level, mode Mode, text string) (*Code, error) {
|
||||
return EncodeChunk(version, level, Chunk{mode, text})
|
||||
}
|
||||
|
||||
func EncodeChunk(version Version, level Level, chunk ...Chunk) (*Code, error) {
|
||||
qi, err := C.QRinput_new2(C.int(version), C.QRecLevel(level))
|
||||
if qi == nil {
|
||||
return nil, fmt.Errorf("QRinput_new2: %v", err)
|
||||
}
|
||||
defer C.QRinput_free(qi)
|
||||
for _, ch := range chunk {
|
||||
data := []byte(ch.Text)
|
||||
n, err := C.QRinput_append(qi, C.QRencodeMode(ch.Mode), C.int(len(data)), (*C.uchar)(&data[0]))
|
||||
if n < 0 {
|
||||
return nil, fmt.Errorf("QRinput_append %q: %v", data, err)
|
||||
}
|
||||
}
|
||||
|
||||
qc, err := C.QRcode_encodeInput(qi)
|
||||
if qc == nil {
|
||||
return nil, fmt.Errorf("QRinput_encodeInput: %v", err)
|
||||
}
|
||||
|
||||
c := &Code{
|
||||
Version: int(qc.version),
|
||||
Width: int(qc.width),
|
||||
Scale: 16,
|
||||
}
|
||||
pix := make([]Pixel, c.Width*c.Width)
|
||||
cdat := (*[1000 * 1000]byte)(unsafe.Pointer(qc.data))[:len(pix)]
|
||||
for i := range pix {
|
||||
pix[i] = Pixel(cdat[i])
|
||||
}
|
||||
c.Pixel = make([][]Pixel, c.Width)
|
||||
for i := range c.Pixel {
|
||||
c.Pixel[i] = pix[i*c.Width : (i+1)*c.Width]
|
||||
}
|
||||
return c, nil
|
||||
}
|
|
@ -12,7 +12,7 @@ import (
|
|||
"image"
|
||||
"image/color"
|
||||
|
||||
"code.google.com/p/rsc/qr/coding"
|
||||
"rsc.io/qr/coding"
|
||||
)
|
||||
|
||||
// A Level denotes a QR error correction level.
|
Loading…
Reference in New Issue