Skip to content

Commit 830c877

Browse files
committed
Avoid trying to call parametric constructors for non-parametric types
Fixes #56
1 parent 602ec6e commit 830c877

File tree

2 files changed

+40
-12
lines changed

2 files changed

+40
-12
lines changed

src/ColorVectorSpace.jl

Lines changed: 19 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -108,6 +108,13 @@ _color_rettype{C<:Colorant}(::Type{C}, ::Type{C}) = C
108108

109109
color_rettype(c1::Colorant, c2::Colorant) = color_rettype(typeof(c1), typeof(c2))
110110

111+
arith_colorant_type(::C) where {C<:Colorant} = arith_colorant_type(C)
112+
arith_colorant_type(::Type{C}) where {C<:Colorant} = base_colorant_type(C)
113+
arith_colorant_type(::Type{Gray24}) = Gray
114+
arith_colorant_type(::Type{AGray32}) = AGray
115+
arith_colorant_type(::Type{RGB24}) = RGB
116+
arith_colorant_type(::Type{ARGB32}) = ARGB
117+
111118
## Math on Colors. These implementations encourage inlining and,
112119
## for the case of Normed types, nearly halve the number of multiplications (for RGB)
113120

@@ -117,23 +124,23 @@ copy(c::AbstractRGB) = c
117124
(+)(c::TransparentRGB) = mapc(+, c)
118125
(-)(c::AbstractRGB) = mapc(-, c)
119126
(-)(c::TransparentRGB) = mapc(-, c)
120-
(*)(f::Real, c::AbstractRGB) = base_colorant_type(c){multype(typeof(f),eltype(c))}(f*red(c), f*green(c), f*blue(c))
121-
(*)(f::Real, c::TransparentRGB) = base_colorant_type(c){multype(typeof(f),eltype(c))}(f*red(c), f*green(c), f*blue(c), f*alpha(c))
127+
(*)(f::Real, c::AbstractRGB) = arith_colorant_type(c){multype(typeof(f),eltype(c))}(f*red(c), f*green(c), f*blue(c))
128+
(*)(f::Real, c::TransparentRGB) = arith_colorant_type(c){multype(typeof(f),eltype(c))}(f*red(c), f*green(c), f*blue(c), f*alpha(c))
122129
function (*){T<:Normed}(f::Real, c::AbstractRGB{T})
123130
fs = f*(1/reinterpret(oneunit(T)))
124-
base_colorant_type(c){multype(typeof(f),T)}(fs*reinterpret(red(c)), fs*reinterpret(green(c)), fs*reinterpret(blue(c)))
131+
arith_colorant_type(c){multype(typeof(f),T)}(fs*reinterpret(red(c)), fs*reinterpret(green(c)), fs*reinterpret(blue(c)))
125132
end
126133
function (*){T<:Normed}(f::Normed, c::AbstractRGB{T})
127134
fs = reinterpret(f)*(1/widen(reinterpret(oneunit(T)))^2)
128-
base_colorant_type(c){multype(typeof(f),T)}(fs*reinterpret(red(c)), fs*reinterpret(green(c)), fs*reinterpret(blue(c)))
135+
arith_colorant_type(c){multype(typeof(f),T)}(fs*reinterpret(red(c)), fs*reinterpret(green(c)), fs*reinterpret(blue(c)))
129136
end
130137
function (/){T<:Normed}(c::AbstractRGB{T}, f::Real)
131138
fs = (one(f)/reinterpret(oneunit(T)))/f
132-
base_colorant_type(c){divtype(typeof(f),T)}(fs*reinterpret(red(c)), fs*reinterpret(green(c)), fs*reinterpret(blue(c)))
139+
arith_colorant_type(c){divtype(typeof(f),T)}(fs*reinterpret(red(c)), fs*reinterpret(green(c)), fs*reinterpret(blue(c)))
133140
end
134141
function (/){T<:Normed}(c::AbstractRGB{T}, f::Integer)
135142
fs = (1/reinterpret(oneunit(T)))/f
136-
base_colorant_type(c){divtype(typeof(f),T)}(fs*reinterpret(red(c)), fs*reinterpret(green(c)), fs*reinterpret(blue(c)))
143+
arith_colorant_type(c){divtype(typeof(f),T)}(fs*reinterpret(red(c)), fs*reinterpret(green(c)), fs*reinterpret(blue(c)))
137144
end
138145
(+){S,T}(a::AbstractRGB{S}, b::AbstractRGB{T}) = color_rettype(a, b){sumtype(S,T)}(red(a)+red(b), green(a)+green(b), blue(a)+blue(b))
139146
(-){S,T}(a::AbstractRGB{S}, b::AbstractRGB{T}) = color_rettype(a, b){sumtype(S,T)}(red(a)-red(b), green(a)-green(b), blue(a)-blue(b))
@@ -202,11 +209,11 @@ for op in unaryOps
202209
@eval ($op)(c::AbstractGray) = $op(gray(c))
203210
end
204211

205-
middle(c::AbstractGray) = base_colorant_type(c)(middle(gray(c)))
206-
middle(x::C, y::C) where {C<:AbstractGray} = C(middle(gray(x), gray(y)))
212+
middle(c::AbstractGray) = arith_colorant_type(c)(middle(gray(c)))
213+
middle(x::C, y::C) where {C<:AbstractGray} = arith_colorant_type(C)(middle(gray(x), gray(y)))
207214

