wangchuanjin 2 gadi atpakaļ
revīzija
9cafa6864f

+ 149 - 0
github.com/SKatiyar/qr/coding/gen.go

@@ -0,0 +1,149 @@
+// +build ignore
+
+package main
+
+import "fmt"
+
+// tables from qrencode-3.1.1/qrspec.c
+
+var capacity = [41]struct {
+	width     int
+	words     int
+	remainder int
+	ec        [4]int
+}{
+	{0, 0, 0, [4]int{0, 0, 0, 0}},
+	{21, 26, 0, [4]int{7, 10, 13, 17}}, // 1
+	{25, 44, 7, [4]int{10, 16, 22, 28}},
+	{29, 70, 7, [4]int{15, 26, 36, 44}},
+	{33, 100, 7, [4]int{20, 36, 52, 64}},
+	{37, 134, 7, [4]int{26, 48, 72, 88}}, // 5
+	{41, 172, 7, [4]int{36, 64, 96, 112}},
+	{45, 196, 0, [4]int{40, 72, 108, 130}},
+	{49, 242, 0, [4]int{48, 88, 132, 156}},
+	{53, 292, 0, [4]int{60, 110, 160, 192}},
+	{57, 346, 0, [4]int{72, 130, 192, 224}}, //10
+	{61, 404, 0, [4]int{80, 150, 224, 264}},
+	{65, 466, 0, [4]int{96, 176, 260, 308}},
+	{69, 532, 0, [4]int{104, 198, 288, 352}},
+	{73, 581, 3, [4]int{120, 216, 320, 384}},
+	{77, 655, 3, [4]int{132, 240, 360, 432}}, //15
+	{81, 733, 3, [4]int{144, 280, 408, 480}},
+	{85, 815, 3, [4]int{168, 308, 448, 532}},
+	{89, 901, 3, [4]int{180, 338, 504, 588}},
+	{93, 991, 3, [4]int{196, 364, 546, 650}},
+	{97, 1085, 3, [4]int{224, 416, 600, 700}}, //20
+	{101, 1156, 4, [4]int{224, 442, 644, 750}},
+	{105, 1258, 4, [4]int{252, 476, 690, 816}},
+	{109, 1364, 4, [4]int{270, 504, 750, 900}},
+	{113, 1474, 4, [4]int{300, 560, 810, 960}},
+	{117, 1588, 4, [4]int{312, 588, 870, 1050}}, //25
+	{121, 1706, 4, [4]int{336, 644, 952, 1110}},
+	{125, 1828, 4, [4]int{360, 700, 1020, 1200}},
+	{129, 1921, 3, [4]int{390, 728, 1050, 1260}},
+	{133, 2051, 3, [4]int{420, 784, 1140, 1350}},
+	{137, 2185, 3, [4]int{450, 812, 1200, 1440}}, //30
+	{141, 2323, 3, [4]int{480, 868, 1290, 1530}},
+	{145, 2465, 3, [4]int{510, 924, 1350, 1620}},
+	{149, 2611, 3, [4]int{540, 980, 1440, 1710}},
+	{153, 2761, 3, [4]int{570, 1036, 1530, 1800}},
+	{157, 2876, 0, [4]int{570, 1064, 1590, 1890}}, //35
+	{161, 3034, 0, [4]int{600, 1120, 1680, 1980}},
+	{165, 3196, 0, [4]int{630, 1204, 1770, 2100}},
+	{169, 3362, 0, [4]int{660, 1260, 1860, 2220}},
+	{173, 3532, 0, [4]int{720, 1316, 1950, 2310}},
+	{177, 3706, 0, [4]int{750, 1372, 2040, 2430}}, //40
+}
+
+var eccTable = [41][4][2]int{
+	{{0, 0}, {0, 0}, {0, 0}, {0, 0}},
+	{{1, 0}, {1, 0}, {1, 0}, {1, 0}}, // 1
+	{{1, 0}, {1, 0}, {1, 0}, {1, 0}},
+	{{1, 0}, {1, 0}, {2, 0}, {2, 0}},
+	{{1, 0}, {2, 0}, {2, 0}, {4, 0}},
+	{{1, 0}, {2, 0}, {2, 2}, {2, 2}}, // 5
+	{{2, 0}, {4, 0}, {4, 0}, {4, 0}},
+	{{2, 0}, {4, 0}, {2, 4}, {4, 1}},
+	{{2, 0}, {2, 2}, {4, 2}, {4, 2}},
+	{{2, 0}, {3, 2}, {4, 4}, {4, 4}},
+	{{2, 2}, {4, 1}, {6, 2}, {6, 2}}, //10
+	{{4, 0}, {1, 4}, {4, 4}, {3, 8}},
+	{{2, 2}, {6, 2}, {4, 6}, {7, 4}},
+	{{4, 0}, {8, 1}, {8, 4}, {12, 4}},
+	{{3, 1}, {4, 5}, {11, 5}, {11, 5}},
+	{{5, 1}, {5, 5}, {5, 7}, {11, 7}}, //15
+	{{5, 1}, {7, 3}, {15, 2}, {3, 13}},
+	{{1, 5}, {10, 1}, {1, 15}, {2, 17}},
+	{{5, 1}, {9, 4}, {17, 1}, {2, 19}},
+	{{3, 4}, {3, 11}, {17, 4}, {9, 16}},
+	{{3, 5}, {3, 13}, {15, 5}, {15, 10}}, //20
+	{{4, 4}, {17, 0}, {17, 6}, {19, 6}},
+	{{2, 7}, {17, 0}, {7, 16}, {34, 0}},
+	{{4, 5}, {4, 14}, {11, 14}, {16, 14}},
+	{{6, 4}, {6, 14}, {11, 16}, {30, 2}},
+	{{8, 4}, {8, 13}, {7, 22}, {22, 13}}, //25
+	{{10, 2}, {19, 4}, {28, 6}, {33, 4}},
+	{{8, 4}, {22, 3}, {8, 26}, {12, 28}},
+	{{3, 10}, {3, 23}, {4, 31}, {11, 31}},
+	{{7, 7}, {21, 7}, {1, 37}, {19, 26}},
+	{{5, 10}, {19, 10}, {15, 25}, {23, 25}}, //30
+	{{13, 3}, {2, 29}, {42, 1}, {23, 28}},
+	{{17, 0}, {10, 23}, {10, 35}, {19, 35}},
+	{{17, 1}, {14, 21}, {29, 19}, {11, 46}},
+	{{13, 6}, {14, 23}, {44, 7}, {59, 1}},
+	{{12, 7}, {12, 26}, {39, 14}, {22, 41}}, //35
+	{{6, 14}, {6, 34}, {46, 10}, {2, 64}},
+	{{17, 4}, {29, 14}, {49, 10}, {24, 46}},
+	{{4, 18}, {13, 32}, {48, 14}, {42, 32}},
+	{{20, 4}, {40, 7}, {43, 22}, {10, 67}},
+	{{19, 6}, {18, 31}, {34, 34}, {20, 61}}, //40
+}
+
+var align = [41][2]int{
+	{0, 0},
+	{0, 0}, {18, 0}, {22, 0}, {26, 0}, {30, 0}, // 1- 5
+	{34, 0}, {22, 38}, {24, 42}, {26, 46}, {28, 50}, // 6-10
+	{30, 54}, {32, 58}, {34, 62}, {26, 46}, {26, 48}, //11-15
+	{26, 50}, {30, 54}, {30, 56}, {30, 58}, {34, 62}, //16-20
+	{28, 50}, {26, 50}, {30, 54}, {28, 54}, {32, 58}, //21-25
+	{30, 58}, {34, 62}, {26, 50}, {30, 54}, {26, 52}, //26-30
+	{30, 56}, {34, 60}, {30, 58}, {34, 62}, {30, 54}, //31-35
+	{24, 50}, {28, 54}, {32, 58}, {26, 54}, {30, 58}, //35-40
+}
+
+var versionPattern = [41]int{
+	0,
+	0, 0, 0, 0, 0, 0,
+	0x07c94, 0x085bc, 0x09a99, 0x0a4d3, 0x0bbf6, 0x0c762, 0x0d847, 0x0e60d,
+	0x0f928, 0x10b78, 0x1145d, 0x12a17, 0x13532, 0x149a6, 0x15683, 0x168c9,
+	0x177ec, 0x18ec4, 0x191e1, 0x1afab, 0x1b08e, 0x1cc1a, 0x1d33f, 0x1ed75,
+	0x1f250, 0x209d5, 0x216f0, 0x228ba, 0x2379f, 0x24b0b, 0x2542e, 0x26a64,
+	0x27541, 0x28c69,
+}
+
+func main() {
+	fmt.Printf("\t{},\n")
+	for i := 1; i <= 40; i++ {
+		apos := align[i][0] - 2
+		if apos < 0 {
+			apos = 100
+		}
+		astride := align[i][1] - align[i][0]
+		if astride < 1 {
+			astride = 100
+		}
+		fmt.Printf("\t{%v, %v, %v, %#x, [4]level{{%v, %v}, {%v, %v}, {%v, %v}, {%v, %v}}},  // %v\n",
+			apos, astride, capacity[i].words,
+			versionPattern[i],
+			eccTable[i][0][0]+eccTable[i][0][1],
+			float64(capacity[i].ec[0])/float64(eccTable[i][0][0]+eccTable[i][0][1]),
+			eccTable[i][1][0]+eccTable[i][1][1],
+			float64(capacity[i].ec[1])/float64(eccTable[i][1][0]+eccTable[i][1][1]),
+			eccTable[i][2][0]+eccTable[i][2][1],
+			float64(capacity[i].ec[2])/float64(eccTable[i][2][0]+eccTable[i][2][1]),
+			eccTable[i][3][0]+eccTable[i][3][1],
+			float64(capacity[i].ec[3])/float64(eccTable[i][3][0]+eccTable[i][3][1]),
+			i,
+		)
+	}
+}

