...
Run Format

Source file src/image/png/reader.go

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

View as plain text