Source file src/pkg/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 // Filter type, as per the PNG spec.
51 const (
52 ftNone = 0
53 ftSub = 1
54 ftUp = 2
55 ftAverage = 3
56 ftPaeth = 4
57 nFilter = 5
58 )
59
60 // Decoding stage.
61 // The PNG specification says that the IHDR, PLTE (if present), IDAT and IEND
62 // chunks must appear in that order. There may be multiple IDAT chunks, and
63 // IDAT chunks must be sequential (i.e. they may not have any other chunks
64 // between them).
65 // http://www.w3.org/TR/PNG/#5ChunkOrdering
66 const (
67 dsStart = iota
68 dsSeenIHDR
69 dsSeenPLTE
70 dsSeenIDAT
71 dsSeenIEND
72 )
73
74 const pngHeader = "\x89PNG\r\n\x1a\n"
75
76 type decoder struct {
77 r io.Reader
78 img image.Image
79 crc hash.Hash32
80 width, height int
81 depth int
82 palette color.Palette
83 cb int
84 stage int
85 idatLength uint32
86 tmp [3 * 256]byte
87 }
88
89 // A FormatError reports that the input is not a valid PNG.
90 type FormatError string
91
92 func (e FormatError) Error() string { return "png: invalid format: " + string(e) }
93
94 var chunkOrderError = FormatError("chunk out of order")
95
96 // An UnsupportedError reports that the input uses a valid but unimplemented PNG feature.
97 type UnsupportedError string
98
99 func (e UnsupportedError) Error() string { return "png: unsupported feature: " + string(e) }
100
101 func abs(x int) int {
102 if x < 0 {
103 return -x
104 }
105 return x
106 }
107
108 func min(a, b int) int {
109 if a < b {
110 return a
111 }
112 return b
113 }
114
115 func (d *decoder) parseIHDR(length uint32) error {
116 if length != 13 {
117 return FormatError("bad IHDR length")
118 }
119 if _, err := io.ReadFull(d.r, d.tmp[:13]); err != nil {
120 return err
121 }
122 d.crc.Write(d.tmp[:13])
123 if d.tmp[10] != 0 || d.tmp[11] != 0 || d.tmp[12] != 0 {
124 return UnsupportedError("compression, filter or interlace method")
125 }
126 w := int32(binary.BigEndian.Uint32(d.tmp[0:4]))
127 h := int32(binary.BigEndian.Uint32(d.tmp[4:8]))
128 if w < 0 || h < 0 {
129 return FormatError("negative dimension")
130 }
131 nPixels := int64(w) * int64(h)
132 if nPixels != int64(int(nPixels)) {
133 return UnsupportedError("dimension overflow")
134 }
135 d.cb = cbInvalid
136 d.depth = int(d.tmp[8])
137 switch d.depth {
138 case 1:
139 switch d.tmp[9] {
140 case ctGrayscale:
141 d.cb = cbG1
142 case ctPaletted:
143 d.cb = cbP1
144 }
145 case 2:
146 switch d.tmp[9] {
147 case ctGrayscale:
148 d.cb = cbG2
149 case ctPaletted:
150 d.cb = cbP2
151 }
152 case 4:
153 switch d.tmp[9] {
154 case ctGrayscale:
155 d.cb = cbG4
156 case ctPaletted:
157 d.cb = cbP4
158 }
159 case 8:
160 switch d.tmp[9] {
161 case ctGrayscale:
162 d.cb = cbG8
163 case ctTrueColor:
164 d.cb = cbTC8
165 case ctPaletted:
166 d.cb = cbP8
167 case ctGrayscaleAlpha:
168 d.cb = cbGA8
169 case ctTrueColorAlpha:
170 d.cb = cbTCA8
171 }
172 case 16:
173 switch d.tmp[9] {
174 case ctGrayscale:
175 d.cb = cbG16
176 case ctTrueColor:
177 d.cb = cbTC16
178 case ctGrayscaleAlpha:
179 d.cb = cbGA16
180 case ctTrueColorAlpha:
181 d.cb = cbTCA16
182 }
183 }
184 if d.cb == cbInvalid {
185 return UnsupportedError(fmt.Sprintf("bit depth %d, color type %d", d.tmp[8], d.tmp[9]))
186 }
187 d.width, d.height = int(w), int(h)
188 return d.verifyChecksum()
189 }
190
191 func (d *decoder) parsePLTE(length uint32) error {
192 np := int(length / 3) // The number of palette entries.
193 if length%3 != 0 || np <= 0 || np > 256 || np > 1<<uint(d.depth) {
194 return FormatError("bad PLTE length")
195 }
196 n, err := io.ReadFull(d.r, d.tmp[:3*np])
197 if err != nil {
198 return err
199 }
200 d.crc.Write(d.tmp[:n])
201 switch d.cb {
202 case cbP1, cbP2, cbP4, cbP8:
203 d.palette = color.Palette(make([]color.Color, np))
204 for i := 0; i < np; i++ {
205 d.palette[i] = color.RGBA{d.tmp[3*i+0], d.tmp[3*i+1], d.tmp[3*i+2], 0xff}
206 }
207 case cbTC8, cbTCA8, cbTC16, cbTCA16:
208 // As per the PNG spec, a PLTE chunk is optional (and for practical purposes,
209 // ignorable) for the ctTrueColor and ctTrueColorAlpha color types (section 4.1.2).
210 default:
211 return FormatError("PLTE, color type mismatch")
212 }
213 return d.verifyChecksum()
214 }
215
216 func (d *decoder) parsetRNS(length uint32) error {
217 if length > 256 {
218 return FormatError("bad tRNS length")
219 }
220 n, err := io.ReadFull(d.r, d.tmp[:length])
221 if err != nil {
222 return err
223 }
224 d.crc.Write(d.tmp[:n])
225 switch d.cb {
226 case cbG8, cbG16:
227 return UnsupportedError("grayscale transparency")
228 case cbTC8, cbTC16:
229 return UnsupportedError("truecolor transparency")
230 case cbP1, cbP2, cbP4, cbP8:
231 if n > len(d.palette) {
232 return FormatError("bad tRNS length")
233 }
234 for i := 0; i < n; i++ {
235 rgba := d.palette[i].(color.RGBA)
236 d.palette[i] = color.RGBA{rgba.R, rgba.G, rgba.B, d.tmp[i]}
237 }
238 case cbGA8, cbGA16, cbTCA8, cbTCA16:
239 return FormatError("tRNS, color type mismatch")
240 }
241 return d.verifyChecksum()
242 }
243
244 // The Paeth filter function, as per the PNG specification.
245 func paeth(a, b, c uint8) uint8 {
246 p := int(a) + int(b) - int(c)
247 pa := abs(p - int(a))
248 pb := abs(p - int(b))
249 pc := abs(p - int(c))
250 if pa <= pb && pa <= pc {
251 return a
252 } else if pb <= pc {
253 return b
254 }
255 return c
256 }
257
258 // Read presents one or more IDAT chunks as one continuous stream (minus the
259 // intermediate chunk headers and footers). If the PNG data looked like:
260 // ... len0 IDAT xxx crc0 len1 IDAT yy crc1 len2 IEND crc2
261 // then this reader presents xxxyy. For well-formed PNG data, the decoder state
262 // immediately before the first Read call is that d.r is positioned between the
263 // first IDAT and xxx, and the decoder state immediately after the last Read
264 // call is that d.r is positioned between yy and crc1.
265 func (d *decoder) Read(p []byte) (int, error) {
266 if len(p) == 0 {
267 return 0, nil
268 }
269 for d.idatLength == 0 {
270 // We have exhausted an IDAT chunk. Verify the checksum of that chunk.
271 if err := d.verifyChecksum(); err != nil {
272 return 0, err
273 }
274 // Read the length and chunk type of the next chunk, and check that
275 // it is an IDAT chunk.
276 if _, err := io.ReadFull(d.r, d.tmp[:8]); err != nil {
277 return 0, err
278 }
279 d.idatLength = binary.BigEndian.Uint32(d.tmp[:4])
280 if string(d.tmp[4:8]) != "IDAT" {
281 return 0, FormatError("not enough pixel data")
282 }
283 d.crc.Reset()
284 d.crc.Write(d.tmp[4:8])
285 }
286 if int(d.idatLength) < 0 {
287 return 0, UnsupportedError("IDAT chunk length overflow")
288 }
289 n, err := d.r.Read(p[:min(len(p), int(d.idatLength))])
290 d.crc.Write(p[:n])
291 d.idatLength -= uint32(n)
292 return n, err
293 }
294
295 // decode decodes the IDAT data into an image.
296 func (d *decoder) decode() (image.Image, error) {
297 r, err := zlib.NewReader(d)
298 if err != nil {
299 return nil, err
300 }
301 defer r.Close()
302 bitsPerPixel := 0
303 maxPalette := uint8(0)
304 var (
305 gray *image.Gray
306 rgba *image.RGBA
307 paletted *image.Paletted
308 nrgba *image.NRGBA
309 gray16 *image.Gray16
310 rgba64 *image.RGBA64
311 nrgba64 *image.NRGBA64
312 img image.Image
313 )
314 switch d.cb {
315 case cbG1, cbG2, cbG4, cbG8:
316 bitsPerPixel = d.depth
317 gray = image.NewGray(image.Rect(0, 0, d.width, d.height))
318 img = gray
319 case cbGA8:
320 bitsPerPixel = 16
321 nrgba = image.NewNRGBA(image.Rect(0, 0, d.width, d.height))
322 img = nrgba
323 case cbTC8:
324 bitsPerPixel = 24
325 rgba = image.NewRGBA(image.Rect(0, 0, d.width, d.height))
326 img = rgba
327 case cbP1, cbP2, cbP4, cbP8:
328 bitsPerPixel = d.depth
329 paletted = image.NewPaletted(image.Rect(0, 0, d.width, d.height), d.palette)
330 img = paletted
331 maxPalette = uint8(len(d.palette) - 1)
332 case cbTCA8:
333 bitsPerPixel = 32
334 nrgba = image.NewNRGBA(image.Rect(0, 0, d.width, d.height))
335 img = nrgba
336 case cbG16:
337 bitsPerPixel = 16
338 gray16 = image.NewGray16(image.Rect(0, 0, d.width, d.height))
339 img = gray16
340 case cbGA16:
341 bitsPerPixel = 32
342 nrgba64 = image.NewNRGBA64(image.Rect(0, 0, d.width, d.height))
343 img = nrgba64
344 case cbTC16:
345 bitsPerPixel = 48
346 rgba64 = image.NewRGBA64(image.Rect(0, 0, d.width, d.height))
347 img = rgba64
348 case cbTCA16:
349 bitsPerPixel = 64
350 nrgba64 = image.NewNRGBA64(image.Rect(0, 0, d.width, d.height))
351 img = nrgba64
352 }
353 bytesPerPixel := (bitsPerPixel + 7) / 8
354
355 // cr and pr are the bytes for the current and previous row.
356 // The +1 is for the per-row filter type, which is at cr[0].
357 cr := make([]uint8, 1+(bitsPerPixel*d.width+7)/8)
358 pr := make([]uint8, 1+(bitsPerPixel*d.width+7)/8)
359
360 for y := 0; y < d.height; y++ {
361 // Read the decompressed bytes.
362 _, err := io.ReadFull(r, cr)
363 if err != nil {
364 return nil, err
365 }
366
367 // Apply the filter.
368 cdat := cr[1:]
369 pdat := pr[1:]
370 switch cr[0] {
371 case ftNone:
372 // No-op.
373 case ftSub:
374 for i := bytesPerPixel; i < len(cdat); i++ {
375 cdat[i] += cdat[i-bytesPerPixel]
376 }
377 case ftUp:
378 for i := 0; i < len(cdat); i++ {
379 cdat[i] += pdat[i]
380 }
381 case ftAverage:
382 for i := 0; i < bytesPerPixel; i++ {
383 cdat[i] += pdat[i] / 2
384 }
385 for i := bytesPerPixel; i < len(cdat); i++ {
386 cdat[i] += uint8((int(cdat[i-bytesPerPixel]) + int(pdat[i])) / 2)
387 }
388 case ftPaeth:
389 for i := 0; i < bytesPerPixel; i++ {
390 cdat[i] += paeth(0, pdat[i], 0)
391 }
392 for i := bytesPerPixel; i < len(cdat); i++ {
393 cdat[i] += paeth(cdat[i-bytesPerPixel], pdat[i], pdat[i-bytesPerPixel])
394 }
395 default:
396 return nil, FormatError("bad filter type")
397 }
398
399 // Convert from bytes to colors.
400 switch d.cb {
401 case cbG1:
402 for x := 0; x < d.width; x += 8 {
403 b := cdat[x/8]
404 for x2 := 0; x2 < 8 && x+x2 < d.width; x2++ {
405 gray.SetGray(x+x2, y, color.Gray{(b >> 7) * 0xff})
406 b <<= 1
407 }
408 }
409 case cbG2:
410 for x := 0; x < d.width; x += 4 {
411 b := cdat[x/4]
412 for x2 := 0; x2 < 4 && x+x2 < d.width; x2++ {
413 gray.SetGray(x+x2, y, color.Gray{(b >> 6) * 0x55})
414 b <<= 2
415 }
416 }
417 case cbG4:
418 for x := 0; x < d.width; x += 2 {
419 b := cdat[x/2]
420 for x2 := 0; x2 < 2 && x+x2 < d.width; x2++ {
421 gray.SetGray(x+x2, y, color.Gray{(b >> 4) * 0x11})
422 b <<= 4
423 }
424 }
425 case cbG8:
426 for x := 0; x < d.width; x++ {
427 gray.SetGray(x, y, color.Gray{cdat[x]})
428 }
429 case cbGA8:
430 for x := 0; x < d.width; x++ {
431 ycol := cdat[2*x+0]
432 nrgba.SetNRGBA(x, y, color.NRGBA{ycol, ycol, ycol, cdat[2*x+1]})
433 }
434 case cbTC8:
435 for x := 0; x < d.width; x++ {
436 rgba.SetRGBA(x, y, color.RGBA{cdat[3*x+0], cdat[3*x+1], cdat[3*x+2], 0xff})
437 }
438 case cbP1:
439 for x := 0; x < d.width; x += 8 {
440 b := cdat[x/8]
441 for x2 := 0; x2 < 8 && x+x2 < d.width; x2++ {
442 idx := b >> 7
443 if idx > maxPalette {
444 return nil, FormatError("palette index out of range")
445 }
446 paletted.SetColorIndex(x+x2, y, idx)
447 b <<= 1
448 }
449 }
450 case cbP2:
451 for x := 0; x < d.width; x += 4 {
452 b := cdat[x/4]
453 for x2 := 0; x2 < 4 && x+x2 < d.width; x2++ {
454 idx := b >> 6
455 if idx > maxPalette {
456 return nil, FormatError("palette index out of range")
457 }
458 paletted.SetColorIndex(x+x2, y, idx)
459 b <<= 2
460 }
461 }
462 case cbP4:
463 for x := 0; x < d.width; x += 2 {
464 b := cdat[x/2]
465 for x2 := 0; x2 < 2 && x+x2 < d.width; x2++ {
466 idx := b >> 4
467 if idx > maxPalette {
468 return nil, FormatError("palette index out of range")
469 }
470 paletted.SetColorIndex(x+x2, y, idx)
471 b <<= 4
472 }
473 }
474 case cbP8:
475 for x := 0; x < d.width; x++ {
476 if cdat[x] > maxPalette {
477 return nil, FormatError("palette index out of range")
478 }
479 paletted.SetColorIndex(x, y, cdat[x])
480 }
481 case cbTCA8:
482 for x := 0; x < d.width; x++ {
483 nrgba.SetNRGBA(x, y, color.NRGBA{cdat[4*x+0], cdat[4*x+1], cdat[4*x+2], cdat[4*x+3]})
484 }
485 case cbG16:
486 for x := 0; x < d.width; x++ {
487 ycol := uint16(cdat[2*x+0])<<8 | uint16(cdat[2*x+1])
488 gray16.SetGray16(x, y, color.Gray16{ycol})
489 }
490 case cbGA16:
491 for x := 0; x < d.width; x++ {
492 ycol := uint16(cdat[4*x+0])<<8 | uint16(cdat[4*x+1])
493 acol := uint16(cdat[4*x+2])<<8 | uint16(cdat[4*x+3])
494 nrgba64.SetNRGBA64(x, y, color.NRGBA64{ycol, ycol, ycol, acol})
495 }
496 case cbTC16:
497 for x := 0; x < d.width; x++ {
498 rcol := uint16(cdat[6*x+0])<<8 | uint16(cdat[6*x+1])
499 gcol := uint16(cdat[6*x+2])<<8 | uint16(cdat[6*x+3])
500 bcol := uint16(cdat[6*x+4])<<8 | uint16(cdat[6*x+5])
501 rgba64.SetRGBA64(x, y, color.RGBA64{rcol, gcol, bcol, 0xffff})
502 }
503 case cbTCA16:
504 for x := 0; x < d.width; x++ {
505 rcol := uint16(cdat[8*x+0])<<8 | uint16(cdat[8*x+1])
506 gcol := uint16(cdat[8*x+2])<<8 | uint16(cdat[8*x+3])
507 bcol := uint16(cdat[8*x+4])<<8 | uint16(cdat[8*x+5])
508 acol := uint16(cdat[8*x+6])<<8 | uint16(cdat[8*x+7])
509 nrgba64.SetNRGBA64(x, y, color.NRGBA64{rcol, gcol, bcol, acol})
510 }
511 }
512
513 // The current row for y is the previous row for y+1.
514 pr, cr = cr, pr
515 }
516
517 // Check for EOF, to verify the zlib checksum.
518 n, err := r.Read(pr[:1])
519 if err != io.EOF {
520 return nil, FormatError(err.Error())
521 }
522 if n != 0 || d.idatLength != 0 {
523 return nil, FormatError("too much pixel data")
524 }
525
526 return img, nil
527 }
528
529 func (d *decoder) parseIDAT(length uint32) (err error) {
530 d.idatLength = length
531 d.img, err = d.decode()
532 if err != nil {
533 return err
534 }
535 return d.verifyChecksum()
536 }
537
538 func (d *decoder) parseIEND(length uint32) error {
539 if length != 0 {
540 return FormatError("bad IEND length")
541 }
542 return d.verifyChecksum()
543 }
544
545 func (d *decoder) parseChunk() error {
546 // Read the length and chunk type.
547 n, err := io.ReadFull(d.r, d.tmp[:8])
548 if err != nil {
549 return err
550 }
551 length := binary.BigEndian.Uint32(d.tmp[:4])
552 d.crc.Reset()
553 d.crc.Write(d.tmp[4:8])
554
555 // Read the chunk data.
556 switch string(d.tmp[4:8]) {
557 case "IHDR":
558 if d.stage != dsStart {
559 return chunkOrderError
560 }
561 d.stage = dsSeenIHDR
562 return d.parseIHDR(length)
563 case "PLTE":
564 if d.stage != dsSeenIHDR {
565 return chunkOrderError
566 }
567 d.stage = dsSeenPLTE
568 return d.parsePLTE(length)
569 case "tRNS":
570 if d.stage != dsSeenPLTE {
571 return chunkOrderError
572 }
573 return d.parsetRNS(length)
574 case "IDAT":
575 if d.stage < dsSeenIHDR || d.stage > dsSeenIDAT || (d.cb == cbP8 && d.stage == dsSeenIHDR) {
576 return chunkOrderError
577 }
578 d.stage = dsSeenIDAT
579 return d.parseIDAT(length)
580 case "IEND":
581 if d.stage != dsSeenIDAT {
582 return chunkOrderError
583 }
584 d.stage = dsSeenIEND
585 return d.parseIEND(length)
586 }
587 // Ignore this chunk (of a known length).
588 var ignored [4096]byte
589 for length > 0 {
590 n, err = io.ReadFull(d.r, ignored[:min(len(ignored), int(length))])
591 if err != nil {
592 return err
593 }
594 d.crc.Write(ignored[:n])
595 length -= uint32(n)
596 }
597 return d.verifyChecksum()
598 }
599
600 func (d *decoder) verifyChecksum() error {
601 if _, err := io.ReadFull(d.r, d.tmp[:4]); err != nil {
602 return err
603 }
604 if binary.BigEndian.Uint32(d.tmp[:4]) != d.crc.Sum32() {
605 return FormatError("invalid checksum")
606 }
607 return nil
608 }
609
610 func (d *decoder) checkHeader() error {
611 _, err := io.ReadFull(d.r, d.tmp[:len(pngHeader)])
612 if err != nil {
613 return err
614 }
615 if string(d.tmp[:len(pngHeader)]) != pngHeader {
616 return FormatError("not a PNG file")
617 }
618 return nil
619 }
620
621 // Decode reads a PNG image from r and returns it as an image.Image.
622 // The type of Image returned depends on the PNG contents.
623 func Decode(r io.Reader) (image.Image, error) {
624 d := &decoder{
625 r: r,
626 crc: crc32.NewIEEE(),
627 }
628 if err := d.checkHeader(); err != nil {
629 if err == io.EOF {
630 err = io.ErrUnexpectedEOF
631 }
632 return nil, err
633 }
634 for d.stage != dsSeenIEND {
635 if err := d.parseChunk(); err != nil {
636 if err == io.EOF {
637 err = io.ErrUnexpectedEOF
638 }
639 return nil, err
640 }
641 }
642 return d.img, nil
643 }
644
645 // DecodeConfig returns the color model and dimensions of a PNG image without
646 // decoding the entire image.
647 func DecodeConfig(r io.Reader) (image.Config, error) {
648 d := &decoder{
649 r: r,
650 crc: crc32.NewIEEE(),
651 }
652 if err := d.checkHeader(); err != nil {
653 if err == io.EOF {
654 err = io.ErrUnexpectedEOF
655 }
656 return image.Config{}, err
657 }
658 for {
659 if err := d.parseChunk(); err != nil {
660 if err == io.EOF {
661 err = io.ErrUnexpectedEOF
662 }
663 return image.Config{}, err
664 }
665 if d.stage == dsSeenIHDR && d.cb != cbP8 {
666 break
667 }
668 if d.stage == dsSeenPLTE && d.cb == cbP8 {
669 break
670 }
671 }
672 var cm color.Model
673 switch d.cb {
674 case cbG1, cbG2, cbG4, cbG8:
675 cm = color.GrayModel
676 case cbGA8:
677 cm = color.NRGBAModel
678 case cbTC8:
679 cm = color.RGBAModel
680 case cbP1, cbP2, cbP4, cbP8:
681 cm = d.palette
682 case cbTCA8:
683 cm = color.NRGBAModel
684 case cbG16:
685 cm = color.Gray16Model
686 case cbGA16:
687 cm = color.NRGBA64Model
688 case cbTC16:
689 cm = color.RGBA64Model
690 case cbTCA16:
691 cm = color.NRGBA64Model
692 }
693 return image.Config{
694 ColorModel: cm,
695 Width: d.width,
696 Height: d.height,
697 }, nil
698 }
699
700 func init() {
701 image.RegisterFormat("png", pngHeader, Decode, DecodeConfig)
702 }