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  }