Skip to Main Content Skip to Search
Login
File Exchange
MATLAB Newsgroup
Link Exchange
  Blogs  
 Contest 
MathWorks.com

Thread Subject: reading binary file from mexFunction

Subject: reading binary file from mexFunction

From: basudha pradhan

Date: 09 Sep, 2007 19:00:02

Message: 1 of 8

how to read binary file from mexFunction and pass entire
content of file to some variable buffer? is there something
similar to fread() in mex function?

Thanks in advance
Basudha

Subject: reading binary file from mexFunction

From: Walter Roberson

Date: 09 Sep, 2007 22:14:43

Message: 2 of 8

"basudha pradhan" <lucky_faith_911@hotmail.com> wrote in
message <fc1fri$au3$1@fred.mathworks.com>...
> how to read binary file from mexFunction and pass entire
> content of file to some variable buffer? is there something
> similar to fread() in mex function?

There is something -very- much like fread() in mex functions.

Use mxCreateDoubleArray (or as appropriate for the
type of the data to read in.) Use mxGetData on the result
of that in order to get a C pointer to the actual data
block. Use C's fopen() to open the file, and use
C's fread() to read the data into the area returned by
mxGetData. When you are done with the file, use C's fclose().


(Note: This information is based upon browsing through the
online documentation, not upon experience.)

Subject: reading binary file from mexFunction

From: basudha pradhan

Date: 11 Sep, 2007 17:58:05

Message: 3 of 8

Thanks Walter. I tried something similar to what you
suggested. I can get the function to compile but when i ran
it , it crashes. This is what i tried.

