aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/image/gif/reader.go41
1 files changed, 34 insertions, 7 deletions
diff --git a/src/image/gif/reader.go b/src/image/gif/reader.go
index 5a863e204f..b3ed0388f4 100644
--- a/src/image/gif/reader.go
+++ b/src/image/gif/reader.go
@@ -34,6 +34,9 @@ const (
// Fields.
fColorMapFollows = 1 << 7
+ // Screen Descriptor flags.
+ sdGlobalColorTable = 1 << 7
+
// Image fields.
ifLocalColorTable = 1 << 7
ifInterlace = 1 << 6
@@ -41,6 +44,14 @@ const (
// Graphic control flags.
gcTransparentColorSet = 1 << 0
+ gcDisposalMethodMask = 7 << 2
+)
+
+// Disposal Methods.
+const (
+ DisposalNone = 0x01
+ DisposalBackground = 0x02
+ DisposalPrevious = 0x03
)
// Section indicators.
@@ -66,11 +77,11 @@ type decoder struct {
vers string
width int
height int
- flags byte
headerFields byte
backgroundIndex byte
loopCount int
delayTime int
+ disposalMethod byte
// Unused from header.
aspect byte
@@ -87,9 +98,10 @@ type decoder struct {
globalColorMap color.Palette
// Used when decoding.
- delay []int
- image []*image.Paletted
- tmp [1024]byte // must be at least 768 so we can read color map
+ delay []int
+ disposal []byte
+ image []*image.Paletted
+ tmp [1024]byte // must be at least 768 so we can read color map
}
// blockReader parses the block structure of GIF image data, which
@@ -235,6 +247,7 @@ func (d *decoder) decode(r io.Reader, configOnly bool) error {
d.image = append(d.image, m)
d.delay = append(d.delay, d.delayTime)
+ d.disposal = append(d.disposal, d.disposalMethod)
// The GIF89a spec, Section 23 (Graphic Control Extension) says:
// "The scope of this extension is the first graphic rendering block
// to follow." We therefore reset the GCE fields to zero.
@@ -265,7 +278,9 @@ func (d *decoder) readHeaderAndScreenDescriptor() error {
d.width = int(d.tmp[6]) + int(d.tmp[7])<<8
d.height = int(d.tmp[8]) + int(d.tmp[9])<<8
d.headerFields = d.tmp[10]
- d.backgroundIndex = d.tmp[11]
+ if d.headerFields&sdGlobalColorTable != 0 {
+ d.backgroundIndex = d.tmp[11]
+ }
d.aspect = d.tmp[12]
d.loopCount = -1
d.pixelSize = uint(d.headerFields&7) + 1
@@ -346,9 +361,10 @@ func (d *decoder) readGraphicControl() error {
if _, err := io.ReadFull(d.r, d.tmp[0:6]); err != nil {
return fmt.Errorf("gif: can't read graphic control: %s", err)
}
- d.flags = d.tmp[1]
+ flags := d.tmp[1]
+ d.disposalMethod = (flags & gcDisposalMethodMask) >> 2
d.delayTime = int(d.tmp[2]) | int(d.tmp[3])<<8
- if d.flags&gcTransparentColorSet != 0 {
+ if flags&gcTransparentColorSet != 0 {
d.transparentIndex = d.tmp[4]
d.hasTransparentIndex = true
}
@@ -428,7 +444,11 @@ func Decode(r io.Reader) (image.Image, error) {
type GIF struct {
Image []*image.Paletted // The successive images.
Delay []int // The successive delay times, one per frame, in 100ths of a second.
+ Disposal []byte // The successive disposal methods, one per frame.
LoopCount int // The loop count.
+ Config image.Config
+ // The background index in the Global Color Map.
+ BackgroundIndex byte
}
// DecodeAll reads a GIF image from r and returns the sequential frames
@@ -442,6 +462,13 @@ func DecodeAll(r io.Reader) (*GIF, error) {
Image: d.image,
LoopCount: d.loopCount,
Delay: d.delay,
+ Disposal: d.disposal,
+ Config: image.Config{
+ ColorModel: d.globalColorMap,
+ Width: d.width,
+ Height: d.height,
+ },
+ BackgroundIndex: d.backgroundIndex,
}
return gif, nil
}