view tools/hdr.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 source
/*
    hdr.c   Operations on AIM header.
    -----

  Usage:  hdr [options] [file]

  Read an AIM output file. If no filename is given then input is expected
  on the stdin. The input from AIM is expected to consist of an AIM header
  followed by some data.

  Options take the form:  <name>=<value>
  and abbreviated option names are recognised provided they are unambiguous
  wrt other names in the input header.

  The operations are header stripping, querying, or modifying:-

  1. If no options are given, then strip the header and write the data which
  follows the header on the stdout.
  Eg:
	gensai output=stdout ... | hdr | ...

  2. An empty value field (ie. <name>=) is interpreted as a query, and the
  corresponding option value found in the header is printed on the stderr.
  Eg., to query the value of option pwidth_aid:

	hdr pwid=  file

  The special option names are:

	"all"       causes all option values to be printed.
	"format"    causes the format of the AIM output file to be printed.

  3. Each option of the form <name>=<value> is substituted for the corresponding
  option found in the input header. A new header is constructed using the
  input header and all given substitutions, and the new header is written
  on the stdout, followed by the data which follows the input header.
  Eg., to change the value of pwidth_aid to 32ms:

	hdr pwid=32ms  file >  file2

*/

#include <stdio.h>
#include <math.h>
#include "header.h"
#include "strmatch.h"

char  **nameptr, *tmpptr ;
int    *namespn,  tmpspn ;

main(argc, argv)
int   argc ;
char *argv[] ;
{
    FILE   *fp=stdin, *fopen() ;
    char   *header, *Header(), str[64], *s, c ;
    int     i, j, min ;
    int     modify=0 ;
    short   data ;

    namespn  = ( int *)malloc( (argc-1) * sizeof(int) ) ;
    nameptr  = (char **)malloc( (argc-1) * sizeof(char *) ) ;

    if ( iststr( "-h", argv[argc-1] ) || iststr( "help=", argv[argc-1] ) )
	printhelp();

    /* search for "=" to get span of each option name, and check option */

    if ( argc == 1 || strchr( argv[argc-1], '=' ) != (char *)0 )
	fp = stdin ;
    else if ( ( fp = fopen( argv[--argc], "r" ) ) == (FILE *)0 ) {
	fprintf(stderr, "can't open %s\n", argv[argc] ) ;
	exit( 1 ) ;
    }

    for ( i=1 ; i<argc ; i++ ) {

	if ( iststr( "-h", argv[argc-1] ) || iststr( "help=", argv[argc-1] ) )
	    printhelp();

	if ( ( namespn[i] = strspnbrk( argv[i], "=" ) ) == ( -1 ) ) {
	    fprintf(stderr,"hdr: [%s] incorrect option syntax (<name>=<value>)\n", argv[i] );
	    exit( 1 ) ;
	}
	else if ( namespn[i] == strlen( argv[i] ) - 1 ) {   /* query */
	    argv[i][namespn[i]] = '\0' ;
	    namespn[i] = 0 ;            /* query denoted by zero span */
	}
    }

    if ( ( header = ReadHeader( fp ) ) == (char *) 0 ) {
	fprintf(stderr,"hdr: header not found\n");
	exit(1);
    }

    /* if no options, then just strip header */

    if ( argc == 1 ) {
	while ( fread(&c, sizeof(char),1,fp) )
	    fwrite(&c,sizeof(char),1,stdout);
	fclose( fp ) ;
	exit( 0 ) ;
    }


    /* find the position of each option name in the header */

    for ( i=1 ; i<argc ; i++ ) {


	if ( namespn[i] > 0 ) {
	    strncpy( str, argv[i], namespn[i] ) ;
	    str[namespn[i]] = '\0' ;
	    if ( ( nameptr[i] = HeaderStrings( header , str ) ) == (char *)0 ) {
		fprintf(stderr,"hdr: option [%s] ambiguous or not found in header\n", str);
		exit(1);
	    }
	    modify++ ;
	}

	else {
	    if ( isstr( argv[i], "all" ) )
		WriteHeader( header, stderr ) ;
	    else if ( isstr( argv[i], "format" ) )
		WriteFormat( header, stderr ) ;
	    else {
		if ( ( s = HeaderValueString( header, argv[i] ) ) == (char *)0 )
		    fprintf( stderr,"option %s ambiguous or not found\n", argv[i] ) ;
		else
		    fprintf( stderr, "%s=%s\n", HeaderNameString( header, argv[i] ), s ) ;
	    }
	}
    }

    if ( modify ) {

	/* sort the name lists into the order the names appear in the header */

	for ( i=1 ; i<argc ; i++ ) {
	    if ( namespn[i] > 0 ) {
		min = i ;
		for ( j=i+1 ; j<argc ; j++ ) {
		    if ( nameptr[j] < nameptr[min] )
			min = j ;
		}
		if ( min != i ) {
		    tmpptr = nameptr[i] ; nameptr[i] = nameptr[min] ; nameptr[min] = tmpptr ;
		    tmpptr = argv[i]    ; argv[i]    = argv[min]    ; argv[min]    = tmpptr ;
		    tmpspn = namespn[i] ; namespn[i] = namespn[min] ; namespn[min] = tmpspn ;
		}
	    }
	}

	header = Header( header, argc, argv ) ;
	WriteHeader( header, stdout );

	/* echo the rest of the file */

	while ( fread( &data, sizeof(short), 1, fp ) != NULL )
	    fwrite( &data, sizeof(short), 1, stdout) ;

    }
    fclose( fp ) ;
}