+ 815 - 0
github.com/SKatiyar/qr/coding/qr.go

@@ -0,0 +1,815 @@
+// Copyright 2011 The Go Authors.  All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Package coding implements low-level QR coding details.
+package coding
+
+import (
+	"fmt"
+	"strconv"
+	"strings"
+
+	"github.com/SKatiyar/qr/gf256"
+)
+
+// Field is the field for QR error correction.
+var Field = gf256.NewField(0x11d, 2)
+
+// A Version represents a QR version.
+// The version specifies the size of the QR code:
+// a QR code with version v has 4v+17 pixels on a side.
+// Versions number from 1 to 40: the larger the version,
+// the more information the code can store.
+type Version int
+
+const MinVersion = 1
+const MaxVersion = 40
+
+func (v Version) String() string {
+	return strconv.Itoa(int(v))
+}
+
+func (v Version) sizeClass() int {
+	if v <= 9 {
+		return 0
+	}
+	if v <= 26 {
+		return 1
+	}
+	return 2
+}
+
+// DataBytes returns the number of data bytes that can be
+// stored in a QR code with the given version and level.
+func (v Version) DataBytes(l Level) int {
+	vt := &vtab[v]
+	lev := &vt.level[l]
+	return vt.bytes - lev.nblock*lev.check
+}
+
+// Encoding implements a QR data encoding scheme.
+// The implementations--Numeric, Alphanumeric, and String--specify
+// the character set and the mapping from UTF-8 to code bits.
+// The more restrictive the mode, the fewer code bits are needed.
+type Encoding interface {
+	Check() error
+	Bits(v Version) int
+	Encode(b *Bits, v Version)
+}
+
+type Bits struct {
+	b    []byte
+	nbit int
+}
+
+func (b *Bits) Reset() {
+	b.b = b.b[:0]
+	b.nbit = 0
+}
+
+func (b *Bits) Bits() int {
+	return b.nbit
+}
+
+func (b *Bits) Bytes() []byte {
+	if b.nbit%8 != 0 {
+		panic("fractional byte")
+	}
+	return b.b
+}
+
+func (b *Bits) Append(p []byte) {
+	if b.nbit%8 != 0 {
+		panic("fractional byte")
+	}
+	b.b = append(b.b, p...)
+	b.nbit += 8 * len(p)
+}
+
+func (b *Bits) Write(v uint, nbit int) {
+	for nbit > 0 {
+		n := nbit
+		if n > 8 {
+			n = 8
+		}
+		if b.nbit%8 == 0 {
+			b.b = append(b.b, 0)
+		} else {
+			m := -b.nbit & 7
+			if n > m {
+				n = m
+			}
+		}
+		b.nbit += n
+		sh := uint(nbit - n)
+		b.b[len(b.b)-1] |= uint8(v >> sh << uint(-b.nbit&7))
+		v -= v >> sh << sh
+		nbit -= n
+	}
+}
+
+// Num is the encoding for numeric data.
+// The only valid characters are the decimal digits 0 through 9.
+type Num string
+
+func (s Num) String() string {
+	return fmt.Sprintf("Num(%#q)", string(s))
+}
+
+func (s Num) Check() error {
+	for _, c := range s {
+		if c < '0' || '9' < c {
+			return fmt.Errorf("non-numeric string %#q", string(s))
+		}
+	}
+	return nil
+}
+
+var numLen = [3]int{10, 12, 14}
+
+func (s Num) Bits(v Version) int {
+	return 4 + numLen[v.sizeClass()] + (10*len(s)+2)/3
+}
+
+func (s Num) Encode(b *Bits, v Version) {
+	b.Write(1, 4)
+	b.Write(uint(len(s)), numLen[v.sizeClass()])
+	var i int
+	for i = 0; i+3 <= len(s); i += 3 {
+		w := uint(s[i]-'0')*100 + uint(s[i+1]-'0')*10 + uint(s[i+2]-'0')
+		b.Write(w, 10)
+	}
+	switch len(s) - i {
+	case 1:
+		w := uint(s[i] - '0')
+		b.Write(w, 4)
+	case 2:
+		w := uint(s[i]-'0')*10 + uint(s[i+1]-'0')
+		b.Write(w, 7)
+	}
+}
+
+// Alpha is the encoding for alphanumeric data.
+// The valid characters are 0-9A-Z$%*+-./: and space.
+type Alpha string
+
+const alphabet = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ $%*+-./:"
+
+func (s Alpha) String() string {
+	return fmt.Sprintf("Alpha(%#q)", string(s))
+}
+
+func (s Alpha) Check() error {
+	for _, c := range s {
+		if strings.IndexRune(alphabet, c) < 0 {
+			return fmt.Errorf("non-alphanumeric string %#q", string(s))
+		}
+	}
+	return nil
+}
+
+var alphaLen = [3]int{9, 11, 13}
+
+func (s Alpha) Bits(v Version) int {
+	return 4 + alphaLen[v.sizeClass()] + (11*len(s)+1)/2
+}
+
+func (s Alpha) Encode(b *Bits, v Version) {
+	b.Write(2, 4)
+	b.Write(uint(len(s)), alphaLen[v.sizeClass()])
+	var i int
+	for i = 0; i+2 <= len(s); i += 2 {
+		w := uint(strings.IndexRune(alphabet, rune(s[i])))*45 +
+			uint(strings.IndexRune(alphabet, rune(s[i+1])))
+		b.Write(w, 11)
+	}
+
+	if i < len(s) {
+		w := uint(strings.IndexRune(alphabet, rune(s[i])))
+		b.Write(w, 6)
+	}
+}
+
+// String is the encoding for 8-bit data.  All bytes are valid.
+type String string
+
+func (s String) String() string {
+	return fmt.Sprintf("String(%#q)", string(s))
+}
+
+func (s String) Check() error {
+	return nil
+}
+
+var stringLen = [3]int{8, 16, 16}
+
+func (s String) Bits(v Version) int {
+	return 4 + stringLen[v.sizeClass()] + 8*len(s)
+}
+
+func (s String) Encode(b *Bits, v Version) {
+	b.Write(4, 4)
+	b.Write(uint(len(s)), stringLen[v.sizeClass()])
+	for i := 0; i < len(s); i++ {
+		b.Write(uint(s[i]), 8)
+	}
+}
+
+// A Pixel describes a single pixel in a QR code.
+type Pixel uint32
+
+const (
+	Black Pixel = 1 << iota
+	Invert
+)
+
+func (p Pixel) Offset() uint {
+	return uint(p >> 6)
+}
+
+func OffsetPixel(o uint) Pixel {
+	return Pixel(o << 6)
+}
+
+func (r PixelRole) Pixel() Pixel {
+	return Pixel(r << 2)
+}
+
+func (p Pixel) Role() PixelRole {
+	return PixelRole(p>>2) & 15
+}
+
+func (p Pixel) String() string {
+	s := p.Role().String()
+	if p&Black != 0 {
+		s += "+black"
+	}
+	if p&Invert != 0 {
+		s += "+invert"
+	}
+	s += "+" + strconv.FormatUint(uint64(p.Offset()), 10)
+	return s
+}
+
+// A PixelRole describes the role of a QR pixel.
+type PixelRole uint32
+
+const (
+	_         PixelRole = iota
+	Position            // position squares (large)
+	Alignment           // alignment squares (small)
+	Timing              // timing strip between position squares
+	Format              // format metadata
+	PVersion            // version pattern
+	Unused              // unused pixel
+	Data                // data bit
+	Check               // error correction check bit
+	Extra
+)
+
+var roles = []string{
+	"",
+	"position",
+	"alignment",
+	"timing",
+	"format",
+	"pversion",
+	"unused",
+	"data",
+	"check",
+	"extra",
+}
+
+func (r PixelRole) String() string {
+	if Position <= r && r <= Check {
+		return roles[r]
+	}
+	return strconv.Itoa(int(r))
+}
+
+// A Level represents a QR error correction level.
+// From least to most tolerant of errors, they are L, M, Q, H.
+type Level int
+
+const (
+	L Level = iota
+	M
+	Q
+	H
+)
+
+func (l Level) String() string {
+	if L <= l && l <= H {
+		return "LMQH"[l : l+1]
+	}
+	return strconv.Itoa(int(l))
+}
+
+// A Code is a square pixel grid.
+type Code struct {
+	Bitmap []byte // 1 is black, 0 is white
+	Size   int    // number of pixels on a side
+	Stride int    // number of bytes per row
+}
+
+func (c *Code) Black(x, y int) bool {
+	return 0 <= x && x < c.Size && 0 <= y && y < c.Size &&
+		c.Bitmap[y*c.Stride+x/8]&(1<<uint(7-x&7)) != 0
+}
+
+// A Mask describes a mask that is applied to the QR
+// code to avoid QR artifacts being interpreted as
+// alignment and timing patterns (such as the squares
+// in the corners).  Valid masks are integers from 0 to 7.
+type Mask int
+
+// http://www.swetake.com/qr/qr5_en.html
+var mfunc = []func(int, int) bool{
+	func(i, j int) bool { return (i+j)%2 == 0 },
+	func(i, j int) bool { return i%2 == 0 },
+	func(i, j int) bool { return j%3 == 0 },
+	func(i, j int) bool { return (i+j)%3 == 0 },
+	func(i, j int) bool { return (i/2+j/3)%2 == 0 },
+	func(i, j int) bool { return i*j%2+i*j%3 == 0 },
+	func(i, j int) bool { return (i*j%2+i*j%3)%2 == 0 },
+	func(i, j int) bool { return (i*j%3+(i+j)%2)%2 == 0 },
+}
+
+func (m Mask) Invert(y, x int) bool {
+	if m < 0 {
+		return false
+	}
+	return mfunc[m](y, x)
+}
+
+// A Plan describes how to construct a QR code
+// with a specific version, level, and mask.
+type Plan struct {
+	Version Version
+	Level   Level
+	Mask    Mask
+
+	DataBytes  int // number of data bytes
+	CheckBytes int // number of error correcting (checksum) bytes
+	Blocks     int // number of data blocks
+
+	Pixel [][]Pixel // pixel map
+}
+
+// NewPlan returns a Plan for a QR code with the given
+// version, level, and mask.
+func NewPlan(version Version, level Level, mask Mask) (*Plan, error) {
+	p, err := vplan(version)
+	if err != nil {
+		return nil, err
+	}
+	if err := fplan(level, mask, p); err != nil {
+		return nil, err
+	}
+	if err := lplan(version, level, p); err != nil {
+		return nil, err
+	}
+	if err := mplan(mask, p); err != nil {
+		return nil, err
+	}
+	return p, nil
+}
+
+func (b *Bits) Pad(n int) {
+	if n < 0 {
+		panic("qr: invalid pad size")
+	}
+	if n <= 4 {
+		b.Write(0, n)
+	} else {
+		b.Write(0, 4)
+		n -= 4
+		n -= -b.Bits() & 7
+		b.Write(0, -b.Bits()&7)
+		pad := n / 8
+		for i := 0; i < pad; i += 2 {
+			b.Write(0xec, 8)
+			if i+1 >= pad {
+				break
+			}
+			b.Write(0x11, 8)
+		}
+	}
+}
+
+func (b *Bits) AddCheckBytes(v Version, l Level) {
+	nd := v.DataBytes(l)
+	if b.nbit < nd*8 {
+		b.Pad(nd*8 - b.nbit)
+	}
+	if b.nbit != nd*8 {
+		panic("qr: too much data")
+	}
+
+	dat := b.Bytes()
+	vt := &vtab[v]
+	lev := &vt.level[l]
+	db := nd / lev.nblock
+	extra := nd % lev.nblock
+	chk := make([]byte, lev.check)
+	rs := gf256.NewRSEncoder(Field, lev.check)
+	for i := 0; i < lev.nblock; i++ {
+		if i == lev.nblock-extra {
+			db++
+		}
+		rs.ECC(dat[:db], chk)
+		b.Append(chk)
+		dat = dat[db:]
+	}
+
+	if len(b.Bytes()) != vt.bytes {
+		panic("qr: internal error")
+	}
+}
+
+func (p *Plan) Encode(text ...Encoding) (*Code, error) {
+	var b Bits
+	for _, t := range text {
+		if err := t.Check(); err != nil {
+			return nil, err
+		}
+		t.Encode(&b, p.Version)
+	}
+	if b.Bits() > p.DataBytes*8 {
+		return nil, fmt.Errorf("cannot encode %d bits into %d-bit code", b.Bits(), p.DataBytes*8)
+	}
+	b.AddCheckBytes(p.Version, p.Level)
+	bytes := b.Bytes()
+
+	// Now we have the checksum bytes and the data bytes.
+	// Construct the actual code.
+	c := &Code{Size: len(p.Pixel), Stride: (len(p.Pixel) + 7) &^ 7}
+	c.Bitmap = make([]byte, c.Stride*c.Size)
+	crow := c.Bitmap
+	for _, row := range p.Pixel {
+		for x, pix := range row {
+			switch pix.Role() {
+			case Data, Check:
+				o := pix.Offset()
+				if bytes[o/8]&(1<<uint(7-o&7)) != 0 {
+					pix ^= Black
+				}
+			}
+			if pix&Black != 0 {
+				crow[x/8] |= 1 << uint(7-x&7)
+			}
+		}
+		crow = crow[c.Stride:]
+	}
+	return c, nil
+}
+
+// A version describes metadata associated with a version.
+type version struct {
+	apos    int
+	astride int
+	bytes   int
+	pattern int
+	level   [4]level
+}
+
+type level struct {
+	nblock int
+	check  int
+}
+
+var vtab = []version{
+	{},
+	{100, 100, 26, 0x0, [4]level{{1, 7}, {1, 10}, {1, 13}, {1, 17}}},          // 1
+	{16, 100, 44, 0x0, [4]level{{1, 10}, {1, 16}, {1, 22}, {1, 28}}},          // 2
+	{20, 100, 70, 0x0, [4]level{{1, 15}, {1, 26}, {2, 18}, {2, 22}}},          // 3
+	{24, 100, 100, 0x0, [4]level{{1, 20}, {2, 18}, {2, 26}, {4, 16}}},         // 4
+	{28, 100, 134, 0x0, [4]level{{1, 26}, {2, 24}, {4, 18}, {4, 22}}},         // 5
+	{32, 100, 172, 0x0, [4]level{{2, 18}, {4, 16}, {4, 24}, {4, 28}}},         // 6
+	{20, 16, 196, 0x7c94, [4]level{{2, 20}, {4, 18}, {6, 18}, {5, 26}}},       // 7
+	{22, 18, 242, 0x85bc, [4]level{{2, 24}, {4, 22}, {6, 22}, {6, 26}}},       // 8
+	{24, 20, 292, 0x9a99, [4]level{{2, 30}, {5, 22}, {8, 20}, {8, 24}}},       // 9
+	{26, 22, 346, 0xa4d3, [4]level{{4, 18}, {5, 26}, {8, 24}, {8, 28}}},       // 10
+	{28, 24, 404, 0xbbf6, [4]level{{4, 20}, {5, 30}, {8, 28}, {11, 24}}},      // 11
+	{30, 26, 466, 0xc762, [4]level{{4, 24}, {8, 22}, {10, 26}, {11, 28}}},     // 12
+	{32, 28, 532, 0xd847, [4]level{{4, 26}, {9, 22}, {12, 24}, {16, 22}}},     // 13
+	{24, 20, 581, 0xe60d, [4]level{{4, 30}, {9, 24}, {16, 20}, {16, 24}}},     // 14
+	{24, 22, 655, 0xf928, [4]level{{6, 22}, {10, 24}, {12, 30}, {18, 24}}},    // 15
+	{24, 24, 733, 0x10b78, [4]level{{6, 24}, {10, 28}, {17, 24}, {16, 30}}},   // 16
+	{28, 24, 815, 0x1145d, [4]level{{6, 28}, {11, 28}, {16, 28}, {19, 28}}},   // 17
+	{28, 26, 901, 0x12a17, [4]level{{6, 30}, {13, 26}, {18, 28}, {21, 28}}},   // 18
+	{28, 28, 991, 0x13532, [4]level{{7, 28}, {14, 26}, {21, 26}, {25, 26}}},   // 19
+	{32, 28, 1085, 0x149a6, [4]level{{8, 28}, {16, 26}, {20, 30}, {25, 28}}},  // 20
+	{26, 22, 1156, 0x15683, [4]level{{8, 28}, {17, 26}, {23, 28}, {25, 30}}},  // 21
+	{24, 24, 1258, 0x168c9, [4]level{{9, 28}, {17, 28}, {23, 30}, {34, 24}}},  // 22
+	{28, 24, 1364, 0x177ec, [4]level{{9, 30}, {18, 28}, {25, 30}, {30, 30}}},  // 23
+	{26, 26, 1474, 0x18ec4, [4]level{{10, 30}, {20, 28}, {27, 30}, {32, 30}}}, // 24
+	{30, 26, 1588, 0x191e1, [4]level{{12, 26}, {21, 28}, {29, 30}, {35, 30}}}, // 25
+	{28, 28, 1706, 0x1afab, [4]level{{12, 28}, {23, 28}, {34, 28}, {37, 30}}}, // 26
+	{32, 28, 1828, 0x1b08e, [4]level{{12, 30}, {25, 28}, {34, 30}, {40, 30}}}, // 27
+	{24, 24, 1921, 0x1cc1a, [4]level{{13, 30}, {26, 28}, {35, 30}, {42, 30}}}, // 28
+	{28, 24, 2051, 0x1d33f, [4]level{{14, 30}, {28, 28}, {38, 30}, {45, 30}}}, // 29
+	{24, 26, 2185, 0x1ed75, [4]level{{15, 30}, {29, 28}, {40, 30}, {48, 30}}}, // 30
+	{28, 26, 2323, 0x1f250, [4]level{{16, 30}, {31, 28}, {43, 30}, {51, 30}}}, // 31
+	{32, 26, 2465, 0x209d5, [4]level{{17, 30}, {33, 28}, {45, 30}, {54, 30}}}, // 32
+	{28, 28, 2611, 0x216f0, [4]level{{18, 30}, {35, 28}, {48, 30}, {57, 30}}}, // 33
+	{32, 28, 2761, 0x228ba, [4]level{{19, 30}, {37, 28}, {51, 30}, {60, 30}}}, // 34
+	{28, 24, 2876, 0x2379f, [4]level{{19, 30}, {38, 28}, {53, 30}, {63, 30}}}, // 35
+	{22, 26, 3034, 0x24b0b, [4]level{{20, 30}, {40, 28}, {56, 30}, {66, 30}}}, // 36
+	{26, 26, 3196, 0x2542e, [4]level{{21, 30}, {43, 28}, {59, 30}, {70, 30}}}, // 37
+	{30, 26, 3362, 0x26a64, [4]level{{22, 30}, {45, 28}, {62, 30}, {74, 30}}}, // 38
+	{24, 28, 3532, 0x27541, [4]level{{24, 30}, {47, 28}, {65, 30}, {77, 30}}}, // 39
+	{28, 28, 3706, 0x28c69, [4]level{{25, 30}, {49, 28}, {68, 30}, {81, 30}}}, // 40
+}
+
+func grid(siz int) [][]Pixel {
+	m := make([][]Pixel, siz)
+	pix := make([]Pixel, siz*siz)
+	for i := range m {
+		m[i], pix = pix[:siz], pix[siz:]
+	}
+	return m
+}
+
+// vplan creates a Plan for the given version.
+func vplan(v Version) (*Plan, error) {
+	p := &Plan{Version: v}
+	if v < 1 || v > 40 {
+		return nil, fmt.Errorf("invalid QR version %d", int(v))
+	}
+	siz := 17 + int(v)*4
+	m := grid(siz)
+	p.Pixel = m
+
+	// Timing markers (overwritten by boxes).
+	const ti = 6 // timing is in row/column 6 (counting from 0)
+	for i := range m {
+		p := Timing.Pixel()
+		if i&1 == 0 {
+			p |= Black
+		}
+		m[i][ti] = p
+		m[ti][i] = p
+	}
+
+	// Position boxes.
+	posBox(m, 0, 0)
+	posBox(m, siz-7, 0)
+	posBox(m, 0, siz-7)
+
+	// Alignment boxes.
+	info := &vtab[v]
+	for x := 4; x+5 < siz; {
+		for y := 4; y+5 < siz; {
+			// don't overwrite timing markers
+			if (x < 7 && y < 7) || (x < 7 && y+5 >= siz-7) || (x+5 >= siz-7 && y < 7) {
+			} else {
+				alignBox(m, x, y)
+			}
+			if y == 4 {
+				y = info.apos
+			} else {
+				y += info.astride
+			}
+		}
+		if x == 4 {
+			x = info.apos
+		} else {
+			x += info.astride
+		}
+	}
+
+	// Version pattern.
+	pat := vtab[v].pattern
+	if pat != 0 {
+		v := pat
+		for x := 0; x < 6; x++ {
+			for y := 0; y < 3; y++ {
+				p := PVersion.Pixel()
+				if v&1 != 0 {
+					p |= Black
+				}
+				m[siz-11+y][x] = p
+				m[x][siz-11+y] = p
+				v >>= 1
+			}
+		}
+	}
+
+	// One lonely black pixel
+	m[siz-8][8] = Unused.Pixel() | Black
+
+	return p, nil
+}
+
+// fplan adds the format pixels
+func fplan(l Level, m Mask, p *Plan) error {
+	// Format pixels.
+	fb := uint32(l^1) << 13 // level: L=01, M=00, Q=11, H=10
+	fb |= uint32(m) << 10   // mask
+	const formatPoly = 0x537
+	rem := fb
+	for i := 14; i >= 10; i-- {
+		if rem&(1<<uint(i)) != 0 {
+			rem ^= formatPoly << uint(i-10)
+		}
+	}
+	fb |= rem
+	invert := uint32(0x5412)
+	siz := len(p.Pixel)
+	for i := uint(0); i < 15; i++ {
+		pix := Format.Pixel() + OffsetPixel(i)
+		if (fb>>i)&1 == 1 {
+			pix |= Black
+		}
+		if (invert>>i)&1 == 1 {
+			pix ^= Invert | Black
+		}
+		// top left
+		switch {
+		case i < 6:
+			p.Pixel[i][8] = pix
+		case i < 8:
+			p.Pixel[i+1][8] = pix
+		case i < 9:
+			p.Pixel[8][7] = pix
+		default:
+			p.Pixel[8][14-i] = pix
+		}
+		// bottom right
+		switch {
+		case i < 8:
+			p.Pixel[8][siz-1-int(i)] = pix
+		default:
+			p.Pixel[siz-1-int(14-i)][8] = pix
+		}
+	}
+	return nil
+}
+
+// lplan edits a version-only Plan to add information
+// about the error correction levels.
+func lplan(v Version, l Level, p *Plan) error {
+	p.Level = l
+
+	nblock := vtab[v].level[l].nblock
+	ne := vtab[v].level[l].check
+	nde := (vtab[v].bytes - ne*nblock) / nblock
+	extra := (vtab[v].bytes - ne*nblock) % nblock
+	dataBits := (nde*nblock + extra) * 8
+	checkBits := ne * nblock * 8
+
+	p.DataBytes = vtab[v].bytes - ne*nblock
+	p.CheckBytes = ne * nblock
+	p.Blocks = nblock
+
+	// Make data + checksum pixels.
+	data := make([]Pixel, dataBits)
+	for i := range data {
+		data[i] = Data.Pixel() | OffsetPixel(uint(i))
+	}
+	check := make([]Pixel, checkBits)
+	for i := range check {
+		check[i] = Check.Pixel() | OffsetPixel(uint(i+dataBits))
+	}
+
+	// Split into blocks.
+	dataList := make([][]Pixel, nblock)
+	checkList := make([][]Pixel, nblock)
+	for i := 0; i < nblock; i++ {
+		// The last few blocks have an extra data byte (8 pixels).
+		nd := nde
+		if i >= nblock-extra {
+			nd++
+		}
+		dataList[i], data = data[0:nd*8], data[nd*8:]
+		checkList[i], check = check[0:ne*8], check[ne*8:]
+	}
+	if len(data) != 0 || len(check) != 0 {
+		panic("data/check math")
+	}
+
+	// Build up bit sequence, taking first byte of each block,
+	// then second byte, and so on.  Then checksums.
+	bits := make([]Pixel, dataBits+checkBits)
+	dst := bits
+	for i := 0; i < nde+1; i++ {
+		for _, b := range dataList {
+			if i*8 < len(b) {
+				copy(dst, b[i*8:(i+1)*8])
+				dst = dst[8:]
+			}
+		}
+	}
+	for i := 0; i < ne; i++ {
+		for _, b := range checkList {
+			if i*8 < len(b) {
+				copy(dst, b[i*8:(i+1)*8])
+				dst = dst[8:]
+			}
+		}
+	}
+	if len(dst) != 0 {
+		panic("dst math")
+	}
+
+	// Sweep up pair of columns,
+	// then down, assigning to right then left pixel.
+	// Repeat.
+	// See Figure 2 of http://www.pclviewer.com/rs2/qrtopology.htm
+	siz := len(p.Pixel)
+	rem := make([]Pixel, 7)
+	for i := range rem {
+		rem[i] = Extra.Pixel()
+	}
+	src := append(bits, rem...)
+	for x := siz; x > 0; {
+		for y := siz - 1; y >= 0; y-- {
+			if p.Pixel[y][x-1].Role() == 0 {
+				p.Pixel[y][x-1], src = src[0], src[1:]
+			}
+			if p.Pixel[y][x-2].Role() == 0 {
+				p.Pixel[y][x-2], src = src[0], src[1:]
+			}
+		}
+		x -= 2
+		if x == 7 { // vertical timing strip
+			x--
+		}
+		for y := 0; y < siz; y++ {
+			if p.Pixel[y][x-1].Role() == 0 {
+				p.Pixel[y][x-1], src = src[0], src[1:]
+			}
+			if p.Pixel[y][x-2].Role() == 0 {
+				p.Pixel[y][x-2], src = src[0], src[1:]
+			}
+		}
+		x -= 2
+	}
+	return nil
+}
+
+// mplan edits a version+level-only Plan to add the mask.
+func mplan(m Mask, p *Plan) error {
+	p.Mask = m
+	for y, row := range p.Pixel {
+		for x, pix := range row {
+			if r := pix.Role(); (r == Data || r == Check || r == Extra) && p.Mask.Invert(y, x) {
+				row[x] ^= Black | Invert
+			}
+		}
+	}
+	return nil
+}
+
+// posBox draws a position (large) box at upper left x, y.
+func posBox(m [][]Pixel, x, y int) {
+	pos := Position.Pixel()
+	// box
+	for dy := 0; dy < 7; dy++ {
+		for dx := 0; dx < 7; dx++ {
+			p := pos
+			if dx == 0 || dx == 6 || dy == 0 || dy == 6 || 2 <= dx && dx <= 4 && 2 <= dy && dy <= 4 {
+				p |= Black
+			}
+			m[y+dy][x+dx] = p
+		}
+	}
+	// white border
+	for dy := -1; dy < 8; dy++ {
+		if 0 <= y+dy && y+dy < len(m) {
+			if x > 0 {
+				m[y+dy][x-1] = pos
+			}
+			if x+7 < len(m) {
+				m[y+dy][x+7] = pos
+			}
+		}
+	}
+	for dx := -1; dx < 8; dx++ {
+		if 0 <= x+dx && x+dx < len(m) {
+			if y > 0 {
+				m[y-1][x+dx] = pos
+			}
+			if y+7 < len(m) {
+				m[y+7][x+dx] = pos
+			}
+		}
+	}
+}
+
+// alignBox draw an alignment (small) box at upper left x, y.
+func alignBox(m [][]Pixel, x, y int) {
+	// box
+	align := Alignment.Pixel()
+	for dy := 0; dy < 5; dy++ {
+		for dx := 0; dx < 5; dx++ {
+			p := align
+			if dx == 0 || dx == 4 || dy == 0 || dy == 4 || dx == 2 && dy == 2 {
+				p |= Black
+			}
+			m[y+dy][x+dx] = p
+		}
+	}
+}

