85 lines
2.1 KiB
Go
85 lines
2.1 KiB
Go
package helper
|
|
|
|
import (
|
|
"fmt"
|
|
"math"
|
|
"testing"
|
|
)
|
|
|
|
func TestLinearize(t *testing.T) {
|
|
tests := []struct {
|
|
value uint32
|
|
want float64
|
|
}{
|
|
// the minimum and maximum legal values should map to 0 and 1, respectively.
|
|
{0x0000, 0.0},
|
|
{0xffff, 1.0},
|
|
|
|
// check what would be 0x01 in 8-bit sRGB.
|
|
// this is below the point where it the function switches from linear to exponential.
|
|
{0x0101, 0x1.3e312a36f1977p-12},
|
|
|
|
// check the midpoint of the gamma curve.
|
|
{0x7fff, 0x1.b6577fc57aa37p-03},
|
|
|
|
// We do support values beyond the maximum legal value, although you probably shouldn't depend on it
|
|
// as the converse function will map these to the maximum legal value, creating an asymmetry.
|
|
{0x10000, 0x1.000246626b604p+00},
|
|
{math.MaxUint32, 0x1.2912a0c535107p+38},
|
|
}
|
|
for _, tt := range tests {
|
|
t.Run(fmt.Sprintf("0x%04x", tt.value), func(t *testing.T) {
|
|
if got := Linearize(tt.value); !EqFloat64Fuzzy(got, tt.want) {
|
|
t.Errorf("Linearize(0x%04x) = %x: want %x", tt.value, got, tt.want)
|
|
}
|
|
})
|
|
}
|
|
|
|
t.Run("monotonically increasing", func(t *testing.T) {
|
|
for i, prev := uint32(1), Linearize(0); i < 0x10000; i++ {
|
|
got := Linearize(i)
|
|
if got <= prev {
|
|
t.Errorf("Linearize(0x%04x) = %x; want > %x", i, got, prev)
|
|
}
|
|
prev = got
|
|
}
|
|
})
|
|
}
|
|
|
|
func TestDelinearize(t *testing.T) {
|
|
tests := []struct {
|
|
value float64
|
|
want uint32
|
|
}{
|
|
// make sure clamping to legal values is happening.
|
|
{-1, 0x0000},
|
|
{2, 0xffff},
|
|
|
|
// again with the next values below 0 and above 1.
|
|
{math.Nextafter(0, math.Inf(-1)), 0},
|
|
{math.Nextafter(1, math.Inf(1)), 0xffff},
|
|
|
|
// and lastly, the non-finites.
|
|
{math.Inf(-1), 0x0000},
|
|
{math.Inf(1), 0xffff},
|
|
{math.NaN(), 0x0000},
|
|
}
|
|
for _, tt := range tests {
|
|
t.Run(fmt.Sprintf("%x", tt.value), func(t *testing.T) {
|
|
if got := Delinearize(tt.value); got != tt.want {
|
|
t.Errorf("Delinearize(%x) = 0x%04x: want 0x%04x", tt.value, got, tt.want)
|
|
}
|
|
})
|
|
}
|
|
|
|
t.Run("lossless conversion of legal values", func(t *testing.T) {
|
|
for c := uint32(0); c < 0x10000; c++ {
|
|
got := Delinearize(Linearize(c))
|
|
if got != c {
|
|
t.Errorf("Delinearize(Linearize(0x%04x)) != 0x%04x", c, got)
|
|
return
|
|
}
|
|
}
|
|
})
|
|
}
|