1 // Copyright 2010 The Go Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style
3 // license that can be found in the LICENSE file.
15 // ErrFormat indicates that decoding encountered an unknown format.
16 var ErrFormat
= errors
.New("image: unknown format")
18 // A format holds an image format's name, magic header and how to decode it.
21 decode
func(io
.Reader
) (Image
, error
)
22 decodeConfig
func(io
.Reader
) (Config
, error
)
25 // Formats is the list of registered formats.
28 atomicFormats atomic
.Value
31 // RegisterFormat registers an image format for use by Decode.
32 // Name is the name of the format, like "jpeg" or "png".
33 // Magic is the magic prefix that identifies the format's encoding. The magic
34 // string can contain "?" wildcards that each match any one byte.
35 // Decode is the function that decodes the encoded image.
36 // DecodeConfig is the function that decodes just its configuration.
37 func RegisterFormat(name
, magic
string, decode
func(io
.Reader
) (Image
, error
), decodeConfig
func(io
.Reader
) (Config
, error
)) {
39 formats
, _
:= atomicFormats
.Load().([]format
)
40 atomicFormats
.Store(append(formats
, format
{name
, magic
, decode
, decodeConfig
}))
44 // A reader is an io.Reader that can also peek ahead.
45 type reader
interface {
47 Peek(int) ([]byte, error
)
50 // asReader converts an io.Reader to a reader.
51 func asReader(r io
.Reader
) reader
{
52 if rr
, ok
:= r
.(reader
); ok
{
55 return bufio
.NewReader(r
)
58 // Match reports whether magic matches b. Magic may contain "?" wildcards.
59 func match(magic
string, b
[]byte) bool {
60 if len(magic
) != len(b
) {
64 if magic
[i
] != c
&& magic
[i
] != '?' {
71 // Sniff determines the format of r's data.
72 func sniff(r reader
) format
{
73 formats
, _
:= atomicFormats
.Load().([]format
)
74 for _
, f
:= range formats
{
75 b
, err
:= r
.Peek(len(f
.magic
))
76 if err
== nil && match(f
.magic
, b
) {
83 // Decode decodes an image that has been encoded in a registered format.
84 // The string returned is the format name used during format registration.
85 // Format registration is typically done by an init function in the codec-
87 func Decode(r io
.Reader
) (Image
, string, error
) {
91 return nil, "", ErrFormat
93 m
, err
:= f
.decode(rr
)
97 // DecodeConfig decodes the color model and dimensions of an image that has
98 // been encoded in a registered format. The string returned is the format name
99 // used during format registration. Format registration is typically done by
100 // an init function in the codec-specific package.
101 func DecodeConfig(r io
.Reader
) (Config
, string, error
) {
104 if f
.decodeConfig
== nil {
105 return Config
{}, "", ErrFormat
107 c
, err
:= f
.decodeConfig(rr
)
108 return c
, f
.name
, err