+ 133 - 0
github.com/SKatiyar/qr/coding/qr_test.go

@@ -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"
+
+	"github.com/SKatiyar/qr/gf256"
+	"github.com/SKatiyar/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)
+	}
+}

+ 85 - 0
github.com/SKatiyar/qr/gf256/blog_test.go

@@ -0,0 +1,85 @@
+// 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.
+
+// This file contains a straightforward implementation of
+// Reed-Solomon encoding, along with a benchmark.
+// It goes with http://research.swtch.com/field.
+//
+// For an optimized implementation, see gf256.go.
+
+package gf256
+
+import (
+	"bytes"
+	"fmt"
+	"testing"
+)
+
+// BlogECC writes to check the error correcting code bytes
+// for data using the given Reed-Solomon parameters.
+func BlogECC(rs *RSEncoder, m []byte, check []byte) {
+	if len(check) < rs.c {
+		panic("gf256: invalid check byte length")
+	}
+	if rs.c == 0 {
+		return
+	}
+
+	// The check bytes are the remainder after dividing
+	// data padded with c zeros by the generator polynomial.
+
+	// p = data padded with c zeros.
+	var p []byte
+	n := len(m) + rs.c
+	if len(rs.p) >= n {
+		p = rs.p
+	} else {
+		p = make([]byte, n)
+	}
+	copy(p, m)
+	for i := len(m); i < len(p); i++ {
+		p[i] = 0
+	}
+
+	gen := rs.gen
+
+	// Divide p by gen, leaving the remainder in p[len(data):].
+	// p[0] is the most significant term in p, and
+	// gen[0] is the most significant term in the generator.
+	for i := 0; i < len(m); i++ {
+		k := f.Mul(p[i], f.Inv(gen[0])) // k = pi / g0
+		// p -= k·g
+		for j, g := range gen {
+			p[i+j] = f.Add(p[i+j], f.Mul(k, g))
+		}
+	}
+
+	copy(check, p[len(m):])
+	rs.p = p
+}
+
+func BenchmarkBlogECC(b *testing.B) {
+	data := []byte{0x10, 0x20, 0x0c, 0x56, 0x61, 0x80, 0xec, 0x11, 0xec, 0x11, 0xec, 0x11, 0xec, 0x11, 0xec, 0x11, 0x10, 0x20, 0x0c, 0x56, 0x61, 0x80, 0xec, 0x11, 0xec, 0x11, 0xec, 0x11, 0xec, 0x11, 0xec, 0x11}
+	check := []byte{0x29, 0x41, 0xb3, 0x93, 0x8, 0xe8, 0xa3, 0xe7, 0x63, 0x8f}
+	out := make([]byte, len(check))
+	rs := NewRSEncoder(f, len(check))
+	for i := 0; i < b.N; i++ {
+		BlogECC(rs, data, out)
+	}
+	b.SetBytes(int64(len(data)))
+	if !bytes.Equal(out, check) {
+		fmt.Printf("have %#v want %#v\n", out, check)
+	}
+}
+
+func TestBlogECC(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}
+	out := make([]byte, len(check))
+	rs := NewRSEncoder(f, len(check))
+	BlogECC(rs, data, out)
+	if !bytes.Equal(out, check) {
+		t.Errorf("have %x want %x", out, check)
+	}
+}

