Skip to content
New issue

Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? # to your account

upgrade to ColorVectorSpace 0.9 and reduce latency #157

Merged
merged 7 commits into from
Apr 21, 2021
Merged
Show file tree
Hide file tree
Changes from 6 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 4 additions & 3 deletions Project.toml
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ version = "0.8.22"

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

[compat]
AbstractFFTs = "0.4, 0.5, 1.0"
ColorVectorSpace = "0.8"
Colors = "0.9, 0.10, 0.11, 0.12"
FixedPointNumbers = "0.6.1, 0.7, 0.8"
ColorVectorSpace = "0.9"
Colors = "0.12"
FixedPointNumbers = "0.8"
Graphics = "0.4, 1.0"
MappedArrays = "0.2, 0.3, 0.4"
MosaicViews = "0.3.3"
Expand Down
12 changes: 1 addition & 11 deletions src/ImageCore.jl
Original file line number Diff line number Diff line change
@@ -1,19 +1,9 @@
VERSION < v"0.7.0-beta2.199" && __precompile__()

module ImageCore

using Reexport
@reexport using FixedPointNumbers
@reexport using Colors
if isdefined(ColorTypes, :XRGB) && isdefined(ColorTypes, :RGB1)
Base.@deprecate_binding RGB1 XRGB
Base.@deprecate_binding RGB4 RGBX
end
# backward compatibility for ColorTypes < v0.9
if !isdefined(ColorTypes, :XRGB)
const XRGB = RGB1
const RGBX = RGB4
end
using ColorVectorSpace
johnnychen94 marked this conversation as resolved.
Show resolved Hide resolved

@reexport using MosaicViews
@reexport using PaddedViews
Expand Down
2 changes: 1 addition & 1 deletion src/colorchannels.jl
Original file line number Diff line number Diff line change
Expand Up @@ -217,7 +217,7 @@ colorview(::Type{C}) where C<:Colorant = (As...) -> colorview(C, As...)
_colorview_type(::Type{Any}, ::Type{T}) where {T} = T
_colorview_type(::Type{T1}, ::Type{T2}) where {T1,T2} = T1

