diff --git a/README.md b/README.md index d2c00e6..a3d4213 100644 --- a/README.md +++ b/README.md @@ -49,14 +49,14 @@ some of your workarounds might interfere with the new approach. You can reset yo ```julia using Homebrew -run(`brew remove imagemagick@6`) -run(`brew prune`) +Homebrew.rm("imagemagick@6") +Homebrew.brew(`prune`) Pkg.build("ImageMagick") ``` You may also find [debugging Homebrew](https://github.com/JuliaLang/Homebrew.jl/wiki/Debugging-Homebrew.jl) -useful. +useful. Finally, an alternative to ImageMagick on OS X is [QuartzImageIO](https://github.com/JuliaIO/QuartzImageIO.jl). diff --git a/deps/build.jl b/deps/build.jl index 9f04d71..3b088c5 100644 --- a/deps/build.jl +++ b/deps/build.jl @@ -15,38 +15,24 @@ libwand = library_dependency("libwand", aliases = aliases) mpath = get(ENV, "MAGICK_HOME", "") # If MAGICK_HOME is defined, add to library search path if !isempty(mpath) - init_fun = - """ - function init_deps() - ccall((:MagickWandGenesis, libwand), Void, ()) - end - """ - - provides(Binaries, mpath, libwand, preload = init_fun, onload = "init_deps()") - provides(Binaries, joinpath(mpath, "lib"), libwand, preload = init_fun, onload = "init_deps()") + provides(Binaries, mpath, libwand) + provides(Binaries, joinpath(mpath, "lib"), libwand) end if is_linux() - init_fun = - """ - function init_deps() - ccall((:MagickWandGenesis, libwand), Void, ()) - end - """ - - provides(AptGet, "libmagickwand4", libwand, preload = init_fun, onload = "init_deps()") - provides(AptGet, "libmagickwand5", libwand, preload = init_fun, onload = "init_deps()") - provides(AptGet, "libmagickwand-6.q16-2", libwand, preload = init_fun, onload = "init_deps()") - provides(Pacman, "imagemagick", libwand, preload = init_fun, onload = "init_deps()") - provides(Yum, "ImageMagick", libwand, preload = init_fun, onload = "init_deps()") + provides(AptGet, "libmagickwand4", libwand) + provides(AptGet, "libmagickwand5", libwand) + provides(AptGet, "libmagickwand-6.q16-2", libwand) + provides(Pacman, "imagemagick", libwand) + provides(Yum, "ImageMagick", libwand) end if is_windows() push!(BinDeps.defaults, BuildProcess) # TODO: remove me when upstream is fixed - const OS_ARCH = Sys.WORD_SIZE == 64 ? "x64" : "x86" + OS_ARCH = Sys.WORD_SIZE == 64 ? "x64" : "x86" # TODO: checksums: we have gpg # Extract the appropriate filename to download @@ -54,77 +40,53 @@ if is_windows() binariesfn = download(magick_base) str = readstring(binariesfn) pattern = "ImageMagick-6.9.*?-Q16-$(OS_ARCH)-dll.exe" - m = match(Regex(pattern), str) - magick_exe = convert(String, m.match) - - magick_tmpdir = BinDeps.downloadsdir(libwand) - 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" - init_fun = + magick_exe = String(match(Regex(pattern), str).match) + + magick_tmpdir = BinDeps.downloadsdir(libwand) + magick_url = "$(magick_base)/$(magick_exe)" + magick_installdir = joinpath(BinDeps.libdir(libwand), OS_ARCH) + magick_libdir = joinpath(magick_installdir, "{app}") + innounp_url = "https://bintray.com/artifact/download/julialang/generic/innounp.exe" + preloads = """ - function init_deps() - ENV["MAGICK_CONFIGURE_PATH"] = \"$(escape_string(magick_libdir))\" - ENV["MAGICK_CODER_MODULE_PATH"] = \"$(escape_string(magick_libdir))\" + function initenv() + ENV["MAGICK_CONFIGURE_PATH"] = "$(escape_string(magick_libdir))" + ENV["MAGICK_CODER_MODULE_PATH"] = "$(escape_string(joinpath(magick_libdir, "modules", "coders")))" + ENV["MAGICK_FILTER_MODULE_PATH"] = "$(escape_string(joinpath(magick_libdir, "modules", "filters")))" + ENV["PATH"] = "$(escape_string(magick_libdir * ";"))" * ENV["PATH"] end """ provides(BuildProcess, (@build_steps begin - CreateDirectory(magick_tmpdir) - CreateDirectory(magick_libdir) FileDownloader(magick_url, joinpath(magick_tmpdir, magick_exe)) FileDownloader(innounp_url, joinpath(magick_tmpdir, "innounp.exe")) @build_steps begin ChangeDirectory(magick_tmpdir) - info("Installing ImageMagick library") - `innounp.exe -q -y -b -e -x -d$(magick_libdir) $(magick_exe)` + `innounp.exe -q -y -b -x -d$(magick_installdir) $(magick_exe)` end end), - libwand, os = :Windows, unpacked_dir = magick_libdir, preload = init_fun, - onload = "init_deps()") + libwand, os = :Windows, unpacked_dir = magick_libdir, preload = preloads) end if is_apple() using Homebrew - imagemagick_prefix = Homebrew.prefix("staticfloat/juliadeps/imagemagick@6") - init_fun = + homebrew_prefix = Homebrew.prefix() + preloads = """ - function init_deps() - ENV["MAGICK_CONFIGURE_PATH"] = joinpath("$(imagemagick_prefix)", - "lib", "ImageMagick", "config-Q16") - ENV["MAGICK_CODER_MODULE_PATH"] = joinpath("$(imagemagick_prefix)", - "lib", "ImageMagick", "modules-Q16", "coders") - ENV["PATH"] = joinpath("$(imagemagick_prefix)", "bin") * ":" * ENV["PATH"] - - ccall((:MagickWandGenesis,libwand), Void, ()) + function initenv() + ENV["MAGICK_CONFIGURE_PATH"] = "$(escape_string(joinpath(homebrew_prefix, "opt", "imagemagick@6", "lib", "ImageMagick", "config-Q16")))" + ENV["MAGICK_CODER_MODULE_PATH"] = "$(escape_string(joinpath(homebrew_prefix, "opt", "imagemagick@6", "lib", "ImageMagick", "modules-Q16", "coders")))" + ENV["MAGICK_FILTER_MODULE_PATH"] = "$(escape_string(joinpath(homebrew_prefix, "opt", "imagemagick@6", "lib", "ImageMagick", "modules-Q16", "filters")))" + ENV["PATH"] = "$(escape_string(joinpath(homebrew_prefix, "opt", "imagemagick@6", "bin") * ":"))" * ENV["PATH"] end """ - provides(Homebrew.HB, "staticfloat/juliadeps/imagemagick@6", libwand, os = :Darwin, - preload = init_fun, onload = "init_deps()") + provides(Homebrew.HB, "homebrew/core/imagemagick@6", libwand, os = :Darwin, preload = preloads) 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(readstring(joinpath(dirname(@__FILE__),"deps.jl")), "init_deps")) - open("deps.jl", "a") do io - write(io, init_fun) - end -end - -module CheckVersion - include("deps.jl") - p = ccall((:MagickQueryConfigureOption, libwand), Ptr{UInt8}, (Ptr{UInt8}, ), - "LIB_VERSION_NUMBER") - vstr = string("v\"", join(split(unsafe_string(p), ',')[1:3], '.'), "\"") - open(joinpath(dirname(@__FILE__), "versioninfo.jl"), "w") do file - write(file, "const libversion = $vstr\n") - end -end - is_windows() && pop!(BinDeps.defaults) diff --git a/src/ImageMagick.jl b/src/ImageMagick.jl index 1142a65..7752dc4 100644 --- a/src/ImageMagick.jl +++ b/src/ImageMagick.jl @@ -19,7 +19,7 @@ include("libmagickwand.jl") # Image / Video formats -image_formats = [ +const image_formats = [ format"BMP", format"AVI", format"CRW", @@ -152,7 +152,7 @@ function image2wand(img, mapi=identity, quality=nothing, permute_horizontal=true T = eltype(imgw) channelorder = T<:Real ? "Gray" : ColorTypes.colorant_string(T) if T <: Union{RGB,RGBA,ARGB,BGRA,ABGR} - cs = libversion > v"6.7.5" ? "sRGB" : "RGB" + cs = getlibversion() > v"6.7.5" ? "sRGB" : "RGB" else cs = channelorder end diff --git a/src/libmagickwand.jl b/src/libmagickwand.jl index df3f852..2e4bf7c 100644 --- a/src/libmagickwand.jl +++ b/src/libmagickwand.jl @@ -18,40 +18,135 @@ export MagickWand, setimageformat, writeimage -# Find the library -depsfile = joinpath(dirname(@__FILE__), "..", "deps", "deps.jl") -versionfile = joinpath(dirname(@__FILE__), "..", "deps", "versioninfo.jl") - +const depsfile = joinpath(dirname(@__DIR__), "deps", "deps.jl") if isfile(depsfile) include(depsfile) else - error("ImageMagick not properly installed. Please run Pkg.build(\"ImageMagick\") then restart Julia.") # now that this is decoupled from images, should this be an error? -end -if isfile(versionfile) - include(versionfile) -end + error("ImageMagick not properly installed. Please run Pkg.build(\"ImageMagick\") then restart Julia.") +end + +const libmagick = Ref{Ptr{Void}}() + +const MagickWandGenesis = Ref{Ptr{Void}}() +const MagickWandTerminus = Ref{Ptr{Void}}() +const NewMagickWand = Ref{Ptr{Void}}() +const DestroyMagickWand = Ref{Ptr{Void}}() +const NewPixelWand = Ref{Ptr{Void}}() +const DestroyPixelWand = Ref{Ptr{Void}}() +const MagickGetException = Ref{Ptr{Void}}() +const PixelGetException = Ref{Ptr{Void}}() +const MagickExportImagePixels = Ref{Ptr{Void}}() +const MagickImportImagePixels = Ref{Ptr{Void}}() +const MagickConstituteImage = Ref{Ptr{Void}}() +const MagickSetImageDepth = Ref{Ptr{Void}}() +const MagickGetImagesBlob = Ref{Ptr{Void}}() +const MagickPingImage = Ref{Ptr{Void}}() +const MagickReadImage = Ref{Ptr{Void}}() +const MagickReadImageFile = Ref{Ptr{Void}}() +const MagickReadImageBlob = Ref{Ptr{Void}}() +const MagickWriteImages = Ref{Ptr{Void}}() +const MagickWriteImagesFile = Ref{Ptr{Void}}() +const MagickGetImageHeight = Ref{Ptr{Void}}() +const MagickGetImageWidth = Ref{Ptr{Void}}() +const MagickGetNumberImages = Ref{Ptr{Void}}() +const MagickNextImage = Ref{Ptr{Void}}() +const MagickResetIterator = Ref{Ptr{Void}}() +const MagickNewImage = Ref{Ptr{Void}}() +const MagickGetImageAlphaChannel = Ref{Ptr{Void}}() +const MagickGetImageProperties = Ref{Ptr{Void}}() +const MagickGetImageProperty = Ref{Ptr{Void}}() +const MagickGetImageColors = Ref{Ptr{Void}}() +const MagickGetImageType = Ref{Ptr{Void}}() +const MagickSetImageType = Ref{Ptr{Void}}() +const MagickGetImageColorspace = Ref{Ptr{Void}}() +const MagickSetImageColorspace = Ref{Ptr{Void}}() +const MagickSetImageCompression = Ref{Ptr{Void}}() +const MagickSetImageCompressionQuality = Ref{Ptr{Void}}() +const MagickGetImageTicksPerSecond = Ref{Ptr{Void}}() +const MagickGetImageDelay = Ref{Ptr{Void}}() +const MagickSetImageDelay = Ref{Ptr{Void}}() +const MagickSetImageFormat = Ref{Ptr{Void}}() +const MagickGetImageDepth = Ref{Ptr{Void}}() +const MagickGetImageChannelDepth = Ref{Ptr{Void}}() +const PixelSetColor = Ref{Ptr{Void}}() +const MagickRelinquishMemory = Ref{Ptr{Void}}() +const MagickQueryConfigureOption = Ref{Ptr{Void}}() +const MagickQueryConfigureOptions = Ref{Ptr{Void}}() + +magickgenesis() = ccall(MagickWandGenesis[], Void, ()) +magickterminus() = ccall(MagickWandTerminus[], Void, ()) + +loadsym(cfun::Symbol) = Libdl.dlsym(libmagick[], cfun) + +getlibversion() = VersionNumber(join(split(queryoption("LIB_VERSION_NUMBER"), ',')[1:3], '.')) -const have_imagemagick = isdefined(:libwand) - -# Initialize the library function __init__() - init_deps() - !have_imagemagick && warn("ImageMagick utilities not found. Install for more file format support.") + isdefined(ImageMagick, :initenv) && initenv() + + libmagick[] = Libdl.dlopen(libwand, Libdl.RTLD_GLOBAL) + + MagickWandGenesis[] = loadsym(:MagickWandGenesis) + MagickWandTerminus[] = loadsym(:MagickWandTerminus) + NewMagickWand[] = loadsym(:NewMagickWand) + DestroyMagickWand[] = loadsym(:DestroyMagickWand) + NewPixelWand[] = loadsym(:NewPixelWand) + DestroyPixelWand[] = loadsym(:DestroyPixelWand) + MagickGetException[] = loadsym(:MagickGetException) + PixelGetException[] = loadsym(:PixelGetException) + MagickExportImagePixels[] = loadsym(:MagickExportImagePixels) + MagickImportImagePixels[] = loadsym(:MagickImportImagePixels) + MagickConstituteImage[] = loadsym(:MagickConstituteImage) + MagickSetImageDepth[] = loadsym(:MagickSetImageDepth) + MagickGetImagesBlob[] = loadsym(:MagickGetImagesBlob) + MagickPingImage[] = loadsym(:MagickPingImage) + MagickReadImage[] = loadsym(:MagickReadImage) + MagickReadImageFile[] = loadsym(:MagickReadImageFile) + MagickReadImageBlob[] = loadsym(:MagickReadImageBlob) + MagickWriteImages[] = loadsym(:MagickWriteImages) + MagickWriteImagesFile[] = loadsym(:MagickWriteImagesFile) + MagickGetImageHeight[] = loadsym(:MagickGetImageHeight) + MagickGetImageWidth[] = loadsym(:MagickGetImageWidth) + MagickGetNumberImages[] = loadsym(:MagickGetNumberImages) + MagickNextImage[] = loadsym(:MagickNextImage) + MagickResetIterator[] = loadsym(:MagickResetIterator) + MagickNewImage[] = loadsym(:MagickNewImage) + MagickGetImageAlphaChannel[] = loadsym(:MagickGetImageAlphaChannel) + MagickGetImageProperties[] = loadsym(:MagickGetImageProperties) + MagickGetImageProperty[] = loadsym(:MagickGetImageProperty) + MagickGetImageColors[] = loadsym(:MagickGetImageColors) + MagickGetImageType[] = loadsym(:MagickGetImageType) + MagickSetImageType[] = loadsym(:MagickSetImageType) + MagickGetImageColorspace[] = loadsym(:MagickGetImageColorspace) + MagickSetImageColorspace[] = loadsym(:MagickSetImageColorspace) + MagickSetImageCompression[] = loadsym(:MagickSetImageCompression) + MagickSetImageCompressionQuality[] = loadsym(:MagickSetImageCompressionQuality) + MagickGetImageTicksPerSecond[] = loadsym(:MagickGetImageTicksPerSecond) + MagickGetImageDelay[] = loadsym(:MagickGetImageDelay) + MagickSetImageDelay[] = loadsym(:MagickSetImageDelay) + MagickSetImageFormat[] = loadsym(:MagickSetImageFormat) + MagickGetImageDepth[] = loadsym(:MagickGetImageDepth) + MagickGetImageChannelDepth[] = loadsym(:MagickGetImageChannelDepth) + PixelSetColor[] = loadsym(:PixelSetColor) + MagickRelinquishMemory[] = loadsym(:MagickRelinquishMemory) + MagickQueryConfigureOptions[] = loadsym(:MagickQueryConfigureOptions) + MagickQueryConfigureOption[] = loadsym(:MagickQueryConfigureOption) + + magickgenesis() + + global libversion = getlibversion() end - - # Constants # Storage types -const CHARPIXEL = 1 -const DOUBLEPIXEL = 2 -const FLOATPIXEL = 3 +const CHARPIXEL = 1 +const DOUBLEPIXEL = 2 +const FLOATPIXEL = 3 const INTEGERPIXEL = 4 -const SHORTPIXEL = 7 -IMStorageTypes = Union{UInt8, UInt16, UInt32, Float32, Float64} -storagetype(::Type{UInt8}) = CHARPIXEL -storagetype(::Type{UInt16}) = SHORTPIXEL -storagetype(::Type{UInt32}) = INTEGERPIXEL +const SHORTPIXEL = 7 +const 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<:Normed}(::Type{T}) = storagetype(FixedPointNumbers.rawtype(T)) @@ -61,26 +156,26 @@ storagetype{CV<:Colorant}(::Type{CV}) = storagetype(eltype(CV)) type ChannelType value::UInt32 end -const UndefinedChannel = ChannelType(0x00000000) -const RedChannel = ChannelType(0x00000001) -const GrayChannel = ChannelType(0x00000001) -const CyanChannel = ChannelType(0x00000001) -const GreenChannel = ChannelType(0x00000002) -const MagentaChannel = ChannelType(0x00000002) -const BlueChannel = ChannelType(0x00000004) -const YellowChannel = ChannelType(0x00000004) -const AlphaChannel = ChannelType(0x00000008) -const MatteChannel = ChannelType(0x00000008) -const OpacityChannel = ChannelType(0x00000008) -const BlackChannel = ChannelType(0x00000020) -const IndexChannel = ChannelType(0x00000020) +const UndefinedChannel = ChannelType(0x00000000) +const RedChannel = ChannelType(0x00000001) +const GrayChannel = ChannelType(0x00000001) +const CyanChannel = ChannelType(0x00000001) +const GreenChannel = ChannelType(0x00000002) +const MagentaChannel = ChannelType(0x00000002) +const BlueChannel = ChannelType(0x00000004) +const YellowChannel = ChannelType(0x00000004) +const AlphaChannel = ChannelType(0x00000008) +const MatteChannel = ChannelType(0x00000008) +const OpacityChannel = ChannelType(0x00000008) +const BlackChannel = ChannelType(0x00000020) +const IndexChannel = ChannelType(0x00000020) const CompositeChannels = ChannelType(0x0000002F) -const TrueAlphaChannel = ChannelType(0x00000040) -const RGBChannels = ChannelType(0x00000080) -const GrayChannels = ChannelType(0x00000080) -const SyncChannels = ChannelType(0x00000100) -const AllChannels = ChannelType(0x7fffffff) -const DefaultChannels = ChannelType( (AllChannels.value | SyncChannels.value) &~ OpacityChannel.value ) +const TrueAlphaChannel = ChannelType(0x00000040) +const RGBChannels = ChannelType(0x00000080) +const GrayChannels = ChannelType(0x00000080) +const SyncChannels = ChannelType(0x00000100) +const AllChannels = ChannelType(0x7fffffff) +const DefaultChannels = ChannelType((AllChannels.value | SyncChannels.value) & ~OpacityChannel.value) # Image type @@ -109,15 +204,15 @@ function flip12(A) end pd(A) = permutedims(A, [2;1;3:ndims(A)]) -orientation_dict = Dict(nothing => pd, - "1" => pd, - "2" => A->pd(flip1(A)), - "3" => A->pd(flip12(A)), - "4" => A->pd(flip2(A)), - "5" => identity, - "6" => flip2, - "7" => flip12, - "8" => flip1) +const orientation_dict = Dict(nothing => pd, + "1" => pd, + "2" => A->pd(flip1(A)), + "3" => A->pd(flip12(A)), + "4" => A->pd(flip2(A)), + "5" => identity, + "6" => flip2, + "7" => flip12, + "8" => flip1) function nchannels(imtype::AbstractString, cs::AbstractString, havealpha = false) n = 3 @@ -141,7 +236,7 @@ type MagickWand ptr::Ptr{Void} function MagickWand() - ptr = ccall((:NewMagickWand, libwand), Ptr{Void}, ()) + ptr = ccall(NewMagickWand[], Ptr{Void}, ()) ptr == C_NULL && throw(OutOfMemoryError()) obj = new(ptr) finalizer(obj, free) @@ -158,7 +253,7 @@ end function free(wand::MagickWand) ptr = wand.ptr if ptr != C_NULL - ccall((:DestroyMagickWand, libwand), Ptr{Void}, (Ptr{Void},), ptr) + ccall(DestroyMagickWand[], Ptr{Void}, (Ptr{Void},), ptr) end wand.ptr = C_NULL nothing @@ -168,7 +263,7 @@ type PixelWand ptr::Ptr{Void} function PixelWand() - ptr = ccall((:NewPixelWand, libwand), Ptr{Void}, ()) + ptr = ccall(NewPixelWand[], Ptr{Void}, ()) ptr == C_NULL && throw(OutOfMemoryError()) obj = new(ptr) finalizer(obj, free) @@ -185,7 +280,7 @@ end function free(wand::PixelWand) ptr = wand.ptr if ptr != C_NULL - ccall((:DestroyPixelWand, libwand), Ptr{Void}, (Ptr{Void},), ptr) + ccall(DestroyPixelWand[], Ptr{Void}, (Ptr{Void},), ptr) end wand.ptr = C_NULL nothing @@ -193,13 +288,13 @@ end const IMExceptionType = Ref{Cint}() function error(wand::MagickWand) - pMsg = ccall((:MagickGetException, libwand), Ptr{UInt8}, (Ptr{Void}, Ptr{Cint}), wand, IMExceptionType) + pMsg = ccall(MagickGetException[], Ptr{UInt8}, (Ptr{Void}, Ptr{Cint}), wand, IMExceptionType) msg = unsafe_string(pMsg) relinquishmemory(pMsg) error(msg) end function error(wand::PixelWand) - pMsg = ccall((:PixelGetException, libwand), Ptr{UInt8}, (Ptr{Void}, Ptr{Cint}), wand, IMExceptionType) + pMsg = ccall(PixelGetException[], Ptr{UInt8}, (Ptr{Void}, Ptr{Cint}), wand, IMExceptionType) msg = unsafe_string(pMsg) relinquishmemory(pMsg) error(msg) @@ -227,7 +322,7 @@ function exportimagepixels!{T<:Unsigned}(buffer::AbstractArray{T}, wand::MagickW p = pointer(buffer) for i = 1:nimages nextimage(wand) - status = ccall((:MagickExportImagePixels, libwand), Cint, (Ptr{Void}, Cssize_t, Cssize_t, Csize_t, Csize_t, Ptr{UInt8}, Cint, Ptr{Void}), wand, x, y, cols, rows, channelorder, storagetype(T), p) + status = ccall(MagickExportImagePixels[], Cint, (Ptr{Void}, Cssize_t, Cssize_t, Csize_t, Csize_t, Ptr{UInt8}, Cint, Ptr{Void}), wand, x, y, cols, rows, channelorder, storagetype(T), p) status == 0 && error(wand) p += sizeof(T)*cols*rows*ncolors end @@ -236,7 +331,7 @@ end # function importimagepixels{T}(buffer::AbstractArray{T}, wand::MagickWand, colorspace::String; x = 0, y = 0) # cols, rows = getsize(buffer, colorspace) -# status = ccall((:MagickImportImagePixels, libwand), Cint, (Ptr{Void}, Cssize_t, Cssize_t, Csize_t, Csize_t, Ptr{UInt8}, Cint, Ptr{Void}), wand, x, y, cols, rows, channelorder[colorspace], storagetype(T), buffer) +# status = ccall(MagickImportImagePixels[], Cint, (Ptr{Void}, Cssize_t, Cssize_t, Csize_t, Csize_t, Ptr{UInt8}, Cint, Ptr{Void}), wand, x, y, cols, rows, channelorder[colorspace], storagetype(T), buffer) # status == 0 && error(wand) # nothing # end @@ -247,11 +342,11 @@ function constituteimage{T<:Unsigned}(buffer::AbstractArray{T}, wand::MagickWand p = pointer(buffer) depth = bitdepth(buffer) for i = 1:nimages - status = ccall((:MagickConstituteImage, libwand), Cint, (Ptr{Void}, Cssize_t, Cssize_t, Ptr{UInt8}, Cint, Ptr{Void}), wand, cols, rows, channelorder, storagetype(T), p) + status = ccall(MagickConstituteImage[], Cint, (Ptr{Void}, Cssize_t, Cssize_t, Ptr{UInt8}, Cint, Ptr{Void}), wand, cols, rows, channelorder, storagetype(T), p) status == 0 && error(wand) setimagecolorspace(wand, colorspace) setimagetype(wand, buffer, channelorder) - status = ccall((:MagickSetImageDepth, libwand), Cint, (Ptr{Void}, Csize_t), wand, depth) + status = ccall(MagickSetImageDepth[], Cint, (Ptr{Void}, Csize_t), wand, depth) status == 0 && error(wand) p += sizeof(T)*cols*rows*ncolors end @@ -261,69 +356,69 @@ end function getblob(wand::MagickWand, format::AbstractString) setimageformat(wand, format) len = Ref{Csize_t}(1) - ptr = ccall((:MagickGetImagesBlob, libwand), Ptr{UInt8}, (Ptr{Void}, Ptr{Csize_t}), wand, len) + ptr = ccall(MagickGetImagesBlob[], Ptr{UInt8}, (Ptr{Void}, Ptr{Csize_t}), wand, len) blob = unsafe_wrap(Array, ptr, convert(Int, len[])) finalizer(blob, relinquishmemory) blob end function pingimage(wand::MagickWand, filename::AbstractString) - status = ccall((:MagickPingImage, libwand), Cint, (Ptr{Void}, Ptr{UInt8}), wand, filename) + status = ccall(MagickPingImage[], Cint, (Ptr{Void}, Ptr{UInt8}), wand, filename) status == 0 && error(wand) nothing end function readimage(wand::MagickWand, filename::AbstractString) - status = ccall((:MagickReadImage, libwand), Cint, (Ptr{Void}, Ptr{UInt8}), wand, filename) + status = ccall(MagickReadImage[], Cint, (Ptr{Void}, Ptr{UInt8}), wand, filename) status == 0 && error(wand) nothing end function readimage(wand::MagickWand, stream::IO) - status = ccall((:MagickReadImageFile, libwand), Cint, (Ptr{Void}, Ptr{Void}), wand, Libc.FILE(stream).ptr) + status = ccall(MagickReadImageFile[], Cint, (Ptr{Void}, Ptr{Void}), wand, Libc.FILE(stream).ptr) status == 0 && error(wand) nothing end function readimage(wand::MagickWand, stream::Vector{UInt8}) - status = ccall((:MagickReadImageBlob, libwand), Cint, (Ptr{Void}, Ptr{Void}, Cint), wand, stream, length(stream)*sizeof(eltype(stream))) + status = ccall(MagickReadImageBlob[], Cint, (Ptr{Void}, Ptr{Void}, Cint), wand, stream, length(stream)*sizeof(eltype(stream))) status == 0 && error(wand) nothing end function writeimage(wand::MagickWand, filename::AbstractString) - status = ccall((:MagickWriteImages, libwand), Cint, (Ptr{Void}, Ptr{UInt8}, Cint), wand, filename, true) + status = ccall(MagickWriteImages[], Cint, (Ptr{Void}, Ptr{UInt8}, Cint), wand, filename, true) status == 0 && error(wand) nothing end function writeimage(wand::MagickWand, stream::IO) - status = ccall((:MagickWriteImagesFile, libwand), Cint, (Ptr{Void}, Ptr{Void}), wand, Libc.FILE(stream).ptr) + status = ccall(MagickWriteImagesFile[], Cint, (Ptr{Void}, Ptr{Void}), wand, Libc.FILE(stream).ptr) status == 0 && error(wand) nothing end function size(wand::MagickWand) - height = ccall((:MagickGetImageHeight, libwand), Csize_t, (Ptr{Void},), wand) - width = ccall((:MagickGetImageWidth, libwand), Csize_t, (Ptr{Void},), wand) + height = ccall(MagickGetImageHeight[], Csize_t, (Ptr{Void},), wand) + width = ccall(MagickGetImageWidth[], Csize_t, (Ptr{Void},), wand) return convert(Int, width), convert(Int, height) end -getnumberimages(wand::MagickWand) = convert(Int, ccall((:MagickGetNumberImages, libwand), Csize_t, (Ptr{Void},), wand)) +getnumberimages(wand::MagickWand) = convert(Int, ccall(MagickGetNumberImages[], Csize_t, (Ptr{Void},), wand)) -nextimage(wand::MagickWand) = ccall((:MagickNextImage, libwand), Cint, (Ptr{Void},), wand) == 1 +nextimage(wand::MagickWand) = ccall(MagickNextImage[], Cint, (Ptr{Void},), wand) == 1 -resetiterator(wand::MagickWand) = ccall((:MagickResetIterator, libwand), Void, (Ptr{Void},), wand) +resetiterator(wand::MagickWand) = ccall(MagickResetIterator[], Void, (Ptr{Void},), wand) -newimage(wand::MagickWand, cols::Integer, rows::Integer, pw::PixelWand) = ccall((:MagickNewImage, libwand), Cint, (Ptr{Void}, Csize_t, Csize_t, Ptr{Void}), wand, cols, rows, pw.ptr) == 0 && error(wand) +newimage(wand::MagickWand, cols::Integer, rows::Integer, pw::PixelWand) = ccall(MagickNewImage[], Cint, (Ptr{Void}, Csize_t, Csize_t, Ptr{Void}), wand, cols, rows, pw.ptr) == 0 && error(wand) # test whether image has an alpha channel -getimagealphachannel(wand::MagickWand) = ccall((:MagickGetImageAlphaChannel, libwand), Cint, (Ptr{Void},), wand) == 1 +getimagealphachannel(wand::MagickWand) = ccall(MagickGetImageAlphaChannel[], Cint, (Ptr{Void},), wand) == 1 function getimageproperties(wand::MagickWand,patt::AbstractString) numbProp = Ref{Csize_t}(0) - p = ccall((:MagickGetImageProperties, libwand), Ptr{Ptr{UInt8}}, (Ptr{Void}, Ptr{UInt8}, Ptr{Csize_t}), wand, patt, numbProp) + p = ccall(MagickGetImageProperties[], Ptr{Ptr{UInt8}}, (Ptr{Void}, Ptr{UInt8}, Ptr{Csize_t}), wand, patt, numbProp) if p == C_NULL error("Pattern not in property names") else @@ -337,7 +432,7 @@ function getimageproperties(wand::MagickWand,patt::AbstractString) end function getimageproperty(wand::MagickWand, prop::AbstractString, warnuser::Bool=true) - p = ccall((:MagickGetImageProperty, libwand), Ptr{UInt8}, (Ptr{Void}, Ptr{UInt8}), wand, prop) + p = ccall(MagickGetImageProperty[], Ptr{UInt8}, (Ptr{Void}, Ptr{UInt8}), wand, prop) if p == convert(Ptr{UInt8}, C_NULL) if warnuser possib = getimageproperties(wand,"*") @@ -350,26 +445,26 @@ function getimageproperty(wand::MagickWand, prop::AbstractString, warnuser::Bool end # # get number of colors in the image -# magickgetimagecolors(wand::MagickWand) = ccall((:MagickGetImageColors, libwand), Csize_t, (Ptr{Void},), wand) +# magickgetimagecolors(wand::MagickWand) = ccall(MagickGetImageColors[], Csize_t, (Ptr{Void},), wand) # get the type function getimagetype(wand::MagickWand) - t = ccall((:MagickGetImageType, libwand), Cint, (Ptr{Void},), wand) + t = ccall(MagickGetImageType[], Cint, (Ptr{Void},), wand) # Apparently the following is necessary, because the type is "potential" - ccall((:MagickSetImageType, libwand), Void, (Ptr{Void}, Cint), wand, t) + ccall(MagickSetImageType[], Void, (Ptr{Void}, Cint), wand, t) 1 <= t <= length(IMType) || error("Image type ", t, " not recognized") IMType[t] end # get the colorspace function getimagecolorspace(wand::MagickWand) - cs = ccall((:MagickGetImageColorspace, libwand), Cint, (Ptr{Void},), wand) + cs = ccall(MagickGetImageColorspace[], Cint, (Ptr{Void},), wand) 1 <= cs <= length(IMColorspace) || error("Colorspace ", cs, " not recognized") IMColorspace[cs] end function setimagecolorspace(wand::MagickWand, cs::String) - status = ccall((:MagickSetImageColorspace, libwand), Cint, (Ptr{Void}, Cint), wand, IMColordict[cs]) + status = ccall(MagickSetImageColorspace[], Cint, (Ptr{Void}, Cint), wand, IMColordict[cs]) status == 0 && error(wand) nothing end @@ -378,39 +473,39 @@ imtype(buffer, cs) = IMTypedict[CStoIMTypedict[cs]] imtype(buffer::AbstractArray{Bool}, cs) = IMTypedict["BilevelType"] function setimagetype(wand::MagickWand, buffer, cs::String) - status = ccall((:MagickSetImageType, libwand), Cint, (Ptr{Void}, Cint), wand, imtype(buffer, cs)) + status = ccall(MagickSetImageType[], Cint, (Ptr{Void}, Cint), wand, imtype(buffer, cs)) status == 0 && error(wand) nothing end # set the compression function setimagecompression(wand::MagickWand, compression::Integer) - status = ccall((:MagickSetImageCompression, libwand), Cint, (Ptr{Void}, Cint), wand, Int32(compression)) + status = ccall(MagickSetImageCompression[], Cint, (Ptr{Void}, Cint), wand, Int32(compression)) status == 0 && error(wand) nothing end function setimagecompressionquality(wand::MagickWand, quality::Integer) 0 < quality <= 100 || error("quality setting must be in the (inclusive) range 1-100.\nSee http://www.imagemagick.org/script/command-line-options.php#quality for details") - status = ccall((:MagickSetImageCompressionQuality, libwand), Cint, (Ptr{Void}, Cint), wand, quality) + status = ccall(MagickSetImageCompressionQuality[], Cint, (Ptr{Void}, Cint), wand, quality) status == 0 && error(wand) nothing end # set fps (for GIF-type images) function getimagetickspersecond(wand::MagickWand) - ccall((:MagickGetImageTicksPerSecond, libwand), Cint, (Ptr{Void},), wand) + ccall(MagickGetImageTicksPerSecond[], Cint, (Ptr{Void},), wand) end function getimagedelay(wand::MagickWand) - ccall((:MagickGetImageDelay, libwand), Cint, (Ptr{Void},), wand) + ccall(MagickGetImageDelay[], Cint, (Ptr{Void},), wand) end function setimagedelay(wand::MagickWand, fps) tps = getimagetickspersecond(wand) delay = round(Int, tps/fps) for i = 1:getnumberimages(wand)+1 # not clear why +1 - status = ccall((:MagickSetImageDelay, libwand), Cint, (Ptr{Void}, Csize_t), wand, delay) + status = ccall(MagickSetImageDelay[], Cint, (Ptr{Void}, Csize_t), wand, delay) status == 0 && error(wand) nextimage(wand) end @@ -420,26 +515,26 @@ end # set the image format function setimageformat(wand::MagickWand, format::String) - status = ccall((:MagickSetImageFormat, libwand), Cint, (Ptr{Void}, Ptr{UInt8}), wand, format) + status = ccall(MagickSetImageFormat[], Cint, (Ptr{Void}, Ptr{UInt8}), wand, format) status == 0 && error(wand) nothing end # get the pixel depth -getimagedepth(wand::MagickWand) = convert(Int, ccall((:MagickGetImageDepth, libwand), Csize_t, (Ptr{Void},), wand)) +getimagedepth(wand::MagickWand) = convert(Int, ccall(MagickGetImageDepth[], Csize_t, (Ptr{Void},), wand)) # pixel depth for given channel type -getimagechanneldepth(wand::MagickWand, channelType::ChannelType) = convert(Int, ccall((:MagickGetImageChannelDepth, libwand), Csize_t, (Ptr{Void}, UInt32), wand, channelType.value)) +getimagechanneldepth(wand::MagickWand, channelType::ChannelType) = convert(Int, ccall(MagickGetImageChannelDepth[], Csize_t, (Ptr{Void}, UInt32), wand, channelType.value)) -pixelsetcolor(wand::PixelWand, colorstr::String) = ccall((:PixelSetColor, libwand), Csize_t, (Ptr{Void}, Ptr{UInt8}), wand, colorstr) == 0 && error(wand) +pixelsetcolor(wand::PixelWand, colorstr::String) = ccall(PixelSetColor[], Csize_t, (Ptr{Void}, Ptr{UInt8}), wand, colorstr) == 0 && error(wand) -relinquishmemory(p) = ccall((:MagickRelinquishMemory, libwand), Ptr{UInt8}, (Ptr{UInt8},), p) +relinquishmemory(p) = ccall(MagickRelinquishMemory[], Ptr{UInt8}, (Ptr{UInt8},), p) # get library information # If you pass in "*", you get the full list of options function queryoptions(pattern::AbstractString) - nops = Ref{Cint}(0) - pops = ccall((:MagickQueryConfigureOptions, libwand), Ptr{Ptr{UInt8}}, (Ptr{UInt8}, Ptr{Cint}), pattern, nops) + nops = Ref{Cint}() + pops = ccall(MagickQueryConfigureOptions[], Ptr{Ptr{UInt8}}, (Ptr{UInt8}, Ptr{Cint}), pattern, nops) ret = Vector{String}(nops[]) for i = 1:nops[] ret[i] = unsafe_string(unsafe_load(pops, i)) @@ -449,6 +544,6 @@ end # queries the value of a particular option function queryoption(option::AbstractString) - p = ccall((:MagickQueryConfigureOption, libwand), Ptr{UInt8}, (Ptr{UInt8},), option) + p = ccall(MagickQueryConfigureOption[], Ptr{UInt8}, (Ptr{UInt8},), option) unsafe_string(p) end diff --git a/test/constructed_images.jl b/test/constructed_images.jl index 11bfb69..44986e9 100644 --- a/test/constructed_images.jl +++ b/test/constructed_images.jl @@ -94,7 +94,11 @@ type TestType end @testset "Colormap usage" begin datafloat = reshape(linspace(0.5, 1.5, 6), 2, 3) - dataint = round(UInt8, 254*(datafloat .- 0.5) .+ 1) # ranges from 1 to 255 + if VERSION < v"0.6-" + dataint = round(UInt8, 254*(datafloat .- 0.5) .+ 1) # ranges from 1 to 255 + else + dataint = round.(UInt8, 254*(datafloat .- 0.5) .+ 1) # ranges from 1 to 255 + end # build our colormap b = RGB(0,0,1) w = RGB(1,1,1)