github.com/mh-cbon/go@v0.0.0-20160603070303-9e112a3fe4c0/src/image/png/reader.go (about)

     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 http://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 http://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  // http://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  
   118  // A FormatError reports that the input is not a valid PNG.
   119  type FormatError string
   120  
   121  func (e FormatError) Error() string { return "png: invalid format: " + string(e) }
   122  
   123  var chunkOrderError = FormatError("chunk out of order")
   124  
   125  // An UnsupportedError reports that the input uses a valid but unimplemented PNG feature.
   126  type UnsupportedError string
   127  
   128  func (e UnsupportedError) Error() string { return "png: unsupported feature: " + string(e) }
   129  
   130  func min(a, b int) int {
   131  	if a < b {
   132  		return a
   133  	}
   134  	return b
   135  }
   136  
   137  func (d *decoder) parseIHDR(length uint32) error {
   138  	if length != 13 {
   139  		return FormatError("bad IHDR length")
   140  	}
   141  	if _, err := io.ReadFull(d.r, d.tmp[:13]); err != nil {
   142  		return err
   143  	}
   144  	d.crc.Write(d.tmp[:13])
   145  	if d.tmp[10] != 0 {
   146  		return UnsupportedError("compression method")
   147  	}
   148  	if d.tmp[11] != 0 {
   149  		return UnsupportedError("filter method")
   150  	}
   151  	if d.tmp[12] != itNone && d.tmp[12] != itAdam7 {
   152  		return FormatError("invalid interlace method")
   153  	}
   154  	d.interlace = int(d.tmp[12])
   155  	w := int32(binary.BigEndian.Uint32(d.tmp[0:4]))
   156  	h := int32(binary.BigEndian.Uint32(d.tmp[4:8]))
   157  	if w <= 0 || h <= 0 {
   158  		return FormatError("non-positive dimension")
   159  	}
   160  	nPixels := int64(w) * int64(h)
   161  	if nPixels != int64(int(nPixels)) {
   162  		return UnsupportedError("dimension overflow")
   163  	}
   164  	d.cb = cbInvalid
   165  	d.depth = int(d.tmp[8])
   166  	switch d.depth {
   167  	case 1:
   168  		switch d.tmp[9] {
   169  		case ctGrayscale:
   170  			d.cb = cbG1
   171  		case ctPaletted:
   172  			d.cb = cbP1
   173  		}
   174  	case 2:
   175  		switch d.tmp[9] {
   176  		case ctGrayscale:
   177  			d.cb = cbG2
   178  		case ctPaletted:
   179  			d.cb = cbP2
   180  		}
   181  	case 4:
   182  		switch d.tmp[9] {
   183  		case ctGrayscale:
   184  			d.cb = cbG4
   185  		case ctPaletted:
   186  			d.cb = cbP4
   187  		}
   188  	case 8:
   189  		switch d.tmp[9] {
   190  		case ctGrayscale:
   191  			d.cb = cbG8
   192  		case ctTrueColor:
   193  			d.cb = cbTC8
   194  		case ctPaletted:
   195  			d.cb = cbP8
   196  		case ctGrayscaleAlpha:
   197  			d.cb = cbGA8
   198  		case ctTrueColorAlpha:
   199  			d.cb = cbTCA8
   200  		}
   201  	case 16:
   202  		switch d.tmp[9] {
   203  		case ctGrayscale:
   204  			d.cb = cbG16
   205  		case ctTrueColor:
   206  			d.cb = cbTC16
   207  		case ctGrayscaleAlpha:
   208  			d.cb = cbGA16
   209  		case ctTrueColorAlpha:
   210  			d.cb = cbTCA16
   211  		}
   212  	}
   213  	if d.cb == cbInvalid {
   214  		return UnsupportedError(fmt.Sprintf("bit depth %d, color type %d", d.tmp[8], d.tmp[9]))
   215  	}
   216  	d.width, d.height = int(w), int(h)
   217  	return d.verifyChecksum()
   218  }
   219  
   220  func (d *decoder) parsePLTE(length uint32) error {
   221  	np := int(length / 3) // The number of palette entries.
   222  	if length%3 != 0 || np <= 0 || np > 256 || np > 1<<uint(d.depth) {
   223  		return FormatError("bad PLTE length")
   224  	}
   225  	n, err := io.ReadFull(d.r, d.tmp[:3*np])
   226  	if err != nil {
   227  		return err
   228  	}
   229  	d.crc.Write(d.tmp[:n])
   230  	switch d.cb {
   231  	case cbP1, cbP2, cbP4, cbP8:
   232  		d.palette = make(color.Palette, 256)
   233  		for i := 0; i < np; i++ {
   234  			d.palette[i] = color.RGBA{d.tmp[3*i+0], d.tmp[3*i+1], d.tmp[3*i+2], 0xff}
   235  		}
   236  		for i := np; i < 256; i++ {
   237  			// Initialize the rest of the palette to opaque black. The spec (section
   238  			// 11.2.3) says that "any out-of-range pixel value found in the image data
   239  			// is an error", but some real-world PNG files have out-of-range pixel
   240  			// values. We fall back to opaque black, the same as libpng 1.5.13;
   241  			// ImageMagick 6.5.7 returns an error.
   242  			d.palette[i] = color.RGBA{0x00, 0x00, 0x00, 0xff}
   243  		}
   244  		d.palette = d.palette[:np]
   245  	case cbTC8, cbTCA8, cbTC16, cbTCA16:
   246  		// As per the PNG spec, a PLTE chunk is optional (and for practical purposes,
   247  		// ignorable) for the ctTrueColor and ctTrueColorAlpha color types (section 4.1.2).
   248  	default:
   249  		return FormatError("PLTE, color type mismatch")
   250  	}
   251  	return d.verifyChecksum()
   252  }
   253  
   254  func (d *decoder) parsetRNS(length uint32) error {
   255  	if length > 256 {
   256  		return FormatError("bad tRNS length")
   257  	}
   258  	n, err := io.ReadFull(d.r, d.tmp[:length])
   259  	if err != nil {
   260  		return err
   261  	}
   262  	d.crc.Write(d.tmp[:n])
   263  	switch d.cb {
   264  	case cbG8, cbG16:
   265  		return UnsupportedError("grayscale transparency")
   266  	case cbTC8, cbTC16:
   267  		return UnsupportedError("truecolor transparency")
   268  	case cbP1, cbP2, cbP4, cbP8:
   269  		if len(d.palette) < n {
   270  			d.palette = d.palette[:n]
   271  		}
   272  		for i := 0; i < n; i++ {
   273  			rgba := d.palette[i].(color.RGBA)
   274  			d.palette[i] = color.NRGBA{rgba.R, rgba.G, rgba.B, d.tmp[i]}
   275  		}
   276  	case cbGA8, cbGA16, cbTCA8, cbTCA16:
   277  		return FormatError("tRNS, color type mismatch")
   278  	}
   279  	return d.verifyChecksum()
   280  }
   281  
   282  // Read presents one or more IDAT chunks as one continuous stream (minus the
   283  // intermediate chunk headers and footers). If the PNG data looked like:
   284  //   ... len0 IDAT xxx crc0 len1 IDAT yy crc1 len2 IEND crc2
   285  // then this reader presents xxxyy. For well-formed PNG data, the decoder state
   286  // immediately before the first Read call is that d.r is positioned between the
   287  // first IDAT and xxx, and the decoder state immediately after the last Read
   288  // call is that d.r is positioned between yy and crc1.
   289  func (d *decoder) Read(p []byte) (int, error) {
   290  	if len(p) == 0 {
   291  		return 0, nil
   292  	}
   293  	for d.idatLength == 0 {
   294  		// We have exhausted an IDAT chunk. Verify the checksum of that chunk.
   295  		if err := d.verifyChecksum(); err != nil {
   296  			return 0, err
   297  		}
   298  		// Read the length and chunk type of the next chunk, and check that
   299  		// it is an IDAT chunk.
   300  		if _, err := io.ReadFull(d.r, d.tmp[:8]); err != nil {
   301  			return 0, err
   302  		}
   303  		d.idatLength = binary.BigEndian.Uint32(d.tmp[:4])
   304  		if string(d.tmp[4:8]) != "IDAT" {
   305  			return 0, FormatError("not enough pixel data")
   306  		}
   307  		d.crc.Reset()
   308  		d.crc.Write(d.tmp[4:8])
   309  	}
   310  	if int(d.idatLength) < 0 {
   311  		return 0, UnsupportedError("IDAT chunk length overflow")
   312  	}
   313  	n, err := d.r.Read(p[:min(len(p), int(d.idatLength))])
   314  	d.crc.Write(p[:n])
   315  	d.idatLength -= uint32(n)
   316  	return n, err
   317  }
   318  
   319  // decode decodes the IDAT data into an image.
   320  func (d *decoder) decode() (image.Image, error) {
   321  	r, err := zlib.NewReader(d)
   322  	if err != nil {
   323  		return nil, err
   324  	}
   325  	defer r.Close()
   326  	var img image.Image
   327  	if d.interlace == itNone {
   328  		img, err = d.readImagePass(r, 0, false)
   329  		if err != nil {
   330  			return nil, err
   331  		}
   332  	} else if d.interlace == itAdam7 {
   333  		// Allocate a blank image of the full size.
   334  		img, err = d.readImagePass(nil, 0, true)
   335  		if err != nil {
   336  			return nil, err
   337  		}
   338  		for pass := 0; pass < 7; pass++ {
   339  			imagePass, err := d.readImagePass(r, pass, false)
   340  			if err != nil {
   341  				return nil, err
   342  			}
   343  			if imagePass != nil {
   344  				d.mergePassInto(img, imagePass, pass)
   345  			}
   346  		}
   347  	}
   348  
   349  	// Check for EOF, to verify the zlib checksum.
   350  	n := 0
   351  	for i := 0; n == 0 && err == nil; i++ {
   352  		if i == 100 {
   353  			return nil, io.ErrNoProgress
   354  		}
   355  		n, err = r.Read(d.tmp[:1])
   356  	}
   357  	if err != nil && err != io.EOF {
   358  		return nil, FormatError(err.Error())
   359  	}
   360  	if n != 0 || d.idatLength != 0 {
   361  		return nil, FormatError("too much pixel data")
   362  	}
   363  
   364  	return img, nil
   365  }
   366  
   367  // readImagePass reads a single image pass, sized according to the pass number.
   368  func (d *decoder) readImagePass(r io.Reader, pass int, allocateOnly bool) (image.Image, error) {
   369  	var bitsPerPixel int = 0
   370  	pixOffset := 0
   371  	var (
   372  		gray     *image.Gray
   373  		rgba     *image.RGBA
   374  		paletted *image.Paletted
   375  		nrgba    *image.NRGBA
   376  		gray16   *image.Gray16
   377  		rgba64   *image.RGBA64
   378  		nrgba64  *image.NRGBA64
   379  		img      image.Image
   380  	)
   381  	width, height := d.width, d.height
   382  	if d.interlace == itAdam7 && !allocateOnly {
   383  		p := interlacing[pass]
   384  		// Add the multiplication factor and subtract one, effectively rounding up.
   385  		width = (width - p.xOffset + p.xFactor - 1) / p.xFactor
   386  		height = (height - p.yOffset + p.yFactor - 1) / p.yFactor
   387  		// A PNG image can't have zero width or height, but for an interlaced
   388  		// image, an individual pass might have zero width or height. If so, we
   389  		// shouldn't even read a per-row filter type byte, so return early.
   390  		if width == 0 || height == 0 {
   391  			return nil, nil
   392  		}
   393  	}
   394  	switch d.cb {
   395  	case cbG1, cbG2, cbG4, cbG8:
   396  		bitsPerPixel = d.depth
   397  		gray = image.NewGray(image.Rect(0, 0, width, height))
   398  		img = gray
   399  	case cbGA8:
   400  		bitsPerPixel = 16
   401  		nrgba = image.NewNRGBA(image.Rect(0, 0, width, height))
   402  		img = nrgba
   403  	case cbTC8:
   404  		bitsPerPixel = 24
   405  		rgba = image.NewRGBA(image.Rect(0, 0, width, height))
   406  		img = rgba
   407  	case cbP1, cbP2, cbP4, cbP8:
   408  		bitsPerPixel = d.depth
   409  		paletted = image.NewPaletted(image.Rect(0, 0, width, height), d.palette)
   410  		img = paletted
   411  	case cbTCA8:
   412  		bitsPerPixel = 32
   413  		nrgba = image.NewNRGBA(image.Rect(0, 0, width, height))
   414  		img = nrgba
   415  	case cbG16:
   416  		bitsPerPixel = 16
   417  		gray16 = image.NewGray16(image.Rect(0, 0, width, height))
   418  		img = gray16
   419  	case cbGA16:
   420  		bitsPerPixel = 32
   421  		nrgba64 = image.NewNRGBA64(image.Rect(0, 0, width, height))
   422  		img = nrgba64
   423  	case cbTC16:
   424  		bitsPerPixel = 48
   425  		rgba64 = image.NewRGBA64(image.Rect(0, 0, width, height))
   426  		img = rgba64
   427  	case cbTCA16:
   428  		bitsPerPixel = 64
   429  		nrgba64 = image.NewNRGBA64(image.Rect(0, 0, width, height))
   430  		img = nrgba64
   431  	}
   432  	if allocateOnly {
   433  		return img, nil
   434  	}
   435  	bytesPerPixel := (bitsPerPixel + 7) / 8
   436  
   437  	// The +1 is for the per-row filter type, which is at cr[0].
   438  	rowSize := 1 + (bitsPerPixel*width+7)/8
   439  	// cr and pr are the bytes for the current and previous row.
   440  	cr := make([]uint8, rowSize)
   441  	pr := make([]uint8, rowSize)
   442  
   443  	for y := 0; y < height; y++ {
   444  		// Read the decompressed bytes.
   445  		_, err := io.ReadFull(r, cr)
   446  		if err != nil {
   447  			if err == io.EOF || err == io.ErrUnexpectedEOF {
   448  				return nil, FormatError("not enough pixel data")
   449  			}
   450  			return nil, err
   451  		}
   452  
   453  		// Apply the filter.
   454  		cdat := cr[1:]
   455  		pdat := pr[1:]
   456  		switch cr[0] {
   457  		case ftNone:
   458  			// No-op.
   459  		case ftSub:
   460  			for i := bytesPerPixel; i < len(cdat); i++ {
   461  				cdat[i] += cdat[i-bytesPerPixel]
   462  			}
   463  		case ftUp:
   464  			for i, p := range pdat {
   465  				cdat[i] += p
   466  			}
   467  		case ftAverage:
   468  			// The first column has no column to the left of it, so it is a
   469  			// special case. We know that the first column exists because we
   470  			// check above that width != 0, and so len(cdat) != 0.
   471  			for i := 0; i < bytesPerPixel; i++ {
   472  				cdat[i] += pdat[i] / 2
   473  			}
   474  			for i := bytesPerPixel; i < len(cdat); i++ {
   475  				cdat[i] += uint8((int(cdat[i-bytesPerPixel]) + int(pdat[i])) / 2)
   476  			}
   477  		case ftPaeth:
   478  			filterPaeth(cdat, pdat, bytesPerPixel)
   479  		default:
   480  			return nil, FormatError("bad filter type")
   481  		}
   482  
   483  		// Convert from bytes to colors.
   484  		switch d.cb {
   485  		case cbG1:
   486  			for x := 0; x < width; x += 8 {
   487  				b := cdat[x/8]
   488  				for x2 := 0; x2 < 8 && x+x2 < width; x2++ {
   489  					gray.SetGray(x+x2, y, color.Gray{(b >> 7) * 0xff})
   490  					b <<= 1
   491  				}
   492  			}
   493  		case cbG2:
   494  			for x := 0; x < width; x += 4 {
   495  				b := cdat[x/4]
   496  				for x2 := 0; x2 < 4 && x+x2 < width; x2++ {
   497  					gray.SetGray(x+x2, y, color.Gray{(b >> 6) * 0x55})
   498  					b <<= 2
   499  				}
   500  			}
   501  		case cbG4:
   502  			for x := 0; x < width; x += 2 {
   503  				b := cdat[x/2]
   504  				for x2 := 0; x2 < 2 && x+x2 < width; x2++ {
   505  					gray.SetGray(x+x2, y, color.Gray{(b >> 4) * 0x11})
   506  					b <<= 4
   507  				}
   508  			}
   509  		case cbG8:
   510  			copy(gray.Pix[pixOffset:], cdat)
   511  			pixOffset += gray.Stride
   512  		case cbGA8:
   513  			for x := 0; x < width; x++ {
   514  				ycol := cdat[2*x+0]
   515  				nrgba.SetNRGBA(x, y, color.NRGBA{ycol, ycol, ycol, cdat[2*x+1]})
   516  			}
   517  		case cbTC8:
   518  			pix, i, j := rgba.Pix, pixOffset, 0
   519  			for x := 0; x < width; x++ {
   520  				pix[i+0] = cdat[j+0]
   521  				pix[i+1] = cdat[j+1]
   522  				pix[i+2] = cdat[j+2]
   523  				pix[i+3] = 0xff
   524  				i += 4
   525  				j += 3
   526  			}
   527  			pixOffset += rgba.Stride
   528  		case cbP1:
   529  			for x := 0; x < width; x += 8 {
   530  				b := cdat[x/8]
   531  				for x2 := 0; x2 < 8 && x+x2 < width; x2++ {
   532  					idx := b >> 7
   533  					if len(paletted.Palette) <= int(idx) {
   534  						paletted.Palette = paletted.Palette[:int(idx)+1]
   535  					}
   536  					paletted.SetColorIndex(x+x2, y, idx)
   537  					b <<= 1
   538  				}
   539  			}
   540  		case cbP2:
   541  			for x := 0; x < width; x += 4 {
   542  				b := cdat[x/4]
   543  				for x2 := 0; x2 < 4 && x+x2 < width; x2++ {
   544  					idx := b >> 6
   545  					if len(paletted.Palette) <= int(idx) {
   546  						paletted.Palette = paletted.Palette[:int(idx)+1]
   547  					}
   548  					paletted.SetColorIndex(x+x2, y, idx)
   549  					b <<= 2
   550  				}
   551  			}
   552  		case cbP4:
   553  			for x := 0; x < width; x += 2 {
   554  				b := cdat[x/2]
   555  				for x2 := 0; x2 < 2 && x+x2 < width; x2++ {
   556  					idx := b >> 4
   557  					if len(paletted.Palette) <= int(idx) {
   558  						paletted.Palette = paletted.Palette[:int(idx)+1]
   559  					}
   560  					paletted.SetColorIndex(x+x2, y, idx)
   561  					b <<= 4
   562  				}
   563  			}
   564  		case cbP8:
   565  			if len(paletted.Palette) != 255 {
   566  				for x := 0; x < width; x++ {
   567  					if len(paletted.Palette) <= int(cdat[x]) {
   568  						paletted.Palette = paletted.Palette[:int(cdat[x])+1]
   569  					}
   570  				}
   571  			}
   572  			copy(paletted.Pix[pixOffset:], cdat)
   573  			pixOffset += paletted.Stride
   574  		case cbTCA8:
   575  			copy(nrgba.Pix[pixOffset:], cdat)
   576  			pixOffset += nrgba.Stride
   577  		case cbG16:
   578  			for x := 0; x < width; x++ {
   579  				ycol := uint16(cdat[2*x+0])<<8 | uint16(cdat[2*x+1])
   580  				gray16.SetGray16(x, y, color.Gray16{ycol})
   581  			}
   582  		case cbGA16:
   583  			for x := 0; x < width; x++ {
   584  				ycol := uint16(cdat[4*x+0])<<8 | uint16(cdat[4*x+1])
   585  				acol := uint16(cdat[4*x+2])<<8 | uint16(cdat[4*x+3])
   586  				nrgba64.SetNRGBA64(x, y, color.NRGBA64{ycol, ycol, ycol, acol})
   587  			}
   588  		case cbTC16:
   589  			for x := 0; x < width; x++ {
   590  				rcol := uint16(cdat[6*x+0])<<8 | uint16(cdat[6*x+1])
   591  				gcol := uint16(cdat[6*x+2])<<8 | uint16(cdat[6*x+3])
   592  				bcol := uint16(cdat[6*x+4])<<8 | uint16(cdat[6*x+5])
   593  				rgba64.SetRGBA64(x, y, color.RGBA64{rcol, gcol, bcol, 0xffff})
   594  			}
   595  		case cbTCA16:
   596  			for x := 0; x < width; x++ {
   597  				rcol := uint16(cdat[8*x+0])<<8 | uint16(cdat[8*x+1])
   598  				gcol := uint16(cdat[8*x+2])<<8 | uint16(cdat[8*x+3])
   599  				bcol := uint16(cdat[8*x+4])<<8 | uint16(cdat[8*x+5])
   600  				acol := uint16(cdat[8*x+6])<<8 | uint16(cdat[8*x+7])
   601  				nrgba64.SetNRGBA64(x, y, color.NRGBA64{rcol, gcol, bcol, acol})
   602  			}
   603  		}
   604  
   605  		// The current row for y is the previous row for y+1.
   606  		pr, cr = cr, pr
   607  	}
   608  
   609  	return img, nil
   610  }
   611  
   612  // mergePassInto merges a single pass into a full sized image.
   613  func (d *decoder) mergePassInto(dst image.Image, src image.Image, pass int) {
   614  	p := interlacing[pass]
   615  	var (
   616  		srcPix        []uint8
   617  		dstPix        []uint8
   618  		stride        int
   619  		rect          image.Rectangle
   620  		bytesPerPixel int
   621  	)
   622  	switch target := dst.(type) {
   623  	case *image.Alpha:
   624  		srcPix = src.(*image.Alpha).Pix
   625  		dstPix, stride, rect = target.Pix, target.Stride, target.Rect
   626  		bytesPerPixel = 1
   627  	case *image.Alpha16:
   628  		srcPix = src.(*image.Alpha16).Pix
   629  		dstPix, stride, rect = target.Pix, target.Stride, target.Rect
   630  		bytesPerPixel = 2
   631  	case *image.Gray:
   632  		srcPix = src.(*image.Gray).Pix
   633  		dstPix, stride, rect = target.Pix, target.Stride, target.Rect
   634  		bytesPerPixel = 1
   635  	case *image.Gray16:
   636  		srcPix = src.(*image.Gray16).Pix
   637  		dstPix, stride, rect = target.Pix, target.Stride, target.Rect
   638  		bytesPerPixel = 2
   639  	case *image.NRGBA:
   640  		srcPix = src.(*image.NRGBA).Pix
   641  		dstPix, stride, rect = target.Pix, target.Stride, target.Rect
   642  		bytesPerPixel = 4
   643  	case *image.NRGBA64:
   644  		srcPix = src.(*image.NRGBA64).Pix
   645  		dstPix, stride, rect = target.Pix, target.Stride, target.Rect
   646  		bytesPerPixel = 8
   647  	case *image.Paletted:
   648  		srcPix = src.(*image.Paletted).Pix
   649  		dstPix, stride, rect = target.Pix, target.Stride, target.Rect
   650  		bytesPerPixel = 1
   651  	case *image.RGBA:
   652  		srcPix = src.(*image.RGBA).Pix
   653  		dstPix, stride, rect = target.Pix, target.Stride, target.Rect
   654  		bytesPerPixel = 4
   655  	case *image.RGBA64:
   656  		srcPix = src.(*image.RGBA64).Pix
   657  		dstPix, stride, rect = target.Pix, target.Stride, target.Rect
   658  		bytesPerPixel = 8
   659  	}
   660  	s, bounds := 0, src.Bounds()
   661  	for y := bounds.Min.Y; y < bounds.Max.Y; y++ {
   662  		dBase := (y*p.yFactor+p.yOffset-rect.Min.Y)*stride + (p.xOffset-rect.Min.X)*bytesPerPixel
   663  		for x := bounds.Min.X; x < bounds.Max.X; x++ {
   664  			d := dBase + x*p.xFactor*bytesPerPixel
   665  			copy(dstPix[d:], srcPix[s:s+bytesPerPixel])
   666  			s += bytesPerPixel
   667  		}
   668  	}
   669  }
   670  
   671  func (d *decoder) parseIDAT(length uint32) (err error) {
   672  	d.idatLength = length
   673  	d.img, err = d.decode()
   674  	if err != nil {
   675  		return err
   676  	}
   677  	return d.verifyChecksum()
   678  }
   679  
   680  func (d *decoder) parseIEND(length uint32) error {
   681  	if length != 0 {
   682  		return FormatError("bad IEND length")
   683  	}
   684  	return d.verifyChecksum()
   685  }
   686  
   687  func (d *decoder) parseChunk() error {
   688  	// Read the length and chunk type.
   689  	n, err := io.ReadFull(d.r, d.tmp[:8])
   690  	if err != nil {
   691  		return err
   692  	}
   693  	length := binary.BigEndian.Uint32(d.tmp[:4])
   694  	d.crc.Reset()
   695  	d.crc.Write(d.tmp[4:8])
   696  
   697  	// Read the chunk data.
   698  	switch string(d.tmp[4:8]) {
   699  	case "IHDR":
   700  		if d.stage != dsStart {
   701  			return chunkOrderError
   702  		}
   703  		d.stage = dsSeenIHDR
   704  		return d.parseIHDR(length)
   705  	case "PLTE":
   706  		if d.stage != dsSeenIHDR {
   707  			return chunkOrderError
   708  		}
   709  		d.stage = dsSeenPLTE
   710  		return d.parsePLTE(length)
   711  	case "tRNS":
   712  		if d.stage != dsSeenPLTE {
   713  			return chunkOrderError
   714  		}
   715  		d.stage = dsSeentRNS
   716  		return d.parsetRNS(length)
   717  	case "IDAT":
   718  		if d.stage < dsSeenIHDR || d.stage > dsSeenIDAT || (d.stage == dsSeenIHDR && cbPaletted(d.cb)) {
   719  			return chunkOrderError
   720  		} else if d.stage == dsSeenIDAT {
   721  			// Ignore trailing zero-length or garbage IDAT chunks.
   722  			//
   723  			// This does not affect valid PNG images that contain multiple IDAT
   724  			// chunks, since the first call to parseIDAT below will consume all
   725  			// consecutive IDAT chunks required for decoding the image.
   726  			break
   727  		}
   728  		d.stage = dsSeenIDAT
   729  		return d.parseIDAT(length)
   730  	case "IEND":
   731  		if d.stage != dsSeenIDAT {
   732  			return chunkOrderError
   733  		}
   734  		d.stage = dsSeenIEND
   735  		return d.parseIEND(length)
   736  	}
   737  	if length > 0x7fffffff {
   738  		return FormatError(fmt.Sprintf("Bad chunk length: %d", length))
   739  	}
   740  	// Ignore this chunk (of a known length).
   741  	var ignored [4096]byte
   742  	for length > 0 {
   743  		n, err = io.ReadFull(d.r, ignored[:min(len(ignored), int(length))])
   744  		if err != nil {
   745  			return err
   746  		}
   747  		d.crc.Write(ignored[:n])
   748  		length -= uint32(n)
   749  	}
   750  	return d.verifyChecksum()
   751  }
   752  
   753  func (d *decoder) verifyChecksum() error {
   754  	if _, err := io.ReadFull(d.r, d.tmp[:4]); err != nil {
   755  		return err
   756  	}
   757  	if binary.BigEndian.Uint32(d.tmp[:4]) != d.crc.Sum32() {
   758  		return FormatError("invalid checksum")
   759  	}
   760  	return nil
   761  }
   762  
   763  func (d *decoder) checkHeader() error {
   764  	_, err := io.ReadFull(d.r, d.tmp[:len(pngHeader)])
   765  	if err != nil {
   766  		return err
   767  	}
   768  	if string(d.tmp[:len(pngHeader)]) != pngHeader {
   769  		return FormatError("not a PNG file")
   770  	}
   771  	return nil
   772  }
   773  
   774  // Decode reads a PNG image from r and returns it as an image.Image.
   775  // The type of Image returned depends on the PNG contents.
   776  func Decode(r io.Reader) (image.Image, error) {
   777  	d := &decoder{
   778  		r:   r,
   779  		crc: crc32.NewIEEE(),
   780  	}
   781  	if err := d.checkHeader(); err != nil {
   782  		if err == io.EOF {
   783  			err = io.ErrUnexpectedEOF
   784  		}
   785  		return nil, err
   786  	}
   787  	for d.stage != dsSeenIEND {
   788  		if err := d.parseChunk(); err != nil {
   789  			if err == io.EOF {
   790  				err = io.ErrUnexpectedEOF
   791  			}
   792  			return nil, err
   793  		}
   794  	}
   795  	return d.img, nil
   796  }
   797  
   798  // DecodeConfig returns the color model and dimensions of a PNG image without
   799  // decoding the entire image.
   800  func DecodeConfig(r io.Reader) (image.Config, error) {
   801  	d := &decoder{
   802  		r:   r,
   803  		crc: crc32.NewIEEE(),
   804  	}
   805  	if err := d.checkHeader(); err != nil {
   806  		if err == io.EOF {
   807  			err = io.ErrUnexpectedEOF
   808  		}
   809  		return image.Config{}, err
   810  	}
   811  	for {
   812  		if err := d.parseChunk(); err != nil {
   813  			if err == io.EOF {
   814  				err = io.ErrUnexpectedEOF
   815  			}
   816  			return image.Config{}, err
   817  		}
   818  		paletted := cbPaletted(d.cb)
   819  		if d.stage == dsSeenIHDR && !paletted {
   820  			break
   821  		}
   822  		if d.stage == dsSeenPLTE && paletted {
   823  			break
   824  		}
   825  	}
   826  	var cm color.Model
   827  	switch d.cb {
   828  	case cbG1, cbG2, cbG4, cbG8:
   829  		cm = color.GrayModel
   830  	case cbGA8:
   831  		cm = color.NRGBAModel
   832  	case cbTC8:
   833  		cm = color.RGBAModel
   834  	case cbP1, cbP2, cbP4, cbP8:
   835  		cm = d.palette
   836  	case cbTCA8:
   837  		cm = color.NRGBAModel
   838  	case cbG16:
   839  		cm = color.Gray16Model
   840  	case cbGA16:
   841  		cm = color.NRGBA64Model
   842  	case cbTC16:
   843  		cm = color.RGBA64Model
   844  	case cbTCA16:
   845  		cm = color.NRGBA64Model
   846  	}
   847  	return image.Config{
   848  		ColorModel: cm,
   849  		Width:      d.width,
   850  		Height:     d.height,
   851  	}, nil
   852  }
   853  
   854  func init() {
   855  	image.RegisterFormat("png", pngHeader, Decode, DecodeConfig)
   856  }