208-
(*)(f::Real, c::AbstractGray) = base_colorant_type(c){multype(typeof(f),eltype(c))}(f*gray(c))
209-
(*)(f::Real, c::TransparentGray) = base_colorant_type(c){multype(typeof(f),eltype(c))}(f*gray(c), f*alpha(c))
215+
(*)(f::Real, c::AbstractGray) = arith_colorant_type(c){multype(typeof(f),eltype(c))}(f*gray(c))
216+
(*)(f::Real, c::TransparentGray) = arith_colorant_type(c){multype(typeof(f),eltype(c))}(f*gray(c), f*alpha(c))
210217
(*)(c::AbstractGray, f::Real) = (*)(f, c)
211218
(*)(c::TransparentGray, f::Real) = (*)(f, c)
212219
(/)(c::AbstractGray, f::Real) = (one(f)/f)*c
@@ -219,8 +226,8 @@ middle(x::C, y::C) where {C<:AbstractGray} = C(middle(gray(x), gray(y)))
219226
(-){S,T}(a::AbstractGray{S}, b::AbstractGray{T}) = color_rettype(a,b){sumtype(S,T)}(gray(a)-gray(b))
220227
(-)(a::TransparentGray, b::TransparentGray) = color_rettype(a,b){sumtype(eltype(a),eltype(b))}(gray(a)-gray(b),alpha(a)-alpha(b))
221228
(*){S,T}(a::AbstractGray{S}, b::AbstractGray{T}) = color_rettype(a,b){multype(S,T)}(gray(a)*gray(b))
222-
(^){S}(a::AbstractGray{S}, b::Integer) = base_colorant_type(a){powtype(S,Int)}(gray(a)^convert(Int,b))
223-
(^){S}(a::AbstractGray{S}, b::Real) = base_colorant_type(a){powtype(S,typeof(b))}(gray(a)^b)
229+
(^){S}(a::AbstractGray{S}, b::Integer) = arith_colorant_type(a){powtype(S,Int)}(gray(a)^convert(Int,b))
230+
(^){S}(a::AbstractGray{S}, b::Real) = arith_colorant_type(a){powtype(S,typeof(b))}(gray(a)^b)
224231
(+)(c::AbstractGray) = c
225232
(+)(c::TransparentGray) = c
226233
(-)(c::AbstractGray) = typeof(c)(-gray(c))

test/runtests.jl

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -120,6 +120,12 @@ end
120120
@test quantile( Gray{N0f16}[0.0,0.5,1.0], 0.1) 0.10000152590218968
121121
@test middle(Gray(0.2)) === Gray(0.2)
122122
@test middle(Gray(0.2), Gray(0.4)) === Gray((0.2+0.4)/2)
123+
124+
# issue #56
125+
@test Gray24(0.8)*N0f8(0.5) === Gray{N0f8}(0.4)
126+
@test Gray24(0.8)*0.5 === Gray(0.4)
127+
@test Gray24(0.8)/2 === Gray(0.5f0*N0f8(0.8))
128+
@test Gray24(0.8)/2.0 === Gray(0.4)
123129
end
124130

125131
@testset "Comparisons with Gray" begin
@@ -195,6 +201,11 @@ end
195201
@test !isapprox(a, b, rtol = 0.01)
196202
@test isapprox(a, b, rtol = 0.1)
197203

204+
# issue #56
205+
@test AGray32(0.8,0.2)*N0f8(0.5) === AGray{N0f8}(0.4,0.1)
206+
@test AGray32(0.8,0.2)*0.5 === AGray(0.4,0.1)
207+
@test AGray32(0.8,0.2)/2 === AGray(0.5f0*N0f8(0.8),0.5f0*N0f8(0.2))
208+
@test AGray32(0.8,0.2)/2.0 === AGray(0.4,0.1)
198209
end
199210

200211
@testset "Arithemtic with RGB" begin
@@ -265,6 +276,11 @@ end
265276
a = RGB{Float64}(1.0, 1.0, 0.99)
266277
@test !(isapprox(a, b, rtol = 0.01))
267278
@test isapprox(a, b, rtol = 0.1)
279+
# issue #56
280+
@test RGB24(1,0,0)*N0f8(0.5) === RGB{N0f8}(0.5,0,0)
281+
@test RGB24(1,0,0)*0.5 === RGB(0.5,0,0)
282+
@test RGB24(1,0,0)/2 === RGB(0.5f0,0,0)
283+
@test RGB24(1,0,0)/2.0 === RGB(0.5,0,0)
268284
end
269285

270286
@testset "Arithemtic with RGBA" begin
@@ -335,6 +351,11 @@ end
335351
a = ARGB{Float64}(1.0, 1.0, 1.0, 0.99)
336352
@test !(isapprox(a, b, rtol = 0.01))
337353
@test isapprox(a, b, rtol = 0.1)
354+
# issue #56
355+
@test ARGB32(1,0,0,0.8)*N0f8(0.5) === ARGB{N0f8}(0.5,0,0,0.4)
356+
@test ARGB32(1,0,0,0.8)*0.5 === ARGB(0.5,0,0,0.4)
357+
@test ARGB32(1,0,0,0.8)/2 === ARGB(0.5f0,0,0,0.5f0*N0f8(0.8))
358+
@test ARGB32(1,0,0,0.8)/2.0 === ARGB(0.5,0,0,0.4)
338359
end
339360

340361
@testset "Mixed-type arithmetic" begin

0 commit comments

Comments
 (0)