diff tools/bufframe.c @ 0:5242703e91d3 tip

Initial checkin for AIM92 aimR8.2 (last updated May 1997).
author tomwalters
date Fri, 20 May 2011 15:19:45 +0100
parents
children
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/bufframe.c	Fri May 20 15:19:45 2011 +0100
@@ -0,0 +1,414 @@
+/*
+    bufframe.c    shifting AIM output frame buffer.
+    ----------
+
+
+
+Examples:
+
+1. To convert gennap output to multiple animated frames:
+
+gennap len=16ms display=off output=stdout file | \
+bufframe width=8ms frstep=0.2ms anim=on > file.sai
+gensai useprev=on top=1000 cegc             -(for landscape plot)
+genspl useprev=on top=1000 pensize=2 cegc   -(for spiral plot)
+
+    (Note: spirals look better in a square box, so you might use options:
+	   dencf=1 width=500 height=500 )
+
+2. To view the basilar membrane from a cross section, animating the waves on it.
+
+genbmm mincf=220 maxcf=660 len=8ms output=stdout display=off file | \
+bufframe width=1p frstep=1p Tran=on display=on anim=on > foo.sai
+gensai bott=-100 useprev=on mag=.2 foo
+
+or:
+
+genbmm mincf=220 maxcf=660 len=32ms output=stdout display=off file | \
+bufframe width=1p frstep=1p Tran=on Header=off > foo
+
+x11play -n75 -a500 foo
+
+*/
+
+
+
+#include <stdio.h>
+#include <math.h>
+#include "header.h"
+#include "options.h"
+#include "units.h"
+#include "strmatch.h"
+
+
+char applic[]     = "shifting AIM output frame buffer. " ;
+
+
+static char *helpstr,   *debugstr, *dispstr,    *anistr,    *transtr  ;
+static char *widthstr,  *shiftstr, *headerstr,  *framestr             ;
+
+static Options option[] = {
+    {   "help"      ,   "off"       ,  &helpstr     ,   "help"                                  , DEBUG   },
+    {   "debug"     ,   "off"       ,  &debugstr    ,   "debugging switch"                      , DEBUG   },
+    {   "width"     ,   "32ms"      ,  &widthstr    ,   "Width of image frame."                 , VAL     },
+    {   "frstep"    ,   "16ms"      ,  &shiftstr    ,   "Step between image frames."            , VAL     },
+    {   "frames"    ,   "min-max"   ,  &framestr    ,   "Select frames inclusively"             , VAL     },
+    {   "Transpose" ,   "off"       ,  &transtr     ,   "Transpose image frames"                , SETFLAG },
+    {   "Header"    ,   "on"        ,  &headerstr   ,   "Header (for gensai useprevious=on)."   , VAL     },
+    {   "display"   ,   "on"        ,  &dispstr     ,   "Display output image."                 , SETFLAG },
+    {   "animate"   ,   "off"       ,  &anistr      ,   "Animate cartoon."                      , SETFLAG },
+   ( char * ) 0 } ;
+
+
+int        frameheight,    framewidth,    frames,    framebytes ;
+int     Newframeheight, Newframewidth, Newframes, Newframebytes ;
+
+int        rows,    cols,    numframes ;
+int     Newrows, Newcols, Newnumframes ;
+
+int     samplerate  ;
+int     frstep      ;
+int     application ;
+int     startbytes  ;
+int     frshift     ;
+int     Transpose   ;
+
+main(argc, argv)
+int   argc ;
+char *argv[] ;
+{
+    FILE   *fp ;
+    char   *header, *Header() ;
+    short  *frame, *endframe ;
+    char   *val1, *val2 ;
+    int     i,j,k, a,b ;
+
+    fp = openopts( option,argc,argv ) ;
+    if ( !isoff( helpstr ) )
+	helpopts( helpstr, argv[0], applic, option ) ;
+
+    if ( ( header = ReadHeader( fp ) ) == (char *) 0 ) {
+	fprintf( stderr, "edframe: header not found\n" ) ;
+	exit( 1 ) ;
+    }
+    frameheight = HeaderInt( header, "frameheight" );
+    framewidth  = HeaderInt( header, "framewidth"  );
+    frames      = HeaderInt( header, "frames"      );
+    samplerate  = HeaderSamplerate( header );
+
+    if ( ( application = Applic( header) ) < 0 ) {
+	fprintf(stderr,"bufframe: application name not found in header\n" ) ;
+	exit( 1 ) ;
+    }
+    if ( Format( application ) != NAP ) {
+	fprintf(stderr,"bufframe: buffer for %s format not implemented\n", gen_applics[application] ) ;
+	exit( 1 ) ;
+    }
+    frame_to_matrix( NAP, &rows, &cols, &numframes, frameheight, framewidth, frames ) ;
+
+    Transpose    = ison( transtr ) ;
+    frstep       = to_p( shiftstr, samplerate ) ;
+    Newrows      = frameheight ;
+    Newcols      = to_p( widthstr, samplerate ) ;
+    Newnumframes = ( cols - Newcols ) / frstep + 1 ;    /* since: Newcols + ( Newnumframes - 1 ) * frstep <= cols */
+
+
+    /* Get limits on specified number of frames */
+
+    if ( getvals( framestr, &val1, &val2, "-" ) == BADVAL ) {
+	fprintf(stderr,"bufframe: bad frame selector [%s]\n", framestr ) ;
+	exit( 1 ) ;
+    }
+    if      ( ismin( val1 ) ) a = 0 ;
+    else if ( ismax( val1 ) ) a = Newnumframes - 1 ;
+    else if ( Units( val1 ) ) a = (int)to_p( val1, samplerate ) / frstep ;
+    else                      a = atoi( val1 ) ;
+
+    if ( isempty( val2 ) )    b = a ;
+    else if ( ismin( val2 ) ) b = 0 ;
+    else if ( ismax( val2 ) ) b = Newnumframes - 1 ;
+    else if ( Units( val2 ) ) b = (int)to_p( val2, samplerate ) / frstep ;
+    else                      b = atoi( val2 ) ;
+
+    if (a<0 || b>=Newnumframes || a>b) {
+	if ( b>=Newnumframes ) fprintf(stderr,"bufframe: bad frame selector [%d frames needed but %d available]\n", b+1, Newnumframes );
+	else                fprintf(stderr,"bufframe: bad frame selector \n" );
+	exit(1);
+    }
+
+    Newnumframes = b - a + 1 ;
+
+    framebytes   = Newrows * ( Newcols + ( Newnumframes - 1 ) * frstep ) * sizeof(short) ;
+
+    if ( Transpose )
+	matrix_to_frame( SAI, Newcols, Newrows, Newnumframes, &Newframeheight, &Newframewidth, &Newframes ) ;
+    else
+	matrix_to_frame( SAI, Newrows, Newcols, Newnumframes, &Newframeheight, &Newframewidth, &Newframes ) ;
+
+    Newframebytes  = Newframeheight * Newframewidth * sizeof(short) ;
+
+    if ( ison( headerstr ) )
+	WriteHeader( Header( header ), stdout ) ;
+
+
+    /* Allocate space for framebytes of data */
+
+    if ( ( frame = (short *)malloc( framebytes ) ) == NULL ) {
+	fprintf( stderr, "bufframe: malloc out of space\n" ) ;
+	exit( 1 ) ;
+    }
+
+    frshift = frstep * rows ;
+
+    /* Seek past `a' frames in blocks of framebytes */
+
+    startbytes = a * frshift * sizeof(short) ;
+    for (i=framebytes ; i < startbytes ; i += framebytes)
+	if ( fread( frame, framebytes, 1, fp ) == NULL ) {
+	    fprintf(stderr,"bufframe: missing data after header\n");
+	    exit(1);
+	}
+    if ( (startbytes -= (i - framebytes)) > 0 )
+	if ( fread( frame, startbytes, 1, fp ) == NULL ) {
+	    fprintf(stderr,"bufframe: missing data after header\n");
+	    exit(1);
+	}
+
+    /* Read framebytes of data */
+
+    if ( fread( frame, framebytes, 1, fp ) == NULL ) {
+	fprintf(stderr,"bufframe: insufficient data after header\n");
+	exit(1);
+    }
+    fclose( fp ) ;
+
+    endframe = frame + Newframes * frshift ;
+
+    fprintf(stderr,"bufframe: %d frames   [height=%d  width=%d]\n", Newnumframes, Newframeheight, Newframewidth );
+
+    if ( ison( debugstr ) ) {
+	fprintf( stderr,"   frameheight=%3d    framewidth=%3d       frames=%3d    framebytes=%d\n",     frameheight,    framewidth,    frames,    framebytes ) ;
+	fprintf( stderr,"Newframeheight=%3d Newframewidth=%3d    Newframes=%3d Newframebytes=%d\n",  Newframeheight, Newframewidth, Newframes, Newframebytes ) ;
+	fprintf( stderr,"          rows=%3d          cols=%3d    numframes=%d\n",     rows,    cols,    numframes ) ;
+	fprintf( stderr,"       Newrows=%3d       Newcols=%3d Newnumframes=%d\n",  Newrows, Newcols, Newnumframes ) ;
+	fprintf( stderr,"frstep=%d  startbytes=%d frshift=%d\n",  frstep, startbytes, frshift ) ;
+	exit( 1 ) ;
+    }
+
+    if ( Transpose ) {
+
+	for (  ; frame < endframe ; frame += frshift )
+	    for ( j=0 ; j < Newcols ; j++ )
+		fwrite( frame + j*frameheight, sizeof(short), Newrows, stdout ) ;
+    }
+
+    else {
+	for (  ; frame < endframe ; frame += frshift )
+	    for (j=0 ; j < Newrows ; j++)
+		for (k=0 , i=j ; k < Newcols ; k++, i+=frameheight)
+		    fwrite( &frame[i], sizeof(short), 1, stdout );
+    }
+    fprintf(stderr,"bufframe: done\n" );
+}
+
+
+
+/* Return 1 if the str has appended units. Otherwise return 0.             */
+/* (A freqency specifier with no units is interpreted as a channel number) */
+
+Units(str)
+char *str ;
+{
+    char *eptr = str + strlen( str ) ;
+
+    if( isdigit( *--eptr ) ) return 0 ; /* last char is digit, so no units */
+    else return 1 ;
+}
+
+
+/*
+   Copy the original (NAP format) header to a new sai header, changing in order:
+     frstep
+     frames
+     framewidth
+     frameheight
+     framebytes
+     animate
+     display
+   Copy application name "sai" into the version string.
+   Finally, update the new header_bytes, and return the new header.
+*/
+
+char *Header( oldheader )
+char *oldheader ;
+{
+    char *saiheader;
+    char *p0, *p1, *p2, *s, str[64];
+
+    saiheader = (char *)malloc( strlen(oldheader) + 256 ) ;
+
+    p0 = saiheader ;
+    p1 = oldheader ;
+
+    /* copy to first item after the header_bytes */
+
+    p2 = HeaderString( oldheader , "header_bytes" ) ;
+    while( p1 < p2 )
+	*p0++ = *p1++ ;
+    while (*p1 != '\n')
+	*p0++ = *p1++ ;
+    *p0++ = *p1++;
+
+    /* insert frstep_aid at top of new header */
+
+    sprintf( str,"frstep_aid=%s\n", shiftstr ) ;
+    for (s = str ; *s != '\n' ; )
+	*p0++ = *s++;
+    *p0++ = *s;
+
+
+    /** copy up to channels_afb (if transpose changes apparent number of channels) **/
+
+    if ( Transpose ) {
+	p2 = HeaderString( oldheader , "channels_afb" ) ;
+	while( p1 < p2 )
+	    *p0++ = *p1++ ;
+
+	sprintf(str,"%d\n", Newframeheight);
+	for (s = str ; *s != '\n' ; )
+	    *p0++ = *s++;
+	*p0++ = *s;
+	while (*p1 != '\n')
+	    *p1++;
+	*p1++;
+    }
+
+
+    /** copy up to frames **/
+
+    p2 = HeaderString( oldheader , "frames" ) ;
+    while( p1 < p2 )
+	*p0++ = *p1++ ;
+
+    sprintf(str,"%d\n", Newframes);
+    for (s = str ; *s != '\n' ; )
+	*p0++ = *s++;
+    *p0++ = *s;
+    while (*p1 != '\n')
+	*p1++;
+    *p1++;
+
+
+    /** copy up to framewidth **/
+
+    p2 = HeaderString( oldheader , "framewidth" ) ;
+    while ( p1 < p2 )
+	*p0++ = *p1++ ;
+
+    sprintf(str,"%d\n", Newframewidth);
+    for (s = str ; *s != '\n' ; )
+	*p0++ = *s++;
+    *p0++ = *s;
+    while (*p1 != '\n')
+	*p1++;
+    *p1++;
+
+
+    /** copy up to frameheight **/
+
+    p2 = HeaderString( oldheader , "frameheight" ) ;
+    while ( p1 < p2 )
+	*p0++ = *p1++ ;
+
+    sprintf(str,"%d\n", Newframeheight);
+    for (s = str ; *s != '\n' ; )
+	*p0++ = *s++;
+    *p0++ = *s;
+    while (*p1 != '\n')
+	*p1++;
+    *p1++;
+
+
+    /** copy up to framebytes **/
+
+    p2 = HeaderString( oldheader , "framebytes" ) ;
+    while ( p1 < p2 )
+	*p0++ = *p1++ ;
+
+    sprintf(str,"%d\n", Newframebytes);
+    for (s = str ; *s != '\n' ; )
+	*p0++ = *s++;
+    *p0++ = *s;
+    while (*p1 != '\n')
+	*p1++;
+    *p1++;
+
+
+    /** copy up to animate_ctn **/
+
+    p2 = HeaderString( oldheader , "animate_ctn" ) ;
+    while ( p1 < p2 )
+	*p0++ = *p1++ ;
+
+    sprintf(str,"%s\n", anistr );
+    for (s = str ; *s != '\n' ; )
+	*p0++ = *s++;
+    *p0++ = *s;
+    while (*p1 != '\n')
+	*p1++;
+    *p1++;
+
+
+    /** copy up to display **/
+
+    p2 = HeaderString( oldheader , "display" ) ;
+    while ( p1 < p2 )
+	*p0++ = *p1++ ;
+
+    sprintf(str,"%s\n", dispstr );
+    for (s = str ; *s != '\n' ; )
+	*p0++ = *s++;
+    *p0++ = *s;
+    while (*p1 != '\n')
+	*p1++;
+    *p1++;
+
+
+    /** copy rest of header **/
+
+    p2 = HeaderString( oldheader , "Version" ) ;
+    while ( p1 < p2 )
+	*p0++ = *p1++ ;
+
+       /** ( copy application name "sai" into header ) **/
+
+    if ( ( p2 = ApplicString( oldheader ) ) == (char *)0 )  {
+	fprintf(stderr,"bufframe: application name not found in header\n");
+	exit( 1 ) ;
+    }
+    while ( p1 < p2 )
+	*p0++ = *p1++ ;
+
+    *p0++ = 's' ; *p0++ = 'a' ; *p0++ = 'i' ;
+    p1 += 3 ;
+
+    while (*p1 != '\n')
+	*p0++ = *p1++ ;
+    *p0++ = *p1++ ;
+
+
+    /** update header_bytes **/
+
+    sprintf(str, "%0*d", 7, p0-saiheader);
+    p0 = HeaderString( saiheader , "header_bytes" ) ;
+    s = str;
+    while(*p0 != '\n')
+	*p0++ = *s++ ;
+
+
+    return saiheader;
+}
+
+
+
+