// 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 (
	
	
	
	
)

// 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 ( *Code) () []byte {
	var  pngWriter
	return .encode()
}

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 ( *pngWriter) ( *Code) []byte {
	 := .Scale
	 := .Size

	.buf.Reset()

	// Header
	.buf.Write(pngHeader)

	// Header block
	binary.BigEndian.PutUint32(.tmp[0:4], uint32((+8)*))
	binary.BigEndian.PutUint32(.tmp[4:8], uint32((+8)*))
	.tmp[8] = 1 // 1-bit
	.tmp[9] = 0 // gray
	.tmp[10] = 0
	.tmp[11] = 0
	.tmp[12] = 0
	.writeChunk("IHDR", .tmp[:13])

	// Comment
	.writeChunk("tEXt", comment)

	// Data
	.zlib.writeCode()
	.writeChunk("IDAT", .zlib.bytes.Bytes())

	// End
	.writeChunk("IEND", nil)

	return .buf.Bytes()
}

var comment = []byte("Software\x00QR-PNG http://qr.swtch.com/")

func ( *pngWriter) ( string,  []byte) {
	if .crc == nil {
		.crc = crc32.NewIEEE()
	}
	binary.BigEndian.PutUint32(.wctmp[0:4], uint32(len()))
	.buf.Write(.wctmp[0:4])
	.crc.Reset()
	copy(.wctmp[0:4], )
	.buf.Write(.wctmp[0:4])
	.crc.Write(.wctmp[0:4])
	.buf.Write()
	.crc.Write()
	 := .crc.Sum32()
	binary.BigEndian.PutUint32(.wctmp[0:4], )
	.buf.Write(.wctmp[0:4])
}

