Commit a2846e65 authored by Nigel Tao's avatar Nigel Tao

image: spin off a new color package out of the image package.

The spin-off renames some types. The new names are simply better:
image.Color              -> color.Color
image.ColorModel         -> color.Model
image.ColorModelFunc     -> color.ModelFunc
image.PalettedColorModel -> color.Palette
image.RGBAColor          -> color.RGBA
image.RGBAColorModel     -> color.RGBAModel
image.RGBA64Color        -> color.RGBA64
image.RGBA64ColorModel   -> color.RGBA64Model
(similarly for NRGBAColor, GrayColorModel, etc)

The image.ColorImage type stays in the image package, but is renamed:
image.ColorImage -> image.Uniform

The image.Image implementations (image.RGBA, image.RGBA64, image.NRGBA,
image.Alpha, etc) do not change their name, and gain a nice symmetry:
an image.RGBA is an image of color.RGBA, etc.

The image.Black, image.Opaque uniform images remain unchanged (although
their type is renamed from image.ColorImage to image.Uniform). The
corresponding color types (color.Black, color.Opaque, etc) are new.

Nothing in the image/ycbcr is renamed yet. The ycbcr.YCbCrColor and
ycbcr.YCbCrImage types will eventually migrate to color.YCbCr and
image.YCbCr, but that will be a separate CL.

