github.com/zebozhuang/go@v0.0.0-20200207033046-f8a98f6f5c5d/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 // useTransparent and transparent are used for grayscale and truecolor 118 // transparency, as opposed to palette transparency. 119 useTransparent bool 120 transparent [6]byte 121 } 122 123 // A FormatError reports that the input is not a valid PNG. 124 type FormatError string 125 126 func (e FormatError) Error() string { return "png: invalid format: " + string(e) } 127 128 var chunkOrderError = FormatError("chunk out of order") 129 130 // An UnsupportedError reports that the input uses a valid but unimplemented PNG feature. 131 type UnsupportedError string 132 133 func (e UnsupportedError) Error() string { return "png: unsupported feature: " + string(e) } 134 135 func min(a, b int) int { 136 if a < b { 137 return a 138 } 139 return b 140 } 141 142 func (d *decoder) parseIHDR(length uint32) error { 143 if length != 13 { 144 return FormatError("bad IHDR length") 145 } 146 if _, err := io.ReadFull(d.r, d.tmp[:13]); err != nil { 147 return err 148 } 149 d.crc.Write(d.tmp[:13]) 150 if d.tmp[10] != 0 { 151 return UnsupportedError("compression method") 152 } 153 if d.tmp[11] != 0 { 154 return UnsupportedError("filter method") 155 } 156 if d.tmp[12] != itNone && d.tmp[12] != itAdam7 { 157 return FormatError("invalid interlace method") 158 } 159 d.interlace = int(d.tmp[12]) 160 w := int32(binary.BigEndian.Uint32(d.tmp[0:4])) 161 h := int32(binary.BigEndian.Uint32(d.tmp[4:8])) 162 if w <= 0 || h <= 0 { 163 return FormatError("non-positive dimension") 164 } 165 nPixels := int64(w) * int64(h) 166 if nPixels != int64(int(nPixels)) { 167 return UnsupportedError("dimension overflow") 168 } 169 d.cb = cbInvalid 170 d.depth = int(d.tmp[8]) 171 switch d.depth { 172 case 1: 173 switch d.tmp[9] { 174 case ctGrayscale: 175 d.cb = cbG1 176 case ctPaletted: 177 d.cb = cbP1 178 } 179 case 2: 180 switch d.tmp[9] { 181 case ctGrayscale: 182 d.cb = cbG2 183 case ctPaletted: 184 d.cb = cbP2 185 } 186 case 4: 187 switch d.tmp[9] { 188 case ctGrayscale: 189 d.cb = cbG4 190 case ctPaletted: 191 d.cb = cbP4 192 } 193 case 8: 194 switch d.tmp[9] { 195 case ctGrayscale: 196 d.cb = cbG8 197 case ctTrueColor: 198 d.cb = cbTC8 199 case ctPaletted: 200 d.cb = cbP8 201 case ctGrayscaleAlpha: 202 d.cb = cbGA8 203 case ctTrueColorAlpha: 204 d.cb = cbTCA8 205 } 206 case 16: 207 switch d.tmp[9] { 208 case ctGrayscale: 209 d.cb = cbG16 210 case ctTrueColor: 211 d.cb = cbTC16 212 case ctGrayscaleAlpha: 213 d.cb = cbGA16 214 case ctTrueColorAlpha: 215 d.cb = cbTCA16 216 } 217 } 218 if d.cb == cbInvalid { 219 return UnsupportedError(fmt.Sprintf("bit depth %d, color type %d", d.tmp[8], d.tmp[9])) 220 } 221 d.width, d.height = int(w), int(h) 222 return d.verifyChecksum() 223 } 224 225 func (d *decoder) parsePLTE(length uint32) error { 226 np := int(length / 3) // The number of palette entries. 227 if length%3 != 0 || np <= 0 || np > 256 || np > 1<<uint(d.depth) { 228 return FormatError("bad PLTE length") 229 } 230 n, err := io.ReadFull(d.r, d.tmp[:3*np]) 231 if err != nil { 232 return err 233 } 234 d.crc.Write(d.tmp[:n]) 235 switch d.cb { 236 case cbP1, cbP2, cbP4, cbP8: 237 d.palette = make(color.Palette, 256) 238 for i := 0; i < np; i++ { 239 d.palette[i] = color.RGBA{d.tmp[3*i+0], d.tmp[3*i+1], d.tmp[3*i+2], 0xff} 240 } 241 for i := np; i < 256; i++ { 242 // Initialize the rest of the palette to opaque black. The spec (section 243 // 11.2.3) says that "any out-of-range pixel value found in the image data 244 // is an error", but some real-world PNG files have out-of-range pixel 245 // values. We fall back to opaque black, the same as libpng 1.5.13; 246 // ImageMagick 6.5.7 returns an error. 247 d.palette[i] = color.RGBA{0x00, 0x00, 0x00, 0xff} 248 } 249 d.palette = d.palette[:np] 250 case cbTC8, cbTCA8, cbTC16, cbTCA16: 251 // As per the PNG spec, a PLTE chunk is optional (and for practical purposes, 252 // ignorable) for the ctTrueColor and ctTrueColorAlpha color types (section 4.1.2). 253 default: 254 return FormatError("PLTE, color type mismatch") 255 } 256 return d.verifyChecksum() 257 } 258 259 func (d *decoder) parsetRNS(length uint32) error { 260 switch d.cb { 261 case cbG1, cbG2, cbG4, cbG8, cbG16: 262 if length != 2 { 263 return FormatError("bad tRNS length") 264 } 265 n, err := io.ReadFull(d.r, d.tmp[:length]) 266 if err != nil { 267 return err 268 } 269 d.crc.Write(d.tmp[:n]) 270 271 copy(d.transparent[:], d.tmp[:length]) 272 switch d.cb { 273 case cbG1: 274 d.transparent[1] *= 0xff 275 case cbG2: 276 d.transparent[1] *= 0x55 277 case cbG4: 278 d.transparent[1] *= 0x11 279 } 280 d.useTransparent = true 281 282 case cbTC8, cbTC16: 283 if length != 6 { 284 return FormatError("bad tRNS length") 285 } 286 n, err := io.ReadFull(d.r, d.tmp[:length]) 287 if err != nil { 288 return err 289 } 290 d.crc.Write(d.tmp[:n]) 291 292 copy(d.transparent[:], d.tmp[:length]) 293 d.useTransparent = true 294 295 case cbP1, cbP2, cbP4, cbP8: 296 if length > 256 { 297 return FormatError("bad tRNS length") 298 } 299 n, err := io.ReadFull(d.r, d.tmp[:length]) 300 if err != nil { 301 return err 302 } 303 d.crc.Write(d.tmp[:n]) 304 305 if len(d.palette) < n { 306 d.palette = d.palette[:n] 307 } 308 for i := 0; i < n; i++ { 309 rgba := d.palette[i].(color.RGBA) 310 d.palette[i] = color.NRGBA{rgba.R, rgba.G, rgba.B, d.tmp[i]} 311 } 312 313 default: 314 return FormatError("tRNS, color type mismatch") 315 } 316 return d.verifyChecksum() 317 } 318 319 // Read presents one or more IDAT chunks as one continuous stream (minus the 320 // intermediate chunk headers and footers). If the PNG data looked like: 321 // ... len0 IDAT xxx crc0 len1 IDAT yy crc1 len2 IEND crc2 322 // then this reader presents xxxyy. For well-formed PNG data, the decoder state 323 // immediately before the first Read call is that d.r is positioned between the 324 // first IDAT and xxx, and the decoder state immediately after the last Read 325 // call is that d.r is positioned between yy and crc1. 326 func (d *decoder) Read(p []byte) (int, error) { 327 if len(p) == 0 { 328 return 0, nil 329 } 330 for d.idatLength == 0 { 331 // We have exhausted an IDAT chunk. Verify the checksum of that chunk. 332 if err := d.verifyChecksum(); err != nil { 333 return 0, err 334 } 335 // Read the length and chunk type of the next chunk, and check that 336 // it is an IDAT chunk. 337 if _, err := io.ReadFull(d.r, d.tmp[:8]); err != nil { 338 return 0, err 339 } 340 d.idatLength = binary.BigEndian.Uint32(d.tmp[:4]) 341 if string(d.tmp[4:8]) != "IDAT" { 342 return 0, FormatError("not enough pixel data") 343 } 344 d.crc.Reset() 345 d.crc.Write(d.tmp[4:8]) 346 } 347 if int(d.idatLength) < 0 { 348 return 0, UnsupportedError("IDAT chunk length overflow") 349 } 350 n, err := d.r.Read(p[:min(len(p), int(d.idatLength))]) 351 d.crc.Write(p[:n]) 352 d.idatLength -= uint32(n) 353 return n, err 354 } 355 356 // decode decodes the IDAT data into an image. 357 func (d *decoder) decode() (image.Image, error) { 358 r, err := zlib.NewReader(d) 359 if err != nil { 360 return nil, err 361 } 362 defer r.Close() 363 var img image.Image 364 if d.interlace == itNone { 365 img, err = d.readImagePass(r, 0, false) 366 if err != nil { 367 return nil, err 368 } 369 } else if d.interlace == itAdam7 { 370 // Allocate a blank image of the full size. 371 img, err = d.readImagePass(nil, 0, true) 372 if err != nil { 373 return nil, err 374 } 375 for pass := 0; pass < 7; pass++ { 376 imagePass, err := d.readImagePass(r, pass, false) 377 if err != nil { 378 return nil, err 379 } 380 if imagePass != nil { 381 d.mergePassInto(img, imagePass, pass) 382 } 383 } 384 } 385 386 // Check for EOF, to verify the zlib checksum. 387 n := 0 388 for i := 0; n == 0 && err == nil; i++ { 389 if i == 100 { 390 return nil, io.ErrNoProgress 391 } 392 n, err = r.Read(d.tmp[:1]) 393 } 394 if err != nil && err != io.EOF { 395 return nil, FormatError(err.Error()) 396 } 397 if n != 0 || d.idatLength != 0 { 398 return nil, FormatError("too much pixel data") 399 } 400 401 return img, nil 402 } 403 404 // readImagePass reads a single image pass, sized according to the pass number. 405 func (d *decoder) readImagePass(r io.Reader, pass int, allocateOnly bool) (image.Image, error) { 406 bitsPerPixel := 0 407 pixOffset := 0 408 var ( 409 gray *image.Gray 410 rgba *image.RGBA 411 paletted *image.Paletted 412 nrgba *image.NRGBA 413 gray16 *image.Gray16 414 rgba64 *image.RGBA64 415 nrgba64 *image.NRGBA64 416 img image.Image 417 ) 418 width, height := d.width, d.height 419 if d.interlace == itAdam7 && !allocateOnly { 420 p := interlacing[pass] 421 // Add the multiplication factor and subtract one, effectively rounding up. 422 width = (width - p.xOffset + p.xFactor - 1) / p.xFactor 423 height = (height - p.yOffset + p.yFactor - 1) / p.yFactor 424 // A PNG image can't have zero width or height, but for an interlaced 425 // image, an individual pass might have zero width or height. If so, we 426 // shouldn't even read a per-row filter type byte, so return early. 427 if width == 0 || height == 0 { 428 return nil, nil 429 } 430 } 431 switch d.cb { 432 case cbG1, cbG2, cbG4, cbG8: 433 bitsPerPixel = d.depth 434 if d.useTransparent { 435 nrgba = image.NewNRGBA(image.Rect(0, 0, width, height)) 436 img = nrgba 437 } else { 438 gray = image.NewGray(image.Rect(0, 0, width, height)) 439 img = gray 440 } 441 case cbGA8: 442 bitsPerPixel = 16 443 nrgba = image.NewNRGBA(image.Rect(0, 0, width, height)) 444 img = nrgba 445 case cbTC8: 446 bitsPerPixel = 24 447 if d.useTransparent { 448 nrgba = image.NewNRGBA(image.Rect(0, 0, width, height)) 449 img = nrgba 450 } else { 451 rgba = image.NewRGBA(image.Rect(0, 0, width, height)) 452 img = rgba 453 } 454 case cbP1, cbP2, cbP4, cbP8: 455 bitsPerPixel = d.depth 456 paletted = image.NewPaletted(image.Rect(0, 0, width, height), d.palette) 457 img = paletted 458 case cbTCA8: 459 bitsPerPixel = 32 460 nrgba = image.NewNRGBA(image.Rect(0, 0, width, height)) 461 img = nrgba 462 case cbG16: 463 bitsPerPixel = 16 464 if d.useTransparent { 465 nrgba64 = image.NewNRGBA64(image.Rect(0, 0, width, height)) 466 img = nrgba64 467 } else { 468 gray16 = image.NewGray16(image.Rect(0, 0, width, height)) 469 img = gray16 470 } 471 case cbGA16: 472 bitsPerPixel = 32 473 nrgba64 = image.NewNRGBA64(image.Rect(0, 0, width, height)) 474 img = nrgba64 475 case cbTC16: 476 bitsPerPixel = 48 477 if d.useTransparent { 478 nrgba64 = image.NewNRGBA64(image.Rect(0, 0, width, height)) 479 img = nrgba64 480 } else { 481 rgba64 = image.NewRGBA64(image.Rect(0, 0, width, height)) 482 img = rgba64 483 } 484 case cbTCA16: 485 bitsPerPixel = 64 486 nrgba64 = image.NewNRGBA64(image.Rect(0, 0, width, height)) 487 img = nrgba64 488 } 489 if allocateOnly { 490 return img, nil 491 } 492 bytesPerPixel := (bitsPerPixel + 7) / 8 493 494 // The +1 is for the per-row filter type, which is at cr[0]. 495 rowSize := 1 + (bitsPerPixel*width+7)/8 496 // cr and pr are the bytes for the current and previous row. 497 cr := make([]uint8, rowSize) 498 pr := make([]uint8, rowSize) 499 500 for y := 0; y < height; y++ { 501 // Read the decompressed bytes. 502 _, err := io.ReadFull(r, cr) 503 if err != nil { 504 if err == io.EOF || err == io.ErrUnexpectedEOF { 505 return nil, FormatError("not enough pixel data") 506 } 507 return nil, err 508 } 509 510 // Apply the filter. 511 cdat := cr[1:] 512 pdat := pr[1:] 513 switch cr[0] { 514 case ftNone: 515 // No-op. 516 case ftSub: 517 for i := bytesPerPixel; i < len(cdat); i++ { 518 cdat[i] += cdat[i-bytesPerPixel] 519 } 520 case ftUp: 521 for i, p := range pdat { 522 cdat[i] += p 523 } 524 case ftAverage: 525 // The first column has no column to the left of it, so it is a 526 // special case. We know that the first column exists because we 527 // check above that width != 0, and so len(cdat) != 0. 528 for i := 0; i < bytesPerPixel; i++ { 529 cdat[i] += pdat[i] / 2 530 } 531 for i := bytesPerPixel; i < len(cdat); i++ { 532 cdat[i] += uint8((int(cdat[i-bytesPerPixel]) + int(pdat[i])) / 2) 533 } 534 case ftPaeth: 535 filterPaeth(cdat, pdat, bytesPerPixel) 536 default: 537 return nil, FormatError("bad filter type") 538 } 539 540 // Convert from bytes to colors. 541 switch d.cb { 542 case cbG1: 543 if d.useTransparent { 544 ty := d.transparent[1] 545 for x := 0; x < width; x += 8 { 546 b := cdat[x/8] 547 for x2 := 0; x2 < 8 && x+x2 < width; x2++ { 548 ycol := (b >> 7) * 0xff 549 acol := uint8(0xff) 550 if ycol == ty { 551 acol = 0x00 552 } 553 nrgba.SetNRGBA(x+x2, y, color.NRGBA{ycol, ycol, ycol, acol}) 554 b <<= 1 555 } 556 } 557 } else { 558 for x := 0; x < width; x += 8 { 559 b := cdat[x/8] 560 for x2 := 0; x2 < 8 && x+x2 < width; x2++ { 561 gray.SetGray(x+x2, y, color.Gray{(b >> 7) * 0xff}) 562 b <<= 1 563 } 564 } 565 } 566 case cbG2: 567 if d.useTransparent { 568 ty := d.transparent[1] 569 for x := 0; x < width; x += 4 { 570 b := cdat[x/4] 571 for x2 := 0; x2 < 4 && x+x2 < width; x2++ { 572 ycol := (b >> 6) * 0x55 573 acol := uint8(0xff) 574 if ycol == ty { 575 acol = 0x00 576 } 577 nrgba.SetNRGBA(x+x2, y, color.NRGBA{ycol, ycol, ycol, acol}) 578 b <<= 2 579 } 580 } 581 } else { 582 for x := 0; x < width; x += 4 { 583 b := cdat[x/4] 584 for x2 := 0; x2 < 4 && x+x2 < width; x2++ { 585 gray.SetGray(x+x2, y, color.Gray{(b >> 6) * 0x55}) 586 b <<= 2 587 } 588 } 589 } 590 case cbG4: 591 if d.useTransparent { 592 ty := d.transparent[1] 593 for x := 0; x < width; x += 2 { 594 b := cdat[x/2] 595 for x2 := 0; x2 < 2 && x+x2 < width; x2++ { 596 ycol := (b >> 4) * 0x11 597 acol := uint8(0xff) 598 if ycol == ty { 599 acol = 0x00 600 } 601 nrgba.SetNRGBA(x+x2, y, color.NRGBA{ycol, ycol, ycol, acol}) 602 b <<= 4 603 } 604 } 605 } else { 606 for x := 0; x < width; x += 2 { 607 b := cdat[x/2] 608 for x2 := 0; x2 < 2 && x+x2 < width; x2++ { 609 gray.SetGray(x+x2, y, color.Gray{(b >> 4) * 0x11}) 610 b <<= 4 611 } 612 } 613 } 614 case cbG8: 615 if d.useTransparent { 616 ty := d.transparent[1] 617 for x := 0; x < width; x++ { 618 ycol := cdat[x] 619 acol := uint8(0xff) 620 if ycol == ty { 621 acol = 0x00 622 } 623 nrgba.SetNRGBA(x, y, color.NRGBA{ycol, ycol, ycol, acol}) 624 } 625 } else { 626 copy(gray.Pix[pixOffset:], cdat) 627 pixOffset += gray.Stride 628 } 629 case cbGA8: 630 for x := 0; x < width; x++ { 631 ycol := cdat[2*x+0] 632 nrgba.SetNRGBA(x, y, color.NRGBA{ycol, ycol, ycol, cdat[2*x+1]}) 633 } 634 case cbTC8: 635 if d.useTransparent { 636 pix, i, j := nrgba.Pix, pixOffset, 0 637 tr, tg, tb := d.transparent[1], d.transparent[3], d.transparent[5] 638 for x := 0; x < width; x++ { 639 r := cdat[j+0] 640 g := cdat[j+1] 641 b := cdat[j+2] 642 a := uint8(0xff) 643 if r == tr && g == tg && b == tb { 644 a = 0x00 645 } 646 pix[i+0] = r 647 pix[i+1] = g 648 pix[i+2] = b 649 pix[i+3] = a 650 i += 4 651 j += 3 652 } 653 pixOffset += nrgba.Stride 654 } else { 655 pix, i, j := rgba.Pix, pixOffset, 0 656 for x := 0; x < width; x++ { 657 pix[i+0] = cdat[j+0] 658 pix[i+1] = cdat[j+1] 659 pix[i+2] = cdat[j+2] 660 pix[i+3] = 0xff 661 i += 4 662 j += 3 663 } 664 pixOffset += rgba.Stride 665 } 666 case cbP1: 667 for x := 0; x < width; x += 8 { 668 b := cdat[x/8] 669 for x2 := 0; x2 < 8 && x+x2 < width; x2++ { 670 idx := b >> 7 671 if len(paletted.Palette) <= int(idx) { 672 paletted.Palette = paletted.Palette[:int(idx)+1] 673 } 674 paletted.SetColorIndex(x+x2, y, idx) 675 b <<= 1 676 } 677 } 678 case cbP2: 679 for x := 0; x < width; x += 4 { 680 b := cdat[x/4] 681 for x2 := 0; x2 < 4 && x+x2 < width; x2++ { 682 idx := b >> 6 683 if len(paletted.Palette) <= int(idx) { 684 paletted.Palette = paletted.Palette[:int(idx)+1] 685 } 686 paletted.SetColorIndex(x+x2, y, idx) 687 b <<= 2 688 } 689 } 690 case cbP4: 691 for x := 0; x < width; x += 2 { 692 b := cdat[x/2] 693 for x2 := 0; x2 < 2 && x+x2 < width; x2++ { 694 idx := b >> 4 695 if len(paletted.Palette) <= int(idx) { 696 paletted.Palette = paletted.Palette[:int(idx)+1] 697 } 698 paletted.SetColorIndex(x+x2, y, idx) 699 b <<= 4 700 } 701 } 702 case cbP8: 703 if len(paletted.Palette) != 255 { 704 for x := 0; x < width; x++ { 705 if len(paletted.Palette) <= int(cdat[x]) { 706 paletted.Palette = paletted.Palette[:int(cdat[x])+1] 707 } 708 } 709 } 710 copy(paletted.Pix[pixOffset:], cdat) 711 pixOffset += paletted.Stride 712 case cbTCA8: 713 copy(nrgba.Pix[pixOffset:], cdat) 714 pixOffset += nrgba.Stride 715 case cbG16: 716 if d.useTransparent { 717 ty := uint16(d.transparent[0])<<8 | uint16(d.transparent[1]) 718 for x := 0; x < width; x++ { 719 ycol := uint16(cdat[2*x+0])<<8 | uint16(cdat[2*x+1]) 720 acol := uint16(0xffff) 721 if ycol == ty { 722 acol = 0x0000 723 } 724 nrgba64.SetNRGBA64(x, y, color.NRGBA64{ycol, ycol, ycol, acol}) 725 } 726 } else { 727 for x := 0; x < width; x++ { 728 ycol := uint16(cdat[2*x+0])<<8 | uint16(cdat[2*x+1]) 729 gray16.SetGray16(x, y, color.Gray16{ycol}) 730 } 731 } 732 case cbGA16: 733 for x := 0; x < width; x++ { 734 ycol := uint16(cdat[4*x+0])<<8 | uint16(cdat[4*x+1]) 735 acol := uint16(cdat[4*x+2])<<8 | uint16(cdat[4*x+3]) 736 nrgba64.SetNRGBA64(x, y, color.NRGBA64{ycol, ycol, ycol, acol}) 737 } 738 case cbTC16: 739 if d.useTransparent { 740 tr := uint16(d.transparent[0])<<8 | uint16(d.transparent[1]) 741 tg := uint16(d.transparent[2])<<8 | uint16(d.transparent[3]) 742 tb := uint16(d.transparent[4])<<8 | uint16(d.transparent[5]) 743 for x := 0; x < width; x++ { 744 rcol := uint16(cdat[6*x+0])<<8 | uint16(cdat[6*x+1]) 745 gcol := uint16(cdat[6*x+2])<<8 | uint16(cdat[6*x+3]) 746 bcol := uint16(cdat[6*x+4])<<8 | uint16(cdat[6*x+5]) 747 acol := uint16(0xffff) 748 if rcol == tr && gcol == tg && bcol == tb { 749 acol = 0x0000 750 } 751 nrgba64.SetNRGBA64(x, y, color.NRGBA64{rcol, gcol, bcol, acol}) 752 } 753 } else { 754 for x := 0; x < width; x++ { 755 rcol := uint16(cdat[6*x+0])<<8 | uint16(cdat[6*x+1]) 756 gcol := uint16(cdat[6*x+2])<<8 | uint16(cdat[6*x+3]) 757 bcol := uint16(cdat[6*x+4])<<8 | uint16(cdat[6*x+5]) 758 rgba64.SetRGBA64(x, y, color.RGBA64{rcol, gcol, bcol, 0xffff}) 759 } 760 } 761 case cbTCA16: 762 for x := 0; x < width; x++ { 763 rcol := uint16(cdat[8*x+0])<<8 | uint16(cdat[8*x+1]) 764 gcol := uint16(cdat[8*x+2])<<8 | uint16(cdat[8*x+3]) 765 bcol := uint16(cdat[8*x+4])<<8 | uint16(cdat[8*x+5]) 766 acol := uint16(cdat[8*x+6])<<8 | uint16(cdat[8*x+7]) 767 nrgba64.SetNRGBA64(x, y, color.NRGBA64{rcol, gcol, bcol, acol}) 768 } 769 } 770 771 // The current row for y is the previous row for y+1. 772 pr, cr = cr, pr 773 } 774 775 return img, nil 776 } 777 778 // mergePassInto merges a single pass into a full sized image. 779 func (d *decoder) mergePassInto(dst image.Image, src image.Image, pass int) { 780 p := interlacing[pass] 781 var ( 782 srcPix []uint8 783 dstPix []uint8 784 stride int 785 rect image.Rectangle 786 bytesPerPixel int 787 ) 788 switch target := dst.(type) { 789 case *image.Alpha: 790 srcPix = src.(*image.Alpha).Pix 791 dstPix, stride, rect = target.Pix, target.Stride, target.Rect 792 bytesPerPixel = 1 793 case *image.Alpha16: 794 srcPix = src.(*image.Alpha16).Pix 795 dstPix, stride, rect = target.Pix, target.Stride, target.Rect 796 bytesPerPixel = 2 797 case *image.Gray: 798 srcPix = src.(*image.Gray).Pix 799 dstPix, stride, rect = target.Pix, target.Stride, target.Rect 800 bytesPerPixel = 1 801 case *image.Gray16: 802 srcPix = src.(*image.Gray16).Pix 803 dstPix, stride, rect = target.Pix, target.Stride, target.Rect 804 bytesPerPixel = 2 805 case *image.NRGBA: 806 srcPix = src.(*image.NRGBA).Pix 807 dstPix, stride, rect = target.Pix, target.Stride, target.Rect 808 bytesPerPixel = 4 809 case *image.NRGBA64: 810 srcPix = src.(*image.NRGBA64).Pix 811 dstPix, stride, rect = target.Pix, target.Stride, target.Rect 812 bytesPerPixel = 8 813 case *image.Paletted: 814 srcPix = src.(*image.Paletted).Pix 815 dstPix, stride, rect = target.Pix, target.Stride, target.Rect 816 bytesPerPixel = 1 817 case *image.RGBA: 818 srcPix = src.(*image.RGBA).Pix 819 dstPix, stride, rect = target.Pix, target.Stride, target.Rect 820 bytesPerPixel = 4 821 case *image.RGBA64: 822 srcPix = src.(*image.RGBA64).Pix 823 dstPix, stride, rect = target.Pix, target.Stride, target.Rect 824 bytesPerPixel = 8 825 } 826 s, bounds := 0, src.Bounds() 827 for y := bounds.Min.Y; y < bounds.Max.Y; y++ { 828 dBase := (y*p.yFactor+p.yOffset-rect.Min.Y)*stride + (p.xOffset-rect.Min.X)*bytesPerPixel 829 for x := bounds.Min.X; x < bounds.Max.X; x++ { 830 d := dBase + x*p.xFactor*bytesPerPixel 831 copy(dstPix[d:], srcPix[s:s+bytesPerPixel]) 832 s += bytesPerPixel 833 } 834 } 835 } 836 837 func (d *decoder) parseIDAT(length uint32) (err error) { 838 d.idatLength = length 839 d.img, err = d.decode() 840 if err != nil { 841 return err 842 } 843 return d.verifyChecksum() 844 } 845 846 func (d *decoder) parseIEND(length uint32) error { 847 if length != 0 { 848 return FormatError("bad IEND length") 849 } 850 return d.verifyChecksum() 851 } 852 853 func (d *decoder) parseChunk() error { 854 // Read the length and chunk type. 855 n, err := io.ReadFull(d.r, d.tmp[:8]) 856 if err != nil { 857 return err 858 } 859 length := binary.BigEndian.Uint32(d.tmp[:4]) 860 d.crc.Reset() 861 d.crc.Write(d.tmp[4:8]) 862 863 // Read the chunk data. 864 switch string(d.tmp[4:8]) { 865 case "IHDR": 866 if d.stage != dsStart { 867 return chunkOrderError 868 } 869 d.stage = dsSeenIHDR 870 return d.parseIHDR(length) 871 case "PLTE": 872 if d.stage != dsSeenIHDR { 873 return chunkOrderError 874 } 875 d.stage = dsSeenPLTE 876 return d.parsePLTE(length) 877 case "tRNS": 878 if cbPaletted(d.cb) { 879 if d.stage != dsSeenPLTE { 880 return chunkOrderError 881 } 882 } else if d.stage != dsSeenIHDR { 883 return chunkOrderError 884 } 885 d.stage = dsSeentRNS 886 return d.parsetRNS(length) 887 case "IDAT": 888 if d.stage < dsSeenIHDR || d.stage > dsSeenIDAT || (d.stage == dsSeenIHDR && cbPaletted(d.cb)) { 889 return chunkOrderError 890 } else if d.stage == dsSeenIDAT { 891 // Ignore trailing zero-length or garbage IDAT chunks. 892 // 893 // This does not affect valid PNG images that contain multiple IDAT 894 // chunks, since the first call to parseIDAT below will consume all 895 // consecutive IDAT chunks required for decoding the image. 896 break 897 } 898 d.stage = dsSeenIDAT 899 return d.parseIDAT(length) 900 case "IEND": 901 if d.stage != dsSeenIDAT { 902 return chunkOrderError 903 } 904 d.stage = dsSeenIEND 905 return d.parseIEND(length) 906 } 907 if length > 0x7fffffff { 908 return FormatError(fmt.Sprintf("Bad chunk length: %d", length)) 909 } 910 // Ignore this chunk (of a known length). 911 var ignored [4096]byte 912 for length > 0 { 913 n, err = io.ReadFull(d.r, ignored[:min(len(ignored), int(length))]) 914 if err != nil { 915 return err 916 } 917 d.crc.Write(ignored[:n]) 918 length -= uint32(n) 919 } 920 return d.verifyChecksum() 921 } 922 923 func (d *decoder) verifyChecksum() error { 924 if _, err := io.ReadFull(d.r, d.tmp[:4]); err != nil { 925 return err 926 } 927 if binary.BigEndian.Uint32(d.tmp[:4]) != d.crc.Sum32() { 928 return FormatError("invalid checksum") 929 } 930 return nil 931 } 932 933 func (d *decoder) checkHeader() error { 934 _, err := io.ReadFull(d.r, d.tmp[:len(pngHeader)]) 935 if err != nil { 936 return err 937 } 938 if string(d.tmp[:len(pngHeader)]) != pngHeader { 939 return FormatError("not a PNG file") 940 } 941 return nil 942 } 943 944 // Decode reads a PNG image from r and returns it as an image.Image. 945 // The type of Image returned depends on the PNG contents. 946 func Decode(r io.Reader) (image.Image, error) { 947 d := &decoder{ 948 r: r, 949 crc: crc32.NewIEEE(), 950 } 951 if err := d.checkHeader(); err != nil { 952 if err == io.EOF { 953 err = io.ErrUnexpectedEOF 954 } 955 return nil, err 956 } 957 for d.stage != dsSeenIEND { 958 if err := d.parseChunk(); err != nil { 959 if err == io.EOF { 960 err = io.ErrUnexpectedEOF 961 } 962 return nil, err 963 } 964 } 965 return d.img, nil 966 } 967 968 // DecodeConfig returns the color model and dimensions of a PNG image without 969 // decoding the entire image. 970 func DecodeConfig(r io.Reader) (image.Config, error) { 971 d := &decoder{ 972 r: r, 973 crc: crc32.NewIEEE(), 974 } 975 if err := d.checkHeader(); err != nil { 976 if err == io.EOF { 977 err = io.ErrUnexpectedEOF 978 } 979 return image.Config{}, err 980 } 981 for { 982 if err := d.parseChunk(); err != nil { 983 if err == io.EOF { 984 err = io.ErrUnexpectedEOF 985 } 986 return image.Config{}, err 987 } 988 paletted := cbPaletted(d.cb) 989 if d.stage == dsSeenIHDR && !paletted { 990 break 991 } 992 if d.stage == dsSeenPLTE && paletted { 993 break 994 } 995 } 996 var cm color.Model 997 switch d.cb { 998 case cbG1, cbG2, cbG4, cbG8: 999 cm = color.GrayModel 1000 case cbGA8: 1001 cm = color.NRGBAModel 1002 case cbTC8: 1003 cm = color.RGBAModel 1004 case cbP1, cbP2, cbP4, cbP8: 1005 cm = d.palette 1006 case cbTCA8: 1007 cm = color.NRGBAModel 1008 case cbG16: 1009 cm = color.Gray16Model 1010 case cbGA16: 1011 cm = color.NRGBA64Model 1012 case cbTC16: 1013 cm = color.RGBA64Model 1014 case cbTCA16: 1015 cm = color.NRGBA64Model 1016 } 1017 return image.Config{ 1018 ColorModel: cm, 1019 Width: d.width, 1020 Height: d.height, 1021 }, nil 1022 } 1023 1024 func init() { 1025 image.RegisterFormat("png", pngHeader, Decode, DecodeConfig) 1026 }