+ 241 - 0
github.com/SKatiyar/qr/gf256/gf256.go

@@ -0,0 +1,241 @@
+// Copyright 2010 The Go Authors.  All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Package gf256 implements arithmetic over the Galois Field GF(256).
+package gf256
+
+import "strconv"
+
+// A Field represents an instance of GF(256) defined by a specific polynomial.
+type Field struct {
+	log [256]byte // log[0] is unused
+	exp [510]byte
+}
+
+// NewField returns a new field corresponding to the polynomial poly
+// and generator α.  The Reed-Solomon encoding in QR codes uses
+// polynomial 0x11d with generator 2.
+//
+// The choice of generator α only affects the Exp and Log operations.
+func NewField(poly, α int) *Field {
+	if poly < 0x100 || poly >= 0x200 || reducible(poly) {
+		panic("gf256: invalid polynomial: " + strconv.Itoa(poly))
+	}
+
+	var f Field
+	x := 1
+	for i := 0; i < 255; i++ {
+		if x == 1 && i != 0 {
+			panic("gf256: invalid generator " + strconv.Itoa(α) +
+				" for polynomial " + strconv.Itoa(poly))
+		}
+		f.exp[i] = byte(x)
+		f.exp[i+255] = byte(x)
+		f.log[x] = byte(i)
+		x = mul(x, α, poly)
+	}
+	f.log[0] = 255
+	for i := 0; i < 255; i++ {
+		if f.log[f.exp[i]] != byte(i) {
+			panic("bad log")
+		}
+		if f.log[f.exp[i+255]] != byte(i) {
+			panic("bad log")
+		}
+	}
+	for i := 1; i < 256; i++ {
+		if f.exp[f.log[i]] != byte(i) {
+			panic("bad log")
+		}
+	}
+
+	return &f
+}
+
+// nbit returns the number of significant in p.
+func nbit(p int) uint {
+	n := uint(0)
+	for ; p > 0; p >>= 1 {
+		n++
+	}
+	return n
+}
+
+// polyDiv divides the polynomial p by q and returns the remainder.
+func polyDiv(p, q int) int {
+	np := nbit(p)
+	nq := nbit(q)
+	for ; np >= nq; np-- {
+		if p&(1<<(np-1)) != 0 {
+			p ^= q << (np - nq)
+		}
+	}
+	return p
+}
+
+// mul returns the product x*y mod poly, a GF(256) multiplication.
+func mul(x, y, poly int) int {
+	z := 0
+	for x > 0 {
+		if x&1 != 0 {
+			z ^= y
+		}
+		x >>= 1
+		y <<= 1
+		if y&0x100 != 0 {
+			y ^= poly
+		}
+	}
+	return z
+}
+
+// reducible reports whether p is reducible.
+func reducible(p int) bool {
+	// Multiplying n-bit * n-bit produces (2n-1)-bit,
+	// so if p is reducible, one of its factors must be
+	// of np/2+1 bits or fewer.
+	np := nbit(p)
+	for q := 2; q < 1<<(np/2+1); q++ {
+		if polyDiv(p, q) == 0 {
+			return true
+		}
+	}
+	return false
+}
+
+// Add returns the sum of x and y in the field.
+func (f *Field) Add(x, y byte) byte {
+	return x ^ y
+}
+
+// Exp returns the base-α exponential of e in the field.
+// If e < 0, Exp returns 0.
+func (f *Field) Exp(e int) byte {
+	if e < 0 {
+		return 0
+	}
+	return f.exp[e%255]
+}
+
+// Log returns the base-α logarithm of x in the field.
+// If x == 0, Log returns -1.
+func (f *Field) Log(x byte) int {
+	if x == 0 {
+		return -1
+	}
+	return int(f.log[x])
+}
+
+// Inv returns the multiplicative inverse of x in the field.
+// If x == 0, Inv returns 0.
+func (f *Field) Inv(x byte) byte {
+	if x == 0 {
+		return 0
+	}
+	return f.exp[255-f.log[x]]
+}
+
+// Mul returns the product of x and y in the field.
+func (f *Field) Mul(x, y byte) byte {
+	if x == 0 || y == 0 {
+		return 0
+	}
+	return f.exp[int(f.log[x])+int(f.log[y])]
+}
+
+// An RSEncoder implements Reed-Solomon encoding
+// over a given field using a given number of error correction bytes.
+type RSEncoder struct {
+	f    *Field
+	c    int
+	gen  []byte
+	lgen []byte
+	p    []byte
+}
+
+func (f *Field) gen(e int) (gen, lgen []byte) {
+	// p = 1
+	p := make([]byte, e+1)
+	p[e] = 1
+
+	for i := 0; i < e; i++ {
+		// p *= (x + Exp(i))
+		// p[j] = p[j]*Exp(i) + p[j+1].
+		c := f.Exp(i)
+		for j := 0; j < e; j++ {
+			p[j] = f.Mul(p[j], c) ^ p[j+1]
+		}
+		p[e] = f.Mul(p[e], c)
+	}
+
+	// lp = log p.
+	lp := make([]byte, e+1)
+	for i, c := range p {
+		if c == 0 {
+			lp[i] = 255
+		} else {
+			lp[i] = byte(f.Log(c))
+		}
+	}
+
+	return p, lp
+}
+
+// NewRSEncoder returns a new Reed-Solomon encoder
+// over the given field and number of error correction bytes.
+func NewRSEncoder(f *Field, c int) *RSEncoder {
+	gen, lgen := f.gen(c)
+	return &RSEncoder{f: f, c: c, gen: gen, lgen: lgen}
+}
+
+// ECC writes to check the error correcting code bytes
+// for data using the given Reed-Solomon parameters.
+func (rs *RSEncoder) ECC(data []byte, check []byte) {
+	if len(check) < rs.c {
+		panic("gf256: invalid check byte length")
+	}
+	if rs.c == 0 {
+		return
+	}
+
+	// The check bytes are the remainder after dividing
+	// data padded with c zeros by the generator polynomial.
+
+	// p = data padded with c zeros.
+	var p []byte
+	n := len(data) + rs.c
+	if len(rs.p) >= n {
+		p = rs.p
+	} else {
+		p = make([]byte, n)
+	}
+	copy(p, data)
+	for i := len(data); i < len(p); i++ {
+		p[i] = 0
+	}
+
+	// Divide p by gen, leaving the remainder in p[len(data):].
+	// p[0] is the most significant term in p, and
+	// gen[0] is the most significant term in the generator,
+	// which is always 1.
+	// To avoid repeated work, we store various values as
+	// lv, not v, where lv = log[v].
+	f := rs.f
+	lgen := rs.lgen[1:]
+	for i := 0; i < len(data); i++ {
+		c := p[i]
+		if c == 0 {
+			continue
+		}
+		q := p[i+1:]
+		exp := f.exp[f.log[c]:]
+		for j, lg := range lgen {
+			if lg != 255 { // lgen uses 255 for log 0
+				q[j] ^= exp[lg]
+			}
+		}
+	}
+	copy(check, p[len(data):])
+	rs.p = p
+}

