Skip to content

Commit

Permalink
Merge pull request #14 from JuliaIO/teh_sd/UFixed
Browse files Browse the repository at this point in the history
Update for the newest Images/FixedPointNumbers, fix? #12
  • Loading branch information
timholy committed Oct 29, 2015
2 parents 9b93798 + 16a9226 commit 7e698b4
Show file tree
Hide file tree
Showing 8 changed files with 109 additions and 89 deletions.
4 changes: 2 additions & 2 deletions .travis.yml
Expand Up @@ -3,8 +3,8 @@ os:
- linux
- osx
julia:
- 0.3
- 0.4
- release
- nightly
notifications:
email: false
# uncomment the following lines to override the default test script
Expand Down
7 changes: 3 additions & 4 deletions REQUIRE
@@ -1,8 +1,7 @@
julia 0.3
FixedPointNumbers
ColorTypes
julia 0.4
FixedPointNumbers 0.1
ColorTypes 0.2
FileIO
Compat
Images
@osx Homebrew
BinDeps
12 changes: 6 additions & 6 deletions appveyor.yml
@@ -1,7 +1,7 @@
environment:
matrix:
- JULIAVERSION: "julialang/bin/winnt/x86/0.3/julia-0.3-latest-win32.exe"
- JULIAVERSION: "julialang/bin/winnt/x64/0.3/julia-0.3-latest-win64.exe"
- JULIAVERSION: "julialang/bin/winnt/x86/0.4/julia-0.4-latest-win32.exe"
- JULIAVERSION: "julialang/bin/winnt/x64/0.4/julia-0.4-latest-win64.exe"
- JULIAVERSION: "julianightlies/bin/winnt/x86/julia-latest-win32.exe"
- JULIAVERSION: "julianightlies/bin/winnt/x64/julia-latest-win64.exe"

Expand All @@ -24,10 +24,10 @@ install:

build_script:
# Need to convert from shallow to complete for Pkg.clone to work
# - git fetch --unshallow
- IF EXIST .git\shallow (git fetch --unshallow)
- C:\projects\julia\bin\julia-debug -e "versioninfo(); Pkg.init();"
- C:\projects\julia\bin\julia-debug -e "Pkg.clone(\"Images\");"
- C:\projects\julia\bin\julia-debug -e "Pkg.checkout(pwd()); Pkg.build(\"ImageMagick\")"
- C:\projects\julia\bin\julia-debug -e "Pkg.clone(pwd(), \"ImageMagick\");"
- C:\projects\julia\bin\julia-debug -e "Pkg.build(\"ImageMagick\")"

test_script:
- C:\projects\julia\bin\julia --check-bounds=yes -e "Pkg.test(\"ImageMagick\")"
- C:\projects\julia\bin\julia -e "Pkg.test(\"ImageMagick\")"
49 changes: 28 additions & 21 deletions deps/build.jl
@@ -1,4 +1,4 @@
using BinDeps, Compat
using BinDeps

@BinDeps.setup

Expand Down Expand Up @@ -48,6 +48,14 @@ end
magick_url = "$(magick_base)/$(magick_exe)"
magick_libdir = joinpath(BinDeps.libdir(libwand), OS_ARCH)
innounp_url = "https://bintray.com/artifact/download/julialang/generic/innounp.exe"
initfun =
"""
function init_deps()
ENV["MAGICK_CONFIGURE_PATH"] = \"$(escape_string(magick_libdir))\"
ENV["MAGICK_CODER_MODULE_PATH"] = \"$(escape_string(magick_libdir))\"
end
init_deps()
"""

provides(BuildProcess,
(@build_steps begin
Expand All @@ -61,40 +69,39 @@ end
`innounp.exe -q -y -b -e -x -d$(magick_libdir) $(magick_exe)`
end
end),
libwand, os = :Windows, unpacked_dir = magick_libdir,
preload ="""
function init_deps()
ENV["MAGICK_CONFIGURE_PATH"] = \"$(escape_string(magick_libdir))\"
ENV["MAGICK_CODER_MODULE_PATH"] = \"$(escape_string(magick_libdir))\"
end
init_deps()
"""
)
libwand, os = :Windows, unpacked_dir = magick_libdir, preload = initfun)
end

