diff options
Diffstat (limited to 'Godeps/_workspace/src/github.com/mattermost/rsc/qr/png.go')
-rw-r--r-- | Godeps/_workspace/src/github.com/mattermost/rsc/qr/png.go | 400 |
1 files changed, 0 insertions, 400 deletions
diff --git a/Godeps/_workspace/src/github.com/mattermost/rsc/qr/png.go b/Godeps/_workspace/src/github.com/mattermost/rsc/qr/png.go deleted file mode 100644 index db49d0577..000000000 --- a/Godeps/_workspace/src/github.com/mattermost/rsc/qr/png.go +++ /dev/null @@ -1,400 +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 - -// 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) } |