github.com/mattn/go@v0.0.0-20171011075504-07f7db3ea99f/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 113 // comprises (n, (n bytes)) blocks, with 1 <= n <= 255. It is the 114 // reader given to the LZW decoder, which is thus immune to the 115 // blocking. After the LZW decoder completes, there will be a 0-byte 116 // block remaining (0, ()), which is consumed when checking that the 117 // blockReader is exhausted. 118 type blockReader struct { 119 r reader 120 slice []byte 121 err error 122 tmp [256]byte 123 } 124 125 func (b *blockReader) Read(p []byte) (int, error) { 126 if b.err != nil { 127 return 0, b.err 128 } 129 if len(p) == 0 { 130 return 0, nil 131 } 132 if len(b.slice) == 0 { 133 var blockLen uint8 134 blockLen, b.err = b.r.ReadByte() 135 if b.err != nil { 136 return 0, b.err 137 } 138 if blockLen == 0 { 139 b.err = io.EOF 140 return 0, b.err 141 } 142 b.slice = b.tmp[:blockLen] 143 if b.err = readFull(b.r, b.slice); b.err != nil { 144 return 0, b.err 145 } 146 } 147 n := copy(p, b.slice) 148 b.slice = b.slice[n:] 149 return n, nil 150 } 151 152 // decode reads a GIF image from r and stores the result in d. 153 func (d *decoder) decode(r io.Reader, configOnly bool) error { 154 // Add buffering if r does not provide ReadByte. 155 if rr, ok := r.(reader); ok { 156 d.r = rr 157 } else { 158 d.r = bufio.NewReader(r) 159 } 160 161 err := d.readHeaderAndScreenDescriptor() 162 if err != nil { 163 return err 164 } 165 if configOnly { 166 return nil 167 } 168 169 for { 170 c, err := readByte(d.r) 171 if err != nil { 172 return fmt.Errorf("gif: reading frames: %v", err) 173 } 174 switch c { 175 case sExtension: 176 if err = d.readExtension(); err != nil { 177 return err 178 } 179 180 case sImageDescriptor: 181 m, err := d.newImageFromDescriptor() 182 if err != nil { 183 return err 184 } 185 useLocalColorTable := d.imageFields&fColorTable != 0 186 if useLocalColorTable { 187 m.Palette, err = d.readColorTable(d.imageFields) 188 if err != nil { 189 return err 190 } 191 } else { 192 if d.globalColorTable == nil { 193 return errors.New("gif: no color table") 194 } 195 m.Palette = d.globalColorTable 196 } 197 if d.hasTransparentIndex { 198 if !useLocalColorTable { 199 // Clone the global color table. 200 m.Palette = append(color.Palette(nil), d.globalColorTable...) 201 } 202 if ti := int(d.transparentIndex); ti < len(m.Palette) { 203 m.Palette[ti] = color.RGBA{} 204 } else { 205 // The transparentIndex is out of range, which is an error 206 // according to the spec, but Firefox and Google Chrome 207 // seem OK with this, so we enlarge the palette with 208 // transparent colors. See golang.org/issue/15059. 209 p := make(color.Palette, ti+1) 210 copy(p, m.Palette) 211 for i := len(m.Palette); i < len(p); i++ { 212 p[i] = color.RGBA{} 213 } 214 m.Palette = p 215 } 216 } 217 litWidth, err := readByte(d.r) 218 if err != nil { 219 return fmt.Errorf("gif: reading image data: %v", err) 220 } 221 if litWidth < 2 || litWidth > 8 { 222 return fmt.Errorf("gif: pixel size in decode out of range: %d", litWidth) 223 } 224 // A wonderfully Go-like piece of magic. 225 br := &blockReader{r: d.r} 226 lzwr := lzw.NewReader(br, lzw.LSB, int(litWidth)) 227 defer lzwr.Close() 228 if err = readFull(lzwr, m.Pix); err != nil { 229 if err != io.ErrUnexpectedEOF { 230 return fmt.Errorf("gif: reading image data: %v", err) 231 } 232 return errNotEnough 233 } 234 // In theory, both lzwr and br should be exhausted. Reading from them 235 // should yield (0, io.EOF). 236 // 237 // The spec (Appendix F - Compression), says that "An End of 238 // Information code... must be the last code output by the encoder 239 // for an image". In practice, though, giflib (a widely used C 240 // library) does not enforce this, so we also accept lzwr returning 241 // io.ErrUnexpectedEOF (meaning that the encoded stream hit io.EOF 242 // before the LZW decoder saw an explicit end code), provided that 243 // the io.ReadFull call above successfully read len(m.Pix) bytes. 244 // See https://golang.org/issue/9856 for an example GIF. 245 if n, err := lzwr.Read(d.tmp[:1]); n != 0 || (err != io.EOF && err != io.ErrUnexpectedEOF) { 246 if err != nil { 247 return fmt.Errorf("gif: reading image data: %v", err) 248 } 249 return errTooMuch 250 } 251 252 // In practice, some GIFs have an extra byte in the data sub-block 253 // stream, which we ignore. See https://golang.org/issue/16146. 254 for nExtraBytes := 0; ; { 255 n, err := br.Read(d.tmp[:2]) 256 nExtraBytes += n 257 if nExtraBytes > 1 { 258 return errTooMuch 259 } 260 if err == io.EOF { 261 break 262 } 263 if err != nil { 264 return fmt.Errorf("gif: reading image data: %v", err) 265 } 266 } 267 268 // Check that the color indexes are inside the palette. 269 if len(m.Palette) < 256 { 270 for _, pixel := range m.Pix { 271 if int(pixel) >= len(m.Palette) { 272 return errBadPixel 273 } 274 } 275 } 276 277 // Undo the interlacing if necessary. 278 if d.imageFields&fInterlace != 0 { 279 uninterlace(m) 280 } 281 282 d.image = append(d.image, m) 283 d.delay = append(d.delay, d.delayTime) 284 d.disposal = append(d.disposal, d.disposalMethod) 285 // The GIF89a spec, Section 23 (Graphic Control Extension) says: 286 // "The scope of this extension is the first graphic rendering block 287 // to follow." We therefore reset the GCE fields to zero. 288 d.delayTime = 0 289 d.hasTransparentIndex = false 290 291 case sTrailer: 292 if len(d.image) == 0 { 293 return fmt.Errorf("gif: missing image data") 294 } 295 return nil 296 297 default: 298 return fmt.Errorf("gif: unknown block type: 0x%.2x", c) 299 } 300 } 301 } 302 303 func (d *decoder) readHeaderAndScreenDescriptor() error { 304 err := readFull(d.r, d.tmp[:13]) 305 if err != nil { 306 return fmt.Errorf("gif: reading header: %v", err) 307 } 308 d.vers = string(d.tmp[:6]) 309 if d.vers != "GIF87a" && d.vers != "GIF89a" { 310 return fmt.Errorf("gif: can't recognize format %q", d.vers) 311 } 312 d.width = int(d.tmp[6]) + int(d.tmp[7])<<8 313 d.height = int(d.tmp[8]) + int(d.tmp[9])<<8 314 if fields := d.tmp[10]; fields&fColorTable != 0 { 315 d.backgroundIndex = d.tmp[11] 316 // readColorTable overwrites the contents of d.tmp, but that's OK. 317 if d.globalColorTable, err = d.readColorTable(fields); err != nil { 318 return err 319 } 320 } 321 // d.tmp[12] is the Pixel Aspect Ratio, which is ignored. 322 return nil 323 } 324 325 func (d *decoder) readColorTable(fields byte) (color.Palette, error) { 326 n := 1 << (1 + uint(fields&fColorTableBitsMask)) 327 err := readFull(d.r, d.tmp[:3*n]) 328 if err != nil { 329 return nil, fmt.Errorf("gif: reading color table: %s", err) 330 } 331 j, p := 0, make(color.Palette, n) 332 for i := range p { 333 p[i] = color.RGBA{d.tmp[j+0], d.tmp[j+1], d.tmp[j+2], 0xFF} 334 j += 3 335 } 336 return p, nil 337 } 338 339 func (d *decoder) readExtension() error { 340 extension, err := readByte(d.r) 341 if err != nil { 342 return fmt.Errorf("gif: reading extension: %v", err) 343 } 344 size := 0 345 switch extension { 346 case eText: 347 size = 13 348 case eGraphicControl: 349 return d.readGraphicControl() 350 case eComment: 351 // nothing to do but read the data. 352 case eApplication: 353 b, err := readByte(d.r) 354 if err != nil { 355 return fmt.Errorf("gif: reading extension: %v", err) 356 } 357 // The spec requires size be 11, but Adobe sometimes uses 10. 358 size = int(b) 359 default: 360 return fmt.Errorf("gif: unknown extension 0x%.2x", extension) 361 } 362 if size > 0 { 363 if err := readFull(d.r, d.tmp[:size]); err != nil { 364 return fmt.Errorf("gif: reading extension: %v", err) 365 } 366 } 367 368 // Application Extension with "NETSCAPE2.0" as string and 1 in data means 369 // this extension defines a loop count. 370 if extension == eApplication && string(d.tmp[:size]) == "NETSCAPE2.0" { 371 n, err := d.readBlock() 372 if err != nil { 373 return fmt.Errorf("gif: reading extension: %v", err) 374 } 375 if n == 0 { 376 return nil 377 } 378 if n == 3 && d.tmp[0] == 1 { 379 d.loopCount = int(d.tmp[1]) | int(d.tmp[2])<<8 380 } 381 } 382 for { 383 n, err := d.readBlock() 384 if err != nil { 385 return fmt.Errorf("gif: reading extension: %v", err) 386 } 387 if n == 0 { 388 return nil 389 } 390 } 391 } 392 393 func (d *decoder) readGraphicControl() error { 394 if err := readFull(d.r, d.tmp[:6]); err != nil { 395 return fmt.Errorf("gif: can't read graphic control: %s", err) 396 } 397 if d.tmp[0] != 4 { 398 return fmt.Errorf("gif: invalid graphic control extension block size: %d", d.tmp[0]) 399 } 400 flags := d.tmp[1] 401 d.disposalMethod = (flags & gcDisposalMethodMask) >> 2 402 d.delayTime = int(d.tmp[2]) | int(d.tmp[3])<<8 403 if flags&gcTransparentColorSet != 0 { 404 d.transparentIndex = d.tmp[4] 405 d.hasTransparentIndex = true 406 } 407 if d.tmp[5] != 0 { 408 return fmt.Errorf("gif: invalid graphic control extension block terminator: %d", d.tmp[5]) 409 } 410 return nil 411 } 412 413 func (d *decoder) newImageFromDescriptor() (*image.Paletted, error) { 414 if err := readFull(d.r, d.tmp[:9]); err != nil { 415 return nil, fmt.Errorf("gif: can't read image descriptor: %s", err) 416 } 417 left := int(d.tmp[0]) + int(d.tmp[1])<<8 418 top := int(d.tmp[2]) + int(d.tmp[3])<<8 419 width := int(d.tmp[4]) + int(d.tmp[5])<<8 420 height := int(d.tmp[6]) + int(d.tmp[7])<<8 421 d.imageFields = d.tmp[8] 422 423 // The GIF89a spec, Section 20 (Image Descriptor) says: "Each image must 424 // fit within the boundaries of the Logical Screen, as defined in the 425 // Logical Screen Descriptor." 426 // 427 // This is conceptually similar to testing 428 // frameBounds := image.Rect(left, top, left+width, top+height) 429 // imageBounds := image.Rect(0, 0, d.width, d.height) 430 // if !frameBounds.In(imageBounds) { etc } 431 // but the semantics of the Go image.Rectangle type is that r.In(s) is true 432 // whenever r is an empty rectangle, even if r.Min.X > s.Max.X. Here, we 433 // want something stricter. 434 // 435 // Note that, by construction, left >= 0 && top >= 0, so we only have to 436 // explicitly compare frameBounds.Max (left+width, top+height) against 437 // imageBounds.Max (d.width, d.height) and not frameBounds.Min (left, top) 438 // against imageBounds.Min (0, 0). 439 if left+width > d.width || top+height > d.height { 440 return nil, errors.New("gif: frame bounds larger than image bounds") 441 } 442 return image.NewPaletted(image.Rectangle{ 443 Min: image.Point{left, top}, 444 Max: image.Point{left + width, top + height}, 445 }, nil), nil 446 } 447 448 func (d *decoder) readBlock() (int, error) { 449 n, err := readByte(d.r) 450 if n == 0 || err != nil { 451 return 0, err 452 } 453 if err := readFull(d.r, d.tmp[:n]); err != nil { 454 return 0, err 455 } 456 return int(n), nil 457 } 458 459 // interlaceScan defines the ordering for a pass of the interlace algorithm. 460 type interlaceScan struct { 461 skip, start int 462 } 463 464 // interlacing represents the set of scans in an interlaced GIF image. 465 var interlacing = []interlaceScan{ 466 {8, 0}, // Group 1 : Every 8th. row, starting with row 0. 467 {8, 4}, // Group 2 : Every 8th. row, starting with row 4. 468 {4, 2}, // Group 3 : Every 4th. row, starting with row 2. 469 {2, 1}, // Group 4 : Every 2nd. row, starting with row 1. 470 } 471 472 // uninterlace rearranges the pixels in m to account for interlaced input. 473 func uninterlace(m *image.Paletted) { 474 var nPix []uint8 475 dx := m.Bounds().Dx() 476 dy := m.Bounds().Dy() 477 nPix = make([]uint8, dx*dy) 478 offset := 0 // steps through the input by sequential scan lines. 479 for _, pass := range interlacing { 480 nOffset := pass.start * dx // steps through the output as defined by pass. 481 for y := pass.start; y < dy; y += pass.skip { 482 copy(nPix[nOffset:nOffset+dx], m.Pix[offset:offset+dx]) 483 offset += dx 484 nOffset += dx * pass.skip 485 } 486 } 487 m.Pix = nPix 488 } 489 490 // Decode reads a GIF image from r and returns the first embedded 491 // image as an image.Image. 492 func Decode(r io.Reader) (image.Image, error) { 493 var d decoder 494 if err := d.decode(r, false); err != nil { 495 return nil, err 496 } 497 return d.image[0], nil 498 } 499 500 // GIF represents the possibly multiple images stored in a GIF file. 501 type GIF struct { 502 Image []*image.Paletted // The successive images. 503 Delay []int // The successive delay times, one per frame, in 100ths of a second. 504 LoopCount int // The loop count. 505 // Disposal is the successive disposal methods, one per frame. For 506 // backwards compatibility, a nil Disposal is valid to pass to EncodeAll, 507 // and implies that each frame's disposal method is 0 (no disposal 508 // specified). 509 Disposal []byte 510 // Config is the global color table (palette), width and height. A nil or 511 // empty-color.Palette Config.ColorModel means that each frame has its own 512 // color table and there is no global color table. Each frame's bounds must 513 // be within the rectangle defined by the two points (0, 0) and 514 // (Config.Width, Config.Height). 515 // 516 // For backwards compatibility, a zero-valued Config is valid to pass to 517 // EncodeAll, and implies that the overall GIF's width and height equals 518 // the first frame's bounds' Rectangle.Max point. 519 Config image.Config 520 // BackgroundIndex is the background index in the global color table, for 521 // use with the DisposalBackground disposal method. 522 BackgroundIndex byte 523 } 524 525 // DecodeAll reads a GIF image from r and returns the sequential frames 526 // and timing information. 527 func DecodeAll(r io.Reader) (*GIF, error) { 528 var d decoder 529 if err := d.decode(r, false); err != nil { 530 return nil, err 531 } 532 gif := &GIF{ 533 Image: d.image, 534 LoopCount: d.loopCount, 535 Delay: d.delay, 536 Disposal: d.disposal, 537 Config: image.Config{ 538 ColorModel: d.globalColorTable, 539 Width: d.width, 540 Height: d.height, 541 }, 542 BackgroundIndex: d.backgroundIndex, 543 } 544 return gif, nil 545 } 546 547 // DecodeConfig returns the global color model and dimensions of a GIF image 548 // without decoding the entire image. 549 func DecodeConfig(r io.Reader) (image.Config, error) { 550 var d decoder 551 if err := d.decode(r, true); err != nil { 552 return image.Config{}, err 553 } 554 return image.Config{ 555 ColorModel: d.globalColorTable, 556 Width: d.width, 557 Height: d.height, 558 }, nil 559 } 560 561 func init() { 562 image.RegisterFormat("gif", "GIF8?a", Decode, DecodeConfig) 563 }