github.com/kdevb0x/go@v0.0.0-20180115030120-39687051e9e7/src/image/gif/reader.go (about) 1 // Copyright 2011 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 gif implements a GIF image decoder and encoder. 6 // 7 // The GIF specification is at http://www.w3.org/Graphics/GIF/spec-gif89a.txt. 8 package gif 9 10 import ( 11 "bufio" 12 "compress/lzw" 13 "errors" 14 "fmt" 15 "image" 16 "image/color" 17 "io" 18 ) 19 20 var ( 21 errNotEnough = errors.New("gif: not enough image data") 22 errTooMuch = errors.New("gif: too much image data") 23 errBadPixel = errors.New("gif: invalid pixel value") 24 ) 25 26 // If the io.Reader does not also have ReadByte, then decode will introduce its own buffering. 27 type reader interface { 28 io.Reader 29 io.ByteReader 30 } 31 32 // Masks etc. 33 const ( 34 // Fields. 35 fColorTable = 1 << 7 36 fInterlace = 1 << 6 37 fColorTableBitsMask = 7 38 39 // Graphic control flags. 40 gcTransparentColorSet = 1 << 0 41 gcDisposalMethodMask = 7 << 2 42 ) 43 44 // Disposal Methods. 45 const ( 46 DisposalNone = 0x01 47 DisposalBackground = 0x02 48 DisposalPrevious = 0x03 49 ) 50 51 // Section indicators. 52 const ( 53 sExtension = 0x21 54 sImageDescriptor = 0x2C 55 sTrailer = 0x3B 56 ) 57 58 // Extensions. 59 const ( 60 eText = 0x01 // Plain Text 61 eGraphicControl = 0xF9 // Graphic Control 62 eComment = 0xFE // Comment 63 eApplication = 0xFF // Application 64 ) 65 66 func readFull(r io.Reader, b []byte) error { 67 _, err := io.ReadFull(r, b) 68 if err == io.EOF { 69 err = io.ErrUnexpectedEOF 70 } 71 return err 72 } 73 74 func readByte(r io.ByteReader) (byte, error) { 75 b, err := r.ReadByte() 76 if err == io.EOF { 77 err = io.ErrUnexpectedEOF 78 } 79 return b, err 80 } 81 82 // decoder is the type used to decode a GIF file. 83 type decoder struct { 84 r reader 85 86 // From header. 87 vers string 88 width int 89 height int 90 loopCount int 91 delayTime int 92 backgroundIndex byte 93 disposalMethod byte 94 95 // From image descriptor. 96 imageFields byte 97 98 // From graphics control. 99 transparentIndex byte 100 hasTransparentIndex bool 101 102 // Computed. 103 globalColorTable color.Palette 104 105 // Used when decoding. 106 delay []int 107 disposal []byte 108 image []*image.Paletted 109 tmp [1024]byte // must be at least 768 so we can read color table 110 } 111 112 // blockReader parses the block structure of GIF image data, which comprises 113 // (n, (n bytes)) blocks, with 1 <= n <= 255. It is the reader given to the 114 // LZW decoder, which is thus immune to the blocking. After the LZW decoder 115 // completes, there will be a 0-byte block remaining (0, ()), which is 116 // consumed when checking that the blockReader is exhausted. 117 // 118 // To avoid the allocation of a bufio.Reader for the lzw Reader, blockReader 119 // implements io.ReadByte and buffers blocks into the decoder's "tmp" buffer. 120 type blockReader struct { 121 d *decoder 122 i, j uint8 // d.tmp[i:j] contains the buffered bytes 123 err error 124 } 125 126 func (b *blockReader) fill() { 127 if b.err != nil { 128 return 129 } 130 b.j, b.err = readByte(b.d.r) 131 if b.j == 0 && b.err == nil { 132 b.err = io.EOF 133 } 134 if b.err != nil { 135 return 136 } 137 138 b.i = 0 139 b.err = readFull(b.d.r, b.d.tmp[:b.j]) 140 if b.err != nil { 141 b.j = 0 142 } 143 } 144 145 func (b *blockReader) ReadByte() (byte, error) { 146 if b.i == b.j { 147 b.fill() 148 if b.err != nil { 149 return 0, b.err 150 } 151 } 152 153 c := b.d.tmp[b.i] 154 b.i++ 155 return c, nil 156 } 157 158 // blockReader must implement io.Reader, but its Read shouldn't ever actually 159 // be called in practice. The compress/lzw package will only call ReadByte. 160 func (b *blockReader) Read(p []byte) (int, error) { 161 if len(p) == 0 || b.err != nil { 162 return 0, b.err 163 } 164 if b.i == b.j { 165 b.fill() 166 if b.err != nil { 167 return 0, b.err 168 } 169 } 170 171 n := copy(p, b.d.tmp[b.i:b.j]) 172 b.i += uint8(n) 173 return n, nil 174 } 175 176 // close primarily detects whether or not a block terminator was encountered 177 // after reading a sequence of data sub-blocks. It allows at most one trailing 178 // sub-block worth of data. I.e., if some number of bytes exist in one sub-block 179 // following the end of LZW data, the very next sub-block must be the block 180 // terminator. If the very end of LZW data happened to fill one sub-block, at 181 // most one more sub-block of length 1 may exist before the block-terminator. 182 // These accomodations allow us to support GIFs created by less strict encoders. 183 // See https://golang.org/issue/16146. 184 func (b *blockReader) close() error { 185 if b.err == io.EOF { 186 // A clean block-sequence terminator was encountered while reading. 187 return nil 188 } else if b.err != nil { 189 // Some other error was encountered while reading. 190 return b.err 191 } 192 193 if b.i == b.j { 194 // We reached the end of a sub block reading LZW data. We'll allow at 195 // most one more sub block of data with a length of 1 byte. 196 b.fill() 197 if b.err == io.EOF { 198 return nil 199 } else if b.err != nil { 200 return b.err 201 } else if b.j > 1 { 202 return errTooMuch 203 } 204 } 205 206 // Part of a sub-block remains buffered. We expect that the next attempt to 207 // buffer a sub-block will reach the block terminator. 208 b.fill() 209 if b.err == io.EOF { 210 return nil 211 } else if b.err != nil { 212 return b.err 213 } 214 215 return errTooMuch 216 } 217 218 // decode reads a GIF image from r and stores the result in d. 219 func (d *decoder) decode(r io.Reader, configOnly, keepAllFrames bool) error { 220 // Add buffering if r does not provide ReadByte. 221 if rr, ok := r.(reader); ok { 222 d.r = rr 223 } else { 224 d.r = bufio.NewReader(r) 225 } 226 227 err := d.readHeaderAndScreenDescriptor() 228 if err != nil { 229 return err 230 } 231 if configOnly { 232 return nil 233 } 234 235 for { 236 c, err := readByte(d.r) 237 if err != nil { 238 return fmt.Errorf("gif: reading frames: %v", err) 239 } 240 switch c { 241 case sExtension: 242 if err = d.readExtension(); err != nil { 243 return err 244 } 245 246 case sImageDescriptor: 247 if err = d.readImageDescriptor(keepAllFrames); err != nil { 248 return err 249 } 250 251 case sTrailer: 252 if len(d.image) == 0 { 253 return fmt.Errorf("gif: missing image data") 254 } 255 return nil 256 257 default: 258 return fmt.Errorf("gif: unknown block type: 0x%.2x", c) 259 } 260 } 261 } 262 263 func (d *decoder) readHeaderAndScreenDescriptor() error { 264 err := readFull(d.r, d.tmp[:13]) 265 if err != nil { 266 return fmt.Errorf("gif: reading header: %v", err) 267 } 268 d.vers = string(d.tmp[:6]) 269 if d.vers != "GIF87a" && d.vers != "GIF89a" { 270 return fmt.Errorf("gif: can't recognize format %q", d.vers) 271 } 272 d.width = int(d.tmp[6]) + int(d.tmp[7])<<8 273 d.height = int(d.tmp[8]) + int(d.tmp[9])<<8 274 if fields := d.tmp[10]; fields&fColorTable != 0 { 275 d.backgroundIndex = d.tmp[11] 276 // readColorTable overwrites the contents of d.tmp, but that's OK. 277 if d.globalColorTable, err = d.readColorTable(fields); err != nil { 278 return err 279 } 280 } 281 // d.tmp[12] is the Pixel Aspect Ratio, which is ignored. 282 return nil 283 } 284 285 func (d *decoder) readColorTable(fields byte) (color.Palette, error) { 286 n := 1 << (1 + uint(fields&fColorTableBitsMask)) 287 err := readFull(d.r, d.tmp[:3*n]) 288 if err != nil { 289 return nil, fmt.Errorf("gif: reading color table: %s", err) 290 } 291 j, p := 0, make(color.Palette, n) 292 for i := range p { 293 p[i] = color.RGBA{d.tmp[j+0], d.tmp[j+1], d.tmp[j+2], 0xFF} 294 j += 3 295 } 296 return p, nil 297 } 298 299 func (d *decoder) readExtension() error { 300 extension, err := readByte(d.r) 301 if err != nil { 302 return fmt.Errorf("gif: reading extension: %v", err) 303 } 304 size := 0 305 switch extension { 306 case eText: 307 size = 13 308 case eGraphicControl: 309 return d.readGraphicControl() 310 case eComment: 311 // nothing to do but read the data. 312 case eApplication: 313 b, err := readByte(d.r) 314 if err != nil { 315 return fmt.Errorf("gif: reading extension: %v", err) 316 } 317 // The spec requires size be 11, but Adobe sometimes uses 10. 318 size = int(b) 319 default: 320 return fmt.Errorf("gif: unknown extension 0x%.2x", extension) 321 } 322 if size > 0 { 323 if err := readFull(d.r, d.tmp[:size]); err != nil { 324 return fmt.Errorf("gif: reading extension: %v", err) 325 } 326 } 327 328 // Application Extension with "NETSCAPE2.0" as string and 1 in data means 329 // this extension defines a loop count. 330 if extension == eApplication && string(d.tmp[:size]) == "NETSCAPE2.0" { 331 n, err := d.readBlock() 332 if err != nil { 333 return fmt.Errorf("gif: reading extension: %v", err) 334 } 335 if n == 0 { 336 return nil 337 } 338 if n == 3 && d.tmp[0] == 1 { 339 d.loopCount = int(d.tmp[1]) | int(d.tmp[2])<<8 340 } 341 } 342 for { 343 n, err := d.readBlock() 344 if err != nil { 345 return fmt.Errorf("gif: reading extension: %v", err) 346 } 347 if n == 0 { 348 return nil 349 } 350 } 351 } 352 353 func (d *decoder) readGraphicControl() error { 354 if err := readFull(d.r, d.tmp[:6]); err != nil { 355 return fmt.Errorf("gif: can't read graphic control: %s", err) 356 } 357 if d.tmp[0] != 4 { 358 return fmt.Errorf("gif: invalid graphic control extension block size: %d", d.tmp[0]) 359 } 360 flags := d.tmp[1] 361 d.disposalMethod = (flags & gcDisposalMethodMask) >> 2 362 d.delayTime = int(d.tmp[2]) | int(d.tmp[3])<<8 363 if flags&gcTransparentColorSet != 0 { 364 d.transparentIndex = d.tmp[4] 365 d.hasTransparentIndex = true 366 } 367 if d.tmp[5] != 0 { 368 return fmt.Errorf("gif: invalid graphic control extension block terminator: %d", d.tmp[5]) 369 } 370 return nil 371 } 372 373 func (d *decoder) readImageDescriptor(keepAllFrames bool) error { 374 m, err := d.newImageFromDescriptor() 375 if err != nil { 376 return err 377 } 378 useLocalColorTable := d.imageFields&fColorTable != 0 379 if useLocalColorTable { 380 m.Palette, err = d.readColorTable(d.imageFields) 381 if err != nil { 382 return err 383 } 384 } else { 385 if d.globalColorTable == nil { 386 return errors.New("gif: no color table") 387 } 388 m.Palette = d.globalColorTable 389 } 390 if d.hasTransparentIndex { 391 if !useLocalColorTable { 392 // Clone the global color table. 393 m.Palette = append(color.Palette(nil), d.globalColorTable...) 394 } 395 if ti := int(d.transparentIndex); ti < len(m.Palette) { 396 m.Palette[ti] = color.RGBA{} 397 } else { 398 // The transparentIndex is out of range, which is an error 399 // according to the spec, but Firefox and Google Chrome 400 // seem OK with this, so we enlarge the palette with 401 // transparent colors. See golang.org/issue/15059. 402 p := make(color.Palette, ti+1) 403 copy(p, m.Palette) 404 for i := len(m.Palette); i < len(p); i++ { 405 p[i] = color.RGBA{} 406 } 407 m.Palette = p 408 } 409 } 410 litWidth, err := readByte(d.r) 411 if err != nil { 412 return fmt.Errorf("gif: reading image data: %v", err) 413 } 414 if litWidth < 2 || litWidth > 8 { 415 return fmt.Errorf("gif: pixel size in decode out of range: %d", litWidth) 416 } 417 // A wonderfully Go-like piece of magic. 418 br := &blockReader{d: d} 419 lzwr := lzw.NewReader(br, lzw.LSB, int(litWidth)) 420 defer lzwr.Close() 421 if err = readFull(lzwr, m.Pix); err != nil { 422 if err != io.ErrUnexpectedEOF { 423 return fmt.Errorf("gif: reading image data: %v", err) 424 } 425 return errNotEnough 426 } 427 // In theory, both lzwr and br should be exhausted. Reading from them 428 // should yield (0, io.EOF). 429 // 430 // The spec (Appendix F - Compression), says that "An End of 431 // Information code... must be the last code output by the encoder 432 // for an image". In practice, though, giflib (a widely used C 433 // library) does not enforce this, so we also accept lzwr returning 434 // io.ErrUnexpectedEOF (meaning that the encoded stream hit io.EOF 435 // before the LZW decoder saw an explicit end code), provided that 436 // the io.ReadFull call above successfully read len(m.Pix) bytes. 437 // See https://golang.org/issue/9856 for an example GIF. 438 if n, err := lzwr.Read(d.tmp[256:257]); n != 0 || (err != io.EOF && err != io.ErrUnexpectedEOF) { 439 if err != nil { 440 return fmt.Errorf("gif: reading image data: %v", err) 441 } 442 return errTooMuch 443 } 444 445 // In practice, some GIFs have an extra byte in the data sub-block 446 // stream, which we ignore. See https://golang.org/issue/16146. 447 if err := br.close(); err == errTooMuch { 448 return errTooMuch 449 } else if err != nil { 450 return fmt.Errorf("gif: reading image data: %v", err) 451 } 452 453 // Check that the color indexes are inside the palette. 454 if len(m.Palette) < 256 { 455 for _, pixel := range m.Pix { 456 if int(pixel) >= len(m.Palette) { 457 return errBadPixel 458 } 459 } 460 } 461 462 // Undo the interlacing if necessary. 463 if d.imageFields&fInterlace != 0 { 464 uninterlace(m) 465 } 466 467 if keepAllFrames || len(d.image) == 0 { 468 d.image = append(d.image, m) 469 d.delay = append(d.delay, d.delayTime) 470 d.disposal = append(d.disposal, d.disposalMethod) 471 } 472 // The GIF89a spec, Section 23 (Graphic Control Extension) says: 473 // "The scope of this extension is the first graphic rendering block 474 // to follow." We therefore reset the GCE fields to zero. 475 d.delayTime = 0 476 d.hasTransparentIndex = false 477 return nil 478 } 479 480 func (d *decoder) newImageFromDescriptor() (*image.Paletted, error) { 481 if err := readFull(d.r, d.tmp[:9]); err != nil { 482 return nil, fmt.Errorf("gif: can't read image descriptor: %s", err) 483 } 484 left := int(d.tmp[0]) + int(d.tmp[1])<<8 485 top := int(d.tmp[2]) + int(d.tmp[3])<<8 486 width := int(d.tmp[4]) + int(d.tmp[5])<<8 487 height := int(d.tmp[6]) + int(d.tmp[7])<<8 488 d.imageFields = d.tmp[8] 489 490 // The GIF89a spec, Section 20 (Image Descriptor) says: "Each image must 491 // fit within the boundaries of the Logical Screen, as defined in the 492 // Logical Screen Descriptor." 493 // 494 // This is conceptually similar to testing 495 // frameBounds := image.Rect(left, top, left+width, top+height) 496 // imageBounds := image.Rect(0, 0, d.width, d.height) 497 // if !frameBounds.In(imageBounds) { etc } 498 // but the semantics of the Go image.Rectangle type is that r.In(s) is true 499 // whenever r is an empty rectangle, even if r.Min.X > s.Max.X. Here, we 500 // want something stricter. 501 // 502 // Note that, by construction, left >= 0 && top >= 0, so we only have to 503 // explicitly compare frameBounds.Max (left+width, top+height) against 504 // imageBounds.Max (d.width, d.height) and not frameBounds.Min (left, top) 505 // against imageBounds.Min (0, 0). 506 if left+width > d.width || top+height > d.height { 507 return nil, errors.New("gif: frame bounds larger than image bounds") 508 } 509 return image.NewPaletted(image.Rectangle{ 510 Min: image.Point{left, top}, 511 Max: image.Point{left + width, top + height}, 512 }, nil), nil 513 } 514 515 func (d *decoder) readBlock() (int, error) { 516 n, err := readByte(d.r) 517 if n == 0 || err != nil { 518 return 0, err 519 } 520 if err := readFull(d.r, d.tmp[:n]); err != nil { 521 return 0, err 522 } 523 return int(n), nil 524 } 525 526 // interlaceScan defines the ordering for a pass of the interlace algorithm. 527 type interlaceScan struct { 528 skip, start int 529 } 530 531 // interlacing represents the set of scans in an interlaced GIF image. 532 var interlacing = []interlaceScan{ 533 {8, 0}, // Group 1 : Every 8th. row, starting with row 0. 534 {8, 4}, // Group 2 : Every 8th. row, starting with row 4. 535 {4, 2}, // Group 3 : Every 4th. row, starting with row 2. 536 {2, 1}, // Group 4 : Every 2nd. row, starting with row 1. 537 } 538 539 // uninterlace rearranges the pixels in m to account for interlaced input. 540 func uninterlace(m *image.Paletted) { 541 var nPix []uint8 542 dx := m.Bounds().Dx() 543 dy := m.Bounds().Dy() 544 nPix = make([]uint8, dx*dy) 545 offset := 0 // steps through the input by sequential scan lines. 546 for _, pass := range interlacing { 547 nOffset := pass.start * dx // steps through the output as defined by pass. 548 for y := pass.start; y < dy; y += pass.skip { 549 copy(nPix[nOffset:nOffset+dx], m.Pix[offset:offset+dx]) 550 offset += dx 551 nOffset += dx * pass.skip 552 } 553 } 554 m.Pix = nPix 555 } 556 557 // Decode reads a GIF image from r and returns the first embedded 558 // image as an image.Image. 559 func Decode(r io.Reader) (image.Image, error) { 560 var d decoder 561 if err := d.decode(r, false, false); err != nil { 562 return nil, err 563 } 564 return d.image[0], nil 565 } 566 567 // GIF represents the possibly multiple images stored in a GIF file. 568 type GIF struct { 569 Image []*image.Paletted // The successive images. 570 Delay []int // The successive delay times, one per frame, in 100ths of a second. 571 LoopCount int // The loop count. 572 // Disposal is the successive disposal methods, one per frame. For 573 // backwards compatibility, a nil Disposal is valid to pass to EncodeAll, 574 // and implies that each frame's disposal method is 0 (no disposal 575 // specified). 576 Disposal []byte 577 // Config is the global color table (palette), width and height. A nil or 578 // empty-color.Palette Config.ColorModel means that each frame has its own 579 // color table and there is no global color table. Each frame's bounds must 580 // be within the rectangle defined by the two points (0, 0) and 581 // (Config.Width, Config.Height). 582 // 583 // For backwards compatibility, a zero-valued Config is valid to pass to 584 // EncodeAll, and implies that the overall GIF's width and height equals 585 // the first frame's bounds' Rectangle.Max point. 586 Config image.Config 587 // BackgroundIndex is the background index in the global color table, for 588 // use with the DisposalBackground disposal method. 589 BackgroundIndex byte 590 } 591 592 // DecodeAll reads a GIF image from r and returns the sequential frames 593 // and timing information. 594 func DecodeAll(r io.Reader) (*GIF, error) { 595 var d decoder 596 if err := d.decode(r, false, true); err != nil { 597 return nil, err 598 } 599 gif := &GIF{ 600 Image: d.image, 601 LoopCount: d.loopCount, 602 Delay: d.delay, 603 Disposal: d.disposal, 604 Config: image.Config{ 605 ColorModel: d.globalColorTable, 606 Width: d.width, 607 Height: d.height, 608 }, 609 BackgroundIndex: d.backgroundIndex, 610 } 611 return gif, nil 612 } 613 614 // DecodeConfig returns the global color model and dimensions of a GIF image 615 // without decoding the entire image. 616 func DecodeConfig(r io.Reader) (image.Config, error) { 617 var d decoder 618 if err := d.decode(r, true, false); err != nil { 619 return image.Config{}, err 620 } 621 return image.Config{ 622 ColorModel: d.globalColorTable, 623 Width: d.width, 624 Height: d.height, 625 }, nil 626 } 627 628 func init() { 629 image.RegisterFormat("gif", "GIF8?a", Decode, DecodeConfig) 630 }