I have a specific binary? file format containing datas about the configuration used to take a picture with a custom camera. This file format is named DAI and contains for example values of offset/gain/etc...
I am using a black-box script in java to turn this file into a .csv and I want to perform the same thing in Matlab. I've got a config file describing in ascii format how this file is built (name of the field, type of the data, first_word, last_word, low_bit, high_bit). For example I know that the first field in the DAI file will be : spare1; PCHAR; first_word=0; low_bit=0; high_bit=7
But right now I have no clue of how to use this information. My first thought were to fopen() the file and use fread() to read the binary data from the file and turn it into the format I want but I don't know how to use the values of "last_word,high_bit,..." to do so. I have a limited understanding of binary files.
To sum up everything :
file.dai contains datas / file.cfg contains the structure :
mband_1_start_line; PCHAR; first_word=12; low_bit=6; high_bit=15
mband_1_length; PCHAR; first_word=12; low_bit=0; high_bit=5
mband_1_gain; PCHAR; first_word=13; low_bit=0; high_bit=7
mband_1_offset; PCHAR; first_word=13; low_bit=8; last_word=14; high_bit=7
and I want to recover the datas corresponding to the fields like mband_1_offset.
If someone can help me to figure the good way of doing that I will be very thankful !
[EDIT : SOLVED] So thanks to your very helpful help I've manage to get the values for each field even when the header changes !! Here's the final code :
Here's the final code :
...code to retrieve the content of the .cfg file....
%% Open and read the DAI file
fid = fopen(dai_file,'r','l');
% First thing is to skip the header
% We read a first time the file
dat=fread(fid,inf,'*uint8');
% We search for the position of the end of the header : NUL NUL ETX
% In decimal it gives :
skip = findstr(dat',[000,000,003]);
% We define the wordsize : 2 bytes (2 words)
wordsize = 2;
% We rewind the file to start over to get the values for each field
frewind(fid);
% We initiate the structure camdat containing the datas of the camera
camdat=struct;
% We start the loop for each field of the layout config file
for ct = 1:length(layout)
% Defining the words/bits
first_word = layout{ct,3};
last_word = layout{ct,5};
low_bit = layout{ct,4};
high_bit = layout{ct,6};
% We position to the "skip value + the position of the first_word in bytes"
fseek(fid,skip+first_word*wordsize,-1);
% We compute the number of words (last - first +1)
datasize=last_word-first_word+1;
% We read the datas as uint16 (words are 16bits)
data=fread(fid,datasize,'*uint16');
% We convert it to bits
% Case of 1 word
bits=bitget(data(1),[1:16]);
% Case of 2 words
if length(data) > 1
bits=[bits,bitget(data(2),1:16)];
high_bit = high_bit+16;
end
% We take only the bits that define the field (between low_bit and
% high_bit)
bits_used = bits(low_bit+1:high_bit+1);
% We convert the bits to dec
data = sum(bits_used.*uint16(2).^uint16([0:length(bits_used)-1]));
% We store it in the camdat.field struct
camdat.(layout{ct,1})=data;
end
% We close the DAI file
fclose(fid);
% Displaying for test
camdat
My approach in this case is to find the part of the file that matches your data.
fid = fopen('dai_file.dai','r','l');
dat=fread(fid,inf,'*uint8');
findstr(dat',[74,210,129,93]);
>> 891 1159 1427 1695 ....
Strange enough this happens 100 times.
If byte 891 is right than bios_1 is NOT in the 4th word from bit 0 to 7, but in the 445th word bit 0 to 7.
Let's try
fid = fopen(dai_file,'r','l');
fseek(fid,445*2,-1)
data=fread(fid,1,'*uint16');
bits=bitget(data(1),[1:16]);
bits = bits(1:8);
data = sum(bits.*uint16(2).^uint16([0:7]))
>> data = 74
Yep, there it is. So I would suggest to add 441 to each word entry and see if it works.