github.com/shijuvar/go@v0.0.0-20141209052335-e8f13700b70c/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 fColorMapFollows = 1 << 7 36 37 // Image fields. 38 ifLocalColorTable = 1 << 7 39 ifInterlace = 1 << 6 40 ifPixelSizeMask = 7 41 42 // Graphic control flags. 43 gcTransparentColorSet = 1 << 0 44 ) 45 46 // Section indicators. 47 const ( 48 sExtension = 0x21 49 sImageDescriptor = 0x2C 50 sTrailer = 0x3B 51 ) 52 53 // Extensions. 54 const ( 55 eText = 0x01 // Plain Text 56 eGraphicControl = 0xF9 // Graphic Control 57 eComment = 0xFE // Comment 58 eApplication = 0xFF // Application 59 ) 60 61 // decoder is the type used to decode a GIF file. 62 type decoder struct { 63 r reader 64 65 // From header. 66 vers string 67 width int 68 height int 69 flags byte 70 headerFields byte 71 backgroundIndex byte 72 loopCount int 73 delayTime int 74 75 // Unused from header. 76 aspect byte 77 78 // From image descriptor. 79 imageFields byte 80 81 // From graphics control. 82 transparentIndex byte 83 hasTransparentIndex bool 84 85 // Computed. 86 pixelSize uint 87 globalColorMap color.Palette 88 89 // Used when decoding. 90 delay []int 91 image []*image.Paletted 92 tmp [1024]byte // must be at least 768 so we can read color map 93 } 94 95 // blockReader parses the block structure of GIF image data, which 96 // comprises (n, (n bytes)) blocks, with 1 <= n <= 255. It is the 97 // reader given to the LZW decoder, which is thus immune to the 98 // blocking. After the LZW decoder completes, there will be a 0-byte 99 // block remaining (0, ()), which is consumed when checking that the 100 // blockReader is exhausted. 101 type blockReader struct { 102 r reader 103 slice []byte 104 err error 105 tmp [256]byte 106 } 107 108 func (b *blockReader) Read(p []byte) (int, error) { 109 if b.err != nil { 110 return 0, b.err 111 } 112 if len(p) == 0 { 113 return 0, nil 114 } 115 if len(b.slice) == 0 { 116 var blockLen uint8 117 blockLen, b.err = b.r.ReadByte() 118 if b.err != nil { 119 return 0, b.err 120 } 121 if blockLen == 0 { 122 b.err = io.EOF 123 return 0, b.err 124 } 125 b.slice = b.tmp[0:blockLen] 126 if _, b.err = io.ReadFull(b.r, b.slice); b.err != nil { 127 return 0, b.err 128 } 129 } 130 n := copy(p, b.slice) 131 b.slice = b.slice[n:] 132 return n, nil 133 } 134 135 // decode reads a GIF image from r and stores the result in d. 136 func (d *decoder) decode(r io.Reader, configOnly bool) error { 137 // Add buffering if r does not provide ReadByte. 138 if rr, ok := r.(reader); ok { 139 d.r = rr 140 } else { 141 d.r = bufio.NewReader(r) 142 } 143 144 err := d.readHeaderAndScreenDescriptor() 145 if err != nil { 146 return err 147 } 148 if configOnly { 149 return nil 150 } 151 152 if d.headerFields&fColorMapFollows != 0 { 153 if d.globalColorMap, err = d.readColorMap(); err != nil { 154 return err 155 } 156 } 157 158 for { 159 c, err := d.r.ReadByte() 160 if err != nil { 161 return err 162 } 163 switch c { 164 case sExtension: 165 if err = d.readExtension(); err != nil { 166 return err 167 } 168 169 case sImageDescriptor: 170 m, err := d.newImageFromDescriptor() 171 if err != nil { 172 return err 173 } 174 useLocalColorMap := d.imageFields&fColorMapFollows != 0 175 if useLocalColorMap { 176 m.Palette, err = d.readColorMap() 177 if err != nil { 178 return err 179 } 180 } else { 181 m.Palette = d.globalColorMap 182 } 183 if d.hasTransparentIndex && int(d.transparentIndex) < len(m.Palette) { 184 if !useLocalColorMap { 185 // Clone the global color map. 186 m.Palette = append(color.Palette(nil), d.globalColorMap...) 187 } 188 m.Palette[d.transparentIndex] = color.RGBA{} 189 } 190 litWidth, err := d.r.ReadByte() 191 if err != nil { 192 return err 193 } 194 if litWidth < 2 || litWidth > 8 { 195 return fmt.Errorf("gif: pixel size in decode out of range: %d", litWidth) 196 } 197 // A wonderfully Go-like piece of magic. 198 br := &blockReader{r: d.r} 199 lzwr := lzw.NewReader(br, lzw.LSB, int(litWidth)) 200 defer lzwr.Close() 201 if _, err = io.ReadFull(lzwr, m.Pix); err != nil { 202 if err != io.ErrUnexpectedEOF { 203 return err 204 } 205 return errNotEnough 206 } 207 // Both lzwr and br should be exhausted. Reading from them 208 // should yield (0, io.EOF). 209 if n, err := lzwr.Read(d.tmp[:1]); n != 0 || err != io.EOF { 210 if err != nil { 211 return err 212 } 213 return errTooMuch 214 } 215 if n, err := br.Read(d.tmp[:1]); n != 0 || err != io.EOF { 216 if err != nil { 217 return err 218 } 219 return errTooMuch 220 } 221 222 // Check that the color indexes are inside the palette. 223 if len(m.Palette) < 256 { 224 for _, pixel := range m.Pix { 225 if int(pixel) >= len(m.Palette) { 226 return errBadPixel 227 } 228 } 229 } 230 231 // Undo the interlacing if necessary. 232 if d.imageFields&ifInterlace != 0 { 233 uninterlace(m) 234 } 235 236 d.image = append(d.image, m) 237 d.delay = append(d.delay, d.delayTime) 238 // The GIF89a spec, Section 23 (Graphic Control Extension) says: 239 // "The scope of this extension is the first graphic rendering block 240 // to follow." We therefore reset the GCE fields to zero. 241 d.delayTime = 0 242 d.hasTransparentIndex = false 243 244 case sTrailer: 245 if len(d.image) == 0 { 246 return io.ErrUnexpectedEOF 247 } 248 return nil 249 250 default: 251 return fmt.Errorf("gif: unknown block type: 0x%.2x", c) 252 } 253 } 254 } 255 256 func (d *decoder) readHeaderAndScreenDescriptor() error { 257 _, err := io.ReadFull(d.r, d.tmp[0:13]) 258 if err != nil { 259 return err 260 } 261 d.vers = string(d.tmp[0:6]) 262 if d.vers != "GIF87a" && d.vers != "GIF89a" { 263 return fmt.Errorf("gif: can't recognize format %s", d.vers) 264 } 265 d.width = int(d.tmp[6]) + int(d.tmp[7])<<8 266 d.height = int(d.tmp[8]) + int(d.tmp[9])<<8 267 d.headerFields = d.tmp[10] 268 d.backgroundIndex = d.tmp[11] 269 d.aspect = d.tmp[12] 270 d.loopCount = -1 271 d.pixelSize = uint(d.headerFields&7) + 1 272 return nil 273 } 274 275 func (d *decoder) readColorMap() (color.Palette, error) { 276 if d.pixelSize > 8 { 277 return nil, fmt.Errorf("gif: can't handle %d bits per pixel", d.pixelSize) 278 } 279 numColors := 1 << d.pixelSize 280 if d.imageFields&ifLocalColorTable != 0 { 281 numColors = 1 << ((d.imageFields & ifPixelSizeMask) + 1) 282 } 283 numValues := 3 * numColors 284 _, err := io.ReadFull(d.r, d.tmp[0:numValues]) 285 if err != nil { 286 return nil, fmt.Errorf("gif: short read on color map: %s", err) 287 } 288 colorMap := make(color.Palette, numColors) 289 j := 0 290 for i := range colorMap { 291 colorMap[i] = color.RGBA{d.tmp[j+0], d.tmp[j+1], d.tmp[j+2], 0xFF} 292 j += 3 293 } 294 return colorMap, nil 295 } 296 297 func (d *decoder) readExtension() error { 298 extension, err := d.r.ReadByte() 299 if err != nil { 300 return err 301 } 302 size := 0 303 switch extension { 304 case eText: 305 size = 13 306 case eGraphicControl: 307 return d.readGraphicControl() 308 case eComment: 309 // nothing to do but read the data. 310 case eApplication: 311 b, err := d.r.ReadByte() 312 if err != nil { 313 return err 314 } 315 // The spec requires size be 11, but Adobe sometimes uses 10. 316 size = int(b) 317 default: 318 return fmt.Errorf("gif: unknown extension 0x%.2x", extension) 319 } 320 if size > 0 { 321 if _, err := io.ReadFull(d.r, d.tmp[0:size]); err != nil { 322 return err 323 } 324 } 325 326 // Application Extension with "NETSCAPE2.0" as string and 1 in data means 327 // this extension defines a loop count. 328 if extension == eApplication && string(d.tmp[:size]) == "NETSCAPE2.0" { 329 n, err := d.readBlock() 330 if n == 0 || err != nil { 331 return err 332 } 333 if n == 3 && d.tmp[0] == 1 { 334 d.loopCount = int(d.tmp[1]) | int(d.tmp[2])<<8 335 } 336 } 337 for { 338 n, err := d.readBlock() 339 if n == 0 || err != nil { 340 return err 341 } 342 } 343 } 344 345 func (d *decoder) readGraphicControl() error { 346 if _, err := io.ReadFull(d.r, d.tmp[0:6]); err != nil { 347 return fmt.Errorf("gif: can't read graphic control: %s", err) 348 } 349 d.flags = d.tmp[1] 350 d.delayTime = int(d.tmp[2]) | int(d.tmp[3])<<8 351 if d.flags&gcTransparentColorSet != 0 { 352 d.transparentIndex = d.tmp[4] 353 d.hasTransparentIndex = true 354 } 355 return nil 356 } 357 358 func (d *decoder) newImageFromDescriptor() (*image.Paletted, error) { 359 if _, err := io.ReadFull(d.r, d.tmp[0:9]); err != nil { 360 return nil, fmt.Errorf("gif: can't read image descriptor: %s", err) 361 } 362 left := int(d.tmp[0]) + int(d.tmp[1])<<8 363 top := int(d.tmp[2]) + int(d.tmp[3])<<8 364 width := int(d.tmp[4]) + int(d.tmp[5])<<8 365 height := int(d.tmp[6]) + int(d.tmp[7])<<8 366 d.imageFields = d.tmp[8] 367 368 // The GIF89a spec, Section 20 (Image Descriptor) says: 369 // "Each image must fit within the boundaries of the Logical 370 // Screen, as defined in the Logical Screen Descriptor." 371 bounds := image.Rect(left, top, left+width, top+height) 372 if bounds != bounds.Intersect(image.Rect(0, 0, d.width, d.height)) { 373 return nil, errors.New("gif: frame bounds larger than image bounds") 374 } 375 return image.NewPaletted(bounds, nil), nil 376 } 377 378 func (d *decoder) readBlock() (int, error) { 379 n, err := d.r.ReadByte() 380 if n == 0 || err != nil { 381 return 0, err 382 } 383 return io.ReadFull(d.r, d.tmp[0:n]) 384 } 385 386 // interlaceScan defines the ordering for a pass of the interlace algorithm. 387 type interlaceScan struct { 388 skip, start int 389 } 390 391 // interlacing represents the set of scans in an interlaced GIF image. 392 var interlacing = []interlaceScan{ 393 {8, 0}, // Group 1 : Every 8th. row, starting with row 0. 394 {8, 4}, // Group 2 : Every 8th. row, starting with row 4. 395 {4, 2}, // Group 3 : Every 4th. row, starting with row 2. 396 {2, 1}, // Group 4 : Every 2nd. row, starting with row 1. 397 } 398 399 // uninterlace rearranges the pixels in m to account for interlaced input. 400 func uninterlace(m *image.Paletted) { 401 var nPix []uint8 402 dx := m.Bounds().Dx() 403 dy := m.Bounds().Dy() 404 nPix = make([]uint8, dx*dy) 405 offset := 0 // steps through the input by sequential scan lines. 406 for _, pass := range interlacing { 407 nOffset := pass.start * dx // steps through the output as defined by pass. 408 for y := pass.start; y < dy; y += pass.skip { 409 copy(nPix[nOffset:nOffset+dx], m.Pix[offset:offset+dx]) 410 offset += dx 411 nOffset += dx * pass.skip 412 } 413 } 414 m.Pix = nPix 415 } 416 417 // Decode reads a GIF image from r and returns the first embedded 418 // image as an image.Image. 419 func Decode(r io.Reader) (image.Image, error) { 420 var d decoder 421 if err := d.decode(r, false); err != nil { 422 return nil, err 423 } 424 return d.image[0], nil 425 } 426 427 // GIF represents the possibly multiple images stored in a GIF file. 428 type GIF struct { 429 Image []*image.Paletted // The successive images. 430 Delay []int // The successive delay times, one per frame, in 100ths of a second. 431 LoopCount int // The loop count. 432 } 433 434 // DecodeAll reads a GIF image from r and returns the sequential frames 435 // and timing information. 436 func DecodeAll(r io.Reader) (*GIF, error) { 437 var d decoder 438 if err := d.decode(r, false); err != nil { 439 return nil, err 440 } 441 gif := &GIF{ 442 Image: d.image, 443 LoopCount: d.loopCount, 444 Delay: d.delay, 445 } 446 return gif, nil 447 } 448 449 // DecodeConfig returns the global color model and dimensions of a GIF image 450 // without decoding the entire image. 451 func DecodeConfig(r io.Reader) (image.Config, error) { 452 var d decoder 453 if err := d.decode(r, true); err != nil { 454 return image.Config{}, err 455 } 456 return image.Config{ 457 ColorModel: d.globalColorMap, 458 Width: d.width, 459 Height: d.height, 460 }, nil 461 } 462 463 func init() { 464 image.RegisterFormat("gif", "GIF8?a", Decode, DecodeConfig) 465 }