github.com/rakyll/go@v0.0.0-20170216000551-64c02460d703/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 // Both lzwr and br should be exhausted. Reading from them should 235 // 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 if n, err := br.Read(d.tmp[:1]); n != 0 || err != io.EOF { 252 if err != nil { 253 return fmt.Errorf("gif: reading image data: %v", err) 254 } 255 return errTooMuch 256 } 257 258 // Check that the color indexes are inside the palette. 259 if len(m.Palette) < 256 { 260 for _, pixel := range m.Pix { 261 if int(pixel) >= len(m.Palette) { 262 return errBadPixel 263 } 264 } 265 } 266 267 // Undo the interlacing if necessary. 268 if d.imageFields&fInterlace != 0 { 269 uninterlace(m) 270 } 271 272 d.image = append(d.image, m) 273 d.delay = append(d.delay, d.delayTime) 274 d.disposal = append(d.disposal, d.disposalMethod) 275 // The GIF89a spec, Section 23 (Graphic Control Extension) says: 276 // "The scope of this extension is the first graphic rendering block 277 // to follow." We therefore reset the GCE fields to zero. 278 d.delayTime = 0 279 d.hasTransparentIndex = false 280 281 case sTrailer: 282 if len(d.image) == 0 { 283 return fmt.Errorf("gif: missing image data") 284 } 285 return nil 286 287 default: 288 return fmt.Errorf("gif: unknown block type: 0x%.2x", c) 289 } 290 } 291 } 292 293 func (d *decoder) readHeaderAndScreenDescriptor() error { 294 err := readFull(d.r, d.tmp[:13]) 295 if err != nil { 296 return fmt.Errorf("gif: reading header: %v", err) 297 } 298 d.vers = string(d.tmp[:6]) 299 if d.vers != "GIF87a" && d.vers != "GIF89a" { 300 return fmt.Errorf("gif: can't recognize format %q", d.vers) 301 } 302 d.width = int(d.tmp[6]) + int(d.tmp[7])<<8 303 d.height = int(d.tmp[8]) + int(d.tmp[9])<<8 304 if fields := d.tmp[10]; fields&fColorTable != 0 { 305 d.backgroundIndex = d.tmp[11] 306 // readColorTable overwrites the contents of d.tmp, but that's OK. 307 if d.globalColorTable, err = d.readColorTable(fields); err != nil { 308 return err 309 } 310 } 311 // d.tmp[12] is the Pixel Aspect Ratio, which is ignored. 312 return nil 313 } 314 315 func (d *decoder) readColorTable(fields byte) (color.Palette, error) { 316 n := 1 << (1 + uint(fields&fColorTableBitsMask)) 317 err := readFull(d.r, d.tmp[:3*n]) 318 if err != nil { 319 return nil, fmt.Errorf("gif: reading color table: %s", err) 320 } 321 j, p := 0, make(color.Palette, n) 322 for i := range p { 323 p[i] = color.RGBA{d.tmp[j+0], d.tmp[j+1], d.tmp[j+2], 0xFF} 324 j += 3 325 } 326 return p, nil 327 } 328 329 func (d *decoder) readExtension() error { 330 extension, err := readByte(d.r) 331 if err != nil { 332 return fmt.Errorf("gif: reading extension: %v", err) 333 } 334 size := 0 335 switch extension { 336 case eText: 337 size = 13 338 case eGraphicControl: 339 return d.readGraphicControl() 340 case eComment: 341 // nothing to do but read the data. 342 case eApplication: 343 b, err := readByte(d.r) 344 if err != nil { 345 return fmt.Errorf("gif: reading extension: %v", err) 346 } 347 // The spec requires size be 11, but Adobe sometimes uses 10. 348 size = int(b) 349 default: 350 return fmt.Errorf("gif: unknown extension 0x%.2x", extension) 351 } 352 if size > 0 { 353 if err := readFull(d.r, d.tmp[:size]); err != nil { 354 return fmt.Errorf("gif: reading extension: %v", err) 355 } 356 } 357 358 // Application Extension with "NETSCAPE2.0" as string and 1 in data means 359 // this extension defines a loop count. 360 if extension == eApplication && string(d.tmp[:size]) == "NETSCAPE2.0" { 361 n, err := d.readBlock() 362 if err != nil { 363 return fmt.Errorf("gif: reading extension: %v", err) 364 } 365 if n == 0 { 366 return nil 367 } 368 if n == 3 && d.tmp[0] == 1 { 369 d.loopCount = int(d.tmp[1]) | int(d.tmp[2])<<8 370 } 371 } 372 for { 373 n, err := d.readBlock() 374 if err != nil { 375 return fmt.Errorf("gif: reading extension: %v", err) 376 } 377 if n == 0 { 378 return nil 379 } 380 } 381 } 382 383 func (d *decoder) readGraphicControl() error { 384 if err := readFull(d.r, d.tmp[:6]); err != nil { 385 return fmt.Errorf("gif: can't read graphic control: %s", err) 386 } 387 if d.tmp[0] != 4 { 388 return fmt.Errorf("gif: invalid graphic control extension block size: %d", d.tmp[0]) 389 } 390 flags := d.tmp[1] 391 d.disposalMethod = (flags & gcDisposalMethodMask) >> 2 392 d.delayTime = int(d.tmp[2]) | int(d.tmp[3])<<8 393 if flags&gcTransparentColorSet != 0 { 394 d.transparentIndex = d.tmp[4] 395 d.hasTransparentIndex = true 396 } 397 if d.tmp[5] != 0 { 398 return fmt.Errorf("gif: invalid graphic control extension block terminator: %d", d.tmp[5]) 399 } 400 return nil 401 } 402 403 func (d *decoder) newImageFromDescriptor() (*image.Paletted, error) { 404 if err := readFull(d.r, d.tmp[:9]); err != nil { 405 return nil, fmt.Errorf("gif: can't read image descriptor: %s", err) 406 } 407 left := int(d.tmp[0]) + int(d.tmp[1])<<8 408 top := int(d.tmp[2]) + int(d.tmp[3])<<8 409 width := int(d.tmp[4]) + int(d.tmp[5])<<8 410 height := int(d.tmp[6]) + int(d.tmp[7])<<8 411 d.imageFields = d.tmp[8] 412 413 // The GIF89a spec, Section 20 (Image Descriptor) says: "Each image must 414 // fit within the boundaries of the Logical Screen, as defined in the 415 // Logical Screen Descriptor." 416 // 417 // This is conceptually similar to testing 418 // frameBounds := image.Rect(left, top, left+width, top+height) 419 // imageBounds := image.Rect(0, 0, d.width, d.height) 420 // if !frameBounds.In(imageBounds) { etc } 421 // but the semantics of the Go image.Rectangle type is that r.In(s) is true 422 // whenever r is an empty rectangle, even if r.Min.X > s.Max.X. Here, we 423 // want something stricter. 424 // 425 // Note that, by construction, left >= 0 && top >= 0, so we only have to 426 // explicitly compare frameBounds.Max (left+width, top+height) against 427 // imageBounds.Max (d.width, d.height) and not frameBounds.Min (left, top) 428 // against imageBounds.Min (0, 0). 429 if left+width > d.width || top+height > d.height { 430 return nil, errors.New("gif: frame bounds larger than image bounds") 431 } 432 return image.NewPaletted(image.Rectangle{ 433 Min: image.Point{left, top}, 434 Max: image.Point{left + width, top + height}, 435 }, nil), nil 436 } 437 438 func (d *decoder) readBlock() (int, error) { 439 n, err := readByte(d.r) 440 if n == 0 || err != nil { 441 return 0, err 442 } 443 if err := readFull(d.r, d.tmp[:n]); err != nil { 444 return 0, err 445 } 446 return int(n), nil 447 } 448 449 // interlaceScan defines the ordering for a pass of the interlace algorithm. 450 type interlaceScan struct { 451 skip, start int 452 } 453 454 // interlacing represents the set of scans in an interlaced GIF image. 455 var interlacing = []interlaceScan{ 456 {8, 0}, // Group 1 : Every 8th. row, starting with row 0. 457 {8, 4}, // Group 2 : Every 8th. row, starting with row 4. 458 {4, 2}, // Group 3 : Every 4th. row, starting with row 2. 459 {2, 1}, // Group 4 : Every 2nd. row, starting with row 1. 460 } 461 462 // uninterlace rearranges the pixels in m to account for interlaced input. 463 func uninterlace(m *image.Paletted) { 464 var nPix []uint8 465 dx := m.Bounds().Dx() 466 dy := m.Bounds().Dy() 467 nPix = make([]uint8, dx*dy) 468 offset := 0 // steps through the input by sequential scan lines. 469 for _, pass := range interlacing { 470 nOffset := pass.start * dx // steps through the output as defined by pass. 471 for y := pass.start; y < dy; y += pass.skip { 472 copy(nPix[nOffset:nOffset+dx], m.Pix[offset:offset+dx]) 473 offset += dx 474 nOffset += dx * pass.skip 475 } 476 } 477 m.Pix = nPix 478 } 479 480 // Decode reads a GIF image from r and returns the first embedded 481 // image as an image.Image. 482 func Decode(r io.Reader) (image.Image, error) { 483 var d decoder 484 if err := d.decode(r, false); err != nil { 485 return nil, err 486 } 487 return d.image[0], nil 488 } 489 490 // GIF represents the possibly multiple images stored in a GIF file. 491 type GIF struct { 492 Image []*image.Paletted // The successive images. 493 Delay []int // The successive delay times, one per frame, in 100ths of a second. 494 LoopCount int // The loop count. 495 // Disposal is the successive disposal methods, one per frame. For 496 // backwards compatibility, a nil Disposal is valid to pass to EncodeAll, 497 // and implies that each frame's disposal method is 0 (no disposal 498 // specified). 499 Disposal []byte 500 // Config is the global color table (palette), width and height. A nil or 501 // empty-color.Palette Config.ColorModel means that each frame has its own 502 // color table and there is no global color table. Each frame's bounds must 503 // be within the rectangle defined by the two points (0, 0) and 504 // (Config.Width, Config.Height). 505 // 506 // For backwards compatibility, a zero-valued Config is valid to pass to 507 // EncodeAll, and implies that the overall GIF's width and height equals 508 // the first frame's bounds' Rectangle.Max point. 509 Config image.Config 510 // BackgroundIndex is the background index in the global color table, for 511 // use with the DisposalBackground disposal method. 512 BackgroundIndex byte 513 } 514 515 // DecodeAll reads a GIF image from r and returns the sequential frames 516 // and timing information. 517 func DecodeAll(r io.Reader) (*GIF, error) { 518 var d decoder 519 if err := d.decode(r, false); err != nil { 520 return nil, err 521 } 522 gif := &GIF{ 523 Image: d.image, 524 LoopCount: d.loopCount, 525 Delay: d.delay, 526 Disposal: d.disposal, 527 Config: image.Config{ 528 ColorModel: d.globalColorTable, 529 Width: d.width, 530 Height: d.height, 531 }, 532 BackgroundIndex: d.backgroundIndex, 533 } 534 return gif, nil 535 } 536 537 // DecodeConfig returns the global color model and dimensions of a GIF image 538 // without decoding the entire image. 539 func DecodeConfig(r io.Reader) (image.Config, error) { 540 var d decoder 541 if err := d.decode(r, true); err != nil { 542 return image.Config{}, err 543 } 544 return image.Config{ 545 ColorModel: d.globalColorTable, 546 Width: d.width, 547 Height: d.height, 548 }, nil 549 } 550 551 func init() { 552 image.RegisterFormat("gif", "GIF8?a", Decode, DecodeConfig) 553 }