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