# Problem in reading TIFF floats file

**URL:** <https://discourse.julialang.org/t/problem-in-reading-tiff-floats-file/106610>\
**Category:** General Usage\
**Tags:** images\
**Created:** [November 23, 2023, 3:03am UTC](https://discourse.julialang.org/t/problem-in-reading-tiff-floats-file/106610 "2023-11-23T03:03:15Z")\
**Posts on this page:** 9\
**Page:** 1

<div class="post-metadata">

**Author:** ![RunguangLi](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/runguangli/32/18012_2.png) [@RunguangLi](https://discourse.julialang.org/u/RunguangLi)\
**Post date:** [November 23, 2023, 3:03am UTC](https://discourse.julialang.org/t/problem-in-reading-tiff-floats-file/106610/1 "2023-11-23T03:03:15Z")

</div>

When I read a tiff floats image ([001.tif](https://1drv.ms/i/s!Alc9TKg71lAsv9AgMZ8NnGb7vdXykw?e=cfbkM1)) using FileIO by `real(load("001.tif"))`, I get a matrix with only 1.0 and 0.0 elements.

```julia
360×2304 Array{N0f32,2} with eltype FixedPointNumbers.N0f32:
 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 … 1.0 1.0 1.0 1.0 1.0 0.0 0.0
 0.0 0.0 0.0 0.0 0.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 0.0
 0.0 0.0 0.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0
 0.0 0.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0
 0.0 0.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0
 0.0 0.0 1.0 1.0 1.0 1.0 1.0 1.0 … 1.0 1.0 1.0 1.0 1.0 1.0 1.0
 0.0 0.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0
 0.0 0.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0
 0.0 0.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0
 0.0 0.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0
 ⋮ ⋮ ⋱ ⋮              
 0.0 0.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0
 0.0 0.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0
 0.0 0.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0
 0.0 0.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0
 0.0 0.0 1.0 1.0 1.0 1.0 1.0 1.0 … 1.0 1.0 1.0 1.0 1.0 1.0 1.0
 0.0 0.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0
 0.0 0.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0
 0.0 0.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 0.0
 0.0 0.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 0.0 0.0

```

But using `importdata('001.tif')` in MATLAB, I can get its raw data as shown below, only (1:10,1:10)

```julia
ans =
  10×10 single matrix
            0 0 0 0 0 0 0 0 0 949.15
            0 0 0 0 0 872.99 864.98 862.22 911.13 940.6
            0 0 0 906 905.21 876.51 866.1 862.07 910.67 940.6
            0 0 869 887.65 905.21 876.51 866.1 862.07 910.67 940.6
            0 0 869 887.35 905.21 876.51 866.1 862.07 910.67 940.6
            0 0 869 887.35 905.21 876.51 866.1 862.07 910.67 940.6
            0 0 869 887.35 905.21 876.51 866.1 862.07 910.67 940.6
            0 0 871.22 887.35 905.21 876.51 866.1 862.07 910.67 940.6
            0 0 877.19 887.35 905.21 876.51 866.1 862.07 910.67 940.6
            0 0 877.19 887.35 905.21 876.51 866.1 862.07 910.67 931.8

```

The MATLAB result looks real. I wonder how I can get the same data as in MATLAB with Julia code. Thanks

---

<div class="post-metadata">

**Author:** ![joa-quim](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/joa-quim/32/227_2.png) [@joa-quim](https://discourse.julialang.org/u/joa-quim)\
**Post date:** [November 23, 2023, 3:34am UTC](https://discourse.julialang.org/t/problem-in-reading-tiff-floats-file/106610/2 "2023-11-23T03:34:58Z")

</div>

Try

```julia
using GMT

G = gmtread("001.tif")

```

---

<div class="post-metadata">

**Author:** ![mkitti](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mkitti/32/12459_2.png) [@mkitti](https://discourse.julialang.org/u/mkitti)\
**Post date:** [November 23, 2023, 3:41am UTC](https://discourse.julialang.org/t/problem-in-reading-tiff-floats-file/106610/3 "2023-11-23T03:41:34Z")

</div>

Could you show us the current output of the following?

```julia
using Pkg
Pkg.status()
Pkg.status(mode=PKGMODE_MANIFEST)

```

@tlnagy any insights here? Are floating point tiffs aomething that TiffImages.jl can handle?

---

<div class="post-metadata">

**Author:** ![mkitti](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mkitti/32/12459_2.png) [@mkitti](https://discourse.julialang.org/u/mkitti)\
**Post date:** [November 23, 2023, 7:43am UTC](https://discourse.julialang.org/t/problem-in-reading-tiff-floats-file/106610/4 "2023-11-23T07:43:34Z")

</div>

TiffImages.jl and ImageMagic.jl both seem to have be having some trouble accessing your tiff file. So I decided to create a new wrapper around libtiff via Clang.jl.

## LibTIFF.jl

[https://github.com/mkitti/LibTIFF.jl](https://github.com/mkitti/LibTIFF.jl)

```julia-repl
julia> using Pkg

julia> Pkg.add("https://github.com/mkitti/LibTIFF.jl")

julia> using LibTIFF

julia> function read_float32_tiff(filepath)
           tif = TIFFOpen(filepath, "r")
           _length = TIFFGetField(tif, TIFFTAG_IMAGELENGTH, Int32)
           _width = TIFFGetField(tif, TIFFTAG_IMAGEWIDTH, Int32)
           _rowsperstrip = TIFFGetField(tif, TIFFTAG_ROWSPERSTRIP, Int32)
           _bitspersample = TIFFGetField(tif, TIFFTAG_BITSPERSAMPLE, Int32)
           _samplesformat = TIFFGetField(tif, TIFFTAG_SAMPLEFORMAT, Int8)
           @info "Image fields" _length _width _rowsperstrip _bitspersample _samplesformat
           image = Matrix{Float32}(undef, _width, _length)
           for (i,col) in zip(0:_length÷_rowsperstrip, eachcol(image))
               TIFFReadEncodedStrip(tif, i, pointer(col), -1)
           end
           TIFFClose(tif)
           image = permutedims(image, (2,1))
           return image
       end
read_float32_tiff (generic function with 1 method)

```

The result looks like it matches the MATLAB example.

```julia
julia> read_float32_tiff("001.tif")[1:10, 1:10]
TIFFFetchNormalTag: Warning, ASCII value for tag "ImageDescription" does not end in null byte.
┌ Info: Image fields
│ _length = 360
│ _width = 2304
│ _rowsperstrip = 1
│ _bitspersample = 32
└ _samplesformat = 3
10×10 Matrix{Float32}:
 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 949.15
 0.0 0.0 0.0 0.0 0.0 872.994 864.982 862.223 911.128 940.604
 0.0 0.0 0.0 906.0 905.209 876.51 866.097 862.072 910.672 940.604
 0.0 0.0 869.0 887.646 905.209 876.51 866.097 862.072 910.672 940.604
 0.0 0.0 869.0 887.351 905.209 876.51 866.097 862.072 910.672 940.604
 0.0 0.0 869.0 887.351 905.209 876.51 866.097 862.072 910.672 940.604
 0.0 0.0 869.0 887.351 905.209 876.51 866.097 862.072 910.672 940.604
 0.0 0.0 871.225 887.351 905.209 876.51 866.097 862.072 910.672 940.604
 0.0 0.0 877.187 887.351 905.209 876.51 866.097 862.072 910.672 940.604
 0.0 0.0 877.187 887.351 905.209 876.51 866.097 862.072 910.672 931.802

```

## TiffImages.jl

TiffImages.jl does not seem to recognize the file and errors with the following.

```julia-auto
ERROR: MethodError: no method matching interpretation(::Val{TiffImages.PHOTOMETRIC_MINISWHITE})

```

> **Stack trace for TiffImages.jl**
>
> ```julia-auto
> 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
> 
> ```

## ImageMagick.jl

ImageMagick.jl seems to read the file as a 32-bit Int TIFF as the original poster displayed.

```julia-auto
julia> load("/home/mkitti/Downloads/001.tif")
[Info: Precompiling ImageMagick [6218d12a-5da1-5696-b52f-db25d2ecc6d1]
┌ Warning: some versions of ImageMagick give spurious low-order bits for 32-bit TIFFs
└ @ ImageMagick ~/.julia/packages/ImageMagick/KDZC2/src/ImageMagick.jl:99

```

---

<div class="post-metadata">

**Author:** ![RunguangLi](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/runguangli/32/18012_2.png) [@RunguangLi](https://discourse.julialang.org/u/RunguangLi)\
**Post date:** [November 23, 2023, 8:59am UTC](https://discourse.julialang.org/t/problem-in-reading-tiff-floats-file/106610/5 "2023-11-23T08:59:58Z")

</div>

Thanks! It works.  
(The time loading GMT may be the only pain…😅)

---

<div class="post-metadata">

**Author:** ![RunguangLi](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/runguangli/32/18012_2.png) [@RunguangLi](https://discourse.julialang.org/u/RunguangLi)\
**Post date:** [November 23, 2023, 9:12am UTC](https://discourse.julialang.org/t/problem-in-reading-tiff-floats-file/106610/6 "2023-11-23T09:12:29Z")

</div>

Excellent update! Hope it can be a built-in function.  
Suh TIFF file was produced by Fit2D (a software processing diffraction images). It’s wired that no one using these packages has encountered this problem before (perhaps because Tiff float isn’t popular).

---

<div class="post-metadata">

**Author:** ![joa-quim](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/joa-quim/32/227_2.png) [@joa-quim](https://discourse.julialang.org/u/joa-quim)\
**Post date:** [November 23, 2023, 12:06pm UTC](https://discourse.julialang.org/t/problem-in-reading-tiff-floats-file/106610/7 "2023-11-23T12:06:53Z")

</div>

> [@RunguangLi](#):
>
> (The time loading GMT may be the only pain…😅)

Hmmm, how long? It’s quite fast for me

```julia
julia> cd("c:/v"); @time using GMT
  0.696514 seconds (610.75 k allocations: 43.228 MiB, 12.31% gc time, 1.25% compilation time)

julia> @time gmtread("lixo.tiff");
  0.194171 seconds (43.40 k allocations: 3.930 MiB, 45.89% compilation time)

julia> @time gmtread("lixo.tiff");
  0.094855 seconds (160 allocations: 1.021 MiB)

```

> [@RunguangLi](#):
>
> (perhaps because Tiff float isn’t popular)

On the contrary, they are very popular in Earth Sciences.

---

<div class="post-metadata">

**Author:** ![mkitti](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mkitti/32/12459_2.png) [@mkitti](https://discourse.julialang.org/u/mkitti)\
**Post date:** [November 24, 2023, 12:07am UTC](https://discourse.julialang.org/t/problem-in-reading-tiff-floats-file/106610/8 "2023-11-24T00:07:15Z")

</div>

This is a halfway solution. Really we should have another kind of “color” than “gray” that represents when the minimum is meant to be white.

```julia-repl
julia> using Pkg

julia> Pkg.activate(; temp = true)
  Activating new project at `/tmp/jl_vRiPuv`

julia> Pkg.add(url="https://github.com/mkitti/TiffImages.jl", rev="mkitti-miniswhite")

julia> using TiffImages

julia> TiffImages.load("/home/mkitti/Downloads/001.tif")[1:10,1:10]
10×10 Array{Gray{Float32},2} with eltype ColorTypes.Gray{Float32}:
 Gray{Float32}(0.0) Gray{Float32}(0.0) Gray{Float32}(0.0) … Gray{Float32}(0.0) Gray{Float32}(949.15)
 Gray{Float32}(0.0) Gray{Float32}(0.0) Gray{Float32}(0.0) Gray{Float32}(911.128) Gray{Float32}(940.604)
 Gray{Float32}(0.0) Gray{Float32}(0.0) Gray{Float32}(0.0) Gray{Float32}(910.672) Gray{Float32}(940.604)
 Gray{Float32}(0.0) Gray{Float32}(0.0) Gray{Float32}(869.0) Gray{Float32}(910.672) Gray{Float32}(940.604)
 Gray{Float32}(0.0) Gray{Float32}(0.0) Gray{Float32}(869.0) Gray{Float32}(910.672) Gray{Float32}(940.604)
 Gray{Float32}(0.0) Gray{Float32}(0.0) Gray{Float32}(869.0) … Gray{Float32}(910.672) Gray{Float32}(940.604)
 Gray{Float32}(0.0) Gray{Float32}(0.0) Gray{Float32}(869.0) Gray{Float32}(910.672) Gray{Float32}(940.604)
 Gray{Float32}(0.0) Gray{Float32}(0.0) Gray{Float32}(871.225) Gray{Float32}(910.672) Gray{Float32}(940.604)
 Gray{Float32}(0.0) Gray{Float32}(0.0) Gray{Float32}(877.187) Gray{Float32}(910.672) Gray{Float32}(940.604)
 Gray{Float32}(0.0) Gray{Float32}(0.0) Gray{Float32}(877.187) Gray{Float32}(910.672) Gray{Float32}(931.802)

```

xref: [Interpret PHOTOMETRIC\_MINISWHITE as Gray by mkitti · Pull Request #134 · tlnagy/TiffImages.jl · GitHub](https://github.com/tlnagy/TiffImages.jl/pull/134)

---

<div class="post-metadata">

**Author:** ![tlnagy](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tlnagy/32/5815_2.png) [@tlnagy](https://discourse.julialang.org/u/tlnagy)\
**Post date:** [November 28, 2023, 3:17am UTC](https://discourse.julialang.org/t/problem-in-reading-tiff-floats-file/106610/9 "2023-11-28T03:17:06Z")

</div>

Nice! Yeah, I never implemented inverted TIFFs because there wasn’t a convenient way to represent them in the `Colors.jl` ecosystem. Your PR works for now, but I agree that an inverted color type would be most faithful to the underlying data.
