tlnagy / TiffImages.jl

💎 Pure-Julia TIFF I/O with a focus on correctness 🧐
http://tamasnagy.com/TiffImages.jl/
MIT License
53 stars 13 forks source link

MethodError: no method matching interpretation(::Val{TiffImages.PHOTOMETRIC_MINISWHITE}), Float32 support #133

Open mkitti opened 9 months ago

mkitti commented 9 months ago

xref: https://discourse.julialang.org/t/problem-in-reading-tiff-floats-file/106610/4

The primary problem is that interpretation(::Val{TiffImages.PHOTOMETRIC_MINISWHITE}) is not implemented.

ERROR: MethodError: no method matching interpretation(::Val{TiffImages.PHOTOMETRIC_MINISWHITE})

Closest candidates are:
  interpretation(::TiffImages.PhotometricInterpretations, ::Val{TiffImages.EXTRASAMPLE_UNSPECIFIED}, ::Val{4})
   @ TiffImages ~/.julia/packages/TiffImages/yETMK/src/layout.jl:63
  interpretation(::TiffImages.PhotometricInterpretations, ::TiffImages.ExtraSamples, ::Int64)
   @ TiffImages ~/.julia/packages/TiffImages/yETMK/src/layout.jl:45
  interpretation(::TiffImages.PhotometricInterpretations)
   @ TiffImages ~/.julia/packages/TiffImages/yETMK/src/layout.jl:38
  ...

Stacktrace:
  [1] interpretation(p::TiffImages.PhotometricInterpretations)
    @ TiffImages ~/.julia/packages/TiffImages/yETMK/src/layout.jl:38
  [2] interpretation(p::TiffImages.PhotometricInterpretations, extrasamples::TiffImages.ExtraSamples, samplesperpixel::Int64)
    @ TiffImages ~/.julia/packages/TiffImages/yETMK/src/layout.jl:46
  [3] interpretation(ifd::TiffImages.IFD{UInt32})
    @ TiffImages ~/.julia/packages/TiffImages/yETMK/src/layout.jl:29
  [4] getcache(ifd::TiffImages.IFD{UInt32})
    @ TiffImages ~/.julia/packages/TiffImages/yETMK/src/layout.jl:91
  [5] load(tf::TiffImages.TiffFile{UInt32, Stream{DataFormat{:TIFF}, IOStream, String}}, ifds::Vector{TiffImages.IFD{UInt32}}, ::Nothing; verbose::Bool)
    @ TiffImages ~/.julia/packages/TiffImages/yETMK/src/load.jl:71
  [6] load
    @ TiffImages ~/.julia/packages/TiffImages/yETMK/src/load.jl:69 [inlined]
  [7] load(tf::TiffImages.TiffFile{UInt32, Stream{DataFormat{:TIFF}, IOStream, String}}; verbose::Bool, mmap::Bool, lazyio::Bool)
    @ TiffImages ~/.julia/packages/TiffImages/yETMK/src/load.jl:36
  [8] load(tf::TiffImages.TiffFile{UInt32, Stream{DataFormat{:TIFF}, IOStream, String}})
    @ TiffImages ~/.julia/packages/TiffImages/yETMK/src/load.jl:18
  [9] load(io::IOStream; kwargs::@Kwargs{})
    @ TiffImages ~/.julia/packages/TiffImages/yETMK/src/load.jl:17
 [10] load
    @ TiffImages ~/.julia/packages/TiffImages/yETMK/src/load.jl:17 [inlined]
 [11] #13
    @ TiffImages ~/.julia/packages/TiffImages/yETMK/src/load.jl:13 [inlined]
 [12] open(::TiffImages.var"#13#14"{@Kwargs{}}, ::String, ::Vararg{String}; kwargs::@Kwargs{})
    @ Base ./io.jl:396
 [13] open
    @ Base ./io.jl:393 [inlined]
 [14] #load#12
    @ TiffImages ~/.julia/packages/TiffImages/yETMK/src/load.jl:12 [inlined]
 [15] load(filepath::String)
    @ TiffImages ~/.julia/packages/TiffImages/yETMK/src/load.jl:11
 [16] #invokelatest#2
    @ Base ./essentials.jl:950 [inlined]
 [17] invokelatest
    @ Base ./essentials.jl:947 [inlined]
 [18] #_#1
    @ LazyModules ~/.julia/packages/LazyModules/d9Be6/src/LazyModules.jl:29 [inlined]
 [19] (::LazyModules.LazyFunction)(args::String)
    @ LazyModules ~/.julia/packages/LazyModules/d9Be6/src/LazyModules.jl:27
 [20] load(f::File{DataFormat{:TIFF}, String}; canonicalize::Nothing, kwargs::@Kwargs{})
    @ ImageIO ~/.julia/packages/ImageIO/XthUV/src/ImageIO.jl:111
 [21] load(f::File{DataFormat{:TIFF}, String})
    @ ImageIO ~/.julia/packages/ImageIO/XthUV/src/ImageIO.jl:109
 [22] #invokelatest#2
    @ Base ./essentials.jl:950 [inlined]
 [23] invokelatest
    @ Base ./essentials.jl:947 [inlined]
 [24] action(::Symbol, ::Vector{Union{Base.PkgId, Module}}, ::Formatted; options::@Kwargs{})
    @ FileIO ~/.julia/packages/FileIO/BE7iZ/src/loadsave.jl:219
 [25] action
    @ FileIO ~/.julia/packages/FileIO/BE7iZ/src/loadsave.jl:196 [inlined]
 [26] action
    @ FileIO ~/.julia/packages/FileIO/BE7iZ/src/loadsave.jl:185 [inlined]
 [27] load(::String; options::@Kwargs{})
    @ FileIO ~/.julia/packages/FileIO/BE7iZ/src/loadsave.jl:113
 [28] load(::String)
    @ FileIO ~/.julia/packages/FileIO/BE7iZ/src/loadsave.jl:109
 [29] top-level scope
    @ REPL[13]:1
