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