Skip to content

Commit

Permalink
Rework for reinterpret with offset axes
Browse files Browse the repository at this point in the history
The final version of support for reinterpreting arrays with offset
axes requires that the first axis starts with 1. Consequently we now
reshape before we reinterpret. This led to a surprising number of
cascading changes.

Also fixes the Base._length deprecation.
  • Loading branch information
timholy committed Jul 12, 2018
1 parent 81907af commit a167433
Show file tree
Hide file tree
Showing 10 changed files with 49 additions and 57 deletions.
1 change: 0 additions & 1 deletion .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ os:
- linux
- osx
julia:
- 0.6
- nightly
notifications:
email: false
Expand Down
6 changes: 3 additions & 3 deletions REQUIRE
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
julia 0.6.0
julia ??
FixedPointNumbers 0.3.0
ColorTypes 0.4
Colors
MappedArrays 0.2
PaddedViews 0.0.2
PaddedViews 0.5
Graphics
OffsetArrays
OffsetArrays 0.8
FFTW
2 changes: 0 additions & 2 deletions appveyor.yml
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
environment:
matrix:
- JULIA_URL: "https://julialang-s3.julialang.org/bin/winnt/x86/0.6/julia-0.6-latest-win32.exe"
- JULIA_URL: "https://julialang-s3.julialang.org/bin/winnt/x64/0.6/julia-0.6-latest-win64.exe"
- JULIA_URL: "https://julialangnightlies-s3.julialang.org/bin/winnt/x86/julia-latest-win32.exe"
- JULIA_URL: "https://julialangnightlies-s3.julialang.org/bin/winnt/x64/julia-latest-win64.exe"

Expand Down
14 changes: 11 additions & 3 deletions src/colorchannels.jl
Original file line number Diff line number Diff line change
Expand Up @@ -105,23 +105,31 @@ _ccolorview(::Type{C}, A::RRArray{T,C}) where {C<:Colorant,T<:Number} =
parent(parent(A))
_ccolorview(::Type{C}, A::Base.ReinterpretArray{T,M,C}) where {C<:AbstractGray,T<:Number,M} =
parent(A)
_ccolorview(::Type{C}, A::Base.ReinterpretArray{T,M,C}) where {C<:RGB,T<:Number,M} =
reshape(parent(A), Base.tail(axes(parent(A))))
_ccolorview(::Type{C}, A::Base.ReinterpretArray{T,M,C}) where {C<:AbstractRGB,T<:Number,M} =
_colorview_reorder(C, A)
_ccolorview(::Type{C}, A::Base.ReinterpretArray{T,M,C}) where {C<:Color,T<:Number,M} =
reshape(parent(A), Base.tail(axes(parent(A))))
_ccolorview(::Type{C}, A::AbstractArray{T}) where {C<:Colorant,T<:Number} =
__ccolorview(C, A) # necessary to avoid ambiguities from dispatch on eltype
__ccolorview(::Type{C}, A::AbstractArray{T}) where {T<:Number,C<:RGB{T}} = reinterpretc(C, A)
__ccolorview(::Type{C}, A::AbstractArray{T}) where {T<:Number,C<:AbstractRGB} =
reinterpretc(C, view(A, dimorder(C), Base.tail(colons(A))...))
_colorview_reorder(C, A)
__ccolorview(::Type{C}, A::AbstractArray{T}) where {T<:Number,C<:Color{T}} = reinterpretc(C, A)
__ccolorview(::Type{C}, A::AbstractArray{T}) where {T<:Number,C<:ColorAlpha} =
_colorviewalpha(base_color_type(C), C, eltype(C), A)
__ccolorview(::Type{C}, A::AbstractArray{T}) where {T<:Number,C<:AlphaColor} =
reinterpretc(C, view(A, dimorder(C), Base.tail(colons(A))...))
_colorview_reorder(C, A)
_colorviewalpha(::Type{C}, ::Type{CA}, ::Type{T}, A::AbstractArray{T}) where {C<:RGB,CA,T} =
reinterpretc(CA, A)
_colorviewalpha(::Type{C}, ::Type{CA}, ::Type{T}, A::AbstractArray{T}) where {C<:AbstractRGB,CA,T} =
reinterpretc(CA, view(A, dimorder(CA), Base.tail(colons(A))...))
_colorview_reorder(CA, A)
_colorviewalpha(::Type{C}, ::Type{CA}, ::Type{T}, A::AbstractArray{T}) where {C<:Color,CA,T} =
reinterpretc(CA, A)

