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