From 893fdbbe5dc2f9b887cd635a3d39283d444d8073 Mon Sep 17 00:00:00 2001 From: Nigel Tao Date: Mon, 9 Aug 2010 10:44:38 +1000 Subject: [PATCH] image: introduce Decode and RegisterFormat. R=r, rsc CC=golang-dev https://golang.org/cl/1849054 --- src/pkg/image/Makefile | 1 + src/pkg/image/format.go | 73 ++++++++++++++++++++++++++++++++++++ src/pkg/image/jpeg/reader.go | 4 ++ src/pkg/image/png/reader.go | 4 ++ 4 files changed, 82 insertions(+) create mode 100644 src/pkg/image/format.go diff --git a/src/pkg/image/Makefile b/src/pkg/image/Makefile index 9c886f9f9f..e26deeac67 100644 --- a/src/pkg/image/Makefile +++ b/src/pkg/image/Makefile @@ -7,6 +7,7 @@ include ../../Make.$(GOARCH) TARG=image GOFILES=\ color.go\ + format.go\ image.go\ names.go\ diff --git a/src/pkg/image/format.go b/src/pkg/image/format.go new file mode 100644 index 0000000000..b20f02e98c --- /dev/null +++ b/src/pkg/image/format.go @@ -0,0 +1,73 @@ +// Copyright 2010 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package image + +import ( + "bufio" + "io" + "os" +) + +// An UnknownFormatErr indicates that decoding encountered an unknown format. +var UnknownFormatErr = os.NewError("image: unknown format") + +// A format holds an image format's name, magic header and how to decode it. +type format struct { + name, magic string + decode func(io.Reader) (Image, os.Error) +} + +// Formats is the list of registered formats. +var formats []format + +// RegisterFormat registers an image format for use by Decode. +// Name is the name of the format, like "jpeg" or "png". +// Magic is the magic prefix that identifies the format's encoding. +// Decode is the function that decodes the encoded image. +func RegisterFormat(name, magic string, decode func(io.Reader) (Image, os.Error)) { + n := len(formats) + if n == cap(formats) { + x := make([]format, n+1, 2*n+4) + copy(x, formats) + formats = x + } else { + formats = formats[0 : n+1] + } + formats[n] = format{name, magic, decode} +} + +// A reader is an io.Reader that can also peek ahead. +type reader interface { + io.Reader + Peek(int) ([]byte, os.Error) +} + +// AsReader converts an io.Reader to a reader. +func asReader(r io.Reader) reader { + if rr, ok := r.(reader); ok { + return rr + } + return bufio.NewReader(r) +} + +// Decode decodes an image that has been encoded in a registered format. +// Format registration is typically done by the init method of the codec- +// specific package. +func Decode(r io.Reader) (m Image, formatName string, err os.Error) { + var f format + rr := asReader(r) + for _, g := range formats { + s, err := rr.Peek(len(g.magic)) + if err == nil && string(s) == g.magic { + f = g + break + } + } + if f.decode == nil { + return nil, "", UnknownFormatErr + } + m, err = f.decode(rr) + return m, f.name, err +} diff --git a/src/pkg/image/jpeg/reader.go b/src/pkg/image/jpeg/reader.go index ec036ef4d6..55cc89aa31 100644 --- a/src/pkg/image/jpeg/reader.go +++ b/src/pkg/image/jpeg/reader.go @@ -432,3 +432,7 @@ func Decode(r io.Reader) (image.Image, os.Error) { } return d.image, nil } + +func init() { + image.RegisterFormat("jpeg", "\xff\xd8", Decode) +} diff --git a/src/pkg/image/png/reader.go b/src/pkg/image/png/reader.go index fddb70423a..b23aa7071a 100644 --- a/src/pkg/image/png/reader.go +++ b/src/pkg/image/png/reader.go @@ -464,3 +464,7 @@ func Decode(r io.Reader) (image.Image, os.Error) { } return d.image, nil } + +func init() { + image.RegisterFormat("png", pngHeader, Decode) +} -- 2.48.1