+ 194 - 0
github.com/SKatiyar/qr/gf256/gf256_test.go

@@ -0,0 +1,194 @@
+// Copyright 2010 The Go Authors.  All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package gf256
+
+import (
+	"bytes"
+	"fmt"
+	"testing"
+)
+
+var f = NewField(0x11d, 2) // x^8 + x^4 + x^3 + x^2 + 1
+
+func TestBasic(t *testing.T) {
+	if f.Exp(0) != 1 || f.Exp(1) != 2 || f.Exp(255) != 1 {
+		panic("bad Exp")
+	}
+}
+
+func TestECC(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}
+	out := make([]byte, len(check))
+	rs := NewRSEncoder(f, len(check))
+	rs.ECC(data, out)
+	if !bytes.Equal(out, check) {
+		t.Errorf("have %x want %x", out, check)
+	}
+}
+
+func TestLinear(t *testing.T) {
+	d1 := []byte{0x00, 0x00}
+	c1 := []byte{0x00, 0x00}
+	out := make([]byte, len(c1))
+	rs := NewRSEncoder(f, len(c1))
+	if rs.ECC(d1, out); !bytes.Equal(out, c1) {
+		t.Errorf("ECBytes(%x, %d) = %x, want 0", d1, len(c1), out)
+	}
+	d2 := []byte{0x00, 0x01}
+	c2 := make([]byte, 2)
+	rs.ECC(d2, c2)
+	d3 := []byte{0x00, 0x02}
+	c3 := make([]byte, 2)
+	rs.ECC(d3, c3)
+	cx := make([]byte, 2)
+	for i := range cx {
+		cx[i] = c2[i] ^ c3[i]
+	}
+	d4 := []byte{0x00, 0x03}
+	c4 := make([]byte, 2)
+	rs.ECC(d4, c4)
+	if !bytes.Equal(cx, c4) {
+		t.Errorf("ECBytes(%x, 2) = %x\nECBytes(%x, 2) = %x\nxor = %x\nECBytes(%x, 2) = %x",
+			d2, c2, d3, c3, cx, d4, c4)
+	}
+}
+
+func TestGaussJordan(t *testing.T) {
+	rs := NewRSEncoder(f, 2)
+	m := make([][]byte, 16)
+	for i := range m {
+		m[i] = make([]byte, 4)
+		m[i][i/8] = 1 << uint(i%8)
+		rs.ECC(m[i][:2], m[i][2:])
+	}
+	if false {
+		fmt.Printf("---\n")
+		for _, row := range m {
+			fmt.Printf("%x\n", row)
+		}
+	}
+	b := []uint{0, 1, 2, 3, 12, 13, 14, 15, 20, 21, 22, 23, 24, 25, 26, 27}
+	for i := 0; i < 16; i++ {
+		bi := b[i]
+		if m[i][bi/8]&(1<<(7-bi%8)) == 0 {
+			for j := i + 1; ; j++ {
+				if j >= len(m) {
+					t.Errorf("lost track for %d", bi)
+					break
+				}
+				if m[j][bi/8]&(1<<(7-bi%8)) != 0 {
+					m[i], m[j] = m[j], m[i]
+					break
+				}
+			}
+		}
+		for j := i + 1; j < len(m); j++ {
+			if m[j][bi/8]&(1<<(7-bi%8)) != 0 {
+				for k := range m[j] {
+					m[j][k] ^= m[i][k]
+				}
+			}
+		}
+	}
+	if false {
+		fmt.Printf("---\n")
+		for _, row := range m {
+			fmt.Printf("%x\n", row)
+		}
+	}
+	for i := 15; i >= 0; i-- {
+		bi := b[i]
+		for j := i - 1; j >= 0; j-- {
+			if m[j][bi/8]&(1<<(7-bi%8)) != 0 {
+				for k := range m[j] {
+					m[j][k] ^= m[i][k]
+				}
+			}
+		}
+	}
+	if false {
+		fmt.Printf("---\n")
+		for _, row := range m {
+			fmt.Printf("%x", row)
+			out := make([]byte, 2)
+			if rs.ECC(row[:2], out); !bytes.Equal(out, row[2:]) {
+				fmt.Printf(" - want %x", out)
+			}
+			fmt.Printf("\n")
+		}
+	}
+}
+
+func BenchmarkECC(b *testing.B) {
+	data := []byte{0x10, 0x20, 0x0c, 0x56, 0x61, 0x80, 0xec, 0x11, 0xec, 0x11, 0xec, 0x11, 0xec, 0x11, 0xec, 0x11, 0x10, 0x20, 0x0c, 0x56, 0x61, 0x80, 0xec, 0x11, 0xec, 0x11, 0xec, 0x11, 0xec, 0x11, 0xec, 0x11}
+	check := []byte{0x29, 0x41, 0xb3, 0x93, 0x8, 0xe8, 0xa3, 0xe7, 0x63, 0x8f}
+	out := make([]byte, len(check))
+	rs := NewRSEncoder(f, len(check))
+	for i := 0; i < b.N; i++ {
+		rs.ECC(data, out)
+	}
+	b.SetBytes(int64(len(data)))
+	if !bytes.Equal(out, check) {
+		fmt.Printf("have %#v want %#v\n", out, check)
+	}
+}
+
+func TestGen(t *testing.T) {
+	for i := 0; i < 256; i++ {
+		_, lg := f.gen(i)
+		if lg[0] != 0 {
+			t.Errorf("#%d: %x", i, lg)
+		}
+	}
+}
+
+func TestReducible(t *testing.T) {
+	var count = []int{1, 2, 3, 6, 9, 18, 30, 56, 99, 186} // oeis.org/A1037
+	for i, want := range count {
+		n := 0
+		for p := 1 << uint(i+2); p < 1<<uint(i+3); p++ {
+			if !reducible(p) {
+				n++
+			}
+		}
+		if n != want {
+			t.Errorf("#reducible(%d-bit) = %d, want %d", i+2, n, want)
+		}
+	}
+}
+
+func TestExhaustive(t *testing.T) {
+	for poly := 0x100; poly < 0x200; poly++ {
+		if reducible(poly) {
+			continue
+		}
+		α := 2
+		for !generates(α, poly) {
+			α++
+		}
+		f := NewField(poly, α)
+		for p := 0; p < 256; p++ {
+			for q := 0; q < 256; q++ {
+				fm := int(f.Mul(byte(p), byte(q)))
+				pm := mul(p, q, poly)
+				if fm != pm {
+					t.Errorf("NewField(%#x).Mul(%#x, %#x) = %#x, want %#x", poly, p, q, fm, pm)
+				}
+			}
+		}
+	}
+}
+
+func generates(α, poly int) bool {
+	x := α
+	for i := 0; i < 254; i++ {
+		if x == 1 {
+			return false
+		}
+		x = mul(x, α, poly)
+	}
+	return true
+}

