Mercurial > hg > aim92
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; +} + + + +