Reputation: 24169
I have some binary files (obtained from a camera), in which frames are stored in some sequential order.
The usual algorithm to working with such files would be something along the lines of: open file -> advance to first frame -> read frame -> advance a few bits until the next frame -> read next frame
and so on. Intuitively, this results in many "short" I\O operations that likely reduce performance when compared with a single "long" operation.
For this reason, it seemed natural to me to initially load the file into memory, and interpret it later "at my leisure" (since reading from RAM is supposed to be much faster than from disk).
So far, I could think of two possible solutions to this problem:
mfile
in the FileExchange. {Even though it looks exactly like what I need, I'm slightly reluctant to use this solution because it's about 7 years old (which invites the assumption that it may be outdated)}My question is: Is there some built-in functionality in MATLAB that allows to achieve this result?
Upvotes: 0
Views: 427
Reputation: 24169
Following the suggestions of @Ben Voigt
and @Peter
, I tried writing some code that reads the binary file to memory and parses it. Below is a comparison of a piece of the original code and my "from memory" implementation that produces the same result (this is just the header and not the frames themselves, but the idea is similar +reshape).
I'd like to point out the documentation in fread.m
is very concise and informative.
fid=fopen(fName,'r');
fseek(fid, 11, 'bof');
ptw.m_MainHeaderSize=fread(fid,1,'int32');
ptw.m_FrameHeaderSize=fread(fid,1,'int32');
fseek(fid, 27, 'bof');
ptw.m_nframes=fread(fid,1,'int32');
fseek(fid, 212 , 'bof');
ptw.m_fHousingTemp=fread(fid,1,'float');
fseek(fid, 216 , 'bof');
ptw.m_fHousingTemp2=fread(fid,1,'float');
fseek(fid, 245, 'bof');
ptw.m_minlut=fread(fid,1,'int16');
ptw.m_maxlut=fread(fid,1,'int16');
function dts = InterpretFromMemory(fName)
%% Definitions
UINT8_IN_CHAR = 1;
UINT8_IN_INT16 = 2;
UINT8_IN_INT32 = 4;
UINT8_IN_FLOAT = 4;
ZERO_POS = 1;
%% Initialization
dts = struct('m_filename',fName);
%% Reading
fid=fopen(fName);
fComplete = fread(fid,'*uint8');
fclose(fid);
%% Parsing
curr_pos = 11;
dts.m_MainHeaderSize = readFromArrayAndAdvance(fComplete,1,'int32');
dts.m_FrameHeaderSize = readFromArrayAndAdvance(fComplete,1,'int32');
curr_pos = 27;
dts.m_nframes = readFromArrayAndAdvance(fComplete,1,'int32');
curr_pos = 212;
dts.m_fHousingTemp = readFromArrayAndAdvance(fComplete,1,'float');
dts.m_fHousingTemp2 = readFromArrayAndAdvance(fComplete,1,'float');
curr_pos = 245;
dts.m_minlut = readFromArrayAndAdvance(fComplete,1,'int16');
dts.m_maxlut = readFromArrayAndAdvance(fComplete,1,'int16');
function [out]=readFromArrayAndAdvance(hArray,numVals,valType)
switch valType
case 'char'
numBytes = UINT8_IN_CHAR;
case {'int16','uint16'}
numBytes = UINT8_IN_INT16;
case {'int32','uint32'}
numBytes = UINT8_IN_INT32;
case 'float'
numBytes = UINT8_IN_FLOAT;
valType = 'single'; %// float equivalent supported by typecast
end
out = typecast(hArray(...
curr_pos+ZERO_POS:curr_pos+ZERO_POS+numVals*numBytes-1),valType);
curr_pos = curr_pos + numVals*numBytes;
end
end
TODO: I intend to run some benchmarks on this in the future and compare the various methods.
Copyright notice: the "original code" snippet belongs to FLIR.
Upvotes: 1