Skip to content

Commit

Permalink
clean up WarpedView API and add warpedview
Browse files Browse the repository at this point in the history
  • Loading branch information
Evizero committed Apr 21, 2017
1 parent 1957490 commit fccebb1
Show file tree
Hide file tree
Showing 2 changed files with 58 additions and 33 deletions.
3 changes: 2 additions & 1 deletion src/ImageTransformations.jl
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,8 @@ export
imresize,
center,
warp,
WarpedView
WarpedView,
warpedview

include("autorange.jl")
include("resizing.jl")
Expand Down
88 changes: 56 additions & 32 deletions src/warpedview.jl
Original file line number Diff line number Diff line change
@@ -1,62 +1,86 @@
immutable WarpedView{T,N,A<:AbstractArray,F1<:Transformation,F2<:Transformation,I} <: AbstractArray{T,N}
_build_extrapolation(etp::AbstractExtrapolation) = etp

function _build_extrapolation{T}(itp::AbstractInterpolation{T}, fill::FillType = _default_fill(T))
etp = extrapolate(itp, fill)
_build_extrapolation(etp)
end

function _build_extrapolation{T,N,D<:Union{Linear,Constant}}(parent::AbstractArray{T,N}, degree::D = Linear(), args...)
itp = Interpolations.BSplineInterpolation{T,N,typeof(parent),BSpline{D},OnGrid,0}(parent)
_build_extrapolation(itp, args...)
end

immutable WarpedView{T,N,A<:AbstractArray,F1<:Transformation,I,F2<:Transformation,E<:AbstractExtrapolation} <: AbstractArray{T,N}
parent::A
transform::F1
transform_inv::F2
indices::I
inverse::F2
extrapolation::E

function (::Type{WarpedView{T,N,A,F1,F2,I}}){T,N,A<:AbstractArray,F1<:Transformation,F2<:Transformation,I}(
parent::A, tform::F1, tinv::F2, indices::I)
function (::Type{WarpedView{T,N,TA,F,I}}){T,N,TA<:AbstractArray,F<:Transformation,I<:Tuple}(
parent::TA,
tform::F,
indices::I)
@assert eltype(parent) == T
new{T,N,A,F1,F2,I}(parent, tform, tinv, indices)
etp = _build_extrapolation(parent)
tinv = inv(tform)
new{T,N,TA,F,I,typeof(tinv),typeof(etp)}(parent, tform, indices, tinv, etp)
end
end

function WarpedView{T,N,F<:Transformation}(inner::WarpedView{T,N}, outer_tform::F)
function WarpedView(inner::WarpedView, outer_tform::Transformation)
tform = compose(outer_tform, inner.transform)
tinv = inv(tform)
etp = parent(inner)
inds = autorange(etp, tform)
WarpedView{T,N,typeof(etp),typeof(tform),typeof(tinv),typeof(inds)}(etp, tform, tinv, inds)
end

function WarpedView{T,N}(parent::AbstractArray{T,N}, args...)
itp = Interpolations.BSplineInterpolation{T,N,typeof(parent),Interpolations.BSpline{Interpolations.Linear},OnGrid,0}(parent)
WarpedView(itp, args...)
A = parent(inner)
inds = autorange(A, tform)
WarpedView(A, tform, inds)
end

function WarpedView{T,F<:Transformation}(itp::AbstractInterpolation{T}, tform::F, fill=_default_fill(T))
WarpedView(extrapolate(itp, fill), tform)
end

function WarpedView{T,N,F<:Transformation}(etp::AbstractExtrapolation{T,N}, tform::F)
inds = autorange(etp, tform)
tinv = inv(tform)
WarpedView{T,N,typeof(etp),F,typeof(tinv),typeof(inds)}(etp, tform, tinv, inds)
function WarpedView{T,N,F<:Transformation,I<:Tuple}(
A::AbstractArray{T,N},
tform::F,
inds::I = autorange(A, tform))
WarpedView{T,N,typeof(A),F,I}(A, tform, inds)
end

Base.parent(A::WarpedView) = A.parent
@inline Base.indices(A::WarpedView) = A.indices

@compat Compat.IndexStyle{T<:WarpedView}(::Type{T}) = IndexCartesian()
@inline Base.getindex{T,N}(A::WarpedView{T,N}, I::Vararg{Int,N}) =
_getindex(A.parent, A.transform_inv(SVector(I)))
_getindex(A.extrapolation, A.inverse(SVector(I)))

Base.size(A::WarpedView) = OffsetArrays.errmsg(A)
Base.size(A::WarpedView, d) = OffsetArrays.errmsg(A)

# This will return the next non-standard parent
# This way only those extrapolations/interpolations are displayed
# that are different to the default settings
_next_custom(A) = A
_next_custom(A::Interpolations.FilledExtrapolation) = _next_custom(A.itp)
_next_custom{T,N,TI,IT<:BSpline{Linear},GT<:OnGrid}(A::Interpolations.BSplineInterpolation{T,N,TI,IT,GT}) = _next_custom(A.coefs)

function ShowItLikeYouBuildIt.showarg(io::IO, A::WarpedView)
print(io, "WarpedView(")
showarg(io, _next_custom(parent(A)))
showarg(io, parent(A))
print(io, ", ")
print(io, A.transform)
print(io, ')')
end

Base.summary(A::WarpedView) = summary_build(A)

"""
TODO
"""
@inline warpedview(A::AbstractArray, tform::Transformation, args...) =
WarpedView(A, tform, args...)

function warpedview{T}(
A::AbstractArray{T},
tform::Transformation,
degree::Union{Linear,Constant},
fill::FillType = _default_fill(T),
args...)
warpedview(_build_extrapolation(A, degree, fill), tform, args...)
end

function warpedview(
A::AbstractArray,
tform::Transformation,
fill::FillType,
args...)
warpedview(_build_extrapolation(A, Linear(), fill), tform, args...)
end

0 comments on commit fccebb1

Please sign in to comment.