Skip to content

Commit 02593d9

Browse files
authored
Merge pull request #145 from JuliaImages/teh/reinterpretarray
Use Julia 1.6's new reinterpretarray machinery
2 parents d9dccd9 + 9ab9089 commit 02593d9

File tree

7 files changed

+159
-95
lines changed

7 files changed

+159
-95
lines changed

src/ImageCore.jl

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,11 @@ ColorA{N,C,T} = ColorAlpha{C,T,N}
4343
const NonparametricColors = Union{RGB24,ARGB32,Gray24,AGray32}
4444
Color1Array{C<:Color1,N} = AbstractArray{C,N}
4545
# Type that arises from reshape(reinterpret(To, A), sz):
46-
const RRArray{To,From,N,M,P} = Base.ReshapedArray{To,N,Base.ReinterpretArray{To,M,From,P}}
46+
if VERSION >= v"1.6.0-DEV.1083"
47+
const RRArray{To,From,M,P} = Base.ReinterpretArray{To,M,From,P,true}
48+
else
49+
const RRArray{To,From,N,M,P} = Base.ReshapedArray{To,N,Base.ReinterpretArray{To,M,From,P}}
50+
end
4751
const RGArray = Union{Base.ReinterpretArray{<:AbstractGray,M,<:Number,P}, Base.ReinterpretArray{<:Number,M,<:AbstractGray,P}} where {M,P}
4852

4953
# delibrately not export these constants to enable extensibility for downstream packages

src/colorchannels.jl

