Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Using fread in mex files

212 views
Skip to first unread message

Eyal

unread,
Mar 6, 2009, 4:55:18 PM3/6/09
to
Hi,

I'm trying to read binary files with mex files. I'm using the following code:

void mexFunction( int nlhs, mxArray *plhs[],
int nrhs, const mxArray *prhs[])
{
struct {
unsigned TimeTag :32;
} Data;
int i=0;
float *Photons;
FILE *fpin1;
char *input1;
mwSize m_Photons;
double *z;
input1 = mxArrayToString(prhs[0]);
if(input1 == NULL )
mexErrMsgTxt("Could not convert input to string.");
if((fpin1=fopen(input1,"rb"))==NULL)
{
mexErrMsgTxt("\ncannot open input file\n");
}
fseek (fpin1 , 0 , SEEK_END);
m_Photons = ftell (fpin1)/4; // Input file data is 4 byte
rewind (fpin1);
plhs[0] = mxCreateDoubleMatrix(m_Photons, 1, mxREAL);
z = mxGetPr(plhs[0]);;
for(i=0;i<m_Photons; i++){
fread( &Data, 1, sizeof(Data) ,fpin1);
*(z+i) = (double)(Data.TimeTag);
}
fclose (fpin1);
}

The code works fine. I was wondering if it is possible to get all the information from the fread function without using a loop. This method of getting the data is rather slow (at least compared with the fread function in Matlab).

Thanks ,
Eyal

Peter Boettcher

unread,
Mar 6, 2009, 5:03:40 PM3/6/09
to
"Eyal " <shaf...@gmail.com> writes:

Why not stick with the native MATLAB fread?

Anyway... your use of Data.TimeTag is quirky. No need for the struct.
This would work fine:

unsigned int TimeTag;
fread(&TimeTag, sizeof(TimeTag), 1, fpin1);
z[i] = (double)TimeTag;

To go faster, you need to read the full file at once, and convert in a
loop. Allocate enough memory (using mxMalloc) to hold
m_Photons*sizeof(unsigned int), fread the entire file into that memory,
loop through and cast to double, then mxFree the temporary buffer.

If m_Photons can be very large, you can do this in blocks to save memory.


-Peter

Eyal

unread,
Mar 16, 2009, 6:41:02 PM3/16/09
to
Peter Boettcher <boet...@ll.mit.edu> wrote in message <muymyby...@G99-Boettcher.llan.ll.mit.edu>...

Thanks for your help Peter.
For some reason I can't read the file properly unless I switch fread(&TimeTag, sizeof(TimeTag), 1, fpin1); to fread(&TimeTag, 1, sizeof(TimeTag), fpin1);
I don't understand why...
Currently, I'm using the Matlab fread but part of my code is in c so I thought that the overall speed might increase by doing everything in c.

Thanks again,
Eyal

James Tursa

unread,
Mar 17, 2009, 2:35:05 AM3/17/09
to
"Eyal " <shaf...@gmail.com> wrote in message <gpmkhu$t5s$1...@fred.mathworks.com>...

>
> Currently, I'm using the Matlab fread but part of my code is in c so I thought that the overall speed might increase by doing everything in c.
>

Another option is to call back into MATLAB to do the fopen, fread, and conversion for you. An example is below. However, this isn't going to be any faster than doing it on the MATLAB side, of course, since you are calling the same functions. It is more a matter of convenience in your code that you might want to use this approach.

James Tursa

------------------------------------------------

>> mex mexfopen.c
>> a = uint32(1:10);
>> fid = fopen('uint32data','w');
>> fwrite(fid,a,'uint32');
>> fclose(fid);
>> b = mexfopen('uint32data')

b =

1
2
3
4
5
6
7
8
9
10

------------------------------------------------

mexfopen.c

#include "mex.h"
void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])
{
int status;
mxArray *mx[3], *mxstatus[1];
if( mexCallMATLAB(1,mx,1,prhs,"fopen") ) { // Put fid into mx[0]
mexErrMsgTxt("Error using MATLAB fopen");
}
mx[1] = mxCreateDoubleScalar(mxGetInf());
mx[2] = mxCreateString("uint32=>double");
if( mexCallMATLAB(1,plhs,3,mx,"fread") ) { // Read the entire file and convert
mexErrMsgTxt("Error using MATLAB fread");
}
status = mexCallMATLAB(1,mxstatus,1,mx,"fclose");
if( status || mxGetScalar(mxstatus[0]) ) {
mexErrMsgTxt("Error using MATLAB fclose");
}
mxDestroyArray(mx[2]);
mxDestroyArray(mx[1]);
mxDestroyArray(mx[0]);
}

James Tursa

unread,
Mar 17, 2009, 2:42:04 AM3/17/09
to
"Eyal " <shaf...@gmail.com> wrote in message <gpmkhu$t5s$1...@fred.mathworks.com>...
>
> For some reason I can't read the file properly unless I switch fread(&TimeTag, sizeof(TimeTag), 1, fpin1); to fread(&TimeTag, 1, sizeof(TimeTag), fpin1);
> I don't understand why...

Can you show how you create and write to the file? Remember the MATLAB fwrite function defaults to uint8 if you don't specify precision.

James Tursa

Eyal

unread,
Mar 17, 2009, 12:36:01 PM3/17/09
to

> Can you show how you create and write to the file? Remember the MATLAB fwrite function defaults to uint8 if you don't specify precision.
>
> James Tursa

Hi James,

I create and write a binary file in Labview using little-endian format. The Matlab fread reads the file just fine, it is only the fread in c that I have to switch between the 1 and sizeof(TimeTag).

Thanks for the example code,
Eyal

Dave

unread,
Feb 23, 2010, 4:24:06 AM2/23/10
to
> >> mex mexfopen.c
> >> a = uint32(1:10);
> >> fid = fopen('uint32data','w');
> >> fwrite(fid,a,'uint32');
> >> fclose(fid);
> >> b = mexfopen('uint32data')
>
> b =
>
> 1
> 2
> 3
> 4
> 5
> 6
> 7
> 8
> 9
> 10
>

This example is a interesting one. However, what should I do if I want to pass the "fid" itself (not the "uint32data"-file) to the mexfopen function?

Rune Allnor

unread,
Feb 23, 2010, 6:17:19 AM2/23/10
to

Don't.

The FID is an internal matlab variable that points to
a list of open files or streams. To pass the FID to the
MEX function you would need to

1) Know the internal workings of the matlab IO system
2) Know the internal workings of the C(++)/Fortran
IO system
3) Know how to match the two.

Not at all trivial.

If you want to access files from inside a MEX function,
pass the file name to the function and do *everything*,
from opening to closing the files, inside the MEX function.

Rune

James Tursa

unread,
Feb 23, 2010, 9:33:21 AM2/23/10
to
"Dave " <beha....@gmail.com> wrote in message <hm06rm$om8$1...@fred.mathworks.com>...

If you pass the fid itself then you must call back into MATLAB to use the MATLAB fread function.

James Tursa

0 new messages