github.com/rsc/go@v0.0.0-20150416155037-e040fd465409/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("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 } else if d.interlace == itAdam7 { 330 // Allocate a blank image of the full size. 331 img, err = d.readImagePass(nil, 0, true) 332 for pass := 0; pass < 7; pass++ { 333 imagePass, err := d.readImagePass(r, pass, false) 334 if err != nil { 335 return nil, err 336 } 337 d.mergePassInto(img, imagePass, pass) 338 } 339 } 340 341 // Check for EOF, to verify the zlib checksum. 342 n := 0 343 for i := 0; n == 0 && err == nil; i++ { 344 if i == 100 { 345 return nil, io.ErrNoProgress 346 } 347 n, err = r.Read(d.tmp[:1]) 348 } 349 if err != nil && err != io.EOF { 350 return nil, FormatError(err.Error()) 351 } 352 if n != 0 || d.idatLength != 0 { 353 return nil, FormatError("too much pixel data") 354 } 355 356 return img, nil 357 } 358 359 // readImagePass reads a single image pass, sized according to the pass number. 360 func (d *decoder) readImagePass(r io.Reader, pass int, allocateOnly bool) (image.Image, error) { 361 var bitsPerPixel int = 0 362 pixOffset := 0 363 var ( 364 gray *image.Gray 365 rgba *image.RGBA 366 paletted *image.Paletted 367 nrgba *image.NRGBA 368 gray16 *image.Gray16 369 rgba64 *image.RGBA64 370 nrgba64 *image.NRGBA64 371 img image.Image 372 ) 373 width, height := d.width, d.height 374 if d.interlace == itAdam7 && !allocateOnly { 375 p := interlacing[pass] 376 // Add the multiplication factor and subtract one, effectively rounding up. 377 width = (width - p.xOffset + p.xFactor - 1) / p.xFactor 378 height = (height - p.yOffset + p.yFactor - 1) / p.yFactor 379 } 380 switch d.cb { 381 case cbG1, cbG2, cbG4, cbG8: 382 bitsPerPixel = d.depth 383 gray = image.NewGray(image.Rect(0, 0, width, height)) 384 img = gray 385 case cbGA8: 386 bitsPerPixel = 16 387 nrgba = image.NewNRGBA(image.Rect(0, 0, width, height)) 388 img = nrgba 389 case cbTC8: 390 bitsPerPixel = 24 391 rgba = image.NewRGBA(image.Rect(0, 0, width, height)) 392 img = rgba 393 case cbP1, cbP2, cbP4, cbP8: 394 bitsPerPixel = d.depth 395 paletted = image.NewPaletted(image.Rect(0, 0, width, height), d.palette) 396 img = paletted 397 case cbTCA8: 398 bitsPerPixel = 32 399 nrgba = image.NewNRGBA(image.Rect(0, 0, width, height)) 400 img = nrgba 401 case cbG16: 402 bitsPerPixel = 16 403 gray16 = image.NewGray16(image.Rect(0, 0, width, height)) 404 img = gray16 405 case cbGA16: 406 bitsPerPixel = 32 407 nrgba64 = image.NewNRGBA64(image.Rect(0, 0, width, height)) 408 img = nrgba64 409 case cbTC16: 410 bitsPerPixel = 48 411 rgba64 = image.NewRGBA64(image.Rect(0, 0, width, height)) 412 img = rgba64 413 case cbTCA16: 414 bitsPerPixel = 64 415 nrgba64 = image.NewNRGBA64(image.Rect(0, 0, width, height)) 416 img = nrgba64 417 } 418 if allocateOnly { 419 return img, nil 420 } 421 bytesPerPixel := (bitsPerPixel + 7) / 8 422 423 // The +1 is for the per-row filter type, which is at cr[0]. 424 rowSize := 1 + (bitsPerPixel*width+7)/8 425 // cr and pr are the bytes for the current and previous row. 426 cr := make([]uint8, rowSize) 427 pr := make([]uint8, rowSize) 428 429 for y := 0; y < height; y++ { 430 // Read the decompressed bytes. 431 _, err := io.ReadFull(r, cr) 432 if err != nil { 433 return nil, err 434 } 435 436 // Apply the filter. 437 cdat := cr[1:] 438 pdat := pr[1:] 439 switch cr[0] { 440 case ftNone: 441 // No-op. 442 case ftSub: 443 for i := bytesPerPixel; i < len(cdat); i++ { 444 cdat[i] += cdat[i-bytesPerPixel] 445 } 446 case ftUp: 447 for i, p := range pdat { 448 cdat[i] += p 449 } 450 case ftAverage: 451 for i := 0; i < bytesPerPixel; i++ { 452 cdat[i] += pdat[i] / 2 453 } 454 for i := bytesPerPixel; i < len(cdat); i++ { 455 cdat[i] += uint8((int(cdat[i-bytesPerPixel]) + int(pdat[i])) / 2) 456 } 457 case ftPaeth: 458 filterPaeth(cdat, pdat, bytesPerPixel) 459 default: 460 return nil, FormatError("bad filter type") 461 } 462 463 // Convert from bytes to colors. 464 switch d.cb { 465 case cbG1: 466 for x := 0; x < width; x += 8 { 467 b := cdat[x/8] 468 for x2 := 0; x2 < 8 && x+x2 < width; x2++ { 469 gray.SetGray(x+x2, y, color.Gray{(b >> 7) * 0xff}) 470 b <<= 1 471 } 472 } 473 case cbG2: 474 for x := 0; x < width; x += 4 { 475 b := cdat[x/4] 476 for x2 := 0; x2 < 4 && x+x2 < width; x2++ { 477 gray.SetGray(x+x2, y, color.Gray{(b >> 6) * 0x55}) 478 b <<= 2 479 } 480 } 481 case cbG4: 482 for x := 0; x < width; x += 2 { 483 b := cdat[x/2] 484 for x2 := 0; x2 < 2 && x+x2 < width; x2++ { 485 gray.SetGray(x+x2, y, color.Gray{(b >> 4) * 0x11}) 486 b <<= 4 487 } 488 } 489 case cbG8: 490 copy(gray.Pix[pixOffset:], cdat) 491 pixOffset += gray.Stride 492 case cbGA8: 493 for x := 0; x < width; x++ { 494 ycol := cdat[2*x+0] 495 nrgba.SetNRGBA(x, y, color.NRGBA{ycol, ycol, ycol, cdat[2*x+1]}) 496 } 497 case cbTC8: 498 pix, i, j := rgba.Pix, pixOffset, 0 499 for x := 0; x < width; x++ { 500 pix[i+0] = cdat[j+0] 501 pix[i+1] = cdat[j+1] 502 pix[i+2] = cdat[j+2] 503 pix[i+3] = 0xff 504 i += 4 505 j += 3 506 } 507 pixOffset += rgba.Stride 508 case cbP1: 509 for x := 0; x < width; x += 8 { 510 b := cdat[x/8] 511 for x2 := 0; x2 < 8 && x+x2 < width; x2++ { 512 idx := b >> 7 513 if len(paletted.Palette) <= int(idx) { 514 paletted.Palette = paletted.Palette[:int(idx)+1] 515 } 516 paletted.SetColorIndex(x+x2, y, idx) 517 b <<= 1 518 } 519 } 520 case cbP2: 521 for x := 0; x < width; x += 4 { 522 b := cdat[x/4] 523 for x2 := 0; x2 < 4 && x+x2 < width; x2++ { 524 idx := b >> 6 525 if len(paletted.Palette) <= int(idx) { 526 paletted.Palette = paletted.Palette[:int(idx)+1] 527 } 528 paletted.SetColorIndex(x+x2, y, idx) 529 b <<= 2 530 } 531 } 532 case cbP4: 533 for x := 0; x < width; x += 2 { 534 b := cdat[x/2] 535 for x2 := 0; x2 < 2 && x+x2 < width; x2++ { 536 idx := b >> 4 537 if len(paletted.Palette) <= int(idx) { 538 paletted.Palette = paletted.Palette[:int(idx)+1] 539 } 540 paletted.SetColorIndex(x+x2, y, idx) 541 b <<= 4 542 } 543 } 544 case cbP8: 545 if len(paletted.Palette) != 255 { 546 for x := 0; x < width; x++ { 547 if len(paletted.Palette) <= int(cdat[x]) { 548 paletted.Palette = paletted.Palette[:int(cdat[x])+1] 549 } 550 } 551 } 552 copy(paletted.Pix[pixOffset:], cdat) 553 pixOffset += paletted.Stride 554 case cbTCA8: 555 copy(nrgba.Pix[pixOffset:], cdat) 556 pixOffset += nrgba.Stride 557 case cbG16: 558 for x := 0; x < width; x++ { 559 ycol := uint16(cdat[2*x+0])<<8 | uint16(cdat[2*x+1]) 560 gray16.SetGray16(x, y, color.Gray16{ycol}) 561 } 562 case cbGA16: 563 for x := 0; x < width; x++ { 564 ycol := uint16(cdat[4*x+0])<<8 | uint16(cdat[4*x+1]) 565 acol := uint16(cdat[4*x+2])<<8 | uint16(cdat[4*x+3]) 566 nrgba64.SetNRGBA64(x, y, color.NRGBA64{ycol, ycol, ycol, acol}) 567 } 568 case cbTC16: 569 for x := 0; x < width; x++ { 570 rcol := uint16(cdat[6*x+0])<<8 | uint16(cdat[6*x+1]) 571 gcol := uint16(cdat[6*x+2])<<8 | uint16(cdat[6*x+3]) 572 bcol := uint16(cdat[6*x+4])<<8 | uint16(cdat[6*x+5]) 573 rgba64.SetRGBA64(x, y, color.RGBA64{rcol, gcol, bcol, 0xffff}) 574 } 575 case cbTCA16: 576 for x := 0; x < width; x++ { 577 rcol := uint16(cdat[8*x+0])<<8 | uint16(cdat[8*x+1]) 578 gcol := uint16(cdat[8*x+2])<<8 | uint16(cdat[8*x+3]) 579 bcol := uint16(cdat[8*x+4])<<8 | uint16(cdat[8*x+5]) 580 acol := uint16(cdat[8*x+6])<<8 | uint16(cdat[8*x+7]) 581 nrgba64.SetNRGBA64(x, y, color.NRGBA64{rcol, gcol, bcol, acol}) 582 } 583 } 584 585 // The current row for y is the previous row for y+1. 586 pr, cr = cr, pr 587 } 588 589 return img, nil 590 } 591 592 // mergePassInto merges a single pass into a full sized image. 593 func (d *decoder) mergePassInto(dst image.Image, src image.Image, pass int) { 594 p := interlacing[pass] 595 var ( 596 srcPix []uint8 597 dstPix []uint8 598 stride int 599 rect image.Rectangle 600 bytesPerPixel int 601 ) 602 switch target := dst.(type) { 603 case *image.Alpha: 604 srcPix = src.(*image.Alpha).Pix 605 dstPix, stride, rect = target.Pix, target.Stride, target.Rect 606 bytesPerPixel = 1 607 case *image.Alpha16: 608 srcPix = src.(*image.Alpha16).Pix 609 dstPix, stride, rect = target.Pix, target.Stride, target.Rect 610 bytesPerPixel = 2 611 case *image.Gray: 612 srcPix = src.(*image.Gray).Pix 613 dstPix, stride, rect = target.Pix, target.Stride, target.Rect 614 bytesPerPixel = 1 615 case *image.Gray16: 616 srcPix = src.(*image.Gray16).Pix 617 dstPix, stride, rect = target.Pix, target.Stride, target.Rect 618 bytesPerPixel = 2 619 case *image.NRGBA: 620 srcPix = src.(*image.NRGBA).Pix 621 dstPix, stride, rect = target.Pix, target.Stride, target.Rect 622 bytesPerPixel = 4 623 case *image.NRGBA64: 624 srcPix = src.(*image.NRGBA64).Pix 625 dstPix, stride, rect = target.Pix, target.Stride, target.Rect 626 bytesPerPixel = 8 627 case *image.Paletted: 628 srcPix = src.(*image.Paletted).Pix 629 dstPix, stride, rect = target.Pix, target.Stride, target.Rect 630 bytesPerPixel = 1 631 case *image.RGBA: 632 srcPix = src.(*image.RGBA).Pix 633 dstPix, stride, rect = target.Pix, target.Stride, target.Rect 634 bytesPerPixel = 4 635 case *image.RGBA64: 636 srcPix = src.(*image.RGBA64).Pix 637 dstPix, stride, rect = target.Pix, target.Stride, target.Rect 638 bytesPerPixel = 8 639 } 640 s, bounds := 0, src.Bounds() 641 for y := bounds.Min.Y; y < bounds.Max.Y; y++ { 642 dBase := (y*p.yFactor+p.yOffset-rect.Min.Y)*stride + (p.xOffset-rect.Min.X)*bytesPerPixel 643 for x := bounds.Min.X; x < bounds.Max.X; x++ { 644 d := dBase + x*p.xFactor*bytesPerPixel 645 copy(dstPix[d:], srcPix[s:s+bytesPerPixel]) 646 s += bytesPerPixel 647 } 648 } 649 } 650 651 func (d *decoder) parseIDAT(length uint32) (err error) { 652 d.idatLength = length 653 d.img, err = d.decode() 654 if err != nil { 655 return err 656 } 657 return d.verifyChecksum() 658 } 659 660 func (d *decoder) parseIEND(length uint32) error { 661 if length != 0 { 662 return FormatError("bad IEND length") 663 } 664 return d.verifyChecksum() 665 } 666 667 func (d *decoder) parseChunk() error { 668 // Read the length and chunk type. 669 n, err := io.ReadFull(d.r, d.tmp[:8]) 670 if err != nil { 671 return err 672 } 673 length := binary.BigEndian.Uint32(d.tmp[:4]) 674 d.crc.Reset() 675 d.crc.Write(d.tmp[4:8]) 676 677 // Read the chunk data. 678 switch string(d.tmp[4:8]) { 679 case "IHDR": 680 if d.stage != dsStart { 681 return chunkOrderError 682 } 683 d.stage = dsSeenIHDR 684 return d.parseIHDR(length) 685 case "PLTE": 686 if d.stage != dsSeenIHDR { 687 return chunkOrderError 688 } 689 d.stage = dsSeenPLTE 690 return d.parsePLTE(length) 691 case "tRNS": 692 if d.stage != dsSeenPLTE { 693 return chunkOrderError 694 } 695 d.stage = dsSeentRNS 696 return d.parsetRNS(length) 697 case "IDAT": 698 if d.stage < dsSeenIHDR || d.stage > dsSeenIDAT || (d.stage == dsSeenIHDR && cbPaletted(d.cb)) { 699 return chunkOrderError 700 } 701 d.stage = dsSeenIDAT 702 return d.parseIDAT(length) 703 case "IEND": 704 if d.stage != dsSeenIDAT { 705 return chunkOrderError 706 } 707 d.stage = dsSeenIEND 708 return d.parseIEND(length) 709 } 710 // Ignore this chunk (of a known length). 711 var ignored [4096]byte 712 for length > 0 { 713 n, err = io.ReadFull(d.r, ignored[:min(len(ignored), int(length))]) 714 if err != nil { 715 return err 716 } 717 d.crc.Write(ignored[:n]) 718 length -= uint32(n) 719 } 720 return d.verifyChecksum() 721 } 722 723 func (d *decoder) verifyChecksum() error { 724 if _, err := io.ReadFull(d.r, d.tmp[:4]); err != nil { 725 return err 726 } 727 if binary.BigEndian.Uint32(d.tmp[:4]) != d.crc.Sum32() { 728 return FormatError("invalid checksum") 729 } 730 return nil 731 } 732 733 func (d *decoder) checkHeader() error { 734 _, err := io.ReadFull(d.r, d.tmp[:len(pngHeader)]) 735 if err != nil { 736 return err 737 } 738 if string(d.tmp[:len(pngHeader)]) != pngHeader { 739 return FormatError("not a PNG file") 740 } 741 return nil 742 } 743 744 // Decode reads a PNG image from r and returns it as an image.Image. 745 // The type of Image returned depends on the PNG contents. 746 func Decode(r io.Reader) (image.Image, error) { 747 d := &decoder{ 748 r: r, 749 crc: crc32.NewIEEE(), 750 } 751 if err := d.checkHeader(); err != nil { 752 if err == io.EOF { 753 err = io.ErrUnexpectedEOF 754 } 755 return nil, err 756 } 757 for d.stage != dsSeenIEND { 758 if err := d.parseChunk(); err != nil { 759 if err == io.EOF { 760 err = io.ErrUnexpectedEOF 761 } 762 return nil, err 763 } 764 } 765 return d.img, nil 766 } 767 768 // DecodeConfig returns the color model and dimensions of a PNG image without 769 // decoding the entire image. 770 func DecodeConfig(r io.Reader) (image.Config, error) { 771 d := &decoder{ 772 r: r, 773 crc: crc32.NewIEEE(), 774 } 775 if err := d.checkHeader(); err != nil { 776 if err == io.EOF { 777 err = io.ErrUnexpectedEOF 778 } 779 return image.Config{}, err 780 } 781 for { 782 if err := d.parseChunk(); err != nil { 783 if err == io.EOF { 784 err = io.ErrUnexpectedEOF 785 } 786 return image.Config{}, err 787 } 788 paletted := cbPaletted(d.cb) 789 if d.stage == dsSeenIHDR && !paletted { 790 break 791 } 792 if d.stage == dsSeenPLTE && paletted { 793 break 794 } 795 } 796 var cm color.Model 797 switch d.cb { 798 case cbG1, cbG2, cbG4, cbG8: 799 cm = color.GrayModel 800 case cbGA8: 801 cm = color.NRGBAModel 802 case cbTC8: 803 cm = color.RGBAModel 804 case cbP1, cbP2, cbP4, cbP8: 805 cm = d.palette 806 case cbTCA8: 807 cm = color.NRGBAModel 808 case cbG16: 809 cm = color.Gray16Model 810 case cbGA16: 811 cm = color.NRGBA64Model 812 case cbTC16: 813 cm = color.RGBA64Model 814 case cbTCA16: 815 cm = color.NRGBA64Model 816 } 817 return image.Config{ 818 ColorModel: cm, 819 Width: d.width, 820 Height: d.height, 821 }, nil 822 } 823 824 func init() { 825 image.RegisterFormat("png", pngHeader, Decode, DecodeConfig) 826 }