
function test_rgb_over_rgb(bm, expected_f64)
    @test all(t->bm(t[1]...) ≈ t[2],
              zip(((c1, c2) for c1 in rgb1_f64, c2 in rgb2_f64), expected_f64))

    @test all(c->bm(c[1], c[2]) ≈ bm(c[1]|>f64, c[2]|>f64)|>f32,
              ((c1, c2) for c1 in rgb1_f32, c2 in rgb2_f32))
    @test all(c->bm(c[1], c[2]) === bm(c[1]|>f64, c[2]|>f64)|>n0f8,
              ((c1, c2) for c1 in rgb1_n0f8, c2 in rgb2_n0f8))
    @test all(c->bm(c[1], c[2]) === bm(c[1]|>f64, c[2]|>f64)|>n0f16,
              ((c1, c2) for c1 in rgb1_n0f16, c2 in rgb2_n0f16))

    @test all(c->bm(c[1], c[2]) ≈ bm(c[1]|>f64, c[2]|>f64)|>f32,
              ((c2, c1) for c1 in rgb1_f32, c2 in rgb2_f32))
    @test all(c->bm(c[1], c[2]) === bm(c[1]|>f64, c[2]|>f64)|>n0f8,
              ((c2, c1) for c1 in rgb1_n0f8, c2 in rgb2_n0f8))
    @test all(c->bm(c[1], c[2]) === bm(c[1]|>f64, c[2]|>f64)|>n0f16,
              ((c2, c1) for c1 in rgb1_n0f16, c2 in rgb2_n0f16))
end

@testset "normal" begin
    @testset "RGB over RGB" begin
        test_rgb_over_rgb(BlendNormal, [c2 for c1 in rgb1_f64, c2 in rgb2_f64])
    end

    @testset "RGBA over RGB: $T" for T in Ts
        @test BlendNormal(RGB{T}(1, 0.75, 0), RGBA{T}(0, 0.5, 1, 0.6)) ≈ RGB{T}(0.4, 0.6, 0.6)
    end

    @testset "RGB over RGBA: $T" for T in Ts
        @test BlendNormal(RGBA{T}(1, 0.75, 0, 0.6), RGB{T}(0, 0.5, 1)) ≈ RGBA{T}(0, 0.5, 1, 1)
    end

    @testset "RGBA over RGBA: $T" for T in Ts
        @test BlendNormal(RGBA{T}(1, 0.75, 0, 0.6), RGBA{T}(0, 0.5, 1, 0.6)) ≈ RGBA{T}(2/7, 4/7, 5/7, 0.84)
    end
end

@testset "multiply" begin
    @testset "RGB over RGB" begin
        test_rgb_over_rgb(BlendMultiply, RGB{Float64}[
            RGB(0.0, 0.0,                     0.0)                    RGB(0.0,                     0.0,                     0.0)                     RGB(0.0,                     0.0,                    0.0)
            RGB(0.0, 0.0,                     5.562684646268003e-309) RGB(1.1125369292536007e-308, 1.1125369292536007e-308, 1.1125369292536007e-308) RGB(2.2250738585072014e-308, 1.668805393880401e-308, 2.2250738585072014e-308)
            RGB(0.0, 5.562684646268003e-309,  0.0625)                 RGB(0.125,                   0.12500000000000003,     0.12499999999999999)     RGB(0.25,                    0.1875,                 0.24999999999999997)
            RGB(0.0, 1.1125369292536007e-308, 0.12499999999999999)    RGB(0.24999999999999997,     0.25,                    0.24999999999999994)     RGB(0.49999999999999994,     0.37499999999999994,    0.4999999999999999)
            RGB(0.0, 1.1125369292536007e-308, 0.125)                  RGB(0.25,                    0.25000000000000006,     0.24999999999999997)     RGB(0.5,                     0.375,                  0.49999999999999994)
            RGB(0.0, 1.1125369292536007e-308, 0.12500000000000003)    RGB(0.25000000000000006,     0.2500000000000001,      0.25)                    RGB(0.5000000000000001,      0.3750000000000001,     0.5)
            RGB(0.0, 1.668805393880401e-308,  0.1875)                 RGB(0.375,                   0.3750000000000001,      0.37499999999999994)     RGB(0.75,                    0.5625,                 0.7499999999999999)
            RGB(0.0, 2.2250738585072014e-308, 0.24999999999999997)    RGB(0.49999999999999994,     0.5,                     0.4999999999999999)      RGB(0.9999999999999999,      0.7499999999999999,     0.9999999999999998)
            RGB(0.0, 2.2250738585072014e-308, 0.25)                   RGB(0.5,                     0.5000000000000001,      0.49999999999999994)     RGB(1.0,                     0.75,                   0.9999999999999999)
        ])
    end

    @testset "RGBA over RGB: $T" for T in Ts
        @test BlendMultiply(RGB{T}(1, 0.75, 0), RGBA{T}(0, 0.5, 1, 0.6)) ≈ RGB{T}(0.4, 0.525, 0.0)
    end

    @testset "RGB over RGBA: $T" for T in Ts
        @test BlendMultiply(RGBA{T}(1, 0.75, 0, 0.6), RGB{T}(0, 0.5, 1)) ≈ RGBA{T}(0, 0.425, 0.4, 1)
    end

    @testset "RGBA over RGBA: $T" for T in Ts
        @test BlendMultiply(RGBA{T}(1, 0.75, 0, 0.6), RGBA{T}(0, 0.5, 1, 0.6)) ≈ RGBA{T}(2/7, 29/56, 2/7, 0.84)
    end
end

