github.com/4ad/go@v0.0.0-20161219182952-69a12818b605/src/image/png/reader.go (about) 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("non-positive 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 } else if d.stage == dsSeenIDAT { 721 // Ignore trailing zero-length or garbage IDAT chunks. 722 // 723 // This does not affect valid PNG images that contain multiple IDAT 724 // chunks, since the first call to parseIDAT below will consume all 725 // consecutive IDAT chunks required for decoding the image. 726 break 727 } 728 d.stage = dsSeenIDAT 729 return d.parseIDAT(length) 730 case "IEND": 731 if d.stage != dsSeenIDAT { 732 return chunkOrderError 733 } 734 d.stage = dsSeenIEND 735 return d.parseIEND(length) 736 } 737 if length > 0x7fffffff { 738 return FormatError(fmt.Sprintf("Bad chunk length: %d", length)) 739 } 740 // Ignore this chunk (of a known length). 741 var ignored [4096]byte 742 for length > 0 { 743 n, err = io.ReadFull(d.r, ignored[:min(len(ignored), int(length))]) 744 if err != nil { 745 return err 746 } 747 d.crc.Write(ignored[:n]) 748 length -= uint32(n) 749 } 750 return d.verifyChecksum() 751 } 752 753 func (d *decoder) verifyChecksum() error { 754 if _, err := io.ReadFull(d.r, d.tmp[:4]); err != nil { 755 return err 756 } 757 if binary.BigEndian.Uint32(d.tmp[:4]) != d.crc.Sum32() { 758 return FormatError("invalid checksum") 759 } 760 return nil 761 } 762 763 func (d *decoder) checkHeader() error { 764 _, err := io.ReadFull(d.r, d.tmp[:len(pngHeader)]) 765 if err != nil { 766 return err 767 } 768 if string(d.tmp[:len(pngHeader)]) != pngHeader { 769 return FormatError("not a PNG file") 770 } 771 return nil 772 } 773 774 // Decode reads a PNG image from r and returns it as an image.Image. 775 // The type of Image returned depends on the PNG contents. 776 func Decode(r io.Reader) (image.Image, error) { 777 d := &decoder{ 778 r: r, 779 crc: crc32.NewIEEE(), 780 } 781 if err := d.checkHeader(); err != nil { 782 if err == io.EOF { 783 err = io.ErrUnexpectedEOF 784 } 785 return nil, err 786 } 787 for d.stage != dsSeenIEND { 788 if err := d.parseChunk(); err != nil { 789 if err == io.EOF { 790 err = io.ErrUnexpectedEOF 791 } 792 return nil, err 793 } 794 } 795 return d.img, nil 796 } 797 798 // DecodeConfig returns the color model and dimensions of a PNG image without 799 // decoding the entire image. 800 func DecodeConfig(r io.Reader) (image.Config, error) { 801 d := &decoder{ 802 r: r, 803 crc: crc32.NewIEEE(), 804 } 805 if err := d.checkHeader(); err != nil { 806 if err == io.EOF { 807 err = io.ErrUnexpectedEOF 808 } 809 return image.Config{}, err 810 } 811 for { 812 if err := d.parseChunk(); err != nil { 813 if err == io.EOF { 814 err = io.ErrUnexpectedEOF 815 } 816 return image.Config{}, err 817 } 818 paletted := cbPaletted(d.cb) 819 if d.stage == dsSeenIHDR && !paletted { 820 break 821 } 822 if d.stage == dsSeenPLTE && paletted { 823 break 824 } 825 } 826 var cm color.Model 827 switch d.cb { 828 case cbG1, cbG2, cbG4, cbG8: 829 cm = color.GrayModel 830 case cbGA8: 831 cm = color.NRGBAModel 832 case cbTC8: 833 cm = color.RGBAModel 834 case cbP1, cbP2, cbP4, cbP8: 835 cm = d.palette 836 case cbTCA8: 837 cm = color.NRGBAModel 838 case cbG16: 839 cm = color.Gray16Model 840 case cbGA16: 841 cm = color.NRGBA64Model 842 case cbTC16: 843 cm = color.RGBA64Model 844 case cbTCA16: 845 cm = color.NRGBA64Model 846 } 847 return image.Config{ 848 ColorModel: cm, 849 Width: d.width, 850 Height: d.height, 851 }, nil 852 } 853 854 func init() { 855 image.RegisterFormat("png", pngHeader, Decode, DecodeConfig) 856 }