d.r = bufio.NewReader(r)
}
+ d.loopCount = -1
+
err := d.readHeaderAndScreenDescriptor()
if err != nil {
return err
// GIF represents the possibly multiple images stored in a GIF file.
type GIF struct {
- Image []*image.Paletted // The successive images.
- Delay []int // The successive delay times, one per frame, in 100ths of a second.
- LoopCount int // The loop count.
+ Image []*image.Paletted // The successive images.
+ Delay []int // The successive delay times, one per frame, in 100ths of a second.
+ // LoopCount controls the number of times an animation will be
+ // restarted during display.
+ // A LoopCount of 0 means to loop forever.
+ // A LoopCount of -1 means to show each frame only once.
+ // Otherwise, the animation is looped LoopCount+1 times.
+ LoopCount int
// Disposal is the successive disposal methods, one per frame. For
// backwards compatibility, a nil Disposal is valid to pass to EncodeAll,
// and implies that each frame's disposal method is 0 (no disposal
}
func TestLoopCount(t *testing.T) {
- data := []byte("GIF89a000\x00000,0\x00\x00\x00\n\x00" +
- "\n\x00\x80000000\x02\b\xf01u\xb9\xfdal\x05\x00;")
- img, err := DecodeAll(bytes.NewReader(data))
- if err != nil {
- t.Fatal("DecodeAll:", err)
- }
- w := new(bytes.Buffer)
- err = EncodeAll(w, img)
- if err != nil {
- t.Fatal("EncodeAll:", err)
- }
- img1, err := DecodeAll(w)
- if err != nil {
- t.Fatal("DecodeAll:", err)
+ testCases := []struct {
+ name string
+ data []byte
+ loopCount int
+ }{
+ {
+ "loopcount-missing",
+ []byte("GIF89a000\x00000" +
+ ",0\x00\x00\x00\n\x00\n\x00\x80000000" + // image 0 descriptor & color table
+ "\x02\b\xf01u\xb9\xfdal\x05\x00;"), // image 0 image data & trailer
+ -1,
+ },
+ {
+ "loopcount-0",
+ []byte("GIF89a000\x00000" +
+ "!\xff\vNETSCAPE2.0\x03\x01\x00\x00\x00" + // loop count = 0
+ ",0\x00\x00\x00\n\x00\n\x00\x80000000" + // image 0 descriptor & color table
+ "\x02\b\xf01u\xb9\xfdal\x05\x00" + // image 0 image data
+ ",0\x00\x00\x00\n\x00\n\x00\x80000000" + // image 1 descriptor & color table
+ "\x02\b\xf01u\xb9\xfdal\x05\x00;"), // image 1 image data & trailer
+ 0,
+ },
+ {
+ "loopcount-1",
+ []byte("GIF89a000\x00000" +
+ "!\xff\vNETSCAPE2.0\x03\x01\x01\x00\x00" + // loop count = 1
+ ",0\x00\x00\x00\n\x00\n\x00\x80000000" + // image 0 descriptor & color table
+ "\x02\b\xf01u\xb9\xfdal\x05\x00" + // image 0 image data
+ ",0\x00\x00\x00\n\x00\n\x00\x80000000" + // image 1 descriptor & color table
+ "\x02\b\xf01u\xb9\xfdal\x05\x00;"), // image 1 image data & trailer
+ 1,
+ },
}
- if img.LoopCount != img1.LoopCount {
- t.Errorf("loop count mismatch: %d vs %d", img.LoopCount, img1.LoopCount)
+
+ for _, tc := range testCases {
+ t.Run(tc.name, func(t *testing.T) {
+ img, err := DecodeAll(bytes.NewReader(tc.data))
+ if err != nil {
+ t.Fatal("DecodeAll:", err)
+ }
+ w := new(bytes.Buffer)
+ err = EncodeAll(w, img)
+ if err != nil {
+ t.Fatal("EncodeAll:", err)
+ }
+ img1, err := DecodeAll(w)
+ if err != nil {
+ t.Fatal("DecodeAll:", err)
+ }
+ if img.LoopCount != tc.loopCount {
+ t.Errorf("loop count mismatch: %d vs %d", img.LoopCount, tc.loopCount)
+ }
+ if img.LoopCount != img1.LoopCount {
+ t.Errorf("loop count failed round-trip: %d vs %d", img.LoopCount, img1.LoopCount)
+ }
+ })
}
}