Skip to content

Commit f341eb6

Browse files
authored
upgrade to ColorVectorSpace 0.9 and reduce latency (#157)
1 parent 5b2202d commit f341eb6

14 files changed

+159
-317
lines changed

Project.toml

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ version = "0.8.22"
44

55
[deps]
66
AbstractFFTs = "621f4979-c628-5d54-868e-fcf4e3e8185c"
7+
ColorVectorSpace = "c3611d14-8923-5661-9e6a-0046d554d3a4"
78
Colors = "5ae59095-9a9b-59fe-a467-6f913c188581"
89
FixedPointNumbers = "53c48c17-4a7d-5ca2-90c5-79b7896eea93"
910
Graphics = "a2bd30eb-e257-5431-a919-1863eab51364"
@@ -15,9 +16,9 @@ Reexport = "189a3867-3050-52da-a836-e630ba90ab69"
1516

1617
[compat]
1718
AbstractFFTs = "0.4, 0.5, 1.0"
18-
ColorVectorSpace = "0.8"
19-
Colors = "0.9, 0.10, 0.11, 0.12"
20-
FixedPointNumbers = "0.6.1, 0.7, 0.8"
19+
ColorVectorSpace = "0.9"
20+
Colors = "0.12"
21+
FixedPointNumbers = "0.8"
2122
Graphics = "0.4, 1.0"
2223
MappedArrays = "0.2, 0.3, 0.4"
2324
MosaicViews = "0.3.3"

src/ImageCore.jl

Lines changed: 1 addition & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,9 @@
1-
VERSION < v"0.7.0-beta2.199" && __precompile__()
2-
31
module ImageCore
42

53
using Reexport
64
@reexport using FixedPointNumbers
75
@reexport using Colors
8-
if isdefined(ColorTypes, :XRGB) && isdefined(ColorTypes, :RGB1)
9-
Base.@deprecate_binding RGB1 XRGB
10-
Base.@deprecate_binding RGB4 RGBX
11-
end
12-
# backward compatibility for ColorTypes < v0.9
13-
if !isdefined(ColorTypes, :XRGB)
14-
const XRGB = RGB1
15-
const RGBX = RGB4
16-
end
6+
@reexport using ColorVectorSpace
177

188
@reexport using MosaicViews
199
@reexport using PaddedViews

src/colorchannels.jl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -217,7 +217,7 @@ colorview(::Type{C}) where C<:Colorant = (As...) -> colorview(C, As...)
217217
_colorview_type(::Type{Any}, ::Type{T}) where {T} = T
218218
_colorview_type(::Type{T1}, ::Type{T2}) where {T1,T2} = T1
219219

220-
Base.@pure promote_eleltype_all(gray, grays...) = _promote_eleltype_all(beltype(eltype(gray)), grays...)
220+
Base.@pure @inline promote_eleltype_all(gray, grays...) = _promote_eleltype_all(beltype(eltype(gray)), grays...)
221221
@inline function _promote_eleltype_all(::Type{T}, gray, grays...) where T
222222
_promote_eleltype_all(promote_type(T, beltype(eltype(gray))), grays...)
223223
end

src/convert_reinterpret.jl

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -83,7 +83,6 @@ for (fn,T) in (#(:float16, Float16), # Float16 currently has promotion problem
8383
($fn)(::Type{S}) where {S<:Number } = $T
8484
($fn)(c::Colorant) = convert(($fn)(typeof(c)), c)
8585
($fn)(n::Number) = convert(($fn)(typeof(n)), n)
86-
@deprecate ($fn)(A::AbstractArray{C}) where {C<:Colorant} ($fn).(A)
8786
fname = $(Expr(:quote, fn))
8887
Tname = shortname($T)
8988
@doc """

src/deprecations.jl

Lines changed: 0 additions & 68 deletions
Original file line numberDiff line numberDiff line change
@@ -16,73 +16,5 @@ else
1616
forced_depwarn(msg, sym) = Base.depwarn(msg, sym)
1717
end
1818

19-
Base.@deprecate_binding ChannelView channelview
20-
21-
export ColorView
22-
23-
struct ColorView{C<:Colorant,N,A<:AbstractArray} <: AbstractArray{C,N}
24-
parent::A
25-
26-
function ColorView{C,N,A}(parent::AbstractArray{T}) where {C,N,A,T<:Number}
27-
n = length(colorview_size(C, parent))
28-
n == N || throw(DimensionMismatch("for an $N-dimensional ColorView with color type $C, input dimensionality should be $n instead of $(ndims(parent))"))
29-
checkdim1(C, axes(parent))
30-
forced_depwarn("ColorView{C}(A) is deprecated, use colorview(C, A)", :ColorView)
31-
colorview(C, A)
32-
end
33-
end
34-
35-
function ColorView{C}(A::AbstractArray) where C<:Colorant
36-
forced_depwarn("ColorView{C}(A) is deprecated, use colorview(C, A)", :ColorView)
37-
colorview(C, A)
38-
end
39-
40-
ColorView(parent::AbstractArray) = error("must specify the colortype, use colorview(C, A)")
41-
42-
Base.@deprecate_binding squeeze1 true
43-
44-
import Base: convert
45-
46-
function cname(::Type{C}) where C
47-
io = IOBuffer()
48-
ColorTypes.colorant_string_with_eltype(io, C)
49-
return String(take!(io))
50-
end
51-
52-
const _explain =
53-
"""will soon switch to returning an array with non-concrete element type, which adds flexibility but
54-
with great cost to performance. To maintain the current behavior, use"""
55-
56-
function convert(::Type{Array{Cdest}}, img::AbstractArray{Csrc,n}) where {Cdest<:Colorant,n,Csrc<:Colorant}
57-
if isconcretetype(Cdest)
58-
# This mimics the Base implementation
59-
return img isa Array{Cdest} ? img : Array{Cdest}(img)
60-
end
61-
forced_depwarn("`convert(Array{$(cname(Cdest))}, img)` $_explain `$(cname(Cdest)).(img)` instead.", :convert)
62-
convert(Array, Cdest.(img))
63-
end
64-
65-
function convert(::Type{Array{Cdest}}, img::AbstractArray{T,n}) where {Cdest<:Color1,n,T<:Real}
66-
if isconcretetype(Cdest)
67-
return img isa Array{Cdest} ? img : Array{Cdest}(img)
68-
end
69-
forced_depwarn("`convert(Array{$(cname(Cdest))}, img)` $_explain `$(cname(Cdest)).(img)` instead.", :convert)
70-
convert(Array, Cdest.(img))
71-
end
72-
73-
function convert(::Type{OffsetArray{Cdest,n,A}}, img::AbstractArray{Csrc,n}) where {Cdest<:Colorant,n, A <:AbstractArray,Csrc<:Colorant}
74-
if isconcretetype(Cdest) && isconcretetype(A) && eltype(A) === Cdest
75-
return img isa OffsetArray{Cdest,n,A} ? img : (img isa OffsetArray ? OffsetArray(A(Cdest.(parent(img))), axes(img)) : OffsetArray(A(Cdest.(img)), axes(img)))
76-
end
77-
if img isa OffsetArray
78-
forced_depwarn("`convert(OffsetArray{$(cname(Cdest))}, img)` $_explain `$(cname(Cdest)).(img)` instead.", :convert)
79-
else
80-
forced_depwarn("`convert(OffsetArray{$(cname(Cdest))}, img)` $_explain `OffsetArray($(cname(Cdest)).(img), axes(img))` instead.", :convert)
81-
end
82-
OffsetArray(Cdest.(img), axes(img))
83-
end
84-
85-
convert(::Type{OffsetArray{Cdest,n,A}}, img::OffsetArray{Cdest,n,A}) where {Cdest<:Colorant,n, A <:AbstractArray} = img
86-
8719
# a perhaps "permanent" deprecation
8820
Base.@deprecate_binding permuteddimsview PermutedDimsArray

src/map.jl

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -210,9 +210,9 @@ See also: [`scalesigned`](@ref).
210210
"""
211211
colorsigned(neg::C, center::C, pos::C) where {C<:Colorant} = function(x)
212212
y = clamp(x, -oneunit(x), oneunit(x))
213-
yabs = abs(y)
214-
C(ifelse(y>0, weighted_color_mean(yabs, pos, center),
215-
weighted_color_mean(yabs, neg, center)))
213+
yabs = norm(y)
214+
C(ifelse(y>zero(y), weighted_color_mean(yabs, pos, center),
215+
weighted_color_mean(yabs, neg, center)))
216216
end
217217

218218
function colorsigned(colorneg::C, colorpos::C) where C<:Colorant

src/precompile.jl

Lines changed: 85 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -1,58 +1,109 @@
1+
macro warnpcfail(ex::Expr)
2+
modl = __module__
3+
file = __source__.file === nothing ? "?" : String(__source__.file)
4+
line = __source__.line
5+
quote
6+
$(esc(ex)) || @warn """precompile directive
7+
$($(Expr(:quote, ex)))
8+
failed. Please report an issue in $($modl) (after checking for duplicates) or remove this directive.""" _file=$file _line=$line
9+
end
10+
end
11+
12+
function pcarray(f::F, ::Type{A}, sz) where {F,A}
13+
a = f(A(undef, sz))
14+
fill!(a, zero(eltype(a)))
15+
return first(a)
16+
end
17+
function pcm(a1, a2; fillvalue = zero(eltype(a1)))
18+
v = mosaic(a1, a2; fillvalue=fillvalue)
19+
return first(v)
20+
end
21+
function pcmv(a; fillvalue = zero(eltype(a)))
22+
v = mosaicview(a; fillvalue=fillvalue)
23+
return first(v)
24+
end
25+
126
function _precompile_()
227
ccall(:jl_generating_output, Cint, ()) == 1 || return nothing
328
eltypes = (N0f8, N0f16, Float32, Float64) # eltypes of parametric colors
429
pctypes = (Gray, RGB, AGray, GrayA, ARGB, RGBA) # parametric colors
530
cctypes = (Gray24, AGray32, RGB24, ARGB32) # non-parametric colors
631
dims = (1, 2, 3, 4)
32+
szs = ((2,), (2, 2), (2, 2, 2), (2, 2, 2, 2))
733

834
for T in eltypes
9-
@assert precompile(clamp01, (T,))
10-
@assert precompile(clamp01nan, (T,))
11-
@assert precompile(scaleminmax, (T, T))
12-
@assert precompile(scalesigned, (T,))
13-
@assert precompile(scalesigned, (T,T,T))
35+
@warnpcfail precompile(clamp01, (T,))
36+
@warnpcfail precompile(clamp01nan, (T,))
37+
@warnpcfail precompile(scaleminmax, (T, T))
38+
@warnpcfail precompile(scalesigned, (T,))
39+
@warnpcfail precompile(scalesigned, (T,T,T))
1440
for C in pctypes
15-
@assert precompile(clamp01, (C{T},))
16-
@assert precompile(clamp01nan, (C{T},))
17-
@assert precompile(colorsigned, (C{T},C{T}))
41+
@warnpcfail precompile(clamp01, (C{T},))
42+
@warnpcfail precompile(clamp01nan, (C{T},))
43+
@warnpcfail precompile(colorsigned, (C{T},C{T}))
1844
end
1945
end
2046
for C in cctypes
21-
@assert precompile(clamp01, (C,))
22-
@assert precompile(clamp01nan, (C,))
23-
@assert precompile(colorsigned, (C,C))
24-
end
25-
for n in dims
47+
@warnpcfail precompile(clamp01, (C,))
48+
@warnpcfail precompile(clamp01nan, (C,))
49+
@warnpcfail precompile(colorsigned, (C,C))
50+
end
51+
# For the arrays, it's better to make them and exercise them so we get the getindex/setindex!
52+
# methods precompiled too.
53+
for sz in szs
2654
for T in eltypes
27-
@assert precompile(rawview, (Array{T,n},))
55+
T <: FixedPoint || continue
56+
pcarray(rawview, Array{T,length(sz)}, sz)
2857
end
29-
@assert precompile(normedview, (Array{UInt8,n},))
30-
@assert precompile(normedview, (Type{N0f8}, Array{UInt8,n}))
31-
@assert precompile(normedview, (Type{N0f16}, Array{UInt16,n}))
58+
pcarray(normedview, Array{UInt8,length(sz)}, sz)
59+
pcarray(a->normedview(N0f8, a), Array{UInt8, length(sz)}, sz)
60+
pcarray(a->normedview(N0f16, a), Array{UInt16,length(sz)}, sz)
3261
end
33-
for T in eltypes
34-
for n in dims
62+
for sz in szs
63+
for T in eltypes
3564
for C in pctypes
36-
@assert precompile(colorview, (Type{C}, Array{T,n}))
37-
@assert precompile(colorview, (Type{C{T}}, Array{T,n}))
38-
if T<:FixedPoint
39-
R = FixedPointNumbers.rawtype(T)
40-
RA = Base.ReinterpretArray{T,n,R,Array{R,n}}
41-
precompile(colorview, (Type{C}, RA))
42-
precompile(colorview, (Type{C{T}}, RA))
43-
precompile(reinterpretc, (Type{C{T}}, RA))
65+
nc = sizeof(C{T}) ÷ sizeof(T)
66+
if nc == 1
67+
pcarray(a->colorview(C, a), Array{T,length(sz)}, sz)
68+
pcarray(a->colorview(C{T}, a), Array{T,length(sz)}, sz)
69+
else
70+
pcarray(a->colorview(C, a), Array{T,length(sz)+1}, (nc, sz...))
71+
pcarray(a->colorview(C{T}, a), Array{T,length(sz)+1}, (nc, sz...))
4472
end
45-
@assert precompile(channelview, (Array{C{T},n},))
46-
end
47-
for C in cctypes
48-
@assert precompile(colorview, (Type{C}, Array{T,n}))
73+
pcarray(channelview, Array{C{T},length(sz)}, sz)
4974
if T<:FixedPoint
5075
R = FixedPointNumbers.rawtype(T)
51-
RA = Base.ReinterpretArray{T,n,R,Array{R,n}}
52-
precompile(colorview, (Type{C}, RA))
76+
if nc == 1
77+
pcarray(a->colorview(C, normedview(T, a)), Array{R,length(sz)}, sz)
78+
pcarray(a->colorview(C{T}, normedview(T, a)), Array{R,length(sz)}, sz)
79+
else
80+
pcarray(a->colorview(C, normedview(T, a)), Array{R,length(sz)+1}, (nc, sz...))
81+
pcarray(a->colorview(C{T}, normedview(T, a)), Array{R,length(sz)+1}, (nc, sz...))
82+
end
5383
end
54-
@assert precompile(channelview, (Array{C,n},))
84+
end
85+
end
86+
T, C = Bool, Gray
87+
pcarray(a->colorview(C, a), Array{T,length(sz)}, sz)
88+
pcarray(a->colorview(C{T}, a), Array{T,length(sz)}, sz)
89+
pcarray(channelview, Array{C{T},length(sz)}, sz)
90+
end
91+
for T in eltypes
92+
a = zeros(T, (2, 2))
93+
a3 = zeros(T, (2, 2, 2))
94+
pcm(a, a)
95+
pcmv(a3)
96+
for C in (Gray, RGB, GrayA, RGBA)
97+
a = zeros(C{T}, (2, 2))
98+
a3 = zeros(C{T}, (2, 2, 3))
99+
pcm(a, a)
100+
pcmv(a3)
101+
if C === RGB
102+
pcm(a, a; fillvalue=zero(Gray{T}))
103+
elseif C === RGBA
104+
pcm(a, a; fillvalue=zero(GrayA{T}))
55105
end
56106
end
57107
end
108+
pcm(zeros(Float32, 2, 2), zeros(Float64, 2, 2)) # heterogeneous
58109
end

src/stackedviews.jl

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -129,15 +129,15 @@ end
129129
# to use tuple tricks (i.e., make a tuple of length(inds)+1)
130130
_stackedview(T, (length(arrays), inds...), arrays_T)
131131
end
132-
_stackedview(::Type{T}, ::Tuple{Vararg{Any,N}}, arrays) where {T,N} = StackedView{T,N,typeof(arrays)}(arrays)
132+
@inline _stackedview(::Type{T}, ::Tuple{Vararg{Any,N}}, arrays) where {T,N} = StackedView{T,N,typeof(arrays)}(arrays)
133133

134134

135135
@inline firstinds(A::AbstractArray, Bs...) = axes(A)
136136
@inline firstinds(::ZeroArrayPromise, Bs...) = firstinds(Bs...)
137137
firstinds() = error("not all arrays can be zeroarray")
138138

139-
@inline take_zeros(T, inds, ::ZeroArrayPromise, Bs...) = (ZeroArrayPromise{T}(inds), take_zeros(T, inds, Bs...)...)
140-
@inline take_zeros(T, inds, A::AbstractArray, Bs...) = (A, take_zeros(T, inds, Bs...)...)
139+
@inline take_zeros(::Type{T}, inds, ::ZeroArrayPromise, Bs...) where T = (ZeroArrayPromise{T}(inds), take_zeros(T, inds, Bs...)...)
140+
@inline take_zeros(::Type{T}, inds, A::AbstractArray, Bs...) where T = (A, take_zeros(T, inds, Bs...)...)
141141
take_zeros(T, inds) = ()
142142

143143
# Extensions of PaddedViews

test/benchmarks.jl

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -83,13 +83,13 @@ cc_setindex_funcs = (myfill1!,
8383

8484
# Performance tolerances
8585
isfast = VERSION >= v"1.6.0-DEV.1083"
86-
chanvtol = Dict(mysum_index_inbounds_simd => isfast ? 3 : 20,
87-
mysum_elt_boundscheck => isfast ? 3 : 20,
88-
myfill1! => 20,
89-
myfill2! => isfast ? 3 : 20)
86+
chanvtol = Dict{Any,Int}(mysum_index_inbounds_simd => isfast ? 3 : 20,
87+
mysum_elt_boundscheck => isfast ? 3 : 20,
88+
myfill1! => 20,
89+
myfill2! => isfast ? 3 : 20)
9090
chanvdefault = isfast ? 3 : 10
91-
colvtol = Dict(mysum_elt_boundscheck=>isfast ? 3 : 5,
92-
mysum_index_boundscheck=>isfast ? 3 : 5)
91+
colvtol = Dict{Any,Int}(mysum_elt_boundscheck=>isfast ? 3 : 5,
92+
mysum_index_boundscheck=>isfast ? 3 : 5)
9393
colvdefault = 3
9494

9595
ssz = (1000,300)

0 commit comments

Comments
 (0)