...

Source file src/image/png/reader.go

Documentation: image/png

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

View as plain text