/* * LIBML library - read, write and manipulate MATLAB MAT-files * Copyright (C) 1994 Michael J. Maurer * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Library General Public License for more details. * * You should have received a copy of the GNU Library General Public * License along with this library; if not, write to the Free * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * * Michael Maurer * Durand Bldg - Room 232 * Stanford, CA 94305-4055 * (415) 723-1024 */ /****************************************************************************** mlread.c Reads Matlab (level 1) format MAT files. Written by Michael Maurer (maurer@nova.stanford.edu), after examples by J. Little in the Matlab 3.5 documentation. Those portions not derived from the Mathworks code are Copyright (c) 1993, Michael Maurer (maurer@nova.stanford.edu). ******************************************************************************/ /* $Log$ */ #include #include #include "libml.h" #include "libml.p" #include "libmlver.h" #include "libmisc.h" /****************************************************************************** mlreadh Reads in header only of a MAT-file matrix. Returns 0 if the read is successful, 1 if an end-of-file or read error is encountered, and -1 if the header contains invalid data. Upon exit, the file pointer is positioned to read the data object itself. If mlreadh() determines that the input file is in foreign order, the header will be swapped to native format. The 'type' value should remain unchanged until 'mlreadd' is called, which will then interpret the input data object in the correct manner and possibly update 'type'. ******************************************************************************/ int mlreadh(fp,type,pname,mrows,ncols,imagf) FILE *fp; /* File pointer */ int *type; /* Type flag: see reference section of guide */ char *pname; /* pointer to matrix name */ int *mrows; /* row dimension */ int *ncols; /* column dimension */ int *imagf; /* imaginary flag */ { Fmatrix x,y; int namlen; /* Read header into Fmatrix structure */ if (fread(&x,sizeof(Fmatrix),1,fp) != 1) return 1; /* check for foreign byte-order */ if (x.type>4000 || x.namlen>100 || (x.imagf!=0 && x.imagf!=1)) { swapb_4((unsigned char *)&x,(unsigned char *)&y,5); if (y.type>4000 || y.namlen>100 || (y.imagf!=0 && y.imagf!=1)) return -1; x=y; } *type = x.type; *mrows = x.mrows; *ncols = x.ncols; *imagf = x.imagf; namlen = x.namlen; /* Read name of matrix */ if (fread(pname,sizeof(char),namlen,fp) != namlen) return 1; return 0; } /****************************************************************************** mlreadd Reads in data only of MAT-file data object. The object's header must already have been read by mlreadh(). Returns 0 if the read is successful and nonzero if an end-of-file or read error is encountered. The 'type' variable may be changed if the data object is stored in a foreign format; mlreadd() always translates to native format and then updates the value of 'type'. ******************************************************************************/ int mlreadd(fp,type,mrows,ncols,imagf,preal,pimag) FILE *fp; /* File pointer */ int *type; /* Type flag: see reference section of guide */ int mrows; /* row dimension */ int ncols; /* column dimension */ int imagf; /* imaginary flag */ void **preal; /* returned pointer to real data */ void **pimag; /* returned pointer to imag data */ { int mn,dsize,M,O,P,T,err; int typei; /* type of data stored in file */ int typeo; /* type of data after loading to memory */ typei= *type; mn=mrows*ncols; dsize=mltype(typei,&M,&O,&P,&T); typeo=ML_TYPE+100*O+10*P+T; /* Read real part of matrix from file */ if ((*preal = malloc(mn*dsize))==NULL) { fprintf(stderr,"\n%s\nError: Variable too big to load\n",ml_versid); return 1; } if (fread(*preal,dsize,mn,fp) != mn) { free(*preal); return 2; } if (err=mlcvt(*preal,*preal,mn,typei,typeo)) { free(*preal); return err; } /* Read imaginary part of matrix from file, if it exists */ if (imagf) { if (!(*pimag = malloc(mn*dsize))) { fprintf(stderr,"\n%s\nError: Variable too big to load\n",ml_versid); free(*preal); return 3; } if (fread(*pimag,dsize,mn,fp) != mn) { free(*pimag); free(*preal); return 4; } if (err=mlcvt(*pimag,*pimag,mn,typei,typeo)) { free(*pimag); free(*preal); return err; } } *type=typeo; return 0; } /****************************************************************************** mlread Combines mlreadh() and mlreadd() to read an entire matlab variable from the file fp. Returns nonzero on failure. ******************************************************************************/ int mlread(fp,type,mrows,ncols,imagf,pname,preal,pimag) FILE *fp; /* File pointer */ int *type; /* Type flag: see reference section of guide */ int *mrows; /* row dimension */ int *ncols; /* column dimension */ int *imagf; /* imaginary flag */ char *pname; /* pointer to matrix name */ void **preal; /* pointer to real data */ void **pimag; /* pointer to imag data */ { int err; err=mlreadh(fp,type,pname,mrows,ncols,imagf); if (!err) err=mlreadd(fp,type,*mrows,*ncols,*imagf,preal,pimag); return err; }