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