+ 149 - 0
github.com/SKatiyar/qr/libqrencode/qrencode.go

@@ -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
+}

+ 400 - 0
github.com/SKatiyar/qr/png.go

@@ -0,0 +1,400 @@
+// Copyright 2011 The Go Authors.  All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package qr
+
+// PNG writer for QR codes.
+
+import (
+	"bytes"
+	"encoding/binary"
+	"hash"
+	"hash/crc32"
+)
+
+// PNG returns a PNG image displaying the code.
+//
+// PNG uses a custom encoder tailored to QR codes.
+// Its compressed size is about 2x away from optimal,
+// but it runs about 20x faster than calling png.Encode
+// on c.Image().
+func (c *Code) PNG() []byte {
+	var p pngWriter
+	return p.encode(c)
+}
+
+type pngWriter struct {
+	tmp   [16]byte
+	wctmp [4]byte
+	buf   bytes.Buffer
+	zlib  bitWriter
+	crc   hash.Hash32
+}
+
+var pngHeader = []byte("\x89PNG\r\n\x1a\n")
+
+func (w *pngWriter) encode(c *Code) []byte {
+	scale := c.Scale
+	siz := c.Size
+
+	w.buf.Reset()
+
+	// Header
+	w.buf.Write(pngHeader)
+
+	// Header block
+	binary.BigEndian.PutUint32(w.tmp[0:4], uint32((siz+8)*scale))
+	binary.BigEndian.PutUint32(w.tmp[4:8], uint32((siz+8)*scale))
+	w.tmp[8] = 1 // 1-bit
+	w.tmp[9] = 0 // gray
+	w.tmp[10] = 0
+	w.tmp[11] = 0
+	w.tmp[12] = 0
+	w.writeChunk("IHDR", w.tmp[:13])
+
+	// Comment
+	w.writeChunk("tEXt", comment)
+
+	// Data
+	w.zlib.writeCode(c)
+	w.writeChunk("IDAT", w.zlib.bytes.Bytes())
+
+	// End
+	w.writeChunk("IEND", nil)
+
+	return w.buf.Bytes()
+}
+
+var comment = []byte("Software\x00QR-PNG http://qr.swtch.com/")
+
+func (w *pngWriter) writeChunk(name string, data []byte) {
+	if w.crc == nil {
+		w.crc = crc32.NewIEEE()
+	}
+	binary.BigEndian.PutUint32(w.wctmp[0:4], uint32(len(data)))
+	w.buf.Write(w.wctmp[0:4])
+	w.crc.Reset()
+	copy(w.wctmp[0:4], name)
+	w.buf.Write(w.wctmp[0:4])
+	w.crc.Write(w.wctmp[0:4])
+	w.buf.Write(data)
+	w.crc.Write(data)
+	crc := w.crc.Sum32()
+	binary.BigEndian.PutUint32(w.wctmp[0:4], crc)
+	w.buf.Write(w.wctmp[0:4])
+}
+
+func (b *bitWriter) writeCode(c *Code) {
+	const ftNone = 0
+
+	b.adler32.Reset()
+	b.bytes.Reset()
+	b.nbit = 0
+
+	scale := c.Scale
+	siz := c.Size
+
+	// zlib header
+	b.tmp[0] = 0x78
+	b.tmp[1] = 0
+	b.tmp[1] += uint8(31 - (uint16(b.tmp[0])<<8+uint16(b.tmp[1]))%31)
+	b.bytes.Write(b.tmp[0:2])
+
+	// Start flate block.
+	b.writeBits(1, 1, false) // final block
+	b.writeBits(1, 2, false) // compressed, fixed Huffman tables
+
+	// White border.
+	// First row.
+	b.byte(ftNone)
+	n := (scale*(siz+8) + 7) / 8
+	b.byte(255)
+	b.repeat(n-1, 1)
+	// 4*scale rows total.
+	b.repeat((4*scale-1)*(1+n), 1+n)
+
+	for i := 0; i < 4*scale; i++ {
+		b.adler32.WriteNByte(ftNone, 1)
+		b.adler32.WriteNByte(255, n)
+	}
+
+	row := make([]byte, 1+n)
+	for y := 0; y < siz; y++ {
+		row[0] = ftNone
+		j := 1
+		var z uint8
+		nz := 0
+		for x := -4; x < siz+4; x++ {
+			// Raw data.
+			for i := 0; i < scale; i++ {
+				z <<= 1
+				if !c.Black(x, y) {
+					z |= 1
+				}
+				if nz++; nz == 8 {
+					row[j] = z
+					j++
+					nz = 0
+				}
+			}
+		}
+		if j < len(row) {
+			row[j] = z
+		}
+		for _, z := range row {
+			b.byte(z)
+		}
+
+		// Scale-1 copies.
+		b.repeat((scale-1)*(1+n), 1+n)
+
+		b.adler32.WriteN(row, scale)
+	}
+
+	// White border.
+	// First row.
+	b.byte(ftNone)
+	b.byte(255)
+	b.repeat(n-1, 1)
+	// 4*scale rows total.
+	b.repeat((4*scale-1)*(1+n), 1+n)
+
+	for i := 0; i < 4*scale; i++ {
+		b.adler32.WriteNByte(ftNone, 1)
+		b.adler32.WriteNByte(255, n)
+	}
+
+	// End of block.
+	b.hcode(256)
+	b.flushBits()
+
+	// adler32
+	binary.BigEndian.PutUint32(b.tmp[0:], b.adler32.Sum32())
+	b.bytes.Write(b.tmp[0:4])
+}
+
+// A bitWriter is a write buffer for bit-oriented data like deflate.
+type bitWriter struct {
+	bytes bytes.Buffer
+	bit   uint32
+	nbit  uint
+
+	tmp     [4]byte
+	adler32 adigest
+}
+
+func (b *bitWriter) writeBits(bit uint32, nbit uint, rev bool) {
+	// reverse, for huffman codes
+	if rev {
+		br := uint32(0)
+		for i := uint(0); i < nbit; i++ {
+			br |= ((bit >> i) & 1) << (nbit - 1 - i)
+		}
+		bit = br
+	}
+	b.bit |= bit << b.nbit
+	b.nbit += nbit
+	for b.nbit >= 8 {
+		b.bytes.WriteByte(byte(b.bit))
+		b.bit >>= 8
+		b.nbit -= 8
+	}
+}
+
+func (b *bitWriter) flushBits() {
+	if b.nbit > 0 {
+		b.bytes.WriteByte(byte(b.bit))
+		b.nbit = 0
+		b.bit = 0
+	}
+}
+
+func (b *bitWriter) hcode(v int) {
+	/*
+	   Lit Value    Bits        Codes
+	   ---------    ----        -----
+	     0 - 143     8          00110000 through
+	                            10111111
+	   144 - 255     9          110010000 through
+	                            111111111
+	   256 - 279     7          0000000 through
+	                            0010111
+	   280 - 287     8          11000000 through
+	                            11000111
+	*/
+	switch {
+	case v <= 143:
+		b.writeBits(uint32(v)+0x30, 8, true)
+	case v <= 255:
+		b.writeBits(uint32(v-144)+0x190, 9, true)
+	case v <= 279:
+		b.writeBits(uint32(v-256)+0, 7, true)
+	case v <= 287:
+		b.writeBits(uint32(v-280)+0xc0, 8, true)
+	default:
+		panic("invalid hcode")
+	}
+}
+
+func (b *bitWriter) byte(x byte) {
+	b.hcode(int(x))
+}
+
+func (b *bitWriter) codex(c int, val int, nx uint) {
+	b.hcode(c + val>>nx)
+	b.writeBits(uint32(val)&(1<<nx-1), nx, false)
+}
+
+func (b *bitWriter) repeat(n, d int) {
+	for ; n >= 258+3; n -= 258 {
+		b.repeat1(258, d)
+	}
+	if n > 258 {
+		// 258 < n < 258+3
+		b.repeat1(10, d)
+		b.repeat1(n-10, d)
+		return
+	}
+	if n < 3 {
+		panic("invalid flate repeat")
+	}
+	b.repeat1(n, d)
+}
+
+func (b *bitWriter) repeat1(n, d int) {
+	/*
+	        Extra               Extra               Extra
+	   Code Bits Length(s) Code Bits Lengths   Code Bits Length(s)
+	   ---- ---- ------     ---- ---- -------   ---- ---- -------
+	    257   0     3       267   1   15,16     277   4   67-82
+	    258   0     4       268   1   17,18     278   4   83-98
+	    259   0     5       269   2   19-22     279   4   99-114
+	    260   0     6       270   2   23-26     280   4  115-130
+	    261   0     7       271   2   27-30     281   5  131-162
+	    262   0     8       272   2   31-34     282   5  163-194
+	    263   0     9       273   3   35-42     283   5  195-226
+	    264   0    10       274   3   43-50     284   5  227-257
+	    265   1  11,12      275   3   51-58     285   0    258
+	    266   1  13,14      276   3   59-66
+	*/
+	switch {
+	case n <= 10:
+		b.codex(257, n-3, 0)
+	case n <= 18:
+		b.codex(265, n-11, 1)
+	case n <= 34:
+		b.codex(269, n-19, 2)
+	case n <= 66:
+		b.codex(273, n-35, 3)
+	case n <= 130:
+		b.codex(277, n-67, 4)
+	case n <= 257:
+		b.codex(281, n-131, 5)
+	case n == 258:
+		b.hcode(285)
+	default:
+		panic("invalid repeat length")
+	}
+
+	/*
+	        Extra           Extra               Extra
+	   Code Bits Dist  Code Bits   Dist     Code Bits Distance
+	   ---- ---- ----  ---- ----  ------    ---- ---- --------
+	     0   0    1     10   4     33-48    20    9   1025-1536
+	     1   0    2     11   4     49-64    21    9   1537-2048
+	     2   0    3     12   5     65-96    22   10   2049-3072
+	     3   0    4     13   5     97-128   23   10   3073-4096
+	     4   1   5,6    14   6    129-192   24   11   4097-6144
+	     5   1   7,8    15   6    193-256   25   11   6145-8192
+	     6   2   9-12   16   7    257-384   26   12  8193-12288
+	     7   2  13-16   17   7    385-512   27   12 12289-16384
+	     8   3  17-24   18   8    513-768   28   13 16385-24576
+	     9   3  25-32   19   8   769-1024   29   13 24577-32768
+	*/
+	if d <= 4 {
+		b.writeBits(uint32(d-1), 5, true)
+	} else if d <= 32768 {
+		nbit := uint(16)
+		for d <= 1<<(nbit-1) {
+			nbit--
+		}
+		v := uint32(d - 1)
+		v &^= 1 << (nbit - 1)      // top bit is implicit
+		code := uint32(2*nbit - 2) // second bit is low bit of code
+		code |= v >> (nbit - 2)
+		v &^= 1 << (nbit - 2)
+		b.writeBits(code, 5, true)
+		// rest of bits follow
+		b.writeBits(uint32(v), nbit-2, false)
+	} else {
+		panic("invalid repeat distance")
+	}
+}
+
+func (b *bitWriter) run(v byte, n int) {
+	if n == 0 {
+		return
+	}
+	b.byte(v)
+	if n-1 < 3 {
+		for i := 0; i < n-1; i++ {
+			b.byte(v)
+		}
+	} else {
+		b.repeat(n-1, 1)
+	}
+}
+
+type adigest struct {
+	a, b uint32
+}
+
+func (d *adigest) Reset() { d.a, d.b = 1, 0 }
+
+const amod = 65521
+
+func aupdate(a, b uint32, pi byte, n int) (aa, bb uint32) {
+	// TODO(rsc): 6g doesn't do magic multiplies for b %= amod,
+	// only for b = b%amod.
+
+	// invariant: a, b < amod
+	if pi == 0 {
+		b += uint32(n%amod) * a
+		b = b % amod
+		return a, b
+	}
+
+	// n times:
+	//	a += pi
+	//	b += a
+	// is same as
+	//	b += n*a + n*(n+1)/2*pi
+	//	a += n*pi
+	m := uint32(n)
+	b += (m % amod) * a
+	b = b % amod
+	b += (m * (m + 1) / 2) % amod * uint32(pi)
+	b = b % amod
+	a += (m % amod) * uint32(pi)
+	a = a % amod
+	return a, b
+}
+
+func afinish(a, b uint32) uint32 {
+	return b<<16 | a
+}
+
+func (d *adigest) WriteN(p []byte, n int) {
+	for i := 0; i < n; i++ {
+		for _, pi := range p {
+			d.a, d.b = aupdate(d.a, d.b, pi, 1)
+		}
+	}
+}
+
+func (d *adigest) WriteNByte(pi byte, n int) {
+	d.a, d.b = aupdate(d.a, d.b, pi, n)
+}
+
+func (d *adigest) Sum32() uint32 { return afinish(d.a, d.b) }