func ( *bitWriter) ( *Code) {
	const  = 0

	.adler32.Reset()
	.bytes.Reset()
	.nbit = 0

	 := .Scale
	 := .Size

	// zlib header
	.tmp[0] = 0x78
	.tmp[1] = 0
	.tmp[1] += uint8(31 - (uint16(.tmp[0])<<8+uint16(.tmp[1]))%31)
	.bytes.Write(.tmp[0:2])

	// Start flate block.
	.writeBits(1, 1, false) // final block
	.writeBits(1, 2, false) // compressed, fixed Huffman tables

	// White border.
	// First row.
	.byte()
	 := (*(+8) + 7) / 8
	.byte(255)
	.repeat(-1, 1)
	// 4*scale rows total.
	.repeat((4*-1)*(1+), 1+)

	for  := 0;  < 4*; ++ {
		.adler32.WriteNByte(, 1)
		.adler32.WriteNByte(255, )
	}

	 := make([]byte, 1+)
	for  := 0;  < ; ++ {
		[0] = 
		 := 1
		var  uint8
		 := 0
		for  := -4;  < +4; ++ {
			// Raw data.
			for  := 0;  < ; ++ {
				 <<= 1
				if !.Black(, ) {
					 |= 1
				}
				if ++;  == 8 {
					[] = 
					++
					 = 0
				}
			}
		}
		if  < len() {
			[] = 
		}
		for ,  := range  {
			.byte()
		}

		// Scale-1 copies.
		.repeat((-1)*(1+), 1+)

		.adler32.WriteN(, )
	}

	// White border.
	// First row.
	.byte()
	.byte(255)
	.repeat(-1, 1)
	// 4*scale rows total.
	.repeat((4*-1)*(1+), 1+)

	for  := 0;  < 4*; ++ {
		.adler32.WriteNByte(, 1)
		.adler32.WriteNByte(255, )
	}

	// End of block.
	.hcode(256)
	.flushBits()

	// adler32
	binary.BigEndian.PutUint32(.tmp[0:], .adler32.Sum32())
	.bytes.Write(.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 ( *bitWriter) ( uint32,  uint,  bool) {
	// reverse, for huffman codes
	if  {
		 := uint32(0)
		for  := uint(0);  < ; ++ {
			 |= (( >> ) & 1) << ( - 1 - )
		}
		 = 
	}
	.bit |=  << .nbit
	.nbit += 
	for .nbit >= 8 {
		.bytes.WriteByte(byte(.bit))
		.bit >>= 8
		.nbit -= 8
	}
}

func ( *bitWriter) () {
	if .nbit > 0 {
		.bytes.WriteByte(byte(.bit))
		.nbit = 0
		.bit = 0
	}
}

func ( *bitWriter) ( 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  <= 143:
		.writeBits(uint32()+0x30, 8, true)
	case  <= 255:
		.writeBits(uint32(-144)+0x190, 9, true)
	case  <= 279:
		.writeBits(uint32(-256)+0, 7, true)
	case  <= 287:
		.writeBits(uint32(-280)+0xc0, 8, true)
	default:
		panic("invalid hcode")
	}
}

func ( *bitWriter) ( byte) {
	.hcode(int())
}

func ( *bitWriter) ( int,  int,  uint) {
	.hcode( + >>)
	.writeBits(uint32()&(1<<-1), , false)
}

func ( *bitWriter) (,  int) {
	for ;  >= 258+3;  -= 258 {
		.repeat1(258, )
	}
	if  > 258 {
		// 258 < n < 258+3
		.repeat1(10, )
		.repeat1(-10, )
		return
	}
	if  < 3 {
		panic("invalid flate repeat")
	}
	.repeat1(, )
}

func ( *bitWriter) (,  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  <= 10:
		.codex(257, -3, 0)
	case  <= 18:
		.codex(265, -11, 1)
	case  <= 34:
		.codex(269, -19, 2)
	case  <= 66:
		.codex(273, -35, 3)
	case  <= 130:
		.codex(277, -67, 4)
	case  <= 257:
		.codex(281, -131, 5)
	case  == 258:
		.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  <= 4 {
		.writeBits(uint32(-1), 5, true)
	} else if  <= 32768 {
		 := uint(16)
		for  <= 1<<(-1) {
			--
		}
		 := uint32( - 1)
		 &^= 1 << ( - 1)      // top bit is implicit
		 := uint32(2* - 2) // second bit is low bit of code
		 |=  >> ( - 2)
		 &^= 1 << ( - 2)
		.writeBits(, 5, true)
		// rest of bits follow
		.writeBits(uint32(), -2, false)
	} else {
		panic("invalid repeat distance")
	}
}

func ( *bitWriter) ( byte,  int) {
	if  == 0 {
		return
	}
	.byte()
	if -1 < 3 {
		for  := 0;  < -1; ++ {
			.byte()
		}
	} else {
		.repeat(-1, 1)
	}
}

type adigest struct {
	a, b uint32
}

func ( *adigest) () { .a, .b = 1, 0 }

const amod = 65521

func (,  uint32,  byte,  int) (,  uint32) {
	// TODO(rsc): 6g doesn't do magic multiplies for b %= amod,
	// only for b = b%amod.

	// invariant: a, b < amod
	if  == 0 {
		 += uint32(%amod) * 
		 =  % amod
		return , 
	}

	// n times:
	//	a += pi
	//	b += a
	// is same as
	//	b += n*a + n*(n+1)/2*pi
	//	a += n*pi
	 := uint32()
	 += ( % amod) * 
	 =  % amod
	 += ( * ( + 1) / 2) % amod * uint32()
	 =  % amod
	 += ( % amod) * uint32()
	 =  % amod
	return , 
}

func (,  uint32) uint32 {
	return <<16 | 
}

func ( *adigest) ( []byte,  int) {
	for  := 0;  < ; ++ {
		for ,  := range  {
			.a, .b = aupdate(.a, .b, , 1)
		}
	}
}

func ( *adigest) ( byte,  int) {
	.a, .b = aupdate(.a, .b, , )
}

func ( *adigest) () uint32 { return afinish(.a, .b) }