github.com/rsc/go@v0.0.0-20150416155037-e040fd465409/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("negative 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  	} else if d.interlace == itAdam7 {
   330  		// Allocate a blank image of the full size.
   331  		img, err = d.readImagePass(nil, 0, true)
   332  		for pass := 0; pass < 7; pass++ {
   333  			imagePass, err := d.readImagePass(r, pass, false)
   334  			if err != nil {
   335  				return nil, err
   336  			}
   337  			d.mergePassInto(img, imagePass, pass)
   338  		}
   339  	}
   340  
   341  	// Check for EOF, to verify the zlib checksum.
   342  	n := 0
   343  	for i := 0; n == 0 && err == nil; i++ {
   344  		if i == 100 {
   345  			return nil, io.ErrNoProgress
   346  		}
   347  		n, err = r.Read(d.tmp[:1])
   348  	}
   349  	if err != nil && err != io.EOF {
   350  		return nil, FormatError(err.Error())
   351  	}
   352  	if n != 0 || d.idatLength != 0 {
   353  		return nil, FormatError("too much pixel data")
   354  	}
   355  
   356  	return img, nil
   357  }
   358  
   359  // readImagePass reads a single image pass, sized according to the pass number.
   360  func (d *decoder) readImagePass(r io.Reader, pass int, allocateOnly bool) (image.Image, error) {
   361  	var bitsPerPixel int = 0
   362  	pixOffset := 0
   363  	var (
   364  		gray     *image.Gray
   365  		rgba     *image.RGBA
   366  		paletted *image.Paletted
   367  		nrgba    *image.NRGBA
   368  		gray16   *image.Gray16
   369  		rgba64   *image.RGBA64
   370  		nrgba64  *image.NRGBA64
   371  		img      image.Image
   372  	)
   373  	width, height := d.width, d.height
   374  	if d.interlace == itAdam7 && !allocateOnly {
   375  		p := interlacing[pass]
   376  		// Add the multiplication factor and subtract one, effectively rounding up.
   377  		width = (width - p.xOffset + p.xFactor - 1) / p.xFactor
   378  		height = (height - p.yOffset + p.yFactor - 1) / p.yFactor
   379  	}
   380  	switch d.cb {
   381  	case cbG1, cbG2, cbG4, cbG8:
   382  		bitsPerPixel = d.depth
   383  		gray = image.NewGray(image.Rect(0, 0, width, height))
   384  		img = gray
   385  	case cbGA8:
   386  		bitsPerPixel = 16
   387  		nrgba = image.NewNRGBA(image.Rect(0, 0, width, height))
   388  		img = nrgba
   389  	case cbTC8:
   390  		bitsPerPixel = 24
   391  		rgba = image.NewRGBA(image.Rect(0, 0, width, height))
   392  		img = rgba
   393  	case cbP1, cbP2, cbP4, cbP8:
   394  		bitsPerPixel = d.depth
   395  		paletted = image.NewPaletted(image.Rect(0, 0, width, height), d.palette)
   396  		img = paletted
   397  	case cbTCA8:
   398  		bitsPerPixel = 32
   399  		nrgba = image.NewNRGBA(image.Rect(0, 0, width, height))
   400  		img = nrgba
   401  	case cbG16:
   402  		bitsPerPixel = 16
   403  		gray16 = image.NewGray16(image.Rect(0, 0, width, height))
   404  		img = gray16
   405  	case cbGA16:
   406  		bitsPerPixel = 32
   407  		nrgba64 = image.NewNRGBA64(image.Rect(0, 0, width, height))
   408  		img = nrgba64
   409  	case cbTC16:
   410  		bitsPerPixel = 48
   411  		rgba64 = image.NewRGBA64(image.Rect(0, 0, width, height))
   412  		img = rgba64
   413  	case cbTCA16:
   414  		bitsPerPixel = 64
   415  		nrgba64 = image.NewNRGBA64(image.Rect(0, 0, width, height))
   416  		img = nrgba64
   417  	}
   418  	if allocateOnly {
   419  		return img, nil
   420  	}
   421  	bytesPerPixel := (bitsPerPixel + 7) / 8
   422  
   423  	// The +1 is for the per-row filter type, which is at cr[0].
   424  	rowSize := 1 + (bitsPerPixel*width+7)/8
   425  	// cr and pr are the bytes for the current and previous row.
   426  	cr := make([]uint8, rowSize)
   427  	pr := make([]uint8, rowSize)
   428  
   429  	for y := 0; y < height; y++ {
   430  		// Read the decompressed bytes.
   431  		_, err := io.ReadFull(r, cr)
   432  		if err != nil {
   433  			return nil, err
   434  		}
   435  
   436  		// Apply the filter.
   437  		cdat := cr[1:]
   438  		pdat := pr[1:]
   439  		switch cr[0] {
   440  		case ftNone:
   441  			// No-op.
   442  		case ftSub:
   443  			for i := bytesPerPixel; i < len(cdat); i++ {
   444  				cdat[i] += cdat[i-bytesPerPixel]
   445  			}
   446  		case ftUp:
   447  			for i, p := range pdat {
   448  				cdat[i] += p
   449  			}
   450  		case ftAverage:
   451  			for i := 0; i < bytesPerPixel; i++ {
   452  				cdat[i] += pdat[i] / 2
   453  			}
   454  			for i := bytesPerPixel; i < len(cdat); i++ {
   455  				cdat[i] += uint8((int(cdat[i-bytesPerPixel]) + int(pdat[i])) / 2)
   456  			}
   457  		case ftPaeth:
   458  			filterPaeth(cdat, pdat, bytesPerPixel)
   459  		default:
   460  			return nil, FormatError("bad filter type")
   461  		}
   462  
   463  		// Convert from bytes to colors.
   464  		switch d.cb {
   465  		case cbG1:
   466  			for x := 0; x < width; x += 8 {
   467  				b := cdat[x/8]
   468  				for x2 := 0; x2 < 8 && x+x2 < width; x2++ {
   469  					gray.SetGray(x+x2, y, color.Gray{(b >> 7) * 0xff})
   470  					b <<= 1
   471  				}
   472  			}
   473  		case cbG2:
   474  			for x := 0; x < width; x += 4 {
   475  				b := cdat[x/4]
   476  				for x2 := 0; x2 < 4 && x+x2 < width; x2++ {
   477  					gray.SetGray(x+x2, y, color.Gray{(b >> 6) * 0x55})
   478  					b <<= 2
   479  				}
   480  			}
   481  		case cbG4:
   482  			for x := 0; x < width; x += 2 {
   483  				b := cdat[x/2]
   484  				for x2 := 0; x2 < 2 && x+x2 < width; x2++ {
   485  					gray.SetGray(x+x2, y, color.Gray{(b >> 4) * 0x11})
   486  					b <<= 4
   487  				}
   488  			}
   489  		case cbG8:
   490  			copy(gray.Pix[pixOffset:], cdat)
   491  			pixOffset += gray.Stride
   492  		case cbGA8:
   493  			for x := 0; x < width; x++ {
   494  				ycol := cdat[2*x+0]
   495  				nrgba.SetNRGBA(x, y, color.NRGBA{ycol, ycol, ycol, cdat[2*x+1]})
   496  			}
   497  		case cbTC8:
   498  			pix, i, j := rgba.Pix, pixOffset, 0
   499  			for x := 0; x < width; x++ {
   500  				pix[i+0] = cdat[j+0]
   501  				pix[i+1] = cdat[j+1]
   502  				pix[i+2] = cdat[j+2]
   503  				pix[i+3] = 0xff
   504  				i += 4
   505  				j += 3
   506  			}
   507  			pixOffset += rgba.Stride
   508  		case cbP1:
   509  			for x := 0; x < width; x += 8 {
   510  				b := cdat[x/8]
   511  				for x2 := 0; x2 < 8 && x+x2 < width; x2++ {
   512  					idx := b >> 7
   513  					if len(paletted.Palette) <= int(idx) {
   514  						paletted.Palette = paletted.Palette[:int(idx)+1]
   515  					}
   516  					paletted.SetColorIndex(x+x2, y, idx)
   517  					b <<= 1
   518  				}
   519  			}
   520  		case cbP2:
   521  			for x := 0; x < width; x += 4 {
   522  				b := cdat[x/4]
   523  				for x2 := 0; x2 < 4 && x+x2 < width; x2++ {
   524  					idx := b >> 6
   525  					if len(paletted.Palette) <= int(idx) {
   526  						paletted.Palette = paletted.Palette[:int(idx)+1]
   527  					}
   528  					paletted.SetColorIndex(x+x2, y, idx)
   529  					b <<= 2
   530  				}
   531  			}
   532  		case cbP4:
   533  			for x := 0; x < width; x += 2 {
   534  				b := cdat[x/2]
   535  				for x2 := 0; x2 < 2 && x+x2 < width; x2++ {
   536  					idx := b >> 4
   537  					if len(paletted.Palette) <= int(idx) {
   538  						paletted.Palette = paletted.Palette[:int(idx)+1]
   539  					}
   540  					paletted.SetColorIndex(x+x2, y, idx)
   541  					b <<= 4
   542  				}
   543  			}
   544  		case cbP8:
   545  			if len(paletted.Palette) != 255 {
   546  				for x := 0; x < width; x++ {
   547  					if len(paletted.Palette) <= int(cdat[x]) {
   548  						paletted.Palette = paletted.Palette[:int(cdat[x])+1]
   549  					}
   550  				}
   551  			}
   552  			copy(paletted.Pix[pixOffset:], cdat)
   553  			pixOffset += paletted.Stride
   554  		case cbTCA8:
   555  			copy(nrgba.Pix[pixOffset:], cdat)
   556  			pixOffset += nrgba.Stride
   557  		case cbG16:
   558  			for x := 0; x < width; x++ {
   559  				ycol := uint16(cdat[2*x+0])<<8 | uint16(cdat[2*x+1])
   560  				gray16.SetGray16(x, y, color.Gray16{ycol})
   561  			}
   562  		case cbGA16:
   563  			for x := 0; x < width; x++ {
   564  				ycol := uint16(cdat[4*x+0])<<8 | uint16(cdat[4*x+1])
   565  				acol := uint16(cdat[4*x+2])<<8 | uint16(cdat[4*x+3])
   566  				nrgba64.SetNRGBA64(x, y, color.NRGBA64{ycol, ycol, ycol, acol})
   567  			}
   568  		case cbTC16:
   569  			for x := 0; x < width; x++ {
   570  				rcol := uint16(cdat[6*x+0])<<8 | uint16(cdat[6*x+1])
   571  				gcol := uint16(cdat[6*x+2])<<8 | uint16(cdat[6*x+3])
   572  				bcol := uint16(cdat[6*x+4])<<8 | uint16(cdat[6*x+5])
   573  				rgba64.SetRGBA64(x, y, color.RGBA64{rcol, gcol, bcol, 0xffff})
   574  			}
   575  		case cbTCA16:
   576  			for x := 0; x < width; x++ {
   577  				rcol := uint16(cdat[8*x+0])<<8 | uint16(cdat[8*x+1])
   578  				gcol := uint16(cdat[8*x+2])<<8 | uint16(cdat[8*x+3])
   579  				bcol := uint16(cdat[8*x+4])<<8 | uint16(cdat[8*x+5])
   580  				acol := uint16(cdat[8*x+6])<<8 | uint16(cdat[8*x+7])
   581  				nrgba64.SetNRGBA64(x, y, color.NRGBA64{rcol, gcol, bcol, acol})
   582  			}
   583  		}
   584  
   585  		// The current row for y is the previous row for y+1.
   586  		pr, cr = cr, pr
   587  	}
   588  
   589  	return img, nil
   590  }
   591  
   592  // mergePassInto merges a single pass into a full sized image.
   593  func (d *decoder) mergePassInto(dst image.Image, src image.Image, pass int) {
   594  	p := interlacing[pass]
   595  	var (
   596  		srcPix        []uint8
   597  		dstPix        []uint8
   598  		stride        int
   599  		rect          image.Rectangle
   600  		bytesPerPixel int
   601  	)
   602  	switch target := dst.(type) {
   603  	case *image.Alpha:
   604  		srcPix = src.(*image.Alpha).Pix
   605  		dstPix, stride, rect = target.Pix, target.Stride, target.Rect
   606  		bytesPerPixel = 1
   607  	case *image.Alpha16:
   608  		srcPix = src.(*image.Alpha16).Pix
   609  		dstPix, stride, rect = target.Pix, target.Stride, target.Rect
   610  		bytesPerPixel = 2
   611  	case *image.Gray:
   612  		srcPix = src.(*image.Gray).Pix
   613  		dstPix, stride, rect = target.Pix, target.Stride, target.Rect
   614  		bytesPerPixel = 1
   615  	case *image.Gray16:
   616  		srcPix = src.(*image.Gray16).Pix
   617  		dstPix, stride, rect = target.Pix, target.Stride, target.Rect
   618  		bytesPerPixel = 2
   619  	case *image.NRGBA:
   620  		srcPix = src.(*image.NRGBA).Pix
   621  		dstPix, stride, rect = target.Pix, target.Stride, target.Rect
   622  		bytesPerPixel = 4
   623  	case *image.NRGBA64:
   624  		srcPix = src.(*image.NRGBA64).Pix
   625  		dstPix, stride, rect = target.Pix, target.Stride, target.Rect
   626  		bytesPerPixel = 8
   627  	case *image.Paletted:
   628  		srcPix = src.(*image.Paletted).Pix
   629  		dstPix, stride, rect = target.Pix, target.Stride, target.Rect
   630  		bytesPerPixel = 1
   631  	case *image.RGBA:
   632  		srcPix = src.(*image.RGBA).Pix
   633  		dstPix, stride, rect = target.Pix, target.Stride, target.Rect
   634  		bytesPerPixel = 4
   635  	case *image.RGBA64:
   636  		srcPix = src.(*image.RGBA64).Pix
   637  		dstPix, stride, rect = target.Pix, target.Stride, target.Rect
   638  		bytesPerPixel = 8
   639  	}
   640  	s, bounds := 0, src.Bounds()
   641  	for y := bounds.Min.Y; y < bounds.Max.Y; y++ {
   642  		dBase := (y*p.yFactor+p.yOffset-rect.Min.Y)*stride + (p.xOffset-rect.Min.X)*bytesPerPixel
   643  		for x := bounds.Min.X; x < bounds.Max.X; x++ {
   644  			d := dBase + x*p.xFactor*bytesPerPixel
   645  			copy(dstPix[d:], srcPix[s:s+bytesPerPixel])
   646  			s += bytesPerPixel
   647  		}
   648  	}
   649  }
   650  
   651  func (d *decoder) parseIDAT(length uint32) (err error) {
   652  	d.idatLength = length
   653  	d.img, err = d.decode()
   654  	if err != nil {
   655  		return err
   656  	}
   657  	return d.verifyChecksum()
   658  }
   659  
   660  func (d *decoder) parseIEND(length uint32) error {
   661  	if length != 0 {
   662  		return FormatError("bad IEND length")
   663  	}
   664  	return d.verifyChecksum()
   665  }
   666  
   667  func (d *decoder) parseChunk() error {
   668  	// Read the length and chunk type.
   669  	n, err := io.ReadFull(d.r, d.tmp[:8])
   670  	if err != nil {
   671  		return err
   672  	}
   673  	length := binary.BigEndian.Uint32(d.tmp[:4])
   674  	d.crc.Reset()
   675  	d.crc.Write(d.tmp[4:8])
   676  
   677  	// Read the chunk data.
   678  	switch string(d.tmp[4:8]) {
   679  	case "IHDR":
   680  		if d.stage != dsStart {
   681  			return chunkOrderError
   682  		}
   683  		d.stage = dsSeenIHDR
   684  		return d.parseIHDR(length)
   685  	case "PLTE":
   686  		if d.stage != dsSeenIHDR {
   687  			return chunkOrderError
   688  		}
   689  		d.stage = dsSeenPLTE
   690  		return d.parsePLTE(length)
   691  	case "tRNS":
   692  		if d.stage != dsSeenPLTE {
   693  			return chunkOrderError
   694  		}
   695  		d.stage = dsSeentRNS
   696  		return d.parsetRNS(length)
   697  	case "IDAT":
   698  		if d.stage < dsSeenIHDR || d.stage > dsSeenIDAT || (d.stage == dsSeenIHDR && cbPaletted(d.cb)) {
   699  			return chunkOrderError
   700  		}
   701  		d.stage = dsSeenIDAT
   702  		return d.parseIDAT(length)
   703  	case "IEND":
   704  		if d.stage != dsSeenIDAT {
   705  			return chunkOrderError
   706  		}
   707  		d.stage = dsSeenIEND
   708  		return d.parseIEND(length)
   709  	}
   710  	// Ignore this chunk (of a known length).
   711  	var ignored [4096]byte
   712  	for length > 0 {
   713  		n, err = io.ReadFull(d.r, ignored[:min(len(ignored), int(length))])
   714  		if err != nil {
   715  			return err
   716  		}
   717  		d.crc.Write(ignored[:n])
   718  		length -= uint32(n)
   719  	}
   720  	return d.verifyChecksum()
   721  }
   722  
   723  func (d *decoder) verifyChecksum() error {
   724  	if _, err := io.ReadFull(d.r, d.tmp[:4]); err != nil {
   725  		return err
   726  	}
   727  	if binary.BigEndian.Uint32(d.tmp[:4]) != d.crc.Sum32() {
   728  		return FormatError("invalid checksum")
   729  	}
   730  	return nil
   731  }
   732  
   733  func (d *decoder) checkHeader() error {
   734  	_, err := io.ReadFull(d.r, d.tmp[:len(pngHeader)])
   735  	if err != nil {
   736  		return err
   737  	}
   738  	if string(d.tmp[:len(pngHeader)]) != pngHeader {
   739  		return FormatError("not a PNG file")
   740  	}
   741  	return nil
   742  }
   743  
   744  // Decode reads a PNG image from r and returns it as an image.Image.
   745  // The type of Image returned depends on the PNG contents.
   746  func Decode(r io.Reader) (image.Image, error) {
   747  	d := &decoder{
   748  		r:   r,
   749  		crc: crc32.NewIEEE(),
   750  	}
   751  	if err := d.checkHeader(); err != nil {
   752  		if err == io.EOF {
   753  			err = io.ErrUnexpectedEOF
   754  		}
   755  		return nil, err
   756  	}
   757  	for d.stage != dsSeenIEND {
   758  		if err := d.parseChunk(); err != nil {
   759  			if err == io.EOF {
   760  				err = io.ErrUnexpectedEOF
   761  			}
   762  			return nil, err
   763  		}
   764  	}
   765  	return d.img, nil
   766  }
   767  
   768  // DecodeConfig returns the color model and dimensions of a PNG image without
   769  // decoding the entire image.
   770  func DecodeConfig(r io.Reader) (image.Config, error) {
   771  	d := &decoder{
   772  		r:   r,
   773  		crc: crc32.NewIEEE(),
   774  	}
   775  	if err := d.checkHeader(); err != nil {
   776  		if err == io.EOF {
   777  			err = io.ErrUnexpectedEOF
   778  		}
   779  		return image.Config{}, err
   780  	}
   781  	for {
   782  		if err := d.parseChunk(); err != nil {
   783  			if err == io.EOF {
   784  				err = io.ErrUnexpectedEOF
   785  			}
   786  			return image.Config{}, err
   787  		}
   788  		paletted := cbPaletted(d.cb)
   789  		if d.stage == dsSeenIHDR && !paletted {
   790  			break
   791  		}
   792  		if d.stage == dsSeenPLTE && paletted {
   793  			break
   794  		}
   795  	}
   796  	var cm color.Model
   797  	switch d.cb {
   798  	case cbG1, cbG2, cbG4, cbG8:
   799  		cm = color.GrayModel
   800  	case cbGA8:
   801  		cm = color.NRGBAModel
   802  	case cbTC8:
   803  		cm = color.RGBAModel
   804  	case cbP1, cbP2, cbP4, cbP8:
   805  		cm = d.palette
   806  	case cbTCA8:
   807  		cm = color.NRGBAModel
   808  	case cbG16:
   809  		cm = color.Gray16Model
   810  	case cbGA16:
   811  		cm = color.NRGBA64Model
   812  	case cbTC16:
   813  		cm = color.RGBA64Model
   814  	case cbTCA16:
   815  		cm = color.NRGBA64Model
   816  	}
   817  	return image.Config{
   818  		ColorModel: cm,
   819  		Width:      d.width,
   820  		Height:     d.height,
   821  	}, nil
   822  }
   823  
   824  func init() {
   825  	image.RegisterFormat("png", pngHeader, Decode, DecodeConfig)
   826  }