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