summaryrefslogtreecommitdiffstats
path: root/vendor/github.com/mattermost/rsc/qr
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/github.com/mattermost/rsc/qr')
-rw-r--r--vendor/github.com/mattermost/rsc/qr/coding/qr_test.go133
-rw-r--r--vendor/github.com/mattermost/rsc/qr/libqrencode/Makefile4
-rw-r--r--vendor/github.com/mattermost/rsc/qr/libqrencode/qrencode.go149
-rw-r--r--vendor/github.com/mattermost/rsc/qr/png_test.go73
-rw-r--r--vendor/github.com/mattermost/rsc/qr/web/pic.go506
-rw-r--r--vendor/github.com/mattermost/rsc/qr/web/play.go1118
-rw-r--r--vendor/github.com/mattermost/rsc/qr/web/resize/resize.go152
7 files changed, 0 insertions, 2135 deletions
diff --git a/vendor/github.com/mattermost/rsc/qr/coding/qr_test.go b/vendor/github.com/mattermost/rsc/qr/coding/qr_test.go
deleted file mode 100644
index b8199bb51..000000000
--- a/vendor/github.com/mattermost/rsc/qr/coding/qr_test.go
+++ /dev/null
@@ -1,133 +0,0 @@
-// 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"
-
- "github.com/mattermost/rsc/gf256"
- "github.com/mattermost/rsc/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)
- }
-}
diff --git a/vendor/github.com/mattermost/rsc/qr/libqrencode/Makefile b/vendor/github.com/mattermost/rsc/qr/libqrencode/Makefile
deleted file mode 100644
index 4c9591462..000000000
--- a/vendor/github.com/mattermost/rsc/qr/libqrencode/Makefile
+++ /dev/null
@@ -1,4 +0,0 @@
-include $(GOROOT)/src/Make.inc
-TARG=rsc.googlecode.com/hg/qr/libqrencode
-CGOFILES=qrencode.go
-include $(GOROOT)/src/Make.pkg
diff --git a/vendor/github.com/mattermost/rsc/qr/libqrencode/qrencode.go b/vendor/github.com/mattermost/rsc/qr/libqrencode/qrencode.go
deleted file mode 100644
index f4ce3ffb6..000000000
--- a/vendor/github.com/mattermost/rsc/qr/libqrencode/qrencode.go
+++ /dev/null
@@ -1,149 +0,0 @@
-// 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
-}
diff --git a/vendor/github.com/mattermost/rsc/qr/png_test.go b/vendor/github.com/mattermost/rsc/qr/png_test.go
deleted file mode 100644
index 27a622924..000000000
--- a/vendor/github.com/mattermost/rsc/qr/png_test.go
+++ /dev/null
@@ -1,73 +0,0 @@
-// Copyright 2011 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package qr
-
-import (
- "bytes"
- "image"
- "image/color"
- "image/png"
- "io/ioutil"
- "testing"
-)
-
-func TestPNG(t *testing.T) {
- c, err := Encode("hello, world", L)
- if err != nil {
- t.Fatal(err)
- }
- pngdat := c.PNG()
- if true {
- ioutil.WriteFile("x.png", pngdat, 0666)
- }
- m, err := png.Decode(bytes.NewBuffer(pngdat))
- if err != nil {
- t.Fatal(err)
- }
- gm := m.(*image.Gray)
-
- scale := c.Scale
- siz := c.Size
- nbad := 0
- for y := 0; y < scale*(8+siz); y++ {
- for x := 0; x < scale*(8+siz); x++ {
- v := byte(255)
- if c.Black(x/scale-4, y/scale-4) {
- v = 0
- }
- if gv := gm.At(x, y).(color.Gray).Y; gv != v {
- t.Errorf("%d,%d = %d, want %d", x, y, gv, v)
- if nbad++; nbad >= 20 {
- t.Fatalf("too many bad pixels")
- }
- }
- }
- }
-}
-
-func BenchmarkPNG(b *testing.B) {
- c, err := Encode("0123456789012345678901234567890123456789", L)
- if err != nil {
- panic(err)
- }
- var bytes []byte
- for i := 0; i < b.N; i++ {
- bytes = c.PNG()
- }
- b.SetBytes(int64(len(bytes)))
-}
-
-func BenchmarkImagePNG(b *testing.B) {
- c, err := Encode("0123456789012345678901234567890123456789", L)
- if err != nil {
- panic(err)
- }
- var buf bytes.Buffer
- for i := 0; i < b.N; i++ {
- buf.Reset()
- png.Encode(&buf, c.Image())
- }
- b.SetBytes(int64(buf.Len()))
-}
diff --git a/vendor/github.com/mattermost/rsc/qr/web/pic.go b/vendor/github.com/mattermost/rsc/qr/web/pic.go
deleted file mode 100644
index 6baef94d2..000000000
--- a/vendor/github.com/mattermost/rsc/qr/web/pic.go
+++ /dev/null
@@ -1,506 +0,0 @@
-package web
-
-import (
- "bytes"
- "fmt"
- "image"
- "image/color"
- "image/draw"
- "image/png"
- "net/http"
- "strconv"
- "strings"
-
- "code.google.com/p/freetype-go/freetype"
- "github.com/mattermost/rsc/appfs/fs"
- "github.com/mattermost/rsc/qr"
- "github.com/mattermost/rsc/qr/coding"
-)
-
-func makeImage(req *http.Request, caption, font string, pt, size, border, scale int, f func(x, y int) uint32) *image.RGBA {
- d := (size + 2*border) * scale
- csize := 0
- if caption != "" {
- if pt == 0 {
- pt = 11
- }
- csize = pt * 2
- }
- c := image.NewRGBA(image.Rect(0, 0, d, d+csize))
-
- // white
- u := &image.Uniform{C: color.White}
- draw.Draw(c, c.Bounds(), u, image.ZP, draw.Src)
-
- for y := 0; y < size; y++ {
- for x := 0; x < size; x++ {
- r := image.Rect((x+border)*scale, (y+border)*scale, (x+border+1)*scale, (y+border+1)*scale)
- rgba := f(x, y)
- u.C = color.RGBA{byte(rgba >> 24), byte(rgba >> 16), byte(rgba >> 8), byte(rgba)}
- draw.Draw(c, r, u, image.ZP, draw.Src)
- }
- }
-
- if csize != 0 {
- if font == "" {
- font = "data/luxisr.ttf"
- }
- ctxt := fs.NewContext(req)
- dat, _, err := ctxt.Read(font)
- if err != nil {
- panic(err)
- }
- tfont, err := freetype.ParseFont(dat)
- if err != nil {
- panic(err)
- }
- ft := freetype.NewContext()
- ft.SetDst(c)
- ft.SetDPI(100)
- ft.SetFont(tfont)
- ft.SetFontSize(float64(pt))
- ft.SetSrc(image.NewUniform(color.Black))
- ft.SetClip(image.Rect(0, 0, 0, 0))
- wid, err := ft.DrawString(caption, freetype.Pt(0, 0))
- if err != nil {
- panic(err)
- }
- p := freetype.Pt(d, d+3*pt/2)
- p.X -= wid.X
- p.X /= 2
- ft.SetClip(c.Bounds())
- ft.DrawString(caption, p)
- }
-
- return c
-}
-
-func makeFrame(req *http.Request, font string, pt, vers, l, scale, dots int) image.Image {
- lev := coding.Level(l)
- p, err := coding.NewPlan(coding.Version(vers), lev, 0)
- if err != nil {
- panic(err)
- }
-
- nd := p.DataBytes / p.Blocks
- nc := p.CheckBytes / p.Blocks
- extra := p.DataBytes - nd*p.Blocks
-
- cap := fmt.Sprintf("QR v%d, %s", vers, lev)
- if dots > 0 {
- cap = fmt.Sprintf("QR v%d order, from bottom right", vers)
- }
- m := makeImage(req, cap, font, pt, len(p.Pixel), 0, scale, func(x, y int) uint32 {
- pix := p.Pixel[y][x]
- switch pix.Role() {
- case coding.Data:
- if dots > 0 {
- return 0xffffffff
- }
- off := int(pix.Offset() / 8)
- nd := nd
- var i int
- for i = 0; i < p.Blocks; i++ {
- if i == extra {
- nd++
- }
- if off < nd {
- break
- }
- off -= nd
- }
- return blockColors[i%len(blockColors)]
- case coding.Check:
- if dots > 0 {
- return 0xffffffff
- }
- i := (int(pix.Offset()/8) - p.DataBytes) / nc
- return dark(blockColors[i%len(blockColors)])
- }
- if pix&coding.Black != 0 {
- return 0x000000ff
- }
- return 0xffffffff
- })
-
- if dots > 0 {
- b := m.Bounds()
- for y := 0; y <= len(p.Pixel); y++ {
- for x := 0; x < b.Dx(); x++ {
- m.SetRGBA(x, y*scale-(y/len(p.Pixel)), color.RGBA{127, 127, 127, 255})
- }
- }
- for x := 0; x <= len(p.Pixel); x++ {
- for y := 0; y < b.Dx(); y++ {
- m.SetRGBA(x*scale-(x/len(p.Pixel)), y, color.RGBA{127, 127, 127, 255})
- }
- }
- order := make([]image.Point, (p.DataBytes+p.CheckBytes)*8+1)
- for y, row := range p.Pixel {
- for x, pix := range row {
- if r := pix.Role(); r != coding.Data && r != coding.Check {
- continue
- }
- // draw.Draw(m, m.Bounds().Add(image.Pt(x*scale, y*scale)), dot, image.ZP, draw.Over)
- order[pix.Offset()] = image.Point{x*scale + scale/2, y*scale + scale/2}
- }
- }
-
- for mode := 0; mode < 2; mode++ {
- for i, p := range order {
- q := order[i+1]
- if q.X == 0 {
- break
- }
- line(m, p, q, mode)
- }
- }
- }
- return m
-}
-
-func line(m *image.RGBA, p, q image.Point, mode int) {
- x := 0
- y := 0
- dx := q.X - p.X
- dy := q.Y - p.Y
- xsign := +1
- ysign := +1
- if dx < 0 {
- xsign = -1
- dx = -dx
- }
- if dy < 0 {
- ysign = -1
- dy = -dy
- }
- pt := func() {
- switch mode {
- case 0:
- for dx := -2; dx <= 2; dx++ {
- for dy := -2; dy <= 2; dy++ {
- if dy*dx <= -4 || dy*dx >= 4 {
- continue
- }
- m.SetRGBA(p.X+x*xsign+dx, p.Y+y*ysign+dy, color.RGBA{255, 192, 192, 255})
- }
- }
-
- case 1:
- m.SetRGBA(p.X+x*xsign, p.Y+y*ysign, color.RGBA{128, 0, 0, 255})
- }
- }
- if dx > dy {
- for x < dx || y < dy {
- pt()
- x++
- if float64(x)*float64(dy)/float64(dx)-float64(y) > 0.5 {
- y++
- }
- }
- } else {
- for x < dx || y < dy {
- pt()
- y++
- if float64(y)*float64(dx)/float64(dy)-float64(x) > 0.5 {
- x++
- }
- }
- }
- pt()
-}
-
-func pngEncode(c image.Image) []byte {
- var b bytes.Buffer
- png.Encode(&b, c)
- return b.Bytes()
-}
-
-// Frame handles a request for a single QR frame.
-func Frame(w http.ResponseWriter, req *http.Request) {
- arg := func(s string) int { x, _ := strconv.Atoi(req.FormValue(s)); return x }
- v := arg("v")
- scale := arg("scale")
- if scale == 0 {
- scale = 8
- }
-
- w.Header().Set("Cache-Control", "public, max-age=3600")
- w.Write(pngEncode(makeFrame(req, req.FormValue("font"), arg("pt"), v, arg("l"), scale, arg("dots"))))
-}
-
-// Frames handles a request for multiple QR frames.
-func Frames(w http.ResponseWriter, req *http.Request) {
- vs := strings.Split(req.FormValue("v"), ",")
-
- arg := func(s string) int { x, _ := strconv.Atoi(req.FormValue(s)); return x }
- scale := arg("scale")
- if scale == 0 {
- scale = 8
- }
- font := req.FormValue("font")
- pt := arg("pt")
- dots := arg("dots")
-
- var images []image.Image
- l := arg("l")
- for _, v := range vs {
- l := l
- if i := strings.Index(v, "."); i >= 0 {
- l, _ = strconv.Atoi(v[i+1:])
- v = v[:i]
- }
- vv, _ := strconv.Atoi(v)
- images = append(images, makeFrame(req, font, pt, vv, l, scale, dots))
- }
-
- b := images[len(images)-1].Bounds()
-
- dx := arg("dx")
- if dx == 0 {
- dx = b.Dx()
- }
- x, y := 0, 0
- xmax := 0
- sep := arg("sep")
- if sep == 0 {
- sep = 10
- }
- var points []image.Point
- for i, m := range images {
- if x > 0 {
- x += sep
- }
- if x > 0 && x+m.Bounds().Dx() > dx {
- y += sep + images[i-1].Bounds().Dy()
- x = 0
- }
- points = append(points, image.Point{x, y})
- x += m.Bounds().Dx()
- if x > xmax {
- xmax = x
- }
-
- }
-
- c := image.NewRGBA(image.Rect(0, 0, xmax, y+b.Dy()))
- for i, m := range images {
- draw.Draw(c, c.Bounds().Add(points[i]), m, image.ZP, draw.Src)
- }
-
- w.Header().Set("Cache-Control", "public, max-age=3600")
- w.Write(pngEncode(c))
-}
-
-// Mask handles a request for a single QR mask.
-func Mask(w http.ResponseWriter, req *http.Request) {
- arg := func(s string) int { x, _ := strconv.Atoi(req.FormValue(s)); return x }
- v := arg("v")
- m := arg("m")
- scale := arg("scale")
- if scale == 0 {
- scale = 8
- }
-
- w.Header().Set("Cache-Control", "public, max-age=3600")
- w.Write(pngEncode(makeMask(req, req.FormValue("font"), arg("pt"), v, m, scale)))
-}
-
-// Masks handles a request for multiple QR masks.
-func Masks(w http.ResponseWriter, req *http.Request) {
- arg := func(s string) int { x, _ := strconv.Atoi(req.FormValue(s)); return x }
- v := arg("v")
- scale := arg("scale")
- if scale == 0 {
- scale = 8
- }
- font := req.FormValue("font")
- pt := arg("pt")
- var mm []image.Image
- for m := 0; m < 8; m++ {
- mm = append(mm, makeMask(req, font, pt, v, m, scale))
- }
- dx := mm[0].Bounds().Dx()
- dy := mm[0].Bounds().Dy()
-
- sep := arg("sep")
- if sep == 0 {
- sep = 10
- }
- c := image.NewRGBA(image.Rect(0, 0, (dx+sep)*4-sep, (dy+sep)*2-sep))
- for m := 0; m < 8; m++ {
- x := (m % 4) * (dx + sep)
- y := (m / 4) * (dy + sep)
- draw.Draw(c, c.Bounds().Add(image.Pt(x, y)), mm[m], image.ZP, draw.Src)
- }
-
- w.Header().Set("Cache-Control", "public, max-age=3600")
- w.Write(pngEncode(c))
-}
-
-var maskName = []string{
- "(x+y) % 2",
- "y % 2",
- "x % 3",
- "(x+y) % 3",
- "(y/2 + x/3) % 2",
- "xy%2 + xy%3",
- "(xy%2 + xy%3) % 2",
- "(xy%3 + (x+y)%2) % 2",
-}
-
-func makeMask(req *http.Request, font string, pt int, vers, mask, scale int) image.Image {
- p, err := coding.NewPlan(coding.Version(vers), coding.L, coding.Mask(mask))
- if err != nil {
- panic(err)
- }
- m := makeImage(req, maskName[mask], font, pt, len(p.Pixel), 0, scale, func(x, y int) uint32 {
- pix := p.Pixel[y][x]
- switch pix.Role() {
- case coding.Data, coding.Check:
- if pix&coding.Invert != 0 {
- return 0x000000ff
- }
- }
- return 0xffffffff
- })
- return m
-}
-
-var blockColors = []uint32{
- 0x7777ffff,
- 0xffff77ff,
- 0xff7777ff,
- 0x77ffffff,
- 0x1e90ffff,
- 0xffffe0ff,
- 0x8b6969ff,
- 0x77ff77ff,
- 0x9b30ffff,
- 0x00bfffff,
- 0x90e890ff,
- 0xfff68fff,
- 0xffec8bff,
- 0xffa07aff,
- 0xffa54fff,
- 0xeee8aaff,
- 0x98fb98ff,
- 0xbfbfbfff,
- 0x54ff9fff,
- 0xffaeb9ff,
- 0xb23aeeff,
- 0xbbffffff,
- 0x7fffd4ff,
- 0xff7a7aff,
- 0x00007fff,
-}
-
-func dark(x uint32) uint32 {
- r, g, b, a := byte(x>>24), byte(x>>16), byte(x>>8), byte(x)
- r = r/2 + r/4
- g = g/2 + g/4
- b = b/2 + b/4
- return uint32(r)<<24 | uint32(g)<<16 | uint32(b)<<8 | uint32(a)
-}
-
-func clamp(x int) byte {
- if x < 0 {
- return 0
- }
- if x > 255 {
- return 255
- }
- return byte(x)
-}
-
-func max(x, y int) int {
- if x > y {
- return x
- }
- return y
-}
-
-// Arrow handles a request for an arrow pointing in a given direction.
-func Arrow(w http.ResponseWriter, req *http.Request) {
- arg := func(s string) int { x, _ := strconv.Atoi(req.FormValue(s)); return x }
- dir := arg("dir")
- size := arg("size")
- if size == 0 {
- size = 50
- }
- del := size / 10
-
- m := image.NewRGBA(image.Rect(0, 0, size, size))
-
- if dir == 4 {
- draw.Draw(m, m.Bounds(), image.Black, image.ZP, draw.Src)
- draw.Draw(m, image.Rect(5, 5, size-5, size-5), image.White, image.ZP, draw.Src)
- }
-
- pt := func(x, y int, c color.RGBA) {
- switch dir {
- case 0:
- m.SetRGBA(x, y, c)
- case 1:
- m.SetRGBA(y, size-1-x, c)
- case 2:
- m.SetRGBA(size-1-x, size-1-y, c)
- case 3:
- m.SetRGBA(size-1-y, x, c)
- }
- }
-
- for y := 0; y < size/2; y++ {
- for x := 0; x < del && x < y; x++ {
- pt(x, y, color.RGBA{0, 0, 0, 255})
- }
- for x := del; x < y-del; x++ {
- pt(x, y, color.RGBA{128, 128, 255, 255})
- }
- for x := max(y-del, 0); x <= y; x++ {
- pt(x, y, color.RGBA{0, 0, 0, 255})
- }
- }
- for y := size / 2; y < size; y++ {
- for x := 0; x < del && x < size-1-y; x++ {
- pt(x, y, color.RGBA{0, 0, 0, 255})
- }
- for x := del; x < size-1-y-del; x++ {
- pt(x, y, color.RGBA{128, 128, 192, 255})
- }
- for x := max(size-1-y-del, 0); x <= size-1-y; x++ {
- pt(x, y, color.RGBA{0, 0, 0, 255})
- }
- }
-
- w.Header().Set("Cache-Control", "public, max-age=3600")
- w.Write(pngEncode(m))
-}
-
-// Encode encodes a string using the given version, level, and mask.
-func Encode(w http.ResponseWriter, req *http.Request) {
- val := func(s string) int {
- v, _ := strconv.Atoi(req.FormValue(s))
- return v
- }
-
- l := coding.Level(val("l"))
- v := coding.Version(val("v"))
- enc := coding.String(req.FormValue("t"))
- m := coding.Mask(val("m"))
-
- p, err := coding.NewPlan(v, l, m)
- if err != nil {
- panic(err)
- }
- cc, err := p.Encode(enc)
- if err != nil {
- panic(err)
- }
-
- c := &qr.Code{Bitmap: cc.Bitmap, Size: cc.Size, Stride: cc.Stride, Scale: 8}
- w.Header().Set("Content-Type", "image/png")
- w.Header().Set("Cache-Control", "public, max-age=3600")
- w.Write(c.PNG())
-}
-
diff --git a/vendor/github.com/mattermost/rsc/qr/web/play.go b/vendor/github.com/mattermost/rsc/qr/web/play.go
deleted file mode 100644
index 120f50b81..000000000
--- a/vendor/github.com/mattermost/rsc/qr/web/play.go
+++ /dev/null
@@ -1,1118 +0,0 @@
-// Copyright 2012 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.
-
-/*
-QR data layout
-
-qr/
- upload/
- id.png
- id.fix
- flag/
- id
-
-*/
-// TODO: Random seed taken from GET for caching, repeatability.
-// TODO: Flag for abuse button + some kind of dashboard.
-// TODO: +1 button on web page? permalink?
-// TODO: Flag for abuse button on permalinks too?
-// TODO: Make the page prettier.
-// TODO: Cache headers.
-
-package web
-
-import (
- "bytes"
- "crypto/md5"
- "encoding/base64"
- "encoding/json"
- "fmt"
- "html/template"
- "image"
- "image/color"
- _ "image/gif"
- _ "image/jpeg"
- "image/png"
- "io"
- "math/rand"
- "net/http"
- "net/url"
- "os"
- "sort"
- "strconv"
- "strings"
- "time"
-
- "github.com/mattermost/rsc/appfs/fs"
- "github.com/mattermost/rsc/gf256"
- "github.com/mattermost/rsc/qr"
- "github.com/mattermost/rsc/qr/coding"
- "github.com/mattermost/rsc/qr/web/resize"
-)
-
-func runTemplate(c *fs.Context, w http.ResponseWriter, name string, data interface{}) {
- t := template.New("main")
-
- main, _, err := c.Read(name)
- if err != nil {
- panic(err)
- }
- style, _, _ := c.Read("style.html")
- main = append(main, style...)
- _, err = t.Parse(string(main))
- if err != nil {
- panic(err)
- }
-
- var buf bytes.Buffer
- if err := t.Execute(&buf, &data); err != nil {
- panic(err)
- }
- w.Write(buf.Bytes())
-}
-
-func isImgName(s string) bool {
- if len(s) != 32 {
- return false
- }
- for i := 0; i < len(s); i++ {
- if '0' <= s[i] && s[i] <= '9' || 'a' <= s[i] && s[i] <= 'f' {
- continue
- }
- return false
- }
- return true
-}
-
-func isTagName(s string) bool {
- if len(s) != 16 {
- return false
- }
- for i := 0; i < len(s); i++ {
- if '0' <= s[i] && s[i] <= '9' || 'a' <= s[i] && s[i] <= 'f' {
- continue
- }
- return false
- }
- return true
-}
-
-// Draw is the handler for drawing a QR code.
-func Draw(w http.ResponseWriter, req *http.Request) {
- ctxt := fs.NewContext(req)
-
- url := req.FormValue("url")
- if url == "" {
- url = "http://swtch.com/qr"
- }
- if req.FormValue("upload") == "1" {
- upload(w, req, url)
- return
- }
-
- t0 := time.Now()
- img := req.FormValue("i")
- if !isImgName(img) {
- img = "pjw"
- }
- if req.FormValue("show") == "png" {
- i := loadSize(ctxt, img, 48)
- var buf bytes.Buffer
- png.Encode(&buf, i)
- w.Write(buf.Bytes())
- return
- }
- if req.FormValue("flag") == "1" {
- flag(w, req, img, ctxt)
- return
- }
- if req.FormValue("x") == "" {
- var data = struct {
- Name string
- URL string
- }{
- Name: img,
- URL: url,
- }
- runTemplate(ctxt, w, "qr/main.html", &data)
- return
- }
-
- arg := func(s string) int { x, _ := strconv.Atoi(req.FormValue(s)); return x }
- targ := makeTarg(ctxt, img, 17+4*arg("v")+arg("z"))
-
- m := &Image{
- Name: img,
- Dx: arg("x"),
- Dy: arg("y"),
- URL: req.FormValue("u"),
- Version: arg("v"),
- Mask: arg("m"),
- RandControl: arg("r") > 0,
- Dither: arg("i") > 0,
- OnlyDataBits: arg("d") > 0,
- SaveControl: arg("c") > 0,
- Scale: arg("scale"),
- Target: targ,
- Seed: int64(arg("s")),
- Rotation: arg("o"),
- Size: arg("z"),
- }
- if m.Version > 8 {
- m.Version = 8
- }
-
- if m.Scale == 0 {
- if arg("l") > 1 {
- m.Scale = 8
- } else {
- m.Scale = 4
- }
- }
- if m.Version >= 12 && m.Scale >= 4 {
- m.Scale /= 2
- }
-
- if arg("l") == 1 {
- data, err := json.Marshal(m)
- if err != nil {
- panic(err)
- }
- h := md5.New()
- h.Write(data)
- tag := fmt.Sprintf("%x", h.Sum(nil))[:16]
- if err := ctxt.Write("qrsave/"+tag, data); err != nil {
- panic(err)
- }
- http.Redirect(w, req, "/qr/show/" + tag, http.StatusTemporaryRedirect)
- return
- }
-
- if err := m.Encode(req); err != nil {
- fmt.Fprintf(w, "%s\n", err)
- return
- }
-
- var dat []byte
- switch {
- case m.SaveControl:
- dat = m.Control
- default:
- dat = m.Code.PNG()
- }
-
- if arg("l") > 0 {
- w.Header().Set("Content-Type", "image/png")
- w.Write(dat)
- return
- }
-
- w.Header().Set("Content-Type", "text/html; charset=utf-8")
- fmt.Fprint(w, "<center><img src=\"data:image/png;base64,")
- io.WriteString(w, base64.StdEncoding.EncodeToString(dat))
- fmt.Fprint(w, "\" /><br>")
- fmt.Fprintf(w, "<form method=\"POST\" action=\"%s&l=1\"><input type=\"submit\" value=\"Save this QR code\"></form>\n", m.Link())
- fmt.Fprintf(w, "</center>\n")
- fmt.Fprintf(w, "<br><center><font size=-1>%v</font></center>\n", time.Now().Sub(t0))
-}
-
-func (m *Image) Small() bool {
- return 8*(17+4*int(m.Version)) < 512
-}
-
-func (m *Image) Link() string {
- s := fmt.Sprint
- b := func(v bool) string {
- if v {
- return "1"
- }
- return "0"
- }
- val := url.Values{
- "i": {m.Name},
- "x": {s(m.Dx)},
- "y": {s(m.Dy)},
- "z": {s(m.Size)},
- "u": {m.URL},
- "v": {s(m.Version)},
- "m": {s(m.Mask)},
- "r": {b(m.RandControl)},
- "t": {b(m.Dither)},
- "d": {b(m.OnlyDataBits)},
- "c": {b(m.SaveControl)},
- "s": {s(m.Seed)},
- }
- return "/qr/draw?" + val.Encode()
-}
-
-// Show is the handler for showing a stored QR code.
-func Show(w http.ResponseWriter, req *http.Request) {
- ctxt := fs.NewContext(req)
- tag := req.URL.Path[len("/qr/show/"):]
- png := strings.HasSuffix(tag, ".png")
- if png {
- tag = tag[:len(tag)-len(".png")]
- }
- if !isTagName(tag) {
- fmt.Fprintf(w, "Sorry, QR code not found\n")
- return
- }
- if req.FormValue("flag") == "1" {
- flag(w, req, tag, ctxt)
- return
- }
- data, _, err := ctxt.Read("qrsave/" + tag)
- if err != nil {
- fmt.Fprintf(w, "Sorry, QR code not found.\n")
- return
- }
-
- var m Image
- if err := json.Unmarshal(data, &m); err != nil {
- panic(err)
- }
- m.Tag = tag
-
- switch req.FormValue("size") {
- case "big":
- m.Scale *= 2
- case "small":
- m.Scale /= 2
- }
-
- if png {
- if err := m.Encode(req); err != nil {
- panic(err)
- return
- }
- w.Header().Set("Cache-Control", "public, max-age=3600")
- w.Write(m.Code.PNG())
- return
- }
-
- w.Header().Set("Cache-Control", "public, max-age=300")
- runTemplate(ctxt, w, "qr/permalink.html", &m)
-}
-
-func upload(w http.ResponseWriter, req *http.Request, link string) {
- // Upload of a new image.
- // Copied from Moustachio demo.
- f, _, err := req.FormFile("image")
- if err != nil {
- fmt.Fprintf(w, "You need to select an image to upload.\n")
- return
- }
- defer f.Close()
-
- i, _, err := image.Decode(f)
- if err != nil {
- panic(err)
- }
-
- // Convert image to 128x128 gray+alpha.
- b := i.Bounds()
- const max = 128
- // If it's gigantic, it's more efficient to downsample first
- // and then resize; resizing will smooth out the roughness.
- var i1 *image.RGBA
- if b.Dx() > 4*max || b.Dy() > 4*max {
- w, h := 2*max, 2*max
- if b.Dx() > b.Dy() {
- h = b.Dy() * h / b.Dx()
- } else {
- w = b.Dx() * w / b.Dy()
- }
- i1 = resize.Resample(i, b, w, h)
- } else {
- // "Resample" to same size, just to convert to RGBA.
- i1 = resize.Resample(i, b, b.Dx(), b.Dy())
- }
- b = i1.Bounds()
-
- // Encode to PNG.
- dx, dy := 128, 128
- if b.Dx() > b.Dy() {
- dy = b.Dy() * dx / b.Dx()
- } else {
- dx = b.Dx() * dy / b.Dy()
- }
- i128 := resize.ResizeRGBA(i1, i1.Bounds(), dx, dy)
-
- var buf bytes.Buffer
- if err := png.Encode(&buf, i128); err != nil {
- panic(err)
- }
-
- h := md5.New()
- h.Write(buf.Bytes())
- tag := fmt.Sprintf("%x", h.Sum(nil))[:32]
-
- ctxt := fs.NewContext(req)
- if err := ctxt.Write("qr/upload/"+tag+".png", buf.Bytes()); err != nil {
- panic(err)
- }
-
- // Redirect with new image tag.
- // Redirect to draw with new image tag.
- http.Redirect(w, req, req.URL.Path+"?"+url.Values{"i": {tag}, "url": {link}}.Encode(), 302)
-}
-
-func flag(w http.ResponseWriter, req *http.Request, img string, ctxt *fs.Context) {
- if !isImgName(img) && !isTagName(img) {
- fmt.Fprintf(w, "Invalid image.\n")
- return
- }
- data, _, _ := ctxt.Read("qr/flag/" + img)
- data = append(data, '!')
- ctxt.Write("qr/flag/" + img, data)
-
- fmt.Fprintf(w, "Thank you. The image has been reported.\n")
-}
-
-func loadSize(ctxt *fs.Context, name string, max int) *image.RGBA {
- data, _, err := ctxt.Read("qr/upload/" + name + ".png")
- if err != nil {
- panic(err)
- }
- i, _, err := image.Decode(bytes.NewBuffer(data))
- if err != nil {
- panic(err)
- }
- b := i.Bounds()
- dx, dy := max, max
- if b.Dx() > b.Dy() {
- dy = b.Dy() * dx / b.Dx()
- } else {
- dx = b.Dx() * dy / b.Dy()
- }
- var irgba *image.RGBA
- switch i := i.(type) {
- case *image.RGBA:
- irgba = resize.ResizeRGBA(i, i.Bounds(), dx, dy)
- case *image.NRGBA:
- irgba = resize.ResizeNRGBA(i, i.Bounds(), dx, dy)
- }
- return irgba
-}
-
-func makeTarg(ctxt *fs.Context, name string, max int) [][]int {
- i := loadSize(ctxt, name, max)
- b := i.Bounds()
- dx, dy := b.Dx(), b.Dy()
- targ := make([][]int, dy)
- arr := make([]int, dx*dy)
- for y := 0; y < dy; y++ {
- targ[y], arr = arr[:dx], arr[dx:]
- row := targ[y]
- for x := 0; x < dx; x++ {
- p := i.Pix[y*i.Stride+4*x:]
- r, g, b, a := p[0], p[1], p[2], p[3]
- if a == 0 {
- row[x] = -1
- } else {
- row[x] = int((299*uint32(r) + 587*uint32(g) + 114*uint32(b) + 500) / 1000)
- }
- }
- }
- return targ
-}
-
-type Image struct {
- Name string
- Target [][]int
- Dx int
- Dy int
- URL string
- Tag string
- Version int
- Mask int
- Scale int
- Rotation int
- Size int
-
- // RandControl says to pick the pixels randomly.
- RandControl bool
- Seed int64
-
- // Dither says to dither instead of using threshold pixel layout.
- Dither bool
-
- // OnlyDataBits says to use only data bits, not check bits.
- OnlyDataBits bool
-
- // Code is the final QR code.
- Code *qr.Code
-
- // Control is a PNG showing the pixels that we controlled.
- // Pixels we don't control are grayed out.
- SaveControl bool
- Control []byte
-}
-
-type Pixinfo struct {
- X int
- Y int
- Pix coding.Pixel
- Targ byte
- DTarg int
- Contrast int
- HardZero bool
- Block *BitBlock
- Bit uint
-}
-
-type Pixorder struct {
- Off int
- Priority int
-}
-
-type byPriority []Pixorder
-
-func (x byPriority) Len() int { return len(x) }
-func (x byPriority) Swap(i, j int) { x[i], x[j] = x[j], x[i] }
-func (x byPriority) Less(i, j int) bool { return x[i].Priority > x[j].Priority }
-
-func (m *Image) target(x, y int) (targ byte, contrast int) {
- tx := x + m.Dx
- ty := y + m.Dy
- if ty < 0 || ty >= len(m.Target) || tx < 0 || tx >= len(m.Target[ty]) {
- return 255, -1
- }
-
- v0 := m.Target[ty][tx]
- if v0 < 0 {
- return 255, -1
- }
- targ = byte(v0)
-
- n := 0
- sum := 0
- sumsq := 0
- const del = 5
- for dy := -del; dy <= del; dy++ {
- for dx := -del; dx <= del; dx++ {
- if 0 <= ty+dy && ty+dy < len(m.Target) && 0 <= tx+dx && tx+dx < len(m.Target[ty+dy]) {
- v := m.Target[ty+dy][tx+dx]
- sum += v
- sumsq += v * v
- n++
- }
- }
- }
-
- avg := sum / n
- contrast = sumsq/n - avg*avg
- return
-}
-
-func (m *Image) rotate(p *coding.Plan, rot int) {
- if rot == 0 {
- return
- }
-
- N := len(p.Pixel)
- pix := make([][]coding.Pixel, N)
- apix := make([]coding.Pixel, N*N)
- for i := range pix {
- pix[i], apix = apix[:N], apix[N:]
- }
-
- switch rot {
- case 0:
- // ok
- case 1:
- for y := 0; y < N; y++ {
- for x := 0; x < N; x++ {
- pix[y][x] = p.Pixel[x][N-1-y]
- }
- }
- case 2:
- for y := 0; y < N; y++ {
- for x := 0; x < N; x++ {
- pix[y][x] = p.Pixel[N-1-y][N-1-x]
- }
- }
- case 3:
- for y := 0; y < N; y++ {
- for x := 0; x < N; x++ {
- pix[y][x] = p.Pixel[N-1-x][y]
- }
- }
- }
-
- p.Pixel = pix
-}
-
-func (m *Image) Encode(req *http.Request) error {
- p, err := coding.NewPlan(coding.Version(m.Version), coding.L, coding.Mask(m.Mask))
- if err != nil {
- return err
- }
-
- m.rotate(p, m.Rotation)
-
- rand := rand.New(rand.NewSource(m.Seed))
-
- // QR parameters.
- nd := p.DataBytes / p.Blocks
- nc := p.CheckBytes / p.Blocks
- extra := p.DataBytes - nd*p.Blocks
- rs := gf256.NewRSEncoder(coding.Field, nc)
-
- // Build information about pixels, indexed by data/check bit number.
- pixByOff := make([]Pixinfo, (p.DataBytes+p.CheckBytes)*8)
- expect := make([][]bool, len(p.Pixel))
- for y, row := range p.Pixel {
- expect[y] = make([]bool, len(row))
- for x, pix := range row {
- targ, contrast := m.target(x, y)
- if m.RandControl && contrast >= 0 {
- contrast = rand.Intn(128) + 64*((x+y)%2) + 64*((x+y)%3%2)
- }
- expect[y][x] = pix&coding.Black != 0
- if r := pix.Role(); r == coding.Data || r == coding.Check {
- pixByOff[pix.Offset()] = Pixinfo{X: x, Y: y, Pix: pix, Targ: targ, Contrast: contrast}
- }
- }
- }
-
-Again:
- // Count fixed initial data bits, prepare template URL.
- url := m.URL + "#"
- var b coding.Bits
- coding.String(url).Encode(&b, p.Version)
- coding.Num("").Encode(&b, p.Version)
- bbit := b.Bits()
- dbit := p.DataBytes*8 - bbit
- if dbit < 0 {
- return fmt.Errorf("cannot encode URL into available bits")
- }
- num := make([]byte, dbit/10*3)
- for i := range num {
- num[i] = '0'
- }
- b.Pad(dbit)
- b.Reset()
- coding.String(url).Encode(&b, p.Version)
- coding.Num(num).Encode(&b, p.Version)
- b.AddCheckBytes(p.Version, p.Level)
- data := b.Bytes()
-
- doff := 0 // data offset
- coff := 0 // checksum offset
- mbit := bbit + dbit/10*10
-
- // Choose pixels.
- bitblocks := make([]*BitBlock, p.Blocks)
- for blocknum := 0; blocknum < p.Blocks; blocknum++ {
- if blocknum == p.Blocks-extra {
- nd++
- }
-
- bdata := data[doff/8 : doff/8+nd]
- cdata := data[p.DataBytes+coff/8 : p.DataBytes+coff/8+nc]
- bb := newBlock(nd, nc, rs, bdata, cdata)
- bitblocks[blocknum] = bb
-
- // Determine which bits in this block we can try to edit.
- lo, hi := 0, nd*8
- if lo < bbit-doff {
- lo = bbit - doff
- if lo > hi {
- lo = hi
- }
- }
- if hi > mbit-doff {
- hi = mbit - doff
- if hi < lo {
- hi = lo
- }
- }
-
- // Preserve [0, lo) and [hi, nd*8).
- for i := 0; i < lo; i++ {
- if !bb.canSet(uint(i), (bdata[i/8]>>uint(7-i&7))&1) {
- return fmt.Errorf("cannot preserve required bits")
- }
- }
- for i := hi; i < nd*8; i++ {
- if !bb.canSet(uint(i), (bdata[i/8]>>uint(7-i&7))&1) {
- return fmt.Errorf("cannot preserve required bits")
- }
- }
-
- // Can edit [lo, hi) and checksum bits to hit target.
- // Determine which ones to try first.
- order := make([]Pixorder, (hi-lo)+nc*8)
- for i := lo; i < hi; i++ {
- order[i-lo].Off = doff + i
- }
- for i := 0; i < nc*8; i++ {
- order[hi-lo+i].Off = p.DataBytes*8 + coff + i
- }
- if m.OnlyDataBits {
- order = order[:hi-lo]
- }
- for i := range order {
- po := &order[i]
- po.Priority = pixByOff[po.Off].Contrast<<8 | rand.Intn(256)
- }
- sort.Sort(byPriority(order))
-
- const mark = false
- for i := range order {
- po := &order[i]
- pinfo := &pixByOff[po.Off]
- bval := pinfo.Targ
- if bval < 128 {
- bval = 1
- } else {
- bval = 0
- }
- pix := pinfo.Pix
- if pix&coding.Invert != 0 {
- bval ^= 1
- }
- if pinfo.HardZero {
- bval = 0
- }
-
- var bi int
- if pix.Role() == coding.Data {
- bi = po.Off - doff
- } else {
- bi = po.Off - p.DataBytes*8 - coff + nd*8
- }
- if bb.canSet(uint(bi), bval) {
- pinfo.Block = bb
- pinfo.Bit = uint(bi)
- if mark {
- p.Pixel[pinfo.Y][pinfo.X] = coding.Black
- }
- } else {
- if pinfo.HardZero {
- panic("hard zero")
- }
- if mark {
- p.Pixel[pinfo.Y][pinfo.X] = 0
- }
- }
- }
- bb.copyOut()
-
- const cheat = false
- for i := 0; i < nd*8; i++ {
- pinfo := &pixByOff[doff+i]
- pix := p.Pixel[pinfo.Y][pinfo.X]
- if bb.B[i/8]&(1<<uint(7-i&7)) != 0 {
- pix ^= coding.Black
- }
- expect[pinfo.Y][pinfo.X] = pix&coding.Black != 0
- if cheat {
- p.Pixel[pinfo.Y][pinfo.X] = pix & coding.Black
- }
- }
- for i := 0; i < nc*8; i++ {
- pinfo := &pixByOff[p.DataBytes*8+coff+i]
- pix := p.Pixel[pinfo.Y][pinfo.X]
- if bb.B[nd+i/8]&(1<<uint(7-i&7)) != 0 {
- pix ^= coding.Black
- }
- expect[pinfo.Y][pinfo.X] = pix&coding.Black != 0
- if cheat {
- p.Pixel[pinfo.Y][pinfo.X] = pix & coding.Black
- }
- }
- doff += nd * 8
- coff += nc * 8
- }
-
- // Pass over all pixels again, dithering.
- if m.Dither {
- for i := range pixByOff {
- pinfo := &pixByOff[i]
- pinfo.DTarg = int(pinfo.Targ)
- }
- for y, row := range p.Pixel {
- for x, pix := range row {
- if pix.Role() != coding.Data && pix.Role() != coding.Check {
- continue
- }
- pinfo := &pixByOff[pix.Offset()]
- if pinfo.Block == nil {
- // did not choose this pixel
- continue
- }
-
- pix := pinfo.Pix
-
- pval := byte(1) // pixel value (black)
- v := 0 // gray value (black)
- targ := pinfo.DTarg
- if targ >= 128 {
- // want white
- pval = 0
- v = 255
- }
-
- bval := pval // bit value
- if pix&coding.Invert != 0 {
- bval ^= 1
- }
- if pinfo.HardZero && bval != 0 {
- bval ^= 1
- pval ^= 1
- v ^= 255
- }
-
- // Set pixel value as we want it.
- pinfo.Block.reset(pinfo.Bit, bval)
-
- _, _ = x, y
-
- err := targ - v
- if x+1 < len(row) {
- addDither(pixByOff, row[x+1], err*7/16)
- }
- if false && y+1 < len(p.Pixel) {
- if x > 0 {
- addDither(pixByOff, p.Pixel[y+1][x-1], err*3/16)
- }
- addDither(pixByOff, p.Pixel[y+1][x], err*5/16)
- if x+1 < len(row) {
- addDither(pixByOff, p.Pixel[y+1][x+1], err*1/16)
- }
- }
- }
- }
-
- for _, bb := range bitblocks {
- bb.copyOut()
- }
- }
-
- noops := 0
- // Copy numbers back out.
- for i := 0; i < dbit/10; i++ {
- // Pull out 10 bits.
- v := 0
- for j := 0; j < 10; j++ {
- bi := uint(bbit + 10*i + j)
- v <<= 1
- v |= int((data[bi/8] >> (7 - bi&7)) & 1)
- }
- // Turn into 3 digits.
- if v >= 1000 {
- // Oops - too many 1 bits.
- // We know the 512, 256, 128, 64, 32 bits are all set.
- // Pick one at random to clear. This will break some
- // checksum bits, but so be it.
- println("oops", i, v)
- pinfo := &pixByOff[bbit+10*i+3] // TODO random
- pinfo.Contrast = 1e9 >> 8
- pinfo.HardZero = true
- noops++
- }
- num[i*3+0] = byte(v/100 + '0')
- num[i*3+1] = byte(v/10%10 + '0')
- num[i*3+2] = byte(v%10 + '0')
- }
- if noops > 0 {
- goto Again
- }
-
- var b1 coding.Bits
- coding.String(url).Encode(&b1, p.Version)
- coding.Num(num).Encode(&b1, p.Version)
- b1.AddCheckBytes(p.Version, p.Level)
- if !bytes.Equal(b.Bytes(), b1.Bytes()) {
- fmt.Printf("mismatch\n%d %x\n%d %x\n", len(b.Bytes()), b.Bytes(), len(b1.Bytes()), b1.Bytes())
- panic("byte mismatch")
- }
-
- cc, err := p.Encode(coding.String(url), coding.Num(num))
- if err != nil {
- return err
- }
-
- if !m.Dither {
- for y, row := range expect {
- for x, pix := range row {
- if cc.Black(x, y) != pix {
- println("mismatch", x, y, p.Pixel[y][x].String())
- }
- }
- }
- }
-
- m.Code = &qr.Code{Bitmap: cc.Bitmap, Size: cc.Size, Stride: cc.Stride, Scale: m.Scale}
-
- if m.SaveControl {
- m.Control = pngEncode(makeImage(req, "", "", 0, cc.Size, 4, m.Scale, func(x, y int) (rgba uint32) {
- pix := p.Pixel[y][x]
- if pix.Role() == coding.Data || pix.Role() == coding.Check {
- pinfo := &pixByOff[pix.Offset()]
- if pinfo.Block != nil {
- if cc.Black(x, y) {
- return 0x000000ff
- }
- return 0xffffffff
- }
- }
- if cc.Black(x, y) {
- return 0x3f3f3fff
- }
- return 0xbfbfbfff
- }))
- }
-
- return nil
-}
-
-func addDither(pixByOff []Pixinfo, pix coding.Pixel, err int) {
- if pix.Role() != coding.Data && pix.Role() != coding.Check {
- return
- }
- pinfo := &pixByOff[pix.Offset()]
- println("add", pinfo.X, pinfo.Y, pinfo.DTarg, err)
- pinfo.DTarg += err
-}
-
-func readTarget(name string) ([][]int, error) {
- f, err := os.Open(name)
- if err != nil {
- return nil, err
- }
- m, err := png.Decode(f)
- if err != nil {
- return nil, fmt.Errorf("decode %s: %v", name, err)
- }
- rect := m.Bounds()
- target := make([][]int, rect.Dy())
- for i := range target {
- target[i] = make([]int, rect.Dx())
- }
- for y, row := range target {
- for x := range row {
- a := int(color.RGBAModel.Convert(m.At(x, y)).(color.RGBA).A)
- t := int(color.GrayModel.Convert(m.At(x, y)).(color.Gray).Y)
- if a == 0 {
- t = -1
- }
- row[x] = t
- }
- }
- return target, nil
-}
-
-type BitBlock struct {
- DataBytes int
- CheckBytes int
- B []byte
- M [][]byte
- Tmp []byte
- RS *gf256.RSEncoder
- bdata []byte
- cdata []byte
-}
-
-func newBlock(nd, nc int, rs *gf256.RSEncoder, dat, cdata []byte) *BitBlock {
- b := &BitBlock{
- DataBytes: nd,
- CheckBytes: nc,
- B: make([]byte, nd+nc),
- Tmp: make([]byte, nc),
- RS: rs,
- bdata: dat,
- cdata: cdata,
- }
- copy(b.B, dat)
- rs.ECC(b.B[:nd], b.B[nd:])
- b.check()
- if !bytes.Equal(b.Tmp, cdata) {
- panic("cdata")
- }
-
- b.M = make([][]byte, nd*8)
- for i := range b.M {
- row := make([]byte, nd+nc)
- b.M[i] = row
- for j := range row {
- row[j] = 0
- }
- row[i/8] = 1 << (7 - uint(i%8))
- rs.ECC(row[:nd], row[nd:])
- }
- return b
-}
-
-func (b *BitBlock) check() {
- b.RS.ECC(b.B[:b.DataBytes], b.Tmp)
- if !bytes.Equal(b.B[b.DataBytes:], b.Tmp) {
- fmt.Printf("ecc mismatch\n%x\n%x\n", b.B[b.DataBytes:], b.Tmp)
- panic("mismatch")
- }
-}
-
-func (b *BitBlock) reset(bi uint, bval byte) {
- if (b.B[bi/8]>>(7-bi&7))&1 == bval {
- // already has desired bit
- return
- }
- // rows that have already been set
- m := b.M[len(b.M):cap(b.M)]
- for _, row := range m {
- if row[bi/8]&(1<<(7-bi&7)) != 0 {
- // Found it.
- for j, v := range row {
- b.B[j] ^= v
- }
- return
- }
- }
- panic("reset of unset bit")
-}
-
-func (b *BitBlock) canSet(bi uint, bval byte) bool {
- found := false
- m := b.M
- for j, row := range m {
- if row[bi/8]&(1<<(7-bi&7)) == 0 {
- continue
- }
- if !found {
- found = true
- if j != 0 {
- m[0], m[j] = m[j], m[0]
- }
- continue
- }
- for k := range row {
- row[k] ^= m[0][k]
- }
- }
- if !found {
- return false
- }
-
- targ := m[0]
-
- // Subtract from saved-away rows too.
- for _, row := range m[len(m):cap(m)] {
- if row[bi/8]&(1<<(7-bi&7)) == 0 {
- continue
- }
- for k := range row {
- row[k] ^= targ[k]
- }
- }
-
- // Found a row with bit #bi == 1 and cut that bit from all the others.
- // Apply to data and remove from m.
- if (b.B[bi/8]>>(7-bi&7))&1 != bval {
- for j, v := range targ {
- b.B[j] ^= v
- }
- }
- b.check()
- n := len(m) - 1
- m[0], m[n] = m[n], m[0]
- b.M = m[:n]
-
- for _, row := range b.M {
- if row[bi/8]&(1<<(7-bi&7)) != 0 {
- panic("did not reduce")
- }
- }
-
- return true
-}
-
-func (b *BitBlock) copyOut() {
- b.check()
- copy(b.bdata, b.B[:b.DataBytes])
- copy(b.cdata, b.B[b.DataBytes:])
-}
-
-func showtable(w http.ResponseWriter, b *BitBlock, gray func(int) bool) {
- nd := b.DataBytes
- nc := b.CheckBytes
-
- fmt.Fprintf(w, "<table class='matrix' cellspacing=0 cellpadding=0 border=0>\n")
- line := func() {
- fmt.Fprintf(w, "<tr height=1 bgcolor='#bbbbbb'><td colspan=%d>\n", (nd+nc)*8)
- }
- line()
- dorow := func(row []byte) {
- fmt.Fprintf(w, "<tr>\n")
- for i := 0; i < (nd+nc)*8; i++ {
- fmt.Fprintf(w, "<td")
- v := row[i/8] >> uint(7-i&7) & 1
- if gray(i) {
- fmt.Fprintf(w, " class='gray'")
- }
- fmt.Fprintf(w, ">")
- if v == 1 {
- fmt.Fprintf(w, "1")
- }
- }
- line()
- }
-
- m := b.M[len(b.M):cap(b.M)]
- for i := len(m) - 1; i >= 0; i-- {
- dorow(m[i])
- }
- m = b.M
- for _, row := range b.M {
- dorow(row)
- }
-
- fmt.Fprintf(w, "</table>\n")
-}
-
-func BitsTable(w http.ResponseWriter, req *http.Request) {
- nd := 2
- nc := 2
- fmt.Fprintf(w, `<html>
- <style type='text/css'>
- .matrix {
- font-family: sans-serif;
- font-size: 0.8em;
- }
- table.matrix {
- padding-left: 1em;
- padding-right: 1em;
- padding-top: 1em;
- padding-bottom: 1em;
- }
- .matrix td {
- padding-left: 0.3em;
- padding-right: 0.3em;
- border-left: 2px solid white;
- border-right: 2px solid white;
- text-align: center;
- color: #aaa;
- }
- .matrix td.gray {
- color: black;
- background-color: #ddd;
- }
- </style>
- `)
- rs := gf256.NewRSEncoder(coding.Field, nc)
- dat := make([]byte, nd+nc)
- b := newBlock(nd, nc, rs, dat[:nd], dat[nd:])
- for i := 0; i < nd*8; i++ {
- b.canSet(uint(i), 0)
- }
- showtable(w, b, func(i int) bool { return i < nd*8 })
-
- b = newBlock(nd, nc, rs, dat[:nd], dat[nd:])
- for j := 0; j < (nd+nc)*8; j += 2 {
- b.canSet(uint(j), 0)
- }
- showtable(w, b, func(i int) bool { return i%2 == 0 })
-
-}
diff --git a/vendor/github.com/mattermost/rsc/qr/web/resize/resize.go b/vendor/github.com/mattermost/rsc/qr/web/resize/resize.go
deleted file mode 100644
index 02c8b0040..000000000
--- a/vendor/github.com/mattermost/rsc/qr/web/resize/resize.go
+++ /dev/null
@@ -1,152 +0,0 @@
-// 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 resize
-
-import (
- "image"
- "image/color"
-)
-
-// average convert the sums to averages and returns the result.
-func average(sum []uint64, w, h int, n uint64) *image.RGBA {
- ret := image.NewRGBA(image.Rect(0, 0, w, h))
- for y := 0; y < h; y++ {
- for x := 0; x < w; x++ {
- index := 4 * (y*w + x)
- pix := ret.Pix[y*ret.Stride+x*4:]
- pix[0] = uint8(sum[index+0] / n)
- pix[1] = uint8(sum[index+1] / n)
- pix[2] = uint8(sum[index+2] / n)
- pix[3] = uint8(sum[index+3] / n)
- }
- }
- return ret
-}
-
-// ResizeRGBA returns a scaled copy of the RGBA image slice r of m.
-// The returned image has width w and height h.
-func ResizeRGBA(m *image.RGBA, r image.Rectangle, w, h int) *image.RGBA {
- ww, hh := uint64(w), uint64(h)
- dx, dy := uint64(r.Dx()), uint64(r.Dy())
- // See comment in Resize.
- n, sum := dx*dy, make([]uint64, 4*w*h)
- for y := r.Min.Y; y < r.Max.Y; y++ {
- pix := m.Pix[(y-r.Min.Y)*m.Stride:]
- for x := r.Min.X; x < r.Max.X; x++ {
- // Get the source pixel.
- p := pix[(x-r.Min.X)*4:]
- r64 := uint64(p[0])
- g64 := uint64(p[1])
- b64 := uint64(p[2])
- a64 := uint64(p[3])
- // Spread the source pixel over 1 or more destination rows.
- py := uint64(y) * hh
- for remy := hh; remy > 0; {
- qy := dy - (py % dy)
- if qy > remy {
- qy = remy
- }
- // Spread the source pixel over 1 or more destination columns.
- px := uint64(x) * ww
- index := 4 * ((py/dy)*ww + (px / dx))
- for remx := ww; remx > 0; {
- qx := dx - (px % dx)
- if qx > remx {
- qx = remx
- }
- qxy := qx * qy
- sum[index+0] += r64 * qxy
- sum[index+1] += g64 * qxy
- sum[index+2] += b64 * qxy
- sum[index+3] += a64 * qxy
- index += 4
- px += qx
- remx -= qx
- }
- py += qy
- remy -= qy
- }
- }
- }
- return average(sum, w, h, n)
-}
-
-// ResizeNRGBA returns a scaled copy of the RGBA image slice r of m.
-// The returned image has width w and height h.
-func ResizeNRGBA(m *image.NRGBA, r image.Rectangle, w, h int) *image.RGBA {
- ww, hh := uint64(w), uint64(h)
- dx, dy := uint64(r.Dx()), uint64(r.Dy())
- // See comment in Resize.
- n, sum := dx*dy, make([]uint64, 4*w*h)
- for y := r.Min.Y; y < r.Max.Y; y++ {
- pix := m.Pix[(y-r.Min.Y)*m.Stride:]
- for x := r.Min.X; x < r.Max.X; x++ {
- // Get the source pixel.
- p := pix[(x-r.Min.X)*4:]
- r64 := uint64(p[0])
- g64 := uint64(p[1])
- b64 := uint64(p[2])
- a64 := uint64(p[3])
- r64 = (r64 * a64) / 255
- g64 = (g64 * a64) / 255
- b64 = (b64 * a64) / 255
- // Spread the source pixel over 1 or more destination rows.
- py := uint64(y) * hh
- for remy := hh; remy > 0; {
- qy := dy - (py % dy)
- if qy > remy {
- qy = remy
- }
- // Spread the source pixel over 1 or more destination columns.
- px := uint64(x) * ww
- index := 4 * ((py/dy)*ww + (px / dx))
- for remx := ww; remx > 0; {
- qx := dx - (px % dx)
- if qx > remx {
- qx = remx
- }
- qxy := qx * qy
- sum[index+0] += r64 * qxy
- sum[index+1] += g64 * qxy
- sum[index+2] += b64 * qxy
- sum[index+3] += a64 * qxy
- index += 4
- px += qx
- remx -= qx
- }
- py += qy
- remy -= qy
- }
- }
- }
- return average(sum, w, h, n)
-}
-
-// Resample returns a resampled copy of the image slice r of m.
-// The returned image has width w and height h.
-func Resample(m image.Image, r image.Rectangle, w, h int) *image.RGBA {
- if w < 0 || h < 0 {
- return nil
- }
- if w == 0 || h == 0 || r.Dx() <= 0 || r.Dy() <= 0 {
- return image.NewRGBA(image.Rect(0, 0, w, h))
- }
- curw, curh := r.Dx(), r.Dy()
- img := image.NewRGBA(image.Rect(0, 0, w, h))
- for y := 0; y < h; y++ {
- for x := 0; x < w; x++ {
- // Get a source pixel.
- subx := x * curw / w
- suby := y * curh / h
- r32, g32, b32, a32 := m.At(subx, suby).RGBA()
- r := uint8(r32 >> 8)
- g := uint8(g32 >> 8)
- b := uint8(b32 >> 8)
- a := uint8(a32 >> 8)
- img.SetRGBA(x, y, color.RGBA{r, g, b, a})
- }
- }
- return img
-}