@testset "screen" begin
    @testset "RGB over RGB" begin
        test_rgb_over_rgb(BlendScreen, RGB{Float64}[
            RGB(0.0,                 0.0,                 0.25)               RGB(0.5,   0.5000000000000001, 0.49999999999999994) RGB(1.0, 0.75,   0.9999999999999999)
            RGB(0.0,                 0.0,                 0.25)               RGB(0.5,   0.5000000000000001, 0.49999999999999994) RGB(1.0, 0.75,   0.9999999999999999)
            RGB(0.25,                0.25,                0.4375)             RGB(0.625, 0.6250000000000001, 0.625)               RGB(1.0, 0.8125, 0.9999999999999999)
            RGB(0.49999999999999994, 0.49999999999999994, 0.625)              RGB(0.75,  0.75,               0.7499999999999999)  RGB(1.0, 0.875,  0.9999999999999999)
            RGB(0.5,                 0.5,                 0.625)              RGB(0.75,  0.75,               0.75)                RGB(1.0, 0.875,  1.0)
            RGB(0.5000000000000001,  0.5000000000000001,  0.6250000000000001) RGB(0.75,  0.7500000000000001, 0.75)                RGB(1.0, 0.875,  1.0)
            RGB(0.75,                0.75,                0.8125)             RGB(0.875, 0.875,              0.875)               RGB(1.0, 0.9375, 1.0)
            RGB(0.9999999999999999,  0.9999999999999999,  0.9999999999999999) RGB(1.0,   1.0,                0.9999999999999999)  RGB(1.0, 1.0,    1.0)
            RGB(1.0,                 1.0,                 1.0)                RGB(1.0,   1.0,                1.0)                 RGB(1.0, 1.0,    1.0)
        ])
    end

    @testset "RGBA over RGB: $T" for T in Ts
        @test BlendScreen(RGB{T}(1, 0.75, 0), RGBA{T}(0, 0.5, 1, 0.6)) ≈ RGB{T}(1.0, 0.825, 0.6)
    end

    @testset "RGB over RGBA: $T" for T in Ts
        @test BlendScreen(RGBA{T}(1, 0.75, 0, 0.6), RGB{T}(0, 0.5, 1)) ≈ RGBA{T}(0.6, 0.725, 1.0, 1)
    end

    @testset "RGBA over RGBA: $T" for T in Ts
        @test BlendScreen(RGBA{T}(1, 0.75, 0, 0.6), RGBA{T}(0, 0.5, 1, 0.6)) ≈ RGBA{T}(5/7, 41/56, 5/7, 0.84)
    end
end

@testset "overlay" begin
    @testset "RGB over RGB" begin
        test_rgb_over_rgb(BlendOverlay, RGB{Float64}[
            RGB(0.0,                   0.0,                     0.0)                     RGB(0.0,                     0.0,                    0.0)                     RGB(0.0,                    0.0,                    0.0)
            RGB(0.0,                   0.0,                     1.1125369292536007e-308) RGB(2.2250738585072014e-308, 2.225073858507202e-308, 2.2250738585072014e-308) RGB(4.450147717014403e-308, 3.337610787760802e-308, 4.4501477170144023e-308)
            RGB(0.0,                   1.1125369292536007e-308, 0.125)                   RGB(0.25,                    0.25000000000000006,    0.24999999999999997)     RGB(0.5,                    0.375,                  0.49999999999999994)
            RGB(0.0,                   2.2250738585072014e-308, 0.24999999999999997)     RGB(0.49999999999999994,     0.5,                    0.4999999999999999)      RGB(0.9999999999999999,     0.7499999999999999,     0.9999999999999998)
            RGB(0.0,                   2.2250738585072014e-308, 0.25)                    RGB(0.5,                     0.5000000000000001,     0.49999999999999994)     RGB(1.0,                    0.75,                   0.9999999999999999)
            RGB(2.220446049250313e-16, 2.220446049250313e-16,   0.25000000000000017)     RGB(0.5000000000000001,      0.5000000000000002,     0.5000000000000001)      RGB(1.0,                    0.75,                   0.9999999999999999)
            RGB(0.5,                   0.5,                     0.625)                   RGB(0.75,                    0.75,                   0.75)                    RGB(1.0,                    0.875,                  1.0)
            RGB(0.9999999999999998,    0.9999999999999998,      0.9999999999999998)      RGB(0.9999999999999999,      0.9999999999999999,     0.9999999999999999)      RGB(1.0,                    1.0,                    1.0)
            RGB(1.0,                   1.0,                     1.0)                     RGB(1.0,                     1.0,                    1.0)                     RGB(1.0,                    1.0,                    1.0)
        ])
    end

    @testset "RGBA over RGB: $T" for T in Ts
        @test BlendOverlay(RGB{T}(1, 0.75, 0), RGBA{T}(0, 0.5, 1, 0.6)) ≈ RGB{T}(1.0, 0.75, 0.0)
    end

    @testset "RGB over RGBA: $T" for T in Ts
        @test BlendOverlay(RGBA{T}(1, 0.75, 0, 0.6), RGB{T}(0, 0.5, 1)) ≈ RGBA{T}(0.6, 0.65, 0.4, 1)
    end

    @testset "RGBA over RGBA: $T" for T in Ts
        @test BlendOverlay(RGBA{T}(1, 0.75, 0, 0.6), RGBA{T}(0, 0.5, 1, 0.6)) ≈ RGBA{T}(5/7, 19/28, 2/7, 0.84)
    end
end