/*
   Copy the original header to a new header, changing the ordered options.
   Then update the new header_bytes, and return the new header.
*/

char *Header( oldheader, argc, argv )
char *oldheader ;
int   argc ;
char *argv[] ;
{
    char *newheader;
    char *p0, *p1, *p2, *s, str[64];
    int   i ;

    newheader = (char *)malloc( strlen(oldheader) + 64 ) ;

    p0 = newheader ;
    p1 = oldheader ;

    /** copy up to each new option **/

    for ( i=1 ; i<argc ; i++ ) {

	if ( namespn[i] > 0 ) {

	    p2 = nameptr[i] ;
	    while( p1 < p2 )
		*p0++ = *p1++ ;

	    sprintf(str,"%s\n", argv[i] + namespn[i] + 1 );
	    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++ ;

    while (*p1 != '\n')
	*p0++ = *p1++ ;
    *p0++ = *p1++ ;


    /** update header_bytes **/

    sprintf(str, "%0*d", 7, p0-newheader);
    p0 = HeaderString( newheader , "header_bytes" ) ;
    s = str;
    while(*p0 != '\n')
	*p0++ = *s++ ;


    return newheader;
}


WriteFormat( header, fp )
char  *header ;
FILE  *fp     ;
{
    int   applic, format, rows, cols, frames ;

    if ( ( applic = Applic( header) ) < 0 ) {
	fprintf(stderr,"hdr: application name not found in header\n" ) ;
	exit( 1 ) ;
    }
    format = Format( applic ) ;

    frame_to_matrix( format, &rows, &cols, &frames,
				HeaderInt( header, "frameheight" ),
				HeaderInt( header, "framewidth"  ),
				HeaderInt( header, "frames"      )  ) ;

    fprintf( fp, "gen%s output file\n", gen_applics[ applic ] ) ;

    switch ( format ) {
	case 0 : fprintf( fp, "wave format (array of time points)\n" ) ;
		 break ;
	case 1 : fprintf( fp, "activity-pattern format (by columns, lowest centre-frequency first in each)\n" ) ;
		 break ;
	case 2 : fprintf( fp, "spectrogram format (by columns, lowest centre-frequency first in each)\n" ) ;
		 break ;
	case 3 : fprintf( fp, "excitation-pattern format (array of frequency points per frame)\n" ) ;
		 break ;
	case 4 : fprintf( fp, "auditory-image format (by rows, lowest centre-frequency first per frame)\n" ) ;
		 break ;
    }

    fprintf( fp, "       rows (channels) = %d  per frame\n", rows   ) ;
    fprintf( fp, "       cols (samples)  = %d  per frame\n", cols   ) ;
    fprintf( fp, "       frames          = %d\n", frames ) ;
    fprintf( fp, "       framesize       = %d bytes\n", rows*cols*2 ) ;

}


printhelp()
{
    fprintf(stderr,"hdr: Operations on AIM header.\n");
    fprintf(stderr,"Usage: hdr [options] [file]\n");
    fprintf(stderr,"options         comment      \n");
    fprintf(stderr,"----------      ----------   \n");
    fprintf(stderr,"                strip header (when no options given) \n");
    fprintf(stderr,"<name>=         query header (for each empty options field) \n");
    fprintf(stderr,"<name>=<value>  modify header by substituting given values\n");
    fprintf(stderr,"\n");
    fprintf(stderr,"option names for special queries: \n");
    fprintf(stderr,"all=            query all options in header \n");
    fprintf(stderr,"format=         query format of AIM output file \n");
    exit( 0 ) ;
}