How to read Binary data little endain from a . jsf file and display an image?

25 views (last 30 days)
I am stuck on trying to extract the data of a .jsf file to produce an image of the binary data. When viewing the format of the data I have the following:
From what I was told by the creator: Each message starts with a SonarMessageHeaderType structure (from SonarMessages.h) which is 16 bytes long. The key field, byteCount indicates the bytes to follow. So to read a JSF file, read the 16-byte header, and then read the number of bytes to follow to get to the next message.To create a time series for this format, extract the array of 16-bit unsigned integers, scale by 2 ** -n where N is the weighting factor in the header.
For this extraction I am trying to use Matlab to read the specific file and then input the data into a function to output an image. From a previous post I have posted,Previous post, my code so far looks as followed:
fid= fopen('20160503.143239.0000000.jsf', 'r', 'l') % removed b from 'rb'
if fid == -1
error('File is not opened');
%X= fseek( fid, 256, 'cof')
while ~feof(fid)
data = fread(fid,1,'uint16');
I am opening the data file to read binary data (rb) and then using ' l ' to use little endain as the machinefmt states machinefmt . I set an if statement to determine if the file is opened correctly, which when I run the above code it does not produce an error. I then run into two situations that I am stuck on. If I am supposed to read the binary data which follows a 16 byte header and a 240 byte sub header , should I use the
X = fseek(fid, 256, 'cof')
to skip over the header and sub header and start at the binary data before reading the data?
Second problem is when I am trying to read the data. I created a while statement to have the fread function read the file until the end. The file contains over 22,000 lines of data. From what the creator said I need to extract a 16-bit unsigned integer array, so i used the 'uint16' in the fread. When I run the code however, I am receiving an empty 0x0 array for data. The attached image shows part of the file in a jsf viewer for more detail about the file. Could anyone put me in the right direction onto how exactly I should be extracting the file to get the array and plug it into a function like image() to see the acoustic images? Would I have to get some kind of count on the file being read to be able to set data = zeros(x,y) before, then reopen the file and extract? Sorry in advance for the lack of coding skill, this is my first time trying to extract a file using Matlab.

Sign in to comment.

Answers (2)

Guillaume on 8 Apr 2019
Edited: Guillaume on 9 Apr 2019
Untested code obviously since I don't have a file to test with. Bugs/typos possible.
See attached.
edit: fixed a few bugs
Guillaume on 9 Apr 2019
Yes, it was missing the depth field. I've fixed the original code (and a few other bugs).
I've also written a completely new design as explained above. I'd recommend you use that. It's easier to extend to support other types of messages. It also automatically check that the record description actually matches what is expected so mistakes like the above are easier to catch.
With that new code, if you don't want to keep just the essential fields of the sonar message, you could replace the sonarheader description with:
sonarheader = cell2table({
'' 16 'int8'
'msb' 1 '*uint16' %probably critical
'' 16 'int8'
'dataformat' 1 'int16' %critical field
'' 78 'int8'
'samplecount' 1 'uint16' %critical field
'' 52 'int8'
'weightingfactor' 1 'int16' %critical field
'' 70 'int8'
}, 'VariableNames', {'Name', 'Count', 'Type'});
and it'd still work.

Sign in to comment.

Ivan V. Dmitriev
Ivan V. Dmitriev on 20 Nov 2019
Ivan V. Dmitriev
Ivan V. Dmitriev on 21 Nov 2019
>> I would recommend adding some documentation on how to use your code directly to the FileExchange submission rather than forcing potential users to dig through your other website.
Please explain what do you mean? The same pdf-document is in the archive both on the FileExchange and on the "other website".
>> See my code for a maintainable way of specifying the data structure which guarantees that the reading actually matches the structure.
Looked at your code. Thanks for the programming style, I took a couple of things for myself. But, for use "in production":
>> tic;messages=decodejsf2('d:\2\088_EVT_site_sentral.jsf');toc
Elapsed time is 4300.944202 seconds.
>> tic;JsfHead=gJsfHeaderRead('d:\2\088_EVT_site_sentral.jsf',1);toc
Mess: 0040=System Status Message (private), Num: 251 [ Subs: 0, Num: 251; Chan: 0, Num: 251 ]
Mess: 0080=Sonar Data Message, Num: 66231 [ Subs: 20, Num: 33116; Chan: 0 1, Num: 16558 16558 ][ Subs: 21, Num: 33115; Chan: 0 1, Num: 16557 16558 ]
Mess: 0181=N......
Mess: 2060=Pressure Sensor Data, Num: 3931 [ Subs: 101, Num: 3931; Chan: 0, Num: 3931 ]
Elapsed time is 10.023261 seconds.
>> tic;[Head,Data]=gJsf0080Read(JsfHead,0,20);toc
Elapsed time is 103.890087 seconds.

Sign in to comment.


Find more on Matrices and Arrays in Help Center and File Exchange

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!