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 }