mirror of
https://github.com/tinygo-org/drivers.git
synced 2026-07-26 10:38:41 +00:00
pixel: fix Image[Monochrome].Set for larger images
For bigger images, the pixel index might not fit in a int16. Therefore, int is needed during the calculation. While fixing this bug, I've added a few tests that verify the Image implementation by creating images, filling them with random data, and then checking whether they still contain the same data. This test failed before the patch.
This commit is contained in:
committed by
Ron Evans
parent
831982ad33
commit
7d983647ad
+3
-3
@@ -104,9 +104,9 @@ func (img Image[T]) setPixel(index int, c T) {
|
||||
switch {
|
||||
case zeroColor.BitsPerPixel() == 1:
|
||||
// Monochrome.
|
||||
x := int16(index) % img.width
|
||||
y := int16(index) / img.width
|
||||
offset := x + (y/8)*img.width
|
||||
x := index % int(img.width)
|
||||
y := index / int(img.width)
|
||||
offset := x + (y/8)*int(img.width)
|
||||
ptr := (*byte)(unsafe.Add(img.data, offset))
|
||||
if c != zeroColor {
|
||||
*((*byte)(ptr)) |= 1 << uint8(y%8)
|
||||
|
||||
@@ -1,7 +1,9 @@
|
||||
package pixel_test
|
||||
|
||||
import (
|
||||
goimage "image"
|
||||
"image/color"
|
||||
"math/rand"
|
||||
"testing"
|
||||
|
||||
"tinygo.org/x/drivers/pixel"
|
||||
@@ -94,3 +96,69 @@ func TestImageMonochrome(t *testing.T) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Test pixel formats by filling them with noise and checking whether they
|
||||
// contain the same data afterwards.
|
||||
func TestImageNoise(t *testing.T) {
|
||||
t.Run("RGB888", func(t *testing.T) {
|
||||
testImageNoise[pixel.RGB888](t)
|
||||
})
|
||||
t.Run("RGB565BE", func(t *testing.T) {
|
||||
testImageNoise[pixel.RGB565BE](t)
|
||||
})
|
||||
t.Run("RGB555", func(t *testing.T) {
|
||||
testImageNoise[pixel.RGB555](t)
|
||||
})
|
||||
t.Run("RGB444BE", func(t *testing.T) {
|
||||
testImageNoise[pixel.RGB444BE](t)
|
||||
})
|
||||
t.Run("Monochrome", func(t *testing.T) {
|
||||
testImageNoise[pixel.Monochrome](t)
|
||||
})
|
||||
}
|
||||
|
||||
func testImageNoise[T pixel.Color](t *testing.T) {
|
||||
// Create an image of a random width/height for extra testing.
|
||||
width := rand.Int()%500 + 10
|
||||
height := rand.Int()%500 + 10
|
||||
t.Log("image size:", width, height)
|
||||
|
||||
// Create two images: the to-be-tested image object and a reference image.
|
||||
img := pixel.NewImage[T](width, height)
|
||||
ref := goimage.NewRGBA(goimage.Rect(0, 0, width, height))
|
||||
|
||||
// Fill the two images with noise.
|
||||
for y := 0; y < height; y++ {
|
||||
for x := 0; x < width; x++ {
|
||||
// Set a random color in both images.
|
||||
c := pixel.NewColor[T](uint8(rand.Uint32()), uint8(rand.Uint32()), uint8(rand.Uint32()))
|
||||
img.Set(x, y, c)
|
||||
ref.Set(x, y, c.RGBA())
|
||||
}
|
||||
}
|
||||
|
||||
// Compare the two images. They should match.
|
||||
mismatch := 0
|
||||
firstX := 0
|
||||
firstY := 0
|
||||
var firstExpected, firstActual color.RGBA
|
||||
for y := 0; y < height; y++ {
|
||||
for x := 0; x < width; x++ {
|
||||
c := img.Get(x, y).RGBA()
|
||||
r2, g2, b2, _ := ref.At(x, y).RGBA()
|
||||
c2 := color.RGBA{R: uint8(r2 >> 8), G: uint8(g2 >> 8), B: uint8(b2 >> 8), A: 255}
|
||||
if c != c2 {
|
||||
mismatch++
|
||||
if mismatch == 1 {
|
||||
firstX = x
|
||||
firstY = y
|
||||
firstExpected = c
|
||||
firstActual = c2
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if mismatch != 0 {
|
||||
t.Errorf("mismatch found: %d pixels are different (first diff at (%d, %d), expected %v, actual %v)", mismatch, firstX, firstY, firstExpected, firstActual)
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user