diff --git a/cmd/ffwebp/main.go b/cmd/ffwebp/main.go index b01ae35..3f11e54 100644 --- a/cmd/ffwebp/main.go +++ b/cmd/ffwebp/main.go @@ -139,11 +139,13 @@ func run(_ context.Context, cmd *cli.Command) error { common.FillDefaults() - oCodec, err := codec.Detect(output, cmd.String("codec")) + oCodec, oExt, err := codec.Detect(output, cmd.String("codec")) if err != nil { return err } + common.OutputExtension = oExt + logx.Printf("output codec: %s (forced=%v)\n", oCodec, cmd.IsSet("codec")) t0 := time.Now() diff --git a/internal/codec/detect.go b/internal/codec/detect.go index c377964..6d7c862 100644 --- a/internal/codec/detect.go +++ b/internal/codec/detect.go @@ -71,34 +71,39 @@ func Sniff(reader io.Reader) (*Sniffed, io.Reader, error) { }, bytes.NewReader(buf), nil } -func Detect(output, override string) (Codec, error) { - if override != "" { - codec, ok := codecs[override] - if !ok { - return nil, fmt.Errorf("unsupported output codec: %q", override) - } +func Detect(output, override string) (Codec, string, error) { + ext := override - if !codec.CanEncode() { - return nil, fmt.Errorf("decode-only output codec: %q", override) - } - - return codec, nil - } - - if output == "-" { - return nil, errors.New("missing codec for output") - } - - ext := strings.ToLower(strings.TrimPrefix(filepath.Ext(output), ".")) if ext == "" { - return nil, fmt.Errorf("output filename %q has no extension", output) + ext = strings.ToLower(strings.TrimPrefix(filepath.Ext(output), ".")) + if ext == "" { + return nil, "", fmt.Errorf("output filename %q has no extension", output) + } + } + + codec, err := FindCodec(ext) + if err != nil { + return nil, "", err + } + + if codec == nil { + return nil, "", fmt.Errorf("unsupported output codec: %q", ext) + } + + return codec, ext, nil +} + +func FindCodec(ext string) (Codec, error) { + codec, ok := codecs[ext] + if ok { + return codec, nil } for _, codec := range codecs { for _, alias := range codec.Extensions() { - if ext == strings.ToLower(alias) { + if ext == alias { if !codec.CanEncode() { - return nil, fmt.Errorf("decode-only output codec: %q", override) + return nil, fmt.Errorf("decode-only output codec: %q", ext) } return codec, nil @@ -106,5 +111,5 @@ func Detect(output, override string) (Codec, error) { } } - return nil, fmt.Errorf("unsupported or unknown file extension: %q", ext) + return nil, nil } diff --git a/internal/codec/tiff/tiff.go b/internal/codec/tiff/tiff.go index 6f885a2..1908263 100644 --- a/internal/codec/tiff/tiff.go +++ b/internal/codec/tiff/tiff.go @@ -86,7 +86,7 @@ func (impl) Decode(reader io.Reader) (image.Image, error) { return tiff.Decode(reader) } -func (impl) Encode(writer io.Writer, img image.Image, options opts.Common) error { +func (impl) Encode(writer io.Writer, img image.Image, _ opts.Common) error { logx.Printf("tiff: compression=%d predictor=%t\n", compression, predictor) return tiff.Encode(writer, img, &tiff.Options{ diff --git a/internal/opts/opts.go b/internal/opts/opts.go index 473cf3a..8cec671 100644 --- a/internal/opts/opts.go +++ b/internal/opts/opts.go @@ -1,8 +1,9 @@ package opts type Common struct { - Quality int - Lossless bool + Quality int + Lossless bool + OutputExtension string } func (c *Common) FillDefaults() {