Stacktrace:
 [1] handle_error(e::MethodError, q::Base.PkgId, bt::Vector{Union{Ptr{Nothing}, Base.InterpreterIP}})
   @ FileIO ~/.julia/packages/FileIO/BE7iZ/src/error_handling.jl:61
 [2] handle_exceptions(exceptions::Vector{Tuple{Any, Union{Base.PkgId, Module}, Vector}}, action::String)
   @ FileIO ~/.julia/packages/FileIO/BE7iZ/src/error_handling.jl:56
 [3] action(::Symbol, ::Vector{Union{Base.PkgId, Module}}, ::Formatted; options::@Kwargs{})
   @ FileIO ~/.julia/packages/FileIO/BE7iZ/src/loadsave.jl:228
 [4] action
   @ FileIO ~/.julia/packages/FileIO/BE7iZ/src/loadsave.jl:196 [inlined]
 [5] action
   @ FileIO ~/.julia/packages/FileIO/BE7iZ/src/loadsave.jl:185 [inlined]
 [6] load(::String; options::@Kwargs{})
   @ FileIO ~/.julia/packages/FileIO/BE7iZ/src/loadsave.jl:113
 [7] load(::String)
   @ FileIO ~/.julia/packages/FileIO/BE7iZ/src/loadsave.jl:109
 [8] top-level scope
   @ REPL[13]:1

TIFFTAG_SAMPLEFORMAT value 3 corresponds to SAMPLEFORMAT_IEEEFP. That is IEEE floating point.

https://gitlab.com/libtiff/libtiff/-/blob/master/libtiff/tiff.h#L335

If TIFFTAG_BITSPERSAMPLE is 32, then the image should be interpreted as consisting of Float32 samples.

See the xref on Discourse for a TIF sample.

mkitti commented 9 months ago

https://github.com/tlnagy/TiffImages.jl/blob/46131077adba3a7461288f1ebc67ceb89ea94ff4/src/utils.jl#L161 the encoding does exist in this package, so what went wrong?

mkitti commented 9 months ago

I guess the actual problem here was

ERROR: MethodError: no method matching interpretation(::Val{TiffImages.PHOTOMETRIC_MINISWHITE})
tlnagy commented 9 months ago

I had never implemented PHOTOMETRIC_MINISWHITE as the Colors.jl ecosystem doesn't have a nice way to represent inverted grayscales and I decided that ignoring the inversion (which is what most libraries do) is in violation of Colors.jl's promise to represent the meaning of colors faithfully despite what the raw data might look like.

timholy commented 4 months ago

Presumably mappedarrays(complement, A) would solve that problem?

mkitti commented 4 months ago

I think we might also need setindex! support as well.