Lines changed: 32 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -28,8 +28,13 @@ dimorder(::Type{<:AlphaColor{<:Color3,T,N}}) where {T,N} = ColorChanPerm((4, 1,
2828
const ColorChanPermIndexType{NC} = Tuple{<:ColorChanPerm,Vararg{<:Base.Slice,NC}}
2929
const ColorChanPermSubArray{T,N,P,I<:ColorChanPermIndexType,L} =
3030
SubArray{T,N,P,I,L}
31-
const RRPermArray{To,From,N,M,P<:ColorChanPermSubArray} =
32-
RRArray{To,From,N,M,P}
31+
if VERSION >= v"1.6.0-DEV.1083"
32+
const RRPermArray{To,From,M,P<:ColorChanPermSubArray} =
33+
RRArray{To,From,M,P}
34+
else
35+
const RRPermArray{To,From,N,M,P<:ColorChanPermSubArray} =
36+
RRArray{To,From,N,M,P}
37+
end
3338

3439
# This type exists solely to set multiple values in the color channel axis
3540
struct NVector{T,N} <: AbstractVector{T}
@@ -62,8 +67,13 @@ A = channelview(img) # a 3×10×10 array
6267
See also: [`colorview`](@ref)
6368
"""
6469
channelview(A::AbstractArray{T}) where {T<:Number} = A
65-
channelview(A::RRPermArray{<:Colorant,<:Number}) = parent(parent(parent(A)))
66-
channelview(A::RRArray{<:Colorant,<:Number}) = parent(parent(A))
70+
if VERSION >= v"1.6.0-DEV.1083"
71+
channelview(A::RRArray{<:Colorant,<:Number}) = parent(A)
72+
channelview(A::RRPermArray{<:Colorant,<:Number}) = parent(parent(A))
73+
else
74+
channelview(A::RRArray{<:Colorant,<:Number}) = parent(parent(A))
75+
channelview(A::RRPermArray{<:Colorant,<:Number}) = parent(parent(parent(A)))
76+
end
6777
channelview(A::Base.ReinterpretArray{<:AbstractGray,M,<:Number}) where M = parent(A)
6878
channelview(A::AbstractArray{RGB{T}}) where {T} = reinterpretc(T, A)
6979
function channelview(A::AbstractArray{C}) where {C<:AbstractRGB}
@@ -108,14 +118,25 @@ _ccolorview(::Type{C}, A::RRPermArray{T,C}) where {C<:Colorant,T<:Number} =
108118
parent(parent(parent(A)))
109119
_ccolorview(::Type{C}, A::RRArray{T,C}) where {C<:Colorant,T<:Number} =
110120
parent(parent(A))
111-
_ccolorview(::Type{C}, A::Base.ReinterpretArray{T,M,C}) where {C<:AbstractGray,T<:Number,M} =
112-
parent(A)
113-
_ccolorview(::Type{C}, A::Base.ReinterpretArray{T,M,C}) where {C<:RGB,T<:Number,M} =
114-
reshape(parent(A), Base.tail(axes(parent(A))))
121+
if VERSION >= v"1.6.0-DEV.1083"
122+
_ccolorview(::Type{C}, A::Base.ReinterpretArray{T,M,C,AA,false}) where {C<:RGB,T<:Number,M,AA} =
123+
reshape(parent(A), Base.tail(axes(parent(A))))
124+
_ccolorview(::Type{C}, A::Base.ReinterpretArray{T,M,C,AA,true}) where {C<:RGB,T<:Number,M,AA} =
125+
parent(A)
126+
_ccolorview(::Type{C}, A::Base.ReinterpretArray{T,M,C,AA,false}) where {C<:Color,T<:Number,M,AA} =
127+
reshape(parent(A), Base.tail(axes(parent(A))))
128+
_ccolorview(::Type{C}, A::Base.ReinterpretArray{T,M,C,AA,true}) where {C<:Color,T<:Number,M,AA} =
129+
parent(A)
130+
else
131+
_ccolorview(::Type{C}, A::Base.ReinterpretArray{T,M,C}) where {C<:AbstractGray,T<:Number,M} =
132+
parent(A)
133+
_ccolorview(::Type{C}, A::Base.ReinterpretArray{T,M,C}) where {C<:RGB,T<:Number,M} =
134+
reshape(parent(A), Base.tail(axes(parent(A))))
135+
_ccolorview(::Type{C}, A::Base.ReinterpretArray{T,M,C}) where {C<:Color,T<:Number,M} =
136+
reshape(parent(A), Base.tail(axes(parent(A))))
137+
end
115138
_ccolorview(::Type{C}, A::Base.ReinterpretArray{T,M,C}) where {C<:AbstractRGB,T<:Number,M} =
116139
_colorview_reorder(C, A)
117-
_ccolorview(::Type{C}, A::Base.ReinterpretArray{T,M,C}) where {C<:Color,T<:Number,M} =
118-
reshape(parent(A), Base.tail(axes(parent(A))))
119140
_ccolorview(::Type{C}, A::AbstractArray{T}) where {C<:Colorant,T<:Number} =
120141
__ccolorview(C, A) # necessary to avoid ambiguities from dispatch on eltype
121142
__ccolorview(::Type{C}, A::AbstractArray{T}) where {T<:Number,C<:RGB{T}} = reinterpretc(C, A)
@@ -178,7 +199,7 @@ Create a function that is equivalent to `(As...) -> colorview(C, Ax...)`.
178199
179200
```jldoctest; setup = :(using ImageCore)
180201
julia> ones(Float32, 2, 2) |> colorview(Gray)
181-
2×2 reinterpret(Gray{Float32}, ::$(Array{Float32,2})):
202+
2×2 reinterpret($(VERSION >= v"1.6.0-DEV.1083" ? "reshape, " : "")Gray{Float32}, ::$(Array{Float32,2}))$(VERSION >= v"1.6.0-DEV.1083" ? " with eltype Gray{Float32}" : ""):
182203
Gray{Float32}(1.0) Gray{Float32}(1.0)
183204
Gray{Float32}(1.0) Gray{Float32}(1.0)
184205
```

src/convert_reinterpret.jl

Lines changed: 51 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -2,61 +2,67 @@
22

33
@pure samesize(::Type{T}, ::Type{S}) where {T,S} = sizeof(T) == sizeof(S)
44

5-
## Color->Color
6-
# function reinterpretc(::Type{CV1}, a::Array{CV2,1}) where {CV1<:Colorant,CV2<:Colorant}
7-
# CV = ccolor(CV1, CV2)
8-
# l = (length(a)*sizeof(CV2))÷sizeof(CV1)
9-
# l*sizeof(CV1) == length(a)*sizeof(CV2) || throw(ArgumentError("sizes are incommensurate"))
10-
# reshape(reinterpret(CV, a), (l,))
11-
# end
12-
function reinterpretc(::Type{CV1}, a::AbstractArray{CV2}) where {CV1<:Colorant,CV2<:Colorant}
13-
CV = ccolor(CV1, CV2)
14-
if samesize(CV, CV2)
15-
return reshape(reinterpret(CV, a), size(a))
5+
if VERSION >= v"1.6.0-DEV.1083"
6+
reinterpretc(::Type{T}, a::AbstractArray) where T = reinterpret(reshape, ccolor_number(T, eltype(a)), a)
7+
reinterpretc(::Type{T}, a::Base.ReinterpretArray{S,N,T,AA,true}) where {T,S,N,AA<:AbstractArray{T}} = parent(a)
8+
else
9+
# Color->Color
10+
function reinterpretc(::Type{CV1}, a::Array{CV2,1}) where {CV1<:Colorant,CV2<:Colorant}
11+
CV = ccolor(CV1, CV2)
12+
l = (length(a)*sizeof(CV2))÷sizeof(CV1)
13+
l*sizeof(CV1) == length(a)*sizeof(CV2) || throw(ArgumentError("sizes are incommensurate"))
14+
reshape(reinterpret(CV, a), (l,))
1615
end
17-
throw(ArgumentError("result shape not specified"))
18-
end
19-
20-
## Color->T
21-
function reinterpretc(::Type{T}, a::AbstractArray{CV}) where {T<:Number,CV<:Colorant}
22-
if samesize(T, CV)
23-
return reinterpret(T, a)
16+
function reinterpretc(::Type{CV1}, a::AbstractArray{CV2}) where {CV1<:Colorant,CV2<:Colorant}
17+
CV = ccolor(CV1, CV2)
18+
if samesize(CV, CV2)
19+
return reshape(reinterpret(CV, a), size(a))
20+
end
21+
throw(ArgumentError("result shape not specified"))
2422
end
25-
axs = axes(a)
26-
if sizeof(CV) == sizeof(T)*_len(CV)
27-
return reinterpret(T, reshape(a, Base.OneTo(1), axs...))
23+
24+
# Color->T
25+
function reinterpretc(::Type{T}, a::AbstractArray{CV}) where {T<:Number,CV<:Colorant}
26+
if samesize(T, CV)
27+
return reinterpret(T, a)
28+
end
29+
axs = axes(a)
30+
if sizeof(CV) == sizeof(T)*_len(CV)
31+
return reinterpret(T, reshape(a, Base.OneTo(1), axs...))
32+
end
33+
throw(ArgumentError("result shape not specified"))
2834
end
29-
throw(ArgumentError("result shape not specified"))
30-
end
31-
reinterpretc(::Type{T}, a::AbstractArray{CV,0}) where {T<:Number,CV<:Colorant} =
32-
reinterpret(T, reshape(a, 1))
35+
reinterpretc(::Type{T}, a::AbstractArray{CV,0}) where {T<:Number,CV<:Colorant} =
36+
reinterpret(T, reshape(a, 1))
3337

34-
_len(::Type{C}) where {C} = _len(C, eltype(C))
35-
_len(::Type{C}, ::Type{Any}) where {C} = error("indeterminate type")
36-
_len(::Type{C}, ::Type{T}) where {C,T} = sizeof(C) ÷ sizeof(T)
38+
_len(::Type{C}) where {C} = _len(C, eltype(C))
39+
_len(::Type{C}, ::Type{Any}) where {C} = error("indeterminate type")
40+
_len(::Type{C}, ::Type{T}) where {C,T} = sizeof(C) ÷ sizeof(T)
3741

38-
## T->Color
39-
# We have to distinguish two forms of call:
40-
# form 1: reinterpretc(RGB{N0f8}, img)
41-
# form 2: reinterpretc(RGB, img)
42-
function reinterpretc(CV::Type{<:Colorant}, a::AbstractArray{T}) where T<:Number # {CV<:Colorant,T<:Number}
43-
@noinline throwdm(C::Type, ind1) =
44-
throw(DimensionMismatch("indices $ind1 are not consistent with color type $C"))
45-
CVT = ccolor_number(CV, T)
46-
if samesize(CVT, T)
47-
return reinterpret(CVT, a)
48-
end
49-
axs = axes(a)
50-
if axs[1] == Base.OneTo(sizeof(CVT) ÷ sizeof(eltype(CVT)))
51-
return reshape(reinterpret(CVT, a), tail(axs))
42+
## T->Color
43+
# We have to distinguish two forms of call:
44+
# form 1: reinterpretc(RGB{N0f8}, img)
45+
# form 2: reinterpretc(RGB, img)
46+
function reinterpretc(CV::Type{<:Colorant}, a::AbstractArray{T}) where T<:Number # {CV<:Colorant,T<:Number}
47+
@noinline throwdm(C::Type, ind1) =
48+
throw(DimensionMismatch("indices $ind1 are not consistent with color type $C"))
49+
CVT = ccolor_number(CV, T)
50+
if samesize(CVT, T)
51+
return reinterpret(CVT, a)
52+
end
53+
axs = axes(a)
54+
if axs[1] == Base.OneTo(sizeof(CVT) ÷ sizeof(eltype(CVT)))
55+
return reshape(reinterpret(CVT, a), tail(axs))
56+
end
57+
throwdm(CV, axs[1])
5258
end
53-
throwdm(CV, axs[1])
5459
end
5560

5661
# ccolor_number converts form 2 calls to form 1 calls
57-
ccolor_number(::Type{CV}, ::Type{T}) where {CV<:Colorant,T<:Number} =
62+
ccolor_number(::Type{T}, ::Any) where T<:Number = T
63+
ccolor_number(::Type{CV}, ::Type{T}) where {CV<:Colorant,T} =
5864
ccolor_number(CV, eltype(CV), T)
59-
ccolor_number(::Type{CV}, ::Type{CVT}, ::Type{T}) where {CV,CVT<:Number,T} = CV # form 1
65+
ccolor_number(::Type{CV}, ::Type{CVT}, ::Type{T}) where {CV,CVT<:Number,T} = CV # form 1
6066
ccolor_number(::Type{CV}, ::Type{Any}, ::Type{T}) where {CV<:Colorant,T} = CV{T} # form 2
6167

6268
# for docstrings in the operations below

test/benchmarks.jl

Lines changed: 56 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -54,13 +54,15 @@ end
5454
function test_getindex(f, ar, cv, n)
5555
t_ar = Array{Float64}(undef, n)
5656
t_cv = Array{Float64}(undef, n)
57+
# Store the results to prevent the compiler from eliding the call
5758
f_ar = Ref(f(ar))
5859
f_cv = Ref(f(cv))
60+
@test f_ar[] f_cv[] # but this also gives us a chance to test correctness
5961
for i = 1:n
6062
t_ar[i] = (tstart = time(); f_ar[] = f(ar); time()-tstart)
6163
t_cv[i] = (tstart = time(); f_cv[] = f(cv); time()-tstart)
6264
end
63-
median(t_ar), median(t_cv), f_ar
65+
median(t_ar), median(t_cv)
6466
end
6567
function test_setindex(f, ar, cv, n)
6668
t_ar = Array{Float64}(undef, n)
@@ -72,45 +74,70 @@ function test_setindex(f, ar, cv, n)
7274
median(t_ar), median(t_cv)
7375
end
7476

75-
ssz = (1000,1000)
76-
c = rand(RGB{Float64}, ssz...)
77-
a = copy(reinterpretc(Float64, c))
78-
vchan = channelview(c)
79-
vcol = colorview(RGB, a)
8077
cc_getindex_funcs = (mysum_elt_boundscheck,
8178
mysum_index_boundscheck,
8279
mysum_elt_inbounds,
8380
mysum_index_inbounds_simd)
8481
cc_setindex_funcs = (myfill1!,
8582
myfill2!)
86-
chanvtol = Dict(mysum_index_inbounds_simd => 20, # @simd doesn't work for ChannelView :(
87-
mysum_elt_boundscheck => 20,
88-
myfill1! => 20, # crappy setindex! performance
89-
myfill2! => 20)
90-
chanvdefault = 10
91-
colvtol = Dict(mysum_elt_boundscheck=>5,
92-
mysum_index_boundscheck=>5)
83+
84+
# Performance tolerances
85+
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)
90+
chanvdefault = isfast ? 3 : 10
91+
colvtol = Dict(mysum_elt_boundscheck=>isfast ? 3 : 5,
92+
mysum_index_boundscheck=>isfast ? 3 : 5)
9393
colvdefault = 3
9494

95+
ssz = (1000,300)
96+
9597
@info "Benchmark tests are warnings for now"
9698
# @testset "benchmarks" begin
97-
for (suite, testf) in ((cc_getindex_funcs, test_getindex),
98-
(cc_setindex_funcs, test_setindex))
99-
for f in suite
100-
# Channelview
101-
t_ar, t_cv = testf(f, a, vchan, 10^2)
102-
tol = haskey(chanvtol, f) ? chanvtol[f] : chanvdefault
103-
if t_cv >= tol*t_ar
104-
@warn "ChannelView: failed on $f, time ratio $(t_cv/t_ar), tol $tol"
105-
end
106-
# @test t_cv < tol*t_ar
107-
# ColorView
108-
t_ar, t_cv = testf(f, c, vcol, 10^2)
109-
tol = haskey(colvtol, f) ? colvtol[f] : colvdefault
110-
if t_cv >= tol*t_ar
111-
@warn "ColorView: failed on $f, time ratio $(t_cv/t_ar), tol $tol"
99+
for T in (Float32, Float64)
100+
c = rand(RGB{T}, ssz...)
101+
a = copy(reinterpretc(T, c))
102+
vchan = channelview(c)
103+
vcol = colorview(RGB, a)
104+
105+
# view versions
106+
rview = 2:ssz[1]-1
107+
csub = view(c, rview, :)
108+
asub = view(a, :, rview, :)
109+
vchansub = channelview(csub)
110+
vcolsub = colorview(RGB, asub)
111+
112+
for (suite, testf) in ((cc_getindex_funcs, test_getindex),
113+
(cc_setindex_funcs, test_setindex))
114+
for f in suite
115+
# channelview
116+
t_ar, t_cv = testf(f, a, vchan, 30)
117+
tol = haskey(chanvtol, f) ? chanvtol[f] : chanvdefault
118+
if t_cv >= tol*t_ar
119+
@warn "channelview1: failed on $f with eltype $T, time ratio $(t_cv/t_ar), tol $tol"
120+
end
121+
122+
t_ar, t_cv = testf(f, asub, vchansub, 30)
123+
tol = haskey(chanvtol, f) ? chanvtol[f] : chanvdefault
124+
if t_cv >= tol*t_ar
125+
@warn "channelview2: failed on $f with eltype $T, time ratio $(t_cv/t_ar), tol $tol"
126+
end
127+
128+
# colorview
129+
t_ar, t_cv = testf(f, c, vcol, 30)
130+
tol = haskey(colvtol, f) ? colvtol[f] : colvdefault
131+
if t_cv >= tol*t_ar
132+
@warn "colorview1: failed on $f with eltype $T, time ratio $(t_cv/t_ar), tol $tol"
133+
end
134+
135+
t_ar, t_cv = testf(f, csub, vcolsub, 30)
136+
tol = haskey(colvtol, f) ? colvtol[f] : colvdefault
137+
if t_cv >= tol*t_ar
138+
@warn "colorview2: failed on $f with eltype $T, time ratio $(t_cv/t_ar), tol $tol"
139+
end
112140
end
113-
# @test t_cv < tol*t_ar
114141
end
115142
end
116143
# end

test/colorchannels.jl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -407,7 +407,7 @@ end
407407
@test @inferred(axes(v)) == (IdentityUnitRange(-1:1), IdentityUnitRange(-2:2))
408408
@test @inferred(v[0,0]) === RGB(a[1,0,0], a[2,0,0], a[3,0,0])
409409
a = OffsetArray(rand(3, 3, 5), 0:2, -1:1, -2:2)
410-
@test_throws DimensionMismatch colorview(RGB, a)
410+
@test_throws (VERSION >= v"1.6.0-DEV.1083" ? ArgumentError : DimensionMismatch) colorview(RGB, a)
411411
end
412412
end
413413

test/convert_reinterpret.jl

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -129,9 +129,9 @@ using Test, Random
129129

130130
# indeterminate type tests
131131
a = Array{RGB{AbstractFloat}}(undef, 3)
132-
@test_throws ErrorException reinterpretc(Float64, a)
132+
@test_throws Union{ArgumentError,ErrorException} reinterpretc(Float64, a)
133133
a = Vector{RGB}(undef, 3)
134-
@test_throws ErrorException reinterpretc(Float64, a)
134+
@test_throws Union{ArgumentError,ErrorException} reinterpretc(Float64, a)
135135

136136
# Invalid conversions
137137
a = rand(UInt8, 4,5)

test/show.jl

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,9 @@ else
66
sumsz(img) = ""
77
end
88

9+
const rrstr = VERSION >= v"1.6.0-DEV.1083" ? "reshape, " : ""
10+
rrdim(n) = VERSION >= v"1.6.0-DEV.1083" ? n-1 : n
11+
912
# N0f8 is shown as either N0f8 or Normed{UInt8, 8}
1013
# RGB is shown as ColorTypes.RGB or RGB
1114
function typestring(::Type{T}) where T
@@ -22,13 +25,15 @@ RGB_str = typestring(RGB)
2225
v = view(rgb32, 2:3, :)
2326
@test summary(v) == "2×5 view(::Array{RGB{Float32},2}, 2:3, :) with eltype $(RGB_str){Float32}"
2427
a = channelview(rgb32)
25-
@test summary(a) == "3×3×5 reinterpret(Float32, ::Array{RGB{Float32},3})"
28+
@test summary(a) == (VERSION >= v"1.6.0-DEV.1083" ? "3×3×5 reinterpret(reshape, Float32, ::Array{RGB{Float32},2}) with eltype Float32" :
29+
"3×3×5 reinterpret(Float32, ::Array{RGB{Float32},3})")
2630
num64 = rand(3,5)
2731
b = colorview(RGB, num64)
28-
@test summary(b) == "5-element reshape(reinterpret(RGB{Float64}, ::$(typeof(num64))), 5) with eltype $(RGB_str){Float64}"
32+
@test summary(b) == (VERSION >= v"1.6.0-DEV.1083" ? "5-element reinterpret(reshape, RGB{Float64}, ::$(typeof(num64))) with eltype $(RGB_str){Float64}" :
33+
"5-element reshape(reinterpret(RGB{Float64}, ::$(typeof(num64))), 5) with eltype $(RGB_str){Float64}")
2934
rgb8 = rand(RGB{N0f8}, 3, 5)
3035
c = rawview(channelview(rgb8))
31-
@test summary(c) == "3×3×5 rawview(reinterpret(N0f8, ::Array{RGB{N0f8},3})) with eltype UInt8"
36+
@test summary(c) == "3×3×5 rawview(reinterpret($(rrstr)N0f8, ::Array{RGB{N0f8},$(rrdim(3))})) with eltype UInt8"
3237
@test summary(rgb8) == "3×5 Array{RGB{N0f8},2} with eltype $(RGB_str){$(N0f8_str)}"
3338
rand8 = rand(UInt8, 3, 5)
3439
d = normedview(PermutedDimsArray(rand8, (2,1)))
@@ -39,14 +44,15 @@ RGB_str = typestring(RGB)
3944
f = PermutedDimsArray(normedview(N0f16, rand16), (2,1))
4045
@test summary(f) == "5×3 PermutedDimsArray(reinterpret(N0f16, ::$(typeof(rand16))), (2, 1)) with eltype $(N0f16_str)"
4146
g = channelview(rgb8)
42-
@test summary(g) == "3×3×5 reinterpret(N0f8, ::Array{RGB{N0f8},3})"
47+
etstr = VERSION >= v"1.6.0-DEV.1083" ? " with eltype N0f8" : ""
48+
@test summary(g) == "3×3×5 reinterpret($(rrstr)N0f8, ::Array{RGB{N0f8},$(rrdim(3))})$etstr"
4349
h = OffsetArray(rgb8, -1:1, -2:2)
4450
@test summary(h) == "$(sumsz(h))OffsetArray(::Array{RGB{N0f8},2}, -1:1, -2:2) with eltype $(RGB_str){$(N0f8_str)} with indices -1:1×-2:2"
4551
i = channelview(h)
46-
@test summary(i) == "$(sumsz(i))reinterpret(N0f8, OffsetArray(::Array{RGB{N0f8},3}, 1:1, -1:1, -2:2)) with indices 1:3×-1:1×-2:2"
52+
@test summary(i) == "$(sumsz(i))reinterpret($(rrstr)N0f8, OffsetArray(::Array{RGB{N0f8},$(rrdim(3))}, 1:1, -1:1, -2:2)) with indices 1:3×-1:1×-2:2"
4753
c = channelview(rand(RGB{N0f8}, 2))
4854
o = OffsetArray(c, -1:1, 0:1)
49-
@test summary(o) == "$(sumsz(o))OffsetArray(reinterpret(N0f8, ::Array{RGB{N0f8},2}), -1:1, 0:1) with eltype $(N0f8_str) with indices -1:1×0:1"
55+
@test summary(o) == "$(sumsz(o))OffsetArray(reinterpret($(rrstr)N0f8, ::Array{RGB{N0f8},$(rrdim(2))}), -1:1, 0:1) with eltype $(N0f8_str) with indices -1:1×0:1"
5056
# Issue #45
5157
a = collect(tuple())
5258
@test summary(a) == "0-element $(typeof(a))"

0 commit comments

Comments
 (0)