comparison 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
comparison
equal deleted inserted replaced
-1:000000000000 0:5242703e91d3
1 /***************************************************************************
2 Utilities for model output headers.
3
4 A header is an ASCII desciption which summarises the state of
5 a process by giving a list of parameter values etc etc..
6 Each parameter is described on a separate line, and the header consists
7 of several lines of the general form:
8
9 <ASCII description> = <value>\n
10
11 For example, the first five lines of the header generated by a command
12 line "gensai -header fname" is as follows:
13
14 header_bytes=0000532
15 scale_sai=0.25
16 imagedurn_sai=16
17 decayrate_sai=10
18 cgmdecay=24
19 ...
20 date=Thu Jan 11 00:19:41 WET 1990\n
21 \000
22
23 This string is written onto the front of the file with padding if
24 desired before any data is written. The header can be of any length
25 and contain any combination of non null characters. Header items are
26 identified by the string on the left of the equals symbol and their
27 value is represented by the string on the remainder of that line.
28
29 The first line is always the HEADER_STRING (ie. header_bytes=....\n)
30 which gives the length of the header.
31
32 Synopsis of utilities:
33 ----------------------
34
35 char *ReadHeader( fp )
36 FILE *fp ;
37
38 WriteHeader(header,fp)
39 char *header;
40 FILE *fp;
41
42 char *HeaderString( header, name )
43 char *header, *name ;
44
45 char *HeaderStringOnly( header, name )
46 char *header, *name ;
47
48 double HeaderDouble( header, name )
49 char *header, *name ;
50
51 double HeaderInt( header, name )
52 char *header, *name ;
53
54 void FreeHeader( header )
55 char *header ;
56
57 ReadHeader() reads a header (if it exists ) from the file into
58 memory and returns a pointer to the header in memory allocated for
59 storing the header. It returns a null pointer if no header is found.
60 It leaves the fp pointing to the data which follows the header.
61 WriteHeader() writes the given header on the given file stream.
62 HeaderString() simply searches through the header for values the user
63 requests and returns a pointer to the beginning of the value.
64 It returns a null pointer if the required string is not found.
65 HeaderStringOnly() returns a pointer to an allocated string that
66 contains only the value rather than a pointer to a string that
67 includes the all the rest of the header (which is what HeaderString()
68 returns). It returns a null pointer if the required string is not found.
69 HeaderDouble() converts values to Doubles.
70 HeaderInt() converts values to Ints.
71 FreeHeader() frees the space allocated for a header by ReadHeader.
72
73 Example:
74 -------
75 A simple example of the use of the header utility routines to read the
76 sai dimensions from a header would be:
77 (This assumes a ".sai" file generated by a command like "gensai -header")
78
79 #include <stdio.h>
80 #include <math.h>
81 #include "header.c"
82 char *header = ReadHeader(fp); fp is file-pointer to ".sai" file
83 int frameheight = HeaderInt(header,"frameheight"); num chans
84 int framewidth = HeaderInt(header,"framewidth"); sai duration
85
86 char *name = "frameheight";
87 printf( "%s=%s\n", name, HeaderStringOnly( header, name ) ) ;
88
89 ****************************************************************************/
90
91 #include <stdio.h>
92 /* #include <strings.h> */
93 #include <string.h>
94 #include <malloc.h>
95 #include "header.h"
96 #include "units.h"
97
98
99 /***************************************************************************
100 ReadHeader() reads a header (if it exists ) from the file into
101 memory and returns a pointer to the header in memory allocated for
102 storing the header. It returns a null pointer if no header is found.
103 ****************************************************************************/
104 char *ReadHeader( fp )
105 FILE *fp ;
106 {
107 static char header_string[] = HEADER_STRING ;
108 static char header_start[] = HEADER_START ;
109 unsigned header_length ;
110 char *header ;
111
112 if( fread( header_string, sizeof ( *header_string ), STRSIZE( header_string ), fp ) == STRSIZE( header_string )
113 && strncmp( header_string, header_start, STRSIZE( header_start ) ) == 0 ) {
114
115 /* header located - remove carriage return */
116
117 header_length = atoi( header_string + STRSIZE( header_start ) ) ;
118
119 header = malloc( header_length ) ;
120
121 if( header != (char *) 0 ) {
122 (void) strcpy( header, header_string ) ;
123 (void) fread( header + STRSIZE( header_string ), sizeof ( *header_string ), (int) header_length - STRSIZE( header_string ), fp ) ;
124 }
125
126 return ( header ) ;
127 }
128 else {
129 /* header not present */
130
131 (void) fseek( fp, 0l, 0 ) ;
132
133 return ( (char *) 0 ) ;
134 }
135 }
136
137 /***************************************************************************
138 WriteHeader() writes the given header on the given file stream.
139 ****************************************************************************/
140 WriteHeader(header,fp)
141 char *header;
142 FILE *fp;
143 {
144 int header_length, HeaderInt();
145
146 header_length = HeaderInt(header,"header_bytes");
147 fwrite(header,sizeof(char),header_length,fp);
148 }
149
150
151 /***************************************************************************
152 HeaderString() simply searches through the header for values the user
153 requests and returns a pointer to the begining of the value.
154 ****************************************************************************/
155 char *HeaderString( header, name )
156 char *header, *name ;
157 {
158 register char *next_line = header ;
159 register int name_len = strlen( name ) ;
160
161 do
162 if( strncmp( next_line, name, name_len ) == 0 ) {
163
164 next_line+=name_len ;
165
166 if( *next_line++ == '=' )
167 return ( next_line ) ;
168 }
169
170 while( ( next_line = strchr( next_line, '\n' ) + 1 ) != (char *) 0 + 1 ) ;
171
172 return ( (char *) 0 ) ;
173 }
174
175
176 /***************************************************************************
177 HeaderStringOnly() returns a pointer to an allocated string that
178 contains only the value rather than a pointer to a string that
179 includes the all the rest of the header which is what HeaderString()
180 returns.
181 ****************************************************************************/
182 char *HeaderStringOnly( header, name )
183 char *header, *name ;
184 {
185 char *value = HeaderString( header, name ) ;
186 unsigned value_length ;
187
188 if( value != (char *) 0 ) {
189 value_length = strchr( value, '\n' ) - value ;
190 return ( strncpy( malloc( value_length+1 ), value, (int) value_length ) ) ;
191 }
192 else
193 return ( (char *) 0 ) ;
194 }
195
196
197 /***************************************************************************
198 HeaderStrings() searches through the header for values the user
199 requests and returns a pointer to the begining of the value.
200 This is a version of HeaderString() which allows abbreviated names,
201 return null ptr if not found or ambiguous.
202 ****************************************************************************/
203 char *HeaderStrings( header, name )
204 char *header, *name ;
205 {
206 register char *next_line = header ;
207 register int name_len = strlen( name ) ;
208 char *valptr ;
209 int count = 0 ;
210
211 do
212 if( strncmp( next_line, name, name_len ) == 0 ) {
213
214 next_line+=name_len ;
215
216 if ( ( valptr = strchr( next_line, '=' ) ) != (char *)0 ) {
217
218 /* return directly if name matches exactly otherwise wait to check ambiguity */
219 if ( valptr == next_line ) return ( valptr + 1 ) ;
220
221 valptr++ ;
222 count++ ;
223 }
224 }
225
226 while( ( next_line = strchr( next_line, '\n' ) + 1 ) != (char *) 0 + 1 ) ;
227
228 if( count == 1 )
229 return ( valptr ) ;
230 else
231 return ( (char *) 0 ) ; /* not found or ambiguous */
232 }
233
234
235 /***************************************************************************
236 HeaderNameString() returns a pointer to an allocated string that
237 contains the full name corresponding to the given name, which can be
238 given in abbreviated form provided this is unambiguous.
239 Return a null ptr if the name is not found or is ambiguous.
240 (This is an amalgam of HeaderString() and HeaderStringOnly() which also
241 checks for ambiguity)
242 ****************************************************************************/
243
244 char *HeaderNameString( header, name )
245 char *header, *name ;
246 {
247 register char *next_line = header ;
248 register int name_len = strlen( name ) ;
249 unsigned name_length ;
250 char *nameptr ;
251 int count = 0 ;
252
253 do
254 if( strncmp( next_line, name, name_len ) == 0 ) {
255 if ( strchr( next_line, '=' ) != (char *)0 ) {
256 nameptr = next_line ;
257
258 /* return directly if name matches exactly otherwise wait to check ambiguity */
259 if ( name_len == ( name_length = strchr( next_line, '=' ) - next_line ) )
260 return ( strncpy( malloc( name_length+1 ), nameptr, (int) name_length ) ) ;
261 count++ ;
262 }
263 }
264
265 while( ( next_line = strchr( next_line, '\n' ) + 1 ) != (char *) 0 + 1 ) ;
266
267 if( count == 1 ) {
268 name_length = strchr( nameptr, '=' ) - nameptr ;
269 return ( strncpy( malloc( name_length+1 ), nameptr, (int) name_length ) ) ;
270 }
271 else
272 return ( (char *) 0 ) ; /* not found or ambiguous */
273 }
274
275
276 /***************************************************************************
277 HeaderValueString() returns a pointer to an allocated string that
278 contains the value corresponding to the given name, which can be given
279 in abbreviated form provided this is unambiguous.
280 Return a null ptr if the name is not found or is ambiguous.
281 (This is an amalgam of HeaderString() and HeaderStringOnly() which also
282 checks for ambiguity)
283 ****************************************************************************/
284
285 char *HeaderValueString( header, name )
286 char *header, *name ;
287 {
288 register char *next_line = header ;
289 register int name_len = strlen( name ) ;
290 unsigned value_length ;
291 char *valptr ;
292 int count = 0 ;
293
294 do
295 if( strncmp( next_line, name, name_len ) == 0 ) {
296
297 next_line+=name_len ;
298
299 if ( ( valptr = strchr( next_line, '=' ) ) != (char *)0 ) {
300
301 /* return directly if name matches exactly otherwise wait to check ambiguity */
302 if ( valptr == next_line ) {
303 valptr++ ;
304 value_length = strchr( valptr, '\n' ) - valptr ;
305 return ( strncpy( malloc( value_length+1 ), valptr, (int) value_length ) ) ;
306 }
307
308 valptr++ ;
309 count++ ;
310 }
311 }
312
313 while( ( next_line = strchr( next_line, '\n' ) + 1 ) != (char *) 0 + 1 ) ;
314
315 if( count == 1 ) {
316 value_length = strchr( valptr, '\n' ) - valptr ;
317 return ( strncpy( malloc( value_length+1 ), valptr, (int) value_length ) ) ;
318 }
319 else
320 return ( (char *) 0 ) ; /* not found or ambiguous */
321 }
322
323
324 /***************************************************************************
325 HeaderDouble() converts values to Doubles.
326 ****************************************************************************/
327 double HeaderDouble( header, name )
328 char *header, *name ;
329 {
330 char *valuestr ;
331
332 if ( (valuestr = HeaderString( header, name )) == (char *) 0) {
333 fprintf(stderr,"option %s not found in header\n", name);
334 exit(1);
335 }
336 return ( atof( HeaderString( header, name ) ) ) ;
337 }
338
339
340 /***************************************************************************
341 HeaderInt() converts values to Ints.
342 ****************************************************************************/
343 int HeaderInt( header, name )
344 char *header, *name ;
345 {
346 char *valuestr ;
347
348 if ( (valuestr = HeaderString( header, name )) == (char *) 0) {
349 fprintf(stderr,"option %s not found in header\n", name);
350 exit(1);
351 }
352 return ( atoi( valuestr ) ) ;
353 }
354
355
356 /***************************************************************************
357 HeaderSamplerate() returns the samplerate
358 ****************************************************************************/
359 HeaderSamplerate( header )
360 char *header ;
361 {
362 char *valuestr ;
363
364 if ( (valuestr = HeaderStringOnly( header, "samplerate" )) == (char *) 0) {
365 fprintf(stderr,"samplerate not found in header\n");
366 exit(1);
367 }
368 return ( (int)to_Hz( valuestr, 1 ) ) ;
369 }
370
371
372 /***************************************************************************
373 FreeHeader frees the space allocated for a header by ReadHeader
374 ****************************************************************************/
375 void FreeHeader( header )
376 char *header ;
377 {
378 free( header ) ;
379 return ;
380 }
381
382
383 /***************************************************************************
384 ApplicString() return a ptr to the rest of the header which starts with
385 the 3-char application name of the program.
386 ***************************************************************************/
387
388 char *ApplicString( header )
389 char *header ;
390 {
391 char *versionstr, *progname ;
392
393 if ( ( versionstr = HeaderString( header, "Version" ) ) == (char *)0 )
394 return (char *)( 0 ) ; /* version string not found in header */
395
396 if ( ( progname = strchr( versionstr, '[' ) ) == (char *)0 )
397 return (char *)( 0 ) ; /* program name not found in version string */
398 if ( strchr( versionstr, ']' ) - ( progname += 4 ) != 3 )
399 return (char *)( 0 ) ; /* application name not found in version string */
400
401 return ( progname ) ;
402 }
403
404
405 /***************************************************************************
406 Applic() returns the index number to the gen_applics list (see header.h)
407 of the application name of the program (the last three letters of its name).
408 This is assumed to be delimited by [ ] in the version string in the header.
409 Return a -ve number on error.
410 ***************************************************************************/
411
412 Applic( header )
413 char *header ;
414 {
415 char *versionstr, *progname ;
416 int i ;
417
418 if ( ( versionstr = HeaderStringOnly( header, "Version" ) ) == (char *)0 )
419 return ( -2 ) ; /* version string not found in header */
420
421 if ( ( progname = strchr( versionstr, '[' ) ) == (char *)0 )
422 return ( -3 ) ; /* program name not found in version string */
423 if ( strchr( versionstr, ']' ) - ( progname += 4 ) != 3 )
424 return ( -4 ) ; /* application name not found in version string */
425 for ( i = 0 ; gen_applics[i] != (char *)0 ; i++ )
426 if ( strncmp( gen_applics[i], progname, 3 ) == 0 )
427 return i ;
428
429 return ( -1 ) ; /* application name not found in version string */
430 }
431
432
433 /**************************************************************************
434
435 The table below gives the meaning of the frame parameters for each gen
436 program. The frame parameters are frameheight, framewidth, and frames.
437 Depending upon the program and the "view", they can mean:
438
439 chans = number of filterbank channels.
440 length = duration in samples.
441 num frames = number of cartoon frames.
442 pwidth = "positive width" of auditory image.
443 nwidth = "negative width" of auditory image.
444
445 In all cases framebytes = frameheight * framewidth * sizeof(short)
446
447 The table also shows how the frame parameters relate to the format of the
448 display, where each of "num frames" frames of a cartoon is described as a
449 matrix of "rows" * "cols". The number of rows describes the vertical direction
450 and the number of cols describes the horizontal direction.
451
452
453 gen Frame parameters in header Format of display matrix
454 --- ------------------------------------- ----------------------------------
455 view height width frames rows cols num frames
456 ---- ------ ----- ------ ---- ---- ----------
457
458 wav wave 1 1 length frameheight frames 1
459
460 bmm landscape chans 1 length frameheight frames 1
461 nap landscape chans 1 length frameheight frames 1
462
463 sgm greyscale chans 1 length frameheight frames 1
464 cgm greyscale chans 1 length frameheight frames 1
465 sas greyscale chans 1 length frameheight frames 1
466
467 asa excitation chans 1 num frames framewidth frameheight frames
468 epn excitation chans 1 num frames framewidth frameheight frames
469 sep excitation chans 1 num frames framewidth frameheight frames
470
471 sai landscape chans p+nwidth num frames frameheight framewidth frames
472
473 spl spiral chans pwidth num frames frameheight framewidth frames
474
475
476 The table below shows the format of the AIM output array for each gen program
477 in terms of the frame parameters.
478
479
480 gen Output array format Comment
481 --- ---------------------------------- -----------------------------
482 wav frames sets of frameheight (=1) array of time samples.
483
484 -----------------------------
485 bmm frames sets of frameheight 2-D array by columns,
486 nap frames sets of frameheight with lowest centre-frequency
487 first in each column.
488 sgm frames sets of frameheight
489 cgm frames sets of frameheight
490 sas frames sets of frameheight
491
492 -----------------------------
493 asa frameheight sets of framewidth (=1) array of frequency samples.
494 epn frameheight sets of framewidth (=1)
495 sep frameheight sets of framewidth (=1)
496
497 -----------------------------
498 sai frameheight sets of framewidth 2-D array by rows,
499 with lowest centre-frequency
500 spl frameheight sets of framewidth row first in each frame.
501
502
503 The gen programs group into five format types each with a particular
504 interpretation of it's frame parameters, it's output array format, and it's
505 "view". These are defined (in header.h) as:
506
507 Format gen programs
508 ------ --------------
509 WAV wav
510 NAP bmm, nap
511 SGM sgm, cgm, sas
512 EPN asa, epn, sep
513 SAI sai, spl
514
515
516
517
518
519 ***************************************************************************/
520
521
522
523
524
525 /**************************************************************************
526 Format() returns the index number to the gen_formats list (see header.h)
527 of the given application number (eg returned by Applic()).
528 0 = wave format (array of time points)
529 1 = nap format (by columns, lowest centre-frequency first in each column)
530 2 = sgm format (by columns, lowest centre-frequency first in each column)
531 3 = epn format (array of frequency points per frame)
532 4 = sai format (by rows, lowest centre-frequency row first per frame)
533 ***************************************************************************/
534
535 Format( applic )
536 int applic ;
537 {
538 switch ( applic ) {
539
540 case 0 : return ( 0 ) ;
541
542 case 1 : case 2 : case 3 :
543 case 4 : case 5 : case 6 :
544 case 7 : return ( 1 ) ;
545
546 case 8 : case 9 : case 10: return ( 2 ) ;
547
548 case 11: case 12: case 13: return ( 3 ) ;
549
550 case 14: case 15: return ( 4 ) ;
551
552 default : fprintf( stderr,"unknown application index number\n" ) ;
553 exit( 1 ) ;
554 }
555 }
556
557
558 /**************************************************************************
559 frame_to_matrix()
560 Given the format number (see: Format(), Applic() and the gen_formats list
561 in header.h), and the frameheight, framewidth, and frames,
562 return the format of the frames in terms of the number of rows
563 (ie. channels) and columns (ie. samples) per frame, and the number of
564 such frames, via the given addresses.
565 The number of bytes per frame is then = rows * cols * 2.
566 ***************************************************************************/
567
568 frame_to_matrix( format, rows, cols, numframes, frameheight, framewidth, frames )
569 int format, *rows, *cols, *numframes, frameheight, framewidth, frames ;
570 {
571 switch ( format ) {
572 case 0 : *rows = 1 ; /* wav format */
573 *cols = frames ;
574 *numframes = 1 ;
575 break ;
576
577 case 1 : *rows = frameheight ; /* nap format */
578 *cols = frames ;
579 *numframes = 1 ;
580 break ;
581
582 case 2 : *rows = frameheight ; /* sgm format */
583 *cols = frames ;
584 *numframes = 1 ;
585 break ;
586
587 case 3 : *rows = 1 ; /* epn format */
588 *cols = frameheight ;
589 *numframes = frames ;
590 break ;
591
592 case 4 : *rows = frameheight ; /* sai format */
593 *cols = framewidth ;
594 *numframes = frames ;
595 break ;
596
597 default : fprintf( stderr,"unknown format number\n" ) ;
598 exit( 1 ) ;
599 }
600 }
601
602
603 /**************************************************************************
604 matrix_to_frame()
605 Inverse of frame_to_matrix().
606 Given the format number and the format in terms of the number of rows and
607 columns per frame and the number of such frames, return the frameheight,
608 framewidth and frames via the given addresses.
609 ***************************************************************************/
610
611 matrix_to_frame( format, rows, cols, numframes, frameheight, framewidth, frames )
612 int format, rows, cols, numframes, *frameheight, *framewidth, *frames ;
613 {
614 switch ( format ) {
615 case 0 : *frameheight = 1 ; /* wav format */
616 *framewidth = 1 ;
617 *frames = cols ;
618 break ;
619
620 case 1 : *frameheight = rows ; /* nap format */
621 *framewidth = 1 ;
622 *frames = cols ;
623 break ;
624
625 case 2 : *frameheight = rows ; /* sgm format */
626 *framewidth = 1 ;
627 *frames = cols ;
628 break ;
629
630 case 3 : *frameheight = cols ; /* epn format */
631 *framewidth = 1 ;
632 *frames = numframes ;
633 break ;
634
635 case 4 : *frameheight = rows ; /* sai format */
636 *framewidth = cols ;
637 *frames = numframes ;
638 break ;
639
640 default : fprintf( stderr,"unknown format number\n" ) ;
641 exit( 1 ) ;
642 }
643 }
644