github.com/ader1990/go@v0.0.0-20140630135419-8c24447fa791/src/pkg/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 if d.imageFields&fColorMapFollows != 0 { 175 m.Palette, err = d.readColorMap() 176 if err != nil { 177 return err 178 } 179 } else { 180 m.Palette = d.globalColorMap 181 } 182 if d.hasTransparentIndex && int(d.transparentIndex) < len(m.Palette) { 183 m.Palette[d.transparentIndex] = color.RGBA{} 184 } 185 litWidth, err := d.r.ReadByte() 186 if err != nil { 187 return err 188 } 189 if litWidth < 2 || litWidth > 8 { 190 return fmt.Errorf("gif: pixel size in decode out of range: %d", litWidth) 191 } 192 // A wonderfully Go-like piece of magic. 193 br := &blockReader{r: d.r} 194 lzwr := lzw.NewReader(br, lzw.LSB, int(litWidth)) 195 defer lzwr.Close() 196 if _, err = io.ReadFull(lzwr, m.Pix); err != nil { 197 if err != io.ErrUnexpectedEOF { 198 return err 199 } 200 return errNotEnough 201 } 202 // Both lzwr and br should be exhausted. Reading from them 203 // should yield (0, io.EOF). 204 if n, err := lzwr.Read(d.tmp[:1]); n != 0 || err != io.EOF { 205 if err != nil { 206 return err 207 } 208 return errTooMuch 209 } 210 if n, err := br.Read(d.tmp[:1]); n != 0 || err != io.EOF { 211 if err != nil { 212 return err 213 } 214 return errTooMuch 215 } 216 217 // Check that the color indexes are inside the palette. 218 if len(m.Palette) < 256 { 219 for _, pixel := range m.Pix { 220 if int(pixel) >= len(m.Palette) { 221 return errBadPixel 222 } 223 } 224 } 225 226 // Undo the interlacing if necessary. 227 if d.imageFields&ifInterlace != 0 { 228 uninterlace(m) 229 } 230 231 d.image = append(d.image, m) 232 d.delay = append(d.delay, d.delayTime) 233 // The GIF89a spec, Section 23 (Graphic Control Extension) says: 234 // "The scope of this extension is the first graphic rendering block 235 // to follow." We therefore reset the GCE fields to zero. 236 d.delayTime = 0 237 d.hasTransparentIndex = false 238 239 case sTrailer: 240 if len(d.image) == 0 { 241 return io.ErrUnexpectedEOF 242 } 243 return nil 244 245 default: 246 return fmt.Errorf("gif: unknown block type: 0x%.2x", c) 247 } 248 } 249 } 250 251 func (d *decoder) readHeaderAndScreenDescriptor() error { 252 _, err := io.ReadFull(d.r, d.tmp[0:13]) 253 if err != nil { 254 return err 255 } 256 d.vers = string(d.tmp[0:6]) 257 if d.vers != "GIF87a" && d.vers != "GIF89a" { 258 return fmt.Errorf("gif: can't recognize format %s", d.vers) 259 } 260 d.width = int(d.tmp[6]) + int(d.tmp[7])<<8 261 d.height = int(d.tmp[8]) + int(d.tmp[9])<<8 262 d.headerFields = d.tmp[10] 263 d.backgroundIndex = d.tmp[11] 264 d.aspect = d.tmp[12] 265 d.loopCount = -1 266 d.pixelSize = uint(d.headerFields&7) + 1 267 return nil 268 } 269 270 func (d *decoder) readColorMap() (color.Palette, error) { 271 if d.pixelSize > 8 { 272 return nil, fmt.Errorf("gif: can't handle %d bits per pixel", d.pixelSize) 273 } 274 numColors := 1 << d.pixelSize 275 if d.imageFields&ifLocalColorTable != 0 { 276 numColors = 1 << ((d.imageFields & ifPixelSizeMask) + 1) 277 } 278 numValues := 3 * numColors 279 _, err := io.ReadFull(d.r, d.tmp[0:numValues]) 280 if err != nil { 281 return nil, fmt.Errorf("gif: short read on color map: %s", err) 282 } 283 colorMap := make(color.Palette, numColors) 284 j := 0 285 for i := range colorMap { 286 colorMap[i] = color.RGBA{d.tmp[j+0], d.tmp[j+1], d.tmp[j+2], 0xFF} 287 j += 3 288 } 289 return colorMap, nil 290 } 291 292 func (d *decoder) readExtension() error { 293 extension, err := d.r.ReadByte() 294 if err != nil { 295 return err 296 } 297 size := 0 298 switch extension { 299 case eText: 300 size = 13 301 case eGraphicControl: 302 return d.readGraphicControl() 303 case eComment: 304 // nothing to do but read the data. 305 case eApplication: 306 b, err := d.r.ReadByte() 307 if err != nil { 308 return err 309 } 310 // The spec requires size be 11, but Adobe sometimes uses 10. 311 size = int(b) 312 default: 313 return fmt.Errorf("gif: unknown extension 0x%.2x", extension) 314 } 315 if size > 0 { 316 if _, err := io.ReadFull(d.r, d.tmp[0:size]); err != nil { 317 return err 318 } 319 } 320 321 // Application Extension with "NETSCAPE2.0" as string and 1 in data means 322 // this extension defines a loop count. 323 if extension == eApplication && string(d.tmp[:size]) == "NETSCAPE2.0" { 324 n, err := d.readBlock() 325 if n == 0 || err != nil { 326 return err 327 } 328 if n == 3 && d.tmp[0] == 1 { 329 d.loopCount = int(d.tmp[1]) | int(d.tmp[2])<<8 330 } 331 } 332 for { 333 n, err := d.readBlock() 334 if n == 0 || err != nil { 335 return err 336 } 337 } 338 } 339 340 func (d *decoder) readGraphicControl() error { 341 if _, err := io.ReadFull(d.r, d.tmp[0:6]); err != nil { 342 return fmt.Errorf("gif: can't read graphic control: %s", err) 343 } 344 d.flags = d.tmp[1] 345 d.delayTime = int(d.tmp[2]) | int(d.tmp[3])<<8 346 if d.flags&gcTransparentColorSet != 0 { 347 d.transparentIndex = d.tmp[4] 348 d.hasTransparentIndex = true 349 } 350 return nil 351 } 352 353 func (d *decoder) newImageFromDescriptor() (*image.Paletted, error) { 354 if _, err := io.ReadFull(d.r, d.tmp[0:9]); err != nil { 355 return nil, fmt.Errorf("gif: can't read image descriptor: %s", err) 356 } 357 left := int(d.tmp[0]) + int(d.tmp[1])<<8 358 top := int(d.tmp[2]) + int(d.tmp[3])<<8 359 width := int(d.tmp[4]) + int(d.tmp[5])<<8 360 height := int(d.tmp[6]) + int(d.tmp[7])<<8 361 d.imageFields = d.tmp[8] 362 363 // The GIF89a spec, Section 20 (Image Descriptor) says: 364 // "Each image must fit within the boundaries of the Logical 365 // Screen, as defined in the Logical Screen Descriptor." 366 bounds := image.Rect(left, top, left+width, top+height) 367 if bounds != bounds.Intersect(image.Rect(0, 0, d.width, d.height)) { 368 return nil, errors.New("gif: frame bounds larger than image bounds") 369 } 370 return image.NewPaletted(bounds, nil), nil 371 } 372 373 func (d *decoder) readBlock() (int, error) { 374 n, err := d.r.ReadByte() 375 if n == 0 || err != nil { 376 return 0, err 377 } 378 return io.ReadFull(d.r, d.tmp[0:n]) 379 } 380 381 // interlaceScan defines the ordering for a pass of the interlace algorithm. 382 type interlaceScan struct { 383 skip, start int 384 } 385 386 // interlacing represents the set of scans in an interlaced GIF image. 387 var interlacing = []interlaceScan{ 388 {8, 0}, // Group 1 : Every 8th. row, starting with row 0. 389 {8, 4}, // Group 2 : Every 8th. row, starting with row 4. 390 {4, 2}, // Group 3 : Every 4th. row, starting with row 2. 391 {2, 1}, // Group 4 : Every 2nd. row, starting with row 1. 392 } 393 394 // uninterlace rearranges the pixels in m to account for interlaced input. 395 func uninterlace(m *image.Paletted) { 396 var nPix []uint8 397 dx := m.Bounds().Dx() 398 dy := m.Bounds().Dy() 399 nPix = make([]uint8, dx*dy) 400 offset := 0 // steps through the input by sequential scan lines. 401 for _, pass := range interlacing { 402 nOffset := pass.start * dx // steps through the output as defined by pass. 403 for y := pass.start; y < dy; y += pass.skip { 404 copy(nPix[nOffset:nOffset+dx], m.Pix[offset:offset+dx]) 405 offset += dx 406 nOffset += dx * pass.skip 407 } 408 } 409 m.Pix = nPix 410 } 411 412 // Decode reads a GIF image from r and returns the first embedded 413 // image as an image.Image. 414 func Decode(r io.Reader) (image.Image, error) { 415 var d decoder 416 if err := d.decode(r, false); err != nil { 417 return nil, err 418 } 419 return d.image[0], nil 420 } 421 422 // GIF represents the possibly multiple images stored in a GIF file. 423 type GIF struct { 424 Image []*image.Paletted // The successive images. 425 Delay []int // The successive delay times, one per frame, in 100ths of a second. 426 LoopCount int // The loop count. 427 } 428 429 // DecodeAll reads a GIF image from r and returns the sequential frames 430 // and timing information. 431 func DecodeAll(r io.Reader) (*GIF, error) { 432 var d decoder 433 if err := d.decode(r, false); err != nil { 434 return nil, err 435 } 436 gif := &GIF{ 437 Image: d.image, 438 LoopCount: d.loopCount, 439 Delay: d.delay, 440 } 441 return gif, nil 442 } 443 444 // DecodeConfig returns the global color model and dimensions of a GIF image 445 // without decoding the entire image. 446 func DecodeConfig(r io.Reader) (image.Config, error) { 447 var d decoder 448 if err := d.decode(r, true); err != nil { 449 return image.Config{}, err 450 } 451 return image.Config{ 452 ColorModel: d.globalColorMap, 453 Width: d.width, 454 Height: d.height, 455 }, nil 456 } 457 458 func init() { 459 image.RegisterFormat("gif", "GIF8?a", Decode, DecodeConfig) 460 }