...
Run Format

Source file src/image/png/reader.go

Documentation: image/png

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

View as plain text