/* * 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 */ static char rcsid[]="$Id: mat2mat.c,v 1.0 1992/04/15 23:04:56 maurer Stable $"; /****************************************************************************** mat2mat.c Copies from one matlab MAT file to another. Can extract selected variables by matching their names as a regular expression. Can convert between foreign and native data formats. Can promote or demote data types (for example, double <-> float). (Format and type conversion together requires two passes.) Type 'mat2mat -h' for usage. Example usage: mat2mat -n foreign.mat | mat2mat -P 0 > nativedouble.mat ******************************************************************************/ /* $Log: mat2mat.c,v $ * Revision 1.0 1992/04/15 23:04:56 maurer * Initial revision * */ #include #include #include #include #include "libml.h" #include "libml.p" #define MAT2MAT_C #include "mat2mat.p" /****************************************************************************** define HAVE_GNU_REGEX if you have it. otherwise, we will use built-in ed(1) style regex. ******************************************************************************/ /* #define HAVE_GNU_REGEX */ #ifdef HAVE_GNU_REGEX #include "regex.h" static regex_t pattern; #else int re_exec(); char *re_comp(); #endif static char *omode="w"; static int nskip=0; static int omach= -1; static int odata= -1; static char *inname=NULL, *outname=NULL, *regexp=".*"; static FILE *infile=NULL, *outfile=NULL; char *prog; int main(argc, argv) int argc; char *argv[]; { int match, err; void *pr, *pi, *opr, *opi; char pname[20]; int itype, mrows, ncols, imagf, otype; int isize,osize,offset,N,M,O,P,T; char msg1[256],*msg2; init(argc,argv); #ifdef HAVE_GNU_REGEX /* use GNU POSIX matching */ if (err=regcomp(&pattern,regexp,REG_EXTENDED)) { regerror(err,&pattern,msg1,sizeof(msg1)); fprintf(stderr,"%s: regcomp failed on %s: %s\n",prog,regexp,msg1); return 1; } #else /* use ed(1) style matching */ if (msg2=re_comp(regexp)) { fprintf(stderr,"%s: re_comp failed on %s: %s\n",prog,regexp,msg2); return 1; } #endif open_files(); while (!mlreadh(infile, &itype, pname, &mrows, &ncols, &imagf)) { pr=pi=opr=opi=NULL; N=mrows*ncols; isize = mltype(itype, &M, &O, &P, &T); offset = isize*N; if (imagf) offset *= 2; #ifdef HAVE_GNU_REGEX match = !regexec(&pattern,pname,0,NULL,0); #else match = re_exec(pname); #endif if (match) { /* we want this variable */ otype = (omach<0 ? M : omach)*1000 + O*100 + (odata<0 ? P : odata)*10 + T; if (itype == otype) { /* no conversion is necessary: just copy the bits */ /* write the header */ if (err=mlwriteh(outfile, otype, pname, mrows, ncols, imagf)) { fprintf(stderr,"[main] mlwriteh error %d\n",err); return 1; } /* copy the data bits */ if (err=fcopyn(infile,outfile,offset)) { fprintf(stderr,"[main] fcopyn error %d\n",err); return 1; } } else { /* we must read into memory and convert data formats */ /* read the data */ if (err=mlreadd(infile,&itype,mrows,ncols,imagf,&pr,&pi)) { fprintf(stderr,"[main] mlreadd error %d\n",err); return 1; } /* check for new size of data */ osize = mltype(otype,NULL,NULL,NULL,NULL); if (osize > isize) { /* new data format requires even more memory */ if ((opr=malloc(N*osize))==NULL) { fprintf(stderr,"[main] malloc failed\n"); return 1; } if (imagf && (opi=malloc(N*osize))==NULL) { fprintf(stderr,"[main] malloc failed\n"); return 1; } } else { opr=pr; opi=pi; } /* convert the data */ if (err=mlcvt(pr,opr,N,itype,otype)) { fprintf(stderr,"[main] mlcvt failed %d\n",err); return 1; } if (imagf && (err=mlcvt(pi,opi,N,itype,otype))) { fprintf(stderr,"[main] mlcvt failed %d\n",err); return 1; } /* write the converted data */ if (err=mlwrite(outfile,otype,pname,mrows,ncols,imagf,opr,opi)) { fprintf(stderr,"[main] mlwrite error %d\n",err); return 1; } if (pr) free(pr); if (pi) free(pi); if (opr && opr!=pr) free(opr); if (opi && opi!=pi) free(opi); } } else { /* skip this variable */ if (fseek(infile, offset, 1)) { fprintf(stderr,"[main] fseek failed\n"); return 1; } } } close_files(); return 0; } static void init(argc,argv) int argc; char *argv[]; { extern int optind; extern char *optarg; int c, err=0, getopt(); /* Get options and arguments */ prog = argv[0]; while ((c = getopt(argc, argv, "anM:P:r:s:")) != EOF) switch (c) { case 'a': omode = "a"; break; case 'n': omach = ML_TYPE/1000; break; case 'M': omach = strtol(optarg,NULL,10); break; case 'P': odata = strtol(optarg,NULL,10); break; case 'r': regexp = optarg; break; case 's': nskip = strtol(optarg,NULL,10); break; default: err++; } if (err) { fprintf(stderr, "\nUsage : %s [options] [infile [outfile]]\n\n", prog); fprintf(stderr, "Extracts named objects in matlab .mat file into another .mat file.\n"); fprintf(stderr, "Specifying .* as -r target or omitting -r means copy all variables.\n"); fprintf(stderr, "The target is a regular expression, either POSIX or ed(1).\n"); fprintf(stderr, "Options:\n"); fprintf(stderr, "\t-a Append to output file (default is overwrite)\n"); fprintf(stderr, "\t-r targ Only extract variables matching regexp targ\n"); fprintf(stderr, "\t-s nskip Skip nskip bytes in input file before reading\n"); fprintf(stderr, "\t-n Convert to native format (same as -c %d)\n",ML_TYPE/1000); fprintf(stderr, "\t-M mach Convert to machine format 'mach', one of:\n"); fprintf(stderr, "\t %d Little-endian IEEE (PC, DecRisc, Intel, Mips)\n",ML_LIT_IEEE/1000); fprintf(stderr, "\t %d Big-endian IEEE (Sun, Apollo, Mac, Motorola)\n",ML_BIG_IEEE/1000); fprintf(stderr, "\t %d Little-endian VAX-D (DecVAX)\n",ML_LIT_VAXD/1000); fprintf(stderr, "\t %d Little-endian VAX-G (DecVAX)\n",ML_LIT_VAXG/1000); fprintf(stderr, "\t-P dtype Convert to data format 'dtype', one of:\n"); fprintf(stderr, "\t %d double\n",ML_DOUBLE/10); fprintf(stderr, "\t %d float\n",ML_FLOAT/10); fprintf(stderr, "\t %d long\n",ML_INT/10); fprintf(stderr, "\t %d short\n",ML_SHORT/10); fprintf(stderr, "\t %d unsigned short\n",ML_USHORT/10); fprintf(stderr, "\t %d unsigned char\n",ML_UCHAR/10); exit(-1); } if (optind0) fseek(infile, nskip, 0); if (!outname || (strlen(outname) == 0) || (!strcmp(outname, "stdout"))) outfile = stdout; else if ((outfile = fopen(outname, omode)) == NULL) { fprintf(stderr,"%s: [open_files] %s\n", prog, outname); exit(1); } } void close_files() { fclose(infile); fclose(outfile); }