# Trying to read binary file into struct with julia

**URL:** <https://discourse.julialang.org/t/trying-to-read-binary-file-into-struct-with-julia/16025>\
**Category:** New to Julia\
**Tags:** question, binaryio\
**Created:** [October 8, 2018, 3:23pm UTC](https://discourse.julialang.org/t/trying-to-read-binary-file-into-struct-with-julia/16025 "2018-10-08T15:23:37Z")\
**Posts on this page:** 11\
**Page:** 1

<div class="post-metadata">

**Author:** ![mgalenb](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mgalenb/32/5645_2.png) [@mgalenb](https://discourse.julialang.org/u/mgalenb)\
**Post date:** [October 8, 2018, 3:23pm UTC](https://discourse.julialang.org/t/trying-to-read-binary-file-into-struct-with-julia/16025/1 "2018-10-08T15:23:37Z")

</div>

i am new to julia. i am trying to read the header of a binary file into a struct. i am using juliapro. i start by defining the struct:

```julia
struct CINEheader
    cinetype :: UInt16
    headersize :: UInt16
    compression :: UInt16
    version :: UInt16
    firstMovieImage :: Int32
    totalImageCount :: UInt32
    firstImageNo :: Int32
    imageCount :: UInt32
    offImageHeader :: UInt32
    offSetup :: UInt32
    offImageOffsets :: UInt32
 
end

```

then i open the file and try to read into d

```julia
s = open("filename.cine","r")
d=CINEheader
read(s,d)

```

however when i run this i get a convert error, which i dont undestand

```julia
ERROR: MethodError: Cannot `convert` an object of type Type{CINEheader} to an object of type Array{UInt8,1}
This may have arisen from a call to the constructor Array{UInt8,1}(...),
since type constructors fall back to convert methods.

```

any tips to help me understand what i am doing wrong?

---

<div class="post-metadata">

**Author:** ![sdanisch](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/sdanisch/32/1406_2.png) [@sdanisch](https://discourse.julialang.org/u/sdanisch)\
**Post date:** [October 8, 2018, 3:37pm UTC](https://discourse.julialang.org/t/trying-to-read-binary-file-into-struct-with-julia/16025/2 "2018-10-08T15:37:24Z")

</div>

This should work:

```nohighlight
s = open("filename.cine","r")
d = Ref{CINEheader}()
read!(s, d)
header = d[]

```

---

<div class="post-metadata">

**Author:** ![mgalenb](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mgalenb/32/5645_2.png) [@mgalenb](https://discourse.julialang.org/u/mgalenb)\
**Post date:** [October 8, 2018, 4:22pm UTC](https://discourse.julialang.org/t/trying-to-read-binary-file-into-struct-with-julia/16025/3 "2018-10-08T16:22:05Z")

</div>

so i tried your code and now i get:

```julia
ERROR: MethodError: no method matching read!(::IOStream, ::Base.RefValue{CINEheader})
Closest candidates are:
  read!(::IO, ::BitArray) at bitarray.jl:2010
  read!(::AbstractString, ::Any) at io.jl:161
  read!(::IO, ::Array{UInt8,N} where N) at io.jl:387

```

---

<div class="post-metadata">

**Author:** ![sdanisch](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/sdanisch/32/1406_2.png) [@sdanisch](https://discourse.julialang.org/u/sdanisch)\
**Post date:** [October 8, 2018, 5:09pm UTC](https://discourse.julialang.org/t/trying-to-read-binary-file-into-struct-with-julia/16025/4 "2018-10-08T17:09:24Z")

</div>

Are you on Julia 0.6? I just tested it on 1.0 and it works on first sight!

---

<div class="post-metadata">

**Author:** ![stillyslalom](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/stillyslalom/32/45687_2.png) [@stillyslalom](https://discourse.julialang.org/u/stillyslalom)\
**Post date:** [October 8, 2018, 5:47pm UTC](https://discourse.julialang.org/t/trying-to-read-binary-file-into-struct-with-julia/16025/5 "2018-10-08T17:47:04Z")

</div>

Here’s my cine reader, written with dicts instead of structs:

```julia
using DataStructures: OrderedDict
using Images: Gray
using FixedPointNumbers, ProgressMeter

function readcine(fname)
    f = open(fname)
    h = OrderedDict()

    # Check magic number
    read(f, UInt16) == UInt(18755) || error(basename(fname), " is not a .cine file")

    fhtypes = OrderedDict( # File header
        :HeadSize => UInt16,
        :Compression => UInt16,
        :Version => UInt16,
        :FirstImageIndex => Int32,
        :TotalImages => UInt32,
        :FirstImageNum => Int32,
        :ImCount => UInt32,
        :OffImageHeader => UInt32,
        :OffSetup => UInt32,
        :OffImageOffsetscl => UInt32,
        :TriggerFrac => UInt32,
        :TriggerSec => UInt32
    )
    ihtypes = OrderedDict( # Image header
        :ImHeadSize => UInt32,
        :Width => Int32,
        :Height => Int32,
        :Planes => UInt16,
        :BitDepth => UInt16,
        :Comp => UInt32,
        :SizeImage => UInt32,
        :PxPerMX => UInt32,
        :PxPerMY => UInt32,
        :ClrUsed => UInt32,
        :ClrImportant => UInt32,
        :FPS => UInt16
    )

    for (ID, headertype) in fhtypes # Read .cine file header
        h[ID] = read(f, headertype)
    end

    seek(f, h[:OffImageHeader])
    for (ID, headertype) in ihtypes # Read image header
        h[ID] = read(f, headertype)
    end

    bittype = h[:BitDepth] == 8 ? Gray{N0f8} : Gray{N4f12}

    numframes = h[:ImCount]
    numframes > 0 || error("no images exist in file")

    seek(f, h[:OffImageOffsetscl])
    imlocs = read!(f, Array{Int64}(undef, numframes))

    seekstart(f)
    i = 1
    while read(f, UInt16) != 1002 # Get location of images
        i += 1
    end
    h[:ImageOffset] = i

    dt = zeros(numframes)
    skip(f, 2)
    for i = 1:numframes # Calculate dt for each frame
        fracstart = read(f, UInt32)
        secstart = read(f, UInt32)
        dt[i] = (secstart - h[:TriggerSec]) + ((fracstart - h[:TriggerFrac])/2^32)
    end
    h[:DeltaT] = dt

    img = zeros(bittype, h[:Height], h[:Width], numframes)
    @showprogress .1 "Loading $(basename(fname)) " for i = 1:numframes
        seek(f, imlocs[i])
        skip(f, read(f, UInt32) - 4)
        img[:,:,i] = rotl90(read!(f, Array{bittype}(undef, h[:Width], h[:Height])))
    end

    close(f)
    return img, h
end

```

---

<div class="post-metadata">

**Author:** ![mgalenb](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mgalenb/32/5645_2.png) [@mgalenb](https://discourse.julialang.org/u/mgalenb)\
**Post date:** [October 8, 2018, 6:11pm UTC](https://discourse.julialang.org/t/trying-to-read-binary-file-into-struct-with-julia/16025/6 "2018-10-08T18:11:24Z")

</div>

yes using juliapro which i believe is on 0.6.4?

---

<div class="post-metadata">

**Author:** ![sdanisch](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/sdanisch/32/1406_2.png) [@sdanisch](https://discourse.julialang.org/u/sdanisch)\
**Post date:** [October 9, 2018, 6:53am UTC](https://discourse.julialang.org/t/trying-to-read-binary-file-into-struct-with-julia/16025/7 "2018-10-09T06:53:41Z")

</div>

oh - dont know, but you should look into switching to 1.0 😉 meanwhile it might work on 0.6 to use an one element array instead of the ref!

---

<div class="post-metadata">

**Author:** ![mgalenb](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mgalenb/32/5645_2.png) [@mgalenb](https://discourse.julialang.org/u/mgalenb)\
**Post date:** [October 10, 2018, 3:49pm UTC](https://discourse.julialang.org/t/trying-to-read-binary-file-into-struct-with-julia/16025/8 "2018-10-10T15:49:19Z")

</div>

will do thanks!

---

<div class="post-metadata">

**Author:** ![mgalenb](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mgalenb/32/5645_2.png) [@mgalenb](https://discourse.julialang.org/u/mgalenb)\
**Post date:** [October 10, 2018, 3:50pm UTC](https://discourse.julialang.org/t/trying-to-read-binary-file-into-struct-with-julia/16025/9 "2018-10-10T15:50:10Z")

</div>

thanks! ill try this out. have you noticed any speed limitations when using dictionaries? im trying to load/manipulate 20 GB phantom videos

---

<div class="post-metadata">

**Author:** ![stillyslalom](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/stillyslalom/32/45687_2.png) [@stillyslalom](https://discourse.julialang.org/u/stillyslalom)\
**Post date:** [October 10, 2018, 4:39pm UTC](https://discourse.julialang.org/t/trying-to-read-binary-file-into-struct-with-julia/16025/10 "2018-10-10T16:39:22Z")

</div>

The header dictionaries shouldn’t have any real impact on performance–almost all the runtime will be spent in the image-loading loop. You might have trouble fitting 20 GB into memory, though–you may want to load and process one frame at a time if your use case allows it.

---

<div class="post-metadata">

**Author:** ![stillyslalom](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/stillyslalom/32/45687_2.png) [@stillyslalom](https://discourse.julialang.org/u/stillyslalom)\
**Post date:** [October 10, 2018, 6:23pm UTC](https://discourse.julialang.org/t/trying-to-read-binary-file-into-struct-with-julia/16025/11 "2018-10-10T18:23:55Z")

</div>

I rewrote the reader to allow loading of individual frames: [https://gist.github.com/stillyslalom/36d72c216da18202d018025d3ef28fff](https://gist.github.com/stillyslalom/36d72c216da18202d018025d3ef28fff)

```julia
filename = "test.cine"
vid, header = readcine(filename) # Read the entire video file

# for individual frames:
header = cineheader(filename) # Just the header
img = readframe(filename, header, 1) # Read the first frame

# for sets of frames
subvid1 = readframe(filename, header, 1:10:500) # Read every tenth frame
subvid2 = readframe(filename, header, [1, 7, 42]) # Read arbitrary sets of frames

```
