github.com/varialus/godfly@v0.0.0-20130904042352-1934f9f095ab/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 84 // Computed. 85 pixelSize uint 86 globalColorMap color.Palette 87 88 // Used when decoding. 89 delay []int 90 image []*image.Paletted 91 tmp [1024]byte // must be at least 768 so we can read color map 92 } 93 94 // blockReader parses the block structure of GIF image data, which 95 // comprises (n, (n bytes)) blocks, with 1 <= n <= 255. It is the 96 // reader given to the LZW decoder, which is thus immune to the 97 // blocking. After the LZW decoder completes, there will be a 0-byte 98 // block remaining (0, ()), which is consumed when checking that the 99 // blockReader is exhausted. 100 type blockReader struct { 101 r reader 102 slice []byte 103 err error 104 tmp [256]byte 105 } 106 107 func (b *blockReader) Read(p []byte) (int, error) { 108 if b.err != nil { 109 return 0, b.err 110 } 111 if len(p) == 0 { 112 return 0, nil 113 } 114 if len(b.slice) == 0 { 115 var blockLen uint8 116 blockLen, b.err = b.r.ReadByte() 117 if b.err != nil { 118 return 0, b.err 119 } 120 if blockLen == 0 { 121 b.err = io.EOF 122 return 0, b.err 123 } 124 b.slice = b.tmp[0:blockLen] 125 if _, b.err = io.ReadFull(b.r, b.slice); b.err != nil { 126 return 0, b.err 127 } 128 } 129 n := copy(p, b.slice) 130 b.slice = b.slice[n:] 131 return n, nil 132 } 133 134 // decode reads a GIF image from r and stores the result in d. 135 func (d *decoder) decode(r io.Reader, configOnly bool) error { 136 // Add buffering if r does not provide ReadByte. 137 if rr, ok := r.(reader); ok { 138 d.r = rr 139 } else { 140 d.r = bufio.NewReader(r) 141 } 142 143 err := d.readHeaderAndScreenDescriptor() 144 if err != nil { 145 return err 146 } 147 if configOnly { 148 return nil 149 } 150 151 if d.headerFields&fColorMapFollows != 0 { 152 if d.globalColorMap, err = d.readColorMap(); err != nil { 153 return err 154 } 155 } 156 157 for { 158 c, err := d.r.ReadByte() 159 if err != nil { 160 return err 161 } 162 switch c { 163 case sExtension: 164 if err = d.readExtension(); err != nil { 165 return err 166 } 167 168 case sImageDescriptor: 169 m, err := d.newImageFromDescriptor() 170 if err != nil { 171 return err 172 } 173 if d.imageFields&fColorMapFollows != 0 { 174 m.Palette, err = d.readColorMap() 175 if err != nil { 176 return err 177 } 178 // TODO: do we set transparency in this map too? That would be 179 // d.setTransparency(m.Palette) 180 } else { 181 m.Palette = d.globalColorMap 182 } 183 litWidth, err := d.r.ReadByte() 184 if err != nil { 185 return err 186 } 187 if litWidth < 2 || litWidth > 8 { 188 return fmt.Errorf("gif: pixel size in decode out of range: %d", litWidth) 189 } 190 // A wonderfully Go-like piece of magic. 191 br := &blockReader{r: d.r} 192 lzwr := lzw.NewReader(br, lzw.LSB, int(litWidth)) 193 defer lzwr.Close() 194 if _, err = io.ReadFull(lzwr, m.Pix); err != nil { 195 if err != io.ErrUnexpectedEOF { 196 return err 197 } 198 return errNotEnough 199 } 200 // Both lzwr and br should be exhausted. Reading from them 201 // should yield (0, io.EOF). 202 if n, err := lzwr.Read(d.tmp[:1]); n != 0 || err != io.EOF { 203 if err != nil { 204 return err 205 } 206 return errTooMuch 207 } 208 if n, err := br.Read(d.tmp[:1]); n != 0 || err != io.EOF { 209 if err != nil { 210 return err 211 } 212 return errTooMuch 213 } 214 215 // Check that the color indexes are inside the palette. 216 if len(m.Palette) < 256 { 217 for _, pixel := range m.Pix { 218 if int(pixel) >= len(m.Palette) { 219 return errBadPixel 220 } 221 } 222 } 223 224 // Undo the interlacing if necessary. 225 if d.imageFields&ifInterlace != 0 { 226 uninterlace(m) 227 } 228 229 d.image = append(d.image, m) 230 d.delay = append(d.delay, d.delayTime) 231 d.delayTime = 0 // TODO: is this correct, or should we hold on to the value? 232 233 case sTrailer: 234 if len(d.image) == 0 { 235 return io.ErrUnexpectedEOF 236 } 237 return nil 238 239 default: 240 return fmt.Errorf("gif: unknown block type: 0x%.2x", c) 241 } 242 } 243 } 244 245 func (d *decoder) readHeaderAndScreenDescriptor() error { 246 _, err := io.ReadFull(d.r, d.tmp[0:13]) 247 if err != nil { 248 return err 249 } 250 d.vers = string(d.tmp[0:6]) 251 if d.vers != "GIF87a" && d.vers != "GIF89a" { 252 return fmt.Errorf("gif: can't recognize format %s", d.vers) 253 } 254 d.width = int(d.tmp[6]) + int(d.tmp[7])<<8 255 d.height = int(d.tmp[8]) + int(d.tmp[9])<<8 256 d.headerFields = d.tmp[10] 257 d.backgroundIndex = d.tmp[11] 258 d.aspect = d.tmp[12] 259 d.loopCount = -1 260 d.pixelSize = uint(d.headerFields&7) + 1 261 return nil 262 } 263 264 func (d *decoder) readColorMap() (color.Palette, error) { 265 if d.pixelSize > 8 { 266 return nil, fmt.Errorf("gif: can't handle %d bits per pixel", d.pixelSize) 267 } 268 numColors := 1 << d.pixelSize 269 if d.imageFields&ifLocalColorTable != 0 { 270 numColors = 1 << ((d.imageFields & ifPixelSizeMask) + 1) 271 } 272 numValues := 3 * numColors 273 _, err := io.ReadFull(d.r, d.tmp[0:numValues]) 274 if err != nil { 275 return nil, fmt.Errorf("gif: short read on color map: %s", err) 276 } 277 colorMap := make(color.Palette, numColors) 278 j := 0 279 for i := range colorMap { 280 colorMap[i] = color.RGBA{d.tmp[j+0], d.tmp[j+1], d.tmp[j+2], 0xFF} 281 j += 3 282 } 283 return colorMap, nil 284 } 285 286 func (d *decoder) readExtension() error { 287 extension, err := d.r.ReadByte() 288 if err != nil { 289 return err 290 } 291 size := 0 292 switch extension { 293 case eText: 294 size = 13 295 case eGraphicControl: 296 return d.readGraphicControl() 297 case eComment: 298 // nothing to do but read the data. 299 case eApplication: 300 b, err := d.r.ReadByte() 301 if err != nil { 302 return err 303 } 304 // The spec requires size be 11, but Adobe sometimes uses 10. 305 size = int(b) 306 default: 307 return fmt.Errorf("gif: unknown extension 0x%.2x", extension) 308 } 309 if size > 0 { 310 if _, err := io.ReadFull(d.r, d.tmp[0:size]); err != nil { 311 return err 312 } 313 } 314 315 // Application Extension with "NETSCAPE2.0" as string and 1 in data means 316 // this extension defines a loop count. 317 if extension == eApplication && string(d.tmp[:size]) == "NETSCAPE2.0" { 318 n, err := d.readBlock() 319 if n == 0 || err != nil { 320 return err 321 } 322 if n == 3 && d.tmp[0] == 1 { 323 d.loopCount = int(d.tmp[1]) | int(d.tmp[2])<<8 324 } 325 } 326 for { 327 n, err := d.readBlock() 328 if n == 0 || err != nil { 329 return err 330 } 331 } 332 } 333 334 func (d *decoder) readGraphicControl() error { 335 if _, err := io.ReadFull(d.r, d.tmp[0:6]); err != nil { 336 return fmt.Errorf("gif: can't read graphic control: %s", err) 337 } 338 d.flags = d.tmp[1] 339 d.delayTime = int(d.tmp[2]) | int(d.tmp[3])<<8 340 if d.flags&gcTransparentColorSet != 0 { 341 d.transparentIndex = d.tmp[4] 342 d.setTransparency(d.globalColorMap) 343 } 344 return nil 345 } 346 347 func (d *decoder) setTransparency(colorMap color.Palette) { 348 if int(d.transparentIndex) < len(colorMap) { 349 colorMap[d.transparentIndex] = color.RGBA{} 350 } 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 }