tlnagy
March 18, 2020, 12:24am
#1
On Julia 1.4.0-rc2
(I don’t think it’s a new behavior), I see the following:
versus the expected:
I’m reading in the image as follows:
io = open("bilevel_example.tif")
seek(io, 8)
data = BitArray(undef, 40160*8)
read!(io, data);
It appears that the bits are vertically flipped every 8 bits. The file was written and read on a little-endian machine. Is there any way to change this?
Here’s the file in question: https://ucsf.box.com/s/n6jpmxknsvnvqcjzqlyv8hxti8rfkum0
tlnagy
March 18, 2020, 12:44am
#2
I believe this is coming from the least significant bit being in the leftmost position of each byte so I need to do a bit swap operation, which AFAIK there isn’t a dedicated Julia function for? (bswap
swaps bytes)
laborg
March 18, 2020, 5:15am
#3
Maybe you can copy parts of this code if you aren’t using master: https://github.com/JuliaLang/julia/pull/34791
3 Likes
Sukera
March 18, 2020, 6:22am
#4
Not really familiar with .tif, but have you tried using Images.jl to read your image? They’re using FileIO.jl in the background which has explicit support for .tif files, maybe they do the flipping already?
Otherwise, maybe Base.ltoh
can help you.
1 Like
tlnagy
March 18, 2020, 5:03pm
#5
I’m actually in the process of writing a pure-Julia TIFF reader/writer, which generalizes an earlier package that I created. See https://github.com/tlnagy/TIFF.jl and https://github.com/tlnagy/OMETIFF.jl
1 Like
tlnagy
March 18, 2020, 5:07pm
#6
This looks exactly like what I was looking for. I’m targeting 1.4, but I can copy that code into the package until it lands in stable.
tlnagy
March 18, 2020, 6:43pm
#7
Thanks @laborg , that code basically did what I want, I just had get rid of the bswap at the end since the byte order is correct (both little-endian).
const _mask1_uint128 = (UInt128(0x5555555555555555) << 64) | UInt128(0x5555555555555555)
const _mask2_uint128 = (UInt128(0x3333333333333333) << 64) | UInt128(0x3333333333333333)
const _mask4_uint128 = (UInt128(0x0f0f0f0f0f0f0f0f) << 64) | UInt128(0x0f0f0f0f0f0f0f0f)
function reversebits!(x::BitArray)
n = length(x.chunks)
for i in 1:n
x.chunks[i] = reversebits(x.chunks[i])
end
end
function reversebits(x::Base.BitInteger)
z = unsigned(x)
mask1 = _mask1_uint128 % typeof(z)
mask2 = _mask2_uint128 % typeof(z)
mask4 = _mask4_uint128 % typeof(z)
z = ((z & mask1) << 1) | ((z >> 1) & mask1)
z = ((z & mask2) << 2) | ((z >> 2) & mask2)
z = ((z & mask4) << 4) | ((z >> 4) & mask4)
return z # <----- got rid of the bswap here
end
seek(tf.io.io, 8)
data = BitArray(undef, 40160*8)
read!(tf.io.io, data);
reversebits!(data)
Gray.(reshape(data, 640, :)')