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