123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400 |
- // 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) }
|