Merge from mainline (167278:168000).
[official-gcc/graphite-test-results.git] / libgo / go / image / format.go
blob1d541b0940669d3efcb385ee96db5fe0e5e25e52
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.
5 package image
7 import (
8 "bufio"
9 "io"
10 "os"
13 // An UnknownFormatErr indicates that decoding encountered an unknown format.
14 var UnknownFormatErr = os.NewError("image: unknown format")
16 // A format holds an image format's name, magic header and how to decode it.
17 type format struct {
18 name, magic string
19 decode func(io.Reader) (Image, os.Error)
20 decodeConfig func(io.Reader) (Config, os.Error)
23 // Formats is the list of registered formats.
24 var formats []format
26 // RegisterFormat registers an image format for use by Decode.
27 // Name is the name of the format, like "jpeg" or "png".
28 // Magic is the magic prefix that identifies the format's encoding.
29 // Decode is the function that decodes the encoded image.
30 // DecodeConfig is the function that decodes just its configuration.
31 func RegisterFormat(name, magic string, decode func(io.Reader) (Image, os.Error), decodeConfig func(io.Reader) (Config, os.Error)) {
32 formats = append(formats, format{name, magic, decode, decodeConfig})
35 // A reader is an io.Reader that can also peek ahead.
36 type reader interface {
37 io.Reader
38 Peek(int) ([]byte, os.Error)
41 // AsReader converts an io.Reader to a reader.
42 func asReader(r io.Reader) reader {
43 if rr, ok := r.(reader); ok {
44 return rr
46 return bufio.NewReader(r)
49 // sniff determines the format of r's data.
50 func sniff(r reader) format {
51 for _, f := range formats {
52 s, err := r.Peek(len(f.magic))
53 if err == nil && string(s) == f.magic {
54 return f
57 return format{}
60 // Decode decodes an image that has been encoded in a registered format.
61 // The string returned is the format name used during format registration.
62 // Format registration is typically done by the init method of the codec-
63 // specific package.
64 func Decode(r io.Reader) (Image, string, os.Error) {
65 rr := asReader(r)
66 f := sniff(rr)
67 if f.decode == nil {
68 return nil, "", UnknownFormatErr
70 m, err := f.decode(rr)
71 return m, f.name, err
74 // DecodeConfig decodes the color model and dimensions of an image that has
75 // been encoded in a registered format. The string returned is the format name
76 // used during format registration. Format registration is typically done by
77 // the init method of the codec-specific package.
78 func DecodeConfig(r io.Reader) (Config, string, os.Error) {
79 rr := asReader(r)
80 f := sniff(rr)
81 if f.decodeConfig == nil {
82 return Config{}, "", UnknownFormatErr
84 c, err := f.decodeConfig(rr)
85 return c, f.name, err