@testset "darken" begin
    @testset "RGB over RGB" begin
        test_rgb_over_rgb(BlendDarken, RGB{Float64}[
            RGB(0.0, 0.0,                     0.0)                     RGB(0.0,                     0.0,                     0.0)                     RGB(0.0,                     0.0,                     0.0)
            RGB(0.0, 2.2250738585072014e-308, 2.2250738585072014e-308) RGB(2.2250738585072014e-308, 2.2250738585072014e-308, 2.2250738585072014e-308) RGB(2.2250738585072014e-308, 2.2250738585072014e-308, 2.2250738585072014e-308)
            RGB(0.0, 2.2250738585072014e-308, 0.25)                    RGB(0.25,                    0.25,                    0.25)                    RGB(0.25,                    0.25,                    0.25)
            RGB(0.0, 2.2250738585072014e-308, 0.25)                    RGB(0.49999999999999994,     0.49999999999999994,     0.49999999999999994)     RGB(0.49999999999999994,     0.49999999999999994,     0.49999999999999994)
            RGB(0.0, 2.2250738585072014e-308, 0.25)                    RGB(0.5,                     0.5,                     0.49999999999999994)     RGB(0.5,                     0.5,                     0.5)
            RGB(0.0, 2.2250738585072014e-308, 0.25)                    RGB(0.5,                     0.5000000000000001,      0.49999999999999994)     RGB(0.5000000000000001,      0.5000000000000001,      0.5000000000000001)
            RGB(0.0, 2.2250738585072014e-308, 0.25)                    RGB(0.5,                     0.5000000000000001,      0.49999999999999994)     RGB(0.75,                    0.75,                    0.75)
            RGB(0.0, 2.2250738585072014e-308, 0.25)                    RGB(0.5,                     0.5000000000000001,      0.49999999999999994)     RGB(0.9999999999999999,      0.75,                    0.9999999999999999)
            RGB(0.0, 2.2250738585072014e-308, 0.25)                    RGB(0.5,                     0.5000000000000001,      0.49999999999999994)     RGB(1.0,                     0.75,                    0.9999999999999999)
        ])
    end

    @testset "RGBA over RGB: $T" for T in Ts
        @test BlendDarken(RGB{T}(1, 0.75, 0), RGBA{T}(0, 0.5, 1, 0.6)) ≈ RGB{T}(0.4, 0.6, 0.0)
    end

    @testset "RGB over RGBA: $T" for T in Ts
        @test BlendDarken(RGBA{T}(1, 0.75, 0, 0.6), RGB{T}(0, 0.5, 1)) ≈ RGBA{T}(0.0, 0.5, 0.4, 1)
    end

    @testset "RGBA over RGBA: $T" for T in Ts
        @test BlendDarken(RGBA{T}(1, 0.75, 0, 0.6), RGBA{T}(0, 0.5, 1, 0.6)) ≈ RGBA{T}(2/7, 4/7, 2/7, 0.84)
    end
end

@testset "lighten" begin
    @testset "RGB over RGB" begin
        test_rgb_over_rgb(BlendLighten, RGB{Float64}[
            RGB(0.0,                     2.2250738585072014e-308, 0.25)                RGB(0.5,                0.5000000000000001, 0.49999999999999994) RGB(1.0, 0.75,               0.9999999999999999)
            RGB(2.2250738585072014e-308, 2.2250738585072014e-308, 0.25)                RGB(0.5,                0.5000000000000001, 0.49999999999999994) RGB(1.0, 0.75,               0.9999999999999999)
            RGB(0.25,                    0.25,                    0.25)                RGB(0.5,                0.5000000000000001, 0.49999999999999994) RGB(1.0, 0.75,               0.9999999999999999)
            RGB(0.49999999999999994,     0.49999999999999994,     0.49999999999999994) RGB(0.5,                0.5000000000000001, 0.49999999999999994) RGB(1.0, 0.75,               0.9999999999999999)
            RGB(0.5,                     0.5,                     0.5)                 RGB(0.5,                0.5000000000000001, 0.5)                 RGB(1.0, 0.75,               0.9999999999999999)
            RGB(0.5000000000000001,      0.5000000000000001,      0.5000000000000001)  RGB(0.5000000000000001, 0.5000000000000001, 0.5000000000000001)  RGB(1.0, 0.75,               0.9999999999999999)
            RGB(0.75,                    0.75,                    0.75)                RGB(0.75,               0.75,               0.75)                RGB(1.0, 0.75,               0.9999999999999999)
            RGB(0.9999999999999999,      0.9999999999999999,      0.9999999999999999)  RGB(0.9999999999999999, 0.9999999999999999, 0.9999999999999999)  RGB(1.0, 0.9999999999999999, 0.9999999999999999)
            RGB(1.0,                     1.0,                     1.0)                 RGB(1.0,                1.0,                1.0)                 RGB(1.0, 1.0,                1.0)
        ])
    end

    @testset "RGBA over RGB: $T" for T in Ts
        @test BlendLighten(RGB{T}(1, 0.75, 0), RGBA{T}(0, 0.5, 1, 0.6)) ≈ RGB{T}(1.0, 0.75, 0.6)
    end

    @testset "RGB over RGBA: $T" for T in Ts
        @test BlendLighten(RGBA{T}(1, 0.75, 0, 0.6), RGB{T}(0, 0.5, 1)) ≈ RGBA{T}(0.6, 0.65, 1.0, 1)
    end

    @testset "RGBA over RGBA: $T" for T in Ts
        @test BlendLighten(RGBA{T}(1, 0.75, 0, 0.6), RGBA{T}(0, 0.5, 1, 0.6)) ≈ RGBA{T}(5/7, 19/28, 5/7, 0.84)
    end
end

