twitchapon-anim

Basic Twitchapon Receiver/Visuals
git clone git://bsandro.tech/twitchapon-anim
Log | Files | Refs | README | LICENSE

stdlibreader.go (26128B)


      1 // Code generated by gen.go. DO NOT EDIT.
      2 
      3 // Copyright 2009 The Go Authors. All rights reserved.
      4 // Use of this source code is governed by a BSD-style
      5 // license that can be found in the LICENSE file.
      6 
      7 // Package png implements a PNG image decoder and encoder.
      8 //
      9 // The PNG specification is at https://www.w3.org/TR/PNG/.
     10 package png
     11 
     12 import (
     13 	"compress/zlib"
     14 	"encoding/binary"
     15 	"fmt"
     16 	"hash"
     17 	"hash/crc32"
     18 	"image"
     19 	"image/color"
     20 	"io"
     21 )
     22 
     23 // Color type, as per the PNG spec.
     24 const (
     25 	ctGrayscale      = 0
     26 	ctTrueColor      = 2
     27 	ctPaletted       = 3
     28 	ctGrayscaleAlpha = 4
     29 	ctTrueColorAlpha = 6
     30 )
     31 
     32 // A cb is a combination of color type and bit depth.
     33 const (
     34 	cbInvalid = iota
     35 	cbG1
     36 	cbG2
     37 	cbG4
     38 	cbG8
     39 	cbGA8
     40 	cbTC8
     41 	cbP1
     42 	cbP2
     43 	cbP4
     44 	cbP8
     45 	cbTCA8
     46 	cbG16
     47 	cbGA16
     48 	cbTC16
     49 	cbTCA16
     50 )
     51 
     52 func cbPaletted(cb int) bool {
     53 	return cbP1 <= cb && cb <= cbP8
     54 }
     55 
     56 // Filter type, as per the PNG spec.
     57 const (
     58 	ftNone    = 0
     59 	ftSub     = 1
     60 	ftUp      = 2
     61 	ftAverage = 3
     62 	ftPaeth   = 4
     63 	nFilter   = 5
     64 )
     65 
     66 // Interlace type.
     67 const (
     68 	itNone  = 0
     69 	itAdam7 = 1
     70 )
     71 
     72 // interlaceScan defines the placement and size of a pass for Adam7 interlacing.
     73 type interlaceScan struct {
     74 	xFactor, yFactor, xOffset, yOffset int
     75 }
     76 
     77 // interlacing defines Adam7 interlacing, with 7 passes of reduced images.
     78 // See https://www.w3.org/TR/PNG/#8Interlace
     79 var interlacing = []interlaceScan{
     80 	{8, 8, 0, 0},
     81 	{8, 8, 4, 0},
     82 	{4, 8, 0, 4},
     83 	{4, 4, 2, 0},
     84 	{2, 4, 0, 2},
     85 	{2, 2, 1, 0},
     86 	{1, 2, 0, 1},
     87 }
     88 
     89 // Decoding stage.
     90 // The PNG specification says that the IHDR, PLTE (if present), tRNS (if
     91 // present), IDAT and IEND chunks must appear in that order. There may be
     92 // multiple IDAT chunks, and IDAT chunks must be sequential (i.e. they may not
     93 // have any other chunks between them).
     94 // https://www.w3.org/TR/PNG/#5ChunkOrdering
     95 const (
     96 	dsStart = iota
     97 	dsSeenIHDR
     98 	dsSeenPLTE
     99 	dsSeentRNS
    100 	dsSeenIDAT
    101 	dsSeenIEND
    102 )
    103 
    104 const pngHeader = "\x89PNG\r\n\x1a\n"
    105 
    106 type decoder struct {
    107 	r             io.Reader
    108 	img           image.Image
    109 	crc           hash.Hash32
    110 	width, height int
    111 	depth         int
    112 	palette       color.Palette
    113 	cb            int
    114 	stage         int
    115 	idatLength    uint32
    116 	tmp           [3 * 256]byte
    117 	interlace     int
    118 
    119 	// useTransparent and transparent are used for grayscale and truecolor
    120 	// transparency, as opposed to palette transparency.
    121 	useTransparent bool
    122 	transparent    [6]byte
    123 }
    124 
    125 // A FormatError reports that the input is not a valid PNG.
    126 type FormatError string
    127 
    128 func (e FormatError) Error() string { return "png: invalid format: " + string(e) }
    129 
    130 var chunkOrderError = FormatError("chunk out of order")
    131 
    132 // An UnsupportedError reports that the input uses a valid but unimplemented PNG feature.
    133 type UnsupportedError string
    134 
    135 func (e UnsupportedError) Error() string { return "png: unsupported feature: " + string(e) }
    136 
    137 func min(a, b int) int {
    138 	if a < b {
    139 		return a
    140 	}
    141 	return b
    142 }
    143 
    144 func (d *decoder) parseIHDR(length uint32) error {
    145 	if length != 13 {
    146 		return FormatError("bad IHDR length")
    147 	}
    148 	if _, err := io.ReadFull(d.r, d.tmp[:13]); err != nil {
    149 		return err
    150 	}
    151 	d.crc.Write(d.tmp[:13])
    152 	if d.tmp[10] != 0 {
    153 		return UnsupportedError("compression method")
    154 	}
    155 	if d.tmp[11] != 0 {
    156 		return UnsupportedError("filter method")
    157 	}
    158 	if d.tmp[12] != itNone && d.tmp[12] != itAdam7 {
    159 		return FormatError("invalid interlace method")
    160 	}
    161 	d.interlace = int(d.tmp[12])
    162 
    163 	w := int32(binary.BigEndian.Uint32(d.tmp[0:4]))
    164 	h := int32(binary.BigEndian.Uint32(d.tmp[4:8]))
    165 	if w <= 0 || h <= 0 {
    166 		return FormatError("non-positive dimension")
    167 	}
    168 	nPixels64 := int64(w) * int64(h)
    169 	nPixels := int(nPixels64)
    170 	if nPixels64 != int64(nPixels) {
    171 		return UnsupportedError("dimension overflow")
    172 	}
    173 	// There can be up to 8 bytes per pixel, for 16 bits per channel RGBA.
    174 	if nPixels != (nPixels*8)/8 {
    175 		return UnsupportedError("dimension overflow")
    176 	}
    177 
    178 	d.cb = cbInvalid
    179 	d.depth = int(d.tmp[8])
    180 	switch d.depth {
    181 	case 1:
    182 		switch d.tmp[9] {
    183 		case ctGrayscale:
    184 			d.cb = cbG1
    185 		case ctPaletted:
    186 			d.cb = cbP1
    187 		}
    188 	case 2:
    189 		switch d.tmp[9] {
    190 		case ctGrayscale:
    191 			d.cb = cbG2
    192 		case ctPaletted:
    193 			d.cb = cbP2
    194 		}
    195 	case 4:
    196 		switch d.tmp[9] {
    197 		case ctGrayscale:
    198 			d.cb = cbG4
    199 		case ctPaletted:
    200 			d.cb = cbP4
    201 		}
    202 	case 8:
    203 		switch d.tmp[9] {
    204 		case ctGrayscale:
    205 			d.cb = cbG8
    206 		case ctTrueColor:
    207 			d.cb = cbTC8
    208 		case ctPaletted:
    209 			d.cb = cbP8
    210 		case ctGrayscaleAlpha:
    211 			d.cb = cbGA8
    212 		case ctTrueColorAlpha:
    213 			d.cb = cbTCA8
    214 		}
    215 	case 16:
    216 		switch d.tmp[9] {
    217 		case ctGrayscale:
    218 			d.cb = cbG16
    219 		case ctTrueColor:
    220 			d.cb = cbTC16
    221 		case ctGrayscaleAlpha:
    222 			d.cb = cbGA16
    223 		case ctTrueColorAlpha:
    224 			d.cb = cbTCA16
    225 		}
    226 	}
    227 	if d.cb == cbInvalid {
    228 		return UnsupportedError(fmt.Sprintf("bit depth %d, color type %d", d.tmp[8], d.tmp[9]))
    229 	}
    230 	d.width, d.height = int(w), int(h)
    231 	return d.verifyChecksum()
    232 }
    233 
    234 func (d *decoder) parsePLTE(length uint32) error {
    235 	np := int(length / 3) // The number of palette entries.
    236 	if length%3 != 0 || np <= 0 || np > 256 || np > 1<<uint(d.depth) {
    237 		return FormatError("bad PLTE length")
    238 	}
    239 	n, err := io.ReadFull(d.r, d.tmp[:3*np])
    240 	if err != nil {
    241 		return err
    242 	}
    243 	d.crc.Write(d.tmp[:n])
    244 	switch d.cb {
    245 	case cbP1, cbP2, cbP4, cbP8:
    246 		d.palette = make(color.Palette, 256)
    247 		for i := 0; i < np; i++ {
    248 			d.palette[i] = color.RGBA{d.tmp[3*i+0], d.tmp[3*i+1], d.tmp[3*i+2], 0xff}
    249 		}
    250 		for i := np; i < 256; i++ {
    251 			// Initialize the rest of the palette to opaque black. The spec (section
    252 			// 11.2.3) says that "any out-of-range pixel value found in the image data
    253 			// is an error", but some real-world PNG files have out-of-range pixel
    254 			// values. We fall back to opaque black, the same as libpng 1.5.13;
    255 			// ImageMagick 6.5.7 returns an error.
    256 			d.palette[i] = color.RGBA{0x00, 0x00, 0x00, 0xff}
    257 		}
    258 		d.palette = d.palette[:np]
    259 	case cbTC8, cbTCA8, cbTC16, cbTCA16:
    260 		// As per the PNG spec, a PLTE chunk is optional (and for practical purposes,
    261 		// ignorable) for the ctTrueColor and ctTrueColorAlpha color types (section 4.1.2).
    262 	default:
    263 		return FormatError("PLTE, color type mismatch")
    264 	}
    265 	return d.verifyChecksum()
    266 }
    267 
    268 func (d *decoder) parsetRNS(length uint32) error {
    269 	switch d.cb {
    270 	case cbG1, cbG2, cbG4, cbG8, cbG16:
    271 		if length != 2 {
    272 			return FormatError("bad tRNS length")
    273 		}
    274 		n, err := io.ReadFull(d.r, d.tmp[:length])
    275 		if err != nil {
    276 			return err
    277 		}
    278 		d.crc.Write(d.tmp[:n])
    279 
    280 		copy(d.transparent[:], d.tmp[:length])
    281 		switch d.cb {
    282 		case cbG1:
    283 			d.transparent[1] *= 0xff
    284 		case cbG2:
    285 			d.transparent[1] *= 0x55
    286 		case cbG4:
    287 			d.transparent[1] *= 0x11
    288 		}
    289 		d.useTransparent = true
    290 
    291 	case cbTC8, cbTC16:
    292 		if length != 6 {
    293 			return FormatError("bad tRNS length")
    294 		}
    295 		n, err := io.ReadFull(d.r, d.tmp[:length])
    296 		if err != nil {
    297 			return err
    298 		}
    299 		d.crc.Write(d.tmp[:n])
    300 
    301 		copy(d.transparent[:], d.tmp[:length])
    302 		d.useTransparent = true
    303 
    304 	case cbP1, cbP2, cbP4, cbP8:
    305 		if length > 256 {
    306 			return FormatError("bad tRNS length")
    307 		}
    308 		n, err := io.ReadFull(d.r, d.tmp[:length])
    309 		if err != nil {
    310 			return err
    311 		}
    312 		d.crc.Write(d.tmp[:n])
    313 
    314 		if len(d.palette) < n {
    315 			d.palette = d.palette[:n]
    316 		}
    317 		for i := 0; i < n; i++ {
    318 			rgba := d.palette[i].(color.RGBA)
    319 			d.palette[i] = color.NRGBA{rgba.R, rgba.G, rgba.B, d.tmp[i]}
    320 		}
    321 
    322 	default:
    323 		return FormatError("tRNS, color type mismatch")
    324 	}
    325 	return d.verifyChecksum()
    326 }
    327 
    328 // Read presents one or more IDAT chunks as one continuous stream (minus the
    329 // intermediate chunk headers and footers). If the PNG data looked like:
    330 //   ... len0 IDAT xxx crc0 len1 IDAT yy crc1 len2 IEND crc2
    331 // then this reader presents xxxyy. For well-formed PNG data, the decoder state
    332 // immediately before the first Read call is that d.r is positioned between the
    333 // first IDAT and xxx, and the decoder state immediately after the last Read
    334 // call is that d.r is positioned between yy and crc1.
    335 func (d *decoder) Read(p []byte) (int, error) {
    336 	if len(p) == 0 {
    337 		return 0, nil
    338 	}
    339 	for d.idatLength == 0 {
    340 		// We have exhausted an IDAT chunk. Verify the checksum of that chunk.
    341 		if err := d.verifyChecksum(); err != nil {
    342 			return 0, err
    343 		}
    344 		// Read the length and chunk type of the next chunk, and check that
    345 		// it is an IDAT chunk.
    346 		if _, err := io.ReadFull(d.r, d.tmp[:8]); err != nil {
    347 			return 0, err
    348 		}
    349 		d.idatLength = binary.BigEndian.Uint32(d.tmp[:4])
    350 		if string(d.tmp[4:8]) != "IDAT" {
    351 			return 0, FormatError("not enough pixel data")
    352 		}
    353 		d.crc.Reset()
    354 		d.crc.Write(d.tmp[4:8])
    355 	}
    356 	if int(d.idatLength) < 0 {
    357 		return 0, UnsupportedError("IDAT chunk length overflow")
    358 	}
    359 	n, err := d.r.Read(p[:min(len(p), int(d.idatLength))])
    360 	d.crc.Write(p[:n])
    361 	d.idatLength -= uint32(n)
    362 	return n, err
    363 }
    364 
    365 // decode decodes the IDAT data into an image.
    366 func (d *decoder) decode() (image.Image, error) {
    367 	r, err := zlib.NewReader(d)
    368 	if err != nil {
    369 		return nil, err
    370 	}
    371 	defer r.Close()
    372 	var img image.Image
    373 	if d.interlace == itNone {
    374 		img, err = d.readImagePass(r, 0, false)
    375 		if err != nil {
    376 			return nil, err
    377 		}
    378 	} else if d.interlace == itAdam7 {
    379 		// Allocate a blank image of the full size.
    380 		img, err = d.readImagePass(nil, 0, true)
    381 		if err != nil {
    382 			return nil, err
    383 		}
    384 		for pass := 0; pass < 7; pass++ {
    385 			imagePass, err := d.readImagePass(r, pass, false)
    386 			if err != nil {
    387 				return nil, err
    388 			}
    389 			if imagePass != nil {
    390 				d.mergePassInto(img, imagePass, pass)
    391 			}
    392 		}
    393 	}
    394 
    395 	// Check for EOF, to verify the zlib checksum.
    396 	n := 0
    397 	for i := 0; n == 0 && err == nil; i++ {
    398 		if i == 100 {
    399 			return nil, io.ErrNoProgress
    400 		}
    401 		n, err = r.Read(d.tmp[:1])
    402 	}
    403 	if err != nil && err != io.EOF {
    404 		return nil, FormatError(err.Error())
    405 	}
    406 	if n != 0 || d.idatLength != 0 {
    407 		return nil, FormatError("too much pixel data")
    408 	}
    409 
    410 	return img, nil
    411 }
    412 
    413 // readImagePass reads a single image pass, sized according to the pass number.
    414 func (d *decoder) readImagePass(r io.Reader, pass int, allocateOnly bool) (image.Image, error) {
    415 	bitsPerPixel := 0
    416 	pixOffset := 0
    417 	var (
    418 		gray     *image.Gray
    419 		rgba     *image.RGBA
    420 		paletted *image.Paletted
    421 		nrgba    *image.NRGBA
    422 		gray16   *image.Gray16
    423 		rgba64   *image.RGBA64
    424 		nrgba64  *image.NRGBA64
    425 		img      image.Image
    426 	)
    427 	width, height := d.width, d.height
    428 	if d.interlace == itAdam7 && !allocateOnly {
    429 		p := interlacing[pass]
    430 		// Add the multiplication factor and subtract one, effectively rounding up.
    431 		width = (width - p.xOffset + p.xFactor - 1) / p.xFactor
    432 		height = (height - p.yOffset + p.yFactor - 1) / p.yFactor
    433 		// A PNG image can't have zero width or height, but for an interlaced
    434 		// image, an individual pass might have zero width or height. If so, we
    435 		// shouldn't even read a per-row filter type byte, so return early.
    436 		if width == 0 || height == 0 {
    437 			return nil, nil
    438 		}
    439 	}
    440 	switch d.cb {
    441 	case cbG1, cbG2, cbG4, cbG8:
    442 		bitsPerPixel = d.depth
    443 		if d.useTransparent {
    444 			nrgba = image.NewNRGBA(image.Rect(0, 0, width, height))
    445 			img = nrgba
    446 		} else {
    447 			gray = image.NewGray(image.Rect(0, 0, width, height))
    448 			img = gray
    449 		}
    450 	case cbGA8:
    451 		bitsPerPixel = 16
    452 		nrgba = image.NewNRGBA(image.Rect(0, 0, width, height))
    453 		img = nrgba
    454 	case cbTC8:
    455 		bitsPerPixel = 24
    456 		if d.useTransparent {
    457 			nrgba = image.NewNRGBA(image.Rect(0, 0, width, height))
    458 			img = nrgba
    459 		} else {
    460 			rgba = image.NewRGBA(image.Rect(0, 0, width, height))
    461 			img = rgba
    462 		}
    463 	case cbP1, cbP2, cbP4, cbP8:
    464 		bitsPerPixel = d.depth
    465 		paletted = image.NewPaletted(image.Rect(0, 0, width, height), d.palette)
    466 		img = paletted
    467 	case cbTCA8:
    468 		bitsPerPixel = 32
    469 		nrgba = image.NewNRGBA(image.Rect(0, 0, width, height))
    470 		img = nrgba
    471 	case cbG16:
    472 		bitsPerPixel = 16
    473 		if d.useTransparent {
    474 			nrgba64 = image.NewNRGBA64(image.Rect(0, 0, width, height))
    475 			img = nrgba64
    476 		} else {
    477 			gray16 = image.NewGray16(image.Rect(0, 0, width, height))
    478 			img = gray16
    479 		}
    480 	case cbGA16:
    481 		bitsPerPixel = 32
    482 		nrgba64 = image.NewNRGBA64(image.Rect(0, 0, width, height))
    483 		img = nrgba64
    484 	case cbTC16:
    485 		bitsPerPixel = 48
    486 		if d.useTransparent {
    487 			nrgba64 = image.NewNRGBA64(image.Rect(0, 0, width, height))
    488 			img = nrgba64
    489 		} else {
    490 			rgba64 = image.NewRGBA64(image.Rect(0, 0, width, height))
    491 			img = rgba64
    492 		}
    493 	case cbTCA16:
    494 		bitsPerPixel = 64
    495 		nrgba64 = image.NewNRGBA64(image.Rect(0, 0, width, height))
    496 		img = nrgba64
    497 	}
    498 	if allocateOnly {
    499 		return img, nil
    500 	}
    501 	bytesPerPixel := (bitsPerPixel + 7) / 8
    502 
    503 	// The +1 is for the per-row filter type, which is at cr[0].
    504 	rowSize := 1 + (int64(bitsPerPixel)*int64(width)+7)/8
    505 	if rowSize != int64(int(rowSize)) {
    506 		return nil, UnsupportedError("dimension overflow")
    507 	}
    508 	// cr and pr are the bytes for the current and previous row.
    509 	cr := make([]uint8, rowSize)
    510 	pr := make([]uint8, rowSize)
    511 
    512 	for y := 0; y < height; y++ {
    513 		// Read the decompressed bytes.
    514 		_, err := io.ReadFull(r, cr)
    515 		if err != nil {
    516 			if err == io.EOF || err == io.ErrUnexpectedEOF {
    517 				return nil, FormatError("not enough pixel data")
    518 			}
    519 			return nil, err
    520 		}
    521 
    522 		// Apply the filter.
    523 		cdat := cr[1:]
    524 		pdat := pr[1:]
    525 		switch cr[0] {
    526 		case ftNone:
    527 			// No-op.
    528 		case ftSub:
    529 			for i := bytesPerPixel; i < len(cdat); i++ {
    530 				cdat[i] += cdat[i-bytesPerPixel]
    531 			}
    532 		case ftUp:
    533 			for i, p := range pdat {
    534 				cdat[i] += p
    535 			}
    536 		case ftAverage:
    537 			// The first column has no column to the left of it, so it is a
    538 			// special case. We know that the first column exists because we
    539 			// check above that width != 0, and so len(cdat) != 0.
    540 			for i := 0; i < bytesPerPixel; i++ {
    541 				cdat[i] += pdat[i] / 2
    542 			}
    543 			for i := bytesPerPixel; i < len(cdat); i++ {
    544 				cdat[i] += uint8((int(cdat[i-bytesPerPixel]) + int(pdat[i])) / 2)
    545 			}
    546 		case ftPaeth:
    547 			filterPaeth(cdat, pdat, bytesPerPixel)
    548 		default:
    549 			return nil, FormatError("bad filter type")
    550 		}
    551 
    552 		// Convert from bytes to colors.
    553 		switch d.cb {
    554 		case cbG1:
    555 			if d.useTransparent {
    556 				ty := d.transparent[1]
    557 				for x := 0; x < width; x += 8 {
    558 					b := cdat[x/8]
    559 					for x2 := 0; x2 < 8 && x+x2 < width; x2++ {
    560 						ycol := (b >> 7) * 0xff
    561 						acol := uint8(0xff)
    562 						if ycol == ty {
    563 							acol = 0x00
    564 						}
    565 						nrgba.SetNRGBA(x+x2, y, color.NRGBA{ycol, ycol, ycol, acol})
    566 						b <<= 1
    567 					}
    568 				}
    569 			} else {
    570 				for x := 0; x < width; x += 8 {
    571 					b := cdat[x/8]
    572 					for x2 := 0; x2 < 8 && x+x2 < width; x2++ {
    573 						gray.SetGray(x+x2, y, color.Gray{(b >> 7) * 0xff})
    574 						b <<= 1
    575 					}
    576 				}
    577 			}
    578 		case cbG2:
    579 			if d.useTransparent {
    580 				ty := d.transparent[1]
    581 				for x := 0; x < width; x += 4 {
    582 					b := cdat[x/4]
    583 					for x2 := 0; x2 < 4 && x+x2 < width; x2++ {
    584 						ycol := (b >> 6) * 0x55
    585 						acol := uint8(0xff)
    586 						if ycol == ty {
    587 							acol = 0x00
    588 						}
    589 						nrgba.SetNRGBA(x+x2, y, color.NRGBA{ycol, ycol, ycol, acol})
    590 						b <<= 2
    591 					}
    592 				}
    593 			} else {
    594 				for x := 0; x < width; x += 4 {
    595 					b := cdat[x/4]
    596 					for x2 := 0; x2 < 4 && x+x2 < width; x2++ {
    597 						gray.SetGray(x+x2, y, color.Gray{(b >> 6) * 0x55})
    598 						b <<= 2
    599 					}
    600 				}
    601 			}
    602 		case cbG4:
    603 			if d.useTransparent {
    604 				ty := d.transparent[1]
    605 				for x := 0; x < width; x += 2 {
    606 					b := cdat[x/2]
    607 					for x2 := 0; x2 < 2 && x+x2 < width; x2++ {
    608 						ycol := (b >> 4) * 0x11
    609 						acol := uint8(0xff)
    610 						if ycol == ty {
    611 							acol = 0x00
    612 						}
    613 						nrgba.SetNRGBA(x+x2, y, color.NRGBA{ycol, ycol, ycol, acol})
    614 						b <<= 4
    615 					}
    616 				}
    617 			} else {
    618 				for x := 0; x < width; x += 2 {
    619 					b := cdat[x/2]
    620 					for x2 := 0; x2 < 2 && x+x2 < width; x2++ {
    621 						gray.SetGray(x+x2, y, color.Gray{(b >> 4) * 0x11})
    622 						b <<= 4
    623 					}
    624 				}
    625 			}
    626 		case cbG8:
    627 			if d.useTransparent {
    628 				ty := d.transparent[1]
    629 				for x := 0; x < width; x++ {
    630 					ycol := cdat[x]
    631 					acol := uint8(0xff)
    632 					if ycol == ty {
    633 						acol = 0x00
    634 					}
    635 					nrgba.SetNRGBA(x, y, color.NRGBA{ycol, ycol, ycol, acol})
    636 				}
    637 			} else {
    638 				copy(gray.Pix[pixOffset:], cdat)
    639 				pixOffset += gray.Stride
    640 			}
    641 		case cbGA8:
    642 			for x := 0; x < width; x++ {
    643 				ycol := cdat[2*x+0]
    644 				nrgba.SetNRGBA(x, y, color.NRGBA{ycol, ycol, ycol, cdat[2*x+1]})
    645 			}
    646 		case cbTC8:
    647 			if d.useTransparent {
    648 				pix, i, j := nrgba.Pix, pixOffset, 0
    649 				tr, tg, tb := d.transparent[1], d.transparent[3], d.transparent[5]
    650 				for x := 0; x < width; x++ {
    651 					r := cdat[j+0]
    652 					g := cdat[j+1]
    653 					b := cdat[j+2]
    654 					a := uint8(0xff)
    655 					if r == tr && g == tg && b == tb {
    656 						a = 0x00
    657 					}
    658 					pix[i+0] = r
    659 					pix[i+1] = g
    660 					pix[i+2] = b
    661 					pix[i+3] = a
    662 					i += 4
    663 					j += 3
    664 				}
    665 				pixOffset += nrgba.Stride
    666 			} else {
    667 				pix, i, j := rgba.Pix, pixOffset, 0
    668 				for x := 0; x < width; x++ {
    669 					pix[i+0] = cdat[j+0]
    670 					pix[i+1] = cdat[j+1]
    671 					pix[i+2] = cdat[j+2]
    672 					pix[i+3] = 0xff
    673 					i += 4
    674 					j += 3
    675 				}
    676 				pixOffset += rgba.Stride
    677 			}
    678 		case cbP1:
    679 			for x := 0; x < width; x += 8 {
    680 				b := cdat[x/8]
    681 				for x2 := 0; x2 < 8 && x+x2 < width; x2++ {
    682 					idx := b >> 7
    683 					if len(paletted.Palette) <= int(idx) {
    684 						paletted.Palette = paletted.Palette[:int(idx)+1]
    685 					}
    686 					paletted.SetColorIndex(x+x2, y, idx)
    687 					b <<= 1
    688 				}
    689 			}
    690 		case cbP2:
    691 			for x := 0; x < width; x += 4 {
    692 				b := cdat[x/4]
    693 				for x2 := 0; x2 < 4 && x+x2 < width; x2++ {
    694 					idx := b >> 6
    695 					if len(paletted.Palette) <= int(idx) {
    696 						paletted.Palette = paletted.Palette[:int(idx)+1]
    697 					}
    698 					paletted.SetColorIndex(x+x2, y, idx)
    699 					b <<= 2
    700 				}
    701 			}
    702 		case cbP4:
    703 			for x := 0; x < width; x += 2 {
    704 				b := cdat[x/2]
    705 				for x2 := 0; x2 < 2 && x+x2 < width; x2++ {
    706 					idx := b >> 4
    707 					if len(paletted.Palette) <= int(idx) {
    708 						paletted.Palette = paletted.Palette[:int(idx)+1]
    709 					}
    710 					paletted.SetColorIndex(x+x2, y, idx)
    711 					b <<= 4
    712 				}
    713 			}
    714 		case cbP8:
    715 			if len(paletted.Palette) != 256 {
    716 				for x := 0; x < width; x++ {
    717 					if len(paletted.Palette) <= int(cdat[x]) {
    718 						paletted.Palette = paletted.Palette[:int(cdat[x])+1]
    719 					}
    720 				}
    721 			}
    722 			copy(paletted.Pix[pixOffset:], cdat)
    723 			pixOffset += paletted.Stride
    724 		case cbTCA8:
    725 			copy(nrgba.Pix[pixOffset:], cdat)
    726 			pixOffset += nrgba.Stride
    727 		case cbG16:
    728 			if d.useTransparent {
    729 				ty := uint16(d.transparent[0])<<8 | uint16(d.transparent[1])
    730 				for x := 0; x < width; x++ {
    731 					ycol := uint16(cdat[2*x+0])<<8 | uint16(cdat[2*x+1])
    732 					acol := uint16(0xffff)
    733 					if ycol == ty {
    734 						acol = 0x0000
    735 					}
    736 					nrgba64.SetNRGBA64(x, y, color.NRGBA64{ycol, ycol, ycol, acol})
    737 				}
    738 			} else {
    739 				for x := 0; x < width; x++ {
    740 					ycol := uint16(cdat[2*x+0])<<8 | uint16(cdat[2*x+1])
    741 					gray16.SetGray16(x, y, color.Gray16{ycol})
    742 				}
    743 			}
    744 		case cbGA16:
    745 			for x := 0; x < width; x++ {
    746 				ycol := uint16(cdat[4*x+0])<<8 | uint16(cdat[4*x+1])
    747 				acol := uint16(cdat[4*x+2])<<8 | uint16(cdat[4*x+3])
    748 				nrgba64.SetNRGBA64(x, y, color.NRGBA64{ycol, ycol, ycol, acol})
    749 			}
    750 		case cbTC16:
    751 			if d.useTransparent {
    752 				tr := uint16(d.transparent[0])<<8 | uint16(d.transparent[1])
    753 				tg := uint16(d.transparent[2])<<8 | uint16(d.transparent[3])
    754 				tb := uint16(d.transparent[4])<<8 | uint16(d.transparent[5])
    755 				for x := 0; x < width; x++ {
    756 					rcol := uint16(cdat[6*x+0])<<8 | uint16(cdat[6*x+1])
    757 					gcol := uint16(cdat[6*x+2])<<8 | uint16(cdat[6*x+3])
    758 					bcol := uint16(cdat[6*x+4])<<8 | uint16(cdat[6*x+5])
    759 					acol := uint16(0xffff)
    760 					if rcol == tr && gcol == tg && bcol == tb {
    761 						acol = 0x0000
    762 					}
    763 					nrgba64.SetNRGBA64(x, y, color.NRGBA64{rcol, gcol, bcol, acol})
    764 				}
    765 			} else {
    766 				for x := 0; x < width; x++ {
    767 					rcol := uint16(cdat[6*x+0])<<8 | uint16(cdat[6*x+1])
    768 					gcol := uint16(cdat[6*x+2])<<8 | uint16(cdat[6*x+3])
    769 					bcol := uint16(cdat[6*x+4])<<8 | uint16(cdat[6*x+5])
    770 					rgba64.SetRGBA64(x, y, color.RGBA64{rcol, gcol, bcol, 0xffff})
    771 				}
    772 			}
    773 		case cbTCA16:
    774 			for x := 0; x < width; x++ {
    775 				rcol := uint16(cdat[8*x+0])<<8 | uint16(cdat[8*x+1])
    776 				gcol := uint16(cdat[8*x+2])<<8 | uint16(cdat[8*x+3])
    777 				bcol := uint16(cdat[8*x+4])<<8 | uint16(cdat[8*x+5])
    778 				acol := uint16(cdat[8*x+6])<<8 | uint16(cdat[8*x+7])
    779 				nrgba64.SetNRGBA64(x, y, color.NRGBA64{rcol, gcol, bcol, acol})
    780 			}
    781 		}
    782 
    783 		// The current row for y is the previous row for y+1.
    784 		pr, cr = cr, pr
    785 	}
    786 
    787 	return img, nil
    788 }
    789 
    790 // mergePassInto merges a single pass into a full sized image.
    791 func (d *decoder) mergePassInto(dst image.Image, src image.Image, pass int) {
    792 	p := interlacing[pass]
    793 	var (
    794 		srcPix        []uint8
    795 		dstPix        []uint8
    796 		stride        int
    797 		rect          image.Rectangle
    798 		bytesPerPixel int
    799 	)
    800 	switch target := dst.(type) {
    801 	case *image.Alpha:
    802 		srcPix = src.(*image.Alpha).Pix
    803 		dstPix, stride, rect = target.Pix, target.Stride, target.Rect
    804 		bytesPerPixel = 1
    805 	case *image.Alpha16:
    806 		srcPix = src.(*image.Alpha16).Pix
    807 		dstPix, stride, rect = target.Pix, target.Stride, target.Rect
    808 		bytesPerPixel = 2
    809 	case *image.Gray:
    810 		srcPix = src.(*image.Gray).Pix
    811 		dstPix, stride, rect = target.Pix, target.Stride, target.Rect
    812 		bytesPerPixel = 1
    813 	case *image.Gray16:
    814 		srcPix = src.(*image.Gray16).Pix
    815 		dstPix, stride, rect = target.Pix, target.Stride, target.Rect
    816 		bytesPerPixel = 2
    817 	case *image.NRGBA:
    818 		srcPix = src.(*image.NRGBA).Pix
    819 		dstPix, stride, rect = target.Pix, target.Stride, target.Rect
    820 		bytesPerPixel = 4
    821 	case *image.NRGBA64:
    822 		srcPix = src.(*image.NRGBA64).Pix
    823 		dstPix, stride, rect = target.Pix, target.Stride, target.Rect
    824 		bytesPerPixel = 8
    825 	case *image.Paletted:
    826 		srcPix = src.(*image.Paletted).Pix
    827 		dstPix, stride, rect = target.Pix, target.Stride, target.Rect
    828 		bytesPerPixel = 1
    829 	case *image.RGBA:
    830 		srcPix = src.(*image.RGBA).Pix
    831 		dstPix, stride, rect = target.Pix, target.Stride, target.Rect
    832 		bytesPerPixel = 4
    833 	case *image.RGBA64:
    834 		srcPix = src.(*image.RGBA64).Pix
    835 		dstPix, stride, rect = target.Pix, target.Stride, target.Rect
    836 		bytesPerPixel = 8
    837 	}
    838 	s, bounds := 0, src.Bounds()
    839 	for y := bounds.Min.Y; y < bounds.Max.Y; y++ {
    840 		dBase := (y*p.yFactor+p.yOffset-rect.Min.Y)*stride + (p.xOffset-rect.Min.X)*bytesPerPixel
    841 		for x := bounds.Min.X; x < bounds.Max.X; x++ {
    842 			d := dBase + x*p.xFactor*bytesPerPixel
    843 			copy(dstPix[d:], srcPix[s:s+bytesPerPixel])
    844 			s += bytesPerPixel
    845 		}
    846 	}
    847 }
    848 
    849 func (d *decoder) parseIDAT(length uint32) (err error) {
    850 	d.idatLength = length
    851 	d.img, err = d.decode()
    852 	if err != nil {
    853 		return err
    854 	}
    855 	return d.verifyChecksum()
    856 }
    857 
    858 func (d *decoder) parseIEND(length uint32) error {
    859 	if length != 0 {
    860 		return FormatError("bad IEND length")
    861 	}
    862 	return d.verifyChecksum()
    863 }
    864 
    865 func (d *decoder) parseChunk() error {
    866 	// Read the length and chunk type.
    867 	if _, err := io.ReadFull(d.r, d.tmp[:8]); err != nil {
    868 		return err
    869 	}
    870 	length := binary.BigEndian.Uint32(d.tmp[:4])
    871 	d.crc.Reset()
    872 	d.crc.Write(d.tmp[4:8])
    873 
    874 	// Read the chunk data.
    875 	switch string(d.tmp[4:8]) {
    876 	case "IHDR":
    877 		if d.stage != dsStart {
    878 			return chunkOrderError
    879 		}
    880 		d.stage = dsSeenIHDR
    881 		return d.parseIHDR(length)
    882 	case "PLTE":
    883 		if d.stage != dsSeenIHDR {
    884 			return chunkOrderError
    885 		}
    886 		d.stage = dsSeenPLTE
    887 		return d.parsePLTE(length)
    888 	case "tRNS":
    889 		if cbPaletted(d.cb) {
    890 			if d.stage != dsSeenPLTE {
    891 				return chunkOrderError
    892 			}
    893 		} else if d.stage != dsSeenIHDR {
    894 			return chunkOrderError
    895 		}
    896 		d.stage = dsSeentRNS
    897 		return d.parsetRNS(length)
    898 	case "IDAT":
    899 		if d.stage < dsSeenIHDR || d.stage > dsSeenIDAT || (d.stage == dsSeenIHDR && cbPaletted(d.cb)) {
    900 			return chunkOrderError
    901 		} else if d.stage == dsSeenIDAT {
    902 			// Ignore trailing zero-length or garbage IDAT chunks.
    903 			//
    904 			// This does not affect valid PNG images that contain multiple IDAT
    905 			// chunks, since the first call to parseIDAT below will consume all
    906 			// consecutive IDAT chunks required for decoding the image.
    907 			break
    908 		}
    909 		d.stage = dsSeenIDAT
    910 		return d.parseIDAT(length)
    911 	case "IEND":
    912 		if d.stage != dsSeenIDAT {
    913 			return chunkOrderError
    914 		}
    915 		d.stage = dsSeenIEND
    916 		return d.parseIEND(length)
    917 	}
    918 	if length > 0x7fffffff {
    919 		return FormatError(fmt.Sprintf("Bad chunk length: %d", length))
    920 	}
    921 	// Ignore this chunk (of a known length).
    922 	var ignored [4096]byte
    923 	for length > 0 {
    924 		n, err := io.ReadFull(d.r, ignored[:min(len(ignored), int(length))])
    925 		if err != nil {
    926 			return err
    927 		}
    928 		d.crc.Write(ignored[:n])
    929 		length -= uint32(n)
    930 	}
    931 	return d.verifyChecksum()
    932 }
    933 
    934 func (d *decoder) verifyChecksum() error {
    935 	if _, err := io.ReadFull(d.r, d.tmp[:4]); err != nil {
    936 		return err
    937 	}
    938 	if binary.BigEndian.Uint32(d.tmp[:4]) != d.crc.Sum32() {
    939 		return FormatError("invalid checksum")
    940 	}
    941 	return nil
    942 }
    943 
    944 func (d *decoder) checkHeader() error {
    945 	_, err := io.ReadFull(d.r, d.tmp[:len(pngHeader)])
    946 	if err != nil {
    947 		return err
    948 	}
    949 	if string(d.tmp[:len(pngHeader)]) != pngHeader {
    950 		return FormatError("not a PNG file")
    951 	}
    952 	return nil
    953 }
    954 
    955 // Decode reads a PNG image from r and returns it as an image.Image.
    956 // The type of Image returned depends on the PNG contents.
    957 func Decode(r io.Reader) (image.Image, error) {
    958 	d := &decoder{
    959 		r:   r,
    960 		crc: crc32.NewIEEE(),
    961 	}
    962 	if err := d.checkHeader(); err != nil {
    963 		if err == io.EOF {
    964 			err = io.ErrUnexpectedEOF
    965 		}
    966 		return nil, err
    967 	}
    968 	for d.stage != dsSeenIEND {
    969 		if err := d.parseChunk(); err != nil {
    970 			if err == io.EOF {
    971 				err = io.ErrUnexpectedEOF
    972 			}
    973 			return nil, err
    974 		}
    975 	}
    976 	return d.img, nil
    977 }
    978 
    979 // DecodeConfig returns the color model and dimensions of a PNG image without
    980 // decoding the entire image.
    981 func DecodeConfig(r io.Reader) (image.Config, error) {
    982 	d := &decoder{
    983 		r:   r,
    984 		crc: crc32.NewIEEE(),
    985 	}
    986 	if err := d.checkHeader(); err != nil {
    987 		if err == io.EOF {
    988 			err = io.ErrUnexpectedEOF
    989 		}
    990 		return image.Config{}, err
    991 	}
    992 	for {
    993 		if err := d.parseChunk(); err != nil {
    994 			if err == io.EOF {
    995 				err = io.ErrUnexpectedEOF
    996 			}
    997 			return image.Config{}, err
    998 		}
    999 		paletted := cbPaletted(d.cb)
   1000 		if d.stage == dsSeenIHDR && !paletted {
   1001 			break
   1002 		}
   1003 		if d.stage == dsSeenPLTE && paletted {
   1004 			break
   1005 		}
   1006 	}
   1007 	var cm color.Model
   1008 	switch d.cb {
   1009 	case cbG1, cbG2, cbG4, cbG8:
   1010 		cm = color.GrayModel
   1011 	case cbGA8:
   1012 		cm = color.NRGBAModel
   1013 	case cbTC8:
   1014 		cm = color.RGBAModel
   1015 	case cbP1, cbP2, cbP4, cbP8:
   1016 		cm = d.palette
   1017 	case cbTCA8:
   1018 		cm = color.NRGBAModel
   1019 	case cbG16:
   1020 		cm = color.Gray16Model
   1021 	case cbGA16:
   1022 		cm = color.NRGBA64Model
   1023 	case cbTC16:
   1024 		cm = color.RGBA64Model
   1025 	case cbTCA16:
   1026 		cm = color.NRGBA64Model
   1027 	}
   1028 	return image.Config{
   1029 		ColorModel: cm,
   1030 		Width:      d.width,
   1031 		Height:     d.height,
   1032 	}, nil
   1033 }
   1034 
   1035 func init() {
   1036 
   1037 }