Skip to content

Commit 7da378d

Browse files
committed
Merge pull request #38 from JuliaIO/teh/ambiguous_formats
Choose a default for ambiguous formats
2 parents fd6e1e8 + 578414a commit 7da378d

File tree

7 files changed

+55
-19
lines changed

7 files changed

+55
-19
lines changed

.travis.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ notifications:
99
email: false
1010
script:
1111
- if [[ -a .git/shallow ]]; then git fetch --unshallow; fi
12+
- julia -e 'Pkg.clone("https://github.com/JuliaIO/Netpbm.jl.git")'
1213
- julia -e 'Pkg.clone(pwd()); Pkg.build("FileIO"); Pkg.test("FileIO"; coverage=true)'
1314
after_success:
1415
- julia -e 'cd(Pkg.dir("FileIO")); Pkg.add("Coverage"); using Coverage; Coveralls.submit(process_folder()); Codecov.submit(process_folder())'

src/FileIO.jl

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,19 @@ function save(s::@compat(Union{AbstractString,IO}), data...; options...)
8686
rethrow(last_exception)
8787
end
8888

89+
# Forced format
90+
function save{sym}(::Type{DataFormat{sym}}, f::AbstractString, data...; options...)
91+
libraries = sym2saver[sym]
92+
check_saver(libraries[1])
93+
save(File(DataFormat{sym}, f), data...; options...)
94+
end
95+
96+
function save{sym}(::Type{DataFormat{sym}}, s::IO, data...; options...)
97+
libraries = sym2saver[sym]
98+
check_saver(libraries[1])
99+
save(Stream(DataFormat{sym}, s), data...; options...)
100+
end
101+
89102
function Base.writemime(io::IO, mime::MIME, x)
90103
handlers = applicable_mime(mime)
91104
last_exception = ErrorException("No package available to writemime $mime")
@@ -102,7 +115,7 @@ function Base.writemime(io::IO, mime::MIME, x)
102115
end
103116

104117
# Fallbacks
105-
load{F}(f::Formatted{F}; options...) = error("No load function defined for format ", F, " with filename ", filename(f))
118+
load{F}(f::Formatted{F}, args...; options...) = error("No load function defined for format ", F, " with filename ", filename(f))
106119
save{F}(f::Formatted{F}, data...; options...) = error("No save function defined for format ", F, " with filename ", filename(f))
107120

108121
end # module

src/query.jl

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
### Format registry infrastructure
2-
abstract OS
3-
abstract Unix <: OS
2+
abstract OS
3+
abstract Unix <: OS
44
immutable Windows <: OS end
55
immutable OSX <: Unix end
66
immutable Linux <: Unix end
@@ -352,7 +352,7 @@ function query(filename::AbstractString)
352352
if lensym(sym) == 1 && (no_magic || !isfile(filename)) # we only found one candidate and there is no magic bytes, or no file, trust the extension
353353
return File{DataFormat{sym}}(filename)
354354
elseif !isfile(filename) && lensym(sym) > 1
355-
error("no file for check of magic bytes and multiple extensions possible: $sym")
355+
return File{DataFormat{sym[1]}}(filename)
356356
end
357357
if no_magic && !hasfunction(sym)
358358
error("Some formats with extension ", ext, " have no magic bytes; use `File{format\"FMT\"}(filename)` to resolve the ambiguity.")
@@ -424,7 +424,7 @@ function iter_eq(A, B)
424424
a=A[i]; b=B[j]
425425
a == b && (i+=1; j+=1; continue)
426426
a == '\r' && (i+=1; continue) # this seems like the shadiest solution to deal with windows \r\n
427-
b == '\r' && (j+=1; continue)
427+
b == '\r' && (j+=1; continue)
428428
return false #now both must be unequal, and no \r windows excemption any more
429429
end
430430
true

src/registry.jl

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2,12 +2,12 @@
22
add_format(format"JLD", "Julia data file (HDF5)", ".jld", [:JLD])
33