@testset "color-dodge" begin
    @testset "RGB over RGB" begin
        test_rgb_over_rgb(BlendColorDodge, RGB{Float64}[
            RGB(0.0,                     0.0,                     0.0)                     RGB(0.0,                    0.0,                    0.0)                     RGB(0.0, 0.0,                    0.0)
            RGB(2.2250738585072014e-308, 2.2250738585072014e-308, 2.9667651446762683e-308) RGB(4.450147717014403e-308, 4.450147717014404e-308, 4.4501477170144023e-308) RGB(1.0, 8.900295434028806e-308, 2.004168360008973e-292)
            RGB(0.25,                    0.25,                    0.3333333333333333)      RGB(0.5,                    0.5000000000000001,     0.49999999999999994)     RGB(1.0, 1.0,                    1.0)
            RGB(0.49999999999999994,     0.49999999999999994,     0.6666666666666666)      RGB(0.9999999999999999,     1.0,                    0.9999999999999998)      RGB(1.0, 1.0,                    1.0)
            RGB(0.5,                     0.5,                     0.6666666666666666)      RGB(1.0,                    1.0,                    0.9999999999999999)      RGB(1.0, 1.0,                    1.0)
            RGB(0.5000000000000001,      0.5000000000000001,      0.6666666666666669)      RGB(1.0,                    1.0,                    1.0)                     RGB(1.0, 1.0,                    1.0)
            RGB(0.75,                    0.75,                    1.0)                     RGB(1.0,                    1.0,                    1.0)                     RGB(1.0, 1.0,                    1.0)
            RGB(0.9999999999999999,      0.9999999999999999,      1.0)                     RGB(1.0,                    1.0,                    1.0)                     RGB(1.0, 1.0,                    1.0)
            RGB(1.0,                     1.0,                     1.0)                     RGB(1.0,                    1.0,                    1.0)                     RGB(1.0, 1.0,                    1.0)
        ])
    end

    @testset "RGBA over RGB: $T" for T in Ts
        @test BlendColorDodge(RGB{T}(1, 0.75, 0), RGBA{T}(0, 0.5, 1, 0.6)) ≈ RGB{T}(1.0, 0.9, 0.0)
    end

    @testset "RGB over RGBA: $T" for T in Ts
        @test BlendColorDodge(RGBA{T}(1, 0.75, 0, 0.6), RGB{T}(0, 0.5, 1)) ≈ RGBA{T}(0.6, 0.8, 0.4, 1)
    end

    @testset "RGBA over RGBA: $T" for T in Ts
        @test BlendColorDodge(RGBA{T}(1, 0.75, 0, 0.6), RGBA{T}(0, 0.5, 1, 0.6)) ≈ RGBA{T}(5/7, 11/14, 2/7, 0.84)
    end
end

