github.com/rakyll/go@v0.0.0-20170216000551-64c02460d703/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  			copy(gray.Pix[pixOffset:], cdat)
   616  			pixOffset += gray.Stride
   617  		case cbGA8:
   618  			for x := 0; x < width; x++ {
   619  				ycol := cdat[2*x+0]
   620  				nrgba.SetNRGBA(x, y, color.NRGBA{ycol, ycol, ycol, cdat[2*x+1]})
   621  			}
   622  		case cbTC8:
   623  			if d.useTransparent {
   624  				pix, i, j := nrgba.Pix, pixOffset, 0
   625  				tr, tg, tb := d.transparent[1], d.transparent[3], d.transparent[5]
   626  				for x := 0; x < width; x++ {
   627  					r := cdat[j+0]
   628  					g := cdat[j+1]
   629  					b := cdat[j+2]
   630  					a := uint8(0xff)
   631  					if r == tr && g == tg && b == tb {
   632  						a = 0x00
   633  					}
   634  					pix[i+0] = r
   635  					pix[i+1] = g
   636  					pix[i+2] = b
   637  					pix[i+3] = a
   638  					i += 4
   639  					j += 3
   640  				}
   641  				pixOffset += nrgba.Stride
   642  			} else {
   643  				pix, i, j := rgba.Pix, pixOffset, 0
   644  				for x := 0; x < width; x++ {
   645  					pix[i+0] = cdat[j+0]
   646  					pix[i+1] = cdat[j+1]
   647  					pix[i+2] = cdat[j+2]
   648  					pix[i+3] = 0xff
   649  					i += 4
   650  					j += 3
   651  				}
   652  				pixOffset += rgba.Stride
   653  			}
   654  		case cbP1:
   655  			for x := 0; x < width; x += 8 {
   656  				b := cdat[x/8]
   657  				for x2 := 0; x2 < 8 && x+x2 < width; x2++ {
   658  					idx := b >> 7
   659  					if len(paletted.Palette) <= int(idx) {
   660  						paletted.Palette = paletted.Palette[:int(idx)+1]
   661  					}
   662  					paletted.SetColorIndex(x+x2, y, idx)
   663  					b <<= 1
   664  				}
   665  			}
   666  		case cbP2:
   667  			for x := 0; x < width; x += 4 {
   668  				b := cdat[x/4]
   669  				for x2 := 0; x2 < 4 && x+x2 < width; x2++ {
   670  					idx := b >> 6
   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 <<= 2
   676  				}
   677  			}
   678  		case cbP4:
   679  			for x := 0; x < width; x += 2 {
   680  				b := cdat[x/2]
   681  				for x2 := 0; x2 < 2 && x+x2 < width; x2++ {
   682  					idx := b >> 4
   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 <<= 4
   688  				}
   689  			}
   690  		case cbP8:
   691  			if len(paletted.Palette) != 255 {
   692  				for x := 0; x < width; x++ {
   693  					if len(paletted.Palette) <= int(cdat[x]) {
   694  						paletted.Palette = paletted.Palette[:int(cdat[x])+1]
   695  					}
   696  				}
   697  			}
   698  			copy(paletted.Pix[pixOffset:], cdat)
   699  			pixOffset += paletted.Stride
   700  		case cbTCA8:
   701  			copy(nrgba.Pix[pixOffset:], cdat)
   702  			pixOffset += nrgba.Stride
   703  		case cbG16:
   704  			if d.useTransparent {
   705  				ty := uint16(d.transparent[0])<<8 | uint16(d.transparent[1])
   706  				for x := 0; x < width; x++ {
   707  					ycol := uint16(cdat[2*x+0])<<8 | uint16(cdat[2*x+1])
   708  					acol := uint16(0xffff)
   709  					if ycol == ty {
   710  						acol = 0x0000
   711  					}
   712  					nrgba64.SetNRGBA64(x, y, color.NRGBA64{ycol, ycol, ycol, acol})
   713  				}
   714  			} else {
   715  				for x := 0; x < width; x++ {
   716  					ycol := uint16(cdat[2*x+0])<<8 | uint16(cdat[2*x+1])
   717  					gray16.SetGray16(x, y, color.Gray16{ycol})
   718  				}
   719  			}
   720  		case cbGA16:
   721  			for x := 0; x < width; x++ {
   722  				ycol := uint16(cdat[4*x+0])<<8 | uint16(cdat[4*x+1])
   723  				acol := uint16(cdat[4*x+2])<<8 | uint16(cdat[4*x+3])
   724  				nrgba64.SetNRGBA64(x, y, color.NRGBA64{ycol, ycol, ycol, acol})
   725  			}
   726  		case cbTC16:
   727  			if d.useTransparent {
   728  				tr := uint16(d.transparent[0])<<8 | uint16(d.transparent[1])
   729  				tg := uint16(d.transparent[2])<<8 | uint16(d.transparent[3])
   730  				tb := uint16(d.transparent[4])<<8 | uint16(d.transparent[5])
   731  				for x := 0; x < width; x++ {
   732  					rcol := uint16(cdat[6*x+0])<<8 | uint16(cdat[6*x+1])
   733  					gcol := uint16(cdat[6*x+2])<<8 | uint16(cdat[6*x+3])
   734  					bcol := uint16(cdat[6*x+4])<<8 | uint16(cdat[6*x+5])
   735  					acol := uint16(0xffff)
   736  					if rcol == tr && gcol == tg && bcol == tb {
   737  						acol = 0x0000
   738  					}
   739  					nrgba64.SetNRGBA64(x, y, color.NRGBA64{rcol, gcol, bcol, acol})
   740  				}
   741  			} else {
   742  				for x := 0; x < width; x++ {
   743  					rcol := uint16(cdat[6*x+0])<<8 | uint16(cdat[6*x+1])
   744  					gcol := uint16(cdat[6*x+2])<<8 | uint16(cdat[6*x+3])
   745  					bcol := uint16(cdat[6*x+4])<<8 | uint16(cdat[6*x+5])
   746  					rgba64.SetRGBA64(x, y, color.RGBA64{rcol, gcol, bcol, 0xffff})
   747  				}
   748  			}
   749  		case cbTCA16:
   750  			for x := 0; x < width; x++ {
   751  				rcol := uint16(cdat[8*x+0])<<8 | uint16(cdat[8*x+1])
   752  				gcol := uint16(cdat[8*x+2])<<8 | uint16(cdat[8*x+3])
   753  				bcol := uint16(cdat[8*x+4])<<8 | uint16(cdat[8*x+5])
   754  				acol := uint16(cdat[8*x+6])<<8 | uint16(cdat[8*x+7])
   755  				nrgba64.SetNRGBA64(x, y, color.NRGBA64{rcol, gcol, bcol, acol})
   756  			}
   757  		}
   758  
   759  		// The current row for y is the previous row for y+1.
   760  		pr, cr = cr, pr
   761  	}
   762  
   763  	return img, nil
   764  }
   765  
   766  // mergePassInto merges a single pass into a full sized image.
   767  func (d *decoder) mergePassInto(dst image.Image, src image.Image, pass int) {
   768  	p := interlacing[pass]
   769  	var (
   770  		srcPix        []uint8
   771  		dstPix        []uint8
   772  		stride        int
   773  		rect          image.Rectangle
   774  		bytesPerPixel int
   775  	)
   776  	switch target := dst.(type) {
   777  	case *image.Alpha:
   778  		srcPix = src.(*image.Alpha).Pix
   779  		dstPix, stride, rect = target.Pix, target.Stride, target.Rect
   780  		bytesPerPixel = 1
   781  	case *image.Alpha16:
   782  		srcPix = src.(*image.Alpha16).Pix
   783  		dstPix, stride, rect = target.Pix, target.Stride, target.Rect
   784  		bytesPerPixel = 2
   785  	case *image.Gray:
   786  		srcPix = src.(*image.Gray).Pix
   787  		dstPix, stride, rect = target.Pix, target.Stride, target.Rect
   788  		bytesPerPixel = 1
   789  	case *image.Gray16:
   790  		srcPix = src.(*image.Gray16).Pix
   791  		dstPix, stride, rect = target.Pix, target.Stride, target.Rect
   792  		bytesPerPixel = 2
   793  	case *image.NRGBA:
   794  		srcPix = src.(*image.NRGBA).Pix
   795  		dstPix, stride, rect = target.Pix, target.Stride, target.Rect
   796  		bytesPerPixel = 4
   797  	case *image.NRGBA64:
   798  		srcPix = src.(*image.NRGBA64).Pix
   799  		dstPix, stride, rect = target.Pix, target.Stride, target.Rect
   800  		bytesPerPixel = 8
   801  	case *image.Paletted:
   802  		srcPix = src.(*image.Paletted).Pix
   803  		dstPix, stride, rect = target.Pix, target.Stride, target.Rect
   804  		bytesPerPixel = 1
   805  	case *image.RGBA:
   806  		srcPix = src.(*image.RGBA).Pix
   807  		dstPix, stride, rect = target.Pix, target.Stride, target.Rect
   808  		bytesPerPixel = 4
   809  	case *image.RGBA64:
   810  		srcPix = src.(*image.RGBA64).Pix
   811  		dstPix, stride, rect = target.Pix, target.Stride, target.Rect
   812  		bytesPerPixel = 8
   813  	}
   814  	s, bounds := 0, src.Bounds()
   815  	for y := bounds.Min.Y; y < bounds.Max.Y; y++ {
   816  		dBase := (y*p.yFactor+p.yOffset-rect.Min.Y)*stride + (p.xOffset-rect.Min.X)*bytesPerPixel
   817  		for x := bounds.Min.X; x < bounds.Max.X; x++ {
   818  			d := dBase + x*p.xFactor*bytesPerPixel
   819  			copy(dstPix[d:], srcPix[s:s+bytesPerPixel])
   820  			s += bytesPerPixel
   821  		}
   822  	}
   823  }
   824  
   825  func (d *decoder) parseIDAT(length uint32) (err error) {
   826  	d.idatLength = length
   827  	d.img, err = d.decode()
   828  	if err != nil {
   829  		return err
   830  	}
   831  	return d.verifyChecksum()
   832  }
   833  
   834  func (d *decoder) parseIEND(length uint32) error {
   835  	if length != 0 {
   836  		return FormatError("bad IEND length")
   837  	}
   838  	return d.verifyChecksum()
   839  }
   840  
   841  func (d *decoder) parseChunk() error {
   842  	// Read the length and chunk type.
   843  	n, err := io.ReadFull(d.r, d.tmp[:8])
   844  	if err != nil {
   845  		return err
   846  	}
   847  	length := binary.BigEndian.Uint32(d.tmp[:4])
   848  	d.crc.Reset()
   849  	d.crc.Write(d.tmp[4:8])
   850  
   851  	// Read the chunk data.
   852  	switch string(d.tmp[4:8]) {
   853  	case "IHDR":
   854  		if d.stage != dsStart {
   855  			return chunkOrderError
   856  		}
   857  		d.stage = dsSeenIHDR
   858  		return d.parseIHDR(length)
   859  	case "PLTE":
   860  		if d.stage != dsSeenIHDR {
   861  			return chunkOrderError
   862  		}
   863  		d.stage = dsSeenPLTE
   864  		return d.parsePLTE(length)
   865  	case "tRNS":
   866  		if cbPaletted(d.cb) {
   867  			if d.stage != dsSeenPLTE {
   868  				return chunkOrderError
   869  			}
   870  		} else if d.stage != dsSeenIHDR {
   871  			return chunkOrderError
   872  		}
   873  		d.stage = dsSeentRNS
   874  		return d.parsetRNS(length)
   875  	case "IDAT":
   876  		if d.stage < dsSeenIHDR || d.stage > dsSeenIDAT || (d.stage == dsSeenIHDR && cbPaletted(d.cb)) {
   877  			return chunkOrderError
   878  		} else if d.stage == dsSeenIDAT {
   879  			// Ignore trailing zero-length or garbage IDAT chunks.
   880  			//
   881  			// This does not affect valid PNG images that contain multiple IDAT
   882  			// chunks, since the first call to parseIDAT below will consume all
   883  			// consecutive IDAT chunks required for decoding the image.
   884  			break
   885  		}
   886  		d.stage = dsSeenIDAT
   887  		return d.parseIDAT(length)
   888  	case "IEND":
   889  		if d.stage != dsSeenIDAT {
   890  			return chunkOrderError
   891  		}
   892  		d.stage = dsSeenIEND
   893  		return d.parseIEND(length)
   894  	}
   895  	if length > 0x7fffffff {
   896  		return FormatError(fmt.Sprintf("Bad chunk length: %d", length))
   897  	}
   898  	// Ignore this chunk (of a known length).
   899  	var ignored [4096]byte
   900  	for length > 0 {
   901  		n, err = io.ReadFull(d.r, ignored[:min(len(ignored), int(length))])
   902  		if err != nil {
   903  			return err
   904  		}
   905  		d.crc.Write(ignored[:n])
   906  		length -= uint32(n)
   907  	}
   908  	return d.verifyChecksum()
   909  }
   910  
   911  func (d *decoder) verifyChecksum() error {
   912  	if _, err := io.ReadFull(d.r, d.tmp[:4]); err != nil {
   913  		return err
   914  	}
   915  	if binary.BigEndian.Uint32(d.tmp[:4]) != d.crc.Sum32() {
   916  		return FormatError("invalid checksum")
   917  	}
   918  	return nil
   919  }
   920  
   921  func (d *decoder) checkHeader() error {
   922  	_, err := io.ReadFull(d.r, d.tmp[:len(pngHeader)])
   923  	if err != nil {
   924  		return err
   925  	}
   926  	if string(d.tmp[:len(pngHeader)]) != pngHeader {
   927  		return FormatError("not a PNG file")
   928  	}
   929  	return nil
   930  }
   931  
   932  // Decode reads a PNG image from r and returns it as an image.Image.
   933  // The type of Image returned depends on the PNG contents.
   934  func Decode(r io.Reader) (image.Image, error) {
   935  	d := &decoder{
   936  		r:   r,
   937  		crc: crc32.NewIEEE(),
   938  	}
   939  	if err := d.checkHeader(); err != nil {
   940  		if err == io.EOF {
   941  			err = io.ErrUnexpectedEOF
   942  		}
   943  		return nil, err
   944  	}
   945  	for d.stage != dsSeenIEND {
   946  		if err := d.parseChunk(); err != nil {
   947  			if err == io.EOF {
   948  				err = io.ErrUnexpectedEOF
   949  			}
   950  			return nil, err
   951  		}
   952  	}
   953  	return d.img, nil
   954  }
   955  
   956  // DecodeConfig returns the color model and dimensions of a PNG image without
   957  // decoding the entire image.
   958  func DecodeConfig(r io.Reader) (image.Config, error) {
   959  	d := &decoder{
   960  		r:   r,
   961  		crc: crc32.NewIEEE(),
   962  	}
   963  	if err := d.checkHeader(); err != nil {
   964  		if err == io.EOF {
   965  			err = io.ErrUnexpectedEOF
   966  		}
   967  		return image.Config{}, err
   968  	}
   969  	for {
   970  		if err := d.parseChunk(); err != nil {
   971  			if err == io.EOF {
   972  				err = io.ErrUnexpectedEOF
   973  			}
   974  			return image.Config{}, err
   975  		}
   976  		paletted := cbPaletted(d.cb)
   977  		if d.stage == dsSeenIHDR && !paletted {
   978  			break
   979  		}
   980  		if d.stage == dsSeenPLTE && paletted {
   981  			break
   982  		}
   983  	}
   984  	var cm color.Model
   985  	switch d.cb {
   986  	case cbG1, cbG2, cbG4, cbG8:
   987  		cm = color.GrayModel
   988  	case cbGA8:
   989  		cm = color.NRGBAModel
   990  	case cbTC8:
   991  		cm = color.RGBAModel
   992  	case cbP1, cbP2, cbP4, cbP8:
   993  		cm = d.palette
   994  	case cbTCA8:
   995  		cm = color.NRGBAModel
   996  	case cbG16:
   997  		cm = color.Gray16Model
   998  	case cbGA16:
   999  		cm = color.NRGBA64Model
  1000  	case cbTC16:
  1001  		cm = color.RGBA64Model
  1002  	case cbTCA16:
  1003  		cm = color.NRGBA64Model
  1004  	}
  1005  	return image.Config{
  1006  		ColorModel: cm,
  1007  		Width:      d.width,
  1008  		Height:     d.height,
  1009  	}, nil
  1010  }
  1011  
  1012  func init() {
  1013  	image.RegisterFormat("png", pngHeader, Decode, DecodeConfig)
  1014  }