1
0
mirror of https://github.com/coalaura/ffwebp.git synced 2025-09-08 13:59:54 +00:00
Files
ffwebp/internal/codec/detect.go

103 lines
1.7 KiB
Go
Raw Normal View History

2025-06-19 12:25:32 +02:00
package codec
import (
"bytes"
"errors"
"fmt"
"io"
"path/filepath"
"strings"
)
2025-06-19 16:14:29 +02:00
type Sniffed struct {
Header []byte
Confidence int
Codec Codec
}
func (s *Sniffed) String() string {
var builder strings.Builder
for _, b := range s.Header {
if b >= 32 && b <= 126 {
builder.WriteByte(b)
} else {
builder.WriteRune('.')
}
}
return builder.String()
}
func Sniff(reader io.Reader) (*Sniffed, io.Reader, error) {
2025-06-19 12:25:32 +02:00
buf, err := io.ReadAll(reader)
if err != nil {
return nil, nil, err
}
ra := bytes.NewReader(buf)
var (
best int
2025-06-19 16:14:29 +02:00
magic []byte
guess Codec
2025-06-19 12:25:32 +02:00
)
for _, codec := range codecs {
2025-06-19 16:14:29 +02:00
confidence, header, err := codec.Sniff(ra)
2025-06-19 12:25:32 +02:00
if err != nil {
2025-06-19 16:29:27 +02:00
if errors.Is(err, io.EOF) {
continue
}
2025-06-19 12:25:32 +02:00
return nil, nil, err
}
if confidence > best {
best = confidence
2025-06-19 16:14:29 +02:00
magic = header
2025-06-19 12:25:32 +02:00
guess = codec
}
}
if guess == nil {
2025-08-11 02:36:35 +02:00
return nil, nil, errors.New("unknown input format")
2025-06-19 12:25:32 +02:00
}
2025-06-19 16:14:29 +02:00
return &Sniffed{
Header: magic,
Confidence: best,
Codec: guess,
}, bytes.NewReader(buf), nil
2025-06-19 12:25:32 +02:00
}
func Detect(output, override string) (Codec, error) {
if override != "" {
codec, ok := codecs[override]
if !ok {
return nil, fmt.Errorf("unsupported 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)
}
for _, codec := range codecs {
for _, alias := range codec.Extensions() {
if ext == strings.ToLower(alias) {
return codec, nil
}
}
}
return nil, fmt.Errorf("unsupported or unknown file extension: %q", ext)
}