Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 13 additions & 6 deletions internal/color.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,16 +30,16 @@ func (c *ClosestColorPicker[RGB, Color]) IndexInPalette(rgba color.Color) (Color
for i, paletteCol := range c.Palette {
r, g, b, _ := rgba.RGBA()
r, g, b = r&0xff, g&0xff, b&0xff
r2, g2, b2 := paletteCol>>16&0xff, paletteCol>>8&0xff, paletteCol&0xff
if r == uint32(r2) && g == uint32(g2) && b == uint32(b2) {
r2, g2, b2 := uint32(paletteCol>>16&0xff),
uint32(paletteCol>>8&0xff),
uint32(paletteCol&0xff)
if r == r2 && g == g2 && b == b2 {
// found perfect match. Short circuit
closestColor = Color(i)
break
}
distance := math.Sqrt(
math.Pow(float64(r2-RGB(r)), 2) +
math.Pow(float64(g2-RGB(g)), 2) +
math.Pow(float64(b2-RGB(b)), 2))
distance := perceptualColorDistance(r, g, b, r2, g2, b2)

if distance < smallestDistance {
smallestDistance = distance
closestColor = Color(i)
Expand All @@ -50,3 +50,10 @@ func (c *ClosestColorPicker[RGB, Color]) IndexInPalette(rgba color.Color) (Color

return closestColor, nil
}

func perceptualColorDistance(r1, g1, b1, r2, g2, b2 uint32) float64 {
rd := float64(r1 - r2)
gd := float64(g1 - g2)
bd := float64(b1 - b2)
return math.Sqrt(0.299*rd*rd + 0.587*gd*gd + 0.114*bd*bd)
}
Binary file added internal/test/decode/indexed-brighter.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added internal/test/decode/indexed.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added internal/test/decode/rgb-brighter.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added internal/test/decode/rgb.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
41 changes: 41 additions & 0 deletions surface_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,9 @@
package pi_test

import (
_ "embed"
"github.com/elgopher/pi/pitest"
"github.com/stretchr/testify/require"
"math/rand"
"testing"

Expand All @@ -12,6 +15,44 @@ import (
"github.com/elgopher/pi"
)

var (
//go:embed "internal/test/decode/indexed.png"
indexedPNG []byte
//go:embed "internal/test/decode/rgb.png"
rgbPNG []byte
//go:embed "internal/test/decode/indexed-brighter.png"
brighterIndexedPNG []byte
//go:embed "internal/test/decode/rgb-brighter.png"
rgbBrighterPNG []byte
)

func TestDecodeCanvasOrErr(t *testing.T) {
tests := map[string][]byte{
"indexed png when palette is the same": indexedPNG,
"RGB png": rgbPNG,
"indexed png when palette is slightly brighter": brighterIndexedPNG,
"RGB png when palette is slightly brighter": rgbBrighterPNG,
}

for testName, png := range tests {
t.Run(testName, func(t *testing.T) {
pi.Palette = pi.DecodePalette(indexedPNG)
// when
canvas, err := pi.DecodeCanvasOrErr(png)
// then
require.NoError(t, err)
expected := pi.NewCanvas(4, 4)
expected.SetAll(
0, 1, 2, 3,
4, 5, 6, 7,
8, 9, 10, 11,
12, 13, 14, 15,
)
pitest.AssertSurfaceEqual(t, expected, canvas)
})
}
}

func TestSet(t *testing.T) {
t.Run("should be noop when outside surface", func(t *testing.T) {
width := 2
Expand Down