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/.
8package png
9
10import (
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.
22const (
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.
31const (
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
50func cbPaletted(cb int) bool {
51	return cbP1 <= cb && cb <= cbP8
52}
53
54func cbTrueColor(cb int) bool {
55	return cb == cbTC8 || cb == cbTC16
56}
57
58// Filter type, as per the PNG spec.
59const (
60	ftNone    = 0
61	ftSub     = 1
62	ftUp      = 2
63	ftAverage = 3
64	ftPaeth   = 4
65	nFilter   = 5
66)
67
68// Interlace type.
69const (
70	itNone  = 0
71	itAdam7 = 1
72)
73
74// interlaceScan defines the placement and size of a pass for Adam7 interlacing.
75type 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
81var 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
97const (
98	dsStart = iota
99	dsSeenIHDR
100	dsSeenPLTE
101	dsSeentRNS
102	dsSeenIDAT
103	dsSeenIEND
104)
105
106const pngHeader = "\x89PNG\r\n\x1a\n"
107
108type 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.
128type FormatError string
129
130func (e FormatError) Error() string { return "png: invalid format: " + string(e) }
131
132var chunkOrderError = FormatError("chunk out of order")
133
134// An UnsupportedError reports that the input uses a valid but unimplemented PNG feature.
135type UnsupportedError string
136
137func (e UnsupportedError) Error() string { return "png: unsupported feature: " + string(e) }
138
139func (d *decoder) parseIHDR(length uint32) error {
140	if length != 13 {
141		return FormatError("bad IHDR length")
142	}
143	if _, err := io.ReadFull(d.r, d.tmp[:13]); err != nil {
144		return err
145	}
146	d.crc.Write(d.tmp[:13])
147	if d.tmp[10] != 0 {
148		return UnsupportedError("compression method")
149	}
150	if d.tmp[11] != 0 {
151		return UnsupportedError("filter method")
152	}
153	if d.tmp[12] != itNone && d.tmp[12] != itAdam7 {
154		return FormatError("invalid interlace method")
155	}
156	d.interlace = int(d.tmp[12])
157
158	w := int32(binary.BigEndian.Uint32(d.tmp[0:4]))
159	h := int32(binary.BigEndian.Uint32(d.tmp[4:8]))
160	if w <= 0 || h <= 0 {
161		return FormatError("non-positive dimension")
162	}
163	nPixels64 := int64(w) * int64(h)
164	nPixels := int(nPixels64)
165	if nPixels64 != int64(nPixels) {
166		return UnsupportedError("dimension overflow")
167	}
168	// There can be up to 8 bytes per pixel, for 16 bits per channel RGBA.
169	if nPixels != (nPixels*8)/8 {
170		return UnsupportedError("dimension overflow")
171	}
172
173	d.cb = cbInvalid
174	d.depth = int(d.tmp[8])
175	switch d.depth {
176	case 1:
177		switch d.tmp[9] {
178		case ctGrayscale:
179			d.cb = cbG1
180		case ctPaletted:
181			d.cb = cbP1
182		}
183	case 2:
184		switch d.tmp[9] {
185		case ctGrayscale:
186			d.cb = cbG2
187		case ctPaletted:
188			d.cb = cbP2
189		}
190	case 4:
191		switch d.tmp[9] {
192		case ctGrayscale:
193			d.cb = cbG4
194		case ctPaletted:
195			d.cb = cbP4
196		}
197	case 8:
198		switch d.tmp[9] {
199		case ctGrayscale:
200			d.cb = cbG8
201		case ctTrueColor:
202			d.cb = cbTC8
203		case ctPaletted:
204			d.cb = cbP8
205		case ctGrayscaleAlpha:
206			d.cb = cbGA8
207		case ctTrueColorAlpha:
208			d.cb = cbTCA8
209		}
210	case 16:
211		switch d.tmp[9] {
212		case ctGrayscale:
213			d.cb = cbG16
214		case ctTrueColor:
215			d.cb = cbTC16
216		case ctGrayscaleAlpha:
217			d.cb = cbGA16
218		case ctTrueColorAlpha:
219			d.cb = cbTCA16
220		}
221	}
222	if d.cb == cbInvalid {
223		return UnsupportedError(fmt.Sprintf("bit depth %d, color type %d", d.tmp[8], d.tmp[9]))
224	}
225	d.width, d.height = int(w), int(h)
226	return d.verifyChecksum()
227}
228
229func (d *decoder) parsePLTE(length uint32) error {
230	np := int(length / 3) // The number of palette entries.
231	if length%3 != 0 || np <= 0 || np > 256 || np > 1<<uint(d.depth) {
232		return FormatError("bad PLTE length")
233	}
234	n, err := io.ReadFull(d.r, d.tmp[:3*np])
235	if err != nil {
236		return err
237	}
238	d.crc.Write(d.tmp[:n])
239	switch d.cb {
240	case cbP1, cbP2, cbP4, cbP8:
241		d.palette = make(color.Palette, 256)
242		for i := 0; i < np; i++ {
243			d.palette[i] = color.RGBA{d.tmp[3*i+0], d.tmp[3*i+1], d.tmp[3*i+2], 0xff}
244		}
245		for i := np; i < 256; i++ {
246			// Initialize the rest of the palette to opaque black. The spec (section
247			// 11.2.3) says that "any out-of-range pixel value found in the image data
248			// is an error", but some real-world PNG files have out-of-range pixel
249			// values. We fall back to opaque black, the same as libpng 1.5.13;
250			// ImageMagick 6.5.7 returns an error.
251			d.palette[i] = color.RGBA{0x00, 0x00, 0x00, 0xff}
252		}
253		d.palette = d.palette[:np]
254	case cbTC8, cbTCA8, cbTC16, cbTCA16:
255		// As per the PNG spec, a PLTE chunk is optional (and for practical purposes,
256		// ignorable) for the ctTrueColor and ctTrueColorAlpha color types (section 4.1.2).
257	default:
258		return FormatError("PLTE, color type mismatch")
259	}
260	return d.verifyChecksum()
261}
262
263func (d *decoder) parsetRNS(length uint32) error {
264	switch d.cb {
265	case cbG1, cbG2, cbG4, cbG8, cbG16:
266		if length != 2 {
267			return FormatError("bad tRNS length")
268		}
269		n, err := io.ReadFull(d.r, d.tmp[:length])
270		if err != nil {
271			return err
272		}
273		d.crc.Write(d.tmp[:n])
274
275		copy(d.transparent[:], d.tmp[:length])
276		switch d.cb {
277		case cbG1:
278			d.transparent[1] *= 0xff
279		case cbG2:
280			d.transparent[1] *= 0x55
281		case cbG4:
282			d.transparent[1] *= 0x11
283		}
284		d.useTransparent = true
285
286	case cbTC8, cbTC16:
287		if length != 6 {
288			return FormatError("bad tRNS length")
289		}
290		n, err := io.ReadFull(d.r, d.tmp[:length])
291		if err != nil {
292			return err
293		}
294		d.crc.Write(d.tmp[:n])
295
296		copy(d.transparent[:], d.tmp[:length])
297		d.useTransparent = true
298
299	case cbP1, cbP2, cbP4, cbP8:
300		if length > 256 {
301			return FormatError("bad tRNS length")
302		}
303		n, err := io.ReadFull(d.r, d.tmp[:length])
304		if err != nil {
305			return err
306		}
307		d.crc.Write(d.tmp[:n])
308
309		if len(d.palette) < n {
310			d.palette = d.palette[:n]
311		}
312		for i := 0; i < n; i++ {
313			rgba := d.palette[i].(color.RGBA)
314			d.palette[i] = color.NRGBA{rgba.R, rgba.G, rgba.B, d.tmp[i]}
315		}
316
317	default:
318		return FormatError("tRNS, color type mismatch")
319	}
320	return d.verifyChecksum()
321}
322
323// Read presents one or more IDAT chunks as one continuous stream (minus the
324// intermediate chunk headers and footers). If the PNG data looked like:
325//
326//	... len0 IDAT xxx crc0 len1 IDAT yy crc1 len2 IEND crc2
327//
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.
332func (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.
363func (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.
411func (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 + (int64(bitsPerPixel)*int64(width)+7)/8
502	if rowSize != int64(int(rowSize)) {
503		return nil, UnsupportedError("dimension overflow")
504	}
505	// cr and pr are the bytes for the current and previous row.
506	cr := make([]uint8, rowSize)
507	pr := make([]uint8, rowSize)
508
509	for y := 0; y < height; y++ {
510		// Read the decompressed bytes.
511		_, err := io.ReadFull(r, cr)
512		if err != nil {
513			if err == io.EOF || err == io.ErrUnexpectedEOF {
514				return nil, FormatError("not enough pixel data")
515			}
516			return nil, err
517		}
518
519		// Apply the filter.
520		cdat := cr[1:]
521		pdat := pr[1:]
522		switch cr[0] {
523		case ftNone:
524			// No-op.
525		case ftSub:
526			for i := bytesPerPixel; i < len(cdat); i++ {
527				cdat[i] += cdat[i-bytesPerPixel]
528			}
529		case ftUp:
530			for i, p := range pdat {
531				cdat[i] += p
532			}
533		case ftAverage:
534			// The first column has no column to the left of it, so it is a
535			// special case. We know that the first column exists because we
536			// check above that width != 0, and so len(cdat) != 0.
537			for i := 0; i < bytesPerPixel; i++ {
538				cdat[i] += pdat[i] / 2
539			}
540			for i := bytesPerPixel; i < len(cdat); i++ {
541				cdat[i] += uint8((int(cdat[i-bytesPerPixel]) + int(pdat[i])) / 2)
542			}
543		case ftPaeth:
544			filterPaeth(cdat, pdat, bytesPerPixel)
545		default:
546			return nil, FormatError("bad filter type")
547		}
548
549		// Convert from bytes to colors.
550		switch d.cb {
551		case cbG1:
552			if d.useTransparent {
553				ty := d.transparent[1]
554				for x := 0; x < width; x += 8 {
555					b := cdat[x/8]
556					for x2 := 0; x2 < 8 && x+x2 < width; x2++ {
557						ycol := (b >> 7) * 0xff
558						acol := uint8(0xff)
559						if ycol == ty {
560							acol = 0x00
561						}
562						nrgba.SetNRGBA(x+x2, y, color.NRGBA{ycol, ycol, ycol, acol})
563						b <<= 1
564					}
565				}
566			} else {
567				for x := 0; x < width; x += 8 {
568					b := cdat[x/8]
569					for x2 := 0; x2 < 8 && x+x2 < width; x2++ {
570						gray.SetGray(x+x2, y, color.Gray{(b >> 7) * 0xff})
571						b <<= 1
572					}
573				}
574			}
575		case cbG2:
576			if d.useTransparent {
577				ty := d.transparent[1]
578				for x := 0; x < width; x += 4 {
579					b := cdat[x/4]
580					for x2 := 0; x2 < 4 && x+x2 < width; x2++ {
581						ycol := (b >> 6) * 0x55
582						acol := uint8(0xff)
583						if ycol == ty {
584							acol = 0x00
585						}
586						nrgba.SetNRGBA(x+x2, y, color.NRGBA{ycol, ycol, ycol, acol})
587						b <<= 2
588					}
589				}
590			} else {
591				for x := 0; x < width; x += 4 {
592					b := cdat[x/4]
593					for x2 := 0; x2 < 4 && x+x2 < width; x2++ {
594						gray.SetGray(x+x2, y, color.Gray{(b >> 6) * 0x55})
595						b <<= 2
596					}
597				}
598			}
599		case cbG4:
600			if d.useTransparent {
601				ty := d.transparent[1]
602				for x := 0; x < width; x += 2 {
603					b := cdat[x/2]
604					for x2 := 0; x2 < 2 && x+x2 < width; x2++ {
605						ycol := (b >> 4) * 0x11
606						acol := uint8(0xff)
607						if ycol == ty {
608							acol = 0x00
609						}
610						nrgba.SetNRGBA(x+x2, y, color.NRGBA{ycol, ycol, ycol, acol})
611						b <<= 4
612					}
613				}
614			} else {
615				for x := 0; x < width; x += 2 {
616					b := cdat[x/2]
617					for x2 := 0; x2 < 2 && x+x2 < width; x2++ {
618						gray.SetGray(x+x2, y, color.Gray{(b >> 4) * 0x11})
619						b <<= 4
620					}
621				}
622			}
623		case cbG8:
624			if d.useTransparent {
625				ty := d.transparent[1]
626				for x := 0; x < width; x++ {
627					ycol := cdat[x]
628					acol := uint8(0xff)
629					if ycol == ty {
630						acol = 0x00
631					}
632					nrgba.SetNRGBA(x, y, color.NRGBA{ycol, ycol, ycol, acol})
633				}
634			} else {
635				copy(gray.Pix[pixOffset:], cdat)
636				pixOffset += gray.Stride
637			}
638		case cbGA8:
639			for x := 0; x < width; x++ {
640				ycol := cdat[2*x+0]
641				nrgba.SetNRGBA(x, y, color.NRGBA{ycol, ycol, ycol, cdat[2*x+1]})
642			}
643		case cbTC8:
644			if d.useTransparent {
645				pix, i, j := nrgba.Pix, pixOffset, 0
646				tr, tg, tb := d.transparent[1], d.transparent[3], d.transparent[5]
647				for x := 0; x < width; x++ {
648					r := cdat[j+0]
649					g := cdat[j+1]
650					b := cdat[j+2]
651					a := uint8(0xff)
652					if r == tr && g == tg && b == tb {
653						a = 0x00
654					}
655					pix[i+0] = r
656					pix[i+1] = g
657					pix[i+2] = b
658					pix[i+3] = a
659					i += 4
660					j += 3
661				}
662				pixOffset += nrgba.Stride
663			} else {
664				pix, i, j := rgba.Pix, pixOffset, 0
665				for x := 0; x < width; x++ {
666					pix[i+0] = cdat[j+0]
667					pix[i+1] = cdat[j+1]
668					pix[i+2] = cdat[j+2]
669					pix[i+3] = 0xff
670					i += 4
671					j += 3
672				}
673				pixOffset += rgba.Stride
674			}
675		case cbP1:
676			for x := 0; x < width; x += 8 {
677				b := cdat[x/8]
678				for x2 := 0; x2 < 8 && x+x2 < width; x2++ {
679					idx := b >> 7
680					if len(paletted.Palette) <= int(idx) {
681						paletted.Palette = paletted.Palette[:int(idx)+1]
682					}
683					paletted.SetColorIndex(x+x2, y, idx)
684					b <<= 1
685				}
686			}
687		case cbP2:
688			for x := 0; x < width; x += 4 {
689				b := cdat[x/4]
690				for x2 := 0; x2 < 4 && x+x2 < width; x2++ {
691					idx := b >> 6
692					if len(paletted.Palette) <= int(idx) {
693						paletted.Palette = paletted.Palette[:int(idx)+1]
694					}
695					paletted.SetColorIndex(x+x2, y, idx)
696					b <<= 2
697				}
698			}
699		case cbP4:
700			for x := 0; x < width; x += 2 {
701				b := cdat[x/2]
702				for x2 := 0; x2 < 2 && x+x2 < width; x2++ {
703					idx := b >> 4
704					if len(paletted.Palette) <= int(idx) {
705						paletted.Palette = paletted.Palette[:int(idx)+1]
706					}
707					paletted.SetColorIndex(x+x2, y, idx)
708					b <<= 4
709				}
710			}
711		case cbP8:
712			if len(paletted.Palette) != 256 {
713				for x := 0; x < width; x++ {
714					if len(paletted.Palette) <= int(cdat[x]) {
715						paletted.Palette = paletted.Palette[:int(cdat[x])+1]
716					}
717				}
718			}
719			copy(paletted.Pix[pixOffset:], cdat)
720			pixOffset += paletted.Stride
721		case cbTCA8:
722			copy(nrgba.Pix[pixOffset:], cdat)
723			pixOffset += nrgba.Stride
724		case cbG16:
725			if d.useTransparent {
726				ty := uint16(d.transparent[0])<<8 | uint16(d.transparent[1])
727				for x := 0; x < width; x++ {
728					ycol := uint16(cdat[2*x+0])<<8 | uint16(cdat[2*x+1])
729					acol := uint16(0xffff)
730					if ycol == ty {
731						acol = 0x0000
732					}
733					nrgba64.SetNRGBA64(x, y, color.NRGBA64{ycol, ycol, ycol, acol})
734				}
735			} else {
736				for x := 0; x < width; x++ {
737					ycol := uint16(cdat[2*x+0])<<8 | uint16(cdat[2*x+1])
738					gray16.SetGray16(x, y, color.Gray16{ycol})
739				}
740			}
741		case cbGA16:
742			for x := 0; x < width; x++ {
743				ycol := uint16(cdat[4*x+0])<<8 | uint16(cdat[4*x+1])
744				acol := uint16(cdat[4*x+2])<<8 | uint16(cdat[4*x+3])
745				nrgba64.SetNRGBA64(x, y, color.NRGBA64{ycol, ycol, ycol, acol})
746			}
747		case cbTC16:
748			if d.useTransparent {
749				tr := uint16(d.transparent[0])<<8 | uint16(d.transparent[1])
750				tg := uint16(d.transparent[2])<<8 | uint16(d.transparent[3])
751				tb := uint16(d.transparent[4])<<8 | uint16(d.transparent[5])
752				for x := 0; x < width; x++ {
753					rcol := uint16(cdat[6*x+0])<<8 | uint16(cdat[6*x+1])
754					gcol := uint16(cdat[6*x+2])<<8 | uint16(cdat[6*x+3])
755					bcol := uint16(cdat[6*x+4])<<8 | uint16(cdat[6*x+5])
756					acol := uint16(0xffff)
757					if rcol == tr && gcol == tg && bcol == tb {
758						acol = 0x0000
759					}
760					nrgba64.SetNRGBA64(x, y, color.NRGBA64{rcol, gcol, bcol, acol})
761				}
762			} else {
763				for x := 0; x < width; x++ {
764					rcol := uint16(cdat[6*x+0])<<8 | uint16(cdat[6*x+1])
765					gcol := uint16(cdat[6*x+2])<<8 | uint16(cdat[6*x+3])
766					bcol := uint16(cdat[6*x+4])<<8 | uint16(cdat[6*x+5])
767					rgba64.SetRGBA64(x, y, color.RGBA64{rcol, gcol, bcol, 0xffff})
768				}
769			}
770		case cbTCA16:
771			for x := 0; x < width; x++ {
772				rcol := uint16(cdat[8*x+0])<<8 | uint16(cdat[8*x+1])
773				gcol := uint16(cdat[8*x+2])<<8 | uint16(cdat[8*x+3])
774				bcol := uint16(cdat[8*x+4])<<8 | uint16(cdat[8*x+5])
775				acol := uint16(cdat[8*x+6])<<8 | uint16(cdat[8*x+7])
776				nrgba64.SetNRGBA64(x, y, color.NRGBA64{rcol, gcol, bcol, acol})
777			}
778		}
779
780		// The current row for y is the previous row for y+1.
781		pr, cr = cr, pr
782	}
783
784	return img, nil
785}
786
787// mergePassInto merges a single pass into a full sized image.
788func (d *decoder) mergePassInto(dst image.Image, src image.Image, pass int) {
789	p := interlacing[pass]
790	var (
791		srcPix        []uint8
792		dstPix        []uint8
793		stride        int
794		rect          image.Rectangle
795		bytesPerPixel int
796	)
797	switch target := dst.(type) {
798	case *image.Alpha:
799		srcPix = src.(*image.Alpha).Pix
800		dstPix, stride, rect = target.Pix, target.Stride, target.Rect
801		bytesPerPixel = 1
802	case *image.Alpha16:
803		srcPix = src.(*image.Alpha16).Pix
804		dstPix, stride, rect = target.Pix, target.Stride, target.Rect
805		bytesPerPixel = 2
806	case *image.Gray:
807		srcPix = src.(*image.Gray).Pix
808		dstPix, stride, rect = target.Pix, target.Stride, target.Rect
809		bytesPerPixel = 1
810	case *image.Gray16:
811		srcPix = src.(*image.Gray16).Pix
812		dstPix, stride, rect = target.Pix, target.Stride, target.Rect
813		bytesPerPixel = 2
814	case *image.NRGBA:
815		srcPix = src.(*image.NRGBA).Pix
816		dstPix, stride, rect = target.Pix, target.Stride, target.Rect
817		bytesPerPixel = 4
818	case *image.NRGBA64:
819		srcPix = src.(*image.NRGBA64).Pix
820		dstPix, stride, rect = target.Pix, target.Stride, target.Rect
821		bytesPerPixel = 8
822	case *image.Paletted:
823		source := src.(*image.Paletted)
824		srcPix = source.Pix
825		dstPix, stride, rect = target.Pix, target.Stride, target.Rect
826		bytesPerPixel = 1
827		if len(target.Palette) < len(source.Palette) {
828			// readImagePass can return a paletted image whose implicit palette
829			// length (one more than the maximum Pix value) is larger than the
830			// explicit palette length (what's in the PLTE chunk). Make the
831			// same adjustment here.
832			target.Palette = source.Palette
833		}
834	case *image.RGBA:
835		srcPix = src.(*image.RGBA).Pix
836		dstPix, stride, rect = target.Pix, target.Stride, target.Rect
837		bytesPerPixel = 4
838	case *image.RGBA64:
839		srcPix = src.(*image.RGBA64).Pix
840		dstPix, stride, rect = target.Pix, target.Stride, target.Rect
841		bytesPerPixel = 8
842	}
843	s, bounds := 0, src.Bounds()
844	for y := bounds.Min.Y; y < bounds.Max.Y; y++ {
845		dBase := (y*p.yFactor+p.yOffset-rect.Min.Y)*stride + (p.xOffset-rect.Min.X)*bytesPerPixel
846		for x := bounds.Min.X; x < bounds.Max.X; x++ {
847			d := dBase + x*p.xFactor*bytesPerPixel
848			copy(dstPix[d:], srcPix[s:s+bytesPerPixel])
849			s += bytesPerPixel
850		}
851	}
852}
853
854func (d *decoder) parseIDAT(length uint32) (err error) {
855	d.idatLength = length
856	d.img, err = d.decode()
857	if err != nil {
858		return err
859	}
860	return d.verifyChecksum()
861}
862
863func (d *decoder) parseIEND(length uint32) error {
864	if length != 0 {
865		return FormatError("bad IEND length")
866	}
867	return d.verifyChecksum()
868}
869
870func (d *decoder) parseChunk(configOnly bool) error {
871	// Read the length and chunk type.
872	if _, err := io.ReadFull(d.r, d.tmp[:8]); err != nil {
873		return err
874	}
875	length := binary.BigEndian.Uint32(d.tmp[:4])
876	d.crc.Reset()
877	d.crc.Write(d.tmp[4:8])
878
879	// Read the chunk data.
880	switch string(d.tmp[4:8]) {
881	case "IHDR":
882		if d.stage != dsStart {
883			return chunkOrderError
884		}
885		d.stage = dsSeenIHDR
886		return d.parseIHDR(length)
887	case "PLTE":
888		if d.stage != dsSeenIHDR {
889			return chunkOrderError
890		}
891		d.stage = dsSeenPLTE
892		return d.parsePLTE(length)
893	case "tRNS":
894		if cbPaletted(d.cb) {
895			if d.stage != dsSeenPLTE {
896				return chunkOrderError
897			}
898		} else if cbTrueColor(d.cb) {
899			if d.stage != dsSeenIHDR && d.stage != dsSeenPLTE {
900				return chunkOrderError
901			}
902		} else if d.stage != dsSeenIHDR {
903			return chunkOrderError
904		}
905		d.stage = dsSeentRNS
906		return d.parsetRNS(length)
907	case "IDAT":
908		if d.stage < dsSeenIHDR || d.stage > dsSeenIDAT || (d.stage == dsSeenIHDR && cbPaletted(d.cb)) {
909			return chunkOrderError
910		} else if d.stage == dsSeenIDAT {
911			// Ignore trailing zero-length or garbage IDAT chunks.
912			//
913			// This does not affect valid PNG images that contain multiple IDAT
914			// chunks, since the first call to parseIDAT below will consume all
915			// consecutive IDAT chunks required for decoding the image.
916			break
917		}
918		d.stage = dsSeenIDAT
919		if configOnly {
920			return nil
921		}
922		return d.parseIDAT(length)
923	case "IEND":
924		if d.stage != dsSeenIDAT {
925			return chunkOrderError
926		}
927		d.stage = dsSeenIEND
928		return d.parseIEND(length)
929	}
930	if length > 0x7fffffff {
931		return FormatError(fmt.Sprintf("Bad chunk length: %d", length))
932	}
933	// Ignore this chunk (of a known length).
934	var ignored [4096]byte
935	for length > 0 {
936		n, err := io.ReadFull(d.r, ignored[:min(len(ignored), int(length))])
937		if err != nil {
938			return err
939		}
940		d.crc.Write(ignored[:n])
941		length -= uint32(n)
942	}
943	return d.verifyChecksum()
944}
945
946func (d *decoder) verifyChecksum() error {
947	if _, err := io.ReadFull(d.r, d.tmp[:4]); err != nil {
948		return err
949	}
950	if binary.BigEndian.Uint32(d.tmp[:4]) != d.crc.Sum32() {
951		return FormatError("invalid checksum")
952	}
953	return nil
954}
955
956func (d *decoder) checkHeader() error {
957	_, err := io.ReadFull(d.r, d.tmp[:len(pngHeader)])
958	if err != nil {
959		return err
960	}
961	if string(d.tmp[:len(pngHeader)]) != pngHeader {
962		return FormatError("not a PNG file")
963	}
964	return nil
965}
966
967// Decode reads a PNG image from r and returns it as an [image.Image].
968// The type of Image returned depends on the PNG contents.
969func Decode(r io.Reader) (image.Image, error) {
970	d := &decoder{
971		r:   r,
972		crc: crc32.NewIEEE(),
973	}
974	if err := d.checkHeader(); err != nil {
975		if err == io.EOF {
976			err = io.ErrUnexpectedEOF
977		}
978		return nil, err
979	}
980	for d.stage != dsSeenIEND {
981		if err := d.parseChunk(false); err != nil {
982			if err == io.EOF {
983				err = io.ErrUnexpectedEOF
984			}
985			return nil, err
986		}
987	}
988	return d.img, nil
989}
990
991// DecodeConfig returns the color model and dimensions of a PNG image without
992// decoding the entire image.
993func DecodeConfig(r io.Reader) (image.Config, error) {
994	d := &decoder{
995		r:   r,
996		crc: crc32.NewIEEE(),
997	}
998	if err := d.checkHeader(); err != nil {
999		if err == io.EOF {
1000			err = io.ErrUnexpectedEOF
1001		}
1002		return image.Config{}, err
1003	}
1004
1005	for {
1006		if err := d.parseChunk(true); err != nil {
1007			if err == io.EOF {
1008				err = io.ErrUnexpectedEOF
1009			}
1010			return image.Config{}, err
1011		}
1012
1013		if cbPaletted(d.cb) {
1014			if d.stage >= dsSeentRNS {
1015				break
1016			}
1017		} else {
1018			if d.stage >= dsSeenIHDR {
1019				break
1020			}
1021		}
1022	}
1023
1024	var cm color.Model
1025	switch d.cb {
1026	case cbG1, cbG2, cbG4, cbG8:
1027		cm = color.GrayModel
1028	case cbGA8:
1029		cm = color.NRGBAModel
1030	case cbTC8:
1031		cm = color.RGBAModel
1032	case cbP1, cbP2, cbP4, cbP8:
1033		cm = d.palette
1034	case cbTCA8:
1035		cm = color.NRGBAModel
1036	case cbG16:
1037		cm = color.Gray16Model
1038	case cbGA16:
1039		cm = color.NRGBA64Model
1040	case cbTC16:
1041		cm = color.RGBA64Model
1042	case cbTCA16:
1043		cm = color.NRGBA64Model
1044	}
1045	return image.Config{
1046		ColorModel: cm,
1047		Width:      d.width,
1048		Height:     d.height,
1049	}, nil
1050}
1051
1052func init() {
1053	image.RegisterFormat("png", pngHeader, Decode, DecodeConfig)
1054}
1055