/* * 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 */ /****************************************************************************** mlcvt.c Provides data-format conversions for matlab MAT file library. Copyright (c) 1993 by Michael Maurer (maurer@nova.stanford.edu). ******************************************************************************/ /* $Log$ */ #include #include #include #include "libml.h" #include "libml.p" #include "libmisc.h" /****************************************************************************** mltype Parses type value into decimal digits, and returns the size in bytes of a single element of this type. Parses the matlab TYPE parameter in matlab format files. Returns 5 values: M Machine ID: 0=PC,MIPS, 1=Sun, 2=VAX, 3=VAX G-FLOAT O 0=column-major order 1=row-major order P 0 8-byte floating-point 1 4-byte floating-point 2 32-bit signed integer 3 16-bit signed integer 4 16-bit unsigned integer 5 8-bit unsigned integer T 0=numerical data 1=string The returned size may be incorrect for VAX-G float: what is the correct answer? We don't normally handle VAX-G. ******************************************************************************/ int mltype(type, Mp, Op, Pp, Tp) int type, *Mp, *Op, *Pp, *Tp; { int dsize,M,O,P,T; T = type%10; type -= T; P = (type%100)/10; type -= P; O = (type%1000)/100; type -= O; M = (type%10000)/1000; switch (P*10) { case ML_DOUBLE: dsize=sizeof(double); break; case ML_FLOAT: dsize=sizeof(float); break; case ML_INT: dsize=sizeof(long); break; case ML_SHORT: dsize=sizeof(short); break; case ML_USHORT: dsize=sizeof(unsigned short); break; case ML_UCHAR: dsize=sizeof(unsigned char); break; default: fprintf(stderr, "[mltype] Illegal P type: %d\n", P); exit(1); } if (Mp) *Mp=M; if (Op) *Op=O; if (Pp) *Pp=P; if (Tp) *Tp=T; return dsize; } /****************************************************************************** mlborder Returns byte-order associated with data format 'type'. See libml.h for definitions of return values. ******************************************************************************/ int mlborder(type) int type; { int M,O,P,T; (void)mltype(type,&M,&O,&P,&T); switch (M*1000) { case ML_LIT_IEEE: return ML_LITEND; case ML_BIG_IEEE: return ML_BIGEND; case ML_LIT_VAXD: return ML_LITEND; case ML_LIT_VAXG: return ML_LITEND; default: return ML_UNKEND; } } /****************************************************************************** mlcast Uses default C cast rules to convert from one type to another of equal or lesser precision. If an overflow occurs, it's up to C to make the cast. Works in place if converting to lesser precision. Cannot cast to greater precision in place because converted values would overwrite old vales before they were used. iVP is pointer to input data (must be in native format) oVP is pointer to output data (will be in native format) itype is input matlab data type (see libml.h) otype is output matlab data type (see libml.h) ******************************************************************************/ static int mlcast(iVP,oVP,n,itype,otype) void *iVP,*oVP; /* input/output pointers */ int n; /* number of elements */ int itype,otype; /* input/output data types */ { int k,idsize,odsize; int iM,iO,iP,iT; int oM,oO,oP,oT; unsigned char *iUC=(unsigned char *)iVP; unsigned char *oUC=(unsigned char *)oVP; unsigned short *iUS=(unsigned short *)iVP; unsigned short *oUS=(unsigned short *)oVP; short *iS=(short *)iVP; short *oS=(short *)oVP; int *iI=(int *)iVP; int *oI=(int *)oVP; float *iF=(float *)iVP; float *oF=(float *)oVP; double *iD=(double *)iVP; double *oD=(double *)oVP; idsize=mltype(itype,&iM,&iO,&iP,&iT); odsize=mltype(otype,&oM,&oO,&oP,&oT); if (iM*1000!=ML_TYPE || oM*1000!=ML_TYPE) { fprintf(stderr,"[mlcast] all data must be in native format\n"); return -1; } if (iVP==oVP && odsize>idsize) { fprintf(stderr,"[mlcast] cannot cast in place to larger type\n"); return -1; } iP*=10; oP*=10; switch (iP) { case ML_DOUBLE: switch (oP) { case ML_DOUBLE: memcpy(oVP,iVP,n*idsize); break; case ML_FLOAT: for (k=0; k