123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172 |
- package imagesize
- import (
- "bufio"
- "errors"
- "io"
- "sync"
- "sync/atomic"
- )
- type Meta struct {
- Format string
- Width, Height int
- }
- type format struct {
- magic string
- decodeMeta func(io.Reader) (*Meta, error)
- }
- type reader interface {
- io.Reader
- Peek(int) ([]byte, error)
- }
- var (
- formatsMu sync.Mutex
- atomicFormats atomic.Value
- ErrFormat = errors.New("unknown image format")
- )
- func asReader(r io.Reader) reader {
- if rr, ok := r.(reader); ok {
- return rr
- }
- return bufio.NewReader(r)
- }
- func matchMagic(magic string, b []byte) bool {
- if len(magic) != len(b) {
- return false
- }
- for i, c := range b {
- if magic[i] != c && magic[i] != '?' {
- return false
- }
- }
- return true
- }
- func RegisterFormat(magic string, decodeMeta func(io.Reader) (*Meta, error)) {
- formatsMu.Lock()
- defer formatsMu.Unlock()
- formats, _ := atomicFormats.Load().([]format)
- atomicFormats.Store(append(formats, format{magic, decodeMeta}))
- }
- func DecodeMeta(r io.Reader) (*Meta, error) {
- rr := asReader(r)
- formats, _ := atomicFormats.Load().([]format)
- for _, f := range formats {
- b, err := rr.Peek(len(f.magic))
- if err == nil && matchMagic(f.magic, b) {
- return f.decodeMeta(rr)
- }
- }
- return nil, ErrFormat
- }
|