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