/* The gateway routine */
void mexFunction(int nlhs, mxArray *plhs[],
                 int nrhs, const mxArray *prhs[])
{
   char *input_buf;
   uint8 *output_buf;
   int buflen;
   int status;
   FILE *pFile;
   long lSize;
   size_t result;
   
  /* Output must be a string. */
  if (mxIsChar(plhs[0]) != 1)
    mexErrMsgTxt("Output must be a string.");

  /* Output must be a row vector. */
  if (mxGetM(plhs[0]) != 1)
    mexErrMsgTxt("Output must be a row vector.");
  
  
  /* Allocate memory for output strings. */
  plhs[0] = mxCalloc(150000, sizeof(char));
  output_buf = mxGetPr(plhs[0]);
  
  
  
  /*Open binary file for read*/
  pFile = fopen ( "file.bin" , "rb" );
     if (pFile==NULL) mexErrMsgTxt("File cannot be
opened.");

     // obtain file size:
     fseek (pFile , 0 , SEEK_END);
     lSize = ftell (pFile);
     rewind (pFile);

     // allocate memory to contain the whole file:
     plhs[1] = (uint8*) mxCalloc(lSize, sizeof(uint8));
     input_buf = mxGetPr(plhs[1]);

     // copy the file into the buffer:
     result = fread (input_buf,1,lSize,pFile);
     if (result != lSize) mexErrMsgTxt("incorrect
reading.");
     /* the whole file is now loaded in the memory buffer.
*/
     fclose(pFile);
      
    /* Call the C subroutine. */
  MQ_dec(input_buf,output_buf);
  mxFree(plhs[0]);
  mxFree(plhs[1]);
}

I would really appreciate your suggestions.

Thanks,
Basudha

Subject: Re: reading binary file from mexFunction

From: Peter Boettcher

Date: 11 Sep, 2007 18:07:07

Message: 4 of 8

"basudha pradhan" <lucky_faith_911@hotmail.com> writes:

> Thanks Walter. I tried something similar to what you
> suggested. I can get the function to compile but when i ran
> it , it crashes. This is what i tried.
>
> /* The gateway routine */
> void mexFunction(int nlhs, mxArray *plhs[],
> int nrhs, const mxArray *prhs[])
> {
> char *input_buf;
> uint8 *output_buf;
> int buflen;
> int status;
> FILE *pFile;
> long lSize;
> size_t result;
>
> /* Output must be a string. */
> if (mxIsChar(plhs[0]) != 1)
> mexErrMsgTxt("Output must be a string.");

plhs[0] doesn't exist until you create it.

> /* Output must be a row vector. */
> if (mxGetM(plhs[0]) != 1)
> mexErrMsgTxt("Output must be a row vector.");

likewise...

> /* Allocate memory for output strings. */
> plhs[0] = mxCalloc(150000, sizeof(char));
> output_buf = mxGetPr(plhs[0]);

You need to create plhs[0] to be an mxArray, not an arbitrary chunk of
memory. So you need something like mxCreateArray() instead.

>
> /*Open binary file for read*/
> pFile = fopen ( "file.bin" , "rb" );
> if (pFile==NULL) mexErrMsgTxt("File cannot be
> opened.");
>
> // obtain file size:
> fseek (pFile , 0 , SEEK_END);
> lSize = ftell (pFile);
> rewind (pFile);
>
> // allocate memory to contain the whole file:
> plhs[1] = (uint8*) mxCalloc(lSize, sizeof(uint8));
> input_buf = mxGetPr(plhs[1]);

Same here. Except you also need to be sure plhs[1] exists, via nlhs

> // copy the file into the buffer:
> result = fread (input_buf,1,lSize,pFile);
> if (result != lSize) mexErrMsgTxt("incorrect
> reading.");
> /* the whole file is now loaded in the memory buffer.
> */
> fclose(pFile);
>
> /* Call the C subroutine. */
> MQ_dec(input_buf,output_buf);
> mxFree(plhs[0]);
> mxFree(plhs[1]);

If you don't need to return the data to MATLAB, then don't use plhs[]
at all! Just use a char* pointer, mxCalloc(), and mxFree(). So
scratch my advice above for this purpose.

If you DO want data returned to MATLAB, then create the arrays like I
recommend, then DON'T try to free them at the end. You want them
delivered to MATLAB.

I can add a little more detail if you clarify what you are trying to
achieve...

-Peter

Subject: Re: reading binary file from mexFunction

From: basudha pradhan

Date: 12 Sep, 2007 00:06:27

Message: 5 of 8

Peter,

I am trying to read content of binary file from a
mexfunction.My mexfunction doesn't have any input argument.
It just open up a binary file and copy the content of
binary file to input_buffer . Then, I would like to call C
function that take this input_buffer as an input and
process it to give output(character array data types) which
i will store in output_buffer. So, i had plhs[0] pointed to
output buffer that will be passed back to Matlab. My
output_buffer is not of fixed length. It may vary depending
upon different content of binary file. So how do i declare
mxCreateCharArray() of variable length.
mxArray *mxCreateCharArray(int ndim, const int *dims);
what will be ndim and *dim if they vary for different inputs
(its not the same size as input). this is what i got till
now. Your suggestions will be greatly appreciated.
 

void mexFunction(int nlhs, mxArray *plhs[],
                 int nrhs, const mxArray *prhs[])
{
   char *input_buf;
   uint8 *output_buf;
   int buflen;
   int status;
   FILE *pFile;
   long lSize;
   size_t result;
   
  /* Output must be a string. */
  if (mxIsChar(plhs[0]) != 1)
    mexErrMsgTxt("Output must be a string.");

  /* Output must be a row vector. */
  if (mxGetM(plhs[0]) != 1)
    mexErrMsgTxt("Output must be a row vector.");
  
  
  /* Allocate memory for output strings. */
  plhs[0] = mxCalloc(150000, sizeof(char));
//not sure how to use mxCreateCharArray()
  output_buf = mxGetPr(plhs[0]);
  
  
  
  /*Open binary file for read*/
  pFile = fopen ( "file.bin" , "rb" );
     if (pFile==NULL) mexErrMsgTxt("File cannot be
opened.");

     // obtain file size:
     fseek (pFile , 0 , SEEK_END);
     lSize = ftell (pFile);
     rewind (pFile);

     // allocate memory to contain the whole file:
     input_buf = (uint8*) mxCalloc(lSize, sizeof(uint8));
      

     // copy the file into the buffer:
     result = fread (input_buf,1,lSize,pFile);
     if (result != lSize) mexErrMsgTxt("incorrect
reading.");
     /* the whole file is now loaded in the memory buffer.
*/
     fclose(pFile);
      
    /* Call the C subroutine. */
  MQ_dec(input_buf,output_buf);
  mxFree(input_buf);
  
}




Thanks
~Basudha


Subject: Re: reading binary file from mexFunction

From: Peter Boettcher

Date: 12 Sep, 2007 13:50:04

Message: 6 of 8

"basudha pradhan" <lucky_faith_911@hotmail.com> writes:

> Peter,
>
> I am trying to read content of binary file from a
> mexfunction.My mexfunction doesn't have any input argument.
> It just open up a binary file and copy the content of
> binary file to input_buffer . Then, I would like to call C
> function that take this input_buffer as an input and
> process it to give output(character array data types) which
> i will store in output_buffer. So, i had plhs[0] pointed to
> output buffer that will be passed back to Matlab. My
> output_buffer is not of fixed length. It may vary depending
> upon different content of binary file. So how do i declare
> mxCreateCharArray() of variable length.
> mxArray *mxCreateCharArray(int ndim, const int *dims);
> what will be ndim and *dim if they vary for different inputs
> (its not the same size as input). this is what i got till
> now. Your suggestions will be greatly appreciated.

input_buf is now exactly correct.

You are on the right track with mxCreateCharArray(). You need to know
what size array you want as you create it. You might move this
creation below the calculation of lSize, then you can just use that
(if that's the size you want!).

Other comments below.

> void mexFunction(int nlhs, mxArray *plhs[],
> int nrhs, const mxArray *prhs[])
> {
> char *input_buf;
> uint8 *output_buf;
> int buflen;
> int status;
> FILE *pFile;
> long lSize;
> size_t result;
>
> /* Output must be a string. */
> if (mxIsChar(plhs[0]) != 1)
> mexErrMsgTxt("Output must be a string.");
>
> /* Output must be a row vector. */
> if (mxGetM(plhs[0]) != 1)
> mexErrMsgTxt("Output must be a row vector.");

plhs[0] does not exist until you create it. Remove the above 2 tests,
they are not necessary, and will probably break anyway.

> /* Allocate memory for output strings. */
> plhs[0] = mxCalloc(150000, sizeof(char));
> //not sure how to use mxCreateCharArray()
> output_buf = mxGetPr(plhs[0]);

Replace the above section with:

int char_dims[2];
char_dims[0] = 1; /* First dimension: number of rows */
char_dims[1] = 150000; /* Second dimension: number of columns */
plhs[0] = mxCreateCharArray(2, char_dims);
output_buf = mxGetPr(plhs[0]);

Aside from putting this segment in a place where you know what size
you want, the rest looks fine.


-Peter

Subject: Re: reading binary file from mexFunction

From: basudha pradhan

Date: 12 Sep, 2007 20:42:36

Message: 7 of 8

Thanks Peter. It works now. That mex function was for
decoder. I have mex function for encoder . The encoder runs
ok in C but when i call it from matlab, the encoded file is
not right. So i am guessing my mex function is bad.

input to the mex function is char array(input_buf). then it
call C subroutine where it pass this input_buf and buflen
(length of input). C subroutine process the input and write
the output to a file. So there is no output variable for
mex function. this is what i tried.

void mexFunction(int nlhs, mxArray *plhs[],
                 int nrhs, const mxArray *prhs[])
{
   char *input_buf;
   int buflen;
   int status;
     
   /* Check for proper number of arguments. */
  if (nrhs != 1)
    mexErrMsgTxt("One input required.");
  
    
  /* Input must be a string. */
  if (mxIsChar(prhs[0]) != 1)
    mexErrMsgTxt("Input must be a string.");

  /* Input must be a row vector. */
  if (mxGetM(prhs[0]) != 1)
    mexErrMsgTxt("Input must be a row vector.");
    
  /* Get the length of the input string. */
  buflen = (mxGetM(prhs[0]) * mxGetN(prhs[0])) + 1;

  /* Allocate memory for input strings. */
  input_buf = mxCalloc(buflen, sizeof(char));
  
  /* Copy the string data from prhs[0] into a C string
   * input_buf. */
  status = mxGetString(prhs[0], input_buf, buflen);
  if (status != 0)
    mexWarnMsgTxt("Not enough space. String is
truncated.");
      
    /* Call the C subroutine. */
  MQ_enc(input_buf, buflen);
  mxFree(input_buf);
}

Your suggestions would be greatly appreciated.

Thanks
~Basudha

Subject: Re: reading binary file from mexFunction

From: Peter Boettcher

Date: 12 Sep, 2007 20:55:48

Message: 8 of 8

"basudha pradhan" <lucky_faith_911@hotmail.com> writes:

> Thanks Peter. It works now. That mex function was for
> decoder. I have mex function for encoder . The encoder runs
> ok in C but when i call it from matlab, the encoded file is
> not right. So i am guessing my mex function is bad.
>
> input to the mex function is char array(input_buf). then it
> call C subroutine where it pass this input_buf and buflen
> (length of input). C subroutine process the input and write
> the output to a file. So there is no output variable for
> mex function. this is what i tried.

OK, makes sense.

> void mexFunction(int nlhs, mxArray *plhs[],
> int nrhs, const mxArray *prhs[])
> {
> char *input_buf;
> int buflen;
> int status;
>
> /* Check for proper number of arguments. */
> if (nrhs != 1)
> mexErrMsgTxt("One input required.");
>
>
> /* Input must be a string. */
> if (mxIsChar(prhs[0]) != 1)
> mexErrMsgTxt("Input must be a string.");
>
> /* Input must be a row vector. */
> if (mxGetM(prhs[0]) != 1)
> mexErrMsgTxt("Input must be a row vector.");

All good.

> /* Get the length of the input string. */
> buflen = (mxGetM(prhs[0]) * mxGetN(prhs[0])) + 1;

Good. mxGetNumberOfElements() is a shortcut.

> /* Allocate memory for input strings. */
> input_buf = mxCalloc(buflen, sizeof(char));
>
> /* Copy the string data from prhs[0] into a C string
> * input_buf. */
> status = mxGetString(prhs[0], input_buf, buflen);

OK. MATLAB strings are funny. They are stored internally as 16-bit,
which is why you use mxGetString. In fact, I'd say this should work.
But, since what you probably really want to send is 8-bit ASCII
characters, the whole thing will be more efficient (and may work!) if
you cast the MATLAB string to an explicit integer type: uint8.

Then, you can use mxGetData(prhs[0]) just like mxGetPr() to grab a
pointer to the actual data, and process directly from there. That
means skip mxCalloc, mxGetString, etc.

> if (status != 0)
> mexWarnMsgTxt("Not enough space. String is
> truncated.");
>
> /* Call the C subroutine. */
> MQ_enc(input_buf, buflen);
> mxFree(input_buf);
> }

You might want to do some debugging by dumping the first and last 16
bytes of your input_buf before you call MQ_enc, and compare that to
your straight C version. Or even dump the full contents of input_buf
to a file in both places and compare.

-Peter

Tags for this Thread

Everyone's Tags:

Add a New Tag:

Separated by commas
Ex.: root locus, bode

What are tags?

A tag is like a keyword or category label associated with each thread. Tags make it easier for you to find threads of interest.

Anyone can tag a thread. Tags are public and visible to everyone.

Tag Activity for This Thread
Tag Applied By Date/Time
binary file read basudha pradhan 11 Sep, 2007 14:00:11
mex Walter Roberson 09 Sep, 2007 18:15:06
binary file basudha pradhan 09 Sep, 2007 15:00:20
mex basudha pradhan 09 Sep, 2007 15:00:20
rssFeed for this Thread

envelope graphic E-mail this page to a colleague

Public Submission Policy
NOTICE: Any content you submit to MATLAB Central, including personal information, is not subject to the protections which may be afforded information collected under other sections of The MathWorks, Inc. Web site. You are entirely responsible for all content that you upload, post, e-mail, transmit or otherwise make available via MATLAB Central. The MathWorks does not control the content posted by visitors to MATLAB Central and, does not guarantee the accuracy, integrity, or quality of such content. Under no circumstances will The MathWorks be liable in any way for any content not authored by The MathWorks, or any loss or damage of any kind incurred as a result of the use of any content posted, e-mailed, transmitted or otherwise made available via MATLAB Central. Read the complete Disclaimer prior to use.
Related Topics