@osx_only begin
if Pkg.installed("Homebrew") === nothing
error("Homebrew package not installed, please run Pkg.add(\"Homebrew\")")
end
using Homebrew
provides( Homebrew.HB, "imagemagick", libwand, os = :Darwin, preload =
"""
function init_deps()
ENV["MAGICK_CONFIGURE_PATH"] = joinpath("$(Homebrew.prefix("imagemagick"))","lib","ImageMagick","config-Q16")
ENV["MAGICK_CODER_MODULE_PATH"] = joinpath("$(Homebrew.prefix("imagemagick"))", "lib","ImageMagick","modules-Q16","coders")
ENV["PATH"] = joinpath("$(Homebrew.prefix("imagemagick"))", "bin") * ":" * ENV["PATH"]
ccall((:MagickWandGenesis,libwand), Void, ())
end
""",
onload="init_deps()")
initfun =
"""
function init_deps()
ENV["MAGICK_CONFIGURE_PATH"] = joinpath("$(Homebrew.prefix("imagemagick"))","lib","ImageMagick","config-Q16")
ENV["MAGICK_CODER_MODULE_PATH"] = joinpath("$(Homebrew.prefix("imagemagick"))", "lib","ImageMagick","modules-Q16","coders")
ENV["PATH"] = joinpath("$(Homebrew.prefix("imagemagick"))", "bin") * ":" * ENV["PATH"]
ccall((:MagickWandGenesis,libwand), Void, ())
end
"""
provides( Homebrew.HB, "imagemagick", libwand, os = :Darwin, preload = initfun, onload="init_deps()")
end

@BinDeps.install Dict([(:libwand, :libwand)])

# Hack-fix for issue #12
# Check to see whether init_deps is present, and if not add it
if isempty(search(readall(joinpath(dirname(@__FILE__),"deps.jl")), "init_deps"))
open("deps.jl", "a") do io
write(io, initfun)
end
end

# Save the library version; by checking this now, we avoid a runtime dependency on libwand
# See https://github.com/timholy/Images.jl/issues/184#issuecomment-55643225
module CheckVersion
using Compat
include("deps.jl")
p = ccall((:MagickQueryConfigureOption, libwand), Ptr{UInt8}, (Ptr{UInt8},), "LIB_VERSION_NUMBER")
vstr = string("v\"", join(split(bytestring(p), ',')[1:3], '.'), "\"")
Expand Down
58 changes: 29 additions & 29 deletions src/ImageMagick.jl
@@ -1,7 +1,7 @@
VERSION >= v"0.4.0-dev+6521" && __precompile__(true)
__precompile__(true)
module ImageMagick

using FixedPointNumbers, ColorTypes, Compat, Images, ColorVectorSpace
using FixedPointNumbers, ColorTypes, Images, ColorVectorSpace
import FileIO: DataFormat, @format_str, Stream, File, filename, stream