+ 56 - 0
github.com/SKatiyar/qr/png_test.go

@@ -0,0 +1,56 @@
+// 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/png"
+	"io/ioutil"
+	"os"
+	"testing"
+)
+
+func Test2File(t *testing.T) {
+	r, _ := Encode("http://www.baidu.com", L)
+	fi, _ := os.OpenFile("C:\\Users\\admin\\Desktop\\2.png", os.O_CREATE|os.O_TRUNC|os.O_RDWR, 0x666)
+	fi.Write(r.PNG())
+}
+
+func TestPNG(t *testing.T) {
+	c, err := Encode("http://www.baidu.com", H)
+	if err != nil {
+		t.Fatal(err)
+	}
+	pngdat := c.PNG()
+	if true {
+		ioutil.WriteFile("x.png", pngdat, 0666)
+	}
+
+}
+
+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()))
+}

+ 116 - 0
github.com/SKatiyar/qr/qr.go

@@ -0,0 +1,116 @@
+// Copyright 2011 The Go Authors.  All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+/*
+Package qr encodes QR codes.
+*/
+package qr
+
+import (
+	"errors"
+	"image"
+	"image/color"
+
+	"github.com/SKatiyar/qr/coding"
+)
+
+// A Level denotes a QR error correction level.
+// From least to most tolerant of errors, they are L, M, Q, H.
+type Level int
+
+const (
+	L Level = iota // 20% redundant
+	M              // 38% redundant
+	Q              // 55% redundant
+	H              // 65% redundant
+)
+
+// Encode returns an encoding of text at the given error correction level.
+func Encode(text string, level Level) (*Code, error) {
+	// Pick data encoding, smallest first.
+	// We could split the string and use different encodings
+	// but that seems like overkill for now.
+	var enc coding.Encoding
+	switch {
+	case coding.Num(text).Check() == nil:
+		enc = coding.Num(text)
+	case coding.Alpha(text).Check() == nil:
+		enc = coding.Alpha(text)
+	default:
+		enc = coding.String(text)
+	}
+
+	// Pick size.
+	l := coding.Level(level)
+	var v coding.Version
+	for v = coding.MinVersion; ; v++ {
+		if v > coding.MaxVersion {
+			return nil, errors.New("text too long to encode as QR")
+		}
+		if enc.Bits(v) <= v.DataBytes(l)*8 {
+			break
+		}
+	}
+
+	// Build and execute plan.
+	p, err := coding.NewPlan(v, l, 0)
+	if err != nil {
+		return nil, err
+	}
+	cc, err := p.Encode(enc)
+	if err != nil {
+		return nil, err
+	}
+
+	// TODO: Pick appropriate mask.
+
+	return &Code{cc.Bitmap, cc.Size, cc.Stride, 8}, nil
+}
+
+// A Code is a square pixel grid.
+// It implements image.Image and direct PNG encoding.
+type Code struct {
+	Bitmap []byte // 1 is black, 0 is white
+	Size   int    // number of pixels on a side
+	Stride int    // number of bytes per row
+	Scale  int    // number of image pixels per QR pixel
+}
+
+// Black returns true if the pixel at (x,y) is black.
+func (c *Code) Black(x, y int) bool {
+	return 0 <= x && x < c.Size && 0 <= y && y < c.Size &&
+		c.Bitmap[y*c.Stride+x/8]&(1<<uint(7-x&7)) != 0
+}
+
+// Image returns an Image displaying the code.
+func (c *Code) Image() image.Image {
+	return &codeImage{c}
+
+}
+
+// codeImage implements image.Image
+type codeImage struct {
+	*Code
+}
+
+var (
+	whiteColor color.Color = color.Gray{0xFF}
+	blackColor color.Color = color.Gray{0x00}
+)
+
+func (c *codeImage) Bounds() image.Rectangle {
+	d := (c.Size + 8) * c.Scale
+	return image.Rect(0, 0, d, d)
+}
+
+func (c *codeImage) At(x, y int) color.Color {
+	if c.Black(x, y) {
+		return blackColor
+	}
+	return whiteColor
+}
+
+func (c *codeImage) ColorModel() color.Model {
+	return color.GrayModel
+}

+ 5 - 0
go.mod

@@ -0,0 +1,5 @@
+module app.yhyue.com/moapp/jypkg
+
+go 1.18
+
+require github.com/SKatiyar/qr v0.0.0-20151201054752-25b6bdf44e67

+ 2 - 0
go.sum

@@ -0,0 +1,2 @@
+github.com/SKatiyar/qr v0.0.0-20151201054752-25b6bdf44e67 h1:x98/gnpyNAiuvg/gX3KgdfKxnZj3t9pIl3BCVJg3qwg=
+github.com/SKatiyar/qr v0.0.0-20151201054752-25b6bdf44e67/go.mod h1:g1VZ0nbzBvfsWw22gNVOxWxJxpBR+CBiFNK2n2ogeUo=

+ 1 - 0
jypkg.go

@@ -0,0 +1 @@
+package jypkg