From 599568382e3de09eb68ec4be200ef2b26fdba6af Mon Sep 17 00:00:00 2001 From: Laura Date: Thu, 19 Jun 2025 12:50:31 +0200 Subject: [PATCH] gif --- internal/codec/gif/gif.go | 72 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 72 insertions(+) create mode 100644 internal/codec/gif/gif.go diff --git a/internal/codec/gif/gif.go b/internal/codec/gif/gif.go new file mode 100644 index 0000000..be9d52b --- /dev/null +++ b/internal/codec/gif/gif.go @@ -0,0 +1,72 @@ +package gif + +import ( + "bytes" + "fmt" + "image" + "image/gif" + "io" + + "github.com/coalaura/ffwebp/internal/codec" + "github.com/coalaura/ffwebp/internal/opts" + "github.com/urfave/cli/v3" +) + +var numColors int + +func init() { + codec.Register(impl{}) +} + +type impl struct{} + +func (impl) Name() string { + return "gif" +} + +func (impl) Extensions() []string { + return []string{"gif"} +} + +func (impl) Flags(flags []cli.Flag) []cli.Flag { + return append(flags, &cli.IntFlag{ + Name: "gif.colors", + Usage: "GIF: Number of colors (1-256)", + Value: 256, + Destination: &numColors, + Validator: func(value int) error { + if value < 1 || value > 256 { + return fmt.Errorf("invalid number of colors: %d", value) + } + + return nil + }, + }) +} + +func (impl) Sniff(reader io.ReaderAt) (int, error) { + magic7a := []byte("GIF87a") + magic9a := []byte("GIF89a") + + buf := make([]byte, 6) + + if _, err := reader.ReadAt(buf, 0); err != nil { + return 0, err + } + + if bytes.Equal(buf, magic7a) || bytes.Equal(buf, magic9a) { + return 100, nil + } + + return 0, nil +} + +func (impl) Decode(reader io.Reader) (image.Image, error) { + return gif.Decode(reader) +} + +func (impl) Encode(writer io.Writer, img image.Image, options opts.Common) error { + return gif.Encode(writer, img, &gif.Options{ + NumColors: numColors, + }) +}