comparison model/review.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 Copyright (c) Applied Psychology Unit, Medical Research Council. 1988, 1989
3 ===========================================================================
4
5 Permission to use, copy, modify, and distribute this software without fee
6 is hereby granted for research purposes, provided that this copyright
7 notice appears in all copies and in all supporting documentation, and that
8 the software is not redistributed for any fee (except for a nominal shipping
9 charge). Anyone wanting to incorporate all or part of this software in a
10 commercial product must obtain a license from the Medical Research Council.
11
12 The MRC makes no representations about the suitability of this
13 software for any purpose. It is provided "as is" without express or implied
14 warranty.
15
16 THE MRC DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
17 ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL THE
18 A.P.U. BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY
19 DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN
20 AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
21 OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
22 */
23
24 /*
25 review.c
26 ========
27
28 formerly known as revsai.c - reviews .ctn screen dump files from disk.
29
30
31 Copyright (c), 1989 The Medical Research Council, Applied Psychology Unit.
32
33
34 Authors : Paul Manson and John Holdsworth.
35 Written : 11th March, 1989
36
37 Edited :
38
39 03 April 1989 (Paul Manson) -- A new star on the horizon! The all-singing, all-dancing
40 new revue emerges from the ashes of last week's version.
41
42 19 April 1989 (Paul Manson) -- Added the <input> option. Changed the name to revsai.
43
44 27 April 1989 (Paul Manson) -- The port to the DecStation (and by implication, the VAX)
45 has revealed several problems and bugs. All such known
46 bugs have been fixed. The <memory> option has been
47 introduced (for non-PCs only) to permit rapid reviewing
48 on X-windows servers. NOTE THAT THE SCREEN SIZE FOR NON
49 PC MACHINES HAS BEEN HARD_CODED! THIS SHOULD CHANGE!
50
51 05 May 1989 (Paul Manson) -- The above problem has been temporarily rectified by
52 using the default width and height options to indicate
53 the actual screen size. Also, the options format change
54 has been accounted for.
55
56 11 May 1989 (Paul Manson) -- Altered options to conform to the new(est) r'egime.
57
58 15 May 1989 (Paul Manson) -- Incorporated the PC-style wildcarding into the Unix version.
59 Made display use "NULL" instead of (char *) 0.
60
61 05 June 1989 (Paul Manson) -- Altered a couple of the option comments to reflect their
62 behaviour more accurately. I also encountered the rather
63 suspicious "bug" whereby revsai gets a segmentation fault
64 whenever it is run on an old "sai" file ... those generated
65 by sai now appear to be OK... If this really is a problem,
66 it should be tracked down!
67
68 06 July 1989 (Paul Manson) -- As well as altering revsai to accomodate all of the new
69 options names, I note that the abovementioned bug appears
70 to have disappeared without trace; hopefully it was just
71 due to previous (buggy) files, etc.
72
73 3 August 1993 (M. Akeroyd) -- Added declarations of "colourstr" and "planemaskstr".
74 They aren't used, but are in X.c (and thus libglib.a),
75 and are therfore required to fool the linker.
76
77 25 March 1994 (M. Akeroyd) -- Added colour. mono etc, so that 'review' would actually work.
78 (the previuos cahnge just made it compile.)
79 */
80
81 #include <string.h>
82 #include <stdio.h>
83 #include <math.h>
84
85 #if defined(THINK_C) || defined(NeXT)
86 #include <stdlib.h>
87 #else
88 #include <malloc.h>
89 #endif
90
91 #include "windows.h"
92 #include "options.h"
93
94
95 char *monostr, *colourstr, *planemaskstr; /* MAA 3-8-1993 */
96 char *fgcolourstr, *bgcolourstr; /* MAA 19-8-1993 */
97 #ifndef lint
98 static char *sccs_id = "@(#)review.c 1.13 Paul Manson, John Holdsworth (MRC-APU) 5/31/91";
99 #endif
100
101 #define max(A,B) (((A) > (B)) ? (A) : (B))
102 #define LENGTH_STR "remainder"
103 #define MAX_LENGTH (9999)
104
105 #define CENTER_STR "center"
106 #define IMAGE_SUFFIX ".ctn"
107
108 #ifdef PC
109 #define READ_BINARY "rb"
110 #else
111 #define READ_BINARY "r"
112 #endif
113
114 /* configurables */
115
116 static char *helpstr ;
117 static char *speed1str, *speed2str ;
118 static char *xstr, *ystr, *widthstr, *heightstr ;
119 static char *start1str, *stop1str, *step1str ;
120 static char *start2str, *stop2str, *step2str ;
121 static char *minstr , *maxstr , *framestr ;
122 static char *in1str, *in2str, *downstr ;
123
124 #if !defined( PC )
125 extern void exit();
126 static char *memorystr;
127 #endif
128
129 static Option res[] = {
130 { "help", "none", &helpstr, "<wave1> [<wave2>]\n\n\
131 Redisplays stored images from memory or directly from disk.\n\
132 Review responds to various simple commands, viz.\n\n\
133 1\t Activate only wave1 (default when only one wave named).\n\
134 2\t Activate only wave2.\n\
135 b or B\t Activate Both waves (default when two waves named).\n\n\
136 a or A\t Animate cartoon wave(s). Hitting space bar is equivalent.\n\
137 s or S\t Single-step activated wave(s). Hit space bar to step.\n\
138 +\t Animate activated wave(s) faster.\n\
139 -\t Animate activated wave(s) slower.\n\n\
140 q or Q\t Quit Revue.\n", SilentOption },
141 { "input1", NULL_OPTION, &in1str, "Default input file name 1", InputOption},
142 { "start1" , "0" , &start1str , "Start point in wave 1 (in ms)", InputOption},
143 { "length1", LENGTH_STR, &stop1str , "Length of wave 1 to display (in ms)", InputOption},
144 { "step1" , "1" , &step1str , "Display every step-th image of wave 1", InputOption},
145 { "speed1", "1" , &speed1str, "Image 1 display speed (1 is fastest)", InputOption},
146
147 { "input2", NULL_OPTION, &in2str, "Default input file name 2\n", InputOption},
148 { "start2" , "0" , &start2str , "Start point in wave 2 (in ms)", InputOption},
149 { "length2", LENGTH_STR, &stop2str , "Length of wave 2 to display (in ms)", InputOption},
150 { "step2" , "1" , &step2str , "Display every step-th image of wave 2", InputOption},
151 { "speed2", "1" , &speed2str, "Image 2 display speed (1 is fastest)", InputOption},
152
153 { "x0_win", CENTER_STR, &xstr, "Left edge of window (in pixels)" , SilentOption},
154 { "y0_win", CENTER_STR, &ystr, "Upper edge of window (in pixels)", SilentOption},
155 { "width_screen", "960", &widthstr, "Physical screen width in pixels", SilentOption},
156 { "height_screen","750", &heightstr, "Physical screen height in pixels", SilentOption},
157
158 /* MAA: 25 March 1994
159 * These next added because they are used from within X.c (although defined in gen.c), and thus the graphics
160 * calls. They are of NO meaning, however; they define how the Model makes the bitmaps.
161 * Once made, you cannot edit bitmaps ...
162 */
163 { "fg_col", "black", &fgcolourstr, "Foreground Colour.\n", SilentOption},
164 { "bg_col", "white", &bgcolourstr, "Background Colour.\n", SilentOption},
165 { "mono_ctn", ON_OPTION, &monostr, "Force monochrome (single plane) cartoons.", SilentOption},
166 { "colour_ctn", OFF_OPTION, &colourstr, "Force colour (multi-plane) cartoons.", SilentOption},
167 {"planemask_ctn", "1", &planemaskstr, "Planemask for creating cartoons.\n", SilentOption},
168 /* MAA: End of that bit */
169
170 #if !defined( PC )
171 { "memory", ON_OPTION, &memorystr, "Read images into memory for reviewing\n", InputOption},
172 #endif
173 ( char * ) 0 } ;
174
175 static Option hiddenRes[] = {
176 { "downsample", "20", &downstr, "Image file frame size (in ms)", InputOption},
177 { "frstep_aid", "20", &framestr, "Image file frame size (in ms)", InputOption},
178 { "mincf_afb", "220", &minstr , "Minimum Center Frequency in Hertz", InputOption},
179 { "maxcf_afb", "4400", &maxstr , "Maximum Center Frequency in Hertz", InputOption},
180 { "width_win", "900", &widthstr, "Window width (pixels)", InputOption},
181 { "height_win", "600", &heightstr, "Window height (pixels)", InputOption},
182 ( char * ) 0 } ;
183
184 #define ONE (1)
185 #define TWO (2)
186 #define BOTH (0)
187
188 #define FALSE (0)
189 #define TRUE (1)
190 #define OVERTHETOP (10000)
191 #define AXES_WIDTH (15)
192
193 static int msToImages(frame, ms)
194 double frame;
195 double ms ;
196 {
197 return (((int) (ms / frame)) + 1); /* Round Up */
198 }
199
200 /* File Name Suffix Conversion Parameters */
201
202 #define BACKSLASH_CHAR '\\'
203 #define SLASH_CHARACTER '/'
204 #define NULL_CHARACTER '\000'
205 #define DOT_CHARACTER '.'
206
207 /******************************************************************************************/
208 /* */
209 /* AlterSuffix(). Returns its argument fileName with a newSuffix appended in place of */
210 /* any previous suffix it may have had. It should be noted that this */
211 /* suffix must include any DOT it wishes to have appended to the name. */
212 /* */
213 /******************************************************************************************/
214
215 char *AlterSuffix(fileName, newSuffix)
216 char *fileName, *newSuffix;
217 {
218 char *temp, *temp2, *lastPart;
219 int i;
220
221 temp = malloc((unsigned) (strlen(fileName) + strlen(newSuffix) + 1));
222
223 temp = strcpy(temp, fileName);
224
225 #if defined( PC )
226 /* Change all backslashes to forward slashes */
227 for (i = 0; temp[i] != NULL_CHARACTER; i++)
228 if (temp[i] == BACKSLASH_CHAR)
229 temp[i] = SLASH_CHARACTER;
230 #endif
231
232 if ((lastPart = strrchr(temp, SLASH_CHARACTER)) == NULL)
233 lastPart = temp;
234 else
235 lastPart++; /* Skip over the actual "/" */
236
237 /* lastPart points to the tail name of the path */
238
239 if ((temp2 = strchr(lastPart, DOT_CHARACTER)) == NULL)
240 temp = strcat(temp, newSuffix);
241 else
242 temp2 = strcpy(temp2, newSuffix);
243
244 return (temp);
245 }
246
247 /* -----------------------------------------------------------------------------------
248
249 A Routine to extend revsai for in-memory animation. This copies every image from
250 <start> to <stop> by <step> into the images buffer for the window <w>. It then
251 expects contiguous animation of these images. The integer returned is the number
252 of images that were saved; subsequent image Recall() calls should refer to images
253 in the range [1 .. this returned value].
254
255 ----------------------------------------------------------------------------------- */
256
257 static int readIntoMemory(w, filePtr, start, stop, step)
258 WindowObject w;
259 FILE *filePtr ;
260 int start;
261 int stop;
262 int step;
263 {
264 int fileImage, memImage;
265
266 memImage = 0;
267
268 fileImage = start;
269
270 while (fileImage <= stop && Read(w, filePtr, fileImage)) {
271 Store(w);
272 fileImage += step;
273 memImage++;
274 }
275
276 return (memImage);
277 }
278
279 main( argc, argv )
280 int argc ;
281 char *argv[] ;
282 {
283 WindowObject w1, w2;
284 int screenWidth, screenHeight ;
285 int firstWidth , firstHeight ;
286 int secondWidth, secondHeight ;
287 int firstPixels, secondPixels ;
288 FILE *firstWave , *secondWave ;
289
290 int OneWave, TwoWaves, spareWidth,
291 spareHeight ;
292
293 int waveMode , image1 , image2;
294 int count1 , count2;
295 int stopFirst, stopSecond ;
296 int start1 , stop1 , step1 ;
297 int start2 , stop2 , step2 ;
298 int speed1 , speed2 ;
299
300 char command, *firstWaveName,
301 *secondWaveName,
302 *programName;
303
304 double mincf1, mincf2, maxcf1, maxcf2, frame1, frame2;
305 int inMemory, x, y;
306
307 programName = argv[0];
308
309 (void) getopts( res, &argc, &argv );
310
311 /* Extract any information from the opts which is NECESSARY for the
312 operation of revue */
313
314 screenWidth = atoi( widthstr );
315 screenHeight= atoi( heightstr);
316
317 #if defined( PC )
318 inMemory = FALSE;
319 #else
320 inMemory = isON( memorystr );
321 #endif
322
323 if (argc > 2 || (argc == 0 && isNULL(in1str))) {
324 (void) helpopts(res, programName);
325 exit(1);
326 }
327 else {
328 OneWave = ((argc == 0 && !isNULL(in1str)) ||
329 (argc == 1 && isNULL(in2str)));
330 TwoWaves = !OneWave;
331 }
332
333 if (argc == 0)
334 firstWaveName = AlterSuffix(in1str, IMAGE_SUFFIX) ;
335 else
336 firstWaveName = AlterSuffix(argv[0], IMAGE_SUFFIX);
337
338 if ((firstWave = fopen(firstWaveName, READ_BINARY )) == NULL) {
339 (void) fprintf(stderr, "Could not open the image file %s.\n", firstWaveName);
340 exit(1);
341 }
342
343 (void) readopts(res, firstWave);
344
345 if (fseek(firstWave, 0l, 0)) {
346 (void) fprintf(stderr, "revsai: Could not re-seek the %s file.\n",
347 firstWaveName);
348 exit(1);
349 }
350
351 (void) readopts(hiddenRes, firstWave);
352
353 if( framestr == (char *) 0 )
354 if( downstr == (char *) 0 )
355 frame1 = 1 ;
356 else
357 frame1 = atof(downstr);
358 else if ((frame1 = atof(framestr)) < 0.0)
359 frame1 = 0.0;
360
361 firstWidth = atoi( widthstr );
362 firstHeight = atoi( heightstr);
363
364 start1 = msToImages(frame1, atof( start1str ));
365
366 if (strcmp(stop1str, LENGTH_STR) == 0)
367 stop1 = MAX_LENGTH;
368 else
369 stop1 = msToImages(frame1, atof( stop1str )) + start1;
370
371 step1 = atoi( step1str );
372 if (step1 < 1)
373 step1 = 1;
374
375 firstPixels = 1; /* atoi( pixelstr ); */
376
377 mincf1 = atof( minstr );
378 maxcf1 = atof( maxstr );
379
380 if (TwoWaves) {
381
382 if (argc == 1)
383 secondWaveName = AlterSuffix(in2str, IMAGE_SUFFIX);
384 else
385 secondWaveName = AlterSuffix(argv[1],IMAGE_SUFFIX);
386
387 if ((secondWave = fopen(secondWaveName, READ_BINARY )) == NULL) {
388 (void) fprintf(stderr, "Could not open the image file %s.\n",
389 secondWaveName);
390 exit(1);
391 }
392
393 (void) readopts(res, secondWave);
394 if (fseek(secondWave, 0l, 0)) {
395 (void) fprintf(stderr, "revsai: Could not re-seek the %s file.\n",
396 secondWaveName);
397 exit(1);
398 }
399 (void) readopts(hiddenRes, secondWave);
400
401 if( framestr == (char *) 0 )
402 if( downstr == (char *) 0 )
403 frame2 = 1. ;
404 else
405 frame2 = atof(downstr);
406 else if ((frame2 = atof(framestr)) < 0.0)
407 frame2 = atof(downstr);
408
409 secondWidth = atoi( widthstr );
410 secondHeight = atoi( heightstr);
411
412 start2 = msToImages(frame2, atof( start2str ));
413
414 if (strcmp(stop2str, LENGTH_STR) == 0)
415 stop2 = MAX_LENGTH;
416 else
417 stop2 = msToImages(frame2, atof( stop2str )) + start2;
418
419 step2 = atoi( step2str );
420 if (step2 < 1)
421 step2 = 1;
422
423 secondPixels = 1; /* atoi( pixelstr ); */
424
425 mincf2 = atof( minstr );
426 maxcf2 = atof( maxstr );
427
428 }
429
430
431 /* Open display window(s) */
432
433 if (TwoWaves) {
434 /* Center them both for height, but try to fit them both on the screen
435 at once, width-wise. Firstly, get the REAL screen size */
436 #if defined( PC )
437 w1 = newDisplayWindow(firstWaveName, -1, -1, OVERTHETOP, OVERTHETOP, 1);
438 screenWidth = Width(w1);
439 screenHeight = Height(w1);
440 Close(w1);
441 #endif
442
443 if (screenHeight < firstHeight || screenHeight < secondHeight) {
444 (void) fprintf(stderr, "revsai: One (or both) of the waves specified was too\n high for this screen.\n");
445 exit(1);
446 }
447 if (screenWidth < firstWidth + secondWidth) {
448 (void) fprintf(stderr, "revsai: These two waves are too wide to be viewed side-by-side.\n Please revue them one at a time, or perhaps generate them smaller.\n");
449 exit(1);
450 }
451
452 spareWidth = screenWidth - (firstWidth + secondWidth + (2 * AXES_WIDTH));
453 spareHeight = screenHeight - (firstHeight + (2 * AXES_WIDTH));
454
455 w1 = newDisplayWindow(firstWaveName, spareWidth/6 + AXES_WIDTH, spareHeight/2,
456 firstWidth, firstHeight, firstPixels);
457 Axes(w1, firstWaveName, 0.0, frame1, "Image Frame Size (in ms)",
458 mincf1, maxcf1, "Center Frequency (in Hz)");
459
460 spareHeight = screenHeight - (secondHeight + (2 * AXES_WIDTH));
461
462 w2 = newDisplayWindow(secondWaveName, (5 * spareWidth / 6) +
463 firstWidth + (2 * AXES_WIDTH),
464 spareHeight/2, secondWidth, secondHeight,
465 secondPixels);
466 Axes(w2, secondWaveName, 0.0, frame2, "Image Frame Size (in ms)",
467 mincf2, maxcf2, "Center Frequency (in Hz)");
468 }
469 else {
470 /* Easy .. MetaPC Centers it for us */
471 if (OptionStringsEqual(xstr, CENTER_STR))
472 x = -1;
473 else
474 x = atoi(xstr);
475
476 if (OptionStringsEqual(ystr, CENTER_STR))
477 y = -1;
478 else
479 y = atoi(ystr);
480
481 w1 = newDisplayWindow(firstWaveName, x, y, firstWidth, firstHeight,
482 firstPixels );
483 Axes(w1, firstWaveName, 0.0, frame1, "Image Frame Size (in ms)",
484 mincf1, maxcf1, "Center Frequency (in Hz)");
485
486 #if defined( SUN )
487 /* Kludge to overcome the window-sizing inconsistency when
488 you open a SunView window with a frame */
489
490 if (Height(w1) > firstHeight || Width(w1) > firstWidth) {
491 #else
492 if (Height(w1) != firstHeight || Width(w1) != firstWidth) {
493 #endif
494 (void) fprintf(stderr, "revsai: The wave you wish to view is too large (ie. either too wide\nor too tall) for the current screen.\n");
495 exit(1);
496 }
497 }
498
499 /* Do the actual reviewing */
500
501 if (TwoWaves)
502 waveMode = BOTH;
503 else
504 waveMode = ONE ;
505
506 speed1 = atoi( speed1str );
507 if (speed1 < 1)
508 speed1 = 1;
509 speed2 = atoi( speed2str );
510 if (speed2 < 1)
511 speed2 = 1;
512
513 /* Initially, just open the files and display the first frame of each, */
514 /* UNLESS the inMemory switch is set, in which case you should read in */
515 /* all of the images and adjust start, stop to suit. */
516
517 if (inMemory) {
518 stop1 = readIntoMemory(w1, firstWave, start1, stop1, step1);
519 start1 = 1; /* Now runs from 0 to the adjusted stop */
520 step1 = 1; /* Now the images are contiguous */
521 if (TwoWaves) {
522 stop2 = readIntoMemory(w2, secondWave, start2, stop2, step2);
523 start2 = 1; /* Now runs from 0 to the adjusted stop */
524 step2 = 1; /* Now the images are contiguous */
525 }
526 }
527 else {
528 if (!Read(w1, firstWave, start1)) {
529 (void) fprintf(stderr, "revsai: Could not read the first image from the first wave.\n");
530 exit(1);
531 }
532
533 if (TwoWaves && !Read(w2, secondWave, start2)) {
534 (void) fprintf(stderr, "revsai: Couldn't read the first image from the second wave.\n");
535 exit(1);
536 }
537 }
538
539 /* Sit and take commands */
540
541 while ((command = Pause(w1)) != 'q' && command != 'Q') {
542 switch (command) {
543 case '1':
544 /* Toggle to Wave number One */
545 waveMode = ONE;
546 break;
547 case '2':
548 /* Try to toggle to Wave number Two */
549 if (TwoWaves)
550 waveMode = TWO;
551 break;
552 case 'b': case 'B':
553 /* Try to toggle to Both Waves */
554 if (TwoWaves)
555 waveMode = BOTH;
556 break;
557 case '+':
558 /* Speed up current Wave(s) */
559 if (waveMode == ONE || waveMode == BOTH)
560 speed1 = ((speed1 > 1) ? (speed1 /= 2) : (1));
561 if (waveMode == TWO || waveMode == BOTH)
562 speed2 = ((speed2 > 1) ? (speed2 /= 2) : (1));
563 break;
564 case '-':
565 /* Slow down current Wave(s) */
566 if (waveMode == ONE || waveMode == BOTH)
567 speed1 *= 2;
568 if (waveMode == TWO || waveMode == BOTH)
569 speed2 *= 2;
570 break;
571 case 's': case 'S':
572 stopFirst = (waveMode == TWO);
573 stopSecond = (waveMode == ONE);
574 image1 = start1;
575 image2 = start2;
576 while (!(stopFirst && stopSecond) && (Pause(w1) == ' ')) {
577 if (!stopFirst) {
578 if (inMemory)
579 Recall(w1, image1);
580 else
581 stopFirst = !Read(w1, firstWave , image1);
582 if (!stopFirst) {
583 image1 += step1;
584 stopFirst = (image1 > stop1);
585 }
586 }
587 if (!stopSecond) {
588 if (inMemory)
589 Recall(w2, image2);
590 else
591 stopSecond = !Read(w2, secondWave, image2);
592 if (!stopSecond) {
593 image2 += step2;
594 stopSecond = (image2 > stop2);
595 }
596 }
597 }
598 break;
599 case 'a': case 'A': case ' ':
600 stopFirst = (waveMode == TWO);
601 stopSecond = (waveMode == ONE);
602 image1 = start1;
603 image2 = start2;
604 count1 = count2 = 0 ;
605 while (!(stopFirst && stopSecond)) {
606 if (stopFirst || image1 > stop1) {
607 if (waveMode == BOTH && !stopSecond && image2 <= stop2 &&
608 image1 > start1 && count1 == 0) {
609 /* Redisplay the previous image for constant speed */
610 if (inMemory)
611 Recall(w1, image1-1);
612 else
613 stopFirst = !Read(w1, firstWave, image1-1);
614 }
615 stopFirst = TRUE;
616 }
617 else {
618 if (inMemory)
619 Recall(w1, image1);
620 else
621 stopFirst = !Read(w1, firstWave, image1);
622 if (!stopFirst)
623 if (++count1 >= speed1) {
624 image1 += step1;
625 count1 = 0 ;
626 }
627 }
628 if (stopSecond || image2 > stop2) {
629 if (waveMode == BOTH && !stopFirst && image1 <= stop1 &&
630 image2 > start2 && count2 == 0) {
631 /* Redisplay the previous image for constant speed */
632 if (inMemory)
633 Recall(w2, image2-1);
634 else
635 stopSecond = !Read(w2, secondWave, image2-1);
636 }
637 stopSecond = TRUE;
638 }
639 else {
640 if (inMemory)
641 Recall(w2, image2);
642 else
643 stopSecond = !Read(w2, secondWave, image2);
644 if (!stopSecond)
645 if (++count2 >= speed2) {
646 image2 += step2;
647 count2 = 0 ;
648 }
649 }
650 }
651 break;
652 default:
653 break;
654 }
655 }
656 if (fclose(firstWave)) {
657 (void) fprintf(stderr, "revsai: Could not close file % correctly.\n",
658 firstWaveName);
659 exit(1);
660 }
661 if (TwoWaves && fclose(secondWave)) {
662 (void) fprintf(stderr, "revsai: Could not close file % correctly.\n",
663 secondWaveName);
664 exit(1);
665 }
666 }