Base.@pure promote_eleltype_all(gray, grays...) = _promote_eleltype_all(beltype(eltype(gray)), grays...)
Base.@pure @inline promote_eleltype_all(gray, grays...) = _promote_eleltype_all(beltype(eltype(gray)), grays...)
@inline function _promote_eleltype_all(::Type{T}, gray, grays...) where T
_promote_eleltype_all(promote_type(T, beltype(eltype(gray))), grays...)
end
Expand Down
1 change: 0 additions & 1 deletion src/convert_reinterpret.jl
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,6 @@ for (fn,T) in (#(:float16, Float16), # Float16 currently has promotion problem
($fn)(::Type{S}) where {S<:Number } = $T
($fn)(c::Colorant) = convert(($fn)(typeof(c)), c)
($fn)(n::Number) = convert(($fn)(typeof(n)), n)
@deprecate ($fn)(A::AbstractArray{C}) where {C<:Colorant} ($fn).(A)
fname = $(Expr(:quote, fn))
Tname = shortname($T)
@doc """
Expand Down
68 changes: 0 additions & 68 deletions src/deprecations.jl
Original file line number Diff line number Diff line change
Expand Up @@ -16,73 +16,5 @@ else
forced_depwarn(msg, sym) = Base.depwarn(msg, sym)
end

Base.@deprecate_binding ChannelView channelview

export ColorView

struct ColorView{C<:Colorant,N,A<:AbstractArray} <: AbstractArray{C,N}
parent::A

function ColorView{C,N,A}(parent::AbstractArray{T}) where {C,N,A,T<:Number}
n = length(colorview_size(C, parent))
n == N || throw(DimensionMismatch("for an $N-dimensional ColorView with color type $C, input dimensionality should be $n instead of $(ndims(parent))"))
checkdim1(C, axes(parent))
forced_depwarn("ColorView{C}(A) is deprecated, use colorview(C, A)", :ColorView)
colorview(C, A)
end
end

function ColorView{C}(A::AbstractArray) where C<:Colorant
forced_depwarn("ColorView{C}(A) is deprecated, use colorview(C, A)", :ColorView)
colorview(C, A)
end

ColorView(parent::AbstractArray) = error("must specify the colortype, use colorview(C, A)")

Base.@deprecate_binding squeeze1 true

import Base: convert

function cname(::Type{C}) where C
io = IOBuffer()
ColorTypes.colorant_string_with_eltype(io, C)
return String(take!(io))
end

const _explain =
"""will soon switch to returning an array with non-concrete element type, which adds flexibility but
with great cost to performance. To maintain the current behavior, use"""

function convert(::Type{Array{Cdest}}, img::AbstractArray{Csrc,n}) where {Cdest<:Colorant,n,Csrc<:Colorant}
if isconcretetype(Cdest)
# This mimics the Base implementation
return img isa Array{Cdest} ? img : Array{Cdest}(img)
end
forced_depwarn("`convert(Array{$(cname(Cdest))}, img)` $_explain `$(cname(Cdest)).(img)` instead.", :convert)
convert(Array, Cdest.(img))
end

function convert(::Type{Array{Cdest}}, img::AbstractArray{T,n}) where {Cdest<:Color1,n,T<:Real}
if isconcretetype(Cdest)
return img isa Array{Cdest} ? img : Array{Cdest}(img)
end
forced_depwarn("`convert(Array{$(cname(Cdest))}, img)` $_explain `$(cname(Cdest)).(img)` instead.", :convert)
convert(Array, Cdest.(img))
end

function convert(::Type{OffsetArray{Cdest,n,A}}, img::AbstractArray{Csrc,n}) where {Cdest<:Colorant,n, A <:AbstractArray,Csrc<:Colorant}
if isconcretetype(Cdest) && isconcretetype(A) && eltype(A) === Cdest
return img isa OffsetArray{Cdest,n,A} ? img : (img isa OffsetArray ? OffsetArray(A(Cdest.(parent(img))), axes(img)) : OffsetArray(A(Cdest.(img)), axes(img)))
end
if img isa OffsetArray
forced_depwarn("`convert(OffsetArray{$(cname(Cdest))}, img)` $_explain `$(cname(Cdest)).(img)` instead.", :convert)
else
forced_depwarn("`convert(OffsetArray{$(cname(Cdest))}, img)` $_explain `OffsetArray($(cname(Cdest)).(img), axes(img))` instead.", :convert)
end
OffsetArray(Cdest.(img), axes(img))
end

convert(::Type{OffsetArray{Cdest,n,A}}, img::OffsetArray{Cdest,n,A}) where {Cdest<:Colorant,n, A <:AbstractArray} = img

# a perhaps "permanent" deprecation
Base.@deprecate_binding permuteddimsview PermutedDimsArray
6 changes: 3 additions & 3 deletions src/map.jl
Original file line number Diff line number Diff line change
Expand Up @@ -210,9 +210,9 @@ See also: [`scalesigned`](@ref).
"""
colorsigned(neg::C, center::C, pos::C) where {C<:Colorant} = function(x)
y = clamp(x, -oneunit(x), oneunit(x))
yabs = abs(y)
C(ifelse(y>0, weighted_color_mean(yabs, pos, center),
weighted_color_mean(yabs, neg, center)))
yabs = norm(y)
C(ifelse(y>zero(y), weighted_color_mean(yabs, pos, center),
weighted_color_mean(yabs, neg, center)))
end

function colorsigned(colorneg::C, colorpos::C) where C<:Colorant
Expand Down
119 changes: 85 additions & 34 deletions src/precompile.jl
Original file line number Diff line number Diff line change
@@ -1,58 +1,109 @@
macro warnpcfail(ex::Expr)
modl = __module__
file = __source__.file === nothing ? "?" : String(__source__.file)
line = __source__.line
quote
$(esc(ex)) || @warn """precompile directive
$($(Expr(:quote, ex)))
failed. Please report an issue in $($modl) (after checking for duplicates) or remove this directive.""" _file=$file _line=$line
end
end

function pcarray(f::F, ::Type{A}, sz) where {F,A}
a = f(A(undef, sz))
fill!(a, zero(eltype(a)))
return first(a)
end
function pcm(a1, a2; fillvalue = zero(eltype(a1)))
v = mosaic(a1, a2; fillvalue=fillvalue)
return first(v)
end
function pcmv(a; fillvalue = zero(eltype(a)))
v = mosaicview(a; fillvalue=fillvalue)
return first(v)
end

function _precompile_()
ccall(:jl_generating_output, Cint, ()) == 1 || return nothing
eltypes = (N0f8, N0f16, Float32, Float64) # eltypes of parametric colors
pctypes = (Gray, RGB, AGray, GrayA, ARGB, RGBA) # parametric colors
cctypes = (Gray24, AGray32, RGB24, ARGB32) # non-parametric colors
dims = (1, 2, 3, 4)
szs = ((2,), (2, 2), (2, 2, 2), (2, 2, 2, 2))

for T in eltypes
@assert precompile(clamp01, (T,))
@assert precompile(clamp01nan, (T,))
@assert precompile(scaleminmax, (T, T))
@assert precompile(scalesigned, (T,))
@assert precompile(scalesigned, (T,T,T))
@warnpcfail precompile(clamp01, (T,))
@warnpcfail precompile(clamp01nan, (T,))
@warnpcfail precompile(scaleminmax, (T, T))
@warnpcfail precompile(scalesigned, (T,))
@warnpcfail precompile(scalesigned, (T,T,T))
for C in pctypes
@assert precompile(clamp01, (C{T},))
@assert precompile(clamp01nan, (C{T},))
@assert precompile(colorsigned, (C{T},C{T}))
@warnpcfail precompile(clamp01, (C{T},))
@warnpcfail precompile(clamp01nan, (C{T},))
@warnpcfail precompile(colorsigned, (C{T},C{T}))
end
end
for C in cctypes
@assert precompile(clamp01, (C,))
@assert precompile(clamp01nan, (C,))
@assert precompile(colorsigned, (C,C))
end
for n in dims
@warnpcfail precompile(clamp01, (C,))
@warnpcfail precompile(clamp01nan, (C,))
@warnpcfail precompile(colorsigned, (C,C))
end
# For the arrays, it's better to make them and exercise them so we get the getindex/setindex!
# methods precompiled too.
for sz in szs
for T in eltypes
@assert precompile(rawview, (Array{T,n},))
T <: FixedPoint || continue
pcarray(rawview, Array{T,length(sz)}, sz)
end
@assert precompile(normedview, (Array{UInt8,n},))
@assert precompile(normedview, (Type{N0f8}, Array{UInt8,n}))
@assert precompile(normedview, (Type{N0f16}, Array{UInt16,n}))
pcarray(normedview, Array{UInt8,length(sz)}, sz)
pcarray(a->normedview(N0f8, a), Array{UInt8, length(sz)}, sz)
pcarray(a->normedview(N0f16, a), Array{UInt16,length(sz)}, sz)
end
for T in eltypes
for n in dims
for sz in szs
for T in eltypes
for C in pctypes
@assert precompile(colorview, (Type{C}, Array{T,n}))
@assert precompile(colorview, (Type{C{T}}, Array{T,n}))
if T<:FixedPoint
R = FixedPointNumbers.rawtype(T)
RA = Base.ReinterpretArray{T,n,R,Array{R,n}}
precompile(colorview, (Type{C}, RA))
precompile(colorview, (Type{C{T}}, RA))
precompile(reinterpretc, (Type{C{T}}, RA))
nc = sizeof(C{T}) ÷ sizeof(T)
if nc == 1
pcarray(a->colorview(C, a), Array{T,length(sz)}, sz)
pcarray(a->colorview(C{T}, a), Array{T,length(sz)}, sz)
else
pcarray(a->colorview(C, a), Array{T,length(sz)+1}, (nc, sz...))
pcarray(a->colorview(C{T}, a), Array{T,length(sz)+1}, (nc, sz...))
end
@assert precompile(channelview, (Array{C{T},n},))
end
for C in cctypes
@assert precompile(colorview, (Type{C}, Array{T,n}))
pcarray(channelview, Array{C{T},length(sz)}, sz)
if T<:FixedPoint
R = FixedPointNumbers.rawtype(T)
RA = Base.ReinterpretArray{T,n,R,Array{R,n}}
precompile(colorview, (Type{C}, RA))
if nc == 1
pcarray(a->colorview(C, normedview(T, a)), Array{R,length(sz)}, sz)
pcarray(a->colorview(C{T}, normedview(T, a)), Array{R,length(sz)}, sz)
else
pcarray(a->colorview(C, normedview(T, a)), Array{R,length(sz)+1}, (nc, sz...))
pcarray(a->colorview(C{T}, normedview(T, a)), Array{R,length(sz)+1}, (nc, sz...))
end
end
@assert precompile(channelview, (Array{C,n},))
end
end
T, C = Bool, Gray
pcarray(a->colorview(C, a), Array{T,length(sz)}, sz)
pcarray(a->colorview(C{T}, a), Array{T,length(sz)}, sz)
pcarray(channelview, Array{C{T},length(sz)}, sz)
end
for T in eltypes
a = zeros(T, (2, 2))
a3 = zeros(T, (2, 2, 2))
pcm(a, a)
pcmv(a3)
for C in (Gray, RGB, GrayA, RGBA)
a = zeros(C{T}, (2, 2))
a3 = zeros(C{T}, (2, 2, 3))
pcm(a, a)
pcmv(a3)
if C === RGB
pcm(a, a; fillvalue=zero(Gray{T}))
elseif C === RGBA
pcm(a, a; fillvalue=zero(GrayA{T}))
end
end
end
pcm(zeros(Float32, 2, 2), zeros(Float64, 2, 2)) # heterogeneous
end
6 changes: 3 additions & 3 deletions src/stackedviews.jl
Original file line number Diff line number Diff line change
Expand Up @@ -129,15 +129,15 @@ end
# to use tuple tricks (i.e., make a tuple of length(inds)+1)
_stackedview(T, (length(arrays), inds...), arrays_T)
end
_stackedview(::Type{T}, ::Tuple{Vararg{Any,N}}, arrays) where {T,N} = StackedView{T,N,typeof(arrays)}(arrays)
@inline _stackedview(::Type{T}, ::Tuple{Vararg{Any,N}}, arrays) where {T,N} = StackedView{T,N,typeof(arrays)}(arrays)


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

@inline take_zeros(T, inds, ::ZeroArrayPromise, Bs...) = (ZeroArrayPromise{T}(inds), take_zeros(T, inds, Bs...)...)
@inline take_zeros(T, inds, A::AbstractArray, Bs...) = (A, take_zeros(T, inds, Bs...)...)
@inline take_zeros(::Type{T}, inds, ::ZeroArrayPromise, Bs...) where T = (ZeroArrayPromise{T}(inds), take_zeros(T, inds, Bs...)...)
@inline take_zeros(::Type{T}, inds, A::AbstractArray, Bs...) where T = (A, take_zeros(T, inds, Bs...)...)
take_zeros(T, inds) = ()

# Extensions of PaddedViews
Expand Down
12 changes: 6 additions & 6 deletions test/benchmarks.jl
Original file line number Diff line number Diff line change
Expand Up @@ -83,13 +83,13 @@ cc_setindex_funcs = (myfill1!,

# Performance tolerances
isfast = VERSION >= v"1.6.0-DEV.1083"
chanvtol = Dict(mysum_index_inbounds_simd => isfast ? 3 : 20,
mysum_elt_boundscheck => isfast ? 3 : 20,
myfill1! => 20,
myfill2! => isfast ? 3 : 20)
chanvtol = Dict{Any,Int}(mysum_index_inbounds_simd => isfast ? 3 : 20,
mysum_elt_boundscheck => isfast ? 3 : 20,
myfill1! => 20,
myfill2! => isfast ? 3 : 20)
chanvdefault = isfast ? 3 : 10
colvtol = Dict(mysum_elt_boundscheck=>isfast ? 3 : 5,
mysum_index_boundscheck=>isfast ? 3 : 5)
colvtol = Dict{Any,Int}(mysum_elt_boundscheck=>isfast ? 3 : 5,
mysum_index_boundscheck=>isfast ? 3 : 5)
colvdefault = 3

ssz = (1000,300)
Expand Down
Loading