tomwalters@0: /* tomwalters@0: Copyright (c) Applied Psychology Unit, Medical Research Council. 1988, 1989 tomwalters@0: =========================================================================== tomwalters@0: tomwalters@0: Permission to use, copy, modify, and distribute this software without fee tomwalters@0: is hereby granted for research purposes, provided that this copyright tomwalters@0: notice appears in all copies and in all supporting documentation, and that tomwalters@0: the software is not redistributed for any fee (except for a nominal shipping tomwalters@0: charge). Anyone wanting to incorporate all or part of this software in a tomwalters@0: commercial product must obtain a license from the Medical Research Council. tomwalters@0: tomwalters@0: The MRC makes no representations about the suitability of this tomwalters@0: software for any purpose. It is provided "as is" without express or implied tomwalters@0: warranty. tomwalters@0: tomwalters@0: THE MRC DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING tomwalters@0: ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL THE tomwalters@0: A.P.U. BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY tomwalters@0: DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN tomwalters@0: AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF tomwalters@0: OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. tomwalters@0: */ tomwalters@0: tomwalters@0: /* tomwalters@0: review.c tomwalters@0: ======== tomwalters@0: tomwalters@0: formerly known as revsai.c - reviews .ctn screen dump files from disk. tomwalters@0: tomwalters@0: tomwalters@0: Copyright (c), 1989 The Medical Research Council, Applied Psychology Unit. tomwalters@0: tomwalters@0: tomwalters@0: Authors : Paul Manson and John Holdsworth. tomwalters@0: Written : 11th March, 1989 tomwalters@0: tomwalters@0: Edited : tomwalters@0: tomwalters@0: 03 April 1989 (Paul Manson) -- A new star on the horizon! The all-singing, all-dancing tomwalters@0: new revue emerges from the ashes of last week's version. tomwalters@0: tomwalters@0: 19 April 1989 (Paul Manson) -- Added the option. Changed the name to revsai. tomwalters@0: tomwalters@0: 27 April 1989 (Paul Manson) -- The port to the DecStation (and by implication, the VAX) tomwalters@0: has revealed several problems and bugs. All such known tomwalters@0: bugs have been fixed. The option has been tomwalters@0: introduced (for non-PCs only) to permit rapid reviewing tomwalters@0: on X-windows servers. NOTE THAT THE SCREEN SIZE FOR NON tomwalters@0: PC MACHINES HAS BEEN HARD_CODED! THIS SHOULD CHANGE! tomwalters@0: tomwalters@0: 05 May 1989 (Paul Manson) -- The above problem has been temporarily rectified by tomwalters@0: using the default width and height options to indicate tomwalters@0: the actual screen size. Also, the options format change tomwalters@0: has been accounted for. tomwalters@0: tomwalters@0: 11 May 1989 (Paul Manson) -- Altered options to conform to the new(est) r'egime. tomwalters@0: tomwalters@0: 15 May 1989 (Paul Manson) -- Incorporated the PC-style wildcarding into the Unix version. tomwalters@0: Made display use "NULL" instead of (char *) 0. tomwalters@0: tomwalters@0: 05 June 1989 (Paul Manson) -- Altered a couple of the option comments to reflect their tomwalters@0: behaviour more accurately. I also encountered the rather tomwalters@0: suspicious "bug" whereby revsai gets a segmentation fault tomwalters@0: whenever it is run on an old "sai" file ... those generated tomwalters@0: by sai now appear to be OK... If this really is a problem, tomwalters@0: it should be tracked down! tomwalters@0: tomwalters@0: 06 July 1989 (Paul Manson) -- As well as altering revsai to accomodate all of the new tomwalters@0: options names, I note that the abovementioned bug appears tomwalters@0: to have disappeared without trace; hopefully it was just tomwalters@0: due to previous (buggy) files, etc. tomwalters@0: tomwalters@0: 3 August 1993 (M. Akeroyd) -- Added declarations of "colourstr" and "planemaskstr". tomwalters@0: They aren't used, but are in X.c (and thus libglib.a), tomwalters@0: and are therfore required to fool the linker. tomwalters@0: tomwalters@0: 25 March 1994 (M. Akeroyd) -- Added colour. mono etc, so that 'review' would actually work. tomwalters@0: (the previuos cahnge just made it compile.) tomwalters@0: */ tomwalters@0: tomwalters@0: #include tomwalters@0: #include tomwalters@0: #include tomwalters@0: tomwalters@0: #if defined(THINK_C) || defined(NeXT) tomwalters@0: #include tomwalters@0: #else tomwalters@0: #include tomwalters@0: #endif tomwalters@0: tomwalters@0: #include "windows.h" tomwalters@0: #include "options.h" tomwalters@0: tomwalters@0: tomwalters@0: char *monostr, *colourstr, *planemaskstr; /* MAA 3-8-1993 */ tomwalters@0: char *fgcolourstr, *bgcolourstr; /* MAA 19-8-1993 */ tomwalters@0: #ifndef lint tomwalters@0: static char *sccs_id = "@(#)review.c 1.13 Paul Manson, John Holdsworth (MRC-APU) 5/31/91"; tomwalters@0: #endif tomwalters@0: tomwalters@0: #define max(A,B) (((A) > (B)) ? (A) : (B)) tomwalters@0: #define LENGTH_STR "remainder" tomwalters@0: #define MAX_LENGTH (9999) tomwalters@0: tomwalters@0: #define CENTER_STR "center" tomwalters@0: #define IMAGE_SUFFIX ".ctn" tomwalters@0: tomwalters@0: #ifdef PC tomwalters@0: #define READ_BINARY "rb" tomwalters@0: #else tomwalters@0: #define READ_BINARY "r" tomwalters@0: #endif tomwalters@0: tomwalters@0: /* configurables */ tomwalters@0: tomwalters@0: static char *helpstr ; tomwalters@0: static char *speed1str, *speed2str ; tomwalters@0: static char *xstr, *ystr, *widthstr, *heightstr ; tomwalters@0: static char *start1str, *stop1str, *step1str ; tomwalters@0: static char *start2str, *stop2str, *step2str ; tomwalters@0: static char *minstr , *maxstr , *framestr ; tomwalters@0: static char *in1str, *in2str, *downstr ; tomwalters@0: tomwalters@0: #if !defined( PC ) tomwalters@0: extern void exit(); tomwalters@0: static char *memorystr; tomwalters@0: #endif tomwalters@0: tomwalters@0: static Option res[] = { tomwalters@0: { "help", "none", &helpstr, " []\n\n\ tomwalters@0: Redisplays stored images from memory or directly from disk.\n\ tomwalters@0: Review responds to various simple commands, viz.\n\n\ tomwalters@0: 1\t Activate only wave1 (default when only one wave named).\n\ tomwalters@0: 2\t Activate only wave2.\n\ tomwalters@0: b or B\t Activate Both waves (default when two waves named).\n\n\ tomwalters@0: a or A\t Animate cartoon wave(s). Hitting space bar is equivalent.\n\ tomwalters@0: s or S\t Single-step activated wave(s). Hit space bar to step.\n\ tomwalters@0: +\t Animate activated wave(s) faster.\n\ tomwalters@0: -\t Animate activated wave(s) slower.\n\n\ tomwalters@0: q or Q\t Quit Revue.\n", SilentOption }, tomwalters@0: { "input1", NULL_OPTION, &in1str, "Default input file name 1", InputOption}, tomwalters@0: { "start1" , "0" , &start1str , "Start point in wave 1 (in ms)", InputOption}, tomwalters@0: { "length1", LENGTH_STR, &stop1str , "Length of wave 1 to display (in ms)", InputOption}, tomwalters@0: { "step1" , "1" , &step1str , "Display every step-th image of wave 1", InputOption}, tomwalters@0: { "speed1", "1" , &speed1str, "Image 1 display speed (1 is fastest)", InputOption}, tomwalters@0: tomwalters@0: { "input2", NULL_OPTION, &in2str, "Default input file name 2\n", InputOption}, tomwalters@0: { "start2" , "0" , &start2str , "Start point in wave 2 (in ms)", InputOption}, tomwalters@0: { "length2", LENGTH_STR, &stop2str , "Length of wave 2 to display (in ms)", InputOption}, tomwalters@0: { "step2" , "1" , &step2str , "Display every step-th image of wave 2", InputOption}, tomwalters@0: { "speed2", "1" , &speed2str, "Image 2 display speed (1 is fastest)", InputOption}, tomwalters@0: tomwalters@0: { "x0_win", CENTER_STR, &xstr, "Left edge of window (in pixels)" , SilentOption}, tomwalters@0: { "y0_win", CENTER_STR, &ystr, "Upper edge of window (in pixels)", SilentOption}, tomwalters@0: { "width_screen", "960", &widthstr, "Physical screen width in pixels", SilentOption}, tomwalters@0: { "height_screen","750", &heightstr, "Physical screen height in pixels", SilentOption}, tomwalters@0: tomwalters@0: /* MAA: 25 March 1994 tomwalters@0: * These next added because they are used from within X.c (although defined in gen.c), and thus the graphics tomwalters@0: * calls. They are of NO meaning, however; they define how the Model makes the bitmaps. tomwalters@0: * Once made, you cannot edit bitmaps ... tomwalters@0: */ tomwalters@0: { "fg_col", "black", &fgcolourstr, "Foreground Colour.\n", SilentOption}, tomwalters@0: { "bg_col", "white", &bgcolourstr, "Background Colour.\n", SilentOption}, tomwalters@0: { "mono_ctn", ON_OPTION, &monostr, "Force monochrome (single plane) cartoons.", SilentOption}, tomwalters@0: { "colour_ctn", OFF_OPTION, &colourstr, "Force colour (multi-plane) cartoons.", SilentOption}, tomwalters@0: {"planemask_ctn", "1", &planemaskstr, "Planemask for creating cartoons.\n", SilentOption}, tomwalters@0: /* MAA: End of that bit */ tomwalters@0: tomwalters@0: #if !defined( PC ) tomwalters@0: { "memory", ON_OPTION, &memorystr, "Read images into memory for reviewing\n", InputOption}, tomwalters@0: #endif tomwalters@0: ( char * ) 0 } ; tomwalters@0: tomwalters@0: static Option hiddenRes[] = { tomwalters@0: { "downsample", "20", &downstr, "Image file frame size (in ms)", InputOption}, tomwalters@0: { "frstep_aid", "20", &framestr, "Image file frame size (in ms)", InputOption}, tomwalters@0: { "mincf_afb", "220", &minstr , "Minimum Center Frequency in Hertz", InputOption}, tomwalters@0: { "maxcf_afb", "4400", &maxstr , "Maximum Center Frequency in Hertz", InputOption}, tomwalters@0: { "width_win", "900", &widthstr, "Window width (pixels)", InputOption}, tomwalters@0: { "height_win", "600", &heightstr, "Window height (pixels)", InputOption}, tomwalters@0: ( char * ) 0 } ; tomwalters@0: tomwalters@0: #define ONE (1) tomwalters@0: #define TWO (2) tomwalters@0: #define BOTH (0) tomwalters@0: tomwalters@0: #define FALSE (0) tomwalters@0: #define TRUE (1) tomwalters@0: #define OVERTHETOP (10000) tomwalters@0: #define AXES_WIDTH (15) tomwalters@0: tomwalters@0: static int msToImages(frame, ms) tomwalters@0: double frame; tomwalters@0: double ms ; tomwalters@0: { tomwalters@0: return (((int) (ms / frame)) + 1); /* Round Up */ tomwalters@0: } tomwalters@0: tomwalters@0: /* File Name Suffix Conversion Parameters */ tomwalters@0: tomwalters@0: #define BACKSLASH_CHAR '\\' tomwalters@0: #define SLASH_CHARACTER '/' tomwalters@0: #define NULL_CHARACTER '\000' tomwalters@0: #define DOT_CHARACTER '.' tomwalters@0: tomwalters@0: /******************************************************************************************/ tomwalters@0: /* */ tomwalters@0: /* AlterSuffix(). Returns its argument fileName with a newSuffix appended in place of */ tomwalters@0: /* any previous suffix it may have had. It should be noted that this */ tomwalters@0: /* suffix must include any DOT it wishes to have appended to the name. */ tomwalters@0: /* */ tomwalters@0: /******************************************************************************************/ tomwalters@0: tomwalters@0: char *AlterSuffix(fileName, newSuffix) tomwalters@0: char *fileName, *newSuffix; tomwalters@0: { tomwalters@0: char *temp, *temp2, *lastPart; tomwalters@0: int i; tomwalters@0: tomwalters@0: temp = malloc((unsigned) (strlen(fileName) + strlen(newSuffix) + 1)); tomwalters@0: tomwalters@0: temp = strcpy(temp, fileName); tomwalters@0: tomwalters@0: #if defined( PC ) tomwalters@0: /* Change all backslashes to forward slashes */ tomwalters@0: for (i = 0; temp[i] != NULL_CHARACTER; i++) tomwalters@0: if (temp[i] == BACKSLASH_CHAR) tomwalters@0: temp[i] = SLASH_CHARACTER; tomwalters@0: #endif tomwalters@0: tomwalters@0: if ((lastPart = strrchr(temp, SLASH_CHARACTER)) == NULL) tomwalters@0: lastPart = temp; tomwalters@0: else tomwalters@0: lastPart++; /* Skip over the actual "/" */ tomwalters@0: tomwalters@0: /* lastPart points to the tail name of the path */ tomwalters@0: tomwalters@0: if ((temp2 = strchr(lastPart, DOT_CHARACTER)) == NULL) tomwalters@0: temp = strcat(temp, newSuffix); tomwalters@0: else tomwalters@0: temp2 = strcpy(temp2, newSuffix); tomwalters@0: tomwalters@0: return (temp); tomwalters@0: } tomwalters@0: tomwalters@0: /* ----------------------------------------------------------------------------------- tomwalters@0: tomwalters@0: A Routine to extend revsai for in-memory animation. This copies every image from tomwalters@0: to by into the images buffer for the window . It then tomwalters@0: expects contiguous animation of these images. The integer returned is the number tomwalters@0: of images that were saved; subsequent image Recall() calls should refer to images tomwalters@0: in the range [1 .. this returned value]. tomwalters@0: tomwalters@0: ----------------------------------------------------------------------------------- */ tomwalters@0: tomwalters@0: static int readIntoMemory(w, filePtr, start, stop, step) tomwalters@0: WindowObject w; tomwalters@0: FILE *filePtr ; tomwalters@0: int start; tomwalters@0: int stop; tomwalters@0: int step; tomwalters@0: { tomwalters@0: int fileImage, memImage; tomwalters@0: tomwalters@0: memImage = 0; tomwalters@0: tomwalters@0: fileImage = start; tomwalters@0: tomwalters@0: while (fileImage <= stop && Read(w, filePtr, fileImage)) { tomwalters@0: Store(w); tomwalters@0: fileImage += step; tomwalters@0: memImage++; tomwalters@0: } tomwalters@0: tomwalters@0: return (memImage); tomwalters@0: } tomwalters@0: tomwalters@0: main( argc, argv ) tomwalters@0: int argc ; tomwalters@0: char *argv[] ; tomwalters@0: { tomwalters@0: WindowObject w1, w2; tomwalters@0: int screenWidth, screenHeight ; tomwalters@0: int firstWidth , firstHeight ; tomwalters@0: int secondWidth, secondHeight ; tomwalters@0: int firstPixels, secondPixels ; tomwalters@0: FILE *firstWave , *secondWave ; tomwalters@0: tomwalters@0: int OneWave, TwoWaves, spareWidth, tomwalters@0: spareHeight ; tomwalters@0: tomwalters@0: int waveMode , image1 , image2; tomwalters@0: int count1 , count2; tomwalters@0: int stopFirst, stopSecond ; tomwalters@0: int start1 , stop1 , step1 ; tomwalters@0: int start2 , stop2 , step2 ; tomwalters@0: int speed1 , speed2 ; tomwalters@0: tomwalters@0: char command, *firstWaveName, tomwalters@0: *secondWaveName, tomwalters@0: *programName; tomwalters@0: tomwalters@0: double mincf1, mincf2, maxcf1, maxcf2, frame1, frame2; tomwalters@0: int inMemory, x, y; tomwalters@0: tomwalters@0: programName = argv[0]; tomwalters@0: tomwalters@0: (void) getopts( res, &argc, &argv ); tomwalters@0: tomwalters@0: /* Extract any information from the opts which is NECESSARY for the tomwalters@0: operation of revue */ tomwalters@0: tomwalters@0: screenWidth = atoi( widthstr ); tomwalters@0: screenHeight= atoi( heightstr); tomwalters@0: tomwalters@0: #if defined( PC ) tomwalters@0: inMemory = FALSE; tomwalters@0: #else tomwalters@0: inMemory = isON( memorystr ); tomwalters@0: #endif tomwalters@0: tomwalters@0: if (argc > 2 || (argc == 0 && isNULL(in1str))) { tomwalters@0: (void) helpopts(res, programName); tomwalters@0: exit(1); tomwalters@0: } tomwalters@0: else { tomwalters@0: OneWave = ((argc == 0 && !isNULL(in1str)) || tomwalters@0: (argc == 1 && isNULL(in2str))); tomwalters@0: TwoWaves = !OneWave; tomwalters@0: } tomwalters@0: tomwalters@0: if (argc == 0) tomwalters@0: firstWaveName = AlterSuffix(in1str, IMAGE_SUFFIX) ; tomwalters@0: else tomwalters@0: firstWaveName = AlterSuffix(argv[0], IMAGE_SUFFIX); tomwalters@0: tomwalters@0: if ((firstWave = fopen(firstWaveName, READ_BINARY )) == NULL) { tomwalters@0: (void) fprintf(stderr, "Could not open the image file %s.\n", firstWaveName); tomwalters@0: exit(1); tomwalters@0: } tomwalters@0: tomwalters@0: (void) readopts(res, firstWave); tomwalters@0: tomwalters@0: if (fseek(firstWave, 0l, 0)) { tomwalters@0: (void) fprintf(stderr, "revsai: Could not re-seek the %s file.\n", tomwalters@0: firstWaveName); tomwalters@0: exit(1); tomwalters@0: } tomwalters@0: tomwalters@0: (void) readopts(hiddenRes, firstWave); tomwalters@0: tomwalters@0: if( framestr == (char *) 0 ) tomwalters@0: if( downstr == (char *) 0 ) tomwalters@0: frame1 = 1 ; tomwalters@0: else tomwalters@0: frame1 = atof(downstr); tomwalters@0: else if ((frame1 = atof(framestr)) < 0.0) tomwalters@0: frame1 = 0.0; tomwalters@0: tomwalters@0: firstWidth = atoi( widthstr ); tomwalters@0: firstHeight = atoi( heightstr); tomwalters@0: tomwalters@0: start1 = msToImages(frame1, atof( start1str )); tomwalters@0: tomwalters@0: if (strcmp(stop1str, LENGTH_STR) == 0) tomwalters@0: stop1 = MAX_LENGTH; tomwalters@0: else tomwalters@0: stop1 = msToImages(frame1, atof( stop1str )) + start1; tomwalters@0: tomwalters@0: step1 = atoi( step1str ); tomwalters@0: if (step1 < 1) tomwalters@0: step1 = 1; tomwalters@0: tomwalters@0: firstPixels = 1; /* atoi( pixelstr ); */ tomwalters@0: tomwalters@0: mincf1 = atof( minstr ); tomwalters@0: maxcf1 = atof( maxstr ); tomwalters@0: tomwalters@0: if (TwoWaves) { tomwalters@0: tomwalters@0: if (argc == 1) tomwalters@0: secondWaveName = AlterSuffix(in2str, IMAGE_SUFFIX); tomwalters@0: else tomwalters@0: secondWaveName = AlterSuffix(argv[1],IMAGE_SUFFIX); tomwalters@0: tomwalters@0: if ((secondWave = fopen(secondWaveName, READ_BINARY )) == NULL) { tomwalters@0: (void) fprintf(stderr, "Could not open the image file %s.\n", tomwalters@0: secondWaveName); tomwalters@0: exit(1); tomwalters@0: } tomwalters@0: tomwalters@0: (void) readopts(res, secondWave); tomwalters@0: if (fseek(secondWave, 0l, 0)) { tomwalters@0: (void) fprintf(stderr, "revsai: Could not re-seek the %s file.\n", tomwalters@0: secondWaveName); tomwalters@0: exit(1); tomwalters@0: } tomwalters@0: (void) readopts(hiddenRes, secondWave); tomwalters@0: tomwalters@0: if( framestr == (char *) 0 ) tomwalters@0: if( downstr == (char *) 0 ) tomwalters@0: frame2 = 1. ; tomwalters@0: else tomwalters@0: frame2 = atof(downstr); tomwalters@0: else if ((frame2 = atof(framestr)) < 0.0) tomwalters@0: frame2 = atof(downstr); tomwalters@0: tomwalters@0: secondWidth = atoi( widthstr ); tomwalters@0: secondHeight = atoi( heightstr); tomwalters@0: tomwalters@0: start2 = msToImages(frame2, atof( start2str )); tomwalters@0: tomwalters@0: if (strcmp(stop2str, LENGTH_STR) == 0) tomwalters@0: stop2 = MAX_LENGTH; tomwalters@0: else tomwalters@0: stop2 = msToImages(frame2, atof( stop2str )) + start2; tomwalters@0: tomwalters@0: step2 = atoi( step2str ); tomwalters@0: if (step2 < 1) tomwalters@0: step2 = 1; tomwalters@0: tomwalters@0: secondPixels = 1; /* atoi( pixelstr ); */ tomwalters@0: tomwalters@0: mincf2 = atof( minstr ); tomwalters@0: maxcf2 = atof( maxstr ); tomwalters@0: tomwalters@0: } tomwalters@0: tomwalters@0: tomwalters@0: /* Open display window(s) */ tomwalters@0: tomwalters@0: if (TwoWaves) { tomwalters@0: /* Center them both for height, but try to fit them both on the screen tomwalters@0: at once, width-wise. Firstly, get the REAL screen size */ tomwalters@0: #if defined( PC ) tomwalters@0: w1 = newDisplayWindow(firstWaveName, -1, -1, OVERTHETOP, OVERTHETOP, 1); tomwalters@0: screenWidth = Width(w1); tomwalters@0: screenHeight = Height(w1); tomwalters@0: Close(w1); tomwalters@0: #endif tomwalters@0: tomwalters@0: if (screenHeight < firstHeight || screenHeight < secondHeight) { tomwalters@0: (void) fprintf(stderr, "revsai: One (or both) of the waves specified was too\n high for this screen.\n"); tomwalters@0: exit(1); tomwalters@0: } tomwalters@0: if (screenWidth < firstWidth + secondWidth) { tomwalters@0: (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"); tomwalters@0: exit(1); tomwalters@0: } tomwalters@0: tomwalters@0: spareWidth = screenWidth - (firstWidth + secondWidth + (2 * AXES_WIDTH)); tomwalters@0: spareHeight = screenHeight - (firstHeight + (2 * AXES_WIDTH)); tomwalters@0: tomwalters@0: w1 = newDisplayWindow(firstWaveName, spareWidth/6 + AXES_WIDTH, spareHeight/2, tomwalters@0: firstWidth, firstHeight, firstPixels); tomwalters@0: Axes(w1, firstWaveName, 0.0, frame1, "Image Frame Size (in ms)", tomwalters@0: mincf1, maxcf1, "Center Frequency (in Hz)"); tomwalters@0: tomwalters@0: spareHeight = screenHeight - (secondHeight + (2 * AXES_WIDTH)); tomwalters@0: tomwalters@0: w2 = newDisplayWindow(secondWaveName, (5 * spareWidth / 6) + tomwalters@0: firstWidth + (2 * AXES_WIDTH), tomwalters@0: spareHeight/2, secondWidth, secondHeight, tomwalters@0: secondPixels); tomwalters@0: Axes(w2, secondWaveName, 0.0, frame2, "Image Frame Size (in ms)", tomwalters@0: mincf2, maxcf2, "Center Frequency (in Hz)"); tomwalters@0: } tomwalters@0: else { tomwalters@0: /* Easy .. MetaPC Centers it for us */ tomwalters@0: if (OptionStringsEqual(xstr, CENTER_STR)) tomwalters@0: x = -1; tomwalters@0: else tomwalters@0: x = atoi(xstr); tomwalters@0: tomwalters@0: if (OptionStringsEqual(ystr, CENTER_STR)) tomwalters@0: y = -1; tomwalters@0: else tomwalters@0: y = atoi(ystr); tomwalters@0: tomwalters@0: w1 = newDisplayWindow(firstWaveName, x, y, firstWidth, firstHeight, tomwalters@0: firstPixels ); tomwalters@0: Axes(w1, firstWaveName, 0.0, frame1, "Image Frame Size (in ms)", tomwalters@0: mincf1, maxcf1, "Center Frequency (in Hz)"); tomwalters@0: tomwalters@0: #if defined( SUN ) tomwalters@0: /* Kludge to overcome the window-sizing inconsistency when tomwalters@0: you open a SunView window with a frame */ tomwalters@0: tomwalters@0: if (Height(w1) > firstHeight || Width(w1) > firstWidth) { tomwalters@0: #else tomwalters@0: if (Height(w1) != firstHeight || Width(w1) != firstWidth) { tomwalters@0: #endif tomwalters@0: (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"); tomwalters@0: exit(1); tomwalters@0: } tomwalters@0: } tomwalters@0: tomwalters@0: /* Do the actual reviewing */ tomwalters@0: tomwalters@0: if (TwoWaves) tomwalters@0: waveMode = BOTH; tomwalters@0: else tomwalters@0: waveMode = ONE ; tomwalters@0: tomwalters@0: speed1 = atoi( speed1str ); tomwalters@0: if (speed1 < 1) tomwalters@0: speed1 = 1; tomwalters@0: speed2 = atoi( speed2str ); tomwalters@0: if (speed2 < 1) tomwalters@0: speed2 = 1; tomwalters@0: tomwalters@0: /* Initially, just open the files and display the first frame of each, */ tomwalters@0: /* UNLESS the inMemory switch is set, in which case you should read in */ tomwalters@0: /* all of the images and adjust start, stop to suit. */ tomwalters@0: tomwalters@0: if (inMemory) { tomwalters@0: stop1 = readIntoMemory(w1, firstWave, start1, stop1, step1); tomwalters@0: start1 = 1; /* Now runs from 0 to the adjusted stop */ tomwalters@0: step1 = 1; /* Now the images are contiguous */ tomwalters@0: if (TwoWaves) { tomwalters@0: stop2 = readIntoMemory(w2, secondWave, start2, stop2, step2); tomwalters@0: start2 = 1; /* Now runs from 0 to the adjusted stop */ tomwalters@0: step2 = 1; /* Now the images are contiguous */ tomwalters@0: } tomwalters@0: } tomwalters@0: else { tomwalters@0: if (!Read(w1, firstWave, start1)) { tomwalters@0: (void) fprintf(stderr, "revsai: Could not read the first image from the first wave.\n"); tomwalters@0: exit(1); tomwalters@0: } tomwalters@0: tomwalters@0: if (TwoWaves && !Read(w2, secondWave, start2)) { tomwalters@0: (void) fprintf(stderr, "revsai: Couldn't read the first image from the second wave.\n"); tomwalters@0: exit(1); tomwalters@0: } tomwalters@0: } tomwalters@0: tomwalters@0: /* Sit and take commands */ tomwalters@0: tomwalters@0: while ((command = Pause(w1)) != 'q' && command != 'Q') { tomwalters@0: switch (command) { tomwalters@0: case '1': tomwalters@0: /* Toggle to Wave number One */ tomwalters@0: waveMode = ONE; tomwalters@0: break; tomwalters@0: case '2': tomwalters@0: /* Try to toggle to Wave number Two */ tomwalters@0: if (TwoWaves) tomwalters@0: waveMode = TWO; tomwalters@0: break; tomwalters@0: case 'b': case 'B': tomwalters@0: /* Try to toggle to Both Waves */ tomwalters@0: if (TwoWaves) tomwalters@0: waveMode = BOTH; tomwalters@0: break; tomwalters@0: case '+': tomwalters@0: /* Speed up current Wave(s) */ tomwalters@0: if (waveMode == ONE || waveMode == BOTH) tomwalters@0: speed1 = ((speed1 > 1) ? (speed1 /= 2) : (1)); tomwalters@0: if (waveMode == TWO || waveMode == BOTH) tomwalters@0: speed2 = ((speed2 > 1) ? (speed2 /= 2) : (1)); tomwalters@0: break; tomwalters@0: case '-': tomwalters@0: /* Slow down current Wave(s) */ tomwalters@0: if (waveMode == ONE || waveMode == BOTH) tomwalters@0: speed1 *= 2; tomwalters@0: if (waveMode == TWO || waveMode == BOTH) tomwalters@0: speed2 *= 2; tomwalters@0: break; tomwalters@0: case 's': case 'S': tomwalters@0: stopFirst = (waveMode == TWO); tomwalters@0: stopSecond = (waveMode == ONE); tomwalters@0: image1 = start1; tomwalters@0: image2 = start2; tomwalters@0: while (!(stopFirst && stopSecond) && (Pause(w1) == ' ')) { tomwalters@0: if (!stopFirst) { tomwalters@0: if (inMemory) tomwalters@0: Recall(w1, image1); tomwalters@0: else tomwalters@0: stopFirst = !Read(w1, firstWave , image1); tomwalters@0: if (!stopFirst) { tomwalters@0: image1 += step1; tomwalters@0: stopFirst = (image1 > stop1); tomwalters@0: } tomwalters@0: } tomwalters@0: if (!stopSecond) { tomwalters@0: if (inMemory) tomwalters@0: Recall(w2, image2); tomwalters@0: else tomwalters@0: stopSecond = !Read(w2, secondWave, image2); tomwalters@0: if (!stopSecond) { tomwalters@0: image2 += step2; tomwalters@0: stopSecond = (image2 > stop2); tomwalters@0: } tomwalters@0: } tomwalters@0: } tomwalters@0: break; tomwalters@0: case 'a': case 'A': case ' ': tomwalters@0: stopFirst = (waveMode == TWO); tomwalters@0: stopSecond = (waveMode == ONE); tomwalters@0: image1 = start1; tomwalters@0: image2 = start2; tomwalters@0: count1 = count2 = 0 ; tomwalters@0: while (!(stopFirst && stopSecond)) { tomwalters@0: if (stopFirst || image1 > stop1) { tomwalters@0: if (waveMode == BOTH && !stopSecond && image2 <= stop2 && tomwalters@0: image1 > start1 && count1 == 0) { tomwalters@0: /* Redisplay the previous image for constant speed */ tomwalters@0: if (inMemory) tomwalters@0: Recall(w1, image1-1); tomwalters@0: else tomwalters@0: stopFirst = !Read(w1, firstWave, image1-1); tomwalters@0: } tomwalters@0: stopFirst = TRUE; tomwalters@0: } tomwalters@0: else { tomwalters@0: if (inMemory) tomwalters@0: Recall(w1, image1); tomwalters@0: else tomwalters@0: stopFirst = !Read(w1, firstWave, image1); tomwalters@0: if (!stopFirst) tomwalters@0: if (++count1 >= speed1) { tomwalters@0: image1 += step1; tomwalters@0: count1 = 0 ; tomwalters@0: } tomwalters@0: } tomwalters@0: if (stopSecond || image2 > stop2) { tomwalters@0: if (waveMode == BOTH && !stopFirst && image1 <= stop1 && tomwalters@0: image2 > start2 && count2 == 0) { tomwalters@0: /* Redisplay the previous image for constant speed */ tomwalters@0: if (inMemory) tomwalters@0: Recall(w2, image2-1); tomwalters@0: else tomwalters@0: stopSecond = !Read(w2, secondWave, image2-1); tomwalters@0: } tomwalters@0: stopSecond = TRUE; tomwalters@0: } tomwalters@0: else { tomwalters@0: if (inMemory) tomwalters@0: Recall(w2, image2); tomwalters@0: else tomwalters@0: stopSecond = !Read(w2, secondWave, image2); tomwalters@0: if (!stopSecond) tomwalters@0: if (++count2 >= speed2) { tomwalters@0: image2 += step2; tomwalters@0: count2 = 0 ; tomwalters@0: } tomwalters@0: } tomwalters@0: } tomwalters@0: break; tomwalters@0: default: tomwalters@0: break; tomwalters@0: } tomwalters@0: } tomwalters@0: if (fclose(firstWave)) { tomwalters@0: (void) fprintf(stderr, "revsai: Could not close file % correctly.\n", tomwalters@0: firstWaveName); tomwalters@0: exit(1); tomwalters@0: } tomwalters@0: if (TwoWaves && fclose(secondWave)) { tomwalters@0: (void) fprintf(stderr, "revsai: Could not close file % correctly.\n", tomwalters@0: secondWaveName); tomwalters@0: exit(1); tomwalters@0: } tomwalters@0: }