_colorview_reorder(::Type{C}, A) where C = reinterpretc(C, view(A, dimorder(C), Base.tail(colons(A))...))

colorview(::Type{ARGB32}, A::AbstractArray{BGRA{N0f8}}) = reinterpret(ARGB32, A)

colorview(::Type{C1}, A::AbstractArray{C2}) where {C1<:Colorant,C2<:Colorant} =
Expand Down
13 changes: 1 addition & 12 deletions src/convert_reinterpret.jl
Original file line number Diff line number Diff line change
Expand Up @@ -18,18 +18,13 @@ function reinterpretc(::Type{CV1}, a::AbstractArray{CV2}) where {CV1<:Colorant,C
end

## Color->T
# function reinterpretc(::Type{T}, a::Array{CV,1}) where {T<:Number,CV<:Colorant}
# l = (length(a)*sizeof(CV))÷sizeof(T)
# l*sizeof(T) == length(a)*sizeof(CV) || throw(ArgumentError("sizes are incommensurate"))
# reshape(reinterpret(T, a), (l,))
# end
function reinterpretc(::Type{T}, a::AbstractArray{CV}) where {T<:Number,CV<:Colorant}
if samesize(T, CV)
return reinterpret(T, a)
end
axs = axes(a)
if sizeof(CV) == sizeof(T)*_len(CV)
return reshape(reinterpret(T, a), (convert(typeof(axs[1]), Base.OneTo(_len(CV))), axs...))
return reinterpret(T, reshape(a, Base.OneTo(1), axs...))
end
throw(ArgumentError("result shape not specified"))
end
Expand All @@ -44,12 +39,6 @@ _len(::Type{C}, ::Type{T}) where {C,T} = sizeof(C) ÷ sizeof(T)
# We have to distinguish two forms of call:
# form 1: reinterpretc(RGB{N0f8}, img)
# form 2: reinterpretc(RGB, img)
function reinterpretc(::Type{CV}, a::AbstractArray{T,1}) where {CV<:Colorant,T<:Number}
CVT = ccolor_number(CV, T)
l = (length(a)*sizeof(T))÷sizeof(CVT)
l*sizeof(CVT) == length(a)*sizeof(T) || throw(ArgumentError("sizes are incommensurate"))
reshape(reinterpret(CVT, a), (l,))
end
function reinterpretc(::Type{CV}, a::AbstractArray{T}) where {CV<:Colorant,T<:Number}
@noinline throwdm(::Type{C}, ind1) where C =
throw(DimensionMismatch("indices $ind1 are not consistent with color type $C"))
Expand Down
2 changes: 2 additions & 0 deletions src/deprecations.jl
Original file line number Diff line number Diff line change
Expand Up @@ -20,3 +20,5 @@ function ColorView{C}(A::AbstractArray) where C<:Colorant
end

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

Base.@deprecate_binding squeeze1 true
2 changes: 1 addition & 1 deletion src/traits.jl
Original file line number Diff line number Diff line change
Expand Up @@ -121,7 +121,7 @@ assert_timedim_last(img::AbstractMappedArray) = assert_timedim_last(parent(img))
assert_timedim_last(img::OffsetArray) = assert_timedim_last(parent(img))
assert_timedim_last(img::SubArray) = assert_timedim_last(parent(img))

widthheight(img::AbstractArray) = Base._length(axes(img,2)), Base._length(axes(img,1))
widthheight(img::AbstractArray) = length(axes(img,2)), length(axes(img,1))

width(img::AbstractArray) = widthheight(img)[1]
height(img::AbstractArray) = widthheight(img)[2]
Expand Down
52 changes: 24 additions & 28 deletions test/colorchannels.jl
Original file line number Diff line number Diff line change
Expand Up @@ -26,12 +26,12 @@ Base.setindex!(A::ArrayLS{T,N}, val, i::Vararg{Int,N}) where {T,N} = A.A[i...] =
for (a, LI) in ((copy(a0), IndexLinear()),
(ArrayLF(copy(a0)), IndexLinear()),
(ArrayLS(copy(a0)), IndexCartesian()))
v = channelview(a)
v = @inferred(channelview(a))
@test @inferred(IndexStyle(v)) == LI
@test ndims(v) == 1
@test size(v) == (2,)
@test eltype(v) == N0f8
@test colorview(Gray, v) === a
@test @inferred(colorview(Gray, v)) === a
@test parent(parent(v)) === a
@test v[1] == N0f8(0.2)
@test v[2] == N0f8(0.4)
Expand Down Expand Up @@ -61,16 +61,14 @@ end
a0 = [T(0.1,0.2,0.3), T(0.4, 0.5, 0.6)]
for a in (copy(a0),
ArrayLS(copy(a0)))
v = channelview(a)
v = @inferred(channelview(a))
@test ndims(v) == 2
@test size(v) == (3,2)
@test eltype(v) == Float64
if T in (RGB, HSV, Lab, XYZ)
@test colorview(T, v) === a
@test parent(parent(v)) === a
@test @inferred(colorview(T, v)) == a && colorview(T, v) isa typeof(a)
else
@test colorview(T, v) == a
@test parent(parent(v)) == a
@test @inferred(colorview(T, v)) == a
end
@test v[1] == v[1,1] == 0.1
@test v[2] == v[2,1] == 0.2
Expand Down Expand Up @@ -101,21 +99,20 @@ end
end
end
a = reshape([RGB(1,0,0)]) # 0-dimensional
v = channelview(a)
v = @inferred(channelview(a))
@test axes(v) === (Base.OneTo(3),)
v = channelview(a)
v = @inferred(channelview(a))
@test axes(v) === (Base.OneTo(3),)
end

@testset "Gray+Alpha" begin
for T in (AGray, GrayA)
a = [T(0.1f0,0.2f0), T(0.3f0,0.4f0), T(0.5f0,0.6f0)]
v = channelview(a)
@test colorview(T, v) == a
v = @inferred(channelview(a))
@test @inferred(colorview(T, v)) == a
@test ndims(v) == 2
@test size(v) == (2,3)
@test eltype(v) == Float32
@test parent(parent(v)) == a
@test v[1] == v[1,1] == 0.1f0
@test v[2] == v[2,1] == 0.2f0
@test v[3] == v[1,2] == 0.3f0
Expand Down Expand Up @@ -160,11 +157,10 @@ end
LabA,
XYZA)
a = [T(0.1,0.2,0.3,0.4), T(0.5,0.6,0.7,0.8)]
v = channelview(a)
v = @inferred(channelview(a))
@test ndims(v) == 2
@test size(v) == (4,2)
@test eltype(v) == Float64
@test parent(parent(v)) == a
@test v[1] == v[1,1] == 0.1
@test v[2] == v[2,1] == 0.2
@test v[3] == v[3,1] == 0.3
Expand Down Expand Up @@ -201,11 +197,11 @@ end