R=r, bsiegert
CC=golang-dev
https://golang.org/cl/5132048
parent 934c7680
......@@ -12,6 +12,7 @@ GOFILES=\
httpfs.go\
httpheaders.go\
httpserver.go\
imagecolor.go\
imagenew.go\
iocopyn.go\
main.go\
......
// Copyright 2011 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 main
import (
"go/ast"
)
func init() {
register(fix{
"color",
color,
`Adapt code to types moved from image to color.
http://codereview.appspot.com/5132048
`,
})
}
var colorRenames = []struct{ in, out string }{
{"Color", "Color"},
{"ColorModel", "Model"},
{"ColorModelFunc", "ModelFunc"},
{"PalettedColorModel", "Palette"},
{"RGBAColor", "RGBA"},
{"RGBA64Color", "RGBA64"},
{"NRGBAColor", "NRGBA"},
{"NRGBA64Color", "NRGBA64"},
{"AlphaColor", "Alpha"},
{"Alpha16Color", "Alpha16"},
{"GrayColor", "Gray"},
{"Gray16Color", "Gray16"},
{"RGBAColorModel", "RGBAModel"},
{"RGBA64ColorModel", "RGBA64Model"},
{"NRGBAColorModel", "NRGBAModel"},
{"NRGBA64ColorModel", "NRGBA64Model"},
{"AlphaColorModel", "AlphaModel"},
{"Alpha16ColorModel", "Alpha16Model"},
{"GrayColorModel", "GrayModel"},
{"Gray16ColorModel", "Gray16Model"},
}
func color(f *ast.File) (fixed bool) {
if !imports(f, "image") {
return
}
importColor := false
walk(f, func(n interface{}) {
s, ok := n.(*ast.SelectorExpr)
if !ok || !isTopName(s.X, "image") {
return
}
switch sel := s.Sel.String(); {
case sel == "ColorImage":
s.Sel = &ast.Ident{Name: "Uniform"}
fixed = true
case sel == "NewColorImage":
s.Sel = &ast.Ident{Name: "NewUniform"}
fixed = true
default:
for _, rename := range colorRenames {
if sel == rename.in {
s.X.(*ast.Ident).Name = "color"
s.Sel.Name = rename.out
fixed = true
importColor = true
}
}
}
})
if importColor {
addImport(f, "image/color")
if !usesImport(f, "image") {
deleteImport(f, "image")
}
}
return
}
// Copyright 2011 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 main
func init() {
addTestCases(colorTests)
}
var colorTests = []testCase{
{
Name: "color.0",
In: `package main
import (
"image"
)
var (
_ image.Image
_ image.RGBA
_ image.Black
_ image.Color
_ image.ColorModel
_ image.ColorModelFunc
_ image.PalettedColorModel
_ image.RGBAColor
_ image.RGBA64Color
_ image.NRGBAColor
_ image.NRGBA64Color
_ image.AlphaColor
_ image.Alpha16Color
_ image.GrayColor
_ image.Gray16Color
)
func f() {
_ = image.RGBAColorModel
_ = image.RGBA64ColorModel
_ = image.NRGBAColorModel
_ = image.NRGBA64ColorModel
_ = image.AlphaColorModel
_ = image.Alpha16ColorModel
_ = image.GrayColorModel
_ = image.Gray16ColorModel
}
`,
Out: `package main
import (
"image"
"image/color"
)
var (
_ image.Image
_ image.RGBA
_ image.Black
_ color.Color
_ color.Model
_ color.ModelFunc
_ color.Palette
_ color.RGBA
_ color.RGBA64
_ color.NRGBA
_ color.NRGBA64
_ color.Alpha
_ color.Alpha16
_ color.Gray
_ color.Gray16
)
func f() {
_ = color.RGBAModel
_ = color.RGBA64Model
_ = color.NRGBAModel
_ = color.NRGBA64Model
_ = color.AlphaModel
_ = color.Alpha16Model
_ = color.GrayModel
_ = color.Gray16Model
}
`,
},
{
Name: "color.1",
In: `package main
import (
"fmt"
"image"
)
func f() {
fmt.Println(image.RGBAColor{1, 2, 3, 4}.RGBA())
}
`,
Out: `package main
import (
"fmt"
"image/color"
)
func f() {
fmt.Println(color.RGBA{1, 2, 3, 4}.RGBA())
}
`,
},
{
Name: "color.2",
In: `package main
import "image"
var c *image.ColorImage = image.NewColorImage(nil)
`,
Out: `package main
import "image"
var c *image.Uniform = image.NewUniform(nil)
`,
},
}
......@@ -26,8 +26,7 @@ func f() {
image.NewAlpha16(1, 2)
image.NewGray(1, 2)
image.NewGray16(1, 2)
var m image.PalettedColorModel
image.NewPaletted(1, 2, m)
image.NewPaletted(1, 2, nil)
}
`,
Out: `package main
......@@ -45,8 +44,7 @@ func f() {
image.NewAlpha16(image.Rect(0, 0, 1, 2))
image.NewGray(image.Rect(0, 0, 1, 2))
image.NewGray16(image.Rect(0, 0, 1, 2))
var m image.PalettedColorModel
image.NewPaletted(image.Rect(0, 0, 1, 2), m)
image.NewPaletted(image.Rect(0, 0, 1, 2), nil)
}
`,
},
......
......@@ -112,6 +112,7 @@ DIRS=\
http/spdy\
image\
image/bmp\
image/color\
image/draw\
image/gif\
image/jpeg\
......@@ -212,6 +213,7 @@ NOTEST+=\
http/pprof\
http/httptest\
image/bmp\
image/color\
image/gif\
net/dict\
rand\
......
......@@ -6,7 +6,6 @@ include ../../Make.inc
TARG=image
GOFILES=\
color.go\
format.go\
geom.go\
image.go\
......
......@@ -8,6 +8,7 @@
package bmp
import (
"image/color"
"image"
"io"
"os"
......@@ -28,7 +29,7 @@ func readUint32(b []byte) uint32 {
// decodePaletted reads an 8 bit-per-pixel BMP image from r.
func decodePaletted(r io.Reader, c image.Config) (image.Image, os.Error) {
var tmp [4]byte
paletted := image.NewPaletted(image.Rect(0, 0, c.Width, c.Height), c.ColorModel.(image.PalettedColorModel))
paletted := image.NewPaletted(image.Rect(0, 0, c.Width, c.Height), c.ColorModel.(color.Palette))
// BMP images are stored bottom-up rather than top-down.
for y := c.Height - 1; y >= 0; y-- {
p := paletted.Pix[y*paletted.Stride : y*paletted.Stride+c.Width]
......@@ -77,7 +78,7 @@ func Decode(r io.Reader) (image.Image, os.Error) {
if err != nil {
return nil, err
}
if c.ColorModel == image.RGBAColorModel {
if c.ColorModel == color.RGBAModel {
return decodeRGBA(r, c)
}
return decodePaletted(r, c)
......@@ -128,11 +129,11 @@ func DecodeConfig(r io.Reader) (config image.Config, err os.Error) {
if err != nil {
return
}
pcm := make(image.PalettedColorModel, 256)
pcm := make(color.Palette, 256)
for i := range pcm {
// BMP images are stored in BGR order rather than RGB order.
// Every 4th byte is padding.
pcm[i] = image.RGBAColor{b[4*i+2], b[4*i+1], b[4*i+0], 0xFF}
pcm[i] = color.RGBA{b[4*i+2], b[4*i+1], b[4*i+0], 0xFF}
}
return image.Config{pcm, width, height}, nil
case 24:
......@@ -140,7 +141,7 @@ func DecodeConfig(r io.Reader) (config image.Config, err os.Error) {
err = ErrUnsupported
return
}
return image.Config{image.RGBAColorModel, width, height}, nil
return image.Config{color.RGBAModel, width, height}, nil
}
err = ErrUnsupported
return
......
# Copyright 2011 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.
include ../../../Make.inc
TARG=image/color
GOFILES=\
color.go\
include ../../../Make.pkg
// Copyright 2011 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 color implements a basic color library.
package color
// Color can convert itself to alpha-premultiplied 16-bits per channel RGBA.
// The conversion may be lossy.
type Color interface {
// RGBA returns the alpha-premultiplied red, green, blue and alpha values
// for the color. Each value ranges within [0, 0xFFFF], but is represented
// by a uint32 so that multiplying by a blend factor up to 0xFFFF will not
// overflow.
RGBA() (r, g, b, a uint32)
}
// RGBA represents a traditional 32-bit alpha-premultiplied color,
// having 8 bits for each of red, green, blue and alpha.
type RGBA struct {
R, G, B, A uint8
}
func (c RGBA) RGBA() (r, g, b, a uint32) {
r = uint32(c.R)
r |= r << 8
g = uint32(c.G)
g |= g << 8
b = uint32(c.B)
b |= b << 8
a = uint32(c.A)
a |= a << 8
return
}
// RGBA64 represents a 64-bit alpha-premultiplied color,
// having 16 bits for each of red, green, blue and alpha.
type RGBA64 struct {
R, G, B, A uint16
}
func (c RGBA64) RGBA() (r, g, b, a uint32) {
return uint32(c.R), uint32(c.G), uint32(c.B), uint32(c.A)
}
// NRGBA represents a non-alpha-premultiplied 32-bit color.
type NRGBA struct {
R, G, B, A uint8
}
func (c NRGBA) RGBA() (r, g, b, a uint32) {
r = uint32(c.R)
r |= r << 8
r *= uint32(c.A)
r /= 0xff
g = uint32(c.G)
g |= g << 8
g *= uint32(c.A)
g /= 0xff
b = uint32(c.B)
b |= b << 8
b *= uint32(c.A)
b /= 0xff
a = uint32(c.A)
a |= a << 8
return
}
// NRGBA64 represents a non-alpha-premultiplied 64-bit color,
// having 16 bits for each of red, green, blue and alpha.
type NRGBA64 struct {
R, G, B, A uint16
}
func (c NRGBA64) RGBA() (r, g, b, a uint32) {
r = uint32(c.R)
r *= uint32(c.A)
r /= 0xffff
g = uint32(c.G)
g *= uint32(c.A)
g /= 0xffff
b = uint32(c.B)
b *= uint32(c.A)
b /= 0xffff
a = uint32(c.A)
return
}
// Alpha represents an 8-bit alpha color.
type Alpha struct {
A uint8
}
func (c Alpha) RGBA() (r, g, b, a uint32) {
a = uint32(c.A)
a |= a << 8
return a, a, a, a
}
// Alpha16 represents a 16-bit alpha color.
type Alpha16 struct {
A uint16
}
func (c Alpha16) RGBA() (r, g, b, a uint32) {
a = uint32(c.A)
return a, a, a, a
}
// Gray represents an 8-bit grayscale color.
type Gray struct {
Y uint8
}
func (c Gray) RGBA() (r, g, b, a uint32) {
y := uint32(c.Y)
y |= y << 8
return y, y, y, 0xffff
}
// Gray16 represents a 16-bit grayscale color.
type Gray16 struct {
Y uint16
}
func (c Gray16) RGBA() (r, g, b, a uint32) {
y := uint32(c.Y)
return y, y, y, 0xffff
}
// Model can convert any Color to one from its own color model. The conversion
// may be lossy.
type Model interface {
Convert(c Color) Color
}
// ModelFunc is an adapter type to allow the use of a color conversion
// function as a Model. If f is such a function, ModelFunc(f) is a Model that
// invokes f to implement the conversion.
type ModelFunc func(Color) Color
func (f ModelFunc) Convert(c Color) Color {
return f(c)
}
// RGBAModel is the Model for RGBA colors.
var RGBAModel Model = ModelFunc(func(c Color) Color {
if _, ok := c.(RGBA); ok {
return c
}
r, g, b, a := c.RGBA()
return RGBA{uint8(r >> 8), uint8(g >> 8), uint8(b >> 8), uint8(a >> 8)}
})
// RGBAModel is the Model for RGBA64 colors.
var RGBA64Model Model = ModelFunc(func(c Color) Color {
if _, ok := c.(RGBA64); ok {
return c
}
r, g, b, a := c.RGBA()
return RGBA64{uint16(r), uint16(g), uint16(b), uint16(a)}
})
// NRGBAModel is the Model for NRGBA colors.
var NRGBAModel Model = ModelFunc(func(c Color) Color {
if _, ok := c.(NRGBA); ok {
return c
}
r, g, b, a := c.RGBA()
if a == 0xffff {
return NRGBA{uint8(r >> 8), uint8(g >> 8), uint8(b >> 8), 0xff}
}
if a == 0 {
return NRGBA{0, 0, 0, 0}
}
// Since Color.RGBA returns a alpha-premultiplied color, we should have r <= a && g <= a && b <= a.
r = (r * 0xffff) / a
g = (g * 0xffff) / a
b = (b * 0xffff) / a
return NRGBA{uint8(r >> 8), uint8(g >> 8), uint8(b >> 8), uint8(a >> 8)}
})
// NRGBAModel is the Model for NRGBA64 colors.
var NRGBA64Model Model = ModelFunc(func(c Color) Color {
if _, ok := c.(NRGBA64); ok {
return c
}
r, g, b, a := c.RGBA()
if a == 0xffff {
return NRGBA64{uint16(r), uint16(g), uint16(b), 0xffff}
}
if a == 0 {
return NRGBA64{0, 0, 0, 0}
}
// Since Color.RGBA returns a alpha-premultiplied color, we should have r <= a && g <= a && b <= a.
r = (r * 0xffff) / a
g = (g * 0xffff) / a
b = (b * 0xffff) / a
return NRGBA64{uint16(r), uint16(g), uint16(b), uint16(a)}
})
// AlphaModel is the Model for Alpha colors.
var AlphaModel Model = ModelFunc(func(c Color) Color {
if _, ok := c.(Alpha); ok {
return c
}
_, _, _, a := c.RGBA()
return Alpha{uint8(a >> 8)}
})
// Alpha16Model is the Model for Alpha16 colors.
var Alpha16Model Model = ModelFunc(func(c Color) Color {
if _, ok := c.(Alpha16); ok {
return c
}
_, _, _, a := c.RGBA()
return Alpha16{uint16(a)}
})
// GrayModel is the Model for Gray colors.
var GrayModel Model = ModelFunc(func(c Color) Color {
if _, ok := c.(Gray); ok {
return c
}
r, g, b, _ := c.RGBA()
y := (299*r + 587*g + 114*b + 500) / 1000
return Gray{uint8(y >> 8)}
})
// Gray16Model is the Model for Gray16 colors.
var Gray16Model Model = ModelFunc(func(c Color) Color {
if _, ok := c.(Gray16); ok {
return c
}
r, g, b, _ := c.RGBA()
y := (299*r + 587*g + 114*b + 500) / 1000
return Gray16{uint16(y)}
})
// Palette is a palette of colors.
type Palette []Color
func diff(a, b uint32) uint32 {
if a > b {
return a - b
}
return b - a
}
// Convert returns the palette color closest to c in Euclidean R,G,B space.
func (p Palette) Convert(c Color) Color {
if len(p) == 0 {
return nil
}
return p[p.Index(c)]
}
// Index returns the index of the palette color closest to c in Euclidean
// R,G,B space.
func (p Palette) Index(c Color) int {
cr, cg, cb, _ := c.RGBA()
// Shift by 1 bit to avoid potential uint32 overflow in sum-squared-difference.
cr >>= 1
cg >>= 1
cb >>= 1
ret, bestSSD := 0, uint32(1<<32-1)
for i, v := range p {
vr, vg, vb, _ := v.RGBA()
vr >>= 1
vg >>= 1
vb >>= 1
dr, dg, db := diff(cr, vr), diff(cg, vg), diff(cb, vb)
ssd := (dr * dr) + (dg * dg) + (db * db)
if ssd < bestSSD {
if ssd == 0 {
return i
}
ret, bestSSD = i, ssd
}
}
return ret
}
var (
// Black is an opaque black Color.
Black = Gray16{0}
// White is an opaque white Color.
White = Gray16{0xffff}
// Transparent is a fully transparent Color.
Transparent = Alpha16{0}
// Opaque is a fully opaque Color.
Opaque = Alpha16{0xffff}
)
......@@ -7,6 +7,7 @@ package image_test
import (
"bufio"
"image"
"image/color"
"os"
"testing"
......@@ -66,7 +67,7 @@ func delta(u0, u1 uint32) int {
return d
}
func withinTolerance(c0, c1 image.Color, tolerance int) bool {
func withinTolerance(c0, c1 color.Color, tolerance int) bool {
r0, g0, b0, a0 := c0.RGBA()
r1, g1, b1, a1 := c1.RGBA()
r := delta(r0, r1)
......
......@@ -6,6 +6,7 @@ package draw
import (
"image"
"image/color"
"image/ycbcr"
"testing"
)
......@@ -18,16 +19,16 @@ const (
// bench benchmarks drawing src and mask images onto a dst image with the
// given op and the color models to create those images from.
// The created images' pixels are initialized to non-zero values.
func bench(b *testing.B, dcm, scm, mcm image.ColorModel, op Op) {
func bench(b *testing.B, dcm, scm, mcm color.Model, op Op) {
b.StopTimer()
var dst Image
switch dcm {
case image.RGBAColorModel:
case color.RGBAModel:
dst1 := image.NewRGBA(image.Rect(0, 0, dstw, dsth))
for y := 0; y < dsth; y++ {
for x := 0; x < dstw; x++ {
dst1.SetRGBA(x, y, image.RGBAColor{
dst1.SetRGBA(x, y, color.RGBA{
uint8(5 * x % 0x100),
uint8(7 * y % 0x100),
uint8((7*x + 5*y) % 0x100),
......@@ -36,11 +37,11 @@ func bench(b *testing.B, dcm, scm, mcm image.ColorModel, op Op) {
}
}
dst = dst1
case image.RGBA64ColorModel:
case color.RGBA64Model:
dst1 := image.NewRGBA64(image.Rect(0, 0, dstw, dsth))
for y := 0; y < dsth; y++ {
for x := 0; x < dstw; x++ {
dst1.SetRGBA64(x, y, image.RGBA64Color{
dst1.SetRGBA64(x, y, color.RGBA64{
uint16(53 * x % 0x10000),
uint16(59 * y % 0x10000),
uint16((59*x + 53*y) % 0x10000),
......@@ -56,12 +57,12 @@ func bench(b *testing.B, dcm, scm, mcm image.ColorModel, op Op) {
var src image.Image
switch scm {
case nil:
src = &image.ColorImage{image.RGBAColor{0x11, 0x22, 0x33, 0xff}}
case image.RGBAColorModel:
src = &image.Uniform{color.RGBA{0x11, 0x22, 0x33, 0xff}}
case color.RGBAModel:
src1 := image.NewRGBA(image.Rect(0, 0, srcw, srch))
for y := 0; y < srch; y++ {
for x := 0; x < srcw; x++ {
src1.SetRGBA(x, y, image.RGBAColor{
src1.SetRGBA(x, y, color.RGBA{
uint8(13 * x % 0x80),
uint8(11 * y % 0x80),
uint8((11*x + 13*y) % 0x80),
......@@ -70,11 +71,11 @@ func bench(b *testing.B, dcm, scm, mcm image.ColorModel, op Op) {
}
}
src = src1
case image.RGBA64ColorModel:
case color.RGBA64Model:
src1 := image.NewRGBA64(image.Rect(0, 0, srcw, srch))
for y := 0; y < srch; y++ {
for x := 0; x < srcw; x++ {
src1.SetRGBA64(x, y, image.RGBA64Color{
src1.SetRGBA64(x, y, color.RGBA64{
uint16(103 * x % 0x8000),
uint16(101 * y % 0x8000),
uint16((101*x + 103*y) % 0x8000),
......@@ -83,11 +84,11 @@ func bench(b *testing.B, dcm, scm, mcm image.ColorModel, op Op) {
}
}
src = src1
case image.NRGBAColorModel:
case color.NRGBAModel:
src1 := image.NewNRGBA(image.Rect(0, 0, srcw, srch))
for y := 0; y < srch; y++ {
for x := 0; x < srcw; x++ {
src1.SetNRGBA(x, y, image.NRGBAColor{
src1.SetNRGBA(x, y, color.NRGBA{
uint8(13 * x % 0x100),
uint8(11 * y % 0x100),
uint8((11*x + 13*y) % 0x100),
......@@ -122,7 +123,7 @@ func bench(b *testing.B, dcm, scm, mcm image.ColorModel, op Op) {
switch mcm {
case nil:
// No-op.
case image.AlphaColorModel:
case color.AlphaModel:
mask1 := image.NewAlpha(image.Rect(0, 0, srcw, srch))
for y := 0; y < srch; y++ {
for x := 0; x < srcw; x++ {
......@@ -130,7 +131,7 @@ func bench(b *testing.B, dcm, scm, mcm image.ColorModel, op Op) {
// Glyph masks are typically mostly zero,
// so we only set a quarter of mask1's pixels.
if a >= 0xc0 {
mask1.SetAlpha(x, y, image.AlphaColor{a})
mask1.SetAlpha(x, y, color.Alpha{a})
}
}
}
......@@ -152,55 +153,55 @@ func bench(b *testing.B, dcm, scm, mcm image.ColorModel, op Op) {
// The BenchmarkFoo functions exercise a drawFoo fast-path function in draw.go.
func BenchmarkFillOver(b *testing.B) {
bench(b, image.RGBAColorModel, nil, nil, Over)
bench(b, color.RGBAModel, nil, nil, Over)
}
func BenchmarkFillSrc(b *testing.B) {
bench(b, image.RGBAColorModel, nil, nil, Src)
bench(b, color.RGBAModel, nil, nil, Src)
}
func BenchmarkCopyOver(b *testing.B) {
bench(b, image.RGBAColorModel, image.RGBAColorModel, nil, Over)
bench(b, color.RGBAModel, color.RGBAModel, nil, Over)
}
func BenchmarkCopySrc(b *testing.B) {
bench(b, image.RGBAColorModel, image.RGBAColorModel, nil, Src)
bench(b, color.RGBAModel, color.RGBAModel, nil, Src)
}
func BenchmarkNRGBAOver(b *testing.B) {
bench(b, image.RGBAColorModel, image.NRGBAColorModel, nil, Over)
bench(b, color.RGBAModel, color.NRGBAModel, nil, Over)
}
func BenchmarkNRGBASrc(b *testing.B) {
bench(b, image.RGBAColorModel, image.NRGBAColorModel, nil, Src)
bench(b, color.RGBAModel, color.NRGBAModel, nil, Src)
}
func BenchmarkYCbCr(b *testing.B) {
bench(b, image.RGBAColorModel, ycbcr.YCbCrColorModel, nil, Over)
bench(b, color.RGBAModel, ycbcr.YCbCrColorModel, nil, Over)
}
func BenchmarkGlyphOver(b *testing.B) {
bench(b, image.RGBAColorModel, nil, image.AlphaColorModel, Over)
bench(b, color.RGBAModel, nil, color.AlphaModel, Over)
}
func BenchmarkRGBA(b *testing.B) {
bench(b, image.RGBAColorModel, image.RGBA64ColorModel, nil, Src)
bench(b, color.RGBAModel, color.RGBA64Model, nil, Src)
}
// The BenchmarkGenericFoo functions exercise the generic, slow-path code.
func BenchmarkGenericOver(b *testing.B) {
bench(b, image.RGBA64ColorModel, image.RGBA64ColorModel, nil, Over)
bench(b, color.RGBA64Model, color.RGBA64Model, nil, Over)
}
func BenchmarkGenericMaskOver(b *testing.B) {
bench(b, image.RGBA64ColorModel, image.RGBA64ColorModel, image.AlphaColorModel, Over)
bench(b, color.RGBA64Model, color.RGBA64Model, color.AlphaModel, Over)
}
func BenchmarkGenericSrc(b *testing.B) {
bench(b, image.RGBA64ColorModel, image.RGBA64ColorModel, nil, Src)
bench(b, color.RGBA64Model, color.RGBA64Model, nil, Src)
}
func BenchmarkGenericMaskSrc(b *testing.B) {
bench(b, image.RGBA64ColorModel, image.RGBA64ColorModel, image.AlphaColorModel, Src)
bench(b, color.RGBA64Model, color.RGBA64Model, color.AlphaModel, Src)
}
......@@ -10,6 +10,7 @@ package draw
import (
"image"
"image/color"
"image/ycbcr"
)
......@@ -26,12 +27,10 @@ const (
Src
)
var zeroColor image.Color = image.AlphaColor{0}
// A draw.Image is an image.Image with a Set method to change a single pixel.
type Image interface {
image.Image
Set(x, y int, c image.Color)
Set(x, y int, c color.Color)
}
// Draw calls DrawMask with a nil mask.
......@@ -73,7 +72,7 @@ func DrawMask(dst Image, r image.Rectangle, src image.Image, sp image.Point, mas
if op == Over {
if mask == nil {
switch src0 := src.(type) {
case *image.ColorImage:
case *image.Uniform:
drawFillOver(dst0, r, src0)
return
case *image.RGBA:
......@@ -88,7 +87,7 @@ func DrawMask(dst Image, r image.Rectangle, src image.Image, sp image.Point, mas
}
} else if mask0, ok := mask.(*image.Alpha); ok {
switch src0 := src.(type) {
case *image.ColorImage:
case *image.Uniform:
drawGlyphOver(dst0, r, src0, mask0, mp)
return
}
......@@ -96,7 +95,7 @@ func DrawMask(dst Image, r image.Rectangle, src image.Image, sp image.Point, mas
} else {
if mask == nil {
switch src0 := src.(type) {
case *image.ColorImage:
case *image.Uniform:
drawFillSrc(dst0, r, src0)
return
case *image.RGBA:
......@@ -125,7 +124,7 @@ func DrawMask(dst Image, r image.Rectangle, src image.Image, sp image.Point, mas
}
}
var out *image.RGBA64Color
var out *color.RGBA64
sy := sp.Y + y0 - r.Min.Y
my := mp.Y + y0 - r.Min.Y
for y := y0; y != y1; y, sy, my = y+dy, sy+dy, my+dy {
......@@ -141,14 +140,14 @@ func DrawMask(dst Image, r image.Rectangle, src image.Image, sp image.Point, mas
if op == Over {
// No-op.
} else {
dst.Set(x, y, zeroColor)
dst.Set(x, y, color.Transparent)
}
case ma == m && op == Src:
dst.Set(x, y, src.At(sx, sy))
default:
sr, sg, sb, sa := src.At(sx, sy).RGBA()
if out == nil {
out = new(image.RGBA64Color)
out = new(color.RGBA64)
}
if op == Over {
dr, dg, db, da := dst.At(x, y).RGBA()
......@@ -169,7 +168,7 @@ func DrawMask(dst Image, r image.Rectangle, src image.Image, sp image.Point, mas
}
}
func drawFillOver(dst *image.RGBA, r image.Rectangle, src *image.ColorImage) {
func drawFillOver(dst *image.RGBA, r image.Rectangle, src *image.Uniform) {
sr, sg, sb, sa := src.RGBA()
// The 0x101 is here for the same reason as in drawRGBA.
a := (m - sa) * 0x101
......@@ -192,7 +191,7 @@ func drawFillOver(dst *image.RGBA, r image.Rectangle, src *image.ColorImage) {
}
}
func drawFillSrc(dst *image.RGBA, r image.Rectangle, src *image.ColorImage) {
func drawFillSrc(dst *image.RGBA, r image.Rectangle, src *image.Uniform) {
sr, sg, sb, sa := src.RGBA()
// The built-in copy function is faster than a straightforward for loop to fill the destination with
// the color, but copy requires a slice source. We therefore use a for loop to fill the first row, and
......@@ -406,7 +405,7 @@ func drawYCbCr(dst *image.RGBA, r image.Rectangle, src *ycbcr.YCbCr, sp image.Po
}
}
func drawGlyphOver(dst *image.RGBA, r image.Rectangle, src *image.ColorImage, mask *image.Alpha, mp image.Point) {
func drawGlyphOver(dst *image.RGBA, r image.Rectangle, src *image.Uniform, mask *image.Alpha, mp image.Point) {
i0 := (r.Min.Y-dst.Rect.Min.Y)*dst.Stride + (r.Min.X-dst.Rect.Min.X)*4
i1 := i0 + r.Dx()*4
mi0 := (mp.Y-mask.Rect.Min.Y)*mask.Stride + mp.X - mask.Rect.Min.X
......
This diff is collapsed.
......@@ -12,6 +12,7 @@ import (
"compress/lzw"
"fmt"
"image"
"image/color"
"io"
"os"
)
......@@ -76,7 +77,7 @@ type decoder struct {
// Computed.
pixelSize uint
globalColorMap image.PalettedColorModel
globalColorMap color.Palette
// Used when decoding.
delay []int
......@@ -235,7 +236,7 @@ func (d *decoder) readHeaderAndScreenDescriptor() os.Error {
return nil
}
func (d *decoder) readColorMap() (image.PalettedColorModel, os.Error) {
func (d *decoder) readColorMap() (color.Palette, os.Error) {
if d.pixelSize > 8 {
return nil, fmt.Errorf("gif: can't handle %d bits per pixel", d.pixelSize)
}
......@@ -248,10 +249,10 @@ func (d *decoder) readColorMap() (image.PalettedColorModel, os.Error) {
if err != nil {
return nil, fmt.Errorf("gif: short read on color map: %s", err)
}
colorMap := make(image.PalettedColorModel, numColors)
colorMap := make(color.Palette, numColors)
j := 0
for i := range colorMap {
colorMap[i] = image.RGBAColor{d.tmp[j+0], d.tmp[j+1], d.tmp[j+2], 0xFF}
colorMap[i] = color.RGBA{d.tmp[j+0], d.tmp[j+1], d.tmp[j+2], 0xFF}
j += 3
}
return colorMap, nil
......@@ -319,9 +320,9 @@ func (d *decoder) readGraphicControl() os.Error {
return nil
}
func (d *decoder) setTransparency(colorMap image.PalettedColorModel) {
func (d *decoder) setTransparency(colorMap color.Palette) {
if int(d.transparentIndex) < len(colorMap) {
colorMap[d.transparentIndex] = image.RGBAColor{}
colorMap[d.transparentIndex] = color.RGBA{}
}
}
......
This diff is collapsed.
......@@ -5,17 +5,18 @@
package image
import (
"image/color"
"testing"
)
type image interface {
Image
Opaque() bool
Set(int, int, Color)
Set(int, int, color.Color)
SubImage(Rectangle) Image
}
func cmp(t *testing.T, cm ColorModel, c0, c1 Color) bool {
func cmp(t *testing.T, cm color.Model, c0, c1 color.Color) bool {
r0, g0, b0, a0 := cm.Convert(c0).RGBA()
r1, g1, b1, a1 := cm.Convert(c1).RGBA()
return r0 == r1 && g0 == g1 && b0 == b1 && a0 == a1
......@@ -31,7 +32,7 @@ func TestImage(t *testing.T) {
NewAlpha16(Rect(0, 0, 10, 10)),
NewGray(Rect(0, 0, 10, 10)),
NewGray16(Rect(0, 0, 10, 10)),
NewPaletted(Rect(0, 0, 10, 10), PalettedColorModel{
NewPaletted(Rect(0, 0, 10, 10), color.Palette{
Transparent,
Opaque,
}),
......@@ -81,14 +82,14 @@ func TestImage(t *testing.T) {
}
func Test16BitsPerColorChannel(t *testing.T) {
testColorModel := []ColorModel{
RGBA64ColorModel,
NRGBA64ColorModel,
Alpha16ColorModel,
Gray16ColorModel,
testColorModel := []color.Model{
color.RGBA64Model,
color.NRGBA64Model,
color.Alpha16Model,
color.Gray16Model,
}
for _, cm := range testColorModel {
c := cm.Convert(RGBA64Color{0x1234, 0x1234, 0x1234, 0x1234}) // Premultiplied alpha.
c := cm.Convert(color.RGBA64{0x1234, 0x1234, 0x1234, 0x1234}) // Premultiplied alpha.
r, _, _, _ := c.RGBA()
if r != 0x1234 {
t.Errorf("%T: want red value 0x%04x got 0x%04x", c, 0x1234, r)
......@@ -102,7 +103,7 @@ func Test16BitsPerColorChannel(t *testing.T) {
NewGray16(Rect(0, 0, 10, 10)),
}
for _, m := range testImage {
m.Set(1, 2, NRGBA64Color{0xffff, 0xffff, 0xffff, 0x1357}) // Non-premultiplied alpha.
m.Set(1, 2, color.NRGBA64{0xffff, 0xffff, 0xffff, 0x1357}) // Non-premultiplied alpha.
r, _, _, _ := m.At(1, 2).RGBA()
if r != 0x1357 {
t.Errorf("%T: want red value 0x%04x got 0x%04x", m, 0x1357, r)
......
......@@ -10,6 +10,7 @@ package jpeg
import (
"bufio"
"image"
"image/color"
"image/ycbcr"
"io"
"os"
......@@ -464,7 +465,7 @@ func DecodeConfig(r io.Reader) (image.Config, os.Error) {
}
switch d.nComp {
case nGrayComponent:
return image.Config{image.GrayColorModel, d.width, d.height}, nil
return image.Config{color.GrayModel, d.width, d.height}, nil
case nColorComponent:
return image.Config{ycbcr.YCbCrColorModel, d.width, d.height}, nil
}
......
......@@ -7,6 +7,7 @@ package jpeg
import (
"bytes"
"image"
"image/color"
"image/png"
"io/ioutil"
"rand"
......@@ -96,7 +97,7 @@ func BenchmarkEncodeRGBOpaque(b *testing.B) {
rnd := rand.New(rand.NewSource(123))
for y := bo.Min.Y; y < bo.Max.Y; y++ {
for x := bo.Min.X; x < bo.Max.X; x++ {
img.Set(x, y, image.RGBAColor{
img.Set(x, y, color.RGBA{
uint8(rnd.Intn(256)),
uint8(rnd.Intn(256)),
uint8(rnd.Intn(256)),
......
......@@ -4,43 +4,47 @@
package image
import (
"image/color"
)
var (
// Black is an opaque black ColorImage.
Black = NewColorImage(Gray16Color{0})
// White is an opaque white ColorImage.
White = NewColorImage(Gray16Color{0xffff})
// Transparent is a fully transparent ColorImage.
Transparent = NewColorImage(Alpha16Color{0})
// Opaque is a fully opaque ColorImage.
Opaque = NewColorImage(Alpha16Color{0xffff})
// Black is an opaque black uniform image.
Black = NewUniform(color.Black)
// White is an opaque white uniform image.
White = NewUniform(color.White)
// Transparent is a fully transparent uniform image.
Transparent = NewUniform(color.Transparent)
// Opaque is a fully opaque uniform image.
Opaque = NewUniform(color.Opaque)
)
// A ColorImage is an infinite-sized Image of uniform Color.
// It implements both the Color and Image interfaces.
type ColorImage struct {
C Color
// Uniform is an infinite-sized Image of uniform color.
// It implements both the color.Color and Image interfaces.
type Uniform struct {
C color.Color
}
func (c *ColorImage) RGBA() (r, g, b, a uint32) {
func (c *Uniform) RGBA() (r, g, b, a uint32) {
return c.C.RGBA()
}
func (c *ColorImage) ColorModel() ColorModel {
return ColorModelFunc(func(Color) Color { return c.C })
func (c *Uniform) ColorModel() color.Model {
return color.ModelFunc(func(color.Color) color.Color { return c.C })
}
func (c *ColorImage) Bounds() Rectangle { return Rectangle{Point{-1e9, -1e9}, Point{1e9, 1e9}} }
func (c *Uniform) Bounds() Rectangle { return Rectangle{Point{-1e9, -1e9}, Point{1e9, 1e9}} }
func (c *ColorImage) At(x, y int) Color { return c.C }
func (c *Uniform) At(x, y int) color.Color { return c.C }
// Opaque scans the entire image and returns whether or not it is fully opaque.
func (c *ColorImage) Opaque() bool {
func (c *Uniform) Opaque() bool {
_, _, _, a := c.C.RGBA()
return a == 0xffff
}
func NewColorImage(c Color) *ColorImage {
return &ColorImage{c}
func NewUniform(c color.Color) *Uniform {
return &Uniform{c}
}
// A Tiled is an infinite-sized Image that repeats another Image in both
......@@ -51,13 +55,13 @@ type Tiled struct {
Offset Point
}
func (t *Tiled) ColorModel() ColorModel {
func (t *Tiled) ColorModel() color.Model {
return t.I.ColorModel()
}
func (t *Tiled) Bounds() Rectangle { return Rectangle{Point{-1e9, -1e9}, Point{1e9, 1e9}} }
func (t *Tiled) At(x, y int) Color {
func (t *Tiled) At(x, y int) color.Color {
p := Point{x, y}.Add(t.Offset).Mod(t.I.Bounds())
return t.I.At(p.X, p.Y)
}
......
......@@ -14,6 +14,7 @@ import (
"hash"
"hash/crc32"
"image"
"image/color"
"io"
"os"
)
......@@ -79,7 +80,7 @@ type decoder struct {
crc hash.Hash32
width, height int
depth int
palette image.PalettedColorModel
palette color.Palette
cb int
stage int
idatLength uint32
......@@ -200,9 +201,9 @@ func (d *decoder) parsePLTE(length uint32) os.Error {
d.crc.Write(d.tmp[:n])
switch d.cb {
case cbP1, cbP2, cbP4, cbP8:
d.palette = image.PalettedColorModel(make([]image.Color, np))
d.palette = color.Palette(make([]color.Color, np))
for i := 0; i < np; i++ {
d.palette[i] = image.RGBAColor{d.tmp[3*i+0], d.tmp[3*i+1], d.tmp[3*i+2], 0xff}
d.palette[i] = color.RGBA{d.tmp[3*i+0], d.tmp[3*i+1], d.tmp[3*i+2], 0xff}
}
case cbTC8, cbTCA8, cbTC16, cbTCA16:
// As per the PNG spec, a PLTE chunk is optional (and for practical purposes,
......@@ -232,8 +233,8 @@ func (d *decoder) parsetRNS(length uint32) os.Error {
return FormatError("bad tRNS length")
}
for i := 0; i < n; i++ {
rgba := d.palette[i].(image.RGBAColor)
d.palette[i] = image.RGBAColor{rgba.R, rgba.G, rgba.B, d.tmp[i]}
rgba := d.palette[i].(color.RGBA)
d.palette[i] = color.RGBA{rgba.R, rgba.G, rgba.B, d.tmp[i]}
}
case cbGA8, cbGA16, cbTCA8, cbTCA16:
return FormatError("tRNS, color type mismatch")
......@@ -402,7 +403,7 @@ func (d *decoder) decode() (image.Image, os.Error) {
for x := 0; x < d.width; x += 8 {
b := cdat[x/8]
for x2 := 0; x2 < 8 && x+x2 < d.width; x2++ {
gray.SetGray(x+x2, y, image.GrayColor{(b >> 7) * 0xff})
gray.SetGray(x+x2, y, color.Gray{(b >> 7) * 0xff})
b <<= 1
}
}
......@@ -410,7 +411,7 @@ func (d *decoder) decode() (image.Image, os.Error) {
for x := 0; x < d.width; x += 4 {
b := cdat[x/4]
for x2 := 0; x2 < 4 && x+x2 < d.width; x2++ {
gray.SetGray(x+x2, y, image.GrayColor{(b >> 6) * 0x55})
gray.SetGray(x+x2, y, color.Gray{(b >> 6) * 0x55})
b <<= 2
}
}
......@@ -418,22 +419,22 @@ func (d *decoder) decode() (image.Image, os.Error) {
for x := 0; x < d.width; x += 2 {
b := cdat[x/2]
for x2 := 0; x2 < 2 && x+x2 < d.width; x2++ {
gray.SetGray(x+x2, y, image.GrayColor{(b >> 4) * 0x11})
gray.SetGray(x+x2, y, color.Gray{(b >> 4) * 0x11})
b <<= 4
}
}
case cbG8:
for x := 0; x < d.width; x++ {
gray.SetGray(x, y, image.GrayColor{cdat[x]})
gray.SetGray(x, y, color.Gray{cdat[x]})
}
case cbGA8:
for x := 0; x < d.width; x++ {
ycol := cdat[2*x+0]
nrgba.SetNRGBA(x, y, image.NRGBAColor{ycol, ycol, ycol, cdat[2*x+1]})
nrgba.SetNRGBA(x, y, color.NRGBA{ycol, ycol, ycol, cdat[2*x+1]})
}
case cbTC8:
for x := 0; x < d.width; x++ {
rgba.SetRGBA(x, y, image.RGBAColor{cdat[3*x+0], cdat[3*x+1], cdat[3*x+2], 0xff})
rgba.SetRGBA(x, y, color.RGBA{cdat[3*x+0], cdat[3*x+1], cdat[3*x+2], 0xff})
}
case cbP1:
for x := 0; x < d.width; x += 8 {
......@@ -480,25 +481,25 @@ func (d *decoder) decode() (image.Image, os.Error) {
}
case cbTCA8:
for x := 0; x < d.width; x++ {
nrgba.SetNRGBA(x, y, image.NRGBAColor{cdat[4*x+0], cdat[4*x+1], cdat[4*x+2], cdat[4*x+3]})
nrgba.SetNRGBA(x, y, color.NRGBA{cdat[4*x+0], cdat[4*x+1], cdat[4*x+2], cdat[4*x+3]})
}
case cbG16:
for x := 0; x < d.width; x++ {
ycol := uint16(cdat[2*x+0])<<8 | uint16(cdat[2*x+1])
gray16.SetGray16(x, y, image.Gray16Color{ycol})
gray16.SetGray16(x, y, color.Gray16{ycol})
}
case cbGA16:
for x := 0; x < d.width; x++ {
ycol := uint16(cdat[4*x+0])<<8 | uint16(cdat[4*x+1])
acol := uint16(cdat[4*x+2])<<8 | uint16(cdat[4*x+3])
nrgba64.SetNRGBA64(x, y, image.NRGBA64Color{ycol, ycol, ycol, acol})
nrgba64.SetNRGBA64(x, y, color.NRGBA64{ycol, ycol, ycol, acol})
}
case cbTC16:
for x := 0; x < d.width; x++ {
rcol := uint16(cdat[6*x+0])<<8 | uint16(cdat[6*x+1])
gcol := uint16(cdat[6*x+2])<<8 | uint16(cdat[6*x+3])
bcol := uint16(cdat[6*x+4])<<8 | uint16(cdat[6*x+5])
rgba64.SetRGBA64(x, y, image.RGBA64Color{rcol, gcol, bcol, 0xffff})
rgba64.SetRGBA64(x, y, color.RGBA64{rcol, gcol, bcol, 0xffff})
}
case cbTCA16:
for x := 0; x < d.width; x++ {
......@@ -506,7 +507,7 @@ func (d *decoder) decode() (image.Image, os.Error) {
gcol := uint16(cdat[8*x+2])<<8 | uint16(cdat[8*x+3])
bcol := uint16(cdat[8*x+4])<<8 | uint16(cdat[8*x+5])
acol := uint16(cdat[8*x+6])<<8 | uint16(cdat[8*x+7])
nrgba64.SetNRGBA64(x, y, image.NRGBA64Color{rcol, gcol, bcol, acol})
nrgba64.SetNRGBA64(x, y, color.NRGBA64{rcol, gcol, bcol, acol})
}
}
......@@ -669,26 +670,26 @@ func DecodeConfig(r io.Reader) (image.Config, os.Error) {
break
}
}
var cm image.ColorModel
var cm color.Model
switch d.cb {
case cbG1, cbG2, cbG4, cbG8:
cm = image.GrayColorModel
cm = color.GrayModel
case cbGA8:
cm = image.NRGBAColorModel
cm = color.NRGBAModel
case cbTC8:
cm = image.RGBAColorModel
cm = color.RGBAModel
case cbP1, cbP2, cbP4, cbP8:
cm = d.palette
case cbTCA8:
cm = image.NRGBAColorModel
cm = color.NRGBAModel
case cbG16:
cm = image.Gray16ColorModel
cm = color.Gray16Model
case cbGA16:
cm = image.NRGBA64ColorModel
cm = color.NRGBA64Model
case cbTC16:
cm = image.RGBA64ColorModel
cm = color.RGBA64Model
case cbTCA16:
cm = image.NRGBA64ColorModel
cm = color.NRGBA64Model
}
return image.Config{cm, d.width, d.height}, nil
}
......
......@@ -8,6 +8,7 @@ import (
"bufio"
"fmt"
"image"
"image/color"
"io"
"os"
"strings"
......@@ -58,12 +59,12 @@ func sng(w io.WriteCloser, filename string, png image.Image) {
cm := png.ColorModel()
var bitdepth int
switch cm {
case image.RGBAColorModel, image.NRGBAColorModel, image.AlphaColorModel, image.GrayColorModel:
case color.RGBAModel, color.NRGBAModel, color.AlphaModel, color.GrayModel:
bitdepth = 8
default:
bitdepth = 16
}
cpm, _ := cm.(image.PalettedColorModel)
cpm, _ := cm.(color.Palette)
var paletted *image.Paletted
if cpm != nil {
switch {
......@@ -83,11 +84,11 @@ func sng(w io.WriteCloser, filename string, png image.Image) {
io.WriteString(w, "#SNG: from "+filename+".png\nIHDR {\n")
fmt.Fprintf(w, " width: %d; height: %d; bitdepth: %d;\n", bounds.Dx(), bounds.Dy(), bitdepth)
switch {
case cm == image.RGBAColorModel, cm == image.RGBA64ColorModel:
case cm == color.RGBAModel, cm == color.RGBA64Model:
io.WriteString(w, " using color;\n")
case cm == image.NRGBAColorModel, cm == image.NRGBA64ColorModel:
case cm == color.NRGBAModel, cm == color.NRGBA64Model:
io.WriteString(w, " using color alpha;\n")
case cm == image.GrayColorModel, cm == image.Gray16ColorModel:
case cm == color.GrayModel, cm == color.Gray16Model:
io.WriteString(w, " using grayscale;\n")
case cpm != nil:
io.WriteString(w, " using color palette;\n")
......@@ -130,34 +131,34 @@ func sng(w io.WriteCloser, filename string, png image.Image) {
io.WriteString(w, "IMAGE {\n pixels hex\n")
for y := bounds.Min.Y; y < bounds.Max.Y; y++ {
switch {
case cm == image.GrayColorModel:
case cm == color.GrayModel:
for x := bounds.Min.X; x < bounds.Max.X; x++ {
gray := png.At(x, y).(image.GrayColor)
gray := png.At(x, y).(color.Gray)
fmt.Fprintf(w, "%02x", gray.Y)
}
case cm == image.Gray16ColorModel:
case cm == color.Gray16Model:
for x := bounds.Min.X; x < bounds.Max.X; x++ {
gray16 := png.At(x, y).(image.Gray16Color)
gray16 := png.At(x, y).(color.Gray16)
fmt.Fprintf(w, "%04x ", gray16.Y)
}
case cm == image.RGBAColorModel:
case cm == color.RGBAModel:
for x := bounds.Min.X; x < bounds.Max.X; x++ {
rgba := png.At(x, y).(image.RGBAColor)
rgba := png.At(x, y).(color.RGBA)
fmt.Fprintf(w, "%02x%02x%02x ", rgba.R, rgba.G, rgba.B)
}
case cm == image.RGBA64ColorModel:
case cm == color.RGBA64Model:
for x := bounds.Min.X; x < bounds.Max.X; x++ {
rgba64 := png.At(x, y).(image.RGBA64Color)
rgba64 := png.At(x, y).(color.RGBA64)
fmt.Fprintf(w, "%04x%04x%04x ", rgba64.R, rgba64.G, rgba64.B)
}
case cm == image.NRGBAColorModel:
case cm == color.NRGBAModel:
for x := bounds.Min.X; x < bounds.Max.X; x++ {
nrgba := png.At(x, y).(image.NRGBAColor)
nrgba := png.At(x, y).(color.NRGBA)
fmt.Fprintf(w, "%02x%02x%02x%02x ", nrgba.R, nrgba.G, nrgba.B, nrgba.A)
}
case cm == image.NRGBA64ColorModel:
case cm == color.NRGBA64Model:
for x := bounds.Min.X; x < bounds.Max.X; x++ {
nrgba64 := png.At(x, y).(image.NRGBA64Color)
nrgba64 := png.At(x, y).(color.NRGBA64)
fmt.Fprintf(w, "%04x%04x%04x%04x ", nrgba64.R, nrgba64.G, nrgba64.B, nrgba64.A)
}
case cpm != nil:
......@@ -193,7 +194,7 @@ func TestReader(t *testing.T) {
if fn == "basn4a16" {
// basn4a16.sng is gray + alpha but sng() will produce true color + alpha
// so we just check a single random pixel.
c := img.At(2, 1).(image.NRGBA64Color)
c := img.At(2, 1).(color.NRGBA64)
if c.R != 0x11a7 || c.G != 0x11a7 || c.B != 0x11a7 || c.A != 0x1085 {
t.Error(fn, fmt.Errorf("wrong pixel value at (2, 1): %x", c))
}
......
......@@ -9,6 +9,7 @@ import (
"compress/zlib"
"hash/crc32"
"image"
"image/color"
"io"
"os"
"strconv"
......@@ -125,7 +126,7 @@ func (e *encoder) writeIHDR() {
e.writeChunk(e.tmp[0:13], "IHDR")
}
func (e *encoder) writePLTE(p image.PalettedColorModel) {
func (e *encoder) writePLTE(p color.Palette) {
if len(p) < 1 || len(p) > 256 {
e.err = FormatError("bad palette length: " + strconv.Itoa(len(p)))
return
......@@ -139,7 +140,7 @@ func (e *encoder) writePLTE(p image.PalettedColorModel) {
e.writeChunk(e.tmp[0:3*len(p)], "PLTE")
}
func (e *encoder) maybeWritetRNS(p image.PalettedColorModel) {
func (e *encoder) maybeWritetRNS(p color.Palette) {
last := -1
for i, c := range p {
_, _, _, a := c.RGBA()
......@@ -306,7 +307,7 @@ func writeImage(w io.Writer, m image.Image, cb int) os.Error {
switch cb {
case cbG8:
for x := b.Min.X; x < b.Max.X; x++ {
c := image.GrayColorModel.Convert(m.At(x, y)).(image.GrayColor)
c := color.GrayModel.Convert(m.At(x, y)).(color.Gray)
cr[0][i] = c.Y
i++
}
......@@ -345,7 +346,7 @@ func writeImage(w io.Writer, m image.Image, cb int) os.Error {
case cbTCA8:
// Convert from image.Image (which is alpha-premultiplied) to PNG's non-alpha-premultiplied.
for x := b.Min.X; x < b.Max.X; x++ {
c := image.NRGBAColorModel.Convert(m.At(x, y)).(image.NRGBAColor)
c := color.NRGBAModel.Convert(m.At(x, y)).(color.NRGBA)
cr[0][i+0] = c.R
cr[0][i+1] = c.G
cr[0][i+2] = c.B
......@@ -354,7 +355,7 @@ func writeImage(w io.Writer, m image.Image, cb int) os.Error {
}
case cbG16:
for x := b.Min.X; x < b.Max.X; x++ {
c := image.Gray16ColorModel.Convert(m.At(x, y)).(image.Gray16Color)
c := color.Gray16Model.Convert(m.At(x, y)).(color.Gray16)
cr[0][i+0] = uint8(c.Y >> 8)
cr[0][i+1] = uint8(c.Y)
i += 2
......@@ -374,7 +375,7 @@ func writeImage(w io.Writer, m image.Image, cb int) os.Error {
case cbTCA16:
// Convert from image.Image (which is alpha-premultiplied) to PNG's non-alpha-premultiplied.
for x := b.Min.X; x < b.Max.X; x++ {
c := image.NRGBA64ColorModel.Convert(m.At(x, y)).(image.NRGBA64Color)
c := color.NRGBA64Model.Convert(m.At(x, y)).(color.NRGBA64)
cr[0][i+0] = uint8(c.R >> 8)
cr[0][i+1] = uint8(c.R)
cr[0][i+2] = uint8(c.G >> 8)
......@@ -436,20 +437,20 @@ func Encode(w io.Writer, m image.Image) os.Error {
e.w = w
e.m = m
var pal image.PalettedColorModel
var pal color.Palette
// cbP8 encoding needs PalettedImage's ColorIndexAt method.
if _, ok := m.(image.PalettedImage); ok {
pal, _ = m.ColorModel().(image.PalettedColorModel)
pal, _ = m.ColorModel().(color.Palette)
}
if pal != nil {
e.cb = cbP8
} else {
switch m.ColorModel() {
case image.GrayColorModel:
case color.GrayModel:
e.cb = cbG8
case image.Gray16ColorModel:
case color.Gray16Model:
e.cb = cbG16
case image.RGBAColorModel, image.NRGBAColorModel, image.AlphaColorModel:
case color.RGBAModel, color.NRGBAModel, color.AlphaModel:
if opaque(m) {
e.cb = cbTC8
} else {
......
......@@ -8,6 +8,7 @@ import (
"bytes"
"fmt"
"image"
"image/color"
"io/ioutil"
"os"
"testing"
......@@ -85,7 +86,7 @@ func TestSubImage(t *testing.T) {
m0 := image.NewRGBA(image.Rect(0, 0, 256, 256))
for y := 0; y < 256; y++ {
for x := 0; x < 256; x++ {
m0.Set(x, y, image.RGBAColor{uint8(x), uint8(y), 0, 255})
m0.Set(x, y, color.RGBA{uint8(x), uint8(y), 0, 255})
}
}
m0 = m0.SubImage(image.Rect(50, 30, 250, 130)).(*image.RGBA)
......@@ -103,11 +104,10 @@ func TestSubImage(t *testing.T) {
func BenchmarkEncodePaletted(b *testing.B) {
b.StopTimer()
img := image.NewPaletted(image.Rect(0, 0, 640, 480),
[]image.Color{
image.RGBAColor{0, 0, 0, 255},
image.RGBAColor{255, 255, 255, 255},
})
img := image.NewPaletted(image.Rect(0, 0, 640, 480), color.Palette{
color.RGBA{0, 0, 0, 255},
color.RGBA{255, 255, 255, 255},
})
b.SetBytes(640 * 480 * 1)
b.StartTimer()
for i := 0; i < b.N; i++ {
......@@ -122,7 +122,7 @@ func BenchmarkEncodeRGBOpaque(b *testing.B) {
bo := img.Bounds()
for y := bo.Min.Y; y < bo.Max.Y; y++ {
for x := bo.Min.X; x < bo.Max.X; x++ {
img.Set(x, y, image.RGBAColor{0, 0, 0, 255})
img.Set(x, y, color.RGBA{0, 0, 0, 255})
}
}
if !img.Opaque() {
......
......@@ -12,6 +12,7 @@ import (
"compress/zlib"
"encoding/binary"
"image"
"image/color"
"io"
"io/ioutil"
"os"
......@@ -45,7 +46,7 @@ type decoder struct {
config image.Config
mode imageMode
features map[int][]uint
palette []image.Color
palette []color.Color
buf []byte
off int // Current offset in buf.
......@@ -129,9 +130,9 @@ func (d *decoder) parseIFD(p []byte) os.Error {
if len(val)%3 != 0 || numcolors <= 0 || numcolors > 256 {
return FormatError("bad ColorMap length")
}
d.palette = make([]image.Color, numcolors)
d.palette = make([]color.Color, numcolors)
for i := 0; i < numcolors; i++ {
d.palette[i] = image.RGBA64Color{
d.palette[i] = color.RGBA64{
uint16(val[i]),
uint16(val[i+numcolors]),
uint16(val[i+2*numcolors]),
......@@ -208,7 +209,7 @@ func (d *decoder) decode(dst image.Image, ymin, ymax int) os.Error {
if d.mode == mGrayInvert {
v = 0xff - v
}
img.SetGray(x, y, image.GrayColor{v})
img.SetGray(x, y, color.Gray{v})
}
d.flushBits()
}
......@@ -308,7 +309,7 @@ func newDecoder(r io.Reader) (*decoder, os.Error) {
return nil, UnsupportedError("non-8-bit RGB image")
}
}
d.config.ColorModel = image.RGBAColorModel
d.config.ColorModel = color.RGBAModel
// RGB images normally have 3 samples per pixel.
// If there are more, ExtraSamples (p. 31-32 of the spec)
// gives their meaning (usually an alpha channel).
......@@ -324,7 +325,7 @@ func newDecoder(r io.Reader) (*decoder, os.Error) {
d.mode = mRGBA
case 2:
d.mode = mNRGBA
d.config.ColorModel = image.NRGBAColorModel
d.config.ColorModel = color.NRGBAModel
default:
return nil, FormatError("wrong number of samples for RGB")
}
......@@ -333,13 +334,13 @@ func newDecoder(r io.Reader) (*decoder, os.Error) {
}
case pPaletted:
d.mode = mPaletted
d.config.ColorModel = image.PalettedColorModel(d.palette)
d.config.ColorModel = color.Palette(d.palette)
case pWhiteIsZero:
d.mode = mGrayInvert
d.config.ColorModel = image.GrayColorModel
d.config.ColorModel = color.GrayModel
case pBlackIsZero:
d.mode = mGray
d.config.ColorModel = image.GrayColorModel
d.config.ColorModel = color.GrayModel
default:
return nil, UnsupportedError("color model")
}
......
......@@ -15,6 +15,7 @@ package ycbcr
import (
"image"
"image/color"
)
// RGBToYCbCr converts an RGB triple to a YCbCr triple. All components lie
......@@ -92,7 +93,7 @@ func (c YCbCrColor) RGBA() (uint32, uint32, uint32, uint32) {
return uint32(r) * 0x101, uint32(g) * 0x101, uint32(b) * 0x101, 0xffff
}
func toYCbCrColor(c image.Color) image.Color {
func toYCbCrColor(c color.Color) color.Color {
if _, ok := c.(YCbCrColor); ok {
return c
}
......@@ -102,7 +103,7 @@ func toYCbCrColor(c image.Color) image.Color {
}
// YCbCrColorModel is the color model for YCbCrColor.
var YCbCrColorModel image.ColorModel = image.ColorModelFunc(toYCbCrColor)
var YCbCrColorModel color.Model = color.ModelFunc(toYCbCrColor)
// SubsampleRatio is the chroma subsample ratio used in a YCbCr image.
type SubsampleRatio int
......@@ -133,7 +134,7 @@ type YCbCr struct {
Rect image.Rectangle
}
func (p *YCbCr) ColorModel() image.ColorModel {
func (p *YCbCr) ColorModel() color.Model {
return YCbCrColorModel
}
......@@ -141,7 +142,7 @@ func (p *YCbCr) Bounds() image.Rectangle {
return p.Rect
}
func (p *YCbCr) At(x, y int) image.Color {
func (p *YCbCr) At(x, y int) color.Color {
if !(image.Point{x, y}.In(p.Rect)) {
return YCbCrColor{}
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment