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 ) ;
+    }
+}
+