]> Cypherpunks repositories - gostls13.git/commitdiff
image: add Paletted.Set, and a basic test of the concrete image types.
authorNigel Tao <nigeltao@golang.org>
Fri, 10 Jun 2011 04:07:29 +0000 (14:07 +1000)
committerNigel Tao <nigeltao@golang.org>
Fri, 10 Jun 2011 04:07:29 +0000 (14:07 +1000)
R=r
CC=golang-dev
https://golang.org/cl/4589045

src/pkg/image/image.go
src/pkg/image/image_test.go [new file with mode: 0644]

index bf75a51261c70734f9d103381a9b59162c993add..f4c38d28a6dab92e9f6ba04cf98264cfc94bc2a0 100644 (file)
@@ -563,14 +563,19 @@ func (p PalettedColorModel) 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 PalettedColorModel) 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
-       result := Color(nil)
-       bestSSD := uint32(1<<32 - 1)
-       for _, v := range p {
+       ret, bestSSD := 0, uint32(1<<32-1)
+       for i, v := range p {
                vr, vg, vb, _ := v.RGBA()
                vr >>= 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)
                ssd := (dr * dr) + (dg * dg) + (db * db)
                if ssd < bestSSD {
-                       bestSSD = ssd
-                       result = v
+                       ret, bestSSD = i, ssd
                }
        }
-       return result
+       return ret
 }
 
 // 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]]
 }
 
+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 {
        if !(Point{x, y}.In(p.Rect)) {
                return 0
diff --git a/src/pkg/image/image_test.go b/src/pkg/image/image_test.go
new file mode 100644 (file)
index 0000000..17e3147
--- /dev/null
@@ -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
+               }
+       }
+}