@testset "color-burn" begin
    @testset "RGB over RGB" begin
        test_rgb_over_rgb(BlendColorBurn, RGB{Float64}[
            RGB(0.0, 0.0, 0.0)                RGB(0.0,                   0.0,                    0.0)                    RGB(0.0,                 0.0,                 0.0)
            RGB(0.0, 0.0, 0.0)                RGB(0.0,                   0.0,                    0.0)                    RGB(0.0,                 0.0,                 0.0)
            RGB(0.0, 0.0, 0.0)                RGB(0.0,                   0.0,                    0.0)                    RGB(0.25,                0.0,                 0.24999999999999992)
            RGB(0.0, 0.0, 0.0)                RGB(0.0,       #=1.11e-16=#2.2204460492503126e-16, 0.0)                    RGB(0.49999999999999994, 0.33333333333333326, 0.4999999999999999)
            RGB(0.0, 0.0, 0.0)                RGB(0.0,                   2.2204460492503126e-16, 0.0)                    RGB(0.5,                 0.3333333333333333,  0.49999999999999994)
            RGB(0.0, 0.0, 0.0)                RGB(2.220446049250313e-16, 4.440892098500625e-16,  1.1102230246251568e-16) RGB(0.5000000000000001,  0.3333333333333335,  0.5000000000000001)
            RGB(0.0, 0.0, 0.0)                RGB(0.5,                   0.5000000000000001,     0.49999999999999994)    RGB(0.75,                0.6666666666666666,  0.75)
            RGB(0.0, 0.0, 0.9999999999999996) RGB(0.9999999999999998,    0.9999999999999998,     0.9999999999999998)     RGB(0.9999999999999999,  0.9999999999999999,  0.9999999999999999)
            RGB(1.0, 1.0, 1.0)                RGB(1.0,                   1.0,                    1.0)                    RGB(1.0,                 1.0,                 1.0)
        ])
    end

    @testset "RGBA over RGB: $T" for T in Ts
        @test BlendColorBurn(RGB{T}(1, 0.75, 0), RGBA{T}(0, 0.5, 1, 0.6)) ≈ RGB{T}(1.0, 0.6, 0.0)
    end

    @testset "RGB over RGBA: $T" for T in Ts
        @test BlendColorBurn(RGBA{T}(1, 0.75, 0, 0.6), RGB{T}(0, 0.5, 1)) ≈ RGBA{T}(0.6, 0.5, 0.4, 1)
    end

    @testset "RGBA over RGBA: $T" for T in Ts
        @test BlendColorBurn(RGBA{T}(1, 0.75, 0, 0.6), RGBA{T}(0, 0.5, 1, 0.6)) ≈ RGBA{T}(5/7, 4/7, 2/7, 0.84)
    end
end

@testset "hard-light" begin
    @testset "RGB over RGB" begin
        test_rgb_over_rgb(BlendHardLight, RGB{Float64}[
            RGB(0.0, 0.0,                     0.0)                     RGB(0.0,                     2.220446049250313e-16, 0.0)                     RGB(1.0, 0.5,   0.9999999999999998)
            RGB(0.0, 0.0,                     1.1125369292536007e-308) RGB(2.2250738585072014e-308, 2.220446049250313e-16, 2.2250738585072014e-308) RGB(1.0, 0.5,   0.9999999999999998)
            RGB(0.0, 1.1125369292536007e-308, 0.125)                   RGB(0.25,                    0.25000000000000017,   0.24999999999999997)     RGB(1.0, 0.625, 0.9999999999999998)
            RGB(0.0, 2.2250738585072014e-308, 0.24999999999999997)     RGB(0.49999999999999994,     0.5000000000000001,    0.4999999999999999)      RGB(1.0, 0.75,  0.9999999999999999)
            RGB(0.0, 2.2250738585072014e-308, 0.25)                    RGB(0.5,                     0.5000000000000001,    0.49999999999999994)     RGB(1.0, 0.75,  0.9999999999999999)
            RGB(0.0, 2.225073858507202e-308,  0.25000000000000006)     RGB(0.5000000000000001,      0.5000000000000002,    0.5)                     RGB(1.0, 0.75,  0.9999999999999999)
            RGB(0.0, 3.337610787760802e-308,  0.375)                   RGB(0.75,                    0.75,                  0.7499999999999999)      RGB(1.0, 0.875, 1.0)
            RGB(0.0, 4.4501477170144023e-308, 0.49999999999999994)     RGB(0.9999999999999999,      0.9999999999999999,    0.9999999999999998)      RGB(1.0, 1.0,   1.0)
            RGB(0.0, 4.450147717014403e-308,  0.5)                     RGB(1.0,                     1.0,                   0.9999999999999999)      RGB(1.0, 1.0,   1.0)
        ])
    end

    @testset "RGBA over RGB: $T" for T in Ts
        @test BlendHardLight(RGB{T}(1, 0.75, 0), RGBA{T}(0, 0.5, 1, 0.6)) ≈ RGB{T}(0.4, 0.75, 0.6)
    end

    @testset "RGB over RGBA: $T" for T in Ts
        @test BlendHardLight(RGBA{T}(1, 0.75, 0, 0.6), RGB{T}(0, 0.5, 1)) ≈ RGBA{T}(0.0, 0.65, 1.0, 1)
    end

    @testset "RGBA over RGBA: $T" for T in Ts
        @test BlendHardLight(RGBA{T}(1, 0.75, 0, 0.6), RGBA{T}(0, 0.5, 1, 0.6)) ≈ RGBA{T}(2/7, 19/28, 5/7, 0.84)
    end
end

@testset "soft-light" begin
    @testset "RGB over RGB" begin
        test_rgb_over_rgb(BlendSoftLight, RGB{Float64}[
            RGB(0.0,                 0.0,                 0.0)                     RGB(0.0,                     0.0,                    0.0)                     RGB(0.0,                    0.0,                    0.0)
            RGB(0.0,                 0.0,                 1.1125369292536007e-308) RGB(2.2250738585072014e-308, 2.225073858507203e-308, 2.2250738585072014e-308) RGB(8.900295434028806e-308, 5.562684646268003e-308, 8.900295434028804e-308)
            RGB(0.0625,              0.0625,              0.15625)                 RGB(0.25,                    0.25000000000000006,    0.24999999999999997)     RGB(0.5,                    0.375,                  0.49999999999999994)
            RGB(0.24999999999999994, 0.24999999999999994, 0.37499999999999994)     RGB(0.49999999999999994,     0.5,                    0.49999999999999994)     RGB(0.7071067811865475,     0.6035533905932737,     0.7071067811865475)
            RGB(0.25,                0.25,                0.375)                   RGB(0.5,                     0.5,                    0.5)                     RGB(0.7071067811865476,     0.6035533905932737,     0.7071067811865475)
            RGB(0.2500000000000001,  0.2500000000000001,  0.3750000000000001)      RGB(0.5000000000000001,      0.5000000000000001,     0.5000000000000001)      RGB(0.7071067811865476,     0.6035533905932738,     0.7071067811865476)
            RGB(0.5625,              0.5625,              0.65625)                 RGB(0.75,                    0.75,                   0.75)                    RGB(0.8660254037844386,     0.8080127018922193,     0.8660254037844386)
            RGB(0.9999999999999998,  0.9999999999999998,  0.9999999999999999)      RGB(0.9999999999999999,      0.9999999999999999,     0.9999999999999999)      RGB(0.9999999999999999,     0.9999999999999999,     0.9999999999999999)
            RGB(1.0,                 1.0,                 1.0)                     RGB(1.0,                     1.0,                    1.0)                     RGB(1.0,                    1.0,                    1.0)
        ])
    end

    @testset "RGBA over RGB: $T" for T in Ts
        @test BlendSoftLight(RGB{T}(1, 0.75, 0), RGBA{T}(0, 0.5, 1, 0.6)) ≈ RGB{T}(1.0, 0.75, 0.0)
    end

    @testset "RGB over RGBA: $T" for T in Ts
        @test BlendSoftLight(RGBA{T}(1, 0.75, 0, 0.6), RGB{T}(0, 0.5, 1)) ≈ RGBA{T}(0.6, 0.65, 0.4, 1)
    end

    @testset "RGBA over RGBA: $T" for T in Ts
        @test BlendSoftLight(RGBA{T}(1, 0.75, 0, 0.6), RGBA{T}(0, 0.5, 1, 0.6)) ≈ RGBA{T}(5/7, 19/28, 2/7, 0.84)
    end
end

@testset "difference" begin
    @testset "RGB over RGB" begin
        test_rgb_over_rgb(BlendDifference, RGB{Float64}[
            RGB(0.0,                     2.2250738585072014e-308, 0.25)                RGB(0.5,                    0.5000000000000001,     0.49999999999999994)    RGB(1.0,                    0.75,                0.9999999999999999)
            RGB(2.2250738585072014e-308, 0.0,                     0.25)                RGB(0.5,                    0.5000000000000001,     0.49999999999999994)    RGB(1.0,                    0.75,                0.9999999999999999)
            RGB(0.25,                    0.25,                    0.0)                 RGB(0.25,                   0.2500000000000001,     0.24999999999999994)    RGB(0.75,                   0.5,                 0.7499999999999999)
            RGB(0.49999999999999994,     0.49999999999999994,     0.24999999999999994) RGB(5.551115123125783e-17,  1.6653345369377348e-16, 0.0)                    RGB(0.5,                    0.25000000000000006, 0.49999999999999994)
            RGB(0.5,                     0.5,                     0.25)                RGB(0.0,                    1.1102230246251565e-16, 5.551115123125783e-17)  RGB(0.5,                    0.25,                0.4999999999999999)
            RGB(0.5000000000000001,      0.5000000000000001,      0.2500000000000001)  RGB(1.1102230246251565e-16, 0.0,                    1.6653345369377348e-16) RGB(0.4999999999999999,     0.2499999999999999,  0.4999999999999998)
            RGB(0.75,                    0.75,                    0.5)                 RGB(0.25,                   0.2499999999999999,     0.25000000000000006)    RGB(0.25,                   0.0,                 0.2499999999999999)
            RGB(0.9999999999999999,      0.9999999999999999,      0.7499999999999999)  RGB(0.4999999999999999,     0.4999999999999998,     0.49999999999999994)    RGB(1.1102230246251565e-16, 0.2499999999999999,  0.0)
            RGB(1.0,                     1.0,                     0.75)                RGB(0.5,                    0.4999999999999999,     0.5)                    RGB(0.0,                    0.25,                1.1102230246251565e-16)
        ])
    end

    @testset "RGBA over RGB: $T" for T in Ts
        @test BlendDifference(RGB{T}(1, 0.75, 0), RGBA{T}(0, 0.5, 1, 0.6)) ≈ RGB{T}(1.0, 0.45, 0.6)
    end

    @testset "RGB over RGBA: $T" for T in Ts
        @test BlendDifference(RGBA{T}(1, 0.75, 0, 0.6), RGB{T}(0, 0.5, 1)) ≈ RGBA{T}(0.6, 0.35, 1.0, 1)
    end

    @testset "RGBA over RGBA: $T" for T in Ts
        @test BlendDifference(RGBA{T}(1, 0.75, 0, 0.6), RGBA{T}(0, 0.5, 1, 0.6)) ≈ RGBA{T}(5/7, 13/28, 5/7, 0.84)
    end
end

@testset "exclusion" begin
    @testset "RGB over RGB" begin
        test_rgb_over_rgb(BlendExclusion, RGB{Float64}[
            RGB(0.0,                     2.2250738585072014e-308, 0.25)  RGB(0.5, 0.5000000000000001,  0.49999999999999994) RGB(1.0,                    0.75,                0.9999999999999999)
            RGB(2.2250738585072014e-308, 4.450147717014403e-308,  0.25)  RGB(0.5, 0.5000000000000001,  0.49999999999999994) RGB(1.0,                    0.75,                0.9999999999999999)
            RGB(0.25,                    0.25,                    0.375) RGB(0.5, 0.5,                 0.5)                 RGB(0.75,                   0.625,               0.75)
            RGB(0.49999999999999994,     0.49999999999999994,     0.5)   RGB(0.5, 0.5,                 0.5)                 RGB(0.5,                    0.5,                 0.5)
            RGB(0.5,                     0.5,                     0.5)   RGB(0.5, 0.5,                 0.5)                 RGB(0.5,                    0.5,                 0.5)
            RGB(0.5000000000000001,      0.5000000000000001,      0.5)   RGB(0.5, 0.5,                 0.5)                 RGB(0.4999999999999999,     0.49999999999999994, 0.4999999999999999)
            RGB(0.75,                    0.75,                    0.625) RGB(0.5, 0.49999999999999994, 0.5)                 RGB(0.25,                   0.375,               0.25000000000000006)
            RGB(0.9999999999999999,      0.9999999999999999,      0.75)  RGB(0.5, 0.4999999999999999,  0.5)                 RGB(1.1102230246251565e-16, 0.25000000000000006, 2.2204460492503128e-16)
            RGB(1.0,                     1.0,                     0.75)  RGB(0.5, 0.4999999999999999,  0.5)                 RGB(0.0,                    0.25,                1.1102230246251565e-16)
        ])
    end

    @testset "RGBA over RGB: $T" for T in Ts
        @test BlendExclusion(RGB{T}(1, 0.75, 0), RGBA{T}(0, 0.5, 1, 0.6)) ≈ RGB{T}(1.0, 0.6, 0.6)
    end

    @testset "RGB over RGBA: $T" for T in Ts
        @test BlendExclusion(RGBA{T}(1, 0.75, 0, 0.6), RGB{T}(0, 0.5, 1)) ≈ RGBA{T}(0.6, 0.5, 1.0, 1)
    end

    @testset "RGBA over RGBA: $T" for T in Ts
        @test BlendExclusion(RGBA{T}(1, 0.75, 0, 0.6), RGBA{T}(0, 0.5, 1, 0.6)) ≈ RGBA{T}(5/7, 4/7, 5/7, 0.84)
    end
end

@testset "hue" begin
    @testset "RGB over RGB" begin
        test_rgb_over_rgb(BlendHue, RGB{Float64}[
            RGB(0.0,                     0.0,                     0.0)                     RGB(0.0,                     0.0,                     0.0)                     RGB(0.0,                     0.0,                     0.0)
            RGB(2.2250738585072014e-308, 2.2250738585072014e-308, 2.2250738585072014e-308) RGB(2.2250738585072014e-308, 2.2250738585072014e-308, 2.2250738585072014e-308) RGB(2.2250738585072014e-308, 2.2250738585072014e-308, 2.2250738585072014e-308)
            RGB(0.25,                    0.25,                    0.25)                    RGB(0.25,                    0.25,                    0.25)                    RGB(0.25,                    0.25,                    0.25)
            RGB(0.49999999999999994,     0.49999999999999994,     0.49999999999999994)     RGB(0.49999999999999994,     0.49999999999999994,     0.49999999999999994)     RGB(0.49999999999999994,     0.49999999999999994,     0.49999999999999994)
            RGB(0.5,                     0.5,                     0.5)                     RGB(0.5,                     0.5,                     0.5)                     RGB(0.5,                     0.5,                     0.5)
            RGB(0.5000000000000001,      0.5000000000000001,      0.5000000000000001)      RGB(0.5000000000000001,      0.5000000000000001,      0.5000000000000001)      RGB(0.5000000000000001,      0.5000000000000001,      0.5000000000000001)
            RGB(0.75,                    0.75,                    0.75)                    RGB(0.75,                    0.75,                    0.75)                    RGB(0.75,                    0.75,                    0.75)
            RGB(0.9999999999999999,      0.9999999999999999,      0.9999999999999999)      RGB(0.9999999999999999,      0.9999999999999999,      0.9999999999999999)      RGB(0.9999999999999999,      0.9999999999999999,      0.9999999999999999)
            RGB(1.0,                     1.0,                     1.0)                     RGB(1.0,                     1.0,                     1.0)                     RGB(1.0,                     1.0,                     1.0)
        ])
    end

    @testset "RGBA over RGB: $T" for T in Ts
        @test BlendHue(RGB{T}(1, 0.75, 0), RGBA{T}(0, 0.5, 1, 0.6)) ≈ RGB{T}(0.740, 0.770, 0.6) atol=max(0.0005, eps(T))
    end

    @testset "RGB over RGBA: $T" for T in Ts
        @test BlendHue(RGBA{T}(1, 0.75, 0, 0.6), RGB{T}(0, 0.5, 1)) ≈ RGBA{T}(0.340, 0.670, 1.0, 1) atol=max(0.0005, eps(T))
    end

    @testset "RGBA over RGBA: $T" for T in Ts
        @test BlendHue(RGBA{T}(1, 0.75, 0, 0.6), RGBA{T}(0, 0.5, 1, 0.6)) ≈ RGBA{T}(0.529, 0.693, 5/7, 0.84) atol=max(0.0005, eps(T))
    end
end

@testset "saturation" begin
    @testset "RGB over RGB" begin
        test_rgb_over_rgb(BlendSaturation, RGB{Float64}[
            RGB(0.0,                     0.0,                     0.0)                     RGB(0.0,                     0.0,                     0.0)                     RGB(0.0,                     0.0,                     0.0)
            RGB(2.2250738585072014e-308, 2.2250738585072014e-308, 2.2250738585072014e-308) RGB(2.2250738585072014e-308, 2.2250738585072014e-308, 2.2250738585072014e-308) RGB(2.2250738585072014e-308, 2.2250738585072014e-308, 2.2250738585072014e-308)
            RGB(0.25,                    0.25,                    0.25)                    RGB(0.25,                    0.25,                    0.25)                    RGB(0.25,                    0.25,                    0.25)
            RGB(0.49999999999999994,     0.49999999999999994,     0.49999999999999994)     RGB(0.49999999999999994,     0.49999999999999994,     0.49999999999999994)     RGB(0.49999999999999994,     0.49999999999999994,     0.49999999999999994)
            RGB(0.5,                     0.5,                     0.5)                     RGB(0.5,                     0.5,                     0.5)                     RGB(0.5,                     0.5,                     0.5)
            RGB(0.5000000000000001,      0.5000000000000001,      0.5000000000000001)      RGB(0.5000000000000001,      0.5000000000000001,      0.5000000000000001)      RGB(0.5000000000000001,      0.5000000000000001,      0.5000000000000001)
            RGB(0.75,                    0.75,                    0.75)                    RGB(0.75,                    0.75,                    0.75)                    RGB(0.75,                    0.75,                    0.75)
            RGB(0.9999999999999999,      0.9999999999999999,      0.9999999999999999)      RGB(0.9999999999999999,      0.9999999999999999,      0.9999999999999999)      RGB(0.9999999999999999,      0.9999999999999999,      0.9999999999999999)
            RGB(1.0,                     1.0,                     1.0)                     RGB(1.0,                     1.0,                     1.0)                     RGB(1.0,                     1.0,                     1.0)
        ])
    end

    @testset "RGBA over RGB: $T" for T in Ts
        @test BlendSaturation(RGB{T}(1, 0.75, 0), RGBA{T}(0, 0.5, 1, 0.6)) ≈ RGB{T}(1.0, 0.75, 0.0)
    end

    @testset "RGB over RGBA: $T" for T in Ts
        @test BlendSaturation(RGBA{T}(1, 0.75, 0, 0.6), RGB{T}(0, 0.5, 1)) ≈ RGBA{T}(0.6, 0.65, 0.4, 1)
    end

    @testset "RGBA over RGBA: $T" for T in Ts
        @test BlendSaturation(RGBA{T}(1, 0.75, 0, 0.6), RGBA{T}(0, 0.5, 1, 0.6)) ≈ RGBA{T}(5/7, 19/28, 2/7, 0.84)
    end
end

@testset "color" begin
    @testset "RGB over RGB" begin
        test_rgb_over_rgb(BlendColor, RGB{Float64}[
            RGB(0.0,                0.0,                0.0)                     RGB(0.0,                     0.0,                    0.0)                 RGB(0.0,                    0.0,                 0.0)
            RGB(0.0,                0.0,                2.0227944168247287e-307) RGB(1.0749149074914015e-308, 3.224744722474205e-308, 0.0)                 RGB(5.427009410993175e-308, 0.0,                 5.427009410993172e-308)
            RGB(0.2225,             0.2225,             0.4725)                  RGB(0.24999999999999994,     0.25000000000000006,    0.2499999999999999)  RGB(0.3975,                 0.14750000000000002, 0.3974999999999999)
            RGB(0.4724999999999999, 0.4724999999999999, 0.7224999999999999)      RGB(0.4999999999999999,      0.5,                    0.49999999999999983) RGB(0.6475,                 0.39749999999999996, 0.6474999999999999)
            RGB(0.4725,             0.4725,             0.7225)                  RGB(0.49999999999999994,     0.5,                    0.4999999999999999)  RGB(0.6475,                 0.3975,              0.6474999999999999)
            RGB(0.4725000000000001, 0.4725000000000001, 0.7225000000000001)      RGB(0.5,                     0.5000000000000001,     0.5)                 RGB(0.6475000000000001,     0.39750000000000013, 0.6475)
            RGB(0.7225,             0.7225,             0.9725)                  RGB(0.7499999999999999,      0.75,                   0.7499999999999999)  RGB(0.8975,                 0.6475,              0.8974999999999999)
            RGB(0.9999999999999999, 1.0,                1.0)                     RGB(0.9999999999999998,      0.9999999999999999,     0.9999999999999998)  RGB(1.0,                    1.0,                 1.0)
            RGB(1.0,                1.0,                1.0)                     RGB(1.0,                     1.0,                    1.0)                 RGB(1.0,                    1.0,                 1.0)
        ])
    end

    @testset "RGBA over RGB: $T" for T in Ts
        @test BlendColor(RGB{T}(1, 0.75, 0), RGBA{T}(0, 0.5, 1, 0.6)) ≈ RGB{T}(0.740, 0.770, 0.6) atol=max(0.0005, eps(T))
    end

    @testset "RGB over RGBA: $T" for T in Ts
        @test BlendColor(RGBA{T}(1, 0.75, 0, 0.6), RGB{T}(0, 0.5, 1)) ≈ RGBA{T}(0.340, 0.670, 1.0, 1) atol=max(0.0005, eps(T))
    end

    @testset "RGBA over RGBA: $T" for T in Ts
        @test BlendColor(RGBA{T}(1, 0.75, 0, 0.6), RGBA{T}(0, 0.5, 1, 0.6)) ≈ RGBA{T}(0.529, 0.693, 5/7, 0.84) atol=max(0.0005, eps(T))
    end
end

@testset "luminosity" begin
    @testset "RGB over RGB" begin
        test_rgb_over_rgb(BlendLuminosity, RGB{Float64}[
            RGB(0.0275, 0.0275, 0.0275) RGB(0.5000000000000001, 0.5000000000000001, 0.5000000000000001) RGB(0.8525, 0.8525, 0.8525)
            RGB(0.0275, 0.0275, 0.0275) RGB(0.5000000000000001, 0.5000000000000001, 0.5000000000000001) RGB(0.8525, 0.8525, 0.8525)
            RGB(0.0275, 0.0275, 0.0275) RGB(0.5000000000000001, 0.5000000000000001, 0.5000000000000001) RGB(0.8525, 0.8525, 0.8525)
            RGB(0.0275, 0.0275, 0.0275) RGB(0.5000000000000001, 0.5000000000000001, 0.5000000000000001) RGB(0.8525, 0.8525, 0.8525)
            RGB(0.0275, 0.0275, 0.0275) RGB(0.5000000000000001, 0.5000000000000001, 0.5000000000000001) RGB(0.8525, 0.8525, 0.8525)
            RGB(0.0275, 0.0275, 0.0275) RGB(0.5000000000000001, 0.5000000000000001, 0.5000000000000001) RGB(0.8525, 0.8525, 0.8525)
            RGB(0.0275, 0.0275, 0.0275) RGB(0.5000000000000001, 0.5000000000000001, 0.5000000000000001) RGB(0.8525, 0.8525, 0.8525)
            RGB(0.0275, 0.0275, 0.0275) RGB(0.5000000000000001, 0.5000000000000001, 0.5000000000000001) RGB(0.8525, 0.8525, 0.8525)
            RGB(0.0275, 0.0275, 0.0275) RGB(0.5000000000000001, 0.5000000000000001, 0.5000000000000001) RGB(0.8525, 0.8525, 0.8525)
        ])
    end

    @testset "RGBA over RGB: $T" for T in Ts
        @test BlendLuminosity(RGB{T}(1, 0.75, 0), RGBA{T}(0, 0.5, 1, 0.6)) ≈ RGB{T}(0.727, 0.545, 0.0) atol=max(0.0005, eps(T))
    end

    @testset "RGB over RGBA: $T" for T in Ts
        @test BlendLuminosity(RGBA{T}(1, 0.75, 0, 0.6), RGB{T}(0, 0.5, 1)) ≈ RGBA{T}(0.327, 0.445, 0.4, 1) atol=max(0.0005, eps(T))
    end

    @testset "RGBA over RGBA: $T" for T in Ts
        @test BlendLuminosity(RGBA{T}(1, 0.75, 0, 0.6), RGBA{T}(0, 0.5, 1, 0.6)) ≈ RGBA{T}(0.519, 0.532, 2/7, 0.84) atol=max(0.0005, eps(T))
    end
end
