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