Mercurial > hg > aim92
view tools/header.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
/*************************************************************************** Utilities for model output headers. A header is an ASCII desciption which summarises the state of a process by giving a list of parameter values etc etc.. Each parameter is described on a separate line, and the header consists of several lines of the general form: <ASCII description> = <value>\n For example, the first five lines of the header generated by a command line "gensai -header fname" is as follows: header_bytes=0000532 scale_sai=0.25 imagedurn_sai=16 decayrate_sai=10 cgmdecay=24 ... date=Thu Jan 11 00:19:41 WET 1990\n \000 This string is written onto the front of the file with padding if desired before any data is written. The header can be of any length and contain any combination of non null characters. Header items are identified by the string on the left of the equals symbol and their value is represented by the string on the remainder of that line. The first line is always the HEADER_STRING (ie. header_bytes=....\n) which gives the length of the header. Synopsis of utilities: ---------------------- char *ReadHeader( fp ) FILE *fp ; WriteHeader(header,fp) char *header; FILE *fp; char *HeaderString( header, name ) char *header, *name ; char *HeaderStringOnly( header, name ) char *header, *name ; double HeaderDouble( header, name ) char *header, *name ; double HeaderInt( header, name ) char *header, *name ; void FreeHeader( header ) char *header ; ReadHeader() reads a header (if it exists ) from the file into memory and returns a pointer to the header in memory allocated for storing the header. It returns a null pointer if no header is found. It leaves the fp pointing to the data which follows the header. WriteHeader() writes the given header on the given file stream. HeaderString() simply searches through the header for values the user requests and returns a pointer to the beginning of the value. It returns a null pointer if the required string is not found. HeaderStringOnly() returns a pointer to an allocated string that contains only the value rather than a pointer to a string that includes the all the rest of the header (which is what HeaderString() returns). It returns a null pointer if the required string is not found. HeaderDouble() converts values to Doubles. HeaderInt() converts values to Ints. FreeHeader() frees the space allocated for a header by ReadHeader. Example: ------- A simple example of the use of the header utility routines to read the sai dimensions from a header would be: (This assumes a ".sai" file generated by a command like "gensai -header") #include <stdio.h> #include <math.h> #include "header.c" char *header = ReadHeader(fp); fp is file-pointer to ".sai" file int frameheight = HeaderInt(header,"frameheight"); num chans int framewidth = HeaderInt(header,"framewidth"); sai duration char *name = "frameheight"; printf( "%s=%s\n", name, HeaderStringOnly( header, name ) ) ; ****************************************************************************/ #include <stdio.h> /* #include <strings.h> */ #include <string.h> #include <malloc.h> #include "header.h" #include "units.h" /*************************************************************************** ReadHeader() reads a header (if it exists ) from the file into memory and returns a pointer to the header in memory allocated for storing the header. It returns a null pointer if no header is found. ****************************************************************************/ char *ReadHeader( fp ) FILE *fp ; { static char header_string[] = HEADER_STRING ; static char header_start[] = HEADER_START ; unsigned header_length ; char *header ; if( fread( header_string, sizeof ( *header_string ), STRSIZE( header_string ), fp ) == STRSIZE( header_string ) && strncmp( header_string, header_start, STRSIZE( header_start ) ) == 0 ) { /* header located - remove carriage return */ header_length = atoi( header_string + STRSIZE( header_start ) ) ; header = malloc( header_length ) ; if( header != (char *) 0 ) { (void) strcpy( header, header_string ) ; (void) fread( header + STRSIZE( header_string ), sizeof ( *header_string ), (int) header_length - STRSIZE( header_string ), fp ) ; } return ( header ) ; } else { /* header not present */ (void) fseek( fp, 0l, 0 ) ; return ( (char *) 0 ) ; } } /*************************************************************************** WriteHeader() writes the given header on the given file stream. ****************************************************************************/ WriteHeader(header,fp) char *header; FILE *fp; { int header_length, HeaderInt(); header_length = HeaderInt(header,"header_bytes"); fwrite(header,sizeof(char),header_length,fp); } /*************************************************************************** HeaderString() simply searches through the header for values the user requests and returns a pointer to the begining of the value. ****************************************************************************/ char *HeaderString( header, name ) char *header, *name ; { register char *next_line = header ; register int name_len = strlen( name ) ; do if( strncmp( next_line, name, name_len ) == 0 ) { next_line+=name_len ; if( *next_line++ == '=' ) return ( next_line ) ; } while( ( next_line = strchr( next_line, '\n' ) + 1 ) != (char *) 0 + 1 ) ; return ( (char *) 0 ) ; } /*************************************************************************** HeaderStringOnly() returns a pointer to an allocated string that contains only the value rather than a pointer to a string that includes the all the rest of the header which is what HeaderString() returns. ****************************************************************************/ char *HeaderStringOnly( header, name ) char *header, *name ; { char *value = HeaderString( header, name ) ; unsigned value_length ; if( value != (char *) 0 ) { value_length = strchr( value, '\n' ) - value ; return ( strncpy( malloc( value_length+1 ), value, (int) value_length ) ) ; } else return ( (char *) 0 ) ; } /*************************************************************************** HeaderStrings() searches through the header for values the user requests and returns a pointer to the begining of the value. This is a version of HeaderString() which allows abbreviated names, return null ptr if not found or ambiguous. ****************************************************************************/ char *HeaderStrings( header, name ) char *header, *name ; { register char *next_line = header ; register int name_len = strlen( name ) ; char *valptr ; int count = 0 ; do if( strncmp( next_line, name, name_len ) == 0 ) { next_line+=name_len ; if ( ( valptr = strchr( next_line, '=' ) ) != (char *)0 ) { /* return directly if name matches exactly otherwise wait to check ambiguity */ if ( valptr == next_line ) return ( valptr + 1 ) ; valptr++ ; count++ ; } } while( ( next_line = strchr( next_line, '\n' ) + 1 ) != (char *) 0 + 1 ) ; if( count == 1 ) return ( valptr ) ; else return ( (char *) 0 ) ; /* not found or ambiguous */ } /*************************************************************************** HeaderNameString() returns a pointer to an allocated string that contains the full name corresponding to the given name, which can be given in abbreviated form provided this is unambiguous. Return a null ptr if the name is not found or is ambiguous. (This is an amalgam of HeaderString() and HeaderStringOnly() which also checks for ambiguity) ****************************************************************************/ char *HeaderNameString( header, name ) char *header, *name ; { register char *next_line = header ; register int name_len = strlen( name ) ; unsigned name_length ; char *nameptr ; int count = 0 ; do if( strncmp( next_line, name, name_len ) == 0 ) { if ( strchr( next_line, '=' ) != (char *)0 ) { nameptr = next_line ; /* return directly if name matches exactly otherwise wait to check ambiguity */ if ( name_len == ( name_length = strchr( next_line, '=' ) - next_line ) ) return ( strncpy( malloc( name_length+1 ), nameptr, (int) name_length ) ) ; count++ ; } } while( ( next_line = strchr( next_line, '\n' ) + 1 ) != (char *) 0 + 1 ) ; if( count == 1 ) { name_length = strchr( nameptr, '=' ) - nameptr ; return ( strncpy( malloc( name_length+1 ), nameptr, (int) name_length ) ) ; } else return ( (char *) 0 ) ; /* not found or ambiguous */ } /*************************************************************************** HeaderValueString() returns a pointer to an allocated string that contains the value corresponding to the given name, which can be given in abbreviated form provided this is unambiguous. Return a null ptr if the name is not found or is ambiguous. (This is an amalgam of HeaderString() and HeaderStringOnly() which also checks for ambiguity) ****************************************************************************/ char *HeaderValueString( header, name ) char *header, *name ; { register char *next_line = header ; register int name_len = strlen( name ) ; unsigned value_length ; char *valptr ; int count = 0 ; do if( strncmp( next_line, name, name_len ) == 0 ) { next_line+=name_len ; if ( ( valptr = strchr( next_line, '=' ) ) != (char *)0 ) { /* return directly if name matches exactly otherwise wait to check ambiguity */ if ( valptr == next_line ) { valptr++ ; value_length = strchr( valptr, '\n' ) - valptr ; return ( strncpy( malloc( value_length+1 ), valptr, (int) value_length ) ) ; } valptr++ ; count++ ; } } while( ( next_line = strchr( next_line, '\n' ) + 1 ) != (char *) 0 + 1 ) ; if( count == 1 ) { value_length = strchr( valptr, '\n' ) - valptr ; return ( strncpy( malloc( value_length+1 ), valptr, (int) value_length ) ) ; } else return ( (char *) 0 ) ; /* not found or ambiguous */ } /*************************************************************************** HeaderDouble() converts values to Doubles. ****************************************************************************/ double HeaderDouble( header, name ) char *header, *name ; { char *valuestr ; if ( (valuestr = HeaderString( header, name )) == (char *) 0) { fprintf(stderr,"option %s not found in header\n", name); exit(1); } return ( atof( HeaderString( header, name ) ) ) ; } /*************************************************************************** HeaderInt() converts values to Ints. ****************************************************************************/ int HeaderInt( header, name ) char *header, *name ; { char *valuestr ; if ( (valuestr = HeaderString( header, name )) == (char *) 0) { fprintf(stderr,"option %s not found in header\n", name); exit(1); } return ( atoi( valuestr ) ) ; } /*************************************************************************** HeaderSamplerate() returns the samplerate ****************************************************************************/ HeaderSamplerate( header ) char *header ; { char *valuestr ; if ( (valuestr = HeaderStringOnly( header, "samplerate" )) == (char *) 0) { fprintf(stderr,"samplerate not found in header\n"); exit(1); } return ( (int)to_Hz( valuestr, 1 ) ) ; } /*************************************************************************** FreeHeader frees the space allocated for a header by ReadHeader ****************************************************************************/ void FreeHeader( header ) char *header ; { free( header ) ; return ; } /*************************************************************************** ApplicString() return a ptr to the rest of the header which starts with the 3-char application name of the program. ***************************************************************************/ char *ApplicString( header ) char *header ; { char *versionstr, *progname ; if ( ( versionstr = HeaderString( header, "Version" ) ) == (char *)0 ) return (char *)( 0 ) ; /* version string not found in header */ if ( ( progname = strchr( versionstr, '[' ) ) == (char *)0 ) return (char *)( 0 ) ; /* program name not found in version string */ if ( strchr( versionstr, ']' ) - ( progname += 4 ) != 3 ) return (char *)( 0 ) ; /* application name not found in version string */ return ( progname ) ; } /*************************************************************************** Applic() returns the index number to the gen_applics list (see header.h) of the application name of the program (the last three letters of its name). This is assumed to be delimited by [ ] in the version string in the header. Return a -ve number on error. ***************************************************************************/ Applic( header ) char *header ; { char *versionstr, *progname ; int i ; if ( ( versionstr = HeaderStringOnly( header, "Version" ) ) == (char *)0 ) return ( -2 ) ; /* version string not found in header */ if ( ( progname = strchr( versionstr, '[' ) ) == (char *)0 ) return ( -3 ) ; /* program name not found in version string */ if ( strchr( versionstr, ']' ) - ( progname += 4 ) != 3 ) return ( -4 ) ; /* application name not found in version string */ for ( i = 0 ; gen_applics[i] != (char *)0 ; i++ ) if ( strncmp( gen_applics[i], progname, 3 ) == 0 ) return i ; return ( -1 ) ; /* application name not found in version string */ } /************************************************************************** The table below gives the meaning of the frame parameters for each gen program. The frame parameters are frameheight, framewidth, and frames. Depending upon the program and the "view", they can mean: chans = number of filterbank channels. length = duration in samples. num frames = number of cartoon frames. pwidth = "positive width" of auditory image. nwidth = "negative width" of auditory image. In all cases framebytes = frameheight * framewidth * sizeof(short) The table also shows how the frame parameters relate to the format of the display, where each of "num frames" frames of a cartoon is described as a matrix of "rows" * "cols". The number of rows describes the vertical direction and the number of cols describes the horizontal direction. gen Frame parameters in header Format of display matrix --- ------------------------------------- ---------------------------------- view height width frames rows cols num frames ---- ------ ----- ------ ---- ---- ---------- wav wave 1 1 length frameheight frames 1 bmm landscape chans 1 length frameheight frames 1 nap landscape chans 1 length frameheight frames 1 sgm greyscale chans 1 length frameheight frames 1 cgm greyscale chans 1 length frameheight frames 1 sas greyscale chans 1 length frameheight frames 1 asa excitation chans 1 num frames framewidth frameheight frames epn excitation chans 1 num frames framewidth frameheight frames sep excitation chans 1 num frames framewidth frameheight frames sai landscape chans p+nwidth num frames frameheight framewidth frames spl spiral chans pwidth num frames frameheight framewidth frames The table below shows the format of the AIM output array for each gen program in terms of the frame parameters. gen Output array format Comment --- ---------------------------------- ----------------------------- wav frames sets of frameheight (=1) array of time samples. ----------------------------- bmm frames sets of frameheight 2-D array by columns, nap frames sets of frameheight with lowest centre-frequency first in each column. sgm frames sets of frameheight cgm frames sets of frameheight sas frames sets of frameheight ----------------------------- asa frameheight sets of framewidth (=1) array of frequency samples. epn frameheight sets of framewidth (=1) sep frameheight sets of framewidth (=1) ----------------------------- sai frameheight sets of framewidth 2-D array by rows, with lowest centre-frequency spl frameheight sets of framewidth row first in each frame. The gen programs group into five format types each with a particular interpretation of it's frame parameters, it's output array format, and it's "view". These are defined (in header.h) as: Format gen programs ------ -------------- WAV wav NAP bmm, nap SGM sgm, cgm, sas EPN asa, epn, sep SAI sai, spl ***************************************************************************/ /************************************************************************** Format() returns the index number to the gen_formats list (see header.h) of the given application number (eg returned by Applic()). 0 = wave format (array of time points) 1 = nap format (by columns, lowest centre-frequency first in each column) 2 = sgm format (by columns, lowest centre-frequency first in each column) 3 = epn format (array of frequency points per frame) 4 = sai format (by rows, lowest centre-frequency row first per frame) ***************************************************************************/ Format( applic ) int applic ; { switch ( applic ) { case 0 : return ( 0 ) ; case 1 : case 2 : case 3 : case 4 : case 5 : case 6 : case 7 : return ( 1 ) ; case 8 : case 9 : case 10: return ( 2 ) ; case 11: case 12: case 13: return ( 3 ) ; case 14: case 15: return ( 4 ) ; default : fprintf( stderr,"unknown application index number\n" ) ; exit( 1 ) ; } } /************************************************************************** frame_to_matrix() Given the format number (see: Format(), Applic() and the gen_formats list in header.h), and the frameheight, framewidth, and frames, return the format of the frames in terms of the number of rows (ie. channels) and columns (ie. samples) per frame, and the number of such frames, via the given addresses. The number of bytes per frame is then = rows * cols * 2. ***************************************************************************/ frame_to_matrix( format, rows, cols, numframes, frameheight, framewidth, frames ) int format, *rows, *cols, *numframes, frameheight, framewidth, frames ; { switch ( format ) { case 0 : *rows = 1 ; /* wav format */ *cols = frames ; *numframes = 1 ; break ; case 1 : *rows = frameheight ; /* nap format */ *cols = frames ; *numframes = 1 ; break ; case 2 : *rows = frameheight ; /* sgm format */ *cols = frames ; *numframes = 1 ; break ; case 3 : *rows = 1 ; /* epn format */ *cols = frameheight ; *numframes = frames ; break ; case 4 : *rows = frameheight ; /* sai format */ *cols = framewidth ; *numframes = frames ; break ; default : fprintf( stderr,"unknown format number\n" ) ; exit( 1 ) ; } } /************************************************************************** matrix_to_frame() Inverse of frame_to_matrix(). Given the format number and the format in terms of the number of rows and columns per frame and the number of such frames, return the frameheight, framewidth and frames via the given addresses. ***************************************************************************/ matrix_to_frame( format, rows, cols, numframes, frameheight, framewidth, frames ) int format, rows, cols, numframes, *frameheight, *framewidth, *frames ; { switch ( format ) { case 0 : *frameheight = 1 ; /* wav format */ *framewidth = 1 ; *frames = cols ; break ; case 1 : *frameheight = rows ; /* nap format */ *framewidth = 1 ; *frames = cols ; break ; case 2 : *frameheight = rows ; /* sgm format */ *framewidth = 1 ; *frames = cols ; break ; case 3 : *frameheight = cols ; /* epn format */ *framewidth = 1 ; *frames = numframes ; break ; case 4 : *frameheight = rows ; /* sai format */ *framewidth = cols ; *frames = numframes ; break ; default : fprintf( stderr,"unknown format number\n" ) ; exit( 1 ) ; } }