mirror of
https://github.com/golang/go
synced 2024-11-24 22:57:57 -07:00
image: add Paletted.Set, and a basic test of the concrete image types.
R=r CC=golang-dev https://golang.org/cl/4589045
This commit is contained in:
parent
d44c4c351d
commit
c0c824cd7b
@ -563,14 +563,19 @@ func (p PalettedColorModel) Convert(c Color) Color {
|
|||||||
if len(p) == 0 {
|
if len(p) == 0 {
|
||||||
return nil
|
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 PalettedColorModel) Index(c Color) int {
|
||||||
cr, cg, cb, _ := c.RGBA()
|
cr, cg, cb, _ := c.RGBA()
|
||||||
// Shift by 1 bit to avoid potential uint32 overflow in sum-squared-difference.
|
// Shift by 1 bit to avoid potential uint32 overflow in sum-squared-difference.
|
||||||
cr >>= 1
|
cr >>= 1
|
||||||
cg >>= 1
|
cg >>= 1
|
||||||
cb >>= 1
|
cb >>= 1
|
||||||
result := Color(nil)
|
ret, bestSSD := 0, uint32(1<<32-1)
|
||||||
bestSSD := uint32(1<<32 - 1)
|
for i, v := range p {
|
||||||
for _, v := range p {
|
|
||||||
vr, vg, vb, _ := v.RGBA()
|
vr, vg, vb, _ := v.RGBA()
|
||||||
vr >>= 1
|
vr >>= 1
|
||||||
vg >>= 1
|
vg >>= 1
|
||||||
@ -578,11 +583,10 @@ func (p PalettedColorModel) Convert(c Color) Color {
|
|||||||
dr, dg, db := diff(cr, vr), diff(cg, vg), diff(cb, vb)
|
dr, dg, db := diff(cr, vr), diff(cg, vg), diff(cb, vb)
|
||||||
ssd := (dr * dr) + (dg * dg) + (db * db)
|
ssd := (dr * dr) + (dg * dg) + (db * db)
|
||||||
if ssd < bestSSD {
|
if ssd < bestSSD {
|
||||||
bestSSD = ssd
|
ret, bestSSD = i, ssd
|
||||||
result = v
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return result
|
return ret
|
||||||
}
|
}
|
||||||
|
|
||||||
// A Paletted is an in-memory image backed by a 2-D slice of uint8 values and a PalettedColorModel.
|
// A Paletted is an in-memory image backed by a 2-D slice of uint8 values and a PalettedColorModel.
|
||||||
@ -610,6 +614,13 @@ func (p *Paletted) At(x, y int) Color {
|
|||||||
return p.Palette[p.Pix[y*p.Stride+x]]
|
return p.Palette[p.Pix[y*p.Stride+x]]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (p *Paletted) Set(x, y int, c Color) {
|
||||||
|
if !(Point{x, y}.In(p.Rect)) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
p.Pix[y*p.Stride+x] = uint8(p.Palette.Index(c))
|
||||||
|
}
|
||||||
|
|
||||||
func (p *Paletted) ColorIndexAt(x, y int) uint8 {
|
func (p *Paletted) ColorIndexAt(x, y int) uint8 {
|
||||||
if !(Point{x, y}.In(p.Rect)) {
|
if !(Point{x, y}.In(p.Rect)) {
|
||||||
return 0
|
return 0
|
||||||
|
71
src/pkg/image/image_test.go
Normal file
71
src/pkg/image/image_test.go
Normal file
@ -0,0 +1,71 @@
|
|||||||
|
// 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 image
|
||||||
|
|
||||||
|
import (
|
||||||
|
"testing"
|
||||||
|
)
|
||||||
|
|
||||||
|
func cmp(t *testing.T, cm ColorModel, c0, c1 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
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestImage(t *testing.T) {
|
||||||
|
type buffered interface {
|
||||||
|
Image
|
||||||
|
Set(int, int, Color)
|
||||||
|
SubImage(Rectangle) Image
|
||||||
|
}
|
||||||
|
testImage := []Image{
|
||||||
|
NewRGBA(10, 10),
|
||||||
|
NewRGBA64(10, 10),
|
||||||
|
NewNRGBA(10, 10),
|
||||||
|
NewNRGBA64(10, 10),
|
||||||
|
NewAlpha(10, 10),
|
||||||
|
NewAlpha16(10, 10),
|
||||||
|
NewGray(10, 10),
|
||||||
|
NewGray16(10, 10),
|
||||||
|
NewPaletted(10, 10, PalettedColorModel{
|
||||||
|
Transparent,
|
||||||
|
Opaque,
|
||||||
|
}),
|
||||||
|
}
|
||||||
|
for _, m := range testImage {
|
||||||
|
b := m.(buffered)
|
||||||
|
if !Rect(0, 0, 10, 10).Eq(b.Bounds()) {
|
||||||
|
t.Errorf("%T: want bounds %v, got %v", b, Rect(0, 0, 10, 10), b.Bounds())
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
if !cmp(t, b.ColorModel(), Transparent, b.At(6, 3)) {
|
||||||
|
t.Errorf("%T: at (6, 3), want a zero color, got %v", b, b.At(6, 3))
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
b.Set(6, 3, Opaque)
|
||||||
|
if !cmp(t, b.ColorModel(), Opaque, b.At(6, 3)) {
|
||||||
|
t.Errorf("%T: at (6, 3), want a non-zero color, got %v", b, b.At(6, 3))
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
b = b.SubImage(Rect(3, 2, 9, 8)).(buffered)
|
||||||
|
if !Rect(3, 2, 9, 8).Eq(b.Bounds()) {
|
||||||
|
t.Errorf("%T: sub-image want bounds %v, got %v", b, Rect(3, 2, 9, 8), b.Bounds())
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
if !cmp(t, b.ColorModel(), Opaque, b.At(6, 3)) {
|
||||||
|
t.Errorf("%T: sub-image at (6, 3), want a non-zero color, got %v", b, b.At(6, 3))
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
if !cmp(t, b.ColorModel(), Transparent, b.At(3, 3)) {
|
||||||
|
t.Errorf("%T: sub-image at (3, 3), want a zero color, got %v", b, b.At(3, 3))
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
b.Set(3, 3, Opaque)
|
||||||
|
if !cmp(t, b.ColorModel(), Opaque, b.At(3, 3)) {
|
||||||
|
t.Errorf("%T: sub-image at (3, 3), want a non-zero color, got %v", b, b.At(3, 3))
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user