44
# Image formats
5-
add_format(format"PBMText", b"P1", ".pbm")
6-
add_format(format"PGMText", b"P2", ".pgm")
7-
add_format(format"PPMText", b"P3", ".ppm")
8-
add_format(format"PBMBinary", b"P4", ".pbm")
9-
add_format(format"PGMBinary", b"P5", ".pgm")
10-
add_format(format"PPMBinary", b"P6", ".ppm")
5+
add_format(format"PBMBinary", b"P4", ".pbm", [:ImageMagick])
6+
add_format(format"PGMBinary", b"P5", ".pgm", [:Netpbm])
7+
add_format(format"PPMBinary", b"P6", ".ppm", [:Netpbm])
8+
add_format(format"PBMText", b"P1", ".pbm", [:ImageMagick, LOAD])
9+
add_format(format"PGMText", b"P2", ".pgm", [:ImageMagick, LOAD])
10+
add_format(format"PPMText", b"P3", ".ppm", [:ImageMagick, LOAD])
1111

1212
add_format(format"NRRD", "NRRD", [".nrrd", ".nhdr"], [:NRRD])
1313

test/REQUIRE

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1 +1,4 @@
11
FactCheck
2+
Images
3+
Netpbm
4+
ImageMagick

test/loadsave.jl

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -115,3 +115,23 @@ context("Save") do
115115
end
116116

117117
del_format(format"DUMMY")
118+
119+
# PPM/PBM can be either binary or text. Test that the defaults work,
120+
# and that we can force a choice.
121+
using Images
122+
context("Ambiguous extension") do
123+
A = rand(UInt8, 3, 2)
124+
fn = string(tempname(), ".pgm")
125+
# Test the forced version first: we wouldn't want some method in Netpbm
126+
# coming to the rescue here, we want to rely on FileIO's logic.
127+
# `save(fn, A)` will load Netpbm, which could conceivably mask a failure
128+
# in the next line.
129+
save(format"PGMBinary", fn, A)
130+
B = load(fn)
131+
@fact raw(convert(Array, B)) --> A
132+
save(fn, A)
133+
B = load(fn)
134+
@fact raw(convert(Array, B)) --> A
135+
136+
rm(fn)
137+
end

test/query.jl

Lines changed: 7 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -148,7 +148,6 @@ try
148148
add_format(format"DOUBLE_1", "test1", ".double")
149149
add_format(format"DOUBLE_2", "test2", ".double")
150150

151-
@fact_throws ErrorException query( "test.double")
152151
fn = string(tempname(), ".double")
153152
open(fn, "w") do file
154153
write(file, "test1")
@@ -209,10 +208,10 @@ try
209208
lenload0 = length(FileIO.sym2loader)
210209
OSKey = @osx ? FileIO.OSX : @windows? FileIO.Windows : @linux ? FileIO.Linux : error("os not supported")
211210
add_format(
212-
format"MultiLib",
211+
format"MultiLib",
213212
UInt8[0x42,0x4d],
214213
".mlb",
215-
[:LoadTest1, FileIO.LOAD, OSKey],
214+
[:LoadTest1, FileIO.LOAD, OSKey],
216215
[:LoadTest2]
217216
)
218217
@fact lensave0 + 1 --> length(FileIO.sym2saver)
@@ -243,25 +242,25 @@ finally
243242
end
244243

245244
file_dir = joinpath(dirname(@__FILE__), "files")
246-
context("STL detection") do
245+
context("STL detection") do
247246
q = query(joinpath(file_dir, "ascii.stl"))
248247
@fact typeof(q) --> File{format"STL_ASCII"}
249248
q = query(joinpath(file_dir, "binary_stl_from_solidworks.STL"))
250249
@fact typeof(q) --> File{format"STL_BINARY"}
251-
open(q) do io
250+
open(q) do io
252251
@fact position(io) --> 0
253252
skipmagic(io)
254253
@fact position(io) --> 0 # no skipping for functions
255254
end
256255
end
257-
context("PLY detection") do
256+
context("PLY detection") do
258257
q = query(joinpath(file_dir, "ascii.ply"))
259258
@fact typeof(q) --> File{format"PLY_ASCII"}
260259
q = query(joinpath(file_dir, "binary.ply"))
261260
@fact typeof(q) --> File{format"PLY_BINARY"}
262261

263262
end
264-
context("Multiple Magic bytes") do
263+
context("Multiple Magic bytes") do
265264
q = query(joinpath(file_dir, "magic1.tiff"))
266265
@fact typeof(q) --> File{format"TIFF"}
267266
q = query(joinpath(file_dir, "magic2.tiff"))
@@ -271,4 +270,4 @@ context("Multiple Magic bytes") do
271270
skipmagic(io)
272271
@fact position(io) --> 4
273272
end
274-
end
273+
end

0 commit comments

Comments
 (0)