@testset "Non-1 indices" begin
a = OffsetArray(rand(RGB{N0f8}, 3, 5), -1:1, -2:2)
v = channelview(a)
v = @inferred(channelview(a))
@test @inferred(axes(v)) === (Base.Slice(1:3), Base.Slice(-1:1), Base.Slice(-2:2))
@test @inferred(v[1,0,0]) === a[0,0].r
a = OffsetArray(rand(Gray{Float32}, 3, 5), -1:1, -2:2)
v = channelview(a)
v = @inferred(channelview(a))
@test @inferred(axes(v)) === (Base.Slice(-1:1), Base.Slice(-2:2))
@test @inferred(v[0,0]) === gray(a[0,0])
@test @inferred(v[5]) === gray(a[5])
Expand All @@ -224,12 +220,12 @@ end
(ArrayLF(copy(a0)), IndexLinear()),
(ArrayLS(copy(a0)), IndexCartesian()))
@test_throws MethodError colorview(a)
v = colorview(Gray, a)
v = @inferred(colorview(Gray, a))
@test @inferred(IndexStyle(v)) == LI
@test ndims(v) == 1
@test size(v) == (2,)
@test eltype(v) == Gray{N0f8}
@test channelview(v) === a
@test @inferred(channelview(v)) === a
@test parent(parent(v)) === a
@test v[1] == Gray(N0f8(0.2))
@test v[2] == Gray(N0f8(0.4))
Expand Down Expand Up @@ -260,12 +256,12 @@ end
(ArrayLF(copy(a0)), IndexLinear()),
(ArrayLS(copy(a0)), IndexCartesian()))
@test_throws MethodError colorview(a)
v = colorview(Gray, a)
v = @inferred(colorview(Gray, a))
@test @inferred(IndexStyle(v)) == LI
@test ndims(v) == 2
@test size(v) == (2,2)
@test eltype(v) == Gray{N0f8}
@test channelview(v) === a
@test @inferred(channelview(v)) === a
@test parent(parent(v)) === a
@test v[1] == Gray(N0f8(0.2))
@test v[2] == Gray(N0f8(0.6))
Expand Down Expand Up @@ -316,11 +312,11 @@ end
@testset "Gray+Alpha" begin
for T in (AGray, GrayA)
a = [0.1f0 0.2f0; 0.3f0 0.4f0; 0.5f0 0.6f0]'
v = colorview(T, a)
v = @inferred(colorview(T, a))
@test ndims(v) == 1
@test size(v) == (3,)
@test eltype(v) == T{Float32}
@test channelview(v) === a
@test @inferred(channelview(v)) === a
@test v[1] == T(0.1f0, 0.2f0)
@test v[2] == T(0.3f0, 0.4f0)
@test v[3] == T(0.5f0, 0.6f0)
Expand Down Expand Up @@ -348,9 +344,9 @@ end

