Mercurial > hg > aim92
diff 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 diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tools/header.c Fri May 20 15:19:45 2011 +0100 @@ -0,0 +1,644 @@ +/*************************************************************************** + 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 ) ; + } +} +