export MagickWand
Expand Down Expand Up @@ -66,11 +66,11 @@ save{T <: DataFormat}(image::File{T}, args...; key_args...) = save_(filename(ima
load{T <: DataFormat}(image::Stream{T}, args...; key_args...) = load_(stream(image), args...; key_args...)
save{T <: DataFormat}(image::Stream{T}, args...; key_args...) = save_(stream(image), args...; key_args...)

const ufixedtype = @compat Dict(10=>Ufixed10, 12=>Ufixed12, 14=>Ufixed14, 16=>Ufixed16)
const ufixedtype = Dict(10=>UFixed10, 12=>UFixed12, 14=>UFixed14, 16=>UFixed16)

readblob(data::Vector{UInt8}) = load_(data)

function load_(file::@compat(Union{AbstractString,IO,Vector{UInt8}}); ImageType=Image, extraprop="", extrapropertynames=false)
function load_(file::Union{AbstractString,IO,Vector{UInt8}}; ImageType=Image, extraprop="", extrapropertynames=false)
wand = MagickWand()
readimage(wand, file)
resetiterator(wand)
Expand All @@ -95,7 +95,7 @@ function load_(file::@compat(Union{AbstractString,IO,Vector{UInt8}}); ImageType=

depth = getimagechanneldepth(wand, DefaultChannels)
if depth <= 8
T = Ufixed8 # always use 8-bit for 8-bit and less
T = UFixed8 # always use 8-bit for 8-bit and less
else
T = ufixedtype[2*((depth+1)>>1)] # always use an even # of bits (see issue 242#issuecomment-68845157)
end
Expand Down Expand Up @@ -178,28 +178,28 @@ function image2wand(img, mapi, quality, permute_horizontal=true)
wand
end

# ImageMagick mapinfo client. Converts to RGB and uses Ufixed.
mapinfo{T<:Ufixed}(img::AbstractArray{T}) = MapNone{T}()
mapinfo{T<:AbstractFloat}(img::AbstractArray{T}) = MapNone{Ufixed8}()
# ImageMagick mapinfo client. Converts to RGB and uses UFixed.
mapinfo{T<:UFixed}(img::AbstractArray{T}) = MapNone{T}()
mapinfo{T<:AbstractFloat}(img::AbstractArray{T}) = MapNone{UFixed8}()
for ACV in (Color, AbstractRGB)
for CV in subtypes(ACV)
(length(CV.parameters) == 1 && !(CV.abstract)) || continue
CVnew = CV<:AbstractGray ? Gray : RGB
@eval mapinfo{T<:Ufixed}(img::AbstractArray{$CV{T}}) = MapNone{$CVnew{T}}()
@eval mapinfo{CV<:$CV}(img::AbstractArray{CV}) = MapNone{$CVnew{Ufixed8}}()
@eval mapinfo{T<:UFixed}(img::AbstractArray{$CV{T}}) = MapNone{$CVnew{T}}()
@eval mapinfo{CV<:$CV}(img::AbstractArray{CV}) = MapNone{$CVnew{UFixed8}}()
CVnew = CV<:AbstractGray ? Gray : BGR
AC, CA = alphacolor(CV), coloralpha(CV)
ACnew, CAnew = alphacolor(CVnew), coloralpha(CVnew)
@eval begin
mapinfo{T<:Ufixed}(img::AbstractArray{$AC{T}}) = MapNone{$ACnew{T}}()
mapinfo{P<:$AC}(img::AbstractArray{P}) = MapNone{$ACnew{Ufixed8}}()
mapinfo{T<:Ufixed}(img::AbstractArray{$CA{T}}) = MapNone{$CAnew{T}}()
mapinfo{P<:$CA}(img::AbstractArray{P}) = MapNone{$CAnew{Ufixed8}}()
mapinfo{T<:UFixed}(img::AbstractArray{$AC{T}}) = MapNone{$ACnew{T}}()
mapinfo{P<:$AC}(img::AbstractArray{P}) = MapNone{$ACnew{UFixed8}}()
mapinfo{T<:UFixed}(img::AbstractArray{$CA{T}}) = MapNone{$CAnew{T}}()
mapinfo{P<:$CA}(img::AbstractArray{P}) = MapNone{$CAnew{UFixed8}}()
end
end
end
mapinfo(img::AbstractArray{RGB24}) = MapNone{RGB{Ufixed8}}()
mapinfo(img::AbstractArray{ARGB32}) = MapNone{BGRA{Ufixed8}}()
mapinfo(img::AbstractArray{RGB24}) = MapNone{RGB{UFixed8}}()
mapinfo(img::AbstractArray{ARGB32}) = MapNone{BGRA{UFixed8}}()


# Make the data contiguous in memory, this is necessary for
Expand All @@ -208,19 +208,19 @@ to_contiguous(A::AbstractArray) = A
to_contiguous(A::SubArray) = copy(A)

to_explicit(A::AbstractArray) = A
to_explicit{T<:Ufixed}(A::AbstractArray{T}) = reinterpret(FixedPointNumbers.rawtype(T), A)
to_explicit{T<:Ufixed}(A::AbstractArray{RGB{T}}) = reinterpret(FixedPointNumbers.rawtype(T), A, tuple(3, size(A)...))
to_explicit{T<:AbstractFloat}(A::AbstractArray{RGB{T}}) = to_explicit(map(ClampMinMax(RGB{Ufixed8}, zero(RGB{T}), one(RGB{T})), A))
to_explicit{T<:Ufixed}(A::AbstractArray{Gray{T}}) = reinterpret(FixedPointNumbers.rawtype(T), A, size(A))
to_explicit{T<:AbstractFloat}(A::AbstractArray{Gray{T}}) = to_explicit(map(ClampMinMax(Gray{Ufixed8}, zero(Gray{T}), one(Gray{T})), A))

to_explicit{T<:Ufixed}(A::AbstractArray{GrayA{T}}) = reinterpret(FixedPointNumbers.rawtype(T), A)
to_explicit{T<:AbstractFloat}(A::AbstractArray{GrayA{T}}) = to_explicit(map(ClampMinMax(GrayA{Ufixed8}, zero(GrayA{T}), one(GrayA{T})), A))

to_explicit{T<:Ufixed}(A::AbstractArray{BGRA{T}}) = reinterpret(FixedPointNumbers.rawtype(T), A, tuple(4, size(A)...))
to_explicit{T<:AbstractFloat}(A::AbstractArray{BGRA{T}}) = to_explicit(map(ClampMinMax(BGRA{Ufixed8}, zero(BGRA{T}), one(BGRA{T})), A))
to_explicit{T<:Ufixed}(A::AbstractArray{RGBA{T}}) = reinterpret(FixedPointNumbers.rawtype(T), A, tuple(4, size(A)...))
to_explicit{T<:AbstractFloat}(A::AbstractArray{RGBA{T}}) = to_explicit(map(ClampMinMax(RGBA{Ufixed8}, zero(RGBA{T}), one(RGBA{T})), A))
to_explicit{T<:UFixed}(A::AbstractArray{T}) = reinterpret(FixedPointNumbers.rawtype(T), A)
to_explicit{T<:UFixed}(A::AbstractArray{RGB{T}}) = reinterpret(FixedPointNumbers.rawtype(T), A, tuple(3, size(A)...))
to_explicit{T<:AbstractFloat}(A::AbstractArray{RGB{T}}) = to_explicit(map(ClampMinMax(RGB{UFixed8}, zero(RGB{T}), one(RGB{T})), A))
to_explicit{T<:UFixed}(A::AbstractArray{Gray{T}}) = reinterpret(FixedPointNumbers.rawtype(T), A, size(A))
to_explicit{T<:AbstractFloat}(A::AbstractArray{Gray{T}}) = to_explicit(map(ClampMinMax(Gray{UFixed8}, zero(Gray{T}), one(Gray{T})), A))

to_explicit{T<:UFixed}(A::AbstractArray{GrayA{T}}) = reinterpret(FixedPointNumbers.rawtype(T), A)
to_explicit{T<:AbstractFloat}(A::AbstractArray{GrayA{T}}) = to_explicit(map(ClampMinMax(GrayA{UFixed8}, zero(GrayA{T}), one(GrayA{T})), A))

to_explicit{T<:UFixed}(A::AbstractArray{BGRA{T}}) = reinterpret(FixedPointNumbers.rawtype(T), A, tuple(4, size(A)...))
to_explicit{T<:AbstractFloat}(A::AbstractArray{BGRA{T}}) = to_explicit(map(ClampMinMax(BGRA{UFixed8}, zero(BGRA{T}), one(BGRA{T})), A))
to_explicit{T<:UFixed}(A::AbstractArray{RGBA{T}}) = reinterpret(FixedPointNumbers.rawtype(T), A, tuple(4, size(A)...))
to_explicit{T<:AbstractFloat}(A::AbstractArray{RGBA{T}}) = to_explicit(map(ClampMinMax(RGBA{UFixed8}, zero(RGBA{T}), one(RGBA{T})), A))



Expand Down
6 changes: 3 additions & 3 deletions src/libmagickwand.jl
Expand Up @@ -48,13 +48,13 @@ const DOUBLEPIXEL = 2
const FLOATPIXEL = 3
const INTEGERPIXEL = 4
const SHORTPIXEL = 7
@compat IMStorageTypes = Union{UInt8, UInt16, UInt32, Float32, Float64}
IMStorageTypes = Union{UInt8, UInt16, UInt32, Float32, Float64}
storagetype(::Type{UInt8}) = CHARPIXEL
storagetype(::Type{UInt16}) = SHORTPIXEL
storagetype(::Type{UInt32}) = INTEGERPIXEL
storagetype(::Type{Float32}) = FLOATPIXEL
storagetype(::Type{Float64}) = DOUBLEPIXEL
storagetype{T<:Ufixed}(::Type{T}) = storagetype(FixedPointNumbers.rawtype(T))
storagetype{T<:UFixed}(::Type{T}) = storagetype(FixedPointNumbers.rawtype(T))
storagetype{CV<:Colorant}(::Type{CV}) = storagetype(eltype(CV))

# Channel types
Expand Down Expand Up @@ -87,7 +87,7 @@ const DefaultChannels = ChannelType( (AllChannels.value | SyncChannels.value) &~
const IMType = ["BilevelType", "GrayscaleType", "GrayscaleMatteType", "PaletteType", "PaletteMatteType", "TrueColorType", "TrueColorMatteType", "ColorSeparationType", "ColorSeparationMatteType", "OptimizeType", "PaletteBilevelMatteType"]
const IMTypedict = Dict([(IMType[i], i) for i = 1:length(IMType)])

const CStoIMTypedict = @compat Dict("Gray" => "GrayscaleType", "GrayA" => "GrayscaleMatteType", "RGB" => "TrueColorType", "ARGB" => "TrueColorMatteType", "CMYK" => "ColorSeparationType")
const CStoIMTypedict = Dict("Gray" => "GrayscaleType", "GrayA" => "GrayscaleMatteType", "RGB" => "TrueColorType", "ARGB" => "TrueColorMatteType", "CMYK" => "ColorSeparationType")

# Colorspace
const IMColorspace = ["RGB", "Gray", "Transparent", "OHTA", "Lab", "XYZ", "YCbCr", "YCC", "YIQ", "YPbPr", "YUV", "CMYK", "sRGB"]
Expand Down
44 changes: 29 additions & 15 deletions test/constructed_images.jl
Expand Up @@ -8,7 +8,8 @@ facts("IO") do

context("Gray png") do
a = rand(2,2)
aa = convert(Array{Ufixed8}, a)
a[1,1] = 1
aa = convert(Array{UFixed8}, a)
fn = joinpath(workdir, "2by2.png")
save(fn, a)
b = load(fn)
Expand All @@ -25,19 +26,21 @@ facts("IO") do
save(fn, aaimg)
b = load(fn)
@fact b --> aaimg
aa = convert(Array{Ufixed16}, a)
aa = convert(Array{UFixed16}, a)
save(fn, aa)
b = load(fn)
@fact convert(Array, b) --> aa
end

context("Color") do
fn = joinpath(workdir, "2by2.png")
img = Images.colorim(rand(3,2,2))
A = rand(3,2,2)
A[1] = 1
img = Images.colorim(A)
img24 = convert(Images.Image{RGB24}, img)
save(fn, img24)
b = load(fn)
imgrgb8 = convert(Images.Image{RGB{Ufixed8}}, img)
imgrgb8 = convert(Images.Image{RGB{UFixed8}}, img)
@fact Images.data(imgrgb8) --> Images.data(b)

open(fn, "w") do io
Expand Down Expand Up @@ -68,7 +71,7 @@ facts("IO") do
end

context("Alpha") do
c = reinterpret(Images.BGRA{Ufixed8}, [0xf0884422]'')
c = reinterpret(Images.BGRA{UFixed8}, [0xf0884422]'')
fn = joinpath(workdir, "alpha.png")
save(fn, c)
C = load(fn)
Expand All @@ -79,23 +82,28 @@ facts("IO") do
end

context("3D TIFF (issue #307)") do
A = Image(map(Gray{Ufixed8}, rand(0x00:0xff, 2, 2, 4)); colorspace="Gray", spatialorder=["x", "y"], timedim=3) # grayim does not use timedim, but load does...
Ar = rand(0x00:0xff, 2, 2, 4)
Ar[1] = 0xff
A = Image(map(x->Gray(UFixed8(x,0)), Ar); colorspace="Gray", spatialorder=["x", "y"], timedim=3) # grayim does not use timedim, but load does...
fn = joinpath(workdir, "3d.tif")
save(fn, A)
B = load(fn)

#@fact A --> B # seems to have different order -.-
@fact A --> B
end

context("Clamping (issue #256)") do
A = grayim(rand(2,2))
Ar = rand(2,2)
Ar[1] = 1
A = grayim(Ar)
A[1,1] = -0.4
fn = joinpath(workdir, "2by2.png")
println("The following InexactError is a sign of normal operation:")
@fact_throws InexactError save(fn, A)
save(fn, A, mapi=mapinfo(Images.Clamp, A))
B = load(fn)
A[1,1] = 0
@fact B --> map(Gray{Ufixed8}, A)
@fact B --> map(Gray{UFixed8}, A)
end

@unix_only context("Reading from a stream (issue #312)") do
Expand All @@ -114,31 +122,37 @@ facts("IO") do
img = readblob(arr)
@fact isa(img, Images.Image) --> true
end

context("writemime") do
a = colorim(rand(UInt8, 3, 2, 2))
Ar = rand(UInt8, 3, 2, 2)
Ar[1] = typemax(eltype(Ar))
a = colorim(Ar)
fn = joinpath(workdir, "2by2.png")
open(fn, "w") do file
writemime(file, MIME("image/png"), a, minpixels=0)
end
b = load(fn)
@fact data(b) --> data(a)

abig = colorim(rand(UInt8, 3, 1021, 1026))
Ar = rand(UInt8, 3, 1021, 1026)
Ar[1] = typemax(eltype(Ar))
abig = colorim(Ar)
fn = joinpath(workdir, "big.png")
open(fn, "w") do file
writemime(file, MIME("image/png"), abig, maxpixels=10^6)
end
b = load(fn)
@fact data(b) --> convert(Array{RGB{Ufixed8},2}, data(restrict(abig, (1,2))))
@fact data(b) --> convert(Array{RGB{UFixed8},2}, data(restrict(abig, (1,2))))

# Issue #269
abig = colorim(rand(UInt16, 3, 1024, 1023))
Ar = rand(UInt16, 3, 1024, 1023)
Ar[1] = typemax(eltype(Ar))
abig = colorim(Ar)
open(fn, "w") do file
writemime(file, MIME("image/png"), abig, maxpixels=10^6)
end
b = load(fn)
@fact data(b) --> convert(Array{RGB{Ufixed8},2}, data(restrict(abig, (1,2))))
@fact data(b) --> convert(Array{RGB{UFixed8},2}, data(restrict(abig, (1,2))))
end

end

0 comments on commit 7e698b4

Please sign in to comment.