@testset "Alpha+RGB, HSV, etc" begin
a = rand(ARGB{N0f8}, 5, 5)
vc = channelview(a)
@test eltype(colorview(ARGB, vc)) == ARGB{N0f8}
cvc = colorview(RGBA, vc)
vc = @inferred(channelview(a))
@test eltype(@inferred(colorview(ARGB, vc))) == ARGB{N0f8}
cvc = @inferred(colorview(RGBA, vc))
@test all(cvc .== a)

for T in (ARGB,
Expand All @@ -364,9 +360,9 @@ end
LabA,
XYZA)
a = [0.1 0.2 0.3 0.4; 0.5 0.6 0.7 0.8]'
v = colorview(T, a)
v = @inferred(colorview(T, a))
@test eltype(v) == T{Float64}
@test channelview(v) === a
@test @inferred(channelview(v)) === a
@test ndims(v) == 1
@test size(v) == (2,)
@test eltype(v) == T{Float64}
Expand Down Expand Up @@ -397,7 +393,7 @@ end

@testset "Non-1 indices" begin
a = OffsetArray(rand(3, 3, 5), 1:3, -1:1, -2:2)
v = colorview(RGB, a)
v = @inferred(colorview(RGB, a))
@test @inferred(axes(v)) === (Base.Slice(-1:1), Base.Slice(-2:2))
@test @inferred(v[0,0]) === RGB(a[1,0,0], a[2,0,0], a[3,0,0])
a = OffsetArray(rand(3, 3, 5), 0:2, -1:1, -2:2)
Expand Down
4 changes: 2 additions & 2 deletions test/convert_reinterpret.jl
Original file line number Diff line number Diff line change
Expand Up @@ -114,15 +114,15 @@ using Test, Random
af = @inferred(reinterpretc(Float64, a))
anew = @inferred(reinterpretc(RGB, vec(af)))
@test anew[1] == a[1]
@test ndims(anew) == 1
@test ndims(anew) == 0

# #33 and its converse
a = reinterpretc(BGRA{N0f8}, [0xf0884422])
@test isa(a, AbstractVector) && a == [BGRA{N0f8}(0.533,0.267,0.133,0.941)]
@test reinterpretc(UInt32, a) == [0xf0884422]
@test size(reinterpretc(BGRA{N0f8}, rand(UInt32, 5, 5))) == (5,5)
@test size(colorview(ARGB32, rand(BGRA{N0f8}, 5, 5))) == (5,5)
a = reinterpretc(BGRA{N0f8}, [0x22, 0x44, 0x88, 0xf0, 0x01, 0x02, 0x03, 0x04])
a = reinterpretc(BGRA{N0f8}, reshape([0x22, 0x44, 0x88, 0xf0, 0x01, 0x02, 0x03, 0x04], 4, 2))
@test a == [BGRA{N0f8}(0.533,0.267,0.133,0.941), BGRA{N0f8}(0.012, 0.008, 0.004, 0.016)]
@test reinterpret(UInt8, a) == [0x22, 0x44, 0x88, 0xf0, 0x01, 0x02, 0x03, 0x04]
@test colorview(ARGB32, a) == reinterpretc(ARGB32, [0xf0884422,0x04030201])
Expand Down
10 changes: 5 additions & 5 deletions test/show.jl
Original file line number Diff line number Diff line change
Expand Up @@ -12,13 +12,13 @@ using ImageCore, Colors, FixedPointNumbers, OffsetArrays, Test
v = view(rgb32, 2:3, :)
@test summary(v) == "2×5 view(::Array{RGB{Float32},2}, 2:3, :) with eltype $(prefixC)RGB{Float32}"
a = channelview(rgb32)
@test summary(a) == "3×3×5 reshape(reinterpret(Float32, ::Array{RGB{Float32},2}), 3, 3, 5) with eltype Float32"
@test summary(a) == "3×3×5 reinterpret(Float32, ::Array{RGB{Float32},3})"
num64 = rand(3,5)
b = colorview(RGB, num64)
@test summary(b) == "5-element reshape(reinterpret(RGB{Float64}, ::Array{Float64,2}), 5) with eltype $(prefixC)RGB{Float64}"
rgb8 = rand(RGB{N0f8}, 3, 5)
c = rawview(channelview(rgb8))
@test summary(c) == "3×3×5 rawview(reshape(reinterpret(N0f8, ::Array{RGB{N0f8},2}), 3, 3, 5)) with eltype UInt8"
@test summary(c) == "3×3×5 rawview(reinterpret(N0f8, ::Array{RGB{N0f8},3})) with eltype UInt8"
@test summary(rgb8) == "3×5 Array{RGB{N0f8},2} with eltype $(prefixC)RGB{$(prefixF)Normed{UInt8,8}}"
rand8 = rand(UInt8, 3, 5)
d = normedview(permuteddimsview(rand8, (2,1)))
Expand All @@ -28,14 +28,14 @@ using ImageCore, Colors, FixedPointNumbers, OffsetArrays, Test
f = permuteddimsview(normedview(N0f16, rand(UInt16, 3, 5)), (2,1))
@test summary(f) == "5×3 PermutedDimsArray(reinterpret(N0f16, ::Array{UInt16,2}), (2, 1)) with eltype $(prefixF)Normed{UInt16,16}"
g = channelview(rgb8)
@test summary(g) == "3×3×5 reshape(reinterpret(N0f8, ::Array{RGB{N0f8},2}), 3, 3, 5) with eltype $(prefixF)Normed{UInt8,8}"
@test summary(g) == "3×3×5 reinterpret(N0f8, ::Array{RGB{N0f8},3})"
h = OffsetArray(rgb8, -1:1, -2:2)
@test summary(h) == "OffsetArray(::Array{RGB{N0f8},2}, -1:1, -2:2) with eltype $(prefixC)RGB{$(prefixF)Normed{UInt8,8}} with indices -1:1×-2:2"
i = channelview(h)
@test summary(i) == "OffsetArray(reshape(reinterpret(N0f8, ::Array{RGB{N0f8},2}), 3, 3, 5), 1:3, -1:1, -2:2) with eltype $(prefixF)Normed{UInt8,8} with indices 1:3×-1:1×-2:2"
@test summary(i) == "reinterpret(N0f8, OffsetArray(::Array{RGB{N0f8},3}, 1:1, -1:1, -2:2)) with indices 1:3×-1:1×-2:2"
c = channelview(rand(RGB{N0f8}, 2))
o = OffsetArray(c, -1:1, 0:1)
@test summary(o) == "OffsetArray(reshape(reinterpret(N0f8, ::Array{RGB{N0f8},1}), 3, 2), -1:1, 0:1) with eltype $(prefixF)Normed{UInt8,8} with indices -1:1×0:1"
@test summary(o) == "OffsetArray(reinterpret(N0f8, ::Array{RGB{N0f8},2}), -1:1, 0:1) with eltype $(prefixF)Normed{UInt8,8} with indices -1:1×0:1"
# Issue #45
a = collect(tuple())
@test summary(a) == "0-element Array{Union{},1}"
Expand Down

0 